mirror of
https://github.com/Sheldan/abstracto.git
synced 2026-04-10 02:22:51 +00:00
Compare commits
92 Commits
abstracto-
...
4b3038078e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4b3038078e | ||
|
|
af5f9a8361 | ||
|
|
e84b5ecbb5 | ||
|
|
1ba8219d7b | ||
|
|
60d2c669a2 | ||
|
|
3a122a72e5 | ||
|
|
d53126e5a5 | ||
|
|
208d9a28ed | ||
|
|
6643359953 | ||
|
|
bd7149d159 | ||
|
|
c0b6a19bca | ||
|
|
58eece0814 | ||
|
|
abfd2c9591 | ||
|
|
a71a448b4b | ||
|
|
4d1ce7158f | ||
|
|
9bbb9430d9 | ||
|
|
a608fba082 | ||
|
|
f97fe42e65 | ||
|
|
f12581f322 | ||
|
|
e8f630c94c | ||
|
|
14f35caede | ||
|
|
915eb8ced9 | ||
|
|
148c10f250 | ||
|
|
74e5154e29 | ||
|
|
baad696a20 | ||
|
|
b7b5dc7b6a | ||
|
|
f27f59c0b3 | ||
|
|
ccd7ace8d9 | ||
|
|
73a73dc4f2 | ||
|
|
156725afa6 | ||
|
|
b369b56823 | ||
|
|
7482bf545d | ||
|
|
9804d165ca | ||
|
|
59ddb0b27d | ||
|
|
9aea9d2b4f | ||
|
|
b042e586a7 | ||
|
|
91e2bea2fc | ||
|
|
f03bee8b1e | ||
|
|
f3144eb094 | ||
|
|
2396bf300b | ||
|
|
06ebf4c882 | ||
|
|
ff534c03ac | ||
|
|
67c76487e2 | ||
|
|
9a2f47e244 | ||
|
|
2f33d19171 | ||
|
|
f6fc02e758 | ||
|
|
007929cfa5 | ||
|
|
77e2eec3d1 | ||
|
|
74c8cf7b6b | ||
|
|
c8739b90ec | ||
|
|
d39a303207 | ||
|
|
3e326fe47e | ||
|
|
a1d460973c | ||
|
|
d2475179e6 | ||
|
|
5adc304e77 | ||
|
|
4940577383 | ||
|
|
bba0a2ace6 | ||
|
|
b7c427026d | ||
|
|
cee10de915 | ||
|
|
1786231e11 | ||
|
|
2231fdf289 | ||
|
|
a46e22b5b2 | ||
|
|
1c9b9af833 | ||
|
|
3cafc95ceb | ||
|
|
6409bbaa1d | ||
|
|
346e462185 | ||
|
|
46baa79d3e | ||
|
|
650d062808 | ||
|
|
bac9832819 | ||
|
|
efbcb5c84b | ||
|
|
fd70e6ac90 | ||
|
|
29bde70796 | ||
|
|
ecd4feabb2 | ||
|
|
abf60409f1 | ||
|
|
080733957f | ||
|
|
8a41f366ae | ||
|
|
dbf478c44c | ||
|
|
3df688571f | ||
|
|
ca530949c6 | ||
|
|
724930e5a4 | ||
|
|
2875da117a | ||
|
|
f95ba6c28f | ||
|
|
1b2e7654f9 | ||
|
|
54976ed1d4 | ||
|
|
735816f5dd | ||
|
|
a984bdb84e | ||
|
|
21add6585d | ||
|
|
99e72245f3 | ||
|
|
9d184ff560 | ||
|
|
97895f5c56 | ||
|
|
f091559c49 | ||
|
|
fa7730975e |
19
.github/workflows/build.yml
vendored
19
.github/workflows/build.yml
vendored
@@ -1,7 +1,7 @@
|
||||
# This workflow will build a Java project with Maven
|
||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
|
||||
|
||||
name: Execute build and Sonar
|
||||
name: Execute Build
|
||||
|
||||
on:
|
||||
push:
|
||||
@@ -20,26 +20,13 @@ jobs:
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up JDK 1.8
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'corretto'
|
||||
java-version: 8
|
||||
java-version: 17
|
||||
- name: Build with Maven
|
||||
run: mvn -B install --file abstracto-application/pom.xml
|
||||
- name: Setup sonarqube
|
||||
uses: warchant/setup-sonar-scanner@v3
|
||||
- name: Run sonarqube
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: sonar-scanner
|
||||
-Dsonar.login=${{ secrets.SONAR_TOKEN }}
|
||||
-Dsonar.organization=sheldan
|
||||
-Dsonar.host.url=https://sonarcloud.io/
|
||||
-Dsonar.projectKey=abstracto-core
|
||||
-Dsonar.java.binaries=**/target/classes
|
||||
-Dsonar.coverage.jacoco.xmlReportPaths=abstracto-application/coverage/target/site/jacoco-aggregate/jacoco.xml
|
||||
-Dsonar.coverage.exclusions=**/*Test.java
|
||||
- uses: actions/setup-ruby@v1
|
||||
- name: Send Webhook Notification
|
||||
if: always()
|
||||
|
||||
23
.github/workflows/release.yml
vendored
23
.github/workflows/release.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'corretto'
|
||||
java-version: 8
|
||||
java-version: 17
|
||||
- name: Load current version
|
||||
id: version
|
||||
run: echo "version=$(mvn --file abstracto-application/pom.xml -q -Dexec.executable="echo" -Dexec.args='${project.version}' --non-recursive exec:exec)" >> $GITHUB_ENV
|
||||
@@ -37,15 +37,20 @@ jobs:
|
||||
branch: master
|
||||
ssh-key: ${{ secrets.ACTIONS_DEPLOY_KEY }}
|
||||
folder: abstracto-application/documentation/target/generated-docs
|
||||
- name: Login to GitHub Packages Docker Registry
|
||||
- name: Login to Harbor
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: docker.pkg.github.com
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Push deployment container
|
||||
working-directory: ./abstracto-application/installer/src/main/docker/deployment
|
||||
registry: harbor.sheldan.dev
|
||||
username: ${{ secrets.HARBOR_USERNAME }}
|
||||
password: ${{ secrets.HARBOR_TOKEN }}
|
||||
- name: Load env files
|
||||
id: dotenv
|
||||
uses: falti/dotenv-action@v1.0.4
|
||||
with:
|
||||
path: ./deployment/installer/.env
|
||||
- name: Push container
|
||||
run: docker-compose build && docker-compose push
|
||||
working-directory: ./deployment/installer/
|
||||
env:
|
||||
REGISTRY_PREFIX: docker.pkg.github.com/sheldan/abstracto/
|
||||
VERSION: ${{ env.version }}
|
||||
REGISTRY_PREFIX: ${{ steps.dotenv.outputs.registry_prefix }}
|
||||
VERSION: ${{ steps.dotenv.outputs.version }}
|
||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Sheldan
|
||||
Copyright (c) 2023 Sheldan
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
14
README.md
14
README.md
@@ -1,8 +1,6 @@
|
||||
# Abstracto
|
||||
|
||||

|
||||
[](https://sonarcloud.io/dashboard?id=abstracto-core)
|
||||
[](https://sonarcloud.io/dashboard?id=abstracto-core)
|
||||

|
||||
[](https://github.com/Sheldan/abstracto/blob/master/LICENSE)
|
||||
|
||||
|
||||
@@ -14,22 +12,20 @@ An example implementation of this bot can be seen [here](https://github.com/Shel
|
||||
|
||||
|
||||
## Technologies
|
||||
* [JDA](https://github.com/DV8FromTheWorld/JDA/) The Discord API Wrapper in the version 5.0.0-alpha.21
|
||||
* [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)
|
||||
* [JDA](https://github.com/DV8FromTheWorld/JDA/) The Discord API Wrapper in the version 5.0.0-beta.13
|
||||
* [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.
|
||||
* [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.
|
||||
* [Ehcache](https://github.com/ehcache/ehcache3) is used as a caching implementation.
|
||||
* [Lombok](https://github.com/rzwitserloot/lombok) is used as a framework in order to speed up creation of container classes and builders.
|
||||
* [Quartz](https://github.com/quartz-scheduler/quartz) is used as a scheduling framework in order to provide functionalities which either require a delayed or cronjob behaviour.
|
||||
* [Docker](https://github.com/docker) is used to package the application into a container and [Docker Compose](https://github.com/docker/compose) is used to connect the required containers together.
|
||||
* [Quartz](https://github.com/quartz-scheduler/quartz) is used as a scheduling framework in order to provide functionalities which either require a scheduled or cronjob behaviour.
|
||||
* [Docker](https://github.com/docker) is used to package the application into an image and [Docker Compose](https://github.com/docker/compose) is used to build the images
|
||||
* [Liquibase](https://github.com/liquibase/liquibase) is used to manage changes to the database
|
||||
|
||||
## Documentation
|
||||
A detailed documentation of the pure form of Abstracto including the terminology and commands in HTML form is available [here](https://sheldan.github.io/abstracto-docs/current). The PDF is available [here](https://sheldan.github.io/abstracto-docs/current/documentation.pdf)
|
||||
If you want to view the documentation to an earlier released version you need to append the desired version to the URL. The current version will be available aforementioned URL, but it is not right now, because Abstracto has not been released yet.
|
||||
|
||||
## Customization documentation
|
||||
TBD when Abstracto is released, as the current version is still being adapted, because of findings from the example customization in Crimson.
|
||||
|
||||
## Issues
|
||||
If you find any issue, feel free to create a GitHub issue.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>anti-raid</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.4.20</version>
|
||||
<version>1.5.14-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>anti-raid</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.4.20</version>
|
||||
<version>1.5.14-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.4.20</version>
|
||||
<version>1.5.14-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>assignable-roles</artifactId>
|
||||
<version>1.4.20</version>
|
||||
<version>1.5.14-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -41,13 +41,19 @@ public class ActivateAssignableRolePlace extends AbstractConditionableCommand {
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter placeName = Parameter.builder().name("name").type(String.class).templated(true).build();
|
||||
Parameter placeName = Parameter
|
||||
.builder()
|
||||
.name("name")
|
||||
.type(String.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
List<Parameter> parameters = Arrays.asList(placeName);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("activateAssignableRolePlace")
|
||||
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
|
||||
.templated(true)
|
||||
.messageCommandOnly(true)
|
||||
.async(true)
|
||||
.supportsEmbedException(true)
|
||||
.causesReaction(true)
|
||||
|
||||
@@ -36,16 +36,40 @@ public class AddAssignableRoleCondition extends AbstractConditionableCommand {
|
||||
|
||||
@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 conditionKey = Parameter.builder().name("conditionKey").type(AssignableRoleConditionType.class).templated(true).build();
|
||||
Parameter conditionValue = Parameter.builder().name("conditionParameter").type(String.class).templated(true).build();
|
||||
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 conditionKey = Parameter
|
||||
.builder()
|
||||
.name("conditionKey")
|
||||
.type(AssignableRoleConditionType.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
Parameter conditionValue = Parameter
|
||||
.builder()
|
||||
.name("conditionParameter")
|
||||
.type(String.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
List<Parameter> parameters = Arrays.asList(placeName, role, conditionKey, conditionValue);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("addAssignableRoleCondition")
|
||||
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
|
||||
.templated(true)
|
||||
.messageCommandOnly(true)
|
||||
.supportsEmbedException(true)
|
||||
.causesReaction(true)
|
||||
.parameters(parameters)
|
||||
|
||||
@@ -62,17 +62,42 @@ public class AddRoleToAssignableRolePost extends AbstractConditionableCommand {
|
||||
|
||||
@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();
|
||||
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();
|
||||
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)
|
||||
|
||||
@@ -47,9 +47,24 @@ public class ChangeAssignableRolePlaceConfig extends AbstractConditionableComman
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter assignableRolePlaceName = Parameter.builder().name("name").type(String.class).templated(true).build();
|
||||
Parameter parameterKey = Parameter.builder().name("key").type(AssignableRolePlaceParameterKey.class).templated(true).build();
|
||||
Parameter parameterValue = Parameter.builder().name("value").type(String.class).templated(true).build();
|
||||
Parameter assignableRolePlaceName = Parameter
|
||||
.builder()
|
||||
.name("name")
|
||||
.type(String.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
Parameter parameterKey = Parameter
|
||||
.builder()
|
||||
.name("key")
|
||||
.type(AssignableRolePlaceParameterKey.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
Parameter parameterValue = Parameter
|
||||
.builder()
|
||||
.name("value")
|
||||
.type(String.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
List<Parameter> parameters = Arrays.asList(assignableRolePlaceName, parameterKey, parameterValue);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
@@ -57,6 +72,7 @@ public class ChangeAssignableRolePlaceConfig extends AbstractConditionableComman
|
||||
.name("changeAssignableRolePlaceConfig")
|
||||
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
|
||||
.templated(true)
|
||||
.messageCommandOnly(true)
|
||||
.async(true)
|
||||
.supportsEmbedException(true)
|
||||
.causesReaction(true)
|
||||
|
||||
@@ -33,9 +33,6 @@ public class CreateAssignableRolePost extends AbstractConditionableCommand {
|
||||
@Autowired
|
||||
private ChannelManagementService channelManagementService;
|
||||
|
||||
@Autowired
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
@Override
|
||||
public CommandResult execute(CommandContext commandContext) {
|
||||
List<Object> parameters = commandContext.getParameters().getParameters();
|
||||
@@ -57,20 +54,47 @@ public class CreateAssignableRolePost extends AbstractConditionableCommand {
|
||||
@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 channel = Parameter.builder().name("channel").type(TextChannel.class).templated(true).build();
|
||||
Parameter type = Parameter.builder().name("type").type(AssignableRolePlaceType.class).templated(true).optional(true).build();
|
||||
Parameter rolePostName = Parameter
|
||||
.builder()
|
||||
.name("name")
|
||||
.validators(rolePlaceNameValidator)
|
||||
.type(String.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
Parameter channel = Parameter
|
||||
.builder()
|
||||
.name("channel")
|
||||
.type(TextChannel.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
Parameter type = Parameter
|
||||
.builder()
|
||||
.name("type")
|
||||
.type(AssignableRolePlaceType.class)
|
||||
.templated(true)
|
||||
.optional(true)
|
||||
.build();
|
||||
List<ParameterValidator> rolePlaceDescriptionValidator = Arrays.asList(MaxStringLengthValidator.max(AssignableRolePlace.ASSIGNABLE_PLACE_NAME_LIMIT));
|
||||
Parameter text = Parameter.builder().name("text").validators(rolePlaceDescriptionValidator).type(String.class).templated(true).build();
|
||||
Parameter text = Parameter
|
||||
.builder()
|
||||
.name("text")
|
||||
.validators(rolePlaceDescriptionValidator)
|
||||
.type(String.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
List<String> aliases = Arrays.asList("crRPl", "crAssRoPl");
|
||||
List<Parameter> parameters = Arrays.asList(rolePostName, channel, text, type);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("createAssignableRolePlace")
|
||||
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
|
||||
.templated(true)
|
||||
.supportsEmbedException(true)
|
||||
.causesReaction(true)
|
||||
.messageCommandOnly(true)
|
||||
.parameters(parameters)
|
||||
.aliases(aliases)
|
||||
.help(helpInfo)
|
||||
|
||||
@@ -41,7 +41,12 @@ public class DeactivateAssignableRolePlace extends AbstractConditionableCommand
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter rolePostName = Parameter.builder().name("name").type(String.class).templated(true).build();
|
||||
Parameter rolePostName = Parameter
|
||||
.builder()
|
||||
.name("name")
|
||||
.type(String.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
List<Parameter> parameters = Arrays.asList(rolePostName);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
return CommandConfiguration.builder()
|
||||
@@ -49,6 +54,7 @@ public class DeactivateAssignableRolePlace extends AbstractConditionableCommand
|
||||
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
|
||||
.templated(true)
|
||||
.async(true)
|
||||
.messageCommandOnly(true)
|
||||
.supportsEmbedException(true)
|
||||
.causesReaction(true)
|
||||
.parameters(parameters)
|
||||
|
||||
@@ -41,7 +41,12 @@ public class DeleteAssignableRolePlace extends AbstractConditionableCommand {
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter rolePostName = Parameter.builder().name("name").type(String.class).templated(true).build();
|
||||
Parameter rolePostName = Parameter
|
||||
.builder()
|
||||
.name("name")
|
||||
.type(String.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
List<Parameter> parameters = Arrays.asList(rolePostName);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
return CommandConfiguration.builder()
|
||||
@@ -50,6 +55,7 @@ public class DeleteAssignableRolePlace extends AbstractConditionableCommand {
|
||||
.templated(true)
|
||||
.causesReaction(true)
|
||||
.async(true)
|
||||
.messageCommandOnly(true)
|
||||
.requiresConfirmation(true)
|
||||
.supportsEmbedException(true)
|
||||
.parameters(parameters)
|
||||
|
||||
@@ -46,15 +46,29 @@ public class EditAssignableRolePlaceText extends AbstractConditionableCommand {
|
||||
@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();
|
||||
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();
|
||||
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)
|
||||
|
||||
@@ -67,6 +67,7 @@ public class MoveAssignableRolePlace extends AbstractConditionableCommand {
|
||||
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
|
||||
.templated(true)
|
||||
.causesReaction(true)
|
||||
.messageCommandOnly(true)
|
||||
.async(true)
|
||||
.supportsEmbedException(true)
|
||||
.parameters(parameters)
|
||||
|
||||
@@ -35,15 +35,31 @@ public class RemoveAssignableRoleCondition extends AbstractConditionableCommand
|
||||
|
||||
@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 conditionKey = Parameter.builder().name("conditionKey").type(AssignableRoleConditionType.class).templated(true).build();
|
||||
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 conditionKey = Parameter
|
||||
.builder()
|
||||
.name("conditionKey")
|
||||
.type(AssignableRoleConditionType.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
List<Parameter> parameters = Arrays.asList(placeName, role, conditionKey);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("removeAssignableRoleCondition")
|
||||
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
|
||||
.templated(true)
|
||||
.messageCommandOnly(true)
|
||||
.supportsEmbedException(true)
|
||||
.causesReaction(true)
|
||||
.parameters(parameters)
|
||||
|
||||
@@ -44,16 +44,30 @@ public class RemoveRoleFromAssignableRolePlace extends AbstractConditionableComm
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter rolePostName = Parameter.builder().name("name").type(String.class).templated(true).build();
|
||||
Parameter role = Parameter.builder().name("role").type(ARole.class).templated(true).build();
|
||||
Parameter rolePostName = Parameter
|
||||
.builder()
|
||||
.name("name")
|
||||
.type(String.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
Parameter role = Parameter
|
||||
.builder()
|
||||
.name("role")
|
||||
.type(ARole.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
List<Parameter> parameters = Arrays.asList(rolePostName, role);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("removeRoleFromAssignableRolePlace")
|
||||
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
|
||||
.templated(true)
|
||||
.causesReaction(true)
|
||||
.async(true)
|
||||
.messageCommandOnly(true)
|
||||
.supportsEmbedException(true)
|
||||
.parameters(parameters)
|
||||
.help(helpInfo)
|
||||
|
||||
@@ -48,14 +48,23 @@ public class SetupAssignableRolePlace extends AbstractConditionableCommand {
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter rolePostName = Parameter.builder().name("name").type(String.class).templated(true).build();
|
||||
Parameter rolePostName = Parameter
|
||||
.builder()
|
||||
.name("name")
|
||||
.type(String.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
List<Parameter> parameters = Arrays.asList(rolePostName);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("setupAssignableRolePlace")
|
||||
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
|
||||
.templated(true)
|
||||
.async(true)
|
||||
.messageCommandOnly(true)
|
||||
.supportsEmbedException(true)
|
||||
.causesReaction(true)
|
||||
.parameters(parameters)
|
||||
|
||||
@@ -48,15 +48,24 @@ public class ShowAssignableRolePlaceConfig extends AbstractConditionableCommand
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter rolePostName = Parameter.builder().name("name").type(String.class).templated(true).build();
|
||||
Parameter rolePostName = Parameter
|
||||
.builder()
|
||||
.name("name")
|
||||
.type(String.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
List<Parameter> parameters = Arrays.asList(rolePostName);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("showAssignableRolePlaceConfig")
|
||||
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
|
||||
.templated(true)
|
||||
.async(true)
|
||||
.causesReaction(false)
|
||||
.messageCommandOnly(true)
|
||||
.supportsEmbedException(true)
|
||||
.parameters(parameters)
|
||||
.help(helpInfo)
|
||||
|
||||
@@ -45,11 +45,15 @@ public class ShowAssignableRolePlaces extends AbstractConditionableCommand {
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("showAssignableRolePlaces")
|
||||
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
|
||||
.templated(true)
|
||||
.messageCommandOnly(true)
|
||||
.async(true)
|
||||
.supportsEmbedException(true)
|
||||
.help(helpInfo)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>assignable-roles</artifactId>
|
||||
<version>1.4.20</version>
|
||||
<version>1.5.14-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>assignable-roles-int</artifactId>
|
||||
|
||||
@@ -6,7 +6,7 @@ import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.database.ComponentPayload;
|
||||
import lombok.*;
|
||||
|
||||
import javax.persistence.*;
|
||||
import jakarta.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -3,7 +3,7 @@ package dev.sheldan.abstracto.assignableroles.model.database;
|
||||
import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRoleConditionType;
|
||||
import lombok.*;
|
||||
|
||||
import javax.persistence.*;
|
||||
import jakarta.persistence.*;
|
||||
|
||||
@Entity
|
||||
@Table(name = "assignable_role_condition")
|
||||
|
||||
@@ -4,7 +4,7 @@ import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import lombok.*;
|
||||
|
||||
import javax.persistence.*;
|
||||
import jakarta.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -3,7 +3,7 @@ package dev.sheldan.abstracto.assignableroles.model.database;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import lombok.*;
|
||||
|
||||
import javax.persistence.*;
|
||||
import jakarta.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.4.20</version>
|
||||
<version>1.5.14-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>custom-command</artifactId>
|
||||
<version>1.4.20</version>
|
||||
<version>1.5.14-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
package dev.sheldan.abstracto.customcommand.command;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.UtilityModuleDefinition;
|
||||
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.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.abstracto.customcommand.config.CustomCommandFeatureDefinition;
|
||||
import dev.sheldan.abstracto.customcommand.config.CustomCommandSlashCommandNames;
|
||||
import dev.sheldan.abstracto.customcommand.service.management.CustomCommandService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class CreateCustomCommand extends AbstractConditionableCommand {
|
||||
|
||||
private static final String CREATE_CUSTOM_COMMAND_COMMAND = "createCustomCommand";
|
||||
private static final String CUSTOM_COMMAND_NAME_PARAMETER = "commandName";
|
||||
private static final String CUSTOM_COMMAND_CONTENT_PARAMETER = "response";
|
||||
private static final String CREATE_CUSTOM_COMMAND_RESPONSE_TEMPLATE_KEY = "createCustomCommand_response";
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Autowired
|
||||
private CustomCommandService customCommandService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
String name = slashCommandParameterService.getCommandOption(CUSTOM_COMMAND_NAME_PARAMETER, event, String.class);
|
||||
String content = slashCommandParameterService.getCommandOption(CUSTOM_COMMAND_CONTENT_PARAMETER, event, String.class);
|
||||
|
||||
customCommandService.createCustomCommand(name, content, event.getMember());
|
||||
return interactionService.replyEmbed(CREATE_CUSTOM_COMMAND_RESPONSE_TEMPLATE_KEY, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return CustomCommandFeatureDefinition.CUSTOM_COMMAND;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter commandNameParameter = Parameter
|
||||
.builder()
|
||||
.name(CUSTOM_COMMAND_NAME_PARAMETER)
|
||||
.templated(true)
|
||||
.type(String.class)
|
||||
.build();
|
||||
|
||||
Parameter commandContentParameter = Parameter
|
||||
.builder()
|
||||
.name(CUSTOM_COMMAND_CONTENT_PARAMETER)
|
||||
.templated(true)
|
||||
.type(String.class)
|
||||
.build();
|
||||
|
||||
List<Parameter> parameters = Arrays.asList(commandNameParameter, commandContentParameter);
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(CustomCommandSlashCommandNames.CUSTOM_COMMAND)
|
||||
.commandName("create")
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name(CREATE_CUSTOM_COMMAND_COMMAND)
|
||||
.module(UtilityModuleDefinition.UTILITY)
|
||||
.templated(true)
|
||||
.async(true)
|
||||
.slashCommandOnly(true)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.causesReaction(true)
|
||||
.supportsEmbedException(true)
|
||||
.parameters(parameters)
|
||||
.help(helpInfo)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package dev.sheldan.abstracto.customcommand.command;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.UtilityModuleDefinition;
|
||||
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.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.abstracto.customcommand.config.CustomCommandFeatureDefinition;
|
||||
import dev.sheldan.abstracto.customcommand.config.CustomCommandSlashCommandNames;
|
||||
import dev.sheldan.abstracto.customcommand.service.management.CustomCommandService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class DeleteCustomCommand extends AbstractConditionableCommand {
|
||||
|
||||
private static final String DELETE_CUSTOM_COMMAND_COMMAND = "deleteCustomCommand";
|
||||
private static final String DELETE_CUSTOM_COMMAND_RESPONSE_TEMPLATE_KEY = "deleteCustomCommand_response";
|
||||
private static final String CUSTOM_COMMAND_NAME_PARAMETER = "commandName";
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Autowired
|
||||
private CustomCommandService customCommandService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
String name = slashCommandParameterService.getCommandOption(CUSTOM_COMMAND_NAME_PARAMETER, event, String.class);
|
||||
|
||||
customCommandService.deleteCustomCommand(name, event.getGuild());
|
||||
return interactionService.replyEmbed(DELETE_CUSTOM_COMMAND_RESPONSE_TEMPLATE_KEY, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter commandNameParameter = Parameter
|
||||
.builder()
|
||||
.name(CUSTOM_COMMAND_NAME_PARAMETER)
|
||||
.templated(true)
|
||||
.type(String.class)
|
||||
.build();
|
||||
|
||||
List<Parameter> parameters = Arrays.asList(commandNameParameter);
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(CustomCommandSlashCommandNames.CUSTOM_COMMAND)
|
||||
.commandName("delete")
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name(DELETE_CUSTOM_COMMAND_COMMAND)
|
||||
.module(UtilityModuleDefinition.UTILITY)
|
||||
.templated(true)
|
||||
.async(true)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.causesReaction(true)
|
||||
.slashCommandOnly(true)
|
||||
.supportsEmbedException(true)
|
||||
.parameters(parameters)
|
||||
.help(helpInfo)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return CustomCommandFeatureDefinition.CUSTOM_COMMAND;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
package dev.sheldan.abstracto.customcommand.command;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.UtilityModuleDefinition;
|
||||
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.parameter.SlashCommandAutoCompleteService;
|
||||
import dev.sheldan.abstracto.core.interaction.slash.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.abstracto.customcommand.config.CustomCommandFeatureDefinition;
|
||||
import dev.sheldan.abstracto.customcommand.config.CustomCommandSlashCommandNames;
|
||||
import dev.sheldan.abstracto.customcommand.model.command.CustomCommandResponseModel;
|
||||
import dev.sheldan.abstracto.customcommand.model.database.CustomCommand;
|
||||
import dev.sheldan.abstracto.customcommand.service.management.CustomCommandService;
|
||||
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.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
public class GetCustomCommand extends AbstractConditionableCommand {
|
||||
|
||||
private static final String GET_CUSTOM_COMMAND_COMMAND = "getCustomCommand";
|
||||
private static final String CUSTOM_COMMAND_NAME_PARAMETER = "commandName";
|
||||
private static final String GET_CUSTOM_COMMAND_RESPONSE_TEMPLATE_KEY = "getCustomCommand_response";
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Autowired
|
||||
private CustomCommandService customCommandService;
|
||||
|
||||
@Autowired
|
||||
private SlashCommandAutoCompleteService slashCommandAutoCompleteService;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
String name = slashCommandParameterService.getCommandOption(CUSTOM_COMMAND_NAME_PARAMETER, event, String.class);
|
||||
CustomCommand customCommand = customCommandService.getCustomCommand(name, event.getGuild());
|
||||
CustomCommandResponseModel model = CustomCommandResponseModel
|
||||
.builder()
|
||||
.additionalText(customCommand.getAdditionalMessage())
|
||||
.build();
|
||||
return interactionService.replyEmbed(GET_CUSTOM_COMMAND_RESPONSE_TEMPLATE_KEY, model, event)
|
||||
.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();
|
||||
return customCommandService.getCustomCommandsStartingWith(input, event.getGuild())
|
||||
.stream()
|
||||
.map(CustomCommand::getName)
|
||||
.limit(25)
|
||||
.toList();
|
||||
} else {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return CustomCommandFeatureDefinition.CUSTOM_COMMAND;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
Parameter commandNameParameter = Parameter
|
||||
.builder()
|
||||
.name(CUSTOM_COMMAND_NAME_PARAMETER)
|
||||
.templated(true)
|
||||
.supportsAutoComplete(true)
|
||||
.type(String.class)
|
||||
.build();
|
||||
|
||||
List<Parameter> parameters = Arrays.asList(commandNameParameter);
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(CustomCommandSlashCommandNames.CUSTOM_COMMAND_PUBLIC)
|
||||
.commandName("get")
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name(GET_CUSTOM_COMMAND_COMMAND)
|
||||
.module(UtilityModuleDefinition.UTILITY)
|
||||
.templated(true)
|
||||
.async(true)
|
||||
.slashCommandOnly(true)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.causesReaction(true)
|
||||
.supportsEmbedException(true)
|
||||
.parameters(parameters)
|
||||
.help(helpInfo)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package dev.sheldan.abstracto.customcommand.command;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.UtilityModuleDefinition;
|
||||
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.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.service.PaginatorService;
|
||||
import dev.sheldan.abstracto.customcommand.config.CustomCommandFeatureDefinition;
|
||||
import dev.sheldan.abstracto.customcommand.config.CustomCommandSlashCommandNames;
|
||||
import dev.sheldan.abstracto.customcommand.model.command.ListCustomCommandsResponseModel;
|
||||
import dev.sheldan.abstracto.customcommand.model.database.CustomCommand;
|
||||
import dev.sheldan.abstracto.customcommand.service.management.CustomCommandService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class ListCustomCommands extends AbstractConditionableCommand {
|
||||
|
||||
private static final String CREATE_CUSTOM_COMMAND_COMMAND = "listCustomCommands";
|
||||
private static final String LIST_CUSTOM_COMMANDS_TEMPLATE_KEY = "listCustomCommands_response";
|
||||
private static final String NO_CUSTOM_COMMANDS_TEMPLATE_KEY = "listCustomCommands_no_commands_response";
|
||||
|
||||
@Autowired
|
||||
private CustomCommandService customCommandService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Autowired
|
||||
private PaginatorService paginatorService;
|
||||
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
List<CustomCommand> customCommands = customCommandService.getCustomCommands(event.getGuild());
|
||||
if(customCommands.isEmpty()) {
|
||||
return interactionService.replyEmbed(NO_CUSTOM_COMMANDS_TEMPLATE_KEY, event)
|
||||
.thenApply(interactionHook -> CommandResult.fromSuccess());
|
||||
}
|
||||
ListCustomCommandsResponseModel model = ListCustomCommandsResponseModel.fromCommands(customCommands);
|
||||
return paginatorService.createPaginatorFromTemplate(LIST_CUSTOM_COMMANDS_TEMPLATE_KEY, model, event)
|
||||
.thenApply(unused -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return CustomCommandFeatureDefinition.CUSTOM_COMMAND;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(CustomCommandSlashCommandNames.CUSTOM_COMMAND_PUBLIC)
|
||||
.commandName("list")
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name(CREATE_CUSTOM_COMMAND_COMMAND)
|
||||
.module(UtilityModuleDefinition.UTILITY)
|
||||
.templated(true)
|
||||
.async(true)
|
||||
.slashCommandOnly(true)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.causesReaction(true)
|
||||
.supportsEmbedException(true)
|
||||
.help(helpInfo)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -5,9 +5,13 @@ import dev.sheldan.abstracto.customcommand.model.database.CustomCommand;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Repository
|
||||
public interface CustomCommandRepository extends JpaRepository<CustomCommand, Long> {
|
||||
Optional<CustomCommand> getByNameIgnoreCaseAndServer(String name, AServer server);
|
||||
void deleteByNameAndServer(String name, AServer server);
|
||||
List<CustomCommand> findByServer(AServer server);
|
||||
List<CustomCommand> findByNameStartsWithIgnoreCaseAndServer(String prefix, AServer server);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
package dev.sheldan.abstracto.customcommand.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.customcommand.exception.CustomCommandExistsException;
|
||||
import dev.sheldan.abstracto.customcommand.exception.CustomCommandNotFoundException;
|
||||
import dev.sheldan.abstracto.customcommand.model.database.CustomCommand;
|
||||
import dev.sheldan.abstracto.customcommand.service.management.CustomCommandManagementService;
|
||||
import dev.sheldan.abstracto.customcommand.service.management.CustomCommandService;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class CustomCommandServiceBean implements CustomCommandService {
|
||||
|
||||
@Autowired
|
||||
private UserInServerManagementService userInServerManagementService;
|
||||
|
||||
@Autowired
|
||||
private CustomCommandManagementService customCommandManagementService;
|
||||
|
||||
@Autowired
|
||||
private ServerManagementService serverManagementService;
|
||||
|
||||
@Override
|
||||
public CustomCommand createCustomCommand(String name, String content, Member creator) {
|
||||
if(customCommandManagementService.getCustomCommandByName(name, creator.getGuild().getIdLong()).isPresent()) {
|
||||
throw new CustomCommandExistsException();
|
||||
}
|
||||
AUserInAServer creatorUser = userInServerManagementService.loadOrCreateUser(creator);
|
||||
return customCommandManagementService.createCustomCommand(name, content, creatorUser);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteCustomCommand(String name, Guild guild) {
|
||||
if(customCommandManagementService.getCustomCommandByName(name, guild.getIdLong()).isEmpty()) {
|
||||
throw new CustomCommandNotFoundException();
|
||||
}
|
||||
AServer server = serverManagementService.loadServer(guild);
|
||||
customCommandManagementService.deleteCustomCommand(name, server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CustomCommand> getCustomCommands(Guild guild) {
|
||||
AServer server = serverManagementService.loadServer(guild);
|
||||
return customCommandManagementService.getCustomCommands(server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomCommand getCustomCommand(String name, Guild guild) {
|
||||
return customCommandManagementService.getCustomCommandByName(name, guild.getIdLong())
|
||||
.orElseThrow(CustomCommandNotFoundException::new);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CustomCommand> getCustomCommandsStartingWith(String prefix, Guild guild) {
|
||||
AServer server = serverManagementService.loadServer(guild);
|
||||
return customCommandManagementService.getCustomCommandsStartingWith(prefix, server);
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,14 @@
|
||||
package dev.sheldan.abstracto.customcommand.service.management;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
|
||||
import dev.sheldan.abstracto.customcommand.model.database.CustomCommand;
|
||||
import dev.sheldan.abstracto.customcommand.repository.CustomCommandRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Component
|
||||
@@ -23,4 +25,32 @@ public class CustomCommandManagementServiceBean implements CustomCommandManageme
|
||||
AServer server = serverManagementService.loadServer(serverId);
|
||||
return repository.getByNameIgnoreCaseAndServer(name, server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomCommand createCustomCommand(String name, String content, AUserInAServer creator) {
|
||||
CustomCommand customCommand = CustomCommand
|
||||
.builder()
|
||||
.name(name)
|
||||
.additionalMessage(content)
|
||||
.server(creator.getServerReference())
|
||||
.creator(creator)
|
||||
.build();
|
||||
return repository.save(customCommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteCustomCommand(String name, AServer server) {
|
||||
repository.deleteByNameAndServer(name, server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CustomCommand> getCustomCommands(AServer server) {
|
||||
return repository.findByServer(server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CustomCommand> getCustomCommandsStartingWith(String prefix, AServer server) {
|
||||
return repository.findByNameStartsWithIgnoreCaseAndServer(prefix, server);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||
<include file="seedData/data.xml" relativeToChangelogFile="true"/>
|
||||
<include file="tables/tables.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||
<property name="utilityModule" value="(SELECT id FROM module WHERE name = 'utility')"/>
|
||||
<property name="customCommandFeature" value="(SELECT id FROM feature WHERE key = 'customCommand')"/>
|
||||
|
||||
<changeSet author="Sheldan" id="customCommand-commands">
|
||||
<insert tableName="command">
|
||||
<column name="name" value="createCustomCommand"/>
|
||||
<column name="module_id" valueComputed="${utilityModule}"/>
|
||||
<column name="feature_id" valueComputed="${customCommandFeature}"/>
|
||||
</insert>
|
||||
<insert tableName="command">
|
||||
<column name="name" value="deleteCustomCommand"/>
|
||||
<column name="module_id" valueComputed="${utilityModule}"/>
|
||||
<column name="feature_id" valueComputed="${customCommandFeature}"/>
|
||||
</insert>
|
||||
<insert tableName="command">
|
||||
<column name="name" value="getCustomCommand"/>
|
||||
<column name="module_id" valueComputed="${utilityModule}"/>
|
||||
<column name="feature_id" valueComputed="${customCommandFeature}"/>
|
||||
</insert>
|
||||
<insert tableName="command">
|
||||
<column name="name" value="listCustomCommands"/>
|
||||
<column name="module_id" valueComputed="${utilityModule}"/>
|
||||
<column name="feature_id" valueComputed="${customCommandFeature}"/>
|
||||
</insert>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||
<include file="command.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||
<changeSet author="Sheldan" id="custom_command-add_auto_increment">
|
||||
<sql>
|
||||
create sequence custom_command_id_seq;
|
||||
alter table custom_command alter id set default nextval('custom_command_id_seq');
|
||||
</sql>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||
<include file="custom_command.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -7,4 +7,5 @@
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||
<include file="1.4.0/collection.xml" relativeToChangelogFile="true"/>
|
||||
<include file="1.5.8/collection.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>custom-command</artifactId>
|
||||
<version>1.4.20</version>
|
||||
<version>1.5.14-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package dev.sheldan.abstracto.customcommand.config;
|
||||
|
||||
public class CustomCommandSlashCommandNames {
|
||||
public static final String CUSTOM_COMMAND = "cc";
|
||||
public static final String CUSTOM_COMMAND_PUBLIC = "customCommands";
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package dev.sheldan.abstracto.customcommand.exception;
|
||||
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException;
|
||||
|
||||
public class CustomCommandExistsException extends AbstractoTemplatableException {
|
||||
@Override
|
||||
public String getTemplateName() {
|
||||
return "custom_command_exists_exception";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getTemplateModel() {
|
||||
return new Object();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package dev.sheldan.abstracto.customcommand.exception;
|
||||
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException;
|
||||
|
||||
public class CustomCommandNotFoundException extends AbstractoTemplatableException {
|
||||
@Override
|
||||
public String getTemplateName() {
|
||||
return "custom_command_not_found_exception";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getTemplateModel() {
|
||||
return new Object();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package dev.sheldan.abstracto.customcommand.model.command;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
|
||||
import dev.sheldan.abstracto.customcommand.model.database.CustomCommand;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@Builder
|
||||
public class ListCustomCommandModel {
|
||||
private String name;
|
||||
private String content;
|
||||
private MemberDisplay creator;
|
||||
|
||||
public static ListCustomCommandModel fromCustomCommand(CustomCommand customCommand) {
|
||||
return ListCustomCommandModel
|
||||
.builder()
|
||||
.name(customCommand.getName())
|
||||
.content(customCommand.getAdditionalMessage())
|
||||
.creator(MemberDisplay.fromAUserInAServer(customCommand.getCreator()))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package dev.sheldan.abstracto.customcommand.model.command;
|
||||
|
||||
import dev.sheldan.abstracto.customcommand.model.database.CustomCommand;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Builder
|
||||
@Getter
|
||||
public class ListCustomCommandsResponseModel {
|
||||
private List<ListCustomCommandModel> customCommands;
|
||||
|
||||
public static ListCustomCommandsResponseModel fromCommands(List<CustomCommand> customCommands) {
|
||||
return ListCustomCommandsResponseModel
|
||||
.builder()
|
||||
.customCommands(customCommands
|
||||
.stream()
|
||||
.map(ListCustomCommandModel::fromCustomCommand)
|
||||
.collect(Collectors.toList()))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ package dev.sheldan.abstracto.customcommand.model.database;
|
||||
import dev.sheldan.abstracto.core.models.database.*;
|
||||
import lombok.*;
|
||||
|
||||
import javax.persistence.*;
|
||||
import jakarta.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
package dev.sheldan.abstracto.customcommand.service.management;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.customcommand.model.database.CustomCommand;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public interface CustomCommandManagementService {
|
||||
Optional<CustomCommand> getCustomCommandByName(String name, Long serverId);
|
||||
CustomCommand createCustomCommand(String name, String content, AUserInAServer creator);
|
||||
void deleteCustomCommand(String name, AServer server);
|
||||
List<CustomCommand> getCustomCommands(AServer server);
|
||||
List<CustomCommand> getCustomCommandsStartingWith(String prefix, AServer server);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package dev.sheldan.abstracto.customcommand.service.management;
|
||||
|
||||
import dev.sheldan.abstracto.customcommand.model.database.CustomCommand;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface CustomCommandService {
|
||||
CustomCommand createCustomCommand(String name, String content, Member creator);
|
||||
void deleteCustomCommand(String name, Guild guild);
|
||||
List<CustomCommand> getCustomCommands(Guild guild);
|
||||
CustomCommand getCustomCommand(String name, Guild guild);
|
||||
List<CustomCommand> getCustomCommandsStartingWith(String prefix, Guild guild);
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.4.20</version>
|
||||
<version>1.5.14-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>dynamic-activity</artifactId>
|
||||
<version>1.4.20</version>
|
||||
<version>1.5.14-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>dynamic-activity</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.4.20</version>
|
||||
<version>1.5.14-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ package dev.sheldan.abstracto.activity.models;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
import javax.persistence.*;
|
||||
import jakarta.persistence.*;
|
||||
import java.time.Instant;
|
||||
|
||||
@Builder
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.4.20</version>
|
||||
<version>1.5.14-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>entertainment</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.4.20</version>
|
||||
<version>1.5.14-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -52,14 +52,28 @@ public class React extends AbstractConditionableCommand {
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
List<Parameter> parameters = new ArrayList<>();
|
||||
parameters.add(Parameter.builder().name("message").type(Message.class).templated(true).build());
|
||||
parameters.add(Parameter.builder().name("text").type(String.class).remainder(true).templated(true).build());
|
||||
Parameter messageParameter = Parameter
|
||||
.builder()
|
||||
.name("message")
|
||||
.type(Message.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
parameters.add(messageParameter);
|
||||
Parameter textParameter = Parameter
|
||||
.builder()
|
||||
.name("text")
|
||||
.type(String.class)
|
||||
.remainder(true)
|
||||
.templated(true)
|
||||
.build();
|
||||
parameters.add(textParameter);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("react")
|
||||
.module(EntertainmentModuleDefinition.ENTERTAINMENT)
|
||||
.templated(true)
|
||||
.causesReaction(true)
|
||||
.messageCommandOnly(true)
|
||||
.async(true)
|
||||
.supportsEmbedException(true)
|
||||
.parameters(parameters)
|
||||
|
||||
@@ -9,8 +9,6 @@ import dev.sheldan.abstracto.entertainment.dto.CreditGambleResult;
|
||||
import dev.sheldan.abstracto.entertainment.dto.PayDayResult;
|
||||
import dev.sheldan.abstracto.entertainment.dto.SlotsResult;
|
||||
import dev.sheldan.abstracto.entertainment.exception.NotEnoughCreditsException;
|
||||
import dev.sheldan.abstracto.entertainment.exception.PayDayCooldownException;
|
||||
import dev.sheldan.abstracto.entertainment.exception.SlotsCooldownException;
|
||||
import dev.sheldan.abstracto.entertainment.model.command.CreditsLeaderboardEntry;
|
||||
import dev.sheldan.abstracto.entertainment.model.database.EconomyLeaderboardResult;
|
||||
import dev.sheldan.abstracto.entertainment.model.database.EconomyUser;
|
||||
@@ -19,14 +17,8 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.*;
|
||||
|
||||
import static dev.sheldan.abstracto.entertainment.config.EconomyFeatureConfig.PAYDAY_COOLDOWN_CONFIG_KEY;
|
||||
import static dev.sheldan.abstracto.entertainment.config.EconomyFeatureConfig.SLOTS_COOLDOWN_CONFIG_KEY;
|
||||
|
||||
@Component
|
||||
public class EconomyServiceBean implements EconomyService {
|
||||
|
||||
@@ -70,42 +62,6 @@ public class EconomyServiceBean implements EconomyService {
|
||||
private static final Integer TRIPLE_FACTOR = 10;
|
||||
private static final Integer DOUBLE_FACTOR = 2;
|
||||
|
||||
@Override
|
||||
public boolean canTriggerPayDay(AUserInAServer aUserInAServer) {
|
||||
Optional<EconomyUser> userOptional = economyUserManagementService.getUser(aUserInAServer);
|
||||
return userOptional.map(this::canTriggerPayDay).orElse(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canTriggerSlots(AUserInAServer aUserInAServer) {
|
||||
Optional<EconomyUser> userOptional = economyUserManagementService.getUser(aUserInAServer);
|
||||
return userOptional.map(this::canTriggerSlots).orElse(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canTriggerPayDay(EconomyUser economyUser) {
|
||||
return slotsTriggerIn(economyUser).isNegative();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canTriggerSlots(EconomyUser economyUser) {
|
||||
return payDayTriggerIn(economyUser).isNegative();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration payDayTriggerIn(EconomyUser economyUser) {
|
||||
Long cooldownSeconds = configService.getLongValueOrConfigDefault(PAYDAY_COOLDOWN_CONFIG_KEY, economyUser.getServer().getId());
|
||||
Instant minTimeStamp = Instant.now().minus(cooldownSeconds, ChronoUnit.SECONDS);
|
||||
return Duration.between(economyUser.getLastPayDay(), minTimeStamp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration slotsTriggerIn(EconomyUser economyUser) {
|
||||
Long cooldownSeconds = configService.getLongValueOrConfigDefault(SLOTS_COOLDOWN_CONFIG_KEY, economyUser.getServer().getId());
|
||||
Instant minTimeStamp = Instant.now().minus(cooldownSeconds, ChronoUnit.SECONDS);
|
||||
return Duration.between(economyUser.getLastSlots(), minTimeStamp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EconomyUser addCredits(AUserInAServer aUserInAServer, Long credits) {
|
||||
Optional<EconomyUser> existingUserOptional = economyUserManagementService.getUser(aUserInAServer);
|
||||
@@ -137,11 +93,6 @@ public class EconomyServiceBean implements EconomyService {
|
||||
Long creditsToAdd = configService.getLongValueOrConfigDefault(EconomyFeatureConfig.PAYDAY_CREDITS_CONFIG_KEY,
|
||||
aUserInAServer.getServerReference().getId());
|
||||
EconomyUser economyUser = addCredits(aUserInAServer, creditsToAdd);
|
||||
Duration durationForPayday = payDayTriggerIn(economyUser);
|
||||
if (durationForPayday.isNegative()) {
|
||||
throw new PayDayCooldownException(durationForPayday.abs());
|
||||
}
|
||||
economyUser.setLastPayDay(Instant.now());
|
||||
return PayDayResult
|
||||
.builder()
|
||||
.currentCredits(economyUser.getCredits())
|
||||
@@ -160,17 +111,12 @@ public class EconomyServiceBean implements EconomyService {
|
||||
if(user.getCredits() < bid) {
|
||||
throw new NotEnoughCreditsException();
|
||||
}
|
||||
Duration durationForSlots = slotsTriggerIn(user);
|
||||
if (durationForSlots.isNegative()) {
|
||||
throw new SlotsCooldownException(durationForSlots.abs());
|
||||
}
|
||||
SlotGame slotGame = playSlots();
|
||||
Integer factor = slotGame.getResultFactor();
|
||||
Long creditChange = bid * factor;
|
||||
addCredits(user, -bid);
|
||||
addCredits(user, creditChange);
|
||||
|
||||
user.setLastSlots(Instant.now());
|
||||
return SlotsResult
|
||||
.builder()
|
||||
.bid(bid)
|
||||
|
||||
@@ -27,8 +27,6 @@ public class EconomyUserManagementServiceBean implements EconomyUserManagementSe
|
||||
.builder()
|
||||
.id(aUserInAServer.getUserInServerId())
|
||||
.server(aUserInAServer.getServerReference())
|
||||
.lastPayDay(Instant.now().minus(1, ChronoUnit.DAYS))
|
||||
.lastSlots(Instant.now().minus(1, ChronoUnit.DAYS))
|
||||
.credits(0L)
|
||||
.user(aUserInAServer)
|
||||
.build();
|
||||
|
||||
@@ -10,13 +10,6 @@ abstracto.featureFlags.entertainment.enabled=false
|
||||
abstracto.systemConfigs.paydayCredits.name=paydayCredits
|
||||
abstracto.systemConfigs.paydayCredits.longValue=120
|
||||
|
||||
# maybe replace this by command cooldowns which are globally on the server, instead of only channel group based
|
||||
abstracto.systemConfigs.paydayCooldown.name=paydayCooldown
|
||||
abstracto.systemConfigs.paydayCooldown.longValue=300
|
||||
|
||||
abstracto.systemConfigs.slotsCooldown.name=slotsCooldown
|
||||
abstracto.systemConfigs.slotsCooldown.longValue=30
|
||||
|
||||
abstracto.featureFlags.economy.featureName=economy
|
||||
abstracto.featureFlags.economy.enabled=false
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||
<include file="system_config.xml" relativeToChangelogFile="true"/>
|
||||
<include file="economy_user.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||
<changeSet author="Sheldan" id="economy_user-delete-cooldown-columns">
|
||||
<dropColumn tableName="economy_user">
|
||||
<column name="last_pay_day" />
|
||||
<column name="last_slots" />
|
||||
</dropColumn>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||
|
||||
<changeSet author="Sheldan" id="economy_cooldown-system-config-deletions">
|
||||
<delete tableName="system_config">
|
||||
<where>name='paydayCooldown'</where>
|
||||
</delete>
|
||||
<delete tableName="system_config">
|
||||
<where>name='slotsCooldown'</where>
|
||||
</delete>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
|
||||
xmlns:pro="http://www.liquibase.org/xml/ns/pro"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/dbchangelog-ext dbchangelog.xsd
|
||||
http://www.liquibase.org/xml/ns/pro dbchangelog.xsd" >
|
||||
<include file="cleanup/deletions.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -12,4 +12,5 @@
|
||||
<include file="1.4.0/collection.xml" relativeToChangelogFile="true"/>
|
||||
<include file="1.4.3/collection.xml" relativeToChangelogFile="true"/>
|
||||
<include file="1.4.11/collection.xml" relativeToChangelogFile="true"/>
|
||||
<include file="1.5.8/collection.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>entertainment</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.4.20</version>
|
||||
<version>1.5.14-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -11,8 +11,6 @@ import java.util.List;
|
||||
public class EconomyFeatureConfig implements FeatureConfig {
|
||||
|
||||
public static final String PAYDAY_CREDITS_CONFIG_KEY = "paydayCredits";
|
||||
public static final String PAYDAY_COOLDOWN_CONFIG_KEY = "paydayCooldown";
|
||||
public static final String SLOTS_COOLDOWN_CONFIG_KEY = "slotsCooldown";
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
@@ -21,6 +19,6 @@ public class EconomyFeatureConfig implements FeatureConfig {
|
||||
|
||||
@Override
|
||||
public List<String> getRequiredSystemConfigKeys() {
|
||||
return Arrays.asList(PAYDAY_CREDITS_CONFIG_KEY, PAYDAY_COOLDOWN_CONFIG_KEY, SLOTS_COOLDOWN_CONFIG_KEY);
|
||||
return Arrays.asList(PAYDAY_CREDITS_CONFIG_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
package dev.sheldan.abstracto.entertainment.exception;
|
||||
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException;
|
||||
import dev.sheldan.abstracto.entertainment.model.exception.PayDayCooldownExceptionModel;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
public class PayDayCooldownException extends AbstractoTemplatableException {
|
||||
|
||||
private final PayDayCooldownExceptionModel model;
|
||||
|
||||
public PayDayCooldownException(Duration duration) {
|
||||
this.model = PayDayCooldownExceptionModel
|
||||
.builder()
|
||||
.tryAgainDuration(duration)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTemplateName() {
|
||||
return "payday_cooldown_exception";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getTemplateModel() {
|
||||
return model;
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package dev.sheldan.abstracto.entertainment.exception;
|
||||
|
||||
import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException;
|
||||
import dev.sheldan.abstracto.entertainment.model.exception.SlotsCooldownExceptionModel;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
public class SlotsCooldownException extends AbstractoTemplatableException {
|
||||
|
||||
private final SlotsCooldownExceptionModel model;
|
||||
|
||||
public SlotsCooldownException(Duration duration) {
|
||||
this.model = SlotsCooldownExceptionModel
|
||||
.builder()
|
||||
.tryAgainDuration(duration)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTemplateName() {
|
||||
return "slots_cooldown_exception";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getTemplateModel() {
|
||||
return model;
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import lombok.*;
|
||||
|
||||
import javax.persistence.*;
|
||||
import jakarta.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
|
||||
@@ -33,12 +33,6 @@ public class EconomyUser implements Serializable {
|
||||
@Column(name = "credits", nullable = false)
|
||||
private Long credits;
|
||||
|
||||
@Column(name = "last_slots", nullable = false)
|
||||
private Instant lastSlots;
|
||||
|
||||
@Column(name = "last_pay_day", nullable = false)
|
||||
private Instant lastPayDay;
|
||||
|
||||
@Column(name = "created", nullable = false, insertable = false, updatable = false)
|
||||
private Instant created;
|
||||
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
package dev.sheldan.abstracto.entertainment.model.exception;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
@Builder
|
||||
@Getter
|
||||
public class PayDayCooldownExceptionModel {
|
||||
private Duration tryAgainDuration;
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package dev.sheldan.abstracto.entertainment.model.exception;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
@Builder
|
||||
@Getter
|
||||
public class SlotsCooldownExceptionModel {
|
||||
private Duration tryAgainDuration;
|
||||
}
|
||||
@@ -10,16 +10,9 @@ import dev.sheldan.abstracto.entertainment.model.database.EconomyUser;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
|
||||
public interface EconomyService {
|
||||
boolean canTriggerPayDay(AUserInAServer aUserInAServer);
|
||||
boolean canTriggerSlots(AUserInAServer aUserInAServer);
|
||||
boolean canTriggerPayDay(EconomyUser economyUser);
|
||||
boolean canTriggerSlots(EconomyUser economyUser);
|
||||
Duration payDayTriggerIn(EconomyUser economyUser);
|
||||
Duration slotsTriggerIn(EconomyUser economyUser);
|
||||
EconomyUser addCredits(AUserInAServer aUserInAServer, Long credits);
|
||||
void addCredits(EconomyUser economyUser, Long credits);
|
||||
void addPayDayCredits(AUserInAServer aUserInAServer);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<version>1.4.20</version>
|
||||
<version>1.5.14-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>experience-tracking</artifactId>
|
||||
<version>1.4.20</version>
|
||||
<version>1.5.14-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -69,6 +69,7 @@ public class SetExpRole extends AbstractConditionableCommand {
|
||||
.module(ExperienceModuleDefinition.EXPERIENCE)
|
||||
.templated(true)
|
||||
.async(true)
|
||||
.messageCommandOnly(true)
|
||||
.supportsEmbedException(true)
|
||||
.causesReaction(true)
|
||||
.requiresConfirmation(true)
|
||||
|
||||
@@ -46,7 +46,10 @@ public class SyncRoles extends AbstractConditionableCommand {
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
List<Parameter> parameters = new ArrayList<>();
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("syncExpRoles")
|
||||
.module(ExperienceModuleDefinition.EXPERIENCE)
|
||||
@@ -54,6 +57,7 @@ public class SyncRoles extends AbstractConditionableCommand {
|
||||
.async(true)
|
||||
.requiresConfirmation(true)
|
||||
.supportsEmbedException(true)
|
||||
.messageCommandOnly(true)
|
||||
.causesReaction(true)
|
||||
.parameters(parameters)
|
||||
.help(helpInfo)
|
||||
|
||||
@@ -59,13 +59,20 @@ public class UnSetExpRole extends AbstractConditionableCommand {
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
List<Parameter> parameters = new ArrayList<>();
|
||||
parameters.add(Parameter.builder().name("role").templated(true).type(ARole.class).build());
|
||||
Parameter roleParameter = Parameter
|
||||
.builder()
|
||||
.name("role")
|
||||
.templated(true)
|
||||
.type(ARole.class)
|
||||
.build();
|
||||
parameters.add(roleParameter);
|
||||
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
|
||||
return CommandConfiguration.builder()
|
||||
.name("unSetExpRole")
|
||||
.module(ExperienceModuleDefinition.EXPERIENCE)
|
||||
.templated(true)
|
||||
.async(true)
|
||||
.messageCommandOnly(true)
|
||||
.causesReaction(true)
|
||||
.requiresConfirmation(true)
|
||||
.supportsEmbedException(true)
|
||||
|
||||
@@ -275,13 +275,13 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
CompletableFuture<Void> returningFuture;
|
||||
if(!Objects.equals(oldRoleId, newRoleId) || forceRoles) {
|
||||
CompletableFuture<Void> addingFuture;
|
||||
if(oldRoleId != null || forceRoles) {
|
||||
if(oldRoleId != null) {
|
||||
addingFuture = roleService.removeRoleFromMemberAsync(member, oldRoleId);
|
||||
} else {
|
||||
addingFuture = CompletableFuture.completedFuture(null);
|
||||
}
|
||||
CompletableFuture<Void> removingFeature;
|
||||
if(newRoleId != null || forceRoles) {
|
||||
if(newRoleId != null) {
|
||||
removingFeature = roleService.addRoleToMemberAsync(member, newRoleId);
|
||||
} else {
|
||||
removingFeature = CompletableFuture.completedFuture(null);
|
||||
@@ -371,21 +371,30 @@ public class AUserExperienceServiceBean implements AUserExperienceService {
|
||||
userExperienceManagementService.saveUser(aUserExperience);
|
||||
}
|
||||
if(!Objects.equals(result.getOldRoleId(), result.getNewRoleId())) {
|
||||
if(result.getOldRoleId() != null) {
|
||||
roleService.removeRoleFromMemberAsync(member, result.getOldRoleId()).thenAccept(unused -> {
|
||||
log.debug("Removed role {} to member {} in server {}.", result.getOldRoleId(), member.getIdLong(), member.getGuild().getIdLong());
|
||||
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 {} 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.getOldRoleId(), 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);
|
||||
log.warn("Failed to remove role {} from and add role {} to member {} in server {}.", result.getOldRoleId(), 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 {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>experience-tracking</artifactId>
|
||||
<version>1.4.20</version>
|
||||
<version>1.5.14-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ package dev.sheldan.abstracto.experience.model.database;
|
||||
import dev.sheldan.abstracto.core.models.database.ARole;
|
||||
import lombok.*;
|
||||
|
||||
import javax.persistence.*;
|
||||
import jakarta.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ package dev.sheldan.abstracto.experience.model.database;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
import javax.persistence.*;
|
||||
import jakarta.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import dev.sheldan.abstracto.core.models.database.ARole;
|
||||
import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import lombok.*;
|
||||
|
||||
import javax.persistence.*;
|
||||
import jakarta.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -4,7 +4,7 @@ import dev.sheldan.abstracto.core.models.database.AServer;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import lombok.*;
|
||||
|
||||
import javax.persistence.*;
|
||||
import jakarta.persistence.*;
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>abstracto-modules</artifactId>
|
||||
<version>1.4.20</version>
|
||||
<version>1.5.14-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>giveaway</artifactId>
|
||||
<version>1.5.14-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>giveaway-impl</artifactId>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<configuration>
|
||||
<descriptors>
|
||||
<descriptor>src/main/assembly/liquibase.xml</descriptor>
|
||||
</descriptors>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-assembly</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>dev.sheldan.abstracto.modules</groupId>
|
||||
<artifactId>giveaway-int</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.sheldan.abstracto.core</groupId>
|
||||
<artifactId>metrics-int</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,18 @@
|
||||
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.1.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.1.0 http://maven.apache.org/xsd/assembly-2.1.0.xsd">
|
||||
<id>liquibase</id>
|
||||
<formats>
|
||||
<format>zip</format>
|
||||
</formats>
|
||||
<includeBaseDirectory>false</includeBaseDirectory>
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<outputDirectory>.</outputDirectory>
|
||||
<directory>${project.basedir}/src/main/resources/migrations</directory>
|
||||
<includes>
|
||||
<include>**/*</include>
|
||||
</includes>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
</assembly>
|
||||
@@ -0,0 +1,103 @@
|
||||
package dev.sheldan.abstracto.giveaway.command;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.UtilityModuleDefinition;
|
||||
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.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.abstracto.core.utils.CompletableFutureList;
|
||||
import dev.sheldan.abstracto.giveaway.config.GiveawayFeatureDefinition;
|
||||
import dev.sheldan.abstracto.giveaway.config.GiveawaySlashCommandNames;
|
||||
import dev.sheldan.abstracto.giveaway.service.GiveawayService;
|
||||
import jakarta.transaction.Transactional;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
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;
|
||||
|
||||
@Component
|
||||
public class CancelGiveaway extends AbstractConditionableCommand {
|
||||
|
||||
private static final String COMMAND_NAME = "cancelGiveaway";
|
||||
private static final String ID_PARAMETER = "id";
|
||||
private static final String CANCEL_GIVEAWAY_RESPONSE_TEMPLATE_KEY = "cancelGiveaway_response";
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Autowired
|
||||
private GiveawayService giveawayService;
|
||||
|
||||
@Autowired
|
||||
private CancelGiveaway self;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
return event.deferReply().submit().thenAccept(interactionHook -> {
|
||||
self.cancelGiveaway(event);
|
||||
}).thenCompose(unused -> {
|
||||
List<CompletableFuture<Message>> futures = interactionService.sendMessageToInteraction(CANCEL_GIVEAWAY_RESPONSE_TEMPLATE_KEY, new Object(), event.getHook());
|
||||
return new CompletableFutureList<>(futures).getMainFuture();
|
||||
})
|
||||
.thenApply(unused -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void cancelGiveaway(SlashCommandInteractionEvent event) {
|
||||
Long giveawayId = slashCommandParameterService.getCommandOption(ID_PARAMETER, event, Integer.class).longValue();
|
||||
giveawayService.cancelGiveaway(giveawayId, event.getGuild().getIdLong());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
|
||||
Parameter giveawayIdParameter = Parameter
|
||||
.builder()
|
||||
.templated(true)
|
||||
.name(ID_PARAMETER)
|
||||
.type(Integer.class)
|
||||
.build();
|
||||
|
||||
List<Parameter> parameters = Arrays.asList(giveawayIdParameter);
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(GiveawaySlashCommandNames.GIVEAWAY)
|
||||
.commandName("cancel")
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name(COMMAND_NAME)
|
||||
.module(UtilityModuleDefinition.UTILITY)
|
||||
.templated(true)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.async(true)
|
||||
.supportsEmbedException(true)
|
||||
.causesReaction(false)
|
||||
.parameters(parameters)
|
||||
.help(helpInfo)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return GiveawayFeatureDefinition.GIVEAWAY;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
package dev.sheldan.abstracto.giveaway.command;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.UtilityModuleDefinition;
|
||||
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.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.abstracto.core.utils.ParseUtils;
|
||||
import dev.sheldan.abstracto.giveaway.config.GiveawayFeatureDefinition;
|
||||
import dev.sheldan.abstracto.giveaway.config.GiveawaySlashCommandNames;
|
||||
import dev.sheldan.abstracto.giveaway.model.GiveawayCreationRequest;
|
||||
import dev.sheldan.abstracto.giveaway.service.GiveawayService;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel;
|
||||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
public class GreateGiveaway extends AbstractConditionableCommand {
|
||||
|
||||
private static final String COMMAND_NAME = "createGiveaway";
|
||||
private static final String TITLE_PARAMETER = "title";
|
||||
private static final String DESCRIPTION_PARAMETER = "description";
|
||||
private static final String BENEFACTOR_PARAMETER = "benefactor";
|
||||
private static final String CHANNEL_PARAMETER = "channel";
|
||||
private static final String DURATION_PARAMETER = "duration";
|
||||
private static final String WINNERS_PARAMETER = "winners";
|
||||
|
||||
private static final String CREATE_GIVEAWAY_RESPONSE_TEMPLATE_KEY = "createGiveaway_response";
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Autowired
|
||||
private GiveawayService giveawayService;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
return event.deferReply()
|
||||
.submit()
|
||||
.thenCompose(interactionHook -> {
|
||||
String title = slashCommandParameterService.getCommandOption(TITLE_PARAMETER, event, String.class);
|
||||
String description;
|
||||
if(slashCommandParameterService.hasCommandOption(DESCRIPTION_PARAMETER, event)) {
|
||||
description = slashCommandParameterService.getCommandOption(DESCRIPTION_PARAMETER, event, String.class);
|
||||
} else {
|
||||
description = null;
|
||||
}
|
||||
|
||||
String durationString = slashCommandParameterService.getCommandOption(DURATION_PARAMETER, event, Duration.class, String.class);
|
||||
Duration duration = ParseUtils.parseDuration(durationString);
|
||||
|
||||
GuildMessageChannel target = null;
|
||||
if(slashCommandParameterService.hasCommandOption(CHANNEL_PARAMETER, event)) {
|
||||
target = slashCommandParameterService.getCommandOption(CHANNEL_PARAMETER, event, GuildMessageChannel.class);
|
||||
}
|
||||
|
||||
Integer winners = 1;
|
||||
if(slashCommandParameterService.hasCommandOption(WINNERS_PARAMETER, event)) {
|
||||
winners = slashCommandParameterService.getCommandOption(WINNERS_PARAMETER, event, Integer.class);
|
||||
}
|
||||
|
||||
Member benefactor;
|
||||
if(slashCommandParameterService.hasCommandOption(BENEFACTOR_PARAMETER, event)) {
|
||||
benefactor = slashCommandParameterService.getCommandOption(BENEFACTOR_PARAMETER, event, Member.class);
|
||||
} else {
|
||||
benefactor = null;
|
||||
}
|
||||
|
||||
Member creator = event.getMember();
|
||||
GiveawayCreationRequest request = GiveawayCreationRequest
|
||||
.builder()
|
||||
.benefactor(benefactor)
|
||||
.creator(creator)
|
||||
.description(description)
|
||||
.duration(duration)
|
||||
.targetChannel(target)
|
||||
.winnerCount(winners)
|
||||
.title(title)
|
||||
.build();
|
||||
|
||||
return giveawayService.createGiveaway(request)
|
||||
.thenAccept(unused -> interactionService.sendEmbed(CREATE_GIVEAWAY_RESPONSE_TEMPLATE_KEY, interactionHook));
|
||||
}).thenApply(unused -> CommandResult.fromSuccess());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
|
||||
Parameter titleParameter = Parameter
|
||||
.builder()
|
||||
.templated(true)
|
||||
.name(TITLE_PARAMETER)
|
||||
.type(String.class)
|
||||
.build();
|
||||
|
||||
Parameter descriptionParameter = Parameter
|
||||
.builder()
|
||||
.templated(true)
|
||||
.name(DESCRIPTION_PARAMETER)
|
||||
.type(String.class)
|
||||
.optional(true)
|
||||
.build();
|
||||
|
||||
Parameter channelParameter = Parameter
|
||||
.builder()
|
||||
.name(CHANNEL_PARAMETER)
|
||||
.type(GuildMessageChannel.class)
|
||||
.optional(true)
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
Parameter durationParameter = Parameter
|
||||
.builder()
|
||||
.name(DURATION_PARAMETER)
|
||||
.type(Duration.class)
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
Parameter winnersParameter = Parameter
|
||||
.builder()
|
||||
.name(WINNERS_PARAMETER)
|
||||
.type(Integer.class)
|
||||
.optional(true)
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
Parameter benefactorParameter = Parameter
|
||||
.builder()
|
||||
.templated(true)
|
||||
.name(BENEFACTOR_PARAMETER)
|
||||
.type(Member.class)
|
||||
.optional(true)
|
||||
.build();
|
||||
|
||||
List<Parameter> parameters = Arrays.asList(titleParameter, durationParameter, benefactorParameter, descriptionParameter,
|
||||
channelParameter, winnersParameter);
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(GiveawaySlashCommandNames.GIVEAWAY)
|
||||
.commandName("create")
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name(COMMAND_NAME)
|
||||
.module(UtilityModuleDefinition.UTILITY)
|
||||
.templated(true)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.async(true)
|
||||
.supportsEmbedException(true)
|
||||
.causesReaction(false)
|
||||
.parameters(parameters)
|
||||
.help(helpInfo)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return GiveawayFeatureDefinition.GIVEAWAY;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
package dev.sheldan.abstracto.giveaway.command;
|
||||
|
||||
import dev.sheldan.abstracto.core.command.UtilityModuleDefinition;
|
||||
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.parameter.SlashCommandParameterService;
|
||||
import dev.sheldan.abstracto.core.utils.CompletableFutureList;
|
||||
import dev.sheldan.abstracto.giveaway.config.GiveawayFeatureDefinition;
|
||||
import dev.sheldan.abstracto.giveaway.config.GiveawaySlashCommandNames;
|
||||
import dev.sheldan.abstracto.giveaway.service.GiveawayService;
|
||||
import jakarta.transaction.Transactional;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
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;
|
||||
|
||||
@Component
|
||||
public class ReRollGiveaway extends AbstractConditionableCommand {
|
||||
|
||||
private static final String COMMAND_NAME = "reRollGiveaway";
|
||||
private static final String ID_PARAMETER = "id";
|
||||
private static final String RE_ROLL_GIVEAWAY_RESPONSE_TEMPLATE_KEY = "reRollGiveaway_response";
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Autowired
|
||||
private SlashCommandParameterService slashCommandParameterService;
|
||||
|
||||
@Autowired
|
||||
private GiveawayService giveawayService;
|
||||
|
||||
@Autowired
|
||||
private ReRollGiveaway self;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<CommandResult> executeSlash(SlashCommandInteractionEvent event) {
|
||||
return event.deferReply().submit().thenAccept(interactionHook -> {
|
||||
self.reRollGiveaway(event);
|
||||
}).thenCompose(unused -> {
|
||||
List<CompletableFuture<Message>> futures = interactionService.sendMessageToInteraction(RE_ROLL_GIVEAWAY_RESPONSE_TEMPLATE_KEY, new Object(), event.getHook());
|
||||
return new CompletableFutureList<>(futures).getMainFuture();
|
||||
})
|
||||
.thenApply(unused -> CommandResult.fromSuccess());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void reRollGiveaway(SlashCommandInteractionEvent event) {
|
||||
Long giveawayId = slashCommandParameterService.getCommandOption(ID_PARAMETER, event, Integer.class).longValue();
|
||||
giveawayService.evaluateGiveaway(giveawayId, event.getGuild().getIdLong());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandConfiguration getConfiguration() {
|
||||
|
||||
Parameter giveawayIdParameter = Parameter
|
||||
.builder()
|
||||
.templated(true)
|
||||
.name(ID_PARAMETER)
|
||||
.type(Integer.class)
|
||||
.build();
|
||||
|
||||
List<Parameter> parameters = Arrays.asList(giveawayIdParameter);
|
||||
HelpInfo helpInfo = HelpInfo
|
||||
.builder()
|
||||
.templated(true)
|
||||
.build();
|
||||
|
||||
SlashCommandConfig slashCommandConfig = SlashCommandConfig
|
||||
.builder()
|
||||
.enabled(true)
|
||||
.rootCommandName(GiveawaySlashCommandNames.GIVEAWAY)
|
||||
.commandName("reroll")
|
||||
.build();
|
||||
|
||||
return CommandConfiguration.builder()
|
||||
.name(COMMAND_NAME)
|
||||
.module(UtilityModuleDefinition.UTILITY)
|
||||
.templated(true)
|
||||
.slashCommandConfig(slashCommandConfig)
|
||||
.async(true)
|
||||
.supportsEmbedException(true)
|
||||
.causesReaction(false)
|
||||
.parameters(parameters)
|
||||
.help(helpInfo)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return GiveawayFeatureDefinition.GIVEAWAY;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package dev.sheldan.abstracto.giveaway.config;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
|
||||
@Configuration
|
||||
@PropertySource("classpath:giveaway-config.properties")
|
||||
public class GiveawayConfig {
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package dev.sheldan.abstracto.giveaway.job;
|
||||
|
||||
import dev.sheldan.abstracto.giveaway.service.GiveawayService;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.quartz.DisallowConcurrentExecution;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.quartz.PersistJobDataAfterExecution;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.quartz.QuartzJobBean;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Slf4j
|
||||
@DisallowConcurrentExecution
|
||||
@Component
|
||||
@PersistJobDataAfterExecution
|
||||
public class GiveawayEvaluationJob extends QuartzJobBean {
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private Long giveawayId;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private Long serverId;
|
||||
|
||||
@Autowired
|
||||
private GiveawayService giveawayService;
|
||||
|
||||
@Override
|
||||
protected void executeInternal(JobExecutionContext context) {
|
||||
try {
|
||||
log.info("Executing giveaway evaluation job for giveaway {} in server {}", giveawayId, serverId);
|
||||
giveawayService.evaluateGiveaway(giveawayId, serverId);
|
||||
} catch (Exception exception) {
|
||||
log.error("Giveaway evaluation job failed.", exception);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package dev.sheldan.abstracto.giveaway.listener;
|
||||
|
||||
import dev.sheldan.abstracto.core.config.FeatureDefinition;
|
||||
import dev.sheldan.abstracto.core.config.ListenerPriority;
|
||||
import dev.sheldan.abstracto.core.interaction.InteractionService;
|
||||
import dev.sheldan.abstracto.core.interaction.button.listener.ButtonClickedListener;
|
||||
import dev.sheldan.abstracto.core.interaction.button.listener.ButtonClickedListenerModel;
|
||||
import dev.sheldan.abstracto.core.interaction.button.listener.ButtonClickedListenerResult;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
|
||||
import dev.sheldan.abstracto.giveaway.config.GiveawayFeatureDefinition;
|
||||
import dev.sheldan.abstracto.giveaway.exception.GiveawayNotFoundException;
|
||||
import dev.sheldan.abstracto.giveaway.model.JoinGiveawayPayload;
|
||||
import dev.sheldan.abstracto.giveaway.model.database.Giveaway;
|
||||
import dev.sheldan.abstracto.giveaway.service.GiveawayService;
|
||||
import dev.sheldan.abstracto.giveaway.service.GiveawayServiceBean;
|
||||
import dev.sheldan.abstracto.giveaway.service.management.GiveawayManagementService;
|
||||
import dev.sheldan.abstracto.giveaway.service.management.GiveawayParticipantManagementService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class GiveawayJoinListener implements ButtonClickedListener {
|
||||
|
||||
private static final String GIVEAWAY_JOIN_RESPONSE_TEMPLATE_KEY = "giveaway_join_response";
|
||||
private static final String GIVEAWAY_ALREADY_JOINED_RESPONSE_TEMPLATE_KEY = "giveaway_already_joined_response";
|
||||
|
||||
@Autowired
|
||||
private GiveawayManagementService giveawayManagementService;
|
||||
|
||||
@Autowired
|
||||
private GiveawayService giveawayService;
|
||||
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Autowired
|
||||
private GiveawayParticipantManagementService giveawayParticipantManagementService;
|
||||
|
||||
@Autowired
|
||||
private UserInServerManagementService userInServerManagementService;
|
||||
|
||||
@Override
|
||||
public ButtonClickedListenerResult execute(ButtonClickedListenerModel model) {
|
||||
JoinGiveawayPayload payload = (JoinGiveawayPayload) model.getDeserializedPayload();
|
||||
Optional<Giveaway> optionalGiveaway = giveawayManagementService.loadGiveawayById(payload.getGiveawayId(), payload.getServerId());
|
||||
if(optionalGiveaway.isPresent()) {
|
||||
Giveaway giveaway = optionalGiveaway.get();
|
||||
AUserInAServer user = userInServerManagementService.loadOrCreateUser(model.getEvent().getMember());
|
||||
Long joiningUserId = model.getEvent().getMember().getIdLong();
|
||||
if(!giveawayParticipantManagementService.userIsAlreadyParticipating(giveaway, user)) {
|
||||
log.info("Adding user {} to giveaway {}.", joiningUserId, payload.getGiveawayId());
|
||||
giveawayService.addGiveawayParticipant(giveaway, model.getEvent().getMember(), model.getEvent().getMessageChannel())
|
||||
.thenAccept(unused -> {
|
||||
log.info("Notified user {} in giveaway {} join event.", joiningUserId, payload.getGiveawayId());
|
||||
interactionService.replyEmbed(GIVEAWAY_JOIN_RESPONSE_TEMPLATE_KEY, model.getEvent());
|
||||
}).exceptionally(throwable -> {
|
||||
log.error("Failed to add {} to giveaway {}.", joiningUserId, payload.getGiveawayId(), throwable);
|
||||
return null;
|
||||
});
|
||||
} else {
|
||||
log.info("User {} was already part of giveaway {}.", joiningUserId, payload.getGiveawayId());
|
||||
interactionService.replyEmbed(GIVEAWAY_ALREADY_JOINED_RESPONSE_TEMPLATE_KEY, model.getEvent());
|
||||
}
|
||||
return ButtonClickedListenerResult.ACKNOWLEDGED;
|
||||
} else {
|
||||
throw new GiveawayNotFoundException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean handlesEvent(ButtonClickedListenerModel model) {
|
||||
return GiveawayServiceBean.GIVEAWAY_JOIN_ORIGIN.equals(model.getOrigin());
|
||||
}
|
||||
|
||||
@Override
|
||||
public FeatureDefinition getFeature() {
|
||||
return GiveawayFeatureDefinition.GIVEAWAY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getPriority() {
|
||||
return ListenerPriority.MEDIUM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean autoAcknowledgeEvent() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package dev.sheldan.abstracto.giveaway.repository;
|
||||
|
||||
import dev.sheldan.abstracto.giveaway.model.database.GiveawayParticipant;
|
||||
import dev.sheldan.abstracto.giveaway.model.database.embed.GiveawayParticipationId;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface GiveawayParticipantRepository extends JpaRepository<GiveawayParticipant, GiveawayParticipationId> {
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package dev.sheldan.abstracto.giveaway.repository;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.ServerSpecificId;
|
||||
import dev.sheldan.abstracto.giveaway.model.database.Giveaway;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface GiveawayRepository extends JpaRepository<Giveaway, ServerSpecificId> {
|
||||
}
|
||||
@@ -0,0 +1,275 @@
|
||||
package dev.sheldan.abstracto.giveaway.service;
|
||||
|
||||
import dev.sheldan.abstracto.core.interaction.ComponentPayloadService;
|
||||
import dev.sheldan.abstracto.core.interaction.ComponentService;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
|
||||
import dev.sheldan.abstracto.core.service.ChannelService;
|
||||
import dev.sheldan.abstracto.core.service.CounterService;
|
||||
import dev.sheldan.abstracto.core.service.PostTargetService;
|
||||
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
|
||||
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.giveaway.config.GiveawayPostTarget;
|
||||
import dev.sheldan.abstracto.giveaway.exception.GiveawayNotFoundException;
|
||||
import dev.sheldan.abstracto.giveaway.model.GiveawayCreationRequest;
|
||||
import dev.sheldan.abstracto.giveaway.model.JoinGiveawayPayload;
|
||||
import dev.sheldan.abstracto.giveaway.model.database.Giveaway;
|
||||
import dev.sheldan.abstracto.giveaway.model.database.GiveawayParticipant;
|
||||
import dev.sheldan.abstracto.giveaway.model.template.GiveawayMessageModel;
|
||||
import dev.sheldan.abstracto.giveaway.model.template.GiveawayResultMessageModel;
|
||||
import dev.sheldan.abstracto.giveaway.service.management.GiveawayManagementService;
|
||||
import dev.sheldan.abstracto.giveaway.service.management.GiveawayParticipantManagementService;
|
||||
import dev.sheldan.abstracto.scheduling.model.JobParameters;
|
||||
import dev.sheldan.abstracto.scheduling.service.SchedulerService;
|
||||
import jakarta.transaction.Transactional;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel;
|
||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class GiveawayServiceBean implements GiveawayService {
|
||||
|
||||
private static final String GIVEAWAY_MESSAGE_TEMPLATE_KEY = "giveaway_post";
|
||||
private static final String GIVEAWAY_RESULT_MESSAGE_TEMPLATE_KEY = "giveaway_result";
|
||||
public static final String GIVEAWAY_JOIN_ORIGIN = "JOIN_GIVEAWAY";
|
||||
|
||||
public static final String GIVEAWAY_COUNTER = "giveaways";
|
||||
|
||||
@Autowired
|
||||
private ChannelManagementService channelManagementService;
|
||||
|
||||
@Autowired
|
||||
private UserInServerManagementService userInServerManagementService;
|
||||
|
||||
@Autowired
|
||||
private GiveawayManagementService giveawayManagementService;
|
||||
|
||||
@Autowired
|
||||
private ComponentService componentService;
|
||||
|
||||
@Autowired
|
||||
private PostTargetService postTargetService;
|
||||
|
||||
@Autowired
|
||||
private ChannelService channelService;
|
||||
|
||||
@Autowired
|
||||
private TemplateService templateService;
|
||||
|
||||
@Autowired
|
||||
private ComponentPayloadService componentPayloadService;
|
||||
|
||||
@Autowired
|
||||
private GiveawayParticipantManagementService giveawayParticipantManagementService;
|
||||
|
||||
@Autowired
|
||||
private SchedulerService schedulerService;
|
||||
|
||||
@Autowired
|
||||
private SecureRandom secureRandom;
|
||||
|
||||
@Autowired
|
||||
private CounterService counterService;
|
||||
|
||||
@Autowired
|
||||
private GiveawayServiceBean self;
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> createGiveaway(GiveawayCreationRequest giveawayCreationRequest) {
|
||||
String componentId = componentService.generateComponentId();
|
||||
Instant targetDate = Instant.now().plus(giveawayCreationRequest.getDuration());
|
||||
Long serverId = giveawayCreationRequest.getCreator().getGuild().getIdLong();
|
||||
Long giveawayId = counterService.getNextCounterValue(serverId, GIVEAWAY_COUNTER);
|
||||
GiveawayMessageModel model = GiveawayMessageModel
|
||||
.builder()
|
||||
.title(giveawayCreationRequest.getTitle())
|
||||
.description(giveawayCreationRequest.getDescription())
|
||||
.giveawayId(giveawayId)
|
||||
.benefactor(giveawayCreationRequest.getBenefactor() != null ? MemberDisplay.fromMember(giveawayCreationRequest.getBenefactor()) : null)
|
||||
.creator(MemberDisplay.fromMember(giveawayCreationRequest.getCreator()))
|
||||
.winnerCount(giveawayCreationRequest.getWinnerCount())
|
||||
.targetDate(targetDate)
|
||||
.joinComponentId(componentId)
|
||||
.build();
|
||||
List<CompletableFuture<Message>> messageFutures;
|
||||
log.info("Rendering giveaway message in server {} by user {}", serverId, giveawayCreationRequest.getCreator().getIdLong());
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(GIVEAWAY_MESSAGE_TEMPLATE_KEY, model, serverId);
|
||||
if(giveawayCreationRequest.getTargetChannel() == null) {
|
||||
log.info("Sending giveaway to post target in server {}", serverId);
|
||||
postTargetService.validatePostTarget(GiveawayPostTarget.GIVEAWAYS, giveawayCreationRequest.getCreator().getGuild().getIdLong());
|
||||
messageFutures = postTargetService.sendEmbedInPostTarget(messageToSend, GiveawayPostTarget.GIVEAWAYS, serverId);
|
||||
} else {
|
||||
log.info("Sending giveaway to channel {} in server {}.", giveawayCreationRequest.getTargetChannel().getId(), serverId);
|
||||
messageFutures = channelService.sendMessageToSendToChannel(messageToSend, giveawayCreationRequest.getTargetChannel());
|
||||
}
|
||||
CompletableFutureList<Message> messageFutureList = new CompletableFutureList<>(messageFutures);
|
||||
return messageFutureList.getMainFuture().thenAccept(o -> {
|
||||
Message createdMessage = messageFutureList.getFutures().get(0).join();
|
||||
giveawayCreationRequest.setTargetChannel(createdMessage.getGuildChannel());
|
||||
self.persistGiveaway(giveawayCreationRequest, giveawayId, createdMessage.getIdLong(), componentId);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> addGiveawayParticipant(Giveaway giveaway, Member member, MessageChannel messageChannel) {
|
||||
GiveawayMessageModel giveawayMessageModel = GiveawayMessageModel.fromGiveaway(giveaway);
|
||||
giveawayMessageModel.setJoinedUserCount(giveaway.getParticipants().size() + 1L);
|
||||
Long giveawayId = giveaway.getGiveawayId().getId();
|
||||
log.info("Adding giveaway participating of user {} to giveaway {} in server {}.", member.getIdLong(), giveawayId, member.getGuild().getIdLong());
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(GIVEAWAY_MESSAGE_TEMPLATE_KEY, giveawayMessageModel);
|
||||
return channelService.editEmbedMessageInAChannel(messageToSend.getEmbeds().get(0), messageChannel, giveaway.getMessageId())
|
||||
.thenAccept(message -> {
|
||||
self.persistAddedParticipant(member, giveawayId);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public CompletableFuture<Void> evaluateGiveaway(Long giveawayId, Long serverId) {
|
||||
Optional<Giveaway> giveAwayOptional = giveawayManagementService.loadGiveawayById(giveawayId, serverId);
|
||||
if(giveAwayOptional.isEmpty()) {
|
||||
throw new GiveawayNotFoundException();
|
||||
}
|
||||
log.info("Evaluating giveaway {} in server {}.", giveawayId, serverId);
|
||||
Giveaway giveaway = giveAwayOptional.get();
|
||||
Set<Long> winners = new HashSet<>();
|
||||
Integer winnerCount = giveaway.getWinnerCount();
|
||||
List<Long> potentialWinners = new ArrayList<>(giveaway
|
||||
.getParticipants()
|
||||
.stream()
|
||||
.map(giveawayParticipant -> giveawayParticipant.getParticipant().getUserInServerId())
|
||||
.toList());
|
||||
|
||||
if(potentialWinners.size() <= winnerCount) {
|
||||
winners.addAll(potentialWinners);
|
||||
log.debug("Less participants than total winners - selecting all for giveaway {} in server {}.", giveawayId, serverId);
|
||||
} else {
|
||||
for (int i = 0; i < winnerCount; i++) {
|
||||
int winnerIndex = secureRandom.nextInt(potentialWinners.size());
|
||||
Long winner = potentialWinners.get(winnerIndex);
|
||||
potentialWinners.remove(winnerIndex);
|
||||
winners.add(winner);
|
||||
}
|
||||
}
|
||||
List<GiveawayParticipant> winningParticipants = giveaway
|
||||
.getParticipants()
|
||||
.stream()
|
||||
.filter(giveawayParticipant -> winners.contains(giveawayParticipant.getParticipant().getUserInServerId()))
|
||||
.toList();
|
||||
List<MemberDisplay> winnerDisplays = winningParticipants
|
||||
.stream()
|
||||
.map(giveawayParticipant -> MemberDisplay.fromAUserInAServer(giveawayParticipant.getParticipant()))
|
||||
.toList();
|
||||
GiveawayResultMessageModel resultModel = GiveawayResultMessageModel
|
||||
.builder()
|
||||
.messageId(giveaway.getMessageId())
|
||||
.title(giveaway.getTitle())
|
||||
.winners(winnerDisplays)
|
||||
.build();
|
||||
log.info("Sending result message for giveaway {} in server {}.", giveawayId, serverId);
|
||||
MessageToSend messageToSend = templateService.renderEmbedTemplate(GIVEAWAY_RESULT_MESSAGE_TEMPLATE_KEY, resultModel);
|
||||
List<CompletableFuture<Message>> resultFutures = channelService.sendMessageEmbedToSendToAChannel(messageToSend, giveaway.getGiveawayChannel());
|
||||
|
||||
GiveawayMessageModel giveawayMessageModel = GiveawayMessageModel.fromGiveaway(giveaway);
|
||||
giveawayMessageModel.setWinners(winnerDisplays);
|
||||
giveawayMessageModel.setEnded(true);
|
||||
MessageToSend giveawayMessageToSend = templateService.renderEmbedTemplate(GIVEAWAY_MESSAGE_TEMPLATE_KEY, giveawayMessageModel);
|
||||
log.info("Updating original giveaway message for giveaway {} in server {}.", giveawayId, serverId);
|
||||
GuildMessageChannel messageChannel = channelService.getMessageChannelFromServer(giveaway.getServer().getId(), giveaway.getGiveawayChannel().getId());
|
||||
CompletableFuture<Message> giveawayUpdateFuture = channelService.editMessageInAChannelFuture(giveawayMessageToSend, messageChannel, giveaway.getMessageId());
|
||||
resultFutures.add(giveawayUpdateFuture);
|
||||
return new CompletableFutureList<>(resultFutures).getMainFuture();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> cancelGiveaway(Long giveawayId, Long serverId) {
|
||||
Optional<Giveaway> giveAwayOptional = giveawayManagementService.loadGiveawayById(giveawayId, serverId);
|
||||
if(giveAwayOptional.isEmpty()) {
|
||||
throw new GiveawayNotFoundException();
|
||||
}
|
||||
Giveaway giveaway = giveAwayOptional.get();
|
||||
log.info("Cancelling giveaway with id {} in server {}.", giveawayId, serverId);
|
||||
GiveawayMessageModel giveawayMessageModel = GiveawayMessageModel.fromGiveaway(giveaway);
|
||||
giveawayMessageModel.setCancelled(true);
|
||||
schedulerService.stopTrigger(giveaway.getReminderTriggerKey());
|
||||
MessageToSend giveawayMessageToSend = templateService.renderEmbedTemplate(GIVEAWAY_MESSAGE_TEMPLATE_KEY, giveawayMessageModel);
|
||||
|
||||
GuildMessageChannel messageChannel = channelService.getMessageChannelFromServer(giveaway.getServer().getId(), giveaway.getGiveawayChannel().getId());
|
||||
log.debug("Updating original giveaway message to consider cancellation for giveaway {} in server {}.", giveawayId, serverId);
|
||||
return channelService.editMessageInAChannelFuture(giveawayMessageToSend, messageChannel, giveaway.getMessageId())
|
||||
.thenAccept(message -> {
|
||||
self.persistGiveawayCancellation(giveawayId, serverId);
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void persistGiveawayCancellation(Long giveawayId, Long serverId) {
|
||||
Optional<Giveaway> giveAwayOptional = giveawayManagementService.loadGiveawayById(giveawayId, serverId);
|
||||
if(giveAwayOptional.isEmpty()) {
|
||||
throw new GiveawayNotFoundException();
|
||||
}
|
||||
log.info("Persisting cancellation of giveaway {} in server {}.", giveawayId, serverId);
|
||||
Giveaway giveaway = giveAwayOptional.get();
|
||||
giveaway.setCancelled(true);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void persistAddedParticipant(Member member, Long giveawayId) {
|
||||
log.info("Storing user {} as participant to giveaway {} in server {}.", member.getIdLong(), giveawayId, member.getGuild().getIdLong());
|
||||
Optional<Giveaway> giveAwayOptional = giveawayManagementService.loadGiveawayById(giveawayId, member.getGuild().getIdLong());
|
||||
giveAwayOptional.ifPresent(giveaway -> {
|
||||
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(member);
|
||||
giveawayParticipantManagementService.addParticipant(giveaway, aUserInAServer);
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void persistGiveaway(GiveawayCreationRequest giveawayCreationRequest, Long giveawayId, Long messageId, String componentId) {
|
||||
Member creatorMember = giveawayCreationRequest.getCreator();
|
||||
log.info("Persisting giveaway in server {} with message id {}.", creatorMember.getGuild().getIdLong(), messageId);
|
||||
Instant targetDate = Instant.now().plus(giveawayCreationRequest.getDuration());
|
||||
AChannel targetChannel = channelManagementService.loadChannel(giveawayCreationRequest.getTargetChannel().getIdLong());
|
||||
AUserInAServer creator = userInServerManagementService.loadOrCreateUser(creatorMember);
|
||||
AUserInAServer benefactor;
|
||||
if(giveawayCreationRequest.getBenefactor() != null) {
|
||||
benefactor = userInServerManagementService.loadOrCreateUser(giveawayCreationRequest.getBenefactor());
|
||||
} else {
|
||||
benefactor = null;
|
||||
}
|
||||
|
||||
Giveaway giveaway = giveawayManagementService.createGiveaway(creator, benefactor, targetChannel, targetDate,
|
||||
giveawayCreationRequest.getTitle(), giveawayCreationRequest.getDescription(), giveawayCreationRequest.getWinnerCount(),
|
||||
messageId, componentId, giveawayId);
|
||||
|
||||
HashMap<Object, Object> parameters = new HashMap<>();
|
||||
parameters.put("giveawayId", giveaway.getGiveawayId().getId().toString());
|
||||
parameters.put("serverId", giveaway.getGiveawayId().getServerId().toString());
|
||||
JobParameters jobParameters = JobParameters
|
||||
.builder()
|
||||
.parameters(parameters)
|
||||
.build();
|
||||
log.info("Scheduling giveaway reminder for giveaway {} originating from message {} in server {}.", giveaway.getGiveawayId().getId(), messageId, creatorMember.getGuild().getIdLong());
|
||||
String triggerKey = schedulerService.executeJobWithParametersOnce("giveawayEvaluationJob", "giveaway", jobParameters, Date.from(giveaway.getTargetDate()));
|
||||
giveaway.setReminderTriggerKey(triggerKey);
|
||||
JoinGiveawayPayload joinPayload = JoinGiveawayPayload
|
||||
.builder()
|
||||
.giveawayId(giveaway.getGiveawayId().getId())
|
||||
.serverId(giveaway.getGiveawayId().getServerId())
|
||||
.build();
|
||||
componentPayloadService.createButtonPayload(componentId, joinPayload, GIVEAWAY_JOIN_ORIGIN, creator.getServerReference());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package dev.sheldan.abstracto.giveaway.service.management;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.ServerSpecificId;
|
||||
import dev.sheldan.abstracto.core.models.database.AChannel;
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.giveaway.model.database.Giveaway;
|
||||
import dev.sheldan.abstracto.giveaway.repository.GiveawayRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Optional;
|
||||
|
||||
@Component
|
||||
public class GiveawayManagementServiceBean implements GiveawayManagementService {
|
||||
|
||||
@Autowired
|
||||
private GiveawayRepository giveawayRepository;
|
||||
|
||||
@Override
|
||||
public Giveaway createGiveaway(AUserInAServer creator, AUserInAServer benefactor, AChannel target,
|
||||
Instant targetDate, String title, String description, Integer winnerCount,
|
||||
Long messageId, String componentId, Long giveawayId) {
|
||||
Giveaway giveaway = Giveaway
|
||||
.builder()
|
||||
.giveawayId(new ServerSpecificId(creator.getServerReference().getId(), giveawayId))
|
||||
.creator(creator)
|
||||
.benefactor(benefactor)
|
||||
.messageId(messageId)
|
||||
.componentId(componentId)
|
||||
.server(creator.getServerReference())
|
||||
.winnerCount(winnerCount)
|
||||
.cancelled(false)
|
||||
.title(title)
|
||||
.giveawayChannel(target)
|
||||
.description(description)
|
||||
.targetDate(targetDate)
|
||||
.build();
|
||||
return giveawayRepository.save(giveaway);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Giveaway> loadGiveawayById(Long giveawayId, Long serverId) {
|
||||
return giveawayRepository.findById(new ServerSpecificId(serverId, giveawayId));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package dev.sheldan.abstracto.giveaway.service.management;
|
||||
|
||||
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
|
||||
import dev.sheldan.abstracto.giveaway.model.database.Giveaway;
|
||||
import dev.sheldan.abstracto.giveaway.model.database.GiveawayParticipant;
|
||||
import dev.sheldan.abstracto.giveaway.model.database.embed.GiveawayParticipationId;
|
||||
import dev.sheldan.abstracto.giveaway.repository.GiveawayParticipantRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class GiveawayParticipantManagementServiceBean implements GiveawayParticipantManagementService {
|
||||
|
||||
@Autowired
|
||||
private GiveawayParticipantRepository repository;
|
||||
|
||||
@Override
|
||||
public void addParticipant(Giveaway giveaway, AUserInAServer aUserInAServer) {
|
||||
GiveawayParticipationId id = new GiveawayParticipationId(aUserInAServer.getUserInServerId(), giveaway.getGiveawayId().getId(), giveaway.getServer().getId());
|
||||
GiveawayParticipant participant = GiveawayParticipant
|
||||
.builder()
|
||||
.id(id)
|
||||
.giveaway(giveaway)
|
||||
.participant(aUserInAServer)
|
||||
.won(false)
|
||||
.build();
|
||||
repository.save(participant);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean userIsAlreadyParticipating(Giveaway giveaway, AUserInAServer aUserInAServer) {
|
||||
return repository.existsById(new GiveawayParticipationId(aUserInAServer.getUserInServerId(), giveaway.getGiveawayId().getId(), giveaway.getServer().getId()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
abstracto.featureFlags.giveaway.featureName=giveaway
|
||||
abstracto.featureFlags.giveaway.enabled=false
|
||||
|
||||
abstracto.postTargets.giveaways.name=giveaways
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user