Permalink
Browse files

Merge pull request #492 from Pieter12345/broadcast-function-event

Fix broadcast() function event consistency
  • Loading branch information...
LadyCailin committed Jul 2, 2018
2 parents 8f94455 + 5097011 commit 336166329cb938582e8d2f8465a7348b1b7d7a20
@@ -19,4 +19,5 @@ true
.DS_Store
/test-backend/
/nbproject/
/dependency-reduced-pom.xml
/dependency-reduced-pom.xml
.checkstyle
@@ -11,7 +11,7 @@
<!-- Supression filter to disable specified modules/checks for specified files -->
<module name="SuppressionFilter">
<property name="file" value="checkstyle_suppressions.xml"/>
<property name="file" value="${config_loc}/checkstyle_suppressions.xml"/>
<property name="optional" value="false"/>
</module>
@@ -929,6 +929,7 @@
<testSourceDirectories>${project.testCompileSourceRoots}</testSourceDirectories>
<includeTestSourceDirectory>true</includeTestSourceDirectory>
<configLocation>${basedir}/checkstyle.xml</configLocation>
<propertyExpansion>config_loc=${basedir}</propertyExpansion>
<encoding>UTF-8</encoding>
<consoleOutput>true</consoleOutput>
<failsOnError>true</failsOnError>
@@ -29,10 +29,27 @@
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();
MCItemFactory getItemFactory();
@@ -38,6 +38,7 @@
import org.bukkit.command.SimpleCommandMap;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.server.BroadcastMessageEvent;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.Recipe;
@@ -206,12 +207,75 @@ 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
public void broadcastMessage(String message, Set<MCCommandSender> recipients) {
// Convert MCCommandsSender recipients to CommandSender recipients.
Set<CommandSender> bukkitRecipients = new HashSet<>();
if(recipients != null) {
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, recipients);
this.s.getPluginManager().callEvent(broadcastMessageEvent);
// Return if the event was cancelled.
if(broadcastMessageEvent.isCancelled()) {
return 0;
}
// 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 : recipients) {
recipient.sendMessage(message);
}
// Return the amount of recipients that received the message.
return recipients.size();
}
@Override
@@ -490,8 +554,8 @@ public boolean addRecipe(MCRecipe recipe) {
@Override
public List<MCRecipe> allRecipes() {
List<MCRecipe> ret = new ArrayList<>();
for(Iterator recipes = s.recipeIterator(); recipes.hasNext();) {
Recipe recipe = (Recipe) recipes.next();
for(Iterator<Recipe> recipes = s.recipeIterator(); recipes.hasNext();) {
Recipe recipe = recipes.next();
ret.add(BukkitConvertor.BukkitGetRecipe(recipe));
}
return ret;
@@ -30,6 +30,7 @@
import com.laytonsmith.core.exceptions.ConfigRuntimeException;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
@@ -623,9 +624,14 @@ public String getName() {
@Override
public String docs() {
return "void {message, [permission] | message, [players]} Broadcasts a message to all or some players."
+ " If permission is given, only players with that permission will see the broadcast."
+ " If an array is given, only players in the list will see the broadcast.";
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 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 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
@@ -646,29 +652,45 @@ public CHVersion since() {
@Override
public Construct exec(Target t, Environment env, Construct... args) throws ConfigRuntimeException {
final MCServer server = Static.getServer();
String permission = null;
if(args.length == 2) {
if(args[1] instanceof CArray) {
CArray array = (CArray) args[1];
if(!array.isAssociative()) {
for(Construct p : array.asList()) {
try {
Static.GetPlayer(p, t).sendMessage(args[0].val());
} catch (CREPlayerOfflineException cre) {
// ignore offline players
}
// Handle "broadcast(message, [null])".
if(args.length == 1 || args[1].nval() == null) { // args.length can only be 1 or 2 due to the numArgs().
server.broadcastMessage(args[0].val());
return CVoid.VOID;
}
// Handle "broadcast(message, recipientsArray)".
if(args[1] instanceof CArray) {
// Get the CArray and validate that it is non-associative.
CArray array = (CArray) args[1];
if(array.isAssociative()) {
throw new CREFormatException(
"Expected a non-associative array or permission as the second parameter.", t);
}
// Get the recipients from the array.
Set<MCCommandSender> recipients = new HashSet<>();
for(Construct p : array.asList()) {
if(p.val().equalsIgnoreCase("~console")) {
recipients.add(server.getConsole());
} else {
try {
recipients.add(Static.GetPlayer(p, t));
} catch (CREPlayerOfflineException cre) {
// Ignore offline players.
}
return CVoid.VOID;
}
throw new CREFormatException("Expected a normal array or permission as the second parameter.", t);
}
permission = args[1].nval();
}
if(permission == null) {
server.broadcastMessage(args[0].val());
} else {
server.broadcastMessage(args[0].val(), permission);
// Perform the broadcast and return cvoid.
server.broadcastMessage(args[0].val(), recipients);
return CVoid.VOID;
}
// Handle "broadcast(message, permission)".
String permission = args[1].nval();
server.broadcastMessage(args[0].val(), permission);
return CVoid.VOID;
}

0 comments on commit 3361663

Please sign in to comment.