Search in sources :

Example 1 with BungeePlayer

use of codecrafter47.bungeetablistplus.player.BungeePlayer in project BungeeTabListPlus by CodeCrafter47.

the class BukkitBridge method handlePluginMessage.

private void handlePluginMessage(ProxiedPlayer player, Server server, DataInput input) throws IOException {
    PlayerConnectionInfo connectionInfo = playerPlayerConnectionInfoMap.get(player);
    if (connectionInfo == null) {
        return;
    }
    int messageId = input.readUnsignedByte();
    if (messageId == BridgeProtocolConstants.MESSAGE_ID_INTRODUCE) {
        int serverIdentifier = input.readInt();
        int protocolVersion = input.readInt();
        int minimumCompatibleProtocolVersion = input.readInt();
        String proxyPluginVersion = input.readUTF();
        int connectionId = serverIdentifier + proxyIdentifier;
        if (connectionId == connectionInfo.connectionIdentifier) {
            return;
        }
        if (BridgeProtocolConstants.VERSION < minimumCompatibleProtocolVersion) {
            rlExecutor.execute(() -> {
                logger.log(Level.WARNING, "Incompatible version of BTLP on server " + server.getInfo().getName() + " detected: " + proxyPluginVersion);
            });
            return;
        }
        // reset connection state
        connectionInfo.connectionIdentifier = connectionId;
        connectionInfo.isConnectionValid = true;
        connectionInfo.nextIntroducePacketDelay = 1;
        connectionInfo.introducePacketDelay = 1;
        connectionInfo.hasReceived = false;
        connectionInfo.protocolVersion = Integer.min(BridgeProtocolConstants.VERSION, protocolVersion);
        BungeePlayer bungeePlayer = bungeePlayerProvider.getPlayerIfPresent(player);
        if (bungeePlayer == null) {
            logger.severe("Internal error - Bridge functionality not available for " + player.getName());
        } else {
            connectionInfo.playerBridgeData = bungeePlayer.getBridgeDataCache();
            connectionInfo.playerBridgeData.setConnectionId(connectionId);
            connectionInfo.playerBridgeData.connection = server;
            connectionInfo.playerBridgeData.requestMissingData();
        }
        connectionInfo.serverBridgeData = getServerDataCache(server.getInfo().getName());
        connectionInfo.serverBridgeData.setConnectionId(connectionId);
        connectionInfo.serverBridgeData.addConnection(server);
        connectionInfo.serverBridgeData.requestMissingData();
        // send ACK 0
        ByteArrayOutputStream byteArrayOutput = new ByteArrayOutputStream();
        DataOutput output = new DataOutputStream(byteArrayOutput);
        output.writeByte(BridgeProtocolConstants.MESSAGE_ID_ACK);
        output.writeInt(connectionId);
        output.writeInt(0);
        byte[] message = byteArrayOutput.toByteArray();
        server.sendData(BridgeProtocolConstants.CHANNEL, message);
    } else {
        if (!connectionInfo.isConnectionValid) {
            return;
        }
        int connectionId = input.readInt();
        if (connectionId != connectionInfo.connectionIdentifier) {
            return;
        }
        connectionInfo.hasReceived = true;
        int sequenceNumber = input.readInt();
        BridgeData bridgeData;
        boolean isServerMessage;
        if ((messageId & 0x80) == 0) {
            bridgeData = connectionInfo.playerBridgeData;
            isServerMessage = false;
        } else {
            bridgeData = connectionInfo.serverBridgeData;
            isServerMessage = true;
        }
        if (bridgeData == null) {
            return;
        }
        messageId = messageId & 0x7f;
        synchronized (bridgeData) {
            if (messageId == BridgeProtocolConstants.MESSAGE_ID_ACK) {
                int confirmed = sequenceNumber - bridgeData.lastConfirmed;
                if (confirmed > bridgeData.messagesPendingConfirmation.size()) {
                    return;
                }
                while (confirmed-- > 0) {
                    bridgeData.lastConfirmed++;
                    bridgeData.messagesPendingConfirmation.remove();
                }
            } else if (messageId == BridgeProtocolConstants.MESSAGE_ID_UPDATE_DATA) {
                if (sequenceNumber > bridgeData.nextIncomingMessageId) {
                    // ignore messages from the future
                    return;
                }
                ByteArrayOutputStream byteArrayOutput = new ByteArrayOutputStream();
                DataOutput output = new DataOutputStream(byteArrayOutput);
                output.writeByte(BridgeProtocolConstants.MESSAGE_ID_ACK | (isServerMessage ? 0x80 : 0x00));
                output.writeInt(connectionId);
                output.writeInt(sequenceNumber);
                byte[] message = byteArrayOutput.toByteArray();
                server.sendData(BridgeProtocolConstants.CHANNEL, message);
                if (sequenceNumber < bridgeData.nextIncomingMessageId) {
                    // ignore messages from the past after sending ACK
                    return;
                }
                bridgeData.nextIncomingMessageId++;
                int size = input.readInt();
                if (size > 0) {
                    onDataReceived(bridgeData, input, size);
                }
            } else {
                throw new IllegalArgumentException("Unexpected message id: " + messageId);
            }
        }
    }
}
Also used : ByteArrayDataOutput(com.google.common.io.ByteArrayDataOutput) BungeePlayer(codecrafter47.bungeetablistplus.player.BungeePlayer)

Example 2 with BungeePlayer

use of codecrafter47.bungeetablistplus.player.BungeePlayer in project BungeeTabListPlus by CodeCrafter47.

the class BungeePlayerProvider method onPlayerConnected.

public BungeePlayer onPlayerConnected(ProxiedPlayer player) {
    BungeePlayer bungeePlayer = new BungeePlayer(player);
    String version = BungeeTabListPlus.getInstance().getProtocolVersionProvider().getVersion(player);
    boolean version_below_1_8 = !BungeeTabListPlus.getInstance().getProtocolVersionProvider().has18OrLater(player);
    mainThread.execute(() -> {
        bungeePlayer.getLocalDataCache().updateValue(BTLPBungeeDataKeys.DATA_KEY_CLIENT_VERSION, version);
        bungeePlayer.getLocalDataCache().updateValue(BTLPBungeeDataKeys.DATA_KEY_CLIENT_VERSION_BELOW_1_8, version_below_1_8);
        players.put(player, bungeePlayer);
        listeners.forEach(listener -> listener.onPlayerAdded(bungeePlayer));
    });
    return bungeePlayer;
}
Also used : BungeePlayer(codecrafter47.bungeetablistplus.player.BungeePlayer)

Example 3 with BungeePlayer

use of codecrafter47.bungeetablistplus.player.BungeePlayer in project BungeeTabListPlus by CodeCrafter47.

the class BungeePlayerProvider method onPlayerDisconnected.

public void onPlayerDisconnected(ProxiedPlayer player) {
    mainThread.execute(() -> {
        BungeePlayer bungeePlayer;
        if (null == (bungeePlayer = players.remove(player))) {
            return;
        }
        listeners.forEach(listener -> listener.onPlayerRemoved(bungeePlayer));
    });
}
Also used : BungeePlayer(codecrafter47.bungeetablistplus.player.BungeePlayer)

Example 4 with BungeePlayer

use of codecrafter47.bungeetablistplus.player.BungeePlayer in project BungeeTabListPlus by CodeCrafter47.

the class RedisPlayerManager method onRedisMessage.

@EventHandler
@SuppressWarnings("unchecked")
public void onRedisMessage(PubSubMessageEvent event) {
    String channel = event.getChannel();
    if (channel.equals(CHANNEL_DATA_REQUEST)) {
        ByteArrayDataInput input = ByteStreams.newDataInput(Base64.getDecoder().decode(event.getMessage()));
        try {
            UUID uuid = DataStreamUtils.readUUID(input);
            ProxiedPlayer proxiedPlayer = ProxyServer.getInstance().getPlayer(uuid);
            if (proxiedPlayer != null) {
                BungeePlayer player = bungeePlayerProvider.getPlayerIfPresent(proxiedPlayer);
                if (player != null) {
                    DataKey<?> key = DataStreamUtils.readDataKey(input, keyRegistry, missingDataKeyLogger);
                    if (key != null) {
                        player.addDataChangeListener((DataKey<Object>) key, new DataChangeListener(player, (DataKey<Object>) key));
                        updateData(uuid, (DataKey<Object>) key, player.get(key));
                    }
                }
            }
        } catch (IOException ex) {
            logger.log(Level.SEVERE, "Unexpected error reading redis message", ex);
        }
    } else if (channel.equals(CHANNEL_DATA_UPDATE)) {
        ByteArrayDataInput input = ByteStreams.newDataInput(Base64.getDecoder().decode(event.getMessage()));
        try {
            UUID uuid = DataStreamUtils.readUUID(input);
            RedisPlayer player = byUUID.get(uuid);
            if (player != null) {
                DataCache cache = player.getData();
                DataKey<?> key = DataStreamUtils.readDataKey(input, keyRegistry, missingDataKeyLogger);
                if (key != null) {
                    boolean removed = input.readBoolean();
                    if (removed) {
                        mainThread.execute(() -> cache.updateValue(key, null));
                    } else {
                        Object value = typeRegistry.getTypeAdapter(key.getType()).read(input);
                        mainThread.execute(() -> cache.updateValue((DataKey<Object>) key, value));
                    }
                }
            }
        } catch (IOException ex) {
            logger.log(Level.SEVERE, "Unexpected error reading redis message", ex);
        }
    } else if (channel.equals(CHANNEL_DATA_OLD) || channel.equals(CHANNEL_REQUEST_DATA_OLD)) {
        logger.warning("BungeeTabListPlus on at least one proxy in your network is outdated.");
    }
}
Also used : ProxiedPlayer(net.md_5.bungee.api.connection.ProxiedPlayer) BungeePlayer(codecrafter47.bungeetablistplus.player.BungeePlayer) DataKey(de.codecrafter47.data.api.DataKey) IOException(java.io.IOException) ByteArrayDataInput(com.google.common.io.ByteArrayDataInput) RedisPlayer(codecrafter47.bungeetablistplus.player.RedisPlayer) DataCache(de.codecrafter47.data.api.DataCache) EventHandler(net.md_5.bungee.event.EventHandler)

Example 5 with BungeePlayer

use of codecrafter47.bungeetablistplus.player.BungeePlayer in project BungeeTabListPlus by CodeCrafter47.

the class CommandHide method hidePlayer.

private void hidePlayer(ProxiedPlayer player) {
    BungeePlayer bungeePlayer = BungeeTabListPlus.getInstance().getBungeePlayerProvider().getPlayer(player);
    bungeePlayer.getLocalDataCache().updateValue(BTLPBungeeDataKeys.DATA_KEY_IS_HIDDEN_PLAYER_COMMAND, true);
}
Also used : BungeePlayer(codecrafter47.bungeetablistplus.player.BungeePlayer)

Aggregations

BungeePlayer (codecrafter47.bungeetablistplus.player.BungeePlayer)9 ProxiedPlayer (net.md_5.bungee.api.connection.ProxiedPlayer)2 EventHandler (net.md_5.bungee.event.EventHandler)2 TrackingDataCache (codecrafter47.bungeetablistplus.data.TrackingDataCache)1 RedisPlayer (codecrafter47.bungeetablistplus.player.RedisPlayer)1 ExcludedServersTabOverlayProvider (codecrafter47.bungeetablistplus.tablist.ExcludedServersTabOverlayProvider)1 ByteArrayDataInput (com.google.common.io.ByteArrayDataInput)1 ByteArrayDataOutput (com.google.common.io.ByteArrayDataOutput)1 DataCache (de.codecrafter47.data.api.DataCache)1 DataKey (de.codecrafter47.data.api.DataKey)1 TabView (de.codecrafter47.taboverlay.TabView)1 EventListener (de.codecrafter47.taboverlay.config.platform.EventListener)1 IOException (java.io.IOException)1 Map (java.util.Map)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 lombok.val (lombok.val)1