288 lines
12 KiB
Java
288 lines
12 KiB
Java
/*
|
|
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
|
* Copyright (C) 2016-2021 ViaVersion and contributors
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in all
|
|
* copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
* SOFTWARE.
|
|
*/
|
|
package com.viaversion.viaversion.api.protocol;
|
|
|
|
import com.google.common.collect.Range;
|
|
import com.viaversion.viaversion.api.connection.UserConnection;
|
|
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
|
|
import com.viaversion.viaversion.api.protocol.packet.PacketType;
|
|
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
|
import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
|
|
import com.viaversion.viaversion.api.protocol.packet.VersionedPacketCreator;
|
|
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
|
|
import com.viaversion.viaversion.api.protocol.version.ServerProtocolVersion;
|
|
import io.netty.buffer.ByteBuf;
|
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
|
|
|
import java.util.List;
|
|
import java.util.SortedSet;
|
|
import java.util.concurrent.CompletableFuture;
|
|
|
|
public interface ProtocolManager {
|
|
|
|
/**
|
|
* Returns the server protocol version. Its methods will return -1 if not set yet.
|
|
*
|
|
* @return server protocol version
|
|
*/
|
|
ServerProtocolVersion getServerProtocolVersion();
|
|
|
|
/**
|
|
* Returns a protocol instance by its class.
|
|
*
|
|
* @param protocolClass class of the protocol
|
|
* @param <T> protocol
|
|
* @return protocol if present
|
|
*/
|
|
@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.
|
|
*
|
|
* @return base protocol
|
|
*/
|
|
Protocol getBaseProtocol();
|
|
|
|
/**
|
|
* Returns the base protocol for a specific server protocol version.
|
|
* The standard base protocols deal with status and login packets for userconnection initialization.
|
|
*
|
|
* @param serverVersion server protocol version
|
|
* @return base protocol for the given server protocol version
|
|
* @throws IllegalStateException if no base protocol could be found
|
|
*/
|
|
Protocol getBaseProtocol(int serverVersion);
|
|
|
|
/**
|
|
* Returns whether the given protocol is a base protocol.
|
|
*
|
|
* @param protocol protocol
|
|
* @return whether the protocol is a base protocol
|
|
* @see Protocol#isBaseProtocol()
|
|
*/
|
|
default boolean isBaseProtocol(Protocol protocol) {
|
|
return protocol.isBaseProtocol();
|
|
}
|
|
|
|
/**
|
|
* Register and initializes a protocol.
|
|
*
|
|
* @param protocol protocol to register
|
|
* @param clientVersion supported client protocol versions
|
|
* @param serverVersion output server protocol version the protocol converts to
|
|
* @throws IllegalArgumentException if the client protocol version is equal to the server protocol version
|
|
*/
|
|
void registerProtocol(Protocol protocol, ProtocolVersion clientVersion, ProtocolVersion serverVersion);
|
|
|
|
/**
|
|
* Register and initializes protocol.
|
|
*
|
|
* @param protocol protocol to register
|
|
* @param supportedClientVersion supported client protocol versions
|
|
* @param serverVersion output server protocol version the protocol converts to
|
|
* @throws IllegalArgumentException if a supported client protocol version is equal to the server protocol version
|
|
*/
|
|
void registerProtocol(Protocol protocol, List<Integer> supportedClientVersion, int serverVersion);
|
|
|
|
/**
|
|
* Registers and initializes 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 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 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 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);
|
|
|
|
/**
|
|
* Returns a versioned packet creator to send packets from a given base version to any client version supported by Via.
|
|
* The used packet types have to match the given protocol version.
|
|
*
|
|
* @param inputVersion input protocol version
|
|
* @param clientboundPacketsClass clientbound packets class
|
|
* @param serverboundPacketsClass serverbound packets class
|
|
* @return versioned packet creator
|
|
* @throws IllegalArgumentException if either of the packet classes are the base {@link ClientboundPacketType} or {@link ServerboundPacketType} interfaces
|
|
*/
|
|
VersionedPacketCreator createVersionedPacketCreator(ProtocolVersion inputVersion,
|
|
Class<? extends ClientboundPacketType> clientboundPacketsClass,
|
|
Class<? extends ServerboundPacketType> serverboundPacketsClass);
|
|
|
|
/**
|
|
* Returns whether protocol path calculation expects the path to come closer to the expected version with each entry, true by default.
|
|
* <p>
|
|
* In practice, this means a path will never go to a protocol version that puts it farther from the desired
|
|
* server protocol version, even if a path existed.
|
|
* If this is set to false, *all* possible paths will be checked until a fitting one is found.
|
|
* <p>
|
|
* Negative examples if this returns true:
|
|
* <ul>
|
|
* A possible path from 3 to 5 in order of 3→10→5 will be dismissed.
|
|
* A possible path from 5 to 3 in order of 5→0→3 will be dismissed.
|
|
* </ul>
|
|
* <p>
|
|
* Negative examples if this returns false:
|
|
* <ul>
|
|
* While searching for a path from 3 to 5, 3→2→1 could be checked first before 3→4→5 is found.
|
|
* While searching for a path from 5 to 3, 5→6→7 could be checked first before 5→4→3 is found.
|
|
* </ul>
|
|
*
|
|
* @return whether protocol path calculation expects the path to come closer to the expected version with each entry
|
|
*/
|
|
boolean onlyCheckLoweringPathEntries();
|
|
|
|
/**
|
|
* Sets whether protocol path calculation expects the path to come closer to the expected version with each entry.
|
|
*
|
|
* @param onlyCheckLoweringPathEntries whether protocol path calculation expects the path to come closer to the expected version with each entry
|
|
* @see #onlyCheckLoweringPathEntries()
|
|
*/
|
|
void setOnlyCheckLoweringPathEntries(boolean onlyCheckLoweringPathEntries);
|
|
|
|
/**
|
|
* Returns the maximum protocol path size applied to {@link #getProtocolPath(int, int)}.
|
|
*
|
|
* @return maximum protocol path size
|
|
*/
|
|
int getMaxProtocolPathSize();
|
|
|
|
/**
|
|
* Sets the maximum protocol path size applied to {@link #getProtocolPath(int, int)}.
|
|
* Its default is 50.
|
|
*
|
|
* @param maxProtocolPathSize maximum protocol path size
|
|
*/
|
|
void setMaxProtocolPathSize(int maxProtocolPathSize);
|
|
|
|
/**
|
|
* Returns the protocol versions compatible with the server.
|
|
*
|
|
* @return sorted, immutable set of supported protocol versions
|
|
*/
|
|
SortedSet<Integer> getSupportedVersions();
|
|
|
|
/**
|
|
* Check if this plugin is useful to the server.
|
|
*
|
|
* @return true if there is a useful pipe
|
|
*/
|
|
boolean isWorkingPipe();
|
|
|
|
/**
|
|
* Ensure that mapping data for that protocol has already been loaded, completes it otherwise.
|
|
*
|
|
* @param protocolClass protocol class
|
|
*/
|
|
void completeMappingDataLoading(Class<? extends Protocol> protocolClass) throws Exception;
|
|
|
|
/**
|
|
* Shuts down the executor and uncaches mappings if all futures have been completed.
|
|
*
|
|
* @return true if the executor has now been shut down
|
|
*/
|
|
boolean checkForMappingCompletion();
|
|
|
|
/**
|
|
* Executes the given runnable asynchronously, adding a {@link CompletableFuture}
|
|
* to the list of data to load bound to their protocols.
|
|
*
|
|
* @param protocolClass protocol class
|
|
* @param runnable runnable to be executed asynchronously
|
|
*/
|
|
void addMappingLoaderFuture(Class<? extends Protocol> protocolClass, Runnable runnable);
|
|
|
|
/**
|
|
* Executes the given runnable asynchronously after the other protocol has finished its data loading,
|
|
* adding a {@link CompletableFuture} to the list of data to load bound to their protocols.
|
|
*
|
|
* @param protocolClass protocol class
|
|
* @param dependsOn class of the protocol that the data loading depends on
|
|
* @param runnable runnable to be executed asynchronously
|
|
*/
|
|
void addMappingLoaderFuture(Class<? extends Protocol> protocolClass, Class<? extends Protocol> dependsOn, Runnable runnable);
|
|
|
|
/**
|
|
* Returns the data loading future bound to the protocol, or null if all loading is complete.
|
|
* The future may or may not have already been completed.
|
|
*
|
|
* @param protocolClass protocol class
|
|
* @return data loading future bound to the protocol, or null if all loading is complete
|
|
*/
|
|
@Nullable CompletableFuture<Void> getMappingLoaderFuture(Class<? extends Protocol> protocolClass);
|
|
|
|
/**
|
|
* Creates a new packet wrapper instance.
|
|
*
|
|
* @param packetType packet type, or null if none should be written to the packet (raw id = -1)
|
|
* @param buf input buffer
|
|
* @param connection user connection
|
|
* @return new packet wrapper instance
|
|
* @see PacketWrapper#create(PacketType, ByteBuf, UserConnection)
|
|
*/
|
|
PacketWrapper createPacketWrapper(@Nullable PacketType packetType, @Nullable ByteBuf buf, UserConnection connection);
|
|
|
|
/**
|
|
* Creates a new packet wrapper instance.
|
|
*
|
|
* @param packetId packet id
|
|
* @param buf input buffer
|
|
* @param connection user connection
|
|
* @return new packet wrapper instance
|
|
* @deprecated magic id; prefer using {@link #createPacketWrapper(PacketType, ByteBuf, UserConnection)}
|
|
*/
|
|
@Deprecated
|
|
PacketWrapper createPacketWrapper(int packetId, @Nullable ByteBuf buf, UserConnection connection);
|
|
}
|