Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion PP.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,4 +111,4 @@ This policy is not applicable to any information collected by **bot** instances

People may get in contact through e-mail at [[email protected]](mailto:[email protected]), or through **Together Java**'s [official Discord](https://discord.com/invite/XXFUXzK).

Other ways of support may be provided but are not guaranteed.
Other ways of support may be provided but are not guaranteed.
2 changes: 1 addition & 1 deletion application/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ dependencies {
implementation 'com.github.ben-manes.caffeine:caffeine:3.0.4'

testImplementation 'org.mockito:mockito-core:4.0.0'
testRuntimeOnly 'org.mockito:mockito-core:4.0.0'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.8.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
}

Expand Down
10 changes: 9 additions & 1 deletion application/config.json.template
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,13 @@
"upVoteEmoteName": "peepo_yes",
"downVoteEmoteName": "peepo_no"
},
"quarantinedRolePattern": "Quarantined"
"quarantinedRolePattern": "Quarantined",
"scamBlocker": {
"mode": "AUTO_DELETE_BUT_APPROVE_QUARANTINE",
"reportChannelPattern": "commands",
"hostWhitelist": ["discord.com", "discord.gg", "discord.media", "discordapp.com", "discordapp.net", "discordstatus.com"],
"hostBlacklist": ["bit.ly"],
"suspiciousHostKeywords": ["discord", "nitro", "premium"],
"isHostSimilarToKeywordDistanceThreshold": 2
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@

import net.dv8tion.jda.api.JDA;
import org.jetbrains.annotations.NotNull;
import org.togetherjava.tjbot.commands.basic.*;
import org.togetherjava.tjbot.commands.basic.PingCommand;
import org.togetherjava.tjbot.commands.basic.RoleSelectCommand;
import org.togetherjava.tjbot.commands.basic.SuggestionsUpDownVoter;
import org.togetherjava.tjbot.commands.basic.VcActivityCommand;
import org.togetherjava.tjbot.commands.free.FreeCommand;
import org.togetherjava.tjbot.commands.mathcommands.TeXCommand;
import org.togetherjava.tjbot.commands.moderation.*;
import org.togetherjava.tjbot.commands.moderation.scam.ScamBlocker;
import org.togetherjava.tjbot.commands.moderation.scam.ScamHistoryPurgeRoutine;
import org.togetherjava.tjbot.commands.moderation.scam.ScamHistoryStore;
import org.togetherjava.tjbot.commands.moderation.temp.TemporaryModerationRoutine;
import org.togetherjava.tjbot.commands.reminder.RemindCommand;
import org.togetherjava.tjbot.commands.reminder.RemindRoutine;
Expand Down Expand Up @@ -52,6 +58,7 @@ public enum Features {
TagSystem tagSystem = new TagSystem(database);
ModerationActionsStore actionsStore = new ModerationActionsStore(database);
ModAuditLogWriter modAuditLogWriter = new ModAuditLogWriter(config);
ScamHistoryStore scamHistoryStore = new ScamHistoryStore(database);

// NOTE The system can add special system relevant commands also by itself,
// hence this list may not necessarily represent the full list of all commands actually
Expand All @@ -63,10 +70,12 @@ public enum Features {
features.add(new TemporaryModerationRoutine(jda, actionsStore, config));
features.add(new TopHelpersPurgeMessagesRoutine(database));
features.add(new RemindRoutine(database));
features.add(new ScamHistoryPurgeRoutine(scamHistoryStore));

// Message receivers
features.add(new TopHelpersMessageListener(database, config));
features.add(new SuggestionsUpDownVoter(config));
features.add(new ScamBlocker(actionsStore, scamHistoryStore, config));

// Event receivers
features.add(new RejoinModerationRoleListener(actionsStore, config));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import net.dv8tion.jda.api.interactions.commands.build.Commands;
import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData;
import net.dv8tion.jda.api.interactions.components.ComponentInteraction;
import net.dv8tion.jda.api.interactions.components.buttons.Button;
import net.dv8tion.jda.api.interactions.components.buttons.ButtonStyle;
import org.jetbrains.annotations.NotNull;
import org.togetherjava.tjbot.commands.componentids.ComponentId;
Expand Down Expand Up @@ -38,20 +37,7 @@
* <p>
* Some example commands are available in {@link org.togetherjava.tjbot.commands.basic}.
*/
public interface SlashCommand extends Feature {

/**
* Gets the name of the command.
* <p>
* Requirements for this are documented in {@link Commands#slash(String, String)}.
* <p>
* <p>
* After registration of the command, the name must not change anymore.
*
* @return the name of the command
*/
@NotNull
String getName();
public interface SlashCommand extends UserInteractor {

/**
* Gets the description of the command.
Expand Down Expand Up @@ -107,9 +93,9 @@ public interface SlashCommand extends Feature {
* <p>
* Buttons or menus have to be created with a component ID (see
* {@link ComponentInteraction#getComponentId()},
* {@link Button#of(ButtonStyle, String, Emoji)}}) in a very specific format, otherwise the core
* system will fail to identify the command that corresponded to the button or menu click event
* and is unable to route it back.
* {@link net.dv8tion.jda.api.interactions.components.buttons.Button#of(ButtonStyle, String, Emoji)})
* in a very specific format, otherwise the core system will fail to identify the command that
* corresponded to the button or menu click event and is unable to route it back.
* <p>
* The component ID has to be a UUID-string (see {@link java.util.UUID}), which is associated to
* a specific database entry, containing meta information about the command being executed. Such
Expand All @@ -133,56 +119,4 @@ public interface SlashCommand extends Feature {
* @param event the event that triggered this
*/
void onSlashCommand(@NotNull SlashCommandInteractionEvent event);

/**
* Triggered by the core system when a button corresponding to this implementation (based on
* {@link #getData()}) has been clicked.
* <p>
* This method may be called multi-threaded. In particular, there are no guarantees that it will
* be executed on the same thread repeatedly or on the same thread that other event methods have
* been called on.
* <p>
* Details are available in the given event and the event also enables implementations to
* respond to it.
* <p>
* This method will be called in a multi-threaded context and the event may not be hold valid
* forever.
*
* @param event the event that triggered this
* @param args the arguments transported with the button, see
* {@link #onSlashCommand(SlashCommandInteractionEvent)} for details on how these are
* created
*/
void onButtonClick(@NotNull ButtonInteractionEvent event, @NotNull List<String> args);

/**
* Triggered by the core system when a selection menu corresponding to this implementation
* (based on {@link #getData()}) has been clicked.
* <p>
* This method may be called multi-threaded. In particular, there are no guarantees that it will
* be executed on the same thread repeatedly or on the same thread that other event methods have
* been called on.
* <p>
* Details are available in the given event and the event also enables implementations to
* respond to it.
* <p>
* This method will be called in a multi-threaded context and the event may not be hold valid
* forever.
*
* @param event the event that triggered this
* @param args the arguments transported with the selection menu, see
* {@link #onSlashCommand(SlashCommandInteractionEvent)} for details on how these are
* created
*/
void onSelectionMenu(@NotNull SelectMenuInteractionEvent event, @NotNull List<String> args);

/**
* Triggered by the core system during its setup phase. It will provide the command a component
* id generator through this method, which can be used to generate component ids, as used for
* button or selection menus. See {@link #onSlashCommand(SlashCommandInteractionEvent)} for
* details on how to use this.
*
* @param generator the provided component id generator
*/
void acceptComponentIdGenerator(@NotNull ComponentIdGenerator generator);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package org.togetherjava.tjbot.commands;

import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
import net.dv8tion.jda.api.events.interaction.component.SelectMenuInteractionEvent;
import org.jetbrains.annotations.NotNull;
import org.togetherjava.tjbot.commands.componentids.ComponentIdGenerator;

import java.util.List;

/**
* Represents a feature that can interact with users. The most important implementation is
* {@link SlashCommand}.
* <p>
* An interactor must have a unique name and can react to button clicks and selection menu actions.
*/
public interface UserInteractor extends Feature {

/**
* Gets the name of the interactor.
* <p>
* Requirements for this are documented in
* {@link net.dv8tion.jda.api.interactions.commands.build.Commands#slash(String, String)}.
* <p>
* <p>
* After registration of the interactor, the name must not change anymore.
*
* @return the name of the interactor
*/
@NotNull
String getName();

/**
* Triggered by the core system when a button corresponding to this implementation (based on
* {@link #getName()}) has been clicked.
* <p>
* This method may be called multi-threaded. In particular, there are no guarantees that it will
* be executed on the same thread repeatedly or on the same thread that other event methods have
* been called on.
* <p>
* Details are available in the given event and the event also enables implementations to
* respond to it.
* <p>
* This method will be called in a multi-threaded context and the event may not be hold valid
* forever.
*
* @param event the event that triggered this
* @param args the arguments transported with the button, see
* {@link SlashCommand#onSlashCommand(SlashCommandInteractionEvent)} for details on how
* these are created
*/
void onButtonClick(@NotNull ButtonInteractionEvent event, @NotNull List<String> args);

/**
* Triggered by the core system when a selection menu corresponding to this implementation
* (based on {@link #getName()}) has been clicked.
* <p>
* This method may be called multi-threaded. In particular, there are no guarantees that it will
* be executed on the same thread repeatedly or on the same thread that other event methods have
* been called on.
* <p>
* Details are available in the given event and the event also enables implementations to
* respond to it.
* <p>
* This method will be called in a multi-threaded context and the event may not be hold valid
* forever.
*
* @param event the event that triggered this
* @param args the arguments transported with the selection menu, see
* {@link SlashCommand#onSlashCommand(SlashCommandInteractionEvent)} for details on how
* these are created
*/
void onSelectionMenu(@NotNull SelectMenuInteractionEvent event, @NotNull List<String> args);

/**
* Triggered by the core system during its setup phase. It will provide the interactor a
* component id generator through this method, which can be used to generate component ids, as
* used for button or selection menus. See
* {@link SlashCommand#onSlashCommand(SlashCommandInteractionEvent)} for details on how to use
* this.
*
* @param generator the provided component id generator
*/
void acceptComponentIdGenerator(@NotNull ComponentIdGenerator generator);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
* {@link org.togetherjava.tjbot.commands.SlashCommand#onSlashCommand(SlashCommandInteractionEvent)}
* for its usages.
*
* @param commandName the name of the command that handles the event associated to this component
* ID, when triggered
* @param userInteractorName the name of the user interactor that handles the event associated to
* this component ID, when triggered
* @param elements the additional elements to carry along this component ID, empty if not desired
*/
public record ComponentId(@NotNull String commandName, @NotNull List<String> elements) {
public record ComponentId(@NotNull String userInteractorName, @NotNull List<String> elements) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -266,8 +266,8 @@ private void evictDatabase() {
recordToDelete.delete();
evictedCounter.getAndIncrement();
logger.debug(
"Evicted component id with uuid '{}' from command '{}', last used '{}'",
uuid, componentId.commandName(), lastUsed);
"Evicted component id with uuid '{}' from user interactor '{}', last used '{}'",
uuid, componentId.userInteractorName(), lastUsed);

// Remove them from the cache if still in there
storeCache.invalidate(uuid);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.components.buttons.Button;
import net.dv8tion.jda.api.interactions.components.buttons.ButtonStyle;
import org.jetbrains.annotations.NotNull;
import org.scilab.forge.jlatexmath.ParseException;
import org.scilab.forge.jlatexmath.TeXConstants;
Expand All @@ -15,7 +14,8 @@
import org.togetherjava.tjbot.commands.SlashCommandVisibility;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.Color;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
Expand Down Expand Up @@ -88,7 +88,7 @@ public void onSlashCommand(@NotNull final SlashCommandInteractionEvent event) {
}
event.getHook()
.editOriginal(renderedTextImageStream.toByteArray(), "tex.png")
.setActionRow(Button.of(ButtonStyle.DANGER, generateComponentId(userID), "Delete"))
.setActionRow(Button.danger(generateComponentId(userID), "Delete"))
.queue();
}

Expand Down
Loading