Merge branch 'scheduled-tasks' into 'main'
Implement scheduled tasks See merge request anthorob/netneutrality!78
This commit is contained in:
commit
b78322e521
42 files changed
+403
-283
No files matched your search
@@ -4,6 +4,7 @@ NETNEUTRALITY_BOT_ENV=dev
|
||||
NETNEUTRALITY_BOT_TOKEN=
|
||||
NETNEUTRALITY_BOT_PREFIX=$
|
||||
NETNEUTRALITY_BOT_OWNER=
|
||||
NETNEUTRALITY_BOT_INVITE=
|
||||
NETNEUTRALITY_API_PORT=9000
|
||||
|
||||
MYSQL_HOST=127.0.0.1
|
||||
|
||||
@@ -2,6 +2,7 @@ NETNEUTRALITY_BOT_ENV=dev
|
||||
NETNEUTRALITY_BOT_TOKEN=
|
||||
NETNEUTRALITY_BOT_PREFIX=
|
||||
NETNEUTRALITY_BOT_OWNER=
|
||||
NETNEUTRALITY_BOT_INVITE=
|
||||
NETNEUTRALITY_API_PORT=9000
|
||||
|
||||
MYSQL_HOST=127.0.0.1
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
services:
|
||||
db:
|
||||
image: mariadb:lts@sha256:4b1e7958f820681b1b93b9cf9ea05a76e0785da12699a1fb1d05e0eb2137e56b
|
||||
container_name: db
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- netneutrality-db:/var/lib/mysql
|
||||
- ./sql:/docker-entrypoint-initdb.d
|
||||
environment:
|
||||
MYSQL_USER: 'java'
|
||||
MYSQL_PASSWORD: 'password'
|
||||
MYSQL_DATABASE: 'netneutrality'
|
||||
MYSQL_ROOT_PASSWORD: 'password'
|
||||
MARIADB_AUTO_UPGRADE: '1'
|
||||
ports:
|
||||
- "3306"
|
||||
networks:
|
||||
- internal
|
||||
|
||||
bot:
|
||||
container_name: bot
|
||||
build: ./
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- db
|
||||
volumes:
|
||||
- ./logs:/app/logs
|
||||
environment:
|
||||
MYSQL_HOST: 'db'
|
||||
MYSQL_USER: 'java'
|
||||
MYSQL_PASSWORD: 'password'
|
||||
MYSQL_DATABASE: 'netneutrality'
|
||||
ports:
|
||||
- "9000:9000"
|
||||
networks:
|
||||
- internal
|
||||
|
||||
webapp:
|
||||
image: bot-webapp:dev
|
||||
build: ../netneutrality-webapp
|
||||
restart: always
|
||||
depends_on:
|
||||
- db
|
||||
- bot
|
||||
volumes:
|
||||
- ./logs:/app/logs
|
||||
environment:
|
||||
DB_CONNECTION: 'mysql'
|
||||
DB_HOST: 'db'
|
||||
DB_PORT: '3306'
|
||||
DB_DATABASE: 'netneutrality'
|
||||
DB_USERNAME: 'java'
|
||||
DB_PASSWORD: 'password'
|
||||
BOT_URL: 'http://bot:9000'
|
||||
ports:
|
||||
- '8080:80'
|
||||
networks:
|
||||
- internal
|
||||
|
||||
volumes:
|
||||
netneutrality-db:
|
||||
|
||||
networks:
|
||||
internal:
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
services:
|
||||
netneutrality-db:
|
||||
image: mariadb:lts@sha256:4b1e7958f820681b1b93b9cf9ea05a76e0785da12699a1fb1d05e0eb2137e56b
|
||||
image: mariadb:11
|
||||
container_name: db
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
|
||||
@@ -259,11 +259,6 @@
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.17.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-codec</groupId>
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<version>1.18.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
|
||||
+9
-1
@@ -9,7 +9,15 @@
|
||||
{
|
||||
"groupName": "hibernate orm",
|
||||
"matchPackageNames": [
|
||||
"org.hibernate.orm:**"
|
||||
"org.hibernate.orm:**",
|
||||
"com.mysql:**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"groupName": "apache commons",
|
||||
"matchPackageNames": [
|
||||
"commons:**",
|
||||
"org.apache.commons:**"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -12,11 +12,11 @@ import me.bobert.netneutrality.core.command.CommandManager;
|
||||
import me.bobert.netneutrality.core.db.DatabaseMigration;
|
||||
import me.bobert.netneutrality.core.db.SessionManager;
|
||||
import me.bobert.netneutrality.core.tasks.TaskManager;
|
||||
import me.bobert.netneutrality.core.thread.ScheduledTaskManager;
|
||||
import me.bobert.netneutrality.core.thread.ThreadManager;
|
||||
import me.bobert.netneutrality.hooks.EventsHandler;
|
||||
import me.bobert.netneutrality.http.server.WebApi;
|
||||
import me.bobert.netneutrality.music.MusicManager;
|
||||
import me.bobert.netneutrality.thread.ShutdownThread;
|
||||
import me.bobert.netneutrality.utils.Settings;
|
||||
import net.dv8tion.jda.api.JDA;
|
||||
import net.dv8tion.jda.api.JDABuilder;
|
||||
@@ -79,7 +79,7 @@ public class NetNeutrality {
|
||||
new WebApi(Integer.parseInt(Settings.getInstance().get("NETNEUTRALITY_API_PORT", "9000")));
|
||||
jda.getPresence().setActivity(Activity.watching("you"));
|
||||
|
||||
Runtime.getRuntime().addShutdownHook(new ShutdownThread(this));
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(this::shutdown));
|
||||
}
|
||||
|
||||
public static NetNeutrality getInstance() {
|
||||
@@ -108,6 +108,7 @@ public class NetNeutrality {
|
||||
|
||||
public void shutdown() {
|
||||
System.out.println("[Net Neutrality] Shutting down...");
|
||||
ScheduledTaskManager.cancelAll();
|
||||
MusicManager.disconnectPlayers();
|
||||
ThreadManager.shutdownExecutor();
|
||||
disconnect();
|
||||
|
||||
@@ -13,7 +13,7 @@ import me.bobert.netneutrality.core.command.CommandOptionsBuilder;
|
||||
import me.bobert.netneutrality.core.command.impl.AbstractCommand;
|
||||
import me.bobert.netneutrality.core.command.options.CommandOption;
|
||||
import me.bobert.netneutrality.core.context.CommandContext;
|
||||
import me.bobert.netneutrality.core.tasks.BuiltInTask;
|
||||
import me.bobert.netneutrality.core.tasks.Task;
|
||||
import me.bobert.netneutrality.tasks.help.BotInfo;
|
||||
import me.bobert.netneutrality.tasks.help.CommandHelp;
|
||||
import me.bobert.netneutrality.tasks.help.ReportBug;
|
||||
@@ -65,9 +65,9 @@ public class HelpCommand extends AbstractCommand {
|
||||
public CommandExecutionResult execute(CommandContext context) {
|
||||
String command = context.getOption("command", null, CommandOption::getAsString);
|
||||
if (command == null) {
|
||||
Button commands = BuiltInTask.createButton(CommandHelp.class);
|
||||
Button info = BuiltInTask.createButton(BotInfo.class);
|
||||
Button reportbug = BuiltInTask.createButton(ReportBug.class);
|
||||
Button commands = Task.createButton(CommandHelp.class);
|
||||
Button info = Task.createButton(BotInfo.class);
|
||||
Button reportbug = Task.createButton(ReportBug.class);
|
||||
ActionRow row = ActionRow.of(commands, info, reportbug);
|
||||
context.replyEphemeral("Thanks for using the Net Neutrality Bot! What do you need help with?", List.of(row));
|
||||
return CommandExecutionResult.none();
|
||||
|
||||
@@ -5,6 +5,7 @@ package me.bobert.netneutrality.core.command;
|
||||
* https://discord.gg/qUa6zNFZsd
|
||||
*/
|
||||
|
||||
import me.bobert.netneutrality.utils.ReflectionHelper;
|
||||
import net.dv8tion.jda.api.JDA;
|
||||
import net.dv8tion.jda.api.interactions.InteractionContextType;
|
||||
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
|
||||
@@ -12,9 +13,7 @@ import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData;
|
||||
import net.dv8tion.jda.api.requests.restaction.CommandListUpdateAction;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.reflections.Reflections;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -39,34 +38,27 @@ public class CommandManager {
|
||||
}
|
||||
|
||||
public static void initCommands() {
|
||||
Set<Class<? extends Command>> classes = new Reflections("me.bobert.netneutrality.command").getSubTypesOf(Command.class);
|
||||
for (Class<? extends Command> s : classes) {
|
||||
try {
|
||||
if (Modifier.isAbstract(s.getModifiers())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Command command = s.getConstructor().newInstance();
|
||||
if (!command.isEnabled()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (command.getCommandName() == null) {
|
||||
throw new IllegalArgumentException("Command name is null");
|
||||
}
|
||||
|
||||
if (command.getDescription() == null && command.getType() == Command.Type.SLASH) {
|
||||
throw new IllegalArgumentException("Command description is null");
|
||||
}
|
||||
|
||||
CommandContainer container = new CommandContainer(command);
|
||||
if (!commands.containsKey(command.getCommandName())) {
|
||||
commands.put(command.getCommandName(), container);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to load command {}: {}", s.getSimpleName(), e.getMessage());
|
||||
ReflectionHelper.loadCommands(Command.class, command -> {
|
||||
if (!command.isEnabled()) {
|
||||
logger.info("Skipping command {} as it is disabled", command.getClass().getName());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (command.getCommandName() == null) {
|
||||
logger.error("Failed to load command {}: Command name is null", command.getClass().getName());
|
||||
return;
|
||||
}
|
||||
|
||||
if (command.getDescription() == null && command.getType() == Command.Type.SLASH) {
|
||||
logger.error("Failed to load command {}: Command description is null", command.getClass().getName());
|
||||
return;
|
||||
}
|
||||
|
||||
CommandContainer container = new CommandContainer(command);
|
||||
if (!commands.containsKey(command.getCommandName())) {
|
||||
commands.put(command.getCommandName(), container);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void registerSlashCommands(JDA jda) {
|
||||
|
||||
@@ -65,7 +65,7 @@ public class CommandProcessor {
|
||||
}
|
||||
|
||||
try {
|
||||
logger.info("Context ID: {}", context.getId());
|
||||
logger.debug("Context ID: {}", context.getId());
|
||||
logger.info("Executing command {} on guild {}", command.getCommandName(), context.getGuild() == null ? "PrivateMessage" : context.getGuild().getId());
|
||||
configureSentry(command);
|
||||
|
||||
|
||||
@@ -151,6 +151,10 @@ public interface Context {
|
||||
replyEphemeralWithLimit(message);
|
||||
}
|
||||
|
||||
default void replyEphemeral(String message, LayoutComponent component) {
|
||||
replyEphemeral(message, List.of(component));
|
||||
}
|
||||
|
||||
default void replyEphemeral(String message, List<LayoutComponent> components) {
|
||||
replyEphemeral(MessageCreateData.fromContent(message), components);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ package me.bobert.netneutrality.core.tasks;
|
||||
* https://discord.gg/qUa6zNFZsd
|
||||
*/
|
||||
|
||||
import net.dv8tion.jda.api.interactions.components.buttons.Button;
|
||||
import me.bobert.netneutrality.core.context.TaskContext;
|
||||
|
||||
/**
|
||||
* Represents a task that has a known ID and is loaded at runtime.
|
||||
@@ -13,13 +13,5 @@ import net.dv8tion.jda.api.interactions.components.buttons.Button;
|
||||
*/
|
||||
public interface BuiltInTask extends Task {
|
||||
|
||||
static Button createButton(Class<? extends BuiltInTask> clazz) {
|
||||
BuiltInTask builtInTask = TaskManager.getInstance().findBuiltInTaskByClass(clazz);
|
||||
|
||||
if (builtInTask == null) {
|
||||
throw new IllegalArgumentException("Task class " + clazz.getName() + " was not registered by the task manager.");
|
||||
}
|
||||
|
||||
return builtInTask.createButton();
|
||||
}
|
||||
void executeTask(TaskContext context);
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package me.bobert.netneutrality.core.tasks;
|
||||
|
||||
/*
|
||||
* Copyright (c) anthorob
|
||||
*
|
||||
* https://discord.gg/qUa6zNFZsd
|
||||
*/
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public interface ScheduledTask {
|
||||
|
||||
class TimeFrame {
|
||||
private final int interval;
|
||||
private final TimeUnit unit;
|
||||
|
||||
private TimeFrame(int interval, TimeUnit unit) {
|
||||
this.interval = interval;
|
||||
this.unit = unit;
|
||||
}
|
||||
|
||||
public static TimeFrame minutely() {
|
||||
return new TimeFrame(1, TimeUnit.MINUTES);
|
||||
}
|
||||
|
||||
public static TimeFrame minutely(int interval) {
|
||||
return new TimeFrame(interval, TimeUnit.MINUTES);
|
||||
}
|
||||
|
||||
public static TimeFrame hourly() {
|
||||
return new TimeFrame(1, TimeUnit.HOURS);
|
||||
}
|
||||
|
||||
public static TimeFrame hourly(int interval) {
|
||||
return new TimeFrame(interval, TimeUnit.HOURS);
|
||||
}
|
||||
|
||||
public static TimeFrame daily() {
|
||||
return new TimeFrame(1, TimeUnit.DAYS);
|
||||
}
|
||||
|
||||
public static TimeFrame daily(int interval) {
|
||||
return new TimeFrame(interval, TimeUnit.DAYS);
|
||||
}
|
||||
|
||||
public static TimeFrame custom(int interval, TimeUnit unit) {
|
||||
return new TimeFrame(interval, unit);
|
||||
}
|
||||
|
||||
public int getInterval() {
|
||||
return interval;
|
||||
}
|
||||
|
||||
public TimeUnit getUnit() {
|
||||
return unit;
|
||||
}
|
||||
}
|
||||
|
||||
String getId();
|
||||
|
||||
TimeFrame getTimeFrame();
|
||||
|
||||
void run();
|
||||
}
|
||||
+1
-1
@@ -6,7 +6,7 @@ package me.bobert.netneutrality.core.tasks;
|
||||
* https://discord.gg/qUa6zNFZsd
|
||||
*/
|
||||
|
||||
public interface IStepTask {
|
||||
public interface StepTask {
|
||||
|
||||
/**
|
||||
* Defines the type of input expected for a step.
|
||||
@@ -7,6 +7,7 @@ package me.bobert.netneutrality.core.tasks;
|
||||
|
||||
import me.bobert.netneutrality.core.context.CommandContext;
|
||||
import me.bobert.netneutrality.core.context.TaskContext;
|
||||
import me.bobert.netneutrality.core.tasks.trait.WithButton;
|
||||
import me.bobert.netneutrality.core.tasks.trait.WithChildren;
|
||||
import net.dv8tion.jda.api.interactions.components.buttons.Button;
|
||||
|
||||
@@ -64,8 +65,6 @@ public interface Task {
|
||||
|
||||
OffsetDateTime getCreationTime();
|
||||
|
||||
Button createButton();
|
||||
|
||||
/**
|
||||
* <p>This method is used to reply to the interaction that triggered this task.</p>
|
||||
* <p>If the task is implementing {@link WithChildren}, the child tasks must be instanciated in this method.</p>
|
||||
@@ -80,4 +79,14 @@ public interface Task {
|
||||
Lifecycle execute(TaskContext context);
|
||||
|
||||
void insert(CommandContext context);
|
||||
|
||||
static Button createButton(Class<? extends WithButton> clazz) {
|
||||
WithButton withButton = TaskManager.getInstance().findButtonTaskByClass(clazz);
|
||||
|
||||
if (withButton == null) {
|
||||
throw new IllegalArgumentException("Task " + clazz.getName() + " was not registered by the task manager.");
|
||||
}
|
||||
|
||||
return withButton.createButton();
|
||||
}
|
||||
}
|
||||
@@ -11,28 +11,24 @@ import me.bobert.netneutrality.core.context.InteractionContext;
|
||||
import me.bobert.netneutrality.core.context.TaskContext;
|
||||
import me.bobert.netneutrality.core.tasks.trait.Deletable;
|
||||
import me.bobert.netneutrality.core.tasks.trait.NotAcknowledgeable;
|
||||
import me.bobert.netneutrality.core.tasks.trait.WithButton;
|
||||
import me.bobert.netneutrality.core.tasks.trait.WithChildren;
|
||||
import me.bobert.netneutrality.core.tasks.trait.WithParent;
|
||||
import me.bobert.netneutrality.core.thread.ThreadManager;
|
||||
import me.bobert.netneutrality.core.thread.ScheduledTaskManager;
|
||||
import me.bobert.netneutrality.db.service.TaskService;
|
||||
import me.bobert.netneutrality.exceptions.GracefulContextError;
|
||||
import me.bobert.netneutrality.exceptions.TaskExecutionException;
|
||||
import me.bobert.netneutrality.thread.CleanupTaskThread;
|
||||
import me.bobert.netneutrality.utils.ReflectionHelper;
|
||||
import net.dv8tion.jda.api.interactions.InteractionHook;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.reflections.Reflections;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -63,12 +59,11 @@ public class TaskManager {
|
||||
|
||||
public void init() {
|
||||
loadBuiltInTasks();
|
||||
loadScheduledTasks();
|
||||
taskService.loadTasks();
|
||||
|
||||
ThreadManager.getScheduledExecutor().scheduleWithFixedDelay(new CleanupTaskThread(), 1, 5, TimeUnit.MINUTES);
|
||||
}
|
||||
|
||||
protected TaskService getTaskService() {
|
||||
public TaskService getTaskService() {
|
||||
return taskService;
|
||||
}
|
||||
|
||||
@@ -101,7 +96,7 @@ public class TaskManager {
|
||||
taskService.persistTask(persistableTask);
|
||||
}
|
||||
|
||||
if (task instanceof IStepTask) {
|
||||
if (task instanceof StepTask) {
|
||||
pendingTasks.add(task);
|
||||
} else {
|
||||
tasks.put(id, task);
|
||||
@@ -176,7 +171,7 @@ public class TaskManager {
|
||||
}
|
||||
}
|
||||
|
||||
logger.debug("Executing task: {}", taskId);
|
||||
logger.info("Executing task: {}", taskId);
|
||||
Task.Lifecycle status = task.execute(context);
|
||||
handleTaskLifecycle(task, status);
|
||||
|
||||
@@ -205,7 +200,7 @@ public class TaskManager {
|
||||
|
||||
public <E extends Task> Optional<E> findTaskByPartialId(Class<E> clazz, String partialId) {
|
||||
List<E> tasks = findTasksByPartialId(clazz, partialId);
|
||||
return Optional.ofNullable(tasks.isEmpty() ? null : tasks.get(0));
|
||||
return Optional.ofNullable(tasks.isEmpty() ? null : tasks.getFirst());
|
||||
}
|
||||
|
||||
public <E extends Task> List<E> findTasksByPartialId(Class<E> clazz, String partialId) {
|
||||
@@ -216,10 +211,10 @@ public class TaskManager {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public BuiltInTask findBuiltInTaskByClass(Class<? extends BuiltInTask> clazz) {
|
||||
public WithButton findButtonTaskByClass(Class<? extends WithButton> clazz) {
|
||||
return tasks.values().stream()
|
||||
.filter(clazz::isInstance)
|
||||
.map(task -> (BuiltInTask) task)
|
||||
.map(task -> (WithButton) task)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
@@ -237,22 +232,27 @@ public class TaskManager {
|
||||
private void loadBuiltInTasks() {
|
||||
logger.info("Loading built-in tasks...");
|
||||
|
||||
Set<Class<? extends BuiltInTask>> classes = new Reflections("me.bobert.netneutrality.tasks").getSubTypesOf(BuiltInTask.class);
|
||||
for (Class<? extends BuiltInTask> s : classes) {
|
||||
try {
|
||||
if (Modifier.isAbstract(s.getModifiers())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
BuiltInTask task = s.getConstructor().newInstance();
|
||||
|
||||
logger.info("Loaded task: {}", task);
|
||||
tasks.put(task.getId(), task);
|
||||
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException
|
||||
| InvocationTargetException | NoSuchMethodException | SecurityException e) {
|
||||
logger.error("Failed to instantiate built-in task", e);
|
||||
ReflectionHelper.loadTasks(BuiltInTask.class, builtInTask -> {
|
||||
if (builtInTask.isInsertable()) {
|
||||
logger.info("Loaded task: {}", builtInTask.getClass().getName());
|
||||
tasks.put(builtInTask.getId(), builtInTask);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void loadScheduledTasks() {
|
||||
logger.info("Loading scheduled tasks...");
|
||||
|
||||
ReflectionHelper.loadTasks(ScheduledTask.class, scheduledTask -> {
|
||||
String taskId = scheduledTask.getId();
|
||||
|
||||
if (taskId == null || taskId.trim().isEmpty()) {
|
||||
logger.error("Cannot load scheduled task {}: task ID is null or empty", scheduledTask.getClass().getName());
|
||||
return;
|
||||
}
|
||||
|
||||
ScheduledTaskManager.schedule(scheduledTask);
|
||||
});
|
||||
}
|
||||
|
||||
private void deleteInteraction(Task task) {
|
||||
|
||||
+2
-3
@@ -1,4 +1,4 @@
|
||||
package me.bobert.netneutrality.core.tasks;
|
||||
package me.bobert.netneutrality.core.tasks.impl;
|
||||
/*
|
||||
* Copyright (c) anthorob
|
||||
*
|
||||
@@ -7,6 +7,7 @@ package me.bobert.netneutrality.core.tasks;
|
||||
|
||||
import me.bobert.netneutrality.core.context.CommandContext;
|
||||
import me.bobert.netneutrality.core.context.TaskContext;
|
||||
import me.bobert.netneutrality.core.tasks.BuiltInTask;
|
||||
|
||||
public abstract class AbstractBuiltInTask extends AbstractTask implements BuiltInTask {
|
||||
|
||||
@@ -35,6 +36,4 @@ public abstract class AbstractBuiltInTask extends AbstractTask implements BuiltI
|
||||
executeTask(context);
|
||||
return Lifecycle.BUILTIN;
|
||||
}
|
||||
|
||||
public abstract void executeTask(TaskContext context);
|
||||
}
|
||||
+3
-1
@@ -1,4 +1,4 @@
|
||||
package me.bobert.netneutrality.core.tasks;
|
||||
package me.bobert.netneutrality.core.tasks.impl;
|
||||
/*
|
||||
* Copyright (c) anthorob
|
||||
*
|
||||
@@ -6,6 +6,8 @@ package me.bobert.netneutrality.core.tasks;
|
||||
*/
|
||||
|
||||
import me.bobert.netneutrality.core.context.CommandContext;
|
||||
import me.bobert.netneutrality.core.tasks.PersistableTask;
|
||||
import me.bobert.netneutrality.core.tasks.TaskManager;
|
||||
import org.json.JSONObject;
|
||||
|
||||
public abstract class AbstractPersistableTask extends AbstractTask implements PersistableTask {
|
||||
+2
-9
@@ -9,13 +9,11 @@ package me.bobert.netneutrality.core.tasks.impl;
|
||||
import me.bobert.netneutrality.core.context.CommandContext;
|
||||
import me.bobert.netneutrality.core.context.MessageContext;
|
||||
import me.bobert.netneutrality.core.context.TaskContext;
|
||||
import me.bobert.netneutrality.core.tasks.AbstractTask;
|
||||
import me.bobert.netneutrality.core.tasks.IStepTask;
|
||||
import me.bobert.netneutrality.core.tasks.StepTask;
|
||||
import me.bobert.netneutrality.core.tasks.TaskManager;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.entities.Role;
|
||||
import net.dv8tion.jda.api.interactions.components.buttons.Button;
|
||||
import net.fellbaum.jemoji.Emoji;
|
||||
import net.fellbaum.jemoji.EmojiManager;
|
||||
|
||||
@@ -27,7 +25,7 @@ import java.util.UUID;
|
||||
* Represents a task that consists of multiple sequential steps. The task starts with an initial message (question)
|
||||
* and expects a user response. Each step can lead to another step, forming a workflow.
|
||||
*/
|
||||
public abstract class StepTask extends AbstractTask implements IStepTask {
|
||||
public abstract class AbstractStepTask extends AbstractTask implements StepTask {
|
||||
private final Object stepLock = new Object();
|
||||
private CommandContext commandContext;
|
||||
private Guild guild;
|
||||
@@ -110,11 +108,6 @@ public abstract class StepTask extends AbstractTask implements IStepTask {
|
||||
return getCreationTime().plusMinutes(60).isBefore(OffsetDateTime.now());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Button createButton() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the user input against the expected step type.
|
||||
*
|
||||
+3
-1
@@ -1,4 +1,4 @@
|
||||
package me.bobert.netneutrality.core.tasks;
|
||||
package me.bobert.netneutrality.core.tasks.impl;
|
||||
/*
|
||||
* Copyright (c) anthorob
|
||||
*
|
||||
@@ -6,6 +6,8 @@ package me.bobert.netneutrality.core.tasks;
|
||||
*/
|
||||
|
||||
import me.bobert.netneutrality.core.context.CommandContext;
|
||||
import me.bobert.netneutrality.core.tasks.Task;
|
||||
import me.bobert.netneutrality.core.tasks.TaskManager;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.Objects;
|
||||
@@ -5,49 +5,40 @@ package me.bobert.netneutrality.core.tasks.impl;
|
||||
* https://discord.gg/qUa6zNFZsd
|
||||
*/
|
||||
|
||||
import me.bobert.netneutrality.core.tasks.GenericRandomIdTask;
|
||||
import me.bobert.netneutrality.core.tasks.Task;
|
||||
import me.bobert.netneutrality.core.tasks.trait.WithChildren;
|
||||
import net.dv8tion.jda.api.interactions.components.ActionRow;
|
||||
import me.bobert.netneutrality.core.tasks.trait.WithButton;
|
||||
import net.dv8tion.jda.api.entities.emoji.Emoji;
|
||||
import net.dv8tion.jda.api.interactions.components.buttons.Button;
|
||||
import net.dv8tion.jda.api.interactions.components.buttons.ButtonStyle;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class ButtonTask extends GenericRandomIdTask {
|
||||
public abstract class ButtonTask extends GenericRandomIdTask implements WithButton {
|
||||
private final ButtonStyle buttonStyle;
|
||||
private final String buttonLabel;
|
||||
private Emoji emoji;
|
||||
|
||||
public ButtonTask(ButtonStyle buttonStyle, String buttonLabel) {
|
||||
this.buttonStyle = buttonStyle;
|
||||
this.buttonLabel = buttonLabel;
|
||||
}
|
||||
|
||||
public Task setEmoji(Emoji emoji) {
|
||||
this.emoji = emoji;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Button createButton() {
|
||||
if (buttonStyle == null || buttonLabel == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Button.of(buttonStyle, getId(), buttonLabel);
|
||||
return Button.of(buttonStyle, getId(), buttonLabel, emoji);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExpired() {
|
||||
return getCreationTime().plusMinutes(15).isBefore(OffsetDateTime.now());
|
||||
}
|
||||
|
||||
public ActionRow createActionRow(List<Task> tasks) {
|
||||
ActionRow row = ActionRow.of(tasks.stream().map(Task::createButton).toList());
|
||||
if (this instanceof WithChildren parent) {
|
||||
parent.addChild(tasks);
|
||||
}
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
public ActionRow createActionRow(Task... tasks) {
|
||||
return createActionRow(List.of(tasks));
|
||||
}
|
||||
}
|
||||
@@ -6,8 +6,6 @@ package me.bobert.netneutrality.core.tasks.impl;
|
||||
*/
|
||||
|
||||
import me.bobert.netneutrality.context.tasks.EmojiTaskContext;
|
||||
import me.bobert.netneutrality.core.tasks.AbstractPersistableTask;
|
||||
import net.dv8tion.jda.api.interactions.components.buttons.Button;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@@ -54,9 +52,4 @@ public abstract class EmojiTask extends AbstractPersistableTask {
|
||||
public String getId() {
|
||||
return String.format(EmojiTaskContext.ID, getGuildId(), getMessageId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Button createButton() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+1
-8
@@ -1,4 +1,4 @@
|
||||
package me.bobert.netneutrality.core.tasks;
|
||||
package me.bobert.netneutrality.core.tasks.impl;
|
||||
|
||||
/*
|
||||
* Copyright (c) anthorob
|
||||
@@ -6,8 +6,6 @@ package me.bobert.netneutrality.core.tasks;
|
||||
* https://discord.gg/qUa6zNFZsd
|
||||
*/
|
||||
|
||||
import net.dv8tion.jda.api.interactions.components.buttons.Button;
|
||||
|
||||
public abstract class GenericCustomIdTask extends AbstractTask {
|
||||
private final String customId;
|
||||
|
||||
@@ -19,9 +17,4 @@ public abstract class GenericCustomIdTask extends AbstractTask {
|
||||
public String getId() {
|
||||
return customId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Button createButton() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package me.bobert.netneutrality.core.tasks;
|
||||
package me.bobert.netneutrality.core.tasks.impl;
|
||||
|
||||
/*
|
||||
* Copyright (c) anthorob
|
||||
@@ -6,7 +6,6 @@ package me.bobert.netneutrality.core.tasks.impl;
|
||||
*/
|
||||
|
||||
import me.bobert.netneutrality.core.context.TaskContext;
|
||||
import me.bobert.netneutrality.core.tasks.GenericRandomIdTask;
|
||||
import net.dv8tion.jda.api.interactions.modals.ModalMapping;
|
||||
|
||||
import java.time.OffsetDateTime;
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package me.bobert.netneutrality.core.tasks.trait;
|
||||
|
||||
/*
|
||||
* Copyright (c) anthorob
|
||||
*
|
||||
* https://discord.gg/qUa6zNFZsd
|
||||
*/
|
||||
|
||||
import me.bobert.netneutrality.core.tasks.Task;
|
||||
import net.dv8tion.jda.api.interactions.components.ActionRow;
|
||||
import net.dv8tion.jda.api.interactions.components.buttons.Button;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface WithButton {
|
||||
|
||||
Button createButton();
|
||||
|
||||
default ActionRow createActionRow(List<Task> tasks) {
|
||||
ActionRow row = ActionRow.of(tasks.stream().filter(task -> task instanceof WithButton).map(task -> (WithButton) task).map(WithButton::createButton).toList());
|
||||
if (this instanceof WithChildren parent) {
|
||||
parent.addChild(tasks);
|
||||
}
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
default ActionRow createActionRow(Task... tasks) {
|
||||
return createActionRow(List.of(tasks));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package me.bobert.netneutrality.core.thread;
|
||||
|
||||
/*
|
||||
* Copyright (c) anthorob
|
||||
*
|
||||
* https://discord.gg/qUa6zNFZsd
|
||||
*/
|
||||
|
||||
import me.bobert.netneutrality.core.LogHandler;
|
||||
import me.bobert.netneutrality.core.tasks.ScheduledTask;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
|
||||
public class ScheduledTaskManager {
|
||||
private static final Logger logger = LogManager.getLogger(ScheduledTaskManager.class);
|
||||
private static final ScheduledExecutorService executorService = ThreadManager.getScheduledExecutor();
|
||||
private static final Map<String, ScheduledFuture<?>> scheduledTasks = new ConcurrentHashMap<>();
|
||||
|
||||
private ScheduledTaskManager() {}
|
||||
|
||||
public static void schedule(ScheduledTask task) {
|
||||
String taskId = task.getId();
|
||||
|
||||
if (scheduledTasks.containsKey(taskId)) {
|
||||
logger.warn("Task {} is already scheduled.", taskId);
|
||||
return;
|
||||
}
|
||||
|
||||
ScheduledTask.TimeFrame timeFrame = task.getTimeFrame();
|
||||
|
||||
Runnable runnable = () -> {
|
||||
logger.info("Executing scheduled task: {}", taskId);
|
||||
|
||||
try {
|
||||
task.run();
|
||||
} catch (Exception e) {
|
||||
logger.error("An exception was thrown while executing scheduled task {}", taskId);
|
||||
LogHandler.log(e);
|
||||
}
|
||||
};
|
||||
|
||||
ScheduledFuture<?> future = executorService.scheduleWithFixedDelay(
|
||||
runnable,
|
||||
1,
|
||||
timeFrame.getInterval(),
|
||||
timeFrame.getUnit()
|
||||
);
|
||||
|
||||
scheduledTasks.put(taskId, future);
|
||||
logger.info("Successfully scheduled task: {} with interval {} {}",
|
||||
taskId, timeFrame.getInterval(), timeFrame.getUnit());
|
||||
}
|
||||
|
||||
public static void cancelAll() {
|
||||
logger.info("Cancelling all {} scheduled tasks", scheduledTasks.size());
|
||||
scheduledTasks.forEach((id, future) -> future.cancel(false));
|
||||
scheduledTasks.clear();
|
||||
}
|
||||
}
|
||||
@@ -15,12 +15,9 @@ import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
|
||||
import dev.lavalink.youtube.YoutubeAudioSourceManager;
|
||||
import me.bobert.netneutrality.core.command.CommandExecutionResult;
|
||||
import me.bobert.netneutrality.core.context.CommandContext;
|
||||
import me.bobert.netneutrality.core.thread.ThreadManager;
|
||||
import me.bobert.netneutrality.db.GSettings;
|
||||
import me.bobert.netneutrality.db.service.GuildService;
|
||||
import me.bobert.netneutrality.music.source.UdioAudioSourceManager;
|
||||
import me.bobert.netneutrality.thread.MusicManagerCleanupThread;
|
||||
import me.bobert.netneutrality.thread.MusicPlayerAutoDisconnectThread;
|
||||
import me.bobert.netneutrality.utils.MusicUtils;
|
||||
import me.bobert.netneutrality.utils.Settings;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
@@ -31,7 +28,6 @@ import org.apache.logging.log4j.Logger;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class MusicManager {
|
||||
|
||||
@@ -72,9 +68,6 @@ public class MusicManager {
|
||||
String po = Settings.getInstance().get("NETNEUTRALITY_PO_TOKEN");
|
||||
String visitor = Settings.getInstance().get("NETNEUTRALITY_VISITOR_DATA");
|
||||
dev.lavalink.youtube.clients.Web.setPoTokenAndVisitorData(po, visitor);
|
||||
|
||||
ThreadManager.getScheduledExecutor().scheduleWithFixedDelay(new MusicPlayerAutoDisconnectThread(), 15, 15, TimeUnit.MINUTES);
|
||||
ThreadManager.getScheduledExecutor().scheduleWithFixedDelay(new MusicManagerCleanupThread(), 1, 1, TimeUnit.HOURS);
|
||||
}
|
||||
|
||||
public static void disconnectPlayers() {
|
||||
|
||||
@@ -6,10 +6,12 @@ package me.bobert.netneutrality.tasks.help;
|
||||
*/
|
||||
|
||||
import me.bobert.netneutrality.core.context.TaskContext;
|
||||
import me.bobert.netneutrality.core.tasks.AbstractBuiltInTask;
|
||||
import me.bobert.netneutrality.core.tasks.impl.AbstractBuiltInTask;
|
||||
import me.bobert.netneutrality.core.tasks.trait.WithButton;
|
||||
import me.bobert.netneutrality.utils.Settings;
|
||||
import net.dv8tion.jda.api.interactions.components.buttons.Button;
|
||||
|
||||
public class BotInfo extends AbstractBuiltInTask {
|
||||
public class BotInfo extends AbstractBuiltInTask implements WithButton {
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
@@ -23,7 +25,7 @@ public class BotInfo extends AbstractBuiltInTask {
|
||||
|
||||
@Override
|
||||
public void executeTask(TaskContext context) {
|
||||
context.sendMessageInPrivate("For information about the bot and to follow the development, " +
|
||||
"you can join the discord here: https://discord.gg/udVJwTgV");
|
||||
context.replyEphemeral("For information about the bot and to follow the development, " +
|
||||
"you can join the discord here: " + Settings.getDiscordInvite());
|
||||
}
|
||||
}
|
||||
@@ -6,12 +6,13 @@ package me.bobert.netneutrality.tasks.help;
|
||||
*/
|
||||
|
||||
import me.bobert.netneutrality.core.context.TaskContext;
|
||||
import me.bobert.netneutrality.core.tasks.AbstractBuiltInTask;
|
||||
import me.bobert.netneutrality.core.tasks.impl.AbstractBuiltInTask;
|
||||
import me.bobert.netneutrality.core.tasks.trait.WithButton;
|
||||
import me.bobert.netneutrality.utils.MessageFunction;
|
||||
import me.bobert.netneutrality.utils.Settings;
|
||||
import net.dv8tion.jda.api.interactions.components.buttons.Button;
|
||||
|
||||
public class CommandHelp extends AbstractBuiltInTask {
|
||||
public class CommandHelp extends AbstractBuiltInTask implements WithButton {
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
|
||||
@@ -6,10 +6,12 @@ package me.bobert.netneutrality.tasks.help;
|
||||
*/
|
||||
|
||||
import me.bobert.netneutrality.core.context.TaskContext;
|
||||
import me.bobert.netneutrality.core.tasks.AbstractBuiltInTask;
|
||||
import me.bobert.netneutrality.core.tasks.impl.AbstractBuiltInTask;
|
||||
import me.bobert.netneutrality.core.tasks.trait.WithButton;
|
||||
import me.bobert.netneutrality.utils.Settings;
|
||||
import net.dv8tion.jda.api.interactions.components.buttons.Button;
|
||||
|
||||
public class ReportBug extends AbstractBuiltInTask {
|
||||
public class ReportBug extends AbstractBuiltInTask implements WithButton {
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
@@ -23,7 +25,7 @@ public class ReportBug extends AbstractBuiltInTask {
|
||||
|
||||
@Override
|
||||
public void executeTask(TaskContext context) {
|
||||
context.sendMessageInPrivate("To report a bug with the bot, you can either use the /report-bug command " +
|
||||
"or join the discord here: https://discord.gg/udVJwTgV");
|
||||
context.replyEphemeral("To report a bug with the bot, you can either use the /report-bug command " +
|
||||
"or join the discord here: " + Settings.getDiscordInvite());
|
||||
}
|
||||
}
|
||||
@@ -109,15 +109,12 @@ public class LoadPlaylistTask extends ButtonTask implements WithChildren, Deleta
|
||||
}
|
||||
|
||||
return Lifecycle.KEEP;
|
||||
});
|
||||
}).setEmoji(Emoji.fromFormatted("U+1F60E"));
|
||||
|
||||
Task cancel = CancelButton.create(this, cancelText, context -> Lifecycle.REMOVE_SELF_AND_CHILDREN);
|
||||
addChild(accept, cancel);
|
||||
Task cancel = CancelButton.create(this, cancelText, context -> Lifecycle.REMOVE_SELF_AND_CHILDREN)
|
||||
.setEmoji(Emoji.fromFormatted("U+1F92E"));
|
||||
|
||||
return ActionRow.of(
|
||||
accept.createButton().withEmoji(Emoji.fromFormatted("U+1F60E")),
|
||||
cancel.createButton().withEmoji(Emoji.fromFormatted("U+1F92E"))
|
||||
);
|
||||
return createActionRow(accept, cancel);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -6,11 +6,11 @@ package me.bobert.netneutrality.tasks.reaction;
|
||||
* https://discord.gg/qUa6zNFZsd
|
||||
*/
|
||||
|
||||
import me.bobert.netneutrality.core.tasks.impl.StepTask;
|
||||
import me.bobert.netneutrality.core.tasks.impl.AbstractStepTask;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.entities.Role;
|
||||
|
||||
public class EmojiRoleFirstStep extends StepTask {
|
||||
public class EmojiRoleFirstStep extends AbstractStepTask {
|
||||
private final Message target;
|
||||
|
||||
public EmojiRoleFirstStep(Message target) {
|
||||
|
||||
@@ -74,7 +74,7 @@ public class EmojiRoleModify extends ButtonTask implements WithChildren {
|
||||
});
|
||||
|
||||
ActionRow row = createActionRow(addEmojiTask, removeEmojiTask, deleteMappingTask);
|
||||
context.replyEphemeral("Select what you want to do with this message", List.of(row));
|
||||
context.replyEphemeral("Select what you want to do with this message", row);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -6,14 +6,14 @@ package me.bobert.netneutrality.tasks.reaction;
|
||||
* https://discord.gg/qUa6zNFZsd
|
||||
*/
|
||||
|
||||
import me.bobert.netneutrality.core.tasks.impl.StepTask;
|
||||
import me.bobert.netneutrality.core.tasks.impl.AbstractStepTask;
|
||||
import me.bobert.netneutrality.tasks.emoji.EmojiReactionRoleTask;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
public class EmojiRoleRemoveStep extends StepTask {
|
||||
public class EmojiRoleRemoveStep extends AbstractStepTask {
|
||||
private final Message target;
|
||||
private final EmojiReactionRoleTask task;
|
||||
|
||||
@@ -22,6 +22,11 @@ public class EmojiRoleRemoveStep extends StepTask {
|
||||
this.task = task;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "emoji-role-remove";
|
||||
}
|
||||
|
||||
@Override
|
||||
public StepType getStepType() {
|
||||
return StepType.EMOJI;
|
||||
@@ -54,9 +59,4 @@ public class EmojiRoleRemoveStep extends StepTask {
|
||||
task.removeEmoji(emoji);
|
||||
return StepResult.success("Removed emoji successfully!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "emoji-role-remove";
|
||||
}
|
||||
}
|
||||
@@ -8,14 +8,14 @@ package me.bobert.netneutrality.tasks.reaction;
|
||||
|
||||
import me.bobert.netneutrality.core.tasks.Task;
|
||||
import me.bobert.netneutrality.core.tasks.TaskManager;
|
||||
import me.bobert.netneutrality.core.tasks.impl.StepTask;
|
||||
import me.bobert.netneutrality.core.tasks.impl.AbstractStepTask;
|
||||
import me.bobert.netneutrality.tasks.emoji.EmojiReactionRoleTask;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.entities.Role;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class EmojiRoleSecondStep extends StepTask {
|
||||
public class EmojiRoleSecondStep extends AbstractStepTask {
|
||||
private final Message target;
|
||||
private final Role role;
|
||||
|
||||
|
||||
+14
-6
@@ -1,27 +1,35 @@
|
||||
package me.bobert.netneutrality.thread;
|
||||
package me.bobert.netneutrality.tasks.scheduled;
|
||||
/*
|
||||
* Copyright (c) anthorob
|
||||
*
|
||||
* https://discord.gg/qUa6zNFZsd
|
||||
*/
|
||||
|
||||
import me.bobert.netneutrality.core.tasks.ScheduledTask;
|
||||
import me.bobert.netneutrality.music.MusicManager;
|
||||
import me.bobert.netneutrality.music.TrackScheduler;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
public class MusicManagerCleanupThread implements Runnable {
|
||||
private static final Logger logger = LogManager.getLogger(MusicManagerCleanupThread.class);
|
||||
public class MusicManagerCleanup implements ScheduledTask {
|
||||
private static final Logger logger = LogManager.getLogger(MusicManagerCleanup.class);
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "MusicManagerCleanup";
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimeFrame getTimeFrame() {
|
||||
return TimeFrame.hourly();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
try {
|
||||
|
||||
for (MusicManager manager : MusicManager.getManagers()) {
|
||||
processManager(manager);
|
||||
}
|
||||
|
||||
} catch (InterruptedException e) {
|
||||
logger.error("Interrupted while running MusicManagerCleanupThread", e);
|
||||
}
|
||||
+15
-5
@@ -1,10 +1,12 @@
|
||||
package me.bobert.netneutrality.thread;
|
||||
package me.bobert.netneutrality.tasks.scheduled;
|
||||
|
||||
/*
|
||||
* Copyright (c) anthorob
|
||||
*
|
||||
* https://discord.gg/qUa6zNFZsd
|
||||
*/
|
||||
|
||||
import me.bobert.netneutrality.core.tasks.ScheduledTask;
|
||||
import me.bobert.netneutrality.music.MusicManager;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.channel.middleman.AudioChannel;
|
||||
@@ -13,17 +15,25 @@ import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class MusicPlayerAutoDisconnectThread implements Runnable {
|
||||
private static final Logger logger = LogManager.getLogger(MusicPlayerAutoDisconnectThread.class);
|
||||
public class MusicPlayerAutoDisconnect implements ScheduledTask {
|
||||
private static final Logger logger = LogManager.getLogger(MusicPlayerAutoDisconnect.class);
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "MusicPlayerAutoDisconnect";
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimeFrame getTimeFrame() {
|
||||
return TimeFrame.minutely(15);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
|
||||
for (MusicManager manager : MusicManager.getManagers()) {
|
||||
processManager(manager);
|
||||
}
|
||||
|
||||
} catch (InterruptedException e) {
|
||||
logger.error("Interrupted while running MusicPlayerAutoDisconnectThread", e);
|
||||
}
|
||||
+14
-3
@@ -1,4 +1,4 @@
|
||||
package me.bobert.netneutrality.thread;/*
|
||||
package me.bobert.netneutrality.tasks.scheduled;/*
|
||||
* Copyright (c) anthorob
|
||||
*
|
||||
* https://discord.gg/qUa6zNFZsd
|
||||
@@ -6,6 +6,7 @@ package me.bobert.netneutrality.thread;/*
|
||||
|
||||
import me.bobert.netneutrality.core.tasks.BuiltInTask;
|
||||
import me.bobert.netneutrality.core.tasks.PersistableTask;
|
||||
import me.bobert.netneutrality.core.tasks.ScheduledTask;
|
||||
import me.bobert.netneutrality.core.tasks.Task;
|
||||
import me.bobert.netneutrality.core.tasks.TaskManager;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
@@ -13,8 +14,18 @@ import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class CleanupTaskThread implements Runnable {
|
||||
private static final Logger logger = LogManager.getLogger(CleanupTaskThread.class);
|
||||
public class TaskCleanup implements ScheduledTask {
|
||||
private static final Logger logger = LogManager.getLogger(TaskCleanup.class);
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "TaskCleanup";
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimeFrame getTimeFrame() {
|
||||
return TimeFrame.minutely(5);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -1,33 +0,0 @@
|
||||
package me.bobert.netneutrality.thread;
|
||||
|
||||
/*
|
||||
* Copyright (c) anthorob
|
||||
*
|
||||
* https://discord.gg/qUa6zNFZsd
|
||||
*/
|
||||
|
||||
import me.bobert.netneutrality.NetNeutrality;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.core.LoggerContext;
|
||||
import org.apache.logging.log4j.core.config.Configurator;
|
||||
|
||||
public class ShutdownThread extends Thread {
|
||||
private final NetNeutrality main;
|
||||
|
||||
public ShutdownThread(NetNeutrality main) {
|
||||
this.main = main;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (LogManager.getContext() instanceof LoggerContext) {
|
||||
System.out.println("Shutting down log4j2");
|
||||
Configurator.shutdown((LoggerContext) LogManager.getContext());
|
||||
}
|
||||
|
||||
if (main.getJDA() != null) {
|
||||
main.shutdown();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package me.bobert.netneutrality.utils;
|
||||
|
||||
/*
|
||||
* Copyright (c) anthorob
|
||||
*
|
||||
* https://discord.gg/qUa6zNFZsd
|
||||
*/
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.reflections.Reflections;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class ReflectionHelper {
|
||||
private static final Logger logger = LogManager.getLogger(ReflectionHelper.class);
|
||||
private static final BiConsumer<Class<?>, Exception> DEFAULT_FAILURE = (aClass, e) -> logger.error("Failed to load class: {}", aClass.getName(), e);
|
||||
|
||||
public static <E> void loadClassesFromPackage(String packageName, Class<E> clazz, Consumer<E> onInstanciated, BiConsumer<Class<?>, Exception> onFailed) {
|
||||
Set<Class<? extends E>> classes = new Reflections(packageName).getSubTypesOf(clazz);
|
||||
for (Class<? extends E> s : classes) {
|
||||
try {
|
||||
if (Modifier.isAbstract(s.getModifiers())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
E instance = s.getConstructor().newInstance();
|
||||
onInstanciated.accept(instance);
|
||||
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException
|
||||
| InvocationTargetException | NoSuchMethodException | SecurityException e) {
|
||||
onFailed.accept(s, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static <E> void loadCommands(Class<E> clazz, Consumer<E> onInstanciated, BiConsumer<Class<?>, Exception> onFailed) {
|
||||
loadClassesFromPackage("me.bobert.netneutrality.command", clazz, onInstanciated, onFailed);
|
||||
}
|
||||
|
||||
public static <E> void loadCommands(Class<E> clazz, Consumer<E> onInstanciated) {
|
||||
loadClassesFromPackage("me.bobert.netneutrality.command", clazz, onInstanciated, DEFAULT_FAILURE);
|
||||
}
|
||||
|
||||
public static <E> void loadTasks(Class<E> clazz, Consumer<E> onInstanciated, BiConsumer<Class<?>, Exception> onFailed) {
|
||||
loadClassesFromPackage("me.bobert.netneutrality.tasks", clazz, onInstanciated, onFailed);
|
||||
}
|
||||
|
||||
public static <E> void loadTasks(Class<E> clazz, Consumer<E> onInstanciated) {
|
||||
loadClassesFromPackage("me.bobert.netneutrality.tasks", clazz, onInstanciated, DEFAULT_FAILURE);
|
||||
}
|
||||
}
|
||||
@@ -54,6 +54,10 @@ public class Settings {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public static String getDiscordInvite() {
|
||||
return Settings.getInstance().get("NETNEUTRALITY_BOT_INVITE", "https://discord.gg/PyCpd7JGMp");
|
||||
}
|
||||
|
||||
public static String getVersion() {
|
||||
return Settings.getInstance().getMavenVersion();
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user