diff --git a/api/build.gradle.kts b/api/build.gradle.kts index 8a1a3cd88..13551a9cd 100644 --- a/api/build.gradle.kts +++ b/api/build.gradle.kts @@ -16,8 +16,6 @@ sourceSets { dependencies { api(libs.fastutil) - api(libs.flare) - api(libs.flareFastutil) api(libs.vianbt) api(libs.gson) implementation(rootProject.libs.text) { diff --git a/api/src/main/java/com/viaversion/viaversion/api/ViaAPI.java b/api/src/main/java/com/viaversion/viaversion/api/ViaAPI.java index 5b7c2b89c..c69d01d20 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/ViaAPI.java +++ b/api/src/main/java/com/viaversion/viaversion/api/ViaAPI.java @@ -66,7 +66,7 @@ public interface ViaAPI { * @return API version incremented with meaningful API changes */ default int apiVersion() { - return 24; + return 25; } /** diff --git a/api/src/main/java/com/viaversion/viaversion/api/protocol/ProtocolPipeline.java b/api/src/main/java/com/viaversion/viaversion/api/protocol/ProtocolPipeline.java index 3876a65a0..926a6ca97 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/protocol/ProtocolPipeline.java +++ b/api/src/main/java/com/viaversion/viaversion/api/protocol/ProtocolPipeline.java @@ -23,6 +23,7 @@ package com.viaversion.viaversion.api.protocol; import com.viaversion.viaversion.api.connection.UserConnection; +import com.viaversion.viaversion.api.protocol.packet.Direction; import java.util.Collection; import java.util.List; import org.checkerframework.checker.nullness.qual.Nullable; @@ -61,25 +62,34 @@ public interface ProtocolPipeline extends SimpleProtocol { * @param pipeClass protocol class * @param

protocol * @return protocol from class - * @see #contains(Class) - * @see ProtocolManager#getProtocol(Class) for a faster implementation + * @deprecated use {@link ProtocolManager#getProtocol(Class)} and/or {@link #contains(Class)} */ + @Deprecated @Nullable

P getProtocol(Class

pipeClass); + List pipes(@Nullable Class protocolClass, boolean skipCurrentPipeline, Direction direction); + /** - * Returns the list of protocols this pipeline contains. + * Returns the list of protocols this pipeline contains, lead by base protocols. * * @return immutable list of protocols in this pipe */ List pipes(); /** - * Returns the list of protocols this pipeline contains in reversed order. + * Returns the list of protocols this pipeline contains in reversed order, although still lead by base protocols. * * @return immutable list of protocols in reversed direction */ List reversedPipes(); + /** + * Returns the number of base protocols in this pipeline. + * + * @return the number of base protocols in this pipeline + */ + int baseProtocolCount(); + /** * Returns whether this pipe has protocols that are not base protocols, as given by {@link Protocol#isBaseProtocol()}. * diff --git a/api/src/main/java/com/viaversion/viaversion/api/protocol/packet/PacketWrapper.java b/api/src/main/java/com/viaversion/viaversion/api/protocol/packet/PacketWrapper.java index e10b131e5..23f02713a 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/protocol/packet/PacketWrapper.java +++ b/api/src/main/java/com/viaversion/viaversion/api/protocol/packet/PacketWrapper.java @@ -92,6 +92,7 @@ public interface PacketWrapper { * @param index The index of the part (relative to the type) * @return True if the type is at the index */ + @Deprecated boolean is(Type type, int index); /** @@ -212,11 +213,11 @@ public interface PacketWrapper { * (Sends it after current) * Also returns the packets ChannelFuture * - * @param packetProtocol The protocol version of the packet. - * @return The packets ChannelFuture + * @param protocolClass the protocol class to start from in the pipeline + * @return new ChannelFuture for the write operation * @throws Exception if it fails to write */ - ChannelFuture sendFuture(Class packetProtocol) throws Exception; + ChannelFuture sendFuture(Class protocolClass) throws Exception; /** * @deprecated misleading; use {@link #sendRaw()}. This method will be removed in 5.0.0 @@ -287,18 +288,24 @@ public interface PacketWrapper { * * @param direction protocol direction * @param state protocol state - * @param index index to start from, will be reversed depending on the reverse parameter * @param pipeline protocol pipeline - * @param reverse whether the array should be looped in reverse, will also reverse the given index - * @return The current packetwrapper * @throws Exception If it fails to transform a packet, exception will be thrown */ + void apply(Direction direction, State state, List pipeline) throws Exception; + + /** + * @deprecated use {@link #apply(Direction, State, List)} + */ + @Deprecated PacketWrapper apply(Direction direction, State state, int index, List pipeline, boolean reverse) throws Exception; /** - * @see #apply(Direction, State, int, List, boolean) + * @deprecated use {@link #apply(Direction, State, List)} */ - PacketWrapper apply(Direction direction, State state, int index, List pipeline) throws Exception; + @Deprecated + default PacketWrapper apply(Direction direction, State state, int index, List pipeline) throws Exception { + return apply(direction, state, index, pipeline, false); + } /** * Check if this packet is cancelled. diff --git a/build-logic/src/main/kotlin/via.shadow-conventions.gradle.kts b/build-logic/src/main/kotlin/via.shadow-conventions.gradle.kts index 15ee2df92..eb9926d0b 100644 --- a/build-logic/src/main/kotlin/via.shadow-conventions.gradle.kts +++ b/build-logic/src/main/kotlin/via.shadow-conventions.gradle.kts @@ -25,7 +25,6 @@ fun ShadowJar.configureRelocations() { relocate("com.google.gson", "com.viaversion.viaversion.libs.gson") relocate("com.github.steveice10.opennbt", "com.viaversion.viaversion.libs.opennbt") relocate("it.unimi.dsi.fastutil", "com.viaversion.viaversion.libs.fastutil") - relocate("space.vectrix.flare", "com.viaversion.viaversion.libs.flare") relocate("net.lenni0451.mcstructs", "com.viaversion.viaversion.libs.mcstructs") } @@ -49,9 +48,4 @@ fun ShadowJar.configureExcludes() { exclude("it/unimi/dsi/fastutil/*/*Big*") exclude("it/unimi/dsi/fastutil/*/*Synchronized*") exclude("it/unimi/dsi/fastutil/*/*Unmodifiable*") - // Flare - only need int maps - exclude("space/vectrix/flare/fastutil/*Double*") - exclude("space/vectrix/flare/fastutil/*Float*") - exclude("space/vectrix/flare/fastutil/*Long*") - exclude("space/vectrix/flare/fastutil/*Short*") } diff --git a/bungee/src/main/java/com/viaversion/viaversion/bungee/handlers/BungeeServerHandler.java b/bungee/src/main/java/com/viaversion/viaversion/bungee/handlers/BungeeServerHandler.java index 25b039ae2..4ebe2350d 100644 --- a/bungee/src/main/java/com/viaversion/viaversion/bungee/handlers/BungeeServerHandler.java +++ b/bungee/src/main/java/com/viaversion/viaversion/bungee/handlers/BungeeServerHandler.java @@ -44,6 +44,7 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.UUID; +import java.util.stream.Collectors; import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.api.connection.Server; import net.md_5.bungee.api.event.ServerConnectEvent; @@ -194,18 +195,15 @@ public class BungeeServerHandler implements Listener { ProtocolPipeline pipeline = user.getProtocolInfo().getPipeline(); user.clearStoredObjects(true); pipeline.cleanPipes(); - if (protocolPath == null) { + if (protocolPath != null) { + info.setServerProtocolVersion(serverProtocolVersion); + pipeline.add(protocolPath.stream().map(ProtocolPathEntry::protocol).collect(Collectors.toList())); + } else { // TODO Check Bungee Supported Protocols? *shrugs* serverProtocolVersion = info.protocolVersion(); - } else { - List protocols = new ArrayList<>(protocolPath.size()); - for (ProtocolPathEntry entry : protocolPath) { - protocols.add(entry.protocol()); - } - pipeline.add(protocols); + info.setServerProtocolVersion(serverProtocolVersion); } - info.setServerProtocolVersion(serverProtocolVersion); // Add version-specific base Protocol pipeline.add(Via.getManager().getProtocolManager().getBaseProtocol(serverProtocolVersion)); @@ -254,11 +252,6 @@ public class BungeeServerHandler implements Listener { 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()) { - protocol.init(user); - } - ProxiedPlayer player = storage.getPlayer(); EntityTracker1_9 newTracker = user.getEntityTracker(Protocol1_9To1_8.class); if (newTracker != null && Via.getConfig().isAutoTeam()) { diff --git a/common/src/main/java/com/viaversion/viaversion/data/entity/EntityTrackerBase.java b/common/src/main/java/com/viaversion/viaversion/data/entity/EntityTrackerBase.java index 3d7548e8c..bcaaf0a94 100644 --- a/common/src/main/java/com/viaversion/viaversion/data/entity/EntityTrackerBase.java +++ b/common/src/main/java/com/viaversion/viaversion/data/entity/EntityTrackerBase.java @@ -28,13 +28,13 @@ import com.viaversion.viaversion.api.data.entity.TrackedEntity; import com.viaversion.viaversion.api.minecraft.entities.EntityType; import com.viaversion.viaversion.util.Key; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import java.util.Collections; import java.util.Map; import org.checkerframework.checker.nullness.qual.Nullable; -import space.vectrix.flare.fastutil.Int2ObjectSyncMap; public class EntityTrackerBase implements EntityTracker, ClientEntityIdChangeListener { - private final Int2ObjectMap entities = Int2ObjectSyncMap.hashmap(); + private final Int2ObjectMap entities = new Int2ObjectOpenHashMap<>(); private final UserConnection connection; private final EntityType playerType; private int clientEntityId = -1; diff --git a/common/src/main/java/com/viaversion/viaversion/protocol/ProtocolPipelineImpl.java b/common/src/main/java/com/viaversion/viaversion/protocol/ProtocolPipelineImpl.java index 9b014d2a7..97bce8082 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocol/ProtocolPipelineImpl.java +++ b/common/src/main/java/com/viaversion/viaversion/protocol/ProtocolPipelineImpl.java @@ -18,6 +18,7 @@ package com.viaversion.viaversion.protocol; import com.viaversion.viaversion.api.Via; +import com.viaversion.viaversion.api.connection.ProtocolInfo; import com.viaversion.viaversion.api.connection.UserConnection; import com.viaversion.viaversion.api.debug.DebugHandler; import com.viaversion.viaversion.api.protocol.AbstractSimpleProtocol; @@ -31,19 +32,16 @@ import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; +import java.util.NoSuchElementException; import java.util.Set; -import java.util.concurrent.CopyOnWriteArrayList; import java.util.logging.Level; import org.checkerframework.checker.nullness.qual.Nullable; public class ProtocolPipelineImpl extends AbstractSimpleProtocol implements ProtocolPipeline { - private final UserConnection userConnection; - /** - * Protocol list ordered from client to server transformation with the base protocols at the end. - */ - private final List protocolList = new CopyOnWriteArrayList<>(); + private final List protocolList = new ArrayList<>(); private final Set> protocolSet = new HashSet<>(); - private List reversedProtocolList = new CopyOnWriteArrayList<>(); + private final UserConnection userConnection; + private List reversedProtocolList = new ArrayList<>(); private int baseProtocols; public ProtocolPipelineImpl(UserConnection userConnection) { @@ -53,13 +51,9 @@ public class ProtocolPipelineImpl extends AbstractSimpleProtocol implements Prot } @Override - protected synchronized void registerPackets() { + protected void registerPackets() { // This is a pipeline so we register basic pipes - final Protocol baseProtocol = Via.getManager().getProtocolManager().getBaseProtocol(); - protocolList.add(baseProtocol); - reversedProtocolList.add(baseProtocol); - protocolSet.add(baseProtocol.getClass()); - baseProtocols++; + this.add(Via.getManager().getProtocolManager().getBaseProtocol()); } @Override @@ -68,15 +62,14 @@ public class ProtocolPipelineImpl extends AbstractSimpleProtocol implements Prot } @Override - public synchronized void add(final Protocol protocol) { + public void add(final Protocol protocol) { + reversedProtocolList.add(baseProtocols, protocol); if (protocol.isBaseProtocol()) { // Add base protocol on top of previous ones protocolList.add(baseProtocols, protocol); - reversedProtocolList.add(baseProtocols, protocol); baseProtocols++; } else { protocolList.add(protocol); - reversedProtocolList.add(0, protocol); } protocolSet.add(protocol.getClass()); @@ -84,22 +77,32 @@ public class ProtocolPipelineImpl extends AbstractSimpleProtocol implements Prot } @Override - public synchronized void add(final Collection protocols) { - protocolList.addAll(protocols); + public void add(final Collection protocols) { for (final Protocol protocol : protocols) { + if (protocol.isBaseProtocol()) { + throw new UnsupportedOperationException("Base protocols cannot be added in bulk"); + } + protocol.init(userConnection); protocolSet.add(protocol.getClass()); } + protocolList.addAll(protocols); refreshReversedList(); } - private synchronized void refreshReversedList() { - final List protocols = new ArrayList<>(protocolList.subList(0, this.baseProtocols)); - final List additionalProtocols = new ArrayList<>(protocolList.subList(this.baseProtocols, protocolList.size())); - Collections.reverse(additionalProtocols); - protocols.addAll(additionalProtocols); - reversedProtocolList = new CopyOnWriteArrayList<>(protocols); + private void refreshReversedList() { + final List reversedProtocols = new ArrayList<>(protocolList.size()); + // Add base protocols in regular order first + for (int i = 0; i < baseProtocols; i++) { + reversedProtocols.add(protocolList.get(i)); + } + + // Add non-base protocols in reverse order + for (int i = protocolList.size() - 1; i >= baseProtocols; i--) { + reversedProtocols.add(protocolList.get(i)); + } + reversedProtocolList = reversedProtocols; } @Override @@ -113,7 +116,7 @@ public class ProtocolPipelineImpl extends AbstractSimpleProtocol implements Prot } // Apply protocols - packetWrapper.apply(direction, state, 0, protocolListFor(direction)); + packetWrapper.apply(direction, state, protocolListFor(direction)); super.transform(direction, state, packetWrapper); if (debug && debugHandler.logPostPacketTransform() && debugHandler.shouldLog(packetWrapper, direction)) { @@ -126,20 +129,21 @@ public class ProtocolPipelineImpl extends AbstractSimpleProtocol implements Prot } private void logPacket(Direction direction, State state, PacketWrapper packetWrapper, int originalID) { - String actualUsername = packetWrapper.user().getProtocolInfo().getUsername(); + ProtocolInfo protocolInfo = userConnection.getProtocolInfo(); + String actualUsername = protocolInfo.getUsername(); String username = actualUsername != null ? actualUsername + " " : ""; Via.getPlatform().getLogger().log(Level.INFO, "{0}{1} {2}: {3} ({4}) -> {5} ({6}) [{7}] {8}", - new Object[]{ - username, - direction, - state, - originalID, - AbstractSimpleProtocol.toNiceHex(originalID), - packetWrapper.getId(), - AbstractSimpleProtocol.toNiceHex(packetWrapper.getId()), - userConnection.getProtocolInfo().protocolVersion().getName(), - packetWrapper - }); + new Object[]{ + username, + direction, + state, + originalID, + AbstractSimpleProtocol.toNiceHex(originalID), + packetWrapper.getId(), + AbstractSimpleProtocol.toNiceHex(packetWrapper.getId()), + protocolInfo.protocolVersion().getName(), + packetWrapper + }); } @Override @@ -157,6 +161,49 @@ public class ProtocolPipelineImpl extends AbstractSimpleProtocol implements Prot return null; } + @Override + public List pipes(@Nullable final Class protocolClass, final boolean skipCurrentPipeline, final Direction direction) { + final List protocolList = this.protocolListFor(direction); + final int index = indexOf(protocolClass, skipCurrentPipeline, protocolList); + + final List pipes = new ArrayList<>(baseProtocols + protocolList.size() - index); + // Always add base protocols to the head + for (int i = 0, size = Math.min(index, baseProtocols); i < size; i++) { + pipes.add(protocolList.get(i)); + } + + // Add remaining protocols on top + for (int i = index, size = protocolList.size(); i < size; i++) { + pipes.add(protocolList.get(i)); + } + return pipes; + } + + private int indexOf(@Nullable Class protocolClass, boolean skipCurrentPipeline, List protocolList) { + if (protocolClass == null) { + return 0; + } + + // Find the index of the given protocol + int index = -1; + for (int i = 0; i < protocolList.size(); i++) { + if (protocolList.get(i).getClass() == protocolClass) { + index = i; + break; + } + } + + if (index == -1) { + // The given protocol is not in the pipeline + throw new NoSuchElementException(protocolClass.getCanonicalName()); + } + + if (skipCurrentPipeline) { + index = Math.min(index + 1, protocolList.size()); + } + return index; + } + @Override public List pipes() { return Collections.unmodifiableList(protocolList); @@ -168,17 +215,17 @@ public class ProtocolPipelineImpl extends AbstractSimpleProtocol implements Prot } @Override - public boolean hasNonBaseProtocols() { - for (Protocol protocol : protocolList) { - if (!protocol.isBaseProtocol()) { - return true; - } - } - return false; + public int baseProtocolCount() { + return baseProtocols; } @Override - public synchronized void cleanPipes() { + public boolean hasNonBaseProtocols() { + return protocolList.size() > baseProtocols; + } + + @Override + public void cleanPipes() { protocolList.clear(); reversedProtocolList.clear(); protocolSet.clear(); @@ -190,7 +237,7 @@ public class ProtocolPipelineImpl extends AbstractSimpleProtocol implements Prot @Override public String toString() { return "ProtocolPipelineImpl{" + - "protocolList=" + protocolList + - '}'; + "protocolList=" + protocolList + + '}'; } } diff --git a/common/src/main/java/com/viaversion/viaversion/protocol/packet/PacketWrapperImpl.java b/common/src/main/java/com/viaversion/viaversion/protocol/packet/PacketWrapperImpl.java index 322473924..aab6945e5 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocol/packet/PacketWrapperImpl.java +++ b/common/src/main/java/com/viaversion/viaversion/protocol/packet/PacketWrapperImpl.java @@ -39,13 +39,10 @@ import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Deque; import java.util.List; -import java.util.NoSuchElementException; import java.util.Objects; import org.checkerframework.checker.nullness.qual.Nullable; public class PacketWrapperImpl implements PacketWrapper { - private static final Protocol[] PROTOCOL_ARRAY = new Protocol[0]; - private final Deque> readableObjects = new ArrayDeque<>(); private final List> packetValues = new ArrayList<>(); private final ByteBuf inputBuffer; @@ -148,8 +145,8 @@ public class PacketWrapperImpl implements PacketWrapper { PacketValue readValue = readableObjects.poll(); Type readType = readValue.type(); if (readType == type - || (type.getBaseClass() == readType.getBaseClass() - && type.getOutputClass() == readType.getOutputClass())) { + || (type.getBaseClass() == readType.getBaseClass() + && type.getOutputClass() == readType.getOutputClass())) { //noinspection unchecked return (T) readValue.value(); } else { @@ -210,25 +207,24 @@ public class PacketWrapperImpl implements PacketWrapper { readableObjects.clear(); } - int index = 0; - for (final PacketValue packetValue : packetValues) { + for (int i = 0; i < packetValues.size(); i++) { + PacketValue packetValue = packetValues.get(i); try { packetValue.write(buffer); } catch (final Exception e) { - throw createInformativeException(e, packetValue.type(), index); + throw createInformativeException(e, packetValue.type(), i); } - index++; } writeRemaining(buffer); } private InformativeException createInformativeException(final Exception cause, final Type type, final int index) { return new InformativeException(cause) - .set("Index", index) - .set("Type", type.getTypeName()) - .set("Packet ID", this.id) - .set("Packet Type", this.packetType) - .set("Data", this.packetValues); + .set("Index", index) + .set("Type", type.getTypeName()) + .set("Packet ID", this.id) + .set("Packet Type", this.packetType) + .set("Data", this.packetValues); } @Override @@ -298,46 +294,17 @@ public class PacketWrapperImpl implements PacketWrapper { /** * Let the packet go through the protocol pipes and write it to ByteBuf * - * @param packetProtocol The protocol version of the packet. - * @param skipCurrentPipeline Skip the current pipeline - * @return Packet buffer + * @param protocolClass protocol class to send the packet from, or null to go through the full pipeline + * @param skipCurrentPipeline whether to start from the next protocol in the pipeline, or the provided one + * @return created packet buffer * @throws Exception if it fails to write */ - private ByteBuf constructPacket(Class packetProtocol, boolean skipCurrentPipeline, Direction direction) throws Exception { + private ByteBuf constructPacket(@Nullable Class protocolClass, boolean skipCurrentPipeline, Direction direction) throws Exception { + resetReader(); // Reset reader before we start + final ProtocolInfo protocolInfo = user().getProtocolInfo(); - final List pipes = direction == Direction.SERVERBOUND ? protocolInfo.getPipeline().pipes() : protocolInfo.getPipeline().reversedPipes(); - final List protocols = new ArrayList<>(); - int index = -1; - for (int i = 0; i < pipes.size(); i++) { - // Always add base protocols to the head - final Protocol protocol = pipes.get(i); - if (protocol.isBaseProtocol()) { - protocols.add(protocol); - } - - if (protocol.getClass() == packetProtocol) { - index = i; - break; - } - } - - if (index == -1) { - // The given protocol is not in the pipeline - throw new NoSuchElementException(packetProtocol.getCanonicalName()); - } - - if (skipCurrentPipeline) { - index = Math.min(index + 1, pipes.size()); - } - - // Add remaining protocols on top - protocols.addAll(pipes.subList(index, pipes.size())); - - // Reset reader before we start - resetReader(); - - // Apply other protocols - apply(direction, protocolInfo.getState(direction), 0, protocols); + final List protocols = protocolInfo.getPipeline().pipes(protocolClass, skipCurrentPipeline, direction); + apply(direction, protocolInfo.getState(direction), protocols); final ByteBuf output = inputBuffer == null ? user().getChannel().alloc().buffer() : inputBuffer.alloc().buffer(); try { writeToBuffer(output); @@ -348,9 +315,9 @@ public class PacketWrapperImpl implements PacketWrapper { } @Override - public ChannelFuture sendFuture(Class packetProtocol) throws Exception { + public ChannelFuture sendFuture(Class protocolClass) throws Exception { if (!isCancelled()) { - ByteBuf output = constructPacket(packetProtocol, true, Direction.CLIENTBOUND); + ByteBuf output = constructPacket(protocolClass, true, Direction.CLIENTBOUND); return user().sendRawPacketFuture(output); } return user().getChannel().newFailedFuture(new Exception("Cancelled packet")); @@ -397,33 +364,36 @@ public class PacketWrapperImpl implements PacketWrapper { } @Override - public PacketWrapperImpl apply(Direction direction, State state, int index, List pipeline, boolean reverse) throws Exception { - Protocol[] array = pipeline.toArray(PROTOCOL_ARRAY); - return apply(direction, state, reverse ? array.length - 1 : index, array, reverse); // Copy to prevent from removal + public void apply(Direction direction, State state, List pipeline) throws Exception { + // Indexed loop to allow additions to the tail + for (int i = 0, size = pipeline.size(); i < size; i++) { + Protocol protocol = pipeline.get(i); + protocol.transform(direction, state, this); + resetReader(); + if (this.packetType != null) { + state = this.packetType.state(); + } + } } @Override - public PacketWrapperImpl apply(Direction direction, State state, int index, List pipeline) throws Exception { - return apply(direction, state, index, pipeline.toArray(PROTOCOL_ARRAY), false); - } - - private PacketWrapperImpl apply(Direction direction, State state, int index, Protocol[] pipeline, boolean reverse) throws Exception { + @Deprecated + public PacketWrapperImpl apply(Direction direction, State state, int index, List pipeline, boolean reverse) throws Exception { // Reset the reader after every transformation for the packetWrapper, so it can be recycled across packets - State updatedState = state; // The state might change while transforming, so we need to check for that if (reverse) { for (int i = index; i >= 0; i--) { - pipeline[i].transform(direction, updatedState, this); + pipeline.get(i).transform(direction, state, this); resetReader(); if (this.packetType != null) { - updatedState = this.packetType.state(); + state = this.packetType.state(); } } } else { - for (int i = index; i < pipeline.length; i++) { - pipeline[i].transform(direction, updatedState, this); + for (int i = index; i < pipeline.size(); i++) { + pipeline.get(i).transform(direction, state, this); resetReader(); if (this.packetType != null) { - updatedState = this.packetType.state(); + state = this.packetType.state(); } } } @@ -447,7 +417,7 @@ public class PacketWrapperImpl implements PacketWrapper { @Override public void resetReader() { - // Move all packet values to the readable for next packet. + // Move all packet values to the readable for next Protocol for (int i = packetValues.size() - 1; i >= 0; i--) { this.readableObjects.addFirst(this.packetValues.get(i)); } @@ -557,11 +527,11 @@ public class PacketWrapperImpl implements PacketWrapper { @Override public String toString() { return "PacketWrapper{" + - "type=" + packetType + - ", id=" + id + - ", values=" + packetValues + - ", readable=" + readableObjects + - '}'; + "type=" + packetType + + ", id=" + id + + ", values=" + packetValues + + ", readable=" + readableObjects + + '}'; } public static final class PacketValue { diff --git a/common/src/main/java/com/viaversion/viaversion/protocol/packet/VersionedPacketTransformerImpl.java b/common/src/main/java/com/viaversion/viaversion/protocol/packet/VersionedPacketTransformerImpl.java index 81cbe7954..f9d544309 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocol/packet/VersionedPacketTransformerImpl.java +++ b/common/src/main/java/com/viaversion/viaversion/protocol/packet/VersionedPacketTransformerImpl.java @@ -33,6 +33,7 @@ import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; +import java.util.stream.Collectors; import org.checkerframework.checker.nullness.qual.Nullable; public class VersionedPacketTransformerImpl implements VersionedPacketTransformer { @@ -44,7 +45,7 @@ public class VersionedPacketTransformerImpl clientboundPacketsClass, @Nullable Class serverboundPacketsClass) { Preconditions.checkNotNull(inputVersion); Preconditions.checkArgument(clientboundPacketsClass != null || serverboundPacketsClass != null, - "Either the clientbound or serverbound packets class has to be non-null"); + "Either the clientbound or serverbound packets class has to be non-null"); this.inputProtocolVersion = inputVersion; this.clientboundPacketsClass = clientboundPacketsClass; this.serverboundPacketsClass = serverboundPacketsClass; @@ -108,7 +109,7 @@ public class VersionedPacketTransformerImpl expectedPacketClass = - packet.getPacketType().direction() == Direction.CLIENTBOUND ? clientboundPacketsClass : serverboundPacketsClass; + packet.getPacketType().direction() == Direction.CLIENTBOUND ? clientboundPacketsClass : serverboundPacketsClass; if (packet.getPacketType().getClass() != expectedPacketClass) { throw new IllegalArgumentException("PacketWrapper packet type is of the wrong packet class"); } @@ -139,34 +140,40 @@ public class VersionedPacketTransformerImpl path = Via.getManager().getProtocolManager().getProtocolPath(clientProtocolVersion, serverProtocolVersion); - List protocolList = null; - if (path != null) { - protocolList = new ArrayList<>(path.size()); + if (path == null) { + if (serverProtocolVersion != clientProtocolVersion) { + throw new RuntimeException("No protocol path between client version " + clientProtocolVersion + " and server version " + serverProtocolVersion); + } + return; + } + + final List protocolList = new ArrayList<>(path.size()); + if (clientbound) { + for (int i = path.size() - 1; i >= 0; i--) { + protocolList.add(path.get(i).protocol()); + } + } else { for (ProtocolPathEntry entry : path) { protocolList.add(entry.protocol()); } - } else if (serverProtocolVersion != clientProtocolVersion) { - throw new RuntimeException("No protocol path between client version " + clientProtocolVersion + " and server version " + serverProtocolVersion); } - if (protocolList != null) { - // Reset reader and apply pipeline - packet.resetReader(); + // Reset reader and apply pipeline + packet.resetReader(); - try { - packet.apply(packetType.direction(), State.PLAY, 0, protocolList, clientbound); - } catch (Exception e) { - throw new Exception("Exception trying to transform packet between client version " + clientProtocolVersion - + " and server version " + serverProtocolVersion + ". Are you sure you used the correct input version and packet write types?", e); - } + try { + packet.apply(packetType.direction(), packetType.state(), protocolList); + } catch (Exception e) { + throw new Exception("Exception trying to transform packet between client version " + clientProtocolVersion + + " and server version " + serverProtocolVersion + ". Are you sure you used the correct input version and packet write types?", e); } } diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/base/BaseProtocol.java b/common/src/main/java/com/viaversion/viaversion/protocols/base/BaseProtocol.java index d33ef3c18..626bd2d72 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/base/BaseProtocol.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/base/BaseProtocol.java @@ -22,6 +22,7 @@ import com.viaversion.viaversion.api.connection.ProtocolInfo; import com.viaversion.viaversion.api.platform.providers.ViaProviders; import com.viaversion.viaversion.api.protocol.AbstractProtocol; import com.viaversion.viaversion.api.protocol.Protocol; +import com.viaversion.viaversion.api.protocol.ProtocolManager; import com.viaversion.viaversion.api.protocol.ProtocolPathEntry; import com.viaversion.viaversion.api.protocol.ProtocolPipeline; import com.viaversion.viaversion.api.protocol.packet.Direction; @@ -72,18 +73,25 @@ public class BaseProtocol extends AbstractProtocol protocolPath = null; // Only allow newer clients (or 1.9.2 on 1.9.4 server if the server supports it) + ProtocolManager protocolManager = Via.getManager().getProtocolManager(); if (info.protocolVersion().newerThanOrEqualTo(serverProtocol) || Via.getPlatform().isOldClientsAllowed()) { - protocolPath = Via.getManager().getProtocolManager().getProtocolPath(info.protocolVersion(), serverProtocol); + protocolPath = protocolManager.getProtocolPath(info.protocolVersion(), serverProtocol); } - ProtocolPipeline pipeline = wrapper.user().getProtocolInfo().getPipeline(); + // Add Base Protocol + ProtocolPipeline pipeline = info.getPipeline(); + if (serverProtocol.getVersionType() != VersionType.SPECIAL) { + pipeline.add(protocolManager.getBaseProtocol(serverProtocol)); + } + + // Add other protocols if (protocolPath != null) { List protocols = new ArrayList<>(protocolPath.size()); for (ProtocolPathEntry entry : protocolPath) { protocols.add(entry.protocol()); // Ensure mapping data has already been loaded - Via.getManager().getProtocolManager().completeMappingDataLoading(entry.protocol().getClass()); + protocolManager.completeMappingDataLoading(entry.protocol().getClass()); } // Add protocols to pipeline @@ -93,11 +101,6 @@ public class BaseProtocol extends AbstractProtocol wrapper.user().getChannel().close()); } }); diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_11to1_10/storage/EntityTracker1_11.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_11to1_10/storage/EntityTracker1_11.java index c9152f60f..c68cb21a0 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_11to1_10/storage/EntityTracker1_11.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_11to1_10/storage/EntityTracker1_11.java @@ -20,11 +20,11 @@ package com.viaversion.viaversion.protocols.protocol1_11to1_10.storage; import com.viaversion.viaversion.api.connection.UserConnection; import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_11.EntityType; import com.viaversion.viaversion.data.entity.EntityTrackerBase; +import it.unimi.dsi.fastutil.ints.IntOpenHashSet; import it.unimi.dsi.fastutil.ints.IntSet; -import space.vectrix.flare.fastutil.Int2ObjectSyncMap; public class EntityTracker1_11 extends EntityTrackerBase { - private final IntSet holograms = Int2ObjectSyncMap.hashset(); + private final IntSet holograms = new IntOpenHashSet(); public EntityTracker1_11(UserConnection user) { super(user, EntityType.PLAYER); diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_13to1_12_2/storage/BlockStorage.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_13to1_12_2/storage/BlockStorage.java index f37631f9e..7ee968213 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_13to1_12_2/storage/BlockStorage.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_13to1_12_2/storage/BlockStorage.java @@ -21,13 +21,13 @@ import com.viaversion.viaversion.api.connection.StorableObject; import com.viaversion.viaversion.api.minecraft.Position; import it.unimi.dsi.fastutil.ints.IntOpenHashSet; import it.unimi.dsi.fastutil.ints.IntSet; +import java.util.HashMap; import java.util.Map; -import space.vectrix.flare.SyncMap; // TODO Fix memory leak lolz (only a smol one tho) public class BlockStorage implements StorableObject { private static final IntSet WHITELIST = new IntOpenHashSet(46, .99F); - private final Map blocks = SyncMap.hashmap(); + private final Map blocks = new HashMap<>(); static { // Flower pots diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_14to1_13_2/storage/EntityTracker1_14.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_14to1_13_2/storage/EntityTracker1_14.java index f7e48b85a..9dd412b68 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_14to1_13_2/storage/EntityTracker1_14.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_14to1_13_2/storage/EntityTracker1_14.java @@ -21,13 +21,13 @@ import com.viaversion.viaversion.api.connection.UserConnection; import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_14; import com.viaversion.viaversion.data.entity.EntityTrackerBase; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import space.vectrix.flare.fastutil.Int2ObjectSyncMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; public class EntityTracker1_14 extends EntityTrackerBase { - private final Int2ObjectMap insentientData = Int2ObjectSyncMap.hashmap(); + private final Int2ObjectMap insentientData = new Int2ObjectOpenHashMap<>(); // 0x1 = sleeping, 0x2 = riptide - private final Int2ObjectMap sleepingAndRiptideData = Int2ObjectSyncMap.hashmap(); - private final Int2ObjectMap playerEntityFlags = Int2ObjectSyncMap.hashmap(); + private final Int2ObjectMap sleepingAndRiptideData = new Int2ObjectOpenHashMap<>(); + private final Int2ObjectMap playerEntityFlags = new Int2ObjectOpenHashMap<>(); private int latestTradeWindowId; private boolean forceSendCenterChunk = true; private int chunkCenterX; diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_9to1_8/storage/EntityTracker1_9.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_9to1_8/storage/EntityTracker1_9.java index 29f7b34d6..924c11392 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_9to1_8/storage/EntityTracker1_9.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_9to1_8/storage/EntityTracker1_9.java @@ -39,26 +39,28 @@ import com.viaversion.viaversion.protocols.protocol1_9to1_8.chat.GameMode; import com.viaversion.viaversion.protocols.protocol1_9to1_8.metadata.MetadataRewriter1_9To1_8; import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.BossBarProvider; import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.EntityIdProvider; +import it.unimi.dsi.fastutil.ints.Int2IntMap; +import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.ints.IntOpenHashSet; import it.unimi.dsi.fastutil.ints.IntSet; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.Map; import java.util.Set; import java.util.UUID; import java.util.concurrent.TimeUnit; -import space.vectrix.flare.fastutil.Int2ObjectSyncMap; public class EntityTracker1_9 extends EntityTrackerBase { public static final String WITHER_TRANSLATABLE = "{\"translate\":\"entity.WitherBoss.name\"}"; public static final String DRAGON_TRANSLATABLE = "{\"translate\":\"entity.EnderDragon.name\"}"; - private final Int2ObjectMap uuidMap = Int2ObjectSyncMap.hashmap(); - private final Int2ObjectMap> metadataBuffer = Int2ObjectSyncMap.hashmap(); - private final Int2ObjectMap vehicleMap = Int2ObjectSyncMap.hashmap(); - private final Int2ObjectMap bossBarMap = Int2ObjectSyncMap.hashmap(); - private final IntSet validBlocking = Int2ObjectSyncMap.hashset(); - private final Set knownHolograms = Int2ObjectSyncMap.hashset(); + private final Int2ObjectMap uuidMap = new Int2ObjectOpenHashMap<>(); + private final Int2ObjectMap> metadataBuffer = new Int2ObjectOpenHashMap<>(); + private final Int2IntMap vehicleMap = new Int2IntOpenHashMap(); + private final Int2ObjectMap bossBarMap = new Int2ObjectOpenHashMap<>(); + private final IntSet validBlocking = new IntOpenHashSet(); + private final IntSet knownHolograms = new IntOpenHashSet(); private final Set blockInteractions = Collections.newSetFromMap(CacheBuilder.newBuilder() .maximumSize(1000) .expireAfterAccess(250, TimeUnit.MILLISECONDS) @@ -368,27 +370,27 @@ public class EntityTracker1_9 extends EntityTrackerBase { } } - public Map getUuidMap() { + public Int2ObjectMap getUuidMap() { return uuidMap; } - public Map> getMetadataBuffer() { + public Int2ObjectMap> getMetadataBuffer() { return metadataBuffer; } - public Map getVehicleMap() { + public Int2IntMap getVehicleMap() { return vehicleMap; } - public Map getBossBarMap() { + public Int2ObjectMap getBossBarMap() { return bossBarMap; } - public Set getValidBlocking() { + public IntSet getValidBlocking() { return validBlocking; } - public Set getKnownHolograms() { + public IntSet getKnownHolograms() { return knownHolograms; } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d9eb3ce36..ca515d782 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -4,7 +4,6 @@ metadata.format.version = "1.1" gson = "2.10.1" fastutil = "8.5.12" -flare = "2.0.1" vianbt = "4.2.0" mcstructs = "2.4.2-SNAPSHOT" @@ -29,8 +28,6 @@ velocity = "3.1.1" gson = { group = "com.google.code.gson", name = "gson", version.ref = "gson" } fastutil = { group = "it.unimi.dsi", name = "fastutil", version.ref = "fastutil" } -flare = { group = "space.vectrix.flare", name = "flare", version.ref = "flare" } -flareFastutil = { group = "space.vectrix.flare", name = "flare-fastutil", version.ref = "flare" } vianbt = { group = "com.viaversion", name = "nbt", version.ref = "vianbt" } # Custom version that uses ViaNBT instead of its own inbuilt NBT library text = { group = "com.viaversion.mcstructs", name = "text", version.ref = "mcstructs" }