HidekoBot/src/main/java/wtf/beatrice/hidekobot/HidekoBot.java

259 lines
12 KiB
Java
Raw Normal View History

package wtf.beatrice.hidekobot;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.JDABuilder;
2022-08-26 00:39:55 +02:00
import net.dv8tion.jda.api.OnlineStatus;
2022-08-25 23:20:51 +02:00
import net.dv8tion.jda.api.requests.GatewayIntent;
2023-01-15 02:05:23 +01:00
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import wtf.beatrice.hidekobot.commands.completer.ProfileImageCommandCompleter;
import wtf.beatrice.hidekobot.commands.message.HelloCommand;
import wtf.beatrice.hidekobot.commands.slash.*;
2022-11-22 23:44:34 +01:00
import wtf.beatrice.hidekobot.datasources.ConfigurationSource;
import wtf.beatrice.hidekobot.datasources.DatabaseSource;
import wtf.beatrice.hidekobot.datasources.PropertiesSource;
import wtf.beatrice.hidekobot.listeners.*;
2022-11-21 15:02:40 +01:00
import wtf.beatrice.hidekobot.runnables.ExpiredMessageTask;
import wtf.beatrice.hidekobot.runnables.HeartBeatTask;
import wtf.beatrice.hidekobot.runnables.RandomOrgSeedTask;
import wtf.beatrice.hidekobot.runnables.StatusUpdateTask;
2022-12-20 14:51:29 +01:00
import wtf.beatrice.hidekobot.util.CommandUtil;
2023-01-15 02:05:23 +01:00
import wtf.beatrice.hidekobot.util.FormatUtil;
import wtf.beatrice.hidekobot.util.RandomUtil;
import java.io.File;
2022-11-21 12:19:35 +01:00
import java.time.LocalDateTime;
import java.util.ArrayList;
2022-08-26 20:43:49 +02:00
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class HidekoBot
{
private static JDA jda;
2023-01-15 02:05:23 +01:00
private static final Logger LOGGER = LoggerFactory.getLogger(HidekoBot.class);
2022-08-25 22:54:08 +02:00
public static void main(String[] args)
{
2022-08-25 22:20:05 +02:00
// load configuration
2023-01-15 02:05:23 +01:00
LOGGER.info("Loading configuration...");
String configFilePath = Cache.getExecPath() + File.separator + "config.yml";
2022-11-22 00:28:33 +01:00
ConfigurationSource configurationSource = new ConfigurationSource(configFilePath);
configurationSource.initConfig();
Cache.setConfigurationSource(configurationSource);
2023-01-15 02:05:23 +01:00
LOGGER.info("Configuration loaded!");
// load properties
2023-01-15 02:05:23 +01:00
LOGGER.info("Loading properties...");
PropertiesSource propertiesSource = new PropertiesSource();
propertiesSource.load();
Cache.setPropertiesSourceInstance(propertiesSource);
2023-01-15 02:05:23 +01:00
LOGGER.info("Properties loaded!");
// check loaded bot token
String botToken = Cache.getBotToken();
if(botToken == null || botToken.isEmpty())
2022-08-25 22:20:05 +02:00
{
2023-01-15 02:05:23 +01:00
LOGGER.error("Invalid bot token!");
shutdown();
2022-08-25 22:20:05 +02:00
return;
}
try
{
2022-08-25 22:37:32 +02:00
// try to create the bot object and authenticate it with discord.
JDABuilder jdaBuilder = JDABuilder.createDefault(botToken);
2022-08-25 23:20:51 +02:00
// enable necessary intents.
jdaBuilder.enableIntents(
GatewayIntent.MESSAGE_CONTENT,
2022-08-25 23:20:51 +02:00
GatewayIntent.DIRECT_MESSAGES,
GatewayIntent.GUILD_MESSAGES
);
2022-08-25 23:20:51 +02:00
jda = jdaBuilder.build().awaitReady();
2023-01-15 05:00:44 +01:00
} catch (InterruptedException e) {
LOGGER.error(e.getMessage()); // print the error message, omit the stack trace.
Thread.currentThread().interrupt(); // send interrupt to the thread.
shutdown(); // if we failed connecting and authenticating, then quit.
}
catch (Exception e)
{
2023-01-15 02:05:23 +01:00
LOGGER.error(e.getMessage()); // print the error message, omit the stack trace.
shutdown(); // if we failed connecting and authenticating, then quit.
}
2022-08-25 22:37:32 +02:00
2022-11-20 18:11:00 +01:00
// find the bot's user/application id
2022-11-20 16:07:04 +01:00
String botUserId = jda.getSelfUser().getId();
2022-11-21 20:20:11 +01:00
Cache.setBotApplicationId(botUserId);
2022-11-20 18:56:57 +01:00
// store if we have to force refresh commands despite no apparent changes.
2022-11-20 18:54:13 +01:00
boolean forceUpdateCommands = false;
2022-11-20 03:01:46 +01:00
// if there is at least one arg, then iterate through them because we have additional things to do.
// we are doing this at the end because we might need the API to be already initialized for some things.
if(args.length > 0) {
List<String> argsList = new ArrayList<>(Arrays.asList(args));
// NOTE: do not replace with enhanced for, since we might need
// to know what position we're at or do further elaboration of the string.
// we were using this for api key parsing in the past.
for(int i = 0; i < argsList.size(); i++)
{
String arg = argsList.get(i);
2022-11-21 20:20:11 +01:00
if(arg.equals("verbose")) Cache.setVerbose(true);
if(arg.equals("refresh")) forceUpdateCommands = true;
}
}
boolean enableRandomSeedUpdaterTask = false;
// initialize random.org object if API key is provided
{
if(RandomUtil.isRandomOrgKeyValid())
{
LOGGER.info("Enabling Random.org integration... This might take a while!");
RandomUtil.initRandomOrg();
enableRandomSeedUpdaterTask = true;
LOGGER.info("Random.org integration enabled!");
}
}
// register slash commands and completers
SlashCommandListener slashCommandListener = new SlashCommandListener();
SlashCommandCompletionListener slashCommandCompletionListener = new SlashCommandCompletionListener();
AvatarCommand avatarCommand = new AvatarCommand();
ProfileImageCommandCompleter avatarCommandCompleter = new ProfileImageCommandCompleter(avatarCommand);
slashCommandListener.registerCommand(avatarCommand);
slashCommandCompletionListener.registerCommandCompleter(avatarCommandCompleter);
slashCommandListener.registerCommand(new BanCommand());
BannerCommand bannerCommand = new BannerCommand();
ProfileImageCommandCompleter bannerCommandCompleter = new ProfileImageCommandCompleter(bannerCommand);
slashCommandListener.registerCommand(bannerCommand);
slashCommandCompletionListener.registerCommandCompleter(bannerCommandCompleter);
slashCommandListener.registerCommand(new BotInfoCommand());
slashCommandListener.registerCommand(new ClearCommand());
slashCommandListener.registerCommand(new CoinFlipCommand());
slashCommandListener.registerCommand(new DiceRollCommand());
slashCommandListener.registerCommand(new DieCommand());
slashCommandListener.registerCommand(new HelpCommand());
slashCommandListener.registerCommand(new InviteCommand());
slashCommandListener.registerCommand(new KickCommand());
slashCommandListener.registerCommand(new LoveCalculatorCommand());
slashCommandListener.registerCommand(new MagicBallCommand());
slashCommandListener.registerCommand(new PingCommand());
slashCommandListener.registerCommand(new SayCommand());
slashCommandListener.registerCommand(new TimeoutCommand());
2022-12-21 23:31:12 +01:00
slashCommandListener.registerCommand(new TriviaCommand());
2022-12-20 02:17:27 +01:00
slashCommandListener.registerCommand(new UrbanDictionaryCommand());
// register message commands
MessageCommandListener messageCommandListener = new MessageCommandListener();
messageCommandListener.registerCommand(new HelloCommand());
2022-12-20 17:18:24 +01:00
messageCommandListener.registerCommand(new wtf.beatrice.hidekobot.commands.message.AliasCommand());
messageCommandListener.registerCommand(new wtf.beatrice.hidekobot.commands.message.AvatarCommand());
2022-12-26 02:40:14 +01:00
messageCommandListener.registerCommand(new wtf.beatrice.hidekobot.commands.message.BanCommand());
messageCommandListener.registerCommand(new wtf.beatrice.hidekobot.commands.message.BannerCommand());
messageCommandListener.registerCommand(new wtf.beatrice.hidekobot.commands.message.BotInfoCommand());
messageCommandListener.registerCommand(new wtf.beatrice.hidekobot.commands.message.CoinFlipCommand());
messageCommandListener.registerCommand(new wtf.beatrice.hidekobot.commands.message.ClearCommand());
messageCommandListener.registerCommand(new wtf.beatrice.hidekobot.commands.message.DiceRollCommand());
messageCommandListener.registerCommand(new wtf.beatrice.hidekobot.commands.message.HelpCommand());
messageCommandListener.registerCommand(new wtf.beatrice.hidekobot.commands.message.InviteCommand());
2022-12-26 00:22:32 +01:00
messageCommandListener.registerCommand(new wtf.beatrice.hidekobot.commands.message.KickCommand());
messageCommandListener.registerCommand(new wtf.beatrice.hidekobot.commands.message.LoveCalculatorCommand());
2022-12-19 18:24:29 +01:00
messageCommandListener.registerCommand(new wtf.beatrice.hidekobot.commands.message.MagicBallCommand());
messageCommandListener.registerCommand(new wtf.beatrice.hidekobot.commands.message.SayCommand());
2022-12-26 03:34:11 +01:00
messageCommandListener.registerCommand(new wtf.beatrice.hidekobot.commands.message.TimeoutCommand());
2022-12-21 02:50:22 +01:00
messageCommandListener.registerCommand(new wtf.beatrice.hidekobot.commands.message.TriviaCommand());
messageCommandListener.registerCommand(new wtf.beatrice.hidekobot.commands.message.UrbanDictionaryCommand());
2022-11-20 18:54:13 +01:00
// register listeners
Cache.setSlashCommandListener(slashCommandListener);
Cache.setSlashCommandCompletionListener(slashCommandCompletionListener);
Cache.setMessageCommandListener(messageCommandListener);
jda.addEventListener(messageCommandListener);
jda.addEventListener(slashCommandListener);
jda.addEventListener(slashCommandCompletionListener);
jda.addEventListener(new ButtonInteractionListener());
jda.addEventListener(new SelectMenuInteractionListener());
2022-11-20 18:54:13 +01:00
// update slash commands (delayed)
final boolean finalForceUpdateCommands = forceUpdateCommands;
Executors.newSingleThreadScheduledExecutor().schedule(() -> // todo: try-with-resources
2022-12-20 14:51:29 +01:00
CommandUtil.updateSlashCommands(finalForceUpdateCommands), 1, TimeUnit.SECONDS);
2022-11-20 18:54:13 +01:00
// set the bot's status
jda.getPresence().setStatus(OnlineStatus.ONLINE);
// connect to database
2023-01-15 02:05:23 +01:00
LOGGER.info("Connecting to database...");
String dbFilePath = Cache.getExecPath() + File.separator + "db.sqlite"; // in current directory
2022-11-22 00:28:33 +01:00
DatabaseSource databaseSource = new DatabaseSource(dbFilePath);
if(databaseSource.connect() && databaseSource.initDb())
{
2023-01-15 02:05:23 +01:00
LOGGER.info("Database connection initialized!");
2022-11-22 00:28:33 +01:00
Cache.setDatabaseSourceInstance(databaseSource);
// load data here...
2023-01-15 02:05:23 +01:00
LOGGER.info("Database data loaded into memory!");
} else {
2023-01-15 02:05:23 +01:00
LOGGER.error("Error initializing database connection!");
}
// start scheduled runnables
2022-12-20 22:49:20 +01:00
ScheduledExecutorService scheduler = Cache.getTaskScheduler();
ExpiredMessageTask expiredMessageTask = new ExpiredMessageTask();
2023-01-15 01:00:44 +01:00
scheduler.scheduleAtFixedRate(expiredMessageTask, 5L, 5L, TimeUnit.SECONDS); //every 5 seconds
HeartBeatTask heartBeatTask = new HeartBeatTask();
2023-01-15 01:00:44 +01:00
scheduler.scheduleAtFixedRate(heartBeatTask, 10L, 30L, TimeUnit.SECONDS); //every 30 seconds
StatusUpdateTask statusUpdateTask = new StatusUpdateTask();
2023-01-15 01:00:44 +01:00
scheduler.scheduleAtFixedRate(statusUpdateTask, 0L, 60L * 5L, TimeUnit.SECONDS); // every 5 minutes
if(enableRandomSeedUpdaterTask)
{
RandomOrgSeedTask randomSeedTask = new RandomOrgSeedTask();
scheduler.scheduleAtFixedRate(randomSeedTask, 15L, 15L, TimeUnit.MINUTES); // every 15 minutes
}
2022-11-21 12:19:35 +01:00
// register shutdown interrupt signal listener for proper shutdown.
Runtime.getRuntime().addShutdownHook(new Thread(HidekoBot::preShutdown));
2022-11-21 12:19:35 +01:00
// set startup time.
2022-11-21 20:20:11 +01:00
Cache.setStartupTime(LocalDateTime.now());
2022-08-25 22:54:08 +02:00
// print the bot logo.
2023-01-15 02:05:23 +01:00
LOGGER.info("\n\n{}\nv{} - bot is ready!\n", FormatUtil.getLogo(), Cache.getBotVersion());
2022-08-25 22:54:08 +02:00
2022-08-25 22:37:32 +02:00
// log the invite-link to console so noob users can just click on it.
2023-01-15 02:05:23 +01:00
LOGGER.info("Bot User ID: {}", botUserId);
LOGGER.info("Invite Link: {}", Cache.getInviteUrl());
2022-08-25 23:20:51 +02:00
}
public static JDA getAPI()
{
return jda;
}
2022-08-25 22:13:39 +02:00
public static void shutdown()
{
preShutdown();
System.exit(0);
}
private static void preShutdown()
{
2023-01-15 02:05:23 +01:00
LOGGER.warn("WARNING! Shutting down!");
if(jda != null) jda.shutdown();
}
}