mirror of
https://github.com/ViaVersion/ViaVersion.git
synced 2024-11-22 01:55:47 +01:00
Allow for multiple base protocols per version (#4106)
This commit is contained in:
parent
6ad3beca76
commit
bc57512ca2
@ -73,13 +73,13 @@ public interface ProtocolManager {
|
||||
Protocol getBaseProtocol();
|
||||
|
||||
/**
|
||||
* Returns the base protocol for a specific server protocol version.
|
||||
* Returns the base protocols 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 if present, else null
|
||||
* @return base protocols for the given server protocol version if present, else null
|
||||
*/
|
||||
@Nullable Protocol getBaseProtocol(ProtocolVersion serverVersion);
|
||||
List<Protocol> getBaseProtocols(ProtocolVersion serverVersion);
|
||||
|
||||
/**
|
||||
* Returns an immutable collection of registered protocols.
|
||||
|
@ -38,9 +38,9 @@ import com.viaversion.viaversion.api.protocol.version.ServerProtocolVersion;
|
||||
import com.viaversion.viaversion.api.protocol.version.VersionType;
|
||||
import com.viaversion.viaversion.protocol.packet.PacketWrapperImpl;
|
||||
import com.viaversion.viaversion.protocol.packet.VersionedPacketTransformerImpl;
|
||||
import com.viaversion.viaversion.protocols.base.BaseProtocol;
|
||||
import com.viaversion.viaversion.protocols.base.BaseProtocol1_16;
|
||||
import com.viaversion.viaversion.protocols.base.BaseProtocol1_7;
|
||||
import com.viaversion.viaversion.protocols.base.InitialBaseProtocol;
|
||||
import com.viaversion.viaversion.protocols.base.v1_7.ClientboundBaseProtocol1_7;
|
||||
import com.viaversion.viaversion.protocols.base.v1_7.ServerboundBaseProtocol1_7;
|
||||
import com.viaversion.viaversion.protocols.v1_20_5to1_21.Protocol1_20_5To1_21;
|
||||
import com.viaversion.viaversion.protocols.v1_10to1_11.Protocol1_10To1_11;
|
||||
import com.viaversion.viaversion.protocols.v1_11_1to1_12.Protocol1_11_1To1_12;
|
||||
@ -109,7 +109,7 @@ import java.util.logging.Level;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public class ProtocolManagerImpl implements ProtocolManager {
|
||||
private static final Protocol BASE_PROTOCOL = new BaseProtocol();
|
||||
private static final Protocol BASE_PROTOCOL = new InitialBaseProtocol();
|
||||
|
||||
// Input Version -> Output Version & Protocol (Allows fast lookup)
|
||||
private final Object2ObjectMap<ProtocolVersion, Object2ObjectMap<ProtocolVersion, Protocol>> registryMap = new Object2ObjectOpenHashMap<>(32);
|
||||
@ -137,8 +137,8 @@ public class ProtocolManagerImpl implements ProtocolManager {
|
||||
// Base Protocol
|
||||
BASE_PROTOCOL.initialize();
|
||||
BASE_PROTOCOL.register(Via.getManager().getProviders());
|
||||
registerBaseProtocol(new BaseProtocol1_7(), Range.closedOpen(ProtocolVersion.v1_7_2, ProtocolVersion.v1_16));
|
||||
registerBaseProtocol(new BaseProtocol1_16(), Range.atLeast(ProtocolVersion.v1_16));
|
||||
registerBaseProtocol(new ClientboundBaseProtocol1_7(), Range.atLeast(ProtocolVersion.v1_7_2));
|
||||
registerBaseProtocol(new ServerboundBaseProtocol1_7(), Range.atLeast(ProtocolVersion.v1_7_2));
|
||||
|
||||
registerProtocol(new Protocol1_8To1_9(), ProtocolVersion.v1_9, ProtocolVersion.v1_8);
|
||||
registerProtocol(new Protocol1_9To1_9_1(), Arrays.asList(ProtocolVersion.v1_9_1, ProtocolVersion.v1_9_2), ProtocolVersion.v1_9);
|
||||
@ -365,13 +365,14 @@ public class ProtocolManagerImpl implements ProtocolManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Protocol getBaseProtocol(ProtocolVersion serverVersion) {
|
||||
public List<Protocol> getBaseProtocols(ProtocolVersion serverVersion) {
|
||||
final List<Protocol> list = new ArrayList<>();
|
||||
for (Pair<Range<ProtocolVersion>, Protocol> rangeProtocol : Lists.reverse(baseProtocols)) {
|
||||
if (rangeProtocol.key().contains(serverVersion)) {
|
||||
return rangeProtocol.value();
|
||||
list.add(rangeProtocol.value());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,30 +0,0 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2024 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viaversion.protocols.base;
|
||||
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import java.util.UUID;
|
||||
|
||||
public class BaseProtocol1_16 extends BaseProtocol1_7 {
|
||||
|
||||
@Override
|
||||
protected UUID passthroughLoginUUID(final PacketWrapper wrapper) {
|
||||
return wrapper.passthrough(Types.UUID);
|
||||
}
|
||||
}
|
@ -39,22 +39,28 @@ import com.viaversion.viaversion.protocol.version.BaseVersionProvider;
|
||||
import com.viaversion.viaversion.protocols.base.packet.BaseClientboundPacket;
|
||||
import com.viaversion.viaversion.protocols.base.packet.BasePacketTypesProvider;
|
||||
import com.viaversion.viaversion.protocols.base.packet.BaseServerboundPacket;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class BaseProtocol extends AbstractProtocol<BaseClientboundPacket, BaseClientboundPacket, BaseServerboundPacket, BaseServerboundPacket> {
|
||||
/**
|
||||
* Initial base protocol which is kept always in the pipeline.
|
||||
* <p>
|
||||
* State tracking for configuration state is done via {@link AbstractProtocol#registerConfigurationChangeHandlers()}
|
||||
*/
|
||||
public class InitialBaseProtocol extends AbstractProtocol<BaseClientboundPacket, BaseClientboundPacket, BaseServerboundPacket, BaseServerboundPacket> {
|
||||
|
||||
private static final int STATUS_INTENT = 1;
|
||||
private static final int LOGIN_INTENT = 2;
|
||||
private static final int TRANSFER_INTENT = 3;
|
||||
|
||||
public BaseProtocol() {
|
||||
public InitialBaseProtocol() {
|
||||
super(BaseClientboundPacket.class, BaseClientboundPacket.class, BaseServerboundPacket.class, BaseServerboundPacket.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerPackets() {
|
||||
// Handshake Packet
|
||||
// Setup protocol pipeline + track initial state
|
||||
registerServerbound(ServerboundHandshakePackets.CLIENT_INTENTION, wrapper -> {
|
||||
int protocolVersion = wrapper.passthrough(Types.VAR_INT);
|
||||
wrapper.passthrough(Types.STRING); // Server Address
|
||||
@ -92,12 +98,11 @@ public class BaseProtocol extends AbstractProtocol<BaseClientboundPacket, BaseCl
|
||||
// Add Base Protocol
|
||||
ProtocolPipeline pipeline = info.getPipeline();
|
||||
|
||||
// Special versions might compare equal to normal versions and would break this getter
|
||||
// Special versions might compare equal to normal versions and would break this getter,
|
||||
// platforms need to add the base protocols manually in this case
|
||||
if (serverProtocol.getVersionType() != VersionType.SPECIAL) {
|
||||
final Protocol baseProtocol = protocolManager.getBaseProtocol(serverProtocol);
|
||||
// Platforms might add their base protocol manually (e.g. SPECIAL versions)
|
||||
if (baseProtocol != null) {
|
||||
pipeline.add(baseProtocol);
|
||||
for (final Protocol protocol : protocolManager.getBaseProtocols(serverProtocol)) {
|
||||
pipeline.add(protocol);
|
||||
}
|
||||
}
|
||||
|
||||
@ -123,6 +128,7 @@ public class BaseProtocol extends AbstractProtocol<BaseClientboundPacket, BaseCl
|
||||
Via.getPlatform().getLogger().info("Protocol pipeline: " + pipeline.pipes());
|
||||
}
|
||||
|
||||
// Set initial state
|
||||
if (state == STATUS_INTENT) {
|
||||
info.setState(State.STATUS);
|
||||
} else if (state == LOGIN_INTENT) {
|
@ -15,7 +15,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viaversion.protocols.base;
|
||||
package com.viaversion.viaversion.protocols.base.v1_7;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.gson.JsonElement;
|
||||
@ -26,7 +26,6 @@ import com.viaversion.viaversion.api.connection.ProtocolInfo;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
|
||||
import com.viaversion.viaversion.api.protocol.ProtocolPathEntry;
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.protocol.packet.State;
|
||||
import com.viaversion.viaversion.api.protocol.packet.provider.PacketTypesProvider;
|
||||
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
|
||||
@ -35,25 +34,25 @@ import com.viaversion.viaversion.api.protocol.version.VersionProvider;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.protocol.ProtocolManagerImpl;
|
||||
import com.viaversion.viaversion.protocol.ServerProtocolVersionSingleton;
|
||||
import com.viaversion.viaversion.protocols.base.ClientboundLoginPackets;
|
||||
import com.viaversion.viaversion.protocols.base.ClientboundStatusPackets;
|
||||
import com.viaversion.viaversion.protocols.base.packet.BaseClientboundPacket;
|
||||
import com.viaversion.viaversion.protocols.base.packet.BasePacketTypesProvider;
|
||||
import com.viaversion.viaversion.protocols.base.packet.BaseServerboundPacket;
|
||||
import com.viaversion.viaversion.util.ChatColorUtil;
|
||||
import com.viaversion.viaversion.util.ComponentUtil;
|
||||
import com.viaversion.viaversion.util.GsonUtil;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class BaseProtocol1_7 extends AbstractProtocol<BaseClientboundPacket, BaseClientboundPacket, BaseServerboundPacket, BaseServerboundPacket> {
|
||||
public class ClientboundBaseProtocol1_7 extends AbstractProtocol<BaseClientboundPacket, BaseClientboundPacket, BaseServerboundPacket, BaseServerboundPacket> {
|
||||
|
||||
public BaseProtocol1_7() {
|
||||
public ClientboundBaseProtocol1_7() {
|
||||
super(BaseClientboundPacket.class, BaseClientboundPacket.class, BaseServerboundPacket.class, BaseServerboundPacket.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerPackets() {
|
||||
// Handle server pinging sent by the client
|
||||
registerClientbound(ClientboundStatusPackets.STATUS_RESPONSE, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
@ -128,60 +127,27 @@ public class BaseProtocol1_7 extends AbstractProtocol<BaseClientboundPacket, Bas
|
||||
}
|
||||
});
|
||||
|
||||
// Login Success Packet
|
||||
// Track player name/uuid and setup connection + track state
|
||||
registerClientbound(ClientboundLoginPackets.GAME_PROFILE, wrapper -> {
|
||||
ProtocolInfo info = wrapper.user().getProtocolInfo();
|
||||
if (info.protocolVersion().olderThan(ProtocolVersion.v1_20_2)) { // On 1.20.2+, wait for the login ack
|
||||
info.setState(State.PLAY);
|
||||
}
|
||||
|
||||
UUID uuid = passthroughLoginUUID(wrapper);
|
||||
info.setUuid(uuid);
|
||||
|
||||
String username = wrapper.passthrough(Types.STRING);
|
||||
info.setUsername(username);
|
||||
// Add to ported clients
|
||||
Via.getManager().getConnectionManager().onLoginSuccess(wrapper.user());
|
||||
|
||||
if (!info.getPipeline().hasNonBaseProtocols()) { // Only base protocol
|
||||
wrapper.user().setActive(false);
|
||||
}
|
||||
|
||||
if (Via.getManager().isDebug()) {
|
||||
// Print out the route to console
|
||||
Via.getPlatform().getLogger().log(Level.INFO, "{0} logged in with protocol {1}, Route: {2}",
|
||||
new Object[]{
|
||||
username,
|
||||
info.protocolVersion().getName(),
|
||||
Joiner.on(", ").join(info.getPipeline().pipes(), ", ")
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Login Start Packet
|
||||
registerServerbound(ServerboundLoginPackets.HELLO, wrapper -> {
|
||||
final UserConnection user = wrapper.user();
|
||||
final ProtocolVersion protocol = user.getProtocolInfo().protocolVersion();
|
||||
if (Via.getConfig().blockedProtocolVersions().contains(protocol)) {
|
||||
if (!user.getChannel().isOpen() || !user.shouldApplyBlockProtocol()) {
|
||||
return;
|
||||
}
|
||||
|
||||
wrapper.cancel(); // cancel current
|
||||
|
||||
final String disconnectMessage = ChatColorUtil.translateAlternateColorCodes(Via.getConfig().getBlockedDisconnectMsg());
|
||||
final PacketWrapper disconnectPacket = PacketWrapper.create(ClientboundLoginPackets.LOGIN_DISCONNECT, user);
|
||||
disconnectPacket.write(Types.COMPONENT, ComponentUtil.plainToJson(disconnectMessage));
|
||||
|
||||
// Send and close
|
||||
final ChannelFuture future = disconnectPacket.sendFuture(null);
|
||||
future.addListener(f -> user.getChannel().close());
|
||||
}
|
||||
});
|
||||
|
||||
registerServerbound(ServerboundLoginPackets.LOGIN_ACKNOWLEDGED, wrapper -> {
|
||||
final ProtocolInfo info = wrapper.user().getProtocolInfo();
|
||||
info.setState(State.CONFIGURATION);
|
||||
|
||||
if (info.serverProtocolVersion().olderThan(ProtocolVersion.v1_16)) {
|
||||
String uuidString = wrapper.passthrough(Types.STRING);
|
||||
if (uuidString.length() == 32) { // Trimmed UUIDs are 32 characters
|
||||
// Trimmed
|
||||
uuidString = addDashes(uuidString);
|
||||
}
|
||||
info.setUuid(UUID.fromString(uuidString));
|
||||
} else {
|
||||
final UUID uuid = wrapper.passthrough(Types.UUID);
|
||||
info.setUuid(uuid);
|
||||
}
|
||||
|
||||
final String username = wrapper.passthrough(Types.STRING);
|
||||
info.setUsername(username);
|
||||
|
||||
// Setup connection
|
||||
onLoginSuccess(wrapper.user());
|
||||
});
|
||||
}
|
||||
|
||||
@ -199,13 +165,28 @@ public class BaseProtocol1_7 extends AbstractProtocol<BaseClientboundPacket, Bas
|
||||
return idBuff.toString();
|
||||
}
|
||||
|
||||
protected UUID passthroughLoginUUID(PacketWrapper wrapper) {
|
||||
String uuidString = wrapper.passthrough(Types.STRING);
|
||||
if (uuidString.length() == 32) { // Trimmed UUIDs are 32 characters
|
||||
// Trimmed
|
||||
uuidString = addDashes(uuidString);
|
||||
public static void onLoginSuccess(final UserConnection connection) {
|
||||
final ProtocolInfo info = connection.getProtocolInfo();
|
||||
if (info.protocolVersion().olderThan(ProtocolVersion.v1_20_2)) { // On 1.20.2+, wait for the login ack
|
||||
info.setState(State.PLAY);
|
||||
}
|
||||
|
||||
// Add to ported clients
|
||||
Via.getManager().getConnectionManager().onLoginSuccess(connection);
|
||||
|
||||
if (!info.getPipeline().hasNonBaseProtocols()) { // Only base protocol
|
||||
connection.setActive(false);
|
||||
}
|
||||
|
||||
if (Via.getManager().isDebug()) {
|
||||
// Print out the route to console
|
||||
Via.getPlatform().getLogger().log(Level.INFO, "{0} logged in with protocol {1}, Route: {2}",
|
||||
new Object[]{
|
||||
info.getUsername(),
|
||||
info.protocolVersion().getName(),
|
||||
Joiner.on(", ").join(info.getPipeline().pipes(), ", ")
|
||||
});
|
||||
}
|
||||
return UUID.fromString(uuidString);
|
||||
}
|
||||
|
||||
@Override
|
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||
* Copyright (C) 2016-2024 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viaversion.protocols.base.v1_7;
|
||||
|
||||
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.protocol.AbstractProtocol;
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.protocol.packet.State;
|
||||
import com.viaversion.viaversion.api.protocol.packet.provider.PacketTypesProvider;
|
||||
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.protocols.base.ClientboundLoginPackets;
|
||||
import com.viaversion.viaversion.protocols.base.ServerboundLoginPackets;
|
||||
import com.viaversion.viaversion.protocols.base.packet.BaseClientboundPacket;
|
||||
import com.viaversion.viaversion.protocols.base.packet.BasePacketTypesProvider;
|
||||
import com.viaversion.viaversion.protocols.base.packet.BaseServerboundPacket;
|
||||
import com.viaversion.viaversion.util.ChatColorUtil;
|
||||
import com.viaversion.viaversion.util.ComponentUtil;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
|
||||
public class ServerboundBaseProtocol1_7 extends AbstractProtocol<BaseClientboundPacket, BaseClientboundPacket, BaseServerboundPacket, BaseServerboundPacket> {
|
||||
|
||||
public ServerboundBaseProtocol1_7() {
|
||||
super(BaseClientboundPacket.class, BaseClientboundPacket.class, BaseServerboundPacket.class, BaseServerboundPacket.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerPackets() {
|
||||
// State tracking
|
||||
registerServerbound(ServerboundLoginPackets.LOGIN_ACKNOWLEDGED, wrapper -> {
|
||||
final ProtocolInfo info = wrapper.user().getProtocolInfo();
|
||||
info.setState(State.CONFIGURATION);
|
||||
});
|
||||
|
||||
// Handle blocked version disconnect
|
||||
registerServerbound(ServerboundLoginPackets.HELLO, wrapper -> {
|
||||
final UserConnection user = wrapper.user();
|
||||
final ProtocolVersion protocol = user.getProtocolInfo().protocolVersion();
|
||||
if (Via.getConfig().blockedProtocolVersions().contains(protocol)) {
|
||||
if (!user.getChannel().isOpen() || !user.shouldApplyBlockProtocol()) {
|
||||
return;
|
||||
}
|
||||
|
||||
wrapper.cancel(); // cancel current
|
||||
|
||||
final String disconnectMessage = ChatColorUtil.translateAlternateColorCodes(Via.getConfig().getBlockedDisconnectMsg());
|
||||
final PacketWrapper disconnectPacket = PacketWrapper.create(ClientboundLoginPackets.LOGIN_DISCONNECT, user);
|
||||
disconnectPacket.write(Types.COMPONENT, ComponentUtil.plainToJson(disconnectMessage));
|
||||
|
||||
// Send and close
|
||||
final ChannelFuture future = disconnectPacket.sendFuture(null);
|
||||
future.addListener(f -> user.getChannel().close());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBaseProtocol() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PacketTypesProvider<BaseClientboundPacket, BaseClientboundPacket, BaseServerboundPacket, BaseServerboundPacket> createPacketTypesProvider() {
|
||||
return BasePacketTypesProvider.INSTANCE;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user