Added basic bot functionality
This commit is contained in:
13
src/main/java/com/redstoner/redstonerBot/Env.java
Normal file
13
src/main/java/com/redstoner/redstonerBot/Env.java
Normal file
@@ -0,0 +1,13 @@
|
||||
package com.redstoner.redstonerBot;
|
||||
|
||||
public class Env {
|
||||
public static final String TOKEN = System.getenv("TOKEN");
|
||||
|
||||
public static final String MYSQL_HOST = System.getenv("MYSQL_HOST");
|
||||
public static final String MYSQL_PORT = System.getenv("MYSQL_PORT");
|
||||
|
||||
public static final String MYSQL_USER = System.getenv("MYSQL_USER");
|
||||
public static final String MYSQL_PASS = System.getenv("MYSQL_PASS");
|
||||
|
||||
public static final String MYSQL_DB = System.getenv("MYSQL_DB");
|
||||
}
|
||||
@@ -1,12 +1,62 @@
|
||||
package com.redstoner.redstonerBot;
|
||||
|
||||
import com.redstoner.redstonerBot.managers.CommandManager;
|
||||
import com.redstoner.redstonerBot.managers.DataManager;
|
||||
import com.redstoner.redstonerBot.managers.DiscordManager;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class Main {
|
||||
public static final Logger logger = LoggerFactory.getLogger(Main.class);
|
||||
private static final Logger logger = LoggerFactory.getLogger(Main.class);
|
||||
|
||||
private static final List<Manager> managers = new ArrayList<>();
|
||||
private static final List<Manager> loadedManagers = new ArrayList<>();
|
||||
|
||||
static {
|
||||
managers.add(new DataManager());
|
||||
managers.add(new DiscordManager());
|
||||
managers.add(new CommandManager());
|
||||
}
|
||||
|
||||
public static void main(final String... args) {
|
||||
logger.info("Starting RedstonerBot...");
|
||||
|
||||
if (!start()) {
|
||||
stop();
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean start() {
|
||||
loadedManagers.clear();
|
||||
|
||||
for (Manager m : managers) {
|
||||
if (m.start()) {
|
||||
loadedManagers.add(m);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean stop() {
|
||||
for (Manager m : getReversedManagers()) {
|
||||
if (!m.stop()) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static List<Manager> getReversedManagers() {
|
||||
List<Manager> reversedManagers = new ArrayList<>(loadedManagers);
|
||||
Collections.reverse(reversedManagers);
|
||||
|
||||
return reversedManagers;
|
||||
}
|
||||
}
|
||||
|
||||
6
src/main/java/com/redstoner/redstonerBot/Manager.java
Normal file
6
src/main/java/com/redstoner/redstonerBot/Manager.java
Normal file
@@ -0,0 +1,6 @@
|
||||
package com.redstoner.redstonerBot;
|
||||
|
||||
public interface Manager {
|
||||
boolean start();
|
||||
boolean stop();
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.redstoner.redstonerBot.commands;
|
||||
|
||||
import net.dv8tion.jda.core.entities.*;
|
||||
|
||||
public interface Command {
|
||||
boolean execute(Guild guild, TextChannel channel, Message message, User author, Member self, String command, String[] params);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.redstoner.redstonerBot.commands;
|
||||
|
||||
import com.redstoner.redstonerBot.managers.DiscordManager;
|
||||
import net.dv8tion.jda.core.EmbedBuilder;
|
||||
import net.dv8tion.jda.core.entities.*;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
public class InfoCommand implements Command {
|
||||
@Override
|
||||
public boolean execute(Guild guild, TextChannel channel, Message message, User author, Member self, String command, String[] params) {
|
||||
EmbedBuilder embed = new EmbedBuilder();
|
||||
|
||||
embed.setTitle("Information");
|
||||
embed.setDescription("This is a Discord bot built by psrcek for the Redstoner Guild.");
|
||||
|
||||
embed.setColor(Color.ORANGE);
|
||||
embed.setFooter("Redstoner bot", "https://cdn.discordapp.com/avatars/576432236702859284/b08d4dc368b2e041ebb3fc208a2e8230.png");
|
||||
|
||||
message.getChannel().sendMessage(embed.build()).queue(DiscordManager::expireMessage);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.redstoner.redstonerBot.commands;
|
||||
|
||||
import com.redstoner.redstonerBot.Main;
|
||||
import com.redstoner.redstonerBot.managers.DiscordManager;
|
||||
import net.dv8tion.jda.core.entities.*;
|
||||
|
||||
public class StopCommand implements Command {
|
||||
@Override
|
||||
public boolean execute(Guild guild, TextChannel channel, Message message, User author, Member self, String command, String[] params) {
|
||||
if (!guild.getOwnerId().equals(author.getId())) return false;
|
||||
|
||||
message.getChannel().sendMessage("This bot will stop in 5 seconds, as requested by " + author.getAsTag()).queue(DiscordManager::expireMessage);
|
||||
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Thread.sleep(6000);
|
||||
} catch (InterruptedException ignored) {
|
||||
}
|
||||
|
||||
Main.stop();
|
||||
}).start();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.redstoner.redstonerBot.listeners;
|
||||
|
||||
import com.redstoner.redstonerBot.managers.CommandManager;
|
||||
import com.redstoner.redstonerBot.managers.DataManager;
|
||||
import net.dv8tion.jda.core.Permission;
|
||||
import net.dv8tion.jda.core.entities.*;
|
||||
import net.dv8tion.jda.core.events.message.guild.GuildMessageReceivedEvent;
|
||||
import net.dv8tion.jda.core.hooks.ListenerAdapter;
|
||||
import net.dv8tion.jda.core.utils.Checks;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class MessageReceived extends ListenerAdapter {
|
||||
private static final Logger logger = LoggerFactory.getLogger(MessageReceived.class);
|
||||
|
||||
@Override
|
||||
public final void onGuildMessageReceived(GuildMessageReceivedEvent event) {
|
||||
Checks.notNull(event, "Event");
|
||||
|
||||
final Guild guild = event.getGuild();
|
||||
final TextChannel channel = event.getChannel();
|
||||
final Message message = event.getMessage();
|
||||
final User author = event.getAuthor();
|
||||
|
||||
final Member self = guild.getSelfMember();
|
||||
|
||||
if (!Objects.equals(guild.getId(), DataManager.getConfigValue("guild_id"))) return;
|
||||
if (author.isBot()) return;
|
||||
if (message.isTTS()) return;
|
||||
if (!self.hasPermission(channel, Permission.MESSAGE_WRITE)) return;
|
||||
if (!self.hasPermission(channel, Permission.MESSAGE_EMBED_LINKS)) return;
|
||||
|
||||
String rawMessage = message.getContentRaw();
|
||||
|
||||
logger.info(author.getAsTag() + " -> " + rawMessage);
|
||||
|
||||
if (rawMessage.startsWith(DataManager.getConfigValue("prefix_char"))) {
|
||||
CommandManager.execute(guild, channel, message, author, self);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.redstoner.redstonerBot.managers;
|
||||
|
||||
import com.redstoner.redstonerBot.Manager;
|
||||
import com.redstoner.redstonerBot.commands.Command;
|
||||
import com.redstoner.redstonerBot.commands.InfoCommand;
|
||||
import com.redstoner.redstonerBot.commands.StopCommand;
|
||||
import net.dv8tion.jda.core.entities.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class CommandManager implements Manager {
|
||||
private static final Logger logger = LoggerFactory.getLogger(CommandManager.class);
|
||||
|
||||
private static Map<String, Command> commands = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public boolean start() {
|
||||
logger.info("Command Manager starting...");
|
||||
|
||||
commands.put("info", new InfoCommand());
|
||||
commands.put("stop", new StopCommand());
|
||||
|
||||
|
||||
logger.info("Command Manager started!");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stop() {
|
||||
logger.info("Command Manager stopping...");
|
||||
|
||||
commands.clear();
|
||||
|
||||
logger.info("Command Manager stopped!");
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void execute(Guild guild, TextChannel channel, Message message, User author, Member self) {
|
||||
String rawMsg = message.getContentRaw();
|
||||
String[] rawCmd = rawMsg.split(" ");
|
||||
String cmd = rawCmd[0].substring(1);
|
||||
String[] params = Arrays.copyOfRange(rawCmd, 1, rawCmd.length);
|
||||
|
||||
Command command = commands.get(cmd);
|
||||
|
||||
if (command == null) return;
|
||||
logger.info("[" + message.getId() + "] User '" + author.getAsTag() + "' executed command " + cmd + " with parameters " + Arrays.toString(params));
|
||||
|
||||
if (command.execute(guild, channel, message, author, self, cmd, params)) {
|
||||
logger.info("[" + message.getId() + "] Command executed successfully!");
|
||||
} else {
|
||||
logger.error("[" + message.getId() + "] Error while executing command!");
|
||||
}
|
||||
|
||||
message.delete().reason("Redstoner Bot command execution").queue();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
package com.redstoner.redstonerBot.managers;
|
||||
|
||||
import com.redstoner.redstonerBot.Env;
|
||||
import com.redstoner.redstonerBot.Manager;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class DataManager implements Manager {
|
||||
private static final Logger logger = LoggerFactory.getLogger(DataManager.class);
|
||||
|
||||
private static final String[] requiredTables = { "config", "opt_in", "rules", "rule_agree_reactions" };
|
||||
|
||||
private static Map<String, String> config = new HashMap<>();
|
||||
|
||||
public boolean start() {
|
||||
logger.info("Data Manager starting...");
|
||||
|
||||
if (checkConnection()) {
|
||||
logger.info("Loading config...");
|
||||
|
||||
if (!loadConfig()) {
|
||||
logger.error("Data Manager failed to load config!");
|
||||
return false;
|
||||
}
|
||||
|
||||
logger.info("Data Manager started!");
|
||||
return true;
|
||||
} else {
|
||||
logger.error("Data Manager failed to start!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean stop() {
|
||||
logger.info("Data Manager stopping...");
|
||||
|
||||
config.clear();
|
||||
|
||||
logger.info("Data Manager stopped!");
|
||||
return true;
|
||||
}
|
||||
|
||||
private static String getConnectionString() {
|
||||
return "jdbc:mysql://"
|
||||
+ Env.MYSQL_HOST + ":" + Env.MYSQL_PORT
|
||||
+ "/" + Env.MYSQL_DB
|
||||
+ "?useUnicode=true&characterEncoding=UTF-8"
|
||||
+ "&user=" + Env.MYSQL_USER
|
||||
+ "&password=" + Env.MYSQL_PASS;
|
||||
}
|
||||
|
||||
private static Connection getConnection() throws SQLException {
|
||||
return DriverManager.getConnection(getConnectionString());
|
||||
}
|
||||
|
||||
private boolean checkConnection() {
|
||||
try {
|
||||
Class.forName("com.mysql.cj.jdbc.Driver");
|
||||
|
||||
Connection conn = getConnection();
|
||||
ResultSet rs = conn.prepareStatement("show tables").executeQuery();
|
||||
|
||||
List<String> tables = new ArrayList<>();
|
||||
|
||||
while (rs.next()) {
|
||||
tables.add(rs.getString(1));
|
||||
}
|
||||
|
||||
conn.close();
|
||||
|
||||
for (String rt : requiredTables) {
|
||||
if (!tables.contains(rt)) {
|
||||
logger.error("The " + rt + " table is missing from the database!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (ClassNotFoundException | SQLException e) {
|
||||
logger.error("SQL error:", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getConfigValue(String name) {
|
||||
return config.get(name);
|
||||
}
|
||||
|
||||
public boolean loadConfig() {
|
||||
config.clear();
|
||||
|
||||
try {
|
||||
Connection conn = getConnection();
|
||||
ResultSet rs = conn.prepareStatement("SELECT * FROM config").executeQuery();
|
||||
|
||||
while (rs.next()) {
|
||||
String name = rs.getString(2);
|
||||
String value = rs.getString(3);
|
||||
|
||||
config.put(name, value);
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (SQLException e) {
|
||||
logger.error("SQL error:", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.redstoner.redstonerBot.managers;
|
||||
|
||||
import com.redstoner.redstonerBot.Env;
|
||||
import com.redstoner.redstonerBot.Manager;
|
||||
import com.redstoner.redstonerBot.listeners.MessageReceived;
|
||||
import net.dv8tion.jda.core.AccountType;
|
||||
import net.dv8tion.jda.core.JDA;
|
||||
import net.dv8tion.jda.core.JDABuilder;
|
||||
import net.dv8tion.jda.core.entities.Guild;
|
||||
import net.dv8tion.jda.core.entities.Message;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.security.auth.login.LoginException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class DiscordManager implements Manager {
|
||||
private static final Logger logger = LoggerFactory.getLogger(DiscordManager.class);
|
||||
|
||||
private JDA jda;
|
||||
|
||||
public boolean start() {
|
||||
logger.info("Discord Manager starting...");
|
||||
|
||||
try {
|
||||
final JDABuilder builder = new JDABuilder(AccountType.BOT);
|
||||
|
||||
builder.setAutoReconnect(true);
|
||||
builder.setAudioEnabled(true);
|
||||
|
||||
builder.setToken(Env.TOKEN);
|
||||
|
||||
builder.addEventListener(new MessageReceived());
|
||||
|
||||
jda = builder.build().awaitReady();
|
||||
} catch (LoginException e) {
|
||||
logger.error("The discord token is invalid!");
|
||||
return false;
|
||||
} catch (Throwable t) {
|
||||
logger.error("JDA setup error:", t);
|
||||
return false;
|
||||
}
|
||||
|
||||
Guild guild = jda.getGuildById(DataManager.getConfigValue("guild_id"));
|
||||
|
||||
String guildName = guild.getName();
|
||||
String infoChannelName = guild.getTextChannelById(DataManager.getConfigValue("info_channel_id")).getName();
|
||||
|
||||
logger.info("Discord Manager started and logged in as '" + jda.getSelfUser().getName() + "'");
|
||||
logger.info("Listening to guild '" + guildName + "'");
|
||||
logger.info("Using channel '" + infoChannelName + "' as the info channel");
|
||||
|
||||
logger.info("Discord Manager started!");
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean stop() {
|
||||
logger.info("Discord Manager stopping...");
|
||||
|
||||
jda.shutdown();
|
||||
|
||||
logger.info("Discord Manager stopped!");
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void expireMessage(Message message) {
|
||||
message.delete().reason("Redstoner Bot message expiry").queueAfter(5, TimeUnit.SECONDS);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user