Skip to content

Commit

Permalink
Merge pull request #8 from ShindouMihou/1.0.0-beta
Browse files Browse the repository at this point in the history
Forwarding into Beta [1.0.0-BETA]
  • Loading branch information
ShindouMihou authored Sep 28, 2023
2 parents 800687e + 9f69cf5 commit 86ebbd0
Show file tree
Hide file tree
Showing 151 changed files with 4,967 additions and 4,178 deletions.
6 changes: 2 additions & 4 deletions .github/workflows/maven.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ jobs:
with:
java-version: '17'
distribution: 'adopt'
cache: maven
- name: Build with Maven
run: mvn -B package --file pom.xml
cache: gradle
- name: Test with Maven
run: mvn test
run: ./gradlew test
261 changes: 53 additions & 208 deletions README.md

Large diffs are not rendered by default.

32 changes: 32 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
plugins {
id 'org.jetbrains.kotlin.jvm' version '1.9.10'
id 'java'
}

group = 'pw.mihou'
version = '1.0.0-beta'
description = 'Nexus is the next-generation Javacord framework that aims to create Discord bots with less code, dynamic, more simplicity and beauty.'

repositories {
mavenCentral()
}

dependencies {
implementation 'org.javacord:javacord:3.8.0'
implementation 'org.slf4j:slf4j-api:2.0.3'
testImplementation 'org.jetbrains.kotlin:kotlin-test'
compileOnly 'com.google.code.findbugs:jsr305:3.0.2'
}

test {
useJUnitPlatform()
}

kotlin {
jvmToolchain {
languageVersion.set(JavaLanguageVersion.of(17))
}
compilerOptions {
freeCompilerArgs.add('-Xjvm-default=all')
}
}
23 changes: 0 additions & 23 deletions examples/authentication/permissions/PingCommand.java

This file was deleted.

22 changes: 0 additions & 22 deletions examples/authentication/roles/PingCommand.java

This file was deleted.

22 changes: 0 additions & 22 deletions examples/authentication/user/PingCommand.java

This file was deleted.

2 changes: 1 addition & 1 deletion examples/interceptors/AnonymousInterceptors.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class AnonymousInterceptors implements NexusHandler {
private final String description = "An example of how a command can share custom fields to a middleware, etc.";

private final List<String> middlewares = List.of(
NexusCommandInterceptor.middleware((event) -> event.stopIf(event.getServer().isEmpty()))
Nexus.getInterceptors().middleware((event) -> event.stopIf(event.getServer().isEmpty()))
);

@Override
Expand Down
2 changes: 1 addition & 1 deletion examples/interceptors/InlineNamedMiddlewares.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public class InlineNamedMiddlewares implements NexusHandler {
private final String description = "An example of how a command can share custom fields to a middleware, etc.";

private final List<String> middlewares = List.of(
NexusCommandInterceptor.addMiddleware("nexus.auth.server", (event) -> event.stopIf(event.getServer().isEmpty()))
Nexus.getInterceptors().middleware("nexus.auth.server", (event) -> event.stopIf(event.getServer().isEmpty()))
);

@Override
Expand Down
13 changes: 13 additions & 0 deletions examples/option_validators/OptionValidators.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package pw.mihou.nexus.features.command.validation.examples

import pw.mihou.nexus.features.command.validation.OptionValidation
import pw.mihou.nexus.features.command.validation.errors.ValidationError

object OptionValidators {
val PING_PONG_VALIDATOR = OptionValidation.create<String>(
validator = { option -> option.equals("ping", ignoreCase = true) || option.equals("pong", ignoreCase = true) },
error = { ValidationError.create("❌ You must either use `ping` or `pong` as an answer!") },
// If you want to support optional values then you must add the line below.
// requirements = OptionValidation.createRequirements { nonNull = null }
)
}
23 changes: 23 additions & 0 deletions examples/option_validators/PingCommand.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package pw.mihou.nexus.features.command.validation.examples

import org.javacord.api.interaction.SlashCommandOption
import pw.mihou.nexus.features.command.facade.NexusCommand
import pw.mihou.nexus.features.command.facade.NexusCommandEvent
import pw.mihou.nexus.features.command.facade.NexusHandler

object PingCommand: NexusHandler {
val name = "ping"
val description = "Does a ping-pong based on your answer."

val options = NexusCommand.createOptions(
SlashCommandOption.createStringOption("answer", "It must be either ping or pong!", true)
)

val validators = NexusCommand.createValidators(
OptionValidators.PING_PONG_VALIDATOR.withCollector { event -> event.interaction.getArgumentStringValueByName("answer") }
)

override fun onEvent(event: NexusCommandEvent) {
event.respondNowWith("Just kidding! Your answer didn't matter in the first place!")
}
}
27 changes: 27 additions & 0 deletions examples/router/PingCommand.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package pw.mihou.nexus.features.command.router.example

import org.javacord.api.interaction.SlashCommandOption
import org.javacord.api.interaction.SlashCommandOptionType
import pw.mihou.nexus.features.command.facade.NexusCommandEvent
import pw.mihou.nexus.features.command.facade.NexusHandler
import pw.mihou.nexus.features.command.router.SubcommandRouter

object PingCommand: NexusHandler {
private val name = "ping"
private val description = "Pings and pongs!"

private val options = listOf(
SlashCommandOption.create(SlashCommandOptionType.SUB_COMMAND, "pong", "Performs a pong!"),
SlashCommandOption.create(SlashCommandOptionType.SUB_COMMAND, "ping", "Performs a ping!")
)

private val router = SubcommandRouter.create {
route("ping", PingSubcommand)
route("pong", PongSubcommand)
}

override fun onEvent(event: NexusCommandEvent) = router.accept(event) {
// Optionally you can add additional shared data such as this:
event.store("message", "Ping pong! You can add stuff like this here!")
}
}
12 changes: 12 additions & 0 deletions examples/router/PingSubcommand.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package pw.mihou.nexus.features.command.router.example

import org.javacord.api.interaction.SlashCommandInteractionOption
import pw.mihou.nexus.features.command.facade.NexusCommandEvent
import pw.mihou.nexus.features.command.router.types.Routeable

object PingSubcommand: Routeable {
override fun accept(event: NexusCommandEvent, option: SlashCommandInteractionOption) {
val message = event["message", String::class.java]
event.respondNowWith("Pong! $message")
}
}
12 changes: 12 additions & 0 deletions examples/router/PongSubcommand.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package pw.mihou.nexus.features.command.router.example

import org.javacord.api.interaction.SlashCommandInteractionOption
import pw.mihou.nexus.features.command.facade.NexusCommandEvent
import pw.mihou.nexus.features.command.router.types.Routeable

object PongSubcommand: Routeable {
override fun accept(event: NexusCommandEvent, option: SlashCommandInteractionOption) {
val message = event["message", String::class.java]
event.respondNowWith("Ping! $message")
}
}
2 changes: 1 addition & 1 deletion examples/shared_fields/PingCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ public class PingCommand implements NexusHandler {

@Override
public void onEvent(NexusCommandEvent event) {
event.respondNow().setContent("Pong!").respond();
event.respondNowWith("Pong!");
}
}
67 changes: 35 additions & 32 deletions examples/synchronization/Main.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package pw.mihou.nexus;

import org.javacord.api.DiscordApiBuilder;
import org.javacord.api.util.logging.ExceptionLogger;
import pw.mihou.nexus.Nexus;
import pw.mihou.nexus.core.threadpool.NexusThreadPool;
import pw.mihou.nexus.features.command.facade.NexusCommand;

Expand All @@ -10,17 +9,14 @@

public class Test {

private static final Nexus nexus = Nexus.builder().build();

public static void main(String[] args) {
nexus.listenMany(new AGlobalCommand(), new ASpecificServerCommand());
NexusCommand dynamic = nexus.createCommandFrom(new ADynamicCommand());

Nexus.commands(new AGlobalCommand(), new ASpecificServerCommand());
NexusCommand dynamic = Nexus.getCommandManager().get("dynamic", null);
new DiscordApiBuilder()
.setToken(System.getenv("token"))
.setAllIntents()
.setTotalShards(4)
.addListener(nexus)
.addListener(Nexus.INSTANCE)
.loginAllShards()
.forEach(future -> future.thenAccept(discordApi -> {
System.out.println("Shard " + discordApi.getCurrentShard() + " is now online.");
Expand All @@ -32,45 +28,47 @@ public static void main(String[] args) {
// and also allows Nexus to function more completely.
// IMPORTANT IMPORTANT IMPORTANT IMPORTANT
// ------------------
nexus.getShardManager().put(discordApi);

Nexus.getShardingManager().set(discordApi);
}).exceptionally(ExceptionLogger.get()));

//---------------------
// Global synchronization of all commands, recommended at startup.
// This updates, creates or removes any commands that are missing, outdated or removed.
//----------------------
nexus.getSynchronizer()
.synchronize(4)
.thenAccept(unused -> System.out.println("Synchronization with Discord's and Nexus' command repository is now complete."))
.exceptionally(ExceptionLogger.get());
Nexus.getSynchronizer()
.synchronize()
.addFinalCompletionListener(unused -> System.out.println("Successsfully migrated all commands to Discord."))
.addTaskErrorListener(exception -> {
System.out.println("An error occurred while trying to migrate commands to Discord: ");
exception.printStackTrace();
});

//------------------
// Demonstration of dynamic server command updating.
//-----------------

NexusThreadPool.schedule(() -> {
dynamic.addSupportFor(853911163355922434L, 858685857511112736L);
dynamic.associate(853911163355922434L, 858685857511112736L);
System.out.println("Attempting to perform dynamic updates...");

// We recommend using batch update if you performed more than 1 `addSupportFor` methods.
// As batch update will update all of those command using only one request.
// batchUpdate(853911163355922434L, 4);
// batchUpdate(858685857511112736L, 4);
// batchUpdate(853911163355922434L);
// batchUpdate(858685857511112736L);

// Single update, on the otherwise, allows multiple server ids but sends a single create or update
// request for a command and doesn't scale well when done with many commands.
singleUpdate(dynamic, 4, 853911163355922434L, 858685857511112736L);
}, 1, TimeUnit.MINUTES);

NexusThreadPool.schedule(() -> {
dynamic.removeSupportFor(853911163355922434L);
dynamic.disassociate(853911163355922434L);
System.out.println("Attempting to perform dynamic updates...");

// The same information as earlier, batch update will update the entire server slash command list
// which means it will remove any slash commands that are no longer supporting that server
// and will update or create any slash commands that still support that server.
// batchUpdate(853911163355922434L, 4);
// batchUpdate(853911163355922434L);

// Single delete is fine when you are only deleting one command on a pile of servers.
singleDelete(dynamic, 4, 853911163355922434L);
Expand All @@ -80,49 +78,54 @@ public static void main(String[] args) {
/**
* Updates, removes or creates any commands that are outdated, removed or missing. This is recommended
* especially when you recently added support to a lot of servers. Not recommended on startup since
* {@link pw.mihou.nexus.features.command.synchronizer.NexusSynchronizer#synchronize(int)} is more recommended for
* {@link pw.mihou.nexus.features.command.synchronizer.NexusSynchronizer#synchronize()} is more recommended for
* startup-related synchronization.
*
* @param serverId The server id to synchronize commands to.
* @param totalShards The total shards of the server.
*/
private static void batchUpdate(long serverId, int totalShards) {
nexus.getSynchronizer()
.batchUpdate(serverId, totalShards)
private static void batchUpdate(long serverId) {
Nexus.getSynchronizer()
.batchUpdate(serverId)
.thenAccept(unused -> System.out.println("A batch update was complete. [server="+serverId+"]"))
.exceptionally(ExceptionLogger.get());
}

/**
* Updates a single command on one or many servers. This is practically the same as batch update but utilizes a more
* update or create approach whilst {@link Test#batchUpdate(long, int)} overrides the entire server slash command list
* update or create approach whilst {@link Test#batchUpdate(long)} overrides the entire server slash command list
* with what Nexus knows.
*
* @param command The command to update on the specified servers.
* @param totalShards The total amount of shards of the bot, this is used for sharding formula.
* @param serverIds The server ids to update the bot on.
*/
private static void singleUpdate(NexusCommand command, int totalShards, long... serverIds) {
nexus.getSynchronizer()
Nexus.getSynchronizer()
.upsert(command, totalShards, serverIds)
.thenAccept(unused -> System.out.println("A batch upsert was complete. [servers="+ Arrays.toString(serverIds) +"]"))
.exceptionally(ExceptionLogger.get());
.addFinalCompletionListener(unused -> System.out.println("A batch upsert was complete. [servers="+ Arrays.toString(serverIds) +"]"))
.addTaskErrorListener(exception -> {
System.out.println("An error occurred while trying to update commands: ");
exception.printStackTrace();
});
}

/**
* Deletes a single command on one or many servers. This is practically the same as batch update but utilizes a more
* delete approach whilst {@link Test#batchUpdate(long, int)} overrides the entire server slash command list
* delete approach whilst {@link Test#batchUpdate(long)} overrides the entire server slash command list
* with what Nexus knows.
*
* @param command The command to update on the specified servers.
* @param totalShards The total amount of shards of the bot, this is used for sharding formula.
* @param serverIds The server ids to update the bot on.
*/
private static void singleDelete(NexusCommand command, int totalShards, long... serverIds) {
nexus.getSynchronizer()
Nexus.getSynchronizer()
.delete(command, totalShards, serverIds)
.thenAccept(unused -> System.out.println("A batch delete was complete. [servers="+ Arrays.toString(serverIds) +"]"))
.exceptionally(ExceptionLogger.get());
.addFinalCompletionListener(unused -> System.out.println("A batch delete was complete. [servers="+ Arrays.toString(serverIds) +"]"))
.addTaskErrorListener(exception -> {
System.out.println("An error occurred while trying to delete commands: ");
exception.printStackTrace();
});
}

}
Loading

0 comments on commit 86ebbd0

Please sign in to comment.