3
0
Mirror von https://github.com/PaperMC/Velocity.git synchronisiert 2024-11-17 05:20:14 +01:00

Merge branch 'dev/1.1.0' into experiment/io_uring

Dieser Commit ist enthalten in:
Andrew Steinborn 2021-01-17 00:43:46 -05:00
Commit 7f4b0ed9bf
12 geänderte Dateien mit 78 neuen und 59 gelöschten Zeilen

Datei anzeigen

@ -16,7 +16,7 @@ allprojects {
apply plugin: "com.github.spotbugs" apply plugin: "com.github.spotbugs"
group 'com.velocitypowered' group 'com.velocitypowered'
version '1.1.3-SNAPSHOT' version '1.1.4-SNAPSHOT'
ext { ext {
// dependency versions // dependency versions
@ -26,7 +26,7 @@ allprojects {
junitVersion = '5.7.0' junitVersion = '5.7.0'
slf4jVersion = '1.7.30' slf4jVersion = '1.7.30'
log4jVersion = '2.13.3' log4jVersion = '2.13.3'
nettyVersion = '4.1.56.Final' nettyVersion = '4.1.58.Final'
guavaVersion = '25.1-jre' guavaVersion = '25.1-jre'
checkerFrameworkVersion = '3.6.1' checkerFrameworkVersion = '3.6.1'
configurateVersion = '3.7.1' configurateVersion = '3.7.1'

Datei anzeigen

@ -209,7 +209,7 @@ public class VelocityCommand implements SimpleCommand {
.append(Component.text(version.getVersion()).decoration(TextDecoration.BOLD, false)) .append(Component.text(version.getVersion()).decoration(TextDecoration.BOLD, false))
.build(); .build();
TextComponent copyright = Component TextComponent copyright = Component
.text("Copyright 2018-2020 " + version.getVendor() + ". " + version.getName() .text("Copyright 2018-2021 " + version.getVendor() + ". " + version.getName()
+ " is freely licensed under the terms of the MIT License."); + " is freely licensed under the terms of the MIT License.");
source.sendMessage(Identity.nil(), velocity); source.sendMessage(Identity.nil(), velocity);
source.sendMessage(Identity.nil(), copyright); source.sendMessage(Identity.nil(), copyright);

Datei anzeigen

@ -646,7 +646,11 @@ public class VelocityConfiguration implements ProxyConfig {
this.loginRatelimit = config.getIntOrElse("login-ratelimit", 3000); this.loginRatelimit = config.getIntOrElse("login-ratelimit", 3000);
this.connectionTimeout = config.getIntOrElse("connection-timeout", 5000); this.connectionTimeout = config.getIntOrElse("connection-timeout", 5000);
this.readTimeout = config.getIntOrElse("read-timeout", 30000); this.readTimeout = config.getIntOrElse("read-timeout", 30000);
this.proxyProtocol = config.getOrElse("proxy-protocol", false); if (config.contains("haproxy-protocol")) {
this.proxyProtocol = config.getOrElse("haproxy-protocol", false);
} else {
this.proxyProtocol = config.getOrElse("proxy-protocol", false);
}
this.tcpFastOpen = config.getOrElse("tcp-fast-open", false); this.tcpFastOpen = config.getOrElse("tcp-fast-open", false);
this.bungeePluginMessageChannel = config.getOrElse("bungee-plugin-message-channel", true); this.bungeePluginMessageChannel = config.getOrElse("bungee-plugin-message-channel", true);
this.showPingRequests = config.getOrElse("show-ping-requests", false); this.showPingRequests = config.getOrElse("show-ping-requests", false);

Datei anzeigen

@ -195,6 +195,8 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
public void write(Object msg) { public void write(Object msg) {
if (channel.isActive()) { if (channel.isActive()) {
channel.writeAndFlush(msg, channel.voidPromise()); channel.writeAndFlush(msg, channel.voidPromise());
} else {
ReferenceCountUtil.release(msg);
} }
} }
@ -205,6 +207,8 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
public void delayedWrite(Object msg) { public void delayedWrite(Object msg) {
if (channel.isActive()) { if (channel.isActive()) {
channel.write(msg, channel.voidPromise()); channel.write(msg, channel.voidPromise());
} else {
ReferenceCountUtil.release(msg);
} }
} }

Datei anzeigen

@ -28,6 +28,7 @@ import com.velocitypowered.proxy.protocol.util.PluginMessageUtil;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil; import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.handler.timeout.ReadTimeoutException; import io.netty.handler.timeout.ReadTimeoutException;
import java.util.Collection; import java.util.Collection;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
@ -36,6 +37,8 @@ import org.apache.logging.log4j.Logger;
public class BackendPlaySessionHandler implements MinecraftSessionHandler { public class BackendPlaySessionHandler implements MinecraftSessionHandler {
private static final Logger logger = LogManager.getLogger(BackendPlaySessionHandler.class); private static final Logger logger = LogManager.getLogger(BackendPlaySessionHandler.class);
private static final boolean BACKPRESSURE_LOG = Boolean
.getBoolean("velocity.log-server-backpressure");
private final VelocityServer server; private final VelocityServer server;
private final VelocityServerConnection serverConn; private final VelocityServerConnection serverConn;
private final ClientPlaySessionHandler playerSessionHandler; private final ClientPlaySessionHandler playerSessionHandler;
@ -284,4 +287,20 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
} }
} }
} }
@Override
public void writabilityChanged() {
Channel serverChan = serverConn.ensureConnected().getChannel();
boolean writable = serverChan.isWritable();
if (BACKPRESSURE_LOG) {
if (writable) {
logger.info("{} is not writable, not auto-reading player connection data", this.serverConn);
} else {
logger.info("{} is writable, will auto-read player connection data", this.serverConn);
}
}
playerConnection.setAutoReading(writable);
}
} }

Datei anzeigen

@ -236,75 +236,52 @@ public class BungeeCordMessageResponder {
}); });
} }
private ByteBuf prepareForwardMessage(ByteBufDataInput in) {
String channel = in.readUTF();
short messageLength = in.readShort();
ByteBuf buf = Unpooled.buffer();
ByteBufDataOutput forwarded = new ByteBufDataOutput(buf);
forwarded.writeUTF(channel);
forwarded.writeShort(messageLength);
buf.writeBytes(in.unwrap().readSlice(messageLength));
return buf;
}
private void processForwardToPlayer(ByteBufDataInput in) { private void processForwardToPlayer(ByteBufDataInput in) {
proxy.getPlayer(in.readUTF()) Optional<Player> player = proxy.getPlayer(in.readUTF());
.flatMap(Player::getCurrentServer) if (player.isPresent()) {
.ifPresent(server -> sendServerResponse(player, prepareForwardMessage(in))); ByteBuf toForward = in.unwrap().copy();
sendServerResponse((ConnectedPlayer) player.get(), toForward);
}
} }
private void processForwardToServer(ByteBufDataInput in) { private void processForwardToServer(ByteBufDataInput in) {
String target = in.readUTF(); String target = in.readUTF();
ByteBuf toForward = prepareForwardMessage(in); ByteBuf toForward = in.unwrap().copy();
if (target.equals("ALL")) { if (target.equals("ALL")) {
ByteBuf unreleasableForward = Unpooled.unreleasableBuffer(toForward);
try { try {
for (RegisteredServer rs : proxy.getAllServers()) { for (RegisteredServer rs : proxy.getAllServers()) {
((VelocityRegisteredServer) rs).sendPluginMessage(LEGACY_CHANNEL, unreleasableForward); ((VelocityRegisteredServer) rs).sendPluginMessage(LEGACY_CHANNEL,
toForward.retainedSlice());
} }
} finally { } finally {
toForward.release(); toForward.release();
} }
} else { } else {
proxy.getServer(target).ifPresent(rs -> ((VelocityRegisteredServer) rs) Optional<RegisteredServer> server = proxy.getServer(target);
.sendPluginMessage(LEGACY_CHANNEL, toForward)); if (server.isPresent()) {
((VelocityRegisteredServer) server.get()).sendPluginMessage(LEGACY_CHANNEL, toForward);
} else {
toForward.release();
}
} }
} }
// Note: this method will always release the buffer!
private void sendResponseOnConnection(ByteBuf buf) {
sendServerResponse(this.player, buf);
}
static String getBungeeCordChannel(ProtocolVersion version) { static String getBungeeCordChannel(ProtocolVersion version) {
return version.compareTo(ProtocolVersion.MINECRAFT_1_13) >= 0 ? MODERN_CHANNEL.getId() return version.compareTo(ProtocolVersion.MINECRAFT_1_13) >= 0 ? MODERN_CHANNEL.getId()
: LEGACY_CHANNEL.getId(); : LEGACY_CHANNEL.getId();
} }
// Note: this method will always release the buffer!
private void sendResponseOnConnection(ByteBuf buf) {
sendServerResponse(this.player, buf);
}
// Note: this method will always release the buffer! // Note: this method will always release the buffer!
private static void sendServerResponse(ConnectedPlayer player, ByteBuf buf) { private static void sendServerResponse(ConnectedPlayer player, ByteBuf buf) {
MinecraftConnection serverConnection = player.ensureAndGetCurrentServer().ensureConnected(); MinecraftConnection serverConnection = player.ensureAndGetCurrentServer().ensureConnected();
String chan = getBungeeCordChannel(serverConnection.getProtocolVersion()); String chan = getBungeeCordChannel(serverConnection.getProtocolVersion());
PluginMessage msg = new PluginMessage(chan, buf);
PluginMessage msg = null; serverConnection.write(msg);
boolean released = false;
try {
VelocityServerConnection vsc = player.getConnectedServer();
if (vsc == null) {
return;
}
MinecraftConnection serverConn = vsc.ensureConnected();
msg = new PluginMessage(chan, buf);
serverConn.write(msg);
released = true;
} finally {
if (!released && msg != null) {
msg.release();
}
}
} }
boolean process(PluginMessage message) { boolean process(PluginMessage message) {

Datei anzeigen

@ -300,7 +300,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
boolean writable = player.getConnection().getChannel().isWritable(); boolean writable = player.getConnection().getChannel().isWritable();
if (!writable) { if (!writable) {
// We might have packets queued for the server, so flush them now to free up memory. // We might have packets queued from the server, so flush them now to free up memory.
player.getConnection().flush(); player.getConnection().flush();
} }

Datei anzeigen

@ -20,7 +20,7 @@ public class MinecraftCompressEncoder extends MessageToByteEncoder<ByteBuf> {
@Override @Override
protected void encode(ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) throws Exception { protected void encode(ChannelHandlerContext ctx, ByteBuf msg, ByteBuf out) throws Exception {
int uncompressed = msg.readableBytes(); int uncompressed = msg.readableBytes();
if (uncompressed <= threshold) { if (uncompressed < threshold) {
// Under the threshold, there is nothing to do. // Under the threshold, there is nothing to do.
ProtocolUtils.writeVarInt(out, 0); ProtocolUtils.writeVarInt(out, 0);
out.writeBytes(msg); out.writeBytes(msg);

Datei anzeigen

@ -5,7 +5,7 @@ import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.proxy.protocol.MinecraftPacket; import com.velocitypowered.proxy.protocol.MinecraftPacket;
import com.velocitypowered.proxy.protocol.ProtocolUtils; import com.velocitypowered.proxy.protocol.ProtocolUtils;
import com.velocitypowered.proxy.protocol.StateRegistry; import com.velocitypowered.proxy.protocol.StateRegistry;
import com.velocitypowered.proxy.util.except.QuietDecoderException; import com.velocitypowered.proxy.util.except.QuietRuntimeException;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.ChannelInboundHandlerAdapter;
@ -14,8 +14,8 @@ import io.netty.handler.codec.CorruptedFrameException;
public class MinecraftDecoder extends ChannelInboundHandlerAdapter { public class MinecraftDecoder extends ChannelInboundHandlerAdapter {
public static final boolean DEBUG = Boolean.getBoolean("velocity.packet-decode-logging"); public static final boolean DEBUG = Boolean.getBoolean("velocity.packet-decode-logging");
private static final QuietDecoderException DECODE_FAILED = private static final QuietRuntimeException DECODE_FAILED =
new QuietDecoderException("A packet did not decode successfully (invalid data). If you are a " new QuietRuntimeException("A packet did not decode successfully (invalid data). If you are a "
+ "developer, launch Velocity with -Dvelocity.packet-decode-logging=true to see more."); + "developer, launch Velocity with -Dvelocity.packet-decode-logging=true to see more.");
private final ProtocolUtils.Direction direction; private final ProtocolUtils.Direction direction;

Datei anzeigen

@ -7,6 +7,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps; import com.google.common.collect.Multimaps;
import com.google.common.util.concurrent.ThreadFactoryBuilder; import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.velocitypowered.api.plugin.PluginContainer;
import com.velocitypowered.api.plugin.PluginManager; import com.velocitypowered.api.plugin.PluginManager;
import com.velocitypowered.api.scheduler.ScheduledTask; import com.velocitypowered.api.scheduler.ScheduledTask;
import com.velocitypowered.api.scheduler.Scheduler; import com.velocitypowered.api.scheduler.Scheduler;
@ -183,8 +184,18 @@ public class VelocityScheduler implements Scheduler {
currentTaskThread = Thread.currentThread(); currentTaskThread = Thread.currentThread();
try { try {
runnable.run(); runnable.run();
} catch (Exception e) { } catch (Throwable e) {
Log.logger.error("Exception in task {} by plugin {}", runnable, plugin, e); //noinspection ConstantConditions
if (e instanceof InterruptedException) {
Thread.currentThread().interrupt();
} else {
String friendlyPluginName = pluginManager.fromInstance(plugin)
.map(container -> container.getDescription().getName()
.orElse(container.getDescription().getId()))
.orElse("UNKNOWN");
Log.logger.error("Exception in task {} by plugin {}", runnable, friendlyPluginName,
e);
}
} finally { } finally {
if (repeat == 0) { if (repeat == 0) {
onFinish(); onFinish();

Datei anzeigen

@ -125,7 +125,9 @@ public class VelocityRegisteredServer implements RegisteredServer, ForwardingAud
} }
/** /**
* Sends a plugin message to the server through this connection. * Sends a plugin message to the server through this connection. The message will be released
* afterwards.
*
* @param identifier the channel ID to use * @param identifier the channel ID to use
* @param data the data * @param data the data
* @return whether or not the message was sent * @return whether or not the message was sent
@ -133,11 +135,12 @@ public class VelocityRegisteredServer implements RegisteredServer, ForwardingAud
public boolean sendPluginMessage(ChannelIdentifier identifier, ByteBuf data) { public boolean sendPluginMessage(ChannelIdentifier identifier, ByteBuf data) {
for (ConnectedPlayer player : players.values()) { for (ConnectedPlayer player : players.values()) {
VelocityServerConnection connection = player.getConnectedServer(); VelocityServerConnection connection = player.getConnectedServer();
if (connection != null && connection.getServerInfo().equals(serverInfo)) { if (connection != null && connection.getServer() == this) {
return connection.sendPluginMessage(identifier, data); return connection.sendPluginMessage(identifier, data);
} }
} }
data.release();
return false; return false;
} }

Datei anzeigen

@ -105,8 +105,9 @@ connection-timeout = 5000
# Specify a read timeout for connections here. The default is 30 seconds. # Specify a read timeout for connections here. The default is 30 seconds.
read-timeout = 30000 read-timeout = 30000
# Enables compatibility with HAProxy. # Enables compatibility with HAProxy's PROXY protocol. If you don't know what this is for, then
proxy-protocol = false # don't enable it.
haproxy-protocol = false
# Enables TCP fast open support on the proxy. Requires the proxy to run on Linux. # Enables TCP fast open support on the proxy. Requires the proxy to run on Linux.
tcp-fast-open = false tcp-fast-open = false