feat: middle save

This commit is contained in:
Project_IO 2024-09-23 16:45:34 +09:00
parent bc4c985735
commit 8c9b4a1112
11 changed files with 68 additions and 38 deletions

View file

@ -8,6 +8,7 @@ import org.slf4j.LoggerFactory
abstract class Plugin {
private val handlerContainer = mutableListOf<ListenerAdapter>()
val config = this.javaClass.getResourceAsStream("/plugin.json")!!.let {
val raw = it.bufferedReader().readText()
val obj = Json.decodeFromString<PluginConfig>(raw)

View file

@ -1,5 +1,8 @@
package net.projecttl.p.x32.api.command
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import net.dv8tion.jda.api.JDA
import net.dv8tion.jda.api.events.interaction.command.MessageContextInteractionEvent
@ -15,6 +18,7 @@ fun commandHandler(block: (CommandHandler) -> Unit): CommandHandler {
return handler
}
@OptIn(DelicateCoroutinesApi::class)
class CommandHandler(val guildId: Long = 0L) : ListenerAdapter() {
private val commands = mutableListOf<CommandExecutor>()
@ -24,7 +28,7 @@ class CommandHandler(val guildId: Long = 0L) : ListenerAdapter() {
commands.forEach { command ->
if (command.data.name == name) {
if (command is GlobalCommand) {
runBlocking {
GlobalScope.launch {
command.execute(ev)
}
@ -40,7 +44,7 @@ class CommandHandler(val guildId: Long = 0L) : ListenerAdapter() {
commands.forEach { command ->
if (command.data.name == name) {
if (command is UserContext) {
runBlocking {
GlobalScope.launch {
command.execute(ev)
}
@ -56,7 +60,7 @@ class CommandHandler(val guildId: Long = 0L) : ListenerAdapter() {
commands.forEach { command ->
if (command.data.name == name) {
if (command is MessageContext) {
runBlocking {
GlobalScope.launch {
command.execute(ev)
}

View file

@ -1,9 +0,0 @@
package net.projecttl.p.x32.api.util
import net.dv8tion.jda.api.EmbedBuilder
import kotlin.random.Random
fun EmbedBuilder.colour(): EmbedBuilder {
val rand = Random.nextInt(0x000001, 0xffffff)
return this.setColor(rand)
}

View file

@ -0,0 +1,24 @@
package net.projecttl.p.x32.api.util
import net.dv8tion.jda.api.EmbedBuilder
import net.dv8tion.jda.api.entities.User
import java.time.LocalDate
import java.time.LocalDateTime
import kotlin.random.Random
fun EmbedBuilder.colour(): EmbedBuilder {
val rand = Random.nextInt(0x000001, 0xffffff)
return this.setColor(rand)
}
fun EmbedBuilder.footer(user: User): EmbedBuilder {
val date = LocalDateTime.now()
val mon = if (date.month.value > 9) {
date.month.value
} else {
"0${date.month.value}"
}
val str = "${user.name}${date.year}-${mon}-${date.dayOfMonth} ${date.hour}:${date.minute}"
return this.setFooter(str, "${user.avatarUrl}?size=1024")
}

View file

@ -1,5 +1,8 @@
package net.projecttl.p.x32
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import net.dv8tion.jda.api.JDA
import net.projecttl.p.x32.command.Info
import net.projecttl.p.x32.command.PluginCommand
@ -17,6 +20,7 @@ lateinit var database: Database
val logger: Logger = LoggerFactory.getLogger(Px32::class.java)
@OptIn(DelicateCoroutinesApi::class)
fun main() {
println("Px32 version v${DefaultConfig.version}")
if (Config.owner.isBlank() || Config.owner.isEmpty()) {
@ -31,6 +35,9 @@ fun main() {
handler.addCommand(PluginCommand)
jda = kernel.build()
GlobalScope.launch {
kernel.register(jda)
}
}
object Px32

View file

@ -7,6 +7,7 @@ import net.dv8tion.jda.api.interactions.commands.build.CommandData
import net.dv8tion.jda.internal.interactions.CommandDataImpl
import net.projecttl.p.x32.api.command.GlobalCommand
import net.projecttl.p.x32.api.util.colour
import net.projecttl.p.x32.api.util.footer
import net.projecttl.p.x32.kernel.PluginLoader
object PluginCommand : GlobalCommand {
@ -18,6 +19,7 @@ object PluginCommand : GlobalCommand {
setThumbnail(ev.jda.selfUser.avatarUrl)
colour()
footer(ev.user)
}
val loader = PluginLoader.getPlugins()

View file

@ -11,7 +11,7 @@ object Reload : GlobalCommand {
override val data = CommandData.fromData(CommandDataImpl("reload", "플러그인을 다시 불러 옵니다").toData())
override suspend fun execute(ev: SlashCommandInteractionEvent) {
if (kernel.memLock) {
if (kernel.memLock.isLocked) {
return
}
@ -20,13 +20,13 @@ object Reload : GlobalCommand {
}
try {
kernel.reload()
kernel.reload(ev.jda)
} catch (ex: Exception) {
ex.printStackTrace()
ev.reply(":warning: 플러그인을 다시 불러오는 도중에 오류가 발생 했어요. 자세한 내용은 콘솔을 확인해 주세요!").queue()
return
}
ev.reply(":white_check_mark: 플러그인을 다시 불러 왔어요!\n불러온 플러그인 수: ${kernel.plugins().size}").queue()
ev.reply(":white_check_mark: 플러그인을 다시 불러 왔어요!\n불러온 플러그인 수: ${kernel.plugins.size}").queue()
}
}

View file

@ -1,19 +1,16 @@
package net.projecttl.p.x32.kernel
import kotlinx.coroutines.sync.Mutex
import net.dv8tion.jda.api.JDA
import net.dv8tion.jda.api.JDABuilder
import net.dv8tion.jda.api.hooks.ListenerAdapter
import net.dv8tion.jda.api.requests.GatewayIntent
import net.projecttl.p.x32.api.Plugin
import net.projecttl.p.x32.api.command.CommandHandler
import net.projecttl.p.x32.config.Config
import net.projecttl.p.x32.func.BundleModule
import net.projecttl.p.x32.jda
import net.projecttl.p.x32.logger
class CoreKernel(token: String) {
var memLock = false
private set
private val builder = JDABuilder.createDefault(token, listOf(
GatewayIntent.GUILD_PRESENCES,
GatewayIntent.GUILD_MEMBERS,
@ -25,6 +22,9 @@ class CoreKernel(token: String) {
private val handlers = mutableListOf<ListenerAdapter>()
private val commandContainer = CommandHandler()
val memLock = Mutex()
val plugins get() = PluginLoader.getPlugins().map { it.value }
private fun include() {
if (Config.bundle) {
val b = BundleModule()
@ -44,15 +44,11 @@ class CoreKernel(token: String) {
handlers.remove(handler)
}
fun plugins(): List<Plugin> {
return PluginLoader.getPlugins().map { it.value }
}
fun build(): JDA {
include()
PluginLoader.load()
plugins().forEach { plugin ->
plugins.forEach { plugin ->
plugin.handlers.forEach { handler ->
handlers.add(handler)
}
@ -64,7 +60,10 @@ class CoreKernel(token: String) {
}
builder.addEventListeners(commandContainer)
val jda = builder.build()
return builder.build()
}
fun register(jda: JDA) {
commandContainer.register(jda)
handlers.forEach { h ->
if (h is CommandHandler) {
@ -75,18 +74,16 @@ class CoreKernel(token: String) {
Runtime.getRuntime().addShutdownHook(Thread {
PluginLoader.destroy()
})
return jda
}
fun reload() {
if (!memLock) {
memLock = true
suspend fun reload(jda: JDA) {
if (!memLock.isLocked) {
memLock.lock()
}
val newHandlers = mutableListOf<ListenerAdapter>()
PluginLoader.destroy()
plugins().forEach { plugin ->
plugins.forEach { plugin ->
plugin.handlers.forEach { handler ->
if (handlers.contains(handler)) {
jda.removeEventListener(handler)
@ -98,7 +95,7 @@ class CoreKernel(token: String) {
include()
PluginLoader.load()
plugins().forEach { plugin ->
plugins.forEach { plugin ->
plugin.handlers.forEach { handler ->
if (!handlers.contains(handler)) {
handlers.add(handler)
@ -108,15 +105,15 @@ class CoreKernel(token: String) {
}
handlers.map {
builder.addEventListeners(it)
jda.addEventListener(it)
}
newHandlers.forEach { h ->
handlers.forEach { h ->
if (h is CommandHandler) {
h.register(jda)
}
}
memLock = false
memLock.unlock()
}
}

View file

@ -6,6 +6,7 @@ import net.dv8tion.jda.api.interactions.commands.build.CommandData
import net.dv8tion.jda.internal.interactions.CommandDataImpl
import net.projecttl.p.x32.api.command.UserContext
import net.projecttl.p.x32.api.util.colour
import net.projecttl.p.x32.api.util.footer
object Avatar : UserContext {
override val data = CommandData.fromData(CommandDataImpl("avatar", "유저의 프로필 이미지를 가져 옵니다").toData())
@ -15,6 +16,7 @@ object Avatar : UserContext {
embed.setTitle(":frame_photo: ${ev.target.name}'s Avatar")
embed.setImage("${ev.target.effectiveAvatarUrl}?size=512")
embed.colour()
embed.footer(ev.user)
ev.replyEmbeds(embed.build()).queue()
}

View file

@ -3,11 +3,13 @@ package net.projecttl.p.x32.func.command
import net.dv8tion.jda.api.EmbedBuilder
import net.dv8tion.jda.api.JDA
import net.dv8tion.jda.api.entities.MessageEmbed
import net.dv8tion.jda.api.entities.User
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent
import net.dv8tion.jda.api.interactions.commands.build.CommandData
import net.dv8tion.jda.internal.interactions.CommandDataImpl
import net.projecttl.p.x32.api.command.GlobalCommand
import net.projecttl.p.x32.api.util.colour
import net.projecttl.p.x32.api.util.footer
object Ping : GlobalCommand {
override val data: CommandData = CommandData.fromData(CommandDataImpl(
@ -25,17 +27,18 @@ object Ping : GlobalCommand {
}.build()
ev.replyEmbeds(embed).queue {
embed = measure(started, ev.jda)
embed = measure(started, ev.user, ev.jda)
it.editOriginalEmbeds(embed).queue()
}
}
private fun measure(started: Long, jda: JDA): MessageEmbed {
private fun measure(started: Long, user: User, jda: JDA): MessageEmbed {
val embed = EmbedBuilder()
embed.setTitle(":ping_pong: **Pong!**")
embed.addField(":electric_plug: **API**", "`${jda.gatewayPing}ms`", true)
embed.addField(":robot: **BOT**", "`${System.currentTimeMillis() - started}ms`", true)
embed.colour()
embed.footer(user)
return embed.build()
}

View file

@ -10,7 +10,6 @@ class CorePlugin extends Plugin {
logger.info "Hello, World!"
CommandHandler handler = new CommandHandler()
handler.addCommand new Greeting()
addHandler handler
}