Mirror von
https://github.com/ViaVersion/ViaVersion.git
synchronisiert 2024-12-27 16:40:10 +01:00
Add method to get Protocol by supported versions, some cleanup
Dieser Commit ist enthalten in:
Ursprung
ff140c421a
Commit
3618914ce9
@ -53,6 +53,28 @@ public interface ProtocolManager {
|
||||
*/
|
||||
@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.
|
||||
*
|
||||
@ -84,37 +106,37 @@ public interface ProtocolManager {
|
||||
/**
|
||||
* Register a protocol.
|
||||
*
|
||||
* @param protocol protocol to register
|
||||
* @param supported supported client versions
|
||||
* @param output output server version the protocol converts to
|
||||
* @param protocol protocol to register
|
||||
* @param clientVersion supported client protocol versions
|
||||
* @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.
|
||||
*
|
||||
* @param protocol protocol to register
|
||||
* @param supported supported client versions
|
||||
* @param output output server version the protocol converts to
|
||||
* @param protocol protocol to register
|
||||
* @param supportedClientVersion supported client protocol versions
|
||||
* @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.
|
||||
* Only base protocol will always be added to pipeline.
|
||||
*
|
||||
* @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()}
|
||||
*/
|
||||
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()}.
|
||||
*
|
||||
* @param clientVersion input client version
|
||||
* @param serverVersion desired output server version
|
||||
* @param clientVersion input client protocol version
|
||||
* @param serverVersion desired output server protocol version
|
||||
* @return path generated, or null if not supported or the length exceeds {@link #getMaxProtocolPathSize()}
|
||||
*/
|
||||
@Nullable List<ProtocolPathEntry> getProtocolPath(int clientVersion, int serverVersion);
|
||||
@ -135,9 +157,9 @@ public interface ProtocolManager {
|
||||
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();
|
||||
|
||||
|
@ -26,11 +26,12 @@ import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
|
||||
public abstract class BaseChunkType extends Type<Chunk> {
|
||||
public BaseChunkType() {
|
||||
|
||||
protected BaseChunkType() {
|
||||
super(Chunk.class);
|
||||
}
|
||||
|
||||
public BaseChunkType(String typeName) {
|
||||
protected BaseChunkType(String typeName) {
|
||||
super(typeName, Chunk.class);
|
||||
}
|
||||
|
||||
|
@ -26,11 +26,12 @@ import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
|
||||
public abstract class BaseItemArrayType extends Type<Item[]> {
|
||||
public BaseItemArrayType() {
|
||||
|
||||
protected BaseItemArrayType() {
|
||||
super(Item[].class);
|
||||
}
|
||||
|
||||
public BaseItemArrayType(String typeName) {
|
||||
protected BaseItemArrayType(String typeName) {
|
||||
super(typeName, Item[].class);
|
||||
}
|
||||
|
||||
|
@ -26,11 +26,12 @@ import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
|
||||
public abstract class BaseItemType extends Type<Item> {
|
||||
public BaseItemType() {
|
||||
|
||||
protected BaseItemType() {
|
||||
super(Item.class);
|
||||
}
|
||||
|
||||
public BaseItemType(String typeName) {
|
||||
protected BaseItemType(String typeName) {
|
||||
super(typeName, Item.class);
|
||||
}
|
||||
|
||||
|
@ -160,12 +160,12 @@ public class ProtocolManagerImpl implements ProtocolManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerProtocol(Protocol protocol, ProtocolVersion supported, ProtocolVersion output) {
|
||||
registerProtocol(protocol, Collections.singletonList(supported.getVersion()), output.getVersion());
|
||||
public void registerProtocol(Protocol protocol, ProtocolVersion clientVersion, ProtocolVersion serverVersion) {
|
||||
registerProtocol(protocol, Collections.singletonList(clientVersion.getVersion()), serverVersion.getVersion());
|
||||
}
|
||||
|
||||
@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.
|
||||
if (!pathCache.isEmpty()) {
|
||||
pathCache.clear();
|
||||
@ -173,9 +173,9 @@ public class ProtocolManagerImpl implements ProtocolManager {
|
||||
|
||||
protocols.put(protocol.getClass(), protocol);
|
||||
|
||||
for (int version : supported) {
|
||||
for (int version : supportedClientVersion) {
|
||||
Int2ObjectMap<Protocol> protocolMap = registryMap.computeIfAbsent(version, s -> new Int2ObjectOpenHashMap<>(2));
|
||||
protocolMap.put(output, protocol);
|
||||
protocolMap.put(serverVersion, protocol);
|
||||
}
|
||||
|
||||
if (Via.getPlatform().isPluginEnabled()) {
|
||||
@ -249,6 +249,7 @@ public class ProtocolManagerImpl implements ProtocolManager {
|
||||
* @return path that has been generated, null if failed
|
||||
*/
|
||||
private @Nullable List<ProtocolPathEntry> getProtocolPath(List<ProtocolPathEntry> current, int clientVersion, int serverVersion) {
|
||||
//TODO optimize?
|
||||
if (clientVersion == serverVersion) return null; // We're already there
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Protocol getProtocol(int clientVersion, int serverVersion) {
|
||||
Int2ObjectMap<Protocol> map = registryMap.get(clientVersion);
|
||||
return map != null ? map.get(serverVersion) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Protocol getBaseProtocol(int serverVersion) {
|
||||
for (Pair<Range<Integer>, Protocol> rangeProtocol : Lists.reverse(baseProtocols)) {
|
||||
|
@ -63,12 +63,11 @@ public class PacketWrapperImpl implements PacketWrapper {
|
||||
public <T> T get(Type<T> type, int index) throws Exception {
|
||||
int currentIndex = 0;
|
||||
for (Pair<Type, Object> packetValue : packetValues) {
|
||||
if (packetValue.getKey() == type) { // Ref check
|
||||
if (currentIndex == index) {
|
||||
return (T) packetValue.getValue();
|
||||
}
|
||||
currentIndex++;
|
||||
if (packetValue.getKey() != type) continue;
|
||||
if (currentIndex == index) {
|
||||
return (T) packetValue.getValue();
|
||||
}
|
||||
currentIndex++;
|
||||
}
|
||||
|
||||
Exception e = new ArrayIndexOutOfBoundsException("Could not find type " + type.getTypeName() + " at " + index);
|
||||
@ -79,12 +78,11 @@ public class PacketWrapperImpl implements PacketWrapper {
|
||||
public boolean is(Type type, int index) {
|
||||
int currentIndex = 0;
|
||||
for (Pair<Type, Object> packetValue : packetValues) {
|
||||
if (packetValue.getKey() == type) { // Ref check
|
||||
if (currentIndex == index) {
|
||||
return true;
|
||||
}
|
||||
currentIndex++;
|
||||
if (packetValue.getKey() != type) continue;
|
||||
if (currentIndex == index) {
|
||||
return true;
|
||||
}
|
||||
currentIndex++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -93,12 +91,11 @@ public class PacketWrapperImpl implements PacketWrapper {
|
||||
public boolean isReadable(Type type, int index) {
|
||||
int currentIndex = 0;
|
||||
for (Pair<Type, Object> packetValue : readableObjects) {
|
||||
if (packetValue.getKey().getBaseClass() == type.getBaseClass()) { // Ref check
|
||||
if (currentIndex == index) {
|
||||
return true;
|
||||
}
|
||||
currentIndex++;
|
||||
if (packetValue.getKey().getBaseClass() != type.getBaseClass()) continue;
|
||||
if (currentIndex == index) {
|
||||
return true;
|
||||
}
|
||||
currentIndex++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -108,13 +105,12 @@ public class PacketWrapperImpl implements PacketWrapper {
|
||||
public <T> void set(Type<T> type, int index, T value) throws Exception {
|
||||
int currentIndex = 0;
|
||||
for (Pair<Type, Object> packetValue : packetValues) {
|
||||
if (packetValue.getKey() == type) { // Ref check
|
||||
if (currentIndex == index) {
|
||||
packetValue.setValue(value);
|
||||
return;
|
||||
}
|
||||
currentIndex++;
|
||||
if (packetValue.getKey() != type) continue;
|
||||
if (currentIndex == index) {
|
||||
packetValue.setValue(attemptTransform(type, value));
|
||||
return;
|
||||
}
|
||||
currentIndex++;
|
||||
}
|
||||
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());
|
||||
@ -131,37 +127,44 @@ public class PacketWrapperImpl implements PacketWrapper {
|
||||
} catch (Exception e) {
|
||||
throw new InformativeException(e).set("Type", type.getTypeName()).set("Packet ID", getId()).set("Data", packetValues);
|
||||
}
|
||||
}
|
||||
|
||||
Pair<Type, Object> read = readableObjects.poll();
|
||||
Type rtype = read.getKey();
|
||||
if (rtype == type
|
||||
|| (type.getBaseClass() == rtype.getBaseClass()
|
||||
&& type.getOutputClass() == rtype.getOutputClass())) {
|
||||
return (T) read.getValue();
|
||||
} else if (rtype == Type.NOTHING) {
|
||||
return read(type); // retry
|
||||
} else {
|
||||
Pair<Type, Object> read = readableObjects.poll();
|
||||
Type rtype = read.getKey();
|
||||
if (rtype.equals(type)
|
||||
|| (type.getBaseClass().equals(rtype.getBaseClass())
|
||||
&& type.getOutputClass().equals(rtype.getOutputClass()))) {
|
||||
return (T) read.getValue();
|
||||
} else {
|
||||
if (rtype == Type.NOTHING) {
|
||||
return read(type); // retry
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void write(Type<T> type, T value) {
|
||||
if (value != null) {
|
||||
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());
|
||||
}
|
||||
packetValues.add(new Pair<>(type, attemptTransform(type, value)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
@ -195,18 +198,7 @@ public class PacketWrapperImpl implements PacketWrapper {
|
||||
int index = 0;
|
||||
for (Pair<Type, Object> packetValue : packetValues) {
|
||||
try {
|
||||
Object value = 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);
|
||||
packetValue.getKey().write(buffer, packetValue.getValue());
|
||||
} catch (Exception e) {
|
||||
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;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ByteBuf getInputBuffer() {
|
||||
public @Nullable ByteBuf getInputBuffer() {
|
||||
return inputBuffer;
|
||||
}
|
||||
|
||||
|
@ -55,13 +55,14 @@ public class BaseProtocol extends AbstractSimpleProtocol {
|
||||
ProtocolInfo info = wrapper.user().getProtocolInfo();
|
||||
info.setProtocolVersion(protocolVersion);
|
||||
// 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);
|
||||
return;
|
||||
}
|
||||
|
||||
// Choose the pipe
|
||||
int serverProtocol = Via.getManager().getProviders().get(VersionProvider.class).getClosestServerProtocol(wrapper.user());
|
||||
int serverProtocol = versionProvider.getClosestServerProtocol(wrapper.user());
|
||||
info.setServerProtocolVersion(serverProtocol);
|
||||
List<ProtocolPathEntry> protocolPath = null;
|
||||
|
||||
@ -94,8 +95,7 @@ public class BaseProtocol extends AbstractSimpleProtocol {
|
||||
// Change state
|
||||
if (state == 1) {
|
||||
info.setState(State.STATUS);
|
||||
}
|
||||
if (state == 2) {
|
||||
} else if (state == 2) {
|
||||
info.setState(State.LOGIN);
|
||||
}
|
||||
});
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren