Skip to content

Commit 3361663

Browse files
authored
Merge pull request #492 from Pieter12345/broadcast-function-event
Fix broadcast() function event consistency
2 parents 8f94455 + 5097011 commit 3361663

File tree

6 files changed

+133
-28
lines changed

6 files changed

+133
-28
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,5 @@ true
1919
.DS_Store
2020
/test-backend/
2121
/nbproject/
22-
/dependency-reduced-pom.xml
22+
/dependency-reduced-pom.xml
23+
.checkstyle

checkstyle.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
<!-- Supression filter to disable specified modules/checks for specified files -->
1313
<module name="SuppressionFilter">
14-
<property name="file" value="checkstyle_suppressions.xml"/>
14+
<property name="file" value="${config_loc}/checkstyle_suppressions.xml"/>
1515
<property name="optional" value="false"/>
1616
</module>
1717

pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -929,6 +929,7 @@
929929
<testSourceDirectories>${project.testCompileSourceRoots}</testSourceDirectories>
930930
<includeTestSourceDirectory>true</includeTestSourceDirectory>
931931
<configLocation>${basedir}/checkstyle.xml</configLocation>
932+
<propertyExpansion>config_loc=${basedir}</propertyExpansion>
932933
<encoding>UTF-8</encoding>
933934
<consoleOutput>true</consoleOutput>
934935
<failsOnError>true</failsOnError>

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,27 @@ 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+
*/
51+
void broadcastMessage(String message, Set<MCCommandSender> recipients);
52+
3653
MCConsoleCommandSender getConsole();
3754

3855
MCItemFactory getItemFactory();

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

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import org.bukkit.command.SimpleCommandMap;
3939
import org.bukkit.entity.Player;
4040
import org.bukkit.event.inventory.InventoryType;
41+
import org.bukkit.event.server.BroadcastMessageEvent;
4142
import org.bukkit.inventory.InventoryHolder;
4243
import org.bukkit.inventory.Recipe;
4344

@@ -206,12 +207,75 @@ public List<MCWorld> getWorlds() {
206207

207208
@Override
208209
public void broadcastMessage(String message) {
209-
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);
210217
}
211218

212219
@Override
213220
public void broadcastMessage(String message, String permission) {
214-
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);
233+
}
234+
235+
@Override
236+
public void broadcastMessage(String message, Set<MCCommandSender> recipients) {
237+
238+
// Convert MCCommandsSender recipients to CommandSender recipients.
239+
Set<CommandSender> bukkitRecipients = new HashSet<>();
240+
if(recipients != null) {
241+
for(MCCommandSender recipient : recipients) {
242+
bukkitRecipients.add((CommandSender) recipient.getHandle());
243+
}
244+
}
245+
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+
259+
// Fire a BroadcastMessageEvent for this broadcast.
260+
BroadcastMessageEvent broadcastMessageEvent = new BroadcastMessageEvent(message, recipients);
261+
this.s.getPluginManager().callEvent(broadcastMessageEvent);
262+
263+
// Return if the event was cancelled.
264+
if(broadcastMessageEvent.isCancelled()) {
265+
return 0;
266+
}
267+
268+
// Get the possibly modified message and recipients.
269+
message = broadcastMessageEvent.getMessage();
270+
recipients = broadcastMessageEvent.getRecipients(); // This returns the same reference, but breaks less likely.
271+
272+
// Perform the actual broadcast to all remaining recipients.
273+
for(CommandSender recipient : recipients) {
274+
recipient.sendMessage(message);
275+
}
276+
277+
// Return the amount of recipients that received the message.
278+
return recipients.size();
215279
}
216280

217281
@Override
@@ -490,8 +554,8 @@ public List<MCRecipe> getRecipesFor(MCItemStack result) {
490554
@Override
491555
public List<MCRecipe> allRecipes() {
492556
List<MCRecipe> ret = new ArrayList<>();
493-
for(Iterator recipes = s.recipeIterator(); recipes.hasNext();) {
494-
Recipe recipe = (Recipe) recipes.next();
557+
for(Iterator<Recipe> recipes = s.recipeIterator(); recipes.hasNext();) {
558+
Recipe recipe = recipes.next();
495559
ret.add(BukkitConvertor.BukkitGetRecipe(recipe));
496560
}
497561
return ret;

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

Lines changed: 44 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import com.laytonsmith.core.exceptions.ConfigRuntimeException;
3131
import java.util.Collections;
3232
import java.util.EnumSet;
33+
import java.util.HashSet;
3334
import java.util.Map;
3435
import java.util.Set;
3536
import java.util.TreeMap;
@@ -623,9 +624,14 @@ public Integer[] numArgs() {
623624

624625
@Override
625626
public String docs() {
626-
return "void {message, [permission] | message, [players]} Broadcasts a message to all or some players."
627-
+ " If permission is given, only players with that permission will see the broadcast."
628-
+ " If an array is given, only players in the list will see the broadcast.";
627+
return "void {message, [permission] | message, [recipients]} Broadcasts a message to all or some players"
628+
+ " and/or console."
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."
631+
+ " Console will receive the broadcast only when the array contains case-insensitive '~console'."
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.";
629635
}
630636

631637
@Override
@@ -646,29 +652,45 @@ public CHVersion since() {
646652
@Override
647653
public Construct exec(Target t, Environment env, Construct... args) throws ConfigRuntimeException {
648654
final MCServer server = Static.getServer();
649-
String permission = null;
650-
if(args.length == 2) {
651-
if(args[1] instanceof CArray) {
652-
CArray array = (CArray) args[1];
653-
if(!array.isAssociative()) {
654-
for(Construct p : array.asList()) {
655-
try {
656-
Static.GetPlayer(p, t).sendMessage(args[0].val());
657-
} catch (CREPlayerOfflineException cre) {
658-
// ignore offline players
659-
}
655+
656+
// Handle "broadcast(message, [null])".
657+
if(args.length == 1 || args[1].nval() == null) { // args.length can only be 1 or 2 due to the numArgs().
658+
server.broadcastMessage(args[0].val());
659+
return CVoid.VOID;
660+
}
661+
662+
// Handle "broadcast(message, recipientsArray)".
663+
if(args[1] instanceof CArray) {
664+
665+
// Get the CArray and validate that it is non-associative.
666+
CArray array = (CArray) args[1];
667+
if(array.isAssociative()) {
668+
throw new CREFormatException(
669+
"Expected a non-associative array or permission as the second parameter.", t);
670+
}
671+
672+
// Get the recipients from the array.
673+
Set<MCCommandSender> recipients = new HashSet<>();
674+
for(Construct p : array.asList()) {
675+
if(p.val().equalsIgnoreCase("~console")) {
676+
recipients.add(server.getConsole());
677+
} else {
678+
try {
679+
recipients.add(Static.GetPlayer(p, t));
680+
} catch (CREPlayerOfflineException cre) {
681+
// Ignore offline players.
660682
}
661-
return CVoid.VOID;
662683
}
663-
throw new CREFormatException("Expected a normal array or permission as the second parameter.", t);
664684
}
665-
permission = args[1].nval();
666-
}
667-
if(permission == null) {
668-
server.broadcastMessage(args[0].val());
669-
} else {
670-
server.broadcastMessage(args[0].val(), permission);
685+
686+
// Perform the broadcast and return cvoid.
687+
server.broadcastMessage(args[0].val(), recipients);
688+
return CVoid.VOID;
671689
}
690+
691+
// Handle "broadcast(message, permission)".
692+
String permission = args[1].nval();
693+
server.broadcastMessage(args[0].val(), permission);
672694
return CVoid.VOID;
673695
}
674696

0 commit comments

Comments
 (0)