<commit_before>package co.phoenixlab.discord;

import co.phoenixlab.common.lang.SafeNav;
import co.phoenixlab.discord.api.DiscordApiClient;
import co.phoenixlab.discord.api.entities.*;
import co.phoenixlab.discord.api.event.*;
import co.phoenixlab.discord.commands.tempstorage.TempServerConfig;
import com.google.common.eventbus.Subscribe;

import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

public class EventListener {

    private final VahrhedralBot bot;
    public Map<String, Consumer<MemberChangeEvent>> memberChangeEventListener;
    public Map<String, String> joinMessageRedirect;
    public Set<String> ignoredServers;
    public int excessiveMentionThreshold;
    public Map<String, Deque<String>> newest = new HashMap<>();
    private Map<String, Consumer<Message>> messageListeners;
    private Map<String, Long> currentDateTimeLastUse = new HashMap<>();

    public EventListener(VahrhedralBot bot) {
        this.bot = bot;
        messageListeners = new HashMap<>();
        memberChangeEventListener = new HashMap<>();
        joinMessageRedirect = new HashMap<>();
        ignoredServers = new HashSet<>();
        messageListeners.put("mention-bot", message -> {
            User me = bot.getApiClient().getClientUser();
            for (User user : message.getMentions()) {
                if (me.equals(user)) {
                    handleMention(message);
                    return;
                }
            }
        });
        excessiveMentionThreshold = 5;
        messageListeners.put("mention-autotimeout", this::handleExcessiveMentions);
        messageListeners.put("invite-pm", this::onInviteLinkPrivateMessage);
        messageListeners.put("other-prefixes", this::onOtherTypesCommand);
//        messageListeners.put("date-time", this::currentDateTime);
    }

    private void currentDateTime(Message message) {
        if (!bot.getMainCommandDispatcher().active().get()) {
            return;
        }
        String channelId = message.getChannelId();
        boolean cd = false;
        if (currentDateTimeLastUse.containsKey(channelId)) {
            long time = currentDateTimeLastUse.get(channelId);
            if (time >= System.currentTimeMillis()) {
                currentDateTimeLastUse.remove(channelId);
            } else if (System.currentTimeMillis() - time < TimeUnit.SECONDS.toMillis(30)) {
                cd = true;
            }
        }
        long time = System.currentTimeMillis();
        DiscordApiClient api = bot.getApiClient();
        String content = message.getContent().toLowerCase();
        if (content.contains("current year")) {
            if (cd) {
                return;
            }
            api.sendMessage("NOFLIPIt's " + ZonedDateTime.now().getYear() + ", `" + message.getAuthor().getUsername() + "`.",
                    channelId);
            currentDateTimeLastUse.put(channelId, time);
        }
        if (content.contains("current date")) {
            if (cd) {
                return;
            }
            api.sendMessage("NOFLIPIt's " + DateTimeFormatter.ofPattern("MMM dd uuuu").format(ZonedDateTime.now()) + ", `" +
                            message.getAuthor().getUsername() + "`.",
                    channelId);
            currentDateTimeLastUse.put(channelId, time);
        }
        if (content.contains("current day")) {
            if (cd) {
                return;
            }
            api.sendMessage("NOFLIPIt's the " + th(ZonedDateTime.now().getDayOfMonth()) + ", `" +
                            message.getAuthor().getUsername() + "`.",
                    channelId);
            currentDateTimeLastUse.put(channelId, time);
        }
        if (content.contains("current time")) {
            if (cd) {
                return;
            }
            api.sendMessage("NOFLIPIt's " + DateTimeFormatter.ofPattern("HH:mm:ss z").format(ZonedDateTime.now()) + ", `" +
                            message.getAuthor().getUsername() + "`.",
                    channelId);
            currentDateTimeLastUse.put(channelId, time);
        }
        if (content.contains("current president")) {
            if (cd) {
                return;
            }
            api.sendMessage("NOFLIPIt's <NAME>, `" + message.getAuthor().getUsername() + "`.",
                    channelId);
            currentDateTimeLastUse.put(channelId, time);
        }
    }

    private String th(int i) {
        switch (i) {
            case 1:
                return "1st";
            case 2:
                return "2nd";
            case 3:
                return "3rd";
            default:
                return Integer.toString(i) + "th";
        }
    }

    @Subscribe
    public void onMessageRecieved(MessageReceivedEvent messageReceivedEvent) {
        Message message = messageReceivedEvent.getMessage();
        if (bot.getConfig().getBlacklist().contains(message.getAuthor().getId())) {
            return;
        }

        Channel channel = bot.getApiClient().getChannelById(message.getChannelId());
        if (channel != DiscordApiClient.NO_CHANNEL && channel.getParent() != null) {
            if (ignoredServers.contains(channel.getParent().getId())) {
                return;
            }
        }
        if (!message.getAuthor().isBot() &&
                message.getContent().startsWith(bot.getConfig().getCommandPrefix())) {
            bot.getMainCommandDispatcher().handleCommand(message);
            return;
        }
        messageListeners.values().forEach(c -> c.accept(message));
    }

    private void handleMention(Message message) {
        if (!bot.getMainCommandDispatcher().active().get()) {
            return;
        }
        String otherId = message.getAuthor().getId();
        bot.getApiClient().sendMessage(bot.getLocalizer().localize("message.mention.response",
                message.getAuthor().getUsername()),
                message.getChannelId(), new String[]{otherId});
    }

    private void handleExcessiveMentions(Message message) {
        if (!bot.getMainCommandDispatcher().active().get()) {
            return;
        }
        User author = message.getAuthor();
        if (bot.getConfig().isAdmin(author.getId())) {
            return;
        }
        Channel channel = bot.getApiClient().getChannelById(message.getChannelId());
        Server server;
        if (channel != DiscordApiClient.NO_CHANNEL && channel.getParent() != null) {
            server = channel.getParent();
        } else {
            return;
        }
        if (!server.getId().equals("106293726271246336")) {
            return;
        }
        Member member = bot.getApiClient().getUserMember(author, server);
        if (member == DiscordApiClient.NO_MEMBER) {
            return;
        }
//        if (Duration.between(ZonedDateTime.
//                from(Commands.DATE_TIME_FORMATTER.parse(member.getJoinedAt())),
//                ZonedDateTime.now()).abs().compareTo(Duration.ofDays(3)) > 0) {
//            return;
//        }
        Set<User> unique = new HashSet<>();
        Collections.addAll(unique, message.getMentions());
        if (unique.size() > excessiveMentionThreshold) {
//            bot.getCommands().getModCommands().applyTimeout(bot.getApiClient().getClientUser(), channel,
//                    server, author, Duration.ofHours(1));
            bot.getCommands().getModCommands().banImpl(author.getId(), bot.getApiClient().getClientUser().getUsername(),
                    server.getId(), channel.getId());
            bot.getApiClient().sendMessage(String.format("`%s#%s` (%s) has been banned for mention spam",<commit_msg>Switch back to timeout for mention spam<commit_after>package co.phoenixlab.discord;

import co.phoenixlab.common.lang.SafeNav;
import co.phoenixlab.discord.api.DiscordApiClient;
import co.phoenixlab.discord.api.entities.*;
import co.phoenixlab.discord.api.event.*;
import co.phoenixlab.discord.commands.tempstorage.TempServerConfig;
import com.google.common.eventbus.Subscribe;

import java.time.Duration;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

public class EventListener {

    private final VahrhedralBot bot;
    public Map<String, Consumer<MemberChangeEvent>> memberChangeEventListener;
    public Map<String, String> joinMessageRedirect;
    public Set<String> ignoredServers;
    public int excessiveMentionThreshold;
    public Map<String, Deque<String>> newest = new HashMap<>();
    private Map<String, Consumer<Message>> messageListeners;
    private Map<String, Long> currentDateTimeLastUse = new HashMap<>();

    public EventListener(VahrhedralBot bot) {
        this.bot = bot;
        messageListeners = new HashMap<>();
        memberChangeEventListener = new HashMap<>();
        joinMessageRedirect = new HashMap<>();
        ignoredServers = new HashSet<>();
        messageListeners.put("mention-bot", message -> {
            User me = bot.getApiClient().getClientUser();
            for (User user : message.getMentions()) {
                if (me.equals(user)) {
                    handleMention(message);
                    return;
                }
            }
        });
        excessiveMentionThreshold = 5;
        messageListeners.put("mention-autotimeout", this::handleExcessiveMentions);
        messageListeners.put("invite-pm", this::onInviteLinkPrivateMessage);
        messageListeners.put("other-prefixes", this::onOtherTypesCommand);
//        messageListeners.put("date-time", this::currentDateTime);
    }

    private void currentDateTime(Message message) {
        if (!bot.getMainCommandDispatcher().active().get()) {
            return;
        }
        String channelId = message.getChannelId();
        boolean cd = false;
        if (currentDateTimeLastUse.containsKey(channelId)) {
            long time = currentDateTimeLastUse.get(channelId);
            if (time >= System.currentTimeMillis()) {
                currentDateTimeLastUse.remove(channelId);
            } else if (System.currentTimeMillis() - time < TimeUnit.SECONDS.toMillis(30)) {
                cd = true;
            }
        }
        long time = System.currentTimeMillis();
        DiscordApiClient api = bot.getApiClient();
        String content = message.getContent().toLowerCase();
        if (content.contains("current year")) {
            if (cd) {
                return;
            }
            api.sendMessage("NOFLIPIt's " + ZonedDateTime.now().getYear() + ", `" + message.getAuthor().getUsername() + "`.",
                    channelId);
            currentDateTimeLastUse.put(channelId, time);
        }
        if (content.contains("current date")) {
            if (cd) {
                return;
            }
            api.sendMessage("NOFLIPIt's " + DateTimeFormatter.ofPattern("MMM dd uuuu").format(ZonedDateTime.now()) + ", `" +
                            message.getAuthor().getUsername() + "`.",
                    channelId);
            currentDateTimeLastUse.put(channelId, time);
        }
        if (content.contains("current day")) {
            if (cd) {
                return;
            }
            api.sendMessage("NOFLIPIt's the " + th(ZonedDateTime.now().getDayOfMonth()) + ", `" +
                            message.getAuthor().getUsername() + "`.",
                    channelId);
            currentDateTimeLastUse.put(channelId, time);
        }
        if (content.contains("current time")) {
            if (cd) {
                return;
            }
            api.sendMessage("NOFLIPIt's " + DateTimeFormatter.ofPattern("HH:mm:ss z").format(ZonedDateTime.now()) + ", `" +
                            message.getAuthor().getUsername() + "`.",
                    channelId);
            currentDateTimeLastUse.put(channelId, time);
        }
        if (content.contains("current president")) {
            if (cd) {
                return;
            }
            api.sendMessage("NOFLIPIt's <NAME>, `" + message.getAuthor().getUsername() + "`.",
                    channelId);
            currentDateTimeLastUse.put(channelId, time);
        }
    }

    private String th(int i) {
        switch (i) {
            case 1:
                return "1st";
            case 2:
                return "2nd";
            case 3:
                return "3rd";
            default:
                return Integer.toString(i) + "th";
        }
    }

    @Subscribe
    public void onMessageRecieved(MessageReceivedEvent messageReceivedEvent) {
        Message message = messageReceivedEvent.getMessage();
        if (bot.getConfig().getBlacklist().contains(message.getAuthor().getId())) {
            return;
        }

        Channel channel = bot.getApiClient().getChannelById(message.getChannelId());
        if (channel != DiscordApiClient.NO_CHANNEL && channel.getParent() != null) {
            if (ignoredServers.contains(channel.getParent().getId())) {
                return;
            }
        }
        if (!message.getAuthor().isBot() &&
                message.getContent().startsWith(bot.getConfig().getCommandPrefix())) {
            bot.getMainCommandDispatcher().handleCommand(message);
            return;
        }
        messageListeners.values().forEach(c -> c.accept(message));
    }

    private void handleMention(Message message) {
        if (!bot.getMainCommandDispatcher().active().get()) {
            return;
        }
        String otherId = message.getAuthor().getId();
        bot.getApiClient().sendMessage(bot.getLocalizer().localize("message.mention.response",
                message.getAuthor().getUsername()),
                message.getChannelId(), new String[]{otherId});
    }

    private void handleExcessiveMentions(Message message) {
        if (!bot.getMainCommandDispatcher().active().get()) {
            return;
        }
        User author = message.getAuthor();
        if (bot.getConfig().isAdmin(author.getId())) {
            return;
        }
        Channel channel = bot.getApiClient().getChannelById(message.getChannelId());
        Server server;
        if (channel != DiscordApiClient.NO_CHANNEL && channel.getParent() != null) {
            server = channel.getParent();
        } else {
            return;
        }
        if (!server.getId().equals("106293726271246336")) {
            return;
        }
        Member member = bot.getApiClient().getUserMember(author, server);
        if (member == DiscordApiClient.NO_MEMBER) {
            return;
        }
//        if (Duration.between(ZonedDateTime.
//                from(Commands.DATE_TIME_FORMATTER.parse(member.getJoinedAt())),
//                ZonedDateTime.now()).abs().compareTo(Duration.ofDays(3)) > 0) {
//            return;
//        }
        Set<User> unique = new HashSet<>();
        Collections.addAll(unique, message.getMentions());
        if (unique.size() > excessiveMentionThreshold) {
            bot.getCommands().getModCommands().applyTimeout(bot.getApiClient().getClientUser(), channel,
                    server, author, Duration.ofHours(1));
//            bot.getCommands().getModCommands().banImpl(author.getId(), author.getUsername(),
//                    server.getId(), channel.getId());
            bot.getApiClient().sendMessage(String.format("`%s#%s` (%s) has been banned for mention spam",
{'fraction_non_alphanumeric': 0.129537687794184, 'fraction_numerical': 0.0038687213875814043, 'mean_word_length': 2.133966457870277, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 49, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '412305', 'n_tokens_mistral': 4140, 'n_tokens_neox': 4060, 'n_words': 685}