Search in sources :

Example 1 with ProtocolPathEntry

use of com.viaversion.viaversion.api.protocol.ProtocolPathEntry in project ViaVersion by ViaVersion.

the class BungeeServerHandler method checkServerChange.

public void checkServerChange(ServerConnectedEvent e, UserConnection user) throws Exception {
    if (user == null)
        return;
    // Handle server/version change
    if (user.has(BungeeStorage.class)) {
        BungeeStorage storage = user.get(BungeeStorage.class);
        ProxiedPlayer player = storage.getPlayer();
        if (e.getServer() != null) {
            if (!e.getServer().getInfo().getName().equals(storage.getCurrentServer())) {
                // Clear auto-team
                EntityTracker1_9 oldEntityTracker = user.getEntityTracker(Protocol1_9To1_8.class);
                if (oldEntityTracker != null) {
                    if (oldEntityTracker.isAutoTeam() && oldEntityTracker.isTeamExists()) {
                        oldEntityTracker.sendTeamPacket(false, true);
                    }
                }
                String serverName = e.getServer().getInfo().getName();
                storage.setCurrentServer(serverName);
                int protocolId = ProtocolDetectorService.getProtocolId(serverName);
                if (protocolId <= ProtocolVersion.v1_8.getVersion()) {
                    // 1.8 doesn't have BossBar packet
                    if (storage.getBossbar() != null) {
                        // This ensures we can encode it properly as only the 1.9 protocol is currently implemented.
                        if (user.getProtocolInfo().getPipeline().contains(Protocol1_9To1_8.class)) {
                            for (UUID uuid : storage.getBossbar()) {
                                PacketWrapper wrapper = PacketWrapper.create(ClientboundPackets1_9.BOSSBAR, null, user);
                                wrapper.write(Type.UUID, uuid);
                                // remove
                                wrapper.write(Type.VAR_INT, 1);
                                wrapper.send(Protocol1_9To1_8.class);
                            }
                        }
                        storage.getBossbar().clear();
                    }
                }
                ProtocolInfo info = user.getProtocolInfo();
                int previousServerProtocol = info.getServerProtocolVersion();
                // Refresh the pipes
                List<ProtocolPathEntry> protocolPath = Via.getManager().getProtocolManager().getProtocolPath(info.getProtocolVersion(), protocolId);
                ProtocolPipeline pipeline = user.getProtocolInfo().getPipeline();
                user.clearStoredObjects();
                pipeline.cleanPipes();
                if (protocolPath == null) {
                    // TODO Check Bungee Supported Protocols? *shrugs*
                    protocolId = info.getProtocolVersion();
                } else {
                    List<Protocol> protocols = new ArrayList<>(protocolPath.size());
                    for (ProtocolPathEntry entry : protocolPath) {
                        protocols.add(entry.protocol());
                    }
                    pipeline.add(protocols);
                }
                info.setServerProtocolVersion(protocolId);
                // Add version-specific base Protocol
                pipeline.add(Via.getManager().getProtocolManager().getBaseProtocol(protocolId));
                // Workaround 1.13 server change
                int id1_13 = ProtocolVersion.v1_13.getVersion();
                boolean toNewId = previousServerProtocol < id1_13 && protocolId >= id1_13;
                boolean toOldId = previousServerProtocol >= id1_13 && protocolId < id1_13;
                if (previousServerProtocol != -1 && (toNewId || toOldId)) {
                    Collection<String> registeredChannels = (Collection<String>) getRegisteredChannels.invoke(e.getPlayer().getPendingConnection());
                    if (!registeredChannels.isEmpty()) {
                        Collection<String> newChannels = new HashSet<>();
                        for (Iterator<String> iterator = registeredChannels.iterator(); iterator.hasNext(); ) {
                            String channel = iterator.next();
                            String oldChannel = channel;
                            if (toNewId) {
                                channel = InventoryPackets.getNewPluginChannelId(channel);
                            } else {
                                channel = InventoryPackets.getOldPluginChannelId(channel);
                            }
                            if (channel == null) {
                                iterator.remove();
                                continue;
                            }
                            if (!oldChannel.equals(channel)) {
                                iterator.remove();
                                newChannels.add(channel);
                            }
                        }
                        registeredChannels.addAll(newChannels);
                    }
                    PluginMessage brandMessage = (PluginMessage) getBrandMessage.invoke(e.getPlayer().getPendingConnection());
                    if (brandMessage != null) {
                        String channel = brandMessage.getTag();
                        if (toNewId) {
                            channel = InventoryPackets.getNewPluginChannelId(channel);
                        } else {
                            channel = InventoryPackets.getOldPluginChannelId(channel);
                        }
                        if (channel != null) {
                            brandMessage.setTag(channel);
                        }
                    }
                }
                user.put(storage);
                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);
                }
                EntityTracker1_9 newTracker = user.getEntityTracker(Protocol1_9To1_8.class);
                if (newTracker != null) {
                    if (Via.getConfig().isAutoTeam()) {
                        String currentTeam = null;
                        for (Team team : player.getScoreboard().getTeams()) {
                            if (team.getPlayers().contains(info.getUsername())) {
                                currentTeam = team.getName();
                            }
                        }
                        // Reinitialize auto-team
                        newTracker.setAutoTeam(true);
                        if (currentTeam == null) {
                            // Send auto-team as it was cleared above
                            newTracker.sendTeamPacket(true, true);
                            newTracker.setCurrentTeam("viaversion");
                        } else {
                            // Auto-team will be sent when bungee send remove packet
                            newTracker.setAutoTeam(Via.getConfig().isAutoTeam());
                            newTracker.setCurrentTeam(currentTeam);
                        }
                    }
                }
                Object wrapper = channelWrapper.get(player);
                setVersion.invoke(wrapper, protocolId);
                Object entityMap = getEntityMap.invoke(null, protocolId);
                entityRewrite.set(player, entityMap);
            }
        }
    }
}
Also used : ProxiedPlayer(net.md_5.bungee.api.connection.ProxiedPlayer) ProtocolPathEntry(com.viaversion.viaversion.api.protocol.ProtocolPathEntry) EntityTracker1_9(com.viaversion.viaversion.protocols.protocol1_9to1_8.storage.EntityTracker1_9) BungeeStorage(com.viaversion.viaversion.bungee.storage.BungeeStorage) PacketWrapper(com.viaversion.viaversion.api.protocol.packet.PacketWrapper) ProtocolPipeline(com.viaversion.viaversion.api.protocol.ProtocolPipeline) PluginMessage(net.md_5.bungee.protocol.packet.PluginMessage) ProtocolInfo(com.viaversion.viaversion.api.connection.ProtocolInfo) Team(net.md_5.bungee.api.score.Team) StorableObject(com.viaversion.viaversion.api.connection.StorableObject) Protocol(com.viaversion.viaversion.api.protocol.Protocol)

Example 2 with ProtocolPathEntry

use of com.viaversion.viaversion.api.protocol.ProtocolPathEntry in project ViaVersion by ViaVersion.

the class ProtocolManagerImpl method refreshVersions.

public void refreshVersions() {
    supportedVersions.clear();
    supportedVersions.add(serverProtocolVersion.lowestSupportedVersion());
    for (ProtocolVersion version : ProtocolVersion.getProtocols()) {
        List<ProtocolPathEntry> protocolPath = getProtocolPath(version.getVersion(), serverProtocolVersion.lowestSupportedVersion());
        if (protocolPath == null)
            continue;
        supportedVersions.add(version.getVersion());
        for (ProtocolPathEntry pathEntry : protocolPath) {
            supportedVersions.add(pathEntry.outputProtocolVersion());
        }
    }
}
Also used : ProtocolPathEntry(com.viaversion.viaversion.api.protocol.ProtocolPathEntry) ServerProtocolVersion(com.viaversion.viaversion.api.protocol.version.ServerProtocolVersion) ProtocolVersion(com.viaversion.viaversion.api.protocol.version.ProtocolVersion)

Example 3 with ProtocolPathEntry

use of com.viaversion.viaversion.api.protocol.ProtocolPathEntry in project ViaVersion by ViaVersion.

the class VersionedPacketTransformerImpl method transformPacket.

private void transformPacket(PacketWrapper packet) throws Exception {
    // If clientbound: Constructor given inputProtocolVersion → Client version
    // If serverbound: Constructor given inputProtocolVersion → Server version
    PacketType packetType = packet.getPacketType();
    UserConnection connection = packet.user();
    boolean clientbound = packetType.direction() == Direction.CLIENTBOUND;
    int serverProtocolVersion = clientbound ? this.inputProtocolVersion : connection.getProtocolInfo().getServerProtocolVersion();
    int clientProtocolVersion = clientbound ? connection.getProtocolInfo().getProtocolVersion() : this.inputProtocolVersion;
    // Construct protocol pipeline
    List<ProtocolPathEntry> path = Via.getManager().getProtocolManager().getProtocolPath(clientProtocolVersion, serverProtocolVersion);
    List<Protocol> protocolList = null;
    if (path != null) {
        protocolList = new ArrayList<>(path.size());
        for (ProtocolPathEntry entry : path) {
            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
        packet.resetReader();
        try {
            packet.apply(packetType.direction(), State.PLAY, 0, protocolList, clientbound);
        } catch (Exception e) {
            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);
        }
    }
}
Also used : ProtocolPathEntry(com.viaversion.viaversion.api.protocol.ProtocolPathEntry) ServerboundPacketType(com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType) PacketType(com.viaversion.viaversion.api.protocol.packet.PacketType) ClientboundPacketType(com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType) Protocol(com.viaversion.viaversion.api.protocol.Protocol) UserConnection(com.viaversion.viaversion.api.connection.UserConnection)

Example 4 with ProtocolPathEntry

use of com.viaversion.viaversion.api.protocol.ProtocolPathEntry in project ViaVersion by ViaVersion.

the class BaseProtocol1_7 method registerPackets.

@Override
protected void registerPackets() {
    /* Outgoing Packets */
    // Status Response Packet
    registerClientbound(ClientboundStatusPackets.STATUS_RESPONSE, new // Status Response Packet
    PacketRemapper() {

        @Override
        public void registerMap() {
            map(Type.STRING);
            handler(new PacketHandler() {

                @Override
                public void handle(PacketWrapper wrapper) throws Exception {
                    ProtocolInfo info = wrapper.user().getProtocolInfo();
                    String originalStatus = wrapper.get(Type.STRING, 0);
                    try {
                        JsonElement json = GsonUtil.getGson().fromJson(originalStatus, JsonElement.class);
                        JsonObject version;
                        // Unknown!
                        int protocolVersion = 0;
                        if (json.isJsonObject()) {
                            if (json.getAsJsonObject().has("version")) {
                                version = json.getAsJsonObject().get("version").getAsJsonObject();
                                if (version.has("protocol")) {
                                    protocolVersion = ((Long) version.get("protocol").getAsLong()).intValue();
                                }
                            } else {
                                json.getAsJsonObject().add("version", version = new JsonObject());
                            }
                        } else {
                            // Format properly
                            json = new JsonObject();
                            json.getAsJsonObject().add("version", version = new JsonObject());
                        }
                        if (Via.getConfig().isSendSupportedVersions()) {
                            // Send supported versions
                            version.add("supportedVersions", GsonUtil.getGson().toJsonTree(Via.getAPI().getSupportedVersions()));
                        }
                        if (!Via.getAPI().getServerVersion().isKnown()) {
                            // Set the Server protocol if the detection on startup failed
                            ProtocolManagerImpl protocolManager = (ProtocolManagerImpl) Via.getManager().getProtocolManager();
                            protocolManager.setServerProtocol(new ServerProtocolVersionSingleton(ProtocolVersion.getProtocol(protocolVersion).getVersion()));
                        }
                        // Ensure the server has a version provider
                        VersionProvider versionProvider = Via.getManager().getProviders().get(VersionProvider.class);
                        if (versionProvider == null) {
                            wrapper.user().setActive(false);
                            return;
                        }
                        int closestServerProtocol = versionProvider.getClosestServerProtocol(wrapper.user());
                        List<ProtocolPathEntry> protocols = null;
                        if (info.getProtocolVersion() >= closestServerProtocol || Via.getPlatform().isOldClientsAllowed()) {
                            protocols = Via.getManager().getProtocolManager().getProtocolPath(info.getProtocolVersion(), closestServerProtocol);
                        }
                        if (protocols != null) {
                            if (protocolVersion == closestServerProtocol || protocolVersion == 0) {
                                // Fix ServerListPlus
                                ProtocolVersion prot = ProtocolVersion.getProtocol(info.getProtocolVersion());
                                version.addProperty("protocol", prot.getOriginalVersion());
                            }
                        } else {
                            // not compatible :(, *plays very sad violin*
                            wrapper.user().setActive(false);
                        }
                        if (Via.getConfig().blockedProtocolVersions().contains(info.getProtocolVersion())) {
                            // Show blocked versions as outdated
                            version.addProperty("protocol", -1);
                        }
                        // Update value
                        wrapper.set(Type.STRING, 0, GsonUtil.getGson().toJson(json));
                    } catch (JsonParseException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    });
    // Login Success Packet
    registerClientbound(ClientboundLoginPackets.GAME_PROFILE, new PacketRemapper() {

        @Override
        public void registerMap() {
            handler(new PacketHandler() {

                @Override
                public void handle(PacketWrapper wrapper) throws Exception {
                    ProtocolInfo info = wrapper.user().getProtocolInfo();
                    info.setState(State.PLAY);
                    UUID uuid = passthroughLoginUUID(wrapper);
                    info.setUuid(uuid);
                    String username = wrapper.passthrough(Type.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.getProtocolVersion(), Joiner.on(", ").join(info.getPipeline().pipes(), ", ") });
                    }
                }
            });
        }
    });
    /* Incoming Packets */
    // Login Start Packet
    registerServerbound(ServerboundLoginPackets.HELLO, new PacketRemapper() {

        @Override
        public void registerMap() {
            handler(new PacketHandler() {

                @Override
                public void handle(final PacketWrapper wrapper) throws Exception {
                    int protocol = wrapper.user().getProtocolInfo().getProtocolVersion();
                    if (Via.getConfig().blockedProtocolVersions().contains(protocol)) {
                        if (!wrapper.user().getChannel().isOpen())
                            return;
                        if (!wrapper.user().shouldApplyBlockProtocol())
                            return;
                        // Disconnect Packet
                        PacketWrapper disconnectPacket = PacketWrapper.create(ClientboundLoginPackets.LOGIN_DISCONNECT, wrapper.user());
                        Protocol1_9To1_8.FIX_JSON.write(disconnectPacket, ChatColorUtil.translateAlternateColorCodes(Via.getConfig().getBlockedDisconnectMsg()));
                        // cancel current
                        wrapper.cancel();
                        // Send and close
                        ChannelFuture future = disconnectPacket.sendFuture(BaseProtocol.class);
                        future.addListener(f -> wrapper.user().getChannel().close());
                    }
                }
            });
        }
    });
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) ProtocolPathEntry(com.viaversion.viaversion.api.protocol.ProtocolPathEntry) PacketRemapper(com.viaversion.viaversion.api.protocol.remapper.PacketRemapper) JsonObject(com.google.gson.JsonObject) ProtocolVersion(com.viaversion.viaversion.api.protocol.version.ProtocolVersion) JsonParseException(com.google.gson.JsonParseException) VersionProvider(com.viaversion.viaversion.api.protocol.version.VersionProvider) ProtocolManagerImpl(com.viaversion.viaversion.protocol.ProtocolManagerImpl) PacketHandler(com.viaversion.viaversion.api.protocol.remapper.PacketHandler) PacketWrapper(com.viaversion.viaversion.api.protocol.packet.PacketWrapper) JsonElement(com.google.gson.JsonElement) ProtocolInfo(com.viaversion.viaversion.api.connection.ProtocolInfo) UUID(java.util.UUID) ServerProtocolVersionSingleton(com.viaversion.viaversion.protocol.ServerProtocolVersionSingleton)

Example 5 with ProtocolPathEntry

use of com.viaversion.viaversion.api.protocol.ProtocolPathEntry in project Geyser by GeyserMC.

the class GeyserSpigotPlugin method isViaVersionNeeded.

/**
 * This function should not run unless ViaVersion is installed on the server.
 *
 * @return true if there is any block mappings difference between the server and client.
 */
private boolean isViaVersionNeeded() {
    ProtocolVersion serverVersion = getServerProtocolVersion();
    List<ProtocolPathEntry> protocolList = Via.getManager().getProtocolManager().getProtocolPath(MinecraftProtocol.getJavaProtocolVersion(), serverVersion.getVersion());
    if (protocolList == null) {
        // No translation needed!
        return false;
    }
    for (int i = protocolList.size() - 1; i >= 0; i--) {
        MappingData mappingData = protocolList.get(i).getProtocol().getMappingData();
        if (mappingData != null) {
            return true;
        }
    }
    // All mapping data is null, which means client and server block states are the same
    return false;
}
Also used : ProtocolPathEntry(com.viaversion.viaversion.api.protocol.ProtocolPathEntry) MappingData(com.viaversion.viaversion.api.data.MappingData) ProtocolVersion(com.viaversion.viaversion.api.protocol.version.ProtocolVersion)

Aggregations

ProtocolPathEntry (com.viaversion.viaversion.api.protocol.ProtocolPathEntry)7 Protocol (com.viaversion.viaversion.api.protocol.Protocol)3 ProtocolVersion (com.viaversion.viaversion.api.protocol.version.ProtocolVersion)3 ProtocolInfo (com.viaversion.viaversion.api.connection.ProtocolInfo)2 StorableObject (com.viaversion.viaversion.api.connection.StorableObject)2 UserConnection (com.viaversion.viaversion.api.connection.UserConnection)2 PacketWrapper (com.viaversion.viaversion.api.protocol.packet.PacketWrapper)2 BungeeStorage (com.viaversion.viaversion.bungee.storage.BungeeStorage)2 JsonElement (com.google.gson.JsonElement)1 JsonObject (com.google.gson.JsonObject)1 JsonParseException (com.google.gson.JsonParseException)1 MappingData (com.viaversion.viaversion.api.data.MappingData)1 ProtocolPathKey (com.viaversion.viaversion.api.protocol.ProtocolPathKey)1 ProtocolPipeline (com.viaversion.viaversion.api.protocol.ProtocolPipeline)1 ClientboundPacketType (com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType)1 PacketType (com.viaversion.viaversion.api.protocol.packet.PacketType)1 ServerboundPacketType (com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType)1 PacketHandler (com.viaversion.viaversion.api.protocol.remapper.PacketHandler)1 PacketRemapper (com.viaversion.viaversion.api.protocol.remapper.PacketRemapper)1 ServerProtocolVersion (com.viaversion.viaversion.api.protocol.version.ServerProtocolVersion)1