From d40ce9fc4a99eb0f1ed4a3c079d7e15003bff1d6 Mon Sep 17 00:00:00 2001 From: KennyTV Date: Wed, 21 Apr 2021 11:58:19 +0200 Subject: [PATCH] Minor optimizations in pipeline filling --- .../ViaVersion/api/data/UserConnection.java | 3 +- .../ViaVersion/api/protocol/Protocol.java | 9 +++ .../api/protocol/ProtocolManager.java | 19 ++++++ .../api/protocol/ProtocolPipeline.java | 59 +++++++++++++++---- .../bungee/handlers/BungeeServerHandler.java | 13 ++-- .../api/protocol/ProtocolManagerImpl.java | 10 +--- .../protocols/base/BaseProtocol.java | 26 +++++--- .../protocols/base/BaseProtocol1_7.java | 5 ++ 8 files changed, 111 insertions(+), 33 deletions(-) diff --git a/api/src/main/java/us/myles/ViaVersion/api/data/UserConnection.java b/api/src/main/java/us/myles/ViaVersion/api/data/UserConnection.java index 030cb898b..516abf9e6 100644 --- a/api/src/main/java/us/myles/ViaVersion/api/data/UserConnection.java +++ b/api/src/main/java/us/myles/ViaVersion/api/data/UserConnection.java @@ -456,7 +456,8 @@ public class UserConnection { } /** - * Returns whether this is a client-side connection (a mod integrated into the client itself). + * Returns whether this is a client-side connection. + * This is a mod integrated into the client itself, or for example a backend Velocity connection. * * @return whether this is a client-side connection */ diff --git a/api/src/main/java/us/myles/ViaVersion/api/protocol/Protocol.java b/api/src/main/java/us/myles/ViaVersion/api/protocol/Protocol.java index 31b9ec7c9..fcdede8d6 100644 --- a/api/src/main/java/us/myles/ViaVersion/api/protocol/Protocol.java +++ b/api/src/main/java/us/myles/ViaVersion/api/protocol/Protocol.java @@ -496,6 +496,15 @@ public abstract class Protocol protocolClass); + /** + * Returns the base protocol handling incoming handshake packets. + * + * @return base protocol + */ Protocol getBaseProtocol(); + /** + * Returns the base protocol for a specific server protocol version. + * The standard base protocols deal with status and login packets for userconnection initialization. + * + * @return base protocol for the given server protocol version + */ Protocol getBaseProtocol(int serverVersion); + /** + * Returns whether the given protocol is a base protocol. + * + * @param protocol protocol + * @return whether the protocol is a base protocol + * @see Protocol#isBaseProtocol() + */ boolean isBaseProtocol(Protocol protocol); /** @@ -76,6 +94,7 @@ public interface ProtocolManager { * * @param baseProtocol base protocol to register * @param supportedProtocols versions supported by the base protocol + * @throws IllegalArgumentException if the protocol is not a base protocol as given by {@link Protocol#isBaseProtocol()} */ void registerBaseProtocol(Protocol baseProtocol, Range supportedProtocols); diff --git a/api/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolPipeline.java b/api/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolPipeline.java index c3772ff87..a0a650348 100644 --- a/api/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolPipeline.java +++ b/api/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolPipeline.java @@ -22,6 +22,7 @@ */ package us.myles.ViaVersion.api.protocol; +import com.google.common.base.Preconditions; import us.myles.ViaVersion.api.PacketWrapper; import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.api.data.UserConnection; @@ -36,6 +37,9 @@ import java.util.concurrent.CopyOnWriteArrayList; import java.util.logging.Level; public class ProtocolPipeline extends SimpleProtocol { + /** + * Protocol list ordered from client to server transforation with the base protocols at the end. + */ private List protocolList; private UserConnection userConnection; @@ -66,26 +70,55 @@ public class ProtocolPipeline extends SimpleProtocol { } /** - * Add a protocol to the current pipeline + * Adds a protocol to the current pipeline. * This will call the {@link Protocol#init(UserConnection)} method. * - * @param protocol The protocol to add to the end + * @param protocol protocol to add to the end */ public void add(Protocol protocol) { - if (protocolList != null) { - protocolList.add(protocol); + Preconditions.checkNotNull(protocolList, "Tried to add protocol too early"); + + protocolList.add(protocol); + protocol.init(userConnection); + + if (!protocol.isBaseProtocol()) { + moveBaseProtocolsToTail(); + } + } + + /** + * Adds a list of protocols to the current pipeline. + * This will call the {@link Protocol#init(UserConnection)} method. + * + * @param protocols protocols to add to the end + */ + public void add(List protocols) { + Preconditions.checkNotNull(protocolList, "Tried to add protocol too early"); + + protocolList.addAll(protocols); + for (Protocol protocol : protocols) { protocol.init(userConnection); - // Move base Protocols to the end, so the login packets can be modified by other protocols - List toMove = new ArrayList<>(); - for (Protocol p : protocolList) { - if (Via.getManager().getProtocolManager().isBaseProtocol(p)) { - toMove.add(p); + } + + moveBaseProtocolsToTail(); + } + + private void moveBaseProtocolsToTail() { + // Move base Protocols to the end, so the login packets can be modified by other protocols + List baseProtocols = null; + for (Protocol protocol : protocolList) { + if (protocol.isBaseProtocol()) { + if (baseProtocols == null) { + baseProtocols = new ArrayList<>(); } + + baseProtocols.add(protocol); } - protocolList.removeAll(toMove); - protocolList.addAll(toMove); - } else { - throw new NullPointerException("Tried to add protocol too early"); + } + + if (baseProtocols != null) { + protocolList.removeAll(baseProtocols); + protocolList.addAll(baseProtocols); } } diff --git a/bungee/src/main/java/us/myles/ViaVersion/bungee/handlers/BungeeServerHandler.java b/bungee/src/main/java/us/myles/ViaVersion/bungee/handlers/BungeeServerHandler.java index 212ededf7..d93e9177b 100644 --- a/bungee/src/main/java/us/myles/ViaVersion/bungee/handlers/BungeeServerHandler.java +++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/handlers/BungeeServerHandler.java @@ -47,6 +47,7 @@ import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Objects; @@ -175,17 +176,19 @@ public class BungeeServerHandler implements Listener { int previousServerProtocol = info.getServerProtocolVersion(); // Refresh the pipes - List protocols = Via.getManager().getProtocolManager().getProtocolPath(info.getProtocolVersion(), protocolId); + List protocolPath = Via.getManager().getProtocolManager().getProtocolPath(info.getProtocolVersion(), protocolId); ProtocolPipeline pipeline = user.getProtocolInfo().getPipeline(); user.clearStoredObjects(); pipeline.cleanPipes(); - if (protocols == null) { + if (protocolPath == null) { // TODO Check Bungee Supported Protocols? *shrugs* protocolId = info.getProtocolVersion(); } else { - for (ProtocolPathEntry prot : protocols) { - pipeline.add(prot.getProtocol()); + List protocols = new ArrayList<>(protocolPath.size()); + for (ProtocolPathEntry entry : protocolPath) { + protocols.add(entry.getProtocol()); } + pipeline.add(protocols); } info.setServerProtocolVersion(protocolId); @@ -230,7 +233,7 @@ public class BungeeServerHandler implements Listener { user.put(info); user.put(storage); - user.setActive(protocols != null); + user.setActive(protocolPath != null); // Init all protocols TODO check if this can get moved up to the previous for loop, and doesn't require the pipeline to already exist. for (Protocol protocol : pipeline.pipes()) { diff --git a/common/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolManagerImpl.java b/common/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolManagerImpl.java index 92da8f748..5d73a28f3 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolManagerImpl.java +++ b/common/src/main/java/us/myles/ViaVersion/api/protocol/ProtocolManagerImpl.java @@ -80,7 +80,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.function.Function; public class ProtocolManagerImpl implements ProtocolManager { - public static final Protocol BASE_PROTOCOL = new BaseProtocol(); + private static final Protocol BASE_PROTOCOL = new BaseProtocol(); // Input Version -> Output Version & Protocol (Allows fast lookup) private final Int2ObjectMap> registryMap = new Int2ObjectOpenHashMap<>(32); @@ -187,6 +187,7 @@ public class ProtocolManagerImpl implements ProtocolManager { @Override public void registerBaseProtocol(Protocol baseProtocol, Range supportedProtocols) { + Preconditions.checkArgument(baseProtocol.isBaseProtocol(), "Protocol is not a base protocol"); baseProtocols.add(new Pair<>(supportedProtocols, baseProtocol)); if (Via.getPlatform().isPluginEnabled()) { baseProtocol.register(Via.getManager().getProviders()); @@ -297,12 +298,7 @@ public class ProtocolManagerImpl implements ProtocolManager { @Override public boolean isBaseProtocol(Protocol protocol) { - for (Pair, Protocol> p : baseProtocols) { - if (p.getValue() == protocol) { - return true; - } - } - return false; + return protocol.isBaseProtocol(); } @Override diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/base/BaseProtocol.java b/common/src/main/java/us/myles/ViaVersion/protocols/base/BaseProtocol.java index d5f588375..13b479d1d 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/base/BaseProtocol.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/base/BaseProtocol.java @@ -21,6 +21,7 @@ import us.myles.ViaVersion.api.PacketWrapper; import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.api.data.UserConnection; import us.myles.ViaVersion.api.platform.providers.ViaProviders; +import us.myles.ViaVersion.api.protocol.Protocol; import us.myles.ViaVersion.api.protocol.ProtocolPathEntry; import us.myles.ViaVersion.api.protocol.ProtocolPipeline; import us.myles.ViaVersion.api.protocol.ProtocolVersion; @@ -30,6 +31,7 @@ import us.myles.ViaVersion.api.type.Type; import us.myles.ViaVersion.packets.Direction; import us.myles.ViaVersion.packets.State; +import java.util.ArrayList; import java.util.List; public class BaseProtocol extends SimpleProtocol { @@ -59,21 +61,26 @@ public class BaseProtocol extends SimpleProtocol { // Choose the pipe int serverProtocol = Via.getManager().getProviders().get(VersionProvider.class).getClosestServerProtocol(wrapper.user()); info.setServerProtocolVersion(serverProtocol); - List protocols = null; + List protocolPath = null; - // Only allow newer clients or (1.9.2 on 1.9.4 server if the server supports it) + // Only allow newer clients (or 1.9.2 on 1.9.4 server if the server supports it) if (info.getProtocolVersion() >= serverProtocol || Via.getPlatform().isOldClientsAllowed()) { - protocols = Via.getManager().getProtocolManager().getProtocolPath(info.getProtocolVersion(), serverProtocol); + protocolPath = Via.getManager().getProtocolManager().getProtocolPath(info.getProtocolVersion(), serverProtocol); } ProtocolPipeline pipeline = wrapper.user().getProtocolInfo().getPipeline(); - if (protocols != null) { - for (ProtocolPathEntry prot : protocols) { - pipeline.add(prot.getProtocol()); + if (protocolPath != null) { + List protocols = new ArrayList<>(protocolPath.size()); + for (ProtocolPathEntry entry : protocolPath) { + protocols.add(entry.getProtocol()); + // Ensure mapping data has already been loaded - Via.getManager().getProtocolManager().completeMappingDataLoading(prot.getProtocol().getClass()); + Via.getManager().getProtocolManager().completeMappingDataLoading(entry.getProtocol().getClass()); } + // Add protocols to pipeline + pipeline.add(protocols); + // Set the original snapshot version if present ProtocolVersion protocol = ProtocolVersion.getProtocol(serverProtocol); wrapper.set(Type.VAR_INT, 0, protocol.getOriginalVersion()); @@ -94,6 +101,11 @@ public class BaseProtocol extends SimpleProtocol { }); } + @Override + public boolean isBaseProtocol() { + return true; + } + @Override public void init(UserConnection userConnection) { // Nothing gets added, ProtocolPipeline handles ProtocolInfo diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/base/BaseProtocol1_7.java b/common/src/main/java/us/myles/ViaVersion/protocols/base/BaseProtocol1_7.java index f832500ea..daef4ffdc 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/base/BaseProtocol1_7.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/base/BaseProtocol1_7.java @@ -199,6 +199,11 @@ public class BaseProtocol1_7 extends SimpleProtocol { registerIncoming(State.LOGIN, 0x02, 0x02); // Plugin Response (1.13) } + @Override + public boolean isBaseProtocol() { + return true; + } + public static String addDashes(String trimmedUUID) { StringBuilder idBuff = new StringBuilder(trimmedUUID); idBuff.insert(20, '-');