Skip to content

Commit

Permalink
Merge pull request #12 from S3nS3IW00/dev
Browse files Browse the repository at this point in the history
Update to 4.1.0
  • Loading branch information
S3nS3IW00 authored Jan 7, 2022
2 parents e3dd0df + d21ff5a commit 03aa841
Show file tree
Hide file tree
Showing 59 changed files with 1,355 additions and 1,289 deletions.
136 changes: 22 additions & 114 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,137 +1,45 @@
# JCommands [![](https://img.shields.io/badge/Version-4.0.2-blue)](https://github.com/S3nS3IW00/JCommands) [![](https://img.shields.io/badge/Javadoc-Latest-green)](https://s3ns3iw00.github.io/JCommands/javadoc/)
# JCommands [![](https://img.shields.io/badge/Version-4.1.0-blue)](https://github.com/S3nS3IW00/JCommands) [![](https://img.shields.io/badge/Javadoc-Latest-green)](https://s3ns3iw00.github.io/JCommands/javadoc/)

With this Javacord extension you can create Slash commands within 1 minute with built-in validating, converting and
extended permission checking for channels and categories. There are so many useful pre-written argument types that can
be used while creating a command.
With this Javacord extension you can create Slash commands within 1 minute with built-in validating, converting,
concatenating and extended permission checking for channels and categories. There are so many useful pre-written
argument types that can be used while creating a command.

## Code example
### Example command

The following examples might help you. Don't hesitate to use them!
This command is created just with about 50 lines of code including the response and error handling. It has a validated
argument with regex, an argument that has two different values that the user can choose from, a number argument that has
a range validation, a normal user mention argument, a normal channel mention argument and an optional URL argument that
is a text input with regex validation. In the response the first argument is separated with regex groups into two
different value, and the response based on every argument's value.

### Registering the error listener

Error listener allows you to create custom functions for every error type.

```java
CommandHandler.setOnError((type, responder) -> {
String errorMessage = null;
switch (type) {
// Occurs when one or more of the arguments are missing or not matching the pattern.
case BAD_ARGUMENTS:
errorMessage = "Something went wrong! :face_with_raised_eyebrow:";
break;
// Occurs when the sender wants to use the command in a category where it is not allowed.
case BAD_CATEGORY:
// Occurs when the sender wants to use the command in a channel where it is not allowed.
case BAD_CHANNEL:
errorMessage = "I'm not sure about that this is the best place to use this command. :face_with_raised_eyebrow:";
break;
}
responder.respondNow()
.setContent(errorMessage)
.respond();
});
```

### Creating a command
It has never been so easy to create a command like the following example shows.

```java
// Create a command with a name and a description
ServerCommand introduceCommand = new ServerCommand("iam", "This command is for to introduce yourself.");
// We want to make this command available in only one category
introduceCommand.addCategoryLimitation(CategoryLimitation.with(myServer, true, api.getChannelCategoryById(787365901552451595L).get()));
// But we have two channels in that category where the command should not to work
introduceCommand.addChannelLimitation(ChannelLimitation.with(myServer, false, api.getTextChannelById(787366035207618573L).get()));
introduceCommand.addChannelLimitation(ChannelLimitation.with(myServer, false, api.getTextChannelById(787366059643502644L).get()));
// This command is only for users who have this role
introduceCommand.addRoleLimitation(RoleLimitation.with(myServer, true, api.getRoleById(787366309561368606L).get()));
// Let's create our command's first argument.
ValueArgument nameArgument = new ValueArgument("fullname", "Your first and last name separated with comma (Firstname,Lastname)", SlashCommandOptionType.STRING);
// This argument only accepts two word separated with comma and each word started with capitalized letter.
nameArgument.validate("(?<first>[A-Z][a-z]+),(?<last>[A-Z][a-z]+)");
// We want to know the user's gender so make an argument that has two acceptable values.
ComboArgument genderArgument = new ComboArgument("gender", "Your gender", SlashCommandOptionType.INTEGER);
genderArgument.addChoice("male", 0);
genderArgument.addChoice("female", 1);
// How old is the user? The user can give numbers from 0 to 99.
NumberArgument ageArgument = new NumberArgument("age", "Your age (number between 0 and 99)");
ageArgument.setRange(0, 99);
// Let's ask the user to mention his or her best friend,
MentionArgument bestFriendArgument = new MentionArgument("bestfriend", "Your best friend on Discord");
// to mention his or her favourite channel on this server
ChannelArgument favouriteChannelArgument = new ChannelArgument("favouritechannel", "Your favourite channel on this server");
// and to send us a funny picture's url, that is just an optional argument
URLArgument funnyPictureArgument = new URLArgument("funnypicture", "A funny picture's url");
funnyPictureArgument.setOptional();
// Add arguments to the command
introduceCommand.addArgument(nameArgument, genderArgument, ageArgument, bestFriendArgument, favouriteChannelArgument, funnyPictureArgument);
// Let's make an action listener where we can listen for inputs.
// user is the sender, args is an array of the converted arguments and responder is a class that manages responses
introduceCommand.setAction((sender, args, responder) -> {
// ValueArgument return as a Matcher by default
Matcher fullName = args[0].get();
String firstName = fullName.group("first");
String lastName = fullName.group("last");
![Example](https://imgur.com/swqZYXH.png)

// The gender contains integer values based on the key
int gender = args[1].get();
> You can find a full code [here](https://github.com/S3nS3IW00/JCommands/blob/master/src/test/java/me/s3ns3iw00/jcommands/TestMain.java) that runs a bot with the example command above.
// The age from a NumberArgument so it's a number by default
// It has been validated so range checking is unnecessary
int age = args[2].get();
## Wiki

User bestFriend = args[3].get();
Channel favouriteChannel = args[4].get();
You can find all the information about how to use `JCommands` on the [Wiki](https://github.com/S3nS3IW00/JCommands/wiki)
page.

// URL arguments are also getting converted into the corresponding type
// This is an optional argument, so we need to check that this have been specified
URL funnyPictureUrl = args.length < 6 ? null : args[5].get();
## Dependencies

// Something that uses all the arguments
MessageBuilder responseMessage = new MessageBuilder();
responseMessage.append("Hi " + firstName + " " + lastName + "! You are very " + (gender == 0 ? "handsome" : "beautiful") + " :heart: As I can see you are " + (age >= 10 && age < 20 ? "" : "not ") + "a teenager.");
if (bestFriend.isBot()) {
responseMessage.append(" What? Did you know that your best friend is a BOT?");
}
if (favouriteChannel.getId() == 791658134153330718L) {
responseMessage.append(" That's my favourite channel too!");
}
if (funnyPictureUrl != null) {
responseMessage.append(" Here is your funny picture: " + funnyPictureUrl.toString());
}
As you can see in the description, this is a Javacord extension. Javacord is a framework and it so much easier to create
bots with it.

// Send the response message to the user
responder.respondNow()
.setContent(responseMessage.getStringBuilder().toString())
.respond();
});
// And don't forget to register the command on the server(s). (I always forget it and never know what's wrong :D)
CommandHandler.registerCommand(introduceCommand, myServer);
```
- [Javacord](https://github.com/Javacord/Javacord)

![Example](https://imgur.com/swqZYXH.png)

> You can find a full code [here](https://github.com/S3nS3IW00/JCommands/blob/master/src/test/java/me/s3ns3iw00/jcommands/TestMain.java) what runs a bot with the example codes above.
## Usage

## Wiki
You can find more information about how to use `JCommands` on the [Wiki](https://github.com/S3nS3IW00/JCommands/wiki) page.

## Dependencies
As you can see in the description, this is a Javacord extension. Javacord is a framework and it so much easier to create bots with it.
- [Javacord](https://github.com/Javacord/Javacord)

## Usage
1. Download
- [Latest release](https://github.com/S3nS3IW00/JCommands/releases/latest)
- [![](https://jitpack.io/v/S3nS3IW00/JCommands.svg)](https://jitpack.io/#S3nS3IW00/JCommands)
- Clone repository
```
git clone https://github.com/S3nS3IW00/JCommands.git
```
2. Initiate the listener
2. Initiate the listener
```java
CommandHandler.setApi(DiscordApi);
```
3. Create an error listener and as many commands as you want.
3. Create an error listener and as many command as you want.
4. Enjoy!
19 changes: 1 addition & 18 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,7 @@ plugins {
}

group 'me.s3ns3iw00'
version '4.0.2'

sourceCompatibility = 1.8
targetCompatibility = 1.8

defaultTasks 'build'

tasks.withType(JavaCompile) {
options.encoding 'UTF-8'
}

sourceSets {
main {
resources {
srcDirs "src/main/resources"
}
}
}
version '4.1.0'

repositories {
mavenCentral()
Expand Down
73 changes: 62 additions & 11 deletions src/main/java/me/s3ns3iw00/jcommands/Command.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 S3nS3IW00
* Copyright (C) 2022 S3nS3IW00
*
* This file is part of JCommands.
*
Expand All @@ -20,11 +20,12 @@

import me.s3ns3iw00.jcommands.argument.Argument;
import me.s3ns3iw00.jcommands.argument.InputArgument;
import me.s3ns3iw00.jcommands.argument.concatenation.Concatenator;
import me.s3ns3iw00.jcommands.event.listener.ArgumentMismatchEventListener;
import me.s3ns3iw00.jcommands.event.listener.CommandActionEventListener;
import me.s3ns3iw00.jcommands.listener.CommandActionListener;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.Optional;
import java.util.*;

/**
* A class that represents a command
Expand All @@ -38,7 +39,10 @@ public class Command {
*/
private final String name, description;
private final LinkedList<Argument> arguments = new LinkedList<>();
private Optional<CommandActionListener> action = Optional.empty();
private final Map<Concatenator, LinkedList<Argument>> concatenators = new LinkedHashMap<>();

private CommandActionEventListener actionListener;
private ArgumentMismatchEventListener argumentMismatchListener;

/**
* Default constructor
Expand Down Expand Up @@ -71,8 +75,11 @@ public Command(String name, String description) {
* @param argument the argument
*/
public void addArgument(Argument argument) {
if (arguments.size() > 0 && (arguments.getLast() instanceof InputArgument) && ((InputArgument) arguments.getLast()).isOptional()) {
throw new IllegalStateException("Cannot add argument after an optional argument!");
if (arguments.size() > 0 &&
(arguments.getLast() instanceof InputArgument) &&
((InputArgument) arguments.getLast()).isOptional() &&
!((InputArgument) argument).isOptional()) {
throw new IllegalStateException("Cannot add non-optional argument after an optional argument!");
}

this.arguments.add(argument);
Expand All @@ -87,13 +94,38 @@ public void addArgument(Argument... arguments) {
Arrays.stream(arguments).forEach(this::addArgument);
}

/**
* Adds a concatenator to the command
* Every argument in the list must belong to this command, otherwise the concatenation won't proceed
*
* @param concatenator the concatenator
* @param arguments the list of arguments
*/
public void addConcatenator(Concatenator concatenator, Argument... arguments) {
if (!concatenators.containsKey(concatenator)) {
concatenators.put(concatenator, new LinkedList<>());
}
concatenators.get(concatenator).addAll(Arrays.asList(arguments));
}

/**
* Sets the action listener of the command
*
* @param action is the listener object
* @deprecated because of the new event system
* use {@link Command#setOnAction(CommandActionEventListener)} instead
*/
@Deprecated
public void setAction(CommandActionListener action) {
this.action = Optional.of(action);
}

/**
* Sets the action listener
*
* @param listener the listener
*/
public void setOnAction(CommandActionEventListener listener) {
this.actionListener = listener;
}

/**
Expand All @@ -113,15 +145,34 @@ public String getDescription() {
/**
* @return the list of the arguments
*/
public LinkedList<Argument> getArguments() {
public List<Argument> getArguments() {
return arguments;
}

/**
* @return the map of concatenators
*/
public Map<Concatenator, LinkedList<Argument>> getConcatenators() {
return concatenators;
}

/**
* @return the command action instance
* @deprecated because of the new event system
*/
@Deprecated
Optional<CommandActionEventListener> getAction() {
return Optional.empty();
}

/**
* Gets the action listener
*
* @return {@link Optional#empty()} when action listener is not specified,
* otherwise {@link Optional#of(Object)} with the listener
*/
Optional<CommandActionListener> getAction() {
return action;
public Optional<CommandActionEventListener> getActionListener() {
return Optional.ofNullable(actionListener);
}

}
2 changes: 2 additions & 0 deletions src/main/java/me/s3ns3iw00/jcommands/CommandErrorType.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@
* Enum with error type constants
*
* @author S3nS3IW00
* @deprecated see {@link me.s3ns3iw00.jcommands.listener.CommandErrorListener} for more information
*/
@Deprecated
public enum CommandErrorType {

/**
Expand Down
Loading

0 comments on commit 03aa841

Please sign in to comment.