Skip to content
This repository has been archived by the owner on Jul 11, 2023. It is now read-only.

Commit

Permalink
Merge pull request #2 from Dominik48N/develop
Browse files Browse the repository at this point in the history
Version 1.0.0
  • Loading branch information
Dominik48N authored Sep 1, 2022
2 parents 2176c7e + 1e571c4 commit d7e3cb0
Show file tree
Hide file tree
Showing 9 changed files with 429 additions and 0 deletions.
26 changes: 26 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# top-most EditorConfig file
root = true

# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true

# Set encoding of files with specified ending.
[*.{java, json, yml, yaml, xml}]
charset = utf-8

# Set indentation for Java source files.
[*.java]
indent_style = space
indent_size = 4

# YAML doesn't like tabs
[*.{yml, yaml}]
indent_style = space
indent_size = 4

# Consistency.
[*{.xml, json}]
indent_style = space
indent_size = 2
10 changes: 10 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Handle line endings automatically for files detected as text
# and leave all files detected as binary untouched.
* text=auto eol=lf

# Force the following filetypes to have unix eols
*.java text eol=lf
*.xml text eol=lf
*.json text eol=lf
*.yaml text eol=lf
*.yml text eol=lf
30 changes: 30 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
target/
dependency-reduced-pom.xml

### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache

### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/

### VS Code ###
.vscode/
59 changes: 59 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.github.dominik48n</groupId>
<artifactId>jda-commands</artifactId>
<version>1.0.0</version>

<name>JDA-Commands</name>
<description>JDA Commands is an extension for JDA to make commands easier and clearer to develop.</description>
<url>https://github.com/Dominik48N/jda-commands</url>

<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>

<dependencies>
<dependency>
<groupId>net.dv8tion</groupId>
<artifactId>JDA</artifactId>
<version>5.0.0-alpha.18</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>23.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
<scope>compile</scope>
</dependency>
</dependencies>

<build>
<finalName>${project.name}-${project.version}</finalName>

<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
112 changes: 112 additions & 0 deletions src/main/java/com/github/dominik48n/jdacommands/Command.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package com.github.dominik48n.jdacommands;

import com.google.common.base.Preconditions;
import java.util.Arrays;
import java.util.stream.Collectors;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Role;
import net.dv8tion.jda.api.entities.channel.unions.GuildChannelUnion;
import net.dv8tion.jda.api.entities.channel.unions.GuildMessageChannelUnion;
import net.dv8tion.jda.api.entities.channel.unions.MessageChannelUnion;

public abstract class Command {

/**
* This is the command name.
*/
private final String name;

/**
* Which prefix should be in front of the command?
* Please make sure that if you use <code>/</code> as a prefix, the command is suggested from Discord.
*/
private final String prefix;

/**
* If you use the <code>/</code> prefix, you can use this to provide a description that will be displayed below the command.
*/
private final String description;

/**
* Use these command aliases.
*/
private final String[] aliases;

/**
* These roles have access to this command. If this array is empty, anyone can access it.
*/
private final Role[] access;

public Command(final String name, final String prefix) {
this(name, prefix, (String) null);
}

public Command(final String name, final String prefix, final String description) {
this(name, prefix, description, new String[]{});
}

public Command(final String name, final String prefix, final Role... access) {
this(name, prefix, null, access);
}

public Command(final String name, final String prefix, final String description, final String... aliases) {
this(name, prefix, description, aliases, new Role[]{});
}

public Command(final String name, final String prefix, final String description, final Role... access) {
this(name, prefix, description, new String[]{}, access);
}

public Command(final String name, final String prefix, final String description, final String[] aliases, final Role[] access) {
// Check null arguments
Preconditions.checkNotNull(name, "The name of a command cannot be null.");
Preconditions.checkNotNull(prefix, "The prefix of a command cannot be null.");
Preconditions.checkNotNull(aliases, "The aliases of a command cannot be null.");
Preconditions.checkNotNull(access, "The access roles of a command cannot be null.");

// Define arguments
this.name = name;
this.prefix = prefix;
this.description = description != null ? description : "-/-";
this.aliases = Arrays.stream(aliases).map(String::toLowerCase).toArray(String[]::new);
this.access = access;
}

public String getName() {
return this.name;
}

public String getPrefix() {
return this.prefix;
}

public String getDescription() {
return this.description;
}

public String[] getAliases() {
return this.aliases;
}

public Role[] getAccess() {
return this.access;
}

/**
* This abstract method is executed when the command is entered.
*
* @param guild the {@link Guild} the command was run on.
* @param member the command executor as {@link Member}
* @param channel the {@link MessageChannelUnion}
* @param guildChannel the {@link GuildChannelUnion}
* @param arguments These are the arguments that were additionally specified.
*/
public abstract void execute(
final Guild guild,
final Member member,
final MessageChannelUnion channel,
final GuildMessageChannelUnion guildChannel,
final String[] arguments
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.github.dominik48n.jdacommands;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import net.dv8tion.jda.api.JDA;

public class CommandRegistry {

private final Map<String, Command> commands = new HashMap<>();

private final JDA jda;

protected CommandRegistry(final JDA jda) {
this.jda = jda;
}

/**
* Register a new command
*
* @param command the {@link Command}
*/
public void registerCommand(final Command command) {
final String name = command.getName().toLowerCase();

this.commands.put(name, command);

for (final String alias : command.getAliases()) {
this.commands.put(alias, command);
}

if (command.getPrefix().startsWith("/")) {
this.jda.upsertCommand(name, command.getDescription()).queue();

for (final String alias : command.getAliases()) {
this.jda.upsertCommand(alias, command.getDescription()).queue();
}
}
}

/**
* Unregister a command
*
* @param name the name of the command
*/
public void unregisterCommand(String name) {
name = name.toLowerCase();

final Command command = this.commands.remove(name);

if (command == null) return; // Command is not exists.

for (final String alias : command.getAliases()) {
this.commands.remove(alias);
}
}

public Map<String, Command> getCommands() {
return Collections.unmodifiableMap(this.commands);
}
}
51 changes: 51 additions & 0 deletions src/main/java/com/github/dominik48n/jdacommands/JDACommands.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.github.dominik48n.jdacommands;

import com.github.dominik48n.jdacommands.listener.MessageReceivedListener;
import com.github.dominik48n.jdacommands.listener.SlashCommandInteractionListener;
import net.dv8tion.jda.api.JDA;

public class JDACommands {

private static JDACommands INSTANCE;

private final CommandRegistry commandRegistry;
private final JDA jda;

private JDACommands(final JDA jda) {
// Initialize variables
this.commandRegistry = new CommandRegistry(jda);
this.jda = jda;

// Register listeners
this.jda.addEventListener(new SlashCommandInteractionListener());
this.jda.addEventListener(new MessageReceivedListener());

// Define class instance
INSTANCE = this;
}

public CommandRegistry getCommandRegistry() {
return this.commandRegistry;
}

public JDA getJDA() {
return this.jda;
}

/**
* Initialize the jda commands.
* Please Note: If the JDA Commands have already been initialized, this will not work a second time.
*
* @param jda the bot {@link JDA}
* @return the initialized {@link JDACommands} class.
*/
public static JDACommands init(final JDA jda) {
if (INSTANCE != null) throw new IllegalStateException("JDACommands is already initialized.");
return new JDACommands(jda);
}

public static JDACommands getInstance() {
if (INSTANCE == null) throw new IllegalStateException("JDACommands is not initialized.");
return INSTANCE;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.github.dominik48n.jdacommands.listener;

import com.github.dominik48n.jdacommands.Command;
import com.github.dominik48n.jdacommands.JDACommands;
import java.util.Arrays;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;

public class MessageReceivedListener extends ListenerAdapter {

public void onMessageReceived(final MessageReceivedEvent event) {
final String message = event.getMessage().getContentStripped();
final Command command = JDACommands.getInstance().getCommandRegistry().getCommands().get(message);

if (command == null || command.getPrefix().startsWith("/"))
// The command is not exists or a slash command!
return;

// Check if member has access
final Member member = event.getMember();
if (member == null) return; // The member cannot be null
if (command.getAccess().length != 0
&& member.getRoles().stream().filter(role -> Arrays.stream(command.getAccess()).anyMatch(role1 -> role1 == role)).count() <= 0L
)
// Member has no access of to the command
return;

// Execute the command
final String[] splitMessage = message.split(" ");
command.execute(
event.getGuild(),
member,
event.getChannel(),
event.getGuildChannel(),
Arrays.copyOfRange(splitMessage, 1, splitMessage.length)
);
}
}
Loading

0 comments on commit d7e3cb0

Please sign in to comment.