Compare commits
23
Commits
68f6a9563e
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
87f78ccbea | ||
|
|
5ab18ff5ce | ||
|
|
e0e9bbff10 | ||
|
|
d0c06cd6bf | ||
|
|
e58854a85c | ||
|
|
e0612f90a8 | ||
|
|
4b88be0517 | ||
|
|
8fec0271cc | ||
|
|
88d954427a | ||
|
|
febd12f2f2 | ||
|
|
ffb393706b | ||
|
|
c021f84415 | ||
|
|
da3142df0c | ||
|
|
15d58bba38 | ||
|
|
247f217e2e | ||
|
|
c98d47b5ca | ||
|
|
81e15a5394 | ||
|
|
ddd7d119bb | ||
|
|
ccf56298d8 | ||
|
|
4fa790259e | ||
|
|
aa587ddf3c | ||
|
|
f8ebe28cb4 | ||
|
|
1544cda9d2 |
No files matched your search
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
.git
|
.git
|
||||||
.gitea
|
.github
|
||||||
.idea
|
.idea
|
||||||
.mvn
|
.mvn
|
||||||
src
|
src
|
||||||
|
|||||||
File renamed without changes.
@@ -226,6 +226,11 @@
|
|||||||
<artifactId>jemoji</artifactId>
|
<artifactId>jemoji</artifactId>
|
||||||
<version>1.7.6</version>
|
<version>1.7.6</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.fellbaum</groupId>
|
||||||
|
<artifactId>jemoji</artifactId>
|
||||||
|
<version>1.7.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.json</groupId>
|
<groupId>org.json</groupId>
|
||||||
|
|||||||
+26
-9
@@ -6,12 +6,6 @@
|
|||||||
"group:flyway"
|
"group:flyway"
|
||||||
],
|
],
|
||||||
"packageRules": [
|
"packageRules": [
|
||||||
{
|
|
||||||
"matchPackageNames": [
|
|
||||||
"quay.io/buildah/stable"
|
|
||||||
],
|
|
||||||
"enabled": false
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"matchPackageNames": [
|
"matchPackageNames": [
|
||||||
"mariadb"
|
"mariadb"
|
||||||
@@ -19,23 +13,46 @@
|
|||||||
"automerge": false,
|
"automerge": false,
|
||||||
"dependencyDashboardApproval": true
|
"dependencyDashboardApproval": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"matchManagers": ["maven"],
|
||||||
|
"extends": ["schedule:monthly"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"groupName": "maven plugins",
|
||||||
|
"matchManagers": ["maven"],
|
||||||
|
"matchDepTypes": ["plugin"],
|
||||||
|
"extends": ["schedule:weekly"]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"groupName": "hibernate orm",
|
"groupName": "hibernate orm",
|
||||||
"matchPackageNames": [
|
"matchPackageNames": [
|
||||||
"org.hibernate.orm:**"
|
"org.hibernate.orm:**"
|
||||||
]
|
],
|
||||||
|
"extends": ["schedule:monthly"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"groupName": "apache commons",
|
"groupName": "apache commons",
|
||||||
"matchPackageNames": [
|
"matchPackageNames": [
|
||||||
"commons-**",
|
"commons-**",
|
||||||
"org.apache.commons:**"
|
"org.apache.commons:**"
|
||||||
]
|
],
|
||||||
|
"extends": ["schedule:monthly"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"matchManagers": ["maven"],
|
||||||
|
"matchDepTypes": ["dependency", "parentPom"],
|
||||||
|
"matchPackageNames": [
|
||||||
|
"net.dv8tion:JDA",
|
||||||
|
"dev.arbjerg:lavaplayer",
|
||||||
|
"dev.lavalink.youtube:**",
|
||||||
|
"club.minnced:jdave-*"
|
||||||
|
],
|
||||||
|
"schedule": ["at any time"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"groupName": "github actions (minor/patch)",
|
"groupName": "github actions (minor/patch)",
|
||||||
"matchManagers": ["github-actions"],
|
"matchManagers": ["github-actions"],
|
||||||
"matchUpdateTypes": ["minor", "patch"]
|
"matchUpdateTypes": ["minor", "patch", "digest"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"groupName": "github actions (major)",
|
"groupName": "github actions (major)",
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ public class NetNeutrality {
|
|||||||
options.setEnvironment(env);
|
options.setEnvironment(env);
|
||||||
options.setTracesSampleRate(1.0);
|
options.setTracesSampleRate(1.0);
|
||||||
options.setDebug(false);
|
options.setDebug(false);
|
||||||
options.setRelease(VERSION);
|
options.setRelease(Settings.getVersion());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,11 @@ public class MusicChannelContext extends AbstractContext implements NoMessageCon
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isFromGuild() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteMessage() {
|
public void deleteMessage() {
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package me.bobert.netneutrality.core.command;
|
||||||
|
/*
|
||||||
|
* Copyright (c) anthorob
|
||||||
|
*
|
||||||
|
* https://discord.gg/qUa6zNFZsd
|
||||||
|
*/
|
||||||
|
|
||||||
|
public abstract class AbstractAdminCommand extends AbstractCommand {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean needAdmin() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommandCategory getCategory() {
|
||||||
|
return CommandCategory.ADMINISTRATION;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package me.bobert.netneutrality.core.command;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) anthorob
|
||||||
|
*
|
||||||
|
* https://discord.gg/qUa6zNFZsd
|
||||||
|
*/
|
||||||
|
|
||||||
|
import me.bobert.netneutrality.context.command.MessageMenuContext;
|
||||||
|
import me.bobert.netneutrality.core.command.options.CommandOptionsBuilder;
|
||||||
|
import me.bobert.netneutrality.core.context.CommandContext;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
|
||||||
|
public abstract class AbstractMessageMenuCommand extends AbstractCommand {
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isGuildOnly() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSlashCommandOnly() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerCommandOptions(CommandOptionsBuilder builder) {
|
||||||
|
// no options for context commands
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommandCategory getCategory() {
|
||||||
|
return CommandCategory.UNLISTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type getType() {
|
||||||
|
return Type.MESSAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommandExecutionResult execute(CommandContext context) {
|
||||||
|
if (context instanceof MessageMenuContext mc) {
|
||||||
|
Message message = mc.getTarget();
|
||||||
|
return execute(message, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalArgumentException("Wrong context type for this command");
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract CommandExecutionResult execute(Message target, CommandContext context);
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package me.bobert.netneutrality.core.command;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) anthorob
|
||||||
|
*
|
||||||
|
* https://discord.gg/qUa6zNFZsd
|
||||||
|
*/
|
||||||
|
|
||||||
|
import me.bobert.netneutrality.context.command.UserMenuContext;
|
||||||
|
import me.bobert.netneutrality.core.command.options.CommandOptionsBuilder;
|
||||||
|
import me.bobert.netneutrality.core.context.CommandContext;
|
||||||
|
import net.dv8tion.jda.api.entities.User;
|
||||||
|
|
||||||
|
public abstract class AbstractUserMenuCommand extends AbstractCommand {
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSlashCommandOnly() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerCommandOptions(CommandOptionsBuilder builder) {
|
||||||
|
// no options for context commands
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Type getType() {
|
||||||
|
return Type.USER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommandExecutionResult execute(CommandContext context) {
|
||||||
|
if (context instanceof UserMenuContext uc) {
|
||||||
|
User user = uc.getTarget();
|
||||||
|
return execute(user, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalArgumentException("Wrong context type for this command");
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract CommandExecutionResult execute(User target, CommandContext context);
|
||||||
|
}
|
||||||
@@ -1,4 +1,8 @@
|
|||||||
|
<<<<<<<< HEAD:src/main/java/me/bobert/netneutrality/core/command/impl/AbstractCommand.java
|
||||||
package me.bobert.netneutrality.core.command.impl;
|
package me.bobert.netneutrality.core.command.impl;
|
||||||
|
========
|
||||||
|
package me.bobert.netneutrality.core.command;
|
||||||
|
>>>>>>>> 8479f71 (change package of core command classes so it makes more sense and rename getType() to getCategory() in command interface):src/main/java/me/bobert/netneutrality/core/command/AbstractCommand.java
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) anthorob
|
* Copyright (c) anthorob
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
|
<<<<<<<< HEAD:src/main/java/me/bobert/netneutrality/core/command/impl/MusicCommand.java
|
||||||
package me.bobert.netneutrality.core.command.impl;
|
package me.bobert.netneutrality.core.command.impl;
|
||||||
|
========
|
||||||
|
package me.bobert.netneutrality.core.command;
|
||||||
|
>>>>>>>> 8479f71 (change package of core command classes so it makes more sense and rename getType() to getCategory() in command interface):src/main/java/me/bobert/netneutrality/core/command/AbstractMusicCommand.java
|
||||||
/*
|
/*
|
||||||
* Copyright (c) anthorob
|
* Copyright (c) anthorob
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -0,0 +1,170 @@
|
|||||||
|
package me.bobert.netneutrality.core.command.options;
|
||||||
|
/*
|
||||||
|
* Copyright (c) anthorob
|
||||||
|
*
|
||||||
|
* https://discord.gg/qUa6zNFZsd
|
||||||
|
*/
|
||||||
|
|
||||||
|
import me.bobert.netneutrality.core.command.Command;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.ChannelType;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.build.SubcommandData;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.build.SubcommandGroupData;
|
||||||
|
import net.dv8tion.jda.internal.interactions.CommandDataImpl;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.StringJoiner;
|
||||||
|
|
||||||
|
public class CommandOptions {
|
||||||
|
private final Command command;
|
||||||
|
private final CommandDataImpl commandData;
|
||||||
|
private final List<OptionData> options;
|
||||||
|
private final List<SubcommandData> subcommands;
|
||||||
|
private final List<SubcommandGroupData> subcommandGroups;
|
||||||
|
|
||||||
|
public CommandOptions(Command command, CommandDataImpl commandData) {
|
||||||
|
this.command = command;
|
||||||
|
this.commandData = commandData;
|
||||||
|
this.options = commandData.getOptions();
|
||||||
|
this.subcommands = commandData.getSubcommands();
|
||||||
|
this.subcommandGroups = commandData.getSubcommandGroups();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Command getCommand() {
|
||||||
|
return command;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SlashCommandData getSlashCommandData() {
|
||||||
|
return commandData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<OptionData> getOptions() {
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<SubcommandData> getSubcommands() {
|
||||||
|
return subcommands;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<SubcommandGroupData> getSubcommandGroups() {
|
||||||
|
return subcommandGroups;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return options.isEmpty() && subcommands.isEmpty() && subcommandGroups.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String printUsage() {
|
||||||
|
StringBuilder usage = new StringBuilder();
|
||||||
|
if (!options.isEmpty()) {
|
||||||
|
usage.append("- Usage: /").append(command.getCommandName());
|
||||||
|
for (OptionData option : options) {
|
||||||
|
usage.append(" <").append(option.getName()).append(">");
|
||||||
|
}
|
||||||
|
|
||||||
|
usage.append(printOptions(options, null, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!subcommands.isEmpty()) {
|
||||||
|
for (SubcommandData subcommand : subcommands) {
|
||||||
|
usage.append("- Usage: /").append(command.getCommandName()).append(" ").append(subcommand.getName());
|
||||||
|
|
||||||
|
for (OptionData option : subcommand.getOptions()) {
|
||||||
|
usage.append(" <").append(option.getName()).append(">");
|
||||||
|
}
|
||||||
|
|
||||||
|
usage.append(" (").append(subcommand.getDescription()).append(")");
|
||||||
|
usage.append(printOptions(subcommand.getOptions(), null, false));
|
||||||
|
|
||||||
|
usage.append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!subcommandGroups.isEmpty()) {
|
||||||
|
for (SubcommandGroupData subcommandGroup : subcommandGroups) {
|
||||||
|
usage.append("- Subcommand: /").append(command.getCommandName())
|
||||||
|
.append(" ").append(subcommandGroup.getName())
|
||||||
|
.append(" (").append(subcommandGroup.getDescription()).append(")")
|
||||||
|
.append("\n");
|
||||||
|
|
||||||
|
for (SubcommandData subcommand : subcommandGroup.getSubcommands()) {
|
||||||
|
usage.append(" - Usage: /").append(command.getCommandName())
|
||||||
|
.append(" ").append(subcommandGroup.getName())
|
||||||
|
.append(" ").append(subcommand.getName());
|
||||||
|
|
||||||
|
for (OptionData option : subcommand.getOptions()) {
|
||||||
|
usage.append(" <").append(option.getName()).append(">");
|
||||||
|
}
|
||||||
|
|
||||||
|
usage.append(printOptions(subcommand.getOptions(), subcommand.getDescription(), true));
|
||||||
|
|
||||||
|
usage.append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isEmpty()) {
|
||||||
|
usage.append("\n\n-# *: required argument");
|
||||||
|
}
|
||||||
|
|
||||||
|
return usage.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String printOptions(List<OptionData> options, String description, boolean group) {
|
||||||
|
StringBuilder usage = new StringBuilder();
|
||||||
|
|
||||||
|
if (description != null) {
|
||||||
|
usage.append(" (").append(description).append(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (OptionData option : options) {
|
||||||
|
usage.append("\n");
|
||||||
|
if (group) usage.append(" ");
|
||||||
|
usage.append(" - ");
|
||||||
|
if (option.isRequired()) {
|
||||||
|
usage.append("*");
|
||||||
|
}
|
||||||
|
usage.append(option.getName()).append(": ").append(option.getDescription());
|
||||||
|
|
||||||
|
if (option.getMinValue() != null) {
|
||||||
|
usage.append(" [Min value: ").append(option.getMinValue().longValue()).append("]");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (option.getMaxValue() != null) {
|
||||||
|
usage.append(" [Max value: ").append(option.getMaxValue().longValue()).append("]");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (option.getMinLength() != null) {
|
||||||
|
usage.append(" [Min length: ").append(option.getMinLength().longValue()).append("]");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (option.getMaxLength() != null) {
|
||||||
|
usage.append(" [Max length: ").append(option.getMaxLength().longValue()).append("]");
|
||||||
|
}
|
||||||
|
|
||||||
|
List<net.dv8tion.jda.api.interactions.commands.Command.Choice> choices = option.getChoices();
|
||||||
|
if (!choices.isEmpty()) {
|
||||||
|
StringJoiner joiner = new StringJoiner(", ");
|
||||||
|
for (net.dv8tion.jda.api.interactions.commands.Command.Choice choice : choices) {
|
||||||
|
joiner.add(choice.getAsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
usage.append(" [Available choices: ").append(joiner).append("]");
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<ChannelType> requiredChannelTypes = option.getChannelTypes();
|
||||||
|
if (!requiredChannelTypes.isEmpty()) {
|
||||||
|
StringJoiner joiner = new StringJoiner(", ");
|
||||||
|
for (ChannelType type : requiredChannelTypes) {
|
||||||
|
joiner.add(type.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
usage.append(" [Required channel types: ").append(joiner).append("]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return usage.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
+185
@@ -0,0 +1,185 @@
|
|||||||
|
package me.bobert.netneutrality.core.command.options;
|
||||||
|
/*
|
||||||
|
* Copyright (c) anthorob
|
||||||
|
*
|
||||||
|
* https://discord.gg/qUa6zNFZsd
|
||||||
|
*/
|
||||||
|
|
||||||
|
import me.bobert.netneutrality.core.command.Command;
|
||||||
|
import net.dv8tion.jda.api.interactions.DiscordLocale;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.build.*;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.localization.LocalizationFunction;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.localization.LocalizationMap;
|
||||||
|
import net.dv8tion.jda.api.utils.data.DataObject;
|
||||||
|
import net.dv8tion.jda.internal.interactions.CommandDataImpl;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
public class CommandOptionsBuilder implements SlashCommandData {
|
||||||
|
private final Command command;
|
||||||
|
private CommandDataImpl commandData;
|
||||||
|
|
||||||
|
public CommandOptionsBuilder(Command.Type type, Command command) {
|
||||||
|
this.command = command;
|
||||||
|
|
||||||
|
if (type == Command.Type.SLASH) {
|
||||||
|
commandData = (CommandDataImpl) Commands.slash(command.getCommandName(), command.getDescription());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == Command.Type.USER) {
|
||||||
|
commandData = (CommandDataImpl) Commands.user(command.getCommandName());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == Command.Type.MESSAGE) {
|
||||||
|
commandData = (CommandDataImpl) Commands.message(command.getCommandName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public CommandOptions build() {
|
||||||
|
return new CommandOptions(command, commandData);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nonnull SlashCommandData setLocalizationFunction(@Nonnull LocalizationFunction localizationFunction) {
|
||||||
|
return commandData.setLocalizationFunction(localizationFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nonnull SlashCommandData setName(@Nonnull String name) {
|
||||||
|
return commandData.setName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nonnull SlashCommandData setNameLocalization(@Nonnull DiscordLocale locale, @Nonnull String name) {
|
||||||
|
return commandData.setNameLocalization(locale, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nonnull SlashCommandData setNameLocalizations(@Nonnull Map<DiscordLocale, String> map) {
|
||||||
|
return commandData.setNameLocalizations(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nonnull SlashCommandData setDefaultPermissions(@Nonnull DefaultMemberPermissions permission) {
|
||||||
|
return commandData.setDefaultPermissions(permission);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nonnull SlashCommandData setGuildOnly(boolean guildOnly) {
|
||||||
|
return commandData.setGuildOnly(guildOnly);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nonnull SlashCommandData setNSFW(boolean nsfw) {
|
||||||
|
return commandData.setNSFW(nsfw);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nonnull String getName() {
|
||||||
|
return commandData.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nonnull LocalizationMap getNameLocalizations() {
|
||||||
|
return commandData.getNameLocalizations();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nonnull net.dv8tion.jda.api.interactions.commands.Command.Type getType() {
|
||||||
|
return commandData.getType();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nonnull DefaultMemberPermissions getDefaultPermissions() {
|
||||||
|
return commandData.getDefaultPermissions();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isGuildOnly() {
|
||||||
|
return commandData.isGuildOnly();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNSFW() {
|
||||||
|
return commandData.isNSFW();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nonnull SlashCommandData setDescription(@Nonnull String description) {
|
||||||
|
return commandData.setDescription(description);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nonnull SlashCommandData setDescriptionLocalization(@Nonnull DiscordLocale locale, @Nonnull String description) {
|
||||||
|
return commandData.setDescriptionLocalization(locale, description);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nonnull SlashCommandData setDescriptionLocalizations(@Nonnull Map<DiscordLocale, String> map) {
|
||||||
|
return commandData.setDescriptionLocalizations(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nonnull String getDescription() {
|
||||||
|
return commandData.getDescription();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nonnull LocalizationMap getDescriptionLocalizations() {
|
||||||
|
return commandData.getDescriptionLocalizations();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean removeOptions(@Nonnull Predicate<? super OptionData> condition) {
|
||||||
|
return commandData.removeOptions(condition);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean removeSubcommands(@Nonnull Predicate<? super SubcommandData> condition) {
|
||||||
|
return commandData.removeSubcommands(condition);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean removeSubcommandGroups(@Nonnull Predicate<? super SubcommandGroupData> condition) {
|
||||||
|
return commandData.removeSubcommandGroups(condition);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nonnull List<SubcommandData> getSubcommands() {
|
||||||
|
return commandData.getSubcommands();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nonnull List<SubcommandGroupData> getSubcommandGroups() {
|
||||||
|
return commandData.getSubcommandGroups();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nonnull List<OptionData> getOptions() {
|
||||||
|
return commandData.getOptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nonnull SlashCommandData addOptions(@Nonnull OptionData... options) {
|
||||||
|
return commandData.addOptions(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nonnull SlashCommandData addSubcommands(@Nonnull SubcommandData... subcommands) {
|
||||||
|
return commandData.addSubcommands(subcommands);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nonnull SlashCommandData addSubcommandGroups(@Nonnull SubcommandGroupData... groups) {
|
||||||
|
return commandData.addSubcommandGroups(groups);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nonnull DataObject toData() {
|
||||||
|
return commandData.toData();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ package me.bobert.netneutrality.core.context;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import io.sentry.Sentry;
|
import io.sentry.Sentry;
|
||||||
|
import me.bobert.netneutrality.context.command.SlashCommandContext;
|
||||||
import net.dv8tion.jda.api.JDA;
|
import net.dv8tion.jda.api.JDA;
|
||||||
import net.dv8tion.jda.api.entities.Guild;
|
import net.dv8tion.jda.api.entities.Guild;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package me.bobert.netneutrality.core.tasks;
|
||||||
|
/*
|
||||||
|
* Copyright (c) anthorob
|
||||||
|
*
|
||||||
|
* https://discord.gg/qUa6zNFZsd
|
||||||
|
*/
|
||||||
|
|
||||||
|
import me.bobert.netneutrality.core.context.CommandContext;
|
||||||
|
import me.bobert.netneutrality.core.context.TaskContext;
|
||||||
|
|
||||||
|
public abstract class AbstractBuiltInTask extends AbstractTask implements BuiltInTask {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInsertable() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isExpired() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void replyToInteraction(CommandContext context) {
|
||||||
|
// Task is loaded at runtime, this will never be called
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Lifecycle execute(TaskContext context) {
|
||||||
|
executeTask(context);
|
||||||
|
return Lifecycle.BUILTIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void executeTask(TaskContext context);
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package me.bobert.netneutrality.core.tasks;
|
||||||
|
/*
|
||||||
|
* Copyright (c) anthorob
|
||||||
|
*
|
||||||
|
* https://discord.gg/qUa6zNFZsd
|
||||||
|
*/
|
||||||
|
|
||||||
|
import me.bobert.netneutrality.core.context.CommandContext;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
public abstract class AbstractPersistableTask extends AbstractTask implements PersistableTask {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInsertable() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isExpired() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void replyToInteraction(CommandContext context) {
|
||||||
|
// Task loaded from database, this will never be called
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void insert(CommandContext context) {
|
||||||
|
if (TaskManager.getInstance().hasTask(getId())) {
|
||||||
|
throw new RuntimeException("Cannot insert a task that already exists");
|
||||||
|
}
|
||||||
|
|
||||||
|
TaskManager.getInstance().insert(context, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void save() {
|
||||||
|
if (!TaskManager.getInstance().hasTask(getId())) {
|
||||||
|
throw new RuntimeException("Cannot save a task that doesn't exist yet");
|
||||||
|
}
|
||||||
|
|
||||||
|
TaskManager.getInstance().getTaskService().persistTask(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void delete() {
|
||||||
|
TaskManager.getInstance().getTaskService().unpersistTask(this);
|
||||||
|
TaskManager.getInstance().removeTask(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toPayload() {
|
||||||
|
JSONObject payload = new JSONObject(this);
|
||||||
|
|
||||||
|
return payload.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package me.bobert.netneutrality.core.tasks;
|
||||||
|
/*
|
||||||
|
* Copyright (c) anthorob
|
||||||
|
*
|
||||||
|
* https://discord.gg/qUa6zNFZsd
|
||||||
|
*/
|
||||||
|
|
||||||
|
import me.bobert.netneutrality.core.context.CommandContext;
|
||||||
|
|
||||||
|
import java.time.OffsetDateTime;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public abstract class AbstractTask implements Task {
|
||||||
|
private final OffsetDateTime creationTime;
|
||||||
|
|
||||||
|
public AbstractTask() {
|
||||||
|
creationTime = OffsetDateTime.now();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OffsetDateTime getCreationTime() {
|
||||||
|
return creationTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void insert(CommandContext context) {
|
||||||
|
TaskManager.getInstance().insert(context, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
AbstractTask that = (AbstractTask) o;
|
||||||
|
return Objects.equals(getId(), that.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hashCode(getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return String.format("Task{id=%s, lockId=%s, class=%s, name=%s, creationTime=%s}", getId(), getLockId(), getClass().getSimpleName(), getName(), getCreationTime());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package me.bobert.netneutrality.core.tasks;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) anthorob
|
||||||
|
*
|
||||||
|
* https://discord.gg/qUa6zNFZsd
|
||||||
|
*/
|
||||||
|
|
||||||
|
import net.dv8tion.jda.api.interactions.components.buttons.Button;
|
||||||
|
|
||||||
|
public abstract class GenericCustomIdTask extends AbstractTask {
|
||||||
|
private final String customId;
|
||||||
|
|
||||||
|
public GenericCustomIdTask(String id) {
|
||||||
|
this.customId = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return customId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Button createButton() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package me.bobert.netneutrality.core.tasks;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) anthorob
|
||||||
|
*
|
||||||
|
* https://discord.gg/qUa6zNFZsd
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public abstract class GenericRandomIdTask extends GenericCustomIdTask {
|
||||||
|
public GenericRandomIdTask() {
|
||||||
|
super(UUID.randomUUID().toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,147 @@
|
|||||||
|
package me.bobert.netneutrality.core.tasks;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) anthorob
|
||||||
|
*
|
||||||
|
* https://discord.gg/qUa6zNFZsd
|
||||||
|
*/
|
||||||
|
|
||||||
|
public interface IStepTask {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the type of input expected for a step.
|
||||||
|
*/
|
||||||
|
enum StepType {
|
||||||
|
/**
|
||||||
|
* Expects a string input from the user.
|
||||||
|
*/
|
||||||
|
STRING,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expects a valid role ID for the current guild.
|
||||||
|
* The role must exist in the guild where the command was executed.
|
||||||
|
*/
|
||||||
|
ROLE,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expects a valid emoji.
|
||||||
|
*/
|
||||||
|
EMOJI
|
||||||
|
}
|
||||||
|
|
||||||
|
class StepResult {
|
||||||
|
private enum ResultType {
|
||||||
|
SUCCESS, FAILURE
|
||||||
|
}
|
||||||
|
|
||||||
|
private final ResultType type;
|
||||||
|
private final String message;
|
||||||
|
private final Task nextStep;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the result of a step execution. Each step can either succeed, fail, or transition to another step.
|
||||||
|
*/
|
||||||
|
private StepResult(ResultType type, String message, Task nextStep) {
|
||||||
|
this.type = type;
|
||||||
|
this.message = message;
|
||||||
|
this.nextStep = nextStep;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that the step was completed successfully, with an optional follow-up step.
|
||||||
|
*
|
||||||
|
* @param message the success message
|
||||||
|
* @param nextStep the next step in the workflow, or null if this is the final step
|
||||||
|
* @return a successful result
|
||||||
|
*/
|
||||||
|
public static StepResult success(String message, Task nextStep) {
|
||||||
|
return new StepResult(ResultType.SUCCESS, message, nextStep);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that the step was completed successfully.
|
||||||
|
*
|
||||||
|
* @param message the success message
|
||||||
|
* @return a successful result without a next step
|
||||||
|
*/
|
||||||
|
public static StepResult success(String message) {
|
||||||
|
return new StepResult(ResultType.SUCCESS, message, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that the step has failed.
|
||||||
|
*
|
||||||
|
* @param message the failure message
|
||||||
|
* @return a failed result
|
||||||
|
*/
|
||||||
|
public static StepResult failure(String message) {
|
||||||
|
return new StepResult(ResultType.FAILURE, message, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves directly to the next step without displaying a message.
|
||||||
|
*
|
||||||
|
* @param nextTask the next task in the workflow
|
||||||
|
* @return a successful result that advances to the next step
|
||||||
|
*/
|
||||||
|
public static StepResult next(Task nextTask) {
|
||||||
|
return new StepResult(ResultType.SUCCESS, null, nextTask);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the message associated with the step result.
|
||||||
|
*
|
||||||
|
* @return the result message, or null if there is no message
|
||||||
|
*/
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the next step in the task workflow.
|
||||||
|
*
|
||||||
|
* @return the next step, or null if this is the last step
|
||||||
|
*/
|
||||||
|
public Task getNextStep() {
|
||||||
|
return nextStep;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the step execution was successful.
|
||||||
|
*
|
||||||
|
* @return true if the step was successful, false otherwise
|
||||||
|
*/
|
||||||
|
public boolean isSuccess() {
|
||||||
|
return type == ResultType.SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the type of step input expected.
|
||||||
|
*
|
||||||
|
* @return the step type
|
||||||
|
*/
|
||||||
|
StepType getStepType();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a general description of the step. This will be displayed before asking the question.
|
||||||
|
*
|
||||||
|
* @return the step description
|
||||||
|
*/
|
||||||
|
String getStepDescription();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the specific question for this step.
|
||||||
|
*
|
||||||
|
* @return the step question
|
||||||
|
*/
|
||||||
|
String getStepQuestion();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes the step using the provided answer.
|
||||||
|
*
|
||||||
|
* @param answer the user's input, validated against the expected step type
|
||||||
|
* @return the result of executing this step
|
||||||
|
*/
|
||||||
|
StepResult executeStep(Object answer);
|
||||||
|
}
|
||||||
@@ -0,0 +1,169 @@
|
|||||||
|
package me.bobert.netneutrality.core.tasks.impl;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) anthorob
|
||||||
|
*
|
||||||
|
* https://discord.gg/qUa6zNFZsd
|
||||||
|
*/
|
||||||
|
|
||||||
|
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.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;
|
||||||
|
|
||||||
|
import java.time.OffsetDateTime;
|
||||||
|
import java.util.Optional;
|
||||||
|
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 {
|
||||||
|
private final Object stepLock = new Object();
|
||||||
|
private CommandContext commandContext;
|
||||||
|
private Guild guild;
|
||||||
|
private String id = UUID.randomUUID().toString();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInsertable() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Guild getGuild() {
|
||||||
|
return guild;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void replyToInteraction(CommandContext context) {
|
||||||
|
synchronized (stepLock) {
|
||||||
|
this.commandContext = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context.isFromGuild()) {
|
||||||
|
guild = context.getGuild();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (guild == null && getStepType() == StepType.ROLE) {
|
||||||
|
throw new IllegalArgumentException("Step task is of type role but it was inserted in a non-guild context");
|
||||||
|
}
|
||||||
|
|
||||||
|
context.replyEphemeral("Please follow the instructions sent in DM.");
|
||||||
|
context.sendMessageInPrivate(getStepDescription() + "\n\n" + getStepQuestion(),
|
||||||
|
asyncContext -> assignId(asyncContext.getMessageId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Lifecycle execute(TaskContext context) {
|
||||||
|
synchronized (stepLock) {
|
||||||
|
if (!context.getDiscordUser().equals(commandContext.getDiscordUser())) {
|
||||||
|
return Lifecycle.KEEP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context instanceof MessageContext messageContext) {
|
||||||
|
Message message = messageContext.getMessage();
|
||||||
|
String input = message.getContentRaw();
|
||||||
|
|
||||||
|
|
||||||
|
Object answer = validateInput(context, input);
|
||||||
|
if (answer == null) {
|
||||||
|
return Lifecycle.KEEP;
|
||||||
|
}
|
||||||
|
|
||||||
|
StepResult result = executeStep(answer);
|
||||||
|
if (!result.isSuccess()) {
|
||||||
|
context.replyEphemeral(result.getMessage());
|
||||||
|
return Lifecycle.KEEP;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.getMessage() != null) {
|
||||||
|
context.replyEphemeral(result.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.getNextStep() != null) {
|
||||||
|
result.getNextStep().insert(commandContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Lifecycle.REMOVE_SELF;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalArgumentException("Step task is not of type MessageContext");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isExpired() {
|
||||||
|
// is it really needed to expire this type of task?
|
||||||
|
return getCreationTime().plusMinutes(60).isBefore(OffsetDateTime.now());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Button createButton() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the user input against the expected step type.
|
||||||
|
*
|
||||||
|
* @param context the task execution context
|
||||||
|
* @param input the user-provided input
|
||||||
|
* @return the parsed input if valid, or null if invalid
|
||||||
|
*/
|
||||||
|
private Object validateInput(TaskContext context, String input) {
|
||||||
|
switch (getStepType()) {
|
||||||
|
case ROLE -> {
|
||||||
|
try {
|
||||||
|
Role role = guild.getRoleById(input);
|
||||||
|
if (role == null) {
|
||||||
|
context.replyEphemeral("The role doesn't exist");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return role;
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
context.replyEphemeral("Not a valid role ID");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case EMOJI -> {
|
||||||
|
Optional<Emoji> parsed = EmojiManager.getEmoji(input);
|
||||||
|
|
||||||
|
if (parsed.isPresent()) {
|
||||||
|
return parsed.get().getEmoji();
|
||||||
|
}
|
||||||
|
|
||||||
|
context.replyEphemeral("Not a valid emoji");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
case STRING -> {
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
default -> throw new IllegalStateException("Unknown step type: " + getStepType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assignId(String newId) {
|
||||||
|
if (newId == null || newId.isBlank()) {
|
||||||
|
throw new IllegalArgumentException("Task ID cannot be null or empty.");
|
||||||
|
}
|
||||||
|
|
||||||
|
String oldId = id;
|
||||||
|
synchronized (this) {
|
||||||
|
this.id = newId;
|
||||||
|
TaskManager.getInstance().activateTask(this, oldId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,6 +13,7 @@ import me.bobert.netneutrality.utils.MessageFunction;
|
|||||||
import me.bobert.netneutrality.utils.MusicUtils;
|
import me.bobert.netneutrality.utils.MusicUtils;
|
||||||
import net.dv8tion.jda.api.components.buttons.ButtonStyle;
|
import net.dv8tion.jda.api.components.buttons.ButtonStyle;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.interactions.components.buttons.ButtonStyle;
|
||||||
|
|
||||||
public class LoadTrackFromPlaylistTask extends AcceptButton<LoadPlaylistTask> {
|
public class LoadTrackFromPlaylistTask extends AcceptButton<LoadPlaylistTask> {
|
||||||
private final AudioTrack track;
|
private final AudioTrack track;
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package me.bobert.netneutrality.thread;
|
||||||
|
/*
|
||||||
|
* Copyright (c) anthorob
|
||||||
|
*
|
||||||
|
* https://discord.gg/qUa6zNFZsd
|
||||||
|
*/
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
for (MusicManager manager : MusicManager.getManagers()) {
|
||||||
|
processManager(manager);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
logger.error("Interrupted while running MusicManagerCleanupThread", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processManager(MusicManager manager) throws InterruptedException {
|
||||||
|
TrackScheduler scheduler = manager.getScheduler();
|
||||||
|
|
||||||
|
// Context is still attached after bot is disconnected, the bot might have been kicked from the channel
|
||||||
|
if (scheduler.getContext() != null && !manager.isConnected()) {
|
||||||
|
manager.disconnect();
|
||||||
|
manager.getQueueManager().clearQueue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user