use of alexh.weak.Weak in project DiscordSRV by Scarsz.
the class AlertListener method process.
private void process(Object event, Dynamic alert, Set<String> triggers, int alertIndex) {
Player player = event instanceof PlayerEvent ? ((PlayerEvent) event).getPlayer() : null;
if (player == null) {
// this will check to see if a #getPlayer() method exists on events coming through
try {
Method getPlayerMethod = event.getClass().getMethod("getPlayer");
if (getPlayerMethod.getReturnType().equals(Player.class)) {
player = (Player) getPlayerMethod.invoke(event);
}
} catch (Exception ignored) {
// we tried ¯\_(ツ)_/¯
}
}
CommandSender sender = null;
String command = null;
List<String> args = new LinkedList<>();
if (event instanceof PlayerCommandPreprocessEvent) {
sender = player;
command = ((PlayerCommandPreprocessEvent) event).getMessage().substring(1);
} else if (event instanceof ServerCommandEvent) {
sender = ((ServerCommandEvent) event).getSender();
command = ((ServerCommandEvent) event).getCommand();
}
if (StringUtils.isNotBlank(command)) {
String[] split = command.split(" ", 2);
String commandBase = split[0];
if (split.length == 2)
args.addAll(Arrays.asList(split[1].split(" ")));
// transform "discordsrv:discord" to just "discord" for example
if (commandBase.contains(":"))
commandBase = commandBase.substring(commandBase.lastIndexOf(":") + 1);
command = commandBase + (split.length == 2 ? (" " + split[1]) : "");
}
MessageFormat messageFormat = DiscordSRV.getPlugin().getMessageFromConfiguration("Alerts." + alertIndex);
for (String trigger : triggers) {
String eventName = getEventName(event);
if (trigger.startsWith("/")) {
if (StringUtils.isBlank(command) || !command.toLowerCase().split("\\s+|$", 2)[0].equals(trigger.substring(1)))
continue;
} else {
// make sure the called event matches what this alert is supposed to trigger on
if (!eventName.equalsIgnoreCase(trigger))
continue;
}
// make sure alert should run even if event is cancelled
if (event instanceof Cancellable && ((Cancellable) event).isCancelled()) {
Dynamic ignoreCancelledDynamic = alert.get("IgnoreCancelled");
boolean ignoreCancelled = ignoreCancelledDynamic.isPresent() ? ignoreCancelledDynamic.as(Boolean.class) : true;
if (ignoreCancelled) {
DiscordSRV.debug(Debug.ALERTS, "Not running alert for event " + eventName + ": event was cancelled");
return;
}
}
Dynamic textChannelsDynamic = alert.get("Channel");
if (textChannelsDynamic == null) {
DiscordSRV.debug(Debug.ALERTS, "Not running alert for trigger " + trigger + ": no target channel was defined");
return;
}
Set<String> channels = new HashSet<>();
if (textChannelsDynamic.isList()) {
textChannelsDynamic.children().map(Weak::asString).filter(Objects::nonNull).forEach(channels::add);
} else if (textChannelsDynamic.isString()) {
channels.add(textChannelsDynamic.asString());
}
Function<Function<String, Collection<TextChannel>>, Set<TextChannel>> channelResolver = converter -> {
Set<TextChannel> textChannels = new HashSet<>();
channels.forEach(channel -> textChannels.addAll(converter.apply(channel)));
textChannels.removeIf(Objects::isNull);
return textChannels;
};
Set<TextChannel> textChannels = channelResolver.apply(s -> {
TextChannel target = DiscordSRV.getPlugin().getDestinationTextChannelForGameChannelName(s);
return Collections.singleton(target);
});
if (textChannels.isEmpty()) {
textChannels.addAll(channelResolver.apply(s -> DiscordUtil.getJda().getTextChannelsByName(s, false)));
}
if (textChannels.isEmpty()) {
textChannels.addAll(channelResolver.apply(s -> NumberUtils.isDigits(s) ? Collections.singleton(DiscordUtil.getJda().getTextChannelById(s)) : Collections.emptyList()));
}
if (textChannels.size() == 0) {
DiscordSRV.debug(Debug.ALERTS, "Not running alert for trigger " + trigger + ": no target channel was defined/found (channels: " + channels + ")");
return;
}
for (TextChannel textChannel : textChannels) {
// check alert conditions
boolean allConditionsMet = true;
Dynamic conditionsDynamic = alert.dget("Conditions");
if (conditionsDynamic.isPresent()) {
Iterator<Dynamic> conditions = conditionsDynamic.children().iterator();
while (conditions.hasNext()) {
Dynamic dynamic = conditions.next();
String expression = dynamic.convert().intoString();
try {
Boolean value = new SpELExpressionBuilder(expression).withPluginVariables().withVariable("event", event).withVariable("server", Bukkit.getServer()).withVariable("discordsrv", DiscordSRV.getPlugin()).withVariable("player", player).withVariable("sender", sender).withVariable("command", command).withVariable("args", args).withVariable("allArgs", String.join(" ", args)).withVariable("channel", textChannel).withVariable("jda", DiscordUtil.getJda()).evaluate(event, Boolean.class);
DiscordSRV.debug(Debug.ALERTS, "Condition \"" + expression + "\" -> " + value);
if (value != null && !value) {
allConditionsMet = false;
break;
}
} catch (ParseException e) {
DiscordSRV.error("Error while parsing expression \"" + expression + "\" for trigger \"" + trigger + "\" -> " + e.getMessage());
} catch (SpelEvaluationException e) {
DiscordSRV.error("Error while evaluating expression \"" + expression + "\" for trigger \"" + trigger + "\" -> " + e.getMessage());
}
}
if (!allConditionsMet)
continue;
}
CommandSender finalSender = sender;
String finalCommand = command;
Player finalPlayer = player;
BiFunction<String, Boolean, String> translator = (content, needsEscape) -> {
if (content == null)
return null;
// evaluate any SpEL expressions
Map<String, Object> variables = new HashMap<>();
variables.put("event", event);
variables.put("server", Bukkit.getServer());
variables.put("discordsrv", DiscordSRV.getPlugin());
variables.put("player", finalPlayer);
variables.put("sender", finalSender);
variables.put("command", finalCommand);
variables.put("args", args);
variables.put("allArgs", String.join(" ", args));
variables.put("channel", textChannel);
variables.put("jda", DiscordUtil.getJda());
content = NamedValueFormatter.formatExpressions(content, event, variables);
// replace any normal placeholders
content = NamedValueFormatter.format(content, key -> {
switch(key) {
case "tps":
return Lag.getTPSString();
case "time":
case "date":
return TimeUtil.timeStamp();
case "ping":
return finalPlayer != null ? PlayerUtil.getPing(finalPlayer) : "-1";
case "name":
case "username":
return finalPlayer != null ? finalPlayer.getName() : "";
case "displayname":
return finalPlayer != null ? MessageUtil.strip(needsEscape ? DiscordUtil.escapeMarkdown(finalPlayer.getDisplayName()) : finalPlayer.getDisplayName()) : "";
case "world":
return finalPlayer != null ? finalPlayer.getWorld().getName() : "";
case "embedavatarurl":
return finalPlayer != null ? DiscordSRV.getAvatarUrl(finalPlayer) : DiscordUtil.getJda().getSelfUser().getEffectiveAvatarUrl();
case "botavatarurl":
return DiscordUtil.getJda().getSelfUser().getEffectiveAvatarUrl();
case "botname":
return DiscordSRV.getPlugin().getMainGuild() != null ? DiscordSRV.getPlugin().getMainGuild().getSelfMember().getEffectiveName() : DiscordUtil.getJda().getSelfUser().getName();
default:
return "{" + key + "}";
}
});
content = DiscordUtil.translateEmotes(content, textChannel.getGuild());
content = PlaceholderUtil.replacePlaceholdersToDiscord(content, finalPlayer);
return content;
};
Message message = DiscordSRV.translateMessage(messageFormat, translator);
if (message == null) {
DiscordSRV.debug(Debug.ALERTS, "Not sending alert because it is configured to have no message content");
return;
}
if (messageFormat.isUseWebhooks()) {
WebhookUtil.deliverMessage(textChannel, translator.apply(messageFormat.getWebhookName(), false), translator.apply(messageFormat.getWebhookAvatarUrl(), false), message.getContentRaw(), message.getEmbeds().stream().findFirst().orElse(null));
} else {
DiscordUtil.queueMessage(textChannel, message);
}
}
}
}
Aggregations