kiafumi/src/main/java/moe/oko/Kiafumi/Kiafumi.java

266 lines
10 KiB
Java
Raw Normal View History

2022-03-23 20:39:52 +00:00
package moe.oko.Kiafumi;
2022-03-28 20:43:04 +00:00
import moe.oko.Kiafumi.command.*;
2022-03-24 04:10:50 +00:00
import moe.oko.Kiafumi.listener.MainListener;
import moe.oko.Kiafumi.model.KiafumiDB;
2022-03-26 05:04:24 +00:00
import moe.oko.Kiafumi.model.ServerManager;
import moe.oko.Kiafumi.util.CommandInfo;
import moe.oko.Kiafumi.util.EmbedUI;
2022-03-24 04:10:50 +00:00
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.JDABuilder;
2022-03-23 20:39:52 +00:00
import net.dv8tion.jda.api.OnlineStatus;
import net.dv8tion.jda.api.entities.Activity;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.interactions.commands.build.SubcommandData;
2022-03-23 20:39:52 +00:00
import net.dv8tion.jda.api.requests.GatewayIntent;
import net.dv8tion.jda.api.requests.restaction.CommandCreateAction;
2022-03-23 20:39:52 +00:00
import net.dv8tion.jda.api.utils.ChunkingFilter;
import net.dv8tion.jda.api.utils.MemberCachePolicy;
2022-03-28 19:42:48 +00:00
import net.dv8tion.jda.api.utils.cache.CacheFlag;
import org.simpleyaml.configuration.file.YamlConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileNotFoundException;
2022-03-24 04:10:50 +00:00
import java.io.InputStream;
import java.nio.file.Files;
2022-03-28 19:42:48 +00:00
import java.time.ZonedDateTime;
import java.util.List;
2022-03-24 04:28:51 +00:00
/**
* Kiafumi Main Class
* @author Kay, oko, Tiddy
* @version 0.8.0-pre
* @apiNote Thanks to:
* | Maxopoly, Orinnari, ProgrammerDan, and more, for helping teach Kay how to code Java from scratch.
* | Favna, and the HC Development community for encouraging the development core of HC.
* | HC as a whole, for being a wonderful community and encouraging the creation of this bot
* | Civ, for encouraging us all to sort out how the hell programming works
* | Discord, for offering a platform to learn these skills on
* | The Java Development Team, for making a Language I personally love and adore - Kay
2022-03-24 04:28:51 +00:00
*/
2022-03-23 20:39:52 +00:00
public class Kiafumi {
private final File CONFIG_FILE = new File("config.yml");
2022-03-24 04:10:50 +00:00
public YamlConfiguration yamlConfiguration = new YamlConfiguration();
2022-03-23 20:39:52 +00:00
public Logger logger = LoggerFactory.getLogger("Kiafumi");
2022-03-23 20:39:52 +00:00
public static Kiafumi instance;
2022-03-23 20:39:52 +00:00
public static JDA JDA;
public List<CommandClass> activeCommands;
2022-03-23 20:39:52 +00:00
public KiafumiConfig config;
2022-03-24 04:10:50 +00:00
public KiafumiDB database;
2022-03-26 05:04:24 +00:00
public ServerManager serverManager;
2022-03-24 04:28:51 +00:00
/**
* Main Class function, makes the classes work or some shit.
* @param args - Arguments for program start.
*/
public static void main(String[] args) {
try {
2022-03-24 04:10:50 +00:00
Kiafumi kia = new Kiafumi();
kia.start();
} catch (Exception ex) {
2022-03-23 20:39:52 +00:00
System.out.println("Failed to start Kiafumi Instance, check your Java installation.");
ex.printStackTrace();
}
}
2022-03-24 04:28:51 +00:00
/**
* Ran on program start. Anything in here can determine whether the program will start.
*/
public void start() {
instance = this;
2022-03-23 20:39:52 +00:00
logger.info("Starting Kiafumi.");
//All commands to be loaded on startup!
activeCommands = new CommandRegistrar().getCommandClasses();
2022-03-24 04:28:51 +00:00
//Logger check
System.out.println("If no other messages are present, logger failed to instantiate.");
logger.info("Config load start...");
2022-03-24 04:28:51 +00:00
//Ensuring the configuration file is generated and/or exists.
if (!CONFIG_FILE.exists()) {
2022-03-24 04:10:50 +00:00
try (InputStream is = this.getClass().getClassLoader().getResourceAsStream("config.yml")) {
//Save the default cfg
Files.copy(is, CONFIG_FILE.toPath());
} catch (Exception ex) {
logger.warn("Failed to create the configuration file. Stopping. (" + CONFIG_FILE.getAbsolutePath() + ")");
ex.printStackTrace();
return;
}
}
2022-03-24 04:28:51 +00:00
//Try to load configuration into our local friendly configuration API.
try {
2022-03-24 04:10:50 +00:00
yamlConfiguration.load("config.yml");
} catch (FileNotFoundException e) {
e.printStackTrace();
2022-03-24 04:10:50 +00:00
logger.warn("File not found, must've failed to create...");
} catch (Exception e) {
logger.warn("Ensure all values are inputted properly.");
e.printStackTrace();
}
2022-03-24 04:28:51 +00:00
//Initializes our configuration helper & ensures it loads properly.
2022-03-23 20:39:52 +00:00
config = new KiafumiConfig(yamlConfiguration);
if(config.load()) {
logger.info("Config loaded, proceeding.");
} else {
logger.error("Failed to load configuration. Stopping process.");
Runtime.getRuntime().exit(0);
}
2022-03-24 04:28:51 +00:00
//Registers the stop() function if the program is stopped.
logger.info("Registering shutdown hook.");
Runtime.getRuntime().addShutdownHook(new Thread(this::stop));
2022-03-24 04:28:51 +00:00
//We have the prefix as a static thing that can be referenced anywhere, this is for simplicity.
2022-03-24 04:28:51 +00:00
//Initializes database and loads credentials.
2022-03-24 04:10:50 +00:00
database = config.createDb();
2022-03-26 05:04:24 +00:00
serverManager = new ServerManager();
//Makes our JDA instance.
startDiscord();
}
2022-03-24 04:28:51 +00:00
/**
* Ran on program shutdown.
*/
public void stop() {
2022-03-29 19:59:26 +00:00
EmbedBuilder build = new EmbedBuilder()
.setColor(EmbedUI.FAILURE)
.setFooter(EmbedUI.BRAND)
.setTimestamp(ZonedDateTime.now())
.setTitle("Offline")
.setDescription("Shutdown SIGINT Received.");
JDA.getTextChannelById(config.getLogChannel()).sendMessageEmbeds(build.build()).queue();
2022-03-28 19:38:25 +00:00
if(database.saveServerInformation()) {
info("Successfully saved server information. Shutting down peacefully.");
} else {
for(int i = 0; i < 15; i++) {
error("FAILED TO SAVE SERVER INFORMATION.");
}
}
}
2022-03-24 04:28:51 +00:00
/**
* Starts a JDA Instance.
*/
public void startDiscord() {
2022-03-23 20:39:52 +00:00
try {
JDA = JDABuilder.create(config.getToken(), GatewayIntent.GUILD_MEMBERS,
GatewayIntent.GUILD_MESSAGES,
2022-03-30 04:04:40 +00:00
GatewayIntent.DIRECT_MESSAGES, GatewayIntent.GUILD_PRESENCES, GatewayIntent.GUILD_VOICE_STATES)
2022-03-23 20:39:52 +00:00
.setChunkingFilter(ChunkingFilter.ALL)
.setMemberCachePolicy(MemberCachePolicy.ALL)
2022-03-30 04:04:40 +00:00
.disableCache(CacheFlag.EMOTE)
2022-03-23 20:39:52 +00:00
.setActivity(Activity.of(Activity.ActivityType.valueOf(config.getActivityType()), config.getActivityMsg()))
.setStatus(OnlineStatus.valueOf(config.getStatusType()))
2022-03-24 04:10:50 +00:00
.addEventListeners(new MainListener()).build().awaitReady();
2022-03-23 20:39:52 +00:00
} catch(Exception ex) {
error("Initialization broke...");
ex.printStackTrace();
2022-03-24 04:10:50 +00:00
return;
2022-03-23 20:39:52 +00:00
}
registerAllCommands();
info("Loaded " + activeCommands.size() + " commands.");
2022-03-28 19:42:48 +00:00
EmbedBuilder eb = new EmbedBuilder()
.setColor(EmbedUI.SUCCESS)
.setAuthor("Kiafumi", null, Kiafumi.JDA.getSelfUser().getAvatarUrl())
.setTitle("Online")
2022-03-28 19:42:48 +00:00
.setFooter("Created by Oko, Laika, and Tiddy")
.setTimestamp(ZonedDateTime.now());
JDA.getTextChannelById(config.getLogChannel()).sendMessageEmbeds(eb.build()).queue();
}
/**
* Quick method to register commands in all servers.
*/
private void registerAllCommands() {
2022-03-29 19:59:26 +00:00
//Registers our slash commands
for(Guild guild : JDA.getGuilds()) {
registerForGuild(guild);
}
2022-03-29 19:59:26 +00:00
//Registers the event listeners for those commands.
for(CommandClass cmd : activeCommands) {
JDA.addEventListener(cmd);
}
}
/**
* Registers all bot commands with the guild provided
* @param guild - guild to have commands provided to
*/
public void registerForGuild(Guild guild) {
2022-04-04 07:27:20 +00:00
info("Registering commands for Guild[" + guild.getId() + "]");
int i = 0;
for(CommandClass cmd : activeCommands) {
for(CommandInfo ci : cmd.getSlashCommandInfo()) {
CommandCreateAction cca = guild.upsertCommand(ci.getName(), ci.getDescription());
i++;
if(ci.hasSubCommands()) {
for (String name : ci.getSubCommands().keySet()) {
CommandInfo si = ci.getSubCommands().get(name);
SubcommandData sd = new SubcommandData(si.getName(), si.getDescription());
for (String option : si.getOptions().keySet()) {
sd.addOption(si.getOptions().get(option), option, si.getOptionDescriptions().get(option), si.getOptionRequirements().get(option));
}
cca.addSubcommands(sd);
}
}
if(ci.hasOptions()) {
for(String name : ci.getOptions().keySet()) {
//Any intelligent IDE will rage about the option not being used, it's added to the action then executed later, DO not edit this (please).
cca.addOption(ci.getOptions().get(name), name, ci.getOptionDescriptions().get(name), ci.getOptionRequirements().get(name));
}
}
//Push w/ modifications.
2022-04-04 07:27:20 +00:00
//commented for spam sake info("Command: " + ci.getName() + " registration on " + guild.getId() + " completed.");
2022-04-01 05:45:26 +00:00
try {
cca.queue();
} catch (Exception ex) {
//Only time this *should* occur is in the event of a server not having the proper scope.
error("Failed to queue command for RestAction, not printing stack to avoid console spam.");
}
}
}
2022-04-04 07:27:20 +00:00
info("Registered " + i + " commands. On Guild[" + guild.getId() + "] \uD83D\uDC4D -> \uD83D\uDCA5");
}
/*
Static logger info reference.
*/
public static void info(String str) {
instance.logger.info(str);
}
/*
Static Logger Error reference.
*/
public static void error(String str) {
instance.logger.error(str);
}
2022-03-24 04:10:50 +00:00
2022-03-24 04:28:51 +00:00
//Gets the active database.
2022-03-24 04:10:50 +00:00
public KiafumiDB getDatabase() { return database; }
2022-03-26 05:04:24 +00:00
//Gets active ServerManager
public ServerManager getServerManager() { return serverManager; }
2022-04-04 07:27:20 +00:00
}