/*
 * This file is part of BlockJamCore, licensed under the MIT License (MIT).
 *
 * Copyright (c) 2016, BlockJam <https://blockjam.org/>
 *
 * 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 org.blockjam.core.bungee;

import static com.google.common.base.Preconditions.checkNotNull;

import org.blockjam.core.BlockJamCorePlugin;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.network.ChannelBinding;

/**
 * A manager for controlling BungeeCord networks.
 */
public class BungeeManager {

    private final ChannelBinding.RawDataChannel channel;

    public BungeeManager() {
        this.channel = Sponge.getGame().getChannelRegistrar().createRawChannel(BlockJamCorePlugin.instance(), "BungeeCord");
    }

    /**
     * Transfers the given {@link Player} to the given server.
     *
     * @param player The player to transfer
     * @param server The server to transfer the {@link Player} to
     */
    public void transferPlayer(Player player, String server) {
        checkNotNull(this.channel, "channel is null!");
        checkNotNull(player, "player is null!");
        checkNotNull(server, "server is null!");
        this.channel.sendTo(player, buf -> buf.writeUTF("Connect").writeUTF(server));
    }

    /**
     * Transfers the given {@link Player} to the given {@link BungeeServers}.
     *
     * @param player The player to transfer
     * @param server The server to transfer the {@link Player} to
     */
    public void transferPlayer(Player player, BungeeServers server) {
        checkNotNull(server, "server is null!");
        this.transferPlayer(player, server.toString());
    }

    /**
     * Transfers all online {@link Player}s to the given server.
     *
     * @param server The server to transfer the {@link Player}s to
     */
    public void transferAllPlayers(String server) {
        checkNotNull(this.channel, "channel is null!");
        checkNotNull(server, "server is null!");
        this.channel.sendToAll(buf -> buf.writeUTF("Connect").writeUTF(server));
    }

    /**
     * Transfers all online {@link Player}s to the given {@link BungeeServers}.
     *
     * @param server The server to transfer the {@link Player}s to
     */
    public void transferAllPlayers(BungeeServers server) {
        checkNotNull(server, "server is null!");
        this.transferAllPlayers(server.toString());
    }

    /**
     * Kicks the given {@link Player} for the given reason.
     *
     * @param player The player to kick from the network
     * @param reason The reason
     */
    public void kickPlayer(Player player, String reason) {
        checkNotNull(this.channel, "channel is null!");
        checkNotNull(player, "player is null!");
        checkNotNull(reason, "reason is null!");
        this.channel.sendTo(player, buf -> buf.writeUTF("KickPlayer").writeUTF(player.getName()).writeUTF(reason));
    }

}

@@ -1357,16 +1357,55 @@
 Plugin;%0A
+import org.spongepowered.api.Platform;%0A
 import o
@@ -1545,16 +1545,56 @@
 nding;%0A%0A
+import java.util.function.IntConsumer;%0A%0A
 /**%0A * A
@@ -3520,32 +3520,1105 @@
 ring());%0A    %7D%0A%0A
+    /**%0A     * Gets the player count for the given server.%0A     *%0A     * @param server The server%0A     * @param consumer The consumer for the player count%0A     */%0A    public void getPlayerCount(String server, IntConsumer consumer) %7B%0A        checkNotNull(server, %22server is null!%22);%0A        checkNotNull(consumer, %22consumer is null!%22);%0A        this.channel.addListener(Platform.Type.SERVER, (data, connection, side) -%3E %7B%0A            if (data.readUTF().equalsIgnoreCase(server)) %7B%0A                consumer.accept(data.readInteger());%0A            %7D%0A        %7D);%0A        this.channel.sendTo(Sponge.getServer().getOnlinePlayers().iterator().next(), buf -%3E buf.writeUTF(%22PlayerCount%22).writeUTF(server));%0A    %7D%0A%0A    /**%0A     * Gets the player count for the given %7B@link BungeeServers%7D.%0A     *%0A     * @param server The server%0A     * @param consumer The consumer for the player count%0A     */%0A    public void getPlayerCount(BungeeServers server, IntConsumer consumer) %7B%0A        checkNotNull(server, %22server is null!%22);%0A        this.getPlayerCount(server.toString(), consumer);%0A    %7D%0A%0A
     /**%0A     * K

Add player count methods