Mirror von
https://github.com/PaperMC/Velocity.git
synchronisiert 2024-11-17 05:20:14 +01:00
Fix some low-hanging code smells using SonarLint.
Dieser Commit ist enthalten in:
Ursprung
32829c5637
Commit
53aa92db92
@ -43,20 +43,20 @@ public interface ResultedEvent<R extends ResultedEvent.Result> {
|
|||||||
private static final GenericResult ALLOWED = new GenericResult(true);
|
private static final GenericResult ALLOWED = new GenericResult(true);
|
||||||
private static final GenericResult DENIED = new GenericResult(false);
|
private static final GenericResult DENIED = new GenericResult(false);
|
||||||
|
|
||||||
private final boolean allowed;
|
private final boolean status;
|
||||||
|
|
||||||
private GenericResult(boolean b) {
|
private GenericResult(boolean b) {
|
||||||
this.allowed = b;
|
this.status = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAllowed() {
|
public boolean isAllowed() {
|
||||||
return allowed;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return allowed ? "allowed" : "denied";
|
return status ? "allowed" : "denied";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GenericResult allowed() {
|
public static GenericResult allowed() {
|
||||||
@ -74,17 +74,17 @@ public interface ResultedEvent<R extends ResultedEvent.Result> {
|
|||||||
final class ComponentResult implements Result {
|
final class ComponentResult implements Result {
|
||||||
private static final ComponentResult ALLOWED = new ComponentResult(true, null);
|
private static final ComponentResult ALLOWED = new ComponentResult(true, null);
|
||||||
|
|
||||||
private final boolean allowed;
|
private final boolean status;
|
||||||
private final @Nullable Component reason;
|
private final @Nullable Component reason;
|
||||||
|
|
||||||
protected ComponentResult(boolean allowed, @Nullable Component reason) {
|
protected ComponentResult(boolean status, @Nullable Component reason) {
|
||||||
this.allowed = allowed;
|
this.status = status;
|
||||||
this.reason = reason;
|
this.reason = reason;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAllowed() {
|
public boolean isAllowed() {
|
||||||
return allowed;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<Component> getReason() {
|
public Optional<Component> getReason() {
|
||||||
@ -93,7 +93,7 @@ public interface ResultedEvent<R extends ResultedEvent.Result> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
if (allowed) {
|
if (status) {
|
||||||
return "allowed";
|
return "allowed";
|
||||||
}
|
}
|
||||||
if (reason != null) {
|
if (reason != null) {
|
||||||
|
@ -78,20 +78,20 @@ public final class PluginMessageEvent implements ResultedEvent<PluginMessageEven
|
|||||||
private static final ForwardResult ALLOWED = new ForwardResult(true);
|
private static final ForwardResult ALLOWED = new ForwardResult(true);
|
||||||
private static final ForwardResult DENIED = new ForwardResult(false);
|
private static final ForwardResult DENIED = new ForwardResult(false);
|
||||||
|
|
||||||
private final boolean allowed;
|
private final boolean status;
|
||||||
|
|
||||||
private ForwardResult(boolean b) {
|
private ForwardResult(boolean b) {
|
||||||
this.allowed = b;
|
this.status = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAllowed() {
|
public boolean isAllowed() {
|
||||||
return allowed;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return allowed ? "forward to sink" : "handled message at proxy";
|
return status ? "forward to sink" : "handled message at proxy";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ForwardResult forward() {
|
public static ForwardResult forward() {
|
||||||
|
@ -58,21 +58,21 @@ public final class PlayerChatEvent implements ResultedEvent<PlayerChatEvent.Chat
|
|||||||
|
|
||||||
// The server can not accept formatted text from clients!
|
// The server can not accept formatted text from clients!
|
||||||
private @Nullable String message;
|
private @Nullable String message;
|
||||||
private final boolean allowed;
|
private final boolean status;
|
||||||
|
|
||||||
protected ChatResult(boolean allowed, @Nullable String message) {
|
protected ChatResult(boolean status, @Nullable String message) {
|
||||||
this.allowed = allowed;
|
this.status = status;
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAllowed() {
|
public boolean isAllowed() {
|
||||||
return allowed;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return allowed ? "allowed" : "denied";
|
return status ? "allowed" : "denied";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ChatResult allowed() {
|
public static ChatResult allowed() {
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package com.velocitypowered.api.permission;
|
package com.velocitypowered.api.permission;
|
||||||
|
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -52,7 +51,10 @@ public enum Tristate {
|
|||||||
* is <code>null</code>, <code>true</code> or <code>false</code>, respectively.
|
* is <code>null</code>, <code>true</code> or <code>false</code>, respectively.
|
||||||
*/
|
*/
|
||||||
public static Tristate fromNullableBoolean(@Nullable Boolean val) {
|
public static Tristate fromNullableBoolean(@Nullable Boolean val) {
|
||||||
return val == null ? UNDEFINED : val ? TRUE : FALSE;
|
if (val == null) {
|
||||||
|
return UNDEFINED;
|
||||||
|
}
|
||||||
|
return val ? TRUE : FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final boolean booleanValue;
|
private final boolean booleanValue;
|
||||||
|
@ -18,8 +18,6 @@ public @interface Dependency {
|
|||||||
*/
|
*/
|
||||||
String id();
|
String id();
|
||||||
|
|
||||||
// TODO Add required version field
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If this dependency is optional for the plugin to work. By default
|
* If this dependency is optional for the plugin to work. By default
|
||||||
* this is {@code false}.
|
* this is {@code false}.
|
||||||
|
@ -42,6 +42,6 @@ public final class LegacyChannelIdentifier implements ChannelIdentifier {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return name;
|
return this.getName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ public final class SkinParts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasCape() {
|
public boolean hasCape() {
|
||||||
return ((bitmask >> 0) & 1) == 1;
|
return (bitmask & 1) == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasJacket() {
|
public boolean hasJacket() {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package com.velocitypowered.api.scheduler;
|
package com.velocitypowered.api.scheduler;
|
||||||
|
|
||||||
import org.checkerframework.common.value.qual.IntRange;
|
import org.checkerframework.common.value.qual.IntRange;
|
||||||
import org.checkerframework.common.value.qual.IntRangeFromNonNegative;
|
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ public final class GameProfile {
|
|||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
|
|
||||||
public final static class Property {
|
public static final class Property {
|
||||||
private final String name;
|
private final String name;
|
||||||
private final String value;
|
private final String value;
|
||||||
private final String signature;
|
private final String signature;
|
||||||
|
@ -51,7 +51,6 @@ import java.nio.file.Paths;
|
|||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
public class VelocityServer implements ProxyServer {
|
public class VelocityServer implements ProxyServer {
|
||||||
@ -98,7 +97,9 @@ public class VelocityServer implements ProxyServer {
|
|||||||
@Override
|
@Override
|
||||||
public ProxyVersion getVersion() {
|
public ProxyVersion getVersion() {
|
||||||
Package pkg = VelocityServer.class.getPackage();
|
Package pkg = VelocityServer.class.getPackage();
|
||||||
String implName, implVersion, implVendor;
|
String implName;
|
||||||
|
String implVersion;
|
||||||
|
String implVendor;
|
||||||
if (pkg != null) {
|
if (pkg != null) {
|
||||||
implName = MoreObjects.firstNonNull(pkg.getImplementationTitle(), "Velocity");
|
implName = MoreObjects.firstNonNull(pkg.getImplementationTitle(), "Velocity");
|
||||||
implVersion = MoreObjects.firstNonNull(pkg.getImplementationVersion(), "<unknown>");
|
implVersion = MoreObjects.firstNonNull(pkg.getImplementationVersion(), "<unknown>");
|
||||||
@ -148,7 +149,7 @@ public class VelocityServer implements ProxyServer {
|
|||||||
|
|
||||||
AnnotatedConfig.saveConfig(configuration.dumpConfig(), configPath); //Resave config to add new values
|
AnnotatedConfig.saveConfig(configuration.dumpConfig(), configPath); //Resave config to add new values
|
||||||
|
|
||||||
} catch (Throwable e) {
|
} catch (Exception e) {
|
||||||
logger.error("Unable to read/load/save your velocity.toml. The server will shut down.", e);
|
logger.error("Unable to read/load/save your velocity.toml. The server will shut down.", e);
|
||||||
LogManager.shutdown();
|
LogManager.shutdown();
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
@ -183,10 +184,10 @@ public class VelocityServer implements ProxyServer {
|
|||||||
try {
|
try {
|
||||||
Path pluginPath = Paths.get("plugins");
|
Path pluginPath = Paths.get("plugins");
|
||||||
|
|
||||||
if (Files.notExists(pluginPath)) {
|
if (!pluginPath.toFile().exists()) {
|
||||||
Files.createDirectory(pluginPath);
|
Files.createDirectory(pluginPath);
|
||||||
} else {
|
} else {
|
||||||
if (!Files.isDirectory(pluginPath)) {
|
if (!pluginPath.toFile().isDirectory()) {
|
||||||
logger.warn("Plugin location {} is not a directory, continuing without loading plugins", pluginPath);
|
logger.warn("Plugin location {} is not a directory, continuing without loading plugins", pluginPath);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -242,6 +243,7 @@ public class VelocityServer implements ProxyServer {
|
|||||||
}
|
}
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
// Not much we can do about this...
|
// Not much we can do about this...
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
shutdown = true;
|
shutdown = true;
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package com.velocitypowered.proxy.connection.backend;
|
package com.velocitypowered.proxy.connection.backend;
|
||||||
|
|
||||||
import com.velocitypowered.api.event.connection.PluginMessageEvent;
|
import com.velocitypowered.api.event.connection.PluginMessageEvent;
|
||||||
import com.velocitypowered.api.event.player.ServerConnectedEvent;
|
|
||||||
import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
|
import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
|
||||||
import com.velocitypowered.proxy.VelocityServer;
|
import com.velocitypowered.proxy.VelocityServer;
|
||||||
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
||||||
@ -67,13 +66,10 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(BossBar packet) {
|
public boolean handle(BossBar packet) {
|
||||||
switch (packet.getAction()) {
|
if (packet.getAction() == BossBar.ADD) {
|
||||||
case BossBar.ADD:
|
playerSessionHandler.getServerBossBars().add(packet.getUuid());
|
||||||
playerSessionHandler.getServerBossBars().add(packet.getUuid());
|
} else if (packet.getAction() == BossBar.REMOVE) {
|
||||||
break;
|
playerSessionHandler.getServerBossBars().remove(packet.getUuid());
|
||||||
case BossBar.REMOVE:
|
|
||||||
playerSessionHandler.getServerBossBars().remove(packet.getUuid());
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return false; // forward
|
return false; // forward
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package com.velocitypowered.proxy.connection.backend;
|
package com.velocitypowered.proxy.connection.backend;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.base.Verify;
|
|
||||||
import com.google.common.base.VerifyException;
|
import com.google.common.base.VerifyException;
|
||||||
import com.velocitypowered.api.proxy.ConnectionRequestBuilder;
|
import com.velocitypowered.api.proxy.ConnectionRequestBuilder;
|
||||||
import com.velocitypowered.api.proxy.ServerConnection;
|
import com.velocitypowered.api.proxy.ServerConnection;
|
||||||
@ -65,10 +64,10 @@ public class VelocityServerConnection implements MinecraftConnectionAssociation,
|
|||||||
.addLast(MINECRAFT_DECODER, new MinecraftDecoder(ProtocolConstants.Direction.CLIENTBOUND))
|
.addLast(MINECRAFT_DECODER, new MinecraftDecoder(ProtocolConstants.Direction.CLIENTBOUND))
|
||||||
.addLast(MINECRAFT_ENCODER, new MinecraftEncoder(ProtocolConstants.Direction.SERVERBOUND));
|
.addLast(MINECRAFT_ENCODER, new MinecraftEncoder(ProtocolConstants.Direction.SERVERBOUND));
|
||||||
|
|
||||||
MinecraftConnection connection = new MinecraftConnection(ch, server);
|
MinecraftConnection mc = new MinecraftConnection(ch, server);
|
||||||
connection.setState(StateRegistry.HANDSHAKE);
|
mc.setState(StateRegistry.HANDSHAKE);
|
||||||
connection.setAssociation(VelocityServerConnection.this);
|
mc.setAssociation(VelocityServerConnection.this);
|
||||||
ch.pipeline().addLast(HANDLER, connection);
|
ch.pipeline().addLast(HANDLER, mc);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.connect(registeredServer.getServerInfo().getAddress())
|
.connect(registeredServer.getServerInfo().getAddress())
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package com.velocitypowered.proxy.connection.client;
|
package com.velocitypowered.proxy.connection.client;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
|
||||||
import com.velocitypowered.api.event.connection.PluginMessageEvent;
|
import com.velocitypowered.api.event.connection.PluginMessageEvent;
|
||||||
import com.velocitypowered.api.event.player.PlayerChatEvent;
|
import com.velocitypowered.api.event.player.PlayerChatEvent;
|
||||||
import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
|
import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
|
||||||
@ -57,13 +56,11 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
VelocityServerConnection serverConnection = player.getConnectedServer();
|
VelocityServerConnection serverConnection = player.getConnectedServer();
|
||||||
if (serverConnection != null && packet.getRandomId() == serverConnection.getLastPingId()) {
|
if (serverConnection != null && packet.getRandomId() == serverConnection.getLastPingId()) {
|
||||||
MinecraftConnection smc = serverConnection.getConnection();
|
MinecraftConnection smc = serverConnection.getConnection();
|
||||||
if (smc == null) {
|
if (smc != null) {
|
||||||
// eat the packet
|
player.setPing(System.currentTimeMillis() - serverConnection.getLastPingSent());
|
||||||
return true;
|
smc.write(packet);
|
||||||
|
serverConnection.resetLastPingId();
|
||||||
}
|
}
|
||||||
player.setPing(System.currentTimeMillis() - serverConnection.getLastPingSent());
|
|
||||||
smc.write(packet);
|
|
||||||
serverConnection.resetLastPingId();
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -122,7 +119,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
String cmd = packet.getCommand().substring(1, spacePos);
|
String cmd = packet.getCommand().substring(1, spacePos);
|
||||||
if (server.getCommandManager().hasCommand(cmd)) {
|
if (server.getCommandManager().hasCommand(cmd)) {
|
||||||
List<String> suggestions = server.getCommandManager().offerSuggestions(player, packet.getCommand().substring(1));
|
List<String> suggestions = server.getCommandManager().offerSuggestions(player, packet.getCommand().substring(1));
|
||||||
if (suggestions.size() > 0) {
|
if (!suggestions.isEmpty()) {
|
||||||
TabCompleteResponse resp = new TabCompleteResponse();
|
TabCompleteResponse resp = new TabCompleteResponse();
|
||||||
resp.getOffers().addAll(suggestions);
|
resp.getOffers().addAll(suggestions);
|
||||||
player.getConnection().write(resp);
|
player.getConnection().write(resp);
|
||||||
@ -153,20 +150,17 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actuallyRegistered.size() > 0) {
|
if (!actuallyRegistered.isEmpty()) {
|
||||||
PluginMessage newRegisterPacket = PluginMessageUtil.constructChannelsPacket(backendConn
|
PluginMessage newRegisterPacket = PluginMessageUtil.constructChannelsPacket(backendConn
|
||||||
.getProtocolVersion(), actuallyRegistered);
|
.getProtocolVersion(), actuallyRegistered);
|
||||||
backendConn.write(newRegisterPacket);
|
backendConn.write(newRegisterPacket);
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
} else if (PluginMessageUtil.isMCUnregister(packet)) {
|
} else if (PluginMessageUtil.isMCUnregister(packet)) {
|
||||||
List<String> channels = PluginMessageUtil.getChannels(packet);
|
List<String> channels = PluginMessageUtil.getChannels(packet);
|
||||||
clientPluginMsgChannels.removeAll(channels);
|
clientPluginMsgChannels.removeAll(channels);
|
||||||
backendConn.write(packet);
|
backendConn.write(packet);
|
||||||
return true;
|
|
||||||
} else if (PluginMessageUtil.isMCBrand(packet)) {
|
} else if (PluginMessageUtil.isMCBrand(packet)) {
|
||||||
backendConn.write(PluginMessageUtil.rewriteMCBrand(packet));
|
backendConn.write(PluginMessageUtil.rewriteMCBrand(packet));
|
||||||
return true;
|
|
||||||
} else if (backendConn.isLegacyForge() && !serverConn.hasCompletedJoin()) {
|
} else if (backendConn.isLegacyForge() && !serverConn.hasCompletedJoin()) {
|
||||||
if (packet.getChannel().equals(ForgeConstants.FORGE_LEGACY_HANDSHAKE_CHANNEL)) {
|
if (packet.getChannel().equals(ForgeConstants.FORGE_LEGACY_HANDSHAKE_CHANNEL)) {
|
||||||
if (!player.getModInfo().isPresent()) {
|
if (!player.getModInfo().isPresent()) {
|
||||||
@ -184,17 +178,14 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
// be sent once the JoinGame packet has been received by the proxy.
|
// be sent once the JoinGame packet has been received by the proxy.
|
||||||
loginPluginMessages.add(packet);
|
loginPluginMessages.add(packet);
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
} else {
|
} else {
|
||||||
ChannelIdentifier id = server.getChannelRegistrar().getFromId(packet.getChannel());
|
ChannelIdentifier id = server.getChannelRegistrar().getFromId(packet.getChannel());
|
||||||
if (id == null) {
|
if (id == null) {
|
||||||
backendConn.write(packet);
|
backendConn.write(packet);
|
||||||
} else {
|
} else {
|
||||||
PluginMessageEvent event = new PluginMessageEvent(player, serverConn, id, packet.getData());
|
PluginMessageEvent event = new PluginMessageEvent(player, serverConn, id, packet.getData());
|
||||||
server.getEventManager().fire(event)
|
server.getEventManager().fire(event).thenAcceptAsync(pme -> backendConn.write(packet),
|
||||||
.thenAcceptAsync(pme -> {
|
backendConn.eventLoop());
|
||||||
backendConn.write(packet);
|
|
||||||
}, backendConn.eventLoop());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -246,10 +237,10 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writabilityChanged() {
|
public void writabilityChanged() {
|
||||||
VelocityServerConnection server = player.getConnectedServer();
|
VelocityServerConnection serverConn = player.getConnectedServer();
|
||||||
if (server != null) {
|
if (serverConn != null) {
|
||||||
boolean writable = player.getConnection().getChannel().isWritable();
|
boolean writable = player.getConnection().getChannel().isWritable();
|
||||||
MinecraftConnection smc = server.getConnection();
|
MinecraftConnection smc = serverConn.getConnection();
|
||||||
if (smc != null) {
|
if (smc != null) {
|
||||||
smc.getChannel().config().setAutoRead(writable);
|
smc.getChannel().config().setAutoRead(writable);
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
|
|||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
public class ClientSettingsWrapper implements PlayerSettings {
|
public class ClientSettingsWrapper implements PlayerSettings {
|
||||||
static PlayerSettings DEFAULT = new ClientSettingsWrapper(new ClientSettings("en_US", (byte) 10, 0, true, (short)127, 1));
|
static final PlayerSettings DEFAULT = new ClientSettingsWrapper(new ClientSettings("en_US", (byte) 10, 0, true, (short)127, 1));
|
||||||
|
|
||||||
private final ClientSettings settings;
|
private final ClientSettings settings;
|
||||||
private final SkinParts parts;
|
private final SkinParts parts;
|
||||||
@ -21,7 +21,10 @@ public class ClientSettingsWrapper implements PlayerSettings {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Locale getLocale() {
|
public Locale getLocale() {
|
||||||
return locale == null ? locale = Locale.forLanguageTag(settings.getLocale().replaceAll("_", "-")) : locale; //Will throw error if locale not found
|
if (locale == null) {
|
||||||
|
locale = Locale.forLanguageTag(settings.getLocale().replaceAll("_", "-"));
|
||||||
|
}
|
||||||
|
return locale;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -43,27 +43,24 @@ import net.kyori.text.serializer.PlainComponentSerializer;
|
|||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
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.NonNull;
|
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.CompletionException;
|
import java.util.concurrent.CompletionException;
|
||||||
|
|
||||||
public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
||||||
private static final PlainComponentSerializer PASS_THRU_TRANSLATE = new PlainComponentSerializer((c) -> "", TranslatableComponent::key);
|
private static final PlainComponentSerializer PASS_THRU_TRANSLATE = new PlainComponentSerializer(c -> "", TranslatableComponent::key);
|
||||||
static final PermissionProvider DEFAULT_PERMISSIONS = s -> PermissionFunction.ALWAYS_UNDEFINED;
|
static final PermissionProvider DEFAULT_PERMISSIONS = s -> PermissionFunction.ALWAYS_UNDEFINED;
|
||||||
|
|
||||||
private static final Logger logger = LogManager.getLogger(ConnectedPlayer.class);
|
private static final Logger logger = LogManager.getLogger(ConnectedPlayer.class);
|
||||||
|
|
||||||
private final MinecraftConnection connection;
|
private final MinecraftConnection connection;
|
||||||
private @Nullable final InetSocketAddress virtualHost;
|
private final @Nullable InetSocketAddress virtualHost;
|
||||||
private GameProfile profile;
|
private GameProfile profile;
|
||||||
private PermissionFunction permissionFunction;
|
private PermissionFunction permissionFunction;
|
||||||
private int tryIndex = 0;
|
private int tryIndex = 0;
|
||||||
@ -84,7 +81,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
|||||||
this.profile = profile;
|
this.profile = profile;
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
this.virtualHost = virtualHost;
|
this.virtualHost = virtualHost;
|
||||||
this.permissionFunction = (permission) -> Tristate.UNDEFINED;
|
this.permissionFunction = PermissionFunction.ALWAYS_UNDEFINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -364,8 +361,8 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
|||||||
|
|
||||||
Optional<RegisteredServer> getNextServerToTry() {
|
Optional<RegisteredServer> getNextServerToTry() {
|
||||||
if (serversToTry == null) {
|
if (serversToTry == null) {
|
||||||
String virtualHost = getVirtualHost().map(InetSocketAddress::getHostString).orElse("");
|
String virtualHostStr = getVirtualHost().map(InetSocketAddress::getHostString).orElse("");
|
||||||
serversToTry = server.getConfiguration().getForcedHosts().getOrDefault(virtualHost, Collections.emptyList());
|
serversToTry = server.getConfiguration().getForcedHosts().getOrDefault(virtualHostStr, Collections.emptyList());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (serversToTry.isEmpty()) {
|
if (serversToTry.isEmpty()) {
|
||||||
@ -401,7 +398,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
|||||||
// Otherwise, initiate the connection.
|
// Otherwise, initiate the connection.
|
||||||
ServerPreConnectEvent event = new ServerPreConnectEvent(this, request.getServer());
|
ServerPreConnectEvent event = new ServerPreConnectEvent(this, request.getServer());
|
||||||
return server.getEventManager().fire(event)
|
return server.getEventManager().fire(event)
|
||||||
.thenCompose((newEvent) -> {
|
.thenCompose(newEvent -> {
|
||||||
Optional<RegisteredServer> connectTo = newEvent.getResult().getServer();
|
Optional<RegisteredServer> connectTo = newEvent.getResult().getServer();
|
||||||
if (!connectTo.isPresent()) {
|
if (!connectTo.isPresent()) {
|
||||||
return CompletableFuture.completedFuture(
|
return CompletableFuture.completedFuture(
|
||||||
@ -431,10 +428,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
|||||||
|
|
||||||
public void sendLegacyForgeHandshakeResetPacket() {
|
public void sendLegacyForgeHandshakeResetPacket() {
|
||||||
if (connection.canSendLegacyFMLResetPacket()) {
|
if (connection.canSendLegacyFMLResetPacket()) {
|
||||||
PluginMessage resetPacket = new PluginMessage();
|
connection.write(ForgeConstants.resetPacket());
|
||||||
resetPacket.setChannel(ForgeConstants.FORGE_LEGACY_HANDSHAKE_CHANNEL);
|
|
||||||
resetPacket.setData(ForgeConstants.FORGE_LEGACY_HANDSHAKE_RESET_DATA);
|
|
||||||
connection.write(resetPacket);
|
|
||||||
connection.setCanSendLegacyFMLResetPacket(false);
|
connection.setCanSendLegacyFMLResetPacket(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -534,6 +528,9 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
|
|||||||
case SERVER_DISCONNECTED:
|
case SERVER_DISCONNECTED:
|
||||||
handleConnectionException(server, Disconnect.create(status.getReason().orElse(ConnectionMessages.INTERNAL_SERVER_CONNECTION_ERROR)));
|
handleConnectionException(server, Disconnect.create(status.getReason().orElse(ConnectionMessages.INTERNAL_SERVER_CONNECTION_ERROR)));
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
// The only remaining value is successful (no need to do anything!)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}, connection.eventLoop())
|
}, connection.eventLoop())
|
||||||
.thenApply(Result::isSuccessful);
|
.thenApply(Result::isSuccessful);
|
||||||
|
@ -48,7 +48,8 @@ public class HandshakeSessionHandler implements MinecraftSessionHandler {
|
|||||||
server.getEventManager().fire(event)
|
server.getEventManager().fire(event)
|
||||||
.thenRunAsync(() -> {
|
.thenRunAsync(() -> {
|
||||||
// The disconnect packet is the same as the server response one.
|
// The disconnect packet is the same as the server response one.
|
||||||
connection.closeWith(LegacyDisconnect.fromPingResponse(LegacyPingResponse.from(event.getPing())));
|
LegacyPingResponse response = LegacyPingResponse.from(event.getPing());
|
||||||
|
connection.closeWith(LegacyDisconnect.fromPingResponse(response));
|
||||||
}, connection.eventLoop());
|
}, connection.eventLoop());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -116,12 +117,13 @@ public class HandshakeSessionHandler implements MinecraftSessionHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleGeneric(MinecraftPacket packet) {
|
public void handleGeneric(MinecraftPacket packet) {
|
||||||
|
// Unknown packet received. Better to close the connection.
|
||||||
|
connection.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleUnknown(ByteBuf buf) {
|
public void handleUnknown(ByteBuf buf) {
|
||||||
// what even is going on?
|
// Unknown packet received. Better to close the connection.
|
||||||
connection.close();
|
connection.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,9 +48,8 @@ public class StatusSessionHandler implements MinecraftSessionHandler {
|
|||||||
|
|
||||||
ProxyPingEvent event = new ProxyPingEvent(inboundWrapper, initialPing);
|
ProxyPingEvent event = new ProxyPingEvent(inboundWrapper, initialPing);
|
||||||
server.getEventManager().fire(event)
|
server.getEventManager().fire(event)
|
||||||
.thenRunAsync(() -> {
|
.thenRunAsync(() -> connection.write(new StatusResponse(VelocityServer.GSON.toJson(event.getPing()))),
|
||||||
connection.write(new StatusResponse(VelocityServer.GSON.toJson(event.getPing())));
|
connection.eventLoop());
|
||||||
}, connection.eventLoop());
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,12 +1,21 @@
|
|||||||
package com.velocitypowered.proxy.connection.forge;
|
package com.velocitypowered.proxy.connection.forge;
|
||||||
|
|
||||||
|
import com.velocitypowered.proxy.protocol.packet.PluginMessage;
|
||||||
|
|
||||||
public class ForgeConstants {
|
public class ForgeConstants {
|
||||||
public static final String FORGE_LEGACY_HANDSHAKE_CHANNEL = "FML|HS";
|
public static final String FORGE_LEGACY_HANDSHAKE_CHANNEL = "FML|HS";
|
||||||
public static final String FORGE_LEGACY_CHANNEL = "FML";
|
public static final String FORGE_LEGACY_CHANNEL = "FML";
|
||||||
public static final String FORGE_MULTIPART_LEGACY_CHANNEL = "FML|MP";
|
public static final String FORGE_MULTIPART_LEGACY_CHANNEL = "FML|MP";
|
||||||
public static final byte[] FORGE_LEGACY_HANDSHAKE_RESET_DATA = new byte[] { -2, 0 };
|
private static final byte[] FORGE_LEGACY_HANDSHAKE_RESET_DATA = new byte[] { -2, 0 };
|
||||||
|
|
||||||
private ForgeConstants() {
|
private ForgeConstants() {
|
||||||
throw new AssertionError();
|
throw new AssertionError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static PluginMessage resetPacket() {
|
||||||
|
PluginMessage msg = new PluginMessage();
|
||||||
|
msg.setChannel(FORGE_LEGACY_HANDSHAKE_CHANNEL);
|
||||||
|
msg.setData(FORGE_LEGACY_HANDSHAKE_RESET_DATA.clone());
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ package com.velocitypowered.proxy.connection.util;
|
|||||||
import com.velocitypowered.api.proxy.ConnectionRequestBuilder;
|
import com.velocitypowered.api.proxy.ConnectionRequestBuilder;
|
||||||
import com.velocitypowered.proxy.protocol.packet.Disconnect;
|
import com.velocitypowered.proxy.protocol.packet.Disconnect;
|
||||||
import net.kyori.text.Component;
|
import net.kyori.text.Component;
|
||||||
import net.kyori.text.TextComponent;
|
|
||||||
import net.kyori.text.serializer.ComponentSerializers;
|
import net.kyori.text.serializer.ComponentSerializers;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
@ -18,7 +18,6 @@ import org.jline.reader.LineReader;
|
|||||||
import org.jline.reader.LineReaderBuilder;
|
import org.jline.reader.LineReaderBuilder;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
public final class VelocityConsole extends SimpleTerminalConsole implements CommandSource {
|
public final class VelocityConsole extends SimpleTerminalConsole implements CommandSource {
|
||||||
private static final Logger logger = LogManager.getLogger(VelocityConsole.class);
|
private static final Logger logger = LogManager.getLogger(VelocityConsole.class);
|
||||||
|
@ -12,7 +12,6 @@ import io.netty.channel.EventLoopGroup;
|
|||||||
import io.netty.channel.WriteBufferWaterMark;
|
import io.netty.channel.WriteBufferWaterMark;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.checkerframework.checker.initialization.qual.UnderInitialization;
|
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@ -94,6 +93,7 @@ public final class ConnectionManager {
|
|||||||
endpoint.close().sync();
|
endpoint.close().sync();
|
||||||
} catch (final InterruptedException e) {
|
} catch (final InterruptedException e) {
|
||||||
LOGGER.info("Interrupted whilst closing endpoint", e);
|
LOGGER.info("Interrupted whilst closing endpoint", e);
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,20 @@
|
|||||||
package com.velocitypowered.proxy.network;
|
package com.velocitypowered.proxy.network;
|
||||||
|
|
||||||
public interface Connections {
|
public class Connections {
|
||||||
String CIPHER_DECODER = "cipher-decoder";
|
public static final String CIPHER_DECODER = "cipher-decoder";
|
||||||
String CIPHER_ENCODER = "cipher-encoder";
|
public static final String CIPHER_ENCODER = "cipher-encoder";
|
||||||
String COMPRESSION_DECODER = "compression-decoder";
|
public static final String COMPRESSION_DECODER = "compression-decoder";
|
||||||
String COMPRESSION_ENCODER = "compression-encoder";
|
public static final String COMPRESSION_ENCODER = "compression-encoder";
|
||||||
String FRAME_DECODER = "frame-decoder";
|
public static final String FRAME_DECODER = "frame-decoder";
|
||||||
String FRAME_ENCODER = "frame-encoder";
|
public static final String FRAME_ENCODER = "frame-encoder";
|
||||||
String HANDLER = "handler";
|
public static final String HANDLER = "handler";
|
||||||
String LEGACY_PING_DECODER = "legacy-ping-decoder";
|
public static final String LEGACY_PING_DECODER = "legacy-ping-decoder";
|
||||||
String LEGACY_PING_ENCODER = "legacy-ping-encoder";
|
public static final String LEGACY_PING_ENCODER = "legacy-ping-encoder";
|
||||||
String MINECRAFT_DECODER = "minecraft-decoder";
|
public static final String MINECRAFT_DECODER = "minecraft-decoder";
|
||||||
String MINECRAFT_ENCODER = "minecraft-encoder";
|
public static final String MINECRAFT_ENCODER = "minecraft-encoder";
|
||||||
String READ_TIMEOUT = "read-timeout";
|
public static final String READ_TIMEOUT = "read-timeout";
|
||||||
|
|
||||||
|
private Connections() {
|
||||||
|
throw new AssertionError();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,8 @@ public class NettyHttpClient {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void channelAcquired(Channel channel) throws Exception {
|
public void channelAcquired(Channel channel) throws Exception {
|
||||||
|
// We don't do anything special when acquiring channels. The channel handler cleans up after
|
||||||
|
// each connection is used.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -72,10 +74,8 @@ public class NettyHttpClient {
|
|||||||
request.headers().add(HttpHeaderNames.USER_AGENT, "Velocity");
|
request.headers().add(HttpHeaderNames.USER_AGENT, "Velocity");
|
||||||
channel.writeAndFlush(request);
|
channel.writeAndFlush(request);
|
||||||
|
|
||||||
reply.whenComplete((resp, err) -> {
|
// Make sure to release this connection
|
||||||
// Make sure to release this connection
|
reply.whenComplete((resp, err) -> poolMap.get(address).release(channel));
|
||||||
poolMap.get(address).release(channel, channel.voidPromise());
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
reply.completeExceptionally(future.cause());
|
reply.completeExceptionally(future.cause());
|
||||||
}
|
}
|
||||||
|
@ -55,11 +55,15 @@ public class VelocityEventManager implements EventManager {
|
|||||||
.setNameFormat("Velocity Event Executor - #%d").setDaemon(true).build());
|
.setNameFormat("Velocity Event Executor - #%d").setDaemon(true).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ensurePlugin(Object plugin) {
|
||||||
|
Preconditions.checkNotNull(plugin, "plugin");
|
||||||
|
Preconditions.checkArgument(pluginManager.fromInstance(plugin).isPresent(), "Specified plugin is not loaded");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void register(Object plugin, Object listener) {
|
public void register(Object plugin, Object listener) {
|
||||||
Preconditions.checkNotNull(plugin, "plugin");
|
ensurePlugin(plugin);
|
||||||
Preconditions.checkNotNull(listener, "listener");
|
Preconditions.checkNotNull(listener, "listener");
|
||||||
Preconditions.checkArgument(pluginManager.fromInstance(plugin).isPresent(), "Specified plugin is not loaded");
|
|
||||||
if (plugin == listener && registeredListenersByPlugin.containsEntry(plugin, plugin)) {
|
if (plugin == listener && registeredListenersByPlugin.containsEntry(plugin, plugin)) {
|
||||||
throw new IllegalArgumentException("Trying to register the plugin main instance. Velocity already takes care of this for you.");
|
throw new IllegalArgumentException("Trying to register the plugin main instance. Velocity already takes care of this for you.");
|
||||||
}
|
}
|
||||||
@ -70,7 +74,7 @@ public class VelocityEventManager implements EventManager {
|
|||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("type.argument.type.incompatible")
|
@SuppressWarnings("type.argument.type.incompatible")
|
||||||
public <E> void register(Object plugin, Class<E> eventClass, PostOrder postOrder, EventHandler<E> handler) {
|
public <E> void register(Object plugin, Class<E> eventClass, PostOrder postOrder, EventHandler<E> handler) {
|
||||||
Preconditions.checkNotNull(plugin, "plugin");
|
ensurePlugin(plugin);
|
||||||
Preconditions.checkNotNull(eventClass, "eventClass");
|
Preconditions.checkNotNull(eventClass, "eventClass");
|
||||||
Preconditions.checkNotNull(postOrder, "postOrder");
|
Preconditions.checkNotNull(postOrder, "postOrder");
|
||||||
Preconditions.checkNotNull(handler, "listener");
|
Preconditions.checkNotNull(handler, "listener");
|
||||||
@ -108,8 +112,7 @@ public class VelocityEventManager implements EventManager {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unregisterListeners(Object plugin) {
|
public void unregisterListeners(Object plugin) {
|
||||||
Preconditions.checkNotNull(plugin, "plugin");
|
ensurePlugin(plugin);
|
||||||
Preconditions.checkArgument(pluginManager.fromInstance(plugin).isPresent(), "Specified plugin is not loaded");
|
|
||||||
Collection<Object> listeners = registeredListenersByPlugin.removeAll(plugin);
|
Collection<Object> listeners = registeredListenersByPlugin.removeAll(plugin);
|
||||||
listeners.forEach(methodAdapter::unregister);
|
listeners.forEach(methodAdapter::unregister);
|
||||||
Collection<EventHandler<?>> handlers = registeredHandlersByPlugin.removeAll(plugin);
|
Collection<EventHandler<?>> handlers = registeredHandlersByPlugin.removeAll(plugin);
|
||||||
@ -118,16 +121,15 @@ public class VelocityEventManager implements EventManager {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unregisterListener(Object plugin, Object listener) {
|
public void unregisterListener(Object plugin, Object listener) {
|
||||||
Preconditions.checkNotNull(plugin, "plugin");
|
ensurePlugin(plugin);
|
||||||
Preconditions.checkNotNull(listener, "listener");
|
Preconditions.checkNotNull(listener, "listener");
|
||||||
Preconditions.checkArgument(pluginManager.fromInstance(plugin).isPresent(), "Specified plugin is not loaded");
|
|
||||||
registeredListenersByPlugin.remove(plugin, listener);
|
registeredListenersByPlugin.remove(plugin, listener);
|
||||||
methodAdapter.unregister(listener);
|
methodAdapter.unregister(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <E> void unregister(Object plugin, EventHandler<E> handler) {
|
public <E> void unregister(Object plugin, EventHandler<E> handler) {
|
||||||
Preconditions.checkNotNull(plugin, "plugin");
|
ensurePlugin(plugin);
|
||||||
Preconditions.checkNotNull(handler, "listener");
|
Preconditions.checkNotNull(handler, "listener");
|
||||||
registeredHandlersByPlugin.remove(plugin, handler);
|
registeredHandlersByPlugin.remove(plugin, handler);
|
||||||
bus.unregister(new KyoriToVelocityHandler<>(handler, PostOrder.LAST));
|
bus.unregister(new KyoriToVelocityHandler<>(handler, PostOrder.LAST));
|
||||||
|
@ -9,7 +9,6 @@ import com.velocitypowered.proxy.plugin.loader.JavaPluginLoader;
|
|||||||
import com.velocitypowered.proxy.plugin.util.PluginDependencyUtils;
|
import com.velocitypowered.proxy.plugin.util.PluginDependencyUtils;
|
||||||
import org.apache.logging.log4j.LogManager;
|
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 java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.DirectoryStream;
|
import java.nio.file.DirectoryStream;
|
||||||
@ -41,12 +40,12 @@ public class VelocityPluginManager implements PluginManager {
|
|||||||
|
|
||||||
public void loadPlugins(Path directory) throws IOException {
|
public void loadPlugins(Path directory) throws IOException {
|
||||||
checkNotNull(directory, "directory");
|
checkNotNull(directory, "directory");
|
||||||
checkArgument(Files.isDirectory(directory), "provided path isn't a directory");
|
checkArgument(directory.toFile().isDirectory(), "provided path isn't a directory");
|
||||||
|
|
||||||
List<PluginDescription> found = new ArrayList<>();
|
List<PluginDescription> found = new ArrayList<>();
|
||||||
JavaPluginLoader loader = new JavaPluginLoader(server, directory);
|
JavaPluginLoader loader = new JavaPluginLoader(server, directory);
|
||||||
|
|
||||||
try (DirectoryStream<Path> stream = Files.newDirectoryStream(directory, p -> Files.isRegularFile(p) && p.toString().endsWith(".jar"))) {
|
try (DirectoryStream<Path> stream = Files.newDirectoryStream(directory, p -> p.toFile().isFile() && p.toString().endsWith(".jar"))) {
|
||||||
for (Path path : stream) {
|
for (Path path : stream) {
|
||||||
try {
|
try {
|
||||||
found.add(loader.loadPlugin(path));
|
found.add(loader.loadPlugin(path));
|
||||||
@ -79,7 +78,7 @@ public class VelocityPluginManager implements PluginManager {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
pluginObject = loader.createPlugin(plugin);
|
pluginObject = loader.createPlugin(plugin);
|
||||||
} catch (Throwable e) {
|
} catch (Exception e) {
|
||||||
logger.error("Can't create plugin {}", plugin.getId(), e);
|
logger.error("Can't create plugin {}", plugin.getId(), e);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,6 @@ import com.velocitypowered.proxy.VelocityServer;
|
|||||||
import com.velocitypowered.proxy.plugin.PluginClassLoader;
|
import com.velocitypowered.proxy.plugin.PluginClassLoader;
|
||||||
import com.velocitypowered.proxy.plugin.loader.java.JavaVelocityPluginDescription;
|
import com.velocitypowered.proxy.plugin.loader.java.JavaVelocityPluginDescription;
|
||||||
import com.velocitypowered.proxy.plugin.loader.java.VelocityPluginModule;
|
import com.velocitypowered.proxy.plugin.loader.java.VelocityPluginModule;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
|
@ -13,6 +13,10 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class PluginDependencyUtils {
|
public class PluginDependencyUtils {
|
||||||
|
private PluginDependencyUtils() {
|
||||||
|
throw new AssertionError();
|
||||||
|
}
|
||||||
|
|
||||||
public static List<PluginDescription> sortCandidates(List<@NonNull PluginDescription> candidates) {
|
public static List<PluginDescription> sortCandidates(List<@NonNull PluginDescription> candidates) {
|
||||||
// Create our graph, we're going to be using this for Kahn's algorithm.
|
// Create our graph, we're going to be using this for Kahn's algorithm.
|
||||||
MutableGraph<PluginDescription> graph = GraphBuilder.directed().allowsSelfLoops(false).build();
|
MutableGraph<PluginDescription> graph = GraphBuilder.directed().allowsSelfLoops(false).build();
|
||||||
|
@ -217,12 +217,12 @@ public enum StateRegistry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public class ProtocolVersion {
|
public class ProtocolVersion {
|
||||||
public final int id;
|
public final int version;
|
||||||
final IntObjectMap<Supplier<? extends MinecraftPacket>> packetIdToSupplier = new IntObjectHashMap<>(16, 0.5f);
|
final IntObjectMap<Supplier<? extends MinecraftPacket>> packetIdToSupplier = new IntObjectHashMap<>(16, 0.5f);
|
||||||
final Object2IntMap<Class<? extends MinecraftPacket>> packetClassToId = new Object2IntOpenHashMap<>(16, 0.5f);
|
final Object2IntMap<Class<? extends MinecraftPacket>> packetClassToId = new Object2IntOpenHashMap<>(16, 0.5f);
|
||||||
|
|
||||||
ProtocolVersion(final int id) {
|
ProtocolVersion(final int version) {
|
||||||
this.id = id;
|
this.version = version;
|
||||||
this.packetClassToId.defaultReturnValue(Integer.MIN_VALUE);
|
this.packetClassToId.defaultReturnValue(Integer.MIN_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,7 +239,7 @@ public enum StateRegistry {
|
|||||||
if (id == Integer.MIN_VALUE) {
|
if (id == Integer.MIN_VALUE) {
|
||||||
throw new IllegalArgumentException(String.format(
|
throw new IllegalArgumentException(String.format(
|
||||||
"Unable to find id for packet of type %s in %s protocol %s",
|
"Unable to find id for packet of type %s in %s protocol %s",
|
||||||
packet.getClass().getName(), PacketRegistry.this.direction, this.id
|
packet.getClass().getName(), PacketRegistry.this.direction, this.version
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
return id;
|
return id;
|
||||||
|
@ -35,15 +35,15 @@ import static com.velocitypowered.api.event.query.ProxyQueryEvent.QueryType.FULL
|
|||||||
public class GS4QueryHandler extends SimpleChannelInboundHandler<DatagramPacket> {
|
public class GS4QueryHandler extends SimpleChannelInboundHandler<DatagramPacket> {
|
||||||
private static final Logger logger = LogManager.getLogger(GS4QueryHandler.class);
|
private static final Logger logger = LogManager.getLogger(GS4QueryHandler.class);
|
||||||
|
|
||||||
private final static short QUERY_MAGIC_FIRST = 0xFE;
|
private static final short QUERY_MAGIC_FIRST = 0xFE;
|
||||||
private final static short QUERY_MAGIC_SECOND = 0xFD;
|
private static final short QUERY_MAGIC_SECOND = 0xFD;
|
||||||
private final static byte QUERY_TYPE_HANDSHAKE = 0x09;
|
private static final byte QUERY_TYPE_HANDSHAKE = 0x09;
|
||||||
private final static byte QUERY_TYPE_STAT = 0x00;
|
private static final byte QUERY_TYPE_STAT = 0x00;
|
||||||
private final static byte[] QUERY_RESPONSE_FULL_PADDING = new byte[] { 0x73, 0x70, 0x6C, 0x69, 0x74, 0x6E, 0x75, 0x6D, 0x00, (byte) 0x80, 0x00 };
|
private static final byte[] QUERY_RESPONSE_FULL_PADDING = new byte[] { 0x73, 0x70, 0x6C, 0x69, 0x74, 0x6E, 0x75, 0x6D, 0x00, (byte) 0x80, 0x00 };
|
||||||
private final static byte[] QUERY_RESPONSE_FULL_PADDING2 = new byte[] { 0x01, 0x70, 0x6C, 0x61, 0x79, 0x65, 0x72, 0x5F, 0x00, 0x00 };
|
private static final byte[] QUERY_RESPONSE_FULL_PADDING2 = new byte[] { 0x01, 0x70, 0x6C, 0x61, 0x79, 0x65, 0x72, 0x5F, 0x00, 0x00 };
|
||||||
|
|
||||||
// Contents to add into basic stat response. See ResponseWriter class below
|
// Contents to add into basic stat response. See ResponseWriter class below
|
||||||
private final static Set<String> QUERY_BASIC_RESPONSE_CONTENTS = ImmutableSet.of(
|
private static final Set<String> QUERY_BASIC_RESPONSE_CONTENTS = ImmutableSet.of(
|
||||||
"hostname",
|
"hostname",
|
||||||
"gametype",
|
"gametype",
|
||||||
"map",
|
"map",
|
||||||
@ -159,10 +159,8 @@ public class GS4QueryHandler extends SimpleChannelInboundHandler<DatagramPacket>
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
default: {
|
|
||||||
throw new IllegalStateException("Invalid query type: " + type);
|
throw new IllegalStateException("Invalid query type: " + type);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.warn("Error while trying to handle a query packet from {}", msg.sender(), e);
|
logger.warn("Error while trying to handle a query packet from {}", msg.sender(), e);
|
||||||
|
@ -38,14 +38,14 @@ public class MinecraftDecoder extends MessageToMessageDecoder<ByteBuf> {
|
|||||||
out.add(slice.retain());
|
out.add(slice.retain());
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
packet.decode(msg, direction, protocolVersion.id);
|
packet.decode(msg, direction, protocolVersion.version);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new CorruptedFrameException("Error decoding " + packet.getClass() + " Direction " + direction
|
throw new CorruptedFrameException("Error decoding " + packet.getClass() + " Direction " + direction
|
||||||
+ " Protocol " + protocolVersion.id + " State " + state + " ID " + Integer.toHexString(packetId), e);
|
+ " Protocol " + protocolVersion.version + " State " + state + " ID " + Integer.toHexString(packetId), e);
|
||||||
}
|
}
|
||||||
if (msg.isReadable()) {
|
if (msg.isReadable()) {
|
||||||
throw new CorruptedFrameException("Did not read full packet for " + packet.getClass() + " Direction " + direction
|
throw new CorruptedFrameException("Did not read full packet for " + packet.getClass() + " Direction " + direction
|
||||||
+ " Protocol " + protocolVersion.id + " State " + state + " ID " + Integer.toHexString(packetId));
|
+ " Protocol " + protocolVersion.version + " State " + state + " ID " + Integer.toHexString(packetId));
|
||||||
}
|
}
|
||||||
out.add(packet);
|
out.add(packet);
|
||||||
}
|
}
|
||||||
@ -57,6 +57,6 @@ public class MinecraftDecoder extends MessageToMessageDecoder<ByteBuf> {
|
|||||||
|
|
||||||
public void setState(StateRegistry state) {
|
public void setState(StateRegistry state) {
|
||||||
this.state = state;
|
this.state = state;
|
||||||
this.setProtocolVersion(protocolVersion.id);
|
this.setProtocolVersion(protocolVersion.version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ public class MinecraftEncoder extends MessageToByteEncoder<MinecraftPacket> {
|
|||||||
protected void encode(ChannelHandlerContext ctx, MinecraftPacket msg, ByteBuf out) {
|
protected void encode(ChannelHandlerContext ctx, MinecraftPacket msg, ByteBuf out) {
|
||||||
int packetId = this.protocolVersion.getPacketId(msg);
|
int packetId = this.protocolVersion.getPacketId(msg);
|
||||||
ProtocolUtils.writeVarInt(out, packetId);
|
ProtocolUtils.writeVarInt(out, packetId);
|
||||||
msg.encode(out, direction, protocolVersion.id);
|
msg.encode(out, direction, protocolVersion.version);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setProtocolVersion(final int protocolVersion) {
|
public void setProtocolVersion(final int protocolVersion) {
|
||||||
@ -33,6 +33,6 @@ public class MinecraftEncoder extends MessageToByteEncoder<MinecraftPacket> {
|
|||||||
|
|
||||||
public void setState(StateRegistry state) {
|
public void setState(StateRegistry state) {
|
||||||
this.state = state;
|
this.state = state;
|
||||||
this.setProtocolVersion(protocolVersion.id);
|
this.setProtocolVersion(protocolVersion.version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,6 +123,8 @@ public class BossBar implements MinecraftPacket {
|
|||||||
case UPDATE_PROPERTIES:
|
case UPDATE_PROPERTIES:
|
||||||
this.flags = buf.readUnsignedByte();
|
this.flags = buf.readUnsignedByte();
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
throw new UnsupportedOperationException("Unknown action " + action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,6 +164,8 @@ public class BossBar implements MinecraftPacket {
|
|||||||
case UPDATE_PROPERTIES:
|
case UPDATE_PROPERTIES:
|
||||||
buf.writeByte(flags);
|
buf.writeByte(flags);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
throw new UnsupportedOperationException("Unknown action " + action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ import net.kyori.text.serializer.ComponentSerializers;
|
|||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
public class Chat implements MinecraftPacket {
|
public class Chat implements MinecraftPacket {
|
||||||
public static final byte CHAT = (byte) 0;
|
public static final byte CHAT_TYPE = (byte) 0;
|
||||||
public static final int MAX_SERVERBOUND_MESSAGE_LENGTH = 256;
|
public static final int MAX_SERVERBOUND_MESSAGE_LENGTH = 256;
|
||||||
|
|
||||||
private @Nullable String message;
|
private @Nullable String message;
|
||||||
@ -77,7 +77,7 @@ public class Chat implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Chat createClientbound(Component component) {
|
public static Chat createClientbound(Component component) {
|
||||||
return createClientbound(component, CHAT);
|
return createClientbound(component, CHAT_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Chat createClientbound(Component component, byte type) {
|
public static Chat createClientbound(Component component, byte type) {
|
||||||
@ -86,6 +86,6 @@ public class Chat implements MinecraftPacket {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Chat createServerbound(String message) {
|
public static Chat createServerbound(String message) {
|
||||||
return new Chat(message, CHAT);
|
return new Chat(message, CHAT_TYPE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,10 +54,7 @@ public class PlayerListItem implements MinecraftPacket {
|
|||||||
item.setProperties(ProtocolUtils.readProperties(buf));
|
item.setProperties(ProtocolUtils.readProperties(buf));
|
||||||
item.setGameMode(ProtocolUtils.readVarInt(buf));
|
item.setGameMode(ProtocolUtils.readVarInt(buf));
|
||||||
item.setLatency(ProtocolUtils.readVarInt(buf));
|
item.setLatency(ProtocolUtils.readVarInt(buf));
|
||||||
boolean hasDisplayName = buf.readBoolean();
|
item.setDisplayName(readOptionalComponent(buf));
|
||||||
if (hasDisplayName) {
|
|
||||||
item.setDisplayName(ComponentSerializers.JSON.deserialize(ProtocolUtils.readString(buf)));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case UPDATE_GAMEMODE:
|
case UPDATE_GAMEMODE:
|
||||||
@ -66,19 +63,26 @@ public class PlayerListItem implements MinecraftPacket {
|
|||||||
case UPDATE_LATENCY:
|
case UPDATE_LATENCY:
|
||||||
item.setLatency(ProtocolUtils.readVarInt(buf));
|
item.setLatency(ProtocolUtils.readVarInt(buf));
|
||||||
break;
|
break;
|
||||||
case UPDATE_DISPLAY_NAME: {
|
case UPDATE_DISPLAY_NAME:
|
||||||
boolean hasDisplayName = buf.readBoolean();
|
item.setDisplayName(readOptionalComponent(buf));
|
||||||
if (hasDisplayName) {
|
break;
|
||||||
item.setDisplayName(ComponentSerializers.JSON.deserialize(ProtocolUtils.readString(buf)));
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
case REMOVE_PLAYER:
|
case REMOVE_PLAYER:
|
||||||
//Do nothing, all that is needed is the uuid
|
//Do nothing, all that is needed is the uuid
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
throw new UnsupportedOperationException("Unknown action " + action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private static Component readOptionalComponent(ByteBuf buf) {
|
||||||
|
if (buf.readBoolean()) {
|
||||||
|
return ComponentSerializers.JSON.deserialize(ProtocolUtils.readString(buf));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void encode(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) {
|
public void encode(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) {
|
||||||
ProtocolUtils.writeVarInt(buf, action);
|
ProtocolUtils.writeVarInt(buf, action);
|
||||||
@ -106,6 +110,8 @@ public class PlayerListItem implements MinecraftPacket {
|
|||||||
case REMOVE_PLAYER:
|
case REMOVE_PLAYER:
|
||||||
//Do nothing, all that is needed is the uuid
|
//Do nothing, all that is needed is the uuid
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
throw new UnsupportedOperationException("Unknown action " + action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,12 +14,12 @@ public class StatusRequest implements MinecraftPacket {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void decode(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) {
|
public void decode(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) {
|
||||||
|
// There is no additional data to decode.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void encode(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) {
|
public void encode(ByteBuf buf, ProtocolConstants.Direction direction, int protocolVersion) {
|
||||||
|
// There is no data to decode.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -51,6 +51,8 @@ public class TitlePacket implements MinecraftPacket {
|
|||||||
case HIDE:
|
case HIDE:
|
||||||
case RESET:
|
case RESET:
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
throw new UnsupportedOperationException("Unknown action " + action);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch (action) {
|
switch (action) {
|
||||||
@ -69,6 +71,8 @@ public class TitlePacket implements MinecraftPacket {
|
|||||||
case HIDE_OLD:
|
case HIDE_OLD:
|
||||||
case RESET_OLD:
|
case RESET_OLD:
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
throw new UnsupportedOperationException("Unknown action " + action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import java.lang.reflect.Type;
|
|||||||
|
|
||||||
public class FaviconSerializer implements JsonSerializer<Favicon>, JsonDeserializer<Favicon> {
|
public class FaviconSerializer implements JsonSerializer<Favicon>, JsonDeserializer<Favicon> {
|
||||||
@Override
|
@Override
|
||||||
public Favicon deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
public Favicon deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) {
|
||||||
return new Favicon(json.getAsString());
|
return new Favicon(json.getAsString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,9 +2,6 @@ package com.velocitypowered.proxy.protocol.util;
|
|||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import com.velocitypowered.api.util.ModInfo;
|
|
||||||
import com.velocitypowered.proxy.connection.VelocityConstants;
|
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolConstants;
|
import com.velocitypowered.proxy.protocol.ProtocolConstants;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||||
import com.velocitypowered.proxy.protocol.packet.PluginMessage;
|
import com.velocitypowered.proxy.protocol.packet.PluginMessage;
|
||||||
@ -14,7 +11,6 @@ import io.netty.buffer.Unpooled;
|
|||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
public class PluginMessageUtil {
|
public class PluginMessageUtil {
|
||||||
public static final String BRAND_CHANNEL_LEGACY = "MC|Brand";
|
public static final String BRAND_CHANNEL_LEGACY = "MC|Brand";
|
||||||
|
@ -45,7 +45,7 @@ public class PingSessionHandler implements MinecraftSessionHandler {
|
|||||||
completed = true;
|
completed = true;
|
||||||
connection.close();
|
connection.close();
|
||||||
|
|
||||||
ServerPing ping = VelocityServer.GSON.fromJson(((StatusResponse) packet).getStatus(), ServerPing.class);
|
ServerPing ping = VelocityServer.GSON.fromJson(packet.getStatus(), ServerPing.class);
|
||||||
result.complete(ping);
|
result.complete(ping);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren