Skip to content
Draft
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
281 changes: 220 additions & 61 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,103 +1,262 @@
# Bot Commons
A framework for creating bots for Discord using [JDA](https://github.com/DV8FromTheWorld/JDA)
# BotCommons

A powerful framework for creating Discord bots using [JDA (Java Discord API)](https://github.com/DV8FromTheWorld/JDA) that simplifies common bot development tasks.

![Version](https://img.shields.io/badge/version-1.11-blue)
![Java](https://img.shields.io/badge/java-21-orange)
![License](https://img.shields.io/badge/license-MIT-green)

## Table of Contents

- [Features](#features)
- [Installation](#installation)
- [Commands Framework](#commands-framework)
- [Config Framework](#config-framework)
- [Menu Framework](#menu-framework)
- [Cache Framework](#cache-framework)

## Features

BotCommons provides several key features to simplify Discord bot development:

- **Commands Framework**: Easy creation and management of slash commands with parameter validation
- **Config Framework**: Simple configuration management for global and per-guild settings
- **Menu Framework**: Interactive menu system for user interactions
- **Cache Framework**: Efficient caching of Discord entities like messages, guilds, channels and members

## Installation

### Maven

Add the following to your `pom.xml`:

```xml
<dependency>
<groupId>dev.scyye</groupId>
<artifactId>BotCommons</artifactId>
<version>1.11</version>
</dependency>
```

### Gradle

Add the following to your `build.gradle`:

```groovy
dependencies {
implementation 'dev.scyye:BotCommons:1.11'
}
```

# Features
## Commands Framework
To create a command, simply create a class that is annotated with `@MethodCommandHolder(string: Optional group)`;
Then create a function that is annotated with `@MethodCommand()`. (View the `@MethodCommand` class for more information on the parameters.)
Then, register the command using `MethodCommandManager.addCommands(CommandHolderClass.class)`.

**Below is an example of a command, along with how to use parameters:**
The Commands Framework simplifies the creation and management of slash commands.

### Creating Commands

1. Create a class annotated with `@CommandHolder`
2. Create methods annotated with `@Command`
3. Register the commands with the `CommandManager`

```java
import botcommons.commands.*;

// You can also specify a group for the commands in the holder
@CommandHolder
public class PingCommand {
@Command(name = "ping", help = "Pong!")
public void execute(GenericCommandEvent event,
@Param(
description = "A user",
type = Param.ParamType.USER
)
// the name of the argument is grabbed from the parameter name
User user) {
event.replySuccess("Pong! " + user.getAsMention()).finish(message -> {
// Success consumer
});
}
@Command(name = "ping", help = "Pong!")
public void execute(GenericCommandEvent event,
@Param(
description = "A user",
type = Param.ParamType.USER
)
// the name of the argument is grabbed from the parameter name
User user) {
event.replySuccess("Pong! " + user.getAsMention()).finish(message -> {
// Success consumer
});
}
}
```

### Setting Up CommandManager

```java
public class Main {
// ...
public static void main(String[] args) {
JDA jda = JDABuilder.createDefault("token")
.addEventListeners(new CommandManager())
.build();

CommandManager.addCommands(PingCommand.class);
}
// ...
public static void main(String[] args) {
JDA jda = JDABuilder.createDefault("token")
.addEventListeners(new CommandManager())
.build();

// Initialize the CommandManager
CommandManager.init(jda);

// Register commands
CommandManager.addCommands(PingCommand.class);
}
}
```

### Parameter Annotations

Use the `@Param` annotation to define command parameters:

```java
@Param(
description = "Description of the parameter",
required = true, // Default is true
type = Param.ParamType.USER, // Type of parameter (STRING, INTEGER, USER, etc.)
autocomplete = true // Enable autocomplete (requires implementing AutoCompleteHandler)
)
```

## Config Framework
There are 2 types of configs: `Config` and `GuildConfig`.

`Config` is a config that is shared across all servers.\
`GuildConfig` is a config that is specific to a server.
The Config Framework provides both global and per-guild configuration management.

### Global Config

### Config
To create a config, simply add this to your bot:
```java
public static void main(String[] args) {
// ...
Config.botName = "BotName"; // This will be used as the name of the config file
Config config = Config.makeConfig(new HashMap<>(){{
put("key", "value");
put("another key", new String[]{"Values can be anything", "Such as lists"});
put("a third key", new Player("PlayerName", 1000)); // Or even objects
// Set the bot name for the config file
Config.botName = "MyBot";

// Create a default config
Config config = Config.makeConfig(new HashMap<>() {{
put("prefix", "!");
put("admins", new String[]{"userId1", "userId2"});
put("defaultSettings", new HashMap<String, Object>() {{
put("welcomeMessage", true);
put("loggingEnabled", false);
}});
}});
// ...

// Access config values
String prefix = config.get("prefix", String.class);
boolean loggingEnabled = ((Map<String, Object>)config.get("defaultSettings")).get("loggingEnabled");
}
```

Then, to get a value, simply call `config#get(String key)`. I recommend storing the `Config` instance in a variable.
### Guild Config

### GuildConfig
To create a server config, add this listener to your JDA instance, however you wish to do that.:
```java
public static void main(String[] args) {
// ...
JDA jda = JDABuilder.createDefault("token")
.addEventListeners(new ConfigManager(new HashMap<>(){{
put("key", "value");
put("another key", new String[]{"Values can be anything", "Such as lists"});
put("a third key", new Player("PlayerName", 1000)); // Or even objects
}}))
.build();
// ...
JDA jda = JDABuilder.createDefault("token")
.addEventListeners(new ConfigManager(new HashMap<>() {{
put("prefix", "!");
put("welcomeMessage", true);
put("loggingEnabled", false);
}}))
.build();

// Later, get a guild's config
Config guildConfig = event.getConfig();
boolean welcomeMessage = guildConfig.get("welcomeMessage", Boolean.class);

// Update a value
ConfigManager.getInstance().setValue(guildId, "welcomeMessage", false);
}
```

### ***__NOTE:__ This will automatically create the `/sql` and `/config` commands***
**Note:** This will automatically create the `/sql` and `/config` commands.

## Menu Framework

# Disclaimer
EVERYTHING AFTER THIS POINT IS NOT ACCURATE. I WILL UPDATE IT SOON.
The Menu Framework allows you to create interactive menus with buttons and pagination.

### Setting Up MenuManager

## Menu Framework
### ***__NOTE:__ YOU MUST call `JDA.addEventListener(PaginationListener)` to enable the menu framework.***
```java
public static void main(String[] args) {
JDA jda = JDABuilder.createDefault("token")
.build();

// Create menu manager instance
MenuManager menuManager = new MenuManager(jda);
}
```

To create a menu, simply call `PaginatedMenuHandler#addMenu(PaginatedMenuHandler#buildMenu())`, and pass in the data for each page.
### Creating and Registering Menus

You can also reply to commands with a menu, by calling `CommandEvent#replyMenu(PaginatedMenuHandler#buildMenu())`.
```java
// Create a simple menu implementation
IMenu helpMenu = new IMenu() {
@Override
public String getMenuId() {
return "help_menu";
}

@Override
public MessageCreateAction generateMenu(Object... args) {
return new MessageCreateAction()
.setContent("Help Menu")
.addActionRow(
Button.primary("prev", "Previous"),
Button.primary("next", "Next")
);
}

@Override
public void handleButtonInteraction(ButtonInteractionEvent event) {
String buttonId = event.getComponentId();
if (buttonId.equals("prev")) {
// Handle previous button
} else if (buttonId.equals("next")) {
// Handle next button
}
}
};

// Register the menu
menuManager.registerMenu(helpMenu);

### ***__NOTE:__ YOU MUST call `JDA.addEventListener(PaginationListener)` to enable the menu framework.***
// Send the menu to a channel
menuManager.sendMenu("help_menu", channelId);

// Or reply to a command with a menu
event.replyMenu("help_menu").finish();
```

## Cache Framework
### TODO

The Cache Framework allows efficient caching of Discord entities for improved performance.

### Initializing Cache

```java
public static void main(String[] args) {
JDA jda = JDABuilder.createDefault("token")
.build();

// Initialize cache with various options
CacheManager.init(
jda,
true, // Cache guild members
true, // Cache mutual guilds
true, // Cache channel messages
true, // Cache user messages
true // Cache users
);
}
```

### Accessing Cached Data

```java
// Access cached members for a guild
List<CacheManager.MemberStructure> members = CacheManager.guildMemberCache.get(guildId);

// Access cached messages
List<CacheManager.MessageStructure> messages = CacheManager.channelMessageCache.get(channelId);

// Update the cache to JSON files
CacheManager.update();
```

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Minor style improvement suggestion.

Consider replacing "feel free to" with a more direct phrase for a more professional tone.

-Contributions are welcome! Please feel free to submit a Pull Request.
+Contributions are welcome! Please submit a Pull Request.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Contributions are welcome! Please feel free to submit a Pull Request.
Contributions are welcome! Please submit a Pull Request.
🧰 Tools
🪛 LanguageTool

[style] ~258-~258: Consider using a less common alternative to make your writing sound more unique and professional.
Context: ...ontributing Contributions are welcome! Please feel free to submit a Pull Request. ## License Thi...

(FEEL_FREE_TO_STYLE_ME)

🤖 Prompt for AI Agents
In README.md at line 258, replace the phrase "feel free to" with a more direct
and professional alternative such as "submit" or "welcome to submit" to improve
the tone of the contribution invitation.


## License

This project is licensed under the MIT License - see the LICENSE file for details.
Loading