feat: implement DISCORD <- MC

This commit is contained in:
Soph :3 2024-10-28 01:25:13 +02:00
parent b2178db695
commit d3d1d2fcf3
Signed by: sophie
GPG key ID: EDA5D222A0C270F2
6 changed files with 106 additions and 8 deletions

View file

@ -45,6 +45,8 @@ dependencies {
implementation("net.dv8tion:JDA:${project.jda_version}") {
exclude module: 'opus-java'
}
include implementation("club.minnced:discord-webhooks:${project.webhooks_version}")
}
processResources {

View file

@ -15,3 +15,4 @@ fabric_version=0.107.0+1.21.1
owo_version=0.12.15+1.21
jda_version=5.1.2
webhooks_version=0.8.4

View file

@ -13,7 +13,7 @@ public class Discord implements ModInitializer {
@Override
public void onInitialize() {
LOGGER.info("slop's custom discord plugin");
DiscordRegistration.createClient();
DiscordRegistration.register();
MinecraftRegistration.register();
}
}

View file

@ -1,14 +1,12 @@
package sad.ovh.discord;
import io.wispforest.owo.config.Option;
import io.wispforest.owo.config.annotation.Config;
import io.wispforest.owo.config.annotation.Sync;
@Sync(Option.SyncMode.NONE)
@Config(name = "slop-discord-config", wrapperName = "DiscordConfig")
public class DiscordConfigModel {
public String token = "";
public String channelId = "";
public String consoleId = "";
public String webhookName = "mc-bridge";
public String avatarApiUrl = "https://vzge.me/bust/256/%s";
}

View file

@ -1,7 +1,12 @@
package sad.ovh.discord;
import club.minnced.discord.webhook.WebhookClient;
import club.minnced.discord.webhook.WebhookClientBuilder;
import club.minnced.discord.webhook.receive.ReadonlyMessage;
import club.minnced.discord.webhook.send.*;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.JDABuilder;
import net.dv8tion.jda.api.entities.Webhook;
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.dv8tion.jda.api.events.message.MessageUpdateEvent;
@ -12,15 +17,21 @@ import net.dv8tion.jda.api.utils.cache.CacheFlag;
import org.jetbrains.annotations.NotNull;
import java.util.EnumSet;
import java.util.UUID;
public class DiscordRegistration {
static public JDA client;
static public TextChannel channel;
static public TextChannel consoleChannel;
static public WebhookClient webhookClient;
static public Boolean isReady;
static public void createClient() {
static public Webhook webhook;
static private Long lastId;
static public void register() {
client = JDABuilder
.create(Discord.CONFIG.token(), EnumSet.of(GatewayIntent.GUILD_MESSAGES, GatewayIntent.GUILD_MEMBERS, GatewayIntent.MESSAGE_CONTENT))
.disableCache(CacheFlag.ACTIVITY, CacheFlag.VOICE_STATE, CacheFlag.EMOJI, CacheFlag.STICKER, CacheFlag.CLIENT_STATUS, CacheFlag.ONLINE_STATUS, CacheFlag.SCHEDULED_EVENTS)
@ -28,6 +39,57 @@ public class DiscordRegistration {
.build();
}
static public void sendPlayerMessage(String message, String name, UUID playerUuid) {
if (!isReady)
return;
String avatarUrl = String.format(Discord.CONFIG.avatarApiUrl(), playerUuid.toString());
WebhookMessage webhookMessage = new WebhookMessageBuilder()
.setAvatarUrl(avatarUrl)
.setUsername(name)
.setContent(message)
.setAllowedMentions(
new AllowedMentions()
.withParseUsers(true)
.withParseRoles(true)
.withParseEveryone(false)
)
.build();
webhookClient.send(webhookMessage);
}
static public void sendPlayerStatus(String message, int color, UUID playerUuid) {
if (!isReady)
return;
String avatarUrl = String.format(Discord.CONFIG.avatarApiUrl(), playerUuid.toString());
var embed = new WebhookEmbedBuilder()
.setAuthor(new WebhookEmbed.EmbedAuthor(message, avatarUrl, null))
.setColor(color)
.build();
webhookClient.send(embed);
}
static public void sendServerUpdate(String message, int color, Boolean deleteLastOne) {
if (!isReady)
return;
if(deleteLastOne && lastId != null) {
channel.deleteMessageById(lastId).complete();
}
WebhookEmbed webhookMessage = new WebhookEmbedBuilder()
.setDescription(message)
.setColor(color)
.build();
webhookClient.send(webhookMessage)
.thenAccept((msg) -> lastId = msg.getId());
}
private static class DiscordEvents extends ListenerAdapter {
@Override
public void onReady(@NotNull ReadyEvent event) {
@ -45,6 +107,27 @@ public class DiscordRegistration {
if (consoleChannel == null) {
Discord.LOGGER.warn("No console channel was set.");
}
var webhookName = Discord.CONFIG.webhookName();
var webhooks = channel.retrieveWebhooks().complete();
webhooks.stream()
.filter((wh) -> wh.getName().equals(webhookName))
.findFirst()
.ifPresent((wh) -> webhook = wh);
if (webhook == null) {
webhook = channel.createWebhook(webhookName).complete();
}
if (webhook == null) {
Discord.LOGGER.error("Attempt to create a webhook failed! Please create a WebHook by the name {} and restart the server", webhookName);
client.shutdown();
return;
}
webhookClient = new WebhookClientBuilder(webhook.getUrl())
.setDaemon(true)
.buildJDA();
isReady = true;
}

View file

@ -6,32 +6,41 @@ import net.fabricmc.fabric.api.message.v1.ServerMessageEvents;
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
import net.minecraft.server.network.ServerPlayerEntity;
import java.awt.*;
public class MinecraftRegistration {
public static void register() {
ServerLifecycleEvents.SERVER_STARTING.register(server -> {
if (!DiscordRegistration.isReady)
return;
DiscordRegistration.sendServerUpdate(":hourglass: **Server is starting...**", Color.YELLOW.getRGB(), false);
});
ServerLifecycleEvents.SERVER_STARTED.register(server -> {
if (!DiscordRegistration.isReady)
return;
DiscordRegistration.sendServerUpdate(":white_check_mark: **Server has started!**", Color.GREEN.getRGB(), true);
});
ServerLifecycleEvents.SERVER_STOPPING.register(server -> {
if (!DiscordRegistration.isReady)
return;
DiscordRegistration.sendServerUpdate(":x: **Server stopping.**", Color.RED.getRGB(), false);
});
ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> {
if (!DiscordRegistration.isReady)
return;
DiscordRegistration.sendPlayerStatus(String.format("%s has joined the server.", handler.player.getDisplayName().getString()), Color.GREEN.getRGB(), handler.player.getUuid());
});
ServerPlayConnectionEvents.DISCONNECT.register((handler, server) -> {
if (!DiscordRegistration.isReady)
return;
DiscordRegistration.sendPlayerStatus(String.format("%s has left the server.", handler.player.getDisplayName().getString()), Color.RED.getRGB(), handler.player.getUuid());
});
ServerLivingEntityEvents.AFTER_DEATH.register((entity, damageSource) -> {
@ -39,11 +48,16 @@ public class MinecraftRegistration {
return;
if (!(entity instanceof ServerPlayerEntity player))
return;
var message = damageSource.getDeathMessage(entity).getString();
DiscordRegistration.sendPlayerStatus(message, Color.RED.getRGB(), player.getUuid());
});
ServerMessageEvents.CHAT_MESSAGE.register((message, sender, params) -> {
if (!DiscordRegistration.isReady)
return;
DiscordRegistration.sendPlayerMessage(message.getContent().getString(), sender.getDisplayName().getString(), sender.getUuid());
});
}
}