3
0
Mirror von https://github.com/ViaVersion/ViaVersion.git synchronisiert 2024-12-30 18:10:12 +01:00

Add method to get Protocol by supported versions, some cleanup

Dieser Commit ist enthalten in:
KennyTV 2021-05-29 20:53:47 +02:00
Ursprung ff140c421a
Commit 3618914ce9
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 6BE3B555EBC5982B
7 geänderte Dateien mit 110 neuen und 87 gelöschten Zeilen

Datei anzeigen

@ -53,6 +53,28 @@ public interface ProtocolManager {
*/ */
@Nullable <T extends Protocol> T getProtocol(Class<T> protocolClass); @Nullable <T extends Protocol> T getProtocol(Class<T> protocolClass);
/**
* Returns a protocol transforming packets for server version to the given client version.
*
* @param clientVersion client protocol version
* @param serverVersion server protocol version
* @return protocol if present, else null
* @see #getProtocolPath(int, int) to get a full path of Protocols between a larger gap of versions
*/
default @Nullable Protocol getProtocol(ProtocolVersion clientVersion, ProtocolVersion serverVersion) {
return getProtocol(clientVersion.getVersion(), serverVersion.getVersion());
}
/**
* Returns a protocol transforming packets for server version to the given client version.
*
* @param clientVersion client protocol version
* @param serverVersion server protocol version
* @return protocol if present, else null
* @see #getProtocolPath(int, int) to get a full path of Protocols between a larger gap of versions
*/
@Nullable Protocol getProtocol(int clientVersion, int serverVersion);
/** /**
* Returns the base protocol handling serverbound handshake packets. * Returns the base protocol handling serverbound handshake packets.
* *
@ -85,36 +107,36 @@ public interface ProtocolManager {
* Register a protocol. * Register a protocol.
* *
* @param protocol protocol to register * @param protocol protocol to register
* @param supported supported client versions * @param clientVersion supported client protocol versions
* @param output output server version the protocol converts to * @param serverVersion output server protocol version the protocol converts to
*/ */
void registerProtocol(Protocol protocol, ProtocolVersion supported, ProtocolVersion output); void registerProtocol(Protocol protocol, ProtocolVersion clientVersion, ProtocolVersion serverVersion);
/** /**
* Register a protocol. * Register a protocol.
* *
* @param protocol protocol to register * @param protocol protocol to register
* @param supported supported client versions * @param supportedClientVersion supported client protocol versions
* @param output output server version the protocol converts to * @param serverVersion output server protocol version the protocol converts to
*/ */
void registerProtocol(Protocol protocol, List<Integer> supported, int output); void registerProtocol(Protocol protocol, List<Integer> supportedClientVersion, int serverVersion);
/** /**
* Registers a base protocol. Base Protocols registered later have higher priority. * Registers a base protocol. Base Protocols registered later have higher priority.
* Only base protocol will always be added to pipeline. * Only base protocol will always be added to pipeline.
* *
* @param baseProtocol base protocol to register * @param baseProtocol base protocol to register
* @param supportedProtocols versions supported by the base protocol * @param supportedProtocols protocol versions supported by the base protocol
* @throws IllegalArgumentException if the protocol is not a base protocol as given by {@link Protocol#isBaseProtocol()} * @throws IllegalArgumentException if the protocol is not a base protocol as given by {@link Protocol#isBaseProtocol()}
*/ */
void registerBaseProtocol(Protocol baseProtocol, Range<Integer> supportedProtocols); void registerBaseProtocol(Protocol baseProtocol, Range<Integer> supportedProtocols);
/** /**
* Calculates and returns the protocol path from a client version to server version. * Calculates and returns the protocol path from a client protocol version to server protocol version.
* Returns null if no path could be found or the path length exceeds the value given by {@link #getMaxProtocolPathSize()}. * Returns null if no path could be found or the path length exceeds the value given by {@link #getMaxProtocolPathSize()}.
* *
* @param clientVersion input client version * @param clientVersion input client protocol version
* @param serverVersion desired output server version * @param serverVersion desired output server protocol version
* @return path generated, or null if not supported or the length exceeds {@link #getMaxProtocolPathSize()} * @return path generated, or null if not supported or the length exceeds {@link #getMaxProtocolPathSize()}
*/ */
@Nullable List<ProtocolPathEntry> getProtocolPath(int clientVersion, int serverVersion); @Nullable List<ProtocolPathEntry> getProtocolPath(int clientVersion, int serverVersion);
@ -135,9 +157,9 @@ public interface ProtocolManager {
void setMaxProtocolPathSize(int maxProtocolPathSize); void setMaxProtocolPathSize(int maxProtocolPathSize);
/** /**
* Returns the versions compatible with the server. * Returns the protocol versions compatible with the server.
* *
* @return sorted, immutable set of supported versions * @return sorted, immutable set of supported protocol versions
*/ */
SortedSet<Integer> getSupportedVersions(); SortedSet<Integer> getSupportedVersions();

Datei anzeigen

@ -26,11 +26,12 @@ import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.api.type.Type;
public abstract class BaseChunkType extends Type<Chunk> { public abstract class BaseChunkType extends Type<Chunk> {
public BaseChunkType() {
protected BaseChunkType() {
super(Chunk.class); super(Chunk.class);
} }
public BaseChunkType(String typeName) { protected BaseChunkType(String typeName) {
super(typeName, Chunk.class); super(typeName, Chunk.class);
} }

Datei anzeigen

@ -26,11 +26,12 @@ import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.api.type.Type;
public abstract class BaseItemArrayType extends Type<Item[]> { public abstract class BaseItemArrayType extends Type<Item[]> {
public BaseItemArrayType() {
protected BaseItemArrayType() {
super(Item[].class); super(Item[].class);
} }
public BaseItemArrayType(String typeName) { protected BaseItemArrayType(String typeName) {
super(typeName, Item[].class); super(typeName, Item[].class);
} }

Datei anzeigen

@ -26,11 +26,12 @@ import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.api.type.Type;
public abstract class BaseItemType extends Type<Item> { public abstract class BaseItemType extends Type<Item> {
public BaseItemType() {
protected BaseItemType() {
super(Item.class); super(Item.class);
} }
public BaseItemType(String typeName) { protected BaseItemType(String typeName) {
super(typeName, Item.class); super(typeName, Item.class);
} }

Datei anzeigen

@ -160,12 +160,12 @@ public class ProtocolManagerImpl implements ProtocolManager {
} }
@Override @Override
public void registerProtocol(Protocol protocol, ProtocolVersion supported, ProtocolVersion output) { public void registerProtocol(Protocol protocol, ProtocolVersion clientVersion, ProtocolVersion serverVersion) {
registerProtocol(protocol, Collections.singletonList(supported.getVersion()), output.getVersion()); registerProtocol(protocol, Collections.singletonList(clientVersion.getVersion()), serverVersion.getVersion());
} }
@Override @Override
public void registerProtocol(Protocol protocol, List<Integer> supported, int output) { public void registerProtocol(Protocol protocol, List<Integer> supportedClientVersion, int serverVersion) {
// Clear cache as this may make new routes. // Clear cache as this may make new routes.
if (!pathCache.isEmpty()) { if (!pathCache.isEmpty()) {
pathCache.clear(); pathCache.clear();
@ -173,9 +173,9 @@ public class ProtocolManagerImpl implements ProtocolManager {
protocols.put(protocol.getClass(), protocol); protocols.put(protocol.getClass(), protocol);
for (int version : supported) { for (int version : supportedClientVersion) {
Int2ObjectMap<Protocol> protocolMap = registryMap.computeIfAbsent(version, s -> new Int2ObjectOpenHashMap<>(2)); Int2ObjectMap<Protocol> protocolMap = registryMap.computeIfAbsent(version, s -> new Int2ObjectOpenHashMap<>(2));
protocolMap.put(output, protocol); protocolMap.put(serverVersion, protocol);
} }
if (Via.getPlatform().isPluginEnabled()) { if (Via.getPlatform().isPluginEnabled()) {
@ -249,6 +249,7 @@ public class ProtocolManagerImpl implements ProtocolManager {
* @return path that has been generated, null if failed * @return path that has been generated, null if failed
*/ */
private @Nullable List<ProtocolPathEntry> getProtocolPath(List<ProtocolPathEntry> current, int clientVersion, int serverVersion) { private @Nullable List<ProtocolPathEntry> getProtocolPath(List<ProtocolPathEntry> current, int clientVersion, int serverVersion) {
//TODO optimize?
if (clientVersion == serverVersion) return null; // We're already there if (clientVersion == serverVersion) return null; // We're already there
if (current.size() > maxProtocolPathSize) return null; // Fail safe, protocol too complicated. if (current.size() > maxProtocolPathSize) return null; // Fail safe, protocol too complicated.
@ -297,6 +298,12 @@ public class ProtocolManagerImpl implements ProtocolManager {
return (T) protocols.get(protocolClass); return (T) protocols.get(protocolClass);
} }
@Override
public @Nullable Protocol getProtocol(int clientVersion, int serverVersion) {
Int2ObjectMap<Protocol> map = registryMap.get(clientVersion);
return map != null ? map.get(serverVersion) : null;
}
@Override @Override
public Protocol getBaseProtocol(int serverVersion) { public Protocol getBaseProtocol(int serverVersion) {
for (Pair<Range<Integer>, Protocol> rangeProtocol : Lists.reverse(baseProtocols)) { for (Pair<Range<Integer>, Protocol> rangeProtocol : Lists.reverse(baseProtocols)) {

Datei anzeigen

@ -63,13 +63,12 @@ public class PacketWrapperImpl implements PacketWrapper {
public <T> T get(Type<T> type, int index) throws Exception { public <T> T get(Type<T> type, int index) throws Exception {
int currentIndex = 0; int currentIndex = 0;
for (Pair<Type, Object> packetValue : packetValues) { for (Pair<Type, Object> packetValue : packetValues) {
if (packetValue.getKey() == type) { // Ref check if (packetValue.getKey() != type) continue;
if (currentIndex == index) { if (currentIndex == index) {
return (T) packetValue.getValue(); return (T) packetValue.getValue();
} }
currentIndex++; currentIndex++;
} }
}
Exception e = new ArrayIndexOutOfBoundsException("Could not find type " + type.getTypeName() + " at " + index); Exception e = new ArrayIndexOutOfBoundsException("Could not find type " + type.getTypeName() + " at " + index);
throw new InformativeException(e).set("Type", type.getTypeName()).set("Index", index).set("Packet ID", getId()).set("Data", packetValues); throw new InformativeException(e).set("Type", type.getTypeName()).set("Index", index).set("Packet ID", getId()).set("Data", packetValues);
@ -79,13 +78,12 @@ public class PacketWrapperImpl implements PacketWrapper {
public boolean is(Type type, int index) { public boolean is(Type type, int index) {
int currentIndex = 0; int currentIndex = 0;
for (Pair<Type, Object> packetValue : packetValues) { for (Pair<Type, Object> packetValue : packetValues) {
if (packetValue.getKey() == type) { // Ref check if (packetValue.getKey() != type) continue;
if (currentIndex == index) { if (currentIndex == index) {
return true; return true;
} }
currentIndex++; currentIndex++;
} }
}
return false; return false;
} }
@ -93,13 +91,12 @@ public class PacketWrapperImpl implements PacketWrapper {
public boolean isReadable(Type type, int index) { public boolean isReadable(Type type, int index) {
int currentIndex = 0; int currentIndex = 0;
for (Pair<Type, Object> packetValue : readableObjects) { for (Pair<Type, Object> packetValue : readableObjects) {
if (packetValue.getKey().getBaseClass() == type.getBaseClass()) { // Ref check if (packetValue.getKey().getBaseClass() != type.getBaseClass()) continue;
if (currentIndex == index) { if (currentIndex == index) {
return true; return true;
} }
currentIndex++; currentIndex++;
} }
}
return false; return false;
} }
@ -108,14 +105,13 @@ public class PacketWrapperImpl implements PacketWrapper {
public <T> void set(Type<T> type, int index, T value) throws Exception { public <T> void set(Type<T> type, int index, T value) throws Exception {
int currentIndex = 0; int currentIndex = 0;
for (Pair<Type, Object> packetValue : packetValues) { for (Pair<Type, Object> packetValue : packetValues) {
if (packetValue.getKey() == type) { // Ref check if (packetValue.getKey() != type) continue;
if (currentIndex == index) { if (currentIndex == index) {
packetValue.setValue(value); packetValue.setValue(attemptTransform(type, value));
return; return;
} }
currentIndex++; currentIndex++;
} }
}
Exception e = new ArrayIndexOutOfBoundsException("Could not find type " + type.getTypeName() + " at " + index); Exception e = new ArrayIndexOutOfBoundsException("Could not find type " + type.getTypeName() + " at " + index);
throw new InformativeException(e).set("Type", type.getTypeName()).set("Index", index).set("Packet ID", getId()); throw new InformativeException(e).set("Type", type.getTypeName()).set("Index", index).set("Packet ID", getId());
} }
@ -131,37 +127,44 @@ public class PacketWrapperImpl implements PacketWrapper {
} catch (Exception e) { } catch (Exception e) {
throw new InformativeException(e).set("Type", type.getTypeName()).set("Packet ID", getId()).set("Data", packetValues); throw new InformativeException(e).set("Type", type.getTypeName()).set("Packet ID", getId()).set("Data", packetValues);
} }
} else { }
Pair<Type, Object> read = readableObjects.poll(); Pair<Type, Object> read = readableObjects.poll();
Type rtype = read.getKey(); Type rtype = read.getKey();
if (rtype.equals(type) if (rtype == type
|| (type.getBaseClass().equals(rtype.getBaseClass()) || (type.getBaseClass() == rtype.getBaseClass()
&& type.getOutputClass().equals(rtype.getOutputClass()))) { && type.getOutputClass() == rtype.getOutputClass())) {
return (T) read.getValue(); return (T) read.getValue();
} else { } else if (rtype == Type.NOTHING) {
if (rtype == Type.NOTHING) {
return read(type); // retry return read(type); // retry
} else { } else {
Exception e = new IOException("Unable to read type " + type.getTypeName() + ", found " + read.getKey().getTypeName()); Exception e = new IOException("Unable to read type " + type.getTypeName() + ", found " + read.getKey().getTypeName());
throw new InformativeException(e).set("Type", type.getTypeName()).set("Packet ID", getId()).set("Data", packetValues); throw new InformativeException(e).set("Type", type.getTypeName()).set("Packet ID", getId()).set("Data", packetValues);
} }
} }
}
}
@Override @Override
public <T> void write(Type<T> type, T value) { public <T> void write(Type<T> type, T value) {
if (value != null) { packetValues.add(new Pair<>(type, attemptTransform(type, value)));
if (!type.getOutputClass().isAssignableFrom(value.getClass())) {
// attempt conversion
if (type instanceof TypeConverter) {
value = (T) ((TypeConverter) type).from(value);
} else {
Via.getPlatform().getLogger().warning("Possible type mismatch: " + value.getClass().getName() + " -> " + type.getOutputClass());
} }
/**
* Returns the value if already matching, else the converted value or possibly unmatched value.
*
* @param expectedType expected type
* @param value value
* @return value if already matching, else the converted value or possibly unmatched value
*/
private @Nullable Object attemptTransform(Type<?> expectedType, @Nullable Object value) {
if (value != null && !expectedType.getOutputClass().isAssignableFrom(value.getClass())) {
// Attempt conversion
if (expectedType instanceof TypeConverter) {
return ((TypeConverter) expectedType).from(value);
} }
Via.getPlatform().getLogger().warning("Possible type mismatch: " + value.getClass().getName() + " -> " + expectedType.getOutputClass());
} }
packetValues.add(new Pair<>(type, value)); return value;
} }
@Override @Override
@ -195,18 +198,7 @@ public class PacketWrapperImpl implements PacketWrapper {
int index = 0; int index = 0;
for (Pair<Type, Object> packetValue : packetValues) { for (Pair<Type, Object> packetValue : packetValues) {
try { try {
Object value = packetValue.getValue(); packetValue.getKey().write(buffer, packetValue.getValue());
if (value != null) {
if (!packetValue.getKey().getOutputClass().isAssignableFrom(value.getClass())) {
// attempt conversion
if (packetValue.getKey() instanceof TypeConverter) {
value = ((TypeConverter) packetValue.getKey()).from(value);
} else {
Via.getPlatform().getLogger().warning("Possible type mismatch: " + value.getClass().getName() + " -> " + packetValue.getKey().getOutputClass());
}
}
}
packetValue.getKey().write(buffer, value);
} catch (Exception e) { } catch (Exception e) {
throw new InformativeException(e).set("Index", index).set("Type", packetValue.getKey().getTypeName()).set("Packet ID", getId()).set("Data", packetValues); throw new InformativeException(e).set("Index", index).set("Type", packetValue.getKey().getTypeName()).set("Packet ID", getId()).set("Data", packetValues);
} }
@ -428,8 +420,7 @@ public class PacketWrapperImpl implements PacketWrapper {
this.id = id; this.id = id;
} }
@Nullable public @Nullable ByteBuf getInputBuffer() {
public ByteBuf getInputBuffer() {
return inputBuffer; return inputBuffer;
} }

Datei anzeigen

@ -55,13 +55,14 @@ public class BaseProtocol extends AbstractSimpleProtocol {
ProtocolInfo info = wrapper.user().getProtocolInfo(); ProtocolInfo info = wrapper.user().getProtocolInfo();
info.setProtocolVersion(protocolVersion); info.setProtocolVersion(protocolVersion);
// Ensure the server has a version provider // Ensure the server has a version provider
if (Via.getManager().getProviders().get(VersionProvider.class) == null) { VersionProvider versionProvider = Via.getManager().getProviders().get(VersionProvider.class);
if (versionProvider == null) {
wrapper.user().setActive(false); wrapper.user().setActive(false);
return; return;
} }
// Choose the pipe // Choose the pipe
int serverProtocol = Via.getManager().getProviders().get(VersionProvider.class).getClosestServerProtocol(wrapper.user()); int serverProtocol = versionProvider.getClosestServerProtocol(wrapper.user());
info.setServerProtocolVersion(serverProtocol); info.setServerProtocolVersion(serverProtocol);
List<ProtocolPathEntry> protocolPath = null; List<ProtocolPathEntry> protocolPath = null;
@ -94,8 +95,7 @@ public class BaseProtocol extends AbstractSimpleProtocol {
// Change state // Change state
if (state == 1) { if (state == 1) {
info.setState(State.STATUS); info.setState(State.STATUS);
} } else if (state == 2) {
if (state == 2) {
info.setState(State.LOGIN); info.setState(State.LOGIN);
} }
}); });