diff --git a/api/src/main/java/com/velocitypowered/api/command/Command.java b/api/src/main/java/com/velocitypowered/api/command/Command.java index e2b7f9256..1e44d0d84 100644 --- a/api/src/main/java/com/velocitypowered/api/command/Command.java +++ b/api/src/main/java/com/velocitypowered/api/command/Command.java @@ -29,5 +29,5 @@ import com.velocitypowered.api.proxy.Player; * * */ -public interface Command { +public sealed interface Command permits BrigadierCommand, InvocableCommand { } diff --git a/api/src/main/java/com/velocitypowered/api/command/InvocableCommand.java b/api/src/main/java/com/velocitypowered/api/command/InvocableCommand.java index 37afa0710..68577a75a 100644 --- a/api/src/main/java/com/velocitypowered/api/command/InvocableCommand.java +++ b/api/src/main/java/com/velocitypowered/api/command/InvocableCommand.java @@ -21,7 +21,8 @@ import java.util.concurrent.CompletableFuture; * * @param the type of the command invocation object */ -public interface InvocableCommand> extends Command { +public sealed interface InvocableCommand> extends Command + permits RawCommand, SimpleCommand { /** * Executes the command for the specified invocation. diff --git a/api/src/main/java/com/velocitypowered/api/command/RawCommand.java b/api/src/main/java/com/velocitypowered/api/command/RawCommand.java index 05da7c6e4..cc626487f 100644 --- a/api/src/main/java/com/velocitypowered/api/command/RawCommand.java +++ b/api/src/main/java/com/velocitypowered/api/command/RawCommand.java @@ -12,7 +12,7 @@ package com.velocitypowered.api.command; * the command and its arguments directly without further processing. * This is useful for bolting on external command frameworks to Velocity. */ -public interface RawCommand extends InvocableCommand { +public non-sealed interface RawCommand extends InvocableCommand { /** * Contains the invocation data for a raw command. diff --git a/api/src/main/java/com/velocitypowered/api/command/SimpleCommand.java b/api/src/main/java/com/velocitypowered/api/command/SimpleCommand.java index 0fb3a7ff8..3b8282e37 100644 --- a/api/src/main/java/com/velocitypowered/api/command/SimpleCommand.java +++ b/api/src/main/java/com/velocitypowered/api/command/SimpleCommand.java @@ -16,7 +16,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; *

Prefer using {@link BrigadierCommand}, which is also * backwards-compatible with older clients. */ -public interface SimpleCommand extends InvocableCommand { +public non-sealed interface SimpleCommand extends InvocableCommand { /** * Contains the invocation data for a simple command. diff --git a/proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java b/proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java index 5db97cbaa..7048288d6 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java @@ -93,6 +93,7 @@ import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.IntFunction; import java.util.stream.Collectors; +import java.util.stream.Stream; import net.kyori.adventure.audience.Audience; import net.kyori.adventure.audience.ForwardingAudience; import net.kyori.adventure.key.Key; @@ -143,7 +144,6 @@ public class VelocityServer implements ProxyServer, ForwardingAudience { private final ConnectionManager cm; private final ProxyOptions options; - private final HttpClient httpClient; private @MonotonicNonNull VelocityConfiguration configuration; private @MonotonicNonNull KeyPair serverKeyPair; private final ServerMap servers; @@ -159,7 +159,7 @@ public class VelocityServer implements ProxyServer, ForwardingAudience { private final VelocityEventManager eventManager; private final VelocityScheduler scheduler; private final VelocityChannelRegistrar channelRegistrar = new VelocityChannelRegistrar(); - private ServerListPingHandler serverListPingHandler; + private final ServerListPingHandler serverListPingHandler; VelocityServer(final ProxyOptions options) { pluginManager = new VelocityPluginManager(this); @@ -168,7 +168,6 @@ public class VelocityServer implements ProxyServer, ForwardingAudience { scheduler = new VelocityScheduler(pluginManager); console = new VelocityConsole(this); cm = new ConnectionManager(this); - httpClient = HttpClient.newHttpClient(); servers = new ServerMap(this); serverListPingHandler = new ServerListPingHandler(this); this.options = options; @@ -282,40 +281,39 @@ public class VelocityServer implements ProxyServer, ForwardingAudience { try { if (!Files.exists(langPath)) { Files.createDirectory(langPath); - Files.walk(path).forEach(file -> { - if (!Files.isRegularFile(file)) { - return; - } - try { - Path langFile = langPath.resolve(file.getFileName().toString()); - if (!Files.exists(langFile)) { - try (InputStream is = Files.newInputStream(file)) { - Files.copy(is, langFile); + try (final Stream files = Files.walk(path)) { + files.filter(Files::isRegularFile).forEach(file -> { + try { + final Path langFile = langPath.resolve(file.getFileName().toString()); + if (!Files.exists(langFile)) { + try (final InputStream is = Files.newInputStream(file)) { + Files.copy(is, langFile); + } } + } catch (IOException e) { + logger.error("Encountered an I/O error whilst loading translations", e); } - } catch (IOException e) { - logger.error("Encountered an I/O error whilst loading translations", e); - } + }); + } + + } + + try (final Stream files = Files.walk(langPath)) { + files.filter(Files::isRegularFile).forEach(file -> { + final String filename = com.google.common.io.Files + .getNameWithoutExtension(file.getFileName().toString()); + final String localeName = filename.replace("messages_", "") + .replace("messages", "") + .replace('_', '-'); + final Locale locale = localeName.isBlank() + ? Locale.US + : Locale.forLanguageTag(localeName); + + translationRegistry.registerAll(locale, file, false); + ClosestLocaleMatcher.INSTANCE.registerKnown(locale); }); } - Files.walk(langPath).forEach(file -> { - if (!Files.isRegularFile(file)) { - return; - } - - String filename = com.google.common.io.Files - .getNameWithoutExtension(file.getFileName().toString()); - String localeName = filename.replace("messages_", "") - .replace("messages", "") - .replace('_', '-'); - Locale locale = localeName.isBlank() - ? Locale.US - : Locale.forLanguageTag(localeName); - - translationRegistry.registerAll(locale, file, false); - ClosestLocaleMatcher.INSTANCE.registerKnown(locale); - }); } catch (IOException e) { logger.error("Encountered an I/O error whilst loading translations", e); } @@ -419,10 +417,9 @@ public class VelocityServer implements ProxyServer, ForwardingAudience { // move back to a fallback server. Collection evacuate = new ArrayList<>(); for (Map.Entry entry : newConfiguration.getServers().entrySet()) { - ServerInfo newInfo = - new ServerInfo(entry.getKey(), AddressUtil.parseAddress(entry.getValue())); + ServerInfo newInfo = new ServerInfo(entry.getKey(), AddressUtil.parseAddress(entry.getValue())); Optional rs = servers.getServer(entry.getKey()); - if (!rs.isPresent()) { + if (rs.isEmpty()) { servers.register(newInfo); } else if (!rs.get().getServerInfo().equals(newInfo)) { for (Player player : rs.get().getPlayersConnected()) { diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/HandshakeSessionHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/HandshakeSessionHandler.java index 8d497d7e1..4ba17624b 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/HandshakeSessionHandler.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/HandshakeSessionHandler.java @@ -84,14 +84,14 @@ public class HandshakeSessionHandler implements MinecraftSessionHandler { } @Override - public boolean handle(HandshakePacket handshake) { - final InitialInboundConnection ic = new InitialInboundConnection(connection, - cleanVhost(handshake.getServerAddress()), handshake); + public boolean handle(final HandshakePacket handshake) { final StateRegistry nextState = getStateForProtocol(handshake.getNextStatus()); if (nextState == null) { - LOGGER.error("{} provided invalid protocol {}", ic, handshake.getNextStatus()); + LOGGER.error("{} provided invalid protocol {}", this, handshake.getNextStatus()); connection.close(true); } else { + final InitialInboundConnection ic = new InitialInboundConnection(connection, + cleanVhost(handshake.getServerAddress()), handshake); connection.setProtocolVersion(handshake.getProtocolVersion()); connection.setAssociation(ic); @@ -208,6 +208,16 @@ public class HandshakeSessionHandler implements MinecraftSessionHandler { connection.close(true); } + @Override + public String toString() { + final boolean isPlayerAddressLoggingEnabled = connection.server.getConfiguration() + .isPlayerAddressLoggingEnabled(); + final String playerIp = + isPlayerAddressLoggingEnabled + ? this.connection.getRemoteAddress().toString() : ""; + return "[initial connection] " + playerIp; + } + private record LegacyInboundConnection( MinecraftConnection connection, LegacyPingPacket ping