Skip to content

Commit 756fd2d

Browse files
committed
Resolve merge conflicts
Signed-off-by: Chris Sdogkos <work@chris-sdogkos.com>
2 parents fdc8e9c + 59de5ee commit 756fd2d

31 files changed

Lines changed: 1637 additions & 107 deletions

CLA.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,6 @@ IF THE DISCLAIMER AND DAMAGE WAIVER MENTIONED IN SECTION 5. AND SECTION 6. CANNO
115115

116116
### Us
117117

118-
Name: Daniel Tischner (aka Zabuzard, acting on behalf of Together Java)
119-
120118
Organization: https://github.com/Together-Java
121119

122120
Contact: https://discord.com/invite/XXFUXzK

application/build.gradle

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ dependencies {
5757

5858
implementation 'io.mikael:urlbuilder:2.0.9'
5959

60-
implementation 'org.jsoup:jsoup:1.21.1'
60+
implementation 'org.jsoup:jsoup:1.22.1'
6161

6262
implementation 'org.scilab.forge:jlatexmath:1.0.7'
6363
implementation 'org.scilab.forge:jlatexmath-font-greek:1.0.7'
@@ -69,7 +69,7 @@ dependencies {
6969
implementation "com.fasterxml.jackson.core:jackson-databind:$jacksonVersion"
7070
implementation "com.sigpwned:jackson-modules-java17-sealed-classes:2.19.0.0"
7171

72-
implementation 'com.github.freva:ascii-table:1.8.0'
72+
implementation 'com.github.freva:ascii-table:1.9.0'
7373

7474
implementation 'io.github.url-detector:url-detector:0.1.23'
7575

@@ -86,8 +86,7 @@ dependencies {
8686
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
8787
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:$junitVersion"
8888

89-
implementation "com.theokanning.openai-gpt3-java:api:$chatGPTVersion"
90-
implementation "com.theokanning.openai-gpt3-java:service:$chatGPTVersion"
89+
implementation "com.openai:openai-java:$chatGPTVersion"
9190
}
9291

9392
application {

application/config.json.template

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,11 +194,26 @@
194194
"videoLinkPattern": "http(s)?://www\\.youtube.com.*",
195195
"pollIntervalInMinutes": 10
196196
},
197+
"quoteBoardConfig": {
198+
"minimumReactionsToTrigger": 5,
199+
"channel": "quotes",
200+
"reactionEmoji": "⭐"
201+
},
197202
"memberCountCategoryPattern": "Info",
198203
"topHelpers": {
199204
"rolePattern": "Top Helper.*",
200205
"assignmentChannelPattern": "community-commands",
201206
"announcementChannelPattern": "hall-of-fame"
207+
},
208+
"dynamicVoiceChatConfig": {
209+
"dynamicChannelPatterns": [
210+
"Gaming",
211+
"Support/Studying Room",
212+
"Chit Chat"
213+
],
214+
"archiveCategoryPattern": "Voice Channel Archives",
215+
"cleanChannelsAmount": 20,
216+
"minimumChannelsAmount": 40
202217
}
203218
"cakeDayConfig": {
204219
"rolePattern": "Cake Day"

application/src/main/java/org/togetherjava/tjbot/config/Config.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ public final class Config {
4848
private final RSSFeedsConfig rssFeedsConfig;
4949
private final String selectRolesChannelPattern;
5050
private final String memberCountCategoryPattern;
51+
private final QuoteBoardConfig quoteBoardConfig;
52+
private final DynamicVoiceChatConfig dynamicVoiceChatConfig;
5153
private final TopHelpersConfig topHelpers;
5254
private final CakeDayConfig cakeDayConfig;
5355

@@ -103,7 +105,11 @@ private Config(@JsonProperty(value = "token", required = true) String token,
103105
@JsonProperty(value = "rssConfig", required = true) RSSFeedsConfig rssFeedsConfig,
104106
@JsonProperty(value = "selectRolesChannelPattern",
105107
required = true) String selectRolesChannelPattern,
108+
@JsonProperty(value = "quoteBoardConfig",
109+
required = true) QuoteBoardConfig quoteBoardConfig,
106110
@JsonProperty(value = "topHelpers", required = true) TopHelpersConfig topHelpers,
111+
@JsonProperty(value = "dynamicVoiceChatConfig",
112+
required = true) DynamicVoiceChatConfig dynamicVoiceChatConfig,
107113
@JsonProperty(value = "cakeDayConfig", required = true) CakeDayConfig cakeDayConfig) {
108114
this.token = Objects.requireNonNull(token);
109115
this.githubApiKey = Objects.requireNonNull(githubApiKey);
@@ -140,6 +146,8 @@ private Config(@JsonProperty(value = "token", required = true) String token,
140146
this.rssFeedsConfig = Objects.requireNonNull(rssFeedsConfig);
141147
this.selectRolesChannelPattern = Objects.requireNonNull(selectRolesChannelPattern);
142148
this.topHelpers = Objects.requireNonNull(topHelpers);
149+
this.quoteBoardConfig = Objects.requireNonNull(quoteBoardConfig);
150+
this.dynamicVoiceChatConfig = Objects.requireNonNull(dynamicVoiceChatConfig);
143151
this.cakeDayConfig = Objects.requireNonNull(cakeDayConfig);
144152
}
145153

@@ -443,6 +451,18 @@ public CakeDayConfig getCakeDayConfig() {
443451
return cakeDayConfig;
444452
}
445453

454+
/**
455+
* The configuration of the quote messages config.
456+
*
457+
* <p>
458+
* >The configuration of the quote board feature. Quotes user selected messages.
459+
*
460+
* @return configuration of quote messages config
461+
*/
462+
public QuoteBoardConfig getQuoteBoardConfig() {
463+
return quoteBoardConfig;
464+
}
465+
446466
/**
447467
* Gets the pattern matching the category that is used to display the total member count.
448468
*
@@ -469,4 +489,13 @@ public RSSFeedsConfig getRSSFeedsConfig() {
469489
public TopHelpersConfig getTopHelpers() {
470490
return topHelpers;
471491
}
492+
493+
/**
494+
* Gets the dynamic voice chat configuration
495+
*
496+
* @return the dynamic voice chat configuration
497+
*/
498+
public DynamicVoiceChatConfig getDynamicVoiceChatConfig() {
499+
return dynamicVoiceChatConfig;
500+
}
472501
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package org.togetherjava.tjbot.config;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
5+
import java.util.List;
6+
import java.util.Objects;
7+
import java.util.regex.Pattern;
8+
9+
/**
10+
* Configuration for the dynamic voice chat feature.
11+
*
12+
* @param archiveCategoryPattern the name of the Discord Guild category in which the archived
13+
* channels will go
14+
* @param cleanChannelsAmount the amount of channels to clean once a cleanup is triggered
15+
* @param minimumChannelsAmount the amount of voice channels for the archive category to have before
16+
* a cleanup triggers
17+
*/
18+
public record DynamicVoiceChatConfig(
19+
@JsonProperty(value = "dynamicChannelPatterns",
20+
required = true) List<Pattern> dynamicChannelPatterns,
21+
@JsonProperty(value = "archiveCategoryPattern",
22+
required = true) String archiveCategoryPattern,
23+
@JsonProperty(value = "cleanChannelsAmount") int cleanChannelsAmount,
24+
@JsonProperty(value = "minimumChannelsAmount", required = true) int minimumChannelsAmount) {
25+
26+
/**
27+
* Constructs an instance of {@code DynamicVoiceChatConfig} and throws if
28+
* {@code dynamicChannelPatterns} or @{code archiveCategoryPattern} is null.
29+
*/
30+
public DynamicVoiceChatConfig {
31+
Objects.requireNonNull(dynamicChannelPatterns);
32+
Objects.requireNonNull(archiveCategoryPattern);
33+
}
34+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package org.togetherjava.tjbot.config;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
import com.fasterxml.jackson.annotation.JsonRootName;
5+
import org.apache.logging.log4j.LogManager;
6+
7+
import org.togetherjava.tjbot.features.basic.QuoteBoardForwarder;
8+
9+
import java.util.Objects;
10+
11+
/**
12+
* Configuration for the quote board feature, see {@link QuoteBoardForwarder}.
13+
*/
14+
@JsonRootName("quoteBoardConfig")
15+
public record QuoteBoardConfig(
16+
@JsonProperty(value = "minimumReactionsToTrigger", required = true) int minimumReactions,
17+
@JsonProperty(required = true) String channel,
18+
@JsonProperty(value = "reactionEmoji", required = true) String reactionEmoji) {
19+
20+
/**
21+
* Creates a QuoteBoardConfig.
22+
*
23+
* @param minimumReactions the minimum amount of reactions
24+
* @param channel the pattern for the board channel
25+
* @param reactionEmoji the emoji with which users should react to
26+
*/
27+
public QuoteBoardConfig {
28+
if (minimumReactions <= 0) {
29+
throw new IllegalArgumentException("minimumReactions must be greater than zero");
30+
}
31+
Objects.requireNonNull(channel);
32+
if (channel.isBlank()) {
33+
throw new IllegalArgumentException("channel must not be empty or blank");
34+
}
35+
Objects.requireNonNull(reactionEmoji);
36+
if (reactionEmoji.isBlank()) {
37+
throw new IllegalArgumentException("reactionEmoji must not be empty or blank");
38+
}
39+
LogManager.getLogger(QuoteBoardConfig.class)
40+
.debug("Quote-Board configs loaded: minimumReactions={}, channel='{}', reactionEmoji='{}'",
41+
minimumReactions, channel, reactionEmoji);
42+
}
43+
}

application/src/main/java/org/togetherjava/tjbot/features/Features.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import org.togetherjava.tjbot.db.Database;
99
import org.togetherjava.tjbot.features.basic.MemberCountDisplayRoutine;
1010
import org.togetherjava.tjbot.features.basic.PingCommand;
11+
import org.togetherjava.tjbot.features.basic.QuoteBoardForwarder;
1112
import org.togetherjava.tjbot.features.basic.RoleSelectCommand;
1213
import org.togetherjava.tjbot.features.basic.SlashCommandEducator;
1314
import org.togetherjava.tjbot.features.basic.SuggestionsUpDownVoter;
@@ -42,6 +43,8 @@
4243
import org.togetherjava.tjbot.features.mathcommands.TeXCommand;
4344
import org.togetherjava.tjbot.features.mathcommands.wolframalpha.WolframAlphaCommand;
4445
import org.togetherjava.tjbot.features.mediaonly.MediaOnlyChannelListener;
46+
import org.togetherjava.tjbot.features.messages.MessageCommand;
47+
import org.togetherjava.tjbot.features.messages.RewriteCommand;
4548
import org.togetherjava.tjbot.features.moderation.BanCommand;
4649
import org.togetherjava.tjbot.features.moderation.KickCommand;
4750
import org.togetherjava.tjbot.features.moderation.ModerationActionsStore;
@@ -80,6 +83,7 @@
8083
import org.togetherjava.tjbot.features.tophelper.TopHelpersMessageListener;
8184
import org.togetherjava.tjbot.features.tophelper.TopHelpersPurgeMessagesRoutine;
8285
import org.togetherjava.tjbot.features.tophelper.TopHelpersService;
86+
import org.togetherjava.tjbot.features.voicechat.DynamicVoiceChat;
8387

8488
import java.util.ArrayList;
8589
import java.util.Collection;
@@ -165,6 +169,10 @@ public static Collection<Feature> createFeatures(JDA jda, Database database, Con
165169
features.add(new CodeMessageManualDetection(codeMessageHandler));
166170
features.add(new SlashCommandEducator());
167171
features.add(new PinnedNotificationRemover(config));
172+
features.add(new QuoteBoardForwarder(config));
173+
174+
// Voice receivers
175+
features.add(new DynamicVoiceChat(config));
168176

169177
// Event receivers
170178
features.add(new RejoinModerationRoleListener(actionsStore, config));
@@ -209,6 +217,8 @@ public static Collection<Feature> createFeatures(JDA jda, Database database, Con
209217
features.add(new BookmarksCommand(bookmarksSystem));
210218
features.add(new ChatGptCommand(chatGptService, helpSystemHelper));
211219
features.add(new JShellCommand(jshellEval));
220+
features.add(new MessageCommand());
221+
features.add(new RewriteCommand(chatGptService));
212222

213223
FeatureBlacklist<Class<?>> blacklist = blacklistConfig.normal();
214224
return blacklist.filterStream(features.stream(), Object::getClass).toList();

application/src/main/java/org/togetherjava/tjbot/features/MessageReceiver.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import net.dv8tion.jda.api.events.message.MessageDeleteEvent;
44
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
55
import net.dv8tion.jda.api.events.message.MessageUpdateEvent;
6+
import net.dv8tion.jda.api.events.message.react.MessageReactionAddEvent;
67

78
import java.util.regex.Pattern;
89

@@ -56,4 +57,13 @@ public interface MessageReceiver extends Feature {
5657
* message that was deleted
5758
*/
5859
void onMessageDeleted(MessageDeleteEvent event);
60+
61+
/**
62+
* Triggered by the core system whenever a new reaction was added to a message in a text channel
63+
* of a guild the bot has been added to.
64+
*
65+
* @param event the event that triggered this, containing information about the corresponding
66+
* reaction that was added
67+
*/
68+
void onMessageReactionAdd(MessageReactionAddEvent event);
5969
}

application/src/main/java/org/togetherjava/tjbot/features/MessageReceiverAdapter.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import net.dv8tion.jda.api.events.message.MessageDeleteEvent;
44
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
55
import net.dv8tion.jda.api.events.message.MessageUpdateEvent;
6+
import net.dv8tion.jda.api.events.message.react.MessageReactionAddEvent;
67

78
import java.util.regex.Pattern;
89

@@ -57,4 +58,10 @@ public void onMessageUpdated(MessageUpdateEvent event) {
5758
public void onMessageDeleted(MessageDeleteEvent event) {
5859
// Adapter does not react by default, subclasses may change this behavior
5960
}
61+
62+
@SuppressWarnings("NoopMethodInAbstractClass")
63+
@Override
64+
public void onMessageReactionAdd(MessageReactionAddEvent event) {
65+
// Adapter does not react by default, subclasses may change this behavior
66+
}
6067
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package org.togetherjava.tjbot.features;
2+
3+
import net.dv8tion.jda.api.events.guild.voice.GuildVoiceDeafenEvent;
4+
import net.dv8tion.jda.api.events.guild.voice.GuildVoiceMuteEvent;
5+
import net.dv8tion.jda.api.events.guild.voice.GuildVoiceStreamEvent;
6+
import net.dv8tion.jda.api.events.guild.voice.GuildVoiceUpdateEvent;
7+
import net.dv8tion.jda.api.events.guild.voice.GuildVoiceVideoEvent;
8+
9+
import java.util.regex.Pattern;
10+
11+
/**
12+
* Receives incoming Discord guild events from voice channels matching a given pattern.
13+
* <p>
14+
* All voice receivers have to implement this interface. For convenience, there is a
15+
* {@link VoiceReceiverAdapter} available that implemented most methods already. A new receiver can
16+
* then be registered by adding it to {@link Features}.
17+
* <p>
18+
* <p>
19+
* After registration, the system will notify a receiver whenever a new event was sent or an
20+
* existing event was updated in any channel matching the {@link #getChannelNamePattern()} the bot
21+
* is added to.
22+
*/
23+
public interface VoiceReceiver extends Feature {
24+
/**
25+
* Retrieves the pattern matching the names of channels of which this receiver is interested in
26+
* receiving events from. Called by the core system once during the startup in order to register
27+
* the receiver accordingly.
28+
* <p>
29+
* Changes on the pattern returned by this method afterwards will not be picked up.
30+
*
31+
* @return the pattern matching the names of relevant channels
32+
*/
33+
Pattern getChannelNamePattern();
34+
35+
/**
36+
* Triggered by the core system whenever a member joined, left or moved voice channels.
37+
*
38+
* @param event the event that triggered this
39+
*/
40+
void onVoiceUpdate(GuildVoiceUpdateEvent event);
41+
42+
/**
43+
* Triggered by the core system whenever a member toggled their camera in a voice channel.
44+
*
45+
* @param event the event that triggered this
46+
*/
47+
void onVideoToggle(GuildVoiceVideoEvent event);
48+
49+
/**
50+
* Triggered by the core system whenever a member started or stopped a stream.
51+
*
52+
* @param event the event that triggered this
53+
*/
54+
void onStreamToggle(GuildVoiceStreamEvent event);
55+
56+
/**
57+
* Triggered by the core system whenever a member toggled their mute status.
58+
*
59+
* @param event the event that triggered this
60+
*/
61+
void onMuteToggle(GuildVoiceMuteEvent event);
62+
63+
/**
64+
* Triggered by the core system whenever a member toggled their deafened status.
65+
*
66+
* @param event the event that triggered this
67+
*/
68+
void onDeafenToggle(GuildVoiceDeafenEvent event);
69+
}

0 commit comments

Comments
 (0)