Skip to content

Commit 5b28070

Browse files
Merge pull request #15 from CocoTheOwner/autoImportCommands
Automatically load commands from packages Screw that not error, i cant read the damn commits
2 parents 720463e + a711fbd commit 5b28070

File tree

13 files changed

+197
-105
lines changed

13 files changed

+197
-105
lines changed

src/main/java/com/volmit/abyssalith/Abyss.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import art.arcane.quill.execution.Looper;
2222
import com.volmit.abyssalith.bot.instance.BotProvider;
2323
import com.volmit.abyssalith.bot.instance.IBotProvider;
24-
import com.volmit.abyssalith.bot.startup.Registrar;
24+
import com.volmit.abyssalith.commands.Registrar;
2525
import com.volmit.abyssalith.handlers.RoleCleanup;
2626
import com.volmit.abyssalith.io.DataLoader;
2727
import com.volmit.abyssalith.io.storage.FileSystemStorageAccess;

src/main/java/com/volmit/abyssalith/bot/startup/Registrar.java

Lines changed: 0 additions & 96 deletions
This file was deleted.
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
/*
2+
* Abyssalith is a Discord Bot for Volmit Software's Community
3+
* Copyright (c) 2021 VolmitSoftware (Arcane Arts)
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
17+
*/
18+
package com.volmit.abyssalith.commands;
19+
20+
import com.volmit.abyssalith.Abyss;
21+
import com.volmit.abyssalith.commands.general.Shutdown;
22+
import com.volmit.abyssalith.commands.general.*;
23+
import com.volmit.abyssalith.commands.moderation.ModHub;
24+
import com.volmit.abyssalith.commands.listeners.*;
25+
import com.volmit.abyssalith.toolbox.Kit;
26+
import net.dv8tion.jda.api.JDA;
27+
import net.dv8tion.jda.api.hooks.ListenerAdapter;
28+
29+
import java.io.BufferedReader;
30+
import java.io.IOException;
31+
import java.io.InputStream;
32+
import java.io.InputStreamReader;
33+
import java.lang.reflect.InvocationTargetException;
34+
import java.util.*;
35+
36+
@SkipCommand
37+
public class Registrar extends ListenerAdapter {
38+
39+
/**
40+
* Command package path. Recursively searched for commands not annotated by {@link SkipCommand}
41+
*/
42+
private static final String commandPackagePath = Registrar.class.getPackage().getName();
43+
44+
public static void All(JDA jda) {
45+
// Main bits, Regardless of platform
46+
jda.addEventListener(new Abyss()); // [ DONT TOUCH THESE LISTENERS ]
47+
jda.addEventListener(new Kit()); // [ DONT TOUCH THESE LISTENERS ]
48+
jda.addEventListener(new Shutdown()); // [ DONT TOUCH THESE LISTENERS ]
49+
50+
String modules = Kit.get().usageModules;
51+
52+
switch (modules) {
53+
case "MPM":
54+
// jda.addEventListener(new ServerInfo()); HELTH STUFF
55+
56+
break;
57+
58+
case "DEV":
59+
// jda.addEventListener(new ServerInfo()); DEVELOPMENT KEY
60+
61+
break;
62+
63+
case "VOL":
64+
// jda.addEventListener(new ServerInfo()); VOLMIT SERVER STANDARDS
65+
jda.addEventListener(new ButtonListener());
66+
jda.addEventListener(new PasteListener());
67+
jda.addEventListener(new Install());
68+
jda.addEventListener(new Log());
69+
jda.addEventListener(new UserInfo());
70+
jda.addEventListener(new GuildListener()); // Persistent Roles
71+
jda.addEventListener(new MessageListener()); // Watches the User's messages for stuff
72+
jda.addEventListener(new MessageReactionListener()); // Watches the User's instances for stuff
73+
jda.addEventListener(new Paste());
74+
jda.addEventListener(new Passive());
75+
jda.addEventListener(new ModHub()); // Mod Subcommand
76+
77+
break;
78+
79+
default:
80+
Abyss.debug("Registering commands...");
81+
try {
82+
registerAllCommands(commandPackagePath, jda);
83+
} catch (IOException e) {
84+
e.printStackTrace();
85+
Abyss.debug("Failed to close input stream for reading command classes!");
86+
}
87+
break;
88+
}
89+
90+
jda.addEventListener(new com.volmit.abyssalith.commands.general.Commands(jda)); // This one MUST be last
91+
}
92+
93+
/**
94+
* Register all commands
95+
* @param jda the {@link JDA} to register to
96+
*/
97+
private static void registerAllCommands(String packagePath, JDA jda) throws NullPointerException, IOException {
98+
99+
// Get stream of class data
100+
InputStream stream = ClassLoader.getSystemClassLoader()
101+
.getResourceAsStream(packagePath.replaceAll("[.]", "/"));
102+
103+
// If stream not accessible (null)
104+
if (stream == null) {
105+
throw new NullPointerException("Command loading, package not found: " + packagePath);
106+
}
107+
108+
List<String> loadedCommands = new ArrayList<>();
109+
new BufferedReader(new InputStreamReader(stream))
110+
.lines()
111+
.filter(line -> {
112+
if (line.endsWith(".class")) {
113+
return true;
114+
}
115+
116+
if (!line.contains(".")) {
117+
try {
118+
registerAllCommands(packagePath + "." + line, jda);
119+
} catch (IOException e) {
120+
e.printStackTrace();
121+
}
122+
}
123+
return false;
124+
})
125+
.map(line -> getCommandClass(line, packagePath))
126+
.filter(Objects::nonNull)
127+
.filter(c -> !c.isAnnotationPresent(SkipCommand.class))
128+
.map(cmdClass -> {
129+
try {
130+
return (ListenerAdapter) cmdClass.getConstructors()[0].newInstance();
131+
} catch (InstantiationException | IllegalAccessException | InvocationTargetException | IllegalArgumentException e) {
132+
e.printStackTrace();
133+
Abyss.debug("Failed to load command " + cmdClass.getName() + " with empty constructor!");
134+
} catch (ArrayIndexOutOfBoundsException e) {
135+
e.printStackTrace();
136+
Abyss.debug("Failed to load command " + cmdClass.getName() + " due to no constructor being present!");
137+
}
138+
return null;
139+
})
140+
.filter(Objects::nonNull)
141+
.forEach(c -> {
142+
jda.addEventListener(c);
143+
loadedCommands.add(c.getClass().getSimpleName());
144+
});
145+
stream.close();
146+
Abyss.debug("Loaded " + (loadedCommands.isEmpty() ? "NONE" : String.join(", ", loadedCommands)) + " from package " + packagePath);
147+
}
148+
149+
/**
150+
* Get a command class from a class name and package.
151+
* @param className name of the class
152+
* @param packageName path to the package
153+
* @return the class or null if not a {@link ListenerAdapter}
154+
*/
155+
private static Class<?> getCommandClass(String className, String packageName) {
156+
try {
157+
Class<?> c = Class.forName(packageName + "."
158+
+ className.substring(0, className.lastIndexOf('.')));
159+
if (c.isAssignableFrom(ListenerAdapter.class)) {
160+
Abyss.debug("Unable to load class: " + c.getName() + " because it does not extend ListenerAdapter");
161+
}
162+
return c;
163+
} catch (ClassNotFoundException e) {
164+
// handle the exception
165+
}
166+
return null;
167+
}
168+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.volmit.abyssalith.commands;
2+
3+
4+
import java.lang.annotation.ElementType;
5+
import java.lang.annotation.Retention;
6+
import java.lang.annotation.RetentionPolicy;
7+
import java.lang.annotation.Target;
8+
9+
/**
10+
* Annotate a command (sub)class by this to skip it during command grabbing.
11+
*/
12+
@Retention(RetentionPolicy.RUNTIME)
13+
@Target({ElementType.TYPE_USE})
14+
@SkipCommand
15+
public @interface SkipCommand {}

src/main/java/com/volmit/abyssalith/commands/general/Commands.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package com.volmit.abyssalith.commands.general;
1919

2020
import com.volmit.abyssalith.Abyss;
21+
import com.volmit.abyssalith.commands.SkipCommand;
2122
import com.volmit.abyssalith.toolbox.Kit;
2223
import com.volmit.abyssalith.util.VolmitCommand;
2324
import com.volmit.abyssalith.util.VolmitEmbed;
@@ -27,7 +28,7 @@
2728
import java.util.ArrayList;
2829
import java.util.List;
2930

30-
31+
@SkipCommand
3132
public class Commands extends VolmitCommand {
3233

3334
// Commands stored

src/main/java/com/volmit/abyssalith/commands/general/ServerInfo.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package com.volmit.abyssalith.commands.general;
1919

2020
import com.volmit.abyssalith.Abyss;
21+
import com.volmit.abyssalith.commands.SkipCommand;
2122
import com.volmit.abyssalith.util.VolmitCommand;
2223
import net.dv8tion.jda.api.EmbedBuilder;
2324
import net.dv8tion.jda.api.OnlineStatus;
@@ -44,6 +45,7 @@ public ServerInfo() {
4445
);
4546
}
4647

48+
@SkipCommand
4749
private static class GuildStats {
4850

4951
private final String name;

src/main/java/com/volmit/abyssalith/commands/botmaster/Shutdown.java renamed to src/main/java/com/volmit/abyssalith/commands/general/Shutdown.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* You should have received a copy of the GNU General Public License
1616
* along with this program. If not, see <https://www.gnu.org/licenses/>.
1717
*/
18-
package com.volmit.abyssalith.commands.botmaster;
18+
package com.volmit.abyssalith.commands.general;
1919

2020
import com.volmit.abyssalith.Abyss;
2121
import com.volmit.abyssalith.toolbox.Kit;

src/main/java/com/volmit/abyssalith/listeners/ButtonListener.java renamed to src/main/java/com/volmit/abyssalith/commands/listeners/ButtonListener.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* You should have received a copy of the GNU General Public License
1616
* along with this program. If not, see <https://www.gnu.org/licenses/>.
1717
*/
18-
package com.volmit.abyssalith.listeners;
18+
package com.volmit.abyssalith.commands.listeners;
1919

2020
import com.volmit.abyssalith.Abyss;
2121
import net.dv8tion.jda.api.events.interaction.ButtonClickEvent;

src/main/java/com/volmit/abyssalith/listeners/GuildListener.java renamed to src/main/java/com/volmit/abyssalith/commands/listeners/GuildListener.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* You should have received a copy of the GNU General Public License
1616
* along with this program. If not, see <https://www.gnu.org/licenses/>.
1717
*/
18-
package com.volmit.abyssalith.listeners;
18+
package com.volmit.abyssalith.commands.listeners;
1919

2020
import com.volmit.abyssalith.Abyss;
2121
import com.volmit.abyssalith.data.User;

src/main/java/com/volmit/abyssalith/listeners/MessageListener.java renamed to src/main/java/com/volmit/abyssalith/commands/listeners/MessageListener.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* You should have received a copy of the GNU General Public License
1616
* along with this program. If not, see <https://www.gnu.org/licenses/>.
1717
*/
18-
package com.volmit.abyssalith.listeners;
18+
package com.volmit.abyssalith.commands.listeners;
1919

2020
import com.github.pemistahl.lingua.api.Language;
2121
import com.github.pemistahl.lingua.api.LanguageDetector;

0 commit comments

Comments
 (0)