22
33import com .dynxsty .dih4jda .DIH4JDA ;
44import com .dynxsty .dih4jda .DIH4JDABuilder ;
5+ import com .dynxsty .dih4jda .DIH4JDALogger ;
6+ import com .dynxsty .dih4jda .interactions .commands .ContextCommand ;
57import com .dynxsty .dih4jda .interactions .commands .RegistrationType ;
8+ import com .dynxsty .dih4jda .interactions .commands .SlashCommand ;
9+ import com .dynxsty .dih4jda .util .Checks ;
10+ import com .dynxsty .dih4jda .util .ClassUtils ;
611import com .zaxxer .hikari .HikariDataSource ;
712import io .sentry .Sentry ;
813import lombok .Getter ;
1722import net .dv8tion .jda .api .utils .MemberCachePolicy ;
1823import net .dv8tion .jda .api .utils .cache .CacheFlag ;
1924import net .javadiscord .javabot .data .config .BotConfig ;
20- import net .javadiscord .javabot .data .config .SystemsConfig ;
2125import net .javadiscord .javabot .data .h2db .DbHelper ;
2226import net .javadiscord .javabot .data .h2db .commands .QuickMigrateSubcommand ;
2327import net .javadiscord .javabot .data .h2db .message_cache .MessageCache ;
4751import net .javadiscord .javabot .util .InteractionUtils ;
4852import org .jetbrains .annotations .NotNull ;
4953import org .quartz .SchedulerException ;
54+ import org .springframework .beans .factory .config .BeanDefinition ;
5055import org .springframework .boot .SpringApplication ;
5156import org .springframework .boot .autoconfigure .SpringBootApplication ;
57+ import org .springframework .context .annotation .ClassPathScanningCandidateComponentProvider ;
58+ import org .springframework .core .type .filter .AssignableTypeFilter ;
5259
5360import java .nio .file .Path ;
5461import java .time .ZoneOffset ;
55- import java .util .EnumSet ;
56- import java .util .List ;
57- import java .util .Map ;
58- import java .util .TimeZone ;
62+ import java .util .*;
5963import java .util .concurrent .Executors ;
6064import java .util .concurrent .ScheduledExecutorService ;
6165
@@ -95,7 +99,7 @@ public class Bot {
9599 * <ol>
96100 * <li>Setting the time zone to UTC, to keep our sanity when working with times.</li>
97101 * <li>Loading the configuration JSON file.</li>
98- * <li>Creating and configuring the {@link JDA} instance that enables the bot's Discord connectivity.</li>
102+ * <li>Creating and configuring the {@link JDA} instance that enables the bots' Discord connectivity.</li>
99103 * <li>Initializing the {@link DIH4JDA} instance.</li>
100104 * <li>Adding event listeners to the bot.</li>
101105 * </ol>
@@ -119,14 +123,13 @@ public static void main(String[] args) throws Exception {
119123 .build ();
120124 AllowedMentions .setDefaultMentions (EnumSet .of (Message .MentionType .ROLE , Message .MentionType .CHANNEL , Message .MentionType .USER , Message .MentionType .EMOJI ));
121125 dih4jda = DIH4JDABuilder .setJDA (jda )
122- .setCommandsPackage ("net.javadiscord.javabot" )
123126 .setDefaultCommandType (RegistrationType .GLOBAL )
124- .disableLogging ()
127+ .disableLogging (DIH4JDALogger . Type . SMART_QUEUE_IGNORED )
125128 .build ();
126- SystemsConfig .ApiConfig apiConfig = config .getSystems ().getApiConfig ();
127129 customTagManager = new CustomTagManager (jda , dataSource );
128130 messageCache = new MessageCache ();
129131 serverLockManager = new ServerLockManager (jda );
132+ addCommands (dih4jda );
130133 addEventListeners (jda , dih4jda );
131134 addComponentHandler (dih4jda );
132135 // initialize Sentry
@@ -147,7 +150,46 @@ public static void main(String[] args) throws Exception {
147150 }
148151
149152 /**
150- * Adds all the bot's event listeners to the JDA instance, except for
153+ * Uses Springs' ClassPath scanning in order to register all {@link SlashCommand} &
154+ * {@link ContextCommand}s using {@link DIH4JDA}.
155+ *
156+ * @param dih4jda The {@link DIH4JDA} which is used in order to execute both {@link SlashCommand}s
157+ * and {@link ContextCommand}.
158+ */
159+ private static void addCommands (DIH4JDA dih4jda ) {
160+ List <SlashCommand > commands = new ArrayList <>();
161+ List <ContextCommand > contexts = new ArrayList <>();
162+ ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider (false );
163+ provider .addIncludeFilter (new AssignableTypeFilter (SlashCommand .class ));
164+ provider .addIncludeFilter (new AssignableTypeFilter (ContextCommand .class ));
165+ Set <BeanDefinition > classes = provider .findCandidateComponents ("net/javadiscord/javabot" );
166+ for (BeanDefinition bean : classes ) {
167+ try {
168+ Class <?> cls = Class .forName (bean .getBeanClassName ());
169+ if (Checks .checkEmptyConstructor (cls )) {
170+ Object instance = ClassUtils .getInstance (cls );
171+ if (instance instanceof SlashCommand slashCommand ) {
172+ commands .add (slashCommand );
173+ } else if (instance instanceof ContextCommand contextCommand ) {
174+ contexts .add (contextCommand );
175+ }
176+ } else {
177+ log .error ("Class {} needs an empty constructor!" , cls .getSimpleName ());
178+ }
179+ } catch (ReflectiveOperationException e ) {
180+ ExceptionLogger .capture (e , Bot .class .getSimpleName ());
181+ }
182+ }
183+ if (!commands .isEmpty ()) {
184+ dih4jda .addSlashCommands (commands .toArray (SlashCommand []::new ));
185+ }
186+ if (!contexts .isEmpty ()) {
187+ dih4jda .addContextCommands (contexts .toArray (ContextCommand []::new ));
188+ }
189+ }
190+
191+ /**
192+ * Adds all the bots' event listeners to the JDA instance, except for
151193 * the {@link AutoMod} instance.
152194 *
153195 * @param jda The JDA bot instance to add listeners to.
@@ -171,7 +213,7 @@ private static void addEventListeners(@NotNull JDA jda, @NotNull DIH4JDA dih4jda
171213 new PingableNameListener (),
172214 new HugListener ()
173215 );
174- dih4jda .addListener (new DIH4JDAListener ());
216+ dih4jda .addEventListener (new DIH4JDAListener ());
175217 }
176218
177219 private static void addComponentHandler (@ NotNull DIH4JDA dih4jda ) {
0 commit comments