Skip to content
This repository was archived by the owner on Oct 21, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public class AccessLevel {
* @param requiredPermissions The permissions required if in a guild.
* @param onlyGuild Flag that indicate that this can only occur in a guild.
* @param onlyPrivate Flag that indicate that this can only occur in a private channel.
* @param user Flag that indicate that only this user can use this, <bold>overwrite every other flag</bold>.
* @param user Flag that indicate that only this user can use this, /!\ overwrite every other flag /!\.
*/
public AccessLevel(@Nonnull EnumSet<Permission> requiredPermissions, boolean onlyGuild, boolean onlyPrivate, long user) {
this.requiredPermissions = requiredPermissions;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,13 +135,13 @@ private void registerCommandPatterns() {

} else if (params[1].isAssignableFrom(Options.class)) {
// CommandEvent, Options
patterns.add(new CommandPattern((event, args, options) -> invokeMethod(method, options)));
patterns.add(new CommandPattern((event, args, options) -> invokeMethod(method, event, options)));

} else {
// CommandEvent, Arg1
patterns.add(new CommandPattern(
translateArguments(method, 1),
(event, args, options) -> invokeMethod(method, args.get(0))
(event, args, options) -> invokeMethod(method, event, args.get(0))
));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,31 @@

public class CommandEvent extends MessageReceivedEvent {

private Command command;
private final CommandModule module;
private final Command command;

public CommandEvent(@Nonnull MessageReceivedEvent baseEvent, Command command) {
this(baseEvent.getJDA(), baseEvent.getResponseNumber(), baseEvent.getMessage(), command);
public CommandEvent(@Nonnull final MessageReceivedEvent baseEvent, @Nonnull final CommandModule module,
@Nonnull final Command command) {
this(baseEvent.getJDA(), baseEvent.getResponseNumber(), baseEvent.getMessage(), module, command);
}

public CommandEvent(JDA api, long responseNumber, Message message, Command command) {
public CommandEvent(@Nonnull final JDA api, final long responseNumber, @Nonnull final Message message,
@Nonnull final CommandModule module, @Nonnull final Command command) {
super(api, responseNumber, message);
this.module = module;
this.command = command;
}

public void fastReply(@Nonnull final String message) {
channel.sendMessage(message).complete();
}

@Nonnull
public CommandModule getModule() {
return module;
}

@Nonnull
public Command getCommand() {
return command;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import com.jesus_crie.modularbot.ModularBotBuilder;
import com.jesus_crie.modularbot.module.BaseModule;
import com.jesus_crie.modularbot_command.listener.CommandListener;
import com.jesus_crie.modularbot_command.listener.DiscordCommandListener;
import com.jesus_crie.modularbot_command.listener.NopCommandListener;
import com.jesus_crie.modularbot_command.processing.CommandProcessor;

import javax.annotation.Nonnull;
Expand All @@ -24,13 +26,15 @@ public class CommandModule extends BaseModule {
// Command processor
private CommandProcessor processor = new CommandProcessor();

private CommandListener listener = new NopCommandListener();

public CommandModule() {
super(INFO);
}

@Override
public void onLoad(@Nonnull ModularBotBuilder builder) {
builder.addListeners(new CommandListener(this));
builder.addListeners(new DiscordCommandListener(this));
}

public void registerCommands(@Nonnull Command... commands) {
Expand Down Expand Up @@ -61,4 +65,13 @@ public Command getCommand(@Nonnull String name) {
.findAny()
.orElse(null);
}

public void setListener(@Nonnull final CommandListener listener) {
this.listener = listener;
}

@Nonnull
public CommandListener getListener() {
return listener;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* Use on a method inside a class that extends {@link Command Command} to associate
* a pattern with it.
* The method should be protected or higher and should take 3 arguments in that order:
* {@link CommandEvent CommandEvent}, {@link java.util.List List<Object>}, {@link Options Options}.
* {@link CommandEvent CommandEvent}, {@link java.util.List List}, {@link Options Options}.
* The return type doesn't matter.
*/
@Target(ElementType.METHOD)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,62 +1,90 @@
package com.jesus_crie.modularbot_command.listener;

import com.jesus_crie.modularbot_command.Command;
import com.jesus_crie.modularbot_command.CommandEvent;
import com.jesus_crie.modularbot_command.CommandModule;
import com.jesus_crie.modularbot_command.exception.CommandProcessingException;
import com.jesus_crie.modularbot_command.exception.UnknownOptionException;
import com.jesus_crie.modularbot_command.processing.Options;
import net.dv8tion.jda.core.events.message.MessageReceivedEvent;
import net.dv8tion.jda.core.hooks.ListenerAdapter;
import net.dv8tion.jda.core.entities.Message;
import net.dv8tion.jda.core.utils.tuple.Pair;

import javax.annotation.Nonnull;
import java.util.List;
import java.util.Map;

public class CommandListener extends ListenerAdapter {
public interface CommandListener {

private final CommandModule module;
/**
* Triggered every time a command is typed (= any message that starts with the prefix
*/
void onCommandReceived();

public CommandListener(CommandModule module) {
this.module = module;
}
/**
* Triggered when a command was typed and it was a real command.
* But nothing has been executed yet and no checks have been performed.
*
* @param command The actual event.
*/
void onCommandFound(@Nonnull final CommandEvent command);

@Override
public void onMessageReceived(MessageReceivedEvent event) {
if (event.getAuthor().getIdLong() == event.getJDA().getSelfUser().getIdLong())
return;
/**
* Triggered when a message starts with the prefix but it was a false alert, the command doesn't exist.
* An error 404 in a manner.
*
* @param name The name of the command that was typed.
* @param message The message containing the wrong command.
*/
void onCommandNotFound(@Nonnull final String name, @Nonnull final Message message);

final String prefix = module.getPrefixForGuild(event.getGuild().getIdLong());
if (!event.getMessage().getContentRaw().startsWith(prefix))
return;
/**
* Triggered when a command is found but the user doesn't satisfy the {@link com.jesus_crie.modularbot_command.AccessLevel AccessLevel}
* associated with this command.
*
* @param event The event that was fired.
*/
void onTooLowAccessLevel(@Nonnull final CommandEvent event);

final String[] parts = event.getMessage().getContentRaw().split(" ", 2);
final String name = parts[0].substring(prefix.length());
final Command command = module.getCommand(name);
/**
* Triggered when a command is found, the user have the correct privileges and what he just typed has been
* successfully parsed.
*
* @param event The event that was fired.
* @param processedContent The output of the command processor.
* @see com.jesus_crie.modularbot_command.processing.CommandProcessor
* @see com.jesus_crie.modularbot_command.processing.CommandProcessor#process(String)
*/
void onCommandSuccessfullyProcessed(@Nonnull final CommandEvent event, @Nonnull final Pair<List<String>, Map<String, String>> processedContent);

if (command == null) {
// TODO 10/06/2018 notify not found
return;
}
/**
* Triggered when the processing of the command has failed, usually a syntax error.
*
* @param event The event that was fired.
* @param error The error from the command processor.
* @see com.jesus_crie.modularbot_command.processing.CommandProcessor
*/
void onCommandFailedProcessing(@Nonnull final CommandEvent event, @Nonnull final CommandProcessingException error);

final CommandEvent cmdEvent = new CommandEvent(event, command);
/**
* Triggered when the command was successfully processed but one of the option is not registered in the command.
*
* @param event The event that was fired.
* @param error The error from the {@link com.jesus_crie.modularbot_command.processing.Options}.
* @see com.jesus_crie.modularbot_command.processing.Options
*/
void onCommandFailedUnknownOption(@Nonnull final CommandEvent event, @Nonnull final UnknownOptionException error);

if (!command.getAccessLevel().check(cmdEvent)) {
// TODO 10/06/2018 notify too low access
return;
}
/**
* Triggered when the command failed to execute because the provided arguments doesn't match any registered pattern.
*
* @param event The actual event.
* @param options The provided options.
* @param arguments The provided arguments.
*/
void onCommandFailedNoPatternMatch(@Nonnull final CommandEvent event, @Nonnull final Options options, @Nonnull final List<String> arguments);

try {
final Pair<List<String>, Map<String, String>> processedContent = module.getCommandProcessor().process(event.getMessage().getContentRaw());

// TODO 13/06/2018 notify command processed successfully

final Options options = new Options(module, command, processedContent.getRight());
if (!command.execute(module, cmdEvent, options, processedContent.getLeft())) {
// TODO 13/06/2018 notify not pattern found
}

} catch (CommandProcessingException e) {
// TODO 11/06/2018 notify error processing command
}
}
/**
* Triggered when the command is successfully executed.
*
* @param event The event that triggered the command in the first place.
*/
void onCommandSuccess(@Nonnull final CommandEvent event);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package com.jesus_crie.modularbot_command.listener;

import com.jesus_crie.modularbot_command.Command;
import com.jesus_crie.modularbot_command.CommandEvent;
import com.jesus_crie.modularbot_command.CommandModule;
import com.jesus_crie.modularbot_command.exception.CommandProcessingException;
import com.jesus_crie.modularbot_command.exception.UnknownOptionException;
import com.jesus_crie.modularbot_command.processing.Options;
import net.dv8tion.jda.core.events.message.MessageReceivedEvent;
import net.dv8tion.jda.core.hooks.ListenerAdapter;
import net.dv8tion.jda.core.utils.tuple.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.Map;

public class DiscordCommandListener extends ListenerAdapter {

private static final Logger LOG = LoggerFactory.getLogger("DiscordCommandListener");

private final CommandModule module;

public DiscordCommandListener(CommandModule module) {
this.module = module;
}

@Override
public void onMessageReceived(MessageReceivedEvent event) {
if (event.getAuthor().getIdLong() == event.getJDA().getSelfUser().getIdLong())
return;

final String prefix = module.getPrefixForGuild(event.getGuild().getIdLong());
if (!event.getMessage().getContentRaw().startsWith(prefix))
return;

final String[] parts = event.getMessage().getContentRaw().split(" ", 2);
final String name = parts[0].substring(prefix.length());
final Command command = module.getCommand(name);

if (command == null) {
module.getListener().onCommandNotFound(name, event.getMessage());
return;
}

final CommandEvent cmdEvent = new CommandEvent(event, module, command);

if (!command.getAccessLevel().check(cmdEvent)) {
module.getListener().onTooLowAccessLevel(cmdEvent);
return;
}

try {
final String fullArgs;
if (parts.length == 2) fullArgs = parts[1];
else fullArgs = "";

final Pair<List<String>, Map<String, String>> processedContent = module.getCommandProcessor().process(fullArgs);

module.getListener().onCommandSuccessfullyProcessed(cmdEvent, processedContent);

final Options options = new Options(module, command, processedContent.getRight());
if (!command.execute(module, cmdEvent, options, processedContent.getLeft()))
module.getListener().onCommandFailedNoPatternMatch(cmdEvent, options, processedContent.getLeft());

} catch (CommandProcessingException e) {
module.getListener().onCommandFailedProcessing(cmdEvent, e);
} catch (UnknownOptionException e) {
module.getListener().onCommandFailedUnknownOption(cmdEvent, e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.jesus_crie.modularbot_command.listener;

import com.jesus_crie.modularbot_command.CommandEvent;
import com.jesus_crie.modularbot_command.exception.CommandProcessingException;
import com.jesus_crie.modularbot_command.exception.UnknownOptionException;
import com.jesus_crie.modularbot_command.processing.Options;
import javafx.util.Pair;
import net.dv8tion.jda.core.entities.Message;

import javax.annotation.Nonnull;
import java.util.List;
import java.util.Map;

public class NopCommandListener implements CommandListener {

@Override
public void onCommandReceived() {
/* no-op */
}

@Override
public void onCommandFound(@Nonnull CommandEvent command) {
/* no-op */
}

@Override
public void onCommandNotFound(@Nonnull String name, @Nonnull Message message) {
/* no-op */
}

@Override
public void onTooLowAccessLevel(@Nonnull CommandEvent event) {
/* no-op */
}

@Override
public void onCommandSuccessfullyProcessed(@Nonnull CommandEvent event, @Nonnull Pair<List<String>, Map<String, String>> processedContent) {
/* no-op */
}

@Override
public void onCommandFailedProcessing(@Nonnull CommandEvent event, @Nonnull CommandProcessingException error) {
/* no-op */
}

@Override
public void onCommandFailedUnknownOption(@Nonnull CommandEvent event, @Nonnull UnknownOptionException error) {
/* no-op */
}

@Override
public void onCommandFailedNoPatternMatch(@Nonnull CommandEvent event, @Nonnull Options options, @Nonnull List<String> arguments) {
/* no-op */
}

@Override
public void onCommandSuccess(@Nonnull CommandEvent event) {
/* no-op */
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,9 @@ private Argument getLastArgument() {
public boolean hasArguments() {
return !arguments.isEmpty();
}

@Override
public String toString() {
return "CommandPattern{ " + arguments + " }";
}
}
Loading