Skip to content

Instantly share code, notes, and snippets.

@Pikachu920
Created August 13, 2018 00:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Pikachu920/5b2b8669760f8f4d56e828db8e88447a to your computer and use it in GitHub Desktop.
Save Pikachu920/5b2b8669760f8f4d56e828db8e88447a to your computer and use it in GitHub Desktop.
/**
* Sends a plugin message using the first player from {@link Bukkit#getOnlinePlayers()}.
*
* The next plugin message to be received through {@code channel} will be assumed to be
* the response.
*
* @param channel the channel for this plugin message
* @param data the data to add to the outgoing message
* @return a completable future for the message of the responding plugin message, if there is one.
* this completable future will complete exceptionally if no players are online.
*/
public static CompletableFuture<ByteArrayDataInput> sendPluginMessage(String channel, String... data) {
return sendPluginMessage(channel, r -> true, data);
}
/**
* Sends a plugin message using the from {@code player}.
*
* The next plugin message to be received through {@code channel} will be assumed to be
* the response.
*
* @param player the player to send the plugin message through
* @param channel the channel for this plugin message
* @param data the data to add to the outgoing message
* @return a completable future for the message of the responding plugin message, if there is one.
* this completable future will complete exceptionally if no players are online.
*/
public static CompletableFuture<ByteArrayDataInput> sendPluginMessage(Player player, String channel, String... data) {
return sendPluginMessage(player, channel, r -> true, data);
}
/**
* Sends a plugin message using the first player from {@link Bukkit#getOnlinePlayers()}.
*
* @param channel the channel for this plugin message
* @param messageVerifier verifies that a plugin message is the response to the sent message
* @param data the data to add to the outgoing message
* @return a completable future for the message of the responding plugin message, if there is one.
* this completable future will complete exceptionally if the player is null.
*/
public static CompletableFuture<ByteArrayDataInput> sendPluginMessage(String channel,
Predicate<ByteArrayDataInput> messageVerifier, String... data) {
Player firstPlayer = Iterables.getFirst(Bukkit.getOnlinePlayers(), null);
return sendPluginMessage(firstPlayer, channel, messageVerifier, data);
}
/**
* Sends a plugin message.
*
* Example usage using the "GetServers" bungee plugin message channel via an overload:
* <code>
* Utils.sendPluginMessage("BungeeCord", r -> "GetServers".equals(r.readUTF()), "GetServers")
* .thenAccept(response -> Bukkit.broadcastMessage(response.readUTF()) // comma delimited server broadcast
* .exceptionally(ex -> {
* Skript.warning("Failed to get servers because there are no players online");
* return null;
* });
* </code>
*
* @param player the player to send the plugin message through
* @param channel the channel for this plugin message
* @param messageVerifier verifies that a plugin message is the response to the sent message
* @param data the data to add to the outgoing message
* @return a completable future for the message of the responding plugin message, if there is one.
* this completable future will complete exceptionally if the player is null.
*/
public static CompletableFuture<ByteArrayDataInput> sendPluginMessage(Player player, String channel,
Predicate<ByteArrayDataInput> messageVerifier, String... data) {
CompletableFuture<ByteArrayDataInput> completableFuture = new CompletableFuture<>();
if (player == null) {
completableFuture.completeExceptionally(new IllegalStateException("Can't send plugin messages from a null player"));
return completableFuture;
}
Bukkit.getMessenger().registerOutgoingPluginChannel(Skript.getInstance(), channel);
Bukkit.getMessenger().registerIncomingPluginChannel(Skript.getInstance(), channel, new PluginMessageListener() {
@Override
public void onPluginMessageReceived(@Nullable String sendingChannel, @Nullable Player sendingPlayer,
@Nullable byte[] message) {
ByteArrayDataInput input = ByteStreams.newDataInput(message);
if (channel.equals(sendingChannel) && sendingPlayer == player && !completableFuture.isDone()
&& messageVerifier.test(input)) {
completableFuture.complete(input);
Bukkit.getMessenger().unregisterIncomingPluginChannel(Skript.getInstance(), channel, this);
}
}
});
ByteArrayDataOutput out = ByteStreams.newDataOutput();
Stream.of(data).forEach(out::writeUTF);
player.sendPluginMessage(Skript.getInstance(), channel, out.toByteArray());
return completableFuture;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment