Search in sources :

Example 1 with Weak

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);
            }
        }
    }
}
Also used : SpelEvaluationException(org.springframework.expression.spel.SpelEvaluationException) Dynamic(alexh.weak.Dynamic) java.util(java.util) MessageFormat(github.scarsz.discordsrv.objects.MessageFormat) BiFunction(java.util.function.BiFunction) TextChannel(net.dv8tion.jda.api.entities.TextChannel) Player(org.bukkit.entity.Player) StringUtils(org.apache.commons.lang3.StringUtils) Function(java.util.function.Function) ServerCommandEvent(org.bukkit.event.server.ServerCommandEvent) Matcher(java.util.regex.Matcher) DiscordSRV(github.scarsz.discordsrv.DiscordSRV) org.bukkit.event(org.bukkit.event) PlayerCommandPreprocessEvent(org.bukkit.event.player.PlayerCommandPreprocessEvent) Weak(alexh.weak.Weak) GenericEvent(net.dv8tion.jda.api.events.GenericEvent) github.scarsz.discordsrv.util(github.scarsz.discordsrv.util) Method(java.lang.reflect.Method) ParseException(org.springframework.expression.ParseException) Bukkit(org.bukkit.Bukkit) Message(net.dv8tion.jda.api.entities.Message) Lag(github.scarsz.discordsrv.objects.Lag) CommandSender(org.bukkit.command.CommandSender) Field(java.lang.reflect.Field) Collectors(java.util.stream.Collectors) InvocationTargetException(java.lang.reflect.InvocationTargetException) Debug(github.scarsz.discordsrv.Debug) Subscribe(github.scarsz.discordsrv.api.Subscribe) RegisteredListener(org.bukkit.plugin.RegisteredListener) TimeUnit(java.util.concurrent.TimeUnit) EventListener(net.dv8tion.jda.api.hooks.EventListener) Modifier(java.lang.reflect.Modifier) NumberUtils(org.apache.commons.lang3.math.NumberUtils) PlayerEvent(org.bukkit.event.player.PlayerEvent) ExpiringDualHashBidiMap(github.scarsz.discordsrv.objects.ExpiringDualHashBidiMap) Pattern(java.util.regex.Pattern) NotNull(org.jetbrains.annotations.NotNull) Dynamic(alexh.weak.Dynamic) Message(net.dv8tion.jda.api.entities.Message) BiFunction(java.util.function.BiFunction) Function(java.util.function.Function) TextChannel(net.dv8tion.jda.api.entities.TextChannel) Player(org.bukkit.entity.Player) SpelEvaluationException(org.springframework.expression.spel.SpelEvaluationException) MessageFormat(github.scarsz.discordsrv.objects.MessageFormat) PlayerEvent(org.bukkit.event.player.PlayerEvent) Method(java.lang.reflect.Method) ServerCommandEvent(org.bukkit.event.server.ServerCommandEvent) SpelEvaluationException(org.springframework.expression.spel.SpelEvaluationException) ParseException(org.springframework.expression.ParseException) InvocationTargetException(java.lang.reflect.InvocationTargetException) PlayerCommandPreprocessEvent(org.bukkit.event.player.PlayerCommandPreprocessEvent) Weak(alexh.weak.Weak) CommandSender(org.bukkit.command.CommandSender) ParseException(org.springframework.expression.ParseException) ExpiringDualHashBidiMap(github.scarsz.discordsrv.objects.ExpiringDualHashBidiMap)

Aggregations

Dynamic (alexh.weak.Dynamic)1 Weak (alexh.weak.Weak)1 Debug (github.scarsz.discordsrv.Debug)1 DiscordSRV (github.scarsz.discordsrv.DiscordSRV)1 Subscribe (github.scarsz.discordsrv.api.Subscribe)1 ExpiringDualHashBidiMap (github.scarsz.discordsrv.objects.ExpiringDualHashBidiMap)1 Lag (github.scarsz.discordsrv.objects.Lag)1 MessageFormat (github.scarsz.discordsrv.objects.MessageFormat)1 github.scarsz.discordsrv.util (github.scarsz.discordsrv.util)1 Field (java.lang.reflect.Field)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 Method (java.lang.reflect.Method)1 Modifier (java.lang.reflect.Modifier)1 java.util (java.util)1 TimeUnit (java.util.concurrent.TimeUnit)1 BiFunction (java.util.function.BiFunction)1 Function (java.util.function.Function)1 Matcher (java.util.regex.Matcher)1 Pattern (java.util.regex.Pattern)1 Collectors (java.util.stream.Collectors)1