3
0
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:
Andrew Steinborn 2020-08-21 19:09:04 -04:00
Ursprung d8dba436d6
Commit c47d25c88a
27 geänderte Dateien mit 194 neuen und 142 gelöschten Zeilen

Datei anzeigen

@ -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) {

Datei anzeigen

@ -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'
}
}
}
} }

Datei anzeigen

@ -1,4 +0,0 @@
dependencies {
errorprone("com.google.errorprone:error_prone_core:2.3.3")
errorproneJavac("com.google.errorprone:javac:9+181-r4173-1")
}

Datei anzeigen

@ -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

Datei anzeigen

@ -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}"
} }

Datei anzeigen

@ -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 {

Datei anzeigen

@ -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;

Datei anzeigen

@ -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) {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
@Override
@SuppressFBWarnings("DM_EXIT")
public Void run() {
System.exit(0); System.exit(0);
return null;
}
});
} }
}; };

Datei anzeigen

@ -276,7 +276,7 @@ public class VelocityConfiguration implements ProxyConfig {
} }
public byte[] getForwardingSecret() { public byte[] getForwardingSecret() {
return forwardingSecret; return forwardingSecret.clone();
} }
@Override @Override

Datei anzeigen

@ -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

Datei anzeigen

@ -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();

Datei anzeigen

@ -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();
} }

Datei anzeigen

@ -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;

Datei anzeigen

@ -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.

Datei anzeigen

@ -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 =

Datei anzeigen

@ -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) {

Datei anzeigen

@ -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();

Datei anzeigen

@ -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

Datei anzeigen

@ -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

Datei anzeigen

@ -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 {

Datei anzeigen

@ -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)

Datei anzeigen

@ -102,4 +102,8 @@ public class ByteBufDataOutput extends OutputStream implements ByteArrayDataOutp
throw new IllegalStateException(e); throw new IllegalStateException(e);
} }
} }
@Override
public void close() {
}
} }

Datei anzeigen

@ -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()));
} }

Datei anzeigen

@ -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

Datei anzeigen

@ -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

Datei anzeigen

@ -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) {

Datei anzeigen

@ -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) {