Compare commits

..

1 Commits

3648 changed files with 9848 additions and 165622 deletions

2
.env
View File

@@ -1,2 +0,0 @@
REGISTRY_PREFIX=harbor.sheldan.dev/abstracto/
VERSION=1.6.0

View File

@@ -1,42 +0,0 @@
name: Bug Report
description: Found a bug that needs fixing?
body:
- type: checkboxes
attributes:
label: General Troubleshooting
description: You confirm to have made the following checks first.
options:
- label: I have checked for similar issues on the Issue-tracker.
required: true
- label: I have updated to the latest version
required: true
- label: I have checked the branches or the maintainers' PRs for upcoming bug fixes.
required: true
- type: textarea
attributes:
label: "Description"
description: "General information about the bug"
placeholder: "..."
validations:
required: true
- type: textarea
attributes:
label: "Steps to reproduce"
description: "What happened when the bug occurred?"
placeholder: "1. ..."
validations:
required: true
- type: textarea
attributes:
label: "Expected behaviour"
description: "What should happen?"
placeholder: "It should..."
validations:
required: true
- type: textarea
attributes:
label: "Actual behaviour"
description: "What did happen instead?"
placeholder: "It actually ..."
validations:
required: true

View File

@@ -1,36 +0,0 @@
name: Feature request
description: Want some functionality added?
body:
- type: checkboxes
attributes:
label: General Information
description: You confirm to have made the following checks first.
options:
- label: I have checked for similar issues on the Issue-tracker.
required: true
- label: I have updated to the latest version
required: true
- label: I have checked the branches or the maintainers' PRs for upcoming features fixes.
required: true
- type: textarea
attributes:
label: "Description"
description: "General description of the feature"
placeholder: "..."
validations:
required: true
- type: textarea
attributes:
label: "Feature worth and general use"
description: "Why should this be in abstracto?"
placeholder: "..."
validations:
required: true
- type: textarea
attributes:
label: "Suggestions for implementation"
description: "Any ideas about what the feature should behave/look like? Commands?"
placeholder: "It should..."
validations:
required: false

View File

@@ -1,40 +0,0 @@
# 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
on:
push:
branches:
- master
- feature/**
- hotfix/**
- bugfix/**
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
distribution: 'corretto'
java-version: 17
- name: Setup node
uses: actions/setup-node@v3
with:
node-version: '21.x'
- name: Build with Maven
run: mvn -B install --file abstracto-application/pom.xml
- name: Install node dependencies and build
working-directory: ./ui/experience-tracking
run: npm ci
- name: Build ui application
working-directory: ./ui/experience-tracking
run: npm run build

View File

@@ -1,78 +0,0 @@
name: Publishes a new version of abstracto
on: workflow_dispatch
permissions:
packages: write
contents: write
jobs:
publish:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
with:
ref: master
- name: Set up JDK
uses: actions/setup-java@v3
with:
distribution: 'corretto'
java-version: 17
- name: Setup node
uses: actions/setup-node@v3
with:
node-version: '21.x'
- name: Load current version
id: version
working-directory: ./abstracto-application
run: echo "version=$(mvn -q -Dexec.executable="echo" -Dexec.args='${project.version}' --non-recursive exec:exec | cut -d- -f1)" >> $GITHUB_ENV
- name: Create a Release
uses: elgohr/Github-Release-Action@v5
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
title: Release of version ${{ env.version }}
- name: Release maven packages
uses: qcastel/github-actions-maven-release@v1.12.43
env:
JAVA_HOME: /usr/lib/jvm/java-17-openjdk/
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
maven-project-folder: "abstracto-application/"
git-release-bot-name: "release-bot"
git-release-bot-email: "release-bot@sheldan.dev"
release-branch-name: master
maven-args: "-Dmaven.javadoc.skip=true -s settings.xml -DskipTests"
access-token: ${{ secrets.GITHUB_TOKEN }}
- name: Install node dependencies and build
working-directory: ./ui/experience-tracking
run: npm ci
- name: Build ui application
working-directory: ./ui/experience-tracking
run: npm run build
- name: Copy built UI
run: cp -R ui/experience-tracking/build/* python/components/experience-tracking/resources/templates/experience/leaderboards/
- name: Login to Harbor
uses: docker/login-action@v2
with:
registry: harbor.sheldan.dev
username: ${{ secrets.HARBOR_USERNAME }}
password: ${{ secrets.HARBOR_TOKEN }}
- name: Update .env version
run:
sed -i '2s/.*/VERSION=${{ env.version }}/' .env
- name: Load env file
id: dotenv
uses: falti/dotenv-action@v1.0.4
with:
path: .env
- name: Build and push Docker containers
run: docker compose build && docker compose push
env:
REGISTRY_PREFIX: ${{ steps.dotenv.outputs.registry_prefix }}
VERSION: ${{ steps.dotenv.outputs.version }}
- name: Fix file permissions
run:
sudo chmod -R ugo+rwX . # https://github.com/actions/checkout/issues/164
- name: Commit updated versions
uses: EndBug/add-and-commit@v9
with:
author_name: "release-bot"
author_email: "release-bot@sheldan.dev"

5
.gitignore vendored
View File

@@ -14,13 +14,12 @@ target/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
venv/

View File

@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2024 Sheldan
Copyright (c) 2019 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

View File

@@ -1,33 +0,0 @@
# Abstracto
![Build](https://github.com/Sheldan/abstracto/workflows/Execute%20Build/badge.svg)
[![GitHub license](https://img.shields.io/github/license/Sheldan/abstracto)](https://github.com/Sheldan/abstracto/blob/master/LICENSE)
Abstracto represents a framework to be used as a basis for a Discord bot. It uses [JDA](https://github.com/DV8FromTheWorld/JDA/) as an API wrapper underneath
and provides an extensive tool set to create new commands and a wide range of commands out of the box.
This repository does not provide the full functionality in order to start a discord bot, because it requires a Main class.
## Technologies
* [JDA](https://github.com/DV8FromTheWorld/JDA/) The Discord API Wrapper in the version 5.0.0-beta.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)
* [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 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.
## Issues
If you find any issue, feel free to create a GitHub issue.
## License
This project is licensed under the MIT license.

View File

@@ -1,54 +0,0 @@
<?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">
<parent>
<artifactId>anti-raid</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.6.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>anti-raid-impl</artifactId>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>dev.sheldan.abstracto.core</groupId>
<artifactId>core-int</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>anti-raid-int</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<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>
</project>

View File

@@ -1,18 +0,0 @@
<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>

View File

@@ -1,10 +0,0 @@
package dev.sheldan.abstracto.antiraid.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
@Configuration
@PropertySource("classpath:antiRaid-config.properties")
public class AntiRaidProperties {
}

View File

@@ -1,36 +0,0 @@
package dev.sheldan.abstracto.antiraid.listener;
import dev.sheldan.abstracto.antiraid.config.AntiRaidFeatureDefinition;
import dev.sheldan.abstracto.antiraid.service.MassPingService;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
import dev.sheldan.abstracto.core.listener.async.jda.AsyncMessageReceivedListener;
import dev.sheldan.abstracto.core.models.listener.MessageReceivedModel;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.channel.ChannelType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class MassPingMessageListener implements AsyncMessageReceivedListener {
@Autowired
private MassPingService massPingService;
@Override
public DefaultListenerResult execute(MessageReceivedModel model) {
Message message = model.getMessage();
if(message.getAuthor().isBot() || message.isWebhookMessage() || !message.isFromGuild() || !message.isFromType(ChannelType.TEXT)) {
return DefaultListenerResult.IGNORED;
}
massPingService.processMessage(message);
return DefaultListenerResult.PROCESSED;
}
@Override
public FeatureDefinition getFeature() {
return AntiRaidFeatureDefinition.ANTI_RAID;
}
}

View File

@@ -1,113 +0,0 @@
package dev.sheldan.abstracto.antiraid.service;
import dev.sheldan.abstracto.antiraid.config.AntiRaidPostTarget;
import dev.sheldan.abstracto.antiraid.model.MassPingNotificationModel;
import dev.sheldan.abstracto.core.models.ConditionContextInstance;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
import dev.sheldan.abstracto.core.service.*;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
import dev.sheldan.abstracto.core.templating.service.TemplateService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import dev.sheldan.abstracto.moderation.service.MuteService;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
@Component
@Slf4j
public class MassPingServiceBean implements MassPingService {
private static final String MASS_PING_MUTE_NOTIFICATION_TEMPLATE_KEY = "massPing_mute_notification";
private static final String LEVEL_CONDITION_NAME = "HAS_LEVEL";
private static final String LEVEL_CONDITION_USER_ID_PARAMETER = "userId";
private static final String LEVEL_CONDITION_LEVEL_PARAMETER = "level";
private static final String LEVEL_CONDITION_SERVER_PARAMETER = "serverId";
@Autowired
private ConfigService configService;
@Autowired
private MuteService muteService;
@Autowired
private TemplateService templateService;
@Autowired
private MassPingServiceBean self;
@Autowired
private PostTargetService postTargetService;
@Autowired
private ConditionService conditionService;
@Value("${abstracto.massPing.maxAllowedMentions}")
private Integer maxAllowedMentions;
@Autowired
private UserInServerManagementService userInServerManagementService;
@Autowired
private MemberService memberService;
@Override
public CompletableFuture<Void> processMessage(Message message) {
if(message.getMentions().getUsers().size() > maxAllowedMentions) {
Integer level = configService.getLongValueOrConfigDefault(MassPingService.MAX_AFFECTED_LEVEL_KEY, message.getGuild().getIdLong()).intValue();
boolean allowed = allowedToMassMention(message, level);
if(!allowed) {
return memberService.timeoutUserMaxDuration(message.getMember())
.thenAccept(unused -> self.sendMassPingMuteNotification(message))
.thenAccept(unused -> log.info("Muted member {} in server {} because of too many member mentions. (> {}).",
message.getAuthor().getIdLong(), message.getGuild().getIdLong(), maxAllowedMentions));
} else {
log.info("User {} in server {} is allowed to mass mention, because of level (or lack of level configuration).",
message.getAuthor().getIdLong(), message.getGuild().getIdLong());
return CompletableFuture.completedFuture(null);
}
} else {
return CompletableFuture.completedFuture(null);
}
}
private boolean allowedToMassMention(Message message, Integer level) {
log.info("Checking if member {} is allowed to mention a lot of users in server {}.", message.getAuthor().getIdLong(), message.getGuild().getIdLong());
Map<String, Object> parameters = new HashMap<>();
AUserInAServer userInAServer = userInServerManagementService.loadOrCreateUser(message.getMember());
parameters.put(LEVEL_CONDITION_USER_ID_PARAMETER, userInAServer.getUserInServerId());
parameters.put(LEVEL_CONDITION_LEVEL_PARAMETER, level);
parameters.put(LEVEL_CONDITION_SERVER_PARAMETER, message.getGuild().getIdLong());
ConditionContextInstance contextInstance = ConditionContextInstance
.builder()
.conditionName(LEVEL_CONDITION_NAME)
.parameters(parameters)
.build();
SystemCondition.Result result = conditionService.checkConditions(contextInstance);
return SystemCondition.Result.consideredSuccessful(result);
}
@Transactional
public CompletableFuture<Void> sendMassPingMuteNotification(Message message) {
Member member = message.getMember();
MassPingNotificationModel model = MassPingNotificationModel
.builder()
.messageLink(message.getJumpUrl())
.mentionCount(message.getMentions().getUsers().size())
.messageContent(message.getContentRaw())
.memberDisplay(MemberDisplay.fromMember(member))
.build();
MessageToSend messageToSend = templateService.renderEmbedTemplate(MASS_PING_MUTE_NOTIFICATION_TEMPLATE_KEY, model, member.getGuild().getIdLong());
return FutureUtils.toSingleFutureGeneric(postTargetService.sendEmbedInPostTarget(messageToSend, AntiRaidPostTarget.MASS_PING_LOG, member.getGuild().getIdLong()));
}
}

View File

@@ -1,9 +0,0 @@
abstracto.featureFlags.antiRaid.featureName=antiRaid
abstracto.featureFlags.antiRaid.enabled=false
abstracto.postTargets.massPingLog.name=massPingLog
abstracto.massPing.maxAllowedMentions=5
abstracto.systemConfigs.massPingMinLevel.name=massPingMinLevel
abstracto.systemConfigs.massPingMinLevel.longValue=15

View File

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

View File

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

View File

@@ -1,10 +0,0 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
<changeSet author="Sheldan" id="anti_raid-feature-insertion">
<insert tableName="feature">
<column name="key" value="antiRaid"/>
</insert>
</changeSet>
</databaseChangeLog>

View File

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

View File

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

View File

@@ -1,31 +0,0 @@
<?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">
<parent>
<artifactId>anti-raid</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.6.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>anti-raid-int</artifactId>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>dev.sheldan.abstracto.core</groupId>
<artifactId>core-int</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>moderation-int</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>

View File

@@ -1,39 +0,0 @@
package dev.sheldan.abstracto.antiraid.config;
import dev.sheldan.abstracto.antiraid.service.MassPingService;
import dev.sheldan.abstracto.core.config.FeatureConfig;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.config.PostTargetEnum;
import dev.sheldan.abstracto.moderation.config.feature.MutingFeatureConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
@Component
public class AntiRaidFeatureConfig implements FeatureConfig {
@Autowired
private MutingFeatureConfig mutingFeatureConfig;
@Override
public FeatureDefinition getFeature() {
return AntiRaidFeatureDefinition.ANTI_RAID;
}
@Override
public List<PostTargetEnum> getRequiredPostTargets() {
return Arrays.asList(AntiRaidPostTarget.MASS_PING_LOG);
}
@Override
public List<String> getRequiredSystemConfigKeys() {
return Arrays.asList(MassPingService.MAX_AFFECTED_LEVEL_KEY);
}
@Override
public List<FeatureConfig> getRequiredFeatures() {
return Arrays.asList(mutingFeatureConfig);
}
}

View File

@@ -1,15 +0,0 @@
package dev.sheldan.abstracto.antiraid.config;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import lombok.Getter;
@Getter
public enum AntiRaidFeatureDefinition implements FeatureDefinition {
ANTI_RAID("antiRaid");
private String key;
AntiRaidFeatureDefinition(String key) {
this.key = key;
}
}

View File

@@ -1,15 +0,0 @@
package dev.sheldan.abstracto.antiraid.config;
import dev.sheldan.abstracto.core.config.PostTargetEnum;
import lombok.Getter;
@Getter
public enum AntiRaidPostTarget implements PostTargetEnum {
MASS_PING_LOG("massPingLog");
private String key;
AntiRaidPostTarget(String key) {
this.key = key;
}
}

View File

@@ -1,16 +0,0 @@
package dev.sheldan.abstracto.antiraid.model;
import dev.sheldan.abstracto.core.models.template.display.MemberDisplay;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Builder
public class MassPingNotificationModel {
private MemberDisplay memberDisplay;
private String messageContent;
private String messageLink;
private Integer mentionCount;
}

View File

@@ -1,10 +0,0 @@
package dev.sheldan.abstracto.antiraid.service;
import net.dv8tion.jda.api.entities.Message;
import java.util.concurrent.CompletableFuture;
public interface MassPingService {
String MAX_AFFECTED_LEVEL_KEY = "massPingMinLevel";
CompletableFuture<Void> processMessage(Message message);
}

View File

@@ -1,17 +0,0 @@
<?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">
<parent>
<artifactId>abstracto-modules</artifactId>
<groupId>dev.sheldan.abstracto.modules</groupId>
<version>1.6.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>anti-raid</artifactId>
<packaging>pom</packaging>
<modules>
<module>anti-raid-int</module>
<module>anti-raid-impl</module>
</modules>
</project>

View File

@@ -1,49 +0,0 @@
<?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">
<parent>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>assignable-roles</artifactId>
<version>1.6.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>assignable-roles-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>assignable-roles-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>

View File

@@ -1,18 +0,0 @@
<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>

View File

@@ -1,69 +0,0 @@
package dev.sheldan.abstracto.assignableroles.command;
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
/**
* Command used to activate an {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace place}
*/
@Component
public class ActivateAssignableRolePlace extends AbstractConditionableCommand {
@Autowired
private AssignableRolePlaceService service;
@Autowired
private ServerManagementService serverManagementService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
String name = (String) parameters.get(0);
AServer server = serverManagementService.loadServer(commandContext.getGuild());
return service.activateAssignableRolePlace(server, name)
.thenApply(unused -> CommandResult.fromSuccess());
}
@Override
public CommandConfiguration getConfiguration() {
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)
.parameters(parameters)
.help(helpInfo)
.build();
}
@Override
public FeatureDefinition getFeature() {
return AssignableRoleFeatureDefinition.ASSIGNABLE_ROLES;
}
}

View File

@@ -1,84 +0,0 @@
package dev.sheldan.abstracto.assignableroles.command;
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRoleConditionType;
import dev.sheldan.abstracto.assignableroles.service.AssignableRoleConditionService;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import net.dv8tion.jda.api.entities.Role;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
@Component
public class AddAssignableRoleCondition extends AbstractConditionableCommand {
@Autowired
private AssignableRoleConditionService assignableRoleConditionService;
@Override
public CommandResult execute(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
String name = (String) parameters.get(0);
Role role = (Role) parameters.get(1);
AssignableRoleConditionType configKey = (AssignableRoleConditionType) parameters.get(2);
String parameterValue = (String) parameters.get(3);
assignableRoleConditionService.createAssignableRoleCondition(name, role, configKey, parameterValue);
return CommandResult.fromSuccess();
}
@Override
public CommandConfiguration getConfiguration() {
Parameter placeName = Parameter
.builder()
.name("name")
.type(String.class)
.templated(true)
.build();
Parameter role = Parameter
.builder()
.name("role")
.type(Role.class)
.templated(true)
.build();
Parameter 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();
return CommandConfiguration.builder()
.name("addAssignableRoleCondition")
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
.templated(true)
.messageCommandOnly(true)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)
.help(helpInfo)
.build();
}
@Override
public FeatureDefinition getFeature() {
return AssignableRoleFeatureDefinition.ASSIGNABLE_ROLES;
}
}

View File

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

View File

@@ -1,20 +0,0 @@
package dev.sheldan.abstracto.assignableroles.command;
import dev.sheldan.abstracto.core.command.config.ModuleInfo;
import dev.sheldan.abstracto.core.command.config.ModuleDefinition;
import org.springframework.stereotype.Component;
@Component
public class AssignableRoleModuleDefinition implements ModuleDefinition {
public static final String ASSIGNABLE_ROLES = "assignableRole";
@Override
public ModuleInfo getInfo() {
return ModuleInfo.builder().name(ASSIGNABLE_ROLES).templated(true).build();
}
@Override
public String getParentModule() {
return "default";
}
}

View File

@@ -1,88 +0,0 @@
package dev.sheldan.abstracto.assignableroles.command;
import dev.sheldan.abstracto.assignableroles.config.AssignableRolePlaceParameterKey;
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
/**
* Command used to change one attribute of an {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace place}
*/
@Component
@Slf4j
public class ChangeAssignableRolePlaceConfig extends AbstractConditionableCommand {
@Autowired
private AssignableRolePlaceService service;
@Autowired
private ServerManagementService serverManagementService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
String name = (String) parameters.get(0);
AssignableRolePlaceParameterKey configKey = (AssignableRolePlaceParameterKey) parameters.get(1);
String parameterValue = (String) parameters.get(2);
AServer server = serverManagementService.loadServer(commandContext.getGuild());
return service.changeConfiguration(server, name, configKey, parameterValue)
.thenApply(aVoid -> CommandResult.fromSuccess());
}
@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();
List<Parameter> parameters = Arrays.asList(assignableRolePlaceName, parameterKey, parameterValue);
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
return CommandConfiguration.builder()
.name("changeAssignableRolePlaceConfig")
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
.templated(true)
.messageCommandOnly(true)
.async(true)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)
.help(helpInfo)
.build();
}
@Override
public FeatureDefinition getFeature() {
return AssignableRoleFeatureDefinition.ASSIGNABLE_ROLES;
}
}

View File

@@ -1,108 +0,0 @@
package dev.sheldan.abstracto.assignableroles.command;
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlaceType;
import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.config.ParameterValidator;
import dev.sheldan.abstracto.core.command.config.validator.MaxStringLengthValidator;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.service.management.ChannelManagementService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
@Component
public class CreateAssignableRolePost extends AbstractConditionableCommand {
@Autowired
private AssignableRolePlaceService service;
@Autowired
private ChannelManagementService channelManagementService;
@Override
public CommandResult execute(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
String name = (String) parameters.get(0);
TextChannel channel = (TextChannel) parameters.get(1);
String text = (String) parameters.get(2);
AssignableRolePlaceType type = AssignableRolePlaceType.DEFAULT;
if(parameters.size() > 3) {
type = (AssignableRolePlaceType) parameters.get(3);
}
if(!channel.getGuild().equals(commandContext.getGuild())) {
throw new EntityGuildMismatchException();
}
AChannel chosenChannel = channelManagementService.loadChannel(channel.getIdLong());
service.createAssignableRolePlace(name, chosenChannel, text, type);
return CommandResult.fromSuccess();
}
@Override
public CommandConfiguration getConfiguration() {
List<ParameterValidator> rolePlaceNameValidator = Arrays.asList(MaxStringLengthValidator.max(AssignableRolePlace.ASSIGNABLE_PLACE_NAME_LIMIT));
Parameter rolePostName = Parameter
.builder()
.name("name")
.validators(rolePlaceNameValidator)
.type(String.class)
.templated(true)
.build();
Parameter 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();
List<String> aliases = Arrays.asList("crRPl", "crAssRoPl");
List<Parameter> parameters = Arrays.asList(rolePostName, channel, text, type);
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)
.build();
}
@Override
public FeatureDefinition getFeature() {
return AssignableRoleFeatureDefinition.ASSIGNABLE_ROLES;
}
}

View File

@@ -1,69 +0,0 @@
package dev.sheldan.abstracto.assignableroles.command;
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
/**
* Command used to deactive an {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace place}
*/
@Component
public class DeactivateAssignableRolePlace extends AbstractConditionableCommand {
@Autowired
private AssignableRolePlaceService service;
@Autowired
private ServerManagementService serverManagementService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
String name = (String) parameters.get(0);
AServer server = serverManagementService.loadServer(commandContext.getGuild());
return service.deactivateAssignableRolePlace(server, name)
.thenApply(unused -> CommandResult.fromSuccess());
}
@Override
public CommandConfiguration getConfiguration() {
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()
.name("deactivateAssignableRolePlace")
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
.templated(true)
.async(true)
.messageCommandOnly(true)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)
.help(helpInfo)
.build();
}
@Override
public FeatureDefinition getFeature() {
return AssignableRoleFeatureDefinition.ASSIGNABLE_ROLES;
}
}

View File

@@ -1,70 +0,0 @@
package dev.sheldan.abstracto.assignableroles.command;
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
/**
* Command used to delete an {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace place}
*/
@Component
public class DeleteAssignableRolePlace extends AbstractConditionableCommand {
@Autowired
private AssignableRolePlaceService service;
@Autowired
private ServerManagementService serverManagementService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
String name = (String) parameters.get(0);
AServer server = serverManagementService.loadServer(commandContext.getGuild());
return service.deleteAssignableRolePlace(server, name)
.thenApply(aVoid -> CommandResult.fromSuccess());
}
@Override
public CommandConfiguration getConfiguration() {
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()
.name("deleteAssignableRolePlace")
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
.templated(true)
.causesReaction(true)
.async(true)
.messageCommandOnly(true)
.requiresConfirmation(true)
.supportsEmbedException(true)
.parameters(parameters)
.help(helpInfo)
.build();
}
@Override
public FeatureDefinition getFeature() {
return AssignableRoleFeatureDefinition.ASSIGNABLE_ROLES;
}
}

View File

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

View File

@@ -1,82 +0,0 @@
package dev.sheldan.abstracto.assignableroles.command;
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.exception.EntityGuildMismatchException;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
/**
* Command used to move an {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace place}
* to another {@link dev.sheldan.abstracto.core.models.database.AChannel channel}
*/
@Component
public class MoveAssignableRolePlace extends AbstractConditionableCommand {
@Autowired
private AssignableRolePlaceService placeManagementService;
@Autowired
private ServerManagementService serverManagementService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
String name = (String) parameters.get(0);
TextChannel newChannel = (TextChannel) parameters.get(1);
if(!newChannel.getGuild().equals(commandContext.getGuild())) {
throw new EntityGuildMismatchException();
}
AServer server = serverManagementService.loadServer(commandContext.getGuild());
return placeManagementService.moveAssignableRolePlace(server, name, newChannel)
.thenApply(unused -> CommandResult.fromSuccess());
}
@Override
public CommandConfiguration getConfiguration() {
Parameter rolePostName = Parameter
.builder()
.name("name")
.type(String.class)
.templated(true)
.build();
Parameter channel = Parameter
.builder()
.name("channel")
.type(TextChannel.class)
.templated(true)
.build();
List<Parameter> parameters = Arrays.asList(rolePostName, channel);
HelpInfo helpInfo = HelpInfo.builder().templated(true).build();
return CommandConfiguration.builder()
.name("moveAssignableRolePlace")
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
.templated(true)
.causesReaction(true)
.messageCommandOnly(true)
.async(true)
.supportsEmbedException(true)
.parameters(parameters)
.help(helpInfo)
.build();
}
@Override
public FeatureDefinition getFeature() {
return AssignableRoleFeatureDefinition.ASSIGNABLE_ROLES;
}
}

View File

@@ -1,74 +0,0 @@
package dev.sheldan.abstracto.assignableroles.command;
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRoleConditionType;
import dev.sheldan.abstracto.assignableroles.service.AssignableRoleConditionService;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import net.dv8tion.jda.api.entities.Role;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
@Component
public class RemoveAssignableRoleCondition extends AbstractConditionableCommand {
@Autowired
private AssignableRoleConditionService assignableRoleConditionService;
@Override
public CommandResult execute(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
String name = (String) parameters.get(0);
Role role = (Role) parameters.get(1);
AssignableRoleConditionType configKey = (AssignableRoleConditionType) parameters.get(2);
assignableRoleConditionService.deleteAssignableRoleCondition(name, role, configKey);
return CommandResult.fromSuccess();
}
@Override
public CommandConfiguration getConfiguration() {
Parameter placeName = Parameter
.builder()
.name("name")
.type(String.class)
.templated(true)
.build();
Parameter role = Parameter
.builder()
.name("role")
.type(Role.class)
.templated(true)
.build();
Parameter 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)
.help(helpInfo)
.build();
}
@Override
public FeatureDefinition getFeature() {
return AssignableRoleFeatureDefinition.ASSIGNABLE_ROLES;
}
}

View File

@@ -1,81 +0,0 @@
package dev.sheldan.abstracto.assignableroles.command;
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.models.database.ARole;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
/**
* Command used to remove a {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRole role}
* from an {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace place}
*/
@Component
public class RemoveRoleFromAssignableRolePlace extends AbstractConditionableCommand {
@Autowired
private AssignableRolePlaceService service;
@Autowired
private ServerManagementService serverManagementService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
String name = (String) parameters.get(0);
ARole role = (ARole) parameters.get(1);
AServer server = serverManagementService.loadServer(commandContext.getGuild());
return service.removeRoleFromAssignableRolePlace(server, name, role)
.thenApply(aVoid -> CommandResult.fromSuccess());
}
@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();
List<Parameter> parameters = Arrays.asList(rolePostName, role);
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)
.build();
}
@Override
public FeatureDefinition getFeature() {
return AssignableRoleFeatureDefinition.ASSIGNABLE_ROLES;
}
}

View File

@@ -1,79 +0,0 @@
package dev.sheldan.abstracto.assignableroles.command;
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
/**
* Command used to render the {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace place}
* and create the {@link net.dv8tion.jda.api.entities.Message messages} used to add {@link net.dv8tion.jda.api.entities.MessageReaction reactions} to
*/
@Component
@Slf4j
public class SetupAssignableRolePlace extends AbstractConditionableCommand {
@Autowired
private AssignableRolePlaceService service;
@Autowired
private ChannelService channelService;
@Autowired
private ServerManagementService serverManagementService;
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
String name = (String) parameters.get(0);
AServer server = serverManagementService.loadServer(commandContext.getGuild());
return service.setupAssignableRolePlace(server, name)
.thenApply(aVoid -> CommandResult.fromSuccess());
}
@Override
public CommandConfiguration getConfiguration() {
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()
.name("setupAssignableRolePlace")
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
.templated(true)
.async(true)
.messageCommandOnly(true)
.supportsEmbedException(true)
.causesReaction(true)
.parameters(parameters)
.help(helpInfo)
.build();
}
@Override
public FeatureDefinition getFeature() {
return AssignableRoleFeatureDefinition.ASSIGNABLE_ROLES;
}
}

View File

@@ -1,79 +0,0 @@
package dev.sheldan.abstracto.assignableroles.command;
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
import dev.sheldan.abstracto.assignableroles.model.template.AssignableRolePlaceConfig;
import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.config.Parameter;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
/**
* Command used to show the configuration of an {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace place}
*/
@Component
public class ShowAssignableRolePlaceConfig extends AbstractConditionableCommand {
@Autowired
private AssignableRolePlaceService service;
@Autowired
private ServerManagementService serverManagementService;
@Autowired
private ChannelService channelService;
public static final String ASSIGNABLE_ROLES_CONFIG_POST_TEMPLATE_KEY = "assignable_roles_config_post";
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
List<Object> parameters = commandContext.getParameters().getParameters();
String name = (String) parameters.get(0);
AssignableRolePlaceConfig config = service.getAssignableRolePlaceConfig(commandContext.getGuild(), name);
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInMessageChannel(ASSIGNABLE_ROLES_CONFIG_POST_TEMPLATE_KEY, config, commandContext.getChannel()))
.thenApply(unused -> CommandResult.fromSuccess());
}
@Override
public CommandConfiguration getConfiguration() {
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()
.name("showAssignableRolePlaceConfig")
.module(AssignableRoleModuleDefinition.ASSIGNABLE_ROLES)
.templated(true)
.async(true)
.causesReaction(false)
.messageCommandOnly(true)
.supportsEmbedException(true)
.parameters(parameters)
.help(helpInfo)
.build();
}
@Override
public FeatureDefinition getFeature() {
return AssignableRoleFeatureDefinition.ASSIGNABLE_ROLES;
}
}

View File

@@ -1,67 +0,0 @@
package dev.sheldan.abstracto.assignableroles.command;
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
import dev.sheldan.abstracto.assignableroles.model.template.AssignablePlaceOverview;
import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceService;
import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand;
import dev.sheldan.abstracto.core.command.config.CommandConfiguration;
import dev.sheldan.abstracto.core.command.config.HelpInfo;
import dev.sheldan.abstracto.core.command.execution.CommandContext;
import dev.sheldan.abstracto.core.command.execution.CommandResult;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.service.ChannelService;
import dev.sheldan.abstracto.core.service.management.ServerManagementService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.concurrent.CompletableFuture;
/**
* Command used to show all {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace places}
* within the current {@link AServer server}
*/
@Component
public class ShowAssignableRolePlaces extends AbstractConditionableCommand {
@Autowired
private AssignableRolePlaceService service;
@Autowired
private ServerManagementService serverManagementService;
@Autowired
private ChannelService channelService;
public static final String ASSIGNABLE_ROLE_PLACES_OVERVIEW_TEMPLATE_KEY = "assignable_role_places_overview";
@Override
public CompletableFuture<CommandResult> executeAsync(CommandContext commandContext) {
AssignablePlaceOverview model = service.getAssignableRolePlaceOverview(commandContext.getGuild());
return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInMessageChannel(ASSIGNABLE_ROLE_PLACES_OVERVIEW_TEMPLATE_KEY, model, commandContext.getChannel()))
.thenApply(unused -> CommandResult.fromSuccess());
}
@Override
public CommandConfiguration getConfiguration() {
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)
.build();
}
@Override
public FeatureDefinition getFeature() {
return AssignableRoleFeatureDefinition.ASSIGNABLE_ROLES;
}
}

View File

@@ -1,91 +0,0 @@
package dev.sheldan.abstracto.assignableroles.condition;
import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRoleConditionType;
import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRoleMinLevelModel;
import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRolePlaceConditionModel;
import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRoleMinLevelResult;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRoleCondition;
import dev.sheldan.abstracto.assignableroles.model.template.condition.AssignableRoleConditionDisplay;
import dev.sheldan.abstracto.assignableroles.model.template.condition.AssignableRoleMinLevelDisplay;
import dev.sheldan.abstracto.core.models.ConditionContextInstance;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.models.template.display.RoleDisplay;
import dev.sheldan.abstracto.core.service.ConditionService;
import dev.sheldan.abstracto.core.service.SystemCondition;
import net.dv8tion.jda.api.entities.Role;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Component
public class AssignableRoleMinimumLevelConditionImpl implements AssignableRoleConditionEvaluator {
private final String conditionName = "HAS_LEVEL";
private final String userIdParameter = "userId";
private final String levelParameter = "level";
private final String serverParameter = "serverId";
@Autowired
private ConditionService conditionService;
@Override
public boolean fulfillsCondition(AssignableRoleCondition conditionDefinition, AUserInAServer aUserInAServer) {
Integer level = parseLevel(conditionDefinition);
Map<String, Object> parameters = new HashMap<>();
parameters.put(userIdParameter, aUserInAServer.getUserInServerId());
parameters.put(levelParameter, level);
parameters.put(serverParameter, aUserInAServer.getServerReference().getId());
ConditionContextInstance contextInstance = ConditionContextInstance
.builder()
.conditionName(conditionName)
.parameters(parameters)
.build();
SystemCondition.Result result = conditionService.checkConditions(contextInstance);
return SystemCondition.Result.consideredSuccessful(result);
}
@Override
public boolean usableValue(String value) {
try {
parseLevelValue(value);
return true;
} catch (Exception exception) {
return false;
}
}
private Integer parseLevel(AssignableRoleCondition conditionDefinition) {
return parseLevelValue(conditionDefinition.getConditionValue());
}
private int parseLevelValue(String value) {
return Integer.parseInt(value);
}
@Override
public AssignableRolePlaceConditionModel createNotificationModel(AssignableRoleCondition conditionDefinition, Role role) {
Integer level = parseLevel(conditionDefinition);
AssignableRoleMinLevelModel model = AssignableRoleMinLevelModel
.builder()
.minLevel(level)
.roleDisplay(RoleDisplay.fromRole(role))
.build();
return AssignableRoleMinLevelResult
.builder()
.model(model)
.build();
}
@Override
public AssignableRoleConditionDisplay getConditionDisplay(AssignableRoleCondition conditionDefinition) {
return new AssignableRoleMinLevelDisplay(Integer.parseInt(conditionDefinition.getConditionValue()));
}
@Override
public boolean handlesCondition(AssignableRoleConditionType type) {
return AssignableRoleConditionType.MIN_LEVEL.equals(type);
}
}

View File

@@ -1,10 +0,0 @@
package dev.sheldan.abstracto.assignableroles.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
@Configuration
@PropertySource("classpath:assignableRoles-config.properties")
public class AssignableRolesConfig {
}

View File

@@ -1,234 +0,0 @@
package dev.sheldan.abstracto.assignableroles.listener;
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
import dev.sheldan.abstracto.assignableroles.exception.AssignableRoleNotFoundException;
import dev.sheldan.abstracto.assignableroles.exception.BoosterAssignableRolePlaceMemberNotBoostingException;
import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRoleConditionResult;
import dev.sheldan.abstracto.assignableroles.model.AssignableRolePlacePayload;
import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRolePlaceConditionModel;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRole;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlaceType;
import dev.sheldan.abstracto.assignableroles.model.database.AssignedRoleUser;
import dev.sheldan.abstracto.assignableroles.model.template.AssignableRoleSuccessNotificationModel;
import dev.sheldan.abstracto.assignableroles.service.AssignableRoleConditionServiceBean;
import dev.sheldan.abstracto.assignableroles.service.AssignableRolePlaceServiceBean;
import dev.sheldan.abstracto.assignableroles.service.AssignableRoleService;
import dev.sheldan.abstracto.assignableroles.service.management.AssignableRolePlaceManagementService;
import dev.sheldan.abstracto.assignableroles.service.management.AssignedRoleUserManagementServiceBean;
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.ButtonClickedListenerResult;
import dev.sheldan.abstracto.core.interaction.button.listener.ButtonClickedListener;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.interaction.button.listener.ButtonClickedListenerModel;
import dev.sheldan.abstracto.core.service.RoleService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import dev.sheldan.abstracto.core.utils.CompletableFutureList;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Role;
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
import net.dv8tion.jda.api.interactions.components.buttons.ButtonInteraction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
@Component
@Slf4j
public class AssignableRoleButtonClickedListener implements ButtonClickedListener {
@Autowired
private AssignableRolePlaceManagementService assignableRolePlaceManagementService;
@Autowired
private RoleService roleService;
@Autowired
private AssignableRoleButtonClickedListener self;
@Autowired
private InteractionService interactionService;
@Autowired
private AssignableRoleService assignableRoleService;
@Autowired
private AssignedRoleUserManagementServiceBean assignedRoleUserManagementServiceBean;
@Autowired
private UserInServerManagementService userInServerManagementService;
@Autowired
private AssignableRoleConditionServiceBean assignableRoleConditionServiceBean;
@Override
public ButtonClickedListenerResult execute(ButtonClickedListenerModel model) {
ButtonInteractionEvent event = model.getEvent();
Member member = event.getMember();
if(event.getGuild() != null && member != null) {
AssignableRolePlacePayload payload = (AssignableRolePlacePayload) model.getDeserializedPayload();
AssignableRolePlace place = assignableRolePlaceManagementService.findByPlaceId(payload.getPlaceId());
Guild guild = event.getGuild();
List<Role> removedRoles = new ArrayList<>();
Role roleById = guild.getRoleById(payload.getRoleId());
Optional<AssignableRole> assignableRoleOptional = place
.getAssignableRoles()
.stream()
.filter(assignableRole -> assignableRole.getRole().getId().equals(payload.getRoleId()))
.findFirst();
if(!assignableRoleOptional.isPresent()) {
throw new AssignableRoleNotFoundException(payload.getRoleId());
}
if(roleById != null) {
boolean memberHasRole = member
.getRoles()
.stream()
.anyMatch(memberRole -> memberRole.getIdLong() == payload.getRoleId());
if(!memberHasRole) {
if(place.getType().equals(AssignableRolePlaceType.BOOSTER) && member.getTimeBoosted() == null) {
assignableRoleService.assignableRoleConditionFailure();
throw new BoosterAssignableRolePlaceMemberNotBoostingException();
}
AssignableRole assignableRole = assignableRoleOptional.get();
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(member);
if(!assignableRole.getConditions().isEmpty()) {
log.debug("Evaluating {} conditions for assignable role {}.", assignableRole.getConditions().size(), assignableRole.getId());
AssignableRoleConditionResult conditionResult =
assignableRoleConditionServiceBean.evaluateConditions(assignableRole.getConditions(), aUserInAServer, roleById);
if(!conditionResult.getFulfilled()) {
log.info("One condition failed to be fulfilled - notifying user.");
self.notifyUserAboutConditionFail(model, event.getInteraction(), conditionResult.getModel());
assignableRoleService.assignableRoleConditionFailure();
return ButtonClickedListenerResult.ACKNOWLEDGED;
}
}
CompletableFuture<Void> removalFuture;
if(place.getUniqueRoles()) {
Optional<AssignedRoleUser> assignedRoleUserOptional = assignedRoleUserManagementServiceBean.findByUserInServerOptional(aUserInAServer);
if(assignedRoleUserOptional.isPresent()) {
AssignedRoleUser roleUser = assignedRoleUserOptional.get();
List<Role> rolesToRemove = roleUser
.getRoles()
.stream()
.filter(roleOfUser -> roleOfUser.getAssignablePlace().equals(place))
.map(roleOfUser -> guild.getRoleById(roleOfUser.getRole().getId()))
.filter(Objects::nonNull)
.collect(Collectors.toList());
log.info("Removing {} because of unique role configuration in place {}.", rolesToRemove.size(), place.getId());
removedRoles.addAll(rolesToRemove);
List<CompletableFuture<Void>> removalFutures = new ArrayList<>();
rolesToRemove.forEach(roleToRemove -> removalFutures.add(roleService.removeRoleFromUserAsync(member, roleToRemove)));
removalFuture = new CompletableFutureList<>(removalFutures).getMainFuture();
} else {
removalFuture = CompletableFuture.completedFuture(null);
}
} else {
removalFuture = CompletableFuture.completedFuture(null);
}
CompletableFuture<Void> roleAdditionFuture = assignableRoleService.assignAssignableRoleToUser(roleById, member);
CompletableFuture.allOf(removalFuture, roleAdditionFuture).whenComplete((unused, throwable) -> {
if(throwable != null) {
log.error("Failed to either add or remove roles for assignable role place {} in server {}.", payload.getPlaceId(), guild.getIdLong());
}
if(!roleAdditionFuture.isCompletedExceptionally()) {
log.info("Added role {} to member {} in server {} for assignable role interaction {} on component {}.",
roleById.getId(), member.getId(), guild.getIdLong(), event.getInteraction().getId(), event.getComponentId());
self.notifyUser(model, true, roleById, event.getInteraction(), removedRoles).thenAccept(unused1 -> {
log.info("Persisting adding assignable role update for user {} in server {} of role {}.", member.getIdLong(), guild.getIdLong(), roleById.getId());
self.persistAssignableUser(member, payload, false);
});
}
}).exceptionally(throwable -> {
log.error("Failed to perform role change in assignable role place.", throwable);
return null;
});
} else {
assignableRoleService.removeAssignableRoleFromUser(roleById, member)
.thenAccept(unused -> {
self.notifyUser(model, false, roleById, event.getInteraction(), new ArrayList<>());
log.info("Removed role {} from member {} in server {} for assignable role interaction {} on component {}.",
roleById.getId(), member.getId(), guild.getIdLong(), event.getInteraction().getId(), event.getComponentId());
}).thenAccept(unused -> {
log.info("Persisting remove assignable role update for user {} in server {} of role {}.", member.getIdLong(), guild.getIdLong(), roleById.getId());
self.persistAssignableUser(member, payload, true);
});
}
} else {
log.warn("Role {} is not available to be assigned in assignable role place {} in server {}. Component {} failed.",
payload.getRoleId(), payload.getPlaceId(), guild.getIdLong(), event.getComponentId());
throw new AssignableRoleNotFoundException(payload.getRoleId());
}
}
return ButtonClickedListenerResult.ACKNOWLEDGED;
}
@Transactional
public void persistAssignableUser(Member member, AssignableRolePlacePayload payload, boolean removeRole){
AssignableRolePlace place = assignableRolePlaceManagementService.findByPlaceId(payload.getPlaceId());
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(member);
if(place.getUniqueRoles() && !removeRole) {
assignableRoleService.clearAllRolesOfUserInPlace(place, aUserInAServer);
}
Optional<AssignableRole> assignableRoleOptional = place
.getAssignableRoles()
.stream()
.filter(assignableRole -> assignableRole.getRole().getId().equals(payload.getRoleId()))
.findFirst();
if(assignableRoleOptional.isPresent()) {
if(removeRole) {
assignableRoleService.removeRoleFromUser(assignableRoleOptional.get(), aUserInAServer);
} else {
assignableRoleService.addRoleToUser(assignableRoleOptional.get(), aUserInAServer);
}
}
}
@Transactional
public CompletableFuture<Void> notifyUser(ButtonClickedListenerModel model, boolean roleAdded, Role role, ButtonInteraction buttonInteraction, List<Role> removedRoles) {
log.info("Notifying user {} in server {} in channel {} about role change with role {}.",
buttonInteraction.getUser().getIdLong(), buttonInteraction.getGuild().getIdLong(), buttonInteraction.getChannel().getIdLong(), role.getId());
AssignableRoleSuccessNotificationModel notificationModel = AssignableRoleSuccessNotificationModel
.builder()
.added(roleAdded)
.removedRoles(removedRoles)
.role(role)
.build();
return FutureUtils.toSingleFutureGeneric(
interactionService.sendMessageToInteraction("assignable_role_success_notification", notificationModel, buttonInteraction.getHook())) ;
}
@Transactional
public CompletableFuture<Void> notifyUserAboutConditionFail(ButtonClickedListenerModel model, ButtonInteraction buttonInteraction,
AssignableRolePlaceConditionModel conditionModel) {
log.info("Notifying user {} in server {} in channel {} about failed condition.", buttonInteraction.getUser().getIdLong(),
buttonInteraction.getGuild().getIdLong(), buttonInteraction.getChannel().getIdLong());
return FutureUtils.toSingleFutureGeneric(
interactionService.sendMessageToInteraction("assignable_role_condition_notification", conditionModel, buttonInteraction.getHook())) ;
}
@Override
public Boolean handlesEvent(ButtonClickedListenerModel model) {
return AssignableRolePlaceServiceBean.ASSIGNABLE_ROLE_COMPONENT_ORIGIN.equals(model.getOrigin()) && model.getEvent().isFromGuild();
}
@Override
public FeatureDefinition getFeature() {
return AssignableRoleFeatureDefinition.ASSIGNABLE_ROLES;
}
@Override
public Integer getPriority() {
return ListenerPriority.MEDIUM;
}
}

View File

@@ -1,112 +0,0 @@
package dev.sheldan.abstracto.assignableroles.listener;
import dev.sheldan.abstracto.assignableroles.config.AssignableRoleFeatureDefinition;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRole;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlaceType;
import dev.sheldan.abstracto.assignableroles.model.database.AssignedRoleUser;
import dev.sheldan.abstracto.assignableroles.service.AssignableRoleService;
import dev.sheldan.abstracto.assignableroles.service.management.AssignableRoleManagementService;
import dev.sheldan.abstracto.assignableroles.service.management.AssignedRoleUserManagementService;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import dev.sheldan.abstracto.core.listener.DefaultListenerResult;
import dev.sheldan.abstracto.core.listener.async.jda.AsyncMemberBoostTimeUpdateListener;
import dev.sheldan.abstracto.core.models.ServerUser;
import dev.sheldan.abstracto.core.models.listener.BoostTimeUpdatedModel;
import dev.sheldan.abstracto.core.service.RoleService;
import dev.sheldan.abstracto.core.utils.FutureUtils;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Role;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
@Component
@Slf4j
public class AssignableRolePlaceBoostTimeUpdateListener implements AsyncMemberBoostTimeUpdateListener {
@Autowired
private AssignedRoleUserManagementService assignedRoleUserManagementService;
@Autowired
private AssignableRoleManagementService assignableRoleManagementService;
@Autowired
private RoleService roleService;
@Autowired
private AssignableRoleService assignableRoleService;
@Autowired
private AssignableRolePlaceBoostTimeUpdateListener self;
@Override
public DefaultListenerResult execute(BoostTimeUpdatedModel model) {
Member member = model.getMember();
if(member.getTimeBoosted() == null) {
removeAssignedBoosterRoles(member);
return DefaultListenerResult.PROCESSED;
}
return DefaultListenerResult.IGNORED;
}
private void removeAssignedBoosterRoles(Member member) {
log.info("Member {} in server {} stopped boosting.", member.getIdLong(), member.getGuild().getIdLong());
ServerUser serverUser = ServerUser.fromMember(member);
Optional<AssignedRoleUser> assignedRoleUserOptional = assignedRoleUserManagementService.findByUserInServerOptional(serverUser);
if(assignedRoleUserOptional.isPresent()) {
AssignedRoleUser assignedRoleUser = assignedRoleUserOptional.get();
List<AssignableRole> boosterRoles = assignableRoleManagementService.getAssignableRolesFromAssignableUserWithPlaceType(assignedRoleUser, AssignableRolePlaceType.BOOSTER);
if(!boosterRoles.isEmpty()) {
log.info("Removing {} assignable role mappings.", boosterRoles.size());
Guild guild = member.getGuild();
List<Role> actualRolesToDelete = boosterRoles
.stream()
.map(assignableRole -> guild.getRoleById(assignableRole.getRole().getId()))
.filter(Objects::nonNull)
.collect(Collectors.toList());
log.debug("Which translated to {} roles in reality.", actualRolesToDelete.size());
List<CompletableFuture<Void>> list = new ArrayList<>();
actualRolesToDelete.forEach(role -> list.add(roleService.removeRoleFromUserAsync(member, role)));
FutureUtils.toSingleFutureGeneric(list)
.thenAccept(unused -> self.clearPersistedBoosterAssignableRoles(member))
.exceptionally(throwable -> {
log.warn("One or more roles might have failed to remove. ", throwable);
self.clearPersistedBoosterAssignableRoles(member);
return null;
});
} else {
log.info("Member {} in server {} did not have boost roles - doing nothing.", member.getIdLong(), member.getGuild().getIdLong());
}
} else {
log.info("Member (ID {}) in server (ID: {}), who was not tracked via assignable roles, stopped boosting - doing nothing.",
member.getIdLong(), member.getGuild().getIdLong());
}
}
@Transactional
public void clearPersistedBoosterAssignableRoles(Member member) {
ServerUser serverUser = ServerUser.fromMember(member);
Optional<AssignedRoleUser> assignedRoleUserOptional = assignedRoleUserManagementService.findByUserInServerOptional(serverUser);
if(assignedRoleUserOptional.isPresent()) {
AssignedRoleUser assignedRoleUser = assignedRoleUserOptional.get();
List<AssignableRole> boosterRoles = assignableRoleManagementService.getAssignableRolesFromAssignableUserWithPlaceType(assignedRoleUser, AssignableRolePlaceType.BOOSTER);
assignableRoleService.removeAssignableRolesFromAssignableRoleUser(boosterRoles, assignedRoleUser);
} else {
log.warn("No assigned role user found for member {} in server {}.", member.getIdLong(), member.getGuild().getIdLong());
}
}
@Override
public FeatureDefinition getFeature() {
return AssignableRoleFeatureDefinition.ASSIGNABLE_ROLES;
}
}

View File

@@ -1,14 +0,0 @@
package dev.sheldan.abstracto.assignableroles.model;
import dev.sheldan.abstracto.core.interaction.button.ButtonPayload;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Builder
public class AssignableRolePlacePayload implements ButtonPayload {
private Long placeId;
private Long roleId;
}

View File

@@ -1,14 +0,0 @@
package dev.sheldan.abstracto.assignableroles.repository;
import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRoleConditionType;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRole;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRoleCondition;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository
public interface AssignableRoleConditionRepository extends JpaRepository<AssignableRoleCondition, Long> {
Optional<AssignableRoleCondition> findByAssignableRoleAndType(AssignableRole assignableRole, AssignableRoleConditionType type);
}

View File

@@ -1,41 +0,0 @@
package dev.sheldan.abstracto.assignableroles.repository;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace;
import dev.sheldan.abstracto.core.models.database.AServer;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
/**
* Repository to manage the access to the table managed by {@link AssignableRolePlace place}
*/
@Repository
public interface AssignableRolePlaceRepository extends JpaRepository<AssignableRolePlace, Long> {
/**
* Whether or not an {@link AssignableRolePlace place} exists in a {@link AServer server} with the given key
* @param server The {@link AServer server} to search in
* @param key The key to search for
* @return Whether or not a {@link AssignableRolePlace place} exists in the {@link AServer server} with the key
*/
boolean existsByServerAndKey(AServer server, String key);
/**
* Finds an {@link AssignableRolePlace place} in a {@link AServer server} with the given key,
* returns an empty {@link Optional optional} otherwise
* @param server The {@link AServer server} to search in
* @param key The key to search for
* @return An {@link Optional optional} containing the {@link AssignableRolePlace place} if it exists, empty otherwise.
*/
Optional<AssignableRolePlace> findByServerAndKey(AServer server, String key);
/**
* Finds all {@link AssignableRolePlace places} in the given {@link AServer server}
* @param server The {@link AServer server} to retrieve {@link AssignableRolePlace places} for
* @return A list of {@link AssignableRolePlace places} which were found in the given {@link AServer server}
*/
List<AssignableRolePlace> findByServer(AServer server);
}

View File

@@ -1,17 +0,0 @@
package dev.sheldan.abstracto.assignableroles.repository;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRole;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlaceType;
import dev.sheldan.abstracto.assignableroles.model.database.AssignedRoleUser;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* Repository to manage the access to the table managed by {@link AssignableRole assignableRole}
*/
@Repository
public interface AssignableRoleRepository extends JpaRepository<AssignableRole, Long> {
List<AssignableRole> findByAssignedUsersContainingAndAssignablePlace_Type(AssignedRoleUser roleUser, AssignableRolePlaceType type);
}

View File

@@ -1,12 +0,0 @@
package dev.sheldan.abstracto.assignableroles.repository;
import dev.sheldan.abstracto.assignableroles.model.database.AssignedRoleUser;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
/**
* Repository to manage the access to the table managed by {@link AssignedRoleUser assignedRoleUser}
*/
@Repository
public interface AssignedRoleUserRepository extends JpaRepository<AssignedRoleUser, Long> {
}

View File

@@ -1,132 +0,0 @@
package dev.sheldan.abstracto.assignableroles.service;
import dev.sheldan.abstracto.assignableroles.condition.AssignableRoleConditionEvaluator;
import dev.sheldan.abstracto.assignableroles.exception.AssignableRoleConditionAlreadyExistsException;
import dev.sheldan.abstracto.assignableroles.exception.AssignableRoleConditionValueNotUsableException;
import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRoleConditionResult;
import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRoleConditionType;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRole;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRoleCondition;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace;
import dev.sheldan.abstracto.assignableroles.exception.AssignableRoleConditionDoesNotExistException;
import dev.sheldan.abstracto.assignableroles.model.template.condition.AssignableRoleConditionDisplay;
import dev.sheldan.abstracto.assignableroles.service.management.AssignableRoleConditionManagementService;
import dev.sheldan.abstracto.assignableroles.service.management.AssignableRolePlaceManagementService;
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 lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Role;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
@Component
@Slf4j
public class AssignableRoleConditionServiceBean implements AssignableRoleConditionService {
@Autowired
private List<AssignableRoleConditionEvaluator> assignableRoleConditionEvaluators;
@Autowired
private UserInServerManagementService userInServerManagementService;
@Autowired
private AssignableRolePlaceManagementService assignableRolePlaceManagementService;
@Autowired
private ServerManagementService serverManagementService;
@Autowired
private AssignableRoleService assignableRoleService;
@Autowired
private AssignableRoleConditionManagementService assignableRoleConditionManagementService;
@Override
public AssignableRoleConditionResult evaluateConditions(List<AssignableRoleCondition> conditions, Member member, Role role) {
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(member);
return evaluateConditions(conditions, aUserInAServer, role);
}
@Override
public AssignableRoleConditionResult evaluateConditions(List<AssignableRoleCondition> conditions, AUserInAServer aUserInAServer, Role role) {
log.debug("Evaluating {} conditions for role {}.", conditions.size(), role.getId());
for (AssignableRoleCondition condition : conditions) {
if(assignableRoleConditionEvaluators != null) {
Optional<AssignableRoleConditionEvaluator> evaluatorOptional = findEvaluatorForCondition(condition.getType());
if(evaluatorOptional.isPresent()) {
AssignableRoleConditionEvaluator evaluator = evaluatorOptional.get();
log.debug("Evaluating condition {} with evaluator {}.", condition.getType(), evaluator.getClass());
if(!evaluator.fulfillsCondition(condition, aUserInAServer)) {
log.info("Condition {} failed for role {} in server {}.", condition.getType(), role.getId(), aUserInAServer.getServerReference().getId());
return AssignableRoleConditionResult.fromFail(condition.getType(), evaluator.createNotificationModel(condition, role));
}
}
}
}
return AssignableRoleConditionResult.fromSuccess();
}
private Optional<AssignableRoleConditionEvaluator> findEvaluatorForCondition(AssignableRoleConditionType type) {
return assignableRoleConditionEvaluators
.stream()
.filter(assignableRoleConditionEvaluator -> assignableRoleConditionEvaluator.handlesCondition(type))
.findFirst();
}
@Override
public AssignableRoleCondition createAssignableRoleCondition(String placeName, Role role, AssignableRoleConditionType type, String value) {
AServer server = serverManagementService.loadServer(role.getGuild());
AssignableRolePlace place = assignableRolePlaceManagementService.findByServerAndKey(server, placeName);
AssignableRole assignableRole = assignableRoleService.getAssignableRoleInPlace(place, role);
Optional<AssignableRoleConditionEvaluator> evaluatorOptional = findEvaluatorForCondition(type);
if(!evaluatorOptional.isPresent()) {
throw new AssignableRoleConditionDoesNotExistException();
}
evaluatorOptional.ifPresent(evaluator -> {
boolean valueUsable = evaluator.usableValue(value);
if(!valueUsable) {
throw new AssignableRoleConditionValueNotUsableException();
}
});
if(assignableRoleConditionManagementService.findAssignableRoleCondition(assignableRole, type).isPresent()) {
throw new AssignableRoleConditionAlreadyExistsException();
}
log.info("Creating new condition for role {} in place {} in server {}.", place.getId(), role.getId(), role.getGuild().getIdLong());
return assignableRoleConditionManagementService.createAssignableRoleCondition(assignableRole, type, value);
}
@Override
public void deleteAssignableRoleCondition(String placeName, Role role, AssignableRoleConditionType type) {
AServer server = serverManagementService.loadServer(role.getGuild());
AssignableRolePlace place = assignableRolePlaceManagementService.findByServerAndKey(server, placeName);
AssignableRole assignableRole = assignableRoleService.getAssignableRoleInPlace(place, role);
Optional<AssignableRoleCondition> existingCondition = assignableRoleConditionManagementService.findAssignableRoleCondition(assignableRole, type);
if(!existingCondition.isPresent()) {
throw new AssignableRoleConditionDoesNotExistException();
}
log.info("Deleting assignable role condition on place {} for role {} in server {}.", place.getId(), role.getId(), role.getGuild().getIdLong());
existingCondition.ifPresent(condition -> assignableRoleConditionManagementService.deleteAssignableRoleCondition(condition));
}
@Override
public List<AssignableRoleConditionDisplay> getConditionDisplays(List<AssignableRoleCondition> conditions) {
return conditions.stream().map(condition -> {
Optional<AssignableRoleConditionEvaluator> evaluatorOptional = findEvaluatorForCondition(condition.getType());
if(evaluatorOptional.isPresent()) {
AssignableRoleConditionEvaluator evaluator = evaluatorOptional.get();
return evaluator.getConditionDisplay(condition);
}
return null;
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
}

View File

@@ -1,528 +0,0 @@
package dev.sheldan.abstracto.assignableroles.service;
import dev.sheldan.abstracto.assignableroles.config.AssignableRolePlaceParameterKey;
import dev.sheldan.abstracto.assignableroles.exception.*;
import dev.sheldan.abstracto.assignableroles.model.AssignableRolePlacePayload;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRole;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlaceType;
import dev.sheldan.abstracto.assignableroles.model.template.*;
import dev.sheldan.abstracto.assignableroles.service.management.*;
import dev.sheldan.abstracto.core.command.exception.CommandParameterKeyValueWrongTypeException;
import dev.sheldan.abstracto.core.exception.ChannelNotInGuildException;
import dev.sheldan.abstracto.core.exception.EmoteNotUsableException;
import dev.sheldan.abstracto.core.interaction.ComponentPayloadManagementService;
import dev.sheldan.abstracto.core.interaction.ComponentPayloadService;
import dev.sheldan.abstracto.core.interaction.ComponentService;
import dev.sheldan.abstracto.core.models.FullEmote;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.ARole;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.ComponentPayload;
import dev.sheldan.abstracto.core.models.template.display.ChannelDisplay;
import dev.sheldan.abstracto.core.models.template.display.RoleDisplay;
import dev.sheldan.abstracto.core.service.*;
import dev.sheldan.abstracto.core.service.management.*;
import dev.sheldan.abstracto.core.templating.model.MessageToSend;
import dev.sheldan.abstracto.core.templating.service.TemplateService;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.*;
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel;
import net.dv8tion.jda.api.interactions.components.buttons.ButtonStyle;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
@Component
@Slf4j
public class AssignableRolePlaceServiceBean implements AssignableRolePlaceService {
public static final String ASSIGNABLE_ROLES_POST_TEMPLATE_KEY = "assignable_roles_post";
public static final int MAX_ASSIGNABLE_ROLES_PER_POST = ComponentService.MAX_BUTTONS_PER_ROW * 5;
public static final String ASSIGNABLE_ROLE_COMPONENT_ORIGIN = "assignableRoleButton";
@Autowired
private AssignableRolePlaceManagementService rolePlaceManagementService;
@Autowired
private AssignableRoleManagementService assignableRoleManagementServiceBean;
@Autowired
private MessageService messageService;
@Autowired
private ChannelService channelService;
@Autowired
private GuildService guildService;
@Autowired
private EmoteService emoteService;
@Autowired
private AssignableRolePlaceServiceBean self;
@Autowired
private TemplateService templateService;
@Autowired
private ChannelManagementService channelManagementService;
@Autowired
private ComponentService componentService;
@Autowired
private ComponentPayloadManagementService componentPayloadManagementService;
@Autowired
private ComponentPayloadService componentPayloadService;
@Autowired
private AssignableRolePlaceManagementServiceBean assignableRolePlaceManagementServiceBean;
@Autowired
private AssignableRoleConditionService assignableRoleConditionService;
@Autowired
private AssignedRoleUserManagementServiceBean assignedRoleUserManagementServiceBean;
@Autowired
private ServerManagementService serverManagementService;
@Override
public void createAssignableRolePlace(String name, AChannel channel, String text, AssignableRolePlaceType type) {
if (rolePlaceManagementService.doesPlaceExist(channel.getServer(), name)) {
throw new AssignableRolePlaceAlreadyExistsException(name);
}
rolePlaceManagementService.createPlace(name, channel, text, type);
}
@Override
@Transactional
public CompletableFuture<Void> addRoleToAssignableRolePlace(AServer server, String placeName, Role role, FullEmote fakeEmote, String description) {
AssignableRolePlace assignableRolePlace = rolePlaceManagementService.findByServerAndKey(server, placeName);
if (assignableRolePlace.getAssignableRoles().size() > MAX_ASSIGNABLE_ROLES_PER_POST) {
log.info("Assignable role place {} has already {} roles. Not possible to add more.", assignableRolePlace.getId(), assignableRolePlace.getAssignableRoles().size());
throw new AssignableRolePlaceMaximumRolesException();
}
if (assignableRolePlace.getAssignableRoles().stream().anyMatch(assignableRole -> assignableRole.getRole().getId().equals(role.getIdLong()))) {
throw new AssignableRoleAlreadyDefinedException(role, placeName);
}
Long placeId = assignableRolePlace.getId();
Long serverId = server.getId();
if (fakeEmote != null && fakeEmote.getEmote() != null) {
// it only may be unusable if its a custom emote
log.debug("Using custom emote {} to create assignable role {} for assignable role place {} in server {}.",
fakeEmote.getEmote().getId(), role.getId(), placeId, serverId);
if (!emoteService.isEmoteUsableByBot(fakeEmote.getEmote())) {
throw new EmoteNotUsableException(fakeEmote.getEmote());
}
}
Optional<GuildMessageChannel> channelOptional = channelService.getMessageChannelFromServerOptional(server.getId(), assignableRolePlace.getChannel().getId());
if (channelOptional.isPresent()) {
GuildMessageChannel textChannel = channelOptional.get();
String buttonId = componentService.generateComponentId();
String emoteMarkdown = fakeEmote != null ? fakeEmote.getEmoteRepr() : null;
if (assignableRolePlace.getMessageId() != null) {
log.debug("Assignable role place {} has already message post with ID {} - updating.", assignableRolePlace.getId(), assignableRolePlace.getMessageId());
return componentService.addButtonToMessage(assignableRolePlace.getMessageId(), textChannel, buttonId, description, emoteMarkdown, ButtonStyle.SECONDARY)
.thenAccept(message -> self.persistAssignableRoleAddition(placeId, role, description, fakeEmote, buttonId));
} else {
log.info("Assignable role place {} is not yet setup - only adding role to the database.", assignableRolePlace.getId());
self.persistAssignableRoleAddition(placeId, role, description, fakeEmote, buttonId);
return CompletableFuture.completedFuture(null);
}
} else {
throw new ChannelNotInGuildException(assignableRolePlace.getChannel().getId());
}
}
@Transactional
public void persistAssignableRoleAddition(Long placeId, Role role, String description, FullEmote fakeEmote, String componentId) {
AssignableRolePlace place = assignableRolePlaceManagementServiceBean.findByPlaceId(placeId);
log.info("Adding role {} to assignable role place {} with component ID {}.", role.getId(), place.getId(), componentId);
ComponentPayload payload = persistButtonCallback(place, componentId, role.getIdLong());
assignableRoleManagementServiceBean.addRoleToPlace(fakeEmote, role, description, place, payload);
}
@Override
public CompletableFuture<Void> removeRoleFromAssignableRolePlace(AServer server, String placeName, ARole role) {
AssignableRolePlace assignableRolePlace = rolePlaceManagementService.findByServerAndKey(server, placeName);
Long assignableRolePlaceId = assignableRolePlace.getId();
for (AssignableRole assignableRole : assignableRolePlace.getAssignableRoles()) {
if (assignableRole.getRole().getId().equals(role.getId())) {
log.info("Found {} role to be removed - removing button from place.", role.getId());
// TODO we might want to actually remove all the assigned roles as well
return removeButtonFromAssignableRolePlace(assignableRole, assignableRolePlace).thenAccept(aVoid ->
self.deleteAssignableRoleFromPlace(assignableRolePlaceId, assignableRole.getId())
);
}
}
throw new AssignableRoleNotFoundException(role.getId());
}
private CompletableFuture<Void> removeButtonFromAssignableRolePlace(AssignableRole assignableRole, AssignableRolePlace assignableRolePlace) {
String componentId = assignableRole.getComponentPayload().getId();
log.debug("Component ID to remove {} for role {}", componentId, assignableRole.getRole().getId());
return channelService.retrieveMessageInChannel(assignableRolePlace.getServer().getId(), assignableRolePlace.getChannel().getId(), assignableRolePlace.getMessageId())
.thenCompose(message -> {
log.debug("Updating message {} to remove component with ID {}.", message.getIdLong(), componentId);
return componentService.removeComponentWithId(message, componentId, true);
}
);
}
@Transactional
public void deleteAssignableRoleFromPlace(Long placeId, Long assignableRoleId) {
AssignableRolePlace assignableRolePlace = rolePlaceManagementService.findByPlaceId(placeId);
log.info("Deleting the entry for assignable role {} in assignable role place {}.", assignableRoleId, placeId);
Optional<AssignableRole> roleToRemoveOptional = assignableRolePlace
.getAssignableRoles()
.stream()
.filter(role -> role.getId().equals(assignableRoleId))
.findAny();
roleToRemoveOptional.ifPresent(assignableRole -> {
ComponentPayload componentPayload = assignableRole.getComponentPayload();
assignedRoleUserManagementServiceBean.removeAssignedRoleFromUsers(assignableRole);
assignableRoleManagementServiceBean.deleteAssignableRole(assignableRole);
componentPayloadManagementService.deletePayload(componentPayload);
});
if (!roleToRemoveOptional.isPresent()) {
log.warn("Assignable role with ID {} was not present in assignable role place {}.", assignableRoleId, placeId);
}
}
@Override
public CompletableFuture<Void> setupAssignableRolePlace(AServer server, String name) {
AssignableRolePlace assignableRolePlace = rolePlaceManagementService.findByServerAndKey(server, name);
log.info("Setting up assignable role place {} in server {} towards channel {}.", assignableRolePlace.getId(), server.getId(), assignableRolePlace.getChannel().getId());
CompletableFuture<Void> oldPostDeletionFuture = deleteExistingMessagePostsForPlace(assignableRolePlace);
Long serverId = server.getId();
Long assignablePlaceId = assignableRolePlace.getId();
CompletableFuture<Void> postingFuture = new CompletableFuture<>();
oldPostDeletionFuture.whenComplete((unused, throwable) -> {
if (throwable != null) {
log.warn("Not able to delete old messages of assignable role place {} in server {}.", assignablePlaceId, serverId);
}
self.createAssignableRolePlacePost(serverId, assignablePlaceId)
.thenAccept(unused1 -> postingFuture.complete(null))
.exceptionally(innerThrowable -> {
postingFuture.completeExceptionally(innerThrowable);
return null;
});
}).exceptionally(throwable -> {
postingFuture.completeExceptionally(throwable);
return null;
});
return postingFuture;
}
@Override
public CompletableFuture<Void> refreshTextFromPlace(AssignableRolePlace place) {
AssignablePostMessage model = prepareAssignablePostMessageModel(place);
MessageToSend messageToSend = templateService.renderEmbedTemplate(ASSIGNABLE_ROLES_POST_TEMPLATE_KEY, model, place.getServer().getId());
Long channelId = place.getChannel().getId();
Optional<GuildMessageChannel> channelOptional = channelService.getMessageChannelFromServerOptional(place.getServer().getId(), channelId);
if (channelOptional.isPresent()) {
log.info("Refreshing text for assignable role place {} in channel {} in post {}.", place.getId(), channelId, place.getMessageId());
return channelService.editEmbedMessageInAChannel(messageToSend.getEmbeds().get(0), channelOptional.get(), place.getMessageId()).thenCompose(message -> CompletableFuture.completedFuture(null));
} else {
throw new ChannelNotInGuildException(channelId);
}
}
@Override
public CompletableFuture<Void> setAssignablePlaceActiveTo(AServer server, String name, Boolean newValue) {
AssignableRolePlace place = rolePlaceManagementService.findByServerAndKey(server, name);
if (newValue) {
return this.activateAssignableRolePlace(place);
} else {
return this.deactivateAssignableRolePlace(place);
}
}
private CompletableFuture<Void> deleteExistingMessagePostsForPlace(AssignableRolePlace assignableRolePlace) {
if (assignableRolePlace.getMessageId() != null) {
log.info("Deleting old message {} for assignable role place {}.", assignableRolePlace.getMessageId(), assignableRolePlace.getId());
return messageService.deleteMessageInChannelInServer(assignableRolePlace.getServer().getId(), assignableRolePlace.getChannel().getId(), assignableRolePlace.getMessageId());
} else {
log.info("Assignable role place {} was not yet set up - no message ID tracked.", assignableRolePlace.getMessageId());
return CompletableFuture.completedFuture(null);
}
}
@Override
public CompletableFuture<Void> deactivateAssignableRolePlace(AServer server, String name) {
return setAssignablePlaceActiveTo(server, name, false);
}
@Override
public CompletableFuture<Void> deactivateAssignableRolePlace(AssignableRolePlace place) {
log.info("Deactivating assignable role place {} in server {}", place.getId(), place.getServer().getId());
return channelService.retrieveMessageInChannel(place.getServer().getId(), place.getChannel().getId(), place.getMessageId())
.thenCompose(message ->
componentService.disableAllButtons(message)
);
}
@Override
public CompletableFuture<Void> activateAssignableRolePlace(AServer server, String name) {
return setAssignablePlaceActiveTo(server, name, true);
}
@Override
public CompletableFuture<Void> activateAssignableRolePlace(AssignableRolePlace place) {
log.info("Activating assignable role place {} in server {}", place.getId(), place.getServer().getId());
return channelService.retrieveMessageInChannel(place.getServer().getId(), place.getChannel().getId(), place.getMessageId())
.thenCompose(message ->
componentService.enableAllButtons(message)
);
}
@Override
public void setAssignablePlaceUniqueTo(AServer server, String name, Boolean newValue) {
AssignableRolePlace place = rolePlaceManagementService.findByServerAndKey(server, name);
if (newValue) {
this.uniqueAssignableRolePlace(place);
} else {
this.multipleAssignableRolePlace(place);
}
}
@Override
public void uniqueAssignableRolePlace(AServer server, String name) {
setAssignablePlaceUniqueTo(server, name, true);
}
@Override
public void uniqueAssignableRolePlace(AssignableRolePlace place) {
log.info("Setting assignable role place uniqueness {} in server {} to {}", place.getId(), place.getServer().getId(), true);
place.setUniqueRoles(true);
}
@Override
public void multipleAssignableRolePlace(AServer server, String name) {
setAssignablePlaceUniqueTo(server, name, false);
}
@Override
public void multipleAssignableRolePlace(AssignableRolePlace place) {
log.info("Setting assignable role place uniqueness {} in server {} to {}", place.getId(), place.getServer().getId(), false);
place.setUniqueRoles(false);
}
@Override
public AssignableRolePlaceConfig getAssignableRolePlaceConfig(Guild guild, String name) {
AServer server = serverManagementService.loadServer(guild);
AssignableRolePlace place = rolePlaceManagementService.findByServerAndKey(server, name);
log.info("Generating assignable role place config for place {} on server {}.", place.getId(), guild.getIdLong());
return convertPlaceToAssignableRolePlaceConfig(guild, place);
}
private AssignableRolePlaceConfig convertPlaceToAssignableRolePlaceConfig(Guild guild, AssignableRolePlace place) {
List<AssignableRolePlaceConfigRole> roles = new ArrayList<>();
List<AssignableRole> assignableRoles = place.getAssignableRoles();
for (AssignableRole role : assignableRoles) {
Role jdaRole = guild.getRoleById(role.getRole().getId());
RoleDisplay display = jdaRole != null ? RoleDisplay.fromRole(jdaRole) : RoleDisplay.fromARole(role.getRole());
AssignableRolePlaceConfigRole postRole = AssignableRolePlaceConfigRole
.builder()
.description(role.getDescription())
.emoteMarkDown(role.getEmoteMarkdown())
.conditions(assignableRoleConditionService.getConditionDisplays(role.getConditions()))
.roleDisplay(display)
.build();
roles.add(postRole);
}
TextChannel placeChannel = guild.getTextChannelById(place.getChannel().getId());
return AssignableRolePlaceConfig
.builder()
.roles(roles)
.type(place.getType())
.placeName(place.getKey())
.placeText(place.getText())
.uniqueRoles(place.getUniqueRoles())
.channelDisplay(ChannelDisplay.fromChannel(placeChannel))
.build();
}
@Override
public CompletableFuture<Void> moveAssignableRolePlace(AServer server, String name, TextChannel newChannel) {
AssignableRolePlace place = rolePlaceManagementService.findByServerAndKey(server, name);
log.info("Moving assignable role place {} from channel {} to channel {} in guild {}.",
place.getId(), place.getChannel().getId(), newChannel.getId(), newChannel.getGuild().getIdLong());
CompletableFuture<Void> oldPostDeletionFuture = deleteExistingMessagePostsForPlace(place);
Long serverId = server.getId();
Long assignablePlaceId = place.getId();
CompletableFuture<Void> returnFuture = new CompletableFuture<>();
oldPostDeletionFuture.whenComplete((unused, throwable) -> {
if (throwable != null) {
log.warn("Not able to delete old messages of assignable role place {} in server {}.", assignablePlaceId, serverId);
}
self.setupAssignableRolePlaceInChannel(serverId, assignablePlaceId, newChannel)
.thenAccept(unused1 -> self.updateAssignableRolePlaceChannel(name, newChannel))
.thenAccept(unused1 -> returnFuture.complete(null))
.exceptionally(innerThrowable -> {
returnFuture.completeExceptionally(innerThrowable);
return null;
});
}).exceptionally(throwable -> {
returnFuture.completeExceptionally(throwable);
return null;
});
return returnFuture;
}
@Transactional
public void updateAssignableRolePlaceChannel(String name, TextChannel textChannel) {
AChannel channel = channelManagementService.loadChannel(textChannel.getIdLong());
log.info("Setting assignable role place to channel {}.", textChannel.getIdLong());
rolePlaceManagementService.moveAssignableRolePlace(name, channel);
}
@Override
public CompletableFuture<Void> deleteAssignableRolePlace(AServer server, String name) {
AssignableRolePlace place = rolePlaceManagementService.findByServerAndKey(server, name);
log.info("Deleting assignable role place {}.", place.getId());
Long placeId = place.getId();
CompletableFuture<Void> deleteFuture = deleteExistingMessagePostsForPlace(place);
return deleteFuture.thenAccept(unused -> self.deleteAssignableRolePlaceInDatabase(placeId));
}
@Transactional
public void deleteAssignableRolePlaceInDatabase(Long placeId) {
AssignableRolePlace place = rolePlaceManagementService.findByPlaceId(placeId);
place.getAssignableRoles()
.forEach(assignableRole -> componentPayloadManagementService.deletePayload(assignableRole.getComponentPayload()));
rolePlaceManagementService.deleteAssignablePlace(place);
}
@Override
public CompletableFuture<Void> changeTextAsync(AServer server, String name, String newText) {
AssignableRolePlace place = rolePlaceManagementService.findByServerAndKey(server, name);
log.info("Changing text of assignable role place {} in server {}.", place.getId(), server.getId());
place.setText(newText);
return refreshTextFromPlace(place);
}
@Override
public CompletableFuture<Void> changeConfiguration(AServer server, String name, AssignableRolePlaceParameterKey keyToChange, String newValue) {
Boolean booleanValue = BooleanUtils.toBooleanObject(newValue);
if (booleanValue == null) {
throw new CommandParameterKeyValueWrongTypeException(Arrays.asList("yes", "no", "true", "false", "on", "off"));
}
if (keyToChange == AssignableRolePlaceParameterKey.UNIQUE) {
setAssignablePlaceUniqueTo(server, name, booleanValue);
return CompletableFuture.completedFuture(null);
}
throw new AssignableRolePlaceIllegalConfigurationException();
}
@Override
public AssignablePlaceOverview getAssignableRolePlaceOverview(Guild guild) {
AServer server = serverManagementService.loadServer(guild);
List<AssignableRolePlace> assignableRolePlaces = rolePlaceManagementService.findAllByServer(server);
List<AssignableRolePlaceConfig> placeConfigs = assignableRolePlaces
.stream()
.map(place -> convertPlaceToAssignableRolePlaceConfig(guild, place))
.collect(Collectors.toList());
log.info("Showing overview over all assignable role places for server {}.", server.getId());
return AssignablePlaceOverview
.builder()
.places(placeConfigs)
.build();
}
private CompletableFuture<Void> sendAssignablePostMessage(AssignableRolePlace place, GuildMessageChannel channel) {
AssignablePostMessage model = prepareAssignablePostMessageModel(place);
MessageToSend messageToSend = templateService.renderEmbedTemplate(ASSIGNABLE_ROLES_POST_TEMPLATE_KEY, model, place.getServer().getId());
log.info("Sending message for assignable role place {}.", place.getId());
CompletableFuture<Message> postFuture = channelService.sendMessageToSendToChannel(messageToSend, channel).get(0);
Long placeId = model.getPlaceId();
return postFuture.thenCompose(unused -> {
CompletableFuture<Void> future = new CompletableFuture<>();
try {
self.persistAssignablePlaceMessageId(placeId, postFuture);
future.complete(null);
} catch (Exception exception) {
future.completeExceptionally(exception);
return future;
}
return future;
});
}
@Transactional
public void persistAssignablePlaceMessageId(Long placeId, CompletableFuture<Message> messageFuture) {
AssignableRolePlace place = assignableRolePlaceManagementServiceBean.findByPlaceId(placeId);
Message message = messageFuture.join();
log.info("Setting message ID of assignable role place {} to {}.", placeId, message.getIdLong());
place.setMessageId(message.getIdLong());
}
private ComponentPayload persistButtonCallback(AssignableRolePlace place, String buttonId, Long roleId) {
AssignableRolePlacePayload payload = AssignableRolePlacePayload
.builder()
.roleId(roleId)
.placeId(place.getId())
.build();
return componentPayloadService.createButtonPayload(buttonId, payload, ASSIGNABLE_ROLE_COMPONENT_ORIGIN, place.getServer());
}
private AssignablePostMessage prepareAssignablePostMessageModel(AssignableRolePlace place) {
List<AssignablePostRole> roles = new ArrayList<>();
List<AssignableRole> rolesToAdd = place.getAssignableRoles();
int maxPosition = 0;
Map<String, Long> componentIdMap = new HashMap<>();
if (!rolesToAdd.isEmpty()) {
rolesToAdd.forEach(assignableRole -> {
String componentId = assignableRole.getComponentPayload().getId();
componentIdMap.put(componentId, assignableRole.getRole().getId());
roles.add(AssignablePostRole
.builder()
.componentId(componentId)
.description(assignableRole.getDescription())
.emoteMarkDown(assignableRole.getEmoteMarkdown())
.build());
});
}
return AssignablePostMessage
.builder()
.roles(roles)
.placeId(place.getId())
.componentIdToRole(componentIdMap)
.placeDescription(place.getText())
.maxPosition(maxPosition)
.build();
}
@Transactional
public CompletableFuture<Void> createAssignableRolePlacePost(Long serverId, Long assignablePlaceId) {
AssignableRolePlace assignableRolePlace = rolePlaceManagementService.findByPlaceId(assignablePlaceId);
Optional<GuildMessageChannel> channelOptional = channelService.getMessageChannelFromServerOptional(serverId, assignableRolePlace.getChannel().getId());
if (channelOptional.isPresent()) {
GuildMessageChannel channel = channelOptional.get();
log.info("Sending assignable role place posts for place {} in channel {} in server {}.", assignableRolePlace.getId(), channel.getId(), serverId);
return sendAssignablePostMessage(assignableRolePlace, channel);
} else {
throw new AssignableRolePlaceChannelDoesNotExistException(assignableRolePlace.getChannel().getId(), assignableRolePlace.getKey());
}
}
@Transactional
public CompletableFuture<Void> setupAssignableRolePlaceInChannel(Long serverId, Long assignablePlaceId, TextChannel textChannel) {
AssignableRolePlace assignableRolePlace = rolePlaceManagementService.findByPlaceId(assignablePlaceId);
log.info("Sending assignable role place posts for place {} in channel {} in server {}.", assignableRolePlace.getId(), textChannel.getId(), serverId);
return sendAssignablePostMessage(assignableRolePlace, textChannel);
}
}

View File

@@ -1,195 +0,0 @@
package dev.sheldan.abstracto.assignableroles.service;
import dev.sheldan.abstracto.assignableroles.exception.AssignableRoleNotFoundException;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRole;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace;
import dev.sheldan.abstracto.assignableroles.model.database.AssignedRoleUser;
import dev.sheldan.abstracto.assignableroles.service.management.AssignableRoleManagementServiceBean;
import dev.sheldan.abstracto.assignableroles.service.management.AssignedRoleUserManagementService;
import dev.sheldan.abstracto.assignableroles.service.management.AssignedRoleUserManagementServiceBean;
import dev.sheldan.abstracto.core.metric.service.CounterMetric;
import dev.sheldan.abstracto.core.metric.service.MetricService;
import dev.sheldan.abstracto.core.metric.service.MetricTag;
import dev.sheldan.abstracto.core.models.database.ARole;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.MemberService;
import dev.sheldan.abstracto.core.service.RoleService;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Role;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.PostConstruct;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
@Component
@Slf4j
public class AssignableRoleServiceBean implements AssignableRoleService {
@Autowired
private RoleService roleService;
@Autowired
private AssignedRoleUserManagementService assignedRoleUserManagementService;
@Autowired
private AssignableRoleManagementServiceBean assignableRoleManagementServiceBean;
@Autowired
private UserInServerManagementService userInServerManagementService;
@Autowired
private AssignedRoleUserManagementServiceBean assignedRoleUserManagementServiceBean;
@Autowired
private AssignableRoleServiceBean self;
@Autowired
private MemberService memberService;
@Autowired
private MetricService metricService;
public static final String ASSIGNABLE_ROLES_METRIC = "assignable.roles";
public static final String ACTION = "action";
private static final CounterMetric ASSIGNABLE_ROLES_ASSIGNED =
CounterMetric
.builder()
.name(ASSIGNABLE_ROLES_METRIC)
.tagList(Arrays.asList(MetricTag.getTag(ACTION, "assigned")))
.build();
private static final CounterMetric ASSIGNABLE_ROLES_REMOVED =
CounterMetric
.builder()
.name(ASSIGNABLE_ROLES_METRIC)
.tagList(Arrays.asList(MetricTag.getTag(ACTION, "removed")))
.build();
private static final CounterMetric ASSIGNABLE_ROLES_CONDITION_FAILED =
CounterMetric
.builder()
.name(ASSIGNABLE_ROLES_METRIC)
.tagList(Arrays.asList(MetricTag.getTag(ACTION, "condition")))
.build();
@Override
public CompletableFuture<Void> assignAssignableRoleToUser(Long assignableRoleId, Member member) {
AssignableRole role = assignableRoleManagementServiceBean.getByAssignableRoleId(assignableRoleId);
log.info("Assigning role {} to member {} in server {}.", assignableRoleId, member.getId(), member.getGuild().getId());
metricService.incrementCounter(ASSIGNABLE_ROLES_ASSIGNED);
return roleService.addRoleToMemberAsync(member, role.getRole());
}
@Override
public CompletableFuture<Void> assignAssignableRoleToUser(Role role, Member member) {
return assignRoleToUser(role.getIdLong(), member);
}
@Override
public void assignableRoleConditionFailure() {
metricService.incrementCounter(ASSIGNABLE_ROLES_CONDITION_FAILED);
}
private CompletableFuture<Void> assignRoleToUser(Long roleId, Member member) {
metricService.incrementCounter(ASSIGNABLE_ROLES_ASSIGNED);
return roleService.addRoleToMemberAsync(member, roleId);
}
@Override
public void clearAllRolesOfUserInPlace(AssignableRolePlace place, AUserInAServer userInAServer) {
Optional<AssignedRoleUser> userOptional = assignedRoleUserManagementServiceBean.findByUserInServerOptional(userInAServer);
userOptional.ifPresent(assignedRoleUser -> {
log.info("Clearing all {} assignable roles in place {} for user {} in server {}.",
assignedRoleUser.getRoles().size(), place.getId(), userInAServer.getUserReference().getId(), userInAServer.getServerReference().getId());
assignedRoleUser.getRoles().forEach(assignableRole -> {
if(assignableRole.getAssignablePlace().equals(place)) {
assignableRole.getAssignedUsers().remove(assignedRoleUser);
}
});
assignedRoleUser.getRoles().removeIf(assignableRole -> assignableRole.getAssignablePlace().equals(place));
});
if(!userOptional.isPresent()) {
log.info("User {} was not yet stored as an assignable role user in server {} - nothing to clear.",
userInAServer.getUserReference().getId(), place.getServer().getId());
}
}
@Override
public CompletableFuture<Void> removeAssignableRoleFromUser(AssignableRole assignableRole, Member member) {
log.info("Removing assignable role {} from user {} in server {}.", assignableRole.getId(), member.getId(), member.getGuild().getId());
return removeRoleFromUser(assignableRole.getRole().getId(), member);
}
@Override
public CompletableFuture<Void> removeAssignableRoleFromUser(Role role, Member member) {
return removeRoleFromUser(role.getIdLong(), member);
}
private CompletableFuture<Void> removeRoleFromUser(Long roleId, Member member) {
metricService.incrementCounter(ASSIGNABLE_ROLES_REMOVED);
return roleService.removeRoleFromMemberAsync(member, roleId);
}
@Override
@Transactional
public CompletableFuture<Void> removeAssignableRoleFromUser(Long assignableRoleId, Member member) {
AssignableRole role = assignableRoleManagementServiceBean.getByAssignableRoleId(assignableRoleId);
return self.removeAssignableRoleFromUser(role, member);
}
@Override
public void addRoleToUser(AssignableRole assignableRole, AUserInAServer aUserInAServer) {
log.info("Persisting storing adding assignable role {} to user {} in server {}.",
assignableRole.getId(), aUserInAServer.getUserReference().getId(), aUserInAServer.getServerReference().getId());
assignedRoleUserManagementServiceBean.addAssignedRoleToUser(assignableRole, aUserInAServer);
}
@Override
public void removeRoleFromUser(AssignableRole assignableRole, AUserInAServer aUserInAServer) {
log.info("Persisting storing removing assignable role {} to user {} in server {}.",
assignableRole.getId(), aUserInAServer.getUserReference().getId(), aUserInAServer.getServerReference().getId());
assignedRoleUserManagementServiceBean.removeAssignedRoleFromUser(assignableRole, aUserInAServer);
}
@Override
public AssignableRole getAssignableRoleInPlace(AssignableRolePlace place, Role role) {
return getAssignableRoleInPlace(place, role.getIdLong());
}
@Override
public AssignableRole getAssignableRoleInPlace(AssignableRolePlace place, ARole role) {
return getAssignableRoleInPlace(place, role.getId());
}
@Override
public AssignableRole getAssignableRoleInPlace(AssignableRolePlace place, Long roleId) {
for (AssignableRole assignableRole : place.getAssignableRoles()) {
if (assignableRole.getRole().getId().equals(roleId)) {
return assignableRole;
}
}
throw new AssignableRoleNotFoundException(roleId);
}
@Override
public void removeAssignableRolesFromAssignableRoleUser(List<AssignableRole> roles, AssignedRoleUser roleUser) {
log.info("Removing {} assignable roles from user {} in server {}.", roles.size(), roleUser.getUser().getUserReference().getId(),
roleUser.getUser().getServerReference().getId());
roles.forEach(assignableRole -> assignedRoleUserManagementServiceBean.removeAssignedRoleFromUser(assignableRole, roleUser));
}
@PostConstruct
public void postConstruct() {
metricService.registerCounter(ASSIGNABLE_ROLES_ASSIGNED, "Assignable roles assigned.");
metricService.registerCounter(ASSIGNABLE_ROLES_REMOVED, "Assignable roles removed.");
metricService.registerCounter(ASSIGNABLE_ROLES_CONDITION_FAILED, "Assignable roles failed to assign because of condition.");
}
}

View File

@@ -1,43 +0,0 @@
package dev.sheldan.abstracto.assignableroles.service.management;
import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRoleConditionType;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRole;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRoleCondition;
import dev.sheldan.abstracto.assignableroles.repository.AssignableRoleConditionRepository;
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 AssignableRoleConditionManagementServiceBean implements AssignableRoleConditionManagementService {
@Autowired
private AssignableRoleConditionRepository repository;
@Override
public AssignableRoleCondition createAssignableRoleCondition(AssignableRole assignableRole, AssignableRoleConditionType type, String value) {
AssignableRoleCondition condition = AssignableRoleCondition
.builder()
.assignableRole(assignableRole)
.type(type)
.conditionValue(value)
.build();
log.info("Creating condition of type {} for assignable role {}", assignableRole.getId(), type);
assignableRole.getConditions().add(condition);
return repository.save(condition);
}
@Override
public void deleteAssignableRoleCondition(AssignableRoleCondition condition) {
log.info("Deleting condition {}.", condition.getId());
repository.delete(condition);
}
@Override
public Optional<AssignableRoleCondition> findAssignableRoleCondition(AssignableRole role, AssignableRoleConditionType type) {
return repository.findByAssignableRoleAndType(role, type);
}
}

View File

@@ -1,75 +0,0 @@
package dev.sheldan.abstracto.assignableroles.service.management;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRole;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlaceType;
import dev.sheldan.abstracto.assignableroles.model.database.AssignedRoleUser;
import dev.sheldan.abstracto.assignableroles.repository.AssignableRoleRepository;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.core.models.FullEmote;
import dev.sheldan.abstracto.core.models.database.ARole;
import dev.sheldan.abstracto.core.models.database.ComponentPayload;
import dev.sheldan.abstracto.core.service.EmoteService;
import dev.sheldan.abstracto.core.service.management.EmoteManagementService;
import dev.sheldan.abstracto.core.service.management.RoleManagementService;
import lombok.extern.slf4j.Slf4j;
import net.dv8tion.jda.api.entities.Role;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
@Slf4j
public class AssignableRoleManagementServiceBean implements AssignableRoleManagementService {
@Autowired
private AssignableRolePlaceManagementService rolePlaceManagementService;
@Autowired
private EmoteManagementService emoteManagementService;
@Autowired
private RoleManagementService roleManagementService;
@Autowired
private AssignableRoleRepository repository;
@Autowired
private EmoteService emoteService;
@Override
public AssignableRole addRoleToPlace(FullEmote emote, Role role, String description, AssignableRolePlace place, ComponentPayload componentPayload) {
ARole arole = roleManagementService.findRole(role.getIdLong());
AssignableRole roleToAdd = AssignableRole
.builder()
.assignablePlace(place)
.emoteMarkdown(emote != null ? emote.getEmoteRepr() : null)
.role(arole)
.componentPayload(componentPayload)
.server(place.getServer())
.description(description)
.build();
place.getAssignableRoles().add(roleToAdd);
log.info("Adding role {} to assignable role place {}. There are now {} roles.", role.getId(), place.getId(), place.getAssignableRoles().size());
return roleToAdd;
}
@Override
public AssignableRole getByAssignableRoleId(Long assignableRoleId) {
return repository.findById(assignableRoleId).orElseThrow(() -> new AbstractoRunTimeException("Assignable role not found"));
}
@Override
public void deleteAssignableRole(AssignableRole assignableRole) {
assignableRole.getAssignablePlace().getAssignableRoles().remove(assignableRole);
assignableRole.setAssignablePlace(null);
repository.delete(assignableRole);
}
@Override
public List<AssignableRole> getAssignableRolesFromAssignableUserWithPlaceType(AssignedRoleUser user, AssignableRolePlaceType type) {
return repository.findByAssignedUsersContainingAndAssignablePlace_Type(user, type);
}
}

View File

@@ -1,89 +0,0 @@
package dev.sheldan.abstracto.assignableroles.service.management;
import dev.sheldan.abstracto.assignableroles.exception.AssignableRolePlaceNotFoundException;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlaceType;
import dev.sheldan.abstracto.assignableroles.repository.AssignableRolePlaceRepository;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AServer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Optional;
@Component
@Slf4j
public class AssignableRolePlaceManagementServiceBean implements AssignableRolePlaceManagementService {
@Autowired
private AssignableRolePlaceRepository repository;
@Override
public AssignableRolePlace createPlace(String name, AChannel channel, String text, AssignableRolePlaceType type) {
boolean unique = false;
if(type.equals(AssignableRolePlaceType.BOOSTER)) {
unique = true;
}
AssignableRolePlace place = AssignableRolePlace
.builder()
.channel(channel)
.server(channel.getServer())
.text(text)
.uniqueRoles(unique)
.type(type)
.key(name)
.build();
log.info("Creating assignable role place in channel {} on server {}.", channel.getId(), channel.getServer().getId());
return repository.save(place);
}
@Override
public boolean doesPlaceExist(AServer server, String name) {
return repository.existsByServerAndKey(server, name);
}
@Override
public AssignableRolePlace findByServerAndKey(AServer server, String name) {
return repository.findByServerAndKey(server, name).orElseThrow(AssignableRolePlaceNotFoundException::new);
}
@Override
public Optional<AssignableRolePlace> findByPlaceIdOptional(Long id) {
return repository.findById(id);
}
@Override
public AssignableRolePlace findByPlaceId(Long id) {
return findByPlaceIdOptional(id).orElseThrow(AssignableRolePlaceNotFoundException::new);
}
@Override
public void moveAssignableRolePlace(String name, AChannel newChannel) {
AssignableRolePlace assignablePlaceToChange = findByServerAndKey(newChannel.getServer(), name);
log.info("Moving assignable role place {} in server {} from channel {} to channel {}.",
assignablePlaceToChange.getId(), newChannel.getServer().getId(), assignablePlaceToChange.getChannel().getId(), newChannel.getId());
assignablePlaceToChange.setChannel(newChannel);
}
@Override
public void changeAssignableRolePlaceDescription(AServer server, String name, String newDescription) {
AssignableRolePlace assignablePlaceToChange = findByServerAndKey(server, name);
log.info("Changing description of assignable role place {} in server {}.", assignablePlaceToChange.getId(), server.getId());
assignablePlaceToChange.setText(newDescription);
}
@Override
public void deleteAssignablePlace(AssignableRolePlace toDelete) {
log.info("Deleting assignable role place {} in server {} which was in server {}.", toDelete.getId(), toDelete.getChannel().getId(), toDelete.getServer().getId());
repository.delete(toDelete);
}
@Override
public List<AssignableRolePlace> findAllByServer(AServer server) {
return repository.findByServer(server);
}
}

View File

@@ -1,87 +0,0 @@
package dev.sheldan.abstracto.assignableroles.service.management;
import dev.sheldan.abstracto.assignableroles.exception.AssignedUserNotFoundException;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRole;
import dev.sheldan.abstracto.assignableroles.model.database.AssignedRoleUser;
import dev.sheldan.abstracto.assignableroles.repository.AssignedRoleUserRepository;
import dev.sheldan.abstracto.core.models.ServerUser;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.service.management.UserInServerManagementService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Optional;
@Component
@Slf4j
public class AssignedRoleUserManagementServiceBean implements AssignedRoleUserManagementService {
@Autowired
private AssignedRoleUserRepository repository;
@Autowired
private UserInServerManagementService userInServerManagementService;
@Override
public void addAssignedRoleToUser(AssignableRole assignableRole, AUserInAServer aUserInAServer) {
Optional<AssignedRoleUser> optional = findByUserInServerOptional(aUserInAServer);
log.info("Adding assignable role {} to user {} in server {} because of assignable role place {}.",
assignableRole.getId(), aUserInAServer.getUserReference().getId(), aUserInAServer.getServerReference().getId(),
assignableRole.getAssignablePlace().getId());
AssignedRoleUser user = optional.orElseGet(() -> createAssignedRoleUser(aUserInAServer));
assignableRole.getAssignedUsers().add(user);
user.getRoles().add(assignableRole);
}
@Override
public void removeAssignedRoleFromUser(AssignableRole assignableRole, AUserInAServer aUserInAServer) {
log.info("Removing assignable role {} from user {} in server {} in assignable role place {}.",
assignableRole.getId(), aUserInAServer.getUserReference().getId(), aUserInAServer.getServerReference().getId(),
assignableRole.getAssignablePlace().getId());
AssignedRoleUser user = findByUserInServer(aUserInAServer);
removeAssignedRoleFromUser(assignableRole, user);
}
@Override
public void removeAssignedRoleFromUsers(AssignableRole assignableRole, List<AssignedRoleUser> users) {
log.info("Clearing all assignable role {} for {} users.", assignableRole.getId(), users.size());
assignableRole.getAssignedUsers().removeAll(users);
users.forEach(roleUser -> roleUser.getRoles().remove(assignableRole));
}
@Override
public void removeAssignedRoleFromUsers(AssignableRole assignableRole) {
removeAssignedRoleFromUsers(assignableRole, assignableRole.getAssignedUsers());
}
@Override
public void removeAssignedRoleFromUser(AssignableRole assignableRole, AssignedRoleUser user) {
assignableRole.getAssignedUsers().remove(user);
user.getRoles().remove(assignableRole);
}
@Override
public AssignedRoleUser createAssignedRoleUser(AUserInAServer aUserInAServer) {
log.info("Creating assigned role user for user {} in server {}.", aUserInAServer.getUserReference().getId(), aUserInAServer.getServerReference().getId());
AssignedRoleUser newUser = AssignedRoleUser.builder().user(aUserInAServer).id(aUserInAServer.getUserInServerId()).build();
return repository.save(newUser);
}
@Override
public Optional<AssignedRoleUser> findByUserInServerOptional(AUserInAServer aUserInAServer) {
return repository.findById(aUserInAServer.getUserInServerId());
}
@Override
public Optional<AssignedRoleUser> findByUserInServerOptional(ServerUser serverUser) {
AUserInAServer aUserInAServer = userInServerManagementService.loadOrCreateUser(serverUser);
return findByUserInServerOptional(aUserInAServer);
}
@Override
public AssignedRoleUser findByUserInServer(AUserInAServer aUserInAServer) {
return findByUserInServerOptional(aUserInAServer).orElseThrow(() -> new AssignedUserNotFoundException(aUserInAServer));
}
}

View File

@@ -1,2 +0,0 @@
abstracto.featureFlags.assignableRole.featureName=assignableRole
abstracto.featureFlags.assignableRole.enabled=false

View File

@@ -1,80 +0,0 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
<property name="assignableRoleModule" value="(SELECT id FROM module WHERE name = 'assignableRoles')"/>
<property name="assignableRoleFeature" value="(SELECT id FROM feature WHERE key = 'assignableRole')"/>
<changeSet author="Sheldan" id="assignable_roles-commands">
<insert tableName="command">
<column name="name" value="addRoleToAssignableRolePlace"/>
<column name="module_id" valueComputed="${assignableRoleModule}"/>
<column name="feature_id" valueComputed="${assignableRoleFeature}"/>
</insert>
<insert tableName="command">
<column name="name" value="setupAssignableRolePlace"/>
<column name="module_id" valueComputed="${assignableRoleModule}"/>
<column name="feature_id" valueComputed="${assignableRoleFeature}"/>
</insert>
<insert tableName="command">
<column name="name" value="activateAssignableRolePlace"/>
<column name="module_id" valueComputed="${assignableRoleModule}"/>
<column name="feature_id" valueComputed="${assignableRoleFeature}"/>
</insert>
<insert tableName="command">
<column name="name" value="deactivateAssignableRolePlace"/>
<column name="module_id" valueComputed="${assignableRoleModule}"/>
<column name="feature_id" valueComputed="${assignableRoleFeature}"/>
</insert>
<insert tableName="command">
<column name="name" value="removeRoleFromAssignableRolePlace"/>
<column name="module_id" valueComputed="${assignableRoleModule}"/>
<column name="feature_id" valueComputed="${assignableRoleFeature}"/>
</insert>
<insert tableName="command">
<column name="name" value="changeAssignableRolePlaceConfig"/>
<column name="module_id" valueComputed="${assignableRoleModule}"/>
<column name="feature_id" valueComputed="${assignableRoleFeature}"/>
</insert>
<insert tableName="command">
<column name="name" value="deleteAssignableRolePlace"/>
<column name="module_id" valueComputed="${assignableRoleModule}"/>
<column name="feature_id" valueComputed="${assignableRoleFeature}"/>
</insert>
<insert tableName="command">
<column name="name" value="createAssignableRolePlace"/>
<column name="module_id" valueComputed="${assignableRoleModule}"/>
<column name="feature_id" valueComputed="${assignableRoleFeature}"/>
</insert>
<insert tableName="command">
<column name="name" value="showAssignableRolePlaceConfig"/>
<column name="module_id" valueComputed="${assignableRoleModule}"/>
<column name="feature_id" valueComputed="${assignableRoleFeature}"/>
</insert>
<insert tableName="command">
<column name="name" value="editAssignableRolePlaceText"/>
<column name="module_id" valueComputed="${assignableRoleModule}"/>
<column name="feature_id" valueComputed="${assignableRoleFeature}"/>
</insert>
<insert tableName="command">
<column name="name" value="moveAssignableRolePlace"/>
<column name="module_id" valueComputed="${assignableRoleModule}"/>
<column name="feature_id" valueComputed="${assignableRoleFeature}"/>
</insert>
<insert tableName="command">
<column name="name" value="showAssignableRolePlaces"/>
<column name="module_id" valueComputed="${assignableRoleModule}"/>
<column name="feature_id" valueComputed="${assignableRoleFeature}"/>
</insert>
<insert tableName="command">
<column name="name" value="addAssignableRoleCondition"/>
<column name="module_id" valueComputed="${assignableRoleModule}"/>
<column name="feature_id" valueComputed="${assignableRoleFeature}"/>
</insert>
<insert tableName="command">
<column name="name" value="removeAssignableRoleCondition"/>
<column name="module_id" valueComputed="${assignableRoleModule}"/>
<column name="feature_id" valueComputed="${assignableRoleFeature}"/>
</insert>
</changeSet>
</databaseChangeLog>

View File

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

View File

@@ -1,10 +0,0 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
<changeSet author="Sheldan" id="assignable_role-feature-insertion">
<insert tableName="feature">
<column name="key" value="assignableRole"/>
</insert>
</changeSet>
</databaseChangeLog>

View File

@@ -1,10 +0,0 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
<changeSet author="Sheldan" id="assignable_role-module-insertion">
<insert tableName="module">
<column name="name" value="assignableRoles"/>
</insert>
</changeSet>
</databaseChangeLog>

View File

@@ -1,48 +0,0 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
<changeSet author="Sheldan" id="assignable_role-table">
<createTable tableName="assignable_role">
<column autoIncrement="true" name="id" type="BIGINT">
<constraints nullable="false" primaryKey="true" primaryKeyName="assignable_role_pkey"/>
</column>
<column name="emote_markdown" type="VARCHAR(100)">
<constraints nullable="true"/>
</column>
<column name="role_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="assignable_place_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="server_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="description" type="VARCHAR(255)">
<constraints nullable="false"/>
</column>
<column name="component_id" type="VARCHAR(100)" />
<column name="created" type="TIMESTAMP WITHOUT TIME ZONE">
<constraints nullable="false"/>
</column>
<column name="updated" type="TIMESTAMP WITHOUT TIME ZONE"/>
</createTable>
<createIndex indexName="idx_assignable_role_role_id" tableName="assignable_role">
<column name="role_id"/>
</createIndex>
<addForeignKeyConstraint baseColumnNames="role_id" baseTableName="assignable_role" constraintName="fk_assignable_role_role" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="role" validate="true"/>
<addForeignKeyConstraint baseColumnNames="assignable_place_id" baseTableName="assignable_role" constraintName="fk_assignable_role_place" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="assignable_role_place" validate="true"/>
<addForeignKeyConstraint baseColumnNames="server_id" baseTableName="assignable_role" constraintName="fk_assignable_role_server" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="server" validate="true"/>
<addForeignKeyConstraint baseColumnNames="component_id" baseTableName="assignable_role" constraintName="fk_assignable_role_payload" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="component_payload" validate="true"/>
<sql>
DROP TRIGGER IF EXISTS assignable_role_update_trigger ON assignable_role;
CREATE TRIGGER assignable_role_update_trigger BEFORE UPDATE ON assignable_role FOR EACH ROW EXECUTE PROCEDURE update_trigger_procedure();
</sql>
<sql>
DROP TRIGGER IF EXISTS assignable_role_insert_trigger ON assignable_role;
CREATE TRIGGER assignable_role_insert_trigger BEFORE INSERT ON assignable_role FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure();
</sql>
</changeSet>
</databaseChangeLog>

View File

@@ -1,29 +0,0 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
<changeSet author="Sheldan" id="assignable_role_condition-table">
<createTable tableName="assignable_role_condition">
<column autoIncrement="true" name="id" type="BIGINT">
<constraints nullable="false" primaryKey="true" primaryKeyName="assignable_role_condition_pkey"/>
</column>
<column name="type" type="VARCHAR(100)">
<constraints nullable="false"/>
</column>
<column name="assignable_role_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="condition_value" type="VARCHAR(255)">
<constraints nullable="false"/>
</column>
<column name="created" type="TIMESTAMP WITHOUT TIME ZONE"/>
</createTable>
<addForeignKeyConstraint baseColumnNames="assignable_role_id" baseTableName="assignable_role_condition" constraintName="fk_assignable_role_condition_assignable_role"
deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="assignable_role" validate="true"/>
<sql>
DROP TRIGGER IF EXISTS assignable_role_condition_insert_trigger ON assignable_role_condition;
CREATE TRIGGER assignable_role_condition_insert_trigger BEFORE INSERT ON assignable_role_condition FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure();
</sql>
</changeSet>
</databaseChangeLog>

View File

@@ -1,47 +0,0 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
<changeSet author="Sheldan" id="assignable_role_place-table">
<createTable tableName="assignable_role_place">
<column autoIncrement="true" name="id" type="BIGINT">
<constraints nullable="false" primaryKey="true" primaryKeyName="assignable_role_place_pkey"/>
</column>
<column name="channel_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="server_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="key" type="VARCHAR(255)">
<constraints nullable="false"/>
</column>
<column name="text" type="VARCHAR(255)">
<constraints nullable="false"/>
</column>
<column name="unique_roles" type="BOOLEAN">
<constraints nullable="false"/>
</column>
<column name="message_id" type="BIGINT" />
<column name="created" type="TIMESTAMP WITHOUT TIME ZONE">
<constraints nullable="false"/>
</column>
<column name="updated" type="TIMESTAMP WITHOUT TIME ZONE"/>
</createTable>
<createIndex indexName="idx_assignable_role_place" tableName="assignable_role_place">
<column name="server_id"/>
<column name="key"/>
</createIndex>
<addForeignKeyConstraint baseColumnNames="channel_id" baseTableName="assignable_role_place" constraintName="fk_assignable_role_place_channel" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="channel" validate="true"/>
<addForeignKeyConstraint baseColumnNames="server_id" baseTableName="assignable_role_place" constraintName="fk_assignable_role_place_server" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="server" validate="true"/>
<sql>
DROP TRIGGER IF EXISTS assignable_role_place_update_trigger ON assignable_role_place;
CREATE TRIGGER assignable_role_place_update_trigger BEFORE UPDATE ON assignable_role_place FOR EACH ROW EXECUTE PROCEDURE update_trigger_procedure();
</sql>
<sql>
DROP TRIGGER IF EXISTS assignable_role_place_insert_trigger ON assignable_role_place;
CREATE TRIGGER assignable_role_place_insert_trigger BEFORE INSERT ON assignable_role_place FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure();
</sql>
</changeSet>
</databaseChangeLog>

View File

@@ -1,38 +0,0 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
<changeSet author="Sheldan" id="assigned_role_user-table">
<createTable tableName="assigned_role_user">
<column name="id" type="BIGINT">
<constraints nullable="false" primaryKey="true" primaryKeyName="assigned_role_user_pkey"/>
</column>
<column name="created" type="TIMESTAMP WITHOUT TIME ZONE">
<constraints nullable="false"/>
</column>
<column name="updated" type="TIMESTAMP WITHOUT TIME ZONE"/>
</createTable>
<addForeignKeyConstraint baseColumnNames="id" baseTableName="assigned_role_user" constraintName="fk_assigned_role_user_user" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="user_in_server_id" referencedTableName="user_in_server" validate="true"/>
<sql>
DROP TRIGGER IF EXISTS assigned_role_user_update_trigger ON assigned_role_user;
CREATE TRIGGER assigned_role_user_update_trigger BEFORE UPDATE ON assigned_role_user FOR EACH ROW EXECUTE PROCEDURE update_trigger_procedure();
</sql>
<sql>
DROP TRIGGER IF EXISTS assigned_role_user_insert_trigger ON assigned_role_user;
CREATE TRIGGER assigned_role_user_insert_trigger BEFORE INSERT ON assigned_role_user FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure();
</sql>
</changeSet>
<changeSet author="Sheldan" id="assigned_role_in_user-table">
<createTable tableName="assigned_role_in_user">
<column name="assigned_role_id" type="BIGINT">
<constraints nullable="false"/>
</column>
<column name="user_in_server_id" type="BIGINT">
<constraints nullable="false"/>
</column>
</createTable>
<addForeignKeyConstraint baseColumnNames="assigned_role_id" baseTableName="assigned_role_in_user" constraintName="fk_assigned_role_in_user_assignable_role" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="assignable_role" validate="true"/>
<addForeignKeyConstraint baseColumnNames="user_in_server_id" baseTableName="assigned_role_in_user" constraintName="fk_assigned_role_in_user_assigned_user" deferrable="false" initiallyDeferred="false" onDelete="NO ACTION" onUpdate="NO ACTION" referencedColumnNames="id" referencedTableName="assigned_role_user" validate="true"/>
</changeSet>
</databaseChangeLog>

View File

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

View File

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

View File

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

View File

@@ -1,11 +0,0 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.26.xsd" >
<changeSet author="Sheldan" id="assignable_role_place-add_type">
<addColumn tableName="assignable_role_place">
<column name="type" type="VARCHAR2(128)" defaultValue="DEFAULT"/>
</addColumn>
</changeSet>
</databaseChangeLog>

View File

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

View File

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

View File

@@ -1,12 +0,0 @@
<?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">
<parent>
<groupId>dev.sheldan.abstracto.modules</groupId>
<artifactId>assignable-roles</artifactId>
<version>1.6.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>assignable-roles-int</artifactId>
</project>

View File

@@ -1,16 +0,0 @@
package dev.sheldan.abstracto.assignableroles.condition;
import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRoleConditionType;
import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRolePlaceConditionModel;
import dev.sheldan.abstracto.assignableroles.model.database.AssignableRoleCondition;
import dev.sheldan.abstracto.assignableroles.model.template.condition.AssignableRoleConditionDisplay;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import net.dv8tion.jda.api.entities.Role;
public interface AssignableRoleConditionEvaluator {
boolean handlesCondition(AssignableRoleConditionType type);
boolean fulfillsCondition(AssignableRoleCondition conditionDefinition, AUserInAServer aUserInAServer);
boolean usableValue(String value);
AssignableRolePlaceConditionModel createNotificationModel(AssignableRoleCondition conditionDefinition, Role role);
AssignableRoleConditionDisplay getConditionDisplay(AssignableRoleCondition conditionDefinition);
}

View File

@@ -1,13 +0,0 @@
package dev.sheldan.abstracto.assignableroles.config;
import dev.sheldan.abstracto.core.config.FeatureConfig;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import org.springframework.stereotype.Component;
@Component
public class AssignableFeatureConfig implements FeatureConfig {
@Override
public FeatureDefinition getFeature() {
return AssignableRoleFeatureDefinition.ASSIGNABLE_ROLES;
}
}

View File

@@ -1,15 +0,0 @@
package dev.sheldan.abstracto.assignableroles.config;
import dev.sheldan.abstracto.core.config.FeatureDefinition;
import lombok.Getter;
@Getter
public enum AssignableRoleFeatureDefinition implements FeatureDefinition {
ASSIGNABLE_ROLES("assignableRole");
private String key;
AssignableRoleFeatureDefinition(String key) {
this.key = key;
}
}

View File

@@ -1,9 +0,0 @@
package dev.sheldan.abstracto.assignableroles.config;
import dev.sheldan.abstracto.core.command.execution.CommandParameterKey;
import lombok.Getter;
@Getter
public enum AssignableRolePlaceParameterKey implements CommandParameterKey {
UNIQUE
}

View File

@@ -1,35 +0,0 @@
package dev.sheldan.abstracto.assignableroles.exception;
import dev.sheldan.abstracto.assignableroles.model.exception.AssignableRoleAlreadyDefinedExceptionModel;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.core.models.template.display.RoleDisplay;
import dev.sheldan.abstracto.core.templating.Templatable;
import net.dv8tion.jda.api.entities.Role;
/**
* Exception thrown in case the {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRole} has already been
* defined for an {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace}. This is identified
* via the emote which is used to react.
*/
public class AssignableRoleAlreadyDefinedException extends AbstractoRunTimeException implements Templatable {
private final AssignableRoleAlreadyDefinedExceptionModel model;
public AssignableRoleAlreadyDefinedException(Role role, String placeName) {
super("Assignable role already assigned");
this.model = AssignableRoleAlreadyDefinedExceptionModel
.builder()
.roleDisplay(RoleDisplay.fromRole(role))
.placeName(placeName)
.build();
}
@Override
public String getTemplateName() {
return "assignable_role_already_defined_exception";
}
@Override
public Object getTemplateModel() {
return model;
}
}

View File

@@ -1,15 +0,0 @@
package dev.sheldan.abstracto.assignableroles.exception;
import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException;
public class AssignableRoleConditionAlreadyExistsException extends AbstractoTemplatableException {
@Override
public String getTemplateName() {
return "assignable_role_condition_already_present_exception";
}
@Override
public Object getTemplateModel() {
return new Object();
}
}

View File

@@ -1,15 +0,0 @@
package dev.sheldan.abstracto.assignableroles.exception;
import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException;
public class AssignableRoleConditionDoesNotExistException extends AbstractoTemplatableException {
@Override
public String getTemplateName() {
return "assignable_role_condition_does_not_exist_exception";
}
@Override
public Object getTemplateModel() {
return new Object();
}
}

View File

@@ -1,15 +0,0 @@
package dev.sheldan.abstracto.assignableroles.exception;
import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException;
public class AssignableRoleConditionValueNotUsableException extends AbstractoTemplatableException {
@Override
public String getTemplateName() {
return "assignable_role_condition_value_not_usable_exception";
}
@Override
public Object getTemplateModel() {
return new Object();
}
}

View File

@@ -1,27 +0,0 @@
package dev.sheldan.abstracto.assignableroles.exception;
import dev.sheldan.abstracto.assignableroles.model.exception.AssignableRoleNotFoundExceptionModel;
import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException;
public class AssignableRoleNotFoundException extends AbstractoTemplatableException {
private final AssignableRoleNotFoundExceptionModel model;
public AssignableRoleNotFoundException(Long roleId) {
super("Role to assign is not available anymore.");
this.model = AssignableRoleNotFoundExceptionModel
.builder()
.roleId(roleId)
.build();
}
@Override
public String getTemplateName() {
return "assignable_role_not_found_exception";
}
@Override
public Object getTemplateModel() {
return this.model;
}
}

View File

@@ -1,34 +0,0 @@
package dev.sheldan.abstracto.assignableroles.exception;
import dev.sheldan.abstracto.assignableroles.model.exception.AssignableRoleNotUsableExceptionModel;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.core.models.template.display.RoleDisplay;
import dev.sheldan.abstracto.core.templating.Templatable;
import net.dv8tion.jda.api.entities.Role;
/**
* Exception thrown in case the defined {@link net.dv8tion.jda.api.entities.Role role} cannot be interacted with by the bot,
* because of permissions, this can happen if the role is the same or higher than the bot, therefore cannot be given to
* {@link net.dv8tion.jda.api.entities.Member members}
*/
public class AssignableRoleNotUsableException extends AbstractoRunTimeException implements Templatable {
private final AssignableRoleNotUsableExceptionModel model;
public AssignableRoleNotUsableException(Role role) {
super("Role is not usable as assignable role");
this.model = AssignableRoleNotUsableExceptionModel
.builder()
.roleDisplay(RoleDisplay.fromRole(role))
.build();
}
@Override
public String getTemplateName() {
return "assignable_role_not_usable_exception";
}
@Override
public Object getTemplateModel() {
return model;
}
}

View File

@@ -1,32 +0,0 @@
package dev.sheldan.abstracto.assignableroles.exception;
import dev.sheldan.abstracto.assignableroles.model.exception.AssignableRolePlaceAlreadyExistsExceptionModel;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.core.templating.Templatable;
/**
* Exception thrown in case the {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace place}
* identified by {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace} key
*/
public class AssignableRolePlaceAlreadyExistsException extends AbstractoRunTimeException implements Templatable {
private final AssignableRolePlaceAlreadyExistsExceptionModel model;
public AssignableRolePlaceAlreadyExistsException(String name) {
super("Assignable role place already exists");
this.model = AssignableRolePlaceAlreadyExistsExceptionModel
.builder()
.name(name)
.build();
}
@Override
public String getTemplateName() {
return "assignable_role_place_exists_exception";
}
@Override
public Object getTemplateModel() {
return model;
}
}

View File

@@ -1,33 +0,0 @@
package dev.sheldan.abstracto.assignableroles.exception;
import dev.sheldan.abstracto.assignableroles.model.exception.AssignableRolePlaceChannelDoesNotExistExceptionModel;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.core.templating.Templatable;
/**
* Exception thrown in case the {@link dev.sheldan.abstracto.core.models.database.AChannel channel} in which a
* {@link dev.sheldan.abstracto.assignableroles.model.database.AssignableRolePlace place} is defined, does not exist
*/
public class AssignableRolePlaceChannelDoesNotExistException extends AbstractoRunTimeException implements Templatable {
private final AssignableRolePlaceChannelDoesNotExistExceptionModel model;
public AssignableRolePlaceChannelDoesNotExistException(Long channelId, String placeName) {
super("Assignable role place channel does not exist");
this.model = AssignableRolePlaceChannelDoesNotExistExceptionModel
.builder()
.channelId(channelId)
.placeName(placeName)
.build();
}
@Override
public String getTemplateName() {
return "assignable_role_place_channel_does_not_exist_exception";
}
@Override
public Object getTemplateModel() {
return this.model;
}
}

View File

@@ -1,20 +0,0 @@
package dev.sheldan.abstracto.assignableroles.exception;
import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException;
public class AssignableRolePlaceIllegalConfigurationException extends AbstractoTemplatableException {
public AssignableRolePlaceIllegalConfigurationException() {
super("An illegal configuration key has been passed to configure the assignable role place config. Doing nothing.");
}
@Override
public String getTemplateName() {
return "assignable_role_place_illegal_configuration_key_exception";
}
@Override
public Object getTemplateModel() {
return new Object();
}
}

View File

@@ -1,20 +0,0 @@
package dev.sheldan.abstracto.assignableroles.exception;
import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException;
public class AssignableRolePlaceMaximumRolesException extends AbstractoTemplatableException {
public AssignableRolePlaceMaximumRolesException() {
super("The maximum amount of assignable roles have been reached.");
}
@Override
public String getTemplateName() {
return "assignable_role_place_maximum_roles_reached_exception";
}
@Override
public Object getTemplateModel() {
return new Object();
}
}

View File

@@ -1,21 +0,0 @@
package dev.sheldan.abstracto.assignableroles.exception;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.core.templating.Templatable;
public class AssignableRolePlaceNotFoundException extends AbstractoRunTimeException implements Templatable {
public AssignableRolePlaceNotFoundException() {
super("Assignable role place not found");
}
@Override
public String getTemplateName() {
return "assignable_role_place_not_found_exception";
}
@Override
public Object getTemplateModel() {
return new Object();
}
}

View File

@@ -1,33 +0,0 @@
package dev.sheldan.abstracto.assignableroles.exception;
import dev.sheldan.abstracto.assignableroles.model.exception.AssignedUserNotFoundExceptionModel;
import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException;
import dev.sheldan.abstracto.core.models.database.AUserInAServer;
import dev.sheldan.abstracto.core.templating.Templatable;
/**
* Exception which is thrown in case an {@link dev.sheldan.abstracto.assignableroles.model.database.AssignedRoleUser user}
* was not found.
*/
public class AssignedUserNotFoundException extends AbstractoRunTimeException implements Templatable {
private final AssignedUserNotFoundExceptionModel model;
public AssignedUserNotFoundException(AUserInAServer userInAServer) {
super("Assigned user was not found");
this.model = AssignedUserNotFoundExceptionModel
.builder()
.userId(userInAServer.getUserReference().getId())
.build();
}
@Override
public String getTemplateName() {
return "assignable_role_place_assigned_user_not_found_exception";
}
@Override
public Object getTemplateModel() {
return model;
}
}

View File

@@ -1,20 +0,0 @@
package dev.sheldan.abstracto.assignableroles.exception;
import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException;
public class BoosterAssignableRolePlaceMemberNotBoostingException extends AbstractoTemplatableException {
public BoosterAssignableRolePlaceMemberNotBoostingException() {
super("Clicking member does not boost");
}
@Override
public String getTemplateName() {
return "assignable_role_booster_place_member_not_boosting_exception";
}
@Override
public Object getTemplateModel() {
return new Object();
}
}

View File

@@ -1,38 +0,0 @@
package dev.sheldan.abstracto.assignableroles.model.condition;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Builder
public class AssignableRoleConditionResult {
private Boolean fulfilled;
private AssignableRoleConditionType causingCondition;
private AssignableRolePlaceConditionModel model;
public static AssignableRoleConditionResult fromFail(AssignableRoleConditionType cause, AssignableRolePlaceConditionModel model) {
return AssignableRoleConditionResult
.builder()
.causingCondition(cause)
.model(model)
.fulfilled(false)
.build();
}
public static AssignableRoleConditionResult fromFail(AssignableRoleConditionType cause) {
return AssignableRoleConditionResult
.builder()
.causingCondition(cause)
.fulfilled(false)
.build();
}
public static AssignableRoleConditionResult fromSuccess() {
return AssignableRoleConditionResult
.builder()
.fulfilled(true)
.build();
}
}

View File

@@ -1,7 +0,0 @@
package dev.sheldan.abstracto.assignableroles.model.condition;
import dev.sheldan.abstracto.core.command.execution.CommandParameterKey;
public enum AssignableRoleConditionType implements CommandParameterKey {
MIN_LEVEL
}

View File

@@ -1,14 +0,0 @@
package dev.sheldan.abstracto.assignableroles.model.condition;
import dev.sheldan.abstracto.core.models.template.display.RoleDisplay;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Builder
public class AssignableRoleMinLevelModel {
private Integer minLevel;
private RoleDisplay roleDisplay;
}

View File

@@ -1,22 +0,0 @@
package dev.sheldan.abstracto.assignableroles.model.condition;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Builder
public class AssignableRoleMinLevelResult implements AssignableRolePlaceConditionModel {
private AssignableRoleMinLevelModel model;
@Override
public String getTemplateName() {
return "assignable_role_condition_min_level";
}
@Override
public Object getTemplateModel() {
return model;
}
}

View File

@@ -1,6 +0,0 @@
package dev.sheldan.abstracto.assignableroles.model.condition;
import dev.sheldan.abstracto.core.templating.Templatable;
public interface AssignableRolePlaceConditionModel extends Templatable {
}

View File

@@ -1,100 +0,0 @@
package dev.sheldan.abstracto.assignableroles.model.database;
import dev.sheldan.abstracto.core.models.database.AEmote;
import dev.sheldan.abstracto.core.models.database.ARole;
import dev.sheldan.abstracto.core.models.database.AServer;
import dev.sheldan.abstracto.core.models.database.ComponentPayload;
import lombok.*;
import jakarta.persistence.*;
import java.io.Serializable;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
/**
* A {@link ARole role} which can be mapped to an {@link AssignableRolePlace ṕlace}. This is uniquely defined by an emote on the
* respective assignable role place, but the same role can be given via different {@link AEmote emote}
*/
@Entity
@Table(name = "assignable_role")
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@EqualsAndHashCode
public class AssignableRole implements Serializable {
/**
* The unique ID of this {@link AssignableRole assignableRole}
*/
@Id
@Column(name = "id", nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "emote_markdown")
private String emoteMarkdown;
/**
* The {@link ARole} which given via this {@link AssignableRole assignableRole}
*/
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "role_id", nullable = false)
private ARole role;
/**
* The {@link AServer server} in which this {@link AssignableRole assignableRole} is used
*/
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "server_id", nullable = false)
private AServer server;
/**
* The {@link AssignableRolePlace} this assignable role is in
*/
@ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "assignable_place_id", nullable = false)
private AssignableRolePlace assignablePlace;
/**
* The {@link AssignedRoleUser users} which currently have this role assigned via this mechanism.
* This is necessary to enforce the unique property of {@link AssignableRolePlace}, in which you only may chose one
* role.
*/
@ManyToMany(mappedBy = "roles")
@Builder.Default
private List<AssignedRoleUser> assignedUsers = new ArrayList<>();
/**
* The display text which is used for the button
*/
@Column(name = "description", nullable = false)
private String description;
@OneToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "component_id", nullable = false)
private ComponentPayload componentPayload;
/**
* The {@link Instant} this entity was created
*/
@Column(name = "created", nullable = false, insertable = false, updatable = false)
private Instant created;
/**
* The {@link Instant} this entity was updated
*/
@Column(name = "updated", insertable = false, updatable = false)
private Instant updated;
@OneToMany(
fetch = FetchType.LAZY,
cascade = {CascadeType.PERSIST, CascadeType.MERGE},
orphanRemoval = true,
mappedBy = "assignableRole"
)
@Builder.Default
private List<AssignableRoleCondition> conditions = new ArrayList<>();
}

View File

@@ -1,34 +0,0 @@
package dev.sheldan.abstracto.assignableroles.model.database;
import dev.sheldan.abstracto.assignableroles.model.condition.AssignableRoleConditionType;
import lombok.*;
import jakarta.persistence.*;
@Entity
@Table(name = "assignable_role_condition")
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@EqualsAndHashCode
public class AssignableRoleCondition {
@Id
@Column(name = "id", nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Getter
@Enumerated(EnumType.STRING)
@Column(name = "type")
private AssignableRoleConditionType type;
@ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "assignable_role_id", nullable = false)
private AssignableRole assignableRole;
@Column(name = "condition_value")
private String conditionValue;
}

View File

@@ -1,92 +0,0 @@
package dev.sheldan.abstracto.assignableroles.model.database;
import dev.sheldan.abstracto.core.models.database.AChannel;
import dev.sheldan.abstracto.core.models.database.AServer;
import lombok.*;
import jakarta.persistence.*;
import java.io.Serializable;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
@Entity
@Table(name = "assignable_role_place")
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@EqualsAndHashCode
public class AssignableRolePlace implements Serializable {
public static final Long ASSIGNABLE_PLACE_NAME_LIMIT = 255L;
public static final Long ASSIGNABLE_PLACE_DESCRIPTION_LIMIT = 255L;
/**
* A unique ID created
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private Long id;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name="channel_id", nullable = false)
private AChannel channel;
/**
* The {@link AServer server} for which this place is configured for. Unique in combination with the key
*/
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "server_id", nullable = false)
private AServer server;
/**
* The key this place is associated with via commands. Unique per server.
*/
@Column(name = "key", nullable = false)
private String key;
/**
* A List containing the {@link AssignableRole} which are associated with this place
*/
@OneToMany(
fetch = FetchType.LAZY,
cascade = {CascadeType.PERSIST, CascadeType.MERGE},
orphanRemoval = true,
mappedBy = "assignablePlace"
)
@Builder.Default
private List<AssignableRole> assignableRoles = new ArrayList<>();
@Column(name = "message_id")
private Long messageId;
@Column(name = "text", nullable = false)
private String text;
/**
* Whether or not it should be restricted, that a {@link AssignedRoleUser} should only have one role of this place
*/
@Builder.Default
@Column(name = "unique_roles", nullable = false)
private Boolean uniqueRoles = false;
/**
* The {@link Instant} this entity was created
*/
@Column(name = "created", nullable = false, insertable = false, updatable = false)
private Instant created;
/**
* The {@link Instant} this entity was updated
*/
@Column(name = "updated", insertable = false, updatable = false)
private Instant updated;
@Enumerated(EnumType.STRING)
@Column(name = "type")
private AssignableRolePlaceType type;
}

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