Skip to content

Commit

Permalink
Add Listener and Sender Method.
Browse files Browse the repository at this point in the history
  • Loading branch information
K-Lqrs committed Jun 29, 2024
1 parent e3964fd commit 29016b2
Show file tree
Hide file tree
Showing 7 changed files with 241 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package net.rk4z.fabricord.mixins;

import net.minecraft.network.ClientConnection;
import net.minecraft.server.PlayerManager;
import net.minecraft.server.network.ConnectedClientData;
import net.minecraft.server.network.ServerPlayerEntity;
import net.rk4z.beacon.EventBus;
import net.rk4z.fabricord.Fabricord;
import net.rk4z.fabricord.events.*;
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;

import java.text.SimpleDateFormat;
import java.util.Date;

@Mixin(PlayerManager.class)
public class PlayerManagerMixin {
@Inject(method = "onPlayerConnect", at = @At("RETURN"))
public void onPlayerConnect(ClientConnection cc, ServerPlayerEntity player, ConnectedClientData ccData, CallbackInfo ci) {
EventBus.callEventAsync(PlayerJoinEvent.get());
String timestamp = new SimpleDateFormat("yyyy-MM-dd HH:mm").format(new Date());
String message = timestamp + " > " + player.getName().getString() + " has joined the server.";

Fabricord.INSTANCE.getLogContainer().add(message);
}

@Inject(method = "remove", at = @At("HEAD"))
public void onPlayerDisconnect(ServerPlayerEntity player, CallbackInfo ci) {
EventBus.callEventAsync(PlayerLeaveEvent.get());
String timestamp = new SimpleDateFormat("yyyy-MM-dd HH:mm").format(new Date());
String message = timestamp + " > " + player.getName().getString() + " has left the server.";

Fabricord.INSTANCE.getLogContainer().add(message);
}
}
25 changes: 24 additions & 1 deletion 1.21/src/main/kotlin/net/rk4z/fabricord/Fabricord.kt
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
package net.rk4z.fabricord

import com.ibm.icu.text.SimpleDateFormat
import net.fabricmc.loader.api.FabricLoader
import net.fabricmc.loader.api.metadata.ModMetadata
import net.rk4z.beacon.EventBus
import net.rk4z.beacon.Listener
import net.rk4z.beacon.handler
import net.rk4z.fabricord.discord.DiscordBotManager
import net.rk4z.fabricord.events.ServerStartEvent
import net.rk4z.fabricord.events.ServerStopEvent
import net.rk4z.fabricord.util.Utils.copyResourceToFile
import net.rk4z.fabricord.util.Utils.getNullableString
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.yaml.snakeyaml.Yaml
import java.io.File
import java.io.IOException
import java.nio.file.Files
import java.nio.file.Path
import java.util.Date

@Suppress("unused", "MemberVisibilityCanBePrivate")
object Fabricord : Listener {
Expand All @@ -31,11 +35,15 @@ object Fabricord : Listener {
val modDir: Path = serverDir.resolve(MOD_ID)
val configFile: Path = modDir.resolve("config.yml")

val logContainer: MutableList<String> = mutableListOf()

// Required
var botToken: String? = null
var logChannelID: String? = null

// Optional
var enableConsoleLog: Boolean = false
var consoleLogChannelID: String? = null
var serverStartMessage: String? = null
var serverStopMessage: String? = null
var botOnlineStatus: String? = null
Expand Down Expand Up @@ -65,11 +73,25 @@ object Fabricord : Listener {
}

val startHandler = handler<ServerStartEvent> {
TODO()
DiscordBotManager.startBot()
}

val stopHandler = handler<ServerStopEvent> {
logger.info("Shutting down $name v$version")
val timeStamp = SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(Date())
val logFile = File("log_${name}_$timeStamp.log")

try {
logFile.bufferedWriter().use { writer ->
logContainer.forEach { log ->
writer.write(log)
writer.newLine()
}
}
} catch (e: IOException) {
e.printStackTrace()
}
DiscordBotManager.stopBot()
EventBus.shutdown()
}

Expand Down Expand Up @@ -105,6 +127,7 @@ object Fabricord : Listener {

botToken = config.getNullableString("BotToken")
logChannelID = config.getNullableString("LogChannelID")

botOnlineStatus = config.getNullableString("BotOnlineStatus")
botActivityStatus = config.getNullableString("BotActivityStatus")
botActivityMessage = config.getNullableString("BotActivityMessage")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,31 @@ import net.dv8tion.jda.api.JDA
import net.dv8tion.jda.api.JDABuilder
import net.dv8tion.jda.api.OnlineStatus
import net.dv8tion.jda.api.entities.Activity
import net.dv8tion.jda.api.events.message.MessageReceivedEvent
import net.dv8tion.jda.api.hooks.ListenerAdapter
import net.dv8tion.jda.api.requests.GatewayIntent
import net.minecraft.server.MinecraftServer
import net.rk4z.beacon.EventBus
import net.rk4z.fabricord.Fabricord.botActivityMessage
import net.rk4z.fabricord.Fabricord.botActivityStatus
import net.rk4z.fabricord.Fabricord.botOnlineStatus
import net.rk4z.fabricord.Fabricord.botToken
import net.rk4z.fabricord.Fabricord.consoleLogChannelID
import net.rk4z.fabricord.Fabricord.enableConsoleLog
import net.rk4z.fabricord.Fabricord.logChannelID
import net.rk4z.fabricord.Fabricord.logger
import net.rk4z.fabricord.Fabricord.serverStartMessage
import net.rk4z.fabricord.Fabricord.serverStopMessage
import net.rk4z.fabricord.events.DiscordMessageReceiveEvent
import net.rk4z.fabricord.events.DiscordMinecraftPlayerMentionEvent
import java.util.*
import javax.security.auth.login.LoginException

@Suppress("unused", "MemberVisibilityCanBePrivate")
object DiscordBotManager {
var jda: JDA? = null
var botIsInitialized: Boolean = false
private val server: MinecraftServer? = null

private val intents = GatewayIntent.MESSAGE_CONTENT

Expand Down Expand Up @@ -50,6 +60,7 @@ object DiscordBotManager {
.setStatus(onlineStatus)
.setActivity(activity)
.enableIntents(intents)
.addEventListeners(discordListener)
.build()
.awaitReady()

Expand All @@ -73,7 +84,51 @@ object DiscordBotManager {
logger.info("Discord bot has been shutdown")
}

private val discordListener = object : ListenerAdapter() {
override fun onMessageReceived(event: MessageReceivedEvent) {
val server = server ?: run {
logger.error("MinecraftServer is not initialized. Cannot process Discord message.")
return
}

val messageContent = event.message.contentRaw
val players = server.playerManager.playerList
var updatedMessageContent = messageContent

var foundMCID = false
players.forEach { player ->
val mcid = player.name.toString()
if (messageContent.contains(mcid)) {
foundMCID = true
}
}

val uuidPattern = Regex("@\\{([0-9a-fA-F-]+)}")
val matches = uuidPattern.findAll(messageContent)
matches.forEach { match ->
val uuidStr = match.groupValues[1]
val player = players.find { it.uuid.toString() == uuidStr }
player?.let {
updatedMessageContent = updatedMessageContent.replace(match.value, it.name.toString())
}
}

if (updatedMessageContent != messageContent || foundMCID) {
event.message.editMessage(updatedMessageContent).queue()
EventBus.callEventAsync(DiscordMinecraftPlayerMentionEvent.get(event, server))
} else {
EventBus.callEventAsync(DiscordMessageReceiveEvent.get(event, server))
}
}
}

fun sendToDiscord(message: String) {
logChannelID?.let { jda?.getTextChannelById(it)?.sendMessage(message)?.queue() }
}

fun sendToDiscordForConsole(message: String) {
if (enableConsoleLog) {
consoleLogChannelID?.let { jda?.getTextChannelById(it)?.sendMessage("```$message```")?.queue() }
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package net.rk4z.fabricord.discord

import net.dv8tion.jda.api.entities.Role
import net.kyori.adventure.text.Component
import net.kyori.adventure.text.event.ClickEvent
import net.kyori.adventure.text.format.TextColor
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer
import net.minecraft.server.network.ServerPlayerEntity
import net.minecraft.text.Text
import net.rk4z.beacon.Listener
import net.rk4z.beacon.handler
import net.rk4z.fabricord.Fabricord.logChannelID
import net.rk4z.fabricord.events.DiscordMessageReceiveEvent
import java.awt.Color
import java.util.function.Consumer

@Suppress("unused")
class DiscordMessageHandler : Listener {

val handleDiscordMessage = handler<DiscordMessageReceiveEvent> { event ->
val channelId: String = logChannelID!!
if (event.c.channel.id != channelId || event.c.author.isBot) {
return@handler
}

val member = event.c.member
val memberName = member?.user?.name ?: "Unknown Name"
val memberId = member?.user?.id ?: "00000000000000000000"
val idSuggest = "<@$memberId>"
val highestRole =
member?.roles?.stream()?.max(Comparator.comparingInt { obj: Role -> obj.position })?.orElse(null)
val roleName = highestRole?.name
val roleId = highestRole?.id
val rIdSuggest = if (roleId != null) "<@&$roleId>" else null
val roleColor = if (highestRole != null && highestRole.color != null) highestRole.color else Color.WHITE
val kyoriRoleColor = TextColor.color(
roleColor!!.red, roleColor.green, roleColor.blue
)


var componentMessage = Component.text("[", TextColor.color(0xFFFFFF))
.append(Component.text("Discord", TextColor.color(0x55CDFC)))

componentMessage = if (roleName != null) {
componentMessage.append(Component.text(" | ", TextColor.color(0xFFFFFF)))
.append(
Component.text(roleName, kyoriRoleColor)
.clickEvent(ClickEvent.suggestCommand(rIdSuggest!!))
)
.append(Component.text("]", TextColor.color(0xFFFFFF)))
.append(Component.text(" "))
} else {
componentMessage.append(Component.text("]", TextColor.color(0xFFFFFF)))
.append(Component.text(" "))
}

componentMessage = componentMessage.append(
Component.text(memberName)
.clickEvent(ClickEvent.suggestCommand(idSuggest))
)
.append(Component.text(" » " + event.c.message.contentDisplay))

val json = GsonComponentSerializer.gson().serialize(componentMessage)

val textMessage: Text? = Text.Serialization.fromJson(json, event.server.registryManager)

event.server.playerManager.playerList.forEach(
Consumer { player: ServerPlayerEntity ->
player.sendMessage(
textMessage,
false
)
}
)
}

}
23 changes: 23 additions & 0 deletions 1.21/src/main/kotlin/net/rk4z/fabricord/events/DiscordEvents.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package net.rk4z.fabricord.events

import net.dv8tion.jda.api.events.message.MessageReceivedEvent
import net.minecraft.server.MinecraftServer
import net.rk4z.beacon.Event

class DiscordMessageReceiveEvent(val c: MessageReceivedEvent, val server: MinecraftServer) : Event() {
companion object {
@JvmStatic
fun get(event: MessageReceivedEvent, server: MinecraftServer): DiscordMessageReceiveEvent {
return DiscordMessageReceiveEvent(event, server)
}
}
}

class DiscordMinecraftPlayerMentionEvent(val c: MessageReceivedEvent, val server: MinecraftServer) : Event() {
companion object {
@JvmStatic
fun get(event: MessageReceivedEvent, server: MinecraftServer): DiscordMinecraftPlayerMentionEvent {
return DiscordMinecraftPlayerMentionEvent(event, server)
}
}
}
23 changes: 23 additions & 0 deletions 1.21/src/main/kotlin/net/rk4z/fabricord/events/PlayerEvents.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package net.rk4z.fabricord.events

import net.rk4z.beacon.Event

class PlayerJoinEvent: Event() {
companion object {
private val instance = PlayerJoinEvent()
@JvmStatic
fun get(): PlayerJoinEvent {
return instance
}
}
}

class PlayerLeaveEvent: Event() {
companion object {
private val instance = PlayerLeaveEvent()
@JvmStatic
fun get(): PlayerLeaveEvent {
return instance
}
}
}
3 changes: 2 additions & 1 deletion 1.21/src/main/resources/fabricord.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
"package": "net.rk4z.fabricord.mixins",
"compatibilityLevel": "JAVA_21",
"mixins": [
"MinecraftServerMixin"
"MinecraftServerMixin",
"PlayerManagerMixin"
],
"injectors": {
"defaultRequire": 1
Expand Down

0 comments on commit 29016b2

Please sign in to comment.