Permalink
Browse files

Fix BukkitMCServer broadcast behaviour + Update broadcast() docs

- Remove usage of Server.broadcastMessage(...) methods since they also broadcast to all active command blocks in-game, effectively setting their last output value in their GUI.
- Broadcast to console unless a recipients set is supplied without the console command sender in it.
- Update broadcast() documentation to match the changes.
- Add javadocs to MCServer to describe the broadcastMessage(...) behaviour that implementations should follow.
  • Loading branch information...
Pieter12345 committed Jun 28, 2018
1 parent 071371d commit 5097011b8f41377fde422206912f0b6ade0c3314
@@ -29,10 +29,25 @@
List<MCWorld> getWorlds();
/**
* Broadcasts a message to all online players and console.
* @param message - The message to broadcast.
*/
void broadcastMessage(String message);
/**
* Broadcasts a message to all online players with a given permission and console.
* @param message - The message to broadcast.
* @param permission - The required permission to receive the message.
*/
void broadcastMessage(String message, String permission);
/**
* Broadcasts a message to a list of recipients.
* {@link MCConsoleCommandSender Console} has to be included in this list to receive the broadcast.
* @param message - The message to broadcast.
* @param recipients - A list of {@link MCCommandSender command senders} to send the message to.
*/
void broadcastMessage(String message, Set<MCCommandSender> recipients);
MCConsoleCommandSender getConsole();
@@ -207,12 +207,29 @@ public MCWorld getWorld(String name) {
@Override
public void broadcastMessage(String message) {
s.broadcastMessage(message);
// Get the set of online players and include console.
Set<CommandSender> recipients = new HashSet<>(this.s.getOnlinePlayers());
recipients.add(this.s.getConsoleSender());
// Perform the broadcast.
this.bukkitBroadcastMessage(message, recipients);
}
@Override
public void broadcastMessage(String message, String permission) {
s.broadcast(message, permission);
// Get the set of online players with the given permission and include console.
Set<CommandSender> recipients = new HashSet<>();
for(Player player : this.s.getOnlinePlayers()) {
if(player.hasPermission(permission)) {
recipients.add(player);
}
}
recipients.add(this.s.getConsoleSender());
// Perform the broadcast.
this.bukkitBroadcastMessage(message, recipients);
}
@Override
@@ -221,27 +238,44 @@ public void broadcastMessage(String message, Set<MCCommandSender> recipients) {
// Convert MCCommandsSender recipients to CommandSender recipients.
Set<CommandSender> bukkitRecipients = new HashSet<>();
if(recipients != null) {
for(MCCommandSender mcSender : recipients) {
bukkitRecipients.add((CommandSender) mcSender.getHandle());
for(MCCommandSender recipient : recipients) {
bukkitRecipients.add((CommandSender) recipient.getHandle());
}
}
// Perform the broadcast.
this.bukkitBroadcastMessage(message, bukkitRecipients);
}
/**
* Broadcasts a message to a list of recipients, fireing a {@link BroadcastMessageEvent} before doing so.
* {@link ConsoleCommandSender Console} has to be included in this list to receive the broadcast.
* @param message - The message to broadcast.
* @param recipients - A list of {@link MCCommandSender command senders} to send the message to.
* @return The amount of recipients that received the message.
*/
private int bukkitBroadcastMessage(String message, Set<CommandSender> recipients) {
// Fire a BroadcastMessageEvent for this broadcast.
BroadcastMessageEvent broadcastMessageEvent = new BroadcastMessageEvent(message, bukkitRecipients);
BroadcastMessageEvent broadcastMessageEvent = new BroadcastMessageEvent(message, recipients);
this.s.getPluginManager().callEvent(broadcastMessageEvent);
// Return if the event was cancelled.
if(broadcastMessageEvent.isCancelled()) {
return;
return 0;
}
// Get the possibly modified message.
// Get the possibly modified message and recipients.
message = broadcastMessageEvent.getMessage();
recipients = broadcastMessageEvent.getRecipients(); // This returns the same reference, but breaks less likely.
// Perform the actual broadcast to all remaining recipients.
for(CommandSender recipient : broadcastMessageEvent.getRecipients()) {
for(CommandSender recipient : recipients) {
recipient.sendMessage(message);
}
// Return the amount of recipients that received the message.
return recipients.size();
}
@Override
@@ -624,15 +624,14 @@ public String getName() {
@Override
public String docs() {
return "void {message, [permission] | message, [players]} Broadcasts a message to all or some players"
return "void {message, [permission] | message, [recipients]} Broadcasts a message to all or some players"
+ " and/or console."
+ " If permission is given, only players with that permission will see the broadcast. On Bukkit"
+ " servers, console will only receive the broadcast when permission is 'bukkit.broadcast'."
+ " If an array is given, only online players in the list will see the broadcast."
+ " If permission is given, only players with that permission and console will see the broadcast."
+ " If an array of recipients is given, only online players in the list will see the broadcast."
+ " Console will receive the broadcast only when the array contains case-insensitive '~console'."
+ " Offline players in the list will be ignored."
+ " If permission/players is null, all players and console will see the broadcast."
+ " Throws CREFormatException when the given players array is associative.";
+ " Offline players and duplicate recipients in the list will be ignored."
+ " If permission/recipients is null, all players and console will see the broadcast."
+ " Throws FormatException when the given recipients array is associative.";
}
@Override
@@ -660,7 +659,7 @@ public Construct exec(Target t, Environment env, Construct... args) throws Confi
return CVoid.VOID;
}
// Handle "broadcast(message, playerArray)".
// Handle "broadcast(message, recipientsArray)".
if(args[1] instanceof CArray) {
// Get the CArray and validate that it is non-associative.
@@ -670,7 +669,7 @@ public Construct exec(Target t, Environment env, Construct... args) throws Confi
"Expected a non-associative array or permission as the second parameter.", t);
}
// Get the player recipients from the array.
// Get the recipients from the array.
Set<MCCommandSender> recipients = new HashSet<>();
for(Construct p : array.asList()) {
if(p.val().equalsIgnoreCase("~console")) {

0 comments on commit 5097011

Please sign in to comment.