mirror of
https://github.com/GayPizzaSpecifications/foundation.git
synced 2025-08-02 21:20:55 +00:00
Major refactoring to use Koin.
This commit is contained in:
parent
f8178c2307
commit
13479b1ae3
@ -82,6 +82,9 @@ subprojects {
|
|||||||
implementation(platform("org.jetbrains.kotlin:kotlin-bom"))
|
implementation(platform("org.jetbrains.kotlin:kotlin-bom"))
|
||||||
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
|
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
|
||||||
|
|
||||||
|
implementation("io.insert-koin:koin-core:3.1.4")
|
||||||
|
testImplementation("io.insert-koin:koin-test:3.1.4")
|
||||||
|
|
||||||
// Serialization
|
// Serialization
|
||||||
implementation("com.charleskorn.kaml:kaml:0.38.0")
|
implementation("com.charleskorn.kaml:kaml:0.38.0")
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.1")
|
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.1")
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
dependencies {
|
dependencies {
|
||||||
// TODO: might be able to ship all dependencies in core? are we duplicating classes in JARs?
|
// TODO: might be able to ship all dependencies in core? are we duplicating classes in JARs?
|
||||||
|
|
||||||
|
implementation("software.amazon.awssdk:s3:2.17.102")
|
||||||
}
|
}
|
||||||
|
@ -1,27 +1,27 @@
|
|||||||
package cloud.kubelet.foundation.core
|
package cloud.kubelet.foundation.core
|
||||||
|
|
||||||
import cloud.kubelet.foundation.core.command.*
|
import cloud.kubelet.foundation.core.abstraction.Feature
|
||||||
import cloud.kubelet.foundation.core.devupdate.DevUpdateServer
|
import cloud.kubelet.foundation.core.abstraction.FoundationPlugin
|
||||||
import cloud.kubelet.foundation.core.persist.PersistentStore
|
import cloud.kubelet.foundation.core.features.backup.BackupFeature
|
||||||
import cloud.kubelet.foundation.core.persist.setAllProperties
|
import cloud.kubelet.foundation.core.features.dev.DevFeature
|
||||||
import io.papermc.paper.event.player.AsyncChatEvent
|
import cloud.kubelet.foundation.core.features.player.PlayerFeature
|
||||||
import net.kyori.adventure.text.Component
|
import cloud.kubelet.foundation.core.features.stats.StatsFeature
|
||||||
import net.kyori.adventure.text.TextComponent
|
import cloud.kubelet.foundation.core.features.update.UpdateFeature
|
||||||
import org.bukkit.GameMode
|
import cloud.kubelet.foundation.core.features.world.WorldFeature
|
||||||
import org.bukkit.command.CommandExecutor
|
import org.koin.dsl.module
|
||||||
import org.bukkit.command.TabCompleter
|
|
||||||
import org.bukkit.event.EventHandler
|
|
||||||
import org.bukkit.event.Listener
|
|
||||||
import org.bukkit.plugin.java.JavaPlugin
|
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.time.Instant
|
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
|
||||||
|
|
||||||
class FoundationCorePlugin : JavaPlugin(), Listener {
|
class FoundationCorePlugin : FoundationPlugin() {
|
||||||
internal val persistentStores = ConcurrentHashMap<String, PersistentStore>()
|
|
||||||
private lateinit var _pluginDataPath: Path
|
private lateinit var _pluginDataPath: Path
|
||||||
private lateinit var chatLogStore: PersistentStore
|
override val features: List<Feature>
|
||||||
private lateinit var devUpdateServer: DevUpdateServer
|
get() = listOf(
|
||||||
|
BackupFeature(),
|
||||||
|
DevFeature(),
|
||||||
|
PlayerFeature(),
|
||||||
|
StatsFeature(),
|
||||||
|
UpdateFeature(),
|
||||||
|
WorldFeature(),
|
||||||
|
)
|
||||||
|
|
||||||
var pluginDataPath: Path
|
var pluginDataPath: Path
|
||||||
/**
|
/**
|
||||||
@ -38,104 +38,15 @@ class FoundationCorePlugin : JavaPlugin(), Listener {
|
|||||||
_pluginDataPath = value
|
_pluginDataPath = value
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
override fun module() = module {
|
||||||
* Fetch a persistent store by name. Make sure the name is path-safe, descriptive and consistent across server runs.
|
single { this@FoundationCorePlugin }
|
||||||
*/
|
}
|
||||||
fun getPersistentStore(name: String) = persistentStores.getOrPut(name) { PersistentStore(this, name) }
|
|
||||||
|
|
||||||
override fun onEnable() {
|
override fun onEnable() {
|
||||||
|
// Create core plugin directory.
|
||||||
pluginDataPath = dataFolder.toPath()
|
pluginDataPath = dataFolder.toPath()
|
||||||
val backupPath = pluginDataPath.resolve(BACKUPS_DIRECTORY)
|
|
||||||
|
|
||||||
// Create Foundation plugin directories.
|
|
||||||
pluginDataPath.toFile().mkdir()
|
pluginDataPath.toFile().mkdir()
|
||||||
backupPath.toFile().mkdir()
|
|
||||||
|
|
||||||
// Register this as an event listener.
|
super.onEnable()
|
||||||
server.pluginManager.registerEvents(this, this)
|
|
||||||
|
|
||||||
// Register commands.
|
|
||||||
registerCommandExecutor("fbackup", BackupCommand(this, backupPath))
|
|
||||||
registerCommandExecutor("fupdate", UpdateCommand())
|
|
||||||
registerCommandExecutor(listOf("survival", "s"), GamemodeCommand(GameMode.SURVIVAL))
|
|
||||||
registerCommandExecutor(listOf("creative", "c"), GamemodeCommand(GameMode.CREATIVE))
|
|
||||||
registerCommandExecutor(listOf("adventure", "a"), GamemodeCommand(GameMode.ADVENTURE))
|
|
||||||
registerCommandExecutor(listOf("spectator", "sp"), GamemodeCommand(GameMode.SPECTATOR))
|
|
||||||
registerCommandExecutor(listOf("leaderboard", "lb"), LeaderboardCommand())
|
|
||||||
registerCommandExecutor("pstore", PersistentStoreCommand(this))
|
|
||||||
registerCommandExecutor("setspawn", SetSpawnCommand())
|
|
||||||
registerCommandExecutor("spawn", SpawnCommand())
|
|
||||||
|
|
||||||
val log = slF4JLogger
|
|
||||||
log.info("Features:")
|
|
||||||
Util.printFeatureStatus(log, "Backup", BACKUP_ENABLED)
|
|
||||||
chatLogStore = getPersistentStore("chat-logs")
|
|
||||||
devUpdateServer = DevUpdateServer(this)
|
|
||||||
devUpdateServer.enable()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDisable() {
|
|
||||||
persistentStores.values.forEach { store -> store.close() }
|
|
||||||
persistentStores.clear()
|
|
||||||
devUpdateServer.disable()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun registerCommandExecutor(name: String, executor: CommandExecutor) {
|
|
||||||
registerCommandExecutor(listOf(name), executor)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun registerCommandExecutor(names: List<String>, executor: CommandExecutor) {
|
|
||||||
for (name in names) {
|
|
||||||
val command = getCommand(name) ?: throw Exception("Failed to get $name command")
|
|
||||||
command.setExecutor(executor)
|
|
||||||
if (executor is TabCompleter) {
|
|
||||||
command.tabCompleter = executor
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Disabling chat reformatting until I do something with it and figure out how to make it
|
|
||||||
// be less disruptive.
|
|
||||||
/*@EventHandler
|
|
||||||
private fun onChatMessage(e: ChatEvent) {
|
|
||||||
return
|
|
||||||
e.isCancelled = true
|
|
||||||
val name = e.player.displayName()
|
|
||||||
val component = Component.empty()
|
|
||||||
.append(leftBracket)
|
|
||||||
.append(name)
|
|
||||||
.append(rightBracket)
|
|
||||||
.append(Component.text(' '))
|
|
||||||
.append(e.message())
|
|
||||||
server.sendMessage(component)
|
|
||||||
}*/
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
private fun logOnChatMessage(e: AsyncChatEvent) {
|
|
||||||
val player = e.player
|
|
||||||
val message = e.message()
|
|
||||||
|
|
||||||
if (message !is TextComponent) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val content = message.content()
|
|
||||||
chatLogStore.create("ChatMessageEvent") {
|
|
||||||
setAllProperties(
|
|
||||||
"timestamp" to Instant.now().toEpochMilli(),
|
|
||||||
"player.id" to player.identity().uuid().toString(),
|
|
||||||
"player.name" to player.name,
|
|
||||||
"message.content" to content
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private const val BACKUPS_DIRECTORY = "backups"
|
|
||||||
|
|
||||||
private val leftBracket: Component = Component.text('[')
|
|
||||||
private val rightBracket: Component = Component.text(']')
|
|
||||||
|
|
||||||
const val BACKUP_ENABLED = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,10 +11,6 @@ object Util {
|
|||||||
private val whitespace: Component = Component.text(' ')
|
private val whitespace: Component = Component.text(' ')
|
||||||
private val foundationName: Component = Component.text("Foundation")
|
private val foundationName: Component = Component.text("Foundation")
|
||||||
|
|
||||||
fun printFeatureStatus(logger: Logger, feature: String?, state: Boolean) {
|
|
||||||
logger.info("{}: {}", feature, if (state) "Enabled" else "Disabled")
|
|
||||||
}
|
|
||||||
|
|
||||||
fun formatSystemMessage(message: String): Component {
|
fun formatSystemMessage(message: String): Component {
|
||||||
return formatSystemMessage(TextColors.AMARANTH_PINK, message)
|
return formatSystemMessage(TextColors.AMARANTH_PINK, message)
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
package cloud.kubelet.foundation.core.abstraction
|
||||||
|
|
||||||
|
import cloud.kubelet.foundation.core.FoundationCorePlugin
|
||||||
|
import org.bukkit.command.CommandExecutor
|
||||||
|
import org.bukkit.command.TabCompleter
|
||||||
|
import org.bukkit.event.Listener
|
||||||
|
import org.koin.core.component.KoinComponent
|
||||||
|
import org.koin.core.component.inject
|
||||||
|
import org.koin.dsl.module
|
||||||
|
|
||||||
|
abstract class Feature : KoinComponent, Listener {
|
||||||
|
private val plugin by inject<FoundationCorePlugin>()
|
||||||
|
|
||||||
|
open fun enable() {}
|
||||||
|
open fun disable() {}
|
||||||
|
open fun module() = module {}
|
||||||
|
|
||||||
|
protected fun registerCommandExecutor(name: String, executor: CommandExecutor) {
|
||||||
|
registerCommandExecutor(listOf(name), executor)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun registerCommandExecutor(names: List<String>, executor: CommandExecutor) {
|
||||||
|
for (name in names) {
|
||||||
|
val command = plugin.getCommand(name) ?: throw Exception("Failed to get $name command")
|
||||||
|
command.setExecutor(executor)
|
||||||
|
if (executor is TabCompleter) {
|
||||||
|
command.tabCompleter = executor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
package cloud.kubelet.foundation.core.abstraction
|
||||||
|
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin
|
||||||
|
import org.koin.core.KoinApplication
|
||||||
|
import org.koin.core.context.startKoin
|
||||||
|
import org.koin.core.context.stopKoin
|
||||||
|
import org.koin.core.module.Module
|
||||||
|
import org.koin.dsl.module
|
||||||
|
|
||||||
|
abstract class FoundationPlugin : JavaPlugin() {
|
||||||
|
private lateinit var pluginModule: Module
|
||||||
|
private lateinit var pluginApplication: KoinApplication
|
||||||
|
protected abstract val features: List<Feature>
|
||||||
|
|
||||||
|
override fun onEnable() {
|
||||||
|
pluginModule = module {
|
||||||
|
single { this@FoundationPlugin }
|
||||||
|
single { server }
|
||||||
|
single { config }
|
||||||
|
single { slF4JLogger }
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: If we have another plugin using this class, we may need to use context isolation.
|
||||||
|
// https://insert-koin.io/docs/reference/koin-core/context-isolation
|
||||||
|
pluginApplication = startKoin {
|
||||||
|
modules(pluginModule)
|
||||||
|
modules(module())
|
||||||
|
}
|
||||||
|
|
||||||
|
features.forEach {
|
||||||
|
pluginApplication.modules(it.module())
|
||||||
|
}
|
||||||
|
|
||||||
|
features.forEach {
|
||||||
|
try {
|
||||||
|
slF4JLogger.info("Enabling feature: ${it.javaClass.simpleName}")
|
||||||
|
it.enable()
|
||||||
|
server.pluginManager.registerEvents(it, this)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
slF4JLogger.error("Failed to enable feature: ${it.javaClass.simpleName}", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDisable() {
|
||||||
|
features.forEach {
|
||||||
|
it.disable()
|
||||||
|
}
|
||||||
|
|
||||||
|
stopKoin()
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun module() = module {}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package cloud.kubelet.foundation.core.command
|
package cloud.kubelet.foundation.core.features.backup
|
||||||
|
|
||||||
import cloud.kubelet.foundation.core.FoundationCorePlugin
|
import cloud.kubelet.foundation.core.FoundationCorePlugin
|
||||||
import cloud.kubelet.foundation.core.Util
|
import cloud.kubelet.foundation.core.Util
|
||||||
@ -26,15 +26,6 @@ class BackupCommand(
|
|||||||
override fun onCommand(
|
override fun onCommand(
|
||||||
sender: CommandSender, command: Command, label: String, args: Array<String>
|
sender: CommandSender, command: Command, label: String, args: Array<String>
|
||||||
): Boolean {
|
): Boolean {
|
||||||
if (!FoundationCorePlugin.BACKUP_ENABLED) {
|
|
||||||
sender.sendMessage(
|
|
||||||
Component
|
|
||||||
.text("Backup is not enabled.")
|
|
||||||
.color(TextColor.fromHexString("#FF0000"))
|
|
||||||
)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
if (RUNNING.get()) {
|
if (RUNNING.get()) {
|
||||||
sender.sendMessage(
|
sender.sendMessage(
|
||||||
Component
|
Component
|
@ -0,0 +1,21 @@
|
|||||||
|
package cloud.kubelet.foundation.core.features.backup
|
||||||
|
|
||||||
|
import cloud.kubelet.foundation.core.FoundationCorePlugin
|
||||||
|
import cloud.kubelet.foundation.core.abstraction.Feature
|
||||||
|
import org.koin.core.component.inject
|
||||||
|
|
||||||
|
class BackupFeature : Feature() {
|
||||||
|
private val plugin by inject<FoundationCorePlugin>()
|
||||||
|
|
||||||
|
override fun enable() {
|
||||||
|
// Create backup directory.
|
||||||
|
val backupPath = plugin.pluginDataPath.resolve(BACKUPS_DIRECTORY)
|
||||||
|
backupPath.toFile().mkdir()
|
||||||
|
|
||||||
|
registerCommandExecutor("fbackup", BackupCommand(plugin, backupPath))
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val BACKUPS_DIRECTORY = "backups"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package cloud.kubelet.foundation.core.features.dev
|
||||||
|
|
||||||
|
import cloud.kubelet.foundation.core.FoundationCorePlugin
|
||||||
|
import cloud.kubelet.foundation.core.abstraction.Feature
|
||||||
|
import cloud.kubelet.foundation.core.devupdate.DevUpdateServer
|
||||||
|
import org.koin.core.component.inject
|
||||||
|
|
||||||
|
class DevFeature : Feature() {
|
||||||
|
private val plugin = inject<FoundationCorePlugin>()
|
||||||
|
private lateinit var devUpdateServer: DevUpdateServer
|
||||||
|
|
||||||
|
override fun enable() {
|
||||||
|
devUpdateServer = DevUpdateServer(plugin.value)
|
||||||
|
devUpdateServer.enable()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun disable() {
|
||||||
|
devUpdateServer.disable()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
package cloud.kubelet.foundation.core.features.player
|
||||||
|
|
||||||
|
import cloud.kubelet.foundation.core.abstraction.Feature
|
||||||
|
import cloud.kubelet.foundation.core.command.GamemodeCommand
|
||||||
|
import org.bukkit.GameMode
|
||||||
|
|
||||||
|
class PlayerFeature : Feature() {
|
||||||
|
override fun enable() {
|
||||||
|
registerCommandExecutor(listOf("survival", "s"), GamemodeCommand(GameMode.SURVIVAL))
|
||||||
|
registerCommandExecutor(listOf("creative", "c"), GamemodeCommand(GameMode.CREATIVE))
|
||||||
|
registerCommandExecutor(listOf("adventure", "a"), GamemodeCommand(GameMode.ADVENTURE))
|
||||||
|
registerCommandExecutor(listOf("spectator", "sp"), GamemodeCommand(GameMode.SPECTATOR))
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package cloud.kubelet.foundation.core.command
|
package cloud.kubelet.foundation.core.features.stats
|
||||||
|
|
||||||
import cloud.kubelet.foundation.core.SortOrder
|
import cloud.kubelet.foundation.core.SortOrder
|
||||||
import cloud.kubelet.foundation.core.allPlayerStatisticsOf
|
import cloud.kubelet.foundation.core.allPlayerStatisticsOf
|
@ -1,15 +1,21 @@
|
|||||||
package cloud.kubelet.foundation.core.command
|
package cloud.kubelet.foundation.core.features.stats
|
||||||
|
|
||||||
import cloud.kubelet.foundation.core.FoundationCorePlugin
|
|
||||||
import org.bukkit.command.Command
|
import org.bukkit.command.Command
|
||||||
import org.bukkit.command.CommandExecutor
|
import org.bukkit.command.CommandExecutor
|
||||||
import org.bukkit.command.CommandSender
|
import org.bukkit.command.CommandSender
|
||||||
import org.bukkit.command.TabCompleter
|
import org.bukkit.command.TabCompleter
|
||||||
|
|
||||||
class PersistentStoreCommand(private val plugin: FoundationCorePlugin) : CommandExecutor, TabCompleter {
|
class PersistentStoreCommand(
|
||||||
|
private val statsFeature: StatsFeature
|
||||||
|
) : CommandExecutor, TabCompleter {
|
||||||
private val allSubCommands = mutableListOf("stats", "sample", "delete-all-entities")
|
private val allSubCommands = mutableListOf("stats", "sample", "delete-all-entities")
|
||||||
|
|
||||||
override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array<out String>): Boolean {
|
override fun onCommand(
|
||||||
|
sender: CommandSender,
|
||||||
|
command: Command,
|
||||||
|
label: String,
|
||||||
|
args: Array<out String>
|
||||||
|
): Boolean {
|
||||||
if (args.isEmpty()) {
|
if (args.isEmpty()) {
|
||||||
sender.sendMessage("Invalid Command Usage.")
|
sender.sendMessage("Invalid Command Usage.")
|
||||||
return true
|
return true
|
||||||
@ -17,7 +23,7 @@ class PersistentStoreCommand(private val plugin: FoundationCorePlugin) : Command
|
|||||||
|
|
||||||
when (args[0]) {
|
when (args[0]) {
|
||||||
"stats" -> {
|
"stats" -> {
|
||||||
plugin.persistentStores.forEach { (name, store) ->
|
statsFeature.persistentStores.forEach { (name, store) ->
|
||||||
val counts = store.transact {
|
val counts = store.transact {
|
||||||
entityTypes.associateWith { type -> getAll(type).size() }.toSortedMap()
|
entityTypes.associateWith { type -> getAll(type).size() }.toSortedMap()
|
||||||
}
|
}
|
||||||
@ -36,7 +42,7 @@ class PersistentStoreCommand(private val plugin: FoundationCorePlugin) : Command
|
|||||||
|
|
||||||
val storeName = args[1]
|
val storeName = args[1]
|
||||||
val entityTypeName = args[2]
|
val entityTypeName = args[2]
|
||||||
val store = plugin.getPersistentStore(storeName)
|
val store = statsFeature.getPersistentStore(storeName)
|
||||||
store.transact {
|
store.transact {
|
||||||
val entities = getAll(entityTypeName).take(3)
|
val entities = getAll(entityTypeName).take(3)
|
||||||
for (entity in entities) {
|
for (entity in entities) {
|
||||||
@ -55,7 +61,7 @@ class PersistentStoreCommand(private val plugin: FoundationCorePlugin) : Command
|
|||||||
|
|
||||||
val storeName = args[1]
|
val storeName = args[1]
|
||||||
val entityTypeName = args[2]
|
val entityTypeName = args[2]
|
||||||
val store = plugin.getPersistentStore(storeName)
|
val store = statsFeature.getPersistentStore(storeName)
|
||||||
store.transact {
|
store.transact {
|
||||||
store.deleteAllEntities(entityTypeName)
|
store.deleteAllEntities(entityTypeName)
|
||||||
}
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
package cloud.kubelet.foundation.core.features.stats
|
||||||
|
|
||||||
|
import cloud.kubelet.foundation.core.FoundationCorePlugin
|
||||||
|
import cloud.kubelet.foundation.core.abstraction.Feature
|
||||||
|
import cloud.kubelet.foundation.core.persist.PersistentStore
|
||||||
|
import cloud.kubelet.foundation.core.persist.setAllProperties
|
||||||
|
import io.papermc.paper.event.player.AsyncChatEvent
|
||||||
|
import net.kyori.adventure.text.TextComponent
|
||||||
|
import org.bukkit.event.EventHandler
|
||||||
|
import org.koin.core.component.inject
|
||||||
|
import java.time.Instant
|
||||||
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
|
||||||
|
class StatsFeature : Feature() {
|
||||||
|
private val plugin = inject<FoundationCorePlugin>()
|
||||||
|
private lateinit var chatLogStore: PersistentStore
|
||||||
|
// TODO: Move persistence stuff to its own module.
|
||||||
|
internal val persistentStores = ConcurrentHashMap<String, PersistentStore>()
|
||||||
|
|
||||||
|
override fun enable() {
|
||||||
|
chatLogStore = getPersistentStore("chat-logs")
|
||||||
|
|
||||||
|
registerCommandExecutor("pstore", PersistentStoreCommand(this))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun disable() {
|
||||||
|
persistentStores.values.forEach { store -> store.close() }
|
||||||
|
persistentStores.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch a persistent store by name. Make sure the name is path-safe, descriptive and consistent across server runs.
|
||||||
|
*/
|
||||||
|
fun getPersistentStore(name: String) =
|
||||||
|
persistentStores.getOrPut(name) { PersistentStore(plugin.value, name) }
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
private fun logOnChatMessage(e: AsyncChatEvent) {
|
||||||
|
val player = e.player
|
||||||
|
val message = e.message()
|
||||||
|
|
||||||
|
if (message !is TextComponent) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val content = message.content()
|
||||||
|
chatLogStore.create("ChatMessageEvent") {
|
||||||
|
setAllProperties(
|
||||||
|
"timestamp" to Instant.now().toEpochMilli(),
|
||||||
|
"player.id" to player.identity().uuid().toString(),
|
||||||
|
"player.name" to player.name,
|
||||||
|
"message.content" to content
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package cloud.kubelet.foundation.core.update
|
package cloud.kubelet.foundation.core.features.update
|
||||||
|
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|
@ -1,6 +1,5 @@
|
|||||||
package cloud.kubelet.foundation.core.command
|
package cloud.kubelet.foundation.core.features.update
|
||||||
|
|
||||||
import cloud.kubelet.foundation.core.service.UpdateService
|
|
||||||
import org.bukkit.command.Command
|
import org.bukkit.command.Command
|
||||||
import org.bukkit.command.CommandExecutor
|
import org.bukkit.command.CommandExecutor
|
||||||
import org.bukkit.command.CommandSender
|
import org.bukkit.command.CommandSender
|
||||||
@ -15,4 +14,4 @@ class UpdateCommand : CommandExecutor {
|
|||||||
UpdateService.updatePlugins(sender)
|
UpdateService.updatePlugins(sender)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package cloud.kubelet.foundation.core.features.update
|
||||||
|
|
||||||
|
import cloud.kubelet.foundation.core.abstraction.Feature
|
||||||
|
|
||||||
|
class UpdateFeature : Feature() {
|
||||||
|
override fun enable() {
|
||||||
|
registerCommandExecutor("fupdate", UpdateCommand())
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,10 @@
|
|||||||
package cloud.kubelet.foundation.core.service
|
package cloud.kubelet.foundation.core.features.update
|
||||||
|
|
||||||
import cloud.kubelet.foundation.core.update.UpdateUtil
|
|
||||||
import org.bukkit.command.CommandSender
|
import org.bukkit.command.CommandSender
|
||||||
import kotlin.io.path.name
|
import kotlin.io.path.name
|
||||||
import kotlin.io.path.toPath
|
import kotlin.io.path.toPath
|
||||||
|
|
||||||
// TODO: Switch to classes and use dependency injection with koin.
|
// TODO: Switch to a class and use dependency injection with koin.
|
||||||
object UpdateService {
|
object UpdateService {
|
||||||
fun updatePlugins(sender: CommandSender, onFinish: (() -> Unit)? = null) {
|
fun updatePlugins(sender: CommandSender, onFinish: (() -> Unit)? = null) {
|
||||||
val updateDir = sender.server.pluginsFolder.resolve("update")
|
val updateDir = sender.server.pluginsFolder.resolve("update")
|
@ -1,4 +1,4 @@
|
|||||||
package cloud.kubelet.foundation.core.update
|
package cloud.kubelet.foundation.core.features.update
|
||||||
|
|
||||||
import kotlinx.serialization.DeserializationStrategy
|
import kotlinx.serialization.DeserializationStrategy
|
||||||
import kotlinx.serialization.builtins.MapSerializer
|
import kotlinx.serialization.builtins.MapSerializer
|
@ -0,0 +1,14 @@
|
|||||||
|
package cloud.kubelet.foundation.core.features.world
|
||||||
|
|
||||||
|
import cloud.kubelet.foundation.core.abstraction.Feature
|
||||||
|
import cloud.kubelet.foundation.core.command.GamemodeCommand
|
||||||
|
import cloud.kubelet.foundation.core.command.SetSpawnCommand
|
||||||
|
import cloud.kubelet.foundation.core.command.SpawnCommand
|
||||||
|
import org.bukkit.GameMode
|
||||||
|
|
||||||
|
class WorldFeature : Feature() {
|
||||||
|
override fun enable() {
|
||||||
|
registerCommandExecutor("setspawn", SetSpawnCommand())
|
||||||
|
registerCommandExecutor("spawn", SpawnCommand())
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user