Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make EffBroadcast calls BroadcastMessageEvent #5979

Merged
Merged
80 changes: 65 additions & 15 deletions src/main/java/ch/njol/skript/effects/EffBroadcast.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@
*/
package ch.njol.skript.effects;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;

import ch.njol.skript.Skript;
import ch.njol.skript.doc.Description;
import ch.njol.skript.doc.Examples;
Expand All @@ -31,19 +38,20 @@
import ch.njol.skript.lang.VariableString;
import ch.njol.skript.registrations.Classes;
import ch.njol.skript.util.LiteralUtils;
import ch.njol.skript.util.SkriptColor;
import ch.njol.skript.util.Utils;
import ch.njol.skript.util.chat.BungeeConverter;
import ch.njol.skript.util.chat.ChatMessages;
import ch.njol.util.Kleenean;
import ch.njol.util.StringUtils;
import ch.njol.util.coll.CollectionUtils;
import net.md_5.bungee.api.chat.BaseComponent;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.event.Event;
import org.eclipse.jdt.annotation.Nullable;

import java.util.ArrayList;
import java.util.List;
import org.bukkit.event.server.BroadcastMessageEvent;
import org.jetbrains.annotations.Nullable;

@Name("Broadcast")
@Description("Broadcasts a message to the server.")
Expand All @@ -54,6 +62,8 @@
@Since("1.0, 2.6 (broadcasting objects), 2.6.1 (using advanced formatting)")
public class EffBroadcast extends Effect {

private static final Pattern HEX_PATTERN = Pattern.compile("(?i)&x((?:&\\p{XDigit}){6})");

Comment on lines +65 to +66
Copy link
Contributor

@Fusezion Fusezion Sep 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be worth while making a public static final for this in Utils? we currently have this created in utils, raw string and now effect broadcast.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would love to honestly, but I'm afraid that such changes seems out of scope of this PR for the team. So I'll leave this as is.

static {
Skript.registerEffect(EffBroadcast.class, "broadcast %objects% [(to|in) %-worlds%]");
}
Expand All @@ -65,56 +75,96 @@ public class EffBroadcast extends Effect {
@Nullable
private Expression<World> worlds;

@SuppressWarnings("unchecked")
@Override
@SuppressWarnings("unchecked")
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
messageExpr = LiteralUtils.defendExpression(exprs[0]);
messages = messageExpr instanceof ExpressionList ?
((ExpressionList<?>) messageExpr).getExpressions() : new Expression[] {messageExpr};
worlds = (Expression<World>) exprs[1];
return LiteralUtils.canInitSafely(messageExpr);
}


/**
* This effect will call {@link BroadcastMessageEvent} as of INSERT_VERSION.
*/
@Override
@SuppressWarnings("deprecation")
public void execute(Event e) {
public void execute(Event event) {
List<CommandSender> receivers = new ArrayList<>();
if (worlds == null) {
receivers.addAll(Bukkit.getOnlinePlayers());
receivers.add(Bukkit.getConsoleSender());
} else {
for (World world : worlds.getArray(e))
for (World world : worlds.getArray(event))
receivers.addAll(world.getPlayers());
}

for (Expression<?> message : getMessages()) {
if (message instanceof VariableString) {
BaseComponent[] components = BungeeConverter.convert(((VariableString) message).getMessageComponents(e));
if (!dispatchEvent(getRawString(event, (VariableString) message), receivers))
continue;
BaseComponent[] components = BungeeConverter.convert(((VariableString) message).getMessageComponents(event));
receivers.forEach(receiver -> receiver.spigot().sendMessage(components));
} else if (message instanceof ExprColoured && ((ExprColoured) message).isUnsafeFormat()) { // Manually marked as trusted
for (Object realMessage : message.getArray(e)) {
for (Object realMessage : message.getArray(event)) {
if (!dispatchEvent(Utils.replaceChatStyles((String) realMessage), receivers))
continue;
BaseComponent[] components = BungeeConverter.convert(ChatMessages.parse((String) realMessage));
receivers.forEach(receiver -> receiver.spigot().sendMessage(components));
}
} else {
for (Object messageObject : message.getArray(e)) {
for (Object messageObject : message.getArray(event)) {
String realMessage = messageObject instanceof String ? (String) messageObject : Classes.toString(messageObject);
if (!dispatchEvent(Utils.replaceChatStyles(realMessage), receivers))
continue;
receivers.forEach(receiver -> receiver.sendMessage(realMessage));
}
}
}
}

@Override
public String toString(@Nullable Event event, boolean debug) {
return "broadcast " + messageExpr.toString(event, debug) + (worlds == null ? "" : " to " + worlds.toString(event, debug));
}

private Expression<?>[] getMessages() {
if (messageExpr instanceof ExpressionList && !messageExpr.getAnd()) {
return new Expression[] {CollectionUtils.getRandom(messages)};
}
return messages;
}

@Override
public String toString(@Nullable Event e, boolean debug) {
return "broadcast " + messageExpr.toString(e, debug) + (worlds == null ? "" : " to " + worlds.toString(e, debug));
/**
* Manually calls a {@link BroadcastMessageEvent}.
* @param message the message
* @return true if the dispatched event does not get cancelled
*/
@SuppressWarnings("deprecation")
private static boolean dispatchEvent(String message, List<CommandSender> receivers) {
Set<CommandSender> recipients = Collections.unmodifiableSet(new HashSet<>(receivers));
BroadcastMessageEvent broadcastEvent;
if (!Skript.isRunningMinecraft(1, 13)) {
broadcastEvent = new BroadcastMessageEvent(!Bukkit.isPrimaryThread(), message, recipients);
} else {
NotSoDelayed marked this conversation as resolved.
Show resolved Hide resolved
broadcastEvent = new BroadcastMessageEvent(message, recipients);
}
Bukkit.getPluginManager().callEvent(broadcastEvent);
return !broadcastEvent.isCancelled();
}


@Nullable
private static String getRawString(Event event, Expression<? extends String> string) {
if (string instanceof VariableString)
Moderocky marked this conversation as resolved.
Show resolved Hide resolved
return ((VariableString) string).toUnformattedString(event);
String rawString = string.getSingle(event);
rawString = SkriptColor.replaceColorChar(rawString);
if (rawString.toLowerCase().contains("&x")) {
rawString = StringUtils.replaceAll(rawString, HEX_PATTERN, matchResult ->
"<#" + matchResult.group(1).replace("&", "") + '>');
}
return rawString;
}

}