diff --git a/TODO.md b/TODO.md index 4155dab..826bb2f 100644 --- a/TODO.md +++ b/TODO.md @@ -5,11 +5,8 @@ This file is basically a checklist of things to do in the codebase. ## Chores * Add comments -* Role mention rendering * fix possible race condition so that the bot doesn't start with nonexistent ids ## Implement -* Performance improvements, don't know how yet -* rewrite using https://github.com/discord-jda/JDA because discord4j is ass -* make a waypoint class for the xearos waypoint parser \ No newline at end of file +* Performance improvements, don't know how yet \ No newline at end of file diff --git a/build.gradle b/build.gradle index 84998d0..a783406 100644 --- a/build.gradle +++ b/build.gradle @@ -50,8 +50,12 @@ dependencies { include "com.discord4j:discord4j-core:3.2.7" */ - extraLibs group: 'com.discord4j', name: 'discord4j-core', version: '3.2.7' + extraLibs (group: 'net.dv8tion', name: 'JDA', version: '5.6.1') { + exclude module: 'opus-java' // required for encoding audio into opus, not needed if audio is already provided in opus encoding + exclude module: 'tink' // required for encrypting and decrypting audio + } extraLibs group: 'com.github.zafarkhaja', name: 'java-semver', version: '0.10.2' + extraLibs group: 'com.google.code.findbugs', name: 'jsr305', version: '3.0.2' configurations.implementation.extendsFrom(configurations.extraLibs) } diff --git a/docs/md/docs.md b/docs/md/docs.md index 1248c7e..df7afff 100644 --- a/docs/md/docs.md +++ b/docs/md/docs.md @@ -54,7 +54,6 @@ messages.server.starting.allowed=true | functions.promotions.enabled | true | false | are tips and hints/promotion embeds allowed to be sent to Discord | | functions.bot.enabled | true | false | is two-way chat (the bot) enabled? | | functions.bot.token | "TOKEN" | (blank string) | bot token | -| functions.bot.prefix | $ | $ | bot command prefix | | functions.update | true | false | auto check for updates | | webhook.url | | (blank string) | url of webhook | | messages.server.starting | The server is starting! | messages.server.starting | start message | @@ -65,7 +64,6 @@ messages.server.starting.allowed=true | messages.server.stopped.allowed | true | false | stop message allowed? | | messages.server.started.allowed | true | false | opened/fully started message | | messages.server.stopping.allowed | true | false | stopping message allowed? | -| messages.server.game.allowed | true | false | default leave/join, advancement and death messages allowed? (currently not functional) | 1. default, as in it's the value generated with the file 2. fallback, as in if the key isn't found, this value will be used instead @@ -80,6 +78,16 @@ Out-of-Character messages. Ending a message with double slashes (`//`) will tell Send a message in the desired Discord channel, and make that message appear in game! +### Utility Commands + +Utility slash commands that you can use to do things like get player listing right from discord or get the current time in the server. Current commands: + +* `time`: get the current time and overworld weather in the server; +* `mods`: get a list of both-sided-mods/plugins; +* `list`: get a list of currently online players; +* `stats`: get some technical details of the server; +* `about`: get some info about the mod. + ### Xaero's World Map support [Xaero's World Map](https://modrinth.com/mod/xaeros-world-map) has a feature, with which you can share waypoints in chat for everyone to save and add. This will be converted to readable coordinates and dimension data when sent to Discord! diff --git a/docs/res/works.png b/docs/res/works.png new file mode 100644 index 0000000..6b48f1f Binary files /dev/null and b/docs/res/works.png differ diff --git a/gradle.properties b/gradle.properties index 5f350df..afa06d6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,7 +9,7 @@ yarn_mappings=1.20.4+build.3 loader_version=0.16.10 # Mod Properties -mod_version=0.3.1-alpha.6+fabric +mod_version=1.0.0+fabric maven_group=com.github.pinmacaroon.dchook archives_base_name=dchook diff --git a/src/main/java/com/github/pinmacaroon/dchook/Hook.java b/src/main/java/com/github/pinmacaroon/dchook/Hook.java index cd16848..97e5074 100644 --- a/src/main/java/com/github/pinmacaroon/dchook/Hook.java +++ b/src/main/java/com/github/pinmacaroon/dchook/Hook.java @@ -24,100 +24,98 @@ public class Hook implements DedicatedServerModInitializer { - public static final String MOD_ID = "dchook"; - public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); - public static final HttpClient HTTPCLIENT = HttpClient.newHttpClient(); - public static final Gson GSON = new GsonBuilder() - .setPrettyPrinting() - .create(); - public static final Version VERSION = new Version.Builder() - .setMajorVersion(0) - .setMinorVersion(3) - .setPatchVersion(2) + public static final String MOD_ID = "dchook"; + public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); + public static final HttpClient HTTPCLIENT = HttpClient.newHttpClient(); + public static final Gson GSON = new GsonBuilder() + .setPrettyPrinting() + .create(); + public static final Version VERSION = new Version.Builder() + .setMajorVersion(1) + .setMinorVersion(0) + .setPatchVersion(0) .setBuildMetadata("fabric") - .setPreReleaseVersion("alpha", "6") + //.setPreReleaseVersion("alpha", "2") .build(); - public static final String DOCS_URL = "https://modrinth.com/mod/dchook"; - public static final Random RANDOM = new Random(Instant.now().getEpochSecond()); - @SuppressWarnings("RegExpRedundantEscape") + public static final String DOCS_URL = "https://modrinth.com/mod/dchook"; + public static final Random RANDOM = new Random(Instant.now().getEpochSecond()); + @SuppressWarnings("RegExpRedundantEscape") public static final Pattern WEBHOOK_URL_PATTERN = Pattern.compile( - "^https:\\/\\/(ptb\\.|canary\\.)?discord\\.com\\/api\\/webhooks\\/\\d+\\/.+$" - ); + "^https:\\/\\/(ptb\\.|canary\\.)?discord\\.com\\/api\\/webhooks\\/\\d+\\/.+$" + ); - public static volatile Bot BOT; - public static Thread BOT_THREAD; + public static volatile Bot BOT; - private static MinecraftServer MINECRAFT_SERVER; + private static MinecraftServer MINECRAFT_SERVER; - public static MinecraftServer getMinecraftServer() { - return MINECRAFT_SERVER; - } + public static MinecraftServer getGameServer() { + return MINECRAFT_SERVER; + } - public static void setMinecraftServer(MinecraftServer minecraftServer) { - MINECRAFT_SERVER = minecraftServer; - } + public static void setMinecraftServer(MinecraftServer minecraftServer) { + MINECRAFT_SERVER = minecraftServer; + } - @Override - public void onInitializeServer() { - ModConfigs.registerConfigs(); + @Override + public void onInitializeServer() { + ModConfigs.registerConfigs(); - if(!ModConfigs.FUNCTIONS_MODENABLED){ - LOGGER.error("hook mod was explicitly told to not operate!"); - return; - } + if(!ModConfigs.FUNCTIONS_MODENABLED){ + LOGGER.error("hook mod was explicitly told to not operate!"); + return; + } - if(!WEBHOOK_URL_PATTERN.matcher(ModConfigs.WEBHOOK_URL).find()){ - LOGGER.error("webhook url was not a valid discord api endpoint, thus the mod cant operate!"); - return; - } + if(!WEBHOOK_URL_PATTERN.matcher(ModConfigs.WEBHOOK_URL).find()){ + LOGGER.error("webhook url was not a valid discord api endpoint, thus the mod cant operate!"); + return; + } - if(ModConfigs.FUNCTIONS_BOT_ENABLED){ - try { - BOT = new Bot(ModConfigs.FUNCTIONS_BOT_TOKEN, ModConfigs.FUNCTIONS_BOT_PREFIX.toCharArray()[0]); - } catch (Exception e){ - LOGGER.error("couldn't initialise bot, two way chat disabled"); + if(ModConfigs.FUNCTIONS_BOT_ENABLED){ + try { + BOT = new Bot(ModConfigs.FUNCTIONS_BOT_TOKEN); + } catch (Exception e){ + LOGGER.error("couldn't initialise bot, two way chat disabled"); LOGGER.error("{}:{}", e.getClass().getName(), e.getMessage()); - return; - } - } - - try { - HttpRequest get_webhook = HttpRequest.newBuilder() - .GET() - .uri(URI.create(ModConfigs.WEBHOOK_URL)) - .build(); - - HttpResponse response = HTTPCLIENT.send(get_webhook, HttpResponse.BodyHandlers.ofString()); - int status = response.statusCode(); - JsonObject body = JsonParser.parseString(response.body()).getAsJsonObject(); - if(status != 200){ - LOGGER.error( - "the webhook was not found or couldn't reach discord servers! discord said: '{}'", - body.get("message").getAsString() - ); - return; - } - Thread bot_rutime_thread = new Thread(() -> { + return; + } + } + + try { + HttpRequest get_webhook = HttpRequest.newBuilder() + .GET() + .uri(URI.create(ModConfigs.WEBHOOK_URL)) + .build(); + + HttpResponse response = HTTPCLIENT.send(get_webhook, HttpResponse.BodyHandlers.ofString()); + int status = response.statusCode(); + JsonObject body = JsonParser.parseString(response.body()).getAsJsonObject(); + if(status != 200){ + LOGGER.error( + "the webhook was not found or couldn't reach discord servers! discord said: '{}'", + body.get("message").getAsString() + ); + return; + } + Thread bot_rutime_thread = new Thread(() -> { while (BOT == null) { Thread.onSpinWait(); } - BOT.setGUILD_ID(body.get("guild_id").getAsLong()); - BOT.setCHANNEL_ID(body.get("channel_id").getAsLong()); - BOT_THREAD = BOT.start(); - }); - bot_rutime_thread.start(); - } catch (Exception e) { - LOGGER.error("{}:{}", e.getClass().getName(), e.getMessage()); - throw new RuntimeException(e); + BOT.setGUILD_ID(body.get("guild_id").getAsLong()); + BOT.setCHANNEL_ID(body.get("channel_id").getAsLong()); + }); + bot_rutime_thread.start(); + } catch (Exception e) { + LOGGER.error("{}:{}", e.getClass().getName(), e.getMessage()); + throw new RuntimeException(e); } - if(ModConfigs.FUNCTIONS_UPDATE) VersionChecker.checkVersion(); + if(ModConfigs.FUNCTIONS_UPDATE) VersionChecker.checkVersion(); - LOGGER.info("all checks succeeded, starting webhook managing! version: {}", VERSION); - if(!ModConfigs.FUNCTIONS_PROMOTIONS_ENABLED){ - LOGGER.warn("promotions were disabled by config. please consider turning them back on to support the mod!"); - } + LOGGER.info("all checks succeeded, starting webhook managing! version: {}", VERSION); + if(!ModConfigs.FUNCTIONS_PROMOTIONS_ENABLED){ + LOGGER.warn("promotions were disabled by config. please consider turning them back on to support the mod!"); + } - EventListeners.registerEventListeners(); - } + EventListeners.registerEventListeners(); + } } \ No newline at end of file diff --git a/src/main/java/com/github/pinmacaroon/dchook/bot/Bot.java b/src/main/java/com/github/pinmacaroon/dchook/bot/Bot.java index 30e8172..95a1549 100644 --- a/src/main/java/com/github/pinmacaroon/dchook/bot/Bot.java +++ b/src/main/java/com/github/pinmacaroon/dchook/bot/Bot.java @@ -1,82 +1,100 @@ package com.github.pinmacaroon.dchook.bot; -import discord4j.core.DiscordClient; -import discord4j.core.GatewayDiscordClient; -import discord4j.core.event.domain.lifecycle.ReadyEvent; -import discord4j.core.event.domain.message.MessageCreateEvent; -import discord4j.core.object.entity.User; -import org.jetbrains.annotations.Nullable; -import reactor.core.publisher.Mono; +import com.github.pinmacaroon.dchook.bot.event.MessageReceivedListener; +import com.github.pinmacaroon.dchook.bot.event.ReadyEventListener; +import com.github.pinmacaroon.dchook.bot.event.SlashCommandInteractionListener; +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.JDABuilder; +import net.dv8tion.jda.api.entities.Activity; +import net.dv8tion.jda.api.entities.SelfUser; +import net.dv8tion.jda.api.interactions.IntegrationType; +import net.dv8tion.jda.api.interactions.InteractionContextType; +import net.dv8tion.jda.api.interactions.commands.OptionType; +import net.dv8tion.jda.api.interactions.commands.build.Commands; +import net.dv8tion.jda.api.interactions.commands.build.OptionData; +import net.dv8tion.jda.api.requests.GatewayIntent; +import net.dv8tion.jda.api.requests.restaction.CommandListUpdateAction; -import java.text.MessageFormat; +import java.util.EnumSet; public class Bot { - private final DiscordClient CLIENT; - private GatewayDiscordClient GATEWAY_CLIENT; + private final JDA JDA; private long GUILD_ID; private long CHANNEL_ID; - private final char PREFIX; - public Bot(String token, char prefix){ - this.CLIENT = DiscordClient.create(token); - this.PREFIX = prefix; - } + public Bot(String token) { + net.dv8tion.jda.api.JDA jda; + jda = JDABuilder.createLight(token, EnumSet.of(GatewayIntent.GUILD_MESSAGES, GatewayIntent.MESSAGE_CONTENT)) + .addEventListeners(new ReadyEventListener(this)) + .addEventListeners(new MessageReceivedListener(this)) + .addEventListeners(new SlashCommandInteractionListener(this)) + .build(); + try { + jda.awaitReady(); + } catch (InterruptedException e) { + this.JDA = null; + return; + } + this.JDA = jda; - public Bot(String token){ - this.CLIENT = DiscordClient.create(token); - this.PREFIX = '$'; - } + this.JDA.getPresence().setActivity(Activity.of(Activity.ActivityType.WATCHING, + "over this server (literally 1984)")); + + CommandListUpdateAction commands = this.JDA.updateCommands().addCommands( + Commands.slash("time", "Check time and weather in the overworld") + .addOptions(new OptionData( + OptionType.BOOLEAN, "ephemeral", "Should the message be only visible to you?" + ).setRequired(false) + ) + .setContexts(InteractionContextType.GUILD) + .setIntegrationTypes(IntegrationType.GUILD_INSTALL), + + Commands.slash("mods", "Check what mods are in the server, if any") + .addOptions(new OptionData( + OptionType.BOOLEAN, "ephemeral", "Should the message be only visible to you?" + ).setRequired(false) + ) + .setContexts(InteractionContextType.GUILD) + .setIntegrationTypes(IntegrationType.GUILD_INSTALL), + + Commands.slash("list", "List online players") + .addOptions(new OptionData( + OptionType.BOOLEAN, "ephemeral", "Should the message be only visible to you?" + ).setRequired(false) + ) + .setContexts(InteractionContextType.GUILD) + .setIntegrationTypes(IntegrationType.GUILD_INSTALL), - public DiscordClient getCLIENT() { - return CLIENT; + Commands.slash("stat", "See some stats about the server") + .addOptions(new OptionData( + OptionType.BOOLEAN, "ephemeral", "Should the message be only visible to you?" + ).setRequired(false) + ) + .setContexts(InteractionContextType.GUILD) + .setIntegrationTypes(IntegrationType.GUILD_INSTALL), + + Commands.slash("about", "Get some info about the integration") + .addOptions(new OptionData( + OptionType.BOOLEAN, "ephemeral", "Should the message be only visible to you?" + ).setRequired(false) + ) + .setContexts(InteractionContextType.GUILD) + .setIntegrationTypes(IntegrationType.GUILD_INSTALL) + ); + + commands.queue(); } - @Nullable - public Thread start(){ - //TODO fix possible race condition so that the bot doesn't start with nonexistent ids - /* - if(GUILD_ID == 0){ - return null; - } - if(CHANNEL_ID == 0){ - return null; - } - */ - Thread lifecyclethread = new Thread(() -> { - Mono login = this.CLIENT.withGateway( - (GatewayDiscordClient gateway) -> { - this.GATEWAY_CLIENT = gateway; - System.out.println("gateway login"); - Mono ready = gateway.on(ReadyEvent.class, readyEvent -> - Mono.fromRunnable(() -> { - final User user = readyEvent.getSelf(); - //noinspection deprecation - System.out.println(MessageFormat.format( - "logged bot in as {0}#{1}", - user.getUsername(), - user.getDiscriminator() - )); - }) - ).then(); - - Mono message = gateway.on(MessageCreateEvent.class, messageCreateEvent -> - Mono.fromRunnable(() -> Messenger.handeMessage(messageCreateEvent, this)) - ).then(); - return ready.and(message); - } - ); - login.block(); - }); - lifecyclethread.start(); - return lifecyclethread; + public JDA getJDA() { + return JDA; } - public void stop(){ - GATEWAY_CLIENT.logout().block(); + public void stop() { + this.JDA.shutdown(); } - public GatewayDiscordClient getGATEWAY_CLIENT() { - return GATEWAY_CLIENT; + public SelfUser getSelfUser() { + return this.JDA.getSelfUser(); } public long getGUILD_ID() { @@ -94,8 +112,4 @@ public long getCHANNEL_ID() { public void setCHANNEL_ID(long CHANNEL_ID) { this.CHANNEL_ID = CHANNEL_ID; } - - public char getPREFIX() { - return PREFIX; - } } diff --git a/src/main/java/com/github/pinmacaroon/dchook/bot/CommandParser.java b/src/main/java/com/github/pinmacaroon/dchook/bot/CommandParser.java index 48d214b..429f560 100644 --- a/src/main/java/com/github/pinmacaroon/dchook/bot/CommandParser.java +++ b/src/main/java/com/github/pinmacaroon/dchook/bot/CommandParser.java @@ -3,6 +3,9 @@ import java.util.ArrayList; import java.util.List; +/** + * im hella proud of this so it isn't going anywhere >:3 + */ public class CommandParser { public static List parseString(String source) { diff --git a/src/main/java/com/github/pinmacaroon/dchook/bot/Messenger.java b/src/main/java/com/github/pinmacaroon/dchook/bot/Messenger.java deleted file mode 100644 index 00e5521..0000000 --- a/src/main/java/com/github/pinmacaroon/dchook/bot/Messenger.java +++ /dev/null @@ -1,290 +0,0 @@ -package com.github.pinmacaroon.dchook.bot; - -import com.github.pinmacaroon.dchook.Hook; -import com.github.pinmacaroon.dchook.conf.ModConfigs; -import com.github.pinmacaroon.dchook.util.TimeConverter; -import discord4j.common.util.Snowflake; -import discord4j.core.event.domain.message.MessageCreateEvent; -import discord4j.core.object.entity.Message; -import discord4j.core.spec.EmbedCreateSpec; -import discord4j.discordjson.json.MessageCreateRequest; -import discord4j.rest.entity.RestChannel; -import net.fabricmc.loader.api.FabricLoader; -import net.fabricmc.loader.api.metadata.ModEnvironment; -import net.minecraft.text.MutableText; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; - -import java.io.IOException; -import java.nio.file.Files; -import java.time.Duration; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -// im not fixing this shit, this is Pandora's box, don't touch it. thanks be to the gods of Olympus for allowing this -// forsaken class to operate - -public class Messenger { - public static final Pattern MENTION_PATTERN = Pattern.compile("<(@)(\\d+)>"); - //TODO fix role pattern not working - public static final Pattern ROLE_PATTERN = Pattern.compile("<(@&)(\\d+)>"); - public static final Pattern CHANNEL_PATTERN = Pattern.compile("<(#)(\\d+)>"); - public static final Pattern EMOJI_PATTERN = Pattern.compile(""); - - public static void handeMessage(MessageCreateEvent messageCreateEvent, Bot bot) { - if (messageCreateEvent.getMessage().getUserMentions().contains(bot.getGATEWAY_CLIENT().getSelf().block())) { - RestChannel restChannel = bot.getGATEWAY_CLIENT().rest() - .getChannelById(messageCreateEvent.getMessage().getChannelId()); - restChannel.createMessage(String.format("-# Heya, my current prefix is `%s`!", - bot.getPREFIX() - ) - ).block(); - } - if (messageCreateEvent.getMessage().getContent() - .strip() - .startsWith(Character.toString(bot.getPREFIX())) - ) { - List arguments = CommandParser.parseString(messageCreateEvent.getMessage().getContent().strip()); - String prefix = Character.toString(bot.getPREFIX()); - Message message = messageCreateEvent.getMessage(); - RestChannel restChannel = bot.getGATEWAY_CLIENT().rest().getChannelById(message.getChannelId()); - - if (arguments.get(0).equals(prefix + "test")) { - long size; - try { - size = Files.walk(Hook.getMinecraftServer().getRunDirectory().toPath()) - .filter(p -> p.toFile().isFile()) - .mapToLong(p -> p.toFile().length()) - .sum()/1024/1024; - } catch (IOException e) { - size = 0L; - } - restChannel.createMessage(String.format(""" - The test was successful! `v:%s,m:%dmb/%dmb,g:%s,IP: %s:%d,s:%dmb`""", - Hook.VERSION, (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())/1024/1024, - Runtime.getRuntime().totalMemory()/1024/1024, - Hook.getMinecraftServer().getVersion(), - Hook.getMinecraftServer().getServerIp(), Hook.getMinecraftServer().getServerPort(), - size - ) - ).block(); - return; - } else if (arguments.get(0).equals(prefix + "list") || arguments.get(0).equals(prefix + "l")) { - StringBuilder player_list = new StringBuilder(); - player_list.append(""" - There are currently **%d**/%d players online:\s""".formatted( - Hook.getMinecraftServer().getPlayerManager().getCurrentPlayerCount(), - Hook.getMinecraftServer().getPlayerManager().getMaxPlayerCount() - )); - Hook.getMinecraftServer().getPlayerManager().getPlayerList().forEach( - serverPlayerEntity -> - player_list.append("`").append(serverPlayerEntity.getName().getString()).append("` ") - ); - restChannel.createMessage(player_list.toString()).block(); - return; - } else if (arguments.get(0).equals(prefix + "time") || arguments.get(0).equals(prefix + "weather")) { - String response = "The current in-game time in the overworld is **" + - TimeConverter.timeOfDayToHoursMinutes2(Hook.getMinecraftServer().getOverworld().getTimeOfDay()) + - "**! The weather is " + - ((Hook.getMinecraftServer().getOverworld().isRaining()) ? "rainy" : "clear") + - "! " + - ((Hook.getMinecraftServer().getOverworld().isThundering()) ? "It is thundering!" : ""); - restChannel.createMessage(response).block(); - return; - } else if (arguments.get(0).equals(prefix + "mods")) { - StringBuilder mod_list = new StringBuilder(); - AtomicInteger mods = new AtomicInteger(); - FabricLoader.getInstance().getAllMods().forEach(modContainer -> { - if (modContainer.getMetadata().getEnvironment() == ModEnvironment.UNIVERSAL - && !modContainer.getMetadata().getType().equals("builtin") - && !modContainer.getMetadata().getId().startsWith("fabric") - && !modContainer.getMetadata().getId().equals("mixinextras") - && modContainer.getContainingMod().isEmpty()) { - mod_list.append(modContainer.getMetadata().getName()).append(' ') - .append(modContainer.getMetadata().getVersion().getFriendlyString()).append('\n'); - mods.getAndIncrement(); - } - }); - String response; - if (mods.get() == 0) { - response = "The server currently has no required mods, you can join with a vanilla client!"; - } else { - response = "The server currently has " + mods.get() + " required mods:\n" + mod_list; - } - if (response.length() > 2000) { - response = response.substring(0, 1995) + "[...]"; - } - restChannel.createMessage(response).block(); - return; - } else if (arguments.get(0).equals(prefix + "help")) { - String response = """ - Every command needs the prefix before its name! - * `list`, aka `l`: list online players - * `time`, aka `weather`: get current overworld time and weather info - * `mods`: list all the required mods in the server (might be inaccurate) - * `test`: idk, testing command - * `skin [['avatar'|'helm'|'cube'|'body'|'bust'] ['true'|'false']]`: get the skin of \ - a given user. optional: select from a list of modes, and toggle outer layer"""; - restChannel.createMessage(response).block(); - return; - } else if (arguments.get(0).equals(prefix + "skin") && arguments.size() >= 2) { - MessageCreateRequest data; - if (arguments.size() >= 4) { - if (arguments.get(2) == "helm" || arguments.get(2) == "avatar") { - data = MessageCreateRequest.builder() - .content("Skin of " + arguments.get(1).toString() + ":") - .addEmbed(EmbedCreateSpec.builder() - .image("https://crafthead.net/" + arguments.get(2) + "/" + arguments.get(1).toString()) - .footer( - "get a closer look at https://pinmacaroon.github.io/skinfetch/index.html", "") - .build().asRequest()) - .build(); - } else { - data = MessageCreateRequest.builder() - .content("Skin of " + arguments.get(1).toString() + ":") - .addEmbed(EmbedCreateSpec.builder() - .image("https://crafthead.net/" + (((boolean) arguments.get(3)) ? "armor/" : "") - + arguments.get(2) + "/" + arguments.get(1).toString()) - .footer( - "get a closer look at https://pinmacaroon.github.io/skinfetch/index.html", "") - .build().asRequest()) - .build(); - } - } else { - data = MessageCreateRequest.builder() - .content("Skin of " + arguments.get(1).toString() + ":") - .addEmbed(EmbedCreateSpec.builder() - .image("https://crafthead.net/skin/" + arguments.get(1).toString()) - .footer( - "get a closer look at https://pinmacaroon.github.io/skinfetch/index.html", "") - .build().asRequest()) - .build(); - } - restChannel.createMessage(data).block(); - return; - } - return; - } - if ((messageCreateEvent.getMessage().getChannelId().asLong() == bot.getCHANNEL_ID()) - && (Hook.getMinecraftServer() != null)) { - if (messageCreateEvent.getMessage().getAuthorAsMember().block() == null) { - return; - } - - if ( - messageCreateEvent.getMessage().getAuthor().isPresent() - && messageCreateEvent.getMessage().getAuthor().get().isBot()) { - return; - } - - String raw_message = messageCreateEvent.getMessage().getContent(); - if (raw_message.endsWith("//") && ModConfigs.FUNCTIONS_ALLOWOOCMESSAGES) { - return; - } - Matcher matcher = MENTION_PATTERN.matcher(raw_message); - int end = 0; - while (matcher.find(end)) { - try { - String username = messageCreateEvent.getGuild().block(Duration.ofSeconds(2)) - .getMemberById(Snowflake.of(matcher.group(2))) - .block(Duration.ofSeconds(2)).getUsername(); - raw_message = matcher.replaceFirst("[@" + username + "]"); - end = matcher.end(); - } catch (Exception e) { - e.printStackTrace(); - raw_message = matcher.replaceFirst("[@unknown_user]"); - end = matcher.end(); - } - } - - matcher = CHANNEL_PATTERN.matcher(raw_message); - end = 0; - while (matcher.find(end)) { - try { - String channel_name = messageCreateEvent.getGuild().block(Duration.ofSeconds(2)) - .getChannelById(Snowflake.of(matcher.group(2))) - .block(Duration.ofSeconds(2)).getName(); - raw_message = matcher.replaceFirst("[#" + channel_name + "]"); - end = matcher.end(); - } catch (Exception e) { - e.printStackTrace(); - raw_message = matcher.replaceFirst("[#unknown_channel]"); - end = matcher.end(); - } - } - - matcher = EMOJI_PATTERN.matcher(raw_message); - end = 0; - while (matcher.find(end)) { - try { - String emoji_name = matcher.group(2); - raw_message = matcher.replaceFirst(":" + emoji_name + ":"); - end = matcher.end(); - } catch (Exception e) { - e.printStackTrace(); - raw_message = matcher.replaceFirst(":unknown_emoji:"); - end = matcher.end(); - } - } - - /* TODO fix!!!! - matcher = ROLE_PATTERN.matcher(raw_message); - end = 0; - while (matcher.find(end)) { - try { - String role_name = messageCreateEvent.getGuild().block(Duration.ofSeconds(2)) - .getRoleById(Snowflake.of(matcher.group(2))) - .block(Duration.ofSeconds(2)).getName(); - raw_message = matcher.replaceFirst("[@" + role_name + "]"); - end = matcher.end(); - } catch (Exception e) { - e.printStackTrace(); - raw_message = matcher.replaceFirst("[@unknown_role]"); - end = matcher.end(); - } - } - */ - //temp fix so that chat doesn't look ugly - matcher = ROLE_PATTERN.matcher(raw_message); - end = 0; - while (matcher.find(end)) { - raw_message = matcher.replaceFirst("[@role]"); - end = matcher.end(); - } - - MutableText signature; - if (messageCreateEvent.getMessage().getMessageReference().isPresent()) { - if (messageCreateEvent.getMessage().getReferencedMessage().get().getAuthor().isEmpty() - && messageCreateEvent.getMessage().getReferencedMessage().get().getWebhook().block().getName() - .isPresent()) { - signature = Text.literal( - "<" + - messageCreateEvent.getMessage().getReferencedMessage().get() - .getWebhook().block().getName().get() + "> -> " + - "<@" + messageCreateEvent.getMessage().getAuthorAsMember().block().getUsername() + ">: " - ); - } else { - signature = Text.literal( - "<@" + - messageCreateEvent.getMessage().getReferencedMessage().get() - .getAuthor().get().getUsername() + "> -> " + - "<@" + messageCreateEvent.getMessage().getAuthorAsMember().block().getUsername() + ">: " - ); - } - } else { - signature = Text.literal( - "<@" + messageCreateEvent.getMessage().getAuthorAsMember().block().getUsername() + ">: " - ); - } - MutableText content = Text.literal( - (raw_message.isBlank()) - ? "" : raw_message - ); - MutableText formatted = signature.formatted(Formatting.BLUE) - .append(content); - Hook.getMinecraftServer().getPlayerManager().broadcast(formatted, false); - } - } -} diff --git a/src/main/java/com/github/pinmacaroon/dchook/bot/commands/AboutCommand.java b/src/main/java/com/github/pinmacaroon/dchook/bot/commands/AboutCommand.java new file mode 100644 index 0000000..dd19e0f --- /dev/null +++ b/src/main/java/com/github/pinmacaroon/dchook/bot/commands/AboutCommand.java @@ -0,0 +1,35 @@ +package com.github.pinmacaroon.dchook.bot.commands; + +import net.dv8tion.jda.api.EmbedBuilder; +import net.dv8tion.jda.api.entities.MessageEmbed; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.interactions.commands.OptionMapping; + +import java.awt.*; +import java.time.Instant; + +public class AboutCommand { + public static void run(SlashCommandInteractionEvent event) { + MessageEmbed embed = new EmbedBuilder() + .setTitle("dchook", "https://modrinth.com/mod/dchook") + .setAuthor("pinmacaroon", "https://pinmacaroon.github.io/", + "https://pinmacaroon.github.io/res/favicon.png") + .setDescription(""" + This bot is operated by [Discord Webhook Wizard](https://modrinth.com/mod/dchook), aka \ + **dchook**, a mod that allows **minecraft chat integration** with discord with simple \ + configuration and straightforward features. Implemented both as a **fabric mod** and a \ + **bukkit/spigot plugin**! All this for free and as an open-source service!""") + .addField("Get started", """ + Want to integrate this with your own server? Want to experiment? Get started by visiting the \ + mod's Modrinth page at !""", false) + .setThumbnail("https://pinmacaroon.github.io/hook/res/b8b3416f1d61e8679b10cf07dff4e5eeb9a2e86e_96.webp") + .setImage("https://cdn.modrinth.com/data/qJ9ZfKma/images/0e822ef2aec1062fd27973191cb2cf85a5734910.png") + .setTimestamp(Instant.now()) + .setFooter("This message was triggered by %s using the /%s command!".formatted( + event.getMember().getUser().getName(), event.getFullCommandName() + )) + .setColor(Color.BLUE) + .build(); + event.replyEmbeds(embed).setEphemeral(event.getOption("ephemeral", false, OptionMapping::getAsBoolean)).queue(); + } +} diff --git a/src/main/java/com/github/pinmacaroon/dchook/bot/commands/ListCommand.java b/src/main/java/com/github/pinmacaroon/dchook/bot/commands/ListCommand.java new file mode 100644 index 0000000..ea50fbf --- /dev/null +++ b/src/main/java/com/github/pinmacaroon/dchook/bot/commands/ListCommand.java @@ -0,0 +1,21 @@ +package com.github.pinmacaroon.dchook.bot.commands; + +import com.github.pinmacaroon.dchook.Hook; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.interactions.commands.OptionMapping; + +public class ListCommand { + public static void run(SlashCommandInteractionEvent event) { + StringBuilder list = new StringBuilder(); + list.append(""" + There are currently **%d**/%d players online:\s""".formatted( + Hook.getGameServer().getPlayerManager().getCurrentPlayerCount(), + Hook.getGameServer().getPlayerManager().getMaxPlayerCount() + )); + Hook.getGameServer().getPlayerManager().getPlayerList().forEach( + serverPlayerEntity -> list.append("`").append(serverPlayerEntity.getName().getString()).append("` ") + ); + event.reply(list.toString()).setEphemeral(event.getOption("ephemeral", false, OptionMapping::getAsBoolean)) + .queue(); + } +} diff --git a/src/main/java/com/github/pinmacaroon/dchook/bot/commands/ModsCommand.java b/src/main/java/com/github/pinmacaroon/dchook/bot/commands/ModsCommand.java new file mode 100644 index 0000000..69b975c --- /dev/null +++ b/src/main/java/com/github/pinmacaroon/dchook/bot/commands/ModsCommand.java @@ -0,0 +1,37 @@ +package com.github.pinmacaroon.dchook.bot.commands; + +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.interactions.commands.OptionMapping; +import net.fabricmc.loader.api.FabricLoader; +import net.fabricmc.loader.api.metadata.ModEnvironment; + +import java.util.concurrent.atomic.AtomicInteger; + +public class ModsCommand { + public static void run(SlashCommandInteractionEvent event) { + StringBuilder mod_list = new StringBuilder(); + AtomicInteger mods_count = new AtomicInteger(); + FabricLoader.getInstance().getAllMods().forEach(modContainer -> { + if (modContainer.getMetadata().getEnvironment() == ModEnvironment.UNIVERSAL + && !modContainer.getMetadata().getType().equals("builtin") + && !modContainer.getMetadata().getId().startsWith("fabric") + && !modContainer.getMetadata().getId().equals("mixinextras") + && modContainer.getContainingMod().isEmpty()) { + mod_list.append(modContainer.getMetadata().getName()).append(' ') + .append(modContainer.getMetadata().getVersion().getFriendlyString()).append('\n'); + mods_count.getAndIncrement(); + } + }); + String response; + if (mods_count.get() == 0) { + response = "The server currently has no required mods, you can join with a vanilla client!"; + } else { + response = "The server currently has " + mods_count.get() + " required mods:\n" + mod_list; + } + if (response.length() > 2000) { + response = response.substring(0, 1995) + "[...]"; + } + + event.reply(response).setEphemeral(event.getOption("ephemeral", false, OptionMapping::getAsBoolean)).queue(); + } +} diff --git a/src/main/java/com/github/pinmacaroon/dchook/bot/commands/StatCommand.java b/src/main/java/com/github/pinmacaroon/dchook/bot/commands/StatCommand.java new file mode 100644 index 0000000..41e96c3 --- /dev/null +++ b/src/main/java/com/github/pinmacaroon/dchook/bot/commands/StatCommand.java @@ -0,0 +1,34 @@ +package com.github.pinmacaroon.dchook.bot.commands; + +import com.github.pinmacaroon.dchook.Hook; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.interactions.commands.OptionMapping; +import net.fabricmc.loader.impl.FabricLoaderImpl; +import net.minecraft.world.GameRules; + +import java.math.BigDecimal; + +public class StatCommand { + public static void run(SlashCommandInteractionEvent event) { + + String list = "Stats of this instance:\n```" + + "uptime = %dmin%n".formatted(Hook.getGameServer().getTicks() / 20 / 60) + + "keepinventory = %b%n".formatted(Hook.getGameServer().getGameRules().get(GameRules.KEEP_INVENTORY) + .get()) + + "mcversion = %s%n".formatted(Hook.getGameServer().getVersion()) + + "fabricmcversion = %s%n".formatted(FabricLoaderImpl.VERSION) + + "dchookversion = %s%n".formatted(Hook.VERSION) + + "players = %d/%d%n".formatted(Hook.getGameServer().getCurrentPlayerCount(), + Hook.getGameServer().getMaxPlayerCount()) + + "memory = ~%smb%n".formatted(Math.rint( + (double) (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1024 / 1024 + )) + + "overworld_border = %s%n".formatted( + BigDecimal.valueOf((int) Hook.getGameServer().getOverworld().getWorldBorder().getSize() / 2) + .toPlainString() + ) + + "```"; + event.reply(list).setEphemeral(event.getOption("ephemeral", false, OptionMapping::getAsBoolean)) + .queue(); + } +} diff --git a/src/main/java/com/github/pinmacaroon/dchook/bot/commands/TimeCommand.java b/src/main/java/com/github/pinmacaroon/dchook/bot/commands/TimeCommand.java new file mode 100644 index 0000000..72b0f45 --- /dev/null +++ b/src/main/java/com/github/pinmacaroon/dchook/bot/commands/TimeCommand.java @@ -0,0 +1,17 @@ +package com.github.pinmacaroon.dchook.bot.commands; + +import com.github.pinmacaroon.dchook.Hook; +import com.github.pinmacaroon.dchook.util.TimeConverter; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.interactions.commands.OptionMapping; + +public class TimeCommand { + public static void run(SlashCommandInteractionEvent event) { + String response = "The current in-game time in the overworld is **%s**! The weather is %s%s!".formatted( + TimeConverter.timeOfDayToHoursMinutes2(Hook.getGameServer().getOverworld().getTimeOfDay()), + (Hook.getGameServer().getOverworld().isRaining()) ? "rainy" : "clear", + (Hook.getGameServer().getOverworld().isThundering()) ? " and it is thundering!" : "" + ); + event.reply(response).setEphemeral(event.getOption("ephemeral", false, OptionMapping::getAsBoolean)).queue(); + } +} diff --git a/src/main/java/com/github/pinmacaroon/dchook/bot/event/MessageReceivedListener.java b/src/main/java/com/github/pinmacaroon/dchook/bot/event/MessageReceivedListener.java new file mode 100644 index 0000000..185d1ce --- /dev/null +++ b/src/main/java/com/github/pinmacaroon/dchook/bot/event/MessageReceivedListener.java @@ -0,0 +1,55 @@ +package com.github.pinmacaroon.dchook.bot.event; + +import com.github.pinmacaroon.dchook.Hook; +import com.github.pinmacaroon.dchook.bot.Bot; +import com.github.pinmacaroon.dchook.conf.ModConfigs; +import net.dv8tion.jda.api.entities.Message; +import net.dv8tion.jda.api.events.message.MessageReceivedEvent; +import net.dv8tion.jda.api.hooks.ListenerAdapter; +import net.minecraft.text.MutableText; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; +import org.jetbrains.annotations.NotNull; + +public class MessageReceivedListener extends ListenerAdapter { + private final Bot BOT; + + public MessageReceivedListener(Bot bot) { + this.BOT = bot; + } + + @Override + public void onMessageReceived(@NotNull MessageReceivedEvent event) { + if (event.getGuild().getIdLong() != this.BOT.getGUILD_ID()) return; + if (event.getMessage().getAuthor().isBot()) return; + if (event.getChannel().getIdLong() == this.BOT.getCHANNEL_ID() && Hook.getGameServer() != null) { + if (event.getMessage().getContentStripped().endsWith("//") && ModConfigs.FUNCTIONS_ALLOWOOCMESSAGES) return; + Hook.getGameServer().getPlayerManager().broadcast(renderMessage(event.getMessage()), false); + } + } + + private static MutableText renderMessage(Message message) { + final String raw_message = message.getContentDisplay(); + MutableText signature; + MutableText reply; + MutableText content; + + if (message.getMessageReference() != null) { + reply = Text.literal("<@%s -> ".formatted( + message.getReferencedMessage().getAuthor().getName() + )); + } else { + reply = Text.literal("<"); + } + + signature = Text.literal("@%s> ".formatted( + message.getAuthor().getName() + )); + + content = (raw_message.isBlank()) + ? Text.literal("[embed]") + : Text.literal(raw_message); + + return reply.append(signature).append(content).formatted(Formatting.BLUE); + } +} diff --git a/src/main/java/com/github/pinmacaroon/dchook/bot/event/ReadyEventListener.java b/src/main/java/com/github/pinmacaroon/dchook/bot/event/ReadyEventListener.java new file mode 100644 index 0000000..ef46313 --- /dev/null +++ b/src/main/java/com/github/pinmacaroon/dchook/bot/event/ReadyEventListener.java @@ -0,0 +1,17 @@ +package com.github.pinmacaroon.dchook.bot.event; + +import com.github.pinmacaroon.dchook.bot.Bot; +import net.dv8tion.jda.api.events.session.ReadyEvent; +import net.dv8tion.jda.api.hooks.ListenerAdapter; +import org.jetbrains.annotations.NotNull; + +public class ReadyEventListener extends ListenerAdapter { + + public ReadyEventListener(Bot bot){ + } + + @Override + public void onReady(@NotNull ReadyEvent event) { + System.out.println("Logged in as %s%s!"); + } +} diff --git a/src/main/java/com/github/pinmacaroon/dchook/bot/event/SlashCommandInteractionListener.java b/src/main/java/com/github/pinmacaroon/dchook/bot/event/SlashCommandInteractionListener.java new file mode 100644 index 0000000..192e429 --- /dev/null +++ b/src/main/java/com/github/pinmacaroon/dchook/bot/event/SlashCommandInteractionListener.java @@ -0,0 +1,36 @@ +package com.github.pinmacaroon.dchook.bot.event; + +import com.github.pinmacaroon.dchook.bot.Bot; +import com.github.pinmacaroon.dchook.bot.commands.*; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.hooks.ListenerAdapter; +import net.dv8tion.jda.api.utils.FileUpload; +import org.jetbrains.annotations.NotNull; + +import java.io.File; + +public class SlashCommandInteractionListener extends ListenerAdapter { + private final Bot BOT; + + public SlashCommandInteractionListener(Bot bot) { + this.BOT = bot; + } + + @Override + public void onSlashCommandInteraction(@NotNull SlashCommandInteractionEvent event) { + if (event.getGuild() == null) return; + if (event.getGuild().getIdLong() != this.BOT.getGUILD_ID()) return; + switch (event.getName()) { + case "time" -> TimeCommand.run(event); + case "mods" -> ModsCommand.run(event); + case "list" -> ListCommand.run(event); + case "stat" -> StatCommand.run(event); + case "about" -> AboutCommand.run(event); + default -> event.reply(""" + An internal error occurred! Please send a bug report: \ + """).setEphemeral(true) + .addFiles(FileUpload.fromData(new File("https://pinmacaroon.github.io/hook/res/works.png"))) + .queue(); + } + } +} diff --git a/src/main/java/com/github/pinmacaroon/dchook/conf/ModConfigs.java b/src/main/java/com/github/pinmacaroon/dchook/conf/ModConfigs.java index 8aa58d1..8d22955 100644 --- a/src/main/java/com/github/pinmacaroon/dchook/conf/ModConfigs.java +++ b/src/main/java/com/github/pinmacaroon/dchook/conf/ModConfigs.java @@ -7,28 +7,22 @@ public class ModConfigs { public static SimpleConfig CONFIG; - private static ModConfigProvider configs; - public static String WEBHOOK_URL; public static String MESSAGES_SERVER_STARTING; public static String MESSAGES_SERVER_STOPPED; public static String MESSAGES_SERVER_STARTED; public static String MESSAGES_SERVER_STOPPING; public static boolean FUNCTIONS_ALLOWOOCMESSAGES; - public static boolean MESSAGES_SERVER_STARTING_ALLOWED; public static boolean MESSAGES_SERVER_STOPPED_ALLOWED; public static boolean MESSAGES_SERVER_STARTED_ALLOWED; public static boolean MESSAGES_SERVER_STOPPING_ALLOWED; - public static boolean FUNCTIONS_MODENABLED; public static boolean FUNCTIONS_PROMOTIONS_ENABLED; - public static boolean FUNCTIONS_BOT_ENABLED; public static String FUNCTIONS_BOT_TOKEN; - public static String FUNCTIONS_BOT_PREFIX; - public static boolean FUNCTIONS_UPDATE; + private static ModConfigProvider configs; public static void registerConfigs() { configs = new ModConfigProvider(); @@ -49,7 +43,6 @@ private static void createConfigs() { configs.addKeyValuePair(new Pair<>("functions.promotions.enabled", true), "are tips and hints/promotion embeds allowed to be sent to Discord"); configs.addKeyValuePair(new Pair<>("functions.bot.enabled", true), "is two-way chat (the bot) enabled?"); configs.addKeyValuePair(new Pair<>("functions.bot.token", "TOKEN"), "bot token"); - configs.addKeyValuePair(new Pair<>("functions.bot.prefix", "$"), "bot command prefix"); configs.addKeyValuePair(new Pair<>("functions.update", true), "check for updates"); configs.addBlankLine(); @@ -89,7 +82,6 @@ private static void assignConfigs() { FUNCTIONS_BOT_ENABLED = CONFIG.getOrDefault("functions.bot.enabled", false); FUNCTIONS_BOT_TOKEN = CONFIG.getOrDefault("functions.bot.token", ""); - FUNCTIONS_BOT_PREFIX = CONFIG.getOrDefault("functions.bot.prefix", "$"); FUNCTIONS_UPDATE = CONFIG.getOrDefault("functions.update", false); diff --git a/src/main/java/com/github/pinmacaroon/dchook/conf/SimpleConfig.java b/src/main/java/com/github/pinmacaroon/dchook/conf/SimpleConfig.java index 91f1660..f68f70f 100644 --- a/src/main/java/com/github/pinmacaroon/dchook/conf/SimpleConfig.java +++ b/src/main/java/com/github/pinmacaroon/dchook/conf/SimpleConfig.java @@ -126,9 +126,7 @@ private void parseConfigEntry( String entry, int line ) { if( !entry.isEmpty() && !entry.startsWith( "#" ) ) { String[] parts = entry.split("=", 2); if( parts.length == 2 ) { - //comments go brrrrrrrrrrr - String temp = parts[1].split(" #")[0]; - config.put( parts[0], temp ); + config.put( parts[0], parts[1] ); }else{ throw new RuntimeException("Syntax error in config file on line " + line + "!"); } diff --git a/src/main/java/com/github/pinmacaroon/dchook/mixin/ExampleMixin.java b/src/main/java/com/github/pinmacaroon/dchook/mixin/ExampleMixin.java deleted file mode 100644 index 16f0cd0..0000000 --- a/src/main/java/com/github/pinmacaroon/dchook/mixin/ExampleMixin.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.github.pinmacaroon.dchook.mixin; - -import net.minecraft.server.MinecraftServer; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(MinecraftServer.class) -public class ExampleMixin { - @Inject(at = @At("HEAD"), method = "loadWorld") - private void init(CallbackInfo info) { - // This code is injected into the start of MinecraftServer.loadWorld()V - - } -} \ No newline at end of file diff --git a/src/main/java/com/github/pinmacaroon/dchook/util/EventListeners.java b/src/main/java/com/github/pinmacaroon/dchook/util/EventListeners.java index d5db47f..f1ea054 100644 --- a/src/main/java/com/github/pinmacaroon/dchook/util/EventListeners.java +++ b/src/main/java/com/github/pinmacaroon/dchook/util/EventListeners.java @@ -2,6 +2,7 @@ import com.github.pinmacaroon.dchook.Hook; import com.github.pinmacaroon.dchook.conf.ModConfigs; +import net.dv8tion.jda.api.utils.MarkdownSanitizer; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; import net.fabricmc.fabric.api.message.v1.ServerMessageEvents; import net.minecraft.text.Text; @@ -120,7 +121,7 @@ public static void registerEventListeners(){ Array.get(list.get(2), 2), list.get(3) )); - } else request_body.put("content", message.getSignedContent()); + } else request_body.put("content", MarkdownSanitizer.escape(message.getSignedContent())); request_body.put("username", sender.getName().getString()); request_body.put("avatar_url", "https://crafthead.net/helm/" + message.getSender().toString()); diff --git a/src/main/java/com/github/pinmacaroon/dchook/util/PromotionProvider.java b/src/main/java/com/github/pinmacaroon/dchook/util/PromotionProvider.java index 982efb9..11c9b30 100644 --- a/src/main/java/com/github/pinmacaroon/dchook/util/PromotionProvider.java +++ b/src/main/java/com/github/pinmacaroon/dchook/util/PromotionProvider.java @@ -295,7 +295,6 @@ public static void sendPromotion(JsonArray embeds, URI webhook){ */ public static @Nullable JsonObject automaticPromotionSelector(){ int id = Hook.RANDOM.nextInt(0, 10); - LOGGER.debug(String.valueOf(id)); return switch (id) { case 0 -> getMcfetchPromotion(); case 1 -> getOocMessageTip(); diff --git a/src/main/java/com/github/pinmacaroon/dchook/util/TimeConverter.java b/src/main/java/com/github/pinmacaroon/dchook/util/TimeConverter.java index 4b2f9d7..c642a51 100644 --- a/src/main/java/com/github/pinmacaroon/dchook/util/TimeConverter.java +++ b/src/main/java/com/github/pinmacaroon/dchook/util/TimeConverter.java @@ -1,10 +1,6 @@ package com.github.pinmacaroon.dchook.util; public class TimeConverter { - /* - public static String timeOfDayToHoursMinutes(long time){ - return (int) Math.floor(time / 1000) + ":" + (int) ((time % 1000) / 1000.0 * 60); - }*/ /** * https://bukkit.org/threads/how-can-i-convert-minecraft-long-time-to-real-hours-and-minutes.122912/ diff --git a/src/main/java/com/github/pinmacaroon/dchook/util/VersionChecker.java b/src/main/java/com/github/pinmacaroon/dchook/util/VersionChecker.java index b14ee57..7e4bdc9 100644 --- a/src/main/java/com/github/pinmacaroon/dchook/util/VersionChecker.java +++ b/src/main/java/com/github/pinmacaroon/dchook/util/VersionChecker.java @@ -58,7 +58,6 @@ else if(Hook.VERSION.withoutBuildMetadata().isHigherThan(remoteVersion.get().wit } } catch (Exception e) { Hook.LOGGER.error("{}:{}", e.getClass().getName(), e.getMessage()); - return; } } } diff --git a/src/main/java/com/github/pinmacaroon/dchook/util/WaypointParser.java b/src/main/java/com/github/pinmacaroon/dchook/util/WaypointParser.java index 17b8fa4..4ea6d7c 100644 --- a/src/main/java/com/github/pinmacaroon/dchook/util/WaypointParser.java +++ b/src/main/java/com/github/pinmacaroon/dchook/util/WaypointParser.java @@ -7,7 +7,7 @@ public class WaypointParser { private static final Pattern WAYPOINT_PATTERN = Pattern.compile( // name marker x y z yaw ? ? dimension - "^xaero-waypoint:([^:]+):(.{1,2}):(-?\\d+):(-?\\d+):(-?\\d+):(-?\\d+):([^:]+):([^:]+):Internal-(the-nether|overworld|the-end)-waypoints$" + "^xaero-waypoint:([^:]+):(.{1,2}):(-?\\d+):(-?\\d+):(-?\\d+):(-?\\d+):([^:]+):([^:]+):Internal-(the-nether|overworld|the-end)[-waypoints]?$" ); public static boolean isWaypoint(String text) { diff --git a/src/main/resources/dchook.mixins.json b/src/main/resources/dchook.mixins.json deleted file mode 100644 index a256baa..0000000 --- a/src/main/resources/dchook.mixins.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "required": true, - "package": "com.github.pinmacaroon.dchook.mixin", - "compatibilityLevel": "JAVA_17", - "mixins": [ - "ExampleMixin" - ], - "injectors": { - "defaultRequire": 1 - } -} \ No newline at end of file diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 81221e4..c017d7b 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -18,9 +18,6 @@ "com.github.pinmacaroon.dchook.Hook" ] }, - "mixins": [ - "dchook.mixins.json" - ], "depends": { "fabricloader": ">=0.16.10", "minecraft": "1.20.*",