Compare commits

...

126 Commits

Author SHA1 Message Date
Sheldan
7f12ac7107 [AB-xxx] adding command to automatically ban all honeypot users
refactored honeypot listener into a service
fixing transfer credits not requiring the inputs
2026-03-29 11:02:47 +02:00
Sheldan
81b1688d97 [AB-xxx] adding unit test and improvement for runtime experience storage 2026-03-05 21:11:36 +01:00
Sheldan
3500ec4123 [AB-xxx] small code improvements 2026-03-05 20:44:02 +01:00
release-bot
4495b12e84 Commit from GitHub Actions (Publishes a new version of abstracto) 2026-02-15 22:09:42 +00:00
release-bot
1f1cb0ed34 [maven-release-plugin] prepare for next development iteration 2026-02-15 21:55:44 +00:00
release-bot
a778518475 [maven-release-plugin] prepare release v1.6.20 2026-02-15 21:55:42 +00:00
Sheldan
fa62353aee [AB-xxx] adding support to use @time inputs for duration and instant command parameters 2026-02-15 22:44:57 +01:00
Sheldan
2f125d0101 [AB-xxx] do not delete embedding message if the message embedding fails
fixing code for top level container config (not sure how that worked before)
2026-01-25 00:02:30 +01:00
Sheldan
4dc92fe49b [AB-xxx] adding metrics for http requests 2026-01-08 00:07:16 +01:00
release-bot
5e908f6837 Commit from GitHub Actions (Publishes a new version of abstracto) 2025-12-30 12:41:23 +00:00
release-bot
95a2813c34 [maven-release-plugin] prepare for next development iteration 2025-12-30 12:27:20 +00:00
release-bot
d844e09f4d [maven-release-plugin] prepare release v1.6.19 2025-12-30 12:27:18 +00:00
Sheldan
8251074aab [AB-xxx] adding command to view system configuration per server
adding auto complete to setConfig command key parameter
2025-12-28 23:46:36 +01:00
Sheldan
4180a07243 [AB-xxx] upgrading to JDA 6.2.0
changing how assignable role places change their buttons
2025-12-28 19:17:58 +01:00
release-bot
cf9e5f67f6 Commit from GitHub Actions (Publishes a new version of abstracto) 2025-12-17 23:12:02 +00:00
release-bot
ae53784da2 [maven-release-plugin] prepare for next development iteration 2025-12-17 22:59:30 +00:00
release-bot
342f0b6043 [maven-release-plugin] prepare release v1.6.18 2025-12-17 22:59:28 +00:00
Sheldan
274dd77eeb [AB-xxx] adding ability to add additional channels to a post target
adding auto complete to post target command
2025-12-17 23:54:54 +01:00
release-bot
0f6adacd90 Commit from GitHub Actions (Publishes a new version of abstracto) 2025-11-29 13:17:32 +00:00
release-bot
2dd5841397 [maven-release-plugin] prepare for next development iteration 2025-11-29 13:06:06 +00:00
release-bot
a2f49a0de9 [maven-release-plugin] prepare release v1.6.17 2025-11-29 13:06:05 +00:00
Sheldan
c791c063e3 [AB-xxx] changing the structure of starboard post model 2025-11-22 15:28:00 +01:00
release-bot
d293d764db Commit from GitHub Actions (Publishes a new version of abstracto) 2025-11-12 22:53:03 +00:00
release-bot
a7cd674cdd [maven-release-plugin] prepare for next development iteration 2025-11-12 22:39:42 +00:00
release-bot
0abefe64e9 [maven-release-plugin] prepare release v1.6.16 2025-11-12 22:39:40 +00:00
Sheldan
d1267605c1 [AB-xxx] adding roles to the model of leave logger 2025-11-12 23:33:50 +01:00
release-bot
b4ffea341c Commit from GitHub Actions (Publishes a new version of abstracto) 2025-10-12 18:28:32 +00:00
release-bot
507c755809 [maven-release-plugin] prepare for next development iteration 2025-10-12 18:15:34 +00:00
release-bot
9e0e92a530 [maven-release-plugin] prepare release v1.6.15 2025-10-12 18:15:32 +00:00
Sheldan
d078b3fa87 [AB-xxx] adding feature to suggest slash commands for message commands, if the command is slash command only 2025-10-12 20:10:14 +02:00
release-bot
71b7dd2383 Commit from GitHub Actions (Publishes a new version of abstracto) 2025-09-10 23:10:18 +00:00
release-bot
ea0384490e [maven-release-plugin] prepare for next development iteration 2025-09-10 22:56:04 +00:00
release-bot
b5dbc0b1ed [maven-release-plugin] prepare release v1.6.14 2025-09-10 22:56:02 +00:00
Sheldan
e265eb6760 [AB-xxx] adding user agent for all outgoing okhttp requests 2025-09-11 00:52:49 +02:00
release-bot
2f18b7431d Commit from GitHub Actions (Publishes a new version of abstracto) 2025-09-10 22:05:18 +00:00
release-bot
2d8827fa81 [maven-release-plugin] prepare for next development iteration 2025-09-10 21:53:38 +00:00
release-bot
dddeb15127 [maven-release-plugin] prepare release v1.6.13 2025-09-10 21:53:37 +00:00
Sheldan
78fbe0723b [AB-xxx] actively restricting length of slash command parameters if a validator is configured for the parameter (more easy solution than a separate one) 2025-09-10 23:46:39 +02:00
release-bot
e1d4a41d60 Commit from GitHub Actions (Publishes a new version of abstracto) 2025-08-04 18:59:22 +00:00
release-bot
354a82f806 [maven-release-plugin] prepare for next development iteration 2025-08-04 18:43:45 +00:00
release-bot
ff3e3d85ba [maven-release-plugin] prepare release v1.6.12 2025-08-04 18:43:43 +00:00
Sheldan
46bf4fbc42 [AB-xxx] changing the method used to edit the giveaway message 2025-08-02 00:06:43 +02:00
Sheldan
97ac25dbb6 [AB-xxx] adding auto complete for feature names/feature mode names 2025-08-01 23:52:15 +02:00
Sheldan
ef4bdb2ab2 [AB-xxx] enabling commands which take users to only require one parameter instead of a string and a member option 2025-07-29 23:04:33 +02:00
release-bot
433fdb7068 Commit from GitHub Actions (Publishes a new version of abstracto) 2025-07-20 09:04:03 +00:00
release-bot
e59b6269e1 [maven-release-plugin] prepare for next development iteration 2025-07-20 08:49:59 +00:00
release-bot
8077501584 [maven-release-plugin] prepare release v1.6.11 2025-07-20 08:49:57 +00:00
Sheldan
cb9ab8f542 [AB-xxx] adding ability to define unique ids for components, a color of the container, disabled state for multiple components and spoiler for container
fixing reminder message not containing a link to the message anymore
2025-07-19 23:56:06 +02:00
release-bot
f513f8890b Commit from GitHub Actions (Publishes a new version of abstracto) 2025-07-13 20:08:48 +00:00
release-bot
6f02834b75 [maven-release-plugin] prepare for next development iteration 2025-07-13 19:56:17 +00:00
release-bot
75456b45c9 [maven-release-plugin] prepare release v1.6.10 2025-07-13 19:56:15 +00:00
Sheldan
92e581305e [AB-xxx] changing logic to replace embedded messages with the link instead of removing the reaction/button for deletion 2025-07-13 21:52:37 +02:00
release-bot
bd8b57e977 Commit from GitHub Actions (Publishes a new version of abstracto) 2025-07-13 18:05:19 +00:00
release-bot
e5fc411dc2 [maven-release-plugin] prepare for next development iteration 2025-07-13 17:52:51 +00:00
release-bot
9d9fdef42e [maven-release-plugin] prepare release v1.6.9 2025-07-13 17:52:49 +00:00
Sheldan
4a3d43b1b0 [AB-xxx] adding initial support for components v2
fixing issue with buttons which only provide an emoji
adding logging in case updating a starboard post goes wrong
2025-07-13 19:45:59 +02:00
release-bot
15d41c58ef Commit from GitHub Actions (Publishes a new version of abstracto) 2025-05-29 20:16:51 +00:00
release-bot
ad863af5d6 [maven-release-plugin] prepare for next development iteration 2025-05-29 20:05:41 +00:00
release-bot
f3dae2f6a3 [maven-release-plugin] prepare release v1.6.8 2025-05-29 20:05:40 +00:00
Sheldan
9f9c0612eb [AB-xxx] fixing youtube sometimes not returning videos even if specified 2025-05-29 22:00:45 +02:00
Sheldan
db73071a71 [AB-xxx] updating JDA version 2025-04-26 13:11:36 +02:00
Sheldan
d7125fbf25 [AB-xxx] adding input to response model for 8ball and choose command 2025-04-26 13:09:34 +02:00
release-bot
fd3bf41406 Commit from GitHub Actions (Publishes a new version of abstracto) 2025-04-01 11:47:09 +00:00
release-bot
d1abe194ec [maven-release-plugin] prepare for next development iteration 2025-04-01 11:37:04 +00:00
release-bot
79477923c6 [maven-release-plugin] prepare release v1.6.7 2025-04-01 11:37:03 +00:00
Sheldan
be9ffa3045 [AB-xxx] updating postgres driver version 2025-04-01 13:34:34 +02:00
release-bot
e29ceb9243 [maven-release-plugin] prepare for next development iteration 2025-03-31 21:49:19 +00:00
release-bot
70acf46cfd [maven-release-plugin] prepare release v1.6.6 2025-03-31 21:49:17 +00:00
Sheldan
022603ae3b [AB-xxx] updating JDA version in readme 2025-03-31 23:46:56 +02:00
release-bot
264082d63d [maven-release-plugin] prepare for next development iteration 2025-03-31 21:32:13 +00:00
release-bot
3e9d53feee [maven-release-plugin] prepare release v1.6.5 2025-03-31 21:32:11 +00:00
Sheldan
6c9cb39ad6 [AB-xxx] merging user and guild reminders for handling in reminders and unremind command
fixing issue with creating reminder in DMs
2025-03-31 23:29:33 +02:00
Sheldan
899afa82c4 [AB-xxx] updating JDA to receive DM command fix 2025-03-31 22:15:00 +02:00
Sheldan
2a357cf09f [AB-xxx] adding clearing existing roles or newly added roles if a member receives the honey pot role 2025-02-27 19:20:00 +01:00
release-bot
1aeb3b56cb Commit from GitHub Actions (Publishes a new version of abstracto) 2025-02-23 20:28:39 +00:00
release-bot
05c3f1ac01 [maven-release-plugin] prepare for next development iteration 2025-02-23 20:17:35 +00:00
release-bot
1379cae707 [maven-release-plugin] prepare release v1.6.4 2025-02-23 20:17:33 +00:00
Sheldan
ec78a0d856 [AB-xxx] reworking moderation commands to use more defer logic, so that they do not time out anymore
removed message command condition, as it seemed unused
2025-02-23 21:13:27 +01:00
Sheldan
33ad3bdc5d [AB-xxx] fixing triggered not working with message replies used 2025-02-20 19:24:59 +01:00
Sheldan
99c4c3e59c [AB-xxx] changing custom command auto complete to be a contains with ignored case
adding auto complete to delete custom commands
2025-02-16 22:53:18 +01:00
Sheldan
8544c0c2b1 [AB-xxx] migrating assignable role commands to slash commands
removing separate command for editing assignable role place text, and adding it to the change command
fixing 2 bugs related with deleting assignable roles with users, and deleting assignable role places
refactoring how enums are handled with slash command parameters
adding cleanup for slash command confirmation payloads once they are clicked
2025-02-16 22:30:27 +01:00
Sheldan
a8c2dfe15a [AB-xxx] removing all message command implementations of lesser used message commands 2025-02-16 00:46:56 +01:00
release-bot
29fd453117 Commit from GitHub Actions (Publishes a new version of abstracto) 2025-02-15 14:45:20 +00:00
release-bot
cfea95f83e [maven-release-plugin] prepare for next development iteration 2025-02-15 14:36:44 +00:00
release-bot
8cb04e2396 [maven-release-plugin] prepare release v1.6.3 2025-02-15 14:36:43 +00:00
Sheldan
f99c5351e6 [AB-xxx] adding default permissions for commands
adding owner limitation for certain internal commands
2025-02-15 15:33:56 +01:00
release-bot
210140b242 [maven-release-plugin] prepare for next development iteration 2025-02-04 22:27:15 +00:00
release-bot
8fded5480d [maven-release-plugin] prepare release v1.6.2 2025-02-04 22:27:13 +00:00
Sheldan
b74a238090 [AB-xxx] update year 2025-02-04 23:25:00 +01:00
release-bot
149a85cde6 Commit from GitHub Actions (Publishes a new version of abstracto) 2025-02-04 22:20:54 +00:00
release-bot
6455d24711 [maven-release-plugin] prepare for next development iteration 2025-02-04 22:04:57 +00:00
release-bot
b862ed95f2 [maven-release-plugin] prepare release v1.6.1 2025-02-04 22:04:55 +00:00
Sheldan
5ba2f2a2f8 [AB-xxx] adding support to have a different template for user command descriptions
enabling user command for currency conversion command
2025-02-04 23:01:50 +01:00
release-bot
ce234f986e [maven-release-plugin] prepare for next development iteration 2025-02-03 22:28:23 +00:00
release-bot
6472c70229 [maven-release-plugin] prepare release v1.6.0 2025-02-03 22:28:22 +00:00
Sheldan
cdb6003976 [AB-xxx] preparing for release of minor version 2025-02-03 23:25:51 +01:00
release-bot
54cf1a8299 Commit from GitHub Actions (Publishes a new version of abstracto) 2025-02-03 22:17:10 +00:00
release-bot
1d6bb7af08 [maven-release-plugin] prepare for next development iteration 2025-02-03 22:08:05 +00:00
release-bot
629cafc902 [maven-release-plugin] prepare release v1.5.61 2025-02-03 22:08:04 +00:00
Sheldan
58632bcf9d [AB-xxx] preparing for minor release 2025-02-03 23:05:44 +01:00
Sheldan
592ac01bfa [AB-xxx] changes for newer JDA version 2025-02-03 23:01:52 +01:00
Sheldan
732535850b [AB-xxx] adding support for user installable apps to varying commands 2025-02-03 22:54:15 +01:00
release-bot
cd3378df32 Commit from GitHub Actions (Publishes a new version of abstracto) 2025-01-31 18:16:43 +00:00
release-bot
87d8338d51 [maven-release-plugin] prepare for next development iteration 2025-01-31 18:07:34 +00:00
release-bot
a371993c87 [maven-release-plugin] prepare release v1.5.60 2025-01-31 18:07:33 +00:00
Sheldan
77b97507b3 [AB-xxx] adding paginators to emote stats
adding handling for emotes which are only provided as ID to command inputs
removing message commands from emote statistic related commands
2025-01-31 19:03:38 +01:00
Sheldan
e952727849 [AB-xxx] fixing incorrect join for deleted emote stats 2025-01-27 23:19:26 +01:00
release-bot
909a08d3d2 Commit from GitHub Actions (Publishes a new version of abstracto) 2025-01-27 20:23:59 +00:00
release-bot
e02236145f [maven-release-plugin] prepare for next development iteration 2025-01-27 20:13:35 +00:00
release-bot
1d810bdc07 [maven-release-plugin] prepare release v1.5.59 2025-01-27 20:13:33 +00:00
Sheldan
f9334d5210 [AB-xxx] always showing all emotes in emote stats output 2025-01-27 21:09:46 +01:00
release-bot
0a7e30cace Commit from GitHub Actions (Publishes a new version of abstracto) 2025-01-27 00:44:12 +00:00
release-bot
d91091d149 [maven-release-plugin] prepare for next development iteration 2025-01-27 00:35:25 +00:00
release-bot
2690b1a5d9 [maven-release-plugin] prepare release v1.5.58 2025-01-27 00:35:24 +00:00
Sheldan
ed42940e29 [AB-xxx] adding ability to track emotes used in reactions
adding ability to have confirmations for slash commands
2025-01-27 01:31:56 +01:00
release-bot
2c3b16879e Commit from GitHub Actions (Publishes a new version of abstracto) 2025-01-15 21:25:59 +00:00
release-bot
bd7fc6aa65 [maven-release-plugin] prepare for next development iteration 2025-01-15 21:16:39 +00:00
release-bot
6dfcebb25b [maven-release-plugin] prepare release v1.5.57 2025-01-15 21:16:38 +00:00
Sheldan
0eaccb4b0f [AB-xxx] adding currency conversion command 2025-01-15 22:13:47 +01:00
Sheldan
4ae6a154c7 [AB-xxx] fixing not being able to delete a giveaway key for which there is no giveaway 2024-12-29 21:10:27 +01:00
release-bot
3ad8369ab3 Commit from GitHub Actions (Publishes a new version of abstracto) 2024-12-25 22:41:02 +00:00
release-bot
6be1b7df04 [maven-release-plugin] prepare for next development iteration 2024-12-25 22:30:39 +00:00
release-bot
df8eb399f7 [maven-release-plugin] prepare release v1.5.56 2024-12-25 22:30:37 +00:00
Sheldan
3b7157714d [AB-xxx] fixing issue of server id not being provided when manually creating a giveaway 2024-12-25 23:27:27 +01:00
release-bot
ef7e5b4a46 Commit from GitHub Actions (Publishes a new version of abstracto) 2024-12-25 19:09:24 +00:00
release-bot
c28286bf3f [maven-release-plugin] prepare for next development iteration 2024-12-25 19:00:30 +00:00
551 changed files with 8517 additions and 4814 deletions

2
.env
View File

@@ -1,2 +1,2 @@
REGISTRY_PREFIX=harbor.sheldan.dev/abstracto/ REGISTRY_PREFIX=harbor.sheldan.dev/abstracto/
VERSION=1.5.54 VERSION=1.6.20

View File

@@ -30,7 +30,7 @@ jobs:
with: with:
title: Release of version ${{ env.version }} title: Release of version ${{ env.version }}
- name: Release maven packages - name: Release maven packages
uses: qcastel/github-actions-maven-release@v1.12.41 uses: qcastel/github-actions-maven-release@v1.12.43
env: env:
JAVA_HOME: /usr/lib/jvm/java-17-openjdk/ JAVA_HOME: /usr/lib/jvm/java-17-openjdk/
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2024 Sheldan Copyright (c) 2025 Sheldan
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@@ -11,7 +11,7 @@ This repository does not provide the full functionality in order to start a disc
## Technologies ## Technologies
* [JDA](https://github.com/DV8FromTheWorld/JDA/) The Discord API Wrapper in the version 5.0.0-beta.21 * [JDA](https://github.com/DV8FromTheWorld/JDA/) The Discord API Wrapper in the version 5.4.0
* [Spring boot](https://github.com/spring-projects/spring-boot) is used as a framework to create standalone application in Java with Java EE methods. (including dependency injection and more) * [Spring boot](https://github.com/spring-projects/spring-boot) is used as a framework to create standalone application in Java with Java EE methods. (including dependency injection and more)
* [Hibernate](https://github.com/hibernate/hibernate-orm) is used as a reference implementation of JPA. * [Hibernate](https://github.com/hibernate/hibernate-orm) is used as a reference implementation of JPA.
* [Freemarker](https://github.com/apache/freemarker) is used as a templating engine. This is used to provide internationalization for user facing text and enable dynamic embed configuration. * [Freemarker](https://github.com/apache/freemarker) is used as a templating engine. This is used to provide internationalization for user facing text and enable dynamic embed configuration.
@@ -30,4 +30,4 @@ If you want to view the documentation to an earlier released version you need to
If you find any issue, feel free to create a GitHub issue. If you find any issue, feel free to create a GitHub issue.
## License ## License
This project is licensed under the MIT license. This project is licensed under the MIT license.

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<artifactId>anti-raid</artifactId> <artifactId>anti-raid</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId> <groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55</version> <version>1.6.21-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -108,6 +108,6 @@ public class MassPingServiceBean implements MassPingService {
.memberDisplay(MemberDisplay.fromMember(member)) .memberDisplay(MemberDisplay.fromMember(member))
.build(); .build();
MessageToSend messageToSend = templateService.renderEmbedTemplate(MASS_PING_MUTE_NOTIFICATION_TEMPLATE_KEY, model, member.getGuild().getIdLong()); MessageToSend messageToSend = templateService.renderEmbedTemplate(MASS_PING_MUTE_NOTIFICATION_TEMPLATE_KEY, model, member.getGuild().getIdLong());
return FutureUtils.toSingleFutureGeneric(postTargetService.sendEmbedInPostTarget(messageToSend, AntiRaidPostTarget.MASS_PING_LOG, member.getGuild().getIdLong())); return FutureUtils.toSingleFutureGenericList(postTargetService.sendEmbedInPostTarget(messageToSend, AntiRaidPostTarget.MASS_PING_LOG, member.getGuild().getIdLong()));
} }
} }

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<artifactId>anti-raid</artifactId> <artifactId>anti-raid</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId> <groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55</version> <version>1.6.21-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<artifactId>abstracto-modules</artifactId> <artifactId>abstracto-modules</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId> <groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55</version> <version>1.6.21-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<groupId>dev.sheldan.abstracto.modules</groupId> <groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>assignable-roles</artifactId> <artifactId>assignable-roles</artifactId>
<version>1.5.55</version> <version>1.6.21-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -1,16 +1,26 @@
package dev.sheldan.abstracto.assignableroles.command; package dev.sheldan.abstracto.assignableroles.command;
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition; import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
import dev.sheldan.abstracto.assignableroles.config.AssignableRolePlaceSlashCommandName;
import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService; import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService;
import dev.sheldan.abstracto.assignableroles.service.management.AssignableRolePlaceManagementService;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand; import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration; import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo; import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter; import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult; import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition; import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandPrivilegeLevels;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandAutoCompleteService;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.models.database.AServer; import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.management.ServerManagementService; import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import java.util.ArrayList;
import java.util.stream.Collectors;
import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -24,37 +34,78 @@ import java.util.concurrent.CompletableFuture;
@Component @Component
public class ActivateAssignableRolePlace extends AbstractConditionableCommand { public class ActivateAssignableRolePlace extends AbstractConditionableCommand {
private static final String ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER = "name";
private static final String ACTIVATE_ASSIGNABLE_ROLE_PLACE_RESPONSE = "activateAssignableRolePlace_response";
@Autowired @Autowired
private AssignableRolePlaceService service; private AssignableRolePlaceService service;
@Autowired @Autowired
private ServerManagementService serverManagementService; private ServerManagementService serverManagementService;
@Autowired
private SlashCommandParameterService slashCommandParameterService;
@Autowired
private InteractionService interactionService;
@Autowired
private SlashCommandAutoCompleteService slashCommandAutoCompleteService;
@Autowired
private AssignableRolePlaceManagementService assignableRolePlaceManagementService;
@Override @Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) { public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
List<Object> parameters = commandContext.getParameters().getParameters(); String assignableRolePlaceName = slashCommandParameterService.getCommandOption(ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER, event, String.class);
String name = (String) parameters.get(0); AServer server = serverManagementService.loadServer(event.getGuild());
AServer server = serverManagementService.loadServer(commandContext.getGuild()); return service.activateAssignableRolePlace(server, assignableRolePlaceName)
return service.activateAssignableRolePlace(server, name) .thenAccept(unused -> interactionService.replyEmbed(ACTIVATE_ASSIGNABLE_ROLE_PLACE_RESPONSE, new Object(), event))
.thenApply(unused -> CommandResult.fromSuccess()); .thenApply(unused -> CommandResult.fromSuccess());
}
@Override
public List<String> performAutoComplete(CommandAutoCompleteInteractionEvent event) {
if(slashCommandAutoCompleteService.matchesParameter(event.getFocusedOption(), ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER)) {
String input = event.getFocusedOption().getValue();
AServer server = serverManagementService.loadServer(event.getGuild());
return assignableRolePlaceManagementService.getAssignableRolePlacesWithNamesContaining(input, server)
.stream().map(assignableRolePlace -> assignableRolePlace.getKey().toLowerCase())
.collect(Collectors.toList());
}
return new ArrayList<>();
} }
@Override @Override
public CommandConfiguration getConfiguration() { public CommandConfiguration getConfiguration() {
Parameter placeName = Parameter Parameter placeName = Parameter
.builder() .builder()
.name("name") .name(ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER)
.type(String.class) .type(String.class)
.supportsAutoComplete(true)
.templated(true) .templated(true)
.build(); .build();
SlashCommandConfig slashCommandConfig = SlashCommandConfig
.builder()
.enabled(true)
.defaultPrivilege(SlashCommandPrivilegeLevels.INVITER)
.rootCommandName(AssignableRolePlaceSlashCommandName.ASSIGNABLE_ROLE_PLACE)
.groupName("place")
.commandName("activate")
.build();
List<Parameter> parameters = Arrays.asList(placeName); List<Parameter> parameters = Arrays.asList(placeName);
HelpInfo helpInfo = HelpInfo.builder().templated(true).build(); HelpInfo helpInfo = HelpInfo
.builder()
.templated(true)
.build();
return CommandConfiguration.builder() return CommandConfiguration.builder()
.name("activateAssignableRolePlace") .name("activateAssignableRolePlace")
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES) .module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
.templated(true) .templated(true)
.messageCommandOnly(true)
.async(true) .async(true)
.slashCommandConfig(slashCommandConfig)
.slashCommandOnly(true)
.supportsEmbedException(true) .supportsEmbedException(true)
.causesReaction(true) .causesReaction(true)
.parameters(parameters) .parameters(parameters)

View File

@@ -1,16 +1,30 @@
package dev.sheldan.abstracto.assignableroles.command; package dev.sheldan.abstracto.assignableroles.command;
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition; import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
import dev.sheldan.abstracto.assignableroles.config.AssignableRolePlaceSlashCommandName;
import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRoleConditionType; import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRoleConditionType;
import dev.sheldan.abstracto.assignableroles.service.AssignableRoleConditionService; import dev.sheldan.abstracto.assignableroles.service.AssignableRoleConditionService;
import dev.sheldan.abstracto.assignableroles.service.management.AssignableRolePlaceManagementService;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand; import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration; import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo; import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter; import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext; import dev.sheldan.abstracto.core.command.execution.CommandParameterKey;
import dev.sheldan.abstracto.core.command.execution.CommandResult; import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition; import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandPrivilegeLevels;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandAutoCompleteService;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import java.util.ArrayList;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import net.dv8tion.jda.api.entities.Role; import net.dv8tion.jda.api.entities.Role;
import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -20,43 +34,79 @@ import java.util.List;
@Component @Component
public class AddAssignableRoleCondition extends AbstractConditionableCommand { public class AddAssignableRoleCondition extends AbstractConditionableCommand {
private static final String ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER = "name";
private static final String ASSIGNABLE_ROLE_PARAMETER = "role";
private static final String CONDITION_KEY_PARAMETER = "conditionKey";
private static final String CONDITION_PARAMETER_PARAMETER = "conditionParameter";
private static final String ADD_ASSIGNABLE_ROLE_CONDITION_RESPONSE = "addAssignableRoleCondition_response";
@Autowired @Autowired
private AssignableRoleConditionService assignableRoleConditionService; private AssignableRoleConditionService assignableRoleConditionService;
@Autowired
private InteractionService interactionService;
@Autowired
private SlashCommandParameterService slashCommandParameterService;
@Autowired
private SlashCommandAutoCompleteService slashCommandAutoCompleteService;
@Autowired
private AssignableRolePlaceManagementService assignableRolePlaceManagementService;
@Autowired
private ServerManagementService serverManagementService;
@Override @Override
public CommandResult execute(CommandContext commandContext) { public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
List<Object> parameters = commandContext.getParameters().getParameters(); String assignableRolePlaceName = slashCommandParameterService.getCommandOption(ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER, event, String.class);
String name = (String) parameters.get(0); Role role = slashCommandParameterService.getCommandOption(ASSIGNABLE_ROLE_PARAMETER, event, Role.class);
Role role = (Role) parameters.get(1); String configKeyString = slashCommandParameterService.getCommandOption(CONDITION_KEY_PARAMETER, event, String.class);
AssignableRoleConditionType configKey = (AssignableRoleConditionType) parameters.get(2); AssignableRoleConditionType configKey = CommandParameterKey.getEnumFromKey(AssignableRoleConditionType.class, configKeyString);
String parameterValue = (String) parameters.get(3); String parameterValue = slashCommandParameterService.getCommandOption(CONDITION_PARAMETER_PARAMETER, event, String.class);
assignableRoleConditionService.createAssignableRoleCondition(name, role, configKey, parameterValue); assignableRoleConditionService.createAssignableRoleCondition(assignableRolePlaceName, role, configKey, parameterValue);
return CommandResult.fromSuccess(); return interactionService.replyEmbed(ADD_ASSIGNABLE_ROLE_CONDITION_RESPONSE, event)
.thenApply(interactionHook -> CommandResult.fromSuccess());
}
@Override
public List<String> performAutoComplete(CommandAutoCompleteInteractionEvent event) {
if(slashCommandAutoCompleteService.matchesParameter(event.getFocusedOption(), ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER)) {
String input = event.getFocusedOption().getValue();
AServer server = serverManagementService.loadServer(event.getGuild());
return assignableRolePlaceManagementService.getAssignableRolePlacesWithNamesContaining(input, server)
.stream().map(assignableRolePlace -> assignableRolePlace.getKey().toLowerCase())
.collect(Collectors.toList());
}
return new ArrayList<>();
} }
@Override @Override
public CommandConfiguration getConfiguration() { public CommandConfiguration getConfiguration() {
Parameter placeName = Parameter Parameter placeName = Parameter
.builder() .builder()
.name("name") .name(ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER)
.type(String.class) .type(String.class)
.supportsAutoComplete(true)
.templated(true) .templated(true)
.build(); .build();
Parameter role = Parameter Parameter role = Parameter
.builder() .builder()
.name("role") .name(ASSIGNABLE_ROLE_PARAMETER)
.type(Role.class) .type(Role.class)
.templated(true) .templated(true)
.build(); .build();
Parameter conditionKey = Parameter Parameter conditionKey = Parameter
.builder() .builder()
.name("conditionKey") .name(CONDITION_KEY_PARAMETER)
.type(AssignableRoleConditionType.class) .type(AssignableRoleConditionType.class)
.templated(true) .templated(true)
.build(); .build();
Parameter conditionValue = Parameter Parameter conditionValue = Parameter
.builder() .builder()
.name("conditionParameter") .name(CONDITION_PARAMETER_PARAMETER)
.type(String.class) .type(String.class)
.templated(true) .templated(true)
.build(); .build();
@@ -65,11 +115,22 @@ public class AddAssignableRoleCondition extends AbstractConditionableCommand {
.builder() .builder()
.templated(true) .templated(true)
.build(); .build();
SlashCommandConfig slashCommandConfig = SlashCommandConfig
.builder()
.enabled(true)
.defaultPrivilege(SlashCommandPrivilegeLevels.INVITER)
.rootCommandName(AssignableRolePlaceSlashCommandName.ASSIGNABLE_ROLE_PLACE)
.groupName("role")
.commandName("addcondition")
.build();
return CommandConfiguration.builder() return CommandConfiguration.builder()
.name("addAssignableRoleCondition") .name("addAssignableRoleCondition")
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES) .module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
.templated(true) .templated(true)
.messageCommandOnly(true) .slashCommandOnly(true)
.slashCommandConfig(slashCommandConfig)
.supportsEmbedException(true) .supportsEmbedException(true)
.causesReaction(true) .causesReaction(true)
.parameters(parameters) .parameters(parameters)

View File

@@ -0,0 +1,170 @@
package dev.sheldan.abstracto.assignableroles.command;
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
import dev.sheldan.abstracto.assignableroles.config.AssignableRolePlaceSlashCommandName;
import dev.sheldan.abstracto.assignableroles.exception.AssignableRoleNotUsableException;
import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService;
import dev.sheldan.abstracto.assignableroles.service.management.AssignableRolePlaceManagementService;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandPrivilegeLevels;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandAutoCompleteService;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.models.database.AEmote;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.RoleService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import java.util.ArrayList;
import java.util.stream.Collectors;
import net.dv8tion.jda.api.entities.Role;
import net.dv8tion.jda.api.entities.emoji.Emoji;
import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
/**
* Command used to add an {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRole assignableRole}
* to an {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace place}
*/
@Component
public class AddRoleToAssignableRolePlace extends AbstractConditionableCommand {
private static final String ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER = "name";
private static final String ASSIGNABLE_ROLE_PARAMETER = "role";
private static final String DISPLAY_TEXT_PARAMETER = "displayText";
private static final String EMOTE_PARAMETER = "emote";
private static final String ADD_ROLE_TO_ASSIGNABLE_ROLE_POST_RESPONSE = "addRoleToAssignableRolePlace_response";
@Autowired
private AssignableRolePlaceService service;
@Autowired
private RoleService roleService;
@Autowired
private ServerManagementService serverManagementService;
@Autowired
private InteractionService interactionService;
@Autowired
private SlashCommandParameterService slashCommandParameterService;
@Autowired
private SlashCommandAutoCompleteService slashCommandAutoCompleteService;
@Autowired
private AssignableRolePlaceManagementService assignableRolePlaceManagementService;
@Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
String assignableRolePlaceName = slashCommandParameterService.getCommandOption(ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER, event, String.class);
Role role = slashCommandParameterService.getCommandOption(ASSIGNABLE_ROLE_PARAMETER, event, Role.class);
String displayText;
if(slashCommandParameterService.hasCommandOption(DISPLAY_TEXT_PARAMETER, event)) {
displayText = slashCommandParameterService.getCommandOption(DISPLAY_TEXT_PARAMETER, event, String.class);
} else {
displayText = null;
}
Emoji emoji;
if(slashCommandParameterService.hasCommandOption(EMOTE_PARAMETER, event)) {
String emoteText = slashCommandParameterService.getCommandOption(EMOTE_PARAMETER, event, String.class);
emoji = slashCommandParameterService.loadEmoteFromString(emoteText, event.getGuild());
} else {
emoji = null;
}
AServer server = serverManagementService.loadServer(event.getGuild());
// already used check via role and assignable role place name
if(!roleService.canBotInteractWithRole(role)) {
throw new AssignableRoleNotUsableException(role);
}
return service.addRoleToAssignableRolePlace(server, assignableRolePlaceName, role, emoji, displayText)
.thenAccept(unused -> interactionService.replyEmbed(ADD_ROLE_TO_ASSIGNABLE_ROLE_POST_RESPONSE, event))
.thenApply(aVoid -> CommandResult.fromSuccess());
}
@Override
public List<String> performAutoComplete(CommandAutoCompleteInteractionEvent event) {
if(slashCommandAutoCompleteService.matchesParameter(event.getFocusedOption(), ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER)) {
String input = event.getFocusedOption().getValue();
AServer server = serverManagementService.loadServer(event.getGuild());
return assignableRolePlaceManagementService.getAssignableRolePlacesWithNamesContaining(input, server)
.stream().map(assignableRolePlace -> assignableRolePlace.getKey().toLowerCase())
.collect(Collectors.toList());
}
return new ArrayList<>();
}
@Override
public CommandConfiguration getConfiguration() {
Parameter placeName = Parameter
.builder()
.name(ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER)
.type(String.class)
.supportsAutoComplete(true)
.templated(true)
.build();
Parameter role = Parameter
.builder()
.name(ASSIGNABLE_ROLE_PARAMETER)
.type(Role.class)
.templated(true)
.build();
Parameter rolePostName = Parameter
.builder()
.name(DISPLAY_TEXT_PARAMETER)
.type(String.class)
.templated(true)
.build();
Parameter emote = Parameter
.builder()
.name(EMOTE_PARAMETER)
.type(AEmote.class)
.optional(true)
.templated(true)
.build();
List<Parameter> parameters = Arrays.asList(placeName, role, rolePostName, emote);
HelpInfo helpInfo = HelpInfo
.builder()
.templated(true)
.build();
SlashCommandConfig slashCommandConfig = SlashCommandConfig
.builder()
.enabled(true)
.defaultPrivilege(SlashCommandPrivilegeLevels.INVITER)
.rootCommandName(AssignableRolePlaceSlashCommandName.ASSIGNABLE_ROLE_PLACE)
.groupName("role")
.commandName("add")
.build();
return CommandConfiguration.builder()
.name("addRoleToAssignableRolePlace")
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
.templated(true)
.causesReaction(true)
.slashCommandConfig(slashCommandConfig)
.async(true)
.supportsEmbedException(true)
.parameters(parameters)
.help(helpInfo)
.build();
}
@Override
public FeatureDefinition getFeature() {
return AssignableRoleFeatureDefinition.ASSIGNABLE_ROLES;
}
}

View File

@@ -1,112 +0,0 @@
package dev.sheldan.abstracto.assignableroles.command;
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
import dev.sheldan.abstracto.assignableroles.exception.AssignableRoleNotUsableException;
import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.models.FullEmote;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.RoleService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import net.dv8tion.jda.api.entities.Role;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
/**
* Command used to add an {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRole assignableRole}
* to an {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace place}
*/
@Component
public class AddRoleToAssignableRolePost extends AbstractConditionableCommand {
@Autowired
private AssignableRolePlaceService service;
@Autowired
private RoleService roleService;
@Autowired
private ServerManagementService serverManagementService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
String name = (String) parameters.get(0);
Role role = (Role) parameters.get(1);
String description = null;
if (parameters.size() > 2) {
description = (String) parameters.get(2);
}
FullEmote emote = null;
if(parameters.size() > 3) {
emote = (FullEmote) parameters.get(3);
}
AServer server = serverManagementService.loadServer(commandContext.getGuild());
// already used check via role and assignable role place name
if(!roleService.canBotInteractWithRole(role)) {
throw new AssignableRoleNotUsableException(role);
}
return service.addRoleToAssignableRolePlace(server, name, role, emote, description)
.thenApply(aVoid -> CommandResult.fromSuccess());
}
@Override
public CommandConfiguration getConfiguration() {
Parameter placeName = Parameter
.builder()
.name("name")
.type(String.class)
.templated(true)
.build();
Parameter role = Parameter
.builder()
.name("role")
.type(Role.class)
.templated(true)
.build();
Parameter rolePostName = Parameter
.builder()
.name("displayText")
.type(String.class)
.templated(true)
.build();
Parameter emote = Parameter
.builder()
.name("emote")
.type(FullEmote.class)
.optional(true)
.templated(true)
.build();
List<Parameter> parameters = Arrays.asList(placeName, role, rolePostName, emote);
HelpInfo helpInfo = HelpInfo
.builder()
.templated(true)
.build();
return CommandConfiguration.builder()
.name("addRoleToAssignableRolePlace")
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
.templated(true)
.causesReaction(true)
.messageCommandOnly(true)
.async(true)
.supportsEmbedException(true)
.parameters(parameters)
.help(helpInfo)
.build();
}
@Override
public FeatureDefinition getFeature() {
return AssignableRoleFeatureDefinition.ASSIGNABLE_ROLES;
}
}

View File

@@ -2,17 +2,28 @@ package dev.sheldan.abstracto.assignableroles.command;
import dev.sheldan.abstracto.assignableroles.config.AssignableRolePlaceParameterKey; import dev.sheldan.abstracto.assignableroles.config.AssignableRolePlaceParameterKey;
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition; import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
import dev.sheldan.abstracto.assignableroles.config.AssignableRolePlaceSlashCommandName;
import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService; import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService;
import dev.sheldan.abstracto.assignableroles.service.management.AssignableRolePlaceManagementService;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand; import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration; import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo; import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter; import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext; import dev.sheldan.abstracto.core.command.execution.CommandParameterKey;
import dev.sheldan.abstracto.core.command.execution.CommandResult; import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition; import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandPrivilegeLevels;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandAutoCompleteService;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.models.database.AServer; import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.management.ServerManagementService; import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import java.util.ArrayList;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -27,52 +38,96 @@ import java.util.concurrent.CompletableFuture;
@Slf4j @Slf4j
public class ChangeAssignableRolePlaceConfig extends AbstractConditionableCommand { public class ChangeAssignableRolePlaceConfig extends AbstractConditionableCommand {
private static final String ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER = "name";
private static final String CONFIGURATION_KEY_PARAMETER = "key";
private static final String CONFIGURATION_VALUE_PARAMETER = "value";
private static final String CHANGE_ASSIGNABLE_ROLE_PLACE_CONFIG_RESPONSE = "changeAssignableRolePlaceConfig_response";
@Autowired @Autowired
private AssignableRolePlaceService service; private AssignableRolePlaceService service;
@Autowired @Autowired
private ServerManagementService serverManagementService; private ServerManagementService serverManagementService;
@Autowired
private InteractionService interactionService;
@Autowired
private SlashCommandParameterService slashCommandParameterService;
@Autowired
private SlashCommandAutoCompleteService slashCommandAutoCompleteService;
@Autowired
private AssignableRolePlaceManagementService assignableRolePlaceManagementService;
@Override @Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) { public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
List<Object> parameters = commandContext.getParameters().getParameters(); String assignableRolePlaceName = slashCommandParameterService.getCommandOption(ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER, event, String.class);
String name = (String) parameters.get(0); String assignableRolePlaceParameterKeyString = slashCommandParameterService.getCommandOption(CONFIGURATION_KEY_PARAMETER, event, String.class);
AssignableRolePlaceParameterKey configKey = (AssignableRolePlaceParameterKey) parameters.get(1); AssignableRolePlaceParameterKey enumFromKey =
String parameterValue = (String) parameters.get(2); CommandParameterKey.getEnumFromKey(AssignableRolePlaceParameterKey.class, assignableRolePlaceParameterKeyString);
AServer server = serverManagementService.loadServer(commandContext.getGuild()); String parameterValue = slashCommandParameterService.getCommandOption(CONFIGURATION_VALUE_PARAMETER, event, String.class);
return service.changeConfiguration(server, name, configKey, parameterValue) AServer server = serverManagementService.loadServer(event.getGuild());
.thenApply(aVoid -> CommandResult.fromSuccess()); return service.changeConfiguration(server, assignableRolePlaceName, enumFromKey, parameterValue)
.thenAccept(unused -> interactionService.replyEmbed(CHANGE_ASSIGNABLE_ROLE_PLACE_CONFIG_RESPONSE, event))
.thenApply(aVoid -> CommandResult.fromSuccess());
}
@Override
public List<String> performAutoComplete(CommandAutoCompleteInteractionEvent event) {
if(slashCommandAutoCompleteService.matchesParameter(event.getFocusedOption(), ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER)) {
String input = event.getFocusedOption().getValue();
AServer server = serverManagementService.loadServer(event.getGuild());
return assignableRolePlaceManagementService.getAssignableRolePlacesWithNamesContaining(input, server)
.stream().map(assignableRolePlace -> assignableRolePlace.getKey().toLowerCase())
.collect(Collectors.toList());
}
return new ArrayList<>();
} }
@Override @Override
public CommandConfiguration getConfiguration() { public CommandConfiguration getConfiguration() {
Parameter assignableRolePlaceName = Parameter Parameter assignableRolePlaceName = Parameter
.builder() .builder()
.name("name") .name(ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER)
.type(String.class) .type(String.class)
.supportsAutoComplete(true)
.templated(true) .templated(true)
.build(); .build();
Parameter parameterKey = Parameter Parameter parameterKey = Parameter
.builder() .builder()
.name("key") .name(CONFIGURATION_KEY_PARAMETER)
.type(AssignableRolePlaceParameterKey.class) .type(AssignableRolePlaceParameterKey.class)
.templated(true) .templated(true)
.build(); .build();
Parameter parameterValue = Parameter Parameter parameterValue = Parameter
.builder() .builder()
.name("value") .name(CONFIGURATION_VALUE_PARAMETER)
.type(String.class) .type(String.class)
.templated(true) .templated(true)
.build(); .build();
SlashCommandConfig slashCommandConfig = SlashCommandConfig
.builder()
.enabled(true)
.defaultPrivilege(SlashCommandPrivilegeLevels.INVITER)
.rootCommandName(AssignableRolePlaceSlashCommandName.ASSIGNABLE_ROLE_PLACE)
.groupName("place")
.commandName("changeconfig")
.build();
List<Parameter> parameters = Arrays.asList(assignableRolePlaceName, parameterKey, parameterValue); List<Parameter> parameters = Arrays.asList(assignableRolePlaceName, parameterKey, parameterValue);
HelpInfo helpInfo = HelpInfo.builder().templated(true).build(); HelpInfo helpInfo = HelpInfo
.builder()
.templated(true)
.build();
return CommandConfiguration.builder() return CommandConfiguration.builder()
.name("changeAssignableRolePlaceConfig") .name("changeAssignableRolePlaceConfig")
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES) .module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
.templated(true) .templated(true)
.messageCommandOnly(true) .slashCommandConfig(slashCommandConfig)
.slashCommandOnly(true)
.async(true) .async(true)
.supportsEmbedException(true) .supportsEmbedException(true)
.causesReaction(true) .causesReaction(true)

View File

@@ -1,6 +1,7 @@
package dev.sheldan.abstracto.assignableroles.command; package dev.sheldan.abstracto.assignableroles.command;
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition; import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
import dev.sheldan.abstracto.assignableroles.config.AssignableRolePlaceSlashCommandName;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace; import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlaceType; import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlaceType;
import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService; import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService;
@@ -10,14 +11,20 @@ import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter; import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.config.ParameterValidator; import dev.sheldan.abstracto.core.command.config.ParameterValidator;
import dev.sheldan.abstracto.core.command.config.validator.MaxStringLengthValidator; import dev.sheldan.abstracto.core.command.config.validator.MaxStringLengthValidator;
import dev.sheldan.abstracto.core.command.execution.CommandContext; import dev.sheldan.abstracto.core.command.execution.CommandParameterKey;
import dev.sheldan.abstracto.core.command.execution.CommandResult; import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition; import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException; import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandPrivilegeLevels;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.models.database.AChannel; import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.service.management.ChannelManagementService; import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService; import java.util.concurrent.CompletableFuture;
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -25,63 +32,87 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
@Component @Component
public class CreateAssignableRolePost extends AbstractConditionableCommand { public class CreateAssignableRolePlace extends AbstractConditionableCommand {
private static final String ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER = "name";
private static final String ASSIGNABLE_ROLE_PLACE_CHANNEL_PARAMETER = "channel";
private static final String ASSIGNABLE_ROLE_PLACE_TYPE_PARAMETER = "type";
private static final String ASSIGNABLE_ROLE_PLACE_TEXT_PARAMETER = "text";
private static final String CREATE_ASSIGNABLE_ROLE_PLACE_RESPONSE_TEMPLATE = "createAssignableRolePlace_response";
@Autowired @Autowired
private AssignableRolePlaceService service; private AssignableRolePlaceService service;
@Autowired @Autowired
private ChannelManagementService channelManagementService; private ChannelManagementService channelManagementService;
@Autowired
private SlashCommandParameterService slashCommandParameterService;
@Autowired
private InteractionService interactionService;
@Override @Override
public CommandResult execute(CommandContext commandContext) { public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
List<Object> parameters = commandContext.getParameters().getParameters(); String assignableRolePlaceName = slashCommandParameterService.getCommandOption(ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER, event, String.class);
String name = (String) parameters.get(0); GuildChannel channel = slashCommandParameterService.getCommandOption(ASSIGNABLE_ROLE_PLACE_CHANNEL_PARAMETER, event, TextChannel.class, GuildChannel.class);
TextChannel channel = (TextChannel) parameters.get(1); if(!channel.getGuild().equals(event.getGuild())) {
String text = (String) parameters.get(2);
AssignableRolePlaceType type = AssignableRolePlaceType.DEFAULT;
if(parameters.size() > 3) {
type = (AssignableRolePlaceType) parameters.get(3);
}
if(!channel.getGuild().equals(commandContext.getGuild())) {
throw new EntityGuildMismatchException(); throw new EntityGuildMismatchException();
} }
String text = slashCommandParameterService.getCommandOption(ASSIGNABLE_ROLE_PLACE_TEXT_PARAMETER, event, String.class);
AssignableRolePlaceType type;
if(slashCommandParameterService.hasCommandOption(ASSIGNABLE_ROLE_PLACE_TYPE_PARAMETER, event)) {
String typeString = slashCommandParameterService.getCommandOption(ASSIGNABLE_ROLE_PLACE_TYPE_PARAMETER, event, String.class);
type = CommandParameterKey.getEnumFromKey(AssignableRolePlaceType.class, typeString);
} else {
type = AssignableRolePlaceType.DEFAULT;
}
AChannel chosenChannel = channelManagementService.loadChannel(channel.getIdLong()); AChannel chosenChannel = channelManagementService.loadChannel(channel.getIdLong());
service.createAssignableRolePlace(name, chosenChannel, text, type); service.createAssignableRolePlace(assignableRolePlaceName, chosenChannel, text, type);
return CommandResult.fromSuccess(); return interactionService.replyEmbed(CREATE_ASSIGNABLE_ROLE_PLACE_RESPONSE_TEMPLATE, event)
.thenApply(interactionHook -> CommandResult.fromSuccess());
} }
@Override @Override
public CommandConfiguration getConfiguration() { public CommandConfiguration getConfiguration() {
List<ParameterValidator> rolePlaceNameValidator = Arrays.asList(MaxStringLengthValidator.max(AssignableRolePlace.ASSIGNABLE_PLACE_NAME_LIMIT)); List<ParameterValidator> rolePlaceNameValidator = Arrays.asList(MaxStringLengthValidator.max(AssignableRolePlace.ASSIGNABLE_PLACE_NAME_LIMIT.intValue()));
Parameter rolePostName = Parameter Parameter rolePostName = Parameter
.builder() .builder()
.name("name") .name(ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER)
.validators(rolePlaceNameValidator) .validators(rolePlaceNameValidator)
.type(String.class) .type(String.class)
.templated(true) .templated(true)
.build(); .build();
Parameter channel = Parameter Parameter channel = Parameter
.builder() .builder()
.name("channel") .name(ASSIGNABLE_ROLE_PLACE_CHANNEL_PARAMETER)
.type(TextChannel.class) .type(TextChannel.class)
.templated(true) .templated(true)
.build(); .build();
Parameter type = Parameter Parameter type = Parameter
.builder() .builder()
.name("type") .name(ASSIGNABLE_ROLE_PLACE_TYPE_PARAMETER)
.type(AssignableRolePlaceType.class) .type(AssignableRolePlaceType.class)
.templated(true) .templated(true)
.optional(true) .optional(true)
.build(); .build();
List<ParameterValidator> rolePlaceDescriptionValidator = Arrays.asList(MaxStringLengthValidator.max(AssignableRolePlace.ASSIGNABLE_PLACE_NAME_LIMIT)); List<ParameterValidator> rolePlaceDescriptionValidator = Arrays.asList(MaxStringLengthValidator.max(AssignableRolePlace.ASSIGNABLE_PLACE_NAME_LIMIT.intValue()));
Parameter text = Parameter Parameter text = Parameter
.builder() .builder()
.name("text") .name(ASSIGNABLE_ROLE_PLACE_TEXT_PARAMETER)
.validators(rolePlaceDescriptionValidator) .validators(rolePlaceDescriptionValidator)
.type(String.class) .type(String.class)
.templated(true) .templated(true)
.build(); .build();
SlashCommandConfig slashCommandConfig = SlashCommandConfig
.builder()
.enabled(true)
.defaultPrivilege(SlashCommandPrivilegeLevels.INVITER)
.rootCommandName(AssignableRolePlaceSlashCommandName.ASSIGNABLE_ROLE_PLACE)
.groupName("place")
.commandName("create")
.build();
List<String> aliases = Arrays.asList("crRPl", "crAssRoPl"); List<String> aliases = Arrays.asList("crRPl", "crAssRoPl");
List<Parameter> parameters = Arrays.asList(rolePostName, channel, text, type); List<Parameter> parameters = Arrays.asList(rolePostName, channel, text, type);
HelpInfo helpInfo = HelpInfo HelpInfo helpInfo = HelpInfo
@@ -94,7 +125,8 @@ public class CreateAssignableRolePost extends AbstractConditionableCommand {
.templated(true) .templated(true)
.supportsEmbedException(true) .supportsEmbedException(true)
.causesReaction(true) .causesReaction(true)
.messageCommandOnly(true) .slashCommandConfig(slashCommandConfig)
.slashCommandOnly(true)
.parameters(parameters) .parameters(parameters)
.aliases(aliases) .aliases(aliases)
.help(helpInfo) .help(helpInfo)

View File

@@ -1,16 +1,26 @@
package dev.sheldan.abstracto.assignableroles.command; package dev.sheldan.abstracto.assignableroles.command;
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition; import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
import dev.sheldan.abstracto.assignableroles.config.AssignableRolePlaceSlashCommandName;
import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService; import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService;
import dev.sheldan.abstracto.assignableroles.service.management.AssignableRolePlaceManagementService;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand; import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration; import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo; import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter; import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult; import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition; import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandPrivilegeLevels;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandAutoCompleteService;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.models.database.AServer; import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.management.ServerManagementService; import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import java.util.ArrayList;
import java.util.stream.Collectors;
import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -24,37 +34,78 @@ import java.util.concurrent.CompletableFuture;
@Component @Component
public class DeactivateAssignableRolePlace extends AbstractConditionableCommand { public class DeactivateAssignableRolePlace extends AbstractConditionableCommand {
private static final String ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER = "name";
private static final String DEACTIVATE_ASSIGNABLE_ROLE_PLACE_RESPONSE_TEMPLATE = "deactivateAssignableRolePlace_response";
@Autowired @Autowired
private AssignableRolePlaceService service; private AssignableRolePlaceService service;
@Autowired @Autowired
private ServerManagementService serverManagementService; private ServerManagementService serverManagementService;
@Autowired
private InteractionService interactionService;
@Autowired
private SlashCommandParameterService slashCommandParameterService;
@Autowired
private SlashCommandAutoCompleteService slashCommandAutoCompleteService;
@Autowired
private AssignableRolePlaceManagementService assignableRolePlaceManagementService;
@Override @Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) { public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
List<Object> parameters = commandContext.getParameters().getParameters(); String assignableRolePlaceName = slashCommandParameterService.getCommandOption(ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER, event, String.class);
String name = (String) parameters.get(0); AServer server = serverManagementService.loadServer(event.getGuild());
AServer server = serverManagementService.loadServer(commandContext.getGuild()); return service.deactivateAssignableRolePlace(server, assignableRolePlaceName)
return service.deactivateAssignableRolePlace(server, name) .thenAccept(unused -> interactionService.replyEmbed(DEACTIVATE_ASSIGNABLE_ROLE_PLACE_RESPONSE_TEMPLATE, event))
.thenApply(unused -> CommandResult.fromSuccess()); .thenApply(unused -> CommandResult.fromSuccess());
}
@Override
public List<String> performAutoComplete(CommandAutoCompleteInteractionEvent event) {
if(slashCommandAutoCompleteService.matchesParameter(event.getFocusedOption(), ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER)) {
String input = event.getFocusedOption().getValue();
AServer server = serverManagementService.loadServer(event.getGuild());
return assignableRolePlaceManagementService.getAssignableRolePlacesWithNamesContaining(input, server)
.stream().map(assignableRolePlace -> assignableRolePlace.getKey().toLowerCase())
.collect(Collectors.toList());
}
return new ArrayList<>();
} }
@Override @Override
public CommandConfiguration getConfiguration() { public CommandConfiguration getConfiguration() {
Parameter rolePostName = Parameter Parameter rolePostName = Parameter
.builder() .builder()
.name("name") .name(ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER)
.type(String.class) .type(String.class)
.supportsAutoComplete(true)
.templated(true) .templated(true)
.build(); .build();
List<Parameter> parameters = Arrays.asList(rolePostName); List<Parameter> parameters = Arrays.asList(rolePostName);
HelpInfo helpInfo = HelpInfo.builder().templated(true).build(); HelpInfo helpInfo = HelpInfo
.builder()
.templated(true)
.build();
SlashCommandConfig slashCommandConfig = SlashCommandConfig
.builder()
.enabled(true)
.defaultPrivilege(SlashCommandPrivilegeLevels.INVITER)
.rootCommandName(AssignableRolePlaceSlashCommandName.ASSIGNABLE_ROLE_PLACE)
.groupName("place")
.commandName("deactivate")
.build();
return CommandConfiguration.builder() return CommandConfiguration.builder()
.name("deactivateAssignableRolePlace") .name("deactivateAssignableRolePlace")
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES) .module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
.templated(true) .templated(true)
.async(true) .async(true)
.messageCommandOnly(true) .slashCommandOnly(true)
.slashCommandConfig(slashCommandConfig)
.supportsEmbedException(true) .supportsEmbedException(true)
.causesReaction(true) .causesReaction(true)
.parameters(parameters) .parameters(parameters)

View File

@@ -1,16 +1,26 @@
package dev.sheldan.abstracto.assignableroles.command; package dev.sheldan.abstracto.assignableroles.command;
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition; import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
import dev.sheldan.abstracto.assignableroles.config.AssignableRolePlaceSlashCommandName;
import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService; import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService;
import dev.sheldan.abstracto.assignableroles.service.management.AssignableRolePlaceManagementService;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand; import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration; import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo; import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter; import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult; import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition; import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandPrivilegeLevels;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandService;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandAutoCompleteService;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.models.database.AServer; import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.management.ServerManagementService; import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import java.util.ArrayList;
import java.util.stream.Collectors;
import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -24,38 +34,80 @@ import java.util.concurrent.CompletableFuture;
@Component @Component
public class DeleteAssignableRolePlace extends AbstractConditionableCommand { public class DeleteAssignableRolePlace extends AbstractConditionableCommand {
private static final String ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER = "name";
private static final String DELETE_ASSIGNABLE_ROLE_PLACE_RESPONSE_TEMPLATE = "deleteAssignableRolePlace_response";
@Autowired @Autowired
private AssignableRolePlaceService service; private AssignableRolePlaceService service;
@Autowired @Autowired
private ServerManagementService serverManagementService; private ServerManagementService serverManagementService;
@Autowired
private SlashCommandService slashCommandService;
@Autowired
private SlashCommandParameterService slashCommandParameterService;
@Autowired
private SlashCommandAutoCompleteService slashCommandAutoCompleteService;
@Autowired
private AssignableRolePlaceManagementService assignableRolePlaceManagementService;
@Override @Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) { public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
List<Object> parameters = commandContext.getParameters().getParameters(); String assignableRolePlaceName = slashCommandParameterService.getCommandOption(ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER, event, String.class);
String name = (String) parameters.get(0); AServer server = serverManagementService.loadServer(event.getGuild());
AServer server = serverManagementService.loadServer(commandContext.getGuild()); return service.deleteAssignableRolePlace(server, assignableRolePlaceName)
return service.deleteAssignableRolePlace(server, name) .thenAccept(unused -> slashCommandService.completeConfirmableCommand(event, DELETE_ASSIGNABLE_ROLE_PLACE_RESPONSE_TEMPLATE))
.thenApply(aVoid -> CommandResult.fromSuccess()); .thenApply(unused -> CommandResult.fromSuccess());
}
@Override
public List<String> performAutoComplete(CommandAutoCompleteInteractionEvent event) {
if(slashCommandAutoCompleteService.matchesParameter(event.getFocusedOption(), ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER)) {
String input = event.getFocusedOption().getValue();
AServer server = serverManagementService.loadServer(event.getGuild());
return assignableRolePlaceManagementService.getAssignableRolePlacesWithNamesContaining(input, server)
.stream().map(assignableRolePlace -> assignableRolePlace.getKey().toLowerCase())
.collect(Collectors.toList());
}
return new ArrayList<>();
} }
@Override @Override
public CommandConfiguration getConfiguration() { public CommandConfiguration getConfiguration() {
Parameter rolePostName = Parameter Parameter rolePostName = Parameter
.builder() .builder()
.name("name") .name(ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER)
.type(String.class) .type(String.class)
.supportsAutoComplete(true)
.templated(true) .templated(true)
.build(); .build();
List<Parameter> parameters = Arrays.asList(rolePostName); List<Parameter> parameters = Arrays.asList(rolePostName);
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
SlashCommandConfig slashCommandConfig = SlashCommandConfig
.builder()
.enabled(true)
.defaultPrivilege(SlashCommandPrivilegeLevels.INVITER)
.rootCommandName(AssignableRolePlaceSlashCommandName.ASSIGNABLE_ROLE_PLACE)
.groupName("place")
.commandName("delete")
.build();
HelpInfo helpInfo = HelpInfo
.builder()
.templated(true)
.build();
return CommandConfiguration.builder() return CommandConfiguration.builder()
.name("deleteAssignableRolePlace") .name("deleteAssignableRolePlace")
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES) .module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
.templated(true) .templated(true)
.causesReaction(true) .causesReaction(true)
.async(true) .async(true)
.messageCommandOnly(true) .slashCommandOnly(true)
.slashCommandConfig(slashCommandConfig)
.requiresConfirmation(true) .requiresConfirmation(true)
.supportsEmbedException(true) .supportsEmbedException(true)
.parameters(parameters) .parameters(parameters)

View File

@@ -1,83 +0,0 @@
package dev.sheldan.abstracto.assignableroles.command;
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace;
import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.config.ParameterValidator;
import dev.sheldan.abstracto.core.command.config.validator.MaxStringLengthValidator;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
/**
* Command used to change the text of an {@link AssignableRolePlace place}
*/
@Component
public class EditAssignableRolePlaceText extends AbstractConditionableCommand {
@Autowired
private AssignableRolePlaceService service;
@Autowired
private ServerManagementService serverManagementService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
String name = (String) parameters.get(0);
String newText = (String) parameters.get(1);
AServer server = serverManagementService.loadServer(commandContext.getGuild());
return service.changeTextAsync(server, name, newText)
.thenApply(aVoid -> CommandResult.fromSuccess());
}
@Override
public CommandConfiguration getConfiguration() {
List<ParameterValidator> rolePlaceNameValidator = Arrays.asList(MaxStringLengthValidator.max(AssignableRolePlace.ASSIGNABLE_PLACE_NAME_LIMIT));
Parameter rolePostName = Parameter
.builder().name("name")
.validators(rolePlaceNameValidator)
.type(String.class)
.templated(true)
.build();
Parameter newText = Parameter
.builder()
.name("newText")
.type(String.class)
.templated(true)
.build();
List<Parameter> parameters = Arrays.asList(rolePostName, newText);
HelpInfo helpInfo = HelpInfo
.builder()
.templated(true)
.build();
return CommandConfiguration.builder()
.name("editAssignableRolePlaceText")
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
.templated(true)
.async(true)
.messageCommandOnly(true)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)
.help(helpInfo)
.build();
}
@Override
public FeatureDefinition getFeature() {
return AssignableRoleFeatureDefinition.ASSIGNABLE_ROLES;
}
}

View File

@@ -1,7 +1,9 @@
package dev.sheldan.abstracto.assignableroles.command; package dev.sheldan.abstracto.assignableroles.command;
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition; import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
import dev.sheldan.abstracto.assignableroles.config.AssignableRolePlaceSlashCommandName;
import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService; import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService;
import dev.sheldan.abstracto.assignableroles.service.management.AssignableRolePlaceManagementService;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand; import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration; import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo; import dev.sheldan.abstracto.core.command.config.HelpInfo;
@@ -10,9 +12,20 @@ import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult; import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition; import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException; import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandPrivilegeLevels;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandAutoCompleteService;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.models.database.AServer; import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.management.ServerManagementService; import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import java.util.ArrayList;
import java.util.stream.Collectors;
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel;
import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel;
import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -27,12 +40,27 @@ import java.util.concurrent.CompletableFuture;
@Component @Component
public class MoveAssignableRolePlace extends AbstractConditionableCommand { public class MoveAssignableRolePlace extends AbstractConditionableCommand {
private static final String ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER = "name";
private static final String NEW_CHANNEL_PARAMETER = "channel";
private static final String MOVE_ASSIGNABLE_ROLE_PLACE_RESPONSE_TEMPLATE = "moveAssignableRolePlace_response";
@Autowired @Autowired
private AssignableRolePlaceService placeManagementService; private AssignableRolePlaceService placeManagementService;
@Autowired @Autowired
private ServerManagementService serverManagementService; private ServerManagementService serverManagementService;
@Autowired
private InteractionService interactionService;
@Autowired
private SlashCommandParameterService slashCommandParameterService;
@Autowired
private SlashCommandAutoCompleteService slashCommandAutoCompleteService;
@Autowired
private AssignableRolePlaceManagementService assignableRolePlaceManagementService;
@Override @Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) { public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters(); List<Object> parameters = commandContext.getParameters().getParameters();
@@ -46,29 +74,69 @@ public class MoveAssignableRolePlace extends AbstractConditionableCommand {
.thenApply(unused -> CommandResult.fromSuccess()); .thenApply(unused -> CommandResult.fromSuccess());
} }
@Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
String assignableRolePlaceName = slashCommandParameterService.getCommandOption(ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER, event, String.class);
GuildChannel channel = slashCommandParameterService.getCommandOption(NEW_CHANNEL_PARAMETER, event, TextChannel.class, GuildChannel.class);
if(!channel.getGuild().equals(event.getGuild()) && !(channel instanceof GuildMessageChannel)) {
throw new EntityGuildMismatchException();
}
AServer server = serverManagementService.loadServer(event.getGuild());
return placeManagementService.moveAssignableRolePlace(server, assignableRolePlaceName, (GuildMessageChannel) channel)
.thenAccept(unused -> interactionService.replyEmbed(MOVE_ASSIGNABLE_ROLE_PLACE_RESPONSE_TEMPLATE, event))
.thenApply(unused -> CommandResult.fromSuccess());
}
@Override
public List<String> performAutoComplete(CommandAutoCompleteInteractionEvent event) {
if(slashCommandAutoCompleteService.matchesParameter(event.getFocusedOption(), ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER)) {
String input = event.getFocusedOption().getValue();
AServer server = serverManagementService.loadServer(event.getGuild());
return assignableRolePlaceManagementService.getAssignableRolePlacesWithNamesContaining(input, server)
.stream().map(assignableRolePlace -> assignableRolePlace.getKey().toLowerCase())
.collect(Collectors.toList());
}
return new ArrayList<>();
}
@Override @Override
public CommandConfiguration getConfiguration() { public CommandConfiguration getConfiguration() {
Parameter rolePostName = Parameter Parameter rolePostName = Parameter
.builder() .builder()
.name("name") .name(ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER)
.type(String.class) .type(String.class)
.supportsAutoComplete(true)
.templated(true) .templated(true)
.build(); .build();
Parameter channel = Parameter Parameter channel = Parameter
.builder() .builder()
.name("channel") .name(NEW_CHANNEL_PARAMETER)
.type(TextChannel.class) .type(TextChannel.class)
.templated(true) .templated(true)
.build(); .build();
List<Parameter> parameters = Arrays.asList(rolePostName, channel); List<Parameter> parameters = Arrays.asList(rolePostName, channel);
HelpInfo helpInfo = HelpInfo.builder().templated(true).build(); HelpInfo helpInfo = HelpInfo
.builder()
.templated(true)
.build();
SlashCommandConfig slashCommandConfig = SlashCommandConfig
.builder()
.enabled(true)
.defaultPrivilege(SlashCommandPrivilegeLevels.INVITER)
.rootCommandName(AssignableRolePlaceSlashCommandName.ASSIGNABLE_ROLE_PLACE)
.groupName("place")
.commandName("move")
.build();
return CommandConfiguration.builder() return CommandConfiguration.builder()
.name("moveAssignableRolePlace") .name("moveAssignableRolePlace")
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES) .module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
.templated(true) .templated(true)
.causesReaction(true) .causesReaction(true)
.messageCommandOnly(true) .slashCommandOnly(true)
.async(true) .async(true)
.slashCommandConfig(slashCommandConfig)
.supportsEmbedException(true) .supportsEmbedException(true)
.parameters(parameters) .parameters(parameters)
.help(helpInfo) .help(helpInfo)

View File

@@ -1,16 +1,30 @@
package dev.sheldan.abstracto.assignableroles.command; package dev.sheldan.abstracto.assignableroles.command;
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition; import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
import dev.sheldan.abstracto.assignableroles.config.AssignableRolePlaceSlashCommandName;
import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRoleConditionType; import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRoleConditionType;
import dev.sheldan.abstracto.assignableroles.service.AssignableRoleConditionService; import dev.sheldan.abstracto.assignableroles.service.AssignableRoleConditionService;
import dev.sheldan.abstracto.assignableroles.service.management.AssignableRolePlaceManagementService;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand; import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration; import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo; import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter; import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext; import dev.sheldan.abstracto.core.command.execution.CommandParameterKey;
import dev.sheldan.abstracto.core.command.execution.CommandResult; import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition; import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandPrivilegeLevels;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandAutoCompleteService;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import java.util.ArrayList;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import net.dv8tion.jda.api.entities.Role; import net.dv8tion.jda.api.entities.Role;
import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -20,46 +34,96 @@ import java.util.List;
@Component @Component
public class RemoveAssignableRoleCondition extends AbstractConditionableCommand { public class RemoveAssignableRoleCondition extends AbstractConditionableCommand {
private static final String ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER = "name";
private static final String ASSIGNABLE_ROLE_PARAMETER = "role";
private static final String CONDITION_KEY_PARAMETER = "conditionKey";
private static final String REMOVE_ASSIGNABLE_ROLE_CONDITION_RESPONSE_TEMPLATE = "removeAssignableRoleCondition_response";
@Autowired @Autowired
private AssignableRoleConditionService assignableRoleConditionService; private AssignableRoleConditionService assignableRoleConditionService;
@Autowired
private InteractionService interactionService;
@Autowired
private SlashCommandParameterService slashCommandParameterService;
@Autowired
private SlashCommandAutoCompleteService slashCommandAutoCompleteService;
@Autowired
private AssignableRolePlaceManagementService assignableRolePlaceManagementService;
@Autowired
private ServerManagementService serverManagementService;
@Override @Override
public CommandResult execute(CommandContext commandContext) { public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
List<Object> parameters = commandContext.getParameters().getParameters(); String assignableRolePlaceName = slashCommandParameterService.getCommandOption(ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER, event, String.class);
String name = (String) parameters.get(0); Role assignableRole = slashCommandParameterService.getCommandOption(ASSIGNABLE_ROLE_PARAMETER, event, Role.class);
Role role = (Role) parameters.get(1); String conditionKeyString = slashCommandParameterService.getCommandOption(CONDITION_KEY_PARAMETER, event, String.class);
AssignableRoleConditionType configKey = (AssignableRoleConditionType) parameters.get(2);
assignableRoleConditionService.deleteAssignableRoleCondition(name, role, configKey); AssignableRoleConditionType assignableRoleConditionType = CommandParameterKey.getEnumFromKey(AssignableRoleConditionType.class, conditionKeyString);
return CommandResult.fromSuccess(); assignableRoleConditionService.deleteAssignableRoleCondition(assignableRolePlaceName, assignableRole, assignableRoleConditionType);
return interactionService.replyEmbed(REMOVE_ASSIGNABLE_ROLE_CONDITION_RESPONSE_TEMPLATE, event)
.thenApply(interactionHook -> CommandResult.fromSuccess());
}
@Override
public List<String> performAutoComplete(CommandAutoCompleteInteractionEvent event) {
if(slashCommandAutoCompleteService.matchesParameter(event.getFocusedOption(), ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER)) {
String input = event.getFocusedOption().getValue();
AServer server = serverManagementService.loadServer(event.getGuild());
return assignableRolePlaceManagementService.getAssignableRolePlacesWithNamesContaining(input, server)
.stream().map(assignableRolePlace -> assignableRolePlace.getKey().toLowerCase())
.collect(Collectors.toList());
}
return new ArrayList<>();
} }
@Override @Override
public CommandConfiguration getConfiguration() { public CommandConfiguration getConfiguration() {
Parameter placeName = Parameter Parameter placeName = Parameter
.builder() .builder()
.name("name") .name(ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER)
.type(String.class) .type(String.class)
.supportsAutoComplete(true)
.templated(true) .templated(true)
.build(); .build();
Parameter role = Parameter Parameter role = Parameter
.builder() .builder()
.name("role") .name(ASSIGNABLE_ROLE_PARAMETER)
.type(Role.class) .type(Role.class)
.templated(true) .templated(true)
.build(); .build();
Parameter conditionKey = Parameter Parameter conditionKey = Parameter
.builder() .builder()
.name("conditionKey") .name(CONDITION_KEY_PARAMETER)
.type(AssignableRoleConditionType.class) .type(AssignableRoleConditionType.class)
.templated(true) .templated(true)
.build(); .build();
List<Parameter> parameters = Arrays.asList(placeName, role, conditionKey); List<Parameter> parameters = Arrays.asList(placeName, role, conditionKey);
HelpInfo helpInfo = HelpInfo.builder().templated(true).build(); HelpInfo helpInfo = HelpInfo
.builder()
.templated(true)
.build();
SlashCommandConfig slashCommandConfig = SlashCommandConfig
.builder()
.enabled(true)
.defaultPrivilege(SlashCommandPrivilegeLevels.INVITER)
.rootCommandName(AssignableRolePlaceSlashCommandName.ASSIGNABLE_ROLE_PLACE)
.groupName("role")
.commandName("removecondition")
.build();
return CommandConfiguration.builder() return CommandConfiguration.builder()
.name("removeAssignableRoleCondition") .name("removeAssignableRoleCondition")
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES) .module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
.templated(true) .templated(true)
.messageCommandOnly(true) .slashCommandOnly(true)
.slashCommandConfig(slashCommandConfig)
.supportsEmbedException(true) .supportsEmbedException(true)
.causesReaction(true) .causesReaction(true)
.parameters(parameters) .parameters(parameters)

View File

@@ -1,17 +1,31 @@
package dev.sheldan.abstracto.assignableroles.command; package dev.sheldan.abstracto.assignableroles.command;
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition; import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
import dev.sheldan.abstracto.assignableroles.config.AssignableRolePlaceSlashCommandName;
import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService; import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService;
import dev.sheldan.abstracto.assignableroles.service.management.AssignableRolePlaceManagementService;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand; import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration; import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo; import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter; import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext; import dev.sheldan.abstracto.core.command.exception.SlashCommandParameterMissingException;
import dev.sheldan.abstracto.core.command.execution.CommandResult; import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition; import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandPrivilegeLevels;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandAutoCompleteService;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.models.database.ARole; import dev.sheldan.abstracto.core.models.database.ARole;
import dev.sheldan.abstracto.core.models.database.AServer; import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.management.RoleManagementService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService; import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import java.util.ArrayList;
import java.util.stream.Collectors;
import net.dv8tion.jda.api.entities.Role;
import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -26,33 +40,73 @@ import java.util.concurrent.CompletableFuture;
@Component @Component
public class RemoveRoleFromAssignableRolePlace extends AbstractConditionableCommand { public class RemoveRoleFromAssignableRolePlace extends AbstractConditionableCommand {
private static final String ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER = "name";
private static final String ASSIGNABLE_ROLE_PARAMETER = "role";
private static final String REMOVE_ROLE_FROM_ASSIGNABLE_ROLE_PLACE_RESPONSE = "removeRoleFromAssignableRolePlace_response";
@Autowired @Autowired
private AssignableRolePlaceService service; private AssignableRolePlaceService service;
@Autowired @Autowired
private ServerManagementService serverManagementService; private ServerManagementService serverManagementService;
@Autowired
private InteractionService interactionService;
@Autowired
private SlashCommandParameterService slashCommandParameterService;
@Autowired
private RoleManagementService roleManagementService;
@Autowired
private SlashCommandAutoCompleteService slashCommandAutoCompleteService;
@Autowired
private AssignableRolePlaceManagementService assignableRolePlaceManagementService;
@Override @Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) { public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
List<Object> parameters = commandContext.getParameters().getParameters(); String assignableRolePlaceName = slashCommandParameterService.getCommandOption(ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER, event, String.class);
String name = (String) parameters.get(0); ARole actualRole;
ARole role = (ARole) parameters.get(1); if(slashCommandParameterService.hasCommandOptionWithFullType(ASSIGNABLE_ROLE_PARAMETER, event, OptionType.ROLE)) {
AServer server = serverManagementService.loadServer(commandContext.getGuild()); Role role = slashCommandParameterService.getCommandOption(ASSIGNABLE_ROLE_PARAMETER, event, ARole.class, Role.class);
return service.removeRoleFromAssignableRolePlace(server, name, role) actualRole = roleManagementService.findRole(role.getIdLong());
.thenApply(aVoid -> CommandResult.fromSuccess()); } else if(slashCommandParameterService.hasCommandOptionWithFullType(ASSIGNABLE_ROLE_PARAMETER, event, OptionType.STRING)) {
String roleId = slashCommandParameterService.getCommandOption(ASSIGNABLE_ROLE_PARAMETER, event, ARole.class, String.class);
actualRole = roleManagementService.findRole(Long.parseLong(roleId));
} else {
throw new SlashCommandParameterMissingException(ASSIGNABLE_ROLE_PARAMETER);
}
AServer server = serverManagementService.loadServer(event.getGuild());
return service.removeRoleFromAssignableRolePlace(server, assignableRolePlaceName, actualRole)
.thenAccept(unused -> interactionService.replyEmbed(REMOVE_ROLE_FROM_ASSIGNABLE_ROLE_PLACE_RESPONSE, event))
.thenApply(unused -> CommandResult.fromSuccess());
}
@Override
public List<String> performAutoComplete(CommandAutoCompleteInteractionEvent event) {
if(slashCommandAutoCompleteService.matchesParameter(event.getFocusedOption(), ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER)) {
String input = event.getFocusedOption().getValue();
AServer server = serverManagementService.loadServer(event.getGuild());
return assignableRolePlaceManagementService.getAssignableRolePlacesWithNamesContaining(input, server)
.stream().map(assignableRolePlace -> assignableRolePlace.getKey().toLowerCase())
.collect(Collectors.toList());
}
return new ArrayList<>();
} }
@Override @Override
public CommandConfiguration getConfiguration() { public CommandConfiguration getConfiguration() {
Parameter rolePostName = Parameter Parameter rolePostName = Parameter
.builder() .builder()
.name("name") .name(ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER)
.type(String.class) .type(String.class)
.supportsAutoComplete(true)
.templated(true) .templated(true)
.build(); .build();
Parameter role = Parameter Parameter role = Parameter
.builder() .builder()
.name("role") .name(ASSIGNABLE_ROLE_PARAMETER)
.type(ARole.class) .type(ARole.class)
.templated(true) .templated(true)
.build(); .build();
@@ -61,13 +115,24 @@ public class RemoveRoleFromAssignableRolePlace extends AbstractConditionableComm
.builder() .builder()
.templated(true) .templated(true)
.build(); .build();
SlashCommandConfig slashCommandConfig = SlashCommandConfig
.builder()
.enabled(true)
.defaultPrivilege(SlashCommandPrivilegeLevels.INVITER)
.rootCommandName(AssignableRolePlaceSlashCommandName.ASSIGNABLE_ROLE_PLACE)
.groupName("role")
.commandName("remove")
.build();
return CommandConfiguration.builder() return CommandConfiguration.builder()
.name("removeRoleFromAssignableRolePlace") .name("removeRoleFromAssignableRolePlace")
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES) .module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
.templated(true) .templated(true)
.causesReaction(true) .causesReaction(true)
.async(true) .async(true)
.messageCommandOnly(true) .slashCommandConfig(slashCommandConfig)
.slashCommandOnly(true)
.supportsEmbedException(true) .supportsEmbedException(true)
.parameters(parameters) .parameters(parameters)
.help(helpInfo) .help(helpInfo)

View File

@@ -1,18 +1,27 @@
package dev.sheldan.abstracto.assignableroles.command; package dev.sheldan.abstracto.assignableroles.command;
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition; import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
import dev.sheldan.abstracto.assignableroles.config.AssignableRolePlaceSlashCommandName;
import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService; import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService;
import dev.sheldan.abstracto.assignableroles.service.management.AssignableRolePlaceManagementService;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand; import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration; import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo; import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter; import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult; import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition; import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandPrivilegeLevels;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandAutoCompleteService;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.models.database.AServer; import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService; import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import java.util.ArrayList;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -28,30 +37,54 @@ import java.util.concurrent.CompletableFuture;
@Slf4j @Slf4j
public class SetupAssignableRolePlace extends AbstractConditionableCommand { public class SetupAssignableRolePlace extends AbstractConditionableCommand {
private static final String ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER = "name";
private static final String SETUP_ASSIGNABLE_ROLE_PLACE_RESPONSE_TEMPLATE = "setupAssignableRolePlace_response";
@Autowired @Autowired
private AssignableRolePlaceService service; private AssignableRolePlaceService service;
@Autowired
private ChannelService channelService;
@Autowired @Autowired
private ServerManagementService serverManagementService; private ServerManagementService serverManagementService;
@Autowired
private InteractionService interactionService;
@Autowired
private SlashCommandParameterService slashCommandParameterService;
@Autowired
private SlashCommandAutoCompleteService slashCommandAutoCompleteService;
@Autowired
private AssignableRolePlaceManagementService assignableRolePlaceManagementService;
@Override @Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) { public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
List<Object> parameters = commandContext.getParameters().getParameters(); String assignableRolePlaceName = slashCommandParameterService.getCommandOption(ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER, event, String.class);
String name = (String) parameters.get(0); AServer server = serverManagementService.loadServer(event.getGuild());
AServer server = serverManagementService.loadServer(commandContext.getGuild()); return service.setupAssignableRolePlace(server, assignableRolePlaceName)
return service.setupAssignableRolePlace(server, name) .thenAccept(unused -> interactionService.replyEmbed(SETUP_ASSIGNABLE_ROLE_PLACE_RESPONSE_TEMPLATE, event))
.thenApply(aVoid -> CommandResult.fromSuccess()); .thenApply(unused -> CommandResult.fromSuccess());
}
@Override
public List<String> performAutoComplete(CommandAutoCompleteInteractionEvent event) {
if(slashCommandAutoCompleteService.matchesParameter(event.getFocusedOption(), ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER)) {
String input = event.getFocusedOption().getValue();
AServer server = serverManagementService.loadServer(event.getGuild());
return assignableRolePlaceManagementService.getAssignableRolePlacesWithNamesContaining(input, server)
.stream().map(assignableRolePlace -> assignableRolePlace.getKey().toLowerCase())
.collect(Collectors.toList());
}
return new ArrayList<>();
} }
@Override @Override
public CommandConfiguration getConfiguration() { public CommandConfiguration getConfiguration() {
Parameter rolePostName = Parameter Parameter rolePostName = Parameter
.builder() .builder()
.name("name") .name(ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER)
.type(String.class) .type(String.class)
.supportsAutoComplete(true)
.templated(true) .templated(true)
.build(); .build();
List<Parameter> parameters = Arrays.asList(rolePostName); List<Parameter> parameters = Arrays.asList(rolePostName);
@@ -59,12 +92,23 @@ public class SetupAssignableRolePlace extends AbstractConditionableCommand {
.builder() .builder()
.templated(true) .templated(true)
.build(); .build();
SlashCommandConfig slashCommandConfig = SlashCommandConfig
.builder()
.enabled(true)
.defaultPrivilege(SlashCommandPrivilegeLevels.INVITER)
.rootCommandName(AssignableRolePlaceSlashCommandName.ASSIGNABLE_ROLE_PLACE)
.groupName("place")
.commandName("setup")
.build();
return CommandConfiguration.builder() return CommandConfiguration.builder()
.name("setupAssignableRolePlace") .name("setupAssignableRolePlace")
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES) .module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
.templated(true) .templated(true)
.async(true) .async(true)
.messageCommandOnly(true) .slashCommandOnly(true)
.slashCommandConfig(slashCommandConfig)
.supportsEmbedException(true) .supportsEmbedException(true)
.causesReaction(true) .causesReaction(true)
.parameters(parameters) .parameters(parameters)

View File

@@ -1,18 +1,20 @@
package dev.sheldan.abstracto.assignableroles.command; package dev.sheldan.abstracto.assignableroles.command;
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition; import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
import dev.sheldan.abstracto.assignableroles.config.AssignableRolePlaceSlashCommandName;
import dev.sheldan.abstracto.assignableroles.model.template.AssignableRolePlaceConfig; import dev.sheldan.abstracto.assignableroles.model.template.AssignableRolePlaceConfig;
import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService; import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand; import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration; import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo; import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter; import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult; import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition; import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.service.ChannelService; import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService; import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.utils.FutureUtils; import dev.sheldan.abstracto.core.interaction.slash.SlashCommandPrivilegeLevels;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -30,27 +32,27 @@ public class ShowAssignableRolePlaceConfig extends AbstractConditionableCommand
private AssignableRolePlaceService service; private AssignableRolePlaceService service;
@Autowired @Autowired
private ServerManagementService serverManagementService; private InteractionService interactionService;
@Autowired @Autowired
private ChannelService channelService; private SlashCommandParameterService slashCommandParameterService;
public static final String ASSIGNABLE_ROLES_CONFIG_POST_TEMPLATE_KEY = "assignable_roles_config_post"; private static final String ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER = "name";
private static final String ASSIGNABLE_ROLES_CONFIG_POST_TEMPLATE_KEY = "assignable_roles_config_post";
@Override @Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) { public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
List<Object> parameters = commandContext.getParameters().getParameters(); String assignableRolePlaceName = slashCommandParameterService.getCommandOption(ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER, event, String.class);
String name = (String) parameters.get(0); AssignableRolePlaceConfig config = service.getAssignableRolePlaceConfig(event.getGuild(), assignableRolePlaceName);
AssignableRolePlaceConfig config = service.getAssignableRolePlaceConfig(commandContext.getGuild(), name); return interactionService.replyEmbed(ASSIGNABLE_ROLES_CONFIG_POST_TEMPLATE_KEY, config, event)
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInMessageChannel(ASSIGNABLE_ROLES_CONFIG_POST_TEMPLATE_KEY, config, commandContext.getChannel())) .thenApply(interactionHook -> CommandResult.fromSuccess());
.thenApply(unused -> CommandResult.fromSuccess());
} }
@Override @Override
public CommandConfiguration getConfiguration() { public CommandConfiguration getConfiguration() {
Parameter rolePostName = Parameter Parameter rolePostName = Parameter
.builder() .builder()
.name("name") .name(ASSIGNABLE_ROLE_PLACE_NAME_PARAMETER)
.type(String.class) .type(String.class)
.templated(true) .templated(true)
.build(); .build();
@@ -59,13 +61,24 @@ public class ShowAssignableRolePlaceConfig extends AbstractConditionableCommand
.builder() .builder()
.templated(true) .templated(true)
.build(); .build();
SlashCommandConfig slashCommandConfig = SlashCommandConfig
.builder()
.enabled(true)
.defaultPrivilege(SlashCommandPrivilegeLevels.INVITER)
.rootCommandName(AssignableRolePlaceSlashCommandName.ASSIGNABLE_ROLE_PLACE)
.groupName("place")
.commandName("showconfig")
.build();
return CommandConfiguration.builder() return CommandConfiguration.builder()
.name("showAssignableRolePlaceConfig") .name("showAssignableRolePlaceConfig")
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES) .module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
.templated(true) .templated(true)
.async(true) .async(true)
.causesReaction(false) .causesReaction(false)
.messageCommandOnly(true) .slashCommandOnly(true)
.slashCommandConfig(slashCommandConfig)
.supportsEmbedException(true) .supportsEmbedException(true)
.parameters(parameters) .parameters(parameters)
.help(helpInfo) .help(helpInfo)

View File

@@ -1,6 +1,7 @@
package dev.sheldan.abstracto.assignableroles.command; package dev.sheldan.abstracto.assignableroles.command;
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition; import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
import dev.sheldan.abstracto.assignableroles.config.AssignableRolePlaceSlashCommandName;
import dev.sheldan.abstracto.assignableroles.model.template.AssignablePlaceOverview; import dev.sheldan.abstracto.assignableroles.model.template.AssignablePlaceOverview;
import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService; import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand; import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
@@ -9,10 +10,13 @@ import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.execution.CommandContext; import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult; import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition; import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandPrivilegeLevels;
import dev.sheldan.abstracto.core.models.database.AServer; import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.ChannelService; import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.core.utils.FutureUtils; import dev.sheldan.abstracto.core.utils.FutureUtils;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -28,13 +32,13 @@ public class ShowAssignableRolePlaces extends AbstractConditionableCommand {
@Autowired @Autowired
private AssignableRolePlaceService service; private AssignableRolePlaceService service;
@Autowired
private ServerManagementService serverManagementService;
@Autowired @Autowired
private ChannelService channelService; private ChannelService channelService;
public static final String ASSIGNABLE_ROLE_PLACES_OVERVIEW_TEMPLATE_KEY = "assignable_role_places_overview"; @Autowired
private InteractionService interactionService;
private static final String ASSIGNABLE_ROLE_PLACES_OVERVIEW_TEMPLATE_KEY = "assignable_role_places_overview";
@Override @Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) { public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
@@ -43,17 +47,35 @@ public class ShowAssignableRolePlaces extends AbstractConditionableCommand {
.thenApply(unused -> CommandResult.fromSuccess()); .thenApply(unused -> CommandResult.fromSuccess());
} }
@Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
AssignablePlaceOverview model = service.getAssignableRolePlaceOverview(event.getGuild());
return interactionService.replyEmbed(ASSIGNABLE_ROLE_PLACES_OVERVIEW_TEMPLATE_KEY, model, event)
.thenApply(interactionHook -> CommandResult.fromSuccess());
}
@Override @Override
public CommandConfiguration getConfiguration() { public CommandConfiguration getConfiguration() {
HelpInfo helpInfo = HelpInfo HelpInfo helpInfo = HelpInfo
.builder() .builder()
.templated(true) .templated(true)
.build(); .build();
SlashCommandConfig slashCommandConfig = SlashCommandConfig
.builder()
.enabled(true)
.defaultPrivilege(SlashCommandPrivilegeLevels.INVITER)
.rootCommandName(AssignableRolePlaceSlashCommandName.ASSIGNABLE_ROLE_PLACE)
.groupName("place")
.commandName("show")
.build();
return CommandConfiguration.builder() return CommandConfiguration.builder()
.name("showAssignableRolePlaces") .name("showAssignableRolePlaces")
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES) .module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
.templated(true) .templated(true)
.messageCommandOnly(true) .slashCommandOnly(true)
.slashCommandConfig(slashCommandConfig)
.async(true) .async(true)
.supportsEmbedException(true) .supportsEmbedException(true)
.help(helpInfo) .help(helpInfo)

View File

@@ -37,5 +37,6 @@ public interface AssignableRolePlaceRepository extends JpaRepository<AssignableR
* @return A list of {@link AssignableRolePlace places} which were found in the given {@link AServer server} * @return A list of {@link AssignableRolePlace places} which were found in the given {@link AServer server}
*/ */
List<AssignableRolePlace> findByServer(AServer server); List<AssignableRolePlace> findByServer(AServer server);
List<AssignableRolePlace> findByKeyContainingIgnoreCaseAndServer(String name, AServer server);
} }

View File

@@ -14,7 +14,6 @@ import dev.sheldan.abstracto.core.exception.EmoteNotUsableException;
import dev.sheldan.abstracto.core.interaction.ComponentPayloadManagementService; import dev.sheldan.abstracto.core.interaction.ComponentPayloadManagementService;
import dev.sheldan.abstracto.core.interaction.ComponentPayloadService; import dev.sheldan.abstracto.core.interaction.ComponentPayloadService;
import dev.sheldan.abstracto.core.interaction.ComponentService; import dev.sheldan.abstracto.core.interaction.ComponentService;
import dev.sheldan.abstracto.core.models.FullEmote;
import dev.sheldan.abstracto.core.models.database.AChannel; import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.ARole; import dev.sheldan.abstracto.core.models.database.ARole;
import dev.sheldan.abstracto.core.models.database.AServer; import dev.sheldan.abstracto.core.models.database.AServer;
@@ -28,8 +27,10 @@ import dev.sheldan.abstracto.core.templating.service.TemplateService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.*; import net.dv8tion.jda.api.entities.*;
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel;
import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel; import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel;
import net.dv8tion.jda.api.interactions.components.buttons.ButtonStyle; import net.dv8tion.jda.api.entities.emoji.CustomEmoji;
import net.dv8tion.jda.api.entities.emoji.Emoji;
import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.BooleanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -58,9 +59,6 @@ public class AssignableRolePlaceServiceBean implements AssignableRolePlaceServic
@Autowired @Autowired
private ChannelService channelService; private ChannelService channelService;
@Autowired
private GuildService guildService;
@Autowired @Autowired
private EmoteService emoteService; private EmoteService emoteService;
@@ -104,7 +102,7 @@ public class AssignableRolePlaceServiceBean implements AssignableRolePlaceServic
@Override @Override
@Transactional @Transactional
public CompletableFuture<Void> addRoleToAssignableRolePlace(AServer server, String placeName, Role role, FullEmote fakeEmote, String description) { public CompletableFuture<Void> addRoleToAssignableRolePlace(AServer server, String placeName, Role role, Emoji emoji, String description) {
AssignableRolePlace assignableRolePlace = rolePlaceManagementService.findByServerAndKey(server, placeName); AssignableRolePlace assignableRolePlace = rolePlaceManagementService.findByServerAndKey(server, placeName);
if (assignableRolePlace.getAssignableRoles().size() > MAX_ASSIGNABLE_ROLES_PER_POST) { if (assignableRolePlace.getAssignableRoles().size() > MAX_ASSIGNABLE_ROLES_PER_POST) {
log.info("Assignable role place {} has already {} roles. Not possible to add more.", assignableRolePlace.getId(), assignableRolePlace.getAssignableRoles().size()); log.info("Assignable role place {} has already {} roles. Not possible to add more.", assignableRolePlace.getId(), assignableRolePlace.getAssignableRoles().size());
@@ -115,26 +113,35 @@ public class AssignableRolePlaceServiceBean implements AssignableRolePlaceServic
} }
Long placeId = assignableRolePlace.getId(); Long placeId = assignableRolePlace.getId();
Long serverId = server.getId(); Long serverId = server.getId();
if (fakeEmote != null && fakeEmote.getEmote() != null) { if (emoji instanceof CustomEmoji customEmoji) {
// it only may be unusable if its a custom emote // it only may be unusable if its a custom emote
log.debug("Using custom emote {} to create assignable role {} for assignable role place {} in server {}.", log.debug("Using custom emote {} to create assignable role {} for assignable role place {} in server {}.",
fakeEmote.getEmote().getId(), role.getId(), placeId, serverId); customEmoji.getId(), role.getId(), placeId, serverId);
if (!emoteService.isEmoteUsableByBot(fakeEmote.getEmote())) { if (!emoteService.isEmoteUsableByBot(customEmoji)) {
throw new EmoteNotUsableException(fakeEmote.getEmote()); throw new EmoteNotUsableException(customEmoji);
} }
} }
Optional<GuildMessageChannel> channelOptional = channelService.getMessageChannelFromServerOptional(server.getId(), assignableRolePlace.getChannel().getId()); Optional<GuildMessageChannel> channelOptional = channelService.getMessageChannelFromServerOptional(server.getId(), assignableRolePlace.getChannel().getId());
if (channelOptional.isPresent()) { if (channelOptional.isPresent()) {
GuildMessageChannel textChannel = channelOptional.get(); GuildMessageChannel textChannel = channelOptional.get();
String buttonId = componentService.generateComponentId(); String buttonId = componentService.generateComponentId();
String emoteMarkdown = fakeEmote != null ? fakeEmote.getEmoteRepr() : null; String emoteMarkdown = emoji != null ? emoji.getFormatted() : null;
if (assignableRolePlace.getMessageId() != null) { if (assignableRolePlace.getMessageId() != null) {
AssignablePostMessage model = prepareAssignablePostMessageModel(assignableRolePlace);
model.getRoles().add(AssignablePostRole
.builder()
.componentId(buttonId)
.emoteMarkDown(emoteMarkdown)
.description(description)
.build());
MessageToSend messageToSend = templateService.renderEmbedTemplate(ASSIGNABLE_ROLES_POST_TEMPLATE_KEY, model, assignableRolePlace.getServer().getId());
log.debug("Assignable role place {} has already message post with ID {} - updating.", assignableRolePlace.getId(), assignableRolePlace.getMessageId()); log.debug("Assignable role place {} has already message post with ID {} - updating.", assignableRolePlace.getId(), assignableRolePlace.getMessageId());
return componentService.addButtonToMessage(assignableRolePlace.getMessageId(), textChannel, buttonId, description, emoteMarkdown, ButtonStyle.SECONDARY) return messageService.editMessageInChannel(textChannel, messageToSend, assignableRolePlace.getMessageId()).thenAccept(unused -> {
.thenAccept(message -> self.persistAssignableRoleAddition(placeId, role, description, fakeEmote, buttonId)); self.persistAssignableRoleAddition(placeId, role, description, emoji, buttonId);
});
} else { } else {
log.info("Assignable role place {} is not yet setup - only adding role to the database.", assignableRolePlace.getId()); log.info("Assignable role place {} is not yet setup - only adding role to the database.", assignableRolePlace.getId());
self.persistAssignableRoleAddition(placeId, role, description, fakeEmote, buttonId); self.persistAssignableRoleAddition(placeId, role, description, emoji, buttonId);
return CompletableFuture.completedFuture(null); return CompletableFuture.completedFuture(null);
} }
} else { } else {
@@ -143,11 +150,11 @@ public class AssignableRolePlaceServiceBean implements AssignableRolePlaceServic
} }
@Transactional @Transactional
public void persistAssignableRoleAddition(Long placeId, Role role, String description, FullEmote fakeEmote, String componentId) { public void persistAssignableRoleAddition(Long placeId, Role role, String description, Emoji emoji, String componentId) {
AssignableRolePlace place = assignableRolePlaceManagementServiceBean.findByPlaceId(placeId); AssignableRolePlace place = assignableRolePlaceManagementServiceBean.findByPlaceId(placeId);
log.info("Adding role {} to assignable role place {} with component ID {}.", role.getId(), place.getId(), componentId); log.info("Adding role {} to assignable role place {} with component ID {}.", role.getId(), place.getId(), componentId);
ComponentPayload payload = persistButtonCallback(place, componentId, role.getIdLong()); ComponentPayload payload = persistButtonCallback(place, componentId, role.getIdLong());
assignableRoleManagementServiceBean.addRoleToPlace(fakeEmote, role, description, place, payload); assignableRoleManagementServiceBean.addRoleToPlace(emoji, role, description, place, payload);
} }
@Override @Override
@@ -172,7 +179,7 @@ public class AssignableRolePlaceServiceBean implements AssignableRolePlaceServic
return channelService.retrieveMessageInChannel(assignableRolePlace.getServer().getId(), assignableRolePlace.getChannel().getId(), assignableRolePlace.getMessageId()) return channelService.retrieveMessageInChannel(assignableRolePlace.getServer().getId(), assignableRolePlace.getChannel().getId(), assignableRolePlace.getMessageId())
.thenCompose(message -> { .thenCompose(message -> {
log.debug("Updating message {} to remove component with ID {}.", message.getIdLong(), componentId); log.debug("Updating message {} to remove component with ID {}.", message.getIdLong(), componentId);
return componentService.removeComponentWithId(message, componentId, true); return componentService.removeComponentById(message, componentId).thenAccept(message1 -> {});
} }
); );
} }
@@ -267,8 +274,8 @@ public class AssignableRolePlaceServiceBean implements AssignableRolePlaceServic
log.info("Deactivating assignable role place {} in server {}", place.getId(), place.getServer().getId()); log.info("Deactivating assignable role place {} in server {}", place.getId(), place.getServer().getId());
return channelService.retrieveMessageInChannel(place.getServer().getId(), place.getChannel().getId(), place.getMessageId()) return channelService.retrieveMessageInChannel(place.getServer().getId(), place.getChannel().getId(), place.getMessageId())
.thenCompose(message -> .thenCompose(message ->
componentService.disableAllButtons(message) componentService.disableAllComponents(message)
); ).thenAccept(message -> {});
} }
@Override @Override
@@ -281,8 +288,8 @@ public class AssignableRolePlaceServiceBean implements AssignableRolePlaceServic
log.info("Activating assignable role place {} in server {}", place.getId(), place.getServer().getId()); log.info("Activating assignable role place {} in server {}", place.getId(), place.getServer().getId());
return channelService.retrieveMessageInChannel(place.getServer().getId(), place.getChannel().getId(), place.getMessageId()) return channelService.retrieveMessageInChannel(place.getServer().getId(), place.getChannel().getId(), place.getMessageId())
.thenCompose(message -> .thenCompose(message ->
componentService.enableAllButtons(message) componentService.enableAllComponents(message)
); ).thenAccept(message -> {});
} }
@Override @Override
@@ -353,7 +360,7 @@ public class AssignableRolePlaceServiceBean implements AssignableRolePlaceServic
} }
@Override @Override
public CompletableFuture<Void> moveAssignableRolePlace(AServer server, String name, TextChannel newChannel) { public CompletableFuture<Void> moveAssignableRolePlace(AServer server, String name, GuildMessageChannel newChannel) {
AssignableRolePlace place = rolePlaceManagementService.findByServerAndKey(server, name); AssignableRolePlace place = rolePlaceManagementService.findByServerAndKey(server, name);
log.info("Moving assignable role place {} from channel {} to channel {} in guild {}.", log.info("Moving assignable role place {} from channel {} to channel {} in guild {}.",
place.getId(), place.getChannel().getId(), newChannel.getId(), newChannel.getGuild().getIdLong()); place.getId(), place.getChannel().getId(), newChannel.getId(), newChannel.getGuild().getIdLong());
@@ -381,7 +388,7 @@ public class AssignableRolePlaceServiceBean implements AssignableRolePlaceServic
} }
@Transactional @Transactional
public void updateAssignableRolePlaceChannel(String name, TextChannel textChannel) { public void updateAssignableRolePlaceChannel(String name, GuildChannel textChannel) {
AChannel channel = channelManagementService.loadChannel(textChannel.getIdLong()); AChannel channel = channelManagementService.loadChannel(textChannel.getIdLong());
log.info("Setting assignable role place to channel {}.", textChannel.getIdLong()); log.info("Setting assignable role place to channel {}.", textChannel.getIdLong());
rolePlaceManagementService.moveAssignableRolePlace(name, channel); rolePlaceManagementService.moveAssignableRolePlace(name, channel);
@@ -400,7 +407,10 @@ public class AssignableRolePlaceServiceBean implements AssignableRolePlaceServic
public void deleteAssignableRolePlaceInDatabase(Long placeId) { public void deleteAssignableRolePlaceInDatabase(Long placeId) {
AssignableRolePlace place = rolePlaceManagementService.findByPlaceId(placeId); AssignableRolePlace place = rolePlaceManagementService.findByPlaceId(placeId);
place.getAssignableRoles() place.getAssignableRoles()
.forEach(assignableRole -> componentPayloadManagementService.deletePayload(assignableRole.getComponentPayload())); .forEach(assignableRole -> {
assignedRoleUserManagementServiceBean.removeAssignedRoleFromUsers(assignableRole);
componentPayloadManagementService.deletePayload(assignableRole.getComponentPayload());
});
rolePlaceManagementService.deleteAssignablePlace(place); rolePlaceManagementService.deleteAssignablePlace(place);
} }
@@ -414,13 +424,15 @@ public class AssignableRolePlaceServiceBean implements AssignableRolePlaceServic
@Override @Override
public CompletableFuture<Void> changeConfiguration(AServer server, String name, AssignableRolePlaceParameterKey keyToChange, String newValue) { public CompletableFuture<Void> changeConfiguration(AServer server, String name, AssignableRolePlaceParameterKey keyToChange, String newValue) {
Boolean booleanValue = BooleanUtils.toBooleanObject(newValue);
if (booleanValue == null) {
throw new CommandParameterKeyValueWrongTypeException(Arrays.asList("yes", "no", "true", "false", "on", "off"));
}
if (keyToChange == AssignableRolePlaceParameterKey.UNIQUE) { if (keyToChange == AssignableRolePlaceParameterKey.UNIQUE) {
Boolean booleanValue = BooleanUtils.toBooleanObject(newValue);
if (booleanValue == null) {
throw new CommandParameterKeyValueWrongTypeException(Arrays.asList("yes", "no", "true", "false", "on", "off"));
}
setAssignablePlaceUniqueTo(server, name, booleanValue); setAssignablePlaceUniqueTo(server, name, booleanValue);
return CompletableFuture.completedFuture(null); return CompletableFuture.completedFuture(null);
} else if(keyToChange == AssignableRolePlaceParameterKey.TEXT) {
return changeTextAsync(server, name, newValue);
} }
throw new AssignableRolePlaceIllegalConfigurationException(); throw new AssignableRolePlaceIllegalConfigurationException();
} }
@@ -518,7 +530,7 @@ public class AssignableRolePlaceServiceBean implements AssignableRolePlaceServic
@Transactional @Transactional
public CompletableFuture<Void> setupAssignableRolePlaceInChannel(Long serverId, Long assignablePlaceId, TextChannel textChannel) { public CompletableFuture<Void> setupAssignableRolePlaceInChannel(Long serverId, Long assignablePlaceId, GuildMessageChannel textChannel) {
AssignableRolePlace assignableRolePlace = rolePlaceManagementService.findByPlaceId(assignablePlaceId); AssignableRolePlace assignableRolePlace = rolePlaceManagementService.findByPlaceId(assignablePlaceId);
log.info("Sending assignable role place posts for place {} in channel {} in server {}.", assignableRolePlace.getId(), textChannel.getId(), serverId); log.info("Sending assignable role place posts for place {} in channel {} in server {}.", assignableRolePlace.getId(), textChannel.getId(), serverId);
return sendAssignablePostMessage(assignableRolePlace, textChannel); return sendAssignablePostMessage(assignableRolePlace, textChannel);

View File

@@ -6,7 +6,6 @@ import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlaceT
import dev.sheldan.abstracto.assignableroles.model.database.AssignedRoleUser; import dev.sheldan.abstracto.assignableroles.model.database.AssignedRoleUser;
import dev.sheldan.abstracto.assignableroles.repository.AssignableRoleRepository; import dev.sheldan.abstracto.assignableroles.repository.AssignableRoleRepository;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException; import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.core.models.FullEmote;
import dev.sheldan.abstracto.core.models.database.ARole; import dev.sheldan.abstracto.core.models.database.ARole;
import dev.sheldan.abstracto.core.models.database.ComponentPayload; import dev.sheldan.abstracto.core.models.database.ComponentPayload;
import dev.sheldan.abstracto.core.service.EmoteService; import dev.sheldan.abstracto.core.service.EmoteService;
@@ -14,6 +13,7 @@ import dev.sheldan.abstracto.core.service.management.EmoteManagementService;
import dev.sheldan.abstracto.core.service.management.RoleManagementService; import dev.sheldan.abstracto.core.service.management.RoleManagementService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Role; import net.dv8tion.jda.api.entities.Role;
import net.dv8tion.jda.api.entities.emoji.Emoji;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -39,12 +39,12 @@ public class AssignableRoleManagementServiceBean implements AssignableRoleManage
private EmoteService emoteService; private EmoteService emoteService;
@Override @Override
public AssignableRole addRoleToPlace(FullEmote emote, Role role, String description, AssignableRolePlace place, ComponentPayload componentPayload) { public AssignableRole addRoleToPlace(Emoji emoji, Role role, String description, AssignableRolePlace place, ComponentPayload componentPayload) {
ARole arole = roleManagementService.findRole(role.getIdLong()); ARole arole = roleManagementService.findRole(role.getIdLong());
AssignableRole roleToAdd = AssignableRole AssignableRole roleToAdd = AssignableRole
.builder() .builder()
.assignablePlace(place) .assignablePlace(place)
.emoteMarkdown(emote != null ? emote.getEmoteRepr() : null) .emoteMarkdown(emoji != null ? emoji.getFormatted() : null)
.role(arole) .role(arole)
.componentPayload(componentPayload) .componentPayload(componentPayload)
.server(place.getServer()) .server(place.getServer())

View File

@@ -86,4 +86,8 @@ public class AssignableRolePlaceManagementServiceBean implements AssignableRoleP
} }
@Override
public List<AssignableRolePlace> getAssignableRolePlacesWithNamesContaining(String name, AServer server) {
return repository.findByKeyContainingIgnoreCaseAndServer(name, server);
}
} }

View File

@@ -47,7 +47,6 @@ public class AssignedRoleUserManagementServiceBean implements AssignedRoleUserMa
@Override @Override
public void removeAssignedRoleFromUsers(AssignableRole assignableRole, List<AssignedRoleUser> users) { public void removeAssignedRoleFromUsers(AssignableRole assignableRole, List<AssignedRoleUser> users) {
log.info("Clearing all assignable role {} for {} users.", assignableRole.getId(), users.size()); log.info("Clearing all assignable role {} for {} users.", assignableRole.getId(), users.size());
assignableRole.getAssignedUsers().removeAll(users);
users.forEach(roleUser -> roleUser.getRoles().remove(assignableRole)); users.forEach(roleUser -> roleUser.getRoles().remove(assignableRole));
} }

View File

@@ -0,0 +1,6 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
<include file="delete/delete.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>

View File

@@ -0,0 +1,30 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
<property name="editAssignableRolePlaceTextCommandId" value="(SELECT id FROM command WHERE name = 'editAssignableRolePlaceText')"/>
<changeSet author="Sheldan" id="delete-editAssignableRolePlaceText_command">
<sql >
delete from ${database.defaultSchemaName}.command_in_server_allowed_role
where command_in_server_id
in
(select
command_in_server_id
from ${database.defaultSchemaName}.command_in_server
where command_id = (SELECT id FROM ${database.defaultSchemaName}.command WHERE name = 'editAssignableRolePlaceText'));
delete from ${database.defaultSchemaName}.command_in_server_alias
where command_in_server_id
in
(select command_in_server_id
from ${database.defaultSchemaName}.command_in_server
where command_id =
(SELECT id FROM ${database.defaultSchemaName}.command WHERE name = 'editAssignableRolePlaceText'))
</sql>
<delete tableName="command_in_server">
<where>command_id=${editAssignableRolePlaceTextCommandId}</where>
</delete>
<delete tableName="command">
<where>id=${editAssignableRolePlaceTextCommandId}</where>
</delete>
</changeSet>
</databaseChangeLog>

View File

@@ -0,0 +1,6 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
<include file="command.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>

View File

@@ -4,4 +4,5 @@
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" > xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
<include file="1.0-assignableRoles/collection.xml" relativeToChangelogFile="true"/> <include file="1.0-assignableRoles/collection.xml" relativeToChangelogFile="true"/>
<include file="1.3.4/collection.xml" relativeToChangelogFile="true"/> <include file="1.3.4/collection.xml" relativeToChangelogFile="true"/>
<include file="1.6.4/collection.xml" relativeToChangelogFile="true"/>
</databaseChangeLog> </databaseChangeLog>

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<groupId>dev.sheldan.abstracto.modules</groupId> <groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>assignable-roles</artifactId> <artifactId>assignable-roles</artifactId>
<version>1.5.55</version> <version>1.6.21-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>assignable-roles-int</artifactId> <artifactId>assignable-roles-int</artifactId>

View File

@@ -5,5 +5,5 @@ import lombok.Getter;
@Getter @Getter
public enum AssignableRolePlaceParameterKey implements CommandParameterKey { public enum AssignableRolePlaceParameterKey implements CommandParameterKey {
UNIQUE UNIQUE, TEXT
} }

View File

@@ -0,0 +1,5 @@
package dev.sheldan.abstracto.assignableroles.config;
public class AssignableRolePlaceSlashCommandName {
public static final String ASSIGNABLE_ROLE_PLACE = "assignablerole";
}

View File

@@ -74,7 +74,7 @@ public class AssignableRole implements Serializable {
private String description; private String description;
@OneToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE}) @OneToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "component_id", nullable = false) @JoinColumn(name = "component_id")
private ComponentPayload componentPayload; private ComponentPayload componentPayload;
/** /**

View File

@@ -5,20 +5,20 @@ import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlaceType; import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlaceType;
import dev.sheldan.abstracto.assignableroles.model.template.AssignablePlaceOverview; import dev.sheldan.abstracto.assignableroles.model.template.AssignablePlaceOverview;
import dev.sheldan.abstracto.assignableroles.model.template.AssignableRolePlaceConfig; import dev.sheldan.abstracto.assignableroles.model.template.AssignableRolePlaceConfig;
import dev.sheldan.abstracto.core.models.FullEmote;
import dev.sheldan.abstracto.core.models.database.AChannel; import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.ARole; import dev.sheldan.abstracto.core.models.database.ARole;
import dev.sheldan.abstracto.core.models.database.AServer; import dev.sheldan.abstracto.core.models.database.AServer;
import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Role; import net.dv8tion.jda.api.entities.Role;
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel;
import net.dv8tion.jda.api.entities.emoji.Emoji;
public interface AssignableRolePlaceService { public interface AssignableRolePlaceService {
void createAssignableRolePlace(String name, AChannel channel, String text, AssignableRolePlaceType type); void createAssignableRolePlace(String name, AChannel channel, String text, AssignableRolePlaceType type);
CompletableFuture<Void> addRoleToAssignableRolePlace(AServer server, String placeName, Role role, FullEmote emote, String description); CompletableFuture<Void> addRoleToAssignableRolePlace(AServer server, String placeName, Role role, Emoji emoji, String description);
CompletableFuture<Void> removeRoleFromAssignableRolePlace(AServer server, String placeName, ARole role); CompletableFuture<Void> removeRoleFromAssignableRolePlace(AServer server, String placeName, ARole role);
@@ -48,7 +48,7 @@ public interface AssignableRolePlaceService {
AssignableRolePlaceConfig getAssignableRolePlaceConfig(Guild guild, String name); AssignableRolePlaceConfig getAssignableRolePlaceConfig(Guild guild, String name);
CompletableFuture<Void> moveAssignableRolePlace(AServer server, String name, TextChannel newChannel); CompletableFuture<Void> moveAssignableRolePlace(AServer server, String name, GuildMessageChannel newChannel);
CompletableFuture<Void> deleteAssignableRolePlace(AServer server, String name); CompletableFuture<Void> deleteAssignableRolePlace(AServer server, String name);

View File

@@ -4,14 +4,14 @@ import dev.sheldan.abstracto.assignableroles.model.database.AssignableRole;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace; import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlaceType; import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlaceType;
import dev.sheldan.abstracto.assignableroles.model.database.AssignedRoleUser; import dev.sheldan.abstracto.assignableroles.model.database.AssignedRoleUser;
import dev.sheldan.abstracto.core.models.FullEmote;
import dev.sheldan.abstracto.core.models.database.ComponentPayload; import dev.sheldan.abstracto.core.models.database.ComponentPayload;
import net.dv8tion.jda.api.entities.Role; import net.dv8tion.jda.api.entities.Role;
import java.util.List; import java.util.List;
import net.dv8tion.jda.api.entities.emoji.Emoji;
public interface AssignableRoleManagementService { public interface AssignableRoleManagementService {
AssignableRole addRoleToPlace(FullEmote emote, Role role, String description, AssignableRolePlace place, ComponentPayload componentPayload); AssignableRole addRoleToPlace(Emoji emoji, Role role, String description, AssignableRolePlace place, ComponentPayload componentPayload);
AssignableRole getByAssignableRoleId(Long assignableRoleId); AssignableRole getByAssignableRoleId(Long assignableRoleId);
void deleteAssignableRole(AssignableRole assignableRole); void deleteAssignableRole(AssignableRole assignableRole);

View File

@@ -28,4 +28,6 @@ public interface AssignableRolePlaceManagementService {
List<AssignableRolePlace> findAllByServer(AServer server); List<AssignableRolePlace> findAllByServer(AServer server);
List<AssignableRolePlace> getAssignableRolePlacesWithNamesContaining(String name, AServer server);
} }

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<groupId>dev.sheldan.abstracto.modules</groupId> <groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>abstracto-modules</artifactId> <artifactId>abstracto-modules</artifactId>
<version>1.5.55</version> <version>1.6.21-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<groupId>dev.sheldan.abstracto.modules</groupId> <groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>custom-command</artifactId> <artifactId>custom-command</artifactId>
<version>1.5.55</version> <version>1.6.21-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -5,11 +5,14 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
import dev.sheldan.abstracto.core.command.config.CommandConfiguration; import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo; import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter; import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.config.UserCommandConfig;
import dev.sheldan.abstracto.core.command.execution.CommandResult; import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition; import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.interaction.InteractionService; import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig; import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandPrivilegeLevels;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService; import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.utils.ContextUtils;
import dev.sheldan.abstracto.customcommand.config.CustomCommandFeatureDefinition; import dev.sheldan.abstracto.customcommand.config.CustomCommandFeatureDefinition;
import dev.sheldan.abstracto.customcommand.config.CustomCommandSlashCommandNames; import dev.sheldan.abstracto.customcommand.config.CustomCommandSlashCommandNames;
import dev.sheldan.abstracto.customcommand.service.management.CustomCommandService; import dev.sheldan.abstracto.customcommand.service.management.CustomCommandService;
@@ -44,8 +47,11 @@ public class CreateCustomCommand extends AbstractConditionableCommand {
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) { public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
String name = slashCommandParameterService.getCommandOption(CUSTOM_COMMAND_NAME_PARAMETER, event, String.class); String name = slashCommandParameterService.getCommandOption(CUSTOM_COMMAND_NAME_PARAMETER, event, String.class);
String content = slashCommandParameterService.getCommandOption(CUSTOM_COMMAND_CONTENT_PARAMETER, event, String.class); String content = slashCommandParameterService.getCommandOption(CUSTOM_COMMAND_CONTENT_PARAMETER, event, String.class);
if(ContextUtils.isUserCommand(event)) {
customCommandService.createCustomCommand(name, content, event.getMember()); customCommandService.createUserCustomCommand(name, content, event.getUser());
} else {
customCommandService.createCustomCommand(name, content, event.getMember());
}
return interactionService.replyEmbed(CREATE_CUSTOM_COMMAND_RESPONSE_TEMPLATE_KEY, event) return interactionService.replyEmbed(CREATE_CUSTOM_COMMAND_RESPONSE_TEMPLATE_KEY, event)
.thenApply(interactionHook -> CommandResult.fromSuccess()); .thenApply(interactionHook -> CommandResult.fromSuccess());
} }
@@ -80,6 +86,9 @@ public class CreateCustomCommand extends AbstractConditionableCommand {
SlashCommandConfig slashCommandConfig = SlashCommandConfig SlashCommandConfig slashCommandConfig = SlashCommandConfig
.builder() .builder()
.enabled(true) .enabled(true)
.userInstallable(true)
.userCommandConfig(UserCommandConfig.all())
.defaultPrivilege(SlashCommandPrivilegeLevels.INVITER)
.rootCommandName(CustomCommandSlashCommandNames.CUSTOM_COMMAND) .rootCommandName(CustomCommandSlashCommandNames.CUSTOM_COMMAND)
.commandName("create") .commandName("create")
.build(); .build();

View File

@@ -5,15 +5,26 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
import dev.sheldan.abstracto.core.command.config.CommandConfiguration; import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo; import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter; import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.config.UserCommandConfig;
import dev.sheldan.abstracto.core.command.execution.CommandResult; import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition; import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.interaction.InteractionService; import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig; import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandPrivilegeLevels;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandAutoCompleteService;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService; import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUser;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.core.service.management.UserManagementService;
import dev.sheldan.abstracto.core.utils.ContextUtils;
import dev.sheldan.abstracto.customcommand.config.CustomCommandFeatureDefinition; import dev.sheldan.abstracto.customcommand.config.CustomCommandFeatureDefinition;
import dev.sheldan.abstracto.customcommand.config.CustomCommandSlashCommandNames; import dev.sheldan.abstracto.customcommand.config.CustomCommandSlashCommandNames;
import dev.sheldan.abstracto.customcommand.service.management.CustomCommandManagementService;
import dev.sheldan.abstracto.customcommand.service.management.CustomCommandService; import dev.sheldan.abstracto.customcommand.service.management.CustomCommandService;
import java.util.ArrayList;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -36,24 +47,59 @@ public class DeleteCustomCommand extends AbstractConditionableCommand {
@Autowired @Autowired
private CustomCommandService customCommandService; private CustomCommandService customCommandService;
@Autowired
private CustomCommandManagementService customCommandManagementService;
@Autowired @Autowired
private InteractionService interactionService; private InteractionService interactionService;
@Autowired
private SlashCommandAutoCompleteService slashCommandAutoCompleteService;
@Autowired
private ServerManagementService serverManagementService;
@Autowired
private UserManagementService userManagementService;
@Override @Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) { public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
String name = slashCommandParameterService.getCommandOption(CUSTOM_COMMAND_NAME_PARAMETER, event, String.class); String name = slashCommandParameterService.getCommandOption(CUSTOM_COMMAND_NAME_PARAMETER, event, String.class);
if(ContextUtils.isUserCommand(event)) {
customCommandService.deleteCustomCommand(name, event.getGuild()); customCommandService.deleteUserCustomCommand(name, event.getUser());
} else {
customCommandService.deleteCustomCommand(name, event.getGuild());
}
return interactionService.replyEmbed(DELETE_CUSTOM_COMMAND_RESPONSE_TEMPLATE_KEY, event) return interactionService.replyEmbed(DELETE_CUSTOM_COMMAND_RESPONSE_TEMPLATE_KEY, event)
.thenApply(interactionHook -> CommandResult.fromSuccess()); .thenApply(interactionHook -> CommandResult.fromSuccess());
} }
@Override
public List<String> performAutoComplete(CommandAutoCompleteInteractionEvent event) {
if(slashCommandAutoCompleteService.matchesParameter(event.getFocusedOption(), CUSTOM_COMMAND_NAME_PARAMETER)) {
String input = event.getFocusedOption().getValue();
if(ContextUtils.isUserCommand(event)) {
AUser user = userManagementService.loadUser(event.getUser().getIdLong());
return customCommandManagementService.getUserCustomCommandsContaining(input, user)
.stream().map(customCommand -> customCommand.getName().toLowerCase())
.toList();
} else {
AServer server = serverManagementService.loadServer(event.getGuild());
return customCommandManagementService.getCustomCommandsContaining(input, server)
.stream().map(customCommand -> customCommand.getName().toLowerCase())
.toList();
}
}
return new ArrayList<>();
}
@Override @Override
public CommandConfiguration getConfiguration() { public CommandConfiguration getConfiguration() {
Parameter commandNameParameter = Parameter Parameter commandNameParameter = Parameter
.builder() .builder()
.name(CUSTOM_COMMAND_NAME_PARAMETER) .name(CUSTOM_COMMAND_NAME_PARAMETER)
.templated(true) .templated(true)
.supportsAutoComplete(true)
.type(String.class) .type(String.class)
.build(); .build();
@@ -66,6 +112,9 @@ public class DeleteCustomCommand extends AbstractConditionableCommand {
SlashCommandConfig slashCommandConfig = SlashCommandConfig SlashCommandConfig slashCommandConfig = SlashCommandConfig
.builder() .builder()
.enabled(true) .enabled(true)
.userInstallable(true)
.userCommandConfig(UserCommandConfig.all())
.defaultPrivilege(SlashCommandPrivilegeLevels.INVITER)
.rootCommandName(CustomCommandSlashCommandNames.CUSTOM_COMMAND) .rootCommandName(CustomCommandSlashCommandNames.CUSTOM_COMMAND)
.commandName("delete") .commandName("delete")
.build(); .build();

View File

@@ -5,12 +5,14 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
import dev.sheldan.abstracto.core.command.config.CommandConfiguration; import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo; import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter; import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.config.UserCommandConfig;
import dev.sheldan.abstracto.core.command.execution.CommandResult; import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition; import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.interaction.InteractionService; import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig; import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandAutoCompleteService; import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandAutoCompleteService;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService; import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.utils.ContextUtils;
import dev.sheldan.abstracto.customcommand.config.CustomCommandFeatureDefinition; import dev.sheldan.abstracto.customcommand.config.CustomCommandFeatureDefinition;
import dev.sheldan.abstracto.customcommand.config.CustomCommandSlashCommandNames; import dev.sheldan.abstracto.customcommand.config.CustomCommandSlashCommandNames;
import dev.sheldan.abstracto.customcommand.model.command.CustomCommandResponseModel; import dev.sheldan.abstracto.customcommand.model.command.CustomCommandResponseModel;
@@ -48,7 +50,12 @@ public class GetCustomCommand extends AbstractConditionableCommand {
@Override @Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) { public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
String name = slashCommandParameterService.getCommandOption(CUSTOM_COMMAND_NAME_PARAMETER, event, String.class); String name = slashCommandParameterService.getCommandOption(CUSTOM_COMMAND_NAME_PARAMETER, event, String.class);
CustomCommand customCommand = customCommandService.getCustomCommand(name, event.getGuild()); CustomCommand customCommand;
if(ContextUtils.isUserCommand(event)) {
customCommand = customCommandService.getUserCustomCommand(name, event.getUser());
} else {
customCommand = customCommandService.getCustomCommand(name, event.getGuild());
}
CustomCommandResponseModel model = CustomCommandResponseModel CustomCommandResponseModel model = CustomCommandResponseModel
.builder() .builder()
.additionalText(customCommand.getAdditionalMessage()) .additionalText(customCommand.getAdditionalMessage())
@@ -61,11 +68,17 @@ public class GetCustomCommand extends AbstractConditionableCommand {
public List<String> performAutoComplete(CommandAutoCompleteInteractionEvent event) { public List<String> performAutoComplete(CommandAutoCompleteInteractionEvent event) {
if(slashCommandAutoCompleteService.matchesParameter(event.getFocusedOption(), CUSTOM_COMMAND_NAME_PARAMETER)) { if(slashCommandAutoCompleteService.matchesParameter(event.getFocusedOption(), CUSTOM_COMMAND_NAME_PARAMETER)) {
String input = event.getFocusedOption().getValue(); String input = event.getFocusedOption().getValue();
return customCommandService.getCustomCommandsStartingWith(input, event.getGuild()) if(ContextUtils.isNotUserCommand(event)) {
.stream() return customCommandService.getCustomCommandsContaining(input, event.getGuild())
.map(CustomCommand::getName) .stream()
.limit(25) .map(CustomCommand::getName)
.toList(); .toList();
} else {
return customCommandService.getUserCustomCommandsContaining(input, event.getUser())
.stream()
.map(CustomCommand::getName)
.toList();
}
} else { } else {
return new ArrayList<>(); return new ArrayList<>();
} }
@@ -95,7 +108,10 @@ public class GetCustomCommand extends AbstractConditionableCommand {
SlashCommandConfig slashCommandConfig = SlashCommandConfig SlashCommandConfig slashCommandConfig = SlashCommandConfig
.builder() .builder()
.enabled(true) .enabled(true)
.userInstallable(true)
.userCommandConfig(UserCommandConfig.all())
.rootCommandName(CustomCommandSlashCommandNames.CUSTOM_COMMAND_PUBLIC) .rootCommandName(CustomCommandSlashCommandNames.CUSTOM_COMMAND_PUBLIC)
.userRootCommandName(CustomCommandSlashCommandNames.CUSTOM_COMMAND)
.commandName("get") .commandName("get")
.build(); .build();

View File

@@ -4,11 +4,13 @@ import dev.sheldan.abstracto.core.command.UtilityModuleDefinition;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand; import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration; import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo; import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.UserCommandConfig;
import dev.sheldan.abstracto.core.command.execution.CommandResult; import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition; import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.interaction.InteractionService; import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig; import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.service.PaginatorService; import dev.sheldan.abstracto.core.service.PaginatorService;
import dev.sheldan.abstracto.core.utils.ContextUtils;
import dev.sheldan.abstracto.customcommand.config.CustomCommandFeatureDefinition; import dev.sheldan.abstracto.customcommand.config.CustomCommandFeatureDefinition;
import dev.sheldan.abstracto.customcommand.config.CustomCommandSlashCommandNames; import dev.sheldan.abstracto.customcommand.config.CustomCommandSlashCommandNames;
import dev.sheldan.abstracto.customcommand.model.command.ListCustomCommandsResponseModel; import dev.sheldan.abstracto.customcommand.model.command.ListCustomCommandsResponseModel;
@@ -42,7 +44,12 @@ public class ListCustomCommands extends AbstractConditionableCommand {
@Override @Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) { public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
List<CustomCommand> customCommands = customCommandService.getCustomCommands(event.getGuild()); List<CustomCommand> customCommands;
if(ContextUtils.isUserCommand(event)) {
customCommands = customCommandService.getUserCustomCommands(event.getUser());
} else {
customCommands = customCommandService.getCustomCommands(event.getGuild());
}
if(customCommands.isEmpty()) { if(customCommands.isEmpty()) {
return interactionService.replyEmbed(NO_CUSTOM_COMMANDS_TEMPLATE_KEY, event) return interactionService.replyEmbed(NO_CUSTOM_COMMANDS_TEMPLATE_KEY, event)
.thenApply(interactionHook -> CommandResult.fromSuccess()); .thenApply(interactionHook -> CommandResult.fromSuccess());
@@ -67,7 +74,10 @@ public class ListCustomCommands extends AbstractConditionableCommand {
SlashCommandConfig slashCommandConfig = SlashCommandConfig SlashCommandConfig slashCommandConfig = SlashCommandConfig
.builder() .builder()
.enabled(true) .enabled(true)
.userInstallable(true)
.userCommandConfig(UserCommandConfig.all())
.rootCommandName(CustomCommandSlashCommandNames.CUSTOM_COMMAND_PUBLIC) .rootCommandName(CustomCommandSlashCommandNames.CUSTOM_COMMAND_PUBLIC)
.userRootCommandName(CustomCommandSlashCommandNames.CUSTOM_COMMAND)
.commandName("list") .commandName("list")
.build(); .build();

View File

@@ -1,6 +1,7 @@
package dev.sheldan.abstracto.customcommand.repository; package dev.sheldan.abstracto.customcommand.repository;
import dev.sheldan.abstracto.core.models.database.AServer; import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUser;
import dev.sheldan.abstracto.customcommand.model.database.CustomCommand; import dev.sheldan.abstracto.customcommand.model.database.CustomCommand;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
@@ -11,7 +12,14 @@ import java.util.Optional;
@Repository @Repository
public interface CustomCommandRepository extends JpaRepository<CustomCommand, Long> { public interface CustomCommandRepository extends JpaRepository<CustomCommand, Long> {
Optional<CustomCommand> getByNameIgnoreCaseAndServer(String name, AServer server); Optional<CustomCommand> getByNameIgnoreCaseAndServer(String name, AServer server);
Optional<CustomCommand> getByNameIgnoreCaseAndCreatorUser(String name, AUser creator);
Optional<CustomCommand> getByNameIgnoreCaseAndCreatorUser_IdAndUserSpecific(String name, Long userId, Boolean userSpecific);
void deleteByNameAndServer(String name, AServer server); void deleteByNameAndServer(String name, AServer server);
void deleteByNameAndCreatorUserAndUserSpecific(String name, AUser aUser, Boolean userSpecific);
List<CustomCommand> findByServer(AServer server); List<CustomCommand> findByServer(AServer server);
List<CustomCommand> findByCreatorUserAndUserSpecific(AUser user, Boolean userSpecific);
List<CustomCommand> findByNameStartsWithIgnoreCaseAndServer(String prefix, AServer server); List<CustomCommand> findByNameStartsWithIgnoreCaseAndServer(String prefix, AServer server);
List<CustomCommand> findByNameStartsWithIgnoreCaseAndCreatorUserAndUserSpecific(String prefix, AUser aUser, Boolean userSpecific);
List<CustomCommand> findByNameContainingIgnoreCaseAndServer(String name, AServer server);
List<CustomCommand> findByNameContainingIgnoreCaseAndCreatorUserAndUserSpecific(String name, AUser user, Boolean userSpecific);
} }

View File

@@ -1,9 +1,11 @@
package dev.sheldan.abstracto.customcommand.service; package dev.sheldan.abstracto.customcommand.service;
import dev.sheldan.abstracto.core.models.database.AServer; import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUser;
import dev.sheldan.abstracto.core.models.database.AUserInAServer; import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.management.ServerManagementService; import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService; import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.service.management.UserManagementService;
import dev.sheldan.abstracto.customcommand.exception.CustomCommandExistsException; import dev.sheldan.abstracto.customcommand.exception.CustomCommandExistsException;
import dev.sheldan.abstracto.customcommand.exception.CustomCommandNotFoundException; import dev.sheldan.abstracto.customcommand.exception.CustomCommandNotFoundException;
import dev.sheldan.abstracto.customcommand.model.database.CustomCommand; import dev.sheldan.abstracto.customcommand.model.database.CustomCommand;
@@ -11,6 +13,7 @@ import dev.sheldan.abstracto.customcommand.service.management.CustomCommandManag
import dev.sheldan.abstracto.customcommand.service.management.CustomCommandService; import dev.sheldan.abstracto.customcommand.service.management.CustomCommandService;
import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.User;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -28,6 +31,9 @@ public class CustomCommandServiceBean implements CustomCommandService {
@Autowired @Autowired
private ServerManagementService serverManagementService; private ServerManagementService serverManagementService;
@Autowired
private UserManagementService userManagementService;
@Override @Override
public CustomCommand createCustomCommand(String name, String content, Member creator) { public CustomCommand createCustomCommand(String name, String content, Member creator) {
if(customCommandManagementService.getCustomCommandByName(name, creator.getGuild().getIdLong()).isPresent()) { if(customCommandManagementService.getCustomCommandByName(name, creator.getGuild().getIdLong()).isPresent()) {
@@ -37,6 +43,15 @@ public class CustomCommandServiceBean implements CustomCommandService {
return customCommandManagementService.createCustomCommand(name, content, creatorUser); return customCommandManagementService.createCustomCommand(name, content, creatorUser);
} }
@Override
public CustomCommand createUserCustomCommand(String name, String content, User user) {
AUser aUser = userManagementService.loadOrCreateUser(user.getIdLong());
if(customCommandManagementService.getUserCustomCommandByName(name, aUser).isPresent()) {
throw new CustomCommandExistsException();
}
return customCommandManagementService.createUserCustomCommand(name, content, aUser);
}
@Override @Override
public void deleteCustomCommand(String name, Guild guild) { public void deleteCustomCommand(String name, Guild guild) {
if(customCommandManagementService.getCustomCommandByName(name, guild.getIdLong()).isEmpty()) { if(customCommandManagementService.getCustomCommandByName(name, guild.getIdLong()).isEmpty()) {
@@ -46,12 +61,27 @@ public class CustomCommandServiceBean implements CustomCommandService {
customCommandManagementService.deleteCustomCommand(name, server); customCommandManagementService.deleteCustomCommand(name, server);
} }
@Override
public void deleteUserCustomCommand(String name, User user) {
if(customCommandManagementService.getUserCustomCommandByName(name, user.getIdLong()).isEmpty()) {
throw new CustomCommandNotFoundException();
}
AUser aUser = userManagementService.loadOrCreateUser(user.getIdLong());
customCommandManagementService.deleteCustomCommand(name, aUser);
}
@Override @Override
public List<CustomCommand> getCustomCommands(Guild guild) { public List<CustomCommand> getCustomCommands(Guild guild) {
AServer server = serverManagementService.loadServer(guild); AServer server = serverManagementService.loadServer(guild);
return customCommandManagementService.getCustomCommands(server); return customCommandManagementService.getCustomCommands(server);
} }
@Override
public List<CustomCommand> getUserCustomCommands(User user) {
AUser aUser = userManagementService.loadOrCreateUser(user.getIdLong());
return customCommandManagementService.getUserCustomCommands(aUser);
}
@Override @Override
public CustomCommand getCustomCommand(String name, Guild guild) { public CustomCommand getCustomCommand(String name, Guild guild) {
return customCommandManagementService.getCustomCommandByName(name, guild.getIdLong()) return customCommandManagementService.getCustomCommandByName(name, guild.getIdLong())
@@ -59,8 +89,20 @@ public class CustomCommandServiceBean implements CustomCommandService {
} }
@Override @Override
public List<CustomCommand> getCustomCommandsStartingWith(String prefix, Guild guild) { public CustomCommand getUserCustomCommand(String name, User user) {
return customCommandManagementService.getUserCustomCommandByName(name, user.getIdLong())
.orElseThrow(CustomCommandNotFoundException::new);
}
@Override
public List<CustomCommand> getCustomCommandsContaining(String name, Guild guild) {
AServer server = serverManagementService.loadServer(guild); AServer server = serverManagementService.loadServer(guild);
return customCommandManagementService.getCustomCommandsStartingWith(prefix, server); return customCommandManagementService.getCustomCommandsContaining(name, server);
}
@Override
public List<CustomCommand> getUserCustomCommandsContaining(String name, User user) {
AUser aUser = userManagementService.loadOrCreateUser(user.getIdLong());
return customCommandManagementService.getUserCustomCommandsContaining(name, aUser);
} }
} }

View File

@@ -1,6 +1,7 @@
package dev.sheldan.abstracto.customcommand.service.management; package dev.sheldan.abstracto.customcommand.service.management;
import dev.sheldan.abstracto.core.models.database.AServer; import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUser;
import dev.sheldan.abstracto.core.models.database.AUserInAServer; import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.management.ServerManagementService; import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.customcommand.model.database.CustomCommand; import dev.sheldan.abstracto.customcommand.model.database.CustomCommand;
@@ -26,6 +27,16 @@ public class CustomCommandManagementServiceBean implements CustomCommandManageme
return repository.getByNameIgnoreCaseAndServer(name, server); return repository.getByNameIgnoreCaseAndServer(name, server);
} }
@Override
public Optional<CustomCommand> getUserCustomCommandByName(String name, AUser user) {
return repository.getByNameIgnoreCaseAndCreatorUser(name, user);
}
@Override
public Optional<CustomCommand> getUserCustomCommandByName(String name, Long userId) {
return repository.getByNameIgnoreCaseAndCreatorUser_IdAndUserSpecific(name, userId, true);
}
@Override @Override
public CustomCommand createCustomCommand(String name, String content, AUserInAServer creator) { public CustomCommand createCustomCommand(String name, String content, AUserInAServer creator) {
CustomCommand customCommand = CustomCommand CustomCommand customCommand = CustomCommand
@@ -34,6 +45,20 @@ public class CustomCommandManagementServiceBean implements CustomCommandManageme
.additionalMessage(content) .additionalMessage(content)
.server(creator.getServerReference()) .server(creator.getServerReference())
.creator(creator) .creator(creator)
.userSpecific(false)
.creatorUser(creator.getUserReference())
.build();
return repository.save(customCommand);
}
@Override
public CustomCommand createUserCustomCommand(String name, String content, AUser user) {
CustomCommand customCommand = CustomCommand
.builder()
.name(name)
.additionalMessage(content)
.creatorUser(user)
.userSpecific(true)
.build(); .build();
return repository.save(customCommand); return repository.save(customCommand);
} }
@@ -43,14 +68,29 @@ public class CustomCommandManagementServiceBean implements CustomCommandManageme
repository.deleteByNameAndServer(name, server); repository.deleteByNameAndServer(name, server);
} }
@Override
public void deleteCustomCommand(String name, AUser user) {
repository.deleteByNameAndCreatorUserAndUserSpecific(name, user, true);
}
@Override @Override
public List<CustomCommand> getCustomCommands(AServer server) { public List<CustomCommand> getCustomCommands(AServer server) {
return repository.findByServer(server); return repository.findByServer(server);
} }
@Override @Override
public List<CustomCommand> getCustomCommandsStartingWith(String prefix, AServer server) { public List<CustomCommand> getUserCustomCommands(AUser aUser) {
return repository.findByNameStartsWithIgnoreCaseAndServer(prefix, server); return repository.findByCreatorUserAndUserSpecific(aUser, true);
}
@Override
public List<CustomCommand> getCustomCommandsContaining(String name, AServer server) {
return repository.findByNameContainingIgnoreCaseAndServer(name, server);
}
@Override
public List<CustomCommand> getUserCustomCommandsContaining(String prefix, AUser aUser) {
return repository.findByNameContainingIgnoreCaseAndCreatorUserAndUserSpecific(prefix, aUser, true);
} }
} }

View File

@@ -0,0 +1,6 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
<include file="tables/tables.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>

View File

@@ -0,0 +1,26 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
<changeSet author="Sheldan" id="custom_command-add_user_installable_support">
<addColumn tableName="custom_command">
<column name="creator_id" type="BIGINT">
<constraints nullable="true"/>
</column>
<column name="user_specific" type="BOOLEAN" value="false">
<constraints nullable="false"/>
</column>
</addColumn>
<sql>
update custom_command set creator_id = (select ua.user_id from user_in_server ua where ua.user_in_server_id = creator_user_in_server_id order by ua.server_id limit 1)
</sql>
<addNotNullConstraint columnName="creator_id"
tableName="custom_command"
validate="true"/>
<sql>
ALTER TABLE custom_command ALTER COLUMN server_id DROP NOT NULL;
ALTER TABLE custom_command ALTER COLUMN creator_user_in_server_id DROP NOT NULL;
</sql>
</changeSet>
</databaseChangeLog>

View File

@@ -0,0 +1,6 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
<include file="custom_command.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>

View File

@@ -4,4 +4,5 @@
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" > xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
<include file="1.4.0/collection.xml" relativeToChangelogFile="true"/> <include file="1.4.0/collection.xml" relativeToChangelogFile="true"/>
<include file="1.5.8/collection.xml" relativeToChangelogFile="true"/> <include file="1.5.8/collection.xml" relativeToChangelogFile="true"/>
<include file="1.5.37/collection.xml" relativeToChangelogFile="true"/>
</databaseChangeLog> </databaseChangeLog>

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<groupId>dev.sheldan.abstracto.modules</groupId> <groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>custom-command</artifactId> <artifactId>custom-command</artifactId>
<version>1.5.55</version> <version>1.6.21-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -13,11 +13,18 @@ public class ListCustomCommandModel {
private MemberDisplay creator; private MemberDisplay creator;
public static ListCustomCommandModel fromCustomCommand(CustomCommand customCommand) { public static ListCustomCommandModel fromCustomCommand(CustomCommand customCommand) {
MemberDisplay creatorObj;
if(customCommand.getUserSpecific()) {
creatorObj = MemberDisplay.fromAUser(customCommand.getCreatorUser());
} else {
creatorObj = MemberDisplay.fromAUserInAServer(customCommand.getCreator());
}
return ListCustomCommandModel return ListCustomCommandModel
.builder() .builder()
.name(customCommand.getName()) .name(customCommand.getName())
.content(customCommand.getAdditionalMessage()) .content(customCommand.getAdditionalMessage())
.creator(MemberDisplay.fromAUserInAServer(customCommand.getCreator())) .creator(creatorObj)
.build(); .build();
} }
} }

View File

@@ -29,13 +29,20 @@ public class CustomCommand implements Serializable {
private String name; private String name;
@ManyToOne(fetch = FetchType.LAZY) @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "server_id", nullable = false) @JoinColumn(name = "server_id")
private AServer server; private AServer server;
@ManyToOne(fetch = FetchType.LAZY) @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "creator_user_in_server_id", nullable = false) @JoinColumn(name = "creator_user_in_server_id")
private AUserInAServer creator; private AUserInAServer creator;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "creator_id", nullable = false)
private AUser creatorUser;
@Column(name = "user_specific")
private Boolean userSpecific;
@Column(name = "created", nullable = false, insertable = false, updatable = false) @Column(name = "created", nullable = false, insertable = false, updatable = false)
private Instant created; private Instant created;

View File

@@ -1,6 +1,7 @@
package dev.sheldan.abstracto.customcommand.service.management; package dev.sheldan.abstracto.customcommand.service.management;
import dev.sheldan.abstracto.core.models.database.AServer; import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUser;
import dev.sheldan.abstracto.core.models.database.AUserInAServer; import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.customcommand.model.database.CustomCommand; import dev.sheldan.abstracto.customcommand.model.database.CustomCommand;
@@ -9,8 +10,14 @@ import java.util.Optional;
public interface CustomCommandManagementService { public interface CustomCommandManagementService {
Optional<CustomCommand> getCustomCommandByName(String name, Long serverId); Optional<CustomCommand> getCustomCommandByName(String name, Long serverId);
Optional<CustomCommand> getUserCustomCommandByName(String name, AUser user);
Optional<CustomCommand> getUserCustomCommandByName(String name, Long userId);
CustomCommand createCustomCommand(String name, String content, AUserInAServer creator); CustomCommand createCustomCommand(String name, String content, AUserInAServer creator);
CustomCommand createUserCustomCommand(String name, String content, AUser user);
void deleteCustomCommand(String name, AServer server); void deleteCustomCommand(String name, AServer server);
void deleteCustomCommand(String name, AUser user);
List<CustomCommand> getCustomCommands(AServer server); List<CustomCommand> getCustomCommands(AServer server);
List<CustomCommand> getCustomCommandsStartingWith(String prefix, AServer server); List<CustomCommand> getUserCustomCommands(AUser aUser);
List<CustomCommand> getCustomCommandsContaining(String prefix, AServer server);
List<CustomCommand> getUserCustomCommandsContaining(String prefix, AUser aUser);
} }

View File

@@ -3,13 +3,19 @@ package dev.sheldan.abstracto.customcommand.service.management;
import dev.sheldan.abstracto.customcommand.model.database.CustomCommand; import dev.sheldan.abstracto.customcommand.model.database.CustomCommand;
import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.User;
import java.util.List; import java.util.List;
public interface CustomCommandService { public interface CustomCommandService {
CustomCommand createCustomCommand(String name, String content, Member creator); CustomCommand createCustomCommand(String name, String content, Member creator);
CustomCommand createUserCustomCommand(String name, String content, User user);
void deleteCustomCommand(String name, Guild guild); void deleteCustomCommand(String name, Guild guild);
void deleteUserCustomCommand(String name, User user);
List<CustomCommand> getCustomCommands(Guild guild); List<CustomCommand> getCustomCommands(Guild guild);
List<CustomCommand> getUserCustomCommands(User user);
CustomCommand getCustomCommand(String name, Guild guild); CustomCommand getCustomCommand(String name, Guild guild);
List<CustomCommand> getCustomCommandsStartingWith(String prefix, Guild guild); CustomCommand getUserCustomCommand(String name, User user);
List<CustomCommand> getCustomCommandsContaining(String name, Guild guild);
List<CustomCommand> getUserCustomCommandsContaining(String name, User user);
} }

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<artifactId>abstracto-modules</artifactId> <artifactId>abstracto-modules</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId> <groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55</version> <version>1.6.21-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<groupId>dev.sheldan.abstracto.modules</groupId> <groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>dynamic-activity</artifactId> <artifactId>dynamic-activity</artifactId>
<version>1.5.55</version> <version>1.6.21-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<artifactId>dynamic-activity</artifactId> <artifactId>dynamic-activity</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId> <groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55</version> <version>1.6.21-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<artifactId>abstracto-modules</artifactId> <artifactId>abstracto-modules</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId> <groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55</version> <version>1.6.21-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<artifactId>entertainment</artifactId> <artifactId>entertainment</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId> <groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55</version> <version>1.6.21-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -4,6 +4,7 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
import dev.sheldan.abstracto.core.command.config.CommandConfiguration; import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo; import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter; import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.config.UserCommandConfig;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig; import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.command.execution.CommandContext; import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult; import dev.sheldan.abstracto.core.command.execution.CommandResult;
@@ -51,6 +52,7 @@ public class Choose extends AbstractConditionableCommand {
String choice = entertainmentService.takeChoice(choices, commandContext.getAuthor()); String choice = entertainmentService.takeChoice(choices, commandContext.getAuthor());
ChooseResponseModel responseModel = ChooseResponseModel ChooseResponseModel responseModel = ChooseResponseModel
.builder() .builder()
.choices(choices)
.chosenValue(choice) .chosenValue(choice)
.build(); .build();
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInMessageChannel(CHOOSE_RESPONSE_TEMPLATE_KEY, responseModel, commandContext.getChannel())) return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInMessageChannel(CHOOSE_RESPONSE_TEMPLATE_KEY, responseModel, commandContext.getChannel()))
@@ -69,6 +71,7 @@ public class Choose extends AbstractConditionableCommand {
String choice = entertainmentService.takeChoice(choices, event.getMember()); String choice = entertainmentService.takeChoice(choices, event.getMember());
ChooseResponseModel responseModel = ChooseResponseModel ChooseResponseModel responseModel = ChooseResponseModel
.builder() .builder()
.choices(choices)
.chosenValue(choice) .chosenValue(choice)
.build(); .build();
return interactionService.replyEmbed(CHOOSE_RESPONSE_TEMPLATE_KEY, responseModel, event) return interactionService.replyEmbed(CHOOSE_RESPONSE_TEMPLATE_KEY, responseModel, event)
@@ -96,6 +99,8 @@ public class Choose extends AbstractConditionableCommand {
SlashCommandConfig slashCommandConfig = SlashCommandConfig SlashCommandConfig slashCommandConfig = SlashCommandConfig
.builder() .builder()
.enabled(true) .enabled(true)
.userInstallable(true)
.userCommandConfig(UserCommandConfig.all())
.rootCommandName(EntertainmentSlashCommandNames.UTILITY) .rootCommandName(EntertainmentSlashCommandNames.UTILITY)
.commandName(CHOOSE_COMMAND) .commandName(CHOOSE_COMMAND)
.build(); .build();

View File

@@ -4,15 +4,14 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
import dev.sheldan.abstracto.core.command.config.CommandConfiguration; import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo; import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter; import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.config.UserCommandConfig;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig; import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult; import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService; import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.config.FeatureDefinition; import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.interaction.InteractionService; import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.templating.model.MessageToSend; import dev.sheldan.abstracto.core.templating.model.MessageToSend;
import dev.sheldan.abstracto.core.utils.FutureUtils; import dev.sheldan.abstracto.core.utils.ContextUtils;
import dev.sheldan.abstracto.core.templating.service.TemplateService; import dev.sheldan.abstracto.core.templating.service.TemplateService;
import dev.sheldan.abstracto.entertainment.config.EntertainmentFeatureDefinition; import dev.sheldan.abstracto.entertainment.config.EntertainmentFeatureDefinition;
import dev.sheldan.abstracto.entertainment.config.EntertainmentModuleDefinition; import dev.sheldan.abstracto.entertainment.config.EntertainmentModuleDefinition;
@@ -39,28 +38,16 @@ public class EightBall extends AbstractConditionableCommand {
@Autowired @Autowired
private TemplateService templateService; private TemplateService templateService;
@Autowired
private ChannelService channelService;
@Autowired @Autowired
private SlashCommandParameterService slashCommandParameterService; private SlashCommandParameterService slashCommandParameterService;
@Autowired @Autowired
private InteractionService interactionService; private InteractionService interactionService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
String text = (String) commandContext.getParameters().getParameters().get(0);
MessageToSend messageToSend = getMessageToSend(text, commandContext.getGuild().getIdLong());
return FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(messageToSend, commandContext.getChannel()))
.thenApply(unused -> CommandResult.fromIgnored());
}
@Override @Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) { public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
String text = slashCommandParameterService.getCommandOption(TEXT_PARAMETER, event, String.class); String text = slashCommandParameterService.getCommandOption(TEXT_PARAMETER, event, String.class);
MessageToSend messageToSend = getMessageToSend(text, event.getGuild().getIdLong()); MessageToSend messageToSend = getMessageToSend(text, ContextUtils.serverIdOrNull(event));
return interactionService.replyMessageToSend(messageToSend, event) return interactionService.replyMessageToSend(messageToSend, event)
.thenApply(interactionHook -> CommandResult.fromSuccess()); .thenApply(interactionHook -> CommandResult.fromSuccess());
} }
@@ -69,6 +56,7 @@ public class EightBall extends AbstractConditionableCommand {
String chosenKey = entertainmentService.getEightBallValue(text); String chosenKey = entertainmentService.getEightBallValue(text);
EightBallResponseModel responseModel = EightBallResponseModel EightBallResponseModel responseModel = EightBallResponseModel
.builder() .builder()
.input(text)
.chosenKey(chosenKey) .chosenKey(chosenKey)
.build(); .build();
return templateService.renderEmbedTemplate(EIGHT_BALL_RESPONSE_TEMPLATE_KEY, responseModel, serverId); return templateService.renderEmbedTemplate(EIGHT_BALL_RESPONSE_TEMPLATE_KEY, responseModel, serverId);
@@ -93,6 +81,8 @@ public class EightBall extends AbstractConditionableCommand {
SlashCommandConfig slashCommandConfig = SlashCommandConfig SlashCommandConfig slashCommandConfig = SlashCommandConfig
.builder() .builder()
.enabled(true) .enabled(true)
.userInstallable(true)
.userCommandConfig(UserCommandConfig.all())
.rootCommandName(EntertainmentSlashCommandNames.UTILITY) .rootCommandName(EntertainmentSlashCommandNames.UTILITY)
.commandName(BALL_COMMAND) .commandName(BALL_COMMAND)
.build(); .build();
@@ -104,6 +94,7 @@ public class EightBall extends AbstractConditionableCommand {
.module(EntertainmentModuleDefinition.ENTERTAINMENT) .module(EntertainmentModuleDefinition.ENTERTAINMENT)
.templated(true) .templated(true)
.supportsEmbedException(true) .supportsEmbedException(true)
.slashCommandOnly(true)
.causesReaction(true) .causesReaction(true)
.parameters(parameters) .parameters(parameters)
.help(helpInfo) .help(helpInfo)

View File

@@ -4,6 +4,7 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
import dev.sheldan.abstracto.core.command.config.CommandConfiguration; import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo; import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter; import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.config.UserCommandConfig;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig; import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.command.execution.CommandContext; import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult; import dev.sheldan.abstracto.core.command.execution.CommandResult;
@@ -13,6 +14,7 @@ import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.service.ChannelService; import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.templating.model.MessageToSend; import dev.sheldan.abstracto.core.templating.model.MessageToSend;
import dev.sheldan.abstracto.core.templating.service.TemplateService; import dev.sheldan.abstracto.core.templating.service.TemplateService;
import dev.sheldan.abstracto.core.utils.ContextUtils;
import dev.sheldan.abstracto.core.utils.FutureUtils; import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.entertainment.config.EntertainmentFeatureDefinition; import dev.sheldan.abstracto.entertainment.config.EntertainmentFeatureDefinition;
import dev.sheldan.abstracto.entertainment.config.EntertainmentModuleDefinition; import dev.sheldan.abstracto.entertainment.config.EntertainmentModuleDefinition;
@@ -64,7 +66,7 @@ public class LoveCalc extends AbstractConditionableCommand {
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) { public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
String firstPart = slashCommandParameterService.getCommandOption(FIRST_SUBJECT_PARAMETER, event, String.class); String firstPart = slashCommandParameterService.getCommandOption(FIRST_SUBJECT_PARAMETER, event, String.class);
String secondPart = slashCommandParameterService.getCommandOption(SECOND_SUBJECT_PARAMETER, event, String.class); String secondPart = slashCommandParameterService.getCommandOption(SECOND_SUBJECT_PARAMETER, event, String.class);
MessageToSend messageToSend = getMessageToSend(event.getGuild().getIdLong(), firstPart, secondPart); MessageToSend messageToSend = getMessageToSend(ContextUtils.serverIdOrNull(event), firstPart, secondPart);
return interactionService.replyMessageToSend(messageToSend, event.getInteraction()) return interactionService.replyMessageToSend(messageToSend, event.getInteraction())
.thenApply(interactionHook -> CommandResult.fromSuccess()); .thenApply(interactionHook -> CommandResult.fromSuccess());
} }
@@ -105,6 +107,8 @@ public class LoveCalc extends AbstractConditionableCommand {
SlashCommandConfig slashCommandConfig = SlashCommandConfig SlashCommandConfig slashCommandConfig = SlashCommandConfig
.builder() .builder()
.enabled(true) .enabled(true)
.userInstallable(true)
.userCommandConfig(UserCommandConfig.all())
.rootCommandName(EntertainmentSlashCommandNames.UTILITY) .rootCommandName(EntertainmentSlashCommandNames.UTILITY)
.commandName(LOVE_CALC_COMMAND) .commandName(LOVE_CALC_COMMAND)
.build(); .build();

View File

@@ -1,10 +1,7 @@
package dev.sheldan.abstracto.entertainment.command; package dev.sheldan.abstracto.entertainment.command;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand; import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CombinedParameterEntry; import dev.sheldan.abstracto.core.command.config.*;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext; import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult; import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.command.handler.parameter.CombinedParameter; import dev.sheldan.abstracto.core.command.handler.parameter.CombinedParameter;
@@ -108,6 +105,8 @@ public class Mock extends AbstractConditionableCommand {
SlashCommandConfig slashCommandConfig = SlashCommandConfig SlashCommandConfig slashCommandConfig = SlashCommandConfig
.builder() .builder()
.enabled(true) .enabled(true)
.userInstallable(true)
.userCommandConfig(UserCommandConfig.all())
.rootCommandName(EntertainmentSlashCommandNames.ENTERTAINMENT) .rootCommandName(EntertainmentSlashCommandNames.ENTERTAINMENT)
.commandName(MOCK_COMMAND) .commandName(MOCK_COMMAND)
.build(); .build();

View File

@@ -4,6 +4,7 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
import dev.sheldan.abstracto.core.command.config.CommandConfiguration; import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo; import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter; import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.config.UserCommandConfig;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig; import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.command.config.validator.MinIntegerValueValidator; import dev.sheldan.abstracto.core.command.config.validator.MinIntegerValueValidator;
import dev.sheldan.abstracto.core.command.execution.CommandContext; import dev.sheldan.abstracto.core.command.execution.CommandContext;
@@ -125,6 +126,8 @@ public class Roll extends AbstractConditionableCommand {
SlashCommandConfig slashCommandConfig = SlashCommandConfig SlashCommandConfig slashCommandConfig = SlashCommandConfig
.builder() .builder()
.enabled(true) .enabled(true)
.userInstallable(true)
.userCommandConfig(UserCommandConfig.all())
.rootCommandName(EntertainmentSlashCommandNames.UTILITY) .rootCommandName(EntertainmentSlashCommandNames.UTILITY)
.commandName(ROLL_COMMAND) .commandName(ROLL_COMMAND)
.build(); .build();

View File

@@ -4,13 +4,11 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
import dev.sheldan.abstracto.core.command.config.CommandConfiguration; import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo; import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter; import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.config.UserCommandConfig;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig; import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult; import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition; import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.interaction.InteractionService; import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.entertainment.config.EntertainmentFeatureDefinition; import dev.sheldan.abstracto.entertainment.config.EntertainmentFeatureDefinition;
import dev.sheldan.abstracto.entertainment.config.EntertainmentModuleDefinition; import dev.sheldan.abstracto.entertainment.config.EntertainmentModuleDefinition;
import dev.sheldan.abstracto.entertainment.config.EntertainmentSlashCommandNames; import dev.sheldan.abstracto.entertainment.config.EntertainmentSlashCommandNames;
@@ -29,8 +27,6 @@ public class Roulette extends AbstractConditionableCommand {
public static final String ROULETTE_RESPONSE_TEMPLATE_KEY = "roulette_response"; public static final String ROULETTE_RESPONSE_TEMPLATE_KEY = "roulette_response";
public static final String ROULETTE_COMMAND = "roulette"; public static final String ROULETTE_COMMAND = "roulette";
@Autowired
private ChannelService channelService;
@Autowired @Autowired
private EntertainmentService entertainmentService; private EntertainmentService entertainmentService;
@@ -38,17 +34,6 @@ public class Roulette extends AbstractConditionableCommand {
@Autowired @Autowired
private InteractionService interactionService; private InteractionService interactionService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
boolean rouletteResult = entertainmentService.executeRoulette(commandContext.getAuthor());
RouletteResponseModel responseModel = RouletteResponseModel
.builder()
.result(rouletteResult)
.build();
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInMessageChannel(ROULETTE_RESPONSE_TEMPLATE_KEY, responseModel, commandContext.getChannel()))
.thenApply(unused -> CommandResult.fromIgnored());
}
@Override @Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) { public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
boolean rouletteResult = entertainmentService.executeRoulette(event.getMember()); boolean rouletteResult = entertainmentService.executeRoulette(event.getMember());
@@ -71,6 +56,8 @@ public class Roulette extends AbstractConditionableCommand {
SlashCommandConfig slashCommandConfig = SlashCommandConfig SlashCommandConfig slashCommandConfig = SlashCommandConfig
.builder() .builder()
.enabled(true) .enabled(true)
.userInstallable(true)
.userCommandConfig(UserCommandConfig.all())
.rootCommandName(EntertainmentSlashCommandNames.UTILITY) .rootCommandName(EntertainmentSlashCommandNames.UTILITY)
.commandName(ROULETTE_COMMAND) .commandName(ROULETTE_COMMAND)
.build(); .build();
@@ -81,6 +68,7 @@ public class Roulette extends AbstractConditionableCommand {
.slashCommandConfig(slashCommandConfig) .slashCommandConfig(slashCommandConfig)
.module(EntertainmentModuleDefinition.ENTERTAINMENT) .module(EntertainmentModuleDefinition.ENTERTAINMENT)
.templated(true) .templated(true)
.slashCommandOnly(true)
.supportsEmbedException(true) .supportsEmbedException(true)
.causesReaction(true) .causesReaction(true)
.parameters(parameters) .parameters(parameters)

View File

@@ -4,17 +4,12 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
import dev.sheldan.abstracto.core.command.config.CommandConfiguration; import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo; import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter; import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult; import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition; import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.interaction.InteractionService; import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig; import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.models.database.AUserInAServer; import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService; import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
import dev.sheldan.abstracto.core.templating.service.TemplateService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.entertainment.config.EntertainmentFeatureDefinition; import dev.sheldan.abstracto.entertainment.config.EntertainmentFeatureDefinition;
import dev.sheldan.abstracto.entertainment.config.EntertainmentModuleDefinition; import dev.sheldan.abstracto.entertainment.config.EntertainmentModuleDefinition;
import dev.sheldan.abstracto.entertainment.config.EntertainmentSlashCommandNames; import dev.sheldan.abstracto.entertainment.config.EntertainmentSlashCommandNames;
@@ -43,22 +38,6 @@ public class CreditGamble extends AbstractConditionableCommand {
@Autowired @Autowired
private InteractionService interactionService; private InteractionService interactionService;
@Autowired
private TemplateService templateService;
@Autowired
private ChannelService channelService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(commandContext.getAuthor());
CreditGambleResult result = economyService.triggerCreditGamble(aUserInAServer);
CreditGambleResultModel model = CreditGambleResultModel.fromCreditGambleResult(result);
MessageToSend messageToSend = templateService.renderEmbedTemplate(CREDIT_GAMBLE_RESPONSE, model, commandContext.getGuild().getIdLong());
return FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(messageToSend, commandContext.getChannel()))
.thenApply(interactionHook -> CommandResult.fromSuccess());
}
@Override @Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) { public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(event.getMember()); AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(event.getMember());
@@ -89,6 +68,7 @@ public class CreditGamble extends AbstractConditionableCommand {
.async(true) .async(true)
.module(EntertainmentModuleDefinition.ENTERTAINMENT) .module(EntertainmentModuleDefinition.ENTERTAINMENT)
.templated(true) .templated(true)
.slashCommandOnly(true)
.supportsEmbedException(true) .supportsEmbedException(true)
.parameters(parameters) .parameters(parameters)
.help(helpInfo) .help(helpInfo)

View File

@@ -4,7 +4,6 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
import dev.sheldan.abstracto.core.command.config.CommandConfiguration; import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo; import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter; import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult; import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition; import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.interaction.InteractionService; import dev.sheldan.abstracto.core.interaction.InteractionService;
@@ -12,12 +11,9 @@ import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService; import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.models.database.AServer; import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.AUserInAServer; import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.MemberService; import dev.sheldan.abstracto.core.service.MemberService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService; import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService; import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
import dev.sheldan.abstracto.core.templating.service.TemplateService;
import dev.sheldan.abstracto.core.utils.CompletableFutureList; import dev.sheldan.abstracto.core.utils.CompletableFutureList;
import dev.sheldan.abstracto.core.utils.FutureUtils; import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.entertainment.config.EntertainmentFeatureDefinition; import dev.sheldan.abstracto.entertainment.config.EntertainmentFeatureDefinition;
@@ -56,38 +52,9 @@ public class CreditLeaderboard extends AbstractConditionableCommand {
@Autowired @Autowired
private InteractionService interactionService; private InteractionService interactionService;
@Autowired
private ChannelService channelService;
@Autowired
private TemplateService templateService;
@Autowired @Autowired
private MemberService memberService; private MemberService memberService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
AServer server = serverManagementService.loadServer(commandContext.getGuild());
List<Object> parameters = commandContext.getParameters().getParameters();
// parameter is optional, in case its not present, we default to the 0th page
Integer page = !parameters.isEmpty() ? (Integer) parameters.get(0) : 1;
List<CreditsLeaderboardEntry> creditLeaderboard = economyService.getCreditLeaderboard(server, page);
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(commandContext.getAuthor());
CreditsLeaderboardEntry ownRank = economyService.getRankOfUser(aUserInAServer);
CreditsLeaderboardResponseModel model = CreditsLeaderboardResponseModel
.builder()
.entries(creditLeaderboard)
.ownRank(ownRank)
.build();
return enrichModelWithMembers(model, commandContext.getGuild().getIdLong())
.thenCompose(model1 -> {
MessageToSend message = templateService.renderEmbedTemplate(CREDIT_LEADERBOARD_RESPONSE, model1, commandContext.getGuild().getIdLong());
return FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(message, commandContext.getChannel()));
})
.thenApply(unused -> CommandResult.fromSuccess());
}
@Override @Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) { public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
event.deferReply().queue(); event.deferReply().queue();
@@ -165,6 +132,7 @@ public class CreditLeaderboard extends AbstractConditionableCommand {
.templated(true) .templated(true)
.async(true) .async(true)
.slashCommandConfig(slashCommandConfig) .slashCommandConfig(slashCommandConfig)
.slashCommandOnly(true)
.supportsEmbedException(true) .supportsEmbedException(true)
.causesReaction(false) .causesReaction(false)
.parameters(parameters) .parameters(parameters)

View File

@@ -4,17 +4,12 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
import dev.sheldan.abstracto.core.command.config.CommandConfiguration; import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo; import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter; import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult; import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition; import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.interaction.InteractionService; import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig; import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.models.database.AUserInAServer; import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService; import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
import dev.sheldan.abstracto.core.templating.service.TemplateService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.entertainment.config.EntertainmentFeatureDefinition; import dev.sheldan.abstracto.entertainment.config.EntertainmentFeatureDefinition;
import dev.sheldan.abstracto.entertainment.config.EntertainmentModuleDefinition; import dev.sheldan.abstracto.entertainment.config.EntertainmentModuleDefinition;
import dev.sheldan.abstracto.entertainment.config.EntertainmentSlashCommandNames; import dev.sheldan.abstracto.entertainment.config.EntertainmentSlashCommandNames;
@@ -44,26 +39,6 @@ public class Credits extends AbstractConditionableCommand {
@Autowired @Autowired
private InteractionService interactionService; private InteractionService interactionService;
@Autowired
private TemplateService templateService;
@Autowired
private ChannelService channelService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
AUserInAServer targetUser = userInServerManagementService.loadOrCreateUser(commandContext.getAuthor());
CreditsLeaderboardEntry rankEntry = economyService.getRankOfUser(targetUser);
rankEntry.setMember(commandContext.getAuthor());
CreditsModel model = CreditsModel
.builder()
.entry(rankEntry)
.build();
MessageToSend messageToSend = templateService.renderEmbedTemplate(CREDITS_RESPONSE, model, commandContext.getGuild().getIdLong());
return FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(messageToSend, commandContext.getChannel()))
.thenApply(interactionHook -> CommandResult.fromSuccess());
}
@Override @Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) { public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
AUserInAServer targetUser = userInServerManagementService.loadOrCreateUser(event.getMember()); AUserInAServer targetUser = userInServerManagementService.loadOrCreateUser(event.getMember());
@@ -98,6 +73,7 @@ public class Credits extends AbstractConditionableCommand {
.async(true) .async(true)
.module(EntertainmentModuleDefinition.ENTERTAINMENT) .module(EntertainmentModuleDefinition.ENTERTAINMENT)
.templated(true) .templated(true)
.slashCommandOnly(true)
.supportsEmbedException(true) .supportsEmbedException(true)
.parameters(parameters) .parameters(parameters)
.help(helpInfo) .help(helpInfo)

View File

@@ -5,18 +5,13 @@ import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo; import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter; import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.config.validator.MinIntegerValueValidator; import dev.sheldan.abstracto.core.command.config.validator.MinIntegerValueValidator;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult; import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition; import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.interaction.InteractionService; import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig; import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService; import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.models.database.AUserInAServer; import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService; import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
import dev.sheldan.abstracto.core.templating.service.TemplateService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.entertainment.config.EntertainmentFeatureDefinition; import dev.sheldan.abstracto.entertainment.config.EntertainmentFeatureDefinition;
import dev.sheldan.abstracto.entertainment.config.EntertainmentModuleDefinition; import dev.sheldan.abstracto.entertainment.config.EntertainmentModuleDefinition;
import dev.sheldan.abstracto.entertainment.config.EntertainmentSlashCommandNames; import dev.sheldan.abstracto.entertainment.config.EntertainmentSlashCommandNames;
@@ -52,24 +47,6 @@ public class Slots extends AbstractConditionableCommand {
@Autowired @Autowired
private UserInServerManagementService userInServerManagementService; private UserInServerManagementService userInServerManagementService;
@Autowired
private TemplateService templateService;
@Autowired
private ChannelService channelService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
Integer bid = (Integer) commandContext.getParameters().getParameters().get(0);
Member member = commandContext.getAuthor();
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(member);
SlotsResult slotsResult = economyUserServiceBean.triggerSlots(aUserInAServer, bid.longValue());
SlotsResponseModel responseModel = SlotsResponseModel.fromSlotsResult(slotsResult);
MessageToSend messageToSend = templateService.renderEmbedTemplate(SLOTS_RESPONSE, responseModel, member.getGuild().getIdLong());
return FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(messageToSend, commandContext.getChannel()))
.thenApply(unused -> CommandResult.fromSuccess());
}
@Override @Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) { public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
Long bid = slashCommandParameterService.getCommandOption(BID_PARAMETER, event, Integer.class).longValue(); Long bid = slashCommandParameterService.getCommandOption(BID_PARAMETER, event, Integer.class).longValue();
@@ -111,6 +88,7 @@ public class Slots extends AbstractConditionableCommand {
.async(true) .async(true)
.module(EntertainmentModuleDefinition.ENTERTAINMENT) .module(EntertainmentModuleDefinition.ENTERTAINMENT)
.templated(true) .templated(true)
.slashCommandOnly(true)
.supportsEmbedException(true) .supportsEmbedException(true)
.parameters(parameters) .parameters(parameters)
.help(helpInfo) .help(helpInfo)

View File

@@ -4,7 +4,6 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
import dev.sheldan.abstracto.core.command.config.CommandConfiguration; import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo; import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter; import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult; import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition; import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.interaction.InteractionService; import dev.sheldan.abstracto.core.interaction.InteractionService;
@@ -12,9 +11,7 @@ import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService; import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.models.database.AUserInAServer; import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay; import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService; import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.entertainment.config.EntertainmentFeatureDefinition; import dev.sheldan.abstracto.entertainment.config.EntertainmentFeatureDefinition;
import dev.sheldan.abstracto.entertainment.config.EntertainmentModuleDefinition; import dev.sheldan.abstracto.entertainment.config.EntertainmentModuleDefinition;
import dev.sheldan.abstracto.entertainment.config.EntertainmentSlashCommandNames; import dev.sheldan.abstracto.entertainment.config.EntertainmentSlashCommandNames;
@@ -48,27 +45,6 @@ public class TransferCredits extends AbstractConditionableCommand {
@Autowired @Autowired
private EconomyService economyService; private EconomyService economyService;
@Autowired
private ChannelService channelService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
Member targetMember = (Member) parameters.get(0);
Integer amount = (Integer) parameters.get(1);
AUserInAServer targetUser = userInServerManagementService.loadOrCreateUser(targetMember);
AUserInAServer sourceUser = userInServerManagementService.loadOrCreateUser(commandContext.getAuthor());
economyService.transferCredits(sourceUser, targetUser, amount.longValue());
TransferCreditsModel responseModel = TransferCreditsModel
.builder()
.sourceMember(MemberDisplay.fromMember(commandContext.getAuthor()))
.targetMember(MemberDisplay.fromMember(targetMember))
.credits(amount)
.build();
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInMessageChannel(TRANSFER_CREDITS_RESPONSE, responseModel, commandContext.getChannel()))
.thenApply(unused -> CommandResult.fromSuccess());
}
@Override @Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) { public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
Member targetMember = slashCommandParameterService.getCommandOption(MEMBER_PARAMETER, event, Member.class); Member targetMember = slashCommandParameterService.getCommandOption(MEMBER_PARAMETER, event, Member.class);
@@ -98,7 +74,6 @@ public class TransferCredits extends AbstractConditionableCommand {
.name(MEMBER_PARAMETER) .name(MEMBER_PARAMETER)
.templated(true) .templated(true)
.type(Member.class) .type(Member.class)
.optional(true)
.build(); .build();
Parameter amountParameter = Parameter Parameter amountParameter = Parameter
@@ -106,7 +81,6 @@ public class TransferCredits extends AbstractConditionableCommand {
.name(AMOUNT_PARAMETER) .name(AMOUNT_PARAMETER)
.templated(true) .templated(true)
.type(Integer.class) .type(Integer.class)
.optional(true)
.build(); .build();
List<Parameter> parameters = Arrays.asList(memberParameter, amountParameter); List<Parameter> parameters = Arrays.asList(memberParameter, amountParameter);
@@ -123,6 +97,7 @@ public class TransferCredits extends AbstractConditionableCommand {
.slashCommandConfig(slashCommandConfig) .slashCommandConfig(slashCommandConfig)
.module(EntertainmentModuleDefinition.ENTERTAINMENT) .module(EntertainmentModuleDefinition.ENTERTAINMENT)
.templated(true) .templated(true)
.slashCommandOnly(true)
.supportsEmbedException(true) .supportsEmbedException(true)
.parameters(parameters) .parameters(parameters)
.causesReaction(false) .causesReaction(false)

View File

@@ -4,18 +4,17 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
import dev.sheldan.abstracto.core.command.config.CommandConfiguration; import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo; import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter; import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext; import dev.sheldan.abstracto.core.command.config.UserCommandConfig;
import dev.sheldan.abstracto.core.command.execution.CommandResult; import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition; import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.interaction.InteractionService; import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig; import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService; import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.models.ServerUser; import dev.sheldan.abstracto.core.models.ServerUser;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.FeatureFlagService; import dev.sheldan.abstracto.core.service.FeatureFlagService;
import dev.sheldan.abstracto.core.templating.model.MessageToSend; import dev.sheldan.abstracto.core.templating.model.MessageToSend;
import dev.sheldan.abstracto.core.templating.service.TemplateService; import dev.sheldan.abstracto.core.templating.service.TemplateService;
import dev.sheldan.abstracto.core.utils.FutureUtils; import dev.sheldan.abstracto.core.utils.ContextUtils;
import dev.sheldan.abstracto.entertainment.config.EntertainmentFeatureDefinition; import dev.sheldan.abstracto.entertainment.config.EntertainmentFeatureDefinition;
import dev.sheldan.abstracto.entertainment.config.EntertainmentModuleDefinition; import dev.sheldan.abstracto.entertainment.config.EntertainmentModuleDefinition;
import dev.sheldan.abstracto.entertainment.config.EntertainmentSlashCommandNames; import dev.sheldan.abstracto.entertainment.config.EntertainmentSlashCommandNames;
@@ -24,7 +23,6 @@ import dev.sheldan.abstracto.entertainment.model.command.games.MineBoard;
import dev.sheldan.abstracto.entertainment.model.database.EconomyUser; import dev.sheldan.abstracto.entertainment.model.database.EconomyUser;
import dev.sheldan.abstracto.entertainment.service.GameService; import dev.sheldan.abstracto.entertainment.service.GameService;
import dev.sheldan.abstracto.entertainment.service.management.EconomyUserManagementService; import dev.sheldan.abstracto.entertainment.service.management.EconomyUserManagementService;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -63,9 +61,6 @@ public class Mines extends AbstractConditionableCommand {
@Autowired @Autowired
private EconomyUserManagementService economyUserManagementService; private EconomyUserManagementService economyUserManagementService;
@Autowired
private ChannelService channelService;
@Override @Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) { public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
Integer width = 5; Integer width = 5;
@@ -81,84 +76,43 @@ public class Mines extends AbstractConditionableCommand {
mines = slashCommandParameterService.getCommandOption(MINES_PARAMETER, event, Integer.class); mines = slashCommandParameterService.getCommandOption(MINES_PARAMETER, event, Integer.class);
} }
Integer credit = null; Integer credit = null;
long serverId = event.getGuild().getIdLong(); Long serverId;
boolean economyEnabled = featureFlagService.getFeatureFlagValue(EntertainmentFeatureDefinition.ECONOMY, serverId); boolean economyEnabled = false;
if(economyEnabled){ if(ContextUtils.isNotUserCommand(event)) {
credit = 50; serverId = event.getGuild().getIdLong();
if(slashCommandParameterService.hasCommandOption(CREDITS_PARAMETER, event)) { economyEnabled = featureFlagService.getFeatureFlagValue(EntertainmentFeatureDefinition.ECONOMY, serverId);
credit = slashCommandParameterService.getCommandOption(CREDITS_PARAMETER, event, Integer.class); if(economyEnabled){
} credit = 50;
if(slashCommandParameterService.hasCommandOption(CREDITS_PARAMETER, event)) {
credit = slashCommandParameterService.getCommandOption(CREDITS_PARAMETER, event, Integer.class);
}
Optional<EconomyUser> userOptional = economyUserManagementService.getUser(ServerUser.fromMember(event.getMember())); Optional<EconomyUser> userOptional = economyUserManagementService.getUser(ServerUser.fromMember(event.getMember()));
if(!userOptional.isPresent()) { if(!userOptional.isPresent()) {
throw new NotEnoughCreditsException(); throw new NotEnoughCreditsException();
} }
EconomyUser user = userOptional.get(); EconomyUser user = userOptional.get();
if(user.getCredits() < credit) { if(user.getCredits() < credit) {
throw new NotEnoughCreditsException(); throw new NotEnoughCreditsException();
}
} }
} else {
serverId = null;
} }
MineBoard board = gameService.createBoard(width, height, mines, serverId); MineBoard board = gameService.createBoard(width, height, mines, serverId);
board.setCreditsEnabled(economyEnabled); board.setCreditsEnabled(economyEnabled);
board.setUserId(event.getMember().getIdLong()); board.setUserId(event.getUser().getIdLong());
board.setServerId(serverId); board.setServerId(serverId);
board.setCredits(credit); board.setCredits(credit);
MessageToSend messageToSend = templateService.renderEmbedTemplate(MINE_BOARD_TEMPLATE_KEY, board, serverId); MessageToSend messageToSend = templateService.renderEmbedTemplate(MINE_BOARD_TEMPLATE_KEY, board, serverId);
return interactionService.replyMessageToSend(messageToSend, event) return interactionService.replyMessageToSend(messageToSend, event)
.thenCompose(interactionHook -> interactionHook.retrieveOriginal().submit()) .thenCompose(interactionHook -> interactionHook.retrieveOriginal().submit())
.thenApply(message -> { .thenApply(message -> {
gameService.persistMineBoardMessage(board, message); gameService.persistMineBoardMessage(board, message, serverId);
return CommandResult.fromSuccess(); return CommandResult.fromSuccess();
}); });
} }
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
Integer width = 5;
List<Object> parameters = commandContext.getParameters().getParameters();
if(!parameters.isEmpty()) {
width = (Integer) parameters.get(0);
}
Integer height = 5;
if(parameters.size() >= 2) {
height = (Integer) parameters.get(1);
}
Integer mines = 5;
if(parameters.size() >= 3) {
mines = (Integer) parameters.get(2);
}
Integer credit = null;
long serverId = commandContext.getGuild().getIdLong();
boolean economyEnabled = featureFlagService.getFeatureFlagValue(EntertainmentFeatureDefinition.ECONOMY, serverId);
if(economyEnabled){
credit = 50;
if(parameters.size() == 4) {
credit = (Integer) parameters.get(3);
}
Optional<EconomyUser> userOptional = economyUserManagementService.getUser(ServerUser.fromMember(commandContext.getAuthor()));
if(!userOptional.isPresent()) {
throw new NotEnoughCreditsException();
}
EconomyUser user = userOptional.get();
if(user.getCredits() < credit) {
throw new NotEnoughCreditsException();
}
}
MineBoard board = gameService.createBoard(width, height, mines, serverId);
board.setCreditsEnabled(economyEnabled);
board.setUserId(commandContext.getAuthor().getIdLong());
board.setServerId(serverId);
board.setCredits(credit);
MessageToSend messageToSend = templateService.renderEmbedTemplate(MINE_BOARD_TEMPLATE_KEY, board, serverId);
List<CompletableFuture<Message>> futures = channelService.sendMessageToSendToChannel(messageToSend, commandContext.getChannel());
return FutureUtils.toSingleFutureGeneric(futures)
.thenAccept(unused -> gameService.persistMineBoardMessage(board, futures.get(0).join()))
.thenApply(unused -> CommandResult.fromSuccess());
}
@Override @Override
public CommandConfiguration getConfiguration() { public CommandConfiguration getConfiguration() {
List<Parameter> parameters = new ArrayList<>(); List<Parameter> parameters = new ArrayList<>();
@@ -207,6 +161,8 @@ public class Mines extends AbstractConditionableCommand {
SlashCommandConfig slashCommandConfig = SlashCommandConfig SlashCommandConfig slashCommandConfig = SlashCommandConfig
.builder() .builder()
.enabled(true) .enabled(true)
.userInstallable(true)
.userCommandConfig(UserCommandConfig.all())
.rootCommandName(EntertainmentSlashCommandNames.GAME) .rootCommandName(EntertainmentSlashCommandNames.GAME)
.commandName(MINES_COMMAND_NAME) .commandName(MINES_COMMAND_NAME)
.build(); .build();
@@ -217,6 +173,7 @@ public class Mines extends AbstractConditionableCommand {
.async(true) .async(true)
.module(EntertainmentModuleDefinition.ENTERTAINMENT) .module(EntertainmentModuleDefinition.ENTERTAINMENT)
.templated(true) .templated(true)
.slashCommandOnly(true)
.supportsEmbedException(true) .supportsEmbedException(true)
.parameters(parameters) .parameters(parameters)
.help(helpInfo) .help(helpInfo)

View File

@@ -9,6 +9,7 @@ import dev.sheldan.abstracto.core.interaction.button.listener.ButtonClickedListe
import dev.sheldan.abstracto.core.service.FeatureFlagService; import dev.sheldan.abstracto.core.service.FeatureFlagService;
import dev.sheldan.abstracto.core.templating.model.MessageToSend; import dev.sheldan.abstracto.core.templating.model.MessageToSend;
import dev.sheldan.abstracto.core.templating.service.TemplateService; import dev.sheldan.abstracto.core.templating.service.TemplateService;
import dev.sheldan.abstracto.core.utils.ContextUtils;
import dev.sheldan.abstracto.entertainment.command.games.Mines; import dev.sheldan.abstracto.entertainment.command.games.Mines;
import dev.sheldan.abstracto.entertainment.config.EntertainmentFeatureDefinition; import dev.sheldan.abstracto.entertainment.config.EntertainmentFeatureDefinition;
import dev.sheldan.abstracto.entertainment.model.command.games.MineBoard; import dev.sheldan.abstracto.entertainment.model.command.games.MineBoard;
@@ -49,13 +50,15 @@ public class MinesButtonClickedListener implements ButtonClickedListener {
GameService.MineResult mineResult = gameService.uncoverField(mineBoard, payload.getX(), payload.getY()); GameService.MineResult mineResult = gameService.uncoverField(mineBoard, payload.getX(), payload.getY());
mineBoard.setState(mineResult); mineBoard.setState(mineResult);
if(mineBoard.getState() != GameService.MineResult.CONTINUE) { if(mineBoard.getState() != GameService.MineResult.CONTINUE) {
if(featureFlagService.getFeatureFlagValue(EntertainmentFeatureDefinition.ECONOMY, model.getServerId())){ if(ContextUtils.isNotUserCommand(model.getEvent())) {
gameService.evaluateCreditChanges(mineBoard); if(featureFlagService.getFeatureFlagValue(EntertainmentFeatureDefinition.ECONOMY, model.getServerId())){
gameService.evaluateCreditChanges(mineBoard);
}
} }
gameService.uncoverBoard(mineBoard); gameService.uncoverBoard(mineBoard);
} }
MessageToSend messageToSend = templateService.renderEmbedTemplate(Mines.MINE_BOARD_TEMPLATE_KEY, mineBoard, model.getServerId()); MessageToSend messageToSend = templateService.renderEmbedTemplate(Mines.MINE_BOARD_TEMPLATE_KEY, mineBoard, model.getServerId());
interactionService.editOriginal(messageToSend, model.getEvent().getHook()).thenAccept(message -> { interactionService.replaceOriginal(messageToSend, model.getEvent().getHook()).thenAccept(message -> {
gameService.updateMineBoard(mineBoard); gameService.updateMineBoard(mineBoard);
log.info("Updated original mineboard for board {}.", mineBoard.getBoardId()); log.info("Updated original mineboard for board {}.", mineBoard.getBoardId());
}); });

View File

@@ -200,8 +200,8 @@ public class EntertainmentServiceBean implements EntertainmentService {
return FutureUtils.toSingleFutureGeneric(channelService.sendMessageEmbedToSendToAChannel(messageToSend, pressF.getPressFChannel())) return FutureUtils.toSingleFutureGeneric(channelService.sendMessageEmbedToSendToAChannel(messageToSend, pressF.getPressFChannel()))
.thenCompose(unused -> messageService.loadMessage(serverId, channelId, messageId).thenCompose(message -> { .thenCompose(unused -> messageService.loadMessage(serverId, channelId, messageId).thenCompose(message -> {
log.info("Clearing buttons from pressF {} in with message {} in channel {} in server {}.", pressFId, pressFId, channelId, serverId); log.info("Clearing buttons from pressF {} in with message {} in channel {} in server {}.", pressFId, pressFId, channelId, serverId);
return componentService.clearButtons(message); return componentService.clearComponents(message);
})); })).thenAccept(message -> {});
} else { } else {
throw new AbstractoRunTimeException(String.format("PressF with id %s not found.", pressFId)); throw new AbstractoRunTimeException(String.format("PressF with id %s not found.", pressFId));
} }

View File

@@ -70,10 +70,16 @@ public class GameServiceBean implements GameService {
@Override @Override
@Transactional @Transactional
public void persistMineBoardMessage(MineBoard mineBoard, Message message) { public void persistMineBoardMessage(MineBoard mineBoard, Message message, Long serverId) {
mineBoard.setMessageId(message.getIdLong()); mineBoard.setMessageId(message.getIdLong());
mineBoard.setChannelId(message.getChannel().getIdLong()); mineBoard.setChannelId(message.getChannel().getIdLong());
AServer server = serverManagementService.loadServer(message.getGuild());
AServer server;
if(serverId != null) {
server = serverManagementService.loadServer(serverId);
} else {
server = null;
}
mineBoard.getFields().forEach(mineBoardField -> { mineBoard.getFields().forEach(mineBoardField -> {
MineBoardPayload payload = MineBoardPayload MineBoardPayload payload = MineBoardPayload
.builder() .builder()

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<artifactId>entertainment</artifactId> <artifactId>entertainment</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId> <groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55</version> <version>1.6.21-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -1,5 +1,6 @@
package dev.sheldan.abstracto.entertainment.model.command; package dev.sheldan.abstracto.entertainment.model.command;
import java.util.List;
import lombok.Builder; import lombok.Builder;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@@ -9,4 +10,5 @@ import lombok.Setter;
@Builder @Builder
public class ChooseResponseModel { public class ChooseResponseModel {
private String chosenValue; private String chosenValue;
private List<String> choices;
} }

View File

@@ -9,4 +9,5 @@ import lombok.Setter;
@Builder @Builder
public class EightBallResponseModel { public class EightBallResponseModel {
private String chosenKey; private String chosenKey;
private String input;
} }

View File

@@ -5,7 +5,7 @@ import net.dv8tion.jda.api.entities.Message;
public interface GameService { public interface GameService {
MineBoard createBoard(Integer width, Integer height, Integer mines, Long serverId); MineBoard createBoard(Integer width, Integer height, Integer mines, Long serverId);
void persistMineBoardMessage(MineBoard mineBoard, Message message); void persistMineBoardMessage(MineBoard mineBoard, Message message, Long serverId);
void updateMineBoard(MineBoard mineBoard); void updateMineBoard(MineBoard mineBoard);
void uncoverBoard(MineBoard mineBoard); void uncoverBoard(MineBoard mineBoard);
void evaluateCreditChanges(MineBoard mineBoard); void evaluateCreditChanges(MineBoard mineBoard);

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<artifactId>abstracto-modules</artifactId> <artifactId>abstracto-modules</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId> <groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.5.55</version> <version>1.6.21-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent> <parent>
<groupId>dev.sheldan.abstracto.modules</groupId> <groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>experience-tracking</artifactId> <artifactId>experience-tracking</artifactId>
<version>1.5.55</version> <version>1.6.21-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@@ -9,6 +9,7 @@ import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.config.FeatureMode; import dev.sheldan.abstracto.core.config.FeatureMode;
import dev.sheldan.abstracto.core.interaction.InteractionService; import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig; import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandPrivilegeLevels;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandAutoCompleteService; import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandAutoCompleteService;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService; import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.models.database.AServer; import dev.sheldan.abstracto.core.models.database.AServer;
@@ -168,6 +169,7 @@ public class AddLevelAction extends AbstractConditionableCommand {
.builder() .builder()
.enabled(true) .enabled(true)
.rootCommandName(ExperienceSlashCommandNames.EXPERIENCE_CONFIG) .rootCommandName(ExperienceSlashCommandNames.EXPERIENCE_CONFIG)
.defaultPrivilege(SlashCommandPrivilegeLevels.INVITER)
.groupName("levelAction") .groupName("levelAction")
.commandName("add") .commandName("add")
.build(); .build();

View File

@@ -5,8 +5,8 @@ import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo; import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter; import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig; import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult; import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandPrivilegeLevels;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService; import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.config.FeatureDefinition; import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException; import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
@@ -47,22 +47,6 @@ public class DisableExpForRole extends AbstractConditionableCommand {
private InteractionService interactionService; private InteractionService interactionService;
@Override
public CommandResult execute(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
Role role = (Role) parameters.get(0);
ARole actualRole = roleManagementService.findRole(role.getIdLong());
if(!actualRole.getServer().getId().equals(commandContext.getGuild().getIdLong())) {
throw new EntityGuildMismatchException();
}
// as we manage experience disabled roles via the existence of them in a table, we should not do anything
// in case it is used a second time as a disabled experience role
if(!disabledExpRoleManagementService.isExperienceDisabledForRole(actualRole)) {
disabledExpRoleManagementService.setRoleToBeDisabledForExp(actualRole);
}
return CommandResult.fromSuccess();
}
@Override @Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) { public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
Role role = slashCommandParameterService.getCommandOption(ROLE_PARAMETER, event, Role.class); Role role = slashCommandParameterService.getCommandOption(ROLE_PARAMETER, event, Role.class);
@@ -97,6 +81,7 @@ public class DisableExpForRole extends AbstractConditionableCommand {
.builder() .builder()
.enabled(true) .enabled(true)
.rootCommandName(ExperienceSlashCommandNames.EXPERIENCE_CONFIG) .rootCommandName(ExperienceSlashCommandNames.EXPERIENCE_CONFIG)
.defaultPrivilege(SlashCommandPrivilegeLevels.INVITER)
.commandName(DISABLE_EXP_FOR_ROLE_COMMAND) .commandName(DISABLE_EXP_FOR_ROLE_COMMAND)
.build(); .build();
@@ -104,6 +89,7 @@ public class DisableExpForRole extends AbstractConditionableCommand {
.name(DISABLE_EXP_FOR_ROLE_COMMAND) .name(DISABLE_EXP_FOR_ROLE_COMMAND)
.module(ExperienceModuleDefinition.EXPERIENCE) .module(ExperienceModuleDefinition.EXPERIENCE)
.templated(true) .templated(true)
.slashCommandOnly(true)
.slashCommandConfig(slashCommandConfig) .slashCommandConfig(slashCommandConfig)
.supportsEmbedException(true) .supportsEmbedException(true)
.causesReaction(true) .causesReaction(true)

View File

@@ -5,8 +5,8 @@ import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo; import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter; import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig; import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult; import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandPrivilegeLevels;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService; import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.config.FeatureDefinition; import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException; import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
@@ -46,17 +46,6 @@ public class DisableExpGain extends AbstractConditionableCommand {
@Autowired @Autowired
private InteractionService interactionService; private InteractionService interactionService;
@Override
public CommandResult execute(CommandContext commandContext) {
Member para = (Member) commandContext.getParameters().getParameters().get(0);
if(!para.getGuild().equals(commandContext.getGuild())) {
throw new EntityGuildMismatchException();
}
AUserInAServer userInAServer = userInServerManagementService.loadOrCreateUser(para);
aUserExperienceService.disableExperienceForUser(userInAServer);
return CommandResult.fromSuccess();
}
@Override @Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) { public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
Member para = slashCommandParameterService.getCommandOption(MEMBER_PARAMETER, event, Member.class); Member para = slashCommandParameterService.getCommandOption(MEMBER_PARAMETER, event, Member.class);
@@ -87,6 +76,7 @@ public class DisableExpGain extends AbstractConditionableCommand {
.builder() .builder()
.enabled(true) .enabled(true)
.rootCommandName(ExperienceSlashCommandNames.EXPERIENCE_CONFIG) .rootCommandName(ExperienceSlashCommandNames.EXPERIENCE_CONFIG)
.defaultPrivilege(SlashCommandPrivilegeLevels.INVITER)
.commandName(DISABLE_EXP_GAIN_COMMAND) .commandName(DISABLE_EXP_GAIN_COMMAND)
.build(); .build();
@@ -96,6 +86,7 @@ public class DisableExpGain extends AbstractConditionableCommand {
.slashCommandConfig(slashCommandConfig) .slashCommandConfig(slashCommandConfig)
.causesReaction(true) .causesReaction(true)
.supportsEmbedException(true) .supportsEmbedException(true)
.slashCommandOnly(true)
.templated(true) .templated(true)
.parameters(parameters) .parameters(parameters)
.help(helpInfo) .help(helpInfo)

View File

@@ -6,11 +6,10 @@ import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter; import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig; import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.command.exception.SlashCommandParameterMissingException; import dev.sheldan.abstracto.core.command.exception.SlashCommandParameterMissingException;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult; import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandPrivilegeLevels;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService; import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.config.FeatureDefinition; import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
import dev.sheldan.abstracto.core.interaction.InteractionService; import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.models.database.ARole; import dev.sheldan.abstracto.core.models.database.ARole;
import dev.sheldan.abstracto.core.service.management.RoleManagementService; import dev.sheldan.abstracto.core.service.management.RoleManagementService;
@@ -49,20 +48,6 @@ public class EnableExpForRole extends AbstractConditionableCommand {
@Autowired @Autowired
private InteractionService interactionService; private InteractionService interactionService;
@Override
public CommandResult execute(CommandContext commandContext) {
ARole role = (ARole) commandContext.getParameters().getParameters().get(0);
ARole actualRole = roleManagementService.findRole(role.getId());
if(!actualRole.getServer().getId().equals(commandContext.getGuild().getIdLong())) {
throw new EntityGuildMismatchException();
}
// If its not disabled for the role, we can remove it
if(disabledExpRoleManagementService.isExperienceDisabledForRole(actualRole)) {
disabledExpRoleManagementService.removeRoleToBeDisabledForExp(actualRole);
}
return CommandResult.fromSuccess();
}
@Override @Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) { public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
ARole actualRole; ARole actualRole;
@@ -100,6 +85,7 @@ public class EnableExpForRole extends AbstractConditionableCommand {
.builder() .builder()
.enabled(true) .enabled(true)
.rootCommandName(ExperienceSlashCommandNames.EXPERIENCE_CONFIG) .rootCommandName(ExperienceSlashCommandNames.EXPERIENCE_CONFIG)
.defaultPrivilege(SlashCommandPrivilegeLevels.INVITER)
.commandName(ENABLE_EXP_FOR_ROLE_COMMAND) .commandName(ENABLE_EXP_FOR_ROLE_COMMAND)
.build(); .build();
@@ -110,6 +96,7 @@ public class EnableExpForRole extends AbstractConditionableCommand {
.slashCommandConfig(slashCommandConfig) .slashCommandConfig(slashCommandConfig)
.causesReaction(true) .causesReaction(true)
.supportsEmbedException(true) .supportsEmbedException(true)
.slashCommandOnly(true)
.parameters(parameters) .parameters(parameters)
.help(helpInfo) .help(helpInfo)
.build(); .build();

View File

@@ -5,8 +5,8 @@ import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo; import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter; import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig; import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult; import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandPrivilegeLevels;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService; import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.config.FeatureDefinition; import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException; import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
@@ -47,17 +47,6 @@ public class EnableExpGain extends AbstractConditionableCommand {
@Autowired @Autowired
private InteractionService interactionService; private InteractionService interactionService;
@Override
public CommandResult execute(CommandContext commandContext) {
Member member = (Member) commandContext.getParameters().getParameters().get(0);
if(!member.getGuild().equals(commandContext.getGuild())) {
throw new EntityGuildMismatchException();
}
AUserInAServer userInAServer = userInServerManagementService.loadOrCreateUser(member);
aUserExperienceService.enableExperienceForUser(userInAServer);
return CommandResult.fromSuccess();
}
@Override @Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) { public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
Member member = slashCommandParameterService.getCommandOption(MEMBER_PARAMETER, event, Member.class); Member member = slashCommandParameterService.getCommandOption(MEMBER_PARAMETER, event, Member.class);
@@ -88,6 +77,7 @@ public class EnableExpGain extends AbstractConditionableCommand {
.builder() .builder()
.enabled(true) .enabled(true)
.rootCommandName(ExperienceSlashCommandNames.EXPERIENCE_CONFIG) .rootCommandName(ExperienceSlashCommandNames.EXPERIENCE_CONFIG)
.defaultPrivilege(SlashCommandPrivilegeLevels.INVITER)
.commandName(ENABLE_EXP_GAIN_COMMAND) .commandName(ENABLE_EXP_GAIN_COMMAND)
.build(); .build();
@@ -98,6 +88,7 @@ public class EnableExpGain extends AbstractConditionableCommand {
.causesReaction(true) .causesReaction(true)
.supportsEmbedException(true) .supportsEmbedException(true)
.templated(true) .templated(true)
.slashCommandOnly(true)
.parameters(parameters) .parameters(parameters)
.help(helpInfo) .help(helpInfo)
.build(); .build();

View File

@@ -4,7 +4,6 @@ import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand
import dev.sheldan.abstracto.core.command.config.CommandConfiguration; import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo; import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter; import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult; import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition; import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.config.FeatureMode; import dev.sheldan.abstracto.core.config.FeatureMode;
@@ -45,13 +44,6 @@ public class ExpLevelUpNotification extends AbstractConditionableCommand {
@Autowired @Autowired
private SlashCommandParameterService slashCommandParameterService; private SlashCommandParameterService slashCommandParameterService;
@Override
public CommandResult execute(CommandContext commandContext) {
Boolean newValue = (Boolean) commandContext.getParameters().getParameters().get(0);
updateExpLevelNotification(commandContext.getAuthor(), newValue);
return CommandResult.fromSuccess();
}
@Override @Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) { public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
Boolean newValue = slashCommandParameterService.getCommandOption(FLAG_PARAMETER, event, Boolean.class); Boolean newValue = slashCommandParameterService.getCommandOption(FLAG_PARAMETER, event, Boolean.class);
@@ -97,6 +89,7 @@ public class ExpLevelUpNotification extends AbstractConditionableCommand {
.slashCommandConfig(slashCommandConfig) .slashCommandConfig(slashCommandConfig)
.causesReaction(true) .causesReaction(true)
.supportsEmbedException(true) .supportsEmbedException(true)
.slashCommandOnly(true)
.templated(true) .templated(true)
.parameters(parameters) .parameters(parameters)
.help(helpInfo) .help(helpInfo)

View File

@@ -5,8 +5,8 @@ import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo; import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter; import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig; import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult; import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandPrivilegeLevels;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService; import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.config.FeatureDefinition; import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.interaction.InteractionService; import dev.sheldan.abstracto.core.interaction.InteractionService;
@@ -44,15 +44,6 @@ public class ExpScale extends AbstractConditionableCommand {
@Autowired @Autowired
private InteractionService interactionService; private InteractionService interactionService;
@Override
public CommandResult execute(CommandContext commandContext) {
Double scale = (Double) commandContext.getParameters().getParameters().get(0);
Long guildId = commandContext.getGuild().getIdLong();
configService.setDoubleValue(ExperienceFeatureConfig.EXP_MULTIPLIER_KEY, guildId, scale);
log.info("Setting experience scale to {} for {}", scale, guildId);
return CommandResult.fromSuccess();
}
@Override @Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) { public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
Double newScale = slashCommandParameterService.getCommandOption(SCALE_PARAMETER, event, Double.class); Double newScale = slashCommandParameterService.getCommandOption(SCALE_PARAMETER, event, Double.class);
@@ -80,6 +71,7 @@ public class ExpScale extends AbstractConditionableCommand {
.builder() .builder()
.enabled(true) .enabled(true)
.rootCommandName(ExperienceSlashCommandNames.EXPERIENCE_CONFIG) .rootCommandName(ExperienceSlashCommandNames.EXPERIENCE_CONFIG)
.defaultPrivilege(SlashCommandPrivilegeLevels.INVITER)
.commandName(EXP_SCALE_COMMAND) .commandName(EXP_SCALE_COMMAND)
.build(); .build();
@@ -88,6 +80,7 @@ public class ExpScale extends AbstractConditionableCommand {
.name(EXP_SCALE_COMMAND) .name(EXP_SCALE_COMMAND)
.module(ExperienceModuleDefinition.EXPERIENCE) .module(ExperienceModuleDefinition.EXPERIENCE)
.causesReaction(true) .causesReaction(true)
.slashCommandOnly(true)
.slashCommandConfig(slashCommandConfig) .slashCommandConfig(slashCommandConfig)
.templated(true) .templated(true)
.supportsEmbedException(true) .supportsEmbedException(true)

View File

@@ -97,7 +97,7 @@ public class LeaderBoardCommand extends AbstractConditionableCommand {
} else { } else {
leaderBoard = userExperienceService.findLeaderBoardData(server, page); leaderBoard = userExperienceService.findLeaderBoardData(server, page);
} }
List<CompletableFuture> futures = new ArrayList<>(); List<CompletableFuture<?>> futures = new ArrayList<>();
CompletableFuture<List<LeaderBoardEntryModel>> completableFutures = converter.fromLeaderBoard(leaderBoard, actorUser.getGuild().getIdLong()); CompletableFuture<List<LeaderBoardEntryModel>> completableFutures = converter.fromLeaderBoard(leaderBoard, actorUser.getGuild().getIdLong());
futures.add(completableFutures); futures.add(completableFutures);
log.info("Rendering leaderboard for page {} in server {} for user {}.", page, actorUser.getId(), actorUser.getGuild().getId()); log.info("Rendering leaderboard for page {} in server {} for user {}.", page, actorUser.getId(), actorUser.getGuild().getId());
@@ -158,7 +158,6 @@ public class LeaderBoardCommand extends AbstractConditionableCommand {
Parameter focusMe = Parameter Parameter focusMe = Parameter
.builder() .builder()
.name(FOCUS_PARAMETER) .name(FOCUS_PARAMETER)
.validators(leaderBoardPageValidators)
.optional(true) .optional(true)
.slashCommandOnly(true) .slashCommandOnly(true)
.templated(true) .templated(true)

View File

@@ -5,25 +5,22 @@ import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo; import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter; import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig; import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult; import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition; import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.interaction.InteractionService; import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandPrivilegeLevels;
import dev.sheldan.abstracto.core.models.FullRole; import dev.sheldan.abstracto.core.models.FullRole;
import dev.sheldan.abstracto.core.models.database.AServer; import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.RoleService; import dev.sheldan.abstracto.core.service.RoleService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService; import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.core.templating.model.MessageToSend; import dev.sheldan.abstracto.core.templating.model.MessageToSend;
import dev.sheldan.abstracto.core.templating.service.TemplateService; import dev.sheldan.abstracto.core.templating.service.TemplateService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.experience.config.ExperienceFeatureDefinition; import dev.sheldan.abstracto.experience.config.ExperienceFeatureDefinition;
import dev.sheldan.abstracto.experience.config.ExperienceSlashCommandNames; import dev.sheldan.abstracto.experience.config.ExperienceSlashCommandNames;
import dev.sheldan.abstracto.experience.model.database.ADisabledExpRole; import dev.sheldan.abstracto.experience.model.database.ADisabledExpRole;
import dev.sheldan.abstracto.experience.model.template.DisabledExperienceRolesModel; import dev.sheldan.abstracto.experience.model.template.DisabledExperienceRolesModel;
import dev.sheldan.abstracto.experience.service.management.DisabledExpRoleManagementService; import dev.sheldan.abstracto.experience.service.management.DisabledExpRoleManagementService;
import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.Role; import net.dv8tion.jda.api.entities.Role;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -49,9 +46,6 @@ public class ListDisabledExperienceRoles extends AbstractConditionableCommand {
@Autowired @Autowired
private RoleService roleService; private RoleService roleService;
@Autowired
private ChannelService channelService;
@Autowired @Autowired
private ServerManagementService serverManagementService; private ServerManagementService serverManagementService;
@@ -61,14 +55,6 @@ public class ListDisabledExperienceRoles extends AbstractConditionableCommand {
@Autowired @Autowired
private InteractionService interactionService; private InteractionService interactionService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
Long serverId = commandContext.getGuild().getIdLong();
MessageToSend messageToSend = getResponseModel(serverId, commandContext.getAuthor());
List<CompletableFuture<Message>> futures = channelService.sendMessageToSendToChannel(messageToSend, commandContext.getChannel());
return FutureUtils.toSingleFutureGeneric(futures).thenApply(aVoid -> CommandResult.fromIgnored());
}
@Override @Override
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) { public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
Long serverId = event.getGuild().getIdLong(); Long serverId = event.getGuild().getIdLong();
@@ -112,6 +98,7 @@ public class ListDisabledExperienceRoles extends AbstractConditionableCommand {
.builder() .builder()
.enabled(true) .enabled(true)
.rootCommandName(ExperienceSlashCommandNames.EXPERIENCE_CONFIG) .rootCommandName(ExperienceSlashCommandNames.EXPERIENCE_CONFIG)
.defaultPrivilege(SlashCommandPrivilegeLevels.INVITER)
.commandName(LIST_DISABLED_EXPERIENCE_ROLES_COMMAND) .commandName(LIST_DISABLED_EXPERIENCE_ROLES_COMMAND)
.build(); .build();
@@ -122,6 +109,7 @@ public class ListDisabledExperienceRoles extends AbstractConditionableCommand {
.templated(true) .templated(true)
.supportsEmbedException(true) .supportsEmbedException(true)
.causesReaction(true) .causesReaction(true)
.slashCommandOnly(true)
.async(true) .async(true)
.aliases(aliases) .aliases(aliases)
.parameters(parameters) .parameters(parameters)

View File

@@ -9,6 +9,7 @@ import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.config.FeatureMode; import dev.sheldan.abstracto.core.config.FeatureMode;
import dev.sheldan.abstracto.core.interaction.InteractionService; import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig; import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandPrivilegeLevels;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandAutoCompleteService; import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandAutoCompleteService;
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService; import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
import dev.sheldan.abstracto.core.models.database.AServer; import dev.sheldan.abstracto.core.models.database.AServer;
@@ -142,6 +143,7 @@ public class RemoveLevelAction extends AbstractConditionableCommand {
.builder() .builder()
.enabled(true) .enabled(true)
.rootCommandName(ExperienceSlashCommandNames.EXPERIENCE_CONFIG) .rootCommandName(ExperienceSlashCommandNames.EXPERIENCE_CONFIG)
.defaultPrivilege(SlashCommandPrivilegeLevels.INVITER)
.groupName("levelAction") .groupName("levelAction")
.commandName("remove") .commandName("remove")
.build(); .build();

View File

@@ -8,6 +8,7 @@ import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.config.FeatureMode; import dev.sheldan.abstracto.core.config.FeatureMode;
import dev.sheldan.abstracto.core.interaction.InteractionService; import dev.sheldan.abstracto.core.interaction.InteractionService;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig; import dev.sheldan.abstracto.core.interaction.slash.SlashCommandConfig;
import dev.sheldan.abstracto.core.interaction.slash.SlashCommandPrivilegeLevels;
import dev.sheldan.abstracto.experience.config.ExperienceFeatureDefinition; import dev.sheldan.abstracto.experience.config.ExperienceFeatureDefinition;
import dev.sheldan.abstracto.experience.config.ExperienceFeatureMode; import dev.sheldan.abstracto.experience.config.ExperienceFeatureMode;
import dev.sheldan.abstracto.experience.config.ExperienceSlashCommandNames; import dev.sheldan.abstracto.experience.config.ExperienceSlashCommandNames;
@@ -51,6 +52,7 @@ public class ShowLevelActions extends AbstractConditionableCommand {
.builder() .builder()
.enabled(true) .enabled(true)
.rootCommandName(ExperienceSlashCommandNames.EXPERIENCE_CONFIG) .rootCommandName(ExperienceSlashCommandNames.EXPERIENCE_CONFIG)
.defaultPrivilege(SlashCommandPrivilegeLevels.INVITER)
.groupName("levelAction") .groupName("levelAction")
.commandName("show") .commandName("show")
.build(); .build();

View File

@@ -313,107 +313,107 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
Long userInServerId = userInAServer.getUserInServerId(); Long userInServerId = userInAServer.getUserInServerId();
Optional<AUserExperience> aUserExperienceOptional = userExperienceManagementService.findByUserInServerIdOptional(userInAServer.getUserInServerId()); Optional<AUserExperience> aUserExperienceOptional = userExperienceManagementService.findByUserInServerIdOptional(userInAServer.getUserInServerId());
AUserExperience aUserExperience = aUserExperienceOptional.orElseGet(() -> userExperienceManagementService.createUserInServer(userInAServer)); AUserExperience aUserExperience = aUserExperienceOptional.orElseGet(() -> userExperienceManagementService.createUserInServer(userInAServer));
if(Boolean.FALSE.equals(aUserExperience.getExperienceGainDisabled())) { if (aUserExperience.getExperienceGainDisabled().equals(Boolean.TRUE)) {
List<AExperienceLevel> levels = experienceLevelManagementService.getLevelConfig();
levels.sort(Comparator.comparing(AExperienceLevel::getExperienceNeeded));
Long minExp = configService.getLongValueOrConfigDefault(ExperienceFeatureConfig.MIN_EXP_KEY, serverId);
Long maxExp = configService.getLongValueOrConfigDefault(ExperienceFeatureConfig.MAX_EXP_KEY, serverId);
Double multiplier = configService.getDoubleValueOrConfigDefault(ExperienceFeatureConfig.EXP_MULTIPLIER_KEY, serverId);
Long experienceRange = maxExp - minExp + 1;
Long gainedExperience = (secureRandom.nextInt(experienceRange.intValue()) + minExp);
gainedExperience = (long) Math.floor(gainedExperience * multiplier);
List<AExperienceRole> roles = experienceRoleManagementService.getExperienceRolesForServer(server);
roles.sort(Comparator.comparing(role -> role.getLevel().getLevel()));
log.debug("Handling {}. The user gains {}.", userInServerId, gainedExperience);
Long oldExperience = aUserExperience.getExperience();
Long newExperienceCount = oldExperience + gainedExperience;
aUserExperience.setExperience(newExperienceCount);
AExperienceLevel newLevel = calculateLevel(levels, newExperienceCount);
RoleCalculationResult result = RoleCalculationResult
.builder()
.build();
boolean userChangesLevel = !Objects.equals(newLevel.getLevel(), aUserExperience.getCurrentLevel().getLevel());
Integer oldLevel = aUserExperience.getCurrentLevel() != null ? aUserExperience.getCurrentLevel().getLevel() : 0;
if(userChangesLevel) {
log.info("User {} in server {} changed level. New {}, Old {}.", member.getIdLong(),
member.getGuild().getIdLong(), newLevel.getLevel(),
oldLevel);
aUserExperience.setCurrentLevel(newLevel);
AExperienceRole calculatedNewRole = experienceRoleService.calculateRole(roles, newLevel.getLevel());
Long oldRoleId = aUserExperience.getCurrentExperienceRole() != null && aUserExperience.getCurrentExperienceRole().getRole() != null ? aUserExperience.getCurrentExperienceRole().getRole().getId() : null;
Long newRoleId = calculatedNewRole != null && calculatedNewRole.getRole() != null ? calculatedNewRole.getRole().getId() : null;
result.setOldRoleId(oldRoleId);
result.setNewRoleId(newRoleId);
if(message != null
&& aUserExperience.getLevelUpNotification()
&& featureModeService.featureModeActive(ExperienceFeatureDefinition.EXPERIENCE, serverId, ExperienceFeatureMode.LEVEL_UP_NOTIFICATION)) {
LevelUpNotificationModel model = LevelUpNotificationModel
.builder()
.memberDisplay(MemberDisplay.fromMember(member))
.oldExperience(oldExperience)
.newExperience(newExperienceCount)
.newLevel(newLevel.getLevel())
.oldLevel(oldLevel)
.newRole(oldRoleId != null ? RoleDisplay.fromRole(oldRoleId) : null)
.newRole(newRoleId != null ? RoleDisplay.fromRole(newRoleId) : null)
.build();
MessageToSend messageToSend = templateService.renderEmbedTemplate("experience_level_up_notification", model, serverId);
FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(messageToSend, message.getChannel())).thenAccept(unused -> {
log.info("Sent level up notification to user {} in server {} in channel {}.", member.getIdLong(), serverId, message.getChannel().getIdLong());
}).exceptionally(throwable -> {
log.warn("Failed to send level up notification to user {} in server {} in channel {}.", member.getIdLong(), serverId, message.getChannel().getIdLong());
return null;
});
}
aUserExperience.setCurrentExperienceRole(calculatedNewRole);
}
aUserExperience.setMessageCount(aUserExperience.getMessageCount() + 1L);
if(userChangesLevel && featureModeService.featureModeActive(ExperienceFeatureDefinition.EXPERIENCE, server, ExperienceFeatureMode.LEVEL_ACTION)) {
levelActionService.applyLevelActionsToUser(aUserExperience, oldLevel)
.thenAccept(unused -> {
log.info("Executed level actions for user {}.", userInServerId);
})
.exceptionally(throwable -> {
log.warn("Failed to execute level actions for user {}.", userInServerId, throwable);
return null;
});
}
if(aUserExperienceOptional.isEmpty()) {
userExperienceManagementService.saveUser(aUserExperience);
}
if(!Objects.equals(result.getOldRoleId(), result.getNewRoleId())) {
if(result.getOldRoleId() != null && result.getNewRoleId() != null) {
roleService.updateRolesIds(member, Arrays.asList(result.getOldRoleId()), Arrays.asList(result.getNewRoleId())).thenAccept(unused -> {
log.debug("Removed role {} from and added role {} to member {} in server {}.", result.getOldRoleId(), result.getNewRoleId(), member.getIdLong(), member.getGuild().getIdLong());
}).exceptionally(throwable -> {
log.warn("Failed to remove role {} from and add role {} to member {} in server {}.", result.getOldRoleId(), result.getNewRoleId(), member.getIdLong(), member.getGuild().getIdLong(), throwable);
return null;
});
} else {
if(result.getOldRoleId() != null) {
roleService.removeRoleFromMemberAsync(member, result.getOldRoleId()).thenAccept(unused -> {
log.debug("Removed role {} from member {} in server {}.", result.getOldRoleId(), member.getIdLong(), member.getGuild().getIdLong());
}).exceptionally(throwable -> {
log.warn("Failed to remove role {} from member {} in server {}.", result.getOldRoleId(), member.getIdLong(), member.getGuild().getIdLong(), throwable);
return null;
});
}
if(result.getNewRoleId() != null) {
roleService.addRoleToMemberAsync(member, result.getNewRoleId()).thenAccept(unused -> {
log.debug("Added role {} to member {} in server {}.", result.getNewRoleId(), member.getIdLong(), member.getGuild().getIdLong());
}).exceptionally(throwable -> {
log.warn("Failed to add role {} to member {} in server {}.", result.getOldRoleId(), member.getIdLong(), member.getGuild().getIdLong(), throwable);
return null;
});
}
}
}
} else {
log.debug("Experience gain was disabled. User did not gain any experience."); log.debug("Experience gain was disabled. User did not gain any experience.");
return;
}
List<AExperienceLevel> levels = experienceLevelManagementService.getLevelConfig();
levels.sort(Comparator.comparing(AExperienceLevel::getExperienceNeeded));
Long minExp = configService.getLongValueOrConfigDefault(ExperienceFeatureConfig.MIN_EXP_KEY, serverId);
Long maxExp = configService.getLongValueOrConfigDefault(ExperienceFeatureConfig.MAX_EXP_KEY, serverId);
Double multiplier = configService.getDoubleValueOrConfigDefault(ExperienceFeatureConfig.EXP_MULTIPLIER_KEY, serverId);
Long experienceRange = maxExp - minExp + 1;
Long gainedExperience = (secureRandom.nextInt(experienceRange.intValue()) + minExp);
gainedExperience = (long) Math.floor(gainedExperience * multiplier);
List<AExperienceRole> roles = experienceRoleManagementService.getExperienceRolesForServer(server);
roles.sort(Comparator.comparing(role -> role.getLevel().getLevel()));
log.debug("Handling {}. The user gains {}.", userInServerId, gainedExperience);
Long oldExperience = aUserExperience.getExperience();
Long newExperienceCount = oldExperience + gainedExperience;
aUserExperience.setExperience(newExperienceCount);
AExperienceLevel newLevel = calculateLevel(levels, newExperienceCount);
RoleCalculationResult result = RoleCalculationResult
.builder()
.build();
boolean userChangesLevel = !Objects.equals(newLevel.getLevel(), aUserExperience.getCurrentLevel().getLevel());
Integer oldLevel = aUserExperience.getCurrentLevel() != null ? aUserExperience.getCurrentLevel().getLevel() : 0;
if(userChangesLevel) {
log.info("User {} in server {} changed level. New {}, Old {}.", member.getIdLong(),
member.getGuild().getIdLong(), newLevel.getLevel(),
oldLevel);
aUserExperience.setCurrentLevel(newLevel);
AExperienceRole calculatedNewRole = experienceRoleService.calculateRole(roles, newLevel.getLevel());
Long oldRoleId = aUserExperience.getCurrentExperienceRole() != null && aUserExperience.getCurrentExperienceRole().getRole() != null ? aUserExperience.getCurrentExperienceRole().getRole().getId() : null;
Long newRoleId = calculatedNewRole != null && calculatedNewRole.getRole() != null ? calculatedNewRole.getRole().getId() : null;
result.setOldRoleId(oldRoleId);
result.setNewRoleId(newRoleId);
if(message != null
&& aUserExperience.getLevelUpNotification()
&& featureModeService.featureModeActive(ExperienceFeatureDefinition.EXPERIENCE, serverId, ExperienceFeatureMode.LEVEL_UP_NOTIFICATION)) {
LevelUpNotificationModel model = LevelUpNotificationModel
.builder()
.memberDisplay(MemberDisplay.fromMember(member))
.oldExperience(oldExperience)
.newExperience(newExperienceCount)
.newLevel(newLevel.getLevel())
.oldLevel(oldLevel)
.newRole(oldRoleId != null ? RoleDisplay.fromRole(oldRoleId) : null)
.newRole(newRoleId != null ? RoleDisplay.fromRole(newRoleId) : null)
.build();
MessageToSend messageToSend = templateService.renderEmbedTemplate("experience_level_up_notification", model, serverId);
FutureUtils.toSingleFutureGeneric(channelService.sendMessageToSendToChannel(messageToSend, message.getChannel())).thenAccept(unused -> {
log.info("Sent level up notification to user {} in server {} in channel {}.", member.getIdLong(), serverId, message.getChannel().getIdLong());
}).exceptionally(throwable -> {
log.warn("Failed to send level up notification to user {} in server {} in channel {}.", member.getIdLong(), serverId, message.getChannel().getIdLong());
return null;
});
}
aUserExperience.setCurrentExperienceRole(calculatedNewRole);
}
aUserExperience.setMessageCount(aUserExperience.getMessageCount() + 1L);
if(userChangesLevel && featureModeService.featureModeActive(ExperienceFeatureDefinition.EXPERIENCE, server, ExperienceFeatureMode.LEVEL_ACTION)) {
levelActionService.applyLevelActionsToUser(aUserExperience, oldLevel)
.thenAccept(unused -> {
log.info("Executed level actions for user {}.", userInServerId);
})
.exceptionally(throwable -> {
log.warn("Failed to execute level actions for user {}.", userInServerId, throwable);
return null;
});
}
if(aUserExperienceOptional.isEmpty()) {
userExperienceManagementService.saveUser(aUserExperience);
}
if(!Objects.equals(result.getOldRoleId(), result.getNewRoleId())) {
if(result.getOldRoleId() != null && result.getNewRoleId() != null) {
roleService.updateRolesIds(member, List.of(result.getOldRoleId()), List.of(result.getNewRoleId())).thenAccept(unused -> {
log.debug("Removed role {} from and added role {} to member {} in server {}.", result.getOldRoleId(), result.getNewRoleId(), member.getIdLong(), member.getGuild().getIdLong());
}).exceptionally(throwable -> {
log.warn("Failed to remove role {} from and add role {} to member {} in server {}.", result.getOldRoleId(), result.getNewRoleId(), member.getIdLong(), member.getGuild().getIdLong(), throwable);
return null;
});
} else {
if(result.getOldRoleId() != null) {
roleService.removeRoleFromMemberAsync(member, result.getOldRoleId()).thenAccept(unused -> {
log.debug("Removed role {} from member {} in server {}.", result.getOldRoleId(), member.getIdLong(), member.getGuild().getIdLong());
}).exceptionally(throwable -> {
log.warn("Failed to remove role {} from member {} in server {}.", result.getOldRoleId(), member.getIdLong(), member.getGuild().getIdLong(), throwable);
return null;
});
}
if(result.getNewRoleId() != null) {
roleService.addRoleToMemberAsync(member, result.getNewRoleId()).thenAccept(unused -> {
log.debug("Added role {} to member {} in server {}.", result.getNewRoleId(), member.getIdLong(), member.getGuild().getIdLong());
}).exceptionally(throwable -> {
log.warn("Failed to add role {} to member {} in server {}.", result.getOldRoleId(), member.getIdLong(), member.getGuild().getIdLong(), throwable);
return null;
});
}
}
} }
} }
@@ -521,7 +521,7 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
public LeaderBoardEntry getRankOfUserInServer(AUserInAServer userInAServer) { public LeaderBoardEntry getRankOfUserInServer(AUserInAServer userInAServer) {
log.debug("Retrieving rank for {}", userInAServer.getUserReference().getId()); log.debug("Retrieving rank for {}", userInAServer.getUserReference().getId());
Optional<AUserExperience> aUserExperienceOptional = userExperienceManagementService.findByUserInServerIdOptional(userInAServer.getUserInServerId()); Optional<AUserExperience> aUserExperienceOptional = userExperienceManagementService.findByUserInServerIdOptional(userInAServer.getUserInServerId());
if(!aUserExperienceOptional.isPresent()) { if(aUserExperienceOptional.isEmpty()) {
throw new NoExperienceTrackedException(); throw new NoExperienceTrackedException();
} }
Integer rank = 0; Integer rank = 0;

View File

@@ -52,7 +52,7 @@ public class ExperienceLevelServiceBean implements ExperienceLevelService {
if(level < 0) { if(level < 0) {
throw new IllegalArgumentException("Level should not be less to 0."); throw new IllegalArgumentException("Level should not be less to 0.");
} }
return 5L * (level * level) + 50 * level + 100; return 5L * ((long) level * level) + 50L * level + 100;
} }
@Override @Override

View File

@@ -88,7 +88,7 @@ public class ExperienceRoleServiceBean implements ExperienceRoleService {
@Override @Override
public CompletableFuture<Void> unsetRoles(List<ARole> rolesToUnset, GuildMessageChannel messageChannel) { public CompletableFuture<Void> unsetRoles(List<ARole> rolesToUnset, GuildMessageChannel messageChannel) {
List<AExperienceRole> rolesInServer = experienceRoleManagementService.getRolesInServer(rolesToUnset); List<AExperienceRole> rolesInServer = experienceRoleManagementService.getRolesInServer(rolesToUnset);
Integer totalCount = 0; int totalCount = 0;
for (AExperienceRole aExperienceRole : rolesInServer) { for (AExperienceRole aExperienceRole : rolesInServer) {
totalCount += aExperienceRole.getUsers().size(); totalCount += aExperienceRole.getUsers().size();
} }

View File

@@ -1,5 +1,8 @@
package dev.sheldan.abstracto.experience.service; package dev.sheldan.abstracto.experience.service;
import java.util.HashSet;
import java.util.Set;
import lombok.Getter;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.time.Instant; import java.time.Instant;
@@ -17,11 +20,9 @@ import java.util.concurrent.locks.ReentrantLock;
@Component @Component
public class RunTimeExperienceService { public class RunTimeExperienceService {
private Map<Long,Map<Long, Instant>> runtimeExperience = new HashMap<>(); @Getter
private final Map<Long,Map<Long, Instant>> runtimeExperience = new HashMap<>();
private static final Lock lock = new ReentrantLock(); private static final Lock lock = new ReentrantLock();
public Map<Long, Map<Long, Instant>> getRuntimeExperience() {
return runtimeExperience;
}
/** /**
* Acquires the lock of the runtime experience data structure. Operations on it should only be done, while holding the lock * Acquires the lock of the runtime experience data structure. Operations on it should only be done, while holding the lock
@@ -39,6 +40,7 @@ public class RunTimeExperienceService {
public void cleanupRunTimeStorage() { public void cleanupRunTimeStorage() {
Instant now = Instant.now(); Instant now = Instant.now();
Set<Long> serverIdsToRemove = new HashSet<>();
runtimeExperience.forEach((serverId, userInstantMap) -> { runtimeExperience.forEach((serverId, userInstantMap) -> {
List<Long> userIdsToRemove = new ArrayList<>(); List<Long> userIdsToRemove = new ArrayList<>();
userInstantMap.forEach((userId, instant) -> { userInstantMap.forEach((userId, instant) -> {
@@ -47,6 +49,10 @@ public class RunTimeExperienceService {
} }
}); });
userIdsToRemove.forEach(userInstantMap::remove); userIdsToRemove.forEach(userInstantMap::remove);
if(userInstantMap.isEmpty()) {
serverIdsToRemove.add(serverId);
}
}); });
serverIdsToRemove.forEach(runtimeExperience::remove);
} }
} }

View File

@@ -0,0 +1,32 @@
package dev.sheldan.abstracto.experience.service;
import static org.assertj.core.api.Assertions.assertThat;
import java.time.Instant;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
public class RuntimeExperienceServiceTest {
@Test
public void shouldCleanExpiredExperience() {
RunTimeExperienceService experienceService = new RunTimeExperienceService();
Map<Long, Instant> mapValue = new HashMap<>(Map.of(2L, Instant.now().minusSeconds(5)));
experienceService.getRuntimeExperience().put(1L, mapValue);
experienceService.cleanupRunTimeStorage();
assertThat(experienceService.getRuntimeExperience()).isEmpty();
}
@Test
public void shouldLeaveExperienceIfNotYetExpired() {
RunTimeExperienceService experienceService = new RunTimeExperienceService();
Map<Long, Instant> mapValue2 = new HashMap<>(Map.of(3L, Instant.now().plusSeconds(5)));
experienceService.getRuntimeExperience().put(2L, mapValue2);
experienceService.cleanupRunTimeStorage();
assertThat(experienceService.getRuntimeExperience().get(2L)).containsKey(3L);
assertThat(experienceService.getRuntimeExperience()).hasSize(1);
}
}

Some files were not shown because too many files have changed in this diff Show More