From 5d1f7013ce32b5f688b01ece3edacca87bbcd3ac Mon Sep 17 00:00:00 2001 From: PrexorJustin Date: Fri, 10 Jan 2025 01:51:24 +0100 Subject: [PATCH 1/9] refactor: reworked rules and matcher --- gradle/libs.versions.toml | 6 +- .../sign/paper/PaperSignStateManager.kt | 4 +- .../sign/paper/PaperSignsPluginBootstrap.kt | 40 ++-- .../sign/paper/listener/SignListener.kt | 10 +- .../sign/paper/rule/PaperRuleRegistry.kt | 11 - .../plugin/sign/paper/rule/PaperSignRules.kt | 20 -- .../sign/paper/rule/PlayerRuleContext.kt | 21 -- .../sign/paper/sender/PaperCommandSender.kt | 6 +- .../sign/paper/service/PaperSignService.kt | 19 +- sign-shared/build.gradle.kts | 2 +- .../plugin/sign/shared/LocationMapper.kt | 6 +- .../plugin/sign/shared/SignManager.kt | 100 +++----- .../plugin/sign/shared/SignManagerProvider.kt | 12 + .../plugin/sign/shared/SignState.kt | 4 - .../plugin/sign/shared/command/SignCommand.kt | 8 +- .../sign/shared/command/SignStateManager.kt | 4 +- .../sign/shared/config/layout/LayoutConfig.kt | 27 +-- .../shared/config/location/LocationsConfig.kt | 2 +- ...{SignLocation.kt => SignLocationConfig.kt} | 2 +- .../config/matcher/MatcherConfigEntry.kt | 10 - .../sign/shared/config/matcher/MatcherType.kt | 8 - .../operations/ContainsOperationMatcher.kt | 12 - .../operations/EndsWithOperationMatcher.kt | 12 - .../EqualsIgnoreCaseOperationMatcher.kt | 12 - .../operations/EqualsOperationMatcher.kt | 12 - .../matcher/operations/MatcherOperations.kt | 18 -- .../operations/NotEqualsOperationMatcher.kt | 12 - .../matcher/operations/OperationMatcher.kt | 7 - .../operations/PatternOperationMatcher.kt | 13 - .../operations/RegexOperationMatcher.kt | 12 - .../operations/StartsWithOperationMatcher.kt | 12 - .../sign/shared/config/rule/RuleConfig.kt | 15 ++ .../sign/shared/matcher/MatcherConfigEntry.kt | 12 + .../plugin/sign/shared/matcher/MatcherType.kt | 8 + .../ResourcedYamlDirectoryRepository.kt | 79 ++++++ .../repository/base/LoadableRepository.kt | 7 - .../sign/shared/repository/base/Repository.kt | 8 - .../base/YamlDirectoryRepository.kt | 225 ------------------ .../repository/layout/LayoutRepository.kt | 10 +- .../location/LocationsRepository.kt | 13 +- .../shared/repository/rule/RuleRepository.kt | 22 ++ .../plugin/sign/shared/rule/RuleChecker.kt | 9 - .../plugin/sign/shared/rule/RuleRegistry.kt | 39 --- .../plugin/sign/shared/rule/SignRule.kt | 11 - .../sign/shared/rule/context/RuleContext.kt | 5 + .../rule/context/impl/ServerRuleContext.kt | 9 + .../shared/rule/impl/DefaultRuleRegistry.kt | 34 --- .../sign/shared/rule/impl/DefaultSignRules.kt | 58 ----- .../sign/shared/rule/impl/RuleContext.kt | 10 - .../rule/serialize/SignRuleSerializer.kt | 26 -- .../sign/shared/sender/SignCommandSender.kt | 4 +- .../plugin/sign/shared/service/SignService.kt | 15 +- .../plugin/sign/shared/utils/MatcherUtil.kt | 98 ++++++++ .../main/resources/layouts/empty_default.yml | 9 +- .../main/resources/layouts/full_default.yml | 9 +- .../resources/layouts/maintenance_default.yml | 9 +- .../resources/layouts/offline_default.yml | 1 - .../main/resources/layouts/online_default.yml | 3 +- .../resources/layouts/starting_default.yml | 1 - .../src/main/resources/rules/available.yml | 7 + .../src/main/resources/rules/offline.yml | 7 + .../src/main/resources/rules/starting.yml | 7 + 62 files changed, 424 insertions(+), 790 deletions(-) delete mode 100644 sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/rule/PaperRuleRegistry.kt delete mode 100644 sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/rule/PaperSignRules.kt delete mode 100644 sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/rule/PlayerRuleContext.kt create mode 100644 sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/SignManagerProvider.kt rename sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/location/{SignLocation.kt => SignLocationConfig.kt} (89%) delete mode 100644 sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/MatcherConfigEntry.kt delete mode 100644 sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/MatcherType.kt delete mode 100644 sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/ContainsOperationMatcher.kt delete mode 100644 sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/EndsWithOperationMatcher.kt delete mode 100644 sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/EqualsIgnoreCaseOperationMatcher.kt delete mode 100644 sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/EqualsOperationMatcher.kt delete mode 100644 sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/MatcherOperations.kt delete mode 100644 sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/NotEqualsOperationMatcher.kt delete mode 100644 sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/OperationMatcher.kt delete mode 100644 sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/PatternOperationMatcher.kt delete mode 100644 sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/RegexOperationMatcher.kt delete mode 100644 sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/StartsWithOperationMatcher.kt create mode 100644 sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/rule/RuleConfig.kt create mode 100644 sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/matcher/MatcherConfigEntry.kt create mode 100644 sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/matcher/MatcherType.kt create mode 100644 sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/ResourcedYamlDirectoryRepository.kt delete mode 100644 sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/base/LoadableRepository.kt delete mode 100644 sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/base/Repository.kt delete mode 100644 sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/base/YamlDirectoryRepository.kt create mode 100644 sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/rule/RuleRepository.kt delete mode 100644 sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/RuleChecker.kt delete mode 100644 sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/RuleRegistry.kt delete mode 100644 sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/SignRule.kt create mode 100644 sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/context/RuleContext.kt create mode 100644 sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/context/impl/ServerRuleContext.kt delete mode 100644 sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/impl/DefaultRuleRegistry.kt delete mode 100644 sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/impl/DefaultSignRules.kt delete mode 100644 sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/impl/RuleContext.kt delete mode 100644 sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/serialize/SignRuleSerializer.kt create mode 100644 sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/utils/MatcherUtil.kt create mode 100644 sign-shared/src/main/resources/rules/available.yml create mode 100644 sign-shared/src/main/resources/rules/offline.yml create mode 100644 sign-shared/src/main/resources/rules/starting.yml diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 9d96247..720aba5 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,9 +1,11 @@ [versions] kotlin = "2.1.0" shadow = "9.0.0-beta4" -simplecloud-controller = "0.0.30-dev.16f91aa" paper = "1.21.4-R0.1-SNAPSHOT" +simplecloud-controller = "0.0.30-dev.16f91aa" +simplecloud-plugin-api = "0.0.1-dev.e7b12c9" + cloud-core = "2.0.0" cloud-commands = "2.0.0-beta.10" cloud-confirmation-processors = "1.0.0-rc.1" @@ -27,6 +29,7 @@ cloud-paper = { module = "org.incendo:cloud-paper", version.ref = "cloud-command cloud-processors-confirmation = { module = "org.incendo:cloud-processors-confirmation", version.ref = "cloud-confirmation-processors" } simplecloud-controller-api = { module = "app.simplecloud.controller:controller-api", version.ref = "simplecloud-controller" } +simplecloud-plugin-api = { module = "app.simplecloud.plugin:plugin-shared", version.ref = "simplecloud-plugin-api" } coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutine" } coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "coroutine" } @@ -39,6 +42,7 @@ cloud-core = ["cloud-core", "cloud-kotlin-coroutines", "cloud-kotlin-extensions" cloud-paper = ["cloud-paper", "cloud-minecraft-extras", "cloud-processors-confirmation"] coroutine = ["coroutines-core", "coroutines-android"] adventure = ["adventure", "adventure-text-minimessage"] +simplecloud = ["simplecloud-controller-api", "simplecloud-plugin-api"] [plugins] kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } diff --git a/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/PaperSignStateManager.kt b/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/PaperSignStateManager.kt index e5a897c..3e32dcc 100644 --- a/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/PaperSignStateManager.kt +++ b/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/PaperSignStateManager.kt @@ -2,7 +2,7 @@ package app.simplecloud.plugin.sign.paper import app.simplecloud.plugin.sign.paper.dispatcher.PaperPlatformDispatcher import app.simplecloud.plugin.sign.shared.command.SignStateManager -import app.simplecloud.plugin.sign.shared.config.location.SignLocation +import app.simplecloud.plugin.sign.shared.config.location.SignLocationConfig import kotlinx.coroutines.withContext import net.kyori.adventure.text.Component import org.bukkit.Location @@ -32,7 +32,7 @@ class PaperSignStateManager( } } - override suspend fun updateSign(location: SignLocation, lines: List) { + override suspend fun updateSign(location: SignLocationConfig, lines: List) { withContext(dispatcher.getDispatcher()) { val mappedLocation = bootstrap.signManager.map(location) diff --git a/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/PaperSignsPluginBootstrap.kt b/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/PaperSignsPluginBootstrap.kt index 904c768..2ce2344 100644 --- a/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/PaperSignsPluginBootstrap.kt +++ b/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/PaperSignsPluginBootstrap.kt @@ -2,8 +2,6 @@ package app.simplecloud.plugin.sign.paper import app.simplecloud.controller.api.ControllerApi import app.simplecloud.plugin.sign.paper.dispatcher.PaperPlatformDispatcher -import app.simplecloud.plugin.sign.paper.rule.PaperRuleRegistry -import app.simplecloud.plugin.sign.paper.rule.PlayerRuleContext import app.simplecloud.plugin.sign.paper.sender.PaperCommandSender import app.simplecloud.plugin.sign.paper.sender.PaperCommandSenderMapper import app.simplecloud.plugin.sign.paper.service.PaperSignService @@ -11,7 +9,6 @@ import app.simplecloud.plugin.sign.shared.CloudSign import app.simplecloud.plugin.sign.shared.SignManager import app.simplecloud.plugin.sign.shared.command.SignCommand import app.simplecloud.plugin.sign.shared.config.layout.FrameConfig -import app.simplecloud.plugin.sign.shared.rule.impl.RuleContext import io.papermc.paper.plugin.bootstrap.BootstrapContext import io.papermc.paper.plugin.bootstrap.PluginBootstrap import io.papermc.paper.plugin.bootstrap.PluginProviderContext @@ -35,6 +32,8 @@ class PaperSignsPluginBootstrap : PluginBootstrap { private val controllerApi = ControllerApi.createCoroutineApi() private val miniMessage = MiniMessage.miniMessage() + private var isEnabled = false + lateinit var signManager: SignManager private set lateinit var commandManager: PaperCommandManager.Bootstrapped @@ -48,6 +47,8 @@ class PaperSignsPluginBootstrap : PluginBootstrap { override fun bootstrap(context: BootstrapContext) { try { + isEnabled = true + initializeSignManager(context) initializeCommandManager(context) registerCommands() @@ -59,12 +60,12 @@ class PaperSignsPluginBootstrap : PluginBootstrap { } } + private fun initializeSignManager(context: BootstrapContext) { signManager = SignManager( controllerApi, context.dataDirectory, PaperSignService(this), - PaperRuleRegistry() ) { cloudSign, frameConfig -> updateSign(cloudSign, frameConfig) } @@ -89,7 +90,9 @@ class PaperSignsPluginBootstrap : PluginBootstrap { } override fun createPlugin(context: PluginProviderContext): JavaPlugin = plugin + fun disable() { + isEnabled = false runBlocking { try { signCommand?.cleanup() @@ -102,34 +105,28 @@ class PaperSignsPluginBootstrap : PluginBootstrap { } private fun updateSign(cloudSign: CloudSign, frameConfig: FrameConfig) { + if (!isEnabled || !plugin.isEnabled) { + logger.debug("Skipping sign update - plugin is disabled") + return + } + val location = cloudSign.location plugin.server.scheduler.runTask(plugin, Runnable { try { val sign = location.block.state as? Sign ?: return@Runnable - val onlinePlayers = plugin.server.onlinePlayers - - onlinePlayers.forEach { player -> - val playerRuleContext = PlayerRuleContext( - server = cloudSign.server, - serverState = cloudSign.server?.state, - player - ) - - updateSignLines(sign, frameConfig, cloudSign, playerRuleContext) - } - + updateSignLines(sign, frameConfig, cloudSign) } catch (e: Exception) { logger.error("Failed to update sign at location: $location", e) } }) } - private fun updateSignLines(sign: Sign, frameConfig: FrameConfig, cloudSign: CloudSign<*>, context: RuleContext) { + private fun updateSignLines(sign: Sign, frameConfig: FrameConfig, cloudSign: CloudSign<*>) { clearSignLines(sign) frameConfig.lines.forEachIndexed { index, line -> - val resolvedLine = miniMessage.deserialize(line, *getPlaceholders(cloudSign, context).toTypedArray()) + val resolvedLine = miniMessage.deserialize(line, *getPlaceholders(cloudSign).toTypedArray()) sign.getSide(Side.FRONT).line(index, resolvedLine) sign.getSide(Side.BACK).line(index, resolvedLine) } @@ -143,7 +140,7 @@ class PaperSignsPluginBootstrap : PluginBootstrap { sign.getSide(Side.BACK).lines().replaceAll { emptyComponent } } - private fun getPlaceholders(cloudSign: CloudSign<*>, context: RuleContext): List = buildList { + private fun getPlaceholders(cloudSign: CloudSign<*>): List = buildList { with(cloudSign.server) { add(Placeholder.parsed("group", this?.group ?: "unknown")) add(Placeholder.parsed("numerical-id", this?.numericalId?.toString() ?: "0")) @@ -157,10 +154,5 @@ class PaperSignsPluginBootstrap : PluginBootstrap { add(Placeholder.parsed("player-count", this?.playerCount?.toString() ?: "0")) add(Placeholder.parsed("state", this?.state?.toString() ?: "unknown")) } - - if (context is PlayerRuleContext) { - add(Placeholder.parsed("player_name", context.player.name)) - add(Placeholder.parsed("player_sender", context.player.server.name)) - } } } diff --git a/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/listener/SignListener.kt b/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/listener/SignListener.kt index 2785874..0edc72e 100644 --- a/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/listener/SignListener.kt +++ b/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/listener/SignListener.kt @@ -1,7 +1,7 @@ package app.simplecloud.plugin.sign.paper.listener import app.simplecloud.plugin.sign.paper.PaperSignsPlugin -import app.simplecloud.plugin.sign.paper.rule.PlayerRuleContext +import app.simplecloud.plugin.sign.shared.rule.context.impl.ServerRuleContext import org.bukkit.block.Sign import org.bukkit.event.EventHandler import org.bukkit.event.Listener @@ -22,14 +22,10 @@ data class SignListener(private val plugin: PaperSignsPlugin) : Listener { plugin.bootstrap.signManager.getCloudSign(sign.location)?.let { cloudSign -> event.isCancelled = true - val playerRuleContext = PlayerRuleContext( - server = cloudSign.server, - serverState = cloudSign.server?.state, - event.player - ) + val serverRuleContext = ServerRuleContext(server = cloudSign.server) cloudSign.server?.let { server -> - val serverName = plugin.bootstrap.signManager.getLayout(playerRuleContext).constructName(server) + val serverName = plugin.bootstrap.signManager.getLayout(serverRuleContext).constructName(server) plugin.sendPlayerToServer(event.player, serverName) } } diff --git a/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/rule/PaperRuleRegistry.kt b/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/rule/PaperRuleRegistry.kt deleted file mode 100644 index 6bc88b2..0000000 --- a/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/rule/PaperRuleRegistry.kt +++ /dev/null @@ -1,11 +0,0 @@ -package app.simplecloud.plugin.sign.paper.rule - -import app.simplecloud.plugin.sign.shared.rule.impl.DefaultRuleRegistry - -class PaperRuleRegistry : DefaultRuleRegistry() { - - init { - PaperSignRules.entries.forEach(::registerRule) - } - -} \ No newline at end of file diff --git a/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/rule/PaperSignRules.kt b/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/rule/PaperSignRules.kt deleted file mode 100644 index 5a152a3..0000000 --- a/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/rule/PaperSignRules.kt +++ /dev/null @@ -1,20 +0,0 @@ -package app.simplecloud.plugin.sign.paper.rule - -import app.simplecloud.plugin.sign.shared.rule.RuleChecker -import app.simplecloud.plugin.sign.shared.rule.SignRule -import build.buf.gen.simplecloud.controller.v1.ServerState -import org.spongepowered.configurate.objectmapping.ConfigSerializable - -@ConfigSerializable -enum class PaperSignRules( - override val serverState: ServerState?, - override val checker: RuleChecker -) : SignRule { - - ; - - override fun getRuleName(): String { - return name - } - -} \ No newline at end of file diff --git a/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/rule/PlayerRuleContext.kt b/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/rule/PlayerRuleContext.kt deleted file mode 100644 index bcf9a88..0000000 --- a/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/rule/PlayerRuleContext.kt +++ /dev/null @@ -1,21 +0,0 @@ -package app.simplecloud.plugin.sign.paper.rule - -import app.simplecloud.controller.shared.server.Server -import app.simplecloud.plugin.sign.shared.rule.impl.RuleContext -import build.buf.gen.simplecloud.controller.v1.ServerState -import org.bukkit.entity.Player - -class PlayerRuleContext( - server: Server?, - serverState: ServerState?, - val player: Player, - additionalData: Map = emptyMap() -) : RuleContext( - server = server, - serverState = serverState, - additionalData = additionalData + mapOf( - "playerId" to player.uniqueId.toString(), - "playerName" to player.name, - "playerServer" to player.server.name - ) -) diff --git a/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/sender/PaperCommandSender.kt b/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/sender/PaperCommandSender.kt index 65d53e7..2cae532 100644 --- a/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/sender/PaperCommandSender.kt +++ b/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/sender/PaperCommandSender.kt @@ -1,7 +1,7 @@ package app.simplecloud.plugin.sign.paper.sender import app.simplecloud.plugin.sign.paper.PaperSignsPlugin -import app.simplecloud.plugin.sign.shared.config.location.SignLocation +import app.simplecloud.plugin.sign.shared.config.location.SignLocationConfig import app.simplecloud.plugin.sign.shared.sender.SignCommandSender import app.simplecloud.plugin.sign.shared.utils.SignCommandMessages import io.papermc.paper.command.brigadier.CommandSourceStack @@ -20,7 +20,7 @@ class PaperCommandSender( override fun sendMessage(component: Component) = sourceStack.sender.sendMessage(component) - override suspend fun getTargetBlock(maxDistance: Int): SignLocation? { + override suspend fun getTargetBlock(maxDistance: Int): SignLocationConfig? { val player = sourceStack.sender as? Player ?: return null return withContext(PaperSignsPlugin.instance.bootstrap.platformDispatcher.getDispatcher()) { @@ -32,7 +32,7 @@ class PaperCommandSender( return@withContext null } - SignLocation( + SignLocationConfig( world = targetBlock.world.name, x = targetBlock.x.toDouble(), y = targetBlock.y.toDouble(), diff --git a/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/service/PaperSignService.kt b/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/service/PaperSignService.kt index 7e0eeb9..7c5eca6 100644 --- a/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/service/PaperSignService.kt +++ b/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/service/PaperSignService.kt @@ -4,7 +4,8 @@ import app.simplecloud.controller.api.ControllerApi import app.simplecloud.plugin.sign.paper.PaperSignsPluginBootstrap import app.simplecloud.plugin.sign.shared.CloudSign import app.simplecloud.plugin.sign.shared.LocationMapper -import app.simplecloud.plugin.sign.shared.config.location.SignLocation +import app.simplecloud.plugin.sign.shared.config.location.SignLocationConfig +import app.simplecloud.plugin.sign.shared.config.rule.RuleConfig import app.simplecloud.plugin.sign.shared.service.SignService import org.bukkit.Location @@ -17,13 +18,13 @@ class PaperSignService(private val bootstrap: PaperSignsPluginBootstrap) : SignS override fun getCloudSign(location: Location): CloudSign? = bootstrap.signManager.getCloudSign(location) - override fun getAllLocations(): List = + override fun getAllLocations(): List = bootstrap.signManager.getAllLocations() override fun getAllGroupsRegistered(): List = bootstrap.signManager.getAllGroupsRegistered() - override fun getLocationsByGroup(group: String): List? = + override fun getLocationsByGroup(group: String): List? = bootstrap.signManager.getLocationsByGroup(group) override fun register(group: String, location: Location) = @@ -35,7 +36,13 @@ class PaperSignService(private val bootstrap: PaperSignsPluginBootstrap) : SignS override fun exists(group: String): Boolean = bootstrap.signManager.exists(group) - override fun map(location: SignLocation): Location = + override fun getAllRules(): List = + bootstrap.signManager.getAllRules() + + override fun getRule(ruleName: String): RuleConfig? = + bootstrap.signManager.getRule(ruleName) + + override fun map(location: SignLocationConfig): Location = Location( bootstrap.plugin.server.getWorld(location.world), location.x, @@ -43,8 +50,8 @@ class PaperSignService(private val bootstrap: PaperSignsPluginBootstrap) : SignS location.z ) - override fun unmap(location: Location): SignLocation = - SignLocation( + override fun unmap(location: Location): SignLocationConfig = + SignLocationConfig( location.world.name, location.x, location.y, diff --git a/sign-shared/build.gradle.kts b/sign-shared/build.gradle.kts index 8ebbfa5..c3c9ec4 100644 --- a/sign-shared/build.gradle.kts +++ b/sign-shared/build.gradle.kts @@ -1,5 +1,5 @@ dependencies { - api(rootProject.libs.simplecloud.controller.api) + api(rootProject.libs.bundles.simplecloud) implementation(rootProject.libs.bundles.cloud.core) implementation(rootProject.libs.bundles.adventure) } \ No newline at end of file diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/LocationMapper.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/LocationMapper.kt index a461c60..0a973a5 100644 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/LocationMapper.kt +++ b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/LocationMapper.kt @@ -1,11 +1,11 @@ package app.simplecloud.plugin.sign.shared -import app.simplecloud.plugin.sign.shared.config.location.SignLocation +import app.simplecloud.plugin.sign.shared.config.location.SignLocationConfig interface LocationMapper { - fun map(location: SignLocation): T + fun map(location: SignLocationConfig): T - fun unmap(location: T): SignLocation + fun unmap(location: T): SignLocationConfig } \ No newline at end of file diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/SignManager.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/SignManager.kt index 18bdeef..b7e45b6 100644 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/SignManager.kt +++ b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/SignManager.kt @@ -2,29 +2,28 @@ package app.simplecloud.plugin.sign.shared import app.simplecloud.controller.api.ControllerApi import app.simplecloud.controller.shared.server.Server +import app.simplecloud.plugin.api.shared.placeholder.provider.GroupPlaceholderProvider +import app.simplecloud.plugin.api.shared.placeholder.provider.ServerPlaceholderProvider import app.simplecloud.plugin.sign.shared.cache.ServerCache import app.simplecloud.plugin.sign.shared.config.layout.LayoutConfig import app.simplecloud.plugin.sign.shared.config.location.LocationsConfig -import app.simplecloud.plugin.sign.shared.config.location.SignLocation -import app.simplecloud.plugin.sign.shared.config.matcher.MatcherConfigEntry -import app.simplecloud.plugin.sign.shared.config.matcher.MatcherType +import app.simplecloud.plugin.sign.shared.config.location.SignLocationConfig +import app.simplecloud.plugin.sign.shared.config.rule.RuleConfig import app.simplecloud.plugin.sign.shared.repository.layout.LayoutRepository import app.simplecloud.plugin.sign.shared.repository.location.LocationsRepository -import app.simplecloud.plugin.sign.shared.rule.RuleRegistry -import app.simplecloud.plugin.sign.shared.rule.SignRule -import app.simplecloud.plugin.sign.shared.rule.impl.RuleContext -import app.simplecloud.plugin.sign.shared.rule.serialize.SignRuleSerializer +import app.simplecloud.plugin.sign.shared.repository.rule.RuleRepository +import app.simplecloud.plugin.sign.shared.rule.context.RuleContext +import app.simplecloud.plugin.sign.shared.rule.context.impl.ServerRuleContext import app.simplecloud.plugin.sign.shared.service.SignService +import app.simplecloud.plugin.sign.shared.utils.MatcherUtil import kotlinx.coroutines.* import org.slf4j.LoggerFactory -import org.spongepowered.configurate.serialize.TypeSerializerCollection import java.nio.file.Path class SignManager( override val controllerApi: ControllerApi.Coroutine, directoryPath: Path, private val locationMapper: LocationMapper, - private val ruleRegistry: RuleRegistry, private val signUpdater: SignUpdater ) : SignService { @@ -38,18 +37,20 @@ class SignManager( directoryPath.resolve("locations"), locationMapper ) + private val ruleRepository = RuleRepository( + directoryPath.resolve("rules"), + ) private val layoutRepository = LayoutRepository( directoryPath.resolve("layouts"), ) - private val serializers = TypeSerializerCollection.defaults().childBuilder().apply { - register(SignRule::class.java, SignRuleSerializer(ruleRegistry)) - }.build() - private val serverCache = ServerCache(controllerApi, locationsRepository) + val groupPlaceholderProvider: GroupPlaceholderProvider = GroupPlaceholderProvider() + val serverPlaceholderProvider: ServerPlaceholderProvider = ServerPlaceholderProvider() + init { - setRuleRegistry(ruleRegistry) + SignManagerProvider.register(this) } fun start() { @@ -86,7 +87,7 @@ class SignManager( override fun getCloudSign(location: T): CloudSign? = state.getCloudSign(location) - override fun getAllLocations(): List = + override fun getAllLocations(): List = locationsRepository.getAll().map { it.locations }.flatten() override fun getAllGroupsRegistered(): List = @@ -94,7 +95,7 @@ class SignManager( .map { it.group } .distinct() - override fun getLocationsByGroup(group: String): List? = + override fun getLocationsByGroup(group: String): List? = locationsRepository.find(group)?.locations override suspend fun removeCloudSign(location: T) { @@ -105,47 +106,33 @@ class SignManager( override fun exists(group: String): Boolean = locationsRepository.getAll().any { it.group == group } - override fun map(location: SignLocation): T = locationMapper.map(location) - - override fun unmap(location: T): SignLocation = locationMapper.unmap(location) - - fun getLayout(context: RuleContext): LayoutConfig { - val serverName = "${context.server?.group}-${context.server?.numericalId}" + override fun getAllRules(): List { + return ruleRepository.getAll() + } - return layoutRepository.getAll() - .asSequence() - .sortedByDescending { it.priority } - .filter { layoutConfig -> - val rule = ruleRegistry.getRule(layoutConfig.rule.getRuleName()) - rule?.checker?.check(context) == true - }.firstOrNull { layoutConfig -> checkMatches(layoutConfig.matcher, serverName) } - ?: LayoutConfig() + override fun getRule(ruleName: String): RuleConfig? { + return ruleRepository.find(ruleName) } - private fun checkMatches(matchers: Map>, serverName: String): Boolean { - if (matchers.containsKey(MatcherType.MATCH_ALL)) { - val matchAllResult = matchers[MatcherType.MATCH_ALL]?.all { - it.operation.matches(serverName, it.value) - } ?: false + override fun map(location: SignLocationConfig): T = locationMapper.map(location) - if (!matchAllResult) { - return false - } - } + override fun unmap(location: T): SignLocationConfig = locationMapper.unmap(location) - if (matchers.containsKey(MatcherType.MATCH_ANY)) { - return matchers[MatcherType.MATCH_ANY]?.any { - it.operation.matches(serverName, it.value) - } ?: false + fun getLayout(ruleContext: RuleContext): LayoutConfig { + return layoutRepository.getAll().firstOrNull { + MatcherUtil.matches(it.matcher, ruleContext) && + MatcherUtil.matches(it.rule.matcher, ruleContext) } - - return true + ?: LayoutConfig() } private fun loadConfigurations() { locationsRepository.load() - layoutRepository.load(serializers) - logger.info("Loaded {} Sign Layouts", layoutRepository.getAll().size) + ruleRepository.load() + layoutRepository.load() + logger.info("Loaded ${locationsRepository.getAll().size} Sign Locations") + logger.info("Loaded ${layoutRepository.getAll().size} Sign Layouts") + logger.info("Loaded ${ruleRepository.getAll().size} Sign Rules") } private fun startUpdateSignJob() { @@ -177,8 +164,8 @@ class SignManager( state.isServerAssigned(server.uniqueId) } .filter { server -> - val context = RuleContext(server, server.state) - ruleRegistry.getRules().any { rule -> rule.checker.check(context) } + val ruleContext = ServerRuleContext(server) + ruleRepository.getAll().any { rule -> MatcherUtil.matches(rule.matcher, ruleContext) } } .sortedBy { it.numericalId } .iterator() @@ -189,7 +176,7 @@ class SignManager( } private suspend fun processLocation( - locationConfig: SignLocation, + locationConfig: SignLocationConfig, unusedServers: Iterator, allServers: List ) { @@ -211,10 +198,9 @@ class SignManager( private suspend fun updateSign(cloudSign: CloudSign) { state.updateCloudSign(cloudSign.location, cloudSign) + val ruleContext = ServerRuleContext(cloudSign.server) - val context = RuleContext(cloudSign.server, cloudSign.server?.state) - - val layout = getLayout(context) + val layout = getLayout(ruleContext) if (layout.frames.isEmpty()) { return } @@ -234,14 +220,6 @@ class SignManager( companion object { private const val UPDATE_INTERVAL = 50L - - private var staticRuleRegistry: RuleRegistry? = null - - fun getRuleRegistry(): RuleRegistry? = staticRuleRegistry - - fun setRuleRegistry(registry: RuleRegistry) { - staticRuleRegistry = registry - } } } diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/SignManagerProvider.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/SignManagerProvider.kt new file mode 100644 index 0000000..5301ff4 --- /dev/null +++ b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/SignManagerProvider.kt @@ -0,0 +1,12 @@ +package app.simplecloud.plugin.sign.shared + +object SignManagerProvider { + + private lateinit var signManager: SignManager<*> + + fun register(signManager: SignManager<*>) { + this.signManager = signManager + } + + fun get(): SignManager<*> = signManager +} \ No newline at end of file diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/SignState.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/SignState.kt index 6193ef7..69abe4d 100644 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/SignState.kt +++ b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/SignState.kt @@ -85,8 +85,4 @@ data class SignState( } } - - companion object { - const val DEFAULT_FRAME_INDEX = 0 - } } diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/command/SignCommand.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/command/SignCommand.kt index 88e8859..6c6b3ad 100644 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/command/SignCommand.kt +++ b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/command/SignCommand.kt @@ -1,6 +1,6 @@ package app.simplecloud.plugin.sign.shared.command -import app.simplecloud.plugin.sign.shared.config.location.SignLocation +import app.simplecloud.plugin.sign.shared.config.location.SignLocationConfig import app.simplecloud.plugin.sign.shared.dispatcher.PlatformDispatcher import app.simplecloud.plugin.sign.shared.sender.SignCommandSender import app.simplecloud.plugin.sign.shared.service.SignService @@ -198,7 +198,7 @@ class SignCommand( private fun sendAllSignsInformation( sender: SignCommandSender, - groupedLocations: List>, + groupedLocations: List>, page: Int ) { val totalPages = ceil(groupedLocations.size.toDouble() / LOCATIONS_PER_PAGE).toInt() @@ -251,7 +251,7 @@ $navigationButtons private fun sendSignGroupInformation( sender: SignCommandSender, group: String, - locations: List, + locations: List, page: Int ) { val totalPages = ceil(locations.size.toDouble() / LOCATIONS_PER_PAGE).toInt() @@ -452,7 +452,7 @@ $navigationButtons private suspend fun getSignLocation( sender: SignCommandSender, operation: SignOperation = SignOperation.ADD - ): SignLocation? = + ): SignLocationConfig? = sender.getTargetBlock(MAX_SIGN_DISTANCE)?.let { location -> val hasExistingSign = signService.getCloudSign(signService.map(location)) != null when (operation) { diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/command/SignStateManager.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/command/SignStateManager.kt index a1eb35a..2082823 100644 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/command/SignStateManager.kt +++ b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/command/SignStateManager.kt @@ -1,11 +1,11 @@ package app.simplecloud.plugin.sign.shared.command -import app.simplecloud.plugin.sign.shared.config.location.SignLocation +import app.simplecloud.plugin.sign.shared.config.location.SignLocationConfig import net.kyori.adventure.text.Component interface SignStateManager { suspend fun clearSign(location: T) - suspend fun updateSign(location: SignLocation, lines: List) + suspend fun updateSign(location: SignLocationConfig, lines: List) } \ No newline at end of file diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/layout/LayoutConfig.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/layout/LayoutConfig.kt index 0393a2f..eae0a22 100644 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/layout/LayoutConfig.kt +++ b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/layout/LayoutConfig.kt @@ -1,38 +1,27 @@ package app.simplecloud.plugin.sign.shared.config.layout import app.simplecloud.controller.shared.server.Server -import app.simplecloud.plugin.sign.shared.SignManager -import app.simplecloud.plugin.sign.shared.config.matcher.MatcherConfigEntry -import app.simplecloud.plugin.sign.shared.config.matcher.MatcherType -import app.simplecloud.plugin.sign.shared.rule.RuleRegistry -import app.simplecloud.plugin.sign.shared.rule.SignRule +import app.simplecloud.plugin.sign.shared.SignManagerProvider +import app.simplecloud.plugin.sign.shared.config.rule.RuleConfig +import app.simplecloud.plugin.sign.shared.matcher.MatcherConfigEntry +import app.simplecloud.plugin.sign.shared.matcher.MatcherType import org.spongepowered.configurate.objectmapping.ConfigSerializable import org.spongepowered.configurate.objectmapping.meta.Setting -import org.spongepowered.configurate.serialize.SerializationException @ConfigSerializable data class LayoutConfig( val name: String = "", - val matcher: Map> = emptyMap(), @Setting("rule") val ruleName: String = "EMPTY", - val priority: Int = 0, + val matcher: Map> = emptyMap(), val serverName: String = "%group%-%numerical-id%", val frameUpdateInterval: Long = 500, val frames: List = listOf(), ) { - val rule: SignRule - get() = SignManager.getRuleRegistry()?.getRule(ruleName) - ?: throw SerializationException("Rule $ruleName not found") - - companion object { - private var ruleRegistry: RuleRegistry? = null - - fun setRegistry(registry: RuleRegistry) { - ruleRegistry = registry - } - } + val rule: RuleConfig + get() = SignManagerProvider.get().getRule(ruleName) + ?: RuleConfig(name = "UNKNOWN_RULE") fun constructName(server: Server): String { return serverName diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/location/LocationsConfig.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/location/LocationsConfig.kt index 137f252..d90bd9b 100644 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/location/LocationsConfig.kt +++ b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/location/LocationsConfig.kt @@ -5,5 +5,5 @@ import org.spongepowered.configurate.objectmapping.ConfigSerializable @ConfigSerializable data class LocationsConfig( val group: String = "", - val locations: List = emptyList() + val locations: List = emptyList() ) diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/location/SignLocation.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/location/SignLocationConfig.kt similarity index 89% rename from sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/location/SignLocation.kt rename to sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/location/SignLocationConfig.kt index 267dcd4..c601640 100644 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/location/SignLocation.kt +++ b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/location/SignLocationConfig.kt @@ -3,7 +3,7 @@ package app.simplecloud.plugin.sign.shared.config.location import org.spongepowered.configurate.objectmapping.ConfigSerializable @ConfigSerializable -data class SignLocation( +data class SignLocationConfig( val world: String = "", val x: Double = 0.0, val y: Double = 0.0, diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/MatcherConfigEntry.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/MatcherConfigEntry.kt deleted file mode 100644 index b953609..0000000 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/MatcherConfigEntry.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.simplecloud.plugin.sign.shared.config.matcher - -import app.simplecloud.plugin.sign.shared.config.matcher.operations.MatcherOperations -import org.spongepowered.configurate.objectmapping.ConfigSerializable - -@ConfigSerializable -data class MatcherConfigEntry( - val operation: MatcherOperations = MatcherOperations.STARTS_WITH, - val value: String = "", -) diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/MatcherType.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/MatcherType.kt deleted file mode 100644 index 2f90efd..0000000 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/MatcherType.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.simplecloud.plugin.sign.shared.config.matcher - -enum class MatcherType() { - - MATCH_ALL, - MATCH_ANY - -} \ No newline at end of file diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/ContainsOperationMatcher.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/ContainsOperationMatcher.kt deleted file mode 100644 index af9cf7a..0000000 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/ContainsOperationMatcher.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.simplecloud.plugin.sign.shared.config.matcher.operations - -import org.spongepowered.configurate.objectmapping.ConfigSerializable - -@ConfigSerializable -class ContainsOperationMatcher : OperationMatcher { - - override fun matches(key: String, value: String): Boolean { - return key.contains(value) - } - -} \ No newline at end of file diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/EndsWithOperationMatcher.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/EndsWithOperationMatcher.kt deleted file mode 100644 index d940f81..0000000 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/EndsWithOperationMatcher.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.simplecloud.plugin.sign.shared.config.matcher.operations - -import org.spongepowered.configurate.objectmapping.ConfigSerializable - -@ConfigSerializable -class EndsWithOperationMatcher : OperationMatcher { - - override fun matches(key: String, value: String): Boolean { - return key.endsWith(value) - } - -} \ No newline at end of file diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/EqualsIgnoreCaseOperationMatcher.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/EqualsIgnoreCaseOperationMatcher.kt deleted file mode 100644 index 1f73f06..0000000 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/EqualsIgnoreCaseOperationMatcher.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.simplecloud.plugin.sign.shared.config.matcher.operations - -import org.spongepowered.configurate.objectmapping.ConfigSerializable - -@ConfigSerializable -class EqualsIgnoreCaseOperationMatcher : OperationMatcher { - - override fun matches(key: String, value: String): Boolean { - return key.equals(value, ignoreCase = true) - } - -} \ No newline at end of file diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/EqualsOperationMatcher.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/EqualsOperationMatcher.kt deleted file mode 100644 index c52d847..0000000 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/EqualsOperationMatcher.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.simplecloud.plugin.sign.shared.config.matcher.operations - -import org.spongepowered.configurate.objectmapping.ConfigSerializable - -@ConfigSerializable -class EqualsOperationMatcher : OperationMatcher { - - override fun matches(key: String, value: String): Boolean { - return key == value - } - -} \ No newline at end of file diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/MatcherOperations.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/MatcherOperations.kt deleted file mode 100644 index 3883f14..0000000 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/MatcherOperations.kt +++ /dev/null @@ -1,18 +0,0 @@ -package app.simplecloud.plugin.sign.shared.config.matcher.operations - -enum class MatcherOperations(val matcher: OperationMatcher) { - - REGEX(RegexOperationMatcher()), - EQUALS(EqualsOperationMatcher()), - EQUALS_IGNORE_CASE(EqualsIgnoreCaseOperationMatcher()), - NOT_EQUALS(NotEqualsOperationMatcher()), - CONTAINS(ContainsOperationMatcher()), - STARTS_WITH(StartsWithOperationMatcher()), - ENDS_WITH(EndsWithOperationMatcher()), - MATCHES_PATTERN(PatternOperationMatcher()); - - fun matches(key: String, value: String): Boolean { - return matcher.matches(key, value); - } - -} \ No newline at end of file diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/NotEqualsOperationMatcher.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/NotEqualsOperationMatcher.kt deleted file mode 100644 index e3af0a5..0000000 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/NotEqualsOperationMatcher.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.simplecloud.plugin.sign.shared.config.matcher.operations - -import org.spongepowered.configurate.objectmapping.ConfigSerializable - -@ConfigSerializable -class NotEqualsOperationMatcher : OperationMatcher { - - override fun matches(key: String, value: String): Boolean { - return key != value - } - -} \ No newline at end of file diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/OperationMatcher.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/OperationMatcher.kt deleted file mode 100644 index 3544831..0000000 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/OperationMatcher.kt +++ /dev/null @@ -1,7 +0,0 @@ -package app.simplecloud.plugin.sign.shared.config.matcher.operations - -interface OperationMatcher { - - fun matches(key: String, value: String): Boolean - -} \ No newline at end of file diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/PatternOperationMatcher.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/PatternOperationMatcher.kt deleted file mode 100644 index 5462b8f..0000000 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/PatternOperationMatcher.kt +++ /dev/null @@ -1,13 +0,0 @@ -package app.simplecloud.plugin.sign.shared.config.matcher.operations - -import org.spongepowered.configurate.objectmapping.ConfigSerializable -import java.util.regex.Pattern - -@ConfigSerializable -class PatternOperationMatcher : OperationMatcher { - - override fun matches(key: String, value: String): Boolean { - return Pattern.matches(value, key) - } - -} \ No newline at end of file diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/RegexOperationMatcher.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/RegexOperationMatcher.kt deleted file mode 100644 index f7bef0c..0000000 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/RegexOperationMatcher.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.simplecloud.plugin.sign.shared.config.matcher.operations - -import org.spongepowered.configurate.objectmapping.ConfigSerializable - -@ConfigSerializable -class RegexOperationMatcher : OperationMatcher { - - override fun matches(key: String, value: String): Boolean { - return key.equals(Regex.fromLiteral(value)) - } - -} \ No newline at end of file diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/StartsWithOperationMatcher.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/StartsWithOperationMatcher.kt deleted file mode 100644 index a32b431..0000000 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/matcher/operations/StartsWithOperationMatcher.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.simplecloud.plugin.sign.shared.config.matcher.operations - -import org.spongepowered.configurate.objectmapping.ConfigSerializable - -@ConfigSerializable -class StartsWithOperationMatcher : OperationMatcher { - - override fun matches(key: String, value: String): Boolean { - return key.startsWith(value) - } - -} \ No newline at end of file diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/rule/RuleConfig.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/rule/RuleConfig.kt new file mode 100644 index 0000000..d93b849 --- /dev/null +++ b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/rule/RuleConfig.kt @@ -0,0 +1,15 @@ +package app.simplecloud.plugin.sign.shared.config.rule + +import app.simplecloud.plugin.sign.shared.matcher.MatcherConfigEntry +import app.simplecloud.plugin.sign.shared.matcher.MatcherType +import org.spongepowered.configurate.objectmapping.ConfigSerializable + +@ConfigSerializable +data class RuleConfig( + val name: String = "", + val inherit: String? = null, + val matcher: Map> = emptyMap(), +) + + + diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/matcher/MatcherConfigEntry.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/matcher/MatcherConfigEntry.kt new file mode 100644 index 0000000..452421c --- /dev/null +++ b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/matcher/MatcherConfigEntry.kt @@ -0,0 +1,12 @@ +package app.simplecloud.plugin.sign.shared.matcher + +import app.simplecloud.plugin.api.shared.matcher.OperationType +import org.spongepowered.configurate.objectmapping.ConfigSerializable + +@ConfigSerializable +data class MatcherConfigEntry( + val operation: OperationType = OperationType.STARTS_WITH, + val key: String = "", + val value: String = "", + val negate: Boolean = false +) diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/matcher/MatcherType.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/matcher/MatcherType.kt new file mode 100644 index 0000000..7ebf2ce --- /dev/null +++ b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/matcher/MatcherType.kt @@ -0,0 +1,8 @@ +package app.simplecloud.plugin.sign.shared.matcher + +enum class MatcherType { + + MATCH_ALL, + MATCH_ANY + +} \ No newline at end of file diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/ResourcedYamlDirectoryRepository.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/ResourcedYamlDirectoryRepository.kt new file mode 100644 index 0000000..649afc2 --- /dev/null +++ b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/ResourcedYamlDirectoryRepository.kt @@ -0,0 +1,79 @@ +package app.simplecloud.plugin.sign.shared.repository + +import app.simplecloud.plugin.api.shared.repository.YamlDirectoryRepository +import java.io.File +import java.io.FileOutputStream +import java.net.URL +import java.nio.file.Path +import java.util.jar.JarFile +import kotlin.io.path.exists +import kotlin.io.path.pathString + +abstract class ResourcedYamlDirectoryRepository( + private val directory: Path, + clazz: Class, +) : YamlDirectoryRepository(directory, clazz) { + + override fun load(): List { + if (!directory.exists()) loadDefaults() + + return super.load() + } + + private fun loadDefaults() { + val targetDirectory = File(directory.toUri()).apply { mkdirs() } + + val last = directory.pathString.split('/').last() + + val resourceUrl = YamlDirectoryRepository::class.java.getResource("/$last") ?: run { + println("$last folder not found in resources") + return + } + + when (resourceUrl.protocol) { + "file" -> handleFileProtocol(resourceUrl, targetDirectory) + "jar" -> handleJarProtocol(resourceUrl, targetDirectory) + else -> println("Unsupported protocol: ${resourceUrl.protocol}") + } + } + + private fun handleFileProtocol(resourceUrl: URL, targetDirectory: File) { + val resourceDir = File(resourceUrl.toURI()) + if (resourceDir.exists()) { + resourceDir.copyRecursively(targetDirectory, overwrite = true) + } else { + println("Resource directory does not exist: ${resourceUrl.path}") + } + } + + private fun handleJarProtocol(resourceUrl: URL, targetDirectory: File) { + val jarPath = resourceUrl.path.substringBefore("!").removePrefix("file:") + try { + JarFile(jarPath).use { jarFile -> + val last = directory.pathString.split('/').last() + jarFile.entries().asSequence() + .filter { it.name.startsWith("$last/") && !it.isDirectory } + .forEach { entry -> + val targetFile = File(targetDirectory, entry.name.removePrefix("$last/")) + targetFile.parentFile.mkdirs() + try { + jarFile.getInputStream(entry).use { inputStream -> + FileOutputStream(targetFile).use { fos -> + fos.write(0xEF) + fos.write(0xBB) + fos.write(0xBF) + + inputStream.copyTo(fos) + } + } + } catch (e: Exception) { + println("Error copying file ${entry.name}: ${e.message}") + } + } + } + } catch (e: Exception) { + println("Error processing JAR file: ${e.message}") + e.printStackTrace() + } + } +} \ No newline at end of file diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/base/LoadableRepository.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/base/LoadableRepository.kt deleted file mode 100644 index eeaf8d5..0000000 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/base/LoadableRepository.kt +++ /dev/null @@ -1,7 +0,0 @@ -package app.simplecloud.plugin.sign.shared.repository.base - -import org.spongepowered.configurate.serialize.TypeSerializerCollection - -interface LoadableRepository : Repository { - fun load(serializers: TypeSerializerCollection? = null): List -} \ No newline at end of file diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/base/Repository.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/base/Repository.kt deleted file mode 100644 index 018f34c..0000000 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/base/Repository.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.simplecloud.plugin.sign.shared.repository.base - -interface Repository { - fun delete(element: E): Boolean - fun save(element: E) - fun find(identifier: I): E? - fun getAll(): List -} \ No newline at end of file diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/base/YamlDirectoryRepository.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/base/YamlDirectoryRepository.kt deleted file mode 100644 index d1a1bc1..0000000 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/base/YamlDirectoryRepository.kt +++ /dev/null @@ -1,225 +0,0 @@ -package app.simplecloud.plugin.sign.shared.repository.base - -import app.simplecloud.plugin.sign.shared.rule.RuleRegistry -import app.simplecloud.plugin.sign.shared.rule.SignRule -import io.leangen.geantyref.TypeToken -import kotlinx.coroutines.* -import org.spongepowered.configurate.ConfigurationNode -import org.spongepowered.configurate.ConfigurationOptions -import org.spongepowered.configurate.kotlin.objectMapperFactory -import org.spongepowered.configurate.loader.ParsingException -import org.spongepowered.configurate.serialize.SerializationException -import org.spongepowered.configurate.serialize.TypeSerializer -import org.spongepowered.configurate.serialize.TypeSerializerCollection -import org.spongepowered.configurate.yaml.NodeStyle -import org.spongepowered.configurate.yaml.YamlConfigurationLoader -import java.io.File -import java.io.FileOutputStream -import java.lang.reflect.Type -import java.net.URL -import java.nio.file.FileSystems -import java.nio.file.Files -import java.nio.file.Path -import java.nio.file.StandardWatchEventKinds -import java.util.jar.JarFile -import kotlin.io.path.pathString - - -abstract class YamlDirectoryRepository( - private val directory: Path, - private val clazz: Class, - private val ruleRegistry: RuleRegistry? = null -) : LoadableRepository { - - private val watchService = FileSystems.getDefault().newWatchService() - private val loaders = mutableMapOf() - protected val entities = mutableMapOf() - - private var serializers: TypeSerializerCollection? = null - - abstract fun getFileName(identifier: I): String - - override fun delete(element: E): Boolean { - val file = entities.keys.find { entities[it] == element } ?: return false - return deleteFile(file) - } - - override fun getAll(): List { - return entities.values.toList() - } - - override fun load(serializers: TypeSerializerCollection?): List { - this.serializers = serializers - - if (!directory.toFile().exists()) { - directory.toFile().mkdirs() - loadDefaults() - } - - registerWatcher() - - return Files.walk(directory) - .toList() - .filter { !it.toFile().isDirectory && it.toString().endsWith(".yml") } - .mapNotNull { load(it.toFile()) } - } - - private fun load(file: File): E? { - try { - val loader = getOrCreateLoader(file) - val node = loader.load(ConfigurationOptions.defaults()) - val entity = node.get(clazz) ?: return null - entities[file] = entity - return entity - } catch (ex: ParsingException) { - val existedBefore = entities.containsKey(file) - if (existedBefore) { - return null - } - - return null - } - } - - private fun deleteFile(file: File): Boolean { - val deletedSuccessfully = file.delete() - val removedSuccessfully = entities.remove(file) != null - return deletedSuccessfully && removedSuccessfully - } - - protected fun save(fileName: String, entity: E) { - val file = directory.resolve(fileName).toFile() - val loader = getOrCreateLoader(file) - val node = loader.createNode(ConfigurationOptions.defaults()) - node.set(clazz, entity) - loader.save(node) - entities[file] = entity - } - - private fun getOrCreateLoader(file: File): YamlConfigurationLoader { - return loaders.getOrPut(file) { - YamlConfigurationLoader.builder() - .path(file.toPath()) - .nodeStyle(NodeStyle.BLOCK) - .defaultOptions { options -> - options.serializers { builder -> - serializers?.let { builder.registerAll(it) } - - ruleRegistry?.let { registry -> - builder.register(TypeToken.get(SignRule::class.java), object : TypeSerializer { - override fun deserialize(type: Type, node: ConfigurationNode): SignRule { - val ruleName = - node.string ?: throw SerializationException("Rule name cannot be null") - - return registry.getRule(ruleName) - ?: throw SerializationException("Unknown rule: $ruleName") - } - - override fun serialize(type: Type, obj: SignRule?, node: ConfigurationNode) { - if (obj != null) { - node.set(obj.getRuleName()) - } - } - }) - } - - builder.registerAnnotatedObjects(objectMapperFactory()) - } - }.build() - } - } - - private fun registerWatcher(): Job { - directory.register( - watchService, - StandardWatchEventKinds.ENTRY_CREATE, - StandardWatchEventKinds.ENTRY_DELETE, - StandardWatchEventKinds.ENTRY_MODIFY - ) - - return CoroutineScope(Dispatchers.IO).launch { - while (isActive) { - val key = watchService.take() - - key.pollEvents().forEach { event -> - val path = event.context() as? Path ?: return@forEach - if (!path.toString().endsWith(".yml")) return@forEach - - val resolvedPath = directory.resolve(path) - if (Files.isDirectory(resolvedPath)) return@forEach - - when (event.kind()) { - StandardWatchEventKinds.ENTRY_CREATE, - StandardWatchEventKinds.ENTRY_MODIFY -> { - delay(100) - load(resolvedPath.toFile()) - } - - StandardWatchEventKinds.ENTRY_DELETE -> { - deleteFile(resolvedPath.toFile()) - } - } - } - - key.reset() - } - } - } - - private fun loadDefaults() { - val targetDirectory = File(directory.toUri()).apply { mkdirs() } - - val last = directory.pathString.split('/').last() - - val resourceUrl = YamlDirectoryRepository::class.java.getResource("/$last") ?: run { - println("$last folder not found in resources") - return - } - - when (resourceUrl.protocol) { - "file" -> handleFileProtocol(resourceUrl, targetDirectory) - "jar" -> handleJarProtocol(resourceUrl, targetDirectory) - else -> println("Unsupported protocol: ${resourceUrl.protocol}") - } - } - - private fun handleFileProtocol(resourceUrl: URL, targetDirectory: File) { - val resourceDir = File(resourceUrl.toURI()) - if (resourceDir.exists()) { - resourceDir.copyRecursively(targetDirectory, overwrite = true) - } else { - println("Resource directory does not exist: ${resourceUrl.path}") - } - } - - private fun handleJarProtocol(resourceUrl: URL, targetDirectory: File) { - val jarPath = resourceUrl.path.substringBefore("!").removePrefix("file:") - try { - JarFile(jarPath).use { jarFile -> - val last = directory.pathString.split('/').last() - jarFile.entries().asSequence() - .filter { it.name.startsWith("$last/") && !it.isDirectory } - .forEach { entry -> - val targetFile = File(targetDirectory, entry.name.removePrefix("$last/")) - targetFile.parentFile.mkdirs() - try { - jarFile.getInputStream(entry).use { inputStream -> - FileOutputStream(targetFile).use { fos -> - fos.write(0xEF) - fos.write(0xBB) - fos.write(0xBF) - - inputStream.copyTo(fos) - } - } - } catch (e: Exception) { - println("Error copying file ${entry.name}: ${e.message}") - } - } - } - } catch (e: Exception) { - println("Error processing JAR file: ${e.message}") - e.printStackTrace() - } - } -} \ No newline at end of file diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/layout/LayoutRepository.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/layout/LayoutRepository.kt index 78bd45d..55c04cf 100644 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/layout/LayoutRepository.kt +++ b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/layout/LayoutRepository.kt @@ -1,15 +1,13 @@ package app.simplecloud.plugin.sign.shared.repository.layout import app.simplecloud.plugin.sign.shared.config.layout.LayoutConfig -import app.simplecloud.plugin.sign.shared.repository.base.YamlDirectoryRepository -import app.simplecloud.plugin.sign.shared.rule.RuleRegistry +import app.simplecloud.plugin.sign.shared.repository.ResourcedYamlDirectoryRepository import java.nio.file.Path @Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE") class LayoutRepository( - directoryPath: Path, - -) : YamlDirectoryRepository(directoryPath, LayoutConfig::class.java) { + directory: Path +) : ResourcedYamlDirectoryRepository(directory, LayoutConfig::class.java) { override fun save(element: LayoutConfig) { save(getFileName(element.name), element) @@ -20,6 +18,6 @@ class LayoutRepository( } override fun find(name: String): LayoutConfig? { - return entities.values.find { it.name == name } + return getAll().find { it.name == name } } } \ No newline at end of file diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/location/LocationsRepository.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/location/LocationsRepository.kt index 4ccc91d..0a6d4e7 100644 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/location/LocationsRepository.kt +++ b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/location/LocationsRepository.kt @@ -1,14 +1,13 @@ package app.simplecloud.plugin.sign.shared.repository.location +import app.simplecloud.plugin.api.shared.repository.YamlDirectoryRepository import app.simplecloud.plugin.sign.shared.LocationMapper import app.simplecloud.plugin.sign.shared.config.location.LocationsConfig -import app.simplecloud.plugin.sign.shared.repository.base.YamlDirectoryRepository -import java.nio.file.Files import java.nio.file.Path @Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE") class LocationsRepository( - private val directoryPath: Path, + directoryPath: Path, private val locationMapper: LocationMapper, ) : YamlDirectoryRepository(directoryPath, LocationsConfig::class.java) { @@ -21,11 +20,11 @@ class LocationsRepository( } override fun find(groupName: String): LocationsConfig? { - return entities.values.find { it.group == groupName } + return getAll().find { it.group == groupName } } private fun findByLocation(location: T): LocationsConfig? { - return entities.values.find { it -> it.locations.any { it == locationMapper.unmap(location) } } + return getAll().find { it -> it.locations.any { it == locationMapper.unmap(location) } } } fun saveLocation(group: String, location: T) { @@ -39,10 +38,6 @@ class LocationsRepository( ) } - fun removeLocationGroup(group: String) { - Files.delete(directoryPath.resolve(getFileName(group))) - } - fun removeLocation(location: T) { val config = findByLocation(location) ?: return val signLocation = locationMapper.unmap(location) diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/rule/RuleRepository.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/rule/RuleRepository.kt new file mode 100644 index 0000000..ff9034f --- /dev/null +++ b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/rule/RuleRepository.kt @@ -0,0 +1,22 @@ +package app.simplecloud.plugin.sign.shared.repository.rule + +import app.simplecloud.plugin.sign.shared.config.rule.RuleConfig +import app.simplecloud.plugin.sign.shared.repository.ResourcedYamlDirectoryRepository +import java.nio.file.Path + +class RuleRepository( + directory: Path, +) : ResourcedYamlDirectoryRepository(directory, RuleConfig::class.java) { + + override fun save(element: RuleConfig) { + save(getFileName(element.name), element) + } + + override fun find(identifier: String): RuleConfig? { + return getAll().find { it.name.uppercase() == identifier.uppercase() } + } + + override fun getFileName(identifier: String): String { + return "$identifier.yml" + } +} \ No newline at end of file diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/RuleChecker.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/RuleChecker.kt deleted file mode 100644 index 627d2c3..0000000 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/RuleChecker.kt +++ /dev/null @@ -1,9 +0,0 @@ -package app.simplecloud.plugin.sign.shared.rule - -import app.simplecloud.plugin.sign.shared.rule.impl.RuleContext - -interface RuleChecker { - - fun check(context: RuleContext): Boolean - -} \ No newline at end of file diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/RuleRegistry.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/RuleRegistry.kt deleted file mode 100644 index 7b52c7a..0000000 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/RuleRegistry.kt +++ /dev/null @@ -1,39 +0,0 @@ -package app.simplecloud.plugin.sign.shared.rule - -/** - * Registry for managing SignRules. - * This interface allows different platforms to register and manage their own rules - * while maintaining compatibility with the shared sign system. - */ -interface RuleRegistry { - /** - * Registers a new rule to the registry - * @param rule The SignRule to register - */ - fun registerRule(rule: SignRule) - - /** - * Retrieves all registered rules - * @return List of all registered SignRules - */ - fun getRules(): List - - /** - * Clears all registered rules - */ - fun clearRules() - - /** - * Checks if a rule is already registered - * @param rule The SignRule to check - * @return true if the rule is already registered, false otherwise - */ - fun hasRule(rule: SignRule): Boolean - - /** - * Gets a rule by its name - * @param name The name of the rule to get - * @return The SignRule if found, null otherwise - */ - fun getRule(name: String): SignRule? -} \ No newline at end of file diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/SignRule.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/SignRule.kt deleted file mode 100644 index 1aca0c9..0000000 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/SignRule.kt +++ /dev/null @@ -1,11 +0,0 @@ -package app.simplecloud.plugin.sign.shared.rule - -import build.buf.gen.simplecloud.controller.v1.ServerState -import org.spongepowered.configurate.objectmapping.ConfigSerializable - -@ConfigSerializable -interface SignRule { - val serverState: ServerState? - val checker: RuleChecker - fun getRuleName(): String -} \ No newline at end of file diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/context/RuleContext.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/context/RuleContext.kt new file mode 100644 index 0000000..fc47cfd --- /dev/null +++ b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/context/RuleContext.kt @@ -0,0 +1,5 @@ +package app.simplecloud.plugin.sign.shared.rule.context + +interface RuleContext { + val additionalData: Map +} \ No newline at end of file diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/context/impl/ServerRuleContext.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/context/impl/ServerRuleContext.kt new file mode 100644 index 0000000..6dcfc1e --- /dev/null +++ b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/context/impl/ServerRuleContext.kt @@ -0,0 +1,9 @@ +package app.simplecloud.plugin.sign.shared.rule.context.impl + +import app.simplecloud.controller.shared.server.Server +import app.simplecloud.plugin.sign.shared.rule.context.RuleContext + +class ServerRuleContext( + val server: Server? = null, + override val additionalData: Map = emptyMap() +) : RuleContext \ No newline at end of file diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/impl/DefaultRuleRegistry.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/impl/DefaultRuleRegistry.kt deleted file mode 100644 index 0e1c5f8..0000000 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/impl/DefaultRuleRegistry.kt +++ /dev/null @@ -1,34 +0,0 @@ -package app.simplecloud.plugin.sign.shared.rule.impl - -import app.simplecloud.plugin.sign.shared.rule.RuleRegistry -import app.simplecloud.plugin.sign.shared.rule.SignRule - -open class DefaultRuleRegistry : RuleRegistry { - - private val rules = mutableListOf() - - init { - DefaultSignRules.entries.forEach(::registerRule) - } - - override fun registerRule(rule: SignRule) { - if (!hasRule(rule)) { - rules.add(rule) - } - } - - override fun getRules(): List = rules.toList() - - override fun clearRules() { - rules.clear() - } - - override fun hasRule(rule: SignRule): Boolean { - return rules.contains(rule) - } - - override fun getRule(name: String): SignRule? { - return rules.find { it.getRuleName() == name } - } - -} \ No newline at end of file diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/impl/DefaultSignRules.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/impl/DefaultSignRules.kt deleted file mode 100644 index fc59298..0000000 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/impl/DefaultSignRules.kt +++ /dev/null @@ -1,58 +0,0 @@ -package app.simplecloud.plugin.sign.shared.rule.impl - -import app.simplecloud.plugin.sign.shared.rule.RuleChecker -import app.simplecloud.plugin.sign.shared.rule.SignRule -import build.buf.gen.simplecloud.controller.v1.ServerState -import org.spongepowered.configurate.objectmapping.ConfigSerializable - -@ConfigSerializable -enum class DefaultSignRules( - override val serverState: ServerState?, override val checker: RuleChecker -) : SignRule { - - STARTING( - ServerState.STARTING, object : RuleChecker { - override fun check(context: RuleContext): Boolean { - return context.server?.state == ServerState.STARTING - } - }), - - OFFLINE( - null, object : RuleChecker { - override fun check(context: RuleContext): Boolean { - return context.server == null - } - }), - - MAINTENANCE( - ServerState.AVAILABLE, object : RuleChecker { - override fun check(context: RuleContext): Boolean { - return context.server?.properties?.getOrDefault("maintenance", false) == true - } - }), - - FULL( - ServerState.AVAILABLE, object : RuleChecker { - override fun check(context: RuleContext): Boolean { - val server = context.server ?: return false - return server.playerCount == server.maxPlayers - } - }), - - EMPTY( - ServerState.AVAILABLE, object : RuleChecker { - override fun check(context: RuleContext): Boolean { - val server = context.server ?: return false - return server.playerCount == server.maxPlayers - } - }), - - ONLINE( - ServerState.AVAILABLE, object : RuleChecker { - override fun check(context: RuleContext): Boolean { - return context.server?.state == ServerState.AVAILABLE - } - }); - - override fun getRuleName(): String = name -} \ No newline at end of file diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/impl/RuleContext.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/impl/RuleContext.kt deleted file mode 100644 index e9ba9ed..0000000 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/impl/RuleContext.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.simplecloud.plugin.sign.shared.rule.impl - -import app.simplecloud.controller.shared.server.Server -import build.buf.gen.simplecloud.controller.v1.ServerState - -open class RuleContext( - val server: Server?, - val serverState: ServerState?, - val additionalData: Map = emptyMap() -) diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/serialize/SignRuleSerializer.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/serialize/SignRuleSerializer.kt deleted file mode 100644 index 9381d30..0000000 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/serialize/SignRuleSerializer.kt +++ /dev/null @@ -1,26 +0,0 @@ -package app.simplecloud.plugin.sign.shared.rule.serialize - -import app.simplecloud.plugin.sign.shared.rule.RuleRegistry -import app.simplecloud.plugin.sign.shared.rule.SignRule -import org.spongepowered.configurate.ConfigurationNode -import org.spongepowered.configurate.serialize.SerializationException -import org.spongepowered.configurate.serialize.TypeSerializer -import java.lang.reflect.Type - -class SignRuleSerializer(private val ruleRegistry: RuleRegistry) : TypeSerializer { - - override fun deserialize(type: Type, node: ConfigurationNode): SignRule { - val ruleName = node.get(String::class.java) ?: throw SerializationException("Rule name must be specified.") - - return ruleRegistry.getRule(ruleName) ?: throw SerializationException("Rule $ruleName not found.") - } - - override fun serialize(type: Type, signRule: SignRule?, node: ConfigurationNode) { - if (signRule == null) { - node.set(null) - return - } - - node.set(signRule.getRuleName()) - } -} \ No newline at end of file diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/sender/SignCommandSender.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/sender/SignCommandSender.kt index 010d09e..ce5ac54 100644 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/sender/SignCommandSender.kt +++ b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/sender/SignCommandSender.kt @@ -1,12 +1,12 @@ package app.simplecloud.plugin.sign.shared.sender -import app.simplecloud.plugin.sign.shared.config.location.SignLocation +import app.simplecloud.plugin.sign.shared.config.location.SignLocationConfig import net.kyori.adventure.text.Component interface SignCommandSender { fun sendMessage(component: Component) - suspend fun getTargetBlock(maxDistance: Int): SignLocation? + suspend fun getTargetBlock(maxDistance: Int): SignLocationConfig? } \ No newline at end of file diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/service/SignService.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/service/SignService.kt index fa26bcb..a5c0951 100644 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/service/SignService.kt +++ b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/service/SignService.kt @@ -2,18 +2,19 @@ package app.simplecloud.plugin.sign.shared.service import app.simplecloud.controller.api.ControllerApi import app.simplecloud.plugin.sign.shared.CloudSign -import app.simplecloud.plugin.sign.shared.config.location.SignLocation +import app.simplecloud.plugin.sign.shared.config.location.SignLocationConfig +import app.simplecloud.plugin.sign.shared.config.rule.RuleConfig interface SignService { val controllerApi: ControllerApi.Coroutine fun getCloudSign(location: T): CloudSign? - fun getAllLocations(): List + fun getAllLocations(): List fun getAllGroupsRegistered(): List - fun getLocationsByGroup(group: String): List? + fun getLocationsByGroup(group: String): List? fun register(group: String, location: T) @@ -21,9 +22,13 @@ interface SignService { fun exists(group: String): Boolean - fun map(location: SignLocation): T + fun getAllRules(): List - fun unmap(location: T): SignLocation + fun getRule(ruleName: String): RuleConfig? + + fun map(location: SignLocationConfig): T + + fun unmap(location: T): SignLocationConfig } \ No newline at end of file diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/utils/MatcherUtil.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/utils/MatcherUtil.kt new file mode 100644 index 0000000..575d8c3 --- /dev/null +++ b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/utils/MatcherUtil.kt @@ -0,0 +1,98 @@ +package app.simplecloud.plugin.sign.shared.utils + +import app.simplecloud.plugin.sign.shared.SignManagerProvider +import app.simplecloud.plugin.sign.shared.matcher.MatcherConfigEntry +import app.simplecloud.plugin.sign.shared.matcher.MatcherType +import app.simplecloud.plugin.sign.shared.rule.context.RuleContext +import app.simplecloud.plugin.sign.shared.rule.context.impl.ServerRuleContext +import kotlinx.coroutines.runBlocking +import net.kyori.adventure.text.minimessage.MiniMessage + +object MatcherUtil { + + private val miniMessage = MiniMessage.miniMessage() + + fun matches(matcher: Map>, ruleContext: RuleContext): Boolean { + return runBlocking { + val ruleMatches = matcher.all { (type, entries) -> + evaluateMatcher(type, entries, ruleContext) + } + if (!ruleMatches) return@runBlocking false + + matcher.all { (type, entries) -> + evaluateMatcher(type, entries, ruleContext) + } + } + } + + private suspend fun evaluateMatcher( + type: MatcherType, + entries: List, + ruleContext: RuleContext + ): Boolean { + return when (type) { + MatcherType.MATCH_ALL -> entries.all { entry -> + entry.operation.matches( + resolvePlaceholder(entry.key, ruleContext), + resolvePlaceholder(entry.value, ruleContext), + entry.negate + ) + } + + MatcherType.MATCH_ANY -> entries.any { entry -> + entry.operation.matches( + resolvePlaceholder(entry.key, ruleContext), + resolvePlaceholder(entry.value, ruleContext), + entry.negate + ) + } + } + } + + private suspend fun resolvePlaceholder(placeholder: String, ruleContext: RuleContext): String { + val pattern = "<(server_|group_|env_)([^>]+)>".toRegex() + + return when { + placeholder.startsWith(" { + if (ruleContext !is ServerRuleContext) return placeholder + if (placeholder == "" && ruleContext.server == null) return "null" + + ruleContext.server?.let { server -> + when { + placeholder.startsWith(" { + val innerKey = pattern.find(placeholder)?.groupValues?.get(2) ?: return placeholder + return miniMessage.serialize( + SignManagerProvider.get() + .serverPlaceholderProvider + .append(server, "<$innerKey>") + ) + } + + placeholder.startsWith(" { + val innerKey = pattern.find(placeholder)?.groupValues?.get(2) ?: return placeholder + val group = SignManagerProvider.get() + .controllerApi + .getGroups() + .getGroupByName(server.group) + miniMessage.serialize( + SignManagerProvider.get() + .groupPlaceholderProvider + .append(group, "<$innerKey>") + ) + } + + else -> placeholder + } + } ?: placeholder + } + + placeholder.startsWith(" { + val innerKey = pattern.find(placeholder)?.groupValues?.get(2) ?: return placeholder + System.getenv(innerKey) ?: placeholder + } + + else -> placeholder + } + } + +} \ No newline at end of file diff --git a/sign-shared/src/main/resources/layouts/empty_default.yml b/sign-shared/src/main/resources/layouts/empty_default.yml index 56db1f8..d5d0457 100644 --- a/sign-shared/src/main/resources/layouts/empty_default.yml +++ b/sign-shared/src/main/resources/layouts/empty_default.yml @@ -1,8 +1,13 @@ name: 'empty_default' -rule: 'EMPTY' -priority: 10 +rule: 'available' frame-update-interval: 1000 +matcher: + MATCH_ALL: + - key: '' + value: '0' + operation: EQUALS + frames: - lines: - '✨' diff --git a/sign-shared/src/main/resources/layouts/full_default.yml b/sign-shared/src/main/resources/layouts/full_default.yml index db13fc9..b8b4155 100644 --- a/sign-shared/src/main/resources/layouts/full_default.yml +++ b/sign-shared/src/main/resources/layouts/full_default.yml @@ -1,8 +1,13 @@ name: 'full_default' -rule: 'FULL' -priority: 8 +rule: 'available' frame-update-interval: 1250 +matcher: + MATCH_ALL: + - key: '' + value: '' + operation: EQUALS + frames: - lines: - '⛔' diff --git a/sign-shared/src/main/resources/layouts/maintenance_default.yml b/sign-shared/src/main/resources/layouts/maintenance_default.yml index 3590577..d11f5f3 100644 --- a/sign-shared/src/main/resources/layouts/maintenance_default.yml +++ b/sign-shared/src/main/resources/layouts/maintenance_default.yml @@ -1,8 +1,13 @@ name: 'maintenance_default' -rule: 'MAINTENANCE' -priority: 7 +rule: 'available' frame-update-interval: 1000 +matcher: + MATCH_ALL: + - key: '' + value: 'true' + operation: EQUALS + frames: - lines: - '🚧' diff --git a/sign-shared/src/main/resources/layouts/offline_default.yml b/sign-shared/src/main/resources/layouts/offline_default.yml index 0118b20..cc96f52 100644 --- a/sign-shared/src/main/resources/layouts/offline_default.yml +++ b/sign-shared/src/main/resources/layouts/offline_default.yml @@ -1,6 +1,5 @@ name: 'offline_default' rule: 'OFFLINE' -priority: 50 frame-update-interval: 500 frames: diff --git a/sign-shared/src/main/resources/layouts/online_default.yml b/sign-shared/src/main/resources/layouts/online_default.yml index 700b41a..3f7b790 100644 --- a/sign-shared/src/main/resources/layouts/online_default.yml +++ b/sign-shared/src/main/resources/layouts/online_default.yml @@ -1,6 +1,5 @@ name: 'online_default' -rule: 'ONLINE' -priority: 9 +rule: 'AVAILABLE' frame-update-interval: 1250 frames: diff --git a/sign-shared/src/main/resources/layouts/starting_default.yml b/sign-shared/src/main/resources/layouts/starting_default.yml index 55d5889..a65eaa7 100644 --- a/sign-shared/src/main/resources/layouts/starting_default.yml +++ b/sign-shared/src/main/resources/layouts/starting_default.yml @@ -1,6 +1,5 @@ name: 'starting_default' rule: 'STARTING' -priority: 6 frame-update-interval: 500 frames: diff --git a/sign-shared/src/main/resources/rules/available.yml b/sign-shared/src/main/resources/rules/available.yml new file mode 100644 index 0000000..9b5e193 --- /dev/null +++ b/sign-shared/src/main/resources/rules/available.yml @@ -0,0 +1,7 @@ +name: 'available' + +matcher: + MATCH_ALL: + - key: '' + value: 'AVAILABLE' + operation: EQUALS \ No newline at end of file diff --git a/sign-shared/src/main/resources/rules/offline.yml b/sign-shared/src/main/resources/rules/offline.yml new file mode 100644 index 0000000..c8922bb --- /dev/null +++ b/sign-shared/src/main/resources/rules/offline.yml @@ -0,0 +1,7 @@ +name: 'offline' + +matcher: + MATCH_ALL: + - key: '' + value: 'NULL' + operation: EQUALS \ No newline at end of file diff --git a/sign-shared/src/main/resources/rules/starting.yml b/sign-shared/src/main/resources/rules/starting.yml new file mode 100644 index 0000000..00eb50c --- /dev/null +++ b/sign-shared/src/main/resources/rules/starting.yml @@ -0,0 +1,7 @@ +name: 'starting' + +matcher: + MATCH_ALL: + - key: '' + value: 'STARTING' + operation: EQUALS \ No newline at end of file From ef820b89395ff96a6263419acab7352bb60e0eaf Mon Sep 17 00:00:00 2001 From: PrexorJustin Date: Fri, 10 Jan 2025 20:00:57 +0100 Subject: [PATCH 2/9] fix: reworked the logic of LayoutConfig.kt and RuleConfig.kt --- .../plugin/sign/shared/SignManager.kt | 9 +++----- .../plugin/sign/shared/SignManagerProvider.kt | 9 ++++++-- .../sign/shared/config/layout/LayoutConfig.kt | 21 +++++++++++++++---- .../plugin/sign/shared/utils/MatcherUtil.kt | 10 +++------ .../layouts/{empty_default.yml => empty.yml} | 10 ++------- .../layouts/{full_default.yml => full.yml} | 10 ++------- ...aintenance_default.yml => maintenance.yml} | 10 ++------- .../{offline_default.yml => offline.yml} | 4 ++-- .../{online_default.yml => online.yml} | 4 ++-- .../{starting_default.yml => starting.yml} | 4 ++-- .../src/main/resources/rules/empty.yml | 8 +++++++ sign-shared/src/main/resources/rules/full.yml | 8 +++++++ .../src/main/resources/rules/maintenance.yml | 8 +++++++ .../{available.yml => state_available.yml} | 0 .../rules/{offline.yml => state_offline.yml} | 0 .../{starting.yml => state_starting.yml} | 0 16 files changed, 66 insertions(+), 49 deletions(-) rename sign-shared/src/main/resources/layouts/{empty_default.yml => empty.yml} (72%) rename sign-shared/src/main/resources/layouts/{full_default.yml => full.yml} (55%) rename sign-shared/src/main/resources/layouts/{maintenance_default.yml => maintenance.yml} (57%) rename sign-shared/src/main/resources/layouts/{offline_default.yml => offline.yml} (90%) rename sign-shared/src/main/resources/layouts/{online_default.yml => online.yml} (83%) rename sign-shared/src/main/resources/layouts/{starting_default.yml => starting.yml} (92%) create mode 100644 sign-shared/src/main/resources/rules/empty.yml create mode 100644 sign-shared/src/main/resources/rules/full.yml create mode 100644 sign-shared/src/main/resources/rules/maintenance.yml rename sign-shared/src/main/resources/rules/{available.yml => state_available.yml} (100%) rename sign-shared/src/main/resources/rules/{offline.yml => state_offline.yml} (100%) rename sign-shared/src/main/resources/rules/{starting.yml => state_starting.yml} (100%) diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/SignManager.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/SignManager.kt index b7e45b6..efe2f23 100644 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/SignManager.kt +++ b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/SignManager.kt @@ -50,7 +50,7 @@ class SignManager( val serverPlaceholderProvider: ServerPlaceholderProvider = ServerPlaceholderProvider() init { - SignManagerProvider.register(this) + SignManagerProvider.initialize(this) } fun start() { @@ -119,10 +119,7 @@ class SignManager( override fun unmap(location: T): SignLocationConfig = locationMapper.unmap(location) fun getLayout(ruleContext: RuleContext): LayoutConfig { - return layoutRepository.getAll().firstOrNull { - MatcherUtil.matches(it.matcher, ruleContext) && - MatcherUtil.matches(it.rule.matcher, ruleContext) - } + return layoutRepository.getAll().sortedByDescending { it.priority }.firstOrNull { it.matches(ruleContext) } ?: LayoutConfig() } @@ -165,7 +162,7 @@ class SignManager( } .filter { server -> val ruleContext = ServerRuleContext(server) - ruleRepository.getAll().any { rule -> MatcherUtil.matches(rule.matcher, ruleContext) } + ruleRepository.getAll().any { rule -> MatcherUtil.matches(rule, ruleContext) } } .sortedBy { it.numericalId } .iterator() diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/SignManagerProvider.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/SignManagerProvider.kt index 5301ff4..43e0d3a 100644 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/SignManagerProvider.kt +++ b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/SignManagerProvider.kt @@ -2,11 +2,16 @@ package app.simplecloud.plugin.sign.shared object SignManagerProvider { - private lateinit var signManager: SignManager<*> + private var signManager: SignManager<*>? = null - fun register(signManager: SignManager<*>) { + @Synchronized + fun initialize(signManager: SignManager<*>) { + if (this.signManager != null) { + throw IllegalStateException("SignManager is already initialize") + } this.signManager = signManager } fun get(): SignManager<*> = signManager + ?: throw IllegalStateException("SignManager has not been initialize") } \ No newline at end of file diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/layout/LayoutConfig.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/layout/LayoutConfig.kt index eae0a22..a307c15 100644 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/layout/LayoutConfig.kt +++ b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/layout/LayoutConfig.kt @@ -3,8 +3,9 @@ package app.simplecloud.plugin.sign.shared.config.layout import app.simplecloud.controller.shared.server.Server import app.simplecloud.plugin.sign.shared.SignManagerProvider import app.simplecloud.plugin.sign.shared.config.rule.RuleConfig -import app.simplecloud.plugin.sign.shared.matcher.MatcherConfigEntry -import app.simplecloud.plugin.sign.shared.matcher.MatcherType +import app.simplecloud.plugin.sign.shared.rule.context.RuleContext +import app.simplecloud.plugin.sign.shared.utils.MatcherUtil +import kotlinx.coroutines.runBlocking import org.spongepowered.configurate.objectmapping.ConfigSerializable import org.spongepowered.configurate.objectmapping.meta.Setting @@ -12,8 +13,8 @@ import org.spongepowered.configurate.objectmapping.meta.Setting data class LayoutConfig( val name: String = "", @Setting("rule") - val ruleName: String = "EMPTY", - val matcher: Map> = emptyMap(), + val ruleName: String = "", + val priority: Int = 0, val serverName: String = "%group%-%numerical-id%", val frameUpdateInterval: Long = 500, val frames: List = listOf(), @@ -23,6 +24,18 @@ data class LayoutConfig( get() = SignManagerProvider.get().getRule(ruleName) ?: RuleConfig(name = "UNKNOWN_RULE") + fun matches(ruleContext: RuleContext): Boolean { + return runBlocking { + rule.inherit?.let { inheritRuleName -> + SignManagerProvider.get().getRule(inheritRuleName)?.let { inheritRule -> + MatcherUtil.matches(inheritRule, ruleContext) + } + } + + MatcherUtil.matches(rule, ruleContext) + } + } + fun constructName(server: Server): String { return serverName .replace("%group%", server.group) diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/utils/MatcherUtil.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/utils/MatcherUtil.kt index 575d8c3..c82676a 100644 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/utils/MatcherUtil.kt +++ b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/utils/MatcherUtil.kt @@ -1,6 +1,7 @@ package app.simplecloud.plugin.sign.shared.utils import app.simplecloud.plugin.sign.shared.SignManagerProvider +import app.simplecloud.plugin.sign.shared.config.rule.RuleConfig import app.simplecloud.plugin.sign.shared.matcher.MatcherConfigEntry import app.simplecloud.plugin.sign.shared.matcher.MatcherType import app.simplecloud.plugin.sign.shared.rule.context.RuleContext @@ -12,14 +13,9 @@ object MatcherUtil { private val miniMessage = MiniMessage.miniMessage() - fun matches(matcher: Map>, ruleContext: RuleContext): Boolean { + fun matches(rule: RuleConfig, ruleContext: RuleContext): Boolean { return runBlocking { - val ruleMatches = matcher.all { (type, entries) -> - evaluateMatcher(type, entries, ruleContext) - } - if (!ruleMatches) return@runBlocking false - - matcher.all { (type, entries) -> + rule.matcher.all { (type, entries) -> evaluateMatcher(type, entries, ruleContext) } } diff --git a/sign-shared/src/main/resources/layouts/empty_default.yml b/sign-shared/src/main/resources/layouts/empty.yml similarity index 72% rename from sign-shared/src/main/resources/layouts/empty_default.yml rename to sign-shared/src/main/resources/layouts/empty.yml index d5d0457..53cd385 100644 --- a/sign-shared/src/main/resources/layouts/empty_default.yml +++ b/sign-shared/src/main/resources/layouts/empty.yml @@ -1,13 +1,7 @@ -name: 'empty_default' -rule: 'available' +name: 'empty' +rule: 'empty' frame-update-interval: 1000 -matcher: - MATCH_ALL: - - key: '' - value: '0' - operation: EQUALS - frames: - lines: - '✨' diff --git a/sign-shared/src/main/resources/layouts/full_default.yml b/sign-shared/src/main/resources/layouts/full.yml similarity index 55% rename from sign-shared/src/main/resources/layouts/full_default.yml rename to sign-shared/src/main/resources/layouts/full.yml index b8b4155..90b85ea 100644 --- a/sign-shared/src/main/resources/layouts/full_default.yml +++ b/sign-shared/src/main/resources/layouts/full.yml @@ -1,13 +1,7 @@ -name: 'full_default' -rule: 'available' +name: 'full' +rule: 'full' frame-update-interval: 1250 -matcher: - MATCH_ALL: - - key: '' - value: '' - operation: EQUALS - frames: - lines: - '⛔' diff --git a/sign-shared/src/main/resources/layouts/maintenance_default.yml b/sign-shared/src/main/resources/layouts/maintenance.yml similarity index 57% rename from sign-shared/src/main/resources/layouts/maintenance_default.yml rename to sign-shared/src/main/resources/layouts/maintenance.yml index d11f5f3..59aeb2e 100644 --- a/sign-shared/src/main/resources/layouts/maintenance_default.yml +++ b/sign-shared/src/main/resources/layouts/maintenance.yml @@ -1,13 +1,7 @@ -name: 'maintenance_default' -rule: 'available' +name: 'maintenance' +rule: 'maintenance' frame-update-interval: 1000 -matcher: - MATCH_ALL: - - key: '' - value: 'true' - operation: EQUALS - frames: - lines: - '🚧' diff --git a/sign-shared/src/main/resources/layouts/offline_default.yml b/sign-shared/src/main/resources/layouts/offline.yml similarity index 90% rename from sign-shared/src/main/resources/layouts/offline_default.yml rename to sign-shared/src/main/resources/layouts/offline.yml index cc96f52..1c73042 100644 --- a/sign-shared/src/main/resources/layouts/offline_default.yml +++ b/sign-shared/src/main/resources/layouts/offline.yml @@ -1,5 +1,5 @@ -name: 'offline_default' -rule: 'OFFLINE' +name: 'offline' +rule: 'state_offline' frame-update-interval: 500 frames: diff --git a/sign-shared/src/main/resources/layouts/online_default.yml b/sign-shared/src/main/resources/layouts/online.yml similarity index 83% rename from sign-shared/src/main/resources/layouts/online_default.yml rename to sign-shared/src/main/resources/layouts/online.yml index 3f7b790..059ce54 100644 --- a/sign-shared/src/main/resources/layouts/online_default.yml +++ b/sign-shared/src/main/resources/layouts/online.yml @@ -1,5 +1,5 @@ -name: 'online_default' -rule: 'AVAILABLE' +name: 'online' +rule: 'state_available' frame-update-interval: 1250 frames: diff --git a/sign-shared/src/main/resources/layouts/starting_default.yml b/sign-shared/src/main/resources/layouts/starting.yml similarity index 92% rename from sign-shared/src/main/resources/layouts/starting_default.yml rename to sign-shared/src/main/resources/layouts/starting.yml index a65eaa7..78687d6 100644 --- a/sign-shared/src/main/resources/layouts/starting_default.yml +++ b/sign-shared/src/main/resources/layouts/starting.yml @@ -1,5 +1,5 @@ -name: 'starting_default' -rule: 'STARTING' +name: 'starting' +rule: 'state_starting' frame-update-interval: 500 frames: diff --git a/sign-shared/src/main/resources/rules/empty.yml b/sign-shared/src/main/resources/rules/empty.yml new file mode 100644 index 0000000..039f7ce --- /dev/null +++ b/sign-shared/src/main/resources/rules/empty.yml @@ -0,0 +1,8 @@ +name: 'empty' +inherit: 'state_available' + +matcher: + MATCH_ALL: + - key: '' + value: '0' + operation: EQUALS diff --git a/sign-shared/src/main/resources/rules/full.yml b/sign-shared/src/main/resources/rules/full.yml new file mode 100644 index 0000000..2a01b14 --- /dev/null +++ b/sign-shared/src/main/resources/rules/full.yml @@ -0,0 +1,8 @@ +name: 'full' +inherit: 'state_available' + +matcher: + MATCH_ALL: + - key: '' + value: '' + operation: EQUALS \ No newline at end of file diff --git a/sign-shared/src/main/resources/rules/maintenance.yml b/sign-shared/src/main/resources/rules/maintenance.yml new file mode 100644 index 0000000..ccb5c2e --- /dev/null +++ b/sign-shared/src/main/resources/rules/maintenance.yml @@ -0,0 +1,8 @@ +name: 'maintenance' +inherit: 'state_available' + +matcher: + MATCH_ALL: + - key: '' + value: 'true' + operation: EQUALS \ No newline at end of file diff --git a/sign-shared/src/main/resources/rules/available.yml b/sign-shared/src/main/resources/rules/state_available.yml similarity index 100% rename from sign-shared/src/main/resources/rules/available.yml rename to sign-shared/src/main/resources/rules/state_available.yml diff --git a/sign-shared/src/main/resources/rules/offline.yml b/sign-shared/src/main/resources/rules/state_offline.yml similarity index 100% rename from sign-shared/src/main/resources/rules/offline.yml rename to sign-shared/src/main/resources/rules/state_offline.yml diff --git a/sign-shared/src/main/resources/rules/starting.yml b/sign-shared/src/main/resources/rules/state_starting.yml similarity index 100% rename from sign-shared/src/main/resources/rules/starting.yml rename to sign-shared/src/main/resources/rules/state_starting.yml From 6e1d4e9e1945e34228e028a736c647fb6602780f Mon Sep 17 00:00:00 2001 From: PrexorJustin Date: Fri, 10 Jan 2025 20:05:42 +0100 Subject: [PATCH 3/9] fix: config names --- .../simplecloud/plugin/sign/shared/config/rule/RuleConfig.kt | 3 --- sign-shared/src/main/resources/rules/state_available.yml | 2 +- sign-shared/src/main/resources/rules/state_offline.yml | 2 +- sign-shared/src/main/resources/rules/state_starting.yml | 2 +- 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/rule/RuleConfig.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/rule/RuleConfig.kt index d93b849..780c7b7 100644 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/rule/RuleConfig.kt +++ b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/rule/RuleConfig.kt @@ -10,6 +10,3 @@ data class RuleConfig( val inherit: String? = null, val matcher: Map> = emptyMap(), ) - - - diff --git a/sign-shared/src/main/resources/rules/state_available.yml b/sign-shared/src/main/resources/rules/state_available.yml index 9b5e193..b6814dc 100644 --- a/sign-shared/src/main/resources/rules/state_available.yml +++ b/sign-shared/src/main/resources/rules/state_available.yml @@ -1,4 +1,4 @@ -name: 'available' +name: 'state_available' matcher: MATCH_ALL: diff --git a/sign-shared/src/main/resources/rules/state_offline.yml b/sign-shared/src/main/resources/rules/state_offline.yml index c8922bb..b767254 100644 --- a/sign-shared/src/main/resources/rules/state_offline.yml +++ b/sign-shared/src/main/resources/rules/state_offline.yml @@ -1,4 +1,4 @@ -name: 'offline' +name: 'state_offline' matcher: MATCH_ALL: diff --git a/sign-shared/src/main/resources/rules/state_starting.yml b/sign-shared/src/main/resources/rules/state_starting.yml index 00eb50c..b3359dd 100644 --- a/sign-shared/src/main/resources/rules/state_starting.yml +++ b/sign-shared/src/main/resources/rules/state_starting.yml @@ -1,4 +1,4 @@ -name: 'starting' +name: 'state_starting' matcher: MATCH_ALL: From 1bb7040493121454607e1d7185160659877a3763 Mon Sep 17 00:00:00 2001 From: PrexorJustin Date: Fri, 10 Jan 2025 22:07:57 +0100 Subject: [PATCH 4/9] fix: using ResourcedYamlDirectoryRepository.kt from Plugin-API --- .../ResourcedYamlDirectoryRepository.kt | 79 ------------------- .../repository/layout/LayoutRepository.kt | 11 ++- .../shared/repository/rule/RuleRepository.kt | 2 +- 3 files changed, 6 insertions(+), 86 deletions(-) delete mode 100644 sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/ResourcedYamlDirectoryRepository.kt diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/ResourcedYamlDirectoryRepository.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/ResourcedYamlDirectoryRepository.kt deleted file mode 100644 index 649afc2..0000000 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/ResourcedYamlDirectoryRepository.kt +++ /dev/null @@ -1,79 +0,0 @@ -package app.simplecloud.plugin.sign.shared.repository - -import app.simplecloud.plugin.api.shared.repository.YamlDirectoryRepository -import java.io.File -import java.io.FileOutputStream -import java.net.URL -import java.nio.file.Path -import java.util.jar.JarFile -import kotlin.io.path.exists -import kotlin.io.path.pathString - -abstract class ResourcedYamlDirectoryRepository( - private val directory: Path, - clazz: Class, -) : YamlDirectoryRepository(directory, clazz) { - - override fun load(): List { - if (!directory.exists()) loadDefaults() - - return super.load() - } - - private fun loadDefaults() { - val targetDirectory = File(directory.toUri()).apply { mkdirs() } - - val last = directory.pathString.split('/').last() - - val resourceUrl = YamlDirectoryRepository::class.java.getResource("/$last") ?: run { - println("$last folder not found in resources") - return - } - - when (resourceUrl.protocol) { - "file" -> handleFileProtocol(resourceUrl, targetDirectory) - "jar" -> handleJarProtocol(resourceUrl, targetDirectory) - else -> println("Unsupported protocol: ${resourceUrl.protocol}") - } - } - - private fun handleFileProtocol(resourceUrl: URL, targetDirectory: File) { - val resourceDir = File(resourceUrl.toURI()) - if (resourceDir.exists()) { - resourceDir.copyRecursively(targetDirectory, overwrite = true) - } else { - println("Resource directory does not exist: ${resourceUrl.path}") - } - } - - private fun handleJarProtocol(resourceUrl: URL, targetDirectory: File) { - val jarPath = resourceUrl.path.substringBefore("!").removePrefix("file:") - try { - JarFile(jarPath).use { jarFile -> - val last = directory.pathString.split('/').last() - jarFile.entries().asSequence() - .filter { it.name.startsWith("$last/") && !it.isDirectory } - .forEach { entry -> - val targetFile = File(targetDirectory, entry.name.removePrefix("$last/")) - targetFile.parentFile.mkdirs() - try { - jarFile.getInputStream(entry).use { inputStream -> - FileOutputStream(targetFile).use { fos -> - fos.write(0xEF) - fos.write(0xBB) - fos.write(0xBF) - - inputStream.copyTo(fos) - } - } - } catch (e: Exception) { - println("Error copying file ${entry.name}: ${e.message}") - } - } - } - } catch (e: Exception) { - println("Error processing JAR file: ${e.message}") - e.printStackTrace() - } - } -} \ No newline at end of file diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/layout/LayoutRepository.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/layout/LayoutRepository.kt index 55c04cf..30b6f4c 100644 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/layout/LayoutRepository.kt +++ b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/layout/LayoutRepository.kt @@ -1,10 +1,9 @@ package app.simplecloud.plugin.sign.shared.repository.layout +import app.simplecloud.plugin.api.shared.repository.ResourcedYamlDirectoryRepository import app.simplecloud.plugin.sign.shared.config.layout.LayoutConfig -import app.simplecloud.plugin.sign.shared.repository.ResourcedYamlDirectoryRepository import java.nio.file.Path -@Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE") class LayoutRepository( directory: Path ) : ResourcedYamlDirectoryRepository(directory, LayoutConfig::class.java) { @@ -13,11 +12,11 @@ class LayoutRepository( save(getFileName(element.name), element) } - override fun getFileName(name: String): String { - return "$name.yml" + override fun getFileName(identifier: String): String { + return "$identifier.yml" } - override fun find(name: String): LayoutConfig? { - return getAll().find { it.name == name } + override fun find(identifier: String): LayoutConfig? { + return getAll().find { it.name == identifier } } } \ No newline at end of file diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/rule/RuleRepository.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/rule/RuleRepository.kt index ff9034f..b640b69 100644 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/rule/RuleRepository.kt +++ b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/repository/rule/RuleRepository.kt @@ -1,7 +1,7 @@ package app.simplecloud.plugin.sign.shared.repository.rule +import app.simplecloud.plugin.api.shared.repository.ResourcedYamlDirectoryRepository import app.simplecloud.plugin.sign.shared.config.rule.RuleConfig -import app.simplecloud.plugin.sign.shared.repository.ResourcedYamlDirectoryRepository import java.nio.file.Path class RuleRepository( From e7aa3be90b3a295531a237a23e5ffef4ad48a3d1 Mon Sep 17 00:00:00 2001 From: PrexorJustin Date: Fri, 10 Jan 2025 23:14:13 +0100 Subject: [PATCH 5/9] fix: using joinstate instead of property:maintenance for the maintenace rule --- .../plugin/sign/shared/config/layout/LayoutConfig.kt | 6 +++--- sign-shared/src/main/resources/layouts/full.yml | 1 + sign-shared/src/main/resources/layouts/maintenance.yml | 1 + sign-shared/src/main/resources/layouts/starting.yml | 1 + sign-shared/src/main/resources/rules/maintenance.yml | 4 ++-- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/layout/LayoutConfig.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/layout/LayoutConfig.kt index a307c15..4868525 100644 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/layout/LayoutConfig.kt +++ b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/layout/LayoutConfig.kt @@ -15,7 +15,7 @@ data class LayoutConfig( @Setting("rule") val ruleName: String = "", val priority: Int = 0, - val serverName: String = "%group%-%numerical-id%", + val serverName: String = "-", val frameUpdateInterval: Long = 500, val frames: List = listOf(), ) { @@ -38,8 +38,8 @@ data class LayoutConfig( fun constructName(server: Server): String { return serverName - .replace("%group%", server.group) - .replace("%numerical-id%", server.numericalId.toString()) + .replace("", server.group) + .replace("", server.numericalId.toString()) } } \ No newline at end of file diff --git a/sign-shared/src/main/resources/layouts/full.yml b/sign-shared/src/main/resources/layouts/full.yml index 90b85ea..6813eed 100644 --- a/sign-shared/src/main/resources/layouts/full.yml +++ b/sign-shared/src/main/resources/layouts/full.yml @@ -1,5 +1,6 @@ name: 'full' rule: 'full' +priority: 3 frame-update-interval: 1250 frames: diff --git a/sign-shared/src/main/resources/layouts/maintenance.yml b/sign-shared/src/main/resources/layouts/maintenance.yml index 59aeb2e..89eb116 100644 --- a/sign-shared/src/main/resources/layouts/maintenance.yml +++ b/sign-shared/src/main/resources/layouts/maintenance.yml @@ -1,5 +1,6 @@ name: 'maintenance' rule: 'maintenance' +priority: 5 frame-update-interval: 1000 frames: diff --git a/sign-shared/src/main/resources/layouts/starting.yml b/sign-shared/src/main/resources/layouts/starting.yml index 78687d6..97fa75a 100644 --- a/sign-shared/src/main/resources/layouts/starting.yml +++ b/sign-shared/src/main/resources/layouts/starting.yml @@ -1,5 +1,6 @@ name: 'starting' rule: 'state_starting' +priority: 4 frame-update-interval: 500 frames: diff --git a/sign-shared/src/main/resources/rules/maintenance.yml b/sign-shared/src/main/resources/rules/maintenance.yml index ccb5c2e..49191a1 100644 --- a/sign-shared/src/main/resources/rules/maintenance.yml +++ b/sign-shared/src/main/resources/rules/maintenance.yml @@ -3,6 +3,6 @@ inherit: 'state_available' matcher: MATCH_ALL: - - key: '' - value: 'true' + - key: '' + value: 'maintenance' operation: EQUALS \ No newline at end of file From 8ef6265556ff595c9ce22207f1e13712d5714ea0 Mon Sep 17 00:00:00 2001 From: PrexorJustin Date: Sun, 12 Jan 2025 15:30:55 +0100 Subject: [PATCH 6/9] fix: now using proper placeholders in layout as well --- .../sign/paper/PaperSignsPluginBootstrap.kt | 21 +-------- .../sign/paper/listener/SignListener.kt | 44 ++++++++++++------- .../plugin/sign/shared/SignManager.kt | 4 +- .../sign/shared/config/layout/LayoutConfig.kt | 2 +- .../shared/rule/{context => }/RuleContext.kt | 2 +- .../{context => }/impl/ServerRuleContext.kt | 4 +- .../plugin/sign/shared/utils/MatcherUtil.kt | 17 ++++++- .../src/main/resources/layouts/empty.yml | 8 ++-- .../main/resources/layouts/maintenance.yml | 2 +- .../src/main/resources/layouts/online.yml | 4 +- .../src/main/resources/layouts/starting.yml | 6 +-- 11 files changed, 60 insertions(+), 54 deletions(-) rename sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/{context => }/RuleContext.kt (54%) rename sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/{context => }/impl/ServerRuleContext.kt (60%) diff --git a/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/PaperSignsPluginBootstrap.kt b/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/PaperSignsPluginBootstrap.kt index 2ce2344..b4c2eaa 100644 --- a/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/PaperSignsPluginBootstrap.kt +++ b/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/PaperSignsPluginBootstrap.kt @@ -9,14 +9,13 @@ import app.simplecloud.plugin.sign.shared.CloudSign import app.simplecloud.plugin.sign.shared.SignManager import app.simplecloud.plugin.sign.shared.command.SignCommand import app.simplecloud.plugin.sign.shared.config.layout.FrameConfig +import app.simplecloud.plugin.sign.shared.utils.MatcherUtil import io.papermc.paper.plugin.bootstrap.BootstrapContext import io.papermc.paper.plugin.bootstrap.PluginBootstrap import io.papermc.paper.plugin.bootstrap.PluginProviderContext import kotlinx.coroutines.runBlocking import net.kyori.adventure.text.Component import net.kyori.adventure.text.minimessage.MiniMessage -import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder -import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver import org.bukkit.Location import org.bukkit.block.Sign import org.bukkit.block.sign.Side @@ -126,7 +125,7 @@ class PaperSignsPluginBootstrap : PluginBootstrap { clearSignLines(sign) frameConfig.lines.forEachIndexed { index, line -> - val resolvedLine = miniMessage.deserialize(line, *getPlaceholders(cloudSign).toTypedArray()) + val resolvedLine = miniMessage.deserialize(MatcherUtil.resolveAllPlaceholders(line, cloudSign.server)) sign.getSide(Side.FRONT).line(index, resolvedLine) sign.getSide(Side.BACK).line(index, resolvedLine) } @@ -139,20 +138,4 @@ class PaperSignsPluginBootstrap : PluginBootstrap { sign.getSide(Side.FRONT).lines().replaceAll { emptyComponent } sign.getSide(Side.BACK).lines().replaceAll { emptyComponent } } - - private fun getPlaceholders(cloudSign: CloudSign<*>): List = buildList { - with(cloudSign.server) { - add(Placeholder.parsed("group", this?.group ?: "unknown")) - add(Placeholder.parsed("numerical-id", this?.numericalId?.toString() ?: "0")) - add(Placeholder.parsed("type", this?.type?.toString() ?: "unknown")) - add(Placeholder.parsed("host", this?.host ?: "unknown")) - add(Placeholder.parsed("ip", this?.ip ?: "unknown")) - add(Placeholder.parsed("port", this?.port?.toString() ?: "0")) - add(Placeholder.parsed("min-memory", this?.minMemory?.toString() ?: "0")) - add(Placeholder.parsed("max-memory", this?.maxMemory?.toString() ?: "0")) - add(Placeholder.parsed("max-players", this?.maxPlayers?.toString() ?: "0")) - add(Placeholder.parsed("player-count", this?.playerCount?.toString() ?: "0")) - add(Placeholder.parsed("state", this?.state?.toString() ?: "unknown")) - } - } } diff --git a/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/listener/SignListener.kt b/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/listener/SignListener.kt index 0edc72e..f2baebf 100644 --- a/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/listener/SignListener.kt +++ b/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/listener/SignListener.kt @@ -1,42 +1,52 @@ package app.simplecloud.plugin.sign.paper.listener import app.simplecloud.plugin.sign.paper.PaperSignsPlugin -import app.simplecloud.plugin.sign.shared.rule.context.impl.ServerRuleContext +import app.simplecloud.plugin.sign.shared.rule.impl.ServerRuleContext +import org.bukkit.block.Block import org.bukkit.block.Sign import org.bukkit.event.EventHandler +import org.bukkit.event.EventPriority import org.bukkit.event.Listener import org.bukkit.event.block.Action import org.bukkit.event.block.BlockBreakEvent import org.bukkit.event.player.PlayerInteractEvent -data class SignListener(private val plugin: PaperSignsPlugin) : Listener { +class SignListener(private val plugin: PaperSignsPlugin) : Listener { - //TODO: Add Click Catching for Different Rules e.g handle click on sign that is staring/offline/current_server - - @EventHandler + @EventHandler(priority = EventPriority.HIGH) fun handleSignInteract(event: PlayerInteractEvent) { - if (event.action != Action.RIGHT_CLICK_BLOCK || event.clickedBlock == null) return + if (!isValidSignInteraction(event)) return - val sign = (event.clickedBlock?.state as? Sign) ?: return + val sign = event.clickedBlock?.state as? Sign ?: return + val cloudSign = plugin.bootstrap.signManager.getCloudSign(sign.location) ?: return - plugin.bootstrap.signManager.getCloudSign(sign.location)?.let { cloudSign -> - event.isCancelled = true + event.isCancelled = true - val serverRuleContext = ServerRuleContext(server = cloudSign.server) + cloudSign.server?.let { server -> + val serverRuleContext = ServerRuleContext(server = server) + val serverName = plugin.bootstrap.signManager.getLayout(serverRuleContext) + .constructName(server) - cloudSign.server?.let { server -> - val serverName = plugin.bootstrap.signManager.getLayout(serverRuleContext).constructName(server) - plugin.sendPlayerToServer(event.player, serverName) - } + plugin.sendPlayerToServer(event.player, serverName) } } - @EventHandler + @EventHandler(priority = EventPriority.HIGH) fun handleSignBreak(event: BlockBreakEvent) { - val sign = (event.block.state as? Sign) ?: return + if (!isSign(event.block)) return - plugin.bootstrap.signManager.getCloudSign(sign.location)?.let { + val sign = event.block.state as Sign + if (plugin.bootstrap.signManager.getCloudSign(sign.location) != null) { event.isCancelled = true } } + + private fun isValidSignInteraction(event: PlayerInteractEvent): Boolean { + return event.action == Action.RIGHT_CLICK_BLOCK && + event.clickedBlock != null && + isSign(event.clickedBlock!!) + } + + private fun isSign(block: Block): Boolean = block.state is Sign + } diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/SignManager.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/SignManager.kt index efe2f23..883c167 100644 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/SignManager.kt +++ b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/SignManager.kt @@ -12,8 +12,8 @@ import app.simplecloud.plugin.sign.shared.config.rule.RuleConfig import app.simplecloud.plugin.sign.shared.repository.layout.LayoutRepository import app.simplecloud.plugin.sign.shared.repository.location.LocationsRepository import app.simplecloud.plugin.sign.shared.repository.rule.RuleRepository -import app.simplecloud.plugin.sign.shared.rule.context.RuleContext -import app.simplecloud.plugin.sign.shared.rule.context.impl.ServerRuleContext +import app.simplecloud.plugin.sign.shared.rule.RuleContext +import app.simplecloud.plugin.sign.shared.rule.impl.ServerRuleContext import app.simplecloud.plugin.sign.shared.service.SignService import app.simplecloud.plugin.sign.shared.utils.MatcherUtil import kotlinx.coroutines.* diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/layout/LayoutConfig.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/layout/LayoutConfig.kt index 4868525..585deaa 100644 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/layout/LayoutConfig.kt +++ b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/layout/LayoutConfig.kt @@ -3,7 +3,7 @@ package app.simplecloud.plugin.sign.shared.config.layout import app.simplecloud.controller.shared.server.Server import app.simplecloud.plugin.sign.shared.SignManagerProvider import app.simplecloud.plugin.sign.shared.config.rule.RuleConfig -import app.simplecloud.plugin.sign.shared.rule.context.RuleContext +import app.simplecloud.plugin.sign.shared.rule.RuleContext import app.simplecloud.plugin.sign.shared.utils.MatcherUtil import kotlinx.coroutines.runBlocking import org.spongepowered.configurate.objectmapping.ConfigSerializable diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/context/RuleContext.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/RuleContext.kt similarity index 54% rename from sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/context/RuleContext.kt rename to sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/RuleContext.kt index fc47cfd..b982f27 100644 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/context/RuleContext.kt +++ b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/RuleContext.kt @@ -1,4 +1,4 @@ -package app.simplecloud.plugin.sign.shared.rule.context +package app.simplecloud.plugin.sign.shared.rule interface RuleContext { val additionalData: Map diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/context/impl/ServerRuleContext.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/impl/ServerRuleContext.kt similarity index 60% rename from sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/context/impl/ServerRuleContext.kt rename to sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/impl/ServerRuleContext.kt index 6dcfc1e..7582604 100644 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/context/impl/ServerRuleContext.kt +++ b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/rule/impl/ServerRuleContext.kt @@ -1,7 +1,7 @@ -package app.simplecloud.plugin.sign.shared.rule.context.impl +package app.simplecloud.plugin.sign.shared.rule.impl import app.simplecloud.controller.shared.server.Server -import app.simplecloud.plugin.sign.shared.rule.context.RuleContext +import app.simplecloud.plugin.sign.shared.rule.RuleContext class ServerRuleContext( val server: Server? = null, diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/utils/MatcherUtil.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/utils/MatcherUtil.kt index c82676a..e2fba8c 100644 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/utils/MatcherUtil.kt +++ b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/utils/MatcherUtil.kt @@ -1,11 +1,12 @@ package app.simplecloud.plugin.sign.shared.utils +import app.simplecloud.controller.shared.server.Server import app.simplecloud.plugin.sign.shared.SignManagerProvider import app.simplecloud.plugin.sign.shared.config.rule.RuleConfig import app.simplecloud.plugin.sign.shared.matcher.MatcherConfigEntry import app.simplecloud.plugin.sign.shared.matcher.MatcherType -import app.simplecloud.plugin.sign.shared.rule.context.RuleContext -import app.simplecloud.plugin.sign.shared.rule.context.impl.ServerRuleContext +import app.simplecloud.plugin.sign.shared.rule.RuleContext +import app.simplecloud.plugin.sign.shared.rule.impl.ServerRuleContext import kotlinx.coroutines.runBlocking import net.kyori.adventure.text.minimessage.MiniMessage @@ -91,4 +92,16 @@ object MatcherUtil { } } + fun resolveAllPlaceholders(line: String, server: Server?): String { + val pattern = "<(server_|group_|env_)([^>]+)>".toRegex() + val ruleContext = ServerRuleContext(server) + + return runBlocking { + pattern.findAll(line).fold(line) { currentLine, matchResult -> + val placeholder = matchResult.value + val resolvedValue = resolvePlaceholder(placeholder, ruleContext) + currentLine.replace(placeholder, resolvedValue) + } + } + } } \ No newline at end of file diff --git a/sign-shared/src/main/resources/layouts/empty.yml b/sign-shared/src/main/resources/layouts/empty.yml index 53cd385..d084f8e 100644 --- a/sign-shared/src/main/resources/layouts/empty.yml +++ b/sign-shared/src/main/resources/layouts/empty.yml @@ -5,11 +5,11 @@ frame-update-interval: 1000 frames: - lines: - '✨' - - '-' + - '-' - 'EMPTY' - - '/' + - '/' - lines: - '✨' - - '-' + - '-' - 'JOIN NOW!' - - '/' \ No newline at end of file + - '/' \ No newline at end of file diff --git a/sign-shared/src/main/resources/layouts/maintenance.yml b/sign-shared/src/main/resources/layouts/maintenance.yml index 89eb116..ad06e8d 100644 --- a/sign-shared/src/main/resources/layouts/maintenance.yml +++ b/sign-shared/src/main/resources/layouts/maintenance.yml @@ -6,6 +6,6 @@ frame-update-interval: 1000 frames: - lines: - '🚧' - - '-' + - '-' - 'MAINTENANCE' - '🚧' \ No newline at end of file diff --git a/sign-shared/src/main/resources/layouts/online.yml b/sign-shared/src/main/resources/layouts/online.yml index 059ce54..f377b5c 100644 --- a/sign-shared/src/main/resources/layouts/online.yml +++ b/sign-shared/src/main/resources/layouts/online.yml @@ -5,6 +5,6 @@ frame-update-interval: 1250 frames: - lines: - '⚡' - - '-' - - '/' + - '-' + - '/' - 'ONLINE' \ No newline at end of file diff --git a/sign-shared/src/main/resources/layouts/starting.yml b/sign-shared/src/main/resources/layouts/starting.yml index 97fa75a..11ed8c1 100644 --- a/sign-shared/src/main/resources/layouts/starting.yml +++ b/sign-shared/src/main/resources/layouts/starting.yml @@ -8,14 +8,14 @@ frames: - '' - 'Starting' - 'Ooo' - - '-' + - '-' - lines: - '' - 'Starting' - 'oOo' - - '-' + - '-' - lines: - '' - 'Starting' - 'ooO' - - '-' + - '-' From f5da4b4a1f19625de4578eb7edfdad0dd8db0a72 Mon Sep 17 00:00:00 2001 From: PrexorJustin Date: Sat, 25 Jan 2025 21:38:46 +0100 Subject: [PATCH 7/9] feat: now frames can be displayed on either the front, back or both --- .../plugin/sign/paper/PaperSignsPluginBootstrap.kt | 12 ++++++++++-- .../plugin/sign/shared/config/layout/FrameConfig.kt | 1 + sign-shared/src/main/resources/layouts/empty.yml | 7 +++++-- sign-shared/src/main/resources/layouts/full.yml | 3 ++- .../src/main/resources/layouts/maintenance.yml | 3 ++- sign-shared/src/main/resources/layouts/offline.yml | 9 ++++++--- sign-shared/src/main/resources/layouts/online.yml | 3 ++- sign-shared/src/main/resources/layouts/starting.yml | 9 ++++++--- 8 files changed, 34 insertions(+), 13 deletions(-) diff --git a/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/PaperSignsPluginBootstrap.kt b/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/PaperSignsPluginBootstrap.kt index b4c2eaa..c0e4b4a 100644 --- a/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/PaperSignsPluginBootstrap.kt +++ b/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/PaperSignsPluginBootstrap.kt @@ -126,8 +126,16 @@ class PaperSignsPluginBootstrap : PluginBootstrap { frameConfig.lines.forEachIndexed { index, line -> val resolvedLine = miniMessage.deserialize(MatcherUtil.resolveAllPlaceholders(line, cloudSign.server)) - sign.getSide(Side.FRONT).line(index, resolvedLine) - sign.getSide(Side.BACK).line(index, resolvedLine) + when (frameConfig.sides) { + "FRONT" -> sign.getSide(Side.FRONT).line(index, resolvedLine) + "BACK" -> sign.getSide(Side.BACK).line(index, resolvedLine) + "BOTH" -> { + sign.getSide(Side.FRONT).line(index, resolvedLine) + sign.getSide(Side.BACK).line(index, resolvedLine) + } + + else -> sign.getSide(Side.FRONT).line(index, resolvedLine) + } } sign.update() diff --git a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/layout/FrameConfig.kt b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/layout/FrameConfig.kt index ac4bc2a..351e20b 100644 --- a/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/layout/FrameConfig.kt +++ b/sign-shared/src/main/kotlin/app/simplecloud/plugin/sign/shared/config/layout/FrameConfig.kt @@ -4,6 +4,7 @@ import org.spongepowered.configurate.objectmapping.ConfigSerializable @ConfigSerializable data class FrameConfig( + val sides: String = "FRONT", val lines: Array = emptyArray(), ) { diff --git a/sign-shared/src/main/resources/layouts/empty.yml b/sign-shared/src/main/resources/layouts/empty.yml index d084f8e..df6bb1d 100644 --- a/sign-shared/src/main/resources/layouts/empty.yml +++ b/sign-shared/src/main/resources/layouts/empty.yml @@ -3,12 +3,15 @@ rule: 'empty' frame-update-interval: 1000 frames: - - lines: + - sides: "BOTH" + lines: - '✨' - '-' - 'EMPTY' - '/' - - lines: + + - sides: "BOTH" + lines: - '✨' - '-' - 'JOIN NOW!' diff --git a/sign-shared/src/main/resources/layouts/full.yml b/sign-shared/src/main/resources/layouts/full.yml index 6813eed..e78f530 100644 --- a/sign-shared/src/main/resources/layouts/full.yml +++ b/sign-shared/src/main/resources/layouts/full.yml @@ -4,7 +4,8 @@ priority: 3 frame-update-interval: 1250 frames: - - lines: + - sides: "BOTH" + lines: - '⛔' - '-' - 'FULL' diff --git a/sign-shared/src/main/resources/layouts/maintenance.yml b/sign-shared/src/main/resources/layouts/maintenance.yml index ad06e8d..840d1ef 100644 --- a/sign-shared/src/main/resources/layouts/maintenance.yml +++ b/sign-shared/src/main/resources/layouts/maintenance.yml @@ -4,7 +4,8 @@ priority: 5 frame-update-interval: 1000 frames: - - lines: + - sides: "BOTH" + lines: - '🚧' - '-' - 'MAINTENANCE' diff --git a/sign-shared/src/main/resources/layouts/offline.yml b/sign-shared/src/main/resources/layouts/offline.yml index 1c73042..20dbb49 100644 --- a/sign-shared/src/main/resources/layouts/offline.yml +++ b/sign-shared/src/main/resources/layouts/offline.yml @@ -3,15 +3,18 @@ rule: 'state_offline' frame-update-interval: 500 frames: - - lines: + - sides: "BOTH" + lines: - '' - 'Offline' - 'Ooo' - - lines: + - sides: "BOTH" + lines: - '' - 'Offline' - 'oOo' - - lines: + - sides: "BOTH" + lines: - '' - 'Offline' - 'ooO' diff --git a/sign-shared/src/main/resources/layouts/online.yml b/sign-shared/src/main/resources/layouts/online.yml index f377b5c..f55af78 100644 --- a/sign-shared/src/main/resources/layouts/online.yml +++ b/sign-shared/src/main/resources/layouts/online.yml @@ -3,7 +3,8 @@ rule: 'state_available' frame-update-interval: 1250 frames: - - lines: + - sides: "BOTH" + lines: - '⚡' - '-' - '/' diff --git a/sign-shared/src/main/resources/layouts/starting.yml b/sign-shared/src/main/resources/layouts/starting.yml index 11ed8c1..4be8ec7 100644 --- a/sign-shared/src/main/resources/layouts/starting.yml +++ b/sign-shared/src/main/resources/layouts/starting.yml @@ -4,17 +4,20 @@ priority: 4 frame-update-interval: 500 frames: - - lines: + - sides: "BOTH" + lines: - '' - 'Starting' - 'Ooo' - '-' - - lines: + - sides: "BOTH" + lines: - '' - 'Starting' - 'oOo' - '-' - - lines: + - sides: "BOTH" + lines: - '' - 'Starting' - 'ooO' From b9fa7decc0fc7af31690d2294cce442c60341992 Mon Sep 17 00:00:00 2001 From: PrexorJustin Date: Sat, 25 Jan 2025 21:42:31 +0100 Subject: [PATCH 8/9] fix: force uppercase for SIDE verification --- .../simplecloud/plugin/sign/paper/PaperSignsPluginBootstrap.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/PaperSignsPluginBootstrap.kt b/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/PaperSignsPluginBootstrap.kt index c0e4b4a..8a204ef 100644 --- a/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/PaperSignsPluginBootstrap.kt +++ b/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/PaperSignsPluginBootstrap.kt @@ -126,7 +126,7 @@ class PaperSignsPluginBootstrap : PluginBootstrap { frameConfig.lines.forEachIndexed { index, line -> val resolvedLine = miniMessage.deserialize(MatcherUtil.resolveAllPlaceholders(line, cloudSign.server)) - when (frameConfig.sides) { + when (frameConfig.sides.uppercase()) { "FRONT" -> sign.getSide(Side.FRONT).line(index, resolvedLine) "BACK" -> sign.getSide(Side.BACK).line(index, resolvedLine) "BOTH" -> { From 17bd2f24788dcc4523463ac0f57ce7643b23cc77 Mon Sep 17 00:00:00 2001 From: PrexorJustin Date: Sun, 26 Jan 2025 17:58:54 +0100 Subject: [PATCH 9/9] fix: formatting --- .../simplecloud/plugin/sign/paper/PaperSignsPluginBootstrap.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/PaperSignsPluginBootstrap.kt b/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/PaperSignsPluginBootstrap.kt index 8a204ef..f0ea9ea 100644 --- a/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/PaperSignsPluginBootstrap.kt +++ b/sign-paper/src/main/kotlin/app/simplecloud/plugin/sign/paper/PaperSignsPluginBootstrap.kt @@ -129,6 +129,7 @@ class PaperSignsPluginBootstrap : PluginBootstrap { when (frameConfig.sides.uppercase()) { "FRONT" -> sign.getSide(Side.FRONT).line(index, resolvedLine) "BACK" -> sign.getSide(Side.BACK).line(index, resolvedLine) + "BOTH" -> { sign.getSide(Side.FRONT).line(index, resolvedLine) sign.getSide(Side.BACK).line(index, resolvedLine)