Skip to content

Commit 5097011

Browse files
committed
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.
1 parent 071371d commit 5097011

File tree

3 files changed

+65
-17
lines changed

3 files changed

+65
-17
lines changed

src/main/java/com/laytonsmith/abstraction/MCServer.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,25 @@ public interface MCServer extends AbstractionObject {
2929

3030
List<MCWorld> getWorlds();
3131

32+
/**
33+
* Broadcasts a message to all online players and console.
34+
* @param message - The message to broadcast.
35+
*/
3236
void broadcastMessage(String message);
3337

38+
/**
39+
* Broadcasts a message to all online players with a given permission and console.
40+
* @param message - The message to broadcast.
41+
* @param permission - The required permission to receive the message.
42+
*/
3443
void broadcastMessage(String message, String permission);
3544

45+
/**
46+
* Broadcasts a message to a list of recipients.
47+
* {@link MCConsoleCommandSender Console} has to be included in this list to receive the broadcast.
48+
* @param message - The message to broadcast.
49+
* @param recipients - A list of {@link MCCommandSender command senders} to send the message to.
50+
*/
3651
void broadcastMessage(String message, Set<MCCommandSender> recipients);
3752

3853
MCConsoleCommandSender getConsole();

src/main/java/com/laytonsmith/abstraction/bukkit/BukkitMCServer.java

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -207,12 +207,29 @@ public List<MCWorld> getWorlds() {
207207

208208
@Override
209209
public void broadcastMessage(String message) {
210-
s.broadcastMessage(message);
210+
211+
// Get the set of online players and include console.
212+
Set<CommandSender> recipients = new HashSet<>(this.s.getOnlinePlayers());
213+
recipients.add(this.s.getConsoleSender());
214+
215+
// Perform the broadcast.
216+
this.bukkitBroadcastMessage(message, recipients);
211217
}
212218

213219
@Override
214220
public void broadcastMessage(String message, String permission) {
215-
s.broadcast(message, permission);
221+
222+
// Get the set of online players with the given permission and include console.
223+
Set<CommandSender> recipients = new HashSet<>();
224+
for(Player player : this.s.getOnlinePlayers()) {
225+
if(player.hasPermission(permission)) {
226+
recipients.add(player);
227+
}
228+
}
229+
recipients.add(this.s.getConsoleSender());
230+
231+
// Perform the broadcast.
232+
this.bukkitBroadcastMessage(message, recipients);
216233
}
217234

218235
@Override
@@ -221,27 +238,44 @@ public void broadcastMessage(String message, Set<MCCommandSender> recipients) {
221238
// Convert MCCommandsSender recipients to CommandSender recipients.
222239
Set<CommandSender> bukkitRecipients = new HashSet<>();
223240
if(recipients != null) {
224-
for(MCCommandSender mcSender : recipients) {
225-
bukkitRecipients.add((CommandSender) mcSender.getHandle());
241+
for(MCCommandSender recipient : recipients) {
242+
bukkitRecipients.add((CommandSender) recipient.getHandle());
226243
}
227244
}
228245

246+
// Perform the broadcast.
247+
this.bukkitBroadcastMessage(message, bukkitRecipients);
248+
}
249+
250+
/**
251+
* Broadcasts a message to a list of recipients, fireing a {@link BroadcastMessageEvent} before doing so.
252+
* {@link ConsoleCommandSender Console} has to be included in this list to receive the broadcast.
253+
* @param message - The message to broadcast.
254+
* @param recipients - A list of {@link MCCommandSender command senders} to send the message to.
255+
* @return The amount of recipients that received the message.
256+
*/
257+
private int bukkitBroadcastMessage(String message, Set<CommandSender> recipients) {
258+
229259
// Fire a BroadcastMessageEvent for this broadcast.
230-
BroadcastMessageEvent broadcastMessageEvent = new BroadcastMessageEvent(message, bukkitRecipients);
260+
BroadcastMessageEvent broadcastMessageEvent = new BroadcastMessageEvent(message, recipients);
231261
this.s.getPluginManager().callEvent(broadcastMessageEvent);
232262

233263
// Return if the event was cancelled.
234264
if(broadcastMessageEvent.isCancelled()) {
235-
return;
265+
return 0;
236266
}
237267

238-
// Get the possibly modified message.
268+
// Get the possibly modified message and recipients.
239269
message = broadcastMessageEvent.getMessage();
270+
recipients = broadcastMessageEvent.getRecipients(); // This returns the same reference, but breaks less likely.
240271

241272
// Perform the actual broadcast to all remaining recipients.
242-
for(CommandSender recipient : broadcastMessageEvent.getRecipients()) {
273+
for(CommandSender recipient : recipients) {
243274
recipient.sendMessage(message);
244275
}
276+
277+
// Return the amount of recipients that received the message.
278+
return recipients.size();
245279
}
246280

247281
@Override

src/main/java/com/laytonsmith/core/functions/Echoes.java

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -624,15 +624,14 @@ public Integer[] numArgs() {
624624

625625
@Override
626626
public String docs() {
627-
return "void {message, [permission] | message, [players]} Broadcasts a message to all or some players"
627+
return "void {message, [permission] | message, [recipients]} Broadcasts a message to all or some players"
628628
+ " and/or console."
629-
+ " If permission is given, only players with that permission will see the broadcast. On Bukkit"
630-
+ " servers, console will only receive the broadcast when permission is 'bukkit.broadcast'."
631-
+ " If an array is given, only online players in the list will see the broadcast."
629+
+ " If permission is given, only players with that permission and console will see the broadcast."
630+
+ " If an array of recipients is given, only online players in the list will see the broadcast."
632631
+ " Console will receive the broadcast only when the array contains case-insensitive '~console'."
633-
+ " Offline players in the list will be ignored."
634-
+ " If permission/players is null, all players and console will see the broadcast."
635-
+ " Throws CREFormatException when the given players array is associative.";
632+
+ " Offline players and duplicate recipients in the list will be ignored."
633+
+ " If permission/recipients is null, all players and console will see the broadcast."
634+
+ " Throws FormatException when the given recipients array is associative.";
636635
}
637636

638637
@Override
@@ -660,7 +659,7 @@ public Construct exec(Target t, Environment env, Construct... args) throws Confi
660659
return CVoid.VOID;
661660
}
662661

663-
// Handle "broadcast(message, playerArray)".
662+
// Handle "broadcast(message, recipientsArray)".
664663
if(args[1] instanceof CArray) {
665664

666665
// 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
670669
"Expected a non-associative array or permission as the second parameter.", t);
671670
}
672671

673-
// Get the player recipients from the array.
672+
// Get the recipients from the array.
674673
Set<MCCommandSender> recipients = new HashSet<>();
675674
for(Construct p : array.asList()) {
676675
if(p.val().equalsIgnoreCase("~console")) {

0 commit comments

Comments
 (0)