Compare commits
360 Commits
d2d898a5b8
...
master
Author | SHA1 | Date | |
---|---|---|---|
7f935da4b4 | |||
f3aad3925a | |||
ae741e1f13 | |||
b78ef6e96c | |||
d3661127cf | |||
fc1216be25 | |||
38089bdcd5 | |||
c424694068 | |||
b3a6284e40 | |||
5f099a97f0 | |||
577c895169 | |||
6db2a01bb3 | |||
4cc4334df4 | |||
a4acdc2ec1 | |||
7ca984e785 | |||
53730a82cf | |||
6f4a787ccb | |||
2b588a5940 | |||
fe4cf3bbf4 | |||
ede931f994 | |||
d5ed2b0b13 | |||
4479bce0a4 | |||
3c80b3ca4b | |||
65fd68f76c | |||
6640dd4368 | |||
96cb634fd4 | |||
0f9a23e4a2 | |||
eb3d8eea29 | |||
7e45b5d880 | |||
892b85ccb4 | |||
f291344c45 | |||
df9b0e2604 | |||
2695a2994a | |||
fa50eb9873 | |||
58bb976f96 | |||
3615ef4b92 | |||
5c78ec907f | |||
c380878039 | |||
cfaa501377 | |||
6f12062311 | |||
3edfab3adb | |||
25d4b247b3 | |||
393c7741ca | |||
001836c88b | |||
be7e03d641 | |||
db357a63f5 | |||
e50fe57ee6 | |||
2c017d0603 | |||
f32d278a6c | |||
b8ebc1de24 | |||
2b2e10d994 | |||
8526036044 | |||
f5c31195da | |||
d6175b3f92 | |||
96e7518f72 | |||
f1bc2b2aaa | |||
4ec65c8d6e | |||
38465f544d | |||
a3f4e2b918 | |||
bc57834366 | |||
87a56700ec | |||
6d98977198 | |||
1256d2ddf9 | |||
7cf970df77 | |||
52557b5c65 | |||
898a39e99c | |||
7a66ed4d87 | |||
5cc504d4ed | |||
29b44edc6b | |||
2a7e2acc88 | |||
0d92a49d95 | |||
2d8779d8e0 | |||
765805fa7a | |||
1d36479a82 | |||
9d6f3b9fef | |||
9be60fee4c | |||
cb82716a17 | |||
80439a3329 | |||
627062ef23 | |||
25dd6cb0dc | |||
217b284f14 | |||
843bb34fb4 | |||
8a01359f6e | |||
8f85ce91da | |||
93f232805e | |||
41f92400c7 | |||
585d3e0793 | |||
b5ac5d6a9b | |||
d9dd175174 | |||
7a1ffc0538 | |||
04c4533c40 | |||
353962e569 | |||
d0ba6e72a4 | |||
b63b25f8ab | |||
2627b80148 | |||
16bbda57f6 | |||
e65b7b8232 | |||
d90bdfe3b6 | |||
8def168ef7 | |||
9379ebb33d | |||
bbbbce557b | |||
6fef1d0092 | |||
f7aba7a49b | |||
514f4757a9 | |||
ee7e8b64c5 | |||
6de1e8b2b1 | |||
98e9003129 | |||
9d78432211 | |||
60ce8df108 | |||
ab5cec535b | |||
ec9b0cc862 | |||
d45cd48ff6 | |||
3126935057 | |||
27244d0d98 | |||
de1da2391d | |||
9395ae73b9 | |||
fa932b7fc2 | |||
bd340448a1 | |||
45460f8b90 | |||
fbb292a591 | |||
31aad2744c | |||
35b8fff808 | |||
8cc465e53d | |||
ec54d5427e | |||
07c5a7358b | |||
4aae21b594 | |||
650556079b | |||
29d3fe3701 | |||
4cc48412f7 | |||
ccdeebdc1c | |||
6dc801dda6 | |||
d01c7d4965 | |||
0e33179260 | |||
36d29caa7a | |||
a605ab2dba | |||
863206bb9f | |||
a7af4108c6 | |||
fdd36d4385 | |||
0cfccc70d8 | |||
2791d6328e | |||
b4f4a12da8 | |||
bb81c098b2 | |||
bef2b695f5 | |||
d575e0ec9e | |||
4f97e181a7 | |||
b5b306cc6d | |||
5b917af1ca | |||
0b09b8ba5f | |||
4e866895a0 | |||
f6a23e4888 | |||
75da7a4b51 | |||
313f43172d | |||
6efb042f14 | |||
9be80a0f7e | |||
cd9563f77e | |||
0ba532a9b5 | |||
96c4e03e81 | |||
3995bf9992 | |||
8946a18b0b | |||
6ebfb4b289 | |||
35223c376a | |||
f637faf0b6 | |||
16e956d718 | |||
ee62eae519 | |||
f7aea851b2 | |||
0e781f3d9a | |||
0c6f3a0b4c | |||
c78033f409 | |||
9a5609f40e | |||
7abdcd4d95 | |||
92a0c23b49 | |||
65ba1d91ac | |||
4ae2e7566a | |||
5e17f655a4 | |||
11299b3ca7 | |||
d023e21575 | |||
d70a29d363 | |||
7bf468b470 | |||
0d9b6ed8f8 | |||
69adc56e4e | |||
57d5dc0c42 | |||
ee1b2e0ae0 | |||
65af4c8c16 | |||
47b4796695 | |||
4fdd00453a | |||
e19334a9ef | |||
66a2d8b2a9 | |||
cbc28701c9 | |||
de6eabc1b7 | |||
26fddc0493 | |||
50796d00f0 | |||
bf2e046718 | |||
05bc0f0a41 | |||
21e7ddf549 | |||
14ff692b87 | |||
26b7b7158a | |||
626a9bd77d | |||
06ded19492 | |||
6ba802912f | |||
c284bb8a7f | |||
dbe6fb4762 | |||
a0e0b82f40 | |||
96e675a6be | |||
ed79a46af3 | |||
ee138cb5a9 | |||
45bfae281e | |||
52d4b65d92 | |||
5b0f06efc2 | |||
43c5473a4f | |||
dc04a2f36a | |||
407ee6f1e9 | |||
09d850146a | |||
e8fa4c72dd | |||
c31ec09e0f | |||
4148f6e05f | |||
0120fa24ef | |||
4a522c084d | |||
188124991e | |||
7f09c6d06c | |||
e873988c47 | |||
79d20672c5 | |||
772787a98e | |||
b6ba778ff2 | |||
cdd953351a | |||
c1d775c9d0 | |||
a4e3598986 | |||
8cdc2a853b | |||
f940bd526c | |||
490080b17a | |||
595c61e789 | |||
040c644ab1 | |||
fa1f18e11b | |||
ece36f7f27 | |||
3b3ea2b3cc | |||
c98d8d7e26 | |||
49beb864d2 | |||
750b8cbfea | |||
2fcc1b66c1 | |||
040846ef0a | |||
96486bb3a1 | |||
78daf4531b | |||
a9e4626dfd | |||
dc7e44239f | |||
2349f10b35 | |||
bd9f4ef971 | |||
6698b7c656 | |||
0a80db8195 | |||
a3af3c3637 | |||
34102e9b22 | |||
7083bebef1 | |||
c81835cb2d | |||
80e7afedea | |||
285a0ca00a | |||
f07e30d843 | |||
bd9ac1e138 | |||
3878d3029b | |||
831bc934b4 | |||
938005f6d9 | |||
5959b814a7 | |||
5f75302f3a | |||
a7a7bc784b | |||
2b4980fb10 | |||
655662c6f8 | |||
642185f8c5 | |||
c2e447f416 | |||
271a1cf88d | |||
11e7ca4aa6 | |||
f6834db9cb | |||
90aaf5422f | |||
e4183b4882 | |||
f62a022ed5 | |||
50b8b4b2c1 | |||
920755eae0 | |||
2255b02a60 | |||
f30697d1a6 | |||
83250d2c08 | |||
d7916ad24a | |||
295d673d06 | |||
da06a01097 | |||
6202aa6691 | |||
82a87c79b2 | |||
e795d542b9 | |||
162d7af46b | |||
821190a144 | |||
cb35182c6a | |||
ac499898e3 | |||
35596b720b | |||
048d2856f9 | |||
5f654f9ca6 | |||
4540bdef99 | |||
eda4eb5973 | |||
68a9a6dc48 | |||
ff23ea1d6c | |||
982c038b07 | |||
52223b5233 | |||
45755503a7 | |||
194a5d8119 | |||
120afee73b | |||
8b7340715c | |||
38bde93d16 | |||
a3ffaf1ab9 | |||
86c147f359 | |||
deb93e442c | |||
6eca92b4cf | |||
3f93df131d | |||
1028dca15a | |||
e03aef0ad5 | |||
8ce3a5d25c | |||
0b8caf3e25 | |||
317eaaec8a | |||
4f975ab07a | |||
1a69bce9dd | |||
37c69597be | |||
3146ed7d6d | |||
69281d113c | |||
c6289d1c8e | |||
3082265ec6 | |||
a057853cbd | |||
8b451c6ee5 | |||
727a4c9a6f | |||
4bf099d25e | |||
20c5f71cd4 | |||
a6e490dbe5 | |||
87bf0b9f67 | |||
419bdf1fea | |||
f2b2dbc794 | |||
8361f3c784 | |||
52349a17c3 | |||
c1f9bfec6a | |||
be7f8a9057 | |||
c93e112ebf | |||
7485bd2ec8 | |||
ed83175a39 | |||
a001f2dd4c | |||
b1785ce373 | |||
b1f5db9b2d | |||
d372c41c98 | |||
f566c3bcb5 | |||
6403c57db5 | |||
22d4558d84 | |||
ea546f02ca | |||
5b1ddb145f | |||
5ce5ef6898 | |||
729e0b482b | |||
5aa56c2955 | |||
ee6456e4d8 | |||
93350f1506 | |||
702aead53a | |||
b7f2b6a3d7 | |||
b66114503c | |||
50391e5344 | |||
91ecc9882c | |||
06a2584e63 | |||
29affe2f12 | |||
86c7afac42 | |||
b0949d17e6 | |||
df44ae90b9 | |||
4821e2a4fa | |||
4cb34fbb9a | |||
d824f957fe |
2
.mvn/wrapper/maven-wrapper.properties
vendored
2
.mvn/wrapper/maven-wrapper.properties
vendored
@ -16,4 +16,4 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
wrapperVersion=3.3.2
|
wrapperVersion=3.3.2
|
||||||
distributionType=only-script
|
distributionType=only-script
|
||||||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.7/apache-maven-3.9.7-bin.zip
|
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# Stage 1: Build the application
|
# Stage 1: Build the application
|
||||||
FROM maven:3.9.6-eclipse-temurin-17-alpine AS builder
|
FROM maven:3.9.9-eclipse-temurin-17-alpine AS builder
|
||||||
|
|
||||||
# Set the working directory
|
# Set the working directory
|
||||||
WORKDIR /home/container
|
WORKDIR /home/container
|
||||||
@ -11,7 +11,7 @@ COPY . .
|
|||||||
RUN mvn package -q -Dmaven.test.skip -DskipTests -T2C
|
RUN mvn package -q -Dmaven.test.skip -DskipTests -T2C
|
||||||
|
|
||||||
# Stage 2: Create the final lightweight image
|
# Stage 2: Create the final lightweight image
|
||||||
FROM eclipse-temurin:17.0.11_9-jre-focal
|
FROM eclipse-temurin:17.0.13_11-jre-focal
|
||||||
|
|
||||||
# Set the working directory
|
# Set the working directory
|
||||||
WORKDIR /home/container
|
WORKDIR /home/container
|
||||||
|
62
pom.xml
62
pom.xml
@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-parent</artifactId>
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
<version>3.3.1</version>
|
<version>3.4.1</version>
|
||||||
<relativePath/> <!-- lookup parent from repository -->
|
<relativePath/> <!-- lookup parent from repository -->
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
@ -41,7 +41,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
<version>3.5.3</version>
|
<version>3.6.0</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||||
</configuration>
|
</configuration>
|
||||||
@ -70,6 +70,12 @@
|
|||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>jitpack.io</id>
|
||||||
|
<url>https://jitpack.io</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<!-- Spring -->
|
<!-- Spring -->
|
||||||
@ -85,47 +91,69 @@
|
|||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-websocket</artifactId>
|
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.sentry</groupId>
|
||||||
|
<artifactId>sentry-spring-boot-starter-jakarta</artifactId>
|
||||||
|
<version>7.16.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Redis for caching -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>io.lettuce</groupId>
|
||||||
|
<artifactId>lettuce-core</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>redis.clients</groupId>
|
||||||
|
<artifactId>jedis</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
<!-- Libraries -->
|
<!-- Libraries -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.projectlombok</groupId>
|
<groupId>org.projectlombok</groupId>
|
||||||
<artifactId>lombok</artifactId>
|
<artifactId>lombok</artifactId>
|
||||||
<version>1.18.32</version>
|
<version>1.18.34</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Dependencies -->
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.dv8tion</groupId>
|
<groupId>io.github.freya022</groupId>
|
||||||
<artifactId>JDA</artifactId>
|
<artifactId>JDA</artifactId>
|
||||||
<version>5.0.0-beta.24</version>
|
<version>2ed819ad15</version>
|
||||||
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.code.gson</groupId>
|
<groupId>com.google.code.gson</groupId>
|
||||||
<artifactId>gson</artifactId>
|
<artifactId>gson</artifactId>
|
||||||
<version>2.10.1</version>
|
<version>2.11.0</version>
|
||||||
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.httpcomponents.client5</groupId>
|
<groupId>org.apache.httpcomponents.client5</groupId>
|
||||||
<artifactId>httpclient5</artifactId>
|
<artifactId>httpclient5</artifactId>
|
||||||
<version>5.3.1</version>
|
<version>5.4.1</version>
|
||||||
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.jodah</groupId>
|
<groupId>net.jodah</groupId>
|
||||||
<artifactId>expiringmap</artifactId>
|
<artifactId>expiringmap</artifactId>
|
||||||
<version>0.5.11</version>
|
<version>0.5.11</version>
|
||||||
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>se.michaelthelin.spotify</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>spotify-web-api-java</artifactId>
|
<artifactId>commons-text</artifactId>
|
||||||
<version>8.4.0</version>
|
<version>1.12.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- Test Dependencies -->
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>com.github.Steppschuh</groupId>
|
||||||
<artifactId>spring-boot-starter-test</artifactId>
|
<artifactId>Java-Markdown-Generator</artifactId>
|
||||||
<scope>test</scope>
|
<version>1.3.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
34
privacy-policy.txt
Normal file
34
privacy-policy.txt
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
Privacy Policy
|
||||||
|
|
||||||
|
1. Introduction
|
||||||
|
|
||||||
|
This Privacy Policy explains how Bat ("we", "us", "our") collects, uses, and protects your information when you use our Discord bot (the "Service").
|
||||||
|
2. Information We Collect
|
||||||
|
|
||||||
|
User Data: When you interact with our bot, we may collect your Discord user ID, server ID, and any messages or commands you send to the bot.
|
||||||
|
Usage Data: We may collect data on how you interact with the bot, such as commands used and features accessed.
|
||||||
|
|
||||||
|
3. How We Use Your Information
|
||||||
|
|
||||||
|
Service Operation: To provide, maintain, and improve the Service.
|
||||||
|
Communication: To respond to your inquiries and provide customer support.
|
||||||
|
Analytics: To analyze usage trends and improve the Service.
|
||||||
|
|
||||||
|
4. Data Sharing
|
||||||
|
|
||||||
|
We do not sell or rent your information to third parties. We may share your information with third-party service providers who assist us in operating the Service, under confidentiality agreements.
|
||||||
|
5. Data Security
|
||||||
|
|
||||||
|
We implement appropriate technical and organizational measures to protect your information from unauthorized access, loss, or misuse.
|
||||||
|
6. Data Retention
|
||||||
|
|
||||||
|
We retain your information for as long as necessary to fulfill the purposes outlined in this Privacy Policy, unless a longer retention period is required or permitted by law.
|
||||||
|
7. Your Rights
|
||||||
|
|
||||||
|
You have the right to access, correct, or delete your personal information. To exercise these rights, please contact us at bat@fascinated.cc.
|
||||||
|
8. Changes to This Privacy Policy
|
||||||
|
|
||||||
|
We may update this Privacy Policy from time to time. We will notify you of any changes by posting the new Privacy Policy on our https://discord.gg/yjj2U3ctEG.
|
||||||
|
9. Contact Us
|
||||||
|
|
||||||
|
If you have any questions about this Privacy Policy, please contact us at bat@fascinated.cc.
|
3
renovate.json
Normal file
3
renovate.json
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"extends": ["config:recommended", ":dependencyDashboard"]
|
||||||
|
}
|
@ -1,5 +1,8 @@
|
|||||||
package cc.fascinated.bat;
|
package cc.fascinated.bat;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.config.Config;
|
||||||
|
import cc.fascinated.bat.event.EventListener;
|
||||||
|
import cc.fascinated.bat.service.EventService;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
@ -7,6 +10,7 @@ import lombok.SneakyThrows;
|
|||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@ -33,7 +37,20 @@ public class BatApplication {
|
|||||||
}
|
}
|
||||||
log.info("Found configuration at '{}'", config.getAbsolutePath()); // Log the found config
|
log.info("Found configuration at '{}'", config.getAbsolutePath()); // Log the found config
|
||||||
|
|
||||||
// Start the app
|
// Start the application
|
||||||
SpringApplication.run(BatApplication.class, args);
|
SpringApplication app = new SpringApplication(BatApplication.class);
|
||||||
|
app.setRegisterShutdownHook(false); // Disable the default shutdown hook
|
||||||
|
ConfigurableApplicationContext context = app.run(args);
|
||||||
|
|
||||||
|
// Register the shutdown hook
|
||||||
|
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
||||||
|
log.info("Shutting down...");
|
||||||
|
for (EventListener listener : EventService.LISTENERS) {
|
||||||
|
listener.onShutdown();
|
||||||
|
}
|
||||||
|
context.close();
|
||||||
|
}));
|
||||||
|
|
||||||
|
log.info("APP IS RUNNING IN %s MODE!!!!!!!!!".formatted(Config.isProduction() ? "PRODUCTION" : "DEVELOPMENT"));
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -4,8 +4,9 @@ package cc.fascinated.bat;
|
|||||||
* @author Fascinated (fascinated7)
|
* @author Fascinated (fascinated7)
|
||||||
*/
|
*/
|
||||||
public class Consts {
|
public class Consts {
|
||||||
public static final String INVITE_URL = "https://discord.com/oauth2/authorize?client_id=1254161119975833652&permissions=8&integration_type=0&scope=bot+applications.commands";
|
public static final String INVITE_URL = "https://dsc.gg/batbot";
|
||||||
public static final String SUPPORT_INVITE_URL = "https://discord.gg/invite/yjj2U3ctEG";
|
public static final String SUPPORT_INVITE_URL = "https://discord.gg/invite/yjj2U3ctEG";
|
||||||
public static String BOT_OWNER = "474221560031608833";
|
public static final String BOT_OWNER = "474221560031608833";
|
||||||
public static String ADMIN_GUILD = "1203163422498361404";
|
public static final String PRIVACY_POLICY_URL = "https://git.fascinated.cc/Fascinated/Bat/raw/branch/master/privacy-policy.txt";
|
||||||
|
public static final String TERMS_OF_SERVICE_URL = "https://git.fascinated.cc/Fascinated/Bat/raw/branch/master/terms-of-service.txt";
|
||||||
}
|
}
|
||||||
|
35
src/main/java/cc/fascinated/bat/Emojis.java
Normal file
35
src/main/java/cc/fascinated/bat/Emojis.java
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package cc.fascinated.bat;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.service.DiscordService;
|
||||||
|
import lombok.extern.log4j.Log4j2;
|
||||||
|
import net.dv8tion.jda.api.JDA;
|
||||||
|
import net.dv8tion.jda.api.entities.emoji.Emoji;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Log4j2(topic = "Emojis")
|
||||||
|
public class Emojis {
|
||||||
|
public static final Emoji SPOTIFY_EMOJI;
|
||||||
|
public static final Emoji CHECK_MARK_EMOJI;
|
||||||
|
public static final Emoji CROSS_MARK_EMOJI;
|
||||||
|
public static final Emoji SAD_FACE_EMOJI;
|
||||||
|
public static final Emoji PAUSE_EMOJI;
|
||||||
|
public static final Emoji PLAY_EMOJI;
|
||||||
|
public static final Emoji SKIP_EMOJI;
|
||||||
|
public static final Emoji HOME_EMOJI;
|
||||||
|
|
||||||
|
static {
|
||||||
|
log.info("Loading emojis...");
|
||||||
|
JDA jda = DiscordService.JDA;
|
||||||
|
SPOTIFY_EMOJI = jda.getEmojiById("1256629771975266479");
|
||||||
|
CHECK_MARK_EMOJI = jda.getEmojiById("1258922852669853817");
|
||||||
|
CROSS_MARK_EMOJI = jda.getEmojiById("1256634487429922897");
|
||||||
|
SAD_FACE_EMOJI = jda.getEmojiById("1256636078258131055");
|
||||||
|
PAUSE_EMOJI = Emoji.fromUnicode("⏸");
|
||||||
|
PLAY_EMOJI = Emoji.fromUnicode("▶");
|
||||||
|
SKIP_EMOJI = Emoji.fromUnicode("⏭");
|
||||||
|
HOME_EMOJI = Emoji.fromUnicode("🏠");
|
||||||
|
log.info("Loaded emojis!");
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,8 @@
|
|||||||
package cc.fascinated.bat.features.afk;
|
package cc.fascinated.bat.afk;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.Category;
|
import cc.fascinated.bat.common.feature.Feature;
|
||||||
import cc.fascinated.bat.features.Feature;
|
import cc.fascinated.bat.common.feature.FeatureProfile;
|
||||||
import cc.fascinated.bat.features.afk.command.AfkCommand;
|
import cc.fascinated.bat.afk.command.AfkCommand;
|
||||||
import cc.fascinated.bat.service.CommandService;
|
import cc.fascinated.bat.service.CommandService;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
@ -14,7 +14,7 @@ import org.springframework.stereotype.Component;
|
|||||||
@Component
|
@Component
|
||||||
public class AfkFeature extends Feature {
|
public class AfkFeature extends Feature {
|
||||||
public AfkFeature(@NonNull ApplicationContext context, @NonNull CommandService commandService) {
|
public AfkFeature(@NonNull ApplicationContext context, @NonNull CommandService commandService) {
|
||||||
super("AFK", Category.GENERAL);
|
super("AFK", FeatureProfile.FeatureState.DISABLED, true);
|
||||||
|
|
||||||
registerCommand(commandService, context.getBean(AfkCommand.class));
|
registerCommand(commandService, context.getBean(AfkCommand.class));
|
||||||
}
|
}
|
@ -1,9 +1,9 @@
|
|||||||
package cc.fascinated.bat.features.afk;
|
package cc.fascinated.bat.afk;
|
||||||
|
|
||||||
import cc.fascinated.bat.event.EventListener;
|
import cc.fascinated.bat.event.EventListener;
|
||||||
import cc.fascinated.bat.features.afk.profile.AfkProfile;
|
import cc.fascinated.bat.afk.profile.AfkProfile;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.entities.Message;
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
import net.dv8tion.jda.api.entities.User;
|
import net.dv8tion.jda.api.entities.User;
|
@ -1,13 +1,11 @@
|
|||||||
package cc.fascinated.bat.features.afk;
|
package cc.fascinated.bat.afk;
|
||||||
|
|
||||||
import cc.fascinated.bat.event.EventListener;
|
import cc.fascinated.bat.event.EventListener;
|
||||||
import cc.fascinated.bat.features.afk.profile.AfkProfile;
|
import cc.fascinated.bat.afk.profile.AfkProfile;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
import cc.fascinated.bat.service.GuildService;
|
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -15,13 +13,6 @@ import org.springframework.stereotype.Component;
|
|||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class AfkReturnListener implements EventListener {
|
public class AfkReturnListener implements EventListener {
|
||||||
private final GuildService guildService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public AfkReturnListener(@NonNull GuildService guildService) {
|
|
||||||
this.guildService = guildService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onGuildMessageReceive(@NonNull BatGuild guild, @NonNull BatUser user, @NonNull MessageReceivedEvent event) {
|
public void onGuildMessageReceive(@NonNull BatGuild guild, @NonNull BatUser user, @NonNull MessageReceivedEvent event) {
|
||||||
AfkProfile profile = guild.getProfile(AfkProfile.class);
|
AfkProfile profile = guild.getProfile(AfkProfile.class);
|
||||||
@ -29,7 +20,6 @@ public class AfkReturnListener implements EventListener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
profile.removeAfkUser(guild, user.getId());
|
profile.removeAfkUser(guild, user.getId());
|
||||||
guildService.saveGuild(guild);
|
|
||||||
event.getMessage().reply("Welcome back, %s! You are no longer AFK.".formatted(user.getDiscordUser().getAsMention())).queue();
|
event.getMessage().reply("Welcome back, %s! You are no longer AFK.".formatted(user.getDiscordUser().getAsMention())).queue();
|
||||||
}
|
}
|
||||||
}
|
}
|
57
src/main/java/cc/fascinated/bat/afk/command/AfkCommand.java
Normal file
57
src/main/java/cc/fascinated/bat/afk/command/AfkCommand.java
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
package cc.fascinated.bat.afk.command;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
|
import cc.fascinated.bat.common.command.Category;
|
||||||
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
|
import cc.fascinated.bat.common.MemberUtils;
|
||||||
|
import cc.fascinated.bat.afk.profile.AfkProfile;
|
||||||
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@CommandInfo(name = "afk", description = "Sets your AFK status", category = Category.GENERAL)
|
||||||
|
public class AfkCommand extends BatCommand {
|
||||||
|
public AfkCommand() {
|
||||||
|
super.addOptions(new OptionData(OptionType.STRING, "reason", "The reason for being AFK", false));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fired when this command is executed.
|
||||||
|
*
|
||||||
|
* @param guild the guild the command was executed in, if any
|
||||||
|
* @param user the user who executed the command
|
||||||
|
* @param channel the channel the command was executed in
|
||||||
|
* @param member the member who executed the command, null if not a guild
|
||||||
|
* @param commandMessage
|
||||||
|
* @param arguments
|
||||||
|
* @param event the event that invoked this command
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
|
AfkProfile profile = guild.getProfile(AfkProfile.class);
|
||||||
|
String reason = null;
|
||||||
|
OptionMapping reasonOption = event.getOption("reason");
|
||||||
|
if (reasonOption != null) {
|
||||||
|
reason = reasonOption.getAsString();
|
||||||
|
}
|
||||||
|
|
||||||
|
profile.addAfkUser(guild, member.getId(), reason);
|
||||||
|
event.reply("You are now AFK: %s%s".formatted(
|
||||||
|
profile.getAfkReason(member.getId()),
|
||||||
|
MemberUtils.hasPermissionToEdit(guild, user) ? "" :
|
||||||
|
"\n\n*I do not have enough permissions to edit your user, and therefore cannot update your nickname*"
|
||||||
|
)).queue();
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,12 @@
|
|||||||
package cc.fascinated.bat.features.afk.profile;
|
package cc.fascinated.bat.afk.profile;
|
||||||
|
|
||||||
import cc.fascinated.bat.common.Profile;
|
import cc.fascinated.bat.common.Serializable;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
import net.dv8tion.jda.api.entities.Guild;
|
import net.dv8tion.jda.api.entities.Guild;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import org.bson.Document;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -13,7 +16,8 @@ import java.util.Map;
|
|||||||
* @author Fascinated (fascinated7)
|
* @author Fascinated (fascinated7)
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class AfkProfile extends Profile {
|
@NoArgsConstructor
|
||||||
|
public class AfkProfile extends Serializable {
|
||||||
private static final String DEFAULT_REASON = "Away";
|
private static final String DEFAULT_REASON = "Away";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -98,4 +102,21 @@ public class AfkProfile extends Profile {
|
|||||||
public void reset() {
|
public void reset() {
|
||||||
afkUsers = new HashMap<>();
|
afkUsers = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void load(Document document, Gson gson) {
|
||||||
|
afkUsers = new HashMap<>();
|
||||||
|
for (String key : document.keySet()) {
|
||||||
|
afkUsers.put(key, document.getString(key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Document serialize(Gson gson) {
|
||||||
|
Document document = new Document();
|
||||||
|
for (String key : afkUsers.keySet()) {
|
||||||
|
document.put(key, afkUsers.get(key));
|
||||||
|
}
|
||||||
|
return document;
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,8 +1,8 @@
|
|||||||
package cc.fascinated.bat.features.autorole;
|
package cc.fascinated.bat.autorole;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.Category;
|
import cc.fascinated.bat.common.feature.Feature;
|
||||||
import cc.fascinated.bat.features.Feature;
|
import cc.fascinated.bat.common.feature.FeatureProfile;
|
||||||
import cc.fascinated.bat.features.autorole.command.AutoRoleCommand;
|
import cc.fascinated.bat.autorole.command.AutoRoleCommand;
|
||||||
import cc.fascinated.bat.service.CommandService;
|
import cc.fascinated.bat.service.CommandService;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@ -16,7 +16,7 @@ import org.springframework.stereotype.Component;
|
|||||||
public class AutoRoleFeature extends Feature {
|
public class AutoRoleFeature extends Feature {
|
||||||
@Autowired
|
@Autowired
|
||||||
public AutoRoleFeature(@NonNull ApplicationContext context, @NonNull CommandService commandService) {
|
public AutoRoleFeature(@NonNull ApplicationContext context, @NonNull CommandService commandService) {
|
||||||
super("AutoRole", Category.SERVER);
|
super("Auto Role", FeatureProfile.FeatureState.DISABLED, true);
|
||||||
|
|
||||||
registerCommand(commandService, context.getBean(AutoRoleCommand.class));
|
registerCommand(commandService, context.getBean(AutoRoleCommand.class));
|
||||||
}
|
}
|
@ -1,13 +1,15 @@
|
|||||||
package cc.fascinated.bat.features.autorole;
|
package cc.fascinated.bat.autorole;
|
||||||
|
|
||||||
import cc.fascinated.bat.event.EventListener;
|
import cc.fascinated.bat.event.EventListener;
|
||||||
import cc.fascinated.bat.features.autorole.profile.AutoRoleProfile;
|
import cc.fascinated.bat.autorole.profile.AutoRoleProfile;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
|
import cc.fascinated.bat.service.FeatureService;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
import net.dv8tion.jda.api.entities.Role;
|
import net.dv8tion.jda.api.entities.Role;
|
||||||
import net.dv8tion.jda.api.events.guild.member.GuildMemberJoinEvent;
|
import net.dv8tion.jda.api.events.guild.member.GuildMemberJoinEvent;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -17,10 +19,22 @@ import java.util.List;
|
|||||||
* @author Fascinated (fascinated7)
|
* @author Fascinated (fascinated7)
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
@Log4j2
|
@Log4j2(topic = "AutoRole Listener")
|
||||||
public class AutoRoleListener implements EventListener {
|
public class AutoRoleListener implements EventListener {
|
||||||
|
private final FeatureService featureService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public AutoRoleListener(@NonNull FeatureService featureService) {
|
||||||
|
this.featureService = featureService;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onGuildMemberJoin(@NonNull BatGuild guild, @NonNull BatUser user, @NonNull GuildMemberJoinEvent event) {
|
public void onGuildMemberJoin(@NonNull BatGuild guild, @NonNull BatUser user, @NonNull GuildMemberJoinEvent event) {
|
||||||
|
AutoRoleFeature autoRoleFeature = featureService.getFeature(AutoRoleFeature.class);
|
||||||
|
if (!guild.getFeatureProfile().isFeatureEnabled(autoRoleFeature)) { // Check if the feature is enabled
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
AutoRoleProfile profile = guild.getProfile(AutoRoleProfile.class);
|
AutoRoleProfile profile = guild.getProfile(AutoRoleProfile.class);
|
||||||
if (profile.getRoles().isEmpty()) {
|
if (profile.getRoles().isEmpty()) {
|
||||||
return;
|
return;
|
||||||
@ -35,7 +49,11 @@ public class AutoRoleListener implements EventListener {
|
|||||||
event.getGuild().addRoleToMember(event.getMember(), role).queue();
|
event.getGuild().addRoleToMember(event.getMember(), role).queue();
|
||||||
}
|
}
|
||||||
toRemove.forEach(profile::removeRole);
|
toRemove.forEach(profile::removeRole);
|
||||||
log.info("Gave user \"{}\" {} auto roles{}", user.getId(), profile.getRoles().size(), toRemove.isEmpty() ? ""
|
log.info("Gave user \"{}\" {} auto roles in guild \"{}\"{}",
|
||||||
: " and removed %s invalid roles".formatted(toRemove.size()));
|
user.getId(),
|
||||||
|
profile.getRoles().size(),
|
||||||
|
guild.getName(),
|
||||||
|
toRemove.isEmpty() ? "" : " and removed %s invalid roles from the profile".formatted(toRemove.size())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,20 +1,21 @@
|
|||||||
package cc.fascinated.bat.features.autorole.command;
|
package cc.fascinated.bat.autorole.command;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatSubCommand;
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
import cc.fascinated.bat.common.RoleUtils;
|
import cc.fascinated.bat.common.RoleUtils;
|
||||||
import cc.fascinated.bat.features.autorole.profile.AutoRoleProfile;
|
import cc.fascinated.bat.autorole.profile.AutoRoleProfile;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
import cc.fascinated.bat.service.GuildService;
|
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
import net.dv8tion.jda.api.entities.Role;
|
import net.dv8tion.jda.api.entities.Role;
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
||||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||||
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@ -23,40 +24,32 @@ import org.springframework.stereotype.Component;
|
|||||||
*/
|
*/
|
||||||
@Component("autoroles:add.sub")
|
@Component("autoroles:add.sub")
|
||||||
@CommandInfo(name = "add", description = "Adds a role to the auto roles list")
|
@CommandInfo(name = "add", description = "Adds a role to the auto roles list")
|
||||||
public class AddSubCommand extends BatSubCommand {
|
public class AddSubCommand extends BatCommand {
|
||||||
private final GuildService guildService;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public AddSubCommand(@NonNull GuildService guildService) {
|
public AddSubCommand() {
|
||||||
super.addOption(OptionType.ROLE, "role", "The role to add", true);
|
super.addOptions(new OptionData(OptionType.ROLE, "role", "The role to add", true));
|
||||||
this.guildService = guildService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction interaction) {
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
AutoRoleProfile profile = guild.getProfile(AutoRoleProfile.class);
|
AutoRoleProfile profile = guild.getProfile(AutoRoleProfile.class);
|
||||||
// Check if the guild has reached the maximum auto roles count
|
// Check if the guild has reached the maximum auto roles count
|
||||||
int maxRoleSlots = AutoRoleProfile.getMaxRoleSlots(guild);
|
int maxRoleSlots = AutoRoleProfile.getMaxRoleSlots(guild);
|
||||||
if (profile.getRoleSlotsInUse() >= maxRoleSlots) {
|
if (profile.getRoleSlotsInUse() >= maxRoleSlots) {
|
||||||
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("The guild can only have a maximum of %d auto roles"
|
.setDescription("The guild can only have a maximum of %d auto roles"
|
||||||
.formatted(maxRoleSlots))
|
.formatted(maxRoleSlots))
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
OptionMapping option = interaction.getOption("role");
|
OptionMapping option = event.getOption("role");
|
||||||
if (option == null) {
|
assert option != null;
|
||||||
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
|
||||||
.setDescription("Please provide a role to add")
|
|
||||||
.build()).queue();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Role role = option.getAsRole();
|
Role role = option.getAsRole();
|
||||||
|
|
||||||
// Check if the role is already in the auto roles list
|
// Check if the role is already in the auto roles list
|
||||||
if (profile.hasRole(role.getId())) {
|
if (profile.hasRole(role.getId())) {
|
||||||
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("The role %s is already in the auto roles list".formatted(role.getAsMention()))
|
.setDescription("The role %s is already in the auto roles list".formatted(role.getAsMention()))
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
@ -64,7 +57,7 @@ public class AddSubCommand extends BatSubCommand {
|
|||||||
|
|
||||||
// Check if the bot has permission to give the role
|
// Check if the bot has permission to give the role
|
||||||
if (!RoleUtils.hasPermissionToGiveRole(guild, guild.getDiscordGuild().getSelfMember(), role)) {
|
if (!RoleUtils.hasPermissionToGiveRole(guild, guild.getDiscordGuild().getSelfMember(), role)) {
|
||||||
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("I do not have permission to give the role %s".formatted(role.getAsMention()))
|
.setDescription("I do not have permission to give the role %s".formatted(role.getAsMention()))
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
@ -72,7 +65,7 @@ public class AddSubCommand extends BatSubCommand {
|
|||||||
|
|
||||||
// Check if the role is higher than the user adding the role
|
// Check if the role is higher than the user adding the role
|
||||||
if (!RoleUtils.hasPermissionToGiveRole(guild, member, role)) {
|
if (!RoleUtils.hasPermissionToGiveRole(guild, member, role)) {
|
||||||
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("You cannot add a role that is higher than you")
|
.setDescription("You cannot add a role that is higher than you")
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
@ -80,8 +73,7 @@ public class AddSubCommand extends BatSubCommand {
|
|||||||
|
|
||||||
// Add the role to the auto roles list
|
// Add the role to the auto roles list
|
||||||
profile.addRole(role.getId());
|
profile.addRole(role.getId());
|
||||||
guildService.saveGuild(guild);
|
event.replyEmbeds(EmbedUtils.successEmbed()
|
||||||
interaction.replyEmbeds(EmbedUtils.successEmbed()
|
|
||||||
.setDescription("You have added %s to the auto roles list".formatted(role.getAsMention()))
|
.setDescription("You have added %s to the auto roles list".formatted(role.getAsMention()))
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
}
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package cc.fascinated.bat.autorole.command;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
|
import cc.fascinated.bat.common.command.Category;
|
||||||
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.dv8tion.jda.api.Permission;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component("autoroles.command")
|
||||||
|
@CommandInfo(
|
||||||
|
name = "autorole",
|
||||||
|
description = "Set up the automatic role system for members on join",
|
||||||
|
requiredPermissions = Permission.MANAGE_SERVER,
|
||||||
|
category = Category.SERVER
|
||||||
|
)
|
||||||
|
public class AutoRoleCommand extends BatCommand {
|
||||||
|
public AutoRoleCommand(@NonNull ApplicationContext context) {
|
||||||
|
super.addSubCommands(
|
||||||
|
context.getBean(ListSubCommand.class),
|
||||||
|
context.getBean(AddSubCommand.class),
|
||||||
|
context.getBean(RemoveSubCommand.class),
|
||||||
|
context.getBean(ClearSubCommand.class),
|
||||||
|
context.getBean(SyncSubCommand.class)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package cc.fascinated.bat.autorole.command;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
|
import cc.fascinated.bat.autorole.profile.AutoRoleProfile;
|
||||||
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component("autoroles:clear.sub")
|
||||||
|
@CommandInfo(name = "clear", description = "Clears all auto roles")
|
||||||
|
public class ClearSubCommand extends BatCommand {
|
||||||
|
@Override
|
||||||
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
|
AutoRoleProfile profile = guild.getProfile(AutoRoleProfile.class);
|
||||||
|
|
||||||
|
profile.reset();
|
||||||
|
event.replyEmbeds(EmbedUtils.successEmbed()
|
||||||
|
.setDescription("Successfully cleared all auto roles")
|
||||||
|
.build()).queue();
|
||||||
|
}
|
||||||
|
}
|
@ -1,14 +1,15 @@
|
|||||||
package cc.fascinated.bat.features.autorole.command;
|
package cc.fascinated.bat.autorole.command;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatSubCommand;
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
import cc.fascinated.bat.features.autorole.profile.AutoRoleProfile;
|
import cc.fascinated.bat.autorole.profile.AutoRoleProfile;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.EmbedBuilder;
|
import net.dv8tion.jda.api.EmbedBuilder;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@ -18,12 +19,12 @@ import org.springframework.stereotype.Component;
|
|||||||
*/
|
*/
|
||||||
@Component("autoroles:list.sub")
|
@Component("autoroles:list.sub")
|
||||||
@CommandInfo(name = "list", description = "Lists all auto roles")
|
@CommandInfo(name = "list", description = "Lists all auto roles")
|
||||||
public class ListSubCommand extends BatSubCommand {
|
public class ListSubCommand extends BatCommand {
|
||||||
@Override
|
@Override
|
||||||
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction interaction) {
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
AutoRoleProfile profile = guild.getProfile(AutoRoleProfile.class);
|
AutoRoleProfile profile = guild.getProfile(AutoRoleProfile.class);
|
||||||
if (profile.getRoles().isEmpty()) {
|
if (profile.getRoles().isEmpty()) {
|
||||||
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("There are no auto roles set")
|
.setDescription("There are no auto roles set")
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
@ -41,6 +42,6 @@ public class ListSubCommand extends BatSubCommand {
|
|||||||
EmbedBuilder embed = EmbedUtils.genericEmbed();
|
EmbedBuilder embed = EmbedUtils.genericEmbed();
|
||||||
embed.setAuthor("Auto Role List");
|
embed.setAuthor("Auto Role List");
|
||||||
embed.setDescription(roles.toString());
|
embed.setDescription(roles.toString());
|
||||||
interaction.replyEmbeds(embed.build()).queue();
|
event.replyEmbeds(embed.build()).queue();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,19 +1,20 @@
|
|||||||
package cc.fascinated.bat.features.autorole.command;
|
package cc.fascinated.bat.autorole.command;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatSubCommand;
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
import cc.fascinated.bat.features.autorole.profile.AutoRoleProfile;
|
import cc.fascinated.bat.autorole.profile.AutoRoleProfile;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
import cc.fascinated.bat.service.GuildService;
|
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
import net.dv8tion.jda.api.entities.Role;
|
import net.dv8tion.jda.api.entities.Role;
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
||||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||||
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@ -22,37 +23,28 @@ import org.springframework.stereotype.Component;
|
|||||||
*/
|
*/
|
||||||
@Component("autoroles:remove.sub")
|
@Component("autoroles:remove.sub")
|
||||||
@CommandInfo(name = "remove", description = "Removes a role from the auto roles list")
|
@CommandInfo(name = "remove", description = "Removes a role from the auto roles list")
|
||||||
public class RemoveSubCommand extends BatSubCommand {
|
public class RemoveSubCommand extends BatCommand {
|
||||||
private final GuildService guildService;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public RemoveSubCommand(GuildService guildService) {
|
public RemoveSubCommand() {
|
||||||
super.addOption(OptionType.ROLE, "role", "The role to remove", true);
|
super.addOptions(new OptionData(OptionType.ROLE, "role", "The role to remove", true));
|
||||||
this.guildService = guildService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction interaction) {
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
AutoRoleProfile profile = guild.getProfile(AutoRoleProfile.class);
|
AutoRoleProfile profile = guild.getProfile(AutoRoleProfile.class);
|
||||||
OptionMapping option = interaction.getOption("role");
|
OptionMapping option = event.getOption("role");
|
||||||
if (option == null) {
|
assert option != null;
|
||||||
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
|
||||||
.setDescription("Please provide a role to remove")
|
|
||||||
.build()).queue();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Role role = option.getAsRole();
|
Role role = option.getAsRole();
|
||||||
if (!profile.hasRole(role.getId())) {
|
if (!profile.hasRole(role.getId())) {
|
||||||
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("The role %s is not in the auto roles list".formatted(role.getAsMention()))
|
.setDescription("The role %s is not in the auto roles list".formatted(role.getAsMention()))
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
profile.removeRole(role.getId());
|
profile.removeRole(role.getId());
|
||||||
guildService.saveGuild(guild);
|
event.replyEmbeds(EmbedUtils.successEmbed()
|
||||||
interaction.replyEmbeds(EmbedUtils.successEmbed()
|
|
||||||
.setDescription("Successfully removed the role %s from the auto roles list".formatted(role.getAsMention()))
|
.setDescription("Successfully removed the role %s from the auto roles list".formatted(role.getAsMention()))
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
}
|
}
|
@ -0,0 +1,113 @@
|
|||||||
|
package cc.fascinated.bat.autorole.command;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
|
import cc.fascinated.bat.common.DescriptionBuilder;
|
||||||
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
|
import cc.fascinated.bat.autorole.profile.AutoRoleProfile;
|
||||||
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import lombok.extern.log4j.Log4j2;
|
||||||
|
import net.dv8tion.jda.api.entities.Guild;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
import net.dv8tion.jda.api.entities.Role;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Log4j2(topic = "AutoRole Sync SubCommand")
|
||||||
|
@Component("autoroles:sync.sub")
|
||||||
|
@CommandInfo(name = "sync", description = "Gives everyone their missing auto roles")
|
||||||
|
public class SyncSubCommand extends BatCommand {
|
||||||
|
@Override
|
||||||
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
|
AutoRoleProfile profile = guild.getProfile(AutoRoleProfile.class);
|
||||||
|
if (profile.getRoles().isEmpty()) {
|
||||||
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
|
.setDescription("There are no auto roles set")
|
||||||
|
.build()).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Guild discordGuild = guild.getDiscordGuild();
|
||||||
|
event.replyEmbeds(EmbedUtils.genericEmbed()
|
||||||
|
.setDescription("Finding members that are missing auto roles...")
|
||||||
|
.build())
|
||||||
|
.queue(message -> {
|
||||||
|
log.info("Finding members that are missing auto roles in guild \"{}\"", discordGuild.getName());
|
||||||
|
List<Member> members = discordGuild.loadMembers().get();
|
||||||
|
Map<Role, Integer> rolesGiven = new HashMap<>();
|
||||||
|
|
||||||
|
// Find members that are missing the auto roles
|
||||||
|
members.removeIf(foundMember -> {
|
||||||
|
if (foundMember.getUser().isBot() || foundMember.getId().equals(discordGuild.getSelfMember().getId())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return new HashSet<>(foundMember.getRoles()).containsAll(profile.getRoles());
|
||||||
|
});
|
||||||
|
log.info("Found {} members that are missing auto roles in guild \"{}\"", members.size(), discordGuild.getName());
|
||||||
|
|
||||||
|
// No members were missing roles
|
||||||
|
if (members.isEmpty()) {
|
||||||
|
message.editOriginalEmbeds(EmbedUtils.successEmbed()
|
||||||
|
.setDescription("There are no members missing auto roles")
|
||||||
|
.build()).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int finished = 0;
|
||||||
|
for (Member foundMember : members) {
|
||||||
|
// Check if the user doesn't have the role, so we can
|
||||||
|
// show the incremented count when we're done
|
||||||
|
for (Role role : profile.getRoles()) {
|
||||||
|
if (foundMember.getRoles().contains(role)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
rolesGiven.put(role, rolesGiven.getOrDefault(role, 0) + 1);
|
||||||
|
}
|
||||||
|
// Give the user the roles
|
||||||
|
discordGuild.modifyMemberRoles(foundMember, profile.getRoles(), null).queue();
|
||||||
|
finished++;
|
||||||
|
|
||||||
|
// Update the message every 10 members
|
||||||
|
if (finished % 10 == 0 || finished == 1) {
|
||||||
|
message.editOriginalEmbeds(EmbedUtils.genericEmbed()
|
||||||
|
.setDescription("""
|
||||||
|
Giving auto roles...
|
||||||
|
Completed: `%s`/`%s`
|
||||||
|
""".formatted(finished, members.size()))
|
||||||
|
.build()).queue();
|
||||||
|
}
|
||||||
|
|
||||||
|
// We're finished giving all the roles
|
||||||
|
if (finished == members.size()) {
|
||||||
|
DescriptionBuilder description = new DescriptionBuilder(
|
||||||
|
"Successfully gave auto roles to `%s` member%s".formatted(
|
||||||
|
members.size(),
|
||||||
|
members.size() == 1 ? "" : "s"
|
||||||
|
));
|
||||||
|
description.emptyLine();
|
||||||
|
description.appendLine("**Auto Roles Given:**", false);
|
||||||
|
for (Map.Entry<Role, Integer> entry : rolesGiven.entrySet()) {
|
||||||
|
description.appendLine("%s: %s member%s".formatted(
|
||||||
|
entry.getKey().getAsMention(),
|
||||||
|
entry.getValue(),
|
||||||
|
entry.getValue() == 1 ? "" : "s"
|
||||||
|
), true);
|
||||||
|
}
|
||||||
|
message.editOriginalEmbeds(EmbedUtils.successEmbed().setDescription(description.build()).build()).queue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,14 @@
|
|||||||
package cc.fascinated.bat.features.autorole.profile;
|
package cc.fascinated.bat.autorole.profile;
|
||||||
|
|
||||||
import cc.fascinated.bat.common.Profile;
|
import cc.fascinated.bat.common.Serializable;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
import cc.fascinated.bat.service.DiscordService;
|
import cc.fascinated.bat.service.DiscordService;
|
||||||
|
import com.google.gson.Gson;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import net.dv8tion.jda.api.entities.Role;
|
import net.dv8tion.jda.api.entities.Role;
|
||||||
|
import org.bson.Document;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -15,7 +18,8 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
@Setter
|
@Setter
|
||||||
@Getter
|
@Getter
|
||||||
public class AutoRoleProfile extends Profile {
|
@NoArgsConstructor
|
||||||
|
public class AutoRoleProfile extends Serializable {
|
||||||
private static final int DEFAULT_MAX_ROLES = 10;
|
private static final int DEFAULT_MAX_ROLES = 10;
|
||||||
private static final int PREMIUM_MAX_ROLES = 25;
|
private static final int PREMIUM_MAX_ROLES = 25;
|
||||||
|
|
||||||
@ -24,10 +28,6 @@ public class AutoRoleProfile extends Profile {
|
|||||||
*/
|
*/
|
||||||
private List<String> roleIds;
|
private List<String> roleIds;
|
||||||
|
|
||||||
public AutoRoleProfile() {
|
|
||||||
super("auto-role");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the maximum amount of roles that can be set in the guild
|
* Gets the maximum amount of roles that can be set in the guild
|
||||||
*
|
*
|
||||||
@ -35,7 +35,7 @@ public class AutoRoleProfile extends Profile {
|
|||||||
* @return the amount of role slots
|
* @return the amount of role slots
|
||||||
*/
|
*/
|
||||||
public static int getMaxRoleSlots(BatGuild guild) {
|
public static int getMaxRoleSlots(BatGuild guild) {
|
||||||
if (guild.getPremium().hasPremium()) {
|
if (guild.getPremiumProfile().hasPremium()) {
|
||||||
return PREMIUM_MAX_ROLES;
|
return PREMIUM_MAX_ROLES;
|
||||||
}
|
}
|
||||||
return DEFAULT_MAX_ROLES;
|
return DEFAULT_MAX_ROLES;
|
||||||
@ -110,4 +110,16 @@ public class AutoRoleProfile extends Profile {
|
|||||||
public void reset() {
|
public void reset() {
|
||||||
roleIds.clear();
|
roleIds.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void load(Document document, Gson gson) {
|
||||||
|
roleIds = document.getList("roleIds", String.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Document serialize(Gson gson) {
|
||||||
|
Document document = new Document();
|
||||||
|
document.put("roleIds", roleIds);
|
||||||
|
return document;
|
||||||
|
}
|
||||||
}
|
}
|
53
src/main/java/cc/fascinated/bat/base/BaseFeature.java
Normal file
53
src/main/java/cc/fascinated/bat/base/BaseFeature.java
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
package cc.fascinated.bat.base;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.base.commands.fun.*;
|
||||||
|
import cc.fascinated.bat.common.feature.Feature;
|
||||||
|
import cc.fascinated.bat.common.feature.FeatureProfile;
|
||||||
|
import cc.fascinated.bat.base.commands.botadmin.BotAdminCommand;
|
||||||
|
import cc.fascinated.bat.base.commands.fun.image.ImageCommand;
|
||||||
|
import cc.fascinated.bat.base.commands.general.*;
|
||||||
|
import cc.fascinated.bat.base.commands.general.avatar.AvatarCommand;
|
||||||
|
import cc.fascinated.bat.base.commands.general.banner.BannerCommand;
|
||||||
|
import cc.fascinated.bat.base.commands.server.MemberCountCommand;
|
||||||
|
import cc.fascinated.bat.base.commands.server.PremiumCommand;
|
||||||
|
import cc.fascinated.bat.base.commands.server.channel.ChannelCommand;
|
||||||
|
import cc.fascinated.bat.base.commands.server.feature.FeatureCommand;
|
||||||
|
import cc.fascinated.bat.base.commands.utility.PastebinCommand;
|
||||||
|
import cc.fascinated.bat.base.commands.utility.lookup.LookupCommand;
|
||||||
|
import cc.fascinated.bat.service.CommandService;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class BaseFeature extends Feature {
|
||||||
|
@Autowired
|
||||||
|
public BaseFeature(@NonNull ApplicationContext context, @NonNull CommandService commandService) {
|
||||||
|
super("Base", FeatureProfile.FeatureState.ENABLED, false);
|
||||||
|
|
||||||
|
super.registerCommand(commandService, context.getBean(PremiumCommand.class));
|
||||||
|
super.registerCommand(commandService, context.getBean(BotAdminCommand.class));
|
||||||
|
super.registerCommand(commandService, context.getBean(MemberCountCommand.class));
|
||||||
|
super.registerCommand(commandService, context.getBean(ChannelCommand.class));
|
||||||
|
super.registerCommand(commandService, context.getBean(VoteCommand.class));
|
||||||
|
super.registerCommand(commandService, context.getBean(PingCommand.class));
|
||||||
|
super.registerCommand(commandService, context.getBean(InviteCommand.class));
|
||||||
|
super.registerCommand(commandService, context.getBean(HelpCommand.class));
|
||||||
|
super.registerCommand(commandService, context.getBean(BotStatsCommand.class));
|
||||||
|
super.registerCommand(commandService, context.getBean(BannerCommand.class));
|
||||||
|
super.registerCommand(commandService, context.getBean(AvatarCommand.class));
|
||||||
|
super.registerCommand(commandService, context.getBean(ImageCommand.class));
|
||||||
|
super.registerCommand(commandService, context.getBean(FeatureCommand.class));
|
||||||
|
super.registerCommand(commandService, context.getBean(EightBallCommand.class));
|
||||||
|
super.registerCommand(commandService, context.getBean(LookupCommand.class));
|
||||||
|
super.registerCommand(commandService, context.getBean(PPSizeCommand.class));
|
||||||
|
super.registerCommand(commandService, context.getBean(PastebinCommand.class));
|
||||||
|
super.registerCommand(commandService, context.getBean(CoinFlipCommand.class));
|
||||||
|
super.registerCommand(commandService, context.getBean(HowGayCommand.class));
|
||||||
|
super.registerCommand(commandService, context.getBean(NerdDetectorCommand.class));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package cc.fascinated.bat.base.commands.botadmin;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
|
import cc.fascinated.bat.base.commands.botadmin.premium.PremiumRemoveSubCommand;
|
||||||
|
import cc.fascinated.bat.base.commands.botadmin.premium.PremiumSetSubCommand;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@CommandInfo(name = "bot-admin", description = "Bot admin commands", botOwnerOnly = true)
|
||||||
|
public class BotAdminCommand extends BatCommand {
|
||||||
|
@Autowired
|
||||||
|
public BotAdminCommand(@NonNull ApplicationContext context) {
|
||||||
|
super.addSubCommands(
|
||||||
|
context.getBean(PremiumSetSubCommand.class),
|
||||||
|
context.getBean(PremiumRemoveSubCommand.class)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
package cc.fascinated.bat.base.commands.botadmin.premium;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
|
import cc.fascinated.bat.premium.PremiumProfile;
|
||||||
|
import cc.fascinated.bat.service.GuildService;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@CommandInfo(name = "premium-remove", description = "Remove premium from a guild")
|
||||||
|
public class PremiumRemoveSubCommand extends BatCommand {
|
||||||
|
private final GuildService guildService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public PremiumRemoveSubCommand(GuildService guildService) {
|
||||||
|
this.guildService = guildService;
|
||||||
|
super.addOptions(new OptionData(OptionType.STRING, "guild", "The guild id to set as premium", true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
|
OptionMapping guildOption = event.getOption("guild");
|
||||||
|
if (guildOption == null) {
|
||||||
|
event.reply("Please provide a guild id").queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String guildId = guildOption.getAsString();
|
||||||
|
BatGuild targetGuild = guildService.getGuild(guildId);
|
||||||
|
if (targetGuild == null) {
|
||||||
|
event.reply("The guild with the id %s does not exist".formatted(guildId)).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PremiumProfile premium = targetGuild.getPremiumProfile();
|
||||||
|
if (!premium.hasPremium()) {
|
||||||
|
event.reply("The guild does not have premium").queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
premium.removePremium();
|
||||||
|
event.reply("The guild **%s** has had its premium removed".formatted(targetGuild.getName())).queue();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
package cc.fascinated.bat.base.commands.botadmin.premium;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
|
import cc.fascinated.bat.premium.PremiumProfile;
|
||||||
|
import cc.fascinated.bat.service.GuildService;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@CommandInfo(name = "premium-set", description = "Adds premium to a guild")
|
||||||
|
public class PremiumSetSubCommand extends BatCommand {
|
||||||
|
private final GuildService guildService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public PremiumSetSubCommand(@NonNull GuildService guildService) {
|
||||||
|
this.guildService = guildService;
|
||||||
|
super.addOptions(
|
||||||
|
new OptionData(OptionType.STRING, "guild", "The guild id to set as premium", true),
|
||||||
|
new OptionData(OptionType.BOOLEAN, "infinite", "Whether the premium length should be infinite", true)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
|
OptionMapping guildOption = event.getOption("guild");
|
||||||
|
if (guildOption == null) {
|
||||||
|
event.reply("Please provide a guild id").queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String guildId = guildOption.getAsString();
|
||||||
|
OptionMapping infiniteOption = event.getOption("infinite");
|
||||||
|
if (infiniteOption == null) {
|
||||||
|
event.reply("Please provide whether the premium length should be infinite").queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean infinite = infiniteOption.getAsBoolean();
|
||||||
|
BatGuild targetGuild = guildService.getGuild(guildId);
|
||||||
|
if (targetGuild == null) {
|
||||||
|
event.reply("The guild with the id %s does not exist".formatted(guildId)).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PremiumProfile premium = targetGuild.getPremiumProfile();
|
||||||
|
if (!infinite) {
|
||||||
|
premium.addTime();
|
||||||
|
} else {
|
||||||
|
premium.addInfiniteTime();
|
||||||
|
}
|
||||||
|
if (!infinite) {
|
||||||
|
event.reply("The guild **%s** has been set as premium until <t:%s>".formatted(targetGuild.getName(), premium.getExpiresAt().toInstant().toEpochMilli() / 1000)).queue();
|
||||||
|
} else {
|
||||||
|
event.reply("The guild **%s** has been set as premium indefinitely".formatted(targetGuild.getName())).queue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package cc.fascinated.bat.base.commands.fun;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@CommandInfo(
|
||||||
|
name = "coinflip",
|
||||||
|
description = "Flips a coin",
|
||||||
|
userInstall = true
|
||||||
|
)
|
||||||
|
@Component
|
||||||
|
public class CoinFlipCommand extends BatCommand {
|
||||||
|
@Override
|
||||||
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member,
|
||||||
|
Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
|
event.reply("%s, you flipped a coin and got **%s**!".formatted(user.getDiscordUser().getAsMention(), flip())).queue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flips a coin
|
||||||
|
*
|
||||||
|
* @return The result of the coin flip
|
||||||
|
*/
|
||||||
|
public String flip() {
|
||||||
|
return new Random().nextBoolean() ? "heads" : "tails";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
package cc.fascinated.bat.base.commands.fun;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
|
import cc.fascinated.bat.common.command.Category;
|
||||||
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@CommandInfo(
|
||||||
|
name = "8ball", description = "Ask the magic 8ball a question",
|
||||||
|
guildOnly = false,
|
||||||
|
userInstall = true,
|
||||||
|
prefixAllowed = true,
|
||||||
|
category = Category.FUN
|
||||||
|
)
|
||||||
|
public class EightBallCommand extends BatCommand {
|
||||||
|
private final String[] responses = new String[]{
|
||||||
|
"It is certain",
|
||||||
|
"It is decidedly so",
|
||||||
|
"Without a doubt",
|
||||||
|
"Yes, definitely",
|
||||||
|
"You may rely on it",
|
||||||
|
"As I see it, yes",
|
||||||
|
"Most likely",
|
||||||
|
"Outlook good",
|
||||||
|
"Yes",
|
||||||
|
"Signs point to yes",
|
||||||
|
"Reply hazy, try again",
|
||||||
|
"Ask again later",
|
||||||
|
"Better not tell you now",
|
||||||
|
"Cannot predict now",
|
||||||
|
"Concentrate and ask again",
|
||||||
|
"Don't count on it",
|
||||||
|
"My reply is no",
|
||||||
|
"My sources say no",
|
||||||
|
"Outlook not so good",
|
||||||
|
"Very doubtful"
|
||||||
|
};
|
||||||
|
|
||||||
|
public EightBallCommand() {
|
||||||
|
super.addOptions(new OptionData(OptionType.STRING, "question", "The question you want to ask the 8ball", true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
|
String question = super.getArgument("question", arguments, 0, true, event).getAsString();
|
||||||
|
if (question == null) {
|
||||||
|
super.replyEmbed(commandMessage, event, EmbedUtils.errorEmbed()
|
||||||
|
.setDescription("You need to provide a question to ask the 8ball")
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String response = responses[(int) (Math.random() * responses.length)];
|
||||||
|
super.replyEmbed(commandMessage, event, EmbedUtils.successEmbed()
|
||||||
|
.setDescription("You asked: `%s`\n\n:8ball: The magic 8ball says: `%s`".formatted(question, response))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
package cc.fascinated.bat.base.commands.fun;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.common.DescriptionBuilder;
|
||||||
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
|
import cc.fascinated.bat.common.MathUtils;
|
||||||
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
|
import cc.fascinated.bat.common.command.Category;
|
||||||
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
import net.dv8tion.jda.api.entities.User;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@CommandInfo(
|
||||||
|
name = "howgay",
|
||||||
|
description = "Checks how gay someone is",
|
||||||
|
userInstall = true,
|
||||||
|
category = Category.FUN
|
||||||
|
)
|
||||||
|
public class HowGayCommand extends BatCommand {
|
||||||
|
public HowGayCommand() {
|
||||||
|
super.addOptions(new OptionData(OptionType.USER, "user", "The user you want to check the gayness of", true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
|
OptionMapping userOption = event.getOption("user");
|
||||||
|
assert userOption != null; // This should never be null
|
||||||
|
User target = userOption.getAsUser();
|
||||||
|
|
||||||
|
event.replyEmbeds(EmbedUtils.genericEmbed()
|
||||||
|
.setDescription(new DescriptionBuilder("How Gay?")
|
||||||
|
.appendLine("%s is %s%% gay".formatted(
|
||||||
|
target.getAsMention(),
|
||||||
|
(int) MathUtils.random(0, 100)
|
||||||
|
), false)
|
||||||
|
.build())
|
||||||
|
.build()).queue();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
package cc.fascinated.bat.base.commands.fun;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.common.DescriptionBuilder;
|
||||||
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
|
import cc.fascinated.bat.common.MathUtils;
|
||||||
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
|
import cc.fascinated.bat.common.command.Category;
|
||||||
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
import net.dv8tion.jda.api.entities.User;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@CommandInfo(
|
||||||
|
name = "nerddetector",
|
||||||
|
description = "Checks how much of a nerd someone is",
|
||||||
|
userInstall = true,
|
||||||
|
category = Category.FUN
|
||||||
|
)
|
||||||
|
public class NerdDetectorCommand extends BatCommand {
|
||||||
|
public NerdDetectorCommand() {
|
||||||
|
super.addOptions(new OptionData(OptionType.USER, "user", "The user you want to check how much of a nerd they are", true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
|
OptionMapping userOption = event.getOption("user");
|
||||||
|
assert userOption != null; // This should never be null
|
||||||
|
User target = userOption.getAsUser();
|
||||||
|
|
||||||
|
event.replyEmbeds(EmbedUtils.genericEmbed()
|
||||||
|
.setDescription(new DescriptionBuilder("Nerd Detector")
|
||||||
|
.appendLine("%s is %s%% nerd 🤓".formatted(
|
||||||
|
target.getAsMention(),
|
||||||
|
(int) MathUtils.random(0, 100)
|
||||||
|
), false)
|
||||||
|
.build())
|
||||||
|
.build()).queue();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,60 @@
|
|||||||
|
package cc.fascinated.bat.base.commands.fun;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
|
import cc.fascinated.bat.common.command.Category;
|
||||||
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
|
import cc.fascinated.bat.common.DescriptionBuilder;
|
||||||
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
|
import cc.fascinated.bat.common.MathUtils;
|
||||||
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
import net.dv8tion.jda.api.entities.User;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@CommandInfo(
|
||||||
|
name = "ppsize",
|
||||||
|
description = "Get the size of someone's pp",
|
||||||
|
userInstall = true,
|
||||||
|
category = Category.FUN
|
||||||
|
)
|
||||||
|
public class PPSizeCommand extends BatCommand {
|
||||||
|
|
||||||
|
public PPSizeCommand() {
|
||||||
|
super.addOptions(new OptionData(OptionType.USER, "user", "The user you want to get the pp size of", true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
|
OptionMapping userOption = event.getOption("user");
|
||||||
|
assert userOption != null; // This should never be null
|
||||||
|
User target = userOption.getAsUser();
|
||||||
|
|
||||||
|
int maxSize = 12;
|
||||||
|
int size = (int) MathUtils.random(1, maxSize);
|
||||||
|
event.replyEmbeds(EmbedUtils.genericEmbed()
|
||||||
|
.setDescription(new DescriptionBuilder("PP Size")
|
||||||
|
.appendLine("""
|
||||||
|
The size of %s's pp is %s inches%s
|
||||||
|
**8%sD**
|
||||||
|
""".formatted(
|
||||||
|
target.getAsMention(),
|
||||||
|
size,
|
||||||
|
size == maxSize ? " 😳" : "",
|
||||||
|
"=".repeat(size)
|
||||||
|
), false)
|
||||||
|
.build())
|
||||||
|
.build()).queue();
|
||||||
|
}
|
||||||
|
}
|
@ -1,14 +1,15 @@
|
|||||||
package cc.fascinated.bat.command.impl.fun.image;
|
package cc.fascinated.bat.base.commands.fun.image;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatSubCommand;
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
import cc.fascinated.bat.common.WebRequest;
|
import cc.fascinated.bat.common.WebRequest;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
import cc.fascinated.bat.model.token.thecatapi.CatImageToken;
|
import cc.fascinated.bat.common.model.token.thecatapi.CatImageToken;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@ -18,16 +19,16 @@ import org.springframework.stereotype.Component;
|
|||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
@CommandInfo(name = "cat", description = "Get a random cat image")
|
@CommandInfo(name = "cat", description = "Get a random cat image")
|
||||||
public class CatSubCommand extends BatSubCommand {
|
public class CatSubCommand extends BatCommand {
|
||||||
@Override
|
@Override
|
||||||
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction interaction) {
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
CatImageToken[] responseEntity = WebRequest.getAsEntity("https://api.thecatapi.com/v1/images/search", CatImageToken[].class);
|
CatImageToken[] responseEntity = WebRequest.getAsEntity("https://api.thecatapi.com/v1/images/search", CatImageToken[].class);
|
||||||
if (responseEntity == null || responseEntity.length == 0) {
|
if (responseEntity == null || responseEntity.length == 0) {
|
||||||
interaction.reply("Failed to get a cat image!").queue();
|
event.reply("Failed to get a cat image!").queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
interaction.replyEmbeds(EmbedUtils.genericEmbed()
|
event.replyEmbeds(EmbedUtils.genericEmbed()
|
||||||
.setAuthor("Here's a random cat image!")
|
.setAuthor("Here's a random cat image!")
|
||||||
.setImage(responseEntity[0].getUrl())
|
.setImage(responseEntity[0].getUrl())
|
||||||
.build()).queue();
|
.build()).queue();
|
@ -1,14 +1,15 @@
|
|||||||
package cc.fascinated.bat.command.impl.fun.image;
|
package cc.fascinated.bat.base.commands.fun.image;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatSubCommand;
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
import cc.fascinated.bat.common.WebRequest;
|
import cc.fascinated.bat.common.WebRequest;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
import cc.fascinated.bat.model.token.dogceo.RandomImage;
|
import cc.fascinated.bat.common.model.token.dogceo.RandomImage;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@ -18,16 +19,16 @@ import org.springframework.stereotype.Component;
|
|||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
@CommandInfo(name = "dog", description = "Get a random dog image")
|
@CommandInfo(name = "dog", description = "Get a random dog image")
|
||||||
public class DogSubCommand extends BatSubCommand {
|
public class DogSubCommand extends BatCommand {
|
||||||
@Override
|
@Override
|
||||||
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction interaction) {
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
RandomImage responseEntity = WebRequest.getAsEntity("https://dog.ceo/api/breeds/image/random", RandomImage.class);
|
RandomImage responseEntity = WebRequest.getAsEntity("https://dog.ceo/api/breeds/image/random", RandomImage.class);
|
||||||
if (responseEntity == null) {
|
if (responseEntity == null) {
|
||||||
interaction.reply("Failed to get a dog image!").queue();
|
event.reply("Failed to get a dog image!").queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
interaction.replyEmbeds(EmbedUtils.genericEmbed()
|
event.replyEmbeds(EmbedUtils.genericEmbed()
|
||||||
.setAuthor("Here's a random dog image!")
|
.setAuthor("Here's a random dog image!")
|
||||||
.setImage(responseEntity.getMessage())
|
.setImage(responseEntity.getMessage())
|
||||||
.build()).queue();
|
.build()).queue();
|
@ -0,0 +1,36 @@
|
|||||||
|
package cc.fascinated.bat.base.commands.fun.image;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
|
import cc.fascinated.bat.common.WebRequest;
|
||||||
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
|
import cc.fascinated.bat.common.model.token.randomd.RandomDuck;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@CommandInfo(name = "duck", description = "Get a random duck image")
|
||||||
|
public class DuckSubCommand extends BatCommand {
|
||||||
|
@Override
|
||||||
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
|
RandomDuck responseEntity = WebRequest.getAsEntity("https://random-d.uk/api/v2/random", RandomDuck.class);
|
||||||
|
if (responseEntity == null) {
|
||||||
|
event.reply("Failed to get a duck image!").queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
event.replyEmbeds(EmbedUtils.genericEmbed()
|
||||||
|
.setAuthor("Here's a random duck image!")
|
||||||
|
.setImage(responseEntity.getUrl())
|
||||||
|
.build()).queue();
|
||||||
|
}
|
||||||
|
}
|
@ -1,14 +1,15 @@
|
|||||||
package cc.fascinated.bat.command.impl.fun.image;
|
package cc.fascinated.bat.base.commands.fun.image;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatSubCommand;
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
import cc.fascinated.bat.common.WebRequest;
|
import cc.fascinated.bat.common.WebRequest;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
import cc.fascinated.bat.model.token.randomfox.RandomFoxToken;
|
import cc.fascinated.bat.common.model.token.randomfox.RandomFoxToken;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@ -18,16 +19,16 @@ import org.springframework.stereotype.Component;
|
|||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
@CommandInfo(name = "fox", description = "Get a random fox image")
|
@CommandInfo(name = "fox", description = "Get a random fox image")
|
||||||
public class FoxSubCommand extends BatSubCommand {
|
public class FoxSubCommand extends BatCommand {
|
||||||
@Override
|
@Override
|
||||||
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction interaction) {
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
RandomFoxToken responseEntity = WebRequest.getAsEntity("https://randomfox.ca/floof/", RandomFoxToken.class);
|
RandomFoxToken responseEntity = WebRequest.getAsEntity("https://randomfox.ca/floof/", RandomFoxToken.class);
|
||||||
if (responseEntity == null) {
|
if (responseEntity == null) {
|
||||||
interaction.reply("Failed to get a fox image!").queue();
|
event.reply("Failed to get a fox image!").queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
interaction.replyEmbeds(EmbedUtils.genericEmbed()
|
event.replyEmbeds(EmbedUtils.genericEmbed()
|
||||||
.setAuthor("Here's a random fox image!")
|
.setAuthor("Here's a random fox image!")
|
||||||
.setImage(responseEntity.getImage())
|
.setImage(responseEntity.getImage())
|
||||||
.build()).queue();
|
.build()).queue();
|
@ -0,0 +1,26 @@
|
|||||||
|
package cc.fascinated.bat.base.commands.fun.image;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
|
import cc.fascinated.bat.common.command.Category;
|
||||||
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@CommandInfo(name = "image", description = "View a random image", guildOnly = false, userInstall = true, category = Category.FUN)
|
||||||
|
public class ImageCommand extends BatCommand {
|
||||||
|
@Autowired
|
||||||
|
public ImageCommand(@NonNull ApplicationContext context) {
|
||||||
|
super.addSubCommands(
|
||||||
|
context.getBean(CatSubCommand.class),
|
||||||
|
context.getBean(DogSubCommand.class),
|
||||||
|
context.getBean(FoxSubCommand.class),
|
||||||
|
context.getBean(DuckSubCommand.class)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,60 @@
|
|||||||
|
package cc.fascinated.bat.base.commands.general;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
|
import cc.fascinated.bat.common.command.Category;
|
||||||
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
|
import cc.fascinated.bat.common.*;
|
||||||
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
|
import cc.fascinated.bat.service.DiscordService;
|
||||||
|
import cc.fascinated.bat.service.GuildService;
|
||||||
|
import cc.fascinated.bat.service.UserService;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.dv8tion.jda.api.JDA;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.lang.management.ManagementFactory;
|
||||||
|
import java.lang.management.RuntimeMXBean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@CommandInfo(name = "botstats", description = "Shows the bot statistics", guildOnly = false, userInstall = true, category = Category.GENERAL)
|
||||||
|
public class BotStatsCommand extends BatCommand {
|
||||||
|
private final GuildService guildService;
|
||||||
|
private final UserService userService;
|
||||||
|
private final RuntimeMXBean bean = ManagementFactory.getRuntimeMXBean();
|
||||||
|
private final Runtime runtime = Runtime.getRuntime();
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public BotStatsCommand(@NonNull GuildService guildService, @NonNull UserService userService) {
|
||||||
|
this.guildService = guildService;
|
||||||
|
this.userService = userService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
|
JDA jda = DiscordService.JDA;
|
||||||
|
long memoryUsed = (runtime.totalMemory() - runtime.freeMemory());
|
||||||
|
|
||||||
|
event.replyEmbeds(EmbedUtils.genericEmbed().setDescription(
|
||||||
|
new DescriptionBuilder("Bat Statistics")
|
||||||
|
.appendLine("Guilds: **%s**".formatted(NumberFormatter.format(jda.getGuilds().size())), true)
|
||||||
|
.appendLine("Users: **%s**".formatted(NumberFormatter.format(jda.getUsers().size())), true)
|
||||||
|
.appendLine("Gateway Ping: **%sms**".formatted(jda.getGatewayPing()), true)
|
||||||
|
.emptyLine()
|
||||||
|
.appendSubtitle("Bot Statistics")
|
||||||
|
.appendLine("Uptime: **%s**".formatted(TimeUtils.format(bean.getUptime())), true)
|
||||||
|
.appendLine("Memory Usage: **%s**".formatted(StringUtils.formatBytes(memoryUsed)), true)
|
||||||
|
.appendLine("Cached Guilds: **%s**".formatted(NumberFormatter.format(guildService.getGuilds().size())), true)
|
||||||
|
.appendLine("Cached Users: **%s**".formatted(NumberFormatter.format(userService.getUsers().size())), true)
|
||||||
|
.build()
|
||||||
|
).build()).queue();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,132 @@
|
|||||||
|
package cc.fascinated.bat.base.commands.general;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.Consts;
|
||||||
|
import cc.fascinated.bat.Emojis;
|
||||||
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
|
import cc.fascinated.bat.common.command.Category;
|
||||||
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
|
import cc.fascinated.bat.common.DescriptionBuilder;
|
||||||
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
|
import cc.fascinated.bat.common.InteractionBuilder;
|
||||||
|
import cc.fascinated.bat.event.EventListener;
|
||||||
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
|
import cc.fascinated.bat.service.CommandService;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
import net.dv8tion.jda.api.entities.MessageEmbed;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@CommandInfo(
|
||||||
|
name = "help",
|
||||||
|
description = "View the bots command categories",
|
||||||
|
userInstall = true,
|
||||||
|
category = Category.GENERAL
|
||||||
|
)
|
||||||
|
public class HelpCommand extends BatCommand implements EventListener {
|
||||||
|
private final CommandService commandService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public HelpCommand(@NonNull CommandService commandService) {
|
||||||
|
this.commandService = commandService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
|
InteractionBuilder interactionBuilder = new InteractionBuilder();
|
||||||
|
interactionBuilder.addUrlButton("Invite Me", Consts.INVITE_URL, null);
|
||||||
|
interactionBuilder.addUrlButton("Support Server", Consts.SUPPORT_INVITE_URL, null);
|
||||||
|
interactionBuilder.addStringSelect("Home", "Return Home", Emojis.HOME_EMOJI, (buttonEvent) -> {
|
||||||
|
buttonEvent.editMessageEmbeds(createHomeEmbed(event.isFromGuild())).queue();
|
||||||
|
});
|
||||||
|
for (Category category : Category.getSortedByName()) {
|
||||||
|
List<BatCommand> categoryCommands = commandService.getCommandsByCategory(category, event.isFromGuild());
|
||||||
|
if (categoryCommands.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
interactionBuilder.addStringSelect(
|
||||||
|
category.getName(),
|
||||||
|
"View commands in the %s category".formatted(category.getName()),
|
||||||
|
category.getEmoji(),
|
||||||
|
(buttonEvent) -> {
|
||||||
|
DescriptionBuilder description = new DescriptionBuilder(null);
|
||||||
|
description.appendLine("Commands in the **%s** Category".formatted(category.getName()), false);
|
||||||
|
description.emptyLine();
|
||||||
|
|
||||||
|
for (BatCommand command : categoryCommands) {
|
||||||
|
if (!command.getSubCommands().isEmpty()) {
|
||||||
|
for (BatCommand subCommand : command.getSubCommands().values()) {
|
||||||
|
description.appendLine("`%s %s` - %s".formatted(
|
||||||
|
command.getInfo().getName(),
|
||||||
|
subCommand.getInfo().getName(),
|
||||||
|
subCommand.getInfo().getDescription()
|
||||||
|
), true);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
description.appendLine("`%s` - %s".formatted(
|
||||||
|
command.getInfo().getName(),
|
||||||
|
command.getInfo().getDescription()
|
||||||
|
), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
buttonEvent.editMessageEmbeds(EmbedUtils.genericEmbed()
|
||||||
|
.setDescription(description.build())
|
||||||
|
.build()).queue();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
event.replyEmbeds(createHomeEmbed(event.isFromGuild()))
|
||||||
|
.addComponents(interactionBuilder.build())
|
||||||
|
.setEphemeral(true)
|
||||||
|
.queue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the home embed for the help command
|
||||||
|
*
|
||||||
|
* @return The home embed
|
||||||
|
*/
|
||||||
|
private MessageEmbed createHomeEmbed(boolean ranInsideGuild) {
|
||||||
|
StringBuilder categories = new StringBuilder();
|
||||||
|
for (Category category : Category.values()) {
|
||||||
|
if (commandService.getCommandsByCategory(category, ranInsideGuild).isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
long commandCount = commandService.getCommandsByCategory(category, ranInsideGuild).size();
|
||||||
|
categories.append("- %s: **%s Command%s**\n".formatted(
|
||||||
|
category.getName(),
|
||||||
|
commandCount,
|
||||||
|
commandCount == 1 ? "" : "s"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
return EmbedUtils.genericEmbed()
|
||||||
|
.setDescription("""
|
||||||
|
**Welcome to the Bat Help Menu!**
|
||||||
|
|
||||||
|
Bat is a multi-purpose bot that has a variety of features to help you with your server. You can change the category be clicking on the category name in the list below.
|
||||||
|
|
||||||
|
%s%s
|
||||||
|
*View our [TOS](%s) and [Privacy Policy](%s) for more information.*
|
||||||
|
""".formatted(
|
||||||
|
categories.toString(),
|
||||||
|
!ranInsideGuild ? "\n*guild only commands won't be shown here*" : "",
|
||||||
|
Consts.TERMS_OF_SERVICE_URL,
|
||||||
|
Consts.PRIVACY_POLICY_URL
|
||||||
|
))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
@ -1,13 +1,15 @@
|
|||||||
package cc.fascinated.bat.command.impl.general;
|
package cc.fascinated.bat.base.commands.general;
|
||||||
|
|
||||||
import cc.fascinated.bat.Consts;
|
import cc.fascinated.bat.Consts;
|
||||||
import cc.fascinated.bat.command.BatCommand;
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.common.command.Category;
|
||||||
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@ -16,11 +18,11 @@ import org.springframework.stereotype.Component;
|
|||||||
* @author Fascinated (fascinated7)
|
* @author Fascinated (fascinated7)
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
@CommandInfo(name = "invite", description = "Invite the bot to your server!", guildOnly = false)
|
@CommandInfo(name = "invite", description = "Invite the bot to your server!", guildOnly = false, category = Category.GENERAL)
|
||||||
public class InviteCommand extends BatCommand {
|
public class InviteCommand extends BatCommand {
|
||||||
@Override
|
@Override
|
||||||
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction interaction) {
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
interaction.replyEmbeds(EmbedUtils.genericEmbed()
|
event.replyEmbeds(EmbedUtils.genericEmbed()
|
||||||
.setDescription("You can invite the bot to your server by clicking [here](%s)".formatted(Consts.INVITE_URL))
|
.setDescription("You can invite the bot to your server by clicking [here](%s)".formatted(Consts.INVITE_URL))
|
||||||
.build())
|
.build())
|
||||||
.setEphemeral(true)
|
.setEphemeral(true)
|
@ -1,12 +1,14 @@
|
|||||||
package cc.fascinated.bat.command.impl.general;
|
package cc.fascinated.bat.base.commands.general;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatCommand;
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.common.command.Category;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
import cc.fascinated.bat.service.DiscordService;
|
import cc.fascinated.bat.service.DiscordService;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@ -15,12 +17,18 @@ import org.springframework.stereotype.Component;
|
|||||||
* @author Fascinated (fascinated7)
|
* @author Fascinated (fascinated7)
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
@CommandInfo(name = "ping", description = "Gets the ping of the bot", guildOnly = false)
|
@CommandInfo(
|
||||||
|
name = "ping",
|
||||||
|
description = "Gets the ping of the bot",
|
||||||
|
guildOnly = false,
|
||||||
|
userInstall = true,
|
||||||
|
category = Category.GENERAL
|
||||||
|
)
|
||||||
public class PingCommand extends BatCommand {
|
public class PingCommand extends BatCommand {
|
||||||
@Override
|
@Override
|
||||||
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction interaction) {
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
long time = System.currentTimeMillis();
|
long time = System.currentTimeMillis();
|
||||||
interaction.reply("Pinging...").queue(response -> {
|
event.reply("Pinging...").queue(response -> {
|
||||||
response.editOriginal("Gateway response time: `%sms`\nAPI response time `%sms`".formatted(
|
response.editOriginal("Gateway response time: `%sms`\nAPI response time `%sms`".formatted(
|
||||||
DiscordService.JDA.getGatewayPing(),
|
DiscordService.JDA.getGatewayPing(),
|
||||||
System.currentTimeMillis() - time
|
System.currentTimeMillis() - time
|
@ -0,0 +1,40 @@
|
|||||||
|
package cc.fascinated.bat.base.commands.general;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
|
import cc.fascinated.bat.common.command.Category;
|
||||||
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
|
import cc.fascinated.bat.common.DescriptionBuilder;
|
||||||
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@CommandInfo(name = "vote", description = "Vote for the bot", guildOnly = false, userInstall = true, category = Category.GENERAL)
|
||||||
|
public class VoteCommand extends BatCommand {
|
||||||
|
private static final String[] VOTE_LINKS = new String[]{
|
||||||
|
"https://top.gg/bot/1254161119975833652/vote",
|
||||||
|
"https://discordbotlist.com/bots/bat/upvote"
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
|
DescriptionBuilder description = new DescriptionBuilder("Vote Links");
|
||||||
|
description.appendLine("Vote for the bot on the following websites to support us!", false);
|
||||||
|
for (String link : VOTE_LINKS) {
|
||||||
|
description.appendLine(link, true);
|
||||||
|
}
|
||||||
|
event.replyEmbeds(EmbedUtils.genericEmbed()
|
||||||
|
.setDescription(description.build())
|
||||||
|
.build()
|
||||||
|
).queue();
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,8 @@
|
|||||||
package cc.fascinated.bat.command.impl.general.avatar;
|
package cc.fascinated.bat.base.commands.general.avatar;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatCommand;
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.common.command.Category;
|
||||||
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
@ -11,11 +12,13 @@ import org.springframework.stereotype.Component;
|
|||||||
* @author Nick (okNick)
|
* @author Nick (okNick)
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
@CommandInfo(name = "avatar", description = "View the avatar of the guild or a user", guildOnly = false)
|
@CommandInfo(name = "avatar", description = "View the avatar of the guild or a user", guildOnly = false, category = Category.GENERAL)
|
||||||
public class AvatarCommand extends BatCommand {
|
public class AvatarCommand extends BatCommand {
|
||||||
@Autowired
|
@Autowired
|
||||||
public AvatarCommand(@NonNull ApplicationContext context) {
|
public AvatarCommand(@NonNull ApplicationContext context) {
|
||||||
super.addSubCommand(context.getBean(GuildSubCommand.class));
|
super.addSubCommands(
|
||||||
super.addSubCommand(context.getBean(UserSubCommand.class));
|
context.getBean(GuildSubCommand.class),
|
||||||
|
context.getBean(UserSubCommand.class)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,12 +1,14 @@
|
|||||||
package cc.fascinated.bat.command.impl.general.avatar;
|
package cc.fascinated.bat.base.commands.general.avatar;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatSubCommand;
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.common.command.Category;
|
||||||
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
import net.dv8tion.jda.api.utils.ImageProxy;
|
import net.dv8tion.jda.api.utils.ImageProxy;
|
||||||
@ -16,21 +18,20 @@ import org.springframework.stereotype.Component;
|
|||||||
* @author Nick (okNick)
|
* @author Nick (okNick)
|
||||||
*/
|
*/
|
||||||
@Component("avatar:guild.sub")
|
@Component("avatar:guild.sub")
|
||||||
@CommandInfo(name = "guild", description = "View the avatar of the guild")
|
@CommandInfo(name = "guild", description = "View the avatar of the guild", category = Category.GENERAL)
|
||||||
public class GuildSubCommand extends BatSubCommand {
|
public class GuildSubCommand extends BatCommand {
|
||||||
@Override
|
@Override
|
||||||
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction interaction) {
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
ImageProxy icon = guild.getDiscordGuild().getIcon();
|
ImageProxy icon = guild.getDiscordGuild().getIcon();
|
||||||
|
|
||||||
if (icon == null) {
|
if (icon == null) {
|
||||||
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("**%s** does not have an avatar!".formatted(guild.getName()))
|
.setDescription("**%s** does not have an avatar!".formatted(guild.getName()))
|
||||||
.build())
|
.build())
|
||||||
.queue();
|
.queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
interaction.replyEmbeds(EmbedUtils.genericEmbed()
|
event.replyEmbeds(EmbedUtils.genericEmbed()
|
||||||
.setAuthor("%s's Avatar".formatted(guild.getName()), null, guild.getDiscordGuild().getIconUrl())
|
.setAuthor("%s's Avatar".formatted(guild.getName()), null, guild.getDiscordGuild().getIconUrl())
|
||||||
.setImage(icon.getUrl(4096))
|
.setImage(icon.getUrl(4096))
|
||||||
.build()
|
.build()
|
@ -1,42 +1,39 @@
|
|||||||
package cc.fascinated.bat.command.impl.general.avatar;
|
package cc.fascinated.bat.base.commands.general.avatar;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatSubCommand;
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.common.command.Category;
|
||||||
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
import net.dv8tion.jda.api.entities.User;
|
import net.dv8tion.jda.api.entities.User;
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
||||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||||
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Nick (okNick)
|
* @author Nick (okNick)
|
||||||
*/
|
*/
|
||||||
@Component("avatar:user.sub")
|
@Component("avatar:user.sub")
|
||||||
@CommandInfo(name = "user", description = "View the avatar of a user", guildOnly = false)
|
@CommandInfo(name = "user", description = "View the avatar of a user", guildOnly = false, category = Category.GENERAL)
|
||||||
public class UserSubCommand extends BatSubCommand {
|
public class UserSubCommand extends BatCommand {
|
||||||
public UserSubCommand() {
|
public UserSubCommand() {
|
||||||
super.addOption(OptionType.USER, "user", "The user to view the avatar of", true);
|
super.addOptions(new OptionData(OptionType.USER, "user", "The user to view the avatar of", true));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction interaction) {
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
OptionMapping userOption = interaction.getOption("user");
|
OptionMapping userOption = event.getOption("user");
|
||||||
if (userOption == null) {
|
assert userOption != null;
|
||||||
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
|
||||||
.setDescription("You must provide a user to view the avatar of!")
|
|
||||||
.build())
|
|
||||||
.queue();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
User target = userOption.getAsUser();
|
User target = userOption.getAsUser();
|
||||||
interaction.replyEmbeds(EmbedUtils.genericEmbed()
|
|
||||||
|
event.replyEmbeds(EmbedUtils.genericEmbed()
|
||||||
.setAuthor("%s's Avatar".formatted(target.getName()), null, target.getEffectiveAvatarUrl())
|
.setAuthor("%s's Avatar".formatted(target.getName()), null, target.getEffectiveAvatarUrl())
|
||||||
.setImage(target.getEffectiveAvatarUrl())
|
.setImage(target.getEffectiveAvatarUrl())
|
||||||
.build()
|
.build()
|
@ -1,7 +1,8 @@
|
|||||||
package cc.fascinated.bat.command.impl.general.banner;
|
package cc.fascinated.bat.base.commands.general.banner;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatCommand;
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.common.command.Category;
|
||||||
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
@ -11,11 +12,13 @@ import org.springframework.stereotype.Component;
|
|||||||
* @author Nick (okNick)
|
* @author Nick (okNick)
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
@CommandInfo(name = "banner", description = "View the banner of the guild or a user", guildOnly = false)
|
@CommandInfo(name = "banner", description = "View the banner of the guild or a user", guildOnly = false, category = Category.GENERAL)
|
||||||
public class BannerCommand extends BatCommand {
|
public class BannerCommand extends BatCommand {
|
||||||
@Autowired
|
@Autowired
|
||||||
public BannerCommand(@NonNull ApplicationContext context) {
|
public BannerCommand(@NonNull ApplicationContext context) {
|
||||||
super.addSubCommand(context.getBean(GuildSubCommand.class));
|
super.addSubCommands(
|
||||||
super.addSubCommand(context.getBean(UserSubCommand.class));
|
context.getBean(GuildSubCommand.class),
|
||||||
|
context.getBean(UserSubCommand.class)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,12 +1,14 @@
|
|||||||
package cc.fascinated.bat.command.impl.general.banner;
|
package cc.fascinated.bat.base.commands.general.banner;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatSubCommand;
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.common.command.Category;
|
||||||
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
import net.dv8tion.jda.api.utils.ImageProxy;
|
import net.dv8tion.jda.api.utils.ImageProxy;
|
||||||
@ -16,20 +18,20 @@ import org.springframework.stereotype.Component;
|
|||||||
* @author Nick (okNick)
|
* @author Nick (okNick)
|
||||||
*/
|
*/
|
||||||
@Component("banner:guild.sub")
|
@Component("banner:guild.sub")
|
||||||
@CommandInfo(name = "guild", description = "View the banner of the guild")
|
@CommandInfo(name = "guild", description = "View the banner of the guild", category = Category.GENERAL)
|
||||||
public class GuildSubCommand extends BatSubCommand {
|
public class GuildSubCommand extends BatCommand {
|
||||||
@Override
|
@Override
|
||||||
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction interaction) {
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
ImageProxy banner = guild.getDiscordGuild().getBanner();
|
ImageProxy banner = guild.getDiscordGuild().getBanner();
|
||||||
if (banner == null) {
|
if (banner == null) {
|
||||||
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("**%s** does not have a banner!".formatted(guild.getName()))
|
.setDescription("**%s** does not have a banner!".formatted(guild.getName()))
|
||||||
.build())
|
.build())
|
||||||
.queue();
|
.queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
interaction.replyEmbeds(EmbedUtils.genericEmbed()
|
event.replyEmbeds(EmbedUtils.genericEmbed()
|
||||||
.setAuthor("%s's Banner".formatted(guild.getName()))
|
.setAuthor("%s's Banner".formatted(guild.getName()))
|
||||||
.setImage(banner.getUrl(512))
|
.setImage(banner.getUrl(512))
|
||||||
.build()
|
.build()
|
@ -1,17 +1,20 @@
|
|||||||
package cc.fascinated.bat.command.impl.general.banner;
|
package cc.fascinated.bat.base.commands.general.banner;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatSubCommand;
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.common.command.Category;
|
||||||
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
import net.dv8tion.jda.api.entities.User;
|
import net.dv8tion.jda.api.entities.User;
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
||||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||||
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
|
||||||
import net.dv8tion.jda.api.utils.ImageProxy;
|
import net.dv8tion.jda.api.utils.ImageProxy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@ -19,34 +22,27 @@ import org.springframework.stereotype.Component;
|
|||||||
* @author Nick (okNick)
|
* @author Nick (okNick)
|
||||||
*/
|
*/
|
||||||
@Component("banner:user.sub")
|
@Component("banner:user.sub")
|
||||||
@CommandInfo(name = "user", description = "View the banner of a user", guildOnly = false)
|
@CommandInfo(name = "user", description = "View the banner of a user", guildOnly = false, category = Category.GENERAL)
|
||||||
public class UserSubCommand extends BatSubCommand {
|
public class UserSubCommand extends BatCommand {
|
||||||
public UserSubCommand() {
|
public UserSubCommand() {
|
||||||
super.addOption(OptionType.USER, "user", "The user to view the banner of", true);
|
super.addOptions(new OptionData(OptionType.USER, "user", "The user to view the banner of", true));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction interaction) {
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
OptionMapping userOption = interaction.getOption("user");
|
OptionMapping userOption = event.getOption("user");
|
||||||
if (userOption == null) {
|
assert userOption != null;
|
||||||
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
|
||||||
.setDescription("You must provide a user to view the banner of!")
|
|
||||||
.build())
|
|
||||||
.queue();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
User target = userOption.getAsUser();
|
User target = userOption.getAsUser();
|
||||||
ImageProxy banner = target.retrieveProfile().complete().getBanner();
|
ImageProxy banner = target.retrieveProfile().complete().getBanner();
|
||||||
if (banner == null) {
|
if (banner == null) {
|
||||||
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("**%s** does not have a banner!".formatted(target.getName()))
|
.setDescription("**%s** does not have a banner!".formatted(target.getName()))
|
||||||
.build())
|
.build())
|
||||||
.queue();
|
.queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
interaction.replyEmbeds(EmbedUtils.genericEmbed()
|
event.replyEmbeds(EmbedUtils.genericEmbed()
|
||||||
.setAuthor("%s's Banner".formatted(target.getName()))
|
.setAuthor("%s's Banner".formatted(target.getName()))
|
||||||
.setImage(banner.getUrl(512))
|
.setImage(banner.getUrl(512))
|
||||||
.build()
|
.build()
|
@ -0,0 +1,47 @@
|
|||||||
|
package cc.fascinated.bat.base.commands.server;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
|
import cc.fascinated.bat.common.NumberFormatter;
|
||||||
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.dv8tion.jda.api.entities.Guild;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Nick (okNick)
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@CommandInfo(name = "membercount", description = "View the member count of the server!")
|
||||||
|
public class MemberCountCommand extends BatCommand {
|
||||||
|
@Override
|
||||||
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
|
Guild discordGuild = guild.getDiscordGuild();
|
||||||
|
int totalMembers = 0, totalUsers = 0, totalBots = 0;
|
||||||
|
for (Member guildMember : discordGuild.getMembers()) {
|
||||||
|
if (guildMember.getUser().isBot()) {
|
||||||
|
totalBots++;
|
||||||
|
} else {
|
||||||
|
totalUsers++;
|
||||||
|
}
|
||||||
|
totalMembers++;
|
||||||
|
}
|
||||||
|
event.replyEmbeds(EmbedUtils.genericEmbed()
|
||||||
|
.setDescription("""
|
||||||
|
**Member Count**
|
||||||
|
Total Members: `%s`
|
||||||
|
Total Users: `%s`
|
||||||
|
Total Bots: `%s`
|
||||||
|
""".formatted(
|
||||||
|
NumberFormatter.format(totalMembers),
|
||||||
|
NumberFormatter.format(totalUsers),
|
||||||
|
NumberFormatter.format(totalBots)
|
||||||
|
)).build()).queue();
|
||||||
|
}
|
||||||
|
}
|
@ -1,14 +1,16 @@
|
|||||||
package cc.fascinated.bat.command.impl.server;
|
package cc.fascinated.bat.base.commands.server;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatCommand;
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
|
import cc.fascinated.bat.premium.PremiumProfile;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.EmbedBuilder;
|
import net.dv8tion.jda.api.EmbedBuilder;
|
||||||
import net.dv8tion.jda.api.Permission;
|
import net.dv8tion.jda.api.Permission;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@ -20,17 +22,17 @@ import org.springframework.stereotype.Component;
|
|||||||
@CommandInfo(name = "premium", description = "View the premium information for the guild", requiredPermissions = Permission.ADMINISTRATOR)
|
@CommandInfo(name = "premium", description = "View the premium information for the guild", requiredPermissions = Permission.ADMINISTRATOR)
|
||||||
public class PremiumCommand extends BatCommand {
|
public class PremiumCommand extends BatCommand {
|
||||||
@Override
|
@Override
|
||||||
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction interaction) {
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
BatGuild.Premium premium = guild.getPremium();
|
PremiumProfile premium = guild.getPremiumProfile();
|
||||||
EmbedBuilder embed = EmbedUtils.genericEmbed().setAuthor("Premium Information");
|
EmbedBuilder embed = EmbedUtils.genericEmbed().setAuthor("Premium Information");
|
||||||
if (premium.hasPremium()) {
|
if (premium.hasPremium()) {
|
||||||
embed.addField("Premium", premium.hasPremium() ? "Yes" : "No", true);
|
embed.addField("Premium", premium.hasPremium() ? "Yes" : "No", true);
|
||||||
embed.addField("Started", "<t:%d>".formatted(premium.getActivatedAt().toInstant().toEpochMilli() / 1000), true);
|
embed.addField("Started", "<t:%d>".formatted(premium.getActivatedAt().toInstant().getEpochSecond()), true);
|
||||||
embed.addField("Expires", premium.isInfinite() ? "Never" : "<t:%d>"
|
embed.addField("Expires", premium.isInfinite() ? "Never" : "<t:%d>"
|
||||||
.formatted(premium.getExpiresAt().toInstant().toEpochMilli() / 1000), true);
|
.formatted(premium.getExpiresAt().toInstant().toEpochMilli() / 1000), true);
|
||||||
} else {
|
} else {
|
||||||
embed.setDescription("The guild does not have premium");
|
embed.setDescription("The guild does not have premium");
|
||||||
}
|
}
|
||||||
interaction.replyEmbeds(embed.build()).queue();
|
event.replyEmbeds(embed.build()).queue();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,8 +1,8 @@
|
|||||||
package cc.fascinated.bat.command.impl.server.channel;
|
package cc.fascinated.bat.base.commands.server.channel;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatCommand;
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
import cc.fascinated.bat.command.Category;
|
import cc.fascinated.bat.common.command.Category;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
@ -16,8 +16,10 @@ import org.springframework.stereotype.Component;
|
|||||||
public class ChannelCommand extends BatCommand {
|
public class ChannelCommand extends BatCommand {
|
||||||
@Autowired
|
@Autowired
|
||||||
public ChannelCommand(@NonNull ApplicationContext context) {
|
public ChannelCommand(@NonNull ApplicationContext context) {
|
||||||
super.addSubCommand(context.getBean(ViewTopicSubCommand.class));
|
super.addSubCommands(
|
||||||
super.addSubCommand(context.getBean(SetTopicSubCommand.class));
|
context.getBean(ViewTopicSubCommand.class),
|
||||||
super.addSubCommand(context.getBean(RemoveTopicSubCommand.class));
|
context.getBean(SetTopicSubCommand.class),
|
||||||
|
context.getBean(RemoveTopicSubCommand.class)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,18 +1,20 @@
|
|||||||
package cc.fascinated.bat.command.impl.server.channel;
|
package cc.fascinated.bat.base.commands.server.channel;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatSubCommand;
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.Permission;
|
import net.dv8tion.jda.api.Permission;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
import net.dv8tion.jda.api.entities.channel.Channel;
|
import net.dv8tion.jda.api.entities.channel.Channel;
|
||||||
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||||
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -20,16 +22,16 @@ import org.springframework.stereotype.Component;
|
|||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
@CommandInfo(name = "removetopic", description = "Remove the topic of a channel", requiredPermissions = Permission.MANAGE_CHANNEL)
|
@CommandInfo(name = "removetopic", description = "Remove the topic of a channel", requiredPermissions = Permission.MANAGE_CHANNEL)
|
||||||
public class RemoveTopicSubCommand extends BatSubCommand {
|
public class RemoveTopicSubCommand extends BatCommand {
|
||||||
public RemoveTopicSubCommand() {
|
public RemoveTopicSubCommand() {
|
||||||
super.addOption(OptionType.CHANNEL, "channel", "The channel to remove the topic of", false);
|
super.addOptions(new OptionData(OptionType.CHANNEL, "channel", "The channel to remove the topic of", false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction interaction) {
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
Channel target = interaction.getOption("channel") == null ? channel : interaction.getOption("channel").getAsChannel();
|
Channel target = event.getOption("channel") == null ? channel : event.getOption("channel").getAsChannel();
|
||||||
if (!(target instanceof TextChannel textChannel)) {
|
if (!(target instanceof TextChannel textChannel)) {
|
||||||
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("<#%s> is not a text channel!".formatted(target.getId()))
|
.setDescription("<#%s> is not a text channel!".formatted(target.getId()))
|
||||||
.build())
|
.build())
|
||||||
.queue();
|
.queue();
|
||||||
@ -37,7 +39,7 @@ public class RemoveTopicSubCommand extends BatSubCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (textChannel.getTopic() == null) {
|
if (textChannel.getTopic() == null) {
|
||||||
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("<#%s> does not have a topic!".formatted(textChannel.getId()))
|
.setDescription("<#%s> does not have a topic!".formatted(textChannel.getId()))
|
||||||
.build())
|
.build())
|
||||||
.queue();
|
.queue();
|
||||||
@ -45,7 +47,7 @@ public class RemoveTopicSubCommand extends BatSubCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
textChannel.getManager().setTopic(null).queue();
|
textChannel.getManager().setTopic(null).queue();
|
||||||
interaction.replyEmbeds(EmbedUtils.successEmbed()
|
event.replyEmbeds(EmbedUtils.successEmbed()
|
||||||
.setDescription("Successfully removed the topic of <#%s>".formatted(textChannel.getId()))
|
.setDescription("Successfully removed the topic of <#%s>".formatted(textChannel.getId()))
|
||||||
.build()
|
.build()
|
||||||
).queue();
|
).queue();
|
@ -1,55 +1,58 @@
|
|||||||
package cc.fascinated.bat.command.impl.server.channel;
|
package cc.fascinated.bat.base.commands.server.channel;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatSubCommand;
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.Permission;
|
import net.dv8tion.jda.api.Permission;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
import net.dv8tion.jda.api.entities.channel.Channel;
|
import net.dv8tion.jda.api.entities.channel.Channel;
|
||||||
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||||
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Nick (okNick)
|
* @author Nick (okNick)
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
@CommandInfo(name = "settopic", description = "Set the topic of a channel", requiredPermissions = Permission.MANAGE_CHANNEL)
|
@CommandInfo(name = "settopic", description = "Set the topic of a channel", requiredPermissions = Permission.MANAGE_CHANNEL)
|
||||||
public class SetTopicSubCommand extends BatSubCommand {
|
public class SetTopicSubCommand extends BatCommand {
|
||||||
public SetTopicSubCommand() {
|
public SetTopicSubCommand() {
|
||||||
super.addOption(OptionType.STRING, "topic", "The topic to set", true);
|
super.addOptions(
|
||||||
super.addOption(OptionType.CHANNEL, "channel", "The channel to set the topic of", false);
|
new OptionData(OptionType.STRING, "topic", "The topic to set", true),
|
||||||
|
new OptionData(OptionType.CHANNEL, "channel", "The channel to set the topic of", false)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction interaction) {
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
Channel target = interaction.getOption("channel") == null ? channel : interaction.getOption("channel").getAsChannel();
|
Channel target = event.getOption("channel") == null ? channel : Objects.requireNonNull(event.getOption("channel")).getAsChannel();
|
||||||
if (!(target instanceof TextChannel textChannel)) {
|
if (!(target instanceof TextChannel textChannel)) {
|
||||||
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("<#%s> is not a text channel!".formatted(target.getId()))
|
.setDescription("<#%s> is not a text channel!".formatted(target.getId()))
|
||||||
.build())
|
.build())
|
||||||
.queue();
|
.queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String topic = interaction.getOption("topic").getAsString();
|
String topic = Objects.requireNonNull(event.getOption("topic")).getAsString();
|
||||||
if (topic.length() > 1024) {
|
if (topic.length() > 1024) {
|
||||||
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("The topic must be 1024 characters or less!")
|
.setDescription("The topic must be 1024 characters or less!")
|
||||||
.build())
|
.build())
|
||||||
.queue();
|
.queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
event.deferReply().queue(hook -> textChannel.getManager().setTopic(topic).queue((voidd) -> hook.editOriginalEmbeds(EmbedUtils.successEmbed()
|
||||||
textChannel.getManager().setTopic(topic).queue();
|
|
||||||
interaction.replyEmbeds(EmbedUtils.successEmbed()
|
|
||||||
.setDescription("Successfully set the topic of <#%s> to: \"%s\"".formatted(textChannel.getId(), topic))
|
.setDescription("Successfully set the topic of <#%s> to: \"%s\"".formatted(textChannel.getId(), topic))
|
||||||
.build()
|
.build()).queue()));
|
||||||
).queue();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,17 +1,19 @@
|
|||||||
package cc.fascinated.bat.command.impl.server.channel;
|
package cc.fascinated.bat.base.commands.server.channel;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatSubCommand;
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
import net.dv8tion.jda.api.entities.channel.Channel;
|
import net.dv8tion.jda.api.entities.channel.Channel;
|
||||||
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||||
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -19,16 +21,16 @@ import org.springframework.stereotype.Component;
|
|||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
@CommandInfo(name = "viewtopic", description = "View the topic of a channel")
|
@CommandInfo(name = "viewtopic", description = "View the topic of a channel")
|
||||||
public class ViewTopicSubCommand extends BatSubCommand {
|
public class ViewTopicSubCommand extends BatCommand {
|
||||||
public ViewTopicSubCommand() {
|
public ViewTopicSubCommand() {
|
||||||
super.addOption(OptionType.CHANNEL, "channel", "The channel to view the topic of", false);
|
super.addOptions(new OptionData(OptionType.CHANNEL, "channel", "The channel to view the topic of", false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction interaction) {
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
Channel target = interaction.getOption("channel") == null ? channel : interaction.getOption("channel").getAsChannel();
|
Channel target = event.getOption("channel") == null ? channel : event.getOption("channel").getAsChannel();
|
||||||
if (!(target instanceof TextChannel textChannel)) {
|
if (!(target instanceof TextChannel textChannel)) {
|
||||||
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("<#%s> is not a text channel!".formatted(target.getId()))
|
.setDescription("<#%s> is not a text channel!".formatted(target.getId()))
|
||||||
.build())
|
.build())
|
||||||
.queue();
|
.queue();
|
||||||
@ -37,14 +39,14 @@ public class ViewTopicSubCommand extends BatSubCommand {
|
|||||||
|
|
||||||
String topic = textChannel.getTopic();
|
String topic = textChannel.getTopic();
|
||||||
if (topic == null) {
|
if (topic == null) {
|
||||||
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("<#%s> does not have a topic!".formatted(textChannel.getId()))
|
.setDescription("<#%s> does not have a topic!".formatted(textChannel.getId()))
|
||||||
.build())
|
.build())
|
||||||
.queue();
|
.queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
interaction.replyEmbeds(EmbedUtils.genericEmbed()
|
event.replyEmbeds(EmbedUtils.genericEmbed()
|
||||||
.setDescription("The topic of <#%s> is: \"%s\"".formatted(textChannel.getId(), topic))
|
.setDescription("The topic of <#%s> is: \"%s\"".formatted(textChannel.getId(), topic))
|
||||||
.build()
|
.build()
|
||||||
).queue();
|
).queue();
|
@ -0,0 +1,63 @@
|
|||||||
|
package cc.fascinated.bat.base.commands.server.feature;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
|
import cc.fascinated.bat.common.feature.Feature;
|
||||||
|
import cc.fascinated.bat.common.feature.FeatureProfile;
|
||||||
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
|
import cc.fascinated.bat.service.FeatureService;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component("feature:disable.sub")
|
||||||
|
@CommandInfo(name = "disable", description = "Disables a feature")
|
||||||
|
public class DisableSubCommand extends BatCommand {
|
||||||
|
@Autowired
|
||||||
|
public DisableSubCommand() {
|
||||||
|
super.addOptions(new OptionData(OptionType.STRING, "feature", "The feature to disable", true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
|
FeatureProfile featureProfile = guild.getFeatureProfile();
|
||||||
|
OptionMapping featureOption = event.getOption("feature");
|
||||||
|
if (featureOption == null) {
|
||||||
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
|
.setDescription("You must provide a feature to enabled")
|
||||||
|
.build()).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String featureName = featureOption.getAsString();
|
||||||
|
if (!FeatureService.INSTANCE.isFeature(featureName)) {
|
||||||
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
|
.setDescription("That feature does not exist")
|
||||||
|
.build()).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Feature feature = FeatureService.INSTANCE.getFeature(featureName);
|
||||||
|
if (featureProfile.isFeatureDisabled(feature)) {
|
||||||
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
|
.setDescription("The feature `%s` is already disabled".formatted(feature.getName()))
|
||||||
|
.build()).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
featureProfile.disableFeature(feature);
|
||||||
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
|
.setDescription("Successfully disabled the `%s` feature".formatted(feature.getName()))
|
||||||
|
.build()).queue();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
package cc.fascinated.bat.base.commands.server.feature;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
|
import cc.fascinated.bat.common.feature.Feature;
|
||||||
|
import cc.fascinated.bat.common.feature.FeatureProfile;
|
||||||
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
|
import cc.fascinated.bat.service.FeatureService;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component("feature:enable.sub")
|
||||||
|
@CommandInfo(name = "enable", description = "Enables a feature")
|
||||||
|
public class EnableSubCommand extends BatCommand {
|
||||||
|
@Autowired
|
||||||
|
public EnableSubCommand() {
|
||||||
|
super.addOptions(new OptionData(OptionType.STRING, "feature", "The feature to enable", true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
|
FeatureProfile featureProfile = guild.getFeatureProfile();
|
||||||
|
OptionMapping featureOption = event.getOption("feature");
|
||||||
|
if (featureOption == null) {
|
||||||
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
|
.setDescription("You must provide a feature to enabled")
|
||||||
|
.build()).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String featureName = featureOption.getAsString();
|
||||||
|
if (!FeatureService.INSTANCE.isFeature(featureName)) {
|
||||||
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
|
.setDescription("That feature does not exist")
|
||||||
|
.build()).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Feature feature = FeatureService.INSTANCE.getFeature(featureName);
|
||||||
|
if (featureProfile.isFeatureEnabled(feature)) {
|
||||||
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
|
.setDescription("The feature `%s` is already enabled".formatted(feature.getName()))
|
||||||
|
.build()).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
featureProfile.enableFeature(feature);
|
||||||
|
event.replyEmbeds(EmbedUtils.successEmbed()
|
||||||
|
.setDescription("Successfully enabled the `%s` feature".formatted(feature.getName()))
|
||||||
|
.build()).queue();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
package cc.fascinated.bat.base.commands.server.feature;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
|
import cc.fascinated.bat.common.command.Category;
|
||||||
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.dv8tion.jda.api.Permission;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@CommandInfo(name = "feature", description = "Configure features in your guild", requiredPermissions = Permission.ADMINISTRATOR, category = Category.SERVER)
|
||||||
|
public class FeatureCommand extends BatCommand {
|
||||||
|
@Autowired
|
||||||
|
public FeatureCommand(@NonNull ApplicationContext context) {
|
||||||
|
super.addSubCommands(
|
||||||
|
context.getBean(EnableSubCommand.class),
|
||||||
|
context.getBean(DisableSubCommand.class),
|
||||||
|
context.getBean(ListSubCommand.class)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package cc.fascinated.bat.base.commands.server.feature;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
|
import cc.fascinated.bat.common.feature.Feature;
|
||||||
|
import cc.fascinated.bat.common.feature.FeatureProfile;
|
||||||
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
|
import cc.fascinated.bat.service.FeatureService;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component("feature:list.sub")
|
||||||
|
@CommandInfo(name = "list", description = "Lists the features and their states")
|
||||||
|
public class ListSubCommand extends BatCommand {
|
||||||
|
@Override
|
||||||
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
|
StringBuilder featureStates = new StringBuilder();
|
||||||
|
for (Feature feature : FeatureService.INSTANCE.getFeaturesSorted()) {
|
||||||
|
FeatureProfile featureProfile = guild.getFeatureProfile();
|
||||||
|
featureStates.append("%s `%s`\n".formatted(
|
||||||
|
featureProfile.getFeatureState(feature).getEmoji(),
|
||||||
|
feature.getName()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
event.replyEmbeds(EmbedUtils.genericEmbed()
|
||||||
|
.setTitle("Feature List")
|
||||||
|
.setDescription(featureStates.toString())
|
||||||
|
.build()
|
||||||
|
).queue();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
package cc.fascinated.bat.base.commands.utility;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
|
import cc.fascinated.bat.common.command.Category;
|
||||||
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
|
import cc.fascinated.bat.common.DescriptionBuilder;
|
||||||
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
|
import cc.fascinated.bat.common.PasteUtils;
|
||||||
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@CommandInfo(
|
||||||
|
name = "pastebin",
|
||||||
|
description = "Uploads the given text to Paste",
|
||||||
|
userInstall = true,
|
||||||
|
category = Category.UTILITY
|
||||||
|
)
|
||||||
|
public class PastebinCommand extends BatCommand {
|
||||||
|
public PastebinCommand() {
|
||||||
|
super.addOptions(
|
||||||
|
new OptionData(OptionType.STRING, "text", "The text to upload to Paste", true)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
|
OptionMapping textOption = event.getOption("text");
|
||||||
|
assert textOption != null;
|
||||||
|
String text = textOption.getAsString();
|
||||||
|
|
||||||
|
// Upload the text to pastebin
|
||||||
|
String url = PasteUtils.uploadPaste(text).getUrl();
|
||||||
|
event.replyEmbeds(EmbedUtils.successEmbed()
|
||||||
|
.setDescription(new DescriptionBuilder("The text has been uploaded to Paste!")
|
||||||
|
.appendLine("URL: %s".formatted(url), true)
|
||||||
|
.build())
|
||||||
|
.build())
|
||||||
|
.setEphemeral(true)
|
||||||
|
.queue();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package cc.fascinated.bat.base.commands.utility.lookup;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
|
import cc.fascinated.bat.common.command.Category;
|
||||||
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Nick (okNick)
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@CommandInfo(
|
||||||
|
name = "lookup",
|
||||||
|
description = "View the banner of the guild or a user",
|
||||||
|
userInstall = true,
|
||||||
|
category = Category.UTILITY
|
||||||
|
)
|
||||||
|
public class LookupCommand extends BatCommand {
|
||||||
|
@Autowired
|
||||||
|
public LookupCommand(@NonNull ApplicationContext context) {
|
||||||
|
super.addSubCommands(
|
||||||
|
context.getBean(UserSubCommand.class)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
package cc.fascinated.bat.base.commands.utility.lookup;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
|
import cc.fascinated.bat.common.DescriptionBuilder;
|
||||||
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
|
import cc.fascinated.bat.service.UserService;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
import net.dv8tion.jda.api.entities.User;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component("lookup.user:sub")
|
||||||
|
@CommandInfo(name = "user", description = "Lookup a user")
|
||||||
|
public class UserSubCommand extends BatCommand {
|
||||||
|
private final UserService userService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public UserSubCommand(@NonNull UserService userService) {
|
||||||
|
this.userService = userService;
|
||||||
|
super.addOptions(new OptionData(OptionType.STRING, "id", "The id of the user", true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
|
OptionMapping idOption = event.getOption("id");
|
||||||
|
if (idOption == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
User target = userService.getUser(idOption.getAsString()).getDiscordUser();
|
||||||
|
if (target == null) {
|
||||||
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
|
.setDescription("User `%s` not found".formatted(idOption.getAsString()))
|
||||||
|
.build())
|
||||||
|
.setEphemeral(true)
|
||||||
|
.queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The flags of the user (eg. Discord Partner, Hypesquad Events, etc.)
|
||||||
|
StringBuilder flags = new StringBuilder();
|
||||||
|
for (User.UserFlag flag : target.getFlags()) {
|
||||||
|
flags.append("`").append(flag.getName()).append("`, ");
|
||||||
|
}
|
||||||
|
String name = target.getGlobalName() == null ? target.getName() : target.getGlobalName().replaceAll("`", "");
|
||||||
|
target.retrieveProfile().queue(profile -> event.replyEmbeds(EmbedUtils.genericEmbed()
|
||||||
|
.setDescription(new DescriptionBuilder("User Lookup")
|
||||||
|
.appendLine("Name: `%s`".formatted(name), true)
|
||||||
|
.appendLine("Username: `%s`".formatted(target.getName()), true)
|
||||||
|
.appendLine("ID: `%s`".formatted(target.getId()), true)
|
||||||
|
.appendLine("Flags: %s".formatted(flags.toString().isEmpty() ? "None" : flags.substring(0, flags.length() - 2)), true)
|
||||||
|
.appendLine("Joined Discord: <t:%s:R>".formatted(target.getTimeCreated().toEpochSecond()), true)
|
||||||
|
.appendLine("Avatar: %s".formatted(target.getAvatar() == null ? "None"
|
||||||
|
: "[click here](%s)".formatted(target.getAvatar().getUrl(4096))), true)
|
||||||
|
.appendLine("Banner: %s".formatted(profile.getBanner() == null ? "None"
|
||||||
|
: "[click here](%s)".formatted(profile.getBanner().getUrl(4096))), true)
|
||||||
|
.build())
|
||||||
|
.setThumbnail(target.getAvatar() == null ? null : target.getAvatar().getUrl(4096))
|
||||||
|
.build())
|
||||||
|
.setEphemeral(true)
|
||||||
|
.queue());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
package cc.fascinated.bat.birthday;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.event.EventListener;
|
||||||
|
import cc.fascinated.bat.common.feature.Feature;
|
||||||
|
import cc.fascinated.bat.common.feature.FeatureProfile;
|
||||||
|
import cc.fascinated.bat.birthday.command.BirthdayCommand;
|
||||||
|
import cc.fascinated.bat.birthday.profile.BirthdayProfile;
|
||||||
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.service.CommandService;
|
||||||
|
import cc.fascinated.bat.service.DiscordService;
|
||||||
|
import cc.fascinated.bat.service.GuildService;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.dv8tion.jda.api.entities.Guild;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class BirthdayFeature extends Feature implements EventListener {
|
||||||
|
private final GuildService guildService;
|
||||||
|
|
||||||
|
public BirthdayFeature(@NonNull ApplicationContext context, @NonNull CommandService commandService, @NonNull GuildService guildService) {
|
||||||
|
super("Birthday", FeatureProfile.FeatureState.DISABLED, true);
|
||||||
|
this.guildService = guildService;
|
||||||
|
|
||||||
|
registerCommand(commandService, context.getBean(BirthdayCommand.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check birthdays every day at midnight
|
||||||
|
*/
|
||||||
|
@Scheduled(cron = "0 1 0 * * *")
|
||||||
|
private void checkBirthdays() {
|
||||||
|
for (Guild guild : DiscordService.JDA.getGuilds()) {
|
||||||
|
BatGuild batGuild = guildService.getGuild(guild.getId());
|
||||||
|
if (batGuild.getFeatureProfile().isFeatureDisabled(this)) { // Check if the feature is disabled
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
BirthdayProfile profile = batGuild.getBirthdayProfile();
|
||||||
|
profile.checkBirthdays(batGuild);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
62
src/main/java/cc/fascinated/bat/birthday/UserBirthday.java
Normal file
62
src/main/java/cc/fascinated/bat/birthday/UserBirthday.java
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
package cc.fascinated.bat.birthday;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.common.Serializable;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.bson.Document;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class UserBirthday extends Serializable {
|
||||||
|
/**
|
||||||
|
* The user's birthday
|
||||||
|
*/
|
||||||
|
private Date birthday;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the birthday should be hidden
|
||||||
|
*/
|
||||||
|
private boolean hidden;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the age of the user
|
||||||
|
*
|
||||||
|
* @return the age of the user
|
||||||
|
*/
|
||||||
|
public int calculateAge() {
|
||||||
|
Calendar birthdayCalendar = Calendar.getInstance();
|
||||||
|
birthdayCalendar.setTime(this.getBirthday());
|
||||||
|
Calendar today = Calendar.getInstance();
|
||||||
|
int age = today.get(Calendar.YEAR) - birthdayCalendar.get(Calendar.YEAR);
|
||||||
|
|
||||||
|
// Check if the birthday hasn't occurred yet this year
|
||||||
|
if (today.get(Calendar.DAY_OF_YEAR) < birthdayCalendar.get(Calendar.DAY_OF_YEAR)) {
|
||||||
|
age--;
|
||||||
|
}
|
||||||
|
return age;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void load(Document document, Gson gson) {
|
||||||
|
this.birthday = document.getDate("birthday");
|
||||||
|
this.hidden = document.getBoolean("hidden", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Document serialize(Gson gson) {
|
||||||
|
Document document = new Document();
|
||||||
|
document.put("birthday", this.birthday);
|
||||||
|
document.put("hidden", this.hidden);
|
||||||
|
return document;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reset() {}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package cc.fascinated.bat.birthday.command;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
|
import cc.fascinated.bat.common.command.Category;
|
||||||
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@CommandInfo(name = "birthday", description = "Modify your birthday settings.", category = Category.UTILITY)
|
||||||
|
public class BirthdayCommand extends BatCommand {
|
||||||
|
@Autowired
|
||||||
|
public BirthdayCommand(@NonNull ApplicationContext context) {
|
||||||
|
super.addSubCommands(
|
||||||
|
context.getBean(SetSubCommand.class),
|
||||||
|
context.getBean(RemoveSubCommand.class),
|
||||||
|
context.getBean(ChannelSubCommand.class),
|
||||||
|
context.getBean(MessageSubCommand.class),
|
||||||
|
context.getBean(ViewSubCommand.class),
|
||||||
|
context.getBean(PrivateSubCommand.class)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1,22 +1,23 @@
|
|||||||
package cc.fascinated.bat.features.birthday.command;
|
package cc.fascinated.bat.birthday.command;
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatSubCommand;
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
import cc.fascinated.bat.common.TextChannelUtils;
|
import cc.fascinated.bat.common.TextChannelUtils;
|
||||||
import cc.fascinated.bat.features.birthday.profile.BirthdayProfile;
|
import cc.fascinated.bat.birthday.profile.BirthdayProfile;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
import cc.fascinated.bat.service.GuildService;
|
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import net.dv8tion.jda.api.Permission;
|
import net.dv8tion.jda.api.Permission;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
import net.dv8tion.jda.api.entities.channel.ChannelType;
|
import net.dv8tion.jda.api.entities.channel.ChannelType;
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
import net.dv8tion.jda.api.entities.channel.unions.GuildChannelUnion;
|
import net.dv8tion.jda.api.entities.channel.unions.GuildChannelUnion;
|
||||||
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
||||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||||
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@ -25,27 +26,24 @@ import org.springframework.stereotype.Component;
|
|||||||
*/
|
*/
|
||||||
@Component("birthday:channel.sub")
|
@Component("birthday:channel.sub")
|
||||||
@CommandInfo(name = "channel", description = "Sets the birthday notification channel", requiredPermissions = Permission.MANAGE_SERVER)
|
@CommandInfo(name = "channel", description = "Sets the birthday notification channel", requiredPermissions = Permission.MANAGE_SERVER)
|
||||||
public class ChannelSubCommand extends BatSubCommand {
|
public class ChannelSubCommand extends BatCommand {
|
||||||
private final GuildService guildService;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public ChannelSubCommand(GuildService guildService) {
|
public ChannelSubCommand() {
|
||||||
super.addOption(OptionType.CHANNEL, "channel", "The channel birthdays will be sent in", false);
|
super.addOptions(new OptionData(OptionType.CHANNEL, "channel", "The channel birthdays will be sent in", false));
|
||||||
this.guildService = guildService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction interaction) {
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
BirthdayProfile profile = guild.getProfile(BirthdayProfile.class);
|
BirthdayProfile profile = guild.getBirthdayProfile();
|
||||||
OptionMapping option = interaction.getOption("channel");
|
OptionMapping option = event.getOption("channel");
|
||||||
if (option == null) {
|
if (option == null) {
|
||||||
if (!TextChannelUtils.isValidChannel(profile.getChannelId())) {
|
if (!TextChannelUtils.isValidChannel(profile.getChannelId())) {
|
||||||
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("There is no channel set for birthday notifications. Please provide a channel to set the birthday channel to")
|
.setDescription("There is no channel set for birthday notifications. Please provide a channel to set the birthday channel to")
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
interaction.replyEmbeds(EmbedUtils.genericEmbed()
|
event.replyEmbeds(EmbedUtils.genericEmbed()
|
||||||
.setDescription("The current birthday channel is %s".formatted(TextChannelUtils.getChannelMention(profile.getChannelId())))
|
.setDescription("The current birthday channel is %s".formatted(TextChannelUtils.getChannelMention(profile.getChannelId())))
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
@ -53,16 +51,14 @@ public class ChannelSubCommand extends BatSubCommand {
|
|||||||
|
|
||||||
GuildChannelUnion targetChannel = option.getAsChannel();
|
GuildChannelUnion targetChannel = option.getAsChannel();
|
||||||
if (targetChannel.getType() != ChannelType.TEXT) {
|
if (targetChannel.getType() != ChannelType.TEXT) {
|
||||||
interaction.replyEmbeds(EmbedUtils.errorEmbed()
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
.setDescription("Invalid channel type, please provide a text channel")
|
.setDescription("Invalid channel type, please provide a text channel")
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
profile.setChannelId(targetChannel.getId());
|
profile.setChannelId(targetChannel.getId());
|
||||||
guildService.saveGuild(guild);
|
event.replyEmbeds(EmbedUtils.successEmbed()
|
||||||
|
|
||||||
interaction.replyEmbeds(EmbedUtils.successEmbed()
|
|
||||||
.setDescription("Successfully set the birthday channel to %s".formatted(targetChannel.asTextChannel().getAsMention()))
|
.setDescription("Successfully set the birthday channel to %s".formatted(targetChannel.asTextChannel().getAsMention()))
|
||||||
.build()).queue();
|
.build()).queue();
|
||||||
}
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
package cc.fascinated.bat.birthday.command;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
|
import cc.fascinated.bat.birthday.profile.BirthdayProfile;
|
||||||
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.dv8tion.jda.api.Permission;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component("birthday:message.sub")
|
||||||
|
@CommandInfo(name = "message", description = "Changes the message that is sent when it is a user's birthday", requiredPermissions = Permission.MANAGE_SERVER)
|
||||||
|
public class MessageSubCommand extends BatCommand {
|
||||||
|
@Autowired
|
||||||
|
public MessageSubCommand() {
|
||||||
|
super.addOptions(new OptionData(OptionType.STRING, "message", "The message that is sent. (Placeholders: {user}, {age})", true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
|
BirthdayProfile profile = guild.getBirthdayProfile();
|
||||||
|
OptionMapping messageOption = event.getOption("message");
|
||||||
|
assert messageOption != null;
|
||||||
|
String message = messageOption.getAsString();
|
||||||
|
|
||||||
|
if (message.length() > 2000) {
|
||||||
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
|
.setDescription("The message must be less than 2000 characters")
|
||||||
|
.build()).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!message.contains("{user}") || !message.contains("{age}")) {
|
||||||
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
|
.setDescription("The message must contain the placeholders {user} and {age}")
|
||||||
|
.build()).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
profile.setMessage(message);
|
||||||
|
event.replyEmbeds(EmbedUtils.successEmbed()
|
||||||
|
.setDescription("You have updated the birthday message!\n\n**Message:** %s".formatted(profile.getBirthdayMessage(user.getDiscordUser())))
|
||||||
|
.build()).queue();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
package cc.fascinated.bat.birthday.command;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
|
import cc.fascinated.bat.birthday.UserBirthday;
|
||||||
|
import cc.fascinated.bat.birthday.profile.BirthdayProfile;
|
||||||
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component("birthday:private.sub")
|
||||||
|
@CommandInfo(name = "private", description = "Changes whether your birthday is private or not")
|
||||||
|
public class PrivateSubCommand extends BatCommand {
|
||||||
|
@Autowired
|
||||||
|
public PrivateSubCommand() {
|
||||||
|
super.addOptions(new OptionData(OptionType.BOOLEAN, "enabled", "Whether your birthday is private or not", true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
|
BirthdayProfile profile = guild.getBirthdayProfile();
|
||||||
|
OptionMapping enabledOption = event.getOption("enabled");
|
||||||
|
assert enabledOption != null;
|
||||||
|
boolean enabled = enabledOption.getAsBoolean();
|
||||||
|
|
||||||
|
UserBirthday birthday = profile.getBirthday(user.getId());
|
||||||
|
if (birthday == null) {
|
||||||
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
|
.setDescription("You have not set your birthday yet")
|
||||||
|
.build()).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
birthday.setHidden(enabled);
|
||||||
|
event.replyEmbeds(EmbedUtils.successEmbed()
|
||||||
|
.setDescription("Your birthday privacy settings have been updated\n\n**Private:** " + (enabled ? "Yes" : "No"))
|
||||||
|
.build()).queue();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
package cc.fascinated.bat.birthday.command;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
|
import cc.fascinated.bat.birthday.profile.BirthdayProfile;
|
||||||
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component("birthday:remove.sub")
|
||||||
|
@CommandInfo(name = "remove", description = "Remove your birthday from this guild")
|
||||||
|
public class RemoveSubCommand extends BatCommand {
|
||||||
|
@Override
|
||||||
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
|
BirthdayProfile profile = guild.getBirthdayProfile();
|
||||||
|
|
||||||
|
profile.removeBirthday(user.getId());
|
||||||
|
event.replyEmbeds(EmbedUtils.successEmbed()
|
||||||
|
.setDescription("Your birthday has been removed from this guild")
|
||||||
|
.build()).queue();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,93 @@
|
|||||||
|
package cc.fascinated.bat.birthday.command;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
|
import cc.fascinated.bat.birthday.UserBirthday;
|
||||||
|
import cc.fascinated.bat.birthday.profile.BirthdayProfile;
|
||||||
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component("birthday:add.sub")
|
||||||
|
@CommandInfo(name = "set", description = "Add your birthday to this guild")
|
||||||
|
public class SetSubCommand extends BatCommand {
|
||||||
|
private static final SimpleDateFormat FORMATTER = new SimpleDateFormat("dd/MM/yyyy");
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public SetSubCommand() {
|
||||||
|
super.addOptions(new OptionData(OptionType.STRING, "birthday", "Your birthday (format: DAY/MONTH/YEAR - 01/05/2004)", true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
|
BirthdayProfile profile = guild.getBirthdayProfile();
|
||||||
|
if (!profile.hasChannelSetup()) {
|
||||||
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
|
.setDescription("Birthdays have not been enabled in this guild. Please ask an administrator to enable them.")
|
||||||
|
.build()).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
OptionMapping birthdayOption = event.getOption("birthday");
|
||||||
|
assert birthdayOption != null;
|
||||||
|
String birthdayString = birthdayOption.getAsString();
|
||||||
|
|
||||||
|
Date birthday = parseBirthday(birthdayString);
|
||||||
|
if (birthday == null) {
|
||||||
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
|
.setDescription("""
|
||||||
|
Invalid birthday format. Please use the following format:
|
||||||
|
DAY/MONTH/YEAR - 01/05/2004
|
||||||
|
""")
|
||||||
|
.build()).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UserBirthday userBirthday = new UserBirthday();
|
||||||
|
userBirthday.setBirthday(birthday);
|
||||||
|
userBirthday.setHidden(false);
|
||||||
|
profile.addBirthday(member.getId(), userBirthday);
|
||||||
|
event.replyEmbeds(EmbedUtils.successEmbed()
|
||||||
|
.setDescription("You have updated your birthday!")
|
||||||
|
.build()).queue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a birthday from the string
|
||||||
|
*
|
||||||
|
* @param birthday the date to parse
|
||||||
|
* @return the birthday
|
||||||
|
*/
|
||||||
|
private Date parseBirthday(String birthday) {
|
||||||
|
try {
|
||||||
|
Date date = FORMATTER.parse(birthday);
|
||||||
|
if (date.after(new Date())) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (date.toInstant().toEpochMilli() < 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return date;
|
||||||
|
} catch (ParseException ignored) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,76 @@
|
|||||||
|
package cc.fascinated.bat.birthday.command;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.common.command.BatCommand;
|
||||||
|
import cc.fascinated.bat.common.command.CommandInfo;
|
||||||
|
import cc.fascinated.bat.common.EmbedUtils;
|
||||||
|
import cc.fascinated.bat.birthday.UserBirthday;
|
||||||
|
import cc.fascinated.bat.birthday.profile.BirthdayProfile;
|
||||||
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
|
import cc.fascinated.bat.service.UserService;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
||||||
|
import net.dv8tion.jda.api.interactions.commands.build.OptionData;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Component("birthday:view.sub")
|
||||||
|
@CommandInfo(name = "view", description = "Add your birthday to this guild")
|
||||||
|
public class ViewSubCommand extends BatCommand {
|
||||||
|
private final UserService userService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public ViewSubCommand(@NonNull UserService userService) {
|
||||||
|
this.userService = userService;
|
||||||
|
super.addOptions(new OptionData(OptionType.USER, "user", "The user to view the birthday of", false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, Message commandMessage, String[] arguments, SlashCommandInteraction event) {
|
||||||
|
BirthdayProfile profile = guild.getBirthdayProfile();
|
||||||
|
if (!profile.hasChannelSetup()) {
|
||||||
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
|
.setDescription("Birthdays have not been enabled in this guild. Please ask an administrator to enable them.")
|
||||||
|
.build()).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
OptionMapping birthdayOption = event.getOption("user");
|
||||||
|
BatUser target = birthdayOption == null ? user : userService.getUser(birthdayOption.getAsUser().getId());
|
||||||
|
if (target == null) {
|
||||||
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
|
.setDescription("You must provide a valid user")
|
||||||
|
.build()).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
UserBirthday birthday = profile.getBirthday(target.getId());
|
||||||
|
if (birthday == null) {
|
||||||
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
|
.setDescription("%s does not have a birthday set".formatted(target.getDiscordUser().getAsMention()))
|
||||||
|
.build()).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (birthday.isHidden() && !user.getId().equals(target.getId())) {
|
||||||
|
event.replyEmbeds(EmbedUtils.errorEmbed()
|
||||||
|
.setDescription("%s has their birthday set to private".formatted(target.getDiscordUser().getAsMention()))
|
||||||
|
.build()).queue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
event.replyEmbeds(EmbedUtils.successEmbed()
|
||||||
|
.setDescription("%s was born on <t:%s:D> they are `%s` years old!".formatted(
|
||||||
|
target.getDiscordUser().getAsMention(), birthday.getBirthday().toInstant().toEpochMilli()/1000,
|
||||||
|
birthday.calculateAge()
|
||||||
|
))
|
||||||
|
.build()).queue();
|
||||||
|
}
|
||||||
|
}
|
@ -1,28 +1,37 @@
|
|||||||
package cc.fascinated.bat.features.birthday.profile;
|
package cc.fascinated.bat.birthday.profile;
|
||||||
|
|
||||||
import cc.fascinated.bat.common.Profile;
|
import cc.fascinated.bat.common.ChannelUtils;
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.common.Serializable;
|
||||||
|
import cc.fascinated.bat.birthday.UserBirthday;
|
||||||
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
|
import com.google.gson.Gson;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import net.dv8tion.jda.api.entities.Guild;
|
import net.dv8tion.jda.api.entities.Guild;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
import net.dv8tion.jda.api.entities.User;
|
import net.dv8tion.jda.api.entities.User;
|
||||||
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
||||||
|
import org.bson.Document;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fascinated (fascinated7)
|
* @author Fascinated (fascinated7)
|
||||||
*/
|
*/
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
public class BirthdayProfile extends Profile {
|
@NoArgsConstructor
|
||||||
|
public class BirthdayProfile extends Serializable {
|
||||||
private static final String DEFAULT_MESSAGE = "Happy Birthday {user} :tada: :birthday: You are now {age} years old!";
|
private static final String DEFAULT_MESSAGE = "Happy Birthday {user} :tada: :birthday: You are now {age} years old!";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of birthdays that are being tracked
|
* The list of birthdays that are being tracked
|
||||||
*/
|
*/
|
||||||
private Map<String, Date> birthdays;
|
private Map<String, UserBirthday> birthdays;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The channel ID of the birthday feed
|
* The channel ID of the birthday feed
|
||||||
@ -34,17 +43,13 @@ public class BirthdayProfile extends Profile {
|
|||||||
*/
|
*/
|
||||||
private String message = DEFAULT_MESSAGE;
|
private String message = DEFAULT_MESSAGE;
|
||||||
|
|
||||||
public BirthdayProfile() {
|
|
||||||
super("birthday");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a birthday to be tracked
|
* Adds a birthday to be tracked
|
||||||
*
|
*
|
||||||
* @param userId the id of the user to track
|
* @param userId the id of the user to track
|
||||||
* @param birthday the birthday of the user
|
* @param birthday the birthday of the user
|
||||||
*/
|
*/
|
||||||
public void addBirthday(String userId, Date birthday) {
|
public void addBirthday(String userId, UserBirthday birthday) {
|
||||||
if (birthdays == null) {
|
if (birthdays == null) {
|
||||||
birthdays = new HashMap<>();
|
birthdays = new HashMap<>();
|
||||||
}
|
}
|
||||||
@ -69,7 +74,7 @@ public class BirthdayProfile extends Profile {
|
|||||||
* @param userId the id of the user
|
* @param userId the id of the user
|
||||||
* @return the birthday of the user
|
* @return the birthday of the user
|
||||||
*/
|
*/
|
||||||
public Date getBirthday(String userId) {
|
public UserBirthday getBirthday(String userId) {
|
||||||
if (birthdays == null) {
|
if (birthdays == null) {
|
||||||
birthdays = new HashMap<>();
|
birthdays = new HashMap<>();
|
||||||
}
|
}
|
||||||
@ -85,33 +90,6 @@ public class BirthdayProfile extends Profile {
|
|||||||
return channelId != null;
|
return channelId != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the age of a user
|
|
||||||
*
|
|
||||||
* @param userId the id of the user
|
|
||||||
* @return the age of the user
|
|
||||||
*/
|
|
||||||
public int calculateAge(String userId) {
|
|
||||||
Date birthday = getBirthday(userId);
|
|
||||||
if (birthday == null) {
|
|
||||||
return 0; // or throw an exception
|
|
||||||
}
|
|
||||||
|
|
||||||
Calendar birthdayCalendar = Calendar.getInstance();
|
|
||||||
birthdayCalendar.setTime(birthday);
|
|
||||||
|
|
||||||
Calendar today = Calendar.getInstance();
|
|
||||||
|
|
||||||
int age = today.get(Calendar.YEAR) - birthdayCalendar.get(Calendar.YEAR);
|
|
||||||
|
|
||||||
// Check if the birthday hasn't occurred yet this year
|
|
||||||
if (today.get(Calendar.DAY_OF_YEAR) < birthdayCalendar.get(Calendar.DAY_OF_YEAR)) {
|
|
||||||
age--;
|
|
||||||
}
|
|
||||||
|
|
||||||
return age;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates the profiles configuration
|
* Validates the profiles configuration
|
||||||
*
|
*
|
||||||
@ -122,33 +100,10 @@ public class BirthdayProfile extends Profile {
|
|||||||
if (birthdays == null) {
|
if (birthdays == null) {
|
||||||
birthdays = new HashMap<>();
|
birthdays = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> toRemove = new ArrayList<>();
|
|
||||||
Guild discordGuild = guild.getDiscordGuild();
|
|
||||||
for (Map.Entry<String, Date> entry : birthdays.entrySet()) {
|
|
||||||
String userId = entry.getKey();
|
|
||||||
Date birthday = entry.getValue();
|
|
||||||
|
|
||||||
if (userId == null || birthday == null) { // this should never happen
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the user is still in the guild, if not remove them
|
|
||||||
Member member = discordGuild.getMemberById(userId);
|
|
||||||
if (member == null) {
|
|
||||||
toRemove.add(userId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (String userId : toRemove) {
|
|
||||||
birthdays.remove(userId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (channelId == null) {
|
if (channelId == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (guild.getDiscordGuild().getTextChannelById(channelId) == null) {
|
||||||
if (discordGuild.getTextChannelById(channelId) == null) {
|
|
||||||
channelId = null;
|
channelId = null;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -170,13 +125,10 @@ public class BirthdayProfile extends Profile {
|
|||||||
int todayDay = today.get(Calendar.DAY_OF_MONTH);
|
int todayDay = today.get(Calendar.DAY_OF_MONTH);
|
||||||
int todayMonth = today.get(Calendar.MONTH); // Note: January is 0
|
int todayMonth = today.get(Calendar.MONTH); // Note: January is 0
|
||||||
|
|
||||||
Iterator<Map.Entry<String, Date>> iterator = birthdays.entrySet().iterator();
|
for (Map.Entry<String, UserBirthday> entry : birthdays.entrySet()) {
|
||||||
while (iterator.hasNext()) {
|
Date birthday = entry.getValue().getBirthday();
|
||||||
Map.Entry<String, Date> entry = iterator.next();
|
|
||||||
Date birthday = entry.getValue();
|
|
||||||
|
|
||||||
if (birthday == null) {
|
if (birthday == null) {
|
||||||
iterator.remove();
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,7 +158,7 @@ public class BirthdayProfile extends Profile {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TextChannel channel = discordGuild.getTextChannelById(channelId);
|
TextChannel channel = ChannelUtils.getTextChannel(channelId);
|
||||||
if (channel == null) { // this should never happen
|
if (channel == null) { // this should never happen
|
||||||
channelId = null;
|
channelId = null;
|
||||||
return;
|
return;
|
||||||
@ -223,7 +175,7 @@ public class BirthdayProfile extends Profile {
|
|||||||
public String getBirthdayMessage(User user) {
|
public String getBirthdayMessage(User user) {
|
||||||
return message
|
return message
|
||||||
.replace("{user}", user.getAsMention())
|
.replace("{user}", user.getAsMention())
|
||||||
.replace("{age}", String.valueOf(calculateAge(user.getId())));
|
.replace("{age}", String.valueOf(birthdays.get(user.getId()).calculateAge()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -231,4 +183,27 @@ public class BirthdayProfile extends Profile {
|
|||||||
birthdays.clear();
|
birthdays.clear();
|
||||||
channelId = null;
|
channelId = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void load(Document document, Gson gson) {
|
||||||
|
birthdays = new HashMap<>();
|
||||||
|
for (String key : document.keySet()) {
|
||||||
|
UserBirthday userBirthday = new UserBirthday();
|
||||||
|
userBirthday.load((Document) document.get(key), gson);
|
||||||
|
birthdays.put(key, userBirthday);
|
||||||
|
}
|
||||||
|
channelId = document.getString("channelId");
|
||||||
|
message = (String) document.getOrDefault("message", DEFAULT_MESSAGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Document serialize(Gson gson) {
|
||||||
|
Document document = new Document();
|
||||||
|
for (String key : birthdays.keySet()) {
|
||||||
|
document.put(key, birthdays.get(key).serialize(gson));
|
||||||
|
}
|
||||||
|
document.put("channelId", channelId);
|
||||||
|
document.put("message", message);
|
||||||
|
return document;
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,91 +0,0 @@
|
|||||||
package cc.fascinated.bat.command;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.NonNull;
|
|
||||||
import lombok.Setter;
|
|
||||||
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
|
||||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
|
||||||
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
|
||||||
import net.dv8tion.jda.internal.interactions.CommandDataImpl;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fascinated (fascinated7)
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
public abstract class BatCommand implements BatCommandExecutor {
|
|
||||||
/**
|
|
||||||
* The information about the command
|
|
||||||
*/
|
|
||||||
private final CommandInfo commandInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The command data for the slash command
|
|
||||||
*/
|
|
||||||
private final CommandDataImpl commandData;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The sub commands of the command
|
|
||||||
*/
|
|
||||||
private final Map<String, BatSubCommand> subCommands = new HashMap<>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The category of the command
|
|
||||||
*/
|
|
||||||
private Category category;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether the command can only be used by the bot owner
|
|
||||||
*/
|
|
||||||
private boolean botOwnerOnly;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The command snowflake from Discord
|
|
||||||
*/
|
|
||||||
private long commandSnowflake;
|
|
||||||
|
|
||||||
public BatCommand() {
|
|
||||||
this.commandInfo = getClass().getAnnotation(CommandInfo.class);
|
|
||||||
this.category = this.commandInfo.category();
|
|
||||||
this.botOwnerOnly = this.commandInfo.botOwnerOnly();
|
|
||||||
|
|
||||||
this.commandData = new CommandDataImpl(this.commandInfo.name(), this.commandInfo.description())
|
|
||||||
.setGuildOnly(this.commandInfo.guildOnly());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a sub command to the command
|
|
||||||
*
|
|
||||||
* @param subCommand The sub command
|
|
||||||
*/
|
|
||||||
public void addSubCommand(@NonNull BatSubCommand subCommand) {
|
|
||||||
this.subCommands.put(subCommand.getCommandInfo().name().toLowerCase(), subCommand);
|
|
||||||
this.commandData.addSubcommands(subCommand.getCommandData());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an option to the sub command
|
|
||||||
*
|
|
||||||
* @param optionType the type of the option
|
|
||||||
* @param name the name of the option
|
|
||||||
* @param description the description of the option
|
|
||||||
* @param required whether the option is required
|
|
||||||
*/
|
|
||||||
protected void addOption(OptionType optionType, String name, String description, boolean required) {
|
|
||||||
this.commandData.addOption(optionType, name, description, required);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets all the options for the command
|
|
||||||
*
|
|
||||||
* @param interaction The slash command interaction
|
|
||||||
* @return The option strings
|
|
||||||
*/
|
|
||||||
public List<String> getOptions(SlashCommandInteraction interaction) {
|
|
||||||
return interaction.getOptions().stream().map(OptionMapping::getName).toList();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
package cc.fascinated.bat.command;
|
|
||||||
|
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
|
||||||
import cc.fascinated.bat.model.BatUser;
|
|
||||||
import lombok.NonNull;
|
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
|
||||||
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fascinated (fascinated7)
|
|
||||||
*/
|
|
||||||
public interface BatCommandExecutor {
|
|
||||||
/**
|
|
||||||
* Executes the command using a slash command interaction.
|
|
||||||
*
|
|
||||||
* @param guild the bat guild the command was executed in (null if the command was executed in a DM)
|
|
||||||
* @param user the bat user that executed the command
|
|
||||||
* @param channel the channel the command was executed in
|
|
||||||
* @param member the member that executed the command
|
|
||||||
* @param interaction the slash command interaction
|
|
||||||
*/
|
|
||||||
default void execute(
|
|
||||||
BatGuild guild,
|
|
||||||
@NonNull BatUser user,
|
|
||||||
@NonNull MessageChannel channel,
|
|
||||||
Member member,
|
|
||||||
@NonNull SlashCommandInteraction interaction
|
|
||||||
) {
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,45 +0,0 @@
|
|||||||
package cc.fascinated.bat.command;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
|
||||||
import net.dv8tion.jda.api.interactions.commands.build.SubcommandData;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fascinated (fascinated7)
|
|
||||||
*/
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
public class BatSubCommand implements BatCommandExecutor {
|
|
||||||
/**
|
|
||||||
* The information about the sub command
|
|
||||||
*/
|
|
||||||
private final CommandInfo commandInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The command data for the slash command
|
|
||||||
*/
|
|
||||||
private final SubcommandData commandData;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The commands snowflake from Discord
|
|
||||||
*/
|
|
||||||
private long commandSnowflake;
|
|
||||||
|
|
||||||
public BatSubCommand() {
|
|
||||||
this.commandInfo = getClass().getAnnotation(CommandInfo.class);
|
|
||||||
this.commandData = new SubcommandData(this.commandInfo.name(), this.commandInfo.description());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an option to the sub command
|
|
||||||
*
|
|
||||||
* @param optionType the type of the option
|
|
||||||
* @param name the name of the option
|
|
||||||
* @param description the description of the option
|
|
||||||
* @param required whether the option is required
|
|
||||||
*/
|
|
||||||
public void addOption(OptionType optionType, String name, String description, boolean required) {
|
|
||||||
this.commandData.addOption(optionType, name, description, required);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,62 +0,0 @@
|
|||||||
package cc.fascinated.bat.command;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
import net.dv8tion.jda.api.entities.emoji.Emoji;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fascinated (fascinated7)
|
|
||||||
*/
|
|
||||||
@AllArgsConstructor
|
|
||||||
@Getter
|
|
||||||
public enum Category {
|
|
||||||
GENERAL(Emoji.fromUnicode("U+2699"), "General", false),
|
|
||||||
FUN(Emoji.fromFormatted("U+1F973"), "Fun", false),
|
|
||||||
SERVER(Emoji.fromFormatted("U+1F5A5"), "Server", false),
|
|
||||||
UTILITY(Emoji.fromFormatted("U+1F6E0"), "Utility", false),
|
|
||||||
MUSIC(Emoji.fromFormatted("U+1F3B5"), "Music", false),
|
|
||||||
BEAT_SABER(Emoji.fromFormatted("U+1FA84"), "Beat Saber", false),
|
|
||||||
BOT_ADMIN(null, null, true);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The emoji for the category
|
|
||||||
*/
|
|
||||||
private final Emoji emoji;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of the category
|
|
||||||
*/
|
|
||||||
private final String name;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If the category is hidden
|
|
||||||
*/
|
|
||||||
private final boolean hidden;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a category by its name
|
|
||||||
*
|
|
||||||
* @param name the name of the category
|
|
||||||
* @return the category
|
|
||||||
*/
|
|
||||||
public static Category getByName(String name) {
|
|
||||||
for (Category category : Category.values()) {
|
|
||||||
if (category.getName().equalsIgnoreCase(name)) {
|
|
||||||
return category;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets all the visible categories
|
|
||||||
*
|
|
||||||
* @return the visible categories
|
|
||||||
*/
|
|
||||||
public static List<Category> getCategories() {
|
|
||||||
return Arrays.stream(Category.values()).filter(category -> !category.isHidden()).toList();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
package cc.fascinated.bat.command.impl.botadmin.premium;
|
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatCommand;
|
|
||||||
import cc.fascinated.bat.command.Category;
|
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
|
||||||
import lombok.NonNull;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.context.ApplicationContext;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fascinated (fascinated7)
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
@CommandInfo(name = "premiumadmin", description = "Set a guild as premium", botOwnerOnly = true, category = Category.BOT_ADMIN)
|
|
||||||
public class PremiumAdminCommand extends BatCommand {
|
|
||||||
@Autowired
|
|
||||||
public PremiumAdminCommand(@NonNull ApplicationContext context) {
|
|
||||||
super.addSubCommand(context.getBean(SetSubCommand.class));
|
|
||||||
super.addSubCommand(context.getBean(RemoveSubCommand.class));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,54 +0,0 @@
|
|||||||
package cc.fascinated.bat.command.impl.botadmin.premium;
|
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatSubCommand;
|
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
|
||||||
import cc.fascinated.bat.model.BatUser;
|
|
||||||
import cc.fascinated.bat.service.GuildService;
|
|
||||||
import lombok.NonNull;
|
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
|
||||||
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
|
||||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
|
||||||
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fascinated (fascinated7)
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
@CommandInfo(name = "remove", description = "Remove premium from a guild")
|
|
||||||
public class RemoveSubCommand extends BatSubCommand {
|
|
||||||
private final GuildService guildService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public RemoveSubCommand(GuildService guildService) {
|
|
||||||
this.guildService = guildService;
|
|
||||||
super.addOption(OptionType.STRING, "guild", "The guild id to set as premium", true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction interaction) {
|
|
||||||
OptionMapping guildOption = interaction.getOption("guild");
|
|
||||||
if (guildOption == null) {
|
|
||||||
interaction.reply("Please provide a guild id").queue();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String guildId = guildOption.getAsString();
|
|
||||||
BatGuild batGuild = guildService.getGuild(guildId);
|
|
||||||
if (batGuild == null) {
|
|
||||||
interaction.reply("The guild with the id %s does not exist".formatted(guildId)).queue();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
BatGuild.Premium premium = batGuild.getPremium();
|
|
||||||
if (!premium.hasPremium()) {
|
|
||||||
interaction.reply("The guild does not have premium").queue();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
premium.removePremium();
|
|
||||||
guildService.saveGuild(batGuild);
|
|
||||||
interaction.reply("The guild **%s** has had its premium removed".formatted(guild.getName())).queue();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,65 +0,0 @@
|
|||||||
package cc.fascinated.bat.command.impl.botadmin.premium;
|
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatSubCommand;
|
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
|
||||||
import cc.fascinated.bat.model.BatUser;
|
|
||||||
import cc.fascinated.bat.service.GuildService;
|
|
||||||
import lombok.NonNull;
|
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
|
||||||
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
|
||||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
|
||||||
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fascinated (fascinated7)
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
@CommandInfo(name = "set", description = "Adds premium to a guild")
|
|
||||||
public class SetSubCommand extends BatSubCommand {
|
|
||||||
private final GuildService guildService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public SetSubCommand(GuildService guildService) {
|
|
||||||
this.guildService = guildService;
|
|
||||||
super.addOption(OptionType.STRING, "guild", "The guild id to set as premium", true);
|
|
||||||
super.addOption(OptionType.BOOLEAN, "infinite", "Whether the premium length should be infinite", true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction interaction) {
|
|
||||||
OptionMapping guildOption = interaction.getOption("guild");
|
|
||||||
if (guildOption == null) {
|
|
||||||
interaction.reply("Please provide a guild id").queue();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String guildId = guildOption.getAsString();
|
|
||||||
OptionMapping infiniteOption = interaction.getOption("infinite");
|
|
||||||
if (infiniteOption == null) {
|
|
||||||
interaction.reply("Please provide whether the premium length should be infinite").queue();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean infinite = infiniteOption.getAsBoolean();
|
|
||||||
BatGuild batGuild = guildService.getGuild(guildId);
|
|
||||||
if (batGuild == null) {
|
|
||||||
interaction.reply("The guild with the id %s does not exist".formatted(guildId)).queue();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
BatGuild.Premium premium = batGuild.getPremium();
|
|
||||||
if (!infinite) {
|
|
||||||
premium.addTime();
|
|
||||||
} else {
|
|
||||||
premium.addInfiniteTime();
|
|
||||||
}
|
|
||||||
guildService.saveGuild(batGuild);
|
|
||||||
if (!infinite) {
|
|
||||||
interaction.reply("The guild **%s** has been set as premium until <t:%s>".formatted(guild.getName(), premium.getExpiresAt().toInstant().toEpochMilli() / 1000)).queue();
|
|
||||||
} else {
|
|
||||||
interaction.reply("The guild **%s** has been set as premium indefinitely".formatted(guild.getName())).queue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
package cc.fascinated.bat.command.impl.fun.image;
|
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatCommand;
|
|
||||||
import cc.fascinated.bat.command.Category;
|
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
|
||||||
import lombok.NonNull;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.context.ApplicationContext;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fascinated (fascinated7)
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
@CommandInfo(name = "image", description = "View a random image", guildOnly = false, category = Category.FUN)
|
|
||||||
public class ImageCommand extends BatCommand {
|
|
||||||
@Autowired
|
|
||||||
public ImageCommand(@NonNull ApplicationContext context) {
|
|
||||||
super.addSubCommand(context.getBean(CatSubCommand.class));
|
|
||||||
super.addSubCommand(context.getBean(DogSubCommand.class));
|
|
||||||
super.addSubCommand(context.getBean(FoxSubCommand.class));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,55 +0,0 @@
|
|||||||
package cc.fascinated.bat.command.impl.general;
|
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatCommand;
|
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
|
||||||
import cc.fascinated.bat.common.TimeUtils;
|
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
|
||||||
import cc.fascinated.bat.model.BatUser;
|
|
||||||
import cc.fascinated.bat.service.DiscordService;
|
|
||||||
import cc.fascinated.bat.service.GuildService;
|
|
||||||
import cc.fascinated.bat.service.UserService;
|
|
||||||
import lombok.NonNull;
|
|
||||||
import net.dv8tion.jda.api.JDA;
|
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
|
||||||
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.lang.management.ManagementFactory;
|
|
||||||
import java.lang.management.RuntimeMXBean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fascinated (fascinated7)
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
@CommandInfo(name = "botstats", description = "Shows the bot statistics", guildOnly = false)
|
|
||||||
public class BotStatsCommand extends BatCommand {
|
|
||||||
private final GuildService guildService;
|
|
||||||
private final UserService userService;
|
|
||||||
private final RuntimeMXBean bean = ManagementFactory.getRuntimeMXBean();
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public BotStatsCommand(@NonNull GuildService guildService, @NonNull UserService userService) {
|
|
||||||
this.guildService = guildService;
|
|
||||||
this.userService = userService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction interaction) {
|
|
||||||
JDA jda = DiscordService.JDA;
|
|
||||||
|
|
||||||
interaction.replyEmbeds(EmbedUtils.genericEmbed().setDescription(
|
|
||||||
"**Bot Statistics**\n" +
|
|
||||||
"➜ Guilds: **%s**\n".formatted(jda.getGuilds().size()) +
|
|
||||||
"➜ Users: **%s**\n".formatted(jda.getUsers().size()) +
|
|
||||||
"➜ Gateway Ping: **%sms**\n".formatted(jda.getGatewayPing()) +
|
|
||||||
"\n" +
|
|
||||||
"**Bat Statistics**\n" +
|
|
||||||
"➜ Uptime: **%s**\n".formatted(TimeUtils.format(bean.getUptime())) +
|
|
||||||
"➜ Cached Guilds: **%s**\n".formatted(guildService.getGuilds().size()) +
|
|
||||||
"➜ Cached Users: **%s**".formatted(userService.getUsers().size())
|
|
||||||
).build()).queue();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,150 +0,0 @@
|
|||||||
package cc.fascinated.bat.command.impl.general;
|
|
||||||
|
|
||||||
import cc.fascinated.bat.Consts;
|
|
||||||
import cc.fascinated.bat.command.BatCommand;
|
|
||||||
import cc.fascinated.bat.command.BatSubCommand;
|
|
||||||
import cc.fascinated.bat.command.Category;
|
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
|
||||||
import cc.fascinated.bat.event.EventListener;
|
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
|
||||||
import cc.fascinated.bat.model.BatUser;
|
|
||||||
import cc.fascinated.bat.service.CommandService;
|
|
||||||
import lombok.NonNull;
|
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
|
||||||
import net.dv8tion.jda.api.entities.MessageEmbed;
|
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
|
||||||
import net.dv8tion.jda.api.entities.emoji.Emoji;
|
|
||||||
import net.dv8tion.jda.api.events.interaction.component.StringSelectInteractionEvent;
|
|
||||||
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
|
||||||
import net.dv8tion.jda.api.interactions.commands.build.SubcommandData;
|
|
||||||
import net.dv8tion.jda.api.interactions.components.ActionRow;
|
|
||||||
import net.dv8tion.jda.api.interactions.components.LayoutComponent;
|
|
||||||
import net.dv8tion.jda.api.interactions.components.buttons.Button;
|
|
||||||
import net.dv8tion.jda.api.interactions.components.buttons.ButtonStyle;
|
|
||||||
import net.dv8tion.jda.api.interactions.components.selections.SelectOption;
|
|
||||||
import net.dv8tion.jda.api.interactions.components.selections.StringSelectMenu;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fascinated (fascinated7)
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
@CommandInfo(name = "help", description = "View the bots command categories.", guildOnly = false)
|
|
||||||
public class HelpCommand extends BatCommand implements EventListener {
|
|
||||||
private final CommandService commandService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public HelpCommand(@NonNull CommandService commandService) {
|
|
||||||
this.commandService = commandService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction interaction) {
|
|
||||||
interaction.replyEmbeds(createHomeEmbed()).addComponents(createHomeActions()).queue();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStringSelectInteraction(BatGuild guild, @NonNull BatUser user, @NonNull StringSelectInteractionEvent event) {
|
|
||||||
String item = event.getSelectedOptions().get(0).getValue();
|
|
||||||
if (item.equalsIgnoreCase("home")) {
|
|
||||||
event.editMessageEmbeds(createHomeEmbed()).queue();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Category category = Category.getByName(item);
|
|
||||||
if (category == null) {
|
|
||||||
event.reply("Invalid category selected.").queue();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String commands = "";
|
|
||||||
List<BatCommand> categoryCommands = commandService.getCommandsByCategory(category, true);
|
|
||||||
if (categoryCommands.isEmpty()) {
|
|
||||||
commands = "No commands available in this category.";
|
|
||||||
} else {
|
|
||||||
for (BatCommand command : categoryCommands) {
|
|
||||||
if (!command.getSubCommands().isEmpty()) {
|
|
||||||
for (Map.Entry<String, BatSubCommand> entry : command.getSubCommands().entrySet()) {
|
|
||||||
BatSubCommand subCommand = entry.getValue();
|
|
||||||
SubcommandData commandData = subCommand.getCommandData();
|
|
||||||
commands += "</%s %s:%s> - %s\n".formatted(
|
|
||||||
command.getCommandInfo().name(),
|
|
||||||
commandData.getName(),
|
|
||||||
subCommand.getCommandSnowflake(),
|
|
||||||
commandData.getDescription()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
commands += "</%s:%s> - %s\n".formatted(
|
|
||||||
command.getCommandInfo().name(),
|
|
||||||
command.getCommandSnowflake(),
|
|
||||||
command.getCommandInfo().description()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int subCommands = categoryCommands.stream().mapToInt(command -> command.getSubCommands().size()).sum();
|
|
||||||
event.editMessageEmbeds(EmbedUtils.genericEmbed()
|
|
||||||
.setAuthor("%s Category".formatted(category.getName()))
|
|
||||||
.setDescription("%s command%s (with %s sub-command%s)\n\n**Commands:**\n%s".formatted(
|
|
||||||
categoryCommands.size(),
|
|
||||||
categoryCommands.size() == 1 ? "" : "s",
|
|
||||||
subCommands,
|
|
||||||
subCommands == 1 ? "" : "s",
|
|
||||||
commands
|
|
||||||
)).build()).queue();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates the home embed for the help command
|
|
||||||
*
|
|
||||||
* @return The home embed
|
|
||||||
*/
|
|
||||||
private MessageEmbed createHomeEmbed() {
|
|
||||||
String categories = "";
|
|
||||||
for (Category category : Category.getCategories()) {
|
|
||||||
long commandCount = commandService.getCommandsByCategory(category, true).size();
|
|
||||||
categories += "➜ %s - **%s Command%s**\n".formatted(
|
|
||||||
category.getName(),
|
|
||||||
commandCount,
|
|
||||||
commandCount == 1 ? "" : "s"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return EmbedUtils.genericEmbed()
|
|
||||||
.setDescription("Here are the available command categories: \n\n" + categories)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates the home actions for the help command
|
|
||||||
*
|
|
||||||
* @return The layout components
|
|
||||||
*/
|
|
||||||
private LayoutComponent[] createHomeActions() {
|
|
||||||
List<SelectOption> options = new ArrayList<>();
|
|
||||||
options.add(SelectOption.of("Home", "home").withEmoji(Emoji.fromUnicode("U+1F3E0")));
|
|
||||||
options.addAll(Category.getCategories().stream().map(category ->
|
|
||||||
SelectOption.of(category.getName(), category.getName()).withEmoji(category.getEmoji()))
|
|
||||||
.toList());
|
|
||||||
|
|
||||||
return new LayoutComponent[]{
|
|
||||||
ActionRow.of(
|
|
||||||
Button.of(ButtonStyle.LINK, Consts.INVITE_URL, "Invite"),
|
|
||||||
Button.of(ButtonStyle.LINK, Consts.SUPPORT_INVITE_URL, "Support")
|
|
||||||
),
|
|
||||||
ActionRow.of(
|
|
||||||
StringSelectMenu.create("help-menu")
|
|
||||||
.addOptions(options)
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
package cc.fascinated.bat.command.impl.server;
|
|
||||||
|
|
||||||
import cc.fascinated.bat.command.BatCommand;
|
|
||||||
import cc.fascinated.bat.command.CommandInfo;
|
|
||||||
import cc.fascinated.bat.common.EmbedUtils;
|
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
|
||||||
import cc.fascinated.bat.model.BatUser;
|
|
||||||
import lombok.NonNull;
|
|
||||||
import net.dv8tion.jda.api.EmbedBuilder;
|
|
||||||
import net.dv8tion.jda.api.entities.Guild;
|
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
|
||||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
|
||||||
import net.dv8tion.jda.api.interactions.commands.SlashCommandInteraction;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Nick (okNick)
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
@CommandInfo(name = "membercount", description = "View the member count of the server!")
|
|
||||||
public class MemberCountCommand extends BatCommand {
|
|
||||||
@Override
|
|
||||||
public void execute(BatGuild guild, @NonNull BatUser user, @NonNull MessageChannel channel, Member member, @NonNull SlashCommandInteraction interaction) {
|
|
||||||
EmbedBuilder embed = EmbedUtils.genericEmbed().setAuthor("Member Count");
|
|
||||||
Guild discordGuild = guild.getDiscordGuild();
|
|
||||||
embed.setDescription("**%s** has a total of %s members.".formatted(discordGuild.getName(), discordGuild.getMembers().size()));
|
|
||||||
interaction.replyEmbeds(embed.build()).queue();
|
|
||||||
}
|
|
||||||
}
|
|
48
src/main/java/cc/fascinated/bat/common/ChannelUtils.java
Normal file
48
src/main/java/cc/fascinated/bat/common/ChannelUtils.java
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
package cc.fascinated.bat.common;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.service.DiscordService;
|
||||||
|
import lombok.experimental.UtilityClass;
|
||||||
|
import lombok.extern.log4j.Log4j2;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@UtilityClass
|
||||||
|
@Log4j2(topic = "ChannelUtils")
|
||||||
|
public class ChannelUtils {
|
||||||
|
/**
|
||||||
|
* Gets the user with the given id
|
||||||
|
*
|
||||||
|
* @param id the id of the user
|
||||||
|
* @param retries the amount of retries
|
||||||
|
* @return the user with the given id
|
||||||
|
*/
|
||||||
|
private static TextChannel getTextChannel(String id, int retries) {
|
||||||
|
if (retries >= 10) {
|
||||||
|
log.error("Failed to find user \"{}\" after {} retries.", id, retries);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (id == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
TextChannel channel = DiscordService.JDA.getTextChannelById(id);
|
||||||
|
if (channel == null) {
|
||||||
|
return getTextChannel(id, retries + 1);
|
||||||
|
}
|
||||||
|
if (retries >= 5) {
|
||||||
|
log.info("Found text channel \"{}\" after {} retries.", channel.getName(), retries);
|
||||||
|
}
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the user with the given id
|
||||||
|
*
|
||||||
|
* @param id the id of the user
|
||||||
|
* @return the user with the given id
|
||||||
|
*/
|
||||||
|
public static TextChannel getTextChannel(String id) {
|
||||||
|
return getTextChannel(id, 0);
|
||||||
|
}
|
||||||
|
}
|
@ -3,12 +3,18 @@ package cc.fascinated.bat.common;
|
|||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
import java.time.ZoneId;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
@UtilityClass
|
@UtilityClass
|
||||||
public class DateUtils {
|
public class DateUtils {
|
||||||
|
private static final ZoneId ZONE_ID = ZoneId.of("Europe/London");
|
||||||
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ISO_INSTANT;
|
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ISO_INSTANT;
|
||||||
|
private static final DateTimeFormatter SIMPLE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss z")
|
||||||
|
.withLocale(Locale.UK)
|
||||||
|
.withZone(ZONE_ID);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the date from a string.
|
* Gets the date from a string.
|
||||||
@ -19,4 +25,14 @@ public class DateUtils {
|
|||||||
public static Date getDateFromString(String date) {
|
public static Date getDateFromString(String date) {
|
||||||
return Date.from(Instant.from(FORMATTER.parse(date)));
|
return Date.from(Instant.from(FORMATTER.parse(date)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats a date to a string.
|
||||||
|
*
|
||||||
|
* @param date The date to format.
|
||||||
|
* @return The formatted date.
|
||||||
|
*/
|
||||||
|
public String formatDate(Date date) {
|
||||||
|
return SIMPLE_FORMATTER.format(date.toInstant());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,43 @@
|
|||||||
|
package cc.fascinated.bat.common;
|
||||||
|
|
||||||
|
import lombok.NonNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
public class DescriptionBuilder {
|
||||||
|
/**
|
||||||
|
* Where the description is stored
|
||||||
|
*/
|
||||||
|
private final StringBuilder builder = new StringBuilder();
|
||||||
|
|
||||||
|
public DescriptionBuilder(String title) {
|
||||||
|
if (title == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
builder.append("**").append(title).append("**").append("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public DescriptionBuilder appendLine(@NonNull String line, boolean arrow) {
|
||||||
|
builder.append(arrow ? "➜ " : "").append(line).append("\n");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public DescriptionBuilder appendSubtitle(@NonNull String title) {
|
||||||
|
builder.append("**").append(title).append("**").append("\n");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public DescriptionBuilder emptyLine() {
|
||||||
|
builder.append("\n");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public String build() {
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,9 @@
|
|||||||
package cc.fascinated.bat.common;
|
package cc.fascinated.bat.common;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.config.Config;
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
import net.dv8tion.jda.api.EmbedBuilder;
|
import net.dv8tion.jda.api.EmbedBuilder;
|
||||||
|
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
@ -42,4 +44,30 @@ public class EmbedUtils {
|
|||||||
.setTimestamp(LocalDateTime.now())
|
.setTimestamp(LocalDateTime.now())
|
||||||
.setColor(Colors.SUCCESS);
|
.setColor(Colors.SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds a generic interaction error embed
|
||||||
|
*
|
||||||
|
* @param ex the exceptionk
|
||||||
|
* @return the embed builder
|
||||||
|
*/
|
||||||
|
public static EmbedBuilder genericInteractionError(Exception ex) {
|
||||||
|
TextChannel channel = ChannelUtils.getTextChannel(Config.INSTANCE.getLogsChannel());
|
||||||
|
EmbedBuilder embed = errorEmbed()
|
||||||
|
.setDescription("""
|
||||||
|
An error has occurred while processing %s interaction. If this issue persists, please contact the developers.
|
||||||
|
Cause: `%s`
|
||||||
|
```java
|
||||||
|
%s
|
||||||
|
```""".formatted(
|
||||||
|
channel == null ? "an" : "your",
|
||||||
|
ex.getStackTrace()[0].getClassName(),
|
||||||
|
ex.getLocalizedMessage()
|
||||||
|
));
|
||||||
|
|
||||||
|
if (channel != null) {
|
||||||
|
channel.sendMessageEmbeds(embed.build()).queue();
|
||||||
|
}
|
||||||
|
return embed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
24
src/main/java/cc/fascinated/bat/common/EnumUtils.java
Normal file
24
src/main/java/cc/fascinated/bat/common/EnumUtils.java
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package cc.fascinated.bat.common;
|
||||||
|
|
||||||
|
import lombok.experimental.UtilityClass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@UtilityClass
|
||||||
|
public class EnumUtils {
|
||||||
|
/**
|
||||||
|
* Gets the name of the enum
|
||||||
|
*
|
||||||
|
* @param e the enum
|
||||||
|
* @return the name
|
||||||
|
*/
|
||||||
|
public static String getEnumName(Enum<?> e) {
|
||||||
|
String[] split = e.name().split("_");
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
for (String s : split) {
|
||||||
|
builder.append(s.substring(0, 1).toUpperCase()).append(s.substring(1).toLowerCase()).append(" ");
|
||||||
|
}
|
||||||
|
return builder.toString().trim();
|
||||||
|
}
|
||||||
|
}
|
58
src/main/java/cc/fascinated/bat/common/HexColorUtils.java
Normal file
58
src/main/java/cc/fascinated/bat/common/HexColorUtils.java
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
package cc.fascinated.bat.common;
|
||||||
|
|
||||||
|
import lombok.experimental.UtilityClass;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@UtilityClass
|
||||||
|
public class HexColorUtils {
|
||||||
|
/**
|
||||||
|
* Checks if the given string is a hex color
|
||||||
|
*
|
||||||
|
* @param hexColor the hex color to check
|
||||||
|
* @return if the given string is a hex color
|
||||||
|
*/
|
||||||
|
public static boolean isHexColor(String hexColor) {
|
||||||
|
return hexColor.matches("^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a hex color to a Color object
|
||||||
|
*
|
||||||
|
* @param hex the hex color to convert
|
||||||
|
* @return the Color object
|
||||||
|
*/
|
||||||
|
public static Color hexToColor(String hex) {
|
||||||
|
if (hex == null || (!hex.matches("^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$"))) {
|
||||||
|
throw new IllegalArgumentException("Invalid hex color code");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the '#' character
|
||||||
|
hex = hex.substring(1);
|
||||||
|
|
||||||
|
// If the hex code is 3 characters long, expand it to 6 characters
|
||||||
|
if (hex.length() == 3) {
|
||||||
|
char r = hex.charAt(0);
|
||||||
|
char g = hex.charAt(1);
|
||||||
|
char b = hex.charAt(2);
|
||||||
|
hex = "" + r + r + g + g + b + b;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert the hex string to an integer and create a Color object
|
||||||
|
int rgb = Integer.parseInt(hex, 16);
|
||||||
|
return new Color(rgb);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a Color object to a hex color
|
||||||
|
*
|
||||||
|
* @param color the Color object to convert
|
||||||
|
* @return the hex color
|
||||||
|
*/
|
||||||
|
public static String colorToHex(Color color) {
|
||||||
|
return String.format("#%02x%02x%02x", color.getRed(), color.getGreen(), color.getBlue());
|
||||||
|
}
|
||||||
|
}
|
105
src/main/java/cc/fascinated/bat/common/InteractionBuilder.java
Normal file
105
src/main/java/cc/fascinated/bat/common/InteractionBuilder.java
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
package cc.fascinated.bat.common;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.service.InteractionService;
|
||||||
|
import lombok.Getter;
|
||||||
|
import net.dv8tion.jda.api.entities.emoji.Emoji;
|
||||||
|
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
|
||||||
|
import net.dv8tion.jda.api.events.interaction.component.StringSelectInteractionEvent;
|
||||||
|
import net.dv8tion.jda.api.interactions.components.ActionRow;
|
||||||
|
import net.dv8tion.jda.api.interactions.components.buttons.Button;
|
||||||
|
import net.dv8tion.jda.api.interactions.components.selections.SelectOption;
|
||||||
|
import net.dv8tion.jda.api.interactions.components.selections.StringSelectMenu;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public class InteractionBuilder {
|
||||||
|
/**
|
||||||
|
* The button interactions
|
||||||
|
*/
|
||||||
|
private final Map<Button, Consumer<ButtonInteractionEvent>> buttonInteractions = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The select menu interactions
|
||||||
|
*/
|
||||||
|
private final Map<SelectOption, Consumer<StringSelectInteractionEvent>> selectMenuInteractions = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The select menu id
|
||||||
|
*/
|
||||||
|
private String selectMenuId;
|
||||||
|
|
||||||
|
public InteractionBuilder() {
|
||||||
|
InteractionService.INSTANCE.addInteractionBuilder(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a button to the interaction builder
|
||||||
|
*
|
||||||
|
* @param display The display of the button
|
||||||
|
* @param onClick The consumer to run when the button is clicked
|
||||||
|
* @return - The interaction builder
|
||||||
|
*/
|
||||||
|
public InteractionBuilder addButton(String display, Consumer<ButtonInteractionEvent> onClick) {
|
||||||
|
String id = StringUtils.randomString(8);
|
||||||
|
this.buttonInteractions.put(Button.primary(id, display), onClick);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a URL button to the interaction builder
|
||||||
|
*
|
||||||
|
* @param display The display of the button
|
||||||
|
* @param url The url to open when the button is clicked
|
||||||
|
* @return - The interaction builder
|
||||||
|
*/
|
||||||
|
public InteractionBuilder addUrlButton(String display, String url, Emoji emoji) {
|
||||||
|
this.buttonInteractions.put(Button.link(url, display).withEmoji(emoji), event -> {});
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a string selection to the interaction builder
|
||||||
|
*
|
||||||
|
* @param display the name of the selection
|
||||||
|
* @param description the description of the selection
|
||||||
|
* @param emoji the emoji of the selection
|
||||||
|
* @param onClick the consumer to run when the selection is clicked
|
||||||
|
* @return the interaction builder
|
||||||
|
*/
|
||||||
|
public InteractionBuilder addStringSelect(String display, String description, Emoji emoji, Consumer<StringSelectInteractionEvent> onClick) {
|
||||||
|
String id = StringUtils.randomString(8);
|
||||||
|
this.selectMenuInteractions.put(SelectOption.of(display, id).withDescription(description).withEmoji(emoji), onClick);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the interactions into an action row
|
||||||
|
*
|
||||||
|
* @return The action row
|
||||||
|
*/
|
||||||
|
public List<ActionRow> build() {
|
||||||
|
List<ActionRow> components = new ArrayList<>();
|
||||||
|
if (!this.getButtonInteractions().isEmpty()) {
|
||||||
|
List<Button> buttons = new ArrayList<>(this.getButtonInteractions().keySet());
|
||||||
|
components.add(ActionRow.of(buttons));
|
||||||
|
}
|
||||||
|
if (!this.getSelectMenuInteractions().isEmpty()) {
|
||||||
|
List<SelectOption> options = new ArrayList<>(this.getSelectMenuInteractions().keySet());
|
||||||
|
String id = StringUtils.randomString(8);
|
||||||
|
this.selectMenuId = id;
|
||||||
|
components.add(ActionRow.of(StringSelectMenu.create(id)
|
||||||
|
.addOptions(options)
|
||||||
|
.build()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return components;
|
||||||
|
}
|
||||||
|
}
|
21
src/main/java/cc/fascinated/bat/common/LongUtils.java
Normal file
21
src/main/java/cc/fascinated/bat/common/LongUtils.java
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package cc.fascinated.bat.common;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
public class LongUtils {
|
||||||
|
/**
|
||||||
|
* Checks if a string is a long
|
||||||
|
*
|
||||||
|
* @param string the string to check
|
||||||
|
* @return if the string is a long
|
||||||
|
*/
|
||||||
|
public static boolean isLong(String string) {
|
||||||
|
try {
|
||||||
|
Long.parseLong(string);
|
||||||
|
return true;
|
||||||
|
} catch (NumberFormatException exception) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -24,4 +24,39 @@ public final class MathUtils {
|
|||||||
).format(number)
|
).format(number)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clamps a value between a minimum and maximum.
|
||||||
|
*
|
||||||
|
* @param value The value to clamp.
|
||||||
|
* @param min The minimum value.
|
||||||
|
* @param max The maximum value.
|
||||||
|
* @return The clamped value.
|
||||||
|
*/
|
||||||
|
public static double clamp(double value, double min, double max) {
|
||||||
|
return Math.max(min, Math.min(max, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Linearly interpolates between two values.
|
||||||
|
*
|
||||||
|
* @param a The first value.
|
||||||
|
* @param b The second value.
|
||||||
|
* @param t The interpolation value.
|
||||||
|
* @return The interpolated value.
|
||||||
|
*/
|
||||||
|
public static double lerp(double a, double b, double t) {
|
||||||
|
return a + t * (b - a);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a random number between a minimum and maximum.
|
||||||
|
*
|
||||||
|
* @param min The minimum value.
|
||||||
|
* @param max The maximum value.
|
||||||
|
* @return The random value.
|
||||||
|
*/
|
||||||
|
public static double random(double min, double max) {
|
||||||
|
return Math.random() * (max - min) + min;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
package cc.fascinated.bat.common;
|
package cc.fascinated.bat.common;
|
||||||
|
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
import cc.fascinated.bat.model.BatUser;
|
import cc.fascinated.bat.common.model.BatUser;
|
||||||
|
import lombok.experimental.UtilityClass;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
import net.dv8tion.jda.api.entities.Role;
|
import net.dv8tion.jda.api.entities.Role;
|
||||||
|
|
||||||
@ -10,6 +11,7 @@ import java.util.Comparator;
|
|||||||
/**
|
/**
|
||||||
* @author Fascinated (fascinated7)
|
* @author Fascinated (fascinated7)
|
||||||
*/
|
*/
|
||||||
|
@UtilityClass
|
||||||
public class MemberUtils {
|
public class MemberUtils {
|
||||||
/**
|
/**
|
||||||
* Checks if a user has permission to edit another user
|
* Checks if a user has permission to edit another user
|
||||||
|
86
src/main/java/cc/fascinated/bat/common/NumberFormatter.java
Normal file
86
src/main/java/cc/fascinated/bat/common/NumberFormatter.java
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
package cc.fascinated.bat.common;
|
||||||
|
|
||||||
|
import lombok.experimental.UtilityClass;
|
||||||
|
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@UtilityClass
|
||||||
|
public class NumberFormatter {
|
||||||
|
/**
|
||||||
|
* The suffixes for the numbers
|
||||||
|
*/
|
||||||
|
private static final String[] SUFFIXES = new String[] { "K", "M", "B", "T", "Q", "QT", "S", "SP", "O", "N", "D", "UD", "DD", "TD" };
|
||||||
|
private static final DecimalFormat FORMAT = new DecimalFormat("#,##0.##");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format the provided double
|
||||||
|
*
|
||||||
|
* @param input the value to format
|
||||||
|
* @return the formatted double, in the format of xx.xx[suffix]
|
||||||
|
*/
|
||||||
|
public static String format(double input) {
|
||||||
|
if (Double.isNaN(input)) {
|
||||||
|
return "ERROR";
|
||||||
|
}
|
||||||
|
if (Double.isInfinite(input) || input == Double.MAX_VALUE) {
|
||||||
|
return "∞";
|
||||||
|
}
|
||||||
|
if (1000 > input) {
|
||||||
|
return FORMAT.format(input);
|
||||||
|
}
|
||||||
|
double power = (int) Math.log10(input);
|
||||||
|
int index = (int) Math.floor(power / 3) - 1;
|
||||||
|
double factor = input / Math.pow(10, 3 + index * 3);
|
||||||
|
if (index >= SUFFIXES.length) {
|
||||||
|
return "ERROR";
|
||||||
|
}
|
||||||
|
return FORMAT.format(factor) + SUFFIXES[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format the provided double with commas
|
||||||
|
*
|
||||||
|
* @param input the value to format
|
||||||
|
* @return the formatted double, in the format of xx,xxx,xxx
|
||||||
|
*/
|
||||||
|
public static String simpleFormat(double input) {
|
||||||
|
return FORMAT.format(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Turns a provided string into a double, for example 1M -> 1000000.00
|
||||||
|
* Accepts decimal and negative values and is not case-sensitive
|
||||||
|
*
|
||||||
|
* @param input the string to convert
|
||||||
|
* @return the value the string represents
|
||||||
|
*/
|
||||||
|
public static double fromString(String input) {
|
||||||
|
if ((input = input.trim()).isEmpty()) {
|
||||||
|
return -1D;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
double value = Double.parseDouble(input); // parse pure numbers
|
||||||
|
if (Double.isNaN(value) || Double.isInfinite(value)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
} catch (NumberFormatException ignored) {
|
||||||
|
input = input.toUpperCase(Locale.UK);
|
||||||
|
for (int i = SUFFIXES.length - 1; i > 0; i--) {
|
||||||
|
String suffix = SUFFIXES[i];
|
||||||
|
if (!input.endsWith(suffix)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String amount = input.substring(0, input.length() - suffix.length());
|
||||||
|
if (!amount.isEmpty()) {
|
||||||
|
return Double.parseDouble(amount) * Math.pow(10, 3 + i * 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
@ -1,27 +1,20 @@
|
|||||||
package cc.fascinated.bat.common;
|
package cc.fascinated.bat.common;
|
||||||
|
|
||||||
import lombok.experimental.UtilityClass;
|
|
||||||
|
|
||||||
import java.text.NumberFormat;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fascinated (fascinated7)
|
* @author Fascinated (fascinated7)
|
||||||
*/
|
*/
|
||||||
@UtilityClass
|
|
||||||
public class NumberUtils {
|
public class NumberUtils {
|
||||||
/**
|
/**
|
||||||
* Formats a number with commas.
|
* Parses a string to an integer
|
||||||
* <p>
|
|
||||||
* Example: 1000 -> 1,000 | Example: 1000.5 -> 1,000.5
|
|
||||||
* </p>
|
|
||||||
*
|
*
|
||||||
* @param number the number to format
|
* @param input the string to parse
|
||||||
* @return the formatted number
|
* @return the parsed integer, or -1 if invalid
|
||||||
*/
|
*/
|
||||||
public static String formatNumberCommas(double number) {
|
public static int parseInt(String input) {
|
||||||
NumberFormat format = NumberFormat.getNumberInstance();
|
try {
|
||||||
format.setGroupingUsed(true);
|
return Integer.parseInt(input);
|
||||||
format.setMaximumFractionDigits(2);
|
} catch (NumberFormatException exception) {
|
||||||
return format.format(number);
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
41
src/main/java/cc/fascinated/bat/common/PasteUtils.java
Normal file
41
src/main/java/cc/fascinated/bat/common/PasteUtils.java
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
package cc.fascinated.bat.common;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.BatApplication;
|
||||||
|
import cc.fascinated.bat.common.model.token.paste.PasteUploadToken;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import lombok.experimental.UtilityClass;
|
||||||
|
import lombok.extern.log4j.Log4j2;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.http.HttpClient;
|
||||||
|
import java.net.http.HttpRequest;
|
||||||
|
import java.net.http.HttpResponse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@UtilityClass
|
||||||
|
@Log4j2(topic = "PasteUtils")
|
||||||
|
public class PasteUtils {
|
||||||
|
private static final String PASTE_URL = "https://paste.fascinated.cc/";
|
||||||
|
private static final String PASTE_UPLOAD_URL = PASTE_URL + "api/upload?expires=" + 60 * 60 * 24 * 30; // 30 days
|
||||||
|
private static final HttpClient httpClient = HttpClient.newHttpClient();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uploads a paste to the paste server
|
||||||
|
*
|
||||||
|
* @param content the content of the paste
|
||||||
|
* @return the paste upload token
|
||||||
|
*/
|
||||||
|
@SneakyThrows
|
||||||
|
public static PasteUploadToken uploadPaste(String content) {
|
||||||
|
HttpResponse<String> response = httpClient.send(HttpRequest.newBuilder()
|
||||||
|
.uri(URI.create(PASTE_UPLOAD_URL))
|
||||||
|
.POST(HttpRequest.BodyPublishers.ofString(content))
|
||||||
|
.build(), HttpResponse.BodyHandlers.ofString());
|
||||||
|
PasteUploadToken paste = BatApplication.GSON.fromJson(response.body(), PasteUploadToken.class);
|
||||||
|
paste.setUrl(PASTE_URL + paste.getKey());
|
||||||
|
log.info("Created paste with key \"{}\" ({})", paste.getKey(), paste.getUrl());
|
||||||
|
return paste;
|
||||||
|
}
|
||||||
|
}
|
@ -1,26 +0,0 @@
|
|||||||
package cc.fascinated.bat.common;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Fascinated (fascinated7)
|
|
||||||
*/
|
|
||||||
@AllArgsConstructor
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
public abstract class Profile {
|
|
||||||
/**
|
|
||||||
* The key of the profile.
|
|
||||||
*/
|
|
||||||
private String profileKey;
|
|
||||||
|
|
||||||
public Profile() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resets the profile
|
|
||||||
*/
|
|
||||||
public abstract void reset();
|
|
||||||
}
|
|
@ -1,6 +1,11 @@
|
|||||||
package cc.fascinated.bat.common;
|
package cc.fascinated.bat.common;
|
||||||
|
|
||||||
|
import cc.fascinated.bat.BatApplication;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import org.bson.Document;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -9,11 +14,12 @@ import java.util.Map;
|
|||||||
* @author Fascinated (fascinated7)
|
* @author Fascinated (fascinated7)
|
||||||
*/
|
*/
|
||||||
@Getter
|
@Getter
|
||||||
public class ProfileHolder {
|
public abstract class ProfileHolder {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(ProfileHolder.class);
|
||||||
/**
|
/**
|
||||||
* The profiles for the holder
|
* The profiles for the holder
|
||||||
*/
|
*/
|
||||||
private Map<String, Profile> profiles;
|
private final Map<String, Serializable> profiles = new HashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a profile for the holder
|
* Gets a profile for the holder
|
||||||
@ -22,19 +28,25 @@ public class ProfileHolder {
|
|||||||
* @param <T> The type of the profile
|
* @param <T> The type of the profile
|
||||||
* @return The profile
|
* @return The profile
|
||||||
*/
|
*/
|
||||||
public <T extends Profile> T getProfile(Class<T> clazz) {
|
public abstract <T extends Serializable> T getProfile(Class<T> clazz);
|
||||||
if (profiles == null) {
|
|
||||||
profiles = new HashMap<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
Profile profile = profiles.values().stream().filter(p -> p.getClass().equals(clazz)).findFirst().orElse(null);
|
/**
|
||||||
|
* Gets the profiles for the holder
|
||||||
|
* using the provided document
|
||||||
|
*
|
||||||
|
* @return the profiles
|
||||||
|
*/
|
||||||
|
@SneakyThrows
|
||||||
|
protected <T extends Serializable> T getProfileFromDocument(Class<T> clazz, Document document) {
|
||||||
|
Serializable profile = getProfiles().get(clazz.getSimpleName());
|
||||||
if (profile == null) {
|
if (profile == null) {
|
||||||
try {
|
T newProfile = clazz.cast(clazz.getDeclaredConstructors()[0].newInstance());
|
||||||
profile = clazz.newInstance();
|
Document profiles = document.get("profiles", new org.bson.Document());
|
||||||
profiles.put(profile.getProfileKey(), profile);
|
Document profileDocument = (Document) profiles.get(clazz.getSimpleName());
|
||||||
} catch (InstantiationException | IllegalAccessException e) {
|
|
||||||
e.printStackTrace();
|
newProfile.load(profileDocument == null ? new Document() : profileDocument, BatApplication.GSON);
|
||||||
}
|
getProfiles().put(clazz.getSimpleName(), newProfile);
|
||||||
|
return newProfile;
|
||||||
}
|
}
|
||||||
return clazz.cast(profile);
|
return clazz.cast(profile);
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,18 @@
|
|||||||
package cc.fascinated.bat.common;
|
package cc.fascinated.bat.common;
|
||||||
|
|
||||||
import cc.fascinated.bat.model.BatGuild;
|
import cc.fascinated.bat.common.model.BatGuild;
|
||||||
|
import lombok.experimental.UtilityClass;
|
||||||
|
import net.dv8tion.jda.api.Permission;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
import net.dv8tion.jda.api.entities.Role;
|
import net.dv8tion.jda.api.entities.Role;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fascinated (fascinated7)
|
* @author Fascinated (fascinated7)
|
||||||
*/
|
*/
|
||||||
|
@UtilityClass
|
||||||
public class RoleUtils {
|
public class RoleUtils {
|
||||||
/**
|
/**
|
||||||
* Checks if a member has permission to give the role to another member
|
* Checks if a member has permission to give the role to another member
|
||||||
@ -19,4 +25,60 @@ public class RoleUtils {
|
|||||||
public static boolean hasPermissionToGiveRole(BatGuild guild, Member member, Role role) {
|
public static boolean hasPermissionToGiveRole(BatGuild guild, Member member, Role role) {
|
||||||
return member.getRoles().stream().anyMatch(r -> r.getPosition() > role.getPosition());
|
return member.getRoles().stream().anyMatch(r -> r.getPosition() > role.getPosition());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a member has a higher role than the specified role
|
||||||
|
*
|
||||||
|
* @param member the member to check
|
||||||
|
* @param targetMember the member to check against
|
||||||
|
* @return if the member has a higher role
|
||||||
|
*/
|
||||||
|
public static boolean hasHigherRole(Member member, Member targetMember) {
|
||||||
|
return member.getRoles().stream().anyMatch(r -> targetMember.getRoles().stream().anyMatch(tr -> tr.getPosition() < r.getPosition()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the formatted permissions of a role
|
||||||
|
*
|
||||||
|
* @param role the role to get the formatted permissions of
|
||||||
|
* @return the formatted permissions
|
||||||
|
*/
|
||||||
|
public String getFormattedPermissions(Role role) {
|
||||||
|
StringBuilder formattedPermissions = new StringBuilder();
|
||||||
|
EnumSet<Permission> permissions = role.getPermissions();
|
||||||
|
if (permissions.isEmpty()) {
|
||||||
|
return "`None`";
|
||||||
|
}
|
||||||
|
for (Permission permission : permissions) {
|
||||||
|
formattedPermissions.append("`").append(permission.getName()).append("`, ");
|
||||||
|
}
|
||||||
|
return formattedPermissions.substring(0, formattedPermissions.length() - 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the formatted color of a role
|
||||||
|
*
|
||||||
|
* @param color the color string to get the formatted color of
|
||||||
|
* @return the formatted color
|
||||||
|
*/
|
||||||
|
public String getFormattedColor(Color color) {
|
||||||
|
if (color == null) {
|
||||||
|
return "Default";
|
||||||
|
}
|
||||||
|
String colorHex = HexColorUtils.colorToHex(color);
|
||||||
|
return "`%s` *[(view)](%s)*".formatted(
|
||||||
|
colorHex,
|
||||||
|
"https://www.colorhexa.com/%s".formatted(colorHex.substring(1))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the formatted color of a role
|
||||||
|
*
|
||||||
|
* @param role the role to get the formatted icon of
|
||||||
|
* @return the formatted icon
|
||||||
|
*/
|
||||||
|
public String getFormattedColor(Role role) {
|
||||||
|
return getFormattedColor(role.getColor());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
36
src/main/java/cc/fascinated/bat/common/Serializable.java
Normal file
36
src/main/java/cc/fascinated/bat/common/Serializable.java
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package cc.fascinated.bat.common;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.bson.Document;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fascinated (fascinated7)
|
||||||
|
*/
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
@NoArgsConstructor
|
||||||
|
public abstract class Serializable {
|
||||||
|
/**
|
||||||
|
* Load data from the provided document into this profile
|
||||||
|
*
|
||||||
|
* @param document the document to load data from
|
||||||
|
* @param gson the GSON instance to use
|
||||||
|
*/
|
||||||
|
public abstract void load(Document document, Gson gson);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serialize this profile into a Bson document
|
||||||
|
*
|
||||||
|
* @param gson the GSON instance to use
|
||||||
|
* @return the serialized document
|
||||||
|
*/
|
||||||
|
public abstract Document serialize(Gson gson);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the profile to its default state
|
||||||
|
*/
|
||||||
|
public abstract void reset();
|
||||||
|
}
|
@ -1,8 +1,11 @@
|
|||||||
package cc.fascinated.bat.common;
|
package cc.fascinated.bat.common;
|
||||||
|
|
||||||
|
import lombok.experimental.UtilityClass;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Fascinated (fascinated7)
|
* @author Fascinated (fascinated7)
|
||||||
*/
|
*/
|
||||||
|
@UtilityClass
|
||||||
public class StringUtils {
|
public class StringUtils {
|
||||||
/**
|
/**
|
||||||
* Generates a random string
|
* Generates a random string
|
||||||
@ -17,4 +20,35 @@ public class StringUtils {
|
|||||||
}
|
}
|
||||||
return stringBuilder.toString();
|
return stringBuilder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escapes meta characters in a string
|
||||||
|
*
|
||||||
|
* @param inputString the input string
|
||||||
|
* @return the string with escaped meta characters
|
||||||
|
*/
|
||||||
|
public static String escapeMetaCharacters(String inputString){
|
||||||
|
final String[] metaCharacters = {"\\","^","$","{","}","[","]","(",")",".","*","+","?","|","<",">","-","&","%"};
|
||||||
|
|
||||||
|
for (String metaCharacter : metaCharacters) {
|
||||||
|
if (inputString.contains(metaCharacter)) {
|
||||||
|
inputString = inputString.replace(metaCharacter, "\\" + metaCharacter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return inputString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats bytes into a human-readable format
|
||||||
|
*
|
||||||
|
* @param bytes the bytes
|
||||||
|
* @return the formatted bytes
|
||||||
|
*/
|
||||||
|
public static String formatBytes(long bytes) {
|
||||||
|
int unit = 1024;
|
||||||
|
if (bytes < unit) return bytes + " B";
|
||||||
|
int exp = (int) (Math.log(bytes) / Math.log(unit));
|
||||||
|
char pre = "KMGTPE".charAt(exp-1);
|
||||||
|
return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package cc.fascinated.bat.common;
|
package cc.fascinated.bat.common;
|
||||||
|
|
||||||
import cc.fascinated.bat.service.DiscordService;
|
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -18,7 +17,7 @@ public class TextChannelUtils {
|
|||||||
if (id == null) {
|
if (id == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return DiscordService.JDA.getTextChannelById(id) != null;
|
return ChannelUtils.getTextChannel(id) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user