Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ makeevrserg.java.ktarget=21
# Project
makeevrserg.project.name=SoulKeeper
makeevrserg.project.group=ru.astrainteractive.soulkeeper
makeevrserg.project.version.string=1.2.9
makeevrserg.project.version.string=1.2.10
makeevrserg.project.description=Keep your items after death
makeevrserg.project.developers=makeevrserg|Makeev Roman|makeevrserg@gmail.com
makeevrserg.project.url=https://github.com/Astra-Interactive/SoulKeeper
Expand Down
3 changes: 2 additions & 1 deletion instances/bukkit/src/main/resources/plugin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ libraries:
- "com.h2database:h2:2.4.240"
commands:
souls:
skreload:
skreload:
soulkrate:
1 change: 1 addition & 0 deletions modules/command-bukkit/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ plugins {

dependencies {
compileOnly(libs.kotlin.coroutines.core)
implementation(libs.kotlin.serialization.json)

implementation(libs.minecraft.astralibs.core)
implementation(libs.minecraft.astralibs.core.bukkit)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package ru.astrainteractive.soulkeeper.command.di
import ru.astrainteractive.astralibs.command.api.registrar.PaperCommandRegistrarContext
import ru.astrainteractive.astralibs.lifecycle.Lifecycle
import ru.astrainteractive.soulkeeper.command.reload.SoulsReloadCommandRegistrar
import ru.astrainteractive.soulkeeper.command.soulkrate.SoulKrateCommandRegistrar
import ru.astrainteractive.soulkeeper.command.souls.SoulsCommandExecutor
import ru.astrainteractive.soulkeeper.command.souls.SoulsListCommandRegistrar
import ru.astrainteractive.soulkeeper.core.di.BukkitCoreModule
Expand Down Expand Up @@ -30,6 +31,12 @@ class CommandModule(
kyoriKrate = coreModule.kyoriComponentSerializer
)
).register()
SoulKrateCommandRegistrar(
registrarContext = paperCommandRegistrar,
stringFormat = coreModule.yamlFormat,
dataFolder = coreModule.dataFolder,
ioScope = coreModule.ioScope
).register()
SoulsReloadCommandRegistrar(
plugin = bukkitCoreModule.plugin,
translationKrate = coreModule.translation,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package ru.astrainteractive.soulkeeper.command.soulkrate

import com.mojang.brigadier.arguments.IntegerArgumentType
import com.mojang.brigadier.arguments.LongArgumentType
import com.mojang.brigadier.arguments.StringArgumentType
import com.mojang.brigadier.tree.LiteralCommandNode
import io.papermc.paper.command.brigadier.CommandSourceStack
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import kotlinx.serialization.StringFormat
import ru.astrainteractive.astralibs.command.api.registrar.PaperCommandRegistrarContext
import ru.astrainteractive.astralibs.command.api.util.argument
import ru.astrainteractive.astralibs.command.api.util.command
import ru.astrainteractive.astralibs.command.api.util.requireArgument
import ru.astrainteractive.astralibs.command.api.util.requirePermission
import ru.astrainteractive.astralibs.command.api.util.requirePlayer
import ru.astrainteractive.astralibs.command.api.util.runs
import ru.astrainteractive.klibs.mikro.core.logging.JUtiltLogger
import ru.astrainteractive.klibs.mikro.core.logging.Logger
import ru.astrainteractive.soulkeeper.core.plugin.PluginPermission
import ru.astrainteractive.soulkeeper.core.serialization.ItemStackSerializer
import ru.astrainteractive.soulkeeper.core.serialization.ItemStackSerializer.decodeFromString
import ru.astrainteractive.soulkeeper.module.souls.database.model.StringFormatObject
import ru.astrainteractive.soulkeeper.module.souls.krate.PlayerSoulKrate
import java.io.File
import java.time.Instant
import java.util.UUID

internal class SoulKrateCommandRegistrar(
private val registrarContext: PaperCommandRegistrarContext,
private val stringFormat: StringFormat,
private val dataFolder: File,
private val ioScope: CoroutineScope
) : Logger by JUtiltLogger("SoulKrateCommandRegistrar") {
private fun createNode(): LiteralCommandNode<CommandSourceStack> {
return command("soulkrate") {
argument("uuid", StringArgumentType.string()) { uuidArg ->
argument("instant", LongArgumentType.longArg()) { instantArg ->
argument("index", IntegerArgumentType.integer()) { indexArg ->
runs { ctx ->
ctx.requirePermission(PluginPermission.LoadSouls)
val player = ctx.requirePlayer()
val instant = ctx.requireArgument(instantArg).let(Instant::ofEpochSecond)
val index = ctx.requireArgument(indexArg)
val uuid = ctx.requireArgument(uuidArg).let(UUID::fromString)
ioScope.launch {
val soul = PlayerSoulKrate(
stringFormat = stringFormat,
dataFolder = dataFolder,
createdAt = instant,
ownerUUID = uuid,
readIndex = index
).getValue()
val items = soul?.items
.orEmpty()
.map(StringFormatObject::raw)
.map(ItemStackSerializer::decodeFromString)
.mapNotNull { itemStackResult ->
itemStackResult
.onFailure { error(it) { "Failed to deserialize item stack" } }
.getOrNull()
}
player.inventory.addItem(*items.toTypedArray())
}
}
}
}
}
}.build()
}

fun register() {
registrarContext.registerWhenReady(createNode())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ sealed class PluginPermission(override val value: String) : Permission {
data object ViewAllSouls : PluginPermission("soulkeeper.all")
data object FreeAllSouls : PluginPermission("soulkeeper.free.all")
data object TeleportToSouls : PluginPermission("soulkeeper.teleport")
data object LoadSouls : PluginPermission("soulkeeper.load")
}
3 changes: 3 additions & 0 deletions modules/dao/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
plugins {
kotlin("jvm")
kotlin("plugin.serialization")
}

dependencies {
Expand All @@ -8,8 +9,10 @@ dependencies {
implementation(libs.exposed.dao)
implementation(libs.exposed.jdbc)
implementation(libs.exposed.java.time)
implementation(libs.kotlin.serialization.json)
// AstraLibs
implementation(libs.minecraft.astralibs.core)
implementation(libs.klibs.mikro.extensions)
implementation(libs.klibs.mikro.core)
implementation(libs.klibs.kstorage)
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
package ru.astrainteractive.soulkeeper.module.souls.database.model

import kotlinx.serialization.Serializable
import ru.astrainteractive.astralibs.server.location.Location
import ru.astrainteractive.klibs.mikro.extensions.serialization.JInstantSerializer
import ru.astrainteractive.klibs.mikro.extensions.serialization.UUIDSerializer
import java.time.Instant
import java.util.UUID

@Serializable
data class DefaultSoul(
@Serializable(with = UUIDSerializer::class)
override val ownerUUID: UUID,
override val ownerLastName: String,
@Serializable(with = JInstantSerializer::class)
override val createdAt: Instant,
override val isFree: Boolean,
override val location: Location,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
package ru.astrainteractive.soulkeeper.module.souls.database.model

import kotlinx.serialization.Serializable

@Serializable
data class StringFormatObject(val raw: String)
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package ru.astrainteractive.soulkeeper.module.souls.krate

import kotlinx.serialization.StringFormat
import ru.astrainteractive.astralibs.util.parse
import ru.astrainteractive.astralibs.util.writeIntoFile
import ru.astrainteractive.klibs.kstorage.suspend.SuspendMutableKrate
import ru.astrainteractive.klibs.kstorage.suspend.impl.DefaultSuspendMutableKrate
import ru.astrainteractive.klibs.mikro.core.logging.JUtiltLogger
import ru.astrainteractive.klibs.mikro.core.logging.Logger
import ru.astrainteractive.soulkeeper.module.souls.database.model.DefaultSoul
import java.io.File
import java.time.Instant
import java.util.UUID

class PlayerSoulKrate(
stringFormat: StringFormat,
private val dataFolder: File,
private val createdAt: Instant,
private val ownerUUID: UUID,
private val readIndex: Int = 0
) : SuspendMutableKrate<DefaultSoul?>, Logger by JUtiltLogger("SoulKeeper-PlayerSoulKrate") {
private fun createFile(): File {
val parentDir = dataFolder.resolve("$ownerUUID")
parentDir.mkdirs()

var index = 0
var file: File
do {
file = parentDir.resolve("${createdAt.epochSecond}_$index.yml")
index++
} while (file.exists())
file.createNewFile()
return file
}

private val krate = DefaultSuspendMutableKrate(
factory = { null },
loader = {
val file = dataFolder
.resolve("$ownerUUID")
.resolve("${createdAt.epochSecond}_$readIndex.yml")
stringFormat.parse<DefaultSoul>(file)
.onFailure { error(it) { "Failed to load soul for $ownerUUID" } }
.getOrNull()
},
saver = saver@{ defaultSoul ->
val file = createFile()
if (defaultSoul == null) {
file.renameTo(file.resolveSibling("${file.nameWithoutExtension}.deleted"))
return@saver
}
stringFormat.writeIntoFile(defaultSoul, file)
}
)

override suspend fun save(value: DefaultSoul?) {
krate.save(value)
}

override suspend fun reset() {
krate.reset()
}

override suspend fun getValue(): DefaultSoul? {
return krate.getValue()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ class BukkitEventModule(
private val event = BukkitSoulEvents(
soulsDao = soulsDaoModule.soulsDao,
soulsConfigKrate = coreModule.soulsConfigKrate,
ioScope = coreModule.ioScope,
dataFolder = coreModule.dataFolder,
stringFormat = coreModule.yamlFormat
)
val lifecycle = Lifecycle.Lambda(
onEnable = {
Expand Down
Loading
Loading