Mirror von
https://github.com/PaperMC/Velocity.git
synchronisiert 2024-11-16 21:10:30 +01:00
Upgrade to Gradle 6.6 and use SpotBugs.
As a result, at least one real bug was fixed! Nice.
Dieser Commit ist enthalten in:
Ursprung
d8dba436d6
Commit
c47d25c88a
@ -1,12 +1,10 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id 'java'
|
id 'java-library'
|
||||||
id 'maven-publish'
|
id 'maven-publish'
|
||||||
id 'checkstyle'
|
id 'checkstyle'
|
||||||
id "net.ltgt.errorprone" version "0.8"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
apply from: '../gradle/checkstyle.gradle'
|
apply from: '../gradle/checkstyle.gradle'
|
||||||
apply from: '../gradle/errorprone.gradle'
|
|
||||||
apply plugin: 'com.github.johnrengelman.shadow'
|
apply plugin: 'com.github.johnrengelman.shadow'
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
@ -16,35 +14,35 @@ sourceSets {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile 'com.google.code.gson:gson:2.8.6'
|
api 'com.google.code.gson:gson:2.8.6'
|
||||||
compile "com.google.guava:guava:${guavaVersion}"
|
api "com.google.guava:guava:${guavaVersion}"
|
||||||
|
|
||||||
// DEPRECATED: Will be removed in Velocity 2.0.0
|
// DEPRECATED: Will be removed in Velocity 2.0.0
|
||||||
compile "net.kyori:text-api:${textVersion}"
|
api "net.kyori:text-api:${textVersion}"
|
||||||
compile "net.kyori:text-serializer-gson:${textVersion}"
|
api "net.kyori:text-serializer-gson:${textVersion}"
|
||||||
compile "net.kyori:text-serializer-legacy:${textVersion}"
|
api "net.kyori:text-serializer-legacy:${textVersion}"
|
||||||
compile "net.kyori:text-serializer-plain:${textVersion}"
|
api "net.kyori:text-serializer-plain:${textVersion}"
|
||||||
|
|
||||||
// DEPRECATED: Will be removed in Velocity 2.0.0
|
// DEPRECATED: Will be removed in Velocity 2.0.0
|
||||||
compile 'com.moandjiezana.toml:toml4j:0.7.2'
|
api 'com.moandjiezana.toml:toml4j:0.7.2'
|
||||||
|
|
||||||
compile "net.kyori:adventure-api:${adventureVersion}"
|
api "net.kyori:adventure-api:${adventureVersion}"
|
||||||
compile "net.kyori:adventure-text-serializer-gson:${adventureVersion}"
|
api "net.kyori:adventure-text-serializer-gson:${adventureVersion}"
|
||||||
compile "net.kyori:adventure-text-serializer-legacy:${adventureVersion}"
|
api "net.kyori:adventure-text-serializer-legacy:${adventureVersion}"
|
||||||
compile "net.kyori:adventure-text-serializer-plain:${adventureVersion}"
|
api "net.kyori:adventure-text-serializer-plain:${adventureVersion}"
|
||||||
compile "net.kyori:adventure-text-serializer-legacy-text3:${adventureVersion}"
|
api "net.kyori:adventure-text-serializer-legacy-text3:${adventureVersion}"
|
||||||
|
|
||||||
compile "org.slf4j:slf4j-api:${slf4jVersion}"
|
api "org.slf4j:slf4j-api:${slf4jVersion}"
|
||||||
compile 'com.google.inject:guice:4.2.3'
|
api 'com.google.inject:guice:4.2.3'
|
||||||
compile "org.checkerframework:checker-qual:${checkerFrameworkVersion}"
|
api "org.checkerframework:checker-qual:${checkerFrameworkVersion}"
|
||||||
compile 'com.mojang:brigadier:1.0.17'
|
api 'com.mojang:brigadier:1.0.17'
|
||||||
|
|
||||||
compile "org.spongepowered:configurate-hocon:${configurateVersion}"
|
api "org.spongepowered:configurate-hocon:${configurateVersion}"
|
||||||
compile "org.spongepowered:configurate-yaml:${configurateVersion}"
|
api "org.spongepowered:configurate-yaml:${configurateVersion}"
|
||||||
compile "org.spongepowered:configurate-gson:${configurateVersion}"
|
api "org.spongepowered:configurate-gson:${configurateVersion}"
|
||||||
|
|
||||||
testCompile "org.junit.jupiter:junit-jupiter-api:${junitVersion}"
|
testImplementation "org.junit.jupiter:junit-jupiter-api:${junitVersion}"
|
||||||
testCompile "org.junit.jupiter:junit-jupiter-engine:${junitVersion}"
|
testImplementation "org.junit.jupiter:junit-jupiter-engine:${junitVersion}"
|
||||||
}
|
}
|
||||||
|
|
||||||
task javadocJar(type: Jar) {
|
task javadocJar(type: Jar) {
|
||||||
|
13
build.gradle
13
build.gradle
@ -9,9 +9,12 @@ buildscript {
|
|||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id 'java'
|
id 'java'
|
||||||
|
id "com.github.spotbugs" version "4.2.4" apply false
|
||||||
}
|
}
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
|
apply plugin: "com.github.spotbugs"
|
||||||
|
|
||||||
group 'com.velocitypowered'
|
group 'com.velocitypowered'
|
||||||
version '1.1.0-SNAPSHOT'
|
version '1.1.0-SNAPSHOT'
|
||||||
|
|
||||||
@ -70,4 +73,14 @@ allprojects {
|
|||||||
junitXml.enabled = true
|
junitXml.enabled = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tasks.withType(com.github.spotbugs.snom.SpotBugsTask) {
|
||||||
|
reports {
|
||||||
|
html {
|
||||||
|
enabled = true
|
||||||
|
destination = file("$buildDir/reports/spotbugs/main/spotbugs.html")
|
||||||
|
stylesheet = 'fancy-hist.xsl'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
dependencies {
|
|
||||||
errorprone("com.google.errorprone:error_prone_core:2.3.3")
|
|
||||||
errorproneJavac("com.google.errorprone:javac:9+181-r4173-1")
|
|
||||||
}
|
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
|||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6-all.zip
|
||||||
|
@ -1,17 +1,15 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id 'java'
|
id 'java-library'
|
||||||
id 'checkstyle'
|
id 'checkstyle'
|
||||||
id "net.ltgt.errorprone" version "0.8"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
apply from: '../gradle/checkstyle.gradle'
|
apply from: '../gradle/checkstyle.gradle'
|
||||||
apply from: '../gradle/errorprone.gradle'
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile "com.google.guava:guava:${guavaVersion}"
|
implementation "com.google.guava:guava:${guavaVersion}"
|
||||||
compile "io.netty:netty-handler:${nettyVersion}"
|
implementation "io.netty:netty-handler:${nettyVersion}"
|
||||||
compile "org.checkerframework:checker-qual:${checkerFrameworkVersion}"
|
implementation "org.checkerframework:checker-qual:${checkerFrameworkVersion}"
|
||||||
|
|
||||||
testCompile "org.junit.jupiter:junit-jupiter-api:${junitVersion}"
|
testImplementation "org.junit.jupiter:junit-jupiter-api:${junitVersion}"
|
||||||
testCompile "org.junit.jupiter:junit-jupiter-engine:${junitVersion}"
|
testImplementation "org.junit.jupiter:junit-jupiter-engine:${junitVersion}"
|
||||||
}
|
}
|
@ -3,11 +3,9 @@ import com.github.jengelman.gradle.plugins.shadow.transformers.Log4j2PluginsCach
|
|||||||
plugins {
|
plugins {
|
||||||
id 'java'
|
id 'java'
|
||||||
id 'checkstyle'
|
id 'checkstyle'
|
||||||
id "net.ltgt.errorprone" version "0.8"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
apply from: '../gradle/checkstyle.gradle'
|
apply from: '../gradle/checkstyle.gradle'
|
||||||
apply from: '../gradle/errorprone.gradle'
|
|
||||||
apply plugin: 'com.github.johnrengelman.shadow'
|
apply plugin: 'com.github.johnrengelman.shadow'
|
||||||
|
|
||||||
jar {
|
jar {
|
||||||
@ -38,43 +36,43 @@ tasks.withType(Checkstyle) {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
// Note: we depend on the API twice, first the main sourceset, and then the annotation processor.
|
// Note: we depend on the API twice, first the main sourceset, and then the annotation processor.
|
||||||
compile project(':velocity-api')
|
implementation project(':velocity-api')
|
||||||
compile project(':velocity-api').sourceSets.ap.output
|
implementation project(':velocity-api').sourceSets.ap.output
|
||||||
compile project(':velocity-native')
|
implementation project(':velocity-native')
|
||||||
|
|
||||||
compile "io.netty:netty-codec:${nettyVersion}"
|
implementation "io.netty:netty-codec:${nettyVersion}"
|
||||||
compile "io.netty:netty-codec-haproxy:${nettyVersion}"
|
implementation "io.netty:netty-codec-haproxy:${nettyVersion}"
|
||||||
compile "io.netty:netty-codec-http:${nettyVersion}"
|
implementation "io.netty:netty-codec-http:${nettyVersion}"
|
||||||
compile "io.netty:netty-handler:${nettyVersion}"
|
implementation "io.netty:netty-handler:${nettyVersion}"
|
||||||
compile "io.netty:netty-transport-native-epoll:${nettyVersion}"
|
implementation "io.netty:netty-transport-native-epoll:${nettyVersion}"
|
||||||
compile "io.netty:netty-transport-native-epoll:${nettyVersion}:linux-x86_64"
|
implementation "io.netty:netty-transport-native-epoll:${nettyVersion}:linux-x86_64"
|
||||||
compile "io.netty:netty-transport-native-epoll:${nettyVersion}:linux-aarch64"
|
implementation "io.netty:netty-transport-native-epoll:${nettyVersion}:linux-aarch64"
|
||||||
compile "io.netty:netty-resolver-dns:${nettyVersion}"
|
implementation "io.netty:netty-resolver-dns:${nettyVersion}"
|
||||||
|
|
||||||
compile "org.apache.logging.log4j:log4j-api:${log4jVersion}"
|
implementation "org.apache.logging.log4j:log4j-api:${log4jVersion}"
|
||||||
compile "org.apache.logging.log4j:log4j-core:${log4jVersion}"
|
implementation "org.apache.logging.log4j:log4j-core:${log4jVersion}"
|
||||||
compile "org.apache.logging.log4j:log4j-slf4j-impl:${log4jVersion}"
|
implementation "org.apache.logging.log4j:log4j-slf4j-impl:${log4jVersion}"
|
||||||
compile "org.apache.logging.log4j:log4j-iostreams:${log4jVersion}"
|
implementation "org.apache.logging.log4j:log4j-iostreams:${log4jVersion}"
|
||||||
|
|
||||||
compile 'net.sf.jopt-simple:jopt-simple:5.0.4' // command-line options
|
implementation 'net.sf.jopt-simple:jopt-simple:5.0.4' // command-line options
|
||||||
compile 'net.minecrell:terminalconsoleappender:1.2.0'
|
implementation 'net.minecrell:terminalconsoleappender:1.2.0'
|
||||||
runtime 'org.jline:jline-terminal-jansi:3.12.1' // Needed for JLine
|
runtimeOnly 'org.jline:jline-terminal-jansi:3.12.1' // Needed for JLine
|
||||||
runtime 'com.lmax:disruptor:3.4.2' // Async loggers
|
runtimeOnly 'com.lmax:disruptor:3.4.2' // Async loggers
|
||||||
|
|
||||||
compile 'it.unimi.dsi:fastutil:8.2.3'
|
implementation 'it.unimi.dsi:fastutil:8.2.3'
|
||||||
compile 'net.kyori:event-method-asm:4.0.0-SNAPSHOT'
|
implementation 'net.kyori:event-method-asm:4.0.0-SNAPSHOT'
|
||||||
compile 'net.kyori:adventure-nbt:4.0.0-SNAPSHOT'
|
implementation 'net.kyori:adventure-nbt:4.0.0-SNAPSHOT'
|
||||||
|
|
||||||
compile 'com.mojang:brigadier:1.0.17'
|
implementation 'org.asynchttpclient:async-http-client:2.10.4'
|
||||||
|
|
||||||
compile 'org.asynchttpclient:async-http-client:2.10.4'
|
implementation 'com.spotify:completable-futures:0.3.2'
|
||||||
|
|
||||||
compile 'com.spotify:completable-futures:0.3.2'
|
implementation 'com.electronwill.night-config:toml:3.6.3'
|
||||||
|
|
||||||
compile 'com.electronwill.night-config:toml:3.6.3'
|
compileOnly 'com.github.spotbugs:spotbugs-annotations:4.1.2'
|
||||||
|
|
||||||
testCompile "org.junit.jupiter:junit-jupiter-api:${junitVersion}"
|
testImplementation "org.junit.jupiter:junit-jupiter-api:${junitVersion}"
|
||||||
testCompile "org.junit.jupiter:junit-jupiter-engine:${junitVersion}"
|
testImplementation "org.junit.jupiter:junit-jupiter-engine:${junitVersion}"
|
||||||
}
|
}
|
||||||
|
|
||||||
shadowJar {
|
shadowJar {
|
||||||
|
@ -39,12 +39,12 @@ public class Metrics {
|
|||||||
// The url to which the data is sent
|
// The url to which the data is sent
|
||||||
private static final String URL = "https://bstats.org/submitData/server-implementation";
|
private static final String URL = "https://bstats.org/submitData/server-implementation";
|
||||||
|
|
||||||
// Should failed requests be logged?
|
|
||||||
private static boolean logFailedRequests = false;
|
|
||||||
|
|
||||||
// The logger for the failed requests
|
// The logger for the failed requests
|
||||||
private static final Logger logger = LogManager.getLogger(Metrics.class);
|
private static final Logger logger = LogManager.getLogger(Metrics.class);
|
||||||
|
|
||||||
|
// Should failed requests be logged?
|
||||||
|
private boolean logFailedRequests = false;
|
||||||
|
|
||||||
// The name of the server software
|
// The name of the server software
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ public class Metrics {
|
|||||||
this.name = name;
|
this.name = name;
|
||||||
this.pluginId = pluginId;
|
this.pluginId = pluginId;
|
||||||
this.serverUuid = serverUuid;
|
this.serverUuid = serverUuid;
|
||||||
Metrics.logFailedRequests = logFailedRequests;
|
this.logFailedRequests = logFailedRequests;
|
||||||
this.server = server;
|
this.server = server;
|
||||||
|
|
||||||
// Start submitting the data
|
// Start submitting the data
|
||||||
@ -262,9 +262,6 @@ public class Metrics {
|
|||||||
}
|
}
|
||||||
chart.add("data", data);
|
chart.add("data", data);
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
if (logFailedRequests) {
|
|
||||||
logger.warn("Failed to get data for custom chart with id {}", chartId, t);
|
|
||||||
}
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return chart;
|
return chart;
|
||||||
|
@ -45,6 +45,7 @@ import com.velocitypowered.proxy.util.bossbar.AdventureBossBarManager;
|
|||||||
import com.velocitypowered.proxy.util.bossbar.VelocityBossBar;
|
import com.velocitypowered.proxy.util.bossbar.VelocityBossBar;
|
||||||
import com.velocitypowered.proxy.util.ratelimit.Ratelimiter;
|
import com.velocitypowered.proxy.util.ratelimit.Ratelimiter;
|
||||||
import com.velocitypowered.proxy.util.ratelimit.Ratelimiters;
|
import com.velocitypowered.proxy.util.ratelimit.Ratelimiters;
|
||||||
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
import io.netty.bootstrap.Bootstrap;
|
import io.netty.bootstrap.Bootstrap;
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
import io.netty.channel.ChannelInitializer;
|
import io.netty.channel.ChannelInitializer;
|
||||||
@ -54,7 +55,9 @@ import java.net.InetSocketAddress;
|
|||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.security.AccessController;
|
||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
|
import java.security.PrivilegedAction;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
@ -75,7 +78,6 @@ import net.kyori.adventure.audience.Audience;
|
|||||||
import net.kyori.adventure.audience.ForwardingAudience;
|
import net.kyori.adventure.audience.ForwardingAudience;
|
||||||
import net.kyori.adventure.text.TextComponent;
|
import net.kyori.adventure.text.TextComponent;
|
||||||
import net.kyori.adventure.text.TranslatableComponent;
|
import net.kyori.adventure.text.TranslatableComponent;
|
||||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
|
||||||
import net.kyori.text.Component;
|
import net.kyori.text.Component;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
@ -198,21 +200,7 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
|
|||||||
commandManager.register("shutdown", new ShutdownCommand(this),"end");
|
commandManager.register("shutdown", new ShutdownCommand(this),"end");
|
||||||
new GlistCommand(this).register();
|
new GlistCommand(this).register();
|
||||||
|
|
||||||
try {
|
this.doStartupConfigLoad();
|
||||||
Path configPath = Paths.get("velocity.toml");
|
|
||||||
configuration = VelocityConfiguration.read(configPath);
|
|
||||||
|
|
||||||
if (!configuration.validate()) {
|
|
||||||
logger.error("Your configuration is invalid. Velocity will not start up until the errors "
|
|
||||||
+ "are resolved.");
|
|
||||||
LogManager.shutdown();
|
|
||||||
System.exit(1);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error("Unable to read/load/save your velocity.toml. The server will shut down.", e);
|
|
||||||
LogManager.shutdown();
|
|
||||||
System.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Map.Entry<String, String> entry : configuration.getServers().entrySet()) {
|
for (Map.Entry<String, String> entry : configuration.getServers().entrySet()) {
|
||||||
servers.register(new ServerInfo(entry.getKey(), AddressUtil.parseAddress(entry.getValue())));
|
servers.register(new ServerInfo(entry.getKey(), AddressUtil.parseAddress(entry.getValue())));
|
||||||
@ -243,6 +231,25 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
|
|||||||
Metrics.VelocityMetrics.startMetrics(this, configuration.getMetrics());
|
Metrics.VelocityMetrics.startMetrics(this, configuration.getMetrics());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressFBWarnings("DM_EXIT")
|
||||||
|
private void doStartupConfigLoad() {
|
||||||
|
try {
|
||||||
|
Path configPath = Paths.get("velocity.toml");
|
||||||
|
configuration = VelocityConfiguration.read(configPath);
|
||||||
|
|
||||||
|
if (!configuration.validate()) {
|
||||||
|
logger.error("Your configuration is invalid. Velocity will not start up until the errors "
|
||||||
|
+ "are resolved.");
|
||||||
|
LogManager.shutdown();
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Unable to read/load/save your velocity.toml. The server will shut down.", e);
|
||||||
|
LogManager.shutdown();
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void loadPlugins() {
|
private void loadPlugins() {
|
||||||
logger.info("Loading plugins...");
|
logger.info("Loading plugins...");
|
||||||
|
|
||||||
@ -438,7 +445,14 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
|
|||||||
shutdown = true;
|
shutdown = true;
|
||||||
|
|
||||||
if (explicitExit) {
|
if (explicitExit) {
|
||||||
System.exit(0);
|
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
||||||
|
@Override
|
||||||
|
@SuppressFBWarnings("DM_EXIT")
|
||||||
|
public Void run() {
|
||||||
|
System.exit(0);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -276,7 +276,7 @@ public class VelocityConfiguration implements ProxyConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getForwardingSecret() {
|
public byte[] getForwardingSecret() {
|
||||||
return forwardingSecret;
|
return forwardingSecret.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -13,6 +13,7 @@ import com.velocitypowered.proxy.protocol.packet.PluginMessage;
|
|||||||
import com.velocitypowered.proxy.protocol.util.ByteBufDataInput;
|
import com.velocitypowered.proxy.protocol.util.ByteBufDataInput;
|
||||||
import com.velocitypowered.proxy.protocol.util.ByteBufDataOutput;
|
import com.velocitypowered.proxy.protocol.util.ByteBufDataOutput;
|
||||||
import com.velocitypowered.proxy.server.VelocityRegisteredServer;
|
import com.velocitypowered.proxy.server.VelocityRegisteredServer;
|
||||||
|
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@ -23,6 +24,9 @@ import net.kyori.adventure.text.serializer.ComponentSerializer;
|
|||||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||||
|
|
||||||
|
@SuppressFBWarnings(value = "OS_OPEN_STREAM", justification = "Most methods in this class open "
|
||||||
|
+ "instances of ByteBufDataOutput backed by heap-allocated ByteBufs. Closing them does "
|
||||||
|
+ "nothing.")
|
||||||
class BungeeCordMessageResponder {
|
class BungeeCordMessageResponder {
|
||||||
|
|
||||||
private static final MinecraftChannelIdentifier MODERN_CHANNEL = MinecraftChannelIdentifier
|
private static final MinecraftChannelIdentifier MODERN_CHANNEL = MinecraftChannelIdentifier
|
||||||
|
@ -305,7 +305,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
|||||||
TitlePacket subtitlePkt = new TitlePacket();
|
TitlePacket subtitlePkt = new TitlePacket();
|
||||||
subtitlePkt.setAction(TitlePacket.SET_SUBTITLE);
|
subtitlePkt.setAction(TitlePacket.SET_SUBTITLE);
|
||||||
subtitlePkt.setComponent(serializer.serialize(title.subtitle()));
|
subtitlePkt.setComponent(serializer.serialize(title.subtitle()));
|
||||||
connection.delayedWrite(titlePkt);
|
connection.delayedWrite(subtitlePkt);
|
||||||
|
|
||||||
TitlePacket timesPkt = TitlePacket.timesForProtocolVersion(this.getProtocolVersion());
|
TitlePacket timesPkt = TitlePacket.timesForProtocolVersion(this.getProtocolVersion());
|
||||||
net.kyori.adventure.title.Title.Times times = title.times();
|
net.kyori.adventure.title.Title.Times times = title.times();
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.velocitypowered.proxy.connection.forge.legacy;
|
package com.velocitypowered.proxy.connection.forge.legacy;
|
||||||
|
|
||||||
import com.velocitypowered.proxy.connection.ConnectionTypes;
|
import com.velocitypowered.proxy.connection.ConnectionTypes;
|
||||||
|
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
||||||
import com.velocitypowered.proxy.connection.backend.BackendConnectionPhase;
|
import com.velocitypowered.proxy.connection.backend.BackendConnectionPhase;
|
||||||
import com.velocitypowered.proxy.connection.backend.BackendConnectionPhases;
|
import com.velocitypowered.proxy.connection.backend.BackendConnectionPhases;
|
||||||
import com.velocitypowered.proxy.connection.backend.VelocityServerConnection;
|
import com.velocitypowered.proxy.connection.backend.VelocityServerConnection;
|
||||||
@ -38,8 +39,9 @@ public enum LegacyForgeHandshakeBackendPhase implements BackendConnectionPhase {
|
|||||||
void onTransitionToNewPhase(VelocityServerConnection connection) {
|
void onTransitionToNewPhase(VelocityServerConnection connection) {
|
||||||
// We must always reset the handshake before a modded connection is established if
|
// We must always reset the handshake before a modded connection is established if
|
||||||
// we haven't done so already.
|
// we haven't done so already.
|
||||||
if (connection.getConnection() != null) {
|
MinecraftConnection mc = connection.getConnection();
|
||||||
connection.getConnection().setType(ConnectionTypes.LEGACY_FORGE);
|
if (mc != null) {
|
||||||
|
mc.setType(ConnectionTypes.LEGACY_FORGE);
|
||||||
}
|
}
|
||||||
connection.getPlayer().sendLegacyForgeHandshakeResetPacket();
|
connection.getPlayer().sendLegacyForgeHandshakeResetPacket();
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package com.velocitypowered.proxy.connection.forge.legacy;
|
|||||||
|
|
||||||
import com.velocitypowered.api.util.ModInfo;
|
import com.velocitypowered.api.util.ModInfo;
|
||||||
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
||||||
|
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
||||||
import com.velocitypowered.proxy.connection.backend.VelocityServerConnection;
|
import com.velocitypowered.proxy.connection.backend.VelocityServerConnection;
|
||||||
import com.velocitypowered.proxy.connection.client.ClientConnectionPhase;
|
import com.velocitypowered.proxy.connection.client.ClientConnectionPhase;
|
||||||
import com.velocitypowered.proxy.connection.client.ClientPlaySessionHandler;
|
import com.velocitypowered.proxy.connection.client.ClientPlaySessionHandler;
|
||||||
@ -153,8 +154,9 @@ public enum LegacyForgeHandshakeClientPhase implements ClientConnectionPhase {
|
|||||||
// just in case the timing is awful
|
// just in case the timing is awful
|
||||||
player.sendKeepAlive();
|
player.sendKeepAlive();
|
||||||
|
|
||||||
if (backendConn.getSessionHandler() instanceof ClientPlaySessionHandler) {
|
MinecraftSessionHandler handler = backendConn.getSessionHandler();
|
||||||
((ClientPlaySessionHandler) backendConn.getSessionHandler()).flushQueuedMessages();
|
if (handler instanceof ClientPlaySessionHandler) {
|
||||||
|
((ClientPlaySessionHandler) handler).flushQueuedMessages();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -12,6 +12,8 @@ import com.velocitypowered.api.event.proxy.ProxyShutdownEvent;
|
|||||||
import com.velocitypowered.api.plugin.PluginManager;
|
import com.velocitypowered.api.plugin.PluginManager;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.security.AccessController;
|
||||||
|
import java.security.PrivilegedAction;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.IdentityHashMap;
|
import java.util.IdentityHashMap;
|
||||||
@ -51,7 +53,8 @@ public class VelocityEventManager implements EventManager {
|
|||||||
public VelocityEventManager(PluginManager pluginManager) {
|
public VelocityEventManager(PluginManager pluginManager) {
|
||||||
// Expose the event executors to the plugins - required in order for the generated ASM classes
|
// Expose the event executors to the plugins - required in order for the generated ASM classes
|
||||||
// to work.
|
// to work.
|
||||||
PluginClassLoader cl = new PluginClassLoader(new URL[0]);
|
PluginClassLoader cl = AccessController.doPrivileged(
|
||||||
|
(PrivilegedAction<PluginClassLoader>) () -> new PluginClassLoader(new URL[0]));
|
||||||
cl.addToClassloaders();
|
cl.addToClassloaders();
|
||||||
|
|
||||||
// Initialize the event bus.
|
// Initialize the event bus.
|
||||||
|
@ -17,10 +17,13 @@ import com.velocitypowered.proxy.plugin.loader.VelocityPluginDescription;
|
|||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
import java.security.AccessController;
|
||||||
|
import java.security.PrivilegedAction;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -58,9 +61,10 @@ public class JavaPluginLoader implements PluginLoader {
|
|||||||
if (!(source instanceof JavaVelocityPluginDescriptionCandidate)) {
|
if (!(source instanceof JavaVelocityPluginDescriptionCandidate)) {
|
||||||
throw new IllegalArgumentException("Description provided isn't of the Java plugin loader");
|
throw new IllegalArgumentException("Description provided isn't of the Java plugin loader");
|
||||||
}
|
}
|
||||||
PluginClassLoader loader = new PluginClassLoader(
|
|
||||||
new URL[]{source.getSource().get().toUri().toURL()}
|
URL pluginJarUrl = source.getSource().get().toUri().toURL();
|
||||||
);
|
PluginClassLoader loader = AccessController.doPrivileged(
|
||||||
|
(PrivilegedAction<PluginClassLoader>) () -> new PluginClassLoader(new URL[]{pluginJarUrl}));
|
||||||
loader.addToClassloaders();
|
loader.addToClassloaders();
|
||||||
|
|
||||||
JavaVelocityPluginDescriptionCandidate candidate =
|
JavaVelocityPluginDescriptionCandidate candidate =
|
||||||
|
@ -135,7 +135,7 @@ public enum ProtocolUtils {
|
|||||||
public static void writeString(ByteBuf buf, CharSequence str) {
|
public static void writeString(ByteBuf buf, CharSequence str) {
|
||||||
int size = ByteBufUtil.utf8Bytes(str);
|
int size = ByteBufUtil.utf8Bytes(str);
|
||||||
writeVarInt(buf, size);
|
writeVarInt(buf, size);
|
||||||
ByteBufUtil.writeUtf8(buf, str);
|
buf.writeCharSequence(str, StandardCharsets.UTF_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] readByteArray(ByteBuf buf) {
|
public static byte[] readByteArray(ByteBuf buf) {
|
||||||
@ -230,12 +230,6 @@ public enum ProtocolUtils {
|
|||||||
* @return {@link net.kyori.adventure.nbt.CompoundBinaryTag} the CompoundTag from the buffer
|
* @return {@link net.kyori.adventure.nbt.CompoundBinaryTag} the CompoundTag from the buffer
|
||||||
*/
|
*/
|
||||||
public static CompoundBinaryTag readCompoundTag(ByteBuf buf) {
|
public static CompoundBinaryTag readCompoundTag(ByteBuf buf) {
|
||||||
int indexBefore = buf.readerIndex();
|
|
||||||
byte startType = buf.readByte();
|
|
||||||
if (startType == 0) {
|
|
||||||
throw new DecoderException("Invalid NBT start-type (end/empty)");
|
|
||||||
}
|
|
||||||
buf.readerIndex(indexBefore);
|
|
||||||
try {
|
try {
|
||||||
return BinaryTagIO.readDataInput(new ByteBufInputStream(buf));
|
return BinaryTagIO.readDataInput(new ByteBufInputStream(buf));
|
||||||
} catch (IOException thrown) {
|
} catch (IOException thrown) {
|
||||||
@ -250,10 +244,6 @@ public enum ProtocolUtils {
|
|||||||
* @param compoundTag the CompoundTag to write
|
* @param compoundTag the CompoundTag to write
|
||||||
*/
|
*/
|
||||||
public static void writeCompoundTag(ByteBuf buf, CompoundBinaryTag compoundTag) {
|
public static void writeCompoundTag(ByteBuf buf, CompoundBinaryTag compoundTag) {
|
||||||
if (compoundTag == null) {
|
|
||||||
buf.writeByte(0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
BinaryTagIO.writeDataOutput(compoundTag, new ByteBufOutputStream(buf));
|
BinaryTagIO.writeDataOutput(compoundTag, new ByteBufOutputStream(buf));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -36,6 +36,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
|||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
public class AvailableCommands implements MinecraftPacket {
|
public class AvailableCommands implements MinecraftPacket {
|
||||||
|
private static final Command<CommandSource> PLACEHOLDER_COMMAND = source -> 0;
|
||||||
|
|
||||||
private static final byte NODE_TYPE_ROOT = 0x00;
|
private static final byte NODE_TYPE_ROOT = 0x00;
|
||||||
private static final byte NODE_TYPE_LITERAL = 0x01;
|
private static final byte NODE_TYPE_LITERAL = 0x01;
|
||||||
private static final byte NODE_TYPE_ARGUMENT = 0x02;
|
private static final byte NODE_TYPE_ARGUMENT = 0x02;
|
||||||
@ -121,16 +123,14 @@ public class AvailableCommands implements MinecraftPacket {
|
|||||||
flags |= FLAG_EXECUTABLE;
|
flags |= FLAG_EXECUTABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node instanceof RootCommandNode<?>) {
|
if (node instanceof LiteralCommandNode<?>) {
|
||||||
flags |= NODE_TYPE_ROOT;
|
|
||||||
} else if (node instanceof LiteralCommandNode<?>) {
|
|
||||||
flags |= NODE_TYPE_LITERAL;
|
flags |= NODE_TYPE_LITERAL;
|
||||||
} else if (node instanceof ArgumentCommandNode<?, ?>) {
|
} else if (node instanceof ArgumentCommandNode<?, ?>) {
|
||||||
flags |= NODE_TYPE_ARGUMENT;
|
flags |= NODE_TYPE_ARGUMENT;
|
||||||
if (((ArgumentCommandNode<CommandSource, ?>) node).getCustomSuggestions() != null) {
|
if (((ArgumentCommandNode<CommandSource, ?>) node).getCustomSuggestions() != null) {
|
||||||
flags |= FLAG_HAS_SUGGESTIONS;
|
flags |= FLAG_HAS_SUGGESTIONS;
|
||||||
}
|
}
|
||||||
} else {
|
} else if (!(node instanceof RootCommandNode<?>)) {
|
||||||
throw new IllegalArgumentException("Unknown node type " + node.getClass().getName());
|
throw new IllegalArgumentException("Unknown node type " + node.getClass().getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,8 +238,9 @@ public class AvailableCommands implements MinecraftPacket {
|
|||||||
throw new IllegalStateException("Node points to non-existent index " + redirectTo);
|
throw new IllegalStateException("Node points to non-existent index " + redirectTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wireNodes[redirectTo].built != null) {
|
WireNode redirect = wireNodes[redirectTo];
|
||||||
args.redirect(wireNodes[redirectTo].built);
|
if (redirect.built != null) {
|
||||||
|
args.redirect(redirect.built);
|
||||||
} else {
|
} else {
|
||||||
// Redirect node does not yet exist
|
// Redirect node does not yet exist
|
||||||
return false;
|
return false;
|
||||||
@ -248,7 +249,7 @@ public class AvailableCommands implements MinecraftPacket {
|
|||||||
|
|
||||||
// If executable, add an empty command
|
// If executable, add an empty command
|
||||||
if ((flags & FLAG_EXECUTABLE) != 0) {
|
if ((flags & FLAG_EXECUTABLE) != 0) {
|
||||||
args.executes((Command<CommandSource>) context -> 0);
|
args.executes(PLACEHOLDER_COMMAND);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.built = args.build();
|
this.built = args.build();
|
||||||
|
@ -16,19 +16,19 @@ public class EncryptionRequest implements MinecraftPacket {
|
|||||||
private byte[] verifyToken = EMPTY_BYTE_ARRAY;
|
private byte[] verifyToken = EMPTY_BYTE_ARRAY;
|
||||||
|
|
||||||
public byte[] getPublicKey() {
|
public byte[] getPublicKey() {
|
||||||
return publicKey;
|
return publicKey.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPublicKey(byte[] publicKey) {
|
public void setPublicKey(byte[] publicKey) {
|
||||||
this.publicKey = publicKey;
|
this.publicKey = publicKey.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getVerifyToken() {
|
public byte[] getVerifyToken() {
|
||||||
return verifyToken;
|
return verifyToken.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setVerifyToken(byte[] verifyToken) {
|
public void setVerifyToken(byte[] verifyToken) {
|
||||||
this.verifyToken = verifyToken;
|
this.verifyToken = verifyToken.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -15,19 +15,11 @@ public class EncryptionResponse implements MinecraftPacket {
|
|||||||
private byte[] verifyToken = EMPTY_BYTE_ARRAY;
|
private byte[] verifyToken = EMPTY_BYTE_ARRAY;
|
||||||
|
|
||||||
public byte[] getSharedSecret() {
|
public byte[] getSharedSecret() {
|
||||||
return sharedSecret;
|
return sharedSecret.clone();
|
||||||
}
|
|
||||||
|
|
||||||
public void setSharedSecret(byte[] sharedSecret) {
|
|
||||||
this.sharedSecret = sharedSecret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getVerifyToken() {
|
public byte[] getVerifyToken() {
|
||||||
return verifyToken;
|
return verifyToken.clone();
|
||||||
}
|
|
||||||
|
|
||||||
public void setVerifyToken(byte[] verifyToken) {
|
|
||||||
this.verifyToken = verifyToken;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -99,7 +99,10 @@ public class PlayerListItem implements MinecraftPacket {
|
|||||||
ProtocolUtils.writeVarInt(buf, action);
|
ProtocolUtils.writeVarInt(buf, action);
|
||||||
ProtocolUtils.writeVarInt(buf, items.size());
|
ProtocolUtils.writeVarInt(buf, items.size());
|
||||||
for (Item item : items) {
|
for (Item item : items) {
|
||||||
ProtocolUtils.writeUuid(buf, item.getUuid());
|
UUID uuid = item.getUuid();
|
||||||
|
assert uuid != null : "UUID-less entry serialization attempt - 1.7 component!";
|
||||||
|
|
||||||
|
ProtocolUtils.writeUuid(buf, uuid);
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case ADD_PLAYER:
|
case ADD_PLAYER:
|
||||||
ProtocolUtils.writeString(buf, item.getName());
|
ProtocolUtils.writeString(buf, item.getName());
|
||||||
@ -127,9 +130,10 @@ public class PlayerListItem implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Item item = items.get(0);
|
Item item = items.get(0);
|
||||||
if (item.getDisplayName() != null) {
|
Component displayNameComponent = item.getDisplayName();
|
||||||
|
if (displayNameComponent != null) {
|
||||||
String displayName = LegacyComponentSerializer.legacySection()
|
String displayName = LegacyComponentSerializer.legacySection()
|
||||||
.serialize(item.getDisplayName());
|
.serialize(displayNameComponent);
|
||||||
ProtocolUtils.writeString(buf,
|
ProtocolUtils.writeString(buf,
|
||||||
displayName.length() > 16 ? displayName.substring(0, 16) : displayName);
|
displayName.length() > 16 ? displayName.substring(0, 16) : displayName);
|
||||||
} else {
|
} else {
|
||||||
|
@ -121,6 +121,25 @@ public class TabCompleteResponse implements MinecraftPacket {
|
|||||||
this.tooltip = tooltip;
|
this.tooltip = tooltip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (o == null || getClass() != o.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Offer offer = (Offer) o;
|
||||||
|
|
||||||
|
return text.equals(offer.text);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return text.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return MoreObjects.toStringHelper(this)
|
return MoreObjects.toStringHelper(this)
|
||||||
|
@ -102,4 +102,8 @@ public class ByteBufDataOutput extends OutputStream implements ByteArrayDataOutp
|
|||||||
throw new IllegalStateException(e);
|
throw new IllegalStateException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,8 +83,10 @@ public class VelocityLegacyHoverEventSerializer implements LegacyHoverEventSeria
|
|||||||
} else {
|
} else {
|
||||||
builder.putString("id", keyAsString);
|
builder.putString("id", keyAsString);
|
||||||
}
|
}
|
||||||
if (input.nbt() != null) {
|
|
||||||
builder.put("tag", TagStringIO.get().asCompound(input.nbt().string()));
|
BinaryTagHolder nbt = input.nbt();
|
||||||
|
if (nbt != null) {
|
||||||
|
builder.put("tag", TagStringIO.get().asCompound(nbt.string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return TextComponent.of(TagStringIO.get().asString(builder.build()));
|
return TextComponent.of(TagStringIO.get().asString(builder.build()));
|
||||||
@ -96,8 +98,9 @@ public class VelocityLegacyHoverEventSerializer implements LegacyHoverEventSeria
|
|||||||
CompoundBinaryTag.Builder tag = CompoundBinaryTag.builder()
|
CompoundBinaryTag.Builder tag = CompoundBinaryTag.builder()
|
||||||
.putString("id", input.id().toString())
|
.putString("id", input.id().toString())
|
||||||
.putString("type", input.type().asString());
|
.putString("type", input.type().asString());
|
||||||
if (input.name() != null) {
|
Component name = input.name();
|
||||||
tag.putString("name", componentEncoder.encode(input.name()));
|
if (name != null) {
|
||||||
|
tag.putString("name", componentEncoder.encode(name));
|
||||||
}
|
}
|
||||||
return TextComponent.of(TagStringIO.get().asString(tag.build()));
|
return TextComponent.of(TagStringIO.get().asString(tag.build()));
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
package com.velocitypowered.proxy.tablist;
|
package com.velocitypowered.proxy.tablist;
|
||||||
|
|
||||||
|
import static com.google.common.base.Verify.verify;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
|
import com.google.common.base.Verify;
|
||||||
import com.velocitypowered.api.proxy.player.TabList;
|
import com.velocitypowered.api.proxy.player.TabList;
|
||||||
import com.velocitypowered.api.proxy.player.TabListEntry;
|
import com.velocitypowered.api.proxy.player.TabListEntry;
|
||||||
import com.velocitypowered.api.util.GameProfile;
|
import com.velocitypowered.api.util.GameProfile;
|
||||||
@ -121,6 +124,7 @@ public class VelocityTabList implements TabList {
|
|||||||
// Packets are already forwarded on, so no need to do that here
|
// Packets are already forwarded on, so no need to do that here
|
||||||
for (PlayerListItem.Item item : packet.getItems()) {
|
for (PlayerListItem.Item item : packet.getItems()) {
|
||||||
UUID uuid = item.getUuid();
|
UUID uuid = item.getUuid();
|
||||||
|
assert uuid != null : "1.7 tab list entry given to modern tab list handler!";
|
||||||
|
|
||||||
if (packet.getAction() != PlayerListItem.ADD_PLAYER && !entries.containsKey(uuid)) {
|
if (packet.getAction() != PlayerListItem.ADD_PLAYER && !entries.containsKey(uuid)) {
|
||||||
// Sometimes UPDATE_GAMEMODE is sent before ADD_PLAYER so don't want to warn here
|
// Sometimes UPDATE_GAMEMODE is sent before ADD_PLAYER so don't want to warn here
|
||||||
|
@ -12,6 +12,12 @@ public class VelocityTabListEntryLegacy extends VelocityTabListEntry {
|
|||||||
super(tabList, profile, displayName, latency, gameMode);
|
super(tabList, profile, displayName, latency, gameMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TabListEntry setDisplayName(net.kyori.text.@Nullable Component displayName) {
|
||||||
|
getTabList().removeEntry(getProfile().getId()); // We have to remove first if updating
|
||||||
|
return super.setDisplayName(displayName);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TabListEntry setDisplayName(@Nullable Component displayName) {
|
public TabListEntry setDisplayName(@Nullable Component displayName) {
|
||||||
getTabList().removeEntry(getProfile().getId()); // We have to remove first if updating
|
getTabList().removeEntry(getProfile().getId()); // We have to remove first if updating
|
||||||
|
@ -6,7 +6,7 @@ import net.kyori.text.Component;
|
|||||||
|
|
||||||
public class MockCommandSource implements CommandSource {
|
public class MockCommandSource implements CommandSource {
|
||||||
|
|
||||||
public static CommandSource INSTANCE = new MockCommandSource();
|
public static final CommandSource INSTANCE = new MockCommandSource();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendMessage(final Component component) {
|
public void sendMessage(final Component component) {
|
||||||
|
@ -9,7 +9,7 @@ import java.util.Optional;
|
|||||||
|
|
||||||
public class MockPluginManager implements PluginManager {
|
public class MockPluginManager implements PluginManager {
|
||||||
|
|
||||||
public static PluginManager INSTANCE = new MockPluginManager();
|
public static final PluginManager INSTANCE = new MockPluginManager();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<PluginContainer> fromInstance(final Object instance) {
|
public Optional<PluginContainer> fromInstance(final Object instance) {
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren