Add command registration via event

This commit is contained in:
Vankka 2022-08-07 20:27:52 +03:00
parent 602c74ba6b
commit 9774eb5879
No known key found for this signature in database
GPG Key ID: 6E50CB7A29B96AD0
3 changed files with 88 additions and 5 deletions

View File

@ -476,6 +476,11 @@ public class Command implements JDAEntity<CommandData> {
*/
REGISTERED,
/**
* Command is already registered, and was ignored.
*/
ALREADY_REGISTERED,
/**
* There was already a command with the same name,
* therefor the command won't be registered unless other commands with the same name are unregistered.

View File

@ -0,0 +1,34 @@
package com.discordsrv.api.discord.events.interaction.command;
import com.discordsrv.api.discord.entity.interaction.command.Command;
import com.discordsrv.api.event.events.Event;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Unmodifiable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* An event for registering {@link com.discordsrv.api.discord.entity.interaction.command.Command}s,
* an alternative to {@link com.discordsrv.api.discord.DiscordAPI#registerCommand(Command)}.
*/
public class CommandRegisterEvent implements Event {
private final List<Command> commands = new ArrayList<>();
/**
* Add events to be registered.
* @param commands the commands to be registered, use of the same command instances is recommended
*/
public void registerCommands(@NotNull Command... commands) {
this.commands.addAll(Arrays.asList(commands));
}
@NotNull
@Unmodifiable
public List<Command> getCommands() {
return Collections.unmodifiableList(commands);
}
}

View File

@ -3,6 +3,7 @@ package com.discordsrv.common.discord.api;
import com.discordsrv.api.discord.entity.JDAEntity;
import com.discordsrv.api.discord.entity.interaction.command.Command;
import com.discordsrv.api.discord.entity.interaction.command.CommandType;
import com.discordsrv.api.discord.events.interaction.command.CommandRegisterEvent;
import com.discordsrv.common.DiscordSRV;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.entities.Guild;
@ -13,6 +14,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class DiscordCommandRegistry {
@ -26,13 +28,28 @@ public class DiscordCommandRegistry {
this.discordSRV = discordSRV;
}
public Command.RegistrationResult register(Command command) {
public void registerCommandsFromEvent() {
CommandRegisterEvent event = new CommandRegisterEvent();
discordSRV.eventBus().publish(event);
List<Command> commands = event.getCommands();
for (Map<CommandType, Registry> registryMap : registries.values()) {
registryMap.values().forEach(registry -> registry.removeIf(reg -> reg.isTemporary() && !commands.contains(reg.getCommand())));
}
commands.forEach(cmd -> register(cmd, true));
}
public Command.RegistrationResult register(Command command, boolean temporary) {
CommandType type = command.getType();
Registry registry = registries
.computeIfAbsent(command.getGuildId().orElse(GLOBAL_ID), key -> new EnumMap<>(CommandType.class))
.computeIfAbsent(type, key -> new Registry());
if (registry.contains(command)) {
return Command.RegistrationResult.ALREADY_REGISTERED;
}
boolean first = registry.register(command);
boolean first = registry.register(command, temporary);
if (!first) {
return Command.RegistrationResult.NAME_ALREADY_IN_USE;
}
@ -124,10 +141,31 @@ public class DiscordCommandRegistry {
private final Map<String, List<Registration>> registry = new ConcurrentHashMap<>();
private final Map<String, Command> activeCommands = new HashMap<>();
public boolean register(@NotNull Command command) {
public void removeIf(Predicate<Registration> commandPredicate) {
List<String> removeKeys = new ArrayList<>();
for (Map.Entry<String, List<Registration>> entry : registry.entrySet()) {
List<Registration> registrations = entry.getValue();
registrations.removeIf(commandPredicate);
if (registrations.isEmpty()) {
removeKeys.add(entry.getKey());
}
}
removeKeys.forEach(registry::remove);
}
public boolean contains(@NotNull Command command) {
List<Registration> commands = registry.get(command.getName());
if (commands == null) {
return false;
}
return commands.stream().anyMatch(reg -> reg.getCommand() == command);
}
public boolean register(@NotNull Command command, boolean temporary) {
List<Registration> commands = registry.computeIfAbsent(command.getName(), key -> new CopyOnWriteArrayList<>());
boolean empty = commands.isEmpty();
commands.add(new Registration(command));
commands.add(new Registration(command, temporary));
return empty;
}
@ -175,10 +213,12 @@ public class DiscordCommandRegistry {
private final Command command;
private final long time;
private final boolean temporary;
public Registration(Command command) {
public Registration(Command command, boolean temporary) {
this.command = command;
this.time = System.currentTimeMillis();
this.temporary = temporary;
}
public Command getCommand() {
@ -188,5 +228,9 @@ public class DiscordCommandRegistry {
public long getTime() {
return time;
}
public boolean isTemporary() {
return temporary;
}
}
}