public class SpigotPlugin extends JavaPlugin implements Listener, PluginMessageListener {
public static final String CHANNEL_NAME = "mapatate:channel";
private static final Map<UUID, CompletableFuture<Boolean>> PENDING_BAN_CHECK = new HashMap<>();
@Override
public void onEnable() {
Server server = this.getServer();
Messenger messenger = server.getMessenger();
PluginManager pm = server.getPluginManager();
if(server.spigot().getConfig().getConfigurationSection("settings").getBoolean("settings.bungeecord")) {
messenger.registerOutgoingPluginChannel(this, CHANNEL_NAME);
messenger.registerIncomingPluginChannel(this, CHANNEL_NAME, this);
}
else {
this.getLogger().severe("BungeeCord is disabled in `spigot.yml`");
pm.disablePlugin(this);
}
pm.registerEvents(this, this);
}
@Override
public void onDisable() {
Messenger messenger = this.getServer().getMessenger();
messenger.unregisterOutgoingPluginChannel(this);
messenger.unregisterIncomingPluginChannel(this);
}
@EventHandler
public void onPlayerLogin(PlayerLoginEvent e) {
if(e.getResult() != PlayerLoginEvent.Result.ALLOWED) {
return;
}
ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeUTF("PlayerCheck");
out.writeUTF("IsBanned");
Player p = e.getPlayer();
UUID playerId = p.getUniqueId();
ByteBuffer uuid = ByteBuffer.wrap(new byte[16]);
uuid.putLong(playerId.getMostSignificantBits());
uuid.putLong(playerId.getLeastSignificantBits());
out.write(uuid.array());
CompletableFuture<Boolean> promise = new CompletableFuture<>();
PENDING_BAN_CHECK.put(playerId, promise);
p.sendPluginMessage(this, CHANNEL_NAME, out.toByteArray());
try {
boolean isBanned = promise.get(1, TimeUnit.SECONDS);
if(isBanned) {
e.setResult(PlayerLoginEvent.Result.KICK_BANNED);
}
}
catch(ExecutionException | InterruptedException | TimeoutException ex) {
e.setResult(PlayerLoginEvent.Result.KICK_OTHER);
ex.printStackTrace();
}
promise.cancel(true);
PENDING_BAN_CHECK.remove(playerId);
}
@Override
public void onPluginMessageReceived(String channel, Player player, byte[] message) {
if(!channel.equals(CHANNEL_NAME)) {
return;
}
ByteArrayDataInput in = ByteStreams.newDataInput(message);
String subchannel = in.readUTF();
if(subchannel.equals("PlayerCheck")) {
String action = in.readUTF();
byte[] buf = new byte[16];
in.readFully(buf);
ByteBuffer bb = ByteBuffer.wrap(buf);
long msb = bb.getLong();
long lsb = bb.getLong();
UUID playerId = new UUID(msb, lsb);
if(action.equals("IsBanned")) {
boolean result = in.readBoolean();
CompletableFuture<Boolean> promise = PENDING_BAN_CHECK.get(playerId);
if(promise != null) promise.complete(result);
}
}
}
}