All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.alex1304.ultimategdbot.api.command.CommandProvider Maven / Gradle / Ivy

There is a newer version: 6.0.2
Show newest version
package com.github.alex1304.ultimategdbot.api.command;

import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;

import com.github.alex1304.ultimategdbot.api.Bot;
import com.github.alex1304.ultimategdbot.api.utils.InputTokenizer;

import discord4j.core.event.domain.message.MessageCreateEvent;
import discord4j.core.object.entity.MessageChannel;
import discord4j.core.object.util.Snowflake;

/**
 * Provides a set of commands. Each command handler provides their own way to
 * handle errors via a {@link CommandErrorHandler}.
 */
public class CommandProvider {
	
	private CommandErrorHandler errorHandler = new CommandErrorHandler();
	private final Map commandMap = new HashMap<>();
	
	/**
	 * Allows to supply a custom command handler. If this method is not called, it will use a default handler.
	 * 
	 * @param errorHandler the error handler to set
	 */
	public void setErrorHandler(CommandErrorHandler errorHandler) {
		this.errorHandler = Objects.requireNonNull(errorHandler);
	}
	
	/**
	 * Adds a command to this provider.
	 * 
	 * @param command the command to add
	 */
	public void add(Command command) {
		for (var alias : command.getAliases()) {
			commandMap.put(alias, command);
		}
	}
	
	/**
	 * Provides a command based on a MessageCreateEvent. The event must come with a
	 * message body containing a prefix and the alias of one of the commands
	 * provided by this provider. If it matches with a provided command, arguments
	 * and flags are parsed, and everything is wrapped in an
	 * {@link ExecutableCommand} which is returned. If the event does not match with
	 * any command, an empty {@link Optional} is returned.
	 * 
	 * @param bot     the bot instance
	 * @param prefix  the guild-specific bot prefix
	 * @param event   the MessageCreateEvent to process
	 * @param channel the channel where the event happened
	 * 
	 * @return an ExecutableCommand if the event results in a command to be
	 *         triggered, an empty Optional otherwise.
	 */
	public Optional provideFromEvent(Bot bot, String prefix, MessageCreateEvent event, MessageChannel channel) {
		return bot.getMainDiscordClient().getSelfId().map(Snowflake::asLong).flatMap(botId -> {
			var prefixes = Set.of("<@" + botId + ">", "<@!" + botId + ">", prefix);
			var content = event.getMessage().getContent().orElse("");
			String prefixUsed = null;
			for (var p : prefixes) {
				if (content.toLowerCase().startsWith(p.toLowerCase())) {
					content = content.substring(p.length());
					prefixUsed = p;
					break;
				}
			}
			if (prefixUsed == null) {
				return Optional.empty();
			}
			var parsed = InputTokenizer.tokenize(content);
			var flags = parsed.getT1();
			var args = parsed.getT2();
			if (args.isEmpty()) {
				return Optional.empty();
			}
			final var fPrefixUsed = prefixUsed;
			var command = commandMap.get(args.get(0));
			return Optional.ofNullable(command)
					.map(cmd -> new ExecutableCommand(cmd, new Context(cmd, event, args, flags, bot, fPrefixUsed, channel), errorHandler));
		});
	}
	
	/**
	 * Gets the error handler assigned to this provider.
	 * 
	 * @return the error handler
	 */
	public CommandErrorHandler getErrorHandler() {
		return errorHandler;
	}
	
	/**
	 * Gets a command instance corresponding to the given alias.
	 *  
	 * @param alias the alias of the command
	 * @return the corresponding command instance, or null if not found
	 */
	public Command getCommandByAlias(String alias) {
		return commandMap.get(alias.toLowerCase());
	}
	
	/**
	 * Gets all provided commands.
	 * 
	 * @return an unmodifiable Set containing all commands provided by this provider
	 */
	public Set getProvidedCommands() {
		return Collections.unmodifiableSet(new HashSet<>(commandMap.values()));
	}
	
	@Override
	public String toString() {
		return "CommandProvider{commandMap=" + commandMap + ", errorHandler=" + errorHandler + "}";
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy