Skip to content

Commit

Permalink
Complete refactor of the bot
Browse files Browse the repository at this point in the history
- update dependencies
- collect all environment variables for ease of maintenance
- update slash commands
  • Loading branch information
Big-Iron-Cheems authored and MineGame159 committed Jan 9, 2024
1 parent c85e3db commit c2e81c7
Show file tree
Hide file tree
Showing 18 changed files with 86 additions and 87 deletions.
6 changes: 3 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ repositories {
}

dependencies {
implementation "net.dv8tion:JDA:5.0.0-beta.6"
implementation "com.konghq:unirest-java:3.14.2:standalone"
implementation "ch.qos.logback:logback-classic:1.4.6"
implementation "net.dv8tion:JDA:5.0.0-beta.19"
implementation "com.konghq:unirest-java:3.14.5:standalone"
implementation "ch.qos.logback:logback-classic:1.4.14"
}

tasks.withType(JavaCompile).configureEach {
Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
18 changes: 18 additions & 0 deletions src/main/java/org/meteordev/meteorbot/Env.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.meteordev.meteorbot;

public enum Env {
DISCORD_TOKEN("DISCORD_TOKEN"),
API_BASE("API_BASE"),
BACKEND_TOKEN("BACKEND_TOKEN"),
GUILD_ID("GUILD_ID"),
COPE_NN_ID("COPE_NN_ID"),
MEMBER_COUNT_ID("MEMBER_COUNT_ID"),
DOWNLOAD_COUNT_ID("DOWNLOAD_COUNT_ID"),
UPTIME_URL("UPTIME_URL");

public final String value;

Env(String key) {
this.value = System.getenv(key);
}
}
20 changes: 8 additions & 12 deletions src/main/java/org/meteordev/meteorbot/InfoChannels.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,44 +7,40 @@

import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import java.util.function.LongSupplier;

public class InfoChannels extends ListenerAdapter {
private static final String GUILD_ID = System.getenv("GUILD_ID");
private static final String MEMBER_COUNT_ID = System.getenv("MEMBER_COUNT_ID");
private static final String DOWNLOAD_COUNT_ID = System.getenv("DOWNLOAD_COUNT_ID");

private static final int UPDATE_PERIOD = 6;
private static int delay;

@Override
public void onReady(ReadyEvent event) {
Guild guild = event.getJDA().getGuildById(GUILD_ID);
Guild guild = event.getJDA().getGuildById(Env.GUILD_ID.value);
if (guild == null) {
MeteorBot.LOG.warn("Failed to fetch guild when initialising info channels.");
return;
}

if (MEMBER_COUNT_ID == null || DOWNLOAD_COUNT_ID == null) {
if (Env.MEMBER_COUNT_ID.value == null || Env.DOWNLOAD_COUNT_ID.value == null) {
MeteorBot.LOG.warn("Must define info channel id's for them to function.");
return;
}

VoiceChannel memberCount = guild.getVoiceChannelById(MEMBER_COUNT_ID);
VoiceChannel downloads = guild.getVoiceChannelById(DOWNLOAD_COUNT_ID);
VoiceChannel memberCount = guild.getVoiceChannelById(Env.MEMBER_COUNT_ID.value);
VoiceChannel downloads = guild.getVoiceChannelById(Env.DOWNLOAD_COUNT_ID.value);
if (memberCount == null || downloads == null) {
MeteorBot.LOG.warn("Failed to fetch channels when initialising info channels.");
return;
}

updateChannel(downloads, () -> Utils.apiGet("stats").asJson().getBody().getObject().getLong("downloads"));
updateChannel(memberCount, () -> (long) MeteorBot.SERVER.getMemberCount());
updateChannel(memberCount, guild::getMemberCount);
}

private static void updateChannel(VoiceChannel channel, Supplier<Long> supplier) {
private static void updateChannel(VoiceChannel channel, LongSupplier supplier) {
Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> {
String name = channel.getName();
name = name.substring(0, name.lastIndexOf(':') + 1) + " " + Utils.formatLong(supplier.get());
name = "%s %s".formatted(name.substring(0, name.lastIndexOf(':') + 1), Utils.formatLong(supplier.getAsLong()));
channel.getManager().setName(name).complete();
}, delay, UPDATE_PERIOD, TimeUnit.MINUTES);

Expand Down
39 changes: 16 additions & 23 deletions src/main/java/org/meteordev/meteorbot/MeteorBot.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,15 @@
import org.slf4j.Logger;

public class MeteorBot extends ListenerAdapter {
private static final String[] HELLOS = { "hi", "hello", "howdy", "bonjour", "ciao", "hej", "hola", "yo" };
private static final String[] HELLOS = {"hi", "hello", "howdy", "bonjour", "ciao", "hej", "hola", "yo"};

public static final Logger LOG = JDALogger.getLog("Meteor Bot");
public static final String BACKEND_TOKEN = System.getenv("BACKEND_TOKEN");

public static JDA BOT;
public static Guild SERVER;
public static RichCustomEmoji COPE_NN;
private Guild server;
private RichCustomEmoji copeEmoji;

public static void main(String[] args) {
String token = System.getenv("DISCORD_TOKEN");

String token = Env.DISCORD_TOKEN.value;
if (token == null) {
MeteorBot.LOG.error("Must specify discord bot token.");
return;
Expand All @@ -46,51 +43,47 @@ public static void main(String[] args) {

@Override
public void onReady(ReadyEvent event) {
BOT = event.getJDA();
BOT.getPresence().setActivity(Activity.playing("Meteor Client"));
JDA bot = event.getJDA();
bot.getPresence().setActivity(Activity.playing("Meteor Client"));

SERVER = BOT.getGuildById(System.getenv("GUILD_ID"));
if (SERVER == null) {
server = bot.getGuildById(Env.GUILD_ID.value);
if (server == null) {
MeteorBot.LOG.error("Couldn't find the specified server.");
System.exit(0);
System.exit(1);
}

COPE_NN = SERVER.getEmojiById(System.getenv("COPE_NN_ID"));
copeEmoji = server.getEmojiById(Env.COPE_NN_ID.value);

LOG.info("Meteor Bot started");
}

@Override
public void onMessageReceived(MessageReceivedEvent event) {
if (!event.isFromType(ChannelType.TEXT) || !event.isFromGuild() || !event.getGuild().equals(SERVER)) return;
if (!event.isFromType(ChannelType.TEXT) || !event.isFromGuild() || !event.getGuild().equals(server)) return;

String content = event.getMessage().getContentRaw();
if (!content.contains(BOT.getSelfUser().getAsMention())) return;

boolean found = false;
if (!content.contains(event.getJDA().getSelfUser().getAsMention())) return;

for (String hello : HELLOS) {
if (content.toLowerCase().contains(hello)) {
found = true;
event.getMessage().reply(hello + " :)").queue();
return;
}
}

if (!found) {
event.getMessage().addReaction(content.toLowerCase().contains("cope") ? COPE_NN : Emoji.fromUnicode("\uD83D\uDC4B")).queue();
}
event.getMessage().addReaction(content.toLowerCase().contains("cope") ? copeEmoji : Emoji.fromUnicode("\uD83D\uDC4B")).queue();
}

@Override
public void onGuildMemberJoin(@NotNull GuildMemberJoinEvent event) {
if (BACKEND_TOKEN == null) return;
if (Env.BACKEND_TOKEN.value == null) return;

Utils.apiPost("discord/userJoined").queryString("id", event.getMember().getId()).asEmpty();
}

@Override
public void onGuildMemberRemove(@NotNull GuildMemberRemoveEvent event) {
if (BACKEND_TOKEN == null) return;
if (Env.BACKEND_TOKEN.value == null) return;

Utils.apiPost("discord/userLeft").asEmpty();
}
Expand Down
8 changes: 3 additions & 5 deletions src/main/java/org/meteordev/meteorbot/Uptime.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,16 @@
import java.util.concurrent.TimeUnit;

public class Uptime extends ListenerAdapter {
private static final String UPTIME_URL = System.getenv("UPTIME_URL");

@Override
public void onReady(@NotNull ReadyEvent event) {
if (UPTIME_URL == null) {
if (Env.UPTIME_URL.value == null) {
MeteorBot.LOG.warn("Uptime URL not configured, uptime requests will not be made");
return;
}

Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> {
String url = UPTIME_URL;
if (url.endsWith("ping=")) url += MeteorBot.BOT.getGatewayPing();
String url = Env.UPTIME_URL.value;
if (url.endsWith("ping=")) url += event.getJDA().getGatewayPing();

Unirest.get(url).asEmpty();
}, 0, 60, TimeUnit.SECONDS);
Expand Down
21 changes: 8 additions & 13 deletions src/main/java/org/meteordev/meteorbot/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,17 @@
import java.awt.*;
import java.text.NumberFormat;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Utils {
public abstract class Utils {
private static final Pattern TIME_PATTERN = Pattern.compile("^(\\d+)(ms|s|m|h|d|w)$");
public static final Color COLOR = new Color(145, 61, 226);
private static final Color COLOR = new Color(145, 61, 226);
private static final String[] SUFFIXES = {"k", "m", "b", "t"};

private static final List<String> suffixes = List.of("k", "m", "b", "t");

private static final String API_BASE = System.getenv("API_BASE");
private static final String BACKEND_TOKEN = System.getenv("BACKEND_TOKEN");
private Utils() {
}

public static long parseAmount(String parse) {
Matcher matcher = TIME_PATTERN.matcher(parse);
Expand Down Expand Up @@ -64,7 +62,6 @@ public static String unitToString(ChronoUnit unit) {
};
}


public static String formatLong(long value) {
String formatted = NumberFormat.getNumberInstance(Locale.UK).format(value);
String first = formatted, second = "", suffix = "";
Expand All @@ -73,7 +70,7 @@ public static String formatLong(long value) {
int firstComma = formatted.indexOf(',');
first = formatted.substring(0, firstComma);
second = "." + formatted.substring(firstComma + 1, firstComma + 3);
suffix = suffixes.get(formatted.replaceAll("[^\",\"]", "").length() - 1);
suffix = SUFFIXES[formatted.replaceAll("[^\",\"]", "").length() - 1];
}

return first + second + suffix;
Expand All @@ -88,12 +85,10 @@ public static EmbedBuilder embed(String format, Object... args) {
}

public static GetRequest apiGet(String path) {
return Unirest.get(API_BASE + path);
return Unirest.get(Env.API_BASE.value + path);
}

public static HttpRequestWithBody apiPost(String path) {
HttpRequestWithBody req = Unirest.post(API_BASE + path);
req.header("Authorization", BACKEND_TOKEN);
return req;
return Unirest.post(Env.API_BASE.value + path).header("Authorization", Env.BACKEND_TOKEN.value);
}
}
7 changes: 3 additions & 4 deletions src/main/java/org/meteordev/meteorbot/command/Command.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@
public abstract class Command {
public final String name, description;

public Command(String name, String description) {
protected Command(String name, String description) {
this.name = name;
this.description = description;
}

public abstract SlashCommandData build(SlashCommandData data);

public abstract void run(SlashCommandInteractionEvent event);

public static Member parseMember(SlashCommandInteractionEvent event) {
Expand All @@ -24,9 +25,7 @@ public static Member parseMember(SlashCommandInteractionEvent event) {
}

Member member = memberOption.getAsMember();
if (member == null) {
event.reply("Couldn't find that member.").setEphemeral(true).queue();
}
if (member == null) event.reply("Couldn't find that member.").setEphemeral(true).queue();

return member;
}
Expand Down
17 changes: 9 additions & 8 deletions src/main/java/org/meteordev/meteorbot/command/Commands.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
import net.dv8tion.jda.internal.interactions.CommandDataImpl;
import org.jetbrains.annotations.NotNull;
import org.meteordev.meteorbot.Env;
import org.meteordev.meteorbot.MeteorBot;
import org.meteordev.meteorbot.command.commands.LinkCommand;
import org.meteordev.meteorbot.command.commands.StatsCommand;
Expand All @@ -25,10 +26,10 @@
import java.util.Map;

public class Commands extends ListenerAdapter {
private static final Map<String, Command> commands = new HashMap<>();
private static final Map<String, Command> BOT_COMMANDS = new HashMap<>();

public static void add(Command command) {
commands.put(command.name, command);
BOT_COMMANDS.put(command.name, command);
}

@Override
Expand All @@ -46,28 +47,28 @@ public void onReady(@NotNull ReadyEvent event) {
add(new CapyCommand());
add(new CatCommand());
add(new DogCommand());
add(new MonkyCommand());
add(new MonkeyCommand());
add(new PandaCommand());

add(new StatsCommand());
if (MeteorBot.BACKEND_TOKEN != null) {
if (Env.BACKEND_TOKEN.value != null) {
add(new LinkCommand());
}

List<CommandData> commandData = new ArrayList<>();

for (Command command : commands.values()) {
for (Command command : BOT_COMMANDS.values()) {
commandData.add(command.build(new CommandDataImpl(command.name, command.description)));
}

MeteorBot.BOT.updateCommands().addCommands(commandData).complete();
event.getJDA().updateCommands().addCommands(commandData).complete();

MeteorBot.LOG.info("Loaded {} commands", commands.size());
MeteorBot.LOG.info("Loaded {} commands", BOT_COMMANDS.size());
}

@Override
public void onSlashCommandInteraction(@NotNull SlashCommandInteractionEvent event) {
Command command = commands.get(event.getName());
Command command = BOT_COMMANDS.get(event.getName());
if (command == null) return;

command.run(event);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import java.util.regex.Pattern;

public class StatsCommand extends Command {
private static final Pattern DATE_PATTERN = Pattern.compile("[0-9]{2}-[0-9]{2}-[0-9]{4}");
private static final Pattern DATE_PATTERN = Pattern.compile("\\d{2}-\\d{2}-\\d{4}");

public StatsCommand() {
super("stats", "Shows various stats about Meteor.");
Expand All @@ -32,11 +32,10 @@ public void run(SlashCommandInteractionEvent event) {

if (option != null && DATE_PATTERN.matcher(option.getAsString()).matches()) {
date = option.getAsString();
}
else {
} else {
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
calendar.setTime(new Date());
date = String.format("%02d-%02d-%d", calendar.get(Calendar.DATE), calendar.get(Calendar.MONTH) + 1, calendar.get(Calendar.YEAR));
date = "%02d-%02d-%d".formatted(calendar.get(Calendar.DATE), calendar.get(Calendar.MONTH) + 1, calendar.get(Calendar.YEAR));
}

if (date == null) {
Expand All @@ -53,6 +52,6 @@ public void run(SlashCommandInteractionEvent event) {

int joins = json.getInt("joins"), leaves = json.getInt("leaves");

event.replyEmbeds(Utils.embed("**Date**: " + json.getString("date") + "\n**Joins**: " + joins + "\n**Leaves**: " + leaves + "\n**Gained**: " + (joins - leaves) + "\n**Downloads**: " + json.getInt("downloads")).build()).queue();
event.replyEmbeds(Utils.embed("**Date**: %s\n**Joins**: %d\n**Leaves**: %d\n**Gained**: %d\n**Downloads**: %d".formatted(json.getString("date"), joins, leaves, joins - leaves, json.getInt("downloads"))).build()).queue();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ public class FaqCommand extends HelpCommand {
public FaqCommand() {
super(
"faq",
"tells someone to read the faq",
"Tells someone to read the faq",
"The FAQ answers your question, please read it.",
Button.link("https://meteorclient.com/faq", "FAQ")
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
import org.meteordev.meteorbot.command.Command;

public abstract class HelpCommand extends Command {
protected ItemComponent[] components;
protected final ItemComponent[] components;
protected final String message;

public HelpCommand(String name, String description, String message, ItemComponent... components) {
protected HelpCommand(String name, String description, String message, ItemComponent... components) {
super(name, description);

this.message = message;
Expand Down
Loading

0 comments on commit c2e81c7

Please sign in to comment.