3
0
Mirror von https://github.com/ViaVersion/ViaVersion.git synchronisiert 2024-07-03 22:18:04 +02:00

Small refactors around ProtocolPipeline and concurrent collections

Make concurrency handling in ProtocolPipelineImpl more defensive, as generally the pipeline is expected to never be called from multiple threads. The only case to look out for is pipeline additions during protocol transformation in a base protocol
Dieser Commit ist enthalten in:
Nassim Jahnke 2024-02-19 22:37:51 +01:00
Ursprung 343b403cf1
Commit 4e1d4a75b2
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: EF6771C01F6EF02F
17 geänderte Dateien mit 235 neuen und 207 gelöschten Zeilen

Datei anzeigen

@ -16,8 +16,6 @@ sourceSets {
dependencies { dependencies {
api(libs.fastutil) api(libs.fastutil)
api(libs.flare)
api(libs.flareFastutil)
api(libs.vianbt) api(libs.vianbt)
api(libs.gson) api(libs.gson)
implementation(rootProject.libs.text) { implementation(rootProject.libs.text) {

Datei anzeigen

@ -66,7 +66,7 @@ public interface ViaAPI<T> {
* @return API version incremented with meaningful API changes * @return API version incremented with meaningful API changes
*/ */
default int apiVersion() { default int apiVersion() {
return 24; return 25;
} }
/** /**

Datei anzeigen

@ -23,6 +23,7 @@
package com.viaversion.viaversion.api.protocol; package com.viaversion.viaversion.api.protocol;
import com.viaversion.viaversion.api.connection.UserConnection; import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.packet.Direction;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
@ -61,25 +62,34 @@ public interface ProtocolPipeline extends SimpleProtocol {
* @param pipeClass protocol class * @param pipeClass protocol class
* @param <P> protocol * @param <P> protocol
* @return protocol from class * @return protocol from class
* @see #contains(Class) * @deprecated use {@link ProtocolManager#getProtocol(Class)} and/or {@link #contains(Class)}
* @see ProtocolManager#getProtocol(Class) for a faster implementation
*/ */
@Deprecated
@Nullable <P extends Protocol> P getProtocol(Class<P> pipeClass); @Nullable <P extends Protocol> P getProtocol(Class<P> pipeClass);
List<Protocol> pipes(@Nullable Class<? extends Protocol> 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 * @return immutable list of protocols in this pipe
*/ */
List<Protocol> pipes(); List<Protocol> 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 * @return immutable list of protocols in reversed direction
*/ */
List<Protocol> reversedPipes(); List<Protocol> 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()}. * Returns whether this pipe has protocols that are not base protocols, as given by {@link Protocol#isBaseProtocol()}.
* *

Datei anzeigen

@ -92,6 +92,7 @@ public interface PacketWrapper {
* @param index The index of the part (relative to the type) * @param index The index of the part (relative to the type)
* @return True if the type is at the index * @return True if the type is at the index
*/ */
@Deprecated
boolean is(Type type, int index); boolean is(Type type, int index);
/** /**
@ -212,11 +213,11 @@ public interface PacketWrapper {
* (Sends it after current) * (Sends it after current)
* Also returns the packets ChannelFuture * Also returns the packets ChannelFuture
* *
* @param packetProtocol The protocol version of the packet. * @param protocolClass the protocol class to start from in the pipeline
* @return The packets ChannelFuture * @return new ChannelFuture for the write operation
* @throws Exception if it fails to write * @throws Exception if it fails to write
*/ */
ChannelFuture sendFuture(Class<? extends Protocol> packetProtocol) throws Exception; ChannelFuture sendFuture(Class<? extends Protocol> protocolClass) throws Exception;
/** /**
* @deprecated misleading; use {@link #sendRaw()}. This method will be removed in 5.0.0 * @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 direction protocol direction
* @param state protocol state * @param state protocol state
* @param index index to start from, will be reversed depending on the reverse parameter
* @param pipeline protocol pipeline * @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 * @throws Exception If it fails to transform a packet, exception will be thrown
*/ */
void apply(Direction direction, State state, List<Protocol> pipeline) throws Exception;
/**
* @deprecated use {@link #apply(Direction, State, List)}
*/
@Deprecated
PacketWrapper apply(Direction direction, State state, int index, List<Protocol> pipeline, boolean reverse) throws Exception; PacketWrapper apply(Direction direction, State state, int index, List<Protocol> 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<Protocol> pipeline) throws Exception; @Deprecated
default PacketWrapper apply(Direction direction, State state, int index, List<Protocol> pipeline) throws Exception {
return apply(direction, state, index, pipeline, false);
}
/** /**
* Check if this packet is cancelled. * Check if this packet is cancelled.

Datei anzeigen

@ -25,7 +25,6 @@ fun ShadowJar.configureRelocations() {
relocate("com.google.gson", "com.viaversion.viaversion.libs.gson") relocate("com.google.gson", "com.viaversion.viaversion.libs.gson")
relocate("com.github.steveice10.opennbt", "com.viaversion.viaversion.libs.opennbt") relocate("com.github.steveice10.opennbt", "com.viaversion.viaversion.libs.opennbt")
relocate("it.unimi.dsi.fastutil", "com.viaversion.viaversion.libs.fastutil") 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") 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/*/*Big*")
exclude("it/unimi/dsi/fastutil/*/*Synchronized*") exclude("it/unimi/dsi/fastutil/*/*Synchronized*")
exclude("it/unimi/dsi/fastutil/*/*Unmodifiable*") 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*")
} }

Datei anzeigen

@ -44,6 +44,7 @@ import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.stream.Collectors;
import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.connection.Server; import net.md_5.bungee.api.connection.Server;
import net.md_5.bungee.api.event.ServerConnectEvent; import net.md_5.bungee.api.event.ServerConnectEvent;
@ -194,18 +195,15 @@ public class BungeeServerHandler implements Listener {
ProtocolPipeline pipeline = user.getProtocolInfo().getPipeline(); ProtocolPipeline pipeline = user.getProtocolInfo().getPipeline();
user.clearStoredObjects(true); user.clearStoredObjects(true);
pipeline.cleanPipes(); 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* // TODO Check Bungee Supported Protocols? *shrugs*
serverProtocolVersion = info.protocolVersion(); serverProtocolVersion = info.protocolVersion();
} else { info.setServerProtocolVersion(serverProtocolVersion);
List<Protocol> protocols = new ArrayList<>(protocolPath.size());
for (ProtocolPathEntry entry : protocolPath) {
protocols.add(entry.protocol());
}
pipeline.add(protocols);
} }
info.setServerProtocolVersion(serverProtocolVersion);
// Add version-specific base Protocol // Add version-specific base Protocol
pipeline.add(Via.getManager().getProtocolManager().getBaseProtocol(serverProtocolVersion)); pipeline.add(Via.getManager().getProtocolManager().getBaseProtocol(serverProtocolVersion));
@ -254,11 +252,6 @@ public class BungeeServerHandler implements Listener {
user.setActive(protocolPath != 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()) {
protocol.init(user);
}
ProxiedPlayer player = storage.getPlayer(); ProxiedPlayer player = storage.getPlayer();
EntityTracker1_9 newTracker = user.getEntityTracker(Protocol1_9To1_8.class); EntityTracker1_9 newTracker = user.getEntityTracker(Protocol1_9To1_8.class);
if (newTracker != null && Via.getConfig().isAutoTeam()) { if (newTracker != null && Via.getConfig().isAutoTeam()) {

Datei anzeigen

@ -28,13 +28,13 @@ import com.viaversion.viaversion.api.data.entity.TrackedEntity;
import com.viaversion.viaversion.api.minecraft.entities.EntityType; import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.util.Key; import com.viaversion.viaversion.util.Key;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import java.util.Collections; import java.util.Collections;
import java.util.Map; import java.util.Map;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import space.vectrix.flare.fastutil.Int2ObjectSyncMap;
public class EntityTrackerBase implements EntityTracker, ClientEntityIdChangeListener { public class EntityTrackerBase implements EntityTracker, ClientEntityIdChangeListener {
private final Int2ObjectMap<TrackedEntity> entities = Int2ObjectSyncMap.hashmap(); private final Int2ObjectMap<TrackedEntity> entities = new Int2ObjectOpenHashMap<>();
private final UserConnection connection; private final UserConnection connection;
private final EntityType playerType; private final EntityType playerType;
private int clientEntityId = -1; private int clientEntityId = -1;

Datei anzeigen

@ -18,6 +18,7 @@
package com.viaversion.viaversion.protocol; package com.viaversion.viaversion.protocol;
import com.viaversion.viaversion.api.Via; 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.connection.UserConnection;
import com.viaversion.viaversion.api.debug.DebugHandler; import com.viaversion.viaversion.api.debug.DebugHandler;
import com.viaversion.viaversion.api.protocol.AbstractSimpleProtocol; import com.viaversion.viaversion.api.protocol.AbstractSimpleProtocol;
@ -31,19 +32,16 @@ import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.NoSuchElementException;
import java.util.Set; import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.logging.Level; import java.util.logging.Level;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
public class ProtocolPipelineImpl extends AbstractSimpleProtocol implements ProtocolPipeline { public class ProtocolPipelineImpl extends AbstractSimpleProtocol implements ProtocolPipeline {
private final UserConnection userConnection; private final List<Protocol> protocolList = new ArrayList<>();
/**
* Protocol list ordered from client to server transformation with the base protocols at the end.
*/
private final List<Protocol> protocolList = new CopyOnWriteArrayList<>();
private final Set<Class<? extends Protocol>> protocolSet = new HashSet<>(); private final Set<Class<? extends Protocol>> protocolSet = new HashSet<>();
private List<Protocol> reversedProtocolList = new CopyOnWriteArrayList<>(); private final UserConnection userConnection;
private List<Protocol> reversedProtocolList = new ArrayList<>();
private int baseProtocols; private int baseProtocols;
public ProtocolPipelineImpl(UserConnection userConnection) { public ProtocolPipelineImpl(UserConnection userConnection) {
@ -53,13 +51,9 @@ public class ProtocolPipelineImpl extends AbstractSimpleProtocol implements Prot
} }
@Override @Override
protected synchronized void registerPackets() { protected void registerPackets() {
// This is a pipeline so we register basic pipes // This is a pipeline so we register basic pipes
final Protocol<?, ?, ?, ?> baseProtocol = Via.getManager().getProtocolManager().getBaseProtocol(); this.add(Via.getManager().getProtocolManager().getBaseProtocol());
protocolList.add(baseProtocol);
reversedProtocolList.add(baseProtocol);
protocolSet.add(baseProtocol.getClass());
baseProtocols++;
} }
@Override @Override
@ -68,15 +62,14 @@ public class ProtocolPipelineImpl extends AbstractSimpleProtocol implements Prot
} }
@Override @Override
public synchronized void add(final Protocol protocol) { public void add(final Protocol protocol) {
reversedProtocolList.add(baseProtocols, protocol);
if (protocol.isBaseProtocol()) { if (protocol.isBaseProtocol()) {
// Add base protocol on top of previous ones // Add base protocol on top of previous ones
protocolList.add(baseProtocols, protocol); protocolList.add(baseProtocols, protocol);
reversedProtocolList.add(baseProtocols, protocol);
baseProtocols++; baseProtocols++;
} else { } else {
protocolList.add(protocol); protocolList.add(protocol);
reversedProtocolList.add(0, protocol);
} }
protocolSet.add(protocol.getClass()); protocolSet.add(protocol.getClass());
@ -84,22 +77,32 @@ public class ProtocolPipelineImpl extends AbstractSimpleProtocol implements Prot
} }
@Override @Override
public synchronized void add(final Collection<Protocol> protocols) { public void add(final Collection<Protocol> protocols) {
protocolList.addAll(protocols);
for (final Protocol protocol : protocols) { for (final Protocol protocol : protocols) {
if (protocol.isBaseProtocol()) {
throw new UnsupportedOperationException("Base protocols cannot be added in bulk");
}
protocol.init(userConnection); protocol.init(userConnection);
protocolSet.add(protocol.getClass()); protocolSet.add(protocol.getClass());
} }
protocolList.addAll(protocols);
refreshReversedList(); refreshReversedList();
} }
private synchronized void refreshReversedList() { private void refreshReversedList() {
final List<Protocol> protocols = new ArrayList<>(protocolList.subList(0, this.baseProtocols)); final List<Protocol> reversedProtocols = new ArrayList<>(protocolList.size());
final List<Protocol> additionalProtocols = new ArrayList<>(protocolList.subList(this.baseProtocols, protocolList.size())); // Add base protocols in regular order first
Collections.reverse(additionalProtocols); for (int i = 0; i < baseProtocols; i++) {
protocols.addAll(additionalProtocols); reversedProtocols.add(protocolList.get(i));
reversedProtocolList = new CopyOnWriteArrayList<>(protocols); }
// Add non-base protocols in reverse order
for (int i = protocolList.size() - 1; i >= baseProtocols; i--) {
reversedProtocols.add(protocolList.get(i));
}
reversedProtocolList = reversedProtocols;
} }
@Override @Override
@ -113,7 +116,7 @@ public class ProtocolPipelineImpl extends AbstractSimpleProtocol implements Prot
} }
// Apply protocols // Apply protocols
packetWrapper.apply(direction, state, 0, protocolListFor(direction)); packetWrapper.apply(direction, state, protocolListFor(direction));
super.transform(direction, state, packetWrapper); super.transform(direction, state, packetWrapper);
if (debug && debugHandler.logPostPacketTransform() && debugHandler.shouldLog(packetWrapper, direction)) { 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) { 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 + " " : ""; String username = actualUsername != null ? actualUsername + " " : "";
Via.getPlatform().getLogger().log(Level.INFO, "{0}{1} {2}: {3} ({4}) -> {5} ({6}) [{7}] {8}", Via.getPlatform().getLogger().log(Level.INFO, "{0}{1} {2}: {3} ({4}) -> {5} ({6}) [{7}] {8}",
new Object[]{ new Object[]{
username, username,
direction, direction,
state, state,
originalID, originalID,
AbstractSimpleProtocol.toNiceHex(originalID), AbstractSimpleProtocol.toNiceHex(originalID),
packetWrapper.getId(), packetWrapper.getId(),
AbstractSimpleProtocol.toNiceHex(packetWrapper.getId()), AbstractSimpleProtocol.toNiceHex(packetWrapper.getId()),
userConnection.getProtocolInfo().protocolVersion().getName(), protocolInfo.protocolVersion().getName(),
packetWrapper packetWrapper
}); });
} }
@Override @Override
@ -157,6 +161,49 @@ public class ProtocolPipelineImpl extends AbstractSimpleProtocol implements Prot
return null; return null;
} }
@Override
public List<Protocol> pipes(@Nullable final Class<? extends Protocol> protocolClass, final boolean skipCurrentPipeline, final Direction direction) {
final List<Protocol> protocolList = this.protocolListFor(direction);
final int index = indexOf(protocolClass, skipCurrentPipeline, protocolList);
final List<Protocol> 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<? extends Protocol> protocolClass, boolean skipCurrentPipeline, List<Protocol> 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 @Override
public List<Protocol> pipes() { public List<Protocol> pipes() {
return Collections.unmodifiableList(protocolList); return Collections.unmodifiableList(protocolList);
@ -168,17 +215,17 @@ public class ProtocolPipelineImpl extends AbstractSimpleProtocol implements Prot
} }
@Override @Override
public boolean hasNonBaseProtocols() { public int baseProtocolCount() {
for (Protocol protocol : protocolList) { return baseProtocols;
if (!protocol.isBaseProtocol()) {
return true;
}
}
return false;
} }
@Override @Override
public synchronized void cleanPipes() { public boolean hasNonBaseProtocols() {
return protocolList.size() > baseProtocols;
}
@Override
public void cleanPipes() {
protocolList.clear(); protocolList.clear();
reversedProtocolList.clear(); reversedProtocolList.clear();
protocolSet.clear(); protocolSet.clear();
@ -190,7 +237,7 @@ public class ProtocolPipelineImpl extends AbstractSimpleProtocol implements Prot
@Override @Override
public String toString() { public String toString() {
return "ProtocolPipelineImpl{" + return "ProtocolPipelineImpl{" +
"protocolList=" + protocolList + "protocolList=" + protocolList +
'}'; '}';
} }
} }

Datei anzeigen

@ -39,13 +39,10 @@ import java.util.ArrayDeque;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Deque; import java.util.Deque;
import java.util.List; import java.util.List;
import java.util.NoSuchElementException;
import java.util.Objects; import java.util.Objects;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
public class PacketWrapperImpl implements PacketWrapper { public class PacketWrapperImpl implements PacketWrapper {
private static final Protocol[] PROTOCOL_ARRAY = new Protocol[0];
private final Deque<PacketValue<?>> readableObjects = new ArrayDeque<>(); private final Deque<PacketValue<?>> readableObjects = new ArrayDeque<>();
private final List<PacketValue<?>> packetValues = new ArrayList<>(); private final List<PacketValue<?>> packetValues = new ArrayList<>();
private final ByteBuf inputBuffer; private final ByteBuf inputBuffer;
@ -148,8 +145,8 @@ public class PacketWrapperImpl implements PacketWrapper {
PacketValue readValue = readableObjects.poll(); PacketValue readValue = readableObjects.poll();
Type<?> readType = readValue.type(); Type<?> readType = readValue.type();
if (readType == type if (readType == type
|| (type.getBaseClass() == readType.getBaseClass() || (type.getBaseClass() == readType.getBaseClass()
&& type.getOutputClass() == readType.getOutputClass())) { && type.getOutputClass() == readType.getOutputClass())) {
//noinspection unchecked //noinspection unchecked
return (T) readValue.value(); return (T) readValue.value();
} else { } else {
@ -210,25 +207,24 @@ public class PacketWrapperImpl implements PacketWrapper {
readableObjects.clear(); readableObjects.clear();
} }
int index = 0; for (int i = 0; i < packetValues.size(); i++) {
for (final PacketValue<?> packetValue : packetValues) { PacketValue<?> packetValue = packetValues.get(i);
try { try {
packetValue.write(buffer); packetValue.write(buffer);
} catch (final Exception e) { } catch (final Exception e) {
throw createInformativeException(e, packetValue.type(), index); throw createInformativeException(e, packetValue.type(), i);
} }
index++;
} }
writeRemaining(buffer); writeRemaining(buffer);
} }
private InformativeException createInformativeException(final Exception cause, final Type<?> type, final int index) { private InformativeException createInformativeException(final Exception cause, final Type<?> type, final int index) {
return new InformativeException(cause) return new InformativeException(cause)
.set("Index", index) .set("Index", index)
.set("Type", type.getTypeName()) .set("Type", type.getTypeName())
.set("Packet ID", this.id) .set("Packet ID", this.id)
.set("Packet Type", this.packetType) .set("Packet Type", this.packetType)
.set("Data", this.packetValues); .set("Data", this.packetValues);
} }
@Override @Override
@ -298,46 +294,17 @@ public class PacketWrapperImpl implements PacketWrapper {
/** /**
* Let the packet go through the protocol pipes and write it to ByteBuf * Let the packet go through the protocol pipes and write it to ByteBuf
* *
* @param packetProtocol The protocol version of the packet. * @param protocolClass protocol class to send the packet from, or null to go through the full pipeline
* @param skipCurrentPipeline Skip the current pipeline * @param skipCurrentPipeline whether to start from the next protocol in the pipeline, or the provided one
* @return Packet buffer * @return created packet buffer
* @throws Exception if it fails to write * @throws Exception if it fails to write
*/ */
private ByteBuf constructPacket(Class<? extends Protocol> packetProtocol, boolean skipCurrentPipeline, Direction direction) throws Exception { private ByteBuf constructPacket(@Nullable Class<? extends Protocol> protocolClass, boolean skipCurrentPipeline, Direction direction) throws Exception {
resetReader(); // Reset reader before we start
final ProtocolInfo protocolInfo = user().getProtocolInfo(); final ProtocolInfo protocolInfo = user().getProtocolInfo();
final List<Protocol> pipes = direction == Direction.SERVERBOUND ? protocolInfo.getPipeline().pipes() : protocolInfo.getPipeline().reversedPipes(); final List<Protocol> protocols = protocolInfo.getPipeline().pipes(protocolClass, skipCurrentPipeline, direction);
final List<Protocol> protocols = new ArrayList<>(); apply(direction, protocolInfo.getState(direction), protocols);
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 ByteBuf output = inputBuffer == null ? user().getChannel().alloc().buffer() : inputBuffer.alloc().buffer(); final ByteBuf output = inputBuffer == null ? user().getChannel().alloc().buffer() : inputBuffer.alloc().buffer();
try { try {
writeToBuffer(output); writeToBuffer(output);
@ -348,9 +315,9 @@ public class PacketWrapperImpl implements PacketWrapper {
} }
@Override @Override
public ChannelFuture sendFuture(Class<? extends Protocol> packetProtocol) throws Exception { public ChannelFuture sendFuture(Class<? extends Protocol> protocolClass) throws Exception {
if (!isCancelled()) { if (!isCancelled()) {
ByteBuf output = constructPacket(packetProtocol, true, Direction.CLIENTBOUND); ByteBuf output = constructPacket(protocolClass, true, Direction.CLIENTBOUND);
return user().sendRawPacketFuture(output); return user().sendRawPacketFuture(output);
} }
return user().getChannel().newFailedFuture(new Exception("Cancelled packet")); return user().getChannel().newFailedFuture(new Exception("Cancelled packet"));
@ -397,33 +364,36 @@ public class PacketWrapperImpl implements PacketWrapper {
} }
@Override @Override
public PacketWrapperImpl apply(Direction direction, State state, int index, List<Protocol> pipeline, boolean reverse) throws Exception { public void apply(Direction direction, State state, List<Protocol> pipeline) throws Exception {
Protocol[] array = pipeline.toArray(PROTOCOL_ARRAY); // Indexed loop to allow additions to the tail
return apply(direction, state, reverse ? array.length - 1 : index, array, reverse); // Copy to prevent from removal 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 @Override
public PacketWrapperImpl apply(Direction direction, State state, int index, List<Protocol> pipeline) throws Exception { @Deprecated
return apply(direction, state, index, pipeline.toArray(PROTOCOL_ARRAY), false); public PacketWrapperImpl apply(Direction direction, State state, int index, List<Protocol> pipeline, boolean reverse) throws Exception {
}
private PacketWrapperImpl apply(Direction direction, State state, int index, Protocol[] pipeline, boolean reverse) throws Exception {
// Reset the reader after every transformation for the packetWrapper, so it can be recycled across packets // 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) { if (reverse) {
for (int i = index; i >= 0; i--) { for (int i = index; i >= 0; i--) {
pipeline[i].transform(direction, updatedState, this); pipeline.get(i).transform(direction, state, this);
resetReader(); resetReader();
if (this.packetType != null) { if (this.packetType != null) {
updatedState = this.packetType.state(); state = this.packetType.state();
} }
} }
} else { } else {
for (int i = index; i < pipeline.length; i++) { for (int i = index; i < pipeline.size(); i++) {
pipeline[i].transform(direction, updatedState, this); pipeline.get(i).transform(direction, state, this);
resetReader(); resetReader();
if (this.packetType != null) { if (this.packetType != null) {
updatedState = this.packetType.state(); state = this.packetType.state();
} }
} }
} }
@ -447,7 +417,7 @@ public class PacketWrapperImpl implements PacketWrapper {
@Override @Override
public void resetReader() { 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--) { for (int i = packetValues.size() - 1; i >= 0; i--) {
this.readableObjects.addFirst(this.packetValues.get(i)); this.readableObjects.addFirst(this.packetValues.get(i));
} }
@ -557,11 +527,11 @@ public class PacketWrapperImpl implements PacketWrapper {
@Override @Override
public String toString() { public String toString() {
return "PacketWrapper{" + return "PacketWrapper{" +
"type=" + packetType + "type=" + packetType +
", id=" + id + ", id=" + id +
", values=" + packetValues + ", values=" + packetValues +
", readable=" + readableObjects + ", readable=" + readableObjects +
'}'; '}';
} }
public static final class PacketValue<T> { public static final class PacketValue<T> {

Datei anzeigen

@ -33,6 +33,7 @@ import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.stream.Collectors;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
public class VersionedPacketTransformerImpl<C extends ClientboundPacketType, S extends ServerboundPacketType> implements VersionedPacketTransformer<C, S> { public class VersionedPacketTransformerImpl<C extends ClientboundPacketType, S extends ServerboundPacketType> implements VersionedPacketTransformer<C, S> {
@ -44,7 +45,7 @@ public class VersionedPacketTransformerImpl<C extends ClientboundPacketType, S e
public VersionedPacketTransformerImpl(ProtocolVersion inputVersion, @Nullable Class<C> clientboundPacketsClass, @Nullable Class<S> serverboundPacketsClass) { public VersionedPacketTransformerImpl(ProtocolVersion inputVersion, @Nullable Class<C> clientboundPacketsClass, @Nullable Class<S> serverboundPacketsClass) {
Preconditions.checkNotNull(inputVersion); Preconditions.checkNotNull(inputVersion);
Preconditions.checkArgument(clientboundPacketsClass != null || serverboundPacketsClass != null, 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.inputProtocolVersion = inputVersion;
this.clientboundPacketsClass = clientboundPacketsClass; this.clientboundPacketsClass = clientboundPacketsClass;
this.serverboundPacketsClass = serverboundPacketsClass; this.serverboundPacketsClass = serverboundPacketsClass;
@ -108,7 +109,7 @@ public class VersionedPacketTransformerImpl<C extends ClientboundPacketType, S e
} }
Class<? extends PacketType> expectedPacketClass = Class<? extends PacketType> expectedPacketClass =
packet.getPacketType().direction() == Direction.CLIENTBOUND ? clientboundPacketsClass : serverboundPacketsClass; packet.getPacketType().direction() == Direction.CLIENTBOUND ? clientboundPacketsClass : serverboundPacketsClass;
if (packet.getPacketType().getClass() != expectedPacketClass) { if (packet.getPacketType().getClass() != expectedPacketClass) {
throw new IllegalArgumentException("PacketWrapper packet type is of the wrong packet class"); throw new IllegalArgumentException("PacketWrapper packet type is of the wrong packet class");
} }
@ -139,34 +140,40 @@ public class VersionedPacketTransformerImpl<C extends ClientboundPacketType, S e
private void transformPacket(PacketWrapper packet) throws Exception { private void transformPacket(PacketWrapper packet) throws Exception {
// If clientbound: Constructor given inputProtocolVersion Client version // If clientbound: Constructor given inputProtocolVersion Client version
// If serverbound: Constructor given inputProtocolVersion Server version // If serverbound: Constructor given inputProtocolVersion Server version
PacketType packetType = packet.getPacketType();
UserConnection connection = packet.user(); UserConnection connection = packet.user();
PacketType packetType = packet.getPacketType();
boolean clientbound = packetType.direction() == Direction.CLIENTBOUND; boolean clientbound = packetType.direction() == Direction.CLIENTBOUND;
ProtocolVersion serverProtocolVersion = clientbound ? this.inputProtocolVersion : connection.getProtocolInfo().serverProtocolVersion(); ProtocolVersion serverProtocolVersion = clientbound ? this.inputProtocolVersion : connection.getProtocolInfo().serverProtocolVersion();
ProtocolVersion clientProtocolVersion = clientbound ? connection.getProtocolInfo().protocolVersion() : this.inputProtocolVersion; ProtocolVersion clientProtocolVersion = clientbound ? connection.getProtocolInfo().protocolVersion() : this.inputProtocolVersion;
// Construct protocol pipeline // Construct protocol pipeline
List<ProtocolPathEntry> path = Via.getManager().getProtocolManager().getProtocolPath(clientProtocolVersion, serverProtocolVersion); List<ProtocolPathEntry> path = Via.getManager().getProtocolManager().getProtocolPath(clientProtocolVersion, serverProtocolVersion);
List<Protocol> protocolList = null; if (path == null) {
if (path != null) { if (serverProtocolVersion != clientProtocolVersion) {
protocolList = new ArrayList<>(path.size()); throw new RuntimeException("No protocol path between client version " + clientProtocolVersion + " and server version " + serverProtocolVersion);
}
return;
}
final List<Protocol> 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) { for (ProtocolPathEntry entry : path) {
protocolList.add(entry.protocol()); 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
// Reset reader and apply pipeline packet.resetReader();
packet.resetReader();
try { try {
packet.apply(packetType.direction(), State.PLAY, 0, protocolList, clientbound); packet.apply(packetType.direction(), packetType.state(), protocolList);
} catch (Exception e) { } catch (Exception e) {
throw new Exception("Exception trying to transform packet between client version " + clientProtocolVersion 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); + " and server version " + serverProtocolVersion + ". Are you sure you used the correct input version and packet write types?", e);
}
} }
} }

Datei anzeigen

@ -22,6 +22,7 @@ import com.viaversion.viaversion.api.connection.ProtocolInfo;
import com.viaversion.viaversion.api.platform.providers.ViaProviders; import com.viaversion.viaversion.api.platform.providers.ViaProviders;
import com.viaversion.viaversion.api.protocol.AbstractProtocol; import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.protocol.Protocol; 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.ProtocolPathEntry;
import com.viaversion.viaversion.api.protocol.ProtocolPipeline; import com.viaversion.viaversion.api.protocol.ProtocolPipeline;
import com.viaversion.viaversion.api.protocol.packet.Direction; import com.viaversion.viaversion.api.protocol.packet.Direction;
@ -72,18 +73,25 @@ public class BaseProtocol extends AbstractProtocol<BaseClientboundPacket, BaseCl
List<ProtocolPathEntry> protocolPath = null; List<ProtocolPathEntry> 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)
ProtocolManager protocolManager = Via.getManager().getProtocolManager();
if (info.protocolVersion().newerThanOrEqualTo(serverProtocol) || Via.getPlatform().isOldClientsAllowed()) { 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) { if (protocolPath != null) {
List<Protocol> protocols = new ArrayList<>(protocolPath.size()); List<Protocol> protocols = new ArrayList<>(protocolPath.size());
for (ProtocolPathEntry entry : protocolPath) { for (ProtocolPathEntry entry : protocolPath) {
protocols.add(entry.protocol()); protocols.add(entry.protocol());
// Ensure mapping data has already been loaded // Ensure mapping data has already been loaded
Via.getManager().getProtocolManager().completeMappingDataLoading(entry.protocol().getClass()); protocolManager.completeMappingDataLoading(entry.protocol().getClass());
} }
// Add protocols to pipeline // Add protocols to pipeline
@ -93,11 +101,6 @@ public class BaseProtocol extends AbstractProtocol<BaseClientboundPacket, BaseCl
wrapper.set(Type.VAR_INT, 0, serverProtocol.getOriginalVersion()); wrapper.set(Type.VAR_INT, 0, serverProtocol.getOriginalVersion());
} }
// Add Base Protocol
if (!serverProtocol.getVersionType().equals(VersionType.SPECIAL)) {
pipeline.add(Via.getManager().getProtocolManager().getBaseProtocol(serverProtocol));
}
if (Via.getManager().isDebug()) { if (Via.getManager().isDebug()) {
Via.getPlatform().getLogger().info("User connected with protocol: " + info.protocolVersion() + " and serverProtocol: " + info.serverProtocolVersion()); Via.getPlatform().getLogger().info("User connected with protocol: " + info.protocolVersion() + " and serverProtocol: " + info.serverProtocolVersion());
Via.getPlatform().getLogger().info("Protocol pipeline: " + pipeline.pipes()); Via.getPlatform().getLogger().info("Protocol pipeline: " + pipeline.pipes());

Datei anzeigen

@ -168,7 +168,7 @@ public class BaseProtocol1_7 extends AbstractProtocol<BaseClientboundPacket, Bas
wrapper.cancel(); // cancel current wrapper.cancel(); // cancel current
// Send and close // Send and close
ChannelFuture future = disconnectPacket.sendFuture(BaseProtocol.class); ChannelFuture future = disconnectPacket.sendFuture(null);
future.addListener(f -> wrapper.user().getChannel().close()); future.addListener(f -> wrapper.user().getChannel().close());
} }
}); });

Datei anzeigen

@ -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.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_11.EntityType; import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_11.EntityType;
import com.viaversion.viaversion.data.entity.EntityTrackerBase; import com.viaversion.viaversion.data.entity.EntityTrackerBase;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet; import it.unimi.dsi.fastutil.ints.IntSet;
import space.vectrix.flare.fastutil.Int2ObjectSyncMap;
public class EntityTracker1_11 extends EntityTrackerBase { public class EntityTracker1_11 extends EntityTrackerBase {
private final IntSet holograms = Int2ObjectSyncMap.hashset(); private final IntSet holograms = new IntOpenHashSet();
public EntityTracker1_11(UserConnection user) { public EntityTracker1_11(UserConnection user) {
super(user, EntityType.PLAYER); super(user, EntityType.PLAYER);

Datei anzeigen

@ -21,13 +21,13 @@ import com.viaversion.viaversion.api.connection.StorableObject;
import com.viaversion.viaversion.api.minecraft.Position; import com.viaversion.viaversion.api.minecraft.Position;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet; import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet; import it.unimi.dsi.fastutil.ints.IntSet;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import space.vectrix.flare.SyncMap;
// TODO Fix memory leak lolz (only a smol one tho) // TODO Fix memory leak lolz (only a smol one tho)
public class BlockStorage implements StorableObject { public class BlockStorage implements StorableObject {
private static final IntSet WHITELIST = new IntOpenHashSet(46, .99F); private static final IntSet WHITELIST = new IntOpenHashSet(46, .99F);
private final Map<Position, ReplacementData> blocks = SyncMap.hashmap(); private final Map<Position, ReplacementData> blocks = new HashMap<>();
static { static {
// Flower pots // Flower pots

Datei anzeigen

@ -21,13 +21,13 @@ import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_14; import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_14;
import com.viaversion.viaversion.data.entity.EntityTrackerBase; import com.viaversion.viaversion.data.entity.EntityTrackerBase;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; 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 { public class EntityTracker1_14 extends EntityTrackerBase {
private final Int2ObjectMap<Byte> insentientData = Int2ObjectSyncMap.hashmap(); private final Int2ObjectMap<Byte> insentientData = new Int2ObjectOpenHashMap<>();
// 0x1 = sleeping, 0x2 = riptide // 0x1 = sleeping, 0x2 = riptide
private final Int2ObjectMap<Byte> sleepingAndRiptideData = Int2ObjectSyncMap.hashmap(); private final Int2ObjectMap<Byte> sleepingAndRiptideData = new Int2ObjectOpenHashMap<>();
private final Int2ObjectMap<Byte> playerEntityFlags = Int2ObjectSyncMap.hashmap(); private final Int2ObjectMap<Byte> playerEntityFlags = new Int2ObjectOpenHashMap<>();
private int latestTradeWindowId; private int latestTradeWindowId;
private boolean forceSendCenterChunk = true; private boolean forceSendCenterChunk = true;
private int chunkCenterX; private int chunkCenterX;

Datei anzeigen

@ -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.metadata.MetadataRewriter1_9To1_8;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.BossBarProvider; import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.BossBarProvider;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.EntityIdProvider; 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.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet; import it.unimi.dsi.fastutil.ints.IntSet;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import space.vectrix.flare.fastutil.Int2ObjectSyncMap;
public class EntityTracker1_9 extends EntityTrackerBase { public class EntityTracker1_9 extends EntityTrackerBase {
public static final String WITHER_TRANSLATABLE = "{\"translate\":\"entity.WitherBoss.name\"}"; public static final String WITHER_TRANSLATABLE = "{\"translate\":\"entity.WitherBoss.name\"}";
public static final String DRAGON_TRANSLATABLE = "{\"translate\":\"entity.EnderDragon.name\"}"; public static final String DRAGON_TRANSLATABLE = "{\"translate\":\"entity.EnderDragon.name\"}";
private final Int2ObjectMap<UUID> uuidMap = Int2ObjectSyncMap.hashmap(); private final Int2ObjectMap<UUID> uuidMap = new Int2ObjectOpenHashMap<>();
private final Int2ObjectMap<List<Metadata>> metadataBuffer = Int2ObjectSyncMap.hashmap(); private final Int2ObjectMap<List<Metadata>> metadataBuffer = new Int2ObjectOpenHashMap<>();
private final Int2ObjectMap<Integer> vehicleMap = Int2ObjectSyncMap.hashmap(); private final Int2IntMap vehicleMap = new Int2IntOpenHashMap();
private final Int2ObjectMap<BossBar> bossBarMap = Int2ObjectSyncMap.hashmap(); private final Int2ObjectMap<BossBar> bossBarMap = new Int2ObjectOpenHashMap<>();
private final IntSet validBlocking = Int2ObjectSyncMap.hashset(); private final IntSet validBlocking = new IntOpenHashSet();
private final Set<Integer> knownHolograms = Int2ObjectSyncMap.hashset(); private final IntSet knownHolograms = new IntOpenHashSet();
private final Set<Position> blockInteractions = Collections.newSetFromMap(CacheBuilder.newBuilder() private final Set<Position> blockInteractions = Collections.newSetFromMap(CacheBuilder.newBuilder()
.maximumSize(1000) .maximumSize(1000)
.expireAfterAccess(250, TimeUnit.MILLISECONDS) .expireAfterAccess(250, TimeUnit.MILLISECONDS)
@ -368,27 +370,27 @@ public class EntityTracker1_9 extends EntityTrackerBase {
} }
} }
public Map<Integer, UUID> getUuidMap() { public Int2ObjectMap<UUID> getUuidMap() {
return uuidMap; return uuidMap;
} }
public Map<Integer, List<Metadata>> getMetadataBuffer() { public Int2ObjectMap<List<Metadata>> getMetadataBuffer() {
return metadataBuffer; return metadataBuffer;
} }
public Map<Integer, Integer> getVehicleMap() { public Int2IntMap getVehicleMap() {
return vehicleMap; return vehicleMap;
} }
public Map<Integer, BossBar> getBossBarMap() { public Int2ObjectMap<BossBar> getBossBarMap() {
return bossBarMap; return bossBarMap;
} }
public Set<Integer> getValidBlocking() { public IntSet getValidBlocking() {
return validBlocking; return validBlocking;
} }
public Set<Integer> getKnownHolograms() { public IntSet getKnownHolograms() {
return knownHolograms; return knownHolograms;
} }

Datei anzeigen

@ -4,7 +4,6 @@ metadata.format.version = "1.1"
gson = "2.10.1" gson = "2.10.1"
fastutil = "8.5.12" fastutil = "8.5.12"
flare = "2.0.1"
vianbt = "4.2.0" vianbt = "4.2.0"
mcstructs = "2.4.2-SNAPSHOT" mcstructs = "2.4.2-SNAPSHOT"
@ -29,8 +28,6 @@ velocity = "3.1.1"
gson = { group = "com.google.code.gson", name = "gson", version.ref = "gson" } gson = { group = "com.google.code.gson", name = "gson", version.ref = "gson" }
fastutil = { group = "it.unimi.dsi", name = "fastutil", version.ref = "fastutil" } 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" } vianbt = { group = "com.viaversion", name = "nbt", version.ref = "vianbt" }
# Custom version that uses ViaNBT instead of its own inbuilt NBT library # Custom version that uses ViaNBT instead of its own inbuilt NBT library
text = { group = "com.viaversion.mcstructs", name = "text", version.ref = "mcstructs" } text = { group = "com.viaversion.mcstructs", name = "text", version.ref = "mcstructs" }