From c3cbb1eca603b8ef0a21885ac4d007c7480fec06 Mon Sep 17 00:00:00 2001 From: Roman Makeev Date: Sat, 30 May 2026 20:01:06 +0300 Subject: [PATCH 01/16] [REFACTOR] Update project structure --- build.gradle.kts | 18 +- gradle.properties | 29 +- gradle/libs.versions.toml | 142 +++++---- gradle/wrapper/gradle-wrapper.properties | 6 +- instances/bukkit/build.gradle.kts | 264 ++++++++++++---- .../rickmorty/RickMortyCommandRegistrar.kt | 2 +- .../astratemplate/di/RootModule.kt | 4 +- instances/fabric/build.gradle.kts | 4 +- instances/forge/build.gradle.kts | 293 +++++++++++++----- .../astratemplate/di/RootModule.kt | 3 +- instances/neoforge/build.gradle.kts | 172 ++++++++++ instances/neoforge/gradle.properties | 1 + .../astratemplate/ForgeEntryPoint.kt | 55 ++++ .../astratemplate/command/di/CommandModule.kt | 19 ++ .../helloworld/HelloCommandRegistrar.kt | 18 ++ .../astratemplate/di/RootModule.kt | 72 +++++ .../astratemplate/event/TickEvent.kt | 18 ++ .../astratemplate/event/di/EventModule.kt | 11 + .../src/main/resources/META-INF/mods.toml | 10 + .../neoforge/src/main/resources/icon.png | Bin 0 -> 5036 bytes .../neoforge/src/main/resources/pack.mcmeta | 7 + instances/velocity/build.gradle.kts | 89 ------ .../astratemplate/AstraTemplate.kt | 69 ----- .../command/api/VelocityCommandRegistry.kt | 22 -- .../api/VelocityCommandRegistryContext.kt | 9 - .../command/reload/ReloadCommandRegistry.kt | 62 ---- .../astratemplate/di/RootModule.kt | 15 - .../astratemplate/di/VelocityModule.kt | 15 - .../src/main/resources/velocity-plugin.json | 13 - .../api/local/di/ApiLocalModule.kt | 68 ---- modules/api-remote/build.gradle.kts | 10 - .../{api-local => api/local}/build.gradle.kts | 7 +- .../astratemplate/api/local/dao/LocalDao.kt | 0 .../api/local/dao/LocalDaoImpl.kt | 16 +- .../api/local/di/ApiLocalModule.kt | 49 +++ .../api/local/entity/UserRatingTable.kt | 2 +- .../api/local/entity/UserTable.kt | 2 +- .../api/local/model/RatingModel.kt | 0 .../api/local/model/UserModel.kt | 0 modules/api/remote/build.gradle.kts | 12 + .../api/remote/api}/RickMortyApi.kt | 2 +- .../api/remote/api}/RickMortyApiImpl.kt | 5 +- .../api/remote/di/ApiRemoteModule.kt | 4 +- .../api/remote/model/RMResponse.kt | 0 modules/build-konfig/build.gradle.kts | 7 +- modules/core/build.gradle.kts | 6 +- .../astratemplate/core/di/CoreModule.kt | 47 ++- .../core/plugin/PluginConfiguration.kt | 9 + .../core/plugin/PluginPermission.kt | 2 +- .../core/plugin/PluginTranslation.kt | 61 +++- settings.gradle.kts | 69 ++--- 51 files changed, 1123 insertions(+), 697 deletions(-) create mode 100644 instances/neoforge/build.gradle.kts create mode 100644 instances/neoforge/gradle.properties create mode 100644 instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/ForgeEntryPoint.kt create mode 100644 instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/command/di/CommandModule.kt create mode 100644 instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/command/helloworld/HelloCommandRegistrar.kt create mode 100644 instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/di/RootModule.kt create mode 100644 instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/event/TickEvent.kt create mode 100644 instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/event/di/EventModule.kt create mode 100644 instances/neoforge/src/main/resources/META-INF/mods.toml create mode 100644 instances/neoforge/src/main/resources/icon.png create mode 100644 instances/neoforge/src/main/resources/pack.mcmeta delete mode 100644 instances/velocity/build.gradle.kts delete mode 100644 instances/velocity/src/main/kotlin/ru/astrainteractive/astratemplate/AstraTemplate.kt delete mode 100644 instances/velocity/src/main/kotlin/ru/astrainteractive/astratemplate/command/api/VelocityCommandRegistry.kt delete mode 100644 instances/velocity/src/main/kotlin/ru/astrainteractive/astratemplate/command/api/VelocityCommandRegistryContext.kt delete mode 100644 instances/velocity/src/main/kotlin/ru/astrainteractive/astratemplate/command/reload/ReloadCommandRegistry.kt delete mode 100644 instances/velocity/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt delete mode 100644 instances/velocity/src/main/kotlin/ru/astrainteractive/astratemplate/di/VelocityModule.kt delete mode 100644 instances/velocity/src/main/resources/velocity-plugin.json delete mode 100644 modules/api-local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/di/ApiLocalModule.kt delete mode 100644 modules/api-remote/build.gradle.kts rename modules/{api-local => api/local}/build.gradle.kts (62%) rename modules/{api-local => api/local}/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/dao/LocalDao.kt (100%) rename modules/{api-local => api/local}/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/dao/LocalDaoImpl.kt (88%) create mode 100644 modules/api/local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/di/ApiLocalModule.kt rename modules/{api-local => api/local}/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/entity/UserRatingTable.kt (77%) rename modules/{api-local => api/local}/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/entity/UserTable.kt (78%) rename modules/{api-local => api/local}/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/model/RatingModel.kt (100%) rename modules/{api-local => api/local}/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/model/UserModel.kt (100%) create mode 100644 modules/api/remote/build.gradle.kts rename modules/{api-remote/src/main/kotlin/ru/astrainteractive/astratemplate/api/remote => api/remote/src/main/kotlin/ru/astrainteractive/astratemplate/api/remote/api}/RickMortyApi.kt (81%) rename modules/{api-remote/src/main/kotlin/ru/astrainteractive/astratemplate/api/remote => api/remote/src/main/kotlin/ru/astrainteractive/astratemplate/api/remote/api}/RickMortyApiImpl.kt (87%) rename modules/{api-remote => api/remote}/src/main/kotlin/ru/astrainteractive/astratemplate/api/remote/di/ApiRemoteModule.kt (66%) rename modules/{api-remote => api/remote}/src/main/kotlin/ru/astrainteractive/astratemplate/api/remote/model/RMResponse.kt (100%) diff --git a/build.gradle.kts b/build.gradle.kts index af240c1..76e6145 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,22 +1,16 @@ plugins { java - `maven-publish` `java-library` - alias(libs.plugins.kotlin.jvm) apply false - alias(libs.plugins.kotlin.serialization) apply false + `maven-publish` alias(libs.plugins.gradle.buildconfig) apply false - - // klibs - core + alias(libs.plugins.gradle.forgegradle) apply false + alias(libs.plugins.gradle.neoforgegradle) apply false alias(libs.plugins.klibs.gradle.detekt) apply false - alias(libs.plugins.klibs.gradle.detekt.compose) apply false alias(libs.plugins.klibs.gradle.dokka.root) apply false - alias(libs.plugins.klibs.gradle.dokka.module) apply false - alias(libs.plugins.klibs.gradle.java.core) apply false + alias(libs.plugins.klibs.gradle.java.version) apply false alias(libs.plugins.klibs.gradle.publication) apply false alias(libs.plugins.klibs.gradle.rootinfo) apply false alias(libs.plugins.klibs.minecraft.resource.processor) apply false + alias(libs.plugins.kotlin.jvm) apply false + alias(libs.plugins.kotlin.serialization) apply false } - -apply(plugin = "ru.astrainteractive.gradleplugin.dokka.root") -apply(plugin = "ru.astrainteractive.gradleplugin.detekt") -apply(plugin = "ru.astrainteractive.gradleplugin.root.info") diff --git a/gradle.properties b/gradle.properties index 69d7f29..12d2e53 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,15 +1,20 @@ -# Kotlin -kotlin.code.style=official # Gradle -org.gradle.jvmargs=-Xmx4000m +org.gradle.parallel=true +org.gradle.configuration-cache=true +org.gradle.caching=true +kotlin.incremental=true +org.gradle.jvmargs=-Xmx5g -XX:+UseParallelGC -Dkotlin.daemon.jvm.options\="-Xmx5G" +kotlin.code.style=official +testTask.ignoreFailures=false # Java -makeevrserg.java.source=8 -makeevrserg.java.target=21 -makeevrserg.java.ktarget=21 +klibs.java.source=8 +klibs.java.target=21 +klibs.java.ktarget=21 # Project -makeevrserg.project.name=AstraTemplate -makeevrserg.project.group=ru.astrainteractive.astratemplate -makeevrserg.project.version.string=8.0.0-alpha01 -makeevrserg.project.description=Template plugin for EmpireProjekt -makeevrserg.project.developers=makeevrserg|Makeev Roman|makeevrserg@gmail.com -makeevrserg.project.url=https://github.com/Astra-Interactive/AstraTemplate +klibs.project.name=AspeKt +klibs.project.group=ru.astrainteractive.aspekt +klibs.project.version.string=2.55.0 +klibs.project.description=Essentials plugin for EmpireProjekt +klibs.project.developers=makeevrserg|Makeev Roman|makeevrserg@gmail.com +klibs.project.url=https://empireprojekt.ru +klibs.publish.developers=makeevrserg|Makeev Roman|makeevrserg@gmail.com diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 89079a8..406f811 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,64 +1,72 @@ [versions] cache4k = "0.14.0" -discordsrv = "1.30.2" +discordsrv = "1.30.5" driver-h2 = "2.4.240" -driver-jdbc = "3.50.3.0" -driver-mariadb = "3.5.6" +driver-jdbc = "3.53.0.0" +driver-mariadb = "3.5.8" driver-mysql = "8.0.33" -exposed = "0.61.0" -forgegradle = "[6.0,6.2)" -gradle-buildconfig = "5.7.0" -gradle-ftp = "0.1.2" -gradle-shadow = "9.2.2" -gson = "2.13.2" -guava = "33.5.0-jre" -jda = "6.1.0" +exposed = "1.2.0" +gradle-buildconfig = "6.0.9" +gradle-ftp = "0.1.3" +gradle-shadow = "9.4.1" +gson = "2.14.0" +guava = "33.6.0-jre" +jda = "6.4.1" jda-webhook = "0.8.4" -klibs-gradleplugin = "1.11.1" +jmh-core = "1.37" +joml = "1.10.8" +klibs-gradleplugin = "2.1.1" klibs-kdi = "1.4.8" -klibs-kstorage = "4.4.1" -klibs-mikro = "1.16.0" -kotlin-benchmark = "0.4.14" +klibs-kstorage = "5.0.4" +klibs-mikro = "1.23.0" +kotlin-benchmark = "0.4.16" kotlin-coroutines = "1.10.2" kotlin-datetime = "0.7.1-0.6.x-compat" -kotlin-json = "1.9.0" -kotlin-serialization-kaml = "0.102.0" -kotlin-serialization = "1.9.0" +kotlin-json = "1.11.0" +kotlin-serialization = "1.11.0" +kotlin-serialization-kaml = "0.104.0" kotlin-version = "2.2.0" -ktor = "3.3.1" -kyori = "4.25.0" -kyori-adventure = "4.25.0" -mcprotocollib = "1.21.7-SNAPSHOT" -minecraft-astralibs = "3.29.0" -minecraft-bstats = "3.1.0" -minecraft-bungee = "1.21-R0.5-SNAPSHOT" +ktor = "3.4.3" +minecraft-astralibs = "3.40.5" +minecraft-brigadier = "1.3.10" +minecraft-authlib = "6.0.54" +minecraft-bstats = "3.2.1" +minecraft-bungee = "26.1-R0.1-SNAPSHOT" +minecraft-datafixerupper = "8.0.16" minecraft-essentialsx = "2.21.2" -minecraft-fabric-api = "0.134.1+" +minecraft-fabric-api = "0.139.5+" +minecraft-fabric-kotlin = "1.13.7+" +minecraft-fabric-loader = "0.19.2" +minecraft-fabric-loom = "1.16.1" minecraft-fabric-yarn = "1.20.1+build.10" -minecraft-fabric-kotlin = "1.13.1+" -minecraft-fabric-loader = "0.17.2" -minecraft-fabric-loom = "1.11.8" +minecraft-forge-bus="6.0.5" +minecraft-forgegradle = "7.0.25" +minecraft-forge-jarjar = "0.2.3" +minecraft-forgerenamer = "1.0.14" +minecraft-forgeversion = "1.20.1-47.4.12" +minecraft-kyori = "5.0.1" minecraft-luckperms = "5.5" -minecraft-mockbukkit = "4.33.2" +minecraft-mcprotocollib = "1.21.7-SNAPSHOT" +minecraft-mockbukkit = "4.108.0" minecraft-mojang-version = "1.20.1" -minecraft-packetevents = "2.10.0" -minecraft-papi = "2.11.6" +minecraft-neoforged-bus = "8.0.2" +minecraft-neoforgegradle = "7.1.20" +minecraft-neoforgeversion = "21.1.129" +minecraft-packetevents = "2.12.1" +minecraft-papi = "2.12.2" minecraft-protocollib = "5.3.0" minecraft-spigot = "1.21.9-R0.1-SNAPSHOT" -minecraft-towny = "0.101.2.1" +minecraft-towny = "0.102.0.0" minecraft-vault = "1.7.1" -minecraft-velocity = "3.4.0-SNAPSHOT" # https://github.com/PaperMC/Velocity -minecraft-forgeversion = "47.2.20" -shadow = "8.1.8" -telegrambots = "9.2.0" -tests-junit-bom = "6.0.1" -tests-junit-jupiter-api = "6.0.1" -tests-mockito = "5.20.0" -tests-org-testing = "7.11.0" -turbine = "1.2.1" +minecraft-velocity = "4.0.0-SNAPSHOT" +telegrambots = "9.5.0" +tests-junit-bom = "6.0.3" +tests-junit-jupiter-api = "6.0.3" +tests-mockito = "5.23.0" +tests-org-testing = "7.12.0" +tests-turbine = "1.2.1" [libraries] -minecraft-astralibs-core = { module = "ru.astrainteractive.astralibs:core", version.ref = "minecraft-astralibs" } cache4k = { module = "io.github.reactivecircus.cache4k:cache4k-jvm", version.ref = "cache4k" } discord-webhook = { module = "club.minnced:discord-webhooks", version.ref = "jda-webhook" } driver-h2 = { module = "com.h2database:h2", version.ref = "driver-h2" } @@ -69,23 +77,24 @@ exposed-core = { module = "org.jetbrains.exposed:exposed-core", version.ref = "e exposed-dao = { module = "org.jetbrains.exposed:exposed-dao", version.ref = "exposed" } exposed-java-time = { module = "org.jetbrains.exposed:exposed-java-time", version.ref = "exposed" } exposed-jdbc = { module = "org.jetbrains.exposed:exposed-jdbc", version.ref = "exposed" } -gradle-shadow = { module = "gradle.plugin.com.github.johnrengelman:shadow", version.ref = "gradle-shadow" } gson = { module = "com.google.code.gson:gson", version.ref = "gson" } guava = { module = "com.google.guava:guava", version.ref = "guava" } jda = { module = "net.dv8tion:JDA", version.ref = "jda" } +jmh-core = { module = "org.openjdk.jmh:jmh-core", version.ref = "jmh-core" } +joml = { module = "org.joml:joml", version.ref = "joml" } klibs-kdi = { module = "ru.astrainteractive.klibs:kdi-jvm", version.ref = "klibs-kdi" } klibs-kstorage = { module = "ru.astrainteractive.klibs:kstorage", version.ref = "klibs-kstorage" } klibs-mikro-core = { module = "ru.astrainteractive.klibs:mikro-core", version.ref = "klibs-mikro" } -klibs-mikro-extensions = { module = "ru.astrainteractive.klibs:mikro-extensions", version.ref = "klibs-mikro" } +klibs-mikro-extensions = { module = "ru.astrainteractive.klibs:mikro-extensions-jvm", version.ref = "klibs-mikro" } kotlin-benchmark-runtime = { module = "org.jetbrains.kotlinx:kotlinx-benchmark-runtime", version.ref = "kotlin-benchmark" } kotlin-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlin-coroutines" } kotlin-coroutines-coreJvm = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm", version.ref = "kotlin-coroutines" } kotlin-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlin-coroutines" } kotlin-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime-jvm", version.ref = "kotlin-datetime" } kotlin-gradle = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin-version" } -kotlin-serialization-kaml = { module = "com.charleskorn.kaml:kaml", version.ref = "kotlin-serialization-kaml" } kotlin-serialization = { module = "org.jetbrains.kotlin:kotlin-serialization", version.ref = "kotlin-version" } kotlin-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlin-serialization" } +kotlin-serialization-kaml = { module = "com.charleskorn.kaml:kaml", version.ref = "kotlin-serialization-kaml" } kotlin-serialization-protobuf = { module = "org.jetbrains.kotlinx:kotlinx-serialization-protobuf", version.ref = "kotlin-json" } kotlin-tooling-core = { module = "org.jetbrains.kotlin:kotlin-tooling-core", version.ref = "kotlin-version" } ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktor" } @@ -94,29 +103,39 @@ ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" } ktor-client-json = { module = "io.ktor:ktor-client-json", version.ref = "ktor" } ktor-logging = { module = "io.ktor:ktor-client-logging", version.ref = "ktor" } ktor-serialization-json = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" } -kyori-plain = { module = "net.kyori:adventure-text-serializer-plain", version.ref = "kyori-adventure" } -kyori-api = { module = "net.kyori:adventure-api", version.ref = "kyori" } -kyori-gson = { module = "net.kyori:adventure-text-serializer-gson", version.ref = "kyori" } -kyori-legacy = { module = "net.kyori:adventure-text-serializer-legacy", version.ref = "kyori" } -kyori-minimessage = { module = "net.kyori:adventure-text-minimessage", version.ref = "kyori" } -mcprotocollib = { module = "org.geysermc.mcprotocollib:protocol", version.ref = "mcprotocollib" } minecraft-astralibs-command = { module = "ru.astrainteractive.astralibs:command", version.ref = "minecraft-astralibs" } minecraft-astralibs-command-bukkit = { module = "ru.astrainteractive.astralibs:command-bukkit", version.ref = "minecraft-astralibs" } +minecraft-astralibs-core = { module = "ru.astrainteractive.astralibs:core", version.ref = "minecraft-astralibs" } minecraft-astralibs-core-bukkit = { module = "ru.astrainteractive.astralibs:core-bukkit", version.ref = "minecraft-astralibs" } minecraft-astralibs-core-forge = { module = "ru.astrainteractive.astralibs:core-forge", version.ref = "minecraft-astralibs" } +minecraft-astralibs-core-minecraft = { module = "ru.astrainteractive.astralibs:core-minecraft", version.ref = "minecraft-astralibs" } +minecraft-astralibs-core-neoforge = { module = "ru.astrainteractive.astralibs:core-neoforge", version.ref = "minecraft-astralibs" } minecraft-astralibs-exposed = { module = "ru.astrainteractive.astralibs:exposed", version.ref = "minecraft-astralibs" } minecraft-astralibs-menu-bukkit = { module = "ru.astrainteractive.astralibs:menu-bukkit", version.ref = "minecraft-astralibs" } minecraft-astralibs-orm = { module = "ru.astrainteractive.astralibs:orm", version.ref = "minecraft-astralibs" } +minecraft-brigadier = { module = "com.mojang:brigadier", version.ref = "minecraft-brigadier" } +minecraft-authlib = { module = "com.mojang:authlib", version.ref = "minecraft-authlib" } minecraft-bstats = { module = "org.bstats:bstats-bukkit", version.ref = "minecraft-bstats" } minecraft-bungee = { module = "net.md-5:bungeecord-api", version.ref = "minecraft-bungee" } +minecraft-datafixerupper = { module = "com.mojang:datafixerupper", version.ref = "minecraft-datafixerupper" } minecraft-discordsrv = { module = "com.discordsrv:discordsrv", version.ref = "discordsrv" } minecraft-essentialsx = { module = "net.essentialsx:EssentialsX", version.ref = "minecraft-essentialsx" } minecraft-fabric-api = { module = "net.fabricmc.fabric-api:fabric-api", version.ref = "minecraft-fabric-api" } minecraft-fabric-kotlin = { module = "net.fabricmc:fabric-language-kotlin", version.ref = "minecraft-fabric-kotlin" } minecraft-fabric-loader = { module = "net.fabricmc:fabric-loader", version.ref = "minecraft-fabric-loader" } minecraft-fabric-mojang = { module = "com.mojang:minecraft", version.ref = "minecraft-mojang-version" } +minecraft-forge-bus = { module = "net.minecraftforge:eventbus", version.ref = "minecraft-forge-bus" } +minecraft-forgeversion = { module = "net.minecraftforge:forge", version.ref = "minecraft-forgeversion" } +minecraft-kyori-api = { module = "net.kyori:adventure-api", version.ref = "minecraft-kyori" } +minecraft-kyori-gson = { module = "net.kyori:adventure-text-serializer-gson", version.ref = "minecraft-kyori" } +minecraft-kyori-legacy = { module = "net.kyori:adventure-text-serializer-legacy", version.ref = "minecraft-kyori" } +minecraft-kyori-minimessage = { module = "net.kyori:adventure-text-minimessage", version.ref = "minecraft-kyori" } +minecraft-kyori-plain = { module = "net.kyori:adventure-text-serializer-plain", version.ref = "minecraft-kyori" } minecraft-luckperms = { module = "net.luckperms:api", version.ref = "minecraft-luckperms" } +minecraft-mcprotocollib = { module = "org.geysermc.mcprotocollib:protocol", version.ref = "minecraft-mcprotocollib" } minecraft-mockbukkit = { module = "com.github.MockBukkit:MockBukkit", version.ref = "minecraft-mockbukkit" } +minecraft-neoforged-bus = { module = "net.neoforged:bus", version.ref = "minecraft-neoforged-bus" } +minecraft-neoforgeversion = { module = "net.neoforged:neoforge", version.ref = "minecraft-neoforgeversion" } minecraft-packetevents = { module = "com.github.retrooper:packetevents-spigot", version.ref = "minecraft-packetevents" } minecraft-paper-api = { module = "io.papermc.paper:paper-api", version.ref = "minecraft-spigot" } minecraft-papi = { module = "me.clip:placeholderapi", version.ref = "minecraft-papi" } @@ -136,28 +155,33 @@ tests-junit5 = { module = "org.jetbrains.kotlin:kotlin-test-junit5" } tests-kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test" } tests-mockito = { module = "org.mockito:mockito-core", version.ref = "tests-mockito" } tests-org-testing = { module = "org.testng:testng", version.ref = "tests-org-testing" } -turbine = { module = "app.cash.turbine:turbine", version.ref = "turbine" } +tests-turbine = { module = "app.cash.turbine:turbine", version.ref = "tests-turbine" } [plugins] -fabric-loom = { id = "fabric-loom", version.ref = "minecraft-fabric-loom" } -forgegradle = { id = "net.minecraftforge.gradle", version.ref = "forgegradle" } gradle-buildconfig = { id = "com.github.gmazzo.buildconfig", version.ref = "gradle-buildconfig" } +gradle-fabric-loom = { id = "fabric-loom", version.ref = "minecraft-fabric-loom" } +gradle-forgegradle = { id = "net.minecraftforge.gradle", version.ref = "minecraft-forgegradle" } +gradle-forge-jarjar = { id = "net.minecraftforge.jarjar", version.ref = "minecraft-forge-jarjar" } +gradle-forgerenamer = { id = "net.minecraftforge.renamer", version.ref = "minecraft-forgerenamer" } gradle-ftp = { id = "ru.astrainteractive.ftpplugin.gradleftp", version.ref = "gradle-ftp" } +gradle-neoforgegradle = { id = "net.neoforged.gradle.userdev", version.ref = "minecraft-neoforgegradle" } gradle-shadow = { id = "com.gradleup.shadow", version.ref = "gradle-shadow" } +klibs-gradle-minecraft-platform = { id = "ru.astrainteractive.gradleplugin.minecraft.platform", version.ref = "klibs-gradleplugin" } klibs-gradle-detekt = { id = "ru.astrainteractive.gradleplugin.detekt", version.ref = "klibs-gradleplugin" } klibs-gradle-detekt-compose = { id = "ru.astrainteractive.gradleplugin.detekt.compose", version.ref = "klibs-gradleplugin" } -klibs-gradle-dokka-module = { id = "ru.astrainteractive.gradleplugin.dokka.module", version.ref = "klibs-gradleplugin" } klibs-gradle-dokka-root = { id = "ru.astrainteractive.gradleplugin.dokka.root", version.ref = "klibs-gradleplugin" } klibs-gradle-java-core = { id = "ru.astrainteractive.gradleplugin.java.core", version.ref = "klibs-gradleplugin" } +klibs-gradle-java-version = { id = "ru.astrainteractive.gradleplugin.java.version", version.ref = "klibs-gradleplugin" } klibs-gradle-minecraft-empty = { id = "ru.astrainteractive.gradleplugin.minecraft.empty", version.ref = "klibs-gradleplugin" } klibs-gradle-minecraft-multiplatform = { id = "ru.astrainteractive.gradleplugin.minecraft.multiplatform", version.ref = "klibs-gradleplugin" } klibs-gradle-publication = { id = "ru.astrainteractive.gradleplugin.publication", version.ref = "klibs-gradleplugin" } -klibs-gradle-rootinfo = { id = "ru.astrainteractive.gradleplugin.root.info", version.ref = "klibs-gradleplugin" } +klibs-gradle-rootinfo = { id = "ru.astrainteractive.gradleplugin.rootinfo", version.ref = "klibs-gradleplugin" } klibs-gradle-stub-javadoc = { id = "ru.astrainteractive.gradleplugin.stub.javadoc", version.ref = "klibs-gradleplugin" } -klibs-minecraft-resource-processor = { id = "ru.astrainteractive.gradleplugin.minecraft.resource-processor", version.ref = "klibs-gradleplugin" } +klibs-minecraft-resource-processor = { id = "ru.astrainteractive.gradleplugin.minecraft.resource.processor", version.ref = "klibs-gradleplugin" } +klibs-minecraft-shadow = { id = "ru.astrainteractive.gradleplugin.minecraft.shadow", version.ref = "klibs-gradleplugin" } kotlin-allopen = { id = "org.jetbrains.kotlin.plugin.allopen", version.ref = "kotlin-version" } kotlin-benchmark = { id = "org.jetbrains.kotlinx.benchmark", version.ref = "kotlin-benchmark" } kotlin-gradle = { id = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin-version" } kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin-version" } kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin-version" } -kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin-version" } +kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin-version" } \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 5c82cb0..b52fb7e 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,9 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.0-bin.zip +networkTimeout=10000 +retries=0 +retryBackOffMs=500 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/instances/bukkit/build.gradle.kts b/instances/bukkit/build.gradle.kts index 53f7c9d..9492265 100644 --- a/instances/bukkit/build.gradle.kts +++ b/instances/bukkit/build.gradle.kts @@ -1,35 +1,44 @@ +import com.github.jengelman.gradle.plugins.shadow.ShadowBasePlugin.Companion.shadow import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar -import org.gradle.kotlin.dsl.named -import ru.astrainteractive.gradleplugin.property.extension.ModelPropertyValueExt.requireProjectInfo - +import org.gradle.kotlin.dsl.shadow +import ru.astrainteractive.gradleplugin.property.util.requireProjectInfo plugins { - kotlin("jvm") - alias(libs.plugins.klibs.gradle.java.core) - alias(libs.plugins.klibs.minecraft.resource.processor) + id("org.jetbrains.kotlin.jvm") + id("org.jetbrains.kotlin.plugin.serialization") + id("ru.astrainteractive.gradleplugin.detekt") + id("ru.astrainteractive.gradleplugin.java.version") alias(libs.plugins.gradle.shadow) + alias(libs.plugins.klibs.minecraft.resource.processor) } dependencies { - // Kotlin - implementation(libs.kotlin.coroutines.core) - implementation(libs.kotlin.serialization.json) - implementation(libs.kotlin.serialization.kaml) - // AstraLibs - implementation(libs.minecraft.astralibs.core) - implementation(libs.minecraft.astralibs.command) - implementation(libs.minecraft.astralibs.command.bukkit) - implementation(libs.minecraft.astralibs.menu.bukkit) - implementation(libs.minecraft.astralibs.core.bukkit) - implementation(libs.klibs.mikro.core) - implementation(libs.klibs.kstorage) - // Spigot dependencies + compileOnly(libs.driver.h2) + compileOnly(libs.driver.jdbc) + compileOnly(libs.driver.mysql) + compileOnly(libs.minecraft.discordsrv) + compileOnly(libs.minecraft.essentialsx) + compileOnly(libs.minecraft.luckperms) compileOnly(libs.minecraft.paper.api) - implementation(libs.minecraft.bstats) - // Local - implementation(projects.modules.apiLocal) - implementation(projects.modules.apiRemote) - implementation(projects.modules.core) + compileOnly(libs.minecraft.vaultapi) + compileOnly(libs.minecraft.kyori.api) + + shadow(libs.klibs.mikro.core) + shadow(libs.kotlin.coroutines.core) + shadow(libs.kotlin.serialization.json) + shadow(libs.minecraft.astralibs.command) + shadow(libs.minecraft.astralibs.command.bukkit) + shadow(libs.minecraft.astralibs.core) + shadow(libs.minecraft.astralibs.core.bukkit) + shadow(libs.minecraft.astralibs.menu.bukkit) + shadow(libs.minecraft.bstats) + + shadow(projects.modules.api.local) + shadow(projects.modules.api.remote) + shadow(projects.modules.buildKonfig) + shadow(projects.modules.core) + + testImplementation(libs.tests.kotlin.test) } minecraftProcessResource { @@ -39,57 +48,178 @@ minecraftProcessResource { libs.driver.h2.get(), libs.driver.jdbc.get(), libs.driver.mysql.get(), + libs.driver.mariadb.get() ).joinToString("\",\"", "[\"", "\"]") ) ) } -val shadowJar = tasks.named("shadowJar") -shadowJar.configure { - - val projectInfo = requireProjectInfo - isReproducibleFileOrder = true +val shadowJar by tasks.getting(ShadowJar::class) { mergeServiceFiles() - dependsOn(configurations) - archiveClassifier.set(null as String?) - - minimize { - exclude(dependency(libs.exposed.jdbc.get())) - exclude(dependency(libs.exposed.dao.get())) - } - archiveVersion.set(projectInfo.versionString) - archiveBaseName.set("${projectInfo.name}-bukkit") - destinationDirectory = rootDir.resolve("build") - .resolve("bukkit") + dependsOn(tasks.named("processResources")) + configurations = listOf(project.configurations.shadow.get()) + isReproducibleFileOrder = true + duplicatesStrategy = DuplicatesStrategy.EXCLUDE + archiveClassifier = null as String? + archiveVersion = requireProjectInfo.versionString + archiveBaseName = "${requireProjectInfo.name}-${project.name}" + destinationDirectory = rootProject.layout.buildDirectory.get() + .asFile + .resolve(project.name) .resolve("plugins") .takeIf(File::exists) - ?: File(rootDir, "jars").also(File::mkdirs) - - relocate("org.bstats", projectInfo.group) - listOf( - "co.touchlab", - "com.mysql", - "google.protobuf", - "io.github.reactivecircus", - "ch.qos.logback", - "com.charleskorn.kaml", - "com.ibm.icu", - "it.krzeminski.snakeyaml", - "net.thauvin.erik", - "okio", - "org.apache", - "org.intellij", - "org.slf4j", - "org.jetbrains.annotations", - "ru.astrainteractive.klibs", - "ru.astrainteractive.astralibs" - ).forEach { pattern -> relocate(pattern, "${projectInfo.group}.$pattern") } - listOf( - "org.jetbrains.exposed", - "kotlinx", - ).forEach { pattern -> - relocate(pattern, "${projectInfo.group}.$pattern") { - exclude("kotlin/kotlin.kotlin_builtins") + ?: rootDir.resolve("jars") + dependencies { + // Dependencies + exclude(dependency("org.jetbrains:annotations")) + exclude("ch/qos/logback/**") + exclude("com/ibm/icu/**") + exclude("it/unimi/dsi/**") + exclude("javax/**") + exclude("mozilla/**") + exclude("org/apache/batik/**") + exclude("org/apache/commons/logging/**") + exclude("org/apache/xmlgraphics/**") + exclude("org/intellij/lang/annotations/**") + exclude("org/jetbrains/annotations/**") + exclude("org/slf4j/**") + exclude("org/w3c/dom/**") + // Root + if (project.name == "forge" || project.name == "neoforge") { + // Use kotlin-neoforge or kotlin-forge + exclude("kotlin/**") + } + exclude("_COROUTINE/**") + exclude("DebugProbesKt.bin") + exclude("jetty-dir.css") + exclude("license/**") + exclude("**LICENCE**") + exclude("**LICENSE**") + // Other dependencies + exclude("club/minnced/opus/**") + exclude("co/touchlab/stately/**") + exclude("com/google/**") + exclude("com/ibm/icu/**") + exclude("com/sun/**") + exclude("google/protobuf/**") + exclude("io/github/**") + exclude("io/javalin/**") + exclude("jakarta/servlet/**") + exclude("javax/annotation/**") + exclude("javax/servlet/**") + exclude("natives/**") + exclude("net/luckperms/**") + exclude("nl/altindag/**") + exclude("org/bouncycastle/**") + exclude("org/checkerframework/**") + exclude("org/conscrypt/**") + exclude("org/apache/batik/**") + exclude("org/apache/xmlgraphics/**") + exclude("org/apache/xmlcommons/**") + exclude("org/eclipse/**") + exclude("jdk/xml/**") + exclude("org/w3c/**") + exclude("tomp2p/opuswrapper/**") + exclude("org/slf4j/**") + exclude("javax/xml/**") + exclude("org/xml/**") + // META + exclude("META-INF/**.md") + exclude("META-INF/**.MD") + exclude("META-INF/**.txt**") + exclude("META-INF/**LICENCE**") + exclude("META-INF/com.android.tools/**") + exclude("META-INF/gradle-plugins/**") + exclude("META-INF/imports/**") + exclude("META-INF/kotlin-reflection.kotlin_module") + exclude("META-INF/license/**") + exclude("META-INF/maven/**") + exclude("META-INF/native-image/**") + exclude("META-INF/native/**") + exclude("META-INF/proguard/**") + exclude("META-INF/rewrite/**") + exclude("META-INF/services/kotlin.reflect.**") + if (project.name != "forge") { + // Don't remove in: [forge] + exclude("META-INF/versions/**") + } + // DEPENDENCIES + if (project.name == "bukkit") { + exclude(dependency("com.fasterxml.jackson.core:.*")) + exclude(dependency("com.google.code.gson:.*")) + exclude(dependency("com.google.crypto.tink:.*")) + exclude(dependency("com.google.errorprone:.*")) + exclude(dependency("com.mojang:brigadier")) + exclude(dependency("com.mysql:mysql-connector-j")) + exclude(dependency("mysql:mysql-connector-java")) + exclude(dependency("net.java.dev.jna:.*")) + exclude(dependency("net.kyori:.*")) + exclude(dependency("org.apache.xmlgraphics:.*")) + exclude(dependency("org.bouncycastle:.*")) + exclude(dependency("org.checkerframework:.*")) + exclude(dependency("org.conscrypt:.*")) + exclude(dependency("org.eclipse.jetty.toolchain:.*")) + exclude(dependency("org.eclipse.jetty:.*")) + exclude(dependency("org.xerial:sqlite-jdbc")) } } + + relocate("org.bstats", requireProjectInfo.group) + // Be sure to relocate EXACT PACKAGES!! + // For example, relocate org.some.package instead of org + // Becuase relocation org will break other non-relocated dependencies such as org.minecraft + // Don't relocate `org.jetbrains.exposed` and `kotlin` + buildList { + add("ch.qos.logback") + add("club.minnced.discord") + add("club.minnced.opus") + add("co.touchlab.stately") + add("com.arkivanov") + add("com.charleskorn.kaml") + if (project.name != "bukkit") { + // Don't relocate on: [bukkit] + add("com.fasterxml") + } + add("com.ibm.icu") + add("com.neovisionaries") + add("dev.icerock") + add("gnu.trove") + add("google.protobuf") + add("io.github.reactivecircus") + add("it.krzeminski") + add("it.krzeminski.snakeyaml") + if (project.name != "bukkit") { + // Is present on: [bukkit] + add("javax.xml") + } + add("kotlinx") + add("net.dv8tion") + if (project.name != "bukkit") { + // Don't relocate on: [bukkit] + add("net.kyori") + } + add("net.thauvin") + add("okhttp3") + add("okio") + add("org.apache") + if (project.name != "bukkit") { + // Don't relocate on: [bukkit] + add("org.h2") + } + + add("org.intellij") + add("org.jetbrains.annotations") +// add("org.jetbrains.exposed") // Don't relocate on: [*] + add("org.jetbrains.kotlinx") + add("org.json") + add("org.json") +// add("org.sqlite") // Don't relocate on: [*] + add("org.telegram") + add("org.telegram.telegrambots") + add("org.w3c.css") + add("org.w3c.dom") + add("ru.astrainteractive.astralibs") + add("ru.astrainteractive.klibs") + add("tomp2p.opuswrapper") + }.forEach { pattern -> relocate(pattern, "${requireProjectInfo.group}.shade.$pattern") } } diff --git a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/command/rickmorty/RickMortyCommandRegistrar.kt b/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/command/rickmorty/RickMortyCommandRegistrar.kt index d5e5ed9..9adeec0 100644 --- a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/command/rickmorty/RickMortyCommandRegistrar.kt +++ b/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/command/rickmorty/RickMortyCommandRegistrar.kt @@ -11,7 +11,7 @@ import ru.astrainteractive.astralibs.command.api.util.command import ru.astrainteractive.astralibs.command.api.util.literal import ru.astrainteractive.astralibs.command.api.util.requireArgument import ru.astrainteractive.astralibs.command.api.util.runs -import ru.astrainteractive.astratemplate.api.remote.RickMortyApi +import ru.astrainteractive.astratemplate.api.remote.api.RickMortyApi import ru.astrainteractive.astratemplate.command.errorhandler.DefaultErrorHandler import ru.astrainteractive.klibs.mikro.core.dispatchers.KotlinDispatchers import kotlin.random.Random diff --git a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt b/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt index ec316eb..aadab38 100644 --- a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt +++ b/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt @@ -1,6 +1,7 @@ package ru.astrainteractive.astratemplate.di import ru.astrainteractive.astralibs.async.DefaultBukkitDispatchers +import ru.astrainteractive.astralibs.coroutines.DefaultBukkitDispatchers import ru.astrainteractive.astralibs.lifecycle.Lifecycle import ru.astrainteractive.astratemplate.AstraTemplate import ru.astrainteractive.astratemplate.api.local.di.ApiLocalModule @@ -20,9 +21,8 @@ internal class RootModule(plugin: AstraTemplate) { ) val apiLocalModule: ApiLocalModule = ApiLocalModule( - dataFolder = bukkitModule.plugin.dataFolder, configFlow = coreModule.configKrate.cachedStateFlow, - scope = coreModule.ioScope + ioScope = coreModule.ioScope ) val apiRemoteModule: ApiRemoteModule = ApiRemoteModule() diff --git a/instances/fabric/build.gradle.kts b/instances/fabric/build.gradle.kts index 0780230..41824da 100644 --- a/instances/fabric/build.gradle.kts +++ b/instances/fabric/build.gradle.kts @@ -29,8 +29,8 @@ dependencies { // Driver implementation(libs.driver.jdbc) // Local - implementation(projects.modules.apiLocal) - implementation(projects.modules.apiRemote) + implementation(projects.modules.api.local) + implementation(projects.modules.api.remote) implementation(projects.modules.core) } diff --git a/instances/forge/build.gradle.kts b/instances/forge/build.gradle.kts index d261acd..dcc055b 100644 --- a/instances/forge/build.gradle.kts +++ b/instances/forge/build.gradle.kts @@ -1,76 +1,114 @@ -@file:Suppress("UnusedPrivateMember") - import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar -import ru.astrainteractive.gradleplugin.property.extension.ModelPropertyValueExt.requireProjectInfo +import net.minecraftforge.jarjar.gradle.JarJar +import net.minecraftforge.jarjar.gradle.JarJarDependencyMethods +import ru.astrainteractive.gradleplugin.property.util.requireProjectInfo plugins { - kotlin("jvm") - alias(libs.plugins.klibs.gradle.java.core) - alias(libs.plugins.forgegradle) + id("org.jetbrains.kotlin.jvm") + id("org.jetbrains.kotlin.plugin.serialization") + id("ru.astrainteractive.gradleplugin.detekt") + id("ru.astrainteractive.gradleplugin.java.version") + alias(libs.plugins.gradle.forgegradle) + alias(libs.plugins.gradle.forgerenamer) alias(libs.plugins.gradle.shadow) alias(libs.plugins.klibs.minecraft.resource.processor) + alias(libs.plugins.gradle.forge.jarjar) } -dependencies { - minecraft( - "net.minecraftforge", - "forge", - "${libs.versions.minecraft.mojang.version.get()}-${libs.versions.minecraft.forgeversion.get()}" - ) - implementation(libs.minecraft.astralibs.core) - implementation(libs.minecraft.astralibs.core.forge) - implementation(libs.minecraft.astralibs.command) - - implementation(libs.klibs.kstorage) - implementation(libs.klibs.mikro.core) - - implementation(libs.kotlin.coroutines.core) - implementation(libs.kotlin.serialization.json) - implementation(libs.kotlin.serialization.kaml) - - implementation(projects.modules.apiLocal) - implementation(projects.modules.apiRemote) - implementation(projects.modules.core) - implementation(projects.modules.buildKonfig) +repositories { + minecraft.mavenizer(this) + mavenCentral() + mavenLocal() + maven(fg.forgeMaven) + maven(fg.minecraftLibsMaven) } -minecraft { - mappings("official", libs.versions.minecraft.mojang.version.get()) - accessTransformer(rootProject.file("build").resolve("accesstransformer.cfg")) +dependencies { + shadow(libs.kotlin.coroutines.core) + shadow(libs.minecraft.astralibs.core) + shadow(libs.minecraft.astralibs.core.forge) + shadow(libs.minecraft.astralibs.command) + shadow(libs.kotlin.serialization.kaml) + shadow(libs.klibs.mikro.core) + shadow(libs.klibs.kstorage) + shadow(libs.minecraft.kyori.plain) + shadow(libs.minecraft.kyori.legacy) + shadow(libs.minecraft.kyori.gson) + shadow(projects.modules.api.local) + shadow(projects.modules.api.remote) + shadow(projects.modules.buildKonfig) + shadow(projects.modules.core) } -configurations { - apiElements { - artifacts.clear() - } - runtimeElements { - setExtendsFrom(emptySet()) - // Publish the jarJar - artifacts.clear() - outgoing.artifact(tasks.jarJar) - } +minecraftProcessResource { + forge( + customProperties = mapOf( + "minecraft_version" to libs.versions.minecraft.forgeversion.get().split("-")[0], + "forge_version" to libs.versions.minecraft.forgeversion.get().split("-")[1], + "mod_license" to "MIT License" + ) + ) } -val destination = File("/home/makeevrsergh/Desktop/server/mods/") - .takeIf(File::exists) - ?: File(rootDir, "jars") - -val reobfShadowJar = reobf.create("shadowJar") +jarJar { + register() +} val shadowJar by tasks.getting(ShadowJar::class) { mergeServiceFiles() - finalizedBy(reobfShadowJar) + dependsOn(tasks.named("processResources")) + dependsOn(tasks.withType()) + from( + tasks.withType() + .map { task -> task.archiveFile } + .map { archiveFile -> project.zipTree(archiveFile) }, + { include("META-INF/jarjar/**") } + ) + configurations = listOf(project.configurations.shadow.get()) isReproducibleFileOrder = true + duplicatesStrategy = DuplicatesStrategy.EXCLUDE archiveClassifier = null as String? archiveVersion = requireProjectInfo.versionString - archiveBaseName = "${requireProjectInfo.name}-forge" - destinationDirectory = destination + archiveBaseName = "${requireProjectInfo.name}-${project.name}" + destinationDirectory = rootProject.layout.buildDirectory.get() + .asFile + .resolve(project.name) + .resolve("mods") + .takeIf(File::exists) + ?: rootDir.resolve("jars") dependencies { + // Dependencies exclude(dependency("org.jetbrains:annotations")) - exclude("co/touchlab/stately/**") + exclude("ch/qos/logback/**") + exclude("com/ibm/icu/**") + exclude("it/unimi/dsi/**") + exclude("javax/**") + exclude("mozilla/**") + exclude("org/apache/batik/**") + exclude("org/apache/commons/logging/**") + exclude("org/apache/xmlgraphics/**") + exclude("org/intellij/lang/annotations/**") + exclude("org/jetbrains/annotations/**") + exclude("org/slf4j/**") + exclude("org/w3c/dom/**") + exclude("org/jspecify/annotations/**") + // Root + if (project.name == "forge" || project.name == "neoforge") { + // Use kotlin-neoforge or kotlin-forge + exclude("kotlin/**") + } + exclude("_COROUTINE/**") + exclude("DebugProbesKt.bin") + exclude("jetty-dir.css") + exclude("license/**") + exclude("**LICENCE**") + exclude("**LICENSE**") + // Other dependencies exclude("club/minnced/opus/**") + exclude("co/touchlab/stately/**") exclude("com/google/**") + exclude("com/ibm/icu/**") exclude("com/sun/**") exclude("google/protobuf/**") exclude("io/github/**") @@ -79,54 +117,139 @@ val shadowJar by tasks.getting(ShadowJar::class) { exclude("javax/annotation/**") exclude("javax/servlet/**") exclude("natives/**") + exclude("net/luckperms/**") exclude("nl/altindag/**") - exclude("org/eclipse/**") exclude("org/bouncycastle/**") exclude("org/checkerframework/**") exclude("org/conscrypt/**") + exclude("org/apache/batik/**") + exclude("org/apache/xmlgraphics/**") + exclude("org/apache/xmlcommons/**") + exclude("org/eclipse/**") + exclude("jdk/xml/**") + exclude("org/w3c/**") exclude("tomp2p/opuswrapper/**") - exclude("DebugProbesKt.bin") - exclude("_COROUTINE/**") - exclude("META-INF/*.kotlin_module") + exclude("org/slf4j/**") + exclude("javax/xml/**") + exclude("org/xml/**") + exclude("org/sqlite/**") + // META + exclude("META-INF/**.md") + exclude("META-INF/**.MD") + exclude("META-INF/**.txt**") + exclude("META-INF/**LICENCE**") exclude("META-INF/com.android.tools/**") exclude("META-INF/gradle-plugins/**") + exclude("META-INF/imports/**") + exclude("META-INF/kotlin-reflection.kotlin_module") + exclude("META-INF/license/**") exclude("META-INF/maven/**") - exclude("META-INF/proguard/**") - exclude("META-INF/versions/**") + exclude("META-INF/native-image/**") exclude("META-INF/native/**") - exclude("META-INF/**LICENCE**") + exclude("META-INF/proguard/**") + exclude("META-INF/rewrite/**") + exclude("META-INF/services/kotlin.reflect.**") + if (project.name != "forge") { + // Don't remove in: [forge] + exclude("META-INF/versions/**") + } + // DEPENDENCIES + if (project.name == "bukkit") { + exclude(dependency("com.fasterxml.jackson.core:.*")) + exclude(dependency("com.google.code.gson:.*")) + exclude(dependency("com.google.crypto.tink:.*")) + exclude(dependency("com.google.errorprone:.*")) + exclude(dependency("com.mojang:brigadier")) + exclude(dependency("com.mysql:mysql-connector-j")) + exclude(dependency("mysql:mysql-connector-java")) + exclude(dependency("net.java.dev.jna:.*")) + exclude(dependency("net.kyori:.*")) + exclude(dependency("org.apache.xmlgraphics:.*")) + exclude(dependency("org.bouncycastle:.*")) + exclude(dependency("org.checkerframework:.*")) + exclude(dependency("org.conscrypt:.*")) + exclude(dependency("org.eclipse.jetty.toolchain:.*")) + exclude(dependency("org.eclipse.jetty:.*")) + exclude(dependency("org.xerial:sqlite-jdbc")) + } } + relocate("org.bstats", requireProjectInfo.group) // Be sure to relocate EXACT PACKAGES!! // For example, relocate org.some.package instead of org // Becuase relocation org will break other non-relocated dependencies such as org.minecraft - listOf( - "com.fasterxml", - "net.kyori", - "org.h2", - "com.neovisionaries", - "gnu.trove", - "org.json", - "org.apache", - "org.telegram", - "okhttp3", - "net.dv8tion", - "okio", - "org.slf4j", - "kotlin", - "kotlinx", - "it.krzeminski", - "net.thauvin", - "org.jetbrains.exposed.dao", - "org.jetbrains.exposed.exceptions", - "org.jetbrains.exposed.sql", - "org.jetbrains.exposed.jdbc", - "org.jetbrains.kotlin", - "org.jetbrains.kotlinx", - "com.charleskorn.kaml", - "ru.astrainteractive.klibs", - "ru.astrainteractive.astralibs", - "club.minnced.discord", - "club.minnced.opus" - ).forEach { pattern -> relocate(pattern, "${requireProjectInfo.group}.shade.$pattern") } + // Don't relocate `org.jetbrains.exposed` and `kotlin` + buildList { + add("ch.qos.logback") + add("club.minnced.discord") + add("club.minnced.opus") + add("co.touchlab.stately") + add("com.arkivanov") + add("com.charleskorn.kaml") + if (project.name != "bukkit") { + // Don't relocate on: [bukkit] + add("com.fasterxml") + } + add("com.ibm.icu") + add("com.neovisionaries") + add("dev.icerock") + add("gnu.trove") + add("google.protobuf") + add("io.github.reactivecircus") + add("it.krzeminski") + add("it.krzeminski.snakeyaml") + if (project.name != "bukkit") { + // Is present on: [bukkit] + add("javax.xml") + } + add("kotlinx") + add("net.dv8tion") + if (project.name != "bukkit") { + // Don't relocate on: [bukkit] + add("net.kyori") + } + add("net.thauvin") + add("okhttp3") + add("okio") + add("org.apache") + add("org.intellij") + add("org.jetbrains.annotations") + add("org.jetbrains.exposed") // Don't relocate on: [*] + add("org.jetbrains.kotlinx") + add("org.json") + add("org.json") + add("org.telegram") + add("org.telegram.telegrambots") + add("org.w3c.css") + add("org.w3c.dom") + add("ru.astrainteractive.astralibs") + add("ru.astrainteractive.klibs") + add("tomp2p.opuswrapper") + }.forEach { pattern -> relocate(pattern, "${requireProjectInfo.group}.shade.$pattern") } +} + +minecraft { + mappings("official", libs.versions.minecraft.mojang.version.get()) + useDefaultAccessTransformer() } + +dependencies { + compileOnly(minecraft.dependency(libs.minecraft.forgeversion.get())) + "jarJar"(libs.driver.jdbc) { + JarJarDependencyMethods.getJarJar(this).setVersion(libs.versions.driver.jdbc) + } + "jarJar"(libs.driver.h2) { + JarJarDependencyMethods.getJarJar(this).setVersion(libs.versions.driver.h2) + } +} + +renamer { + mappings.from(minecraft.dependency.toSrgFile) +} + +val reobfShadowJar by renamer.classes(tasks.named("shadowJar")) { + output = input +} + +shadowJar.finalizedBy(reobfShadowJar) +reobfShadowJar.mustRunAfter(shadowJar) diff --git a/instances/forge/src/main/java/ru/astrainteractive/astratemplate/di/RootModule.kt b/instances/forge/src/main/java/ru/astrainteractive/astratemplate/di/RootModule.kt index 022c0fa..b652cf5 100644 --- a/instances/forge/src/main/java/ru/astrainteractive/astratemplate/di/RootModule.kt +++ b/instances/forge/src/main/java/ru/astrainteractive/astratemplate/di/RootModule.kt @@ -29,9 +29,8 @@ class RootModule { val apiLocalModule: ApiLocalModule by lazy { ApiLocalModule( - dataFolder = coreModule.dataFolder, configFlow = coreModule.configKrate.cachedStateFlow, - scope = coreModule.ioScope + ioScope = coreModule.ioScope ) } diff --git a/instances/neoforge/build.gradle.kts b/instances/neoforge/build.gradle.kts new file mode 100644 index 0000000..ddb7928 --- /dev/null +++ b/instances/neoforge/build.gradle.kts @@ -0,0 +1,172 @@ +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar +import ru.astrainteractive.gradleplugin.property.util.requireProjectInfo + +plugins { + id("org.jetbrains.kotlin.jvm") + id("org.jetbrains.kotlin.plugin.serialization") + id("ru.astrainteractive.gradleplugin.detekt") + id("ru.astrainteractive.gradleplugin.java.version") + alias(libs.plugins.gradle.neoforgegradle) + alias(libs.plugins.klibs.minecraft.resource.processor) + alias(libs.plugins.gradle.shadow) +} + +repositories { + mavenCentral() + mavenLocal() +} + +dependencies { + shadow(libs.kotlin.coroutines.core) + shadow(libs.minecraft.astralibs.core) + shadow(libs.minecraft.astralibs.core.forge) + shadow(libs.minecraft.astralibs.command) + shadow(libs.kotlin.serialization.kaml) + shadow(libs.klibs.mikro.core) + shadow(libs.klibs.kstorage) + shadow(libs.minecraft.kyori.plain) + shadow(libs.minecraft.kyori.legacy) + shadow(libs.minecraft.kyori.gson) + shadow(projects.modules.api.local) + shadow(projects.modules.api.remote) + shadow(projects.modules.buildKonfig) + shadow(projects.modules.core) +} + +minecraftProcessResource { + neoForge( + customProperties = mapOf( + "minecraft_version" to libs.versions.minecraft.mojang.version.get(), + "minecraft_version_range" to listOf(libs.versions.minecraft.mojang.version.get()) + .joinToString(","), + "neo_version" to "neo_version", + "neo_version_range" to "[${libs.versions.minecraft.neoforgeversion.get()},)", + ) + ) +} + +val shadowJar by tasks.getting(ShadowJar::class) { + mergeServiceFiles() + dependsOn(tasks.named("processResources")) + configurations = listOf(project.configurations.shadow.get()) + isReproducibleFileOrder = true + duplicatesStrategy = DuplicatesStrategy.EXCLUDE + archiveClassifier = null as String? + archiveVersion = requireProjectInfo.versionString + archiveBaseName = "${requireProjectInfo.name}-${project.name}" + destinationDirectory = rootProject.layout.buildDirectory.get() + .asFile + .resolve(project.name) + .resolve("mods") + .takeIf(File::exists) + ?: rootDir.resolve("jars") + dependencies { + // Dependencies + exclude(dependency("org.jetbrains:annotations")) + // Root +// exclude("kotlin/**") // Use kotlin-neoforge or kotlin-forge + exclude("_COROUTINE/**") + exclude("DebugProbesKt.bin") + exclude("jetty-dir.css") + exclude("license/**") + exclude("**LICENCE**") + exclude("**LICENSE**") + // Other dependencies + exclude("club/minnced/opus/**") + exclude("co/touchlab/stately/**") + exclude("com/google/**") + exclude("com/ibm/icu/**") + exclude("com/sun/**") + exclude("google/protobuf/**") + exclude("io/github/**") + exclude("io/javalin/**") + exclude("jakarta/servlet/**") + exclude("javax/annotation/**") + exclude("javax/servlet/**") + exclude("natives/**") + exclude("net/luckperms/**") + exclude("nl/altindag/**") + exclude("org/bouncycastle/**") + exclude("org/checkerframework/**") + exclude("org/conscrypt/**") + exclude("org/apache/batik/**") + exclude("org/apache/xmlgraphics/**") + exclude("org/apache/xmlcommons/**") + exclude("org/eclipse/**") + exclude("jdk/xml/**") + exclude("org/w3c/**") + exclude("tomp2p/opuswrapper/**") + exclude("org/slf4j/**") + exclude("javax/xml/**") + exclude("org/xml/**") + // META + exclude("META-INF/**.md") + exclude("META-INF/**.MD") + exclude("META-INF/**.txt**") + exclude("META-INF/**LICENCE**") + exclude("META-INF/com.android.tools/**") + exclude("META-INF/gradle-plugins/**") + exclude("META-INF/imports/**") + exclude("META-INF/kotlin-reflection.kotlin_module") + exclude("META-INF/license/**") + exclude("META-INF/maven/**") + exclude("META-INF/native-image/**") + exclude("META-INF/native/**") + exclude("META-INF/proguard/**") + exclude("META-INF/rewrite/**") + exclude("META-INF/services/kotlin.reflect.**") +// exclude("META-INF/versions/**") // Don't remove in Forge + } + + // Be sure to relocate EXACT PACKAGES!! + // For example, relocate org.some.package instead of org + // Becuase relocation org will break other non-relocated dependencies such as org.minecraft + // Don't relocate `org.jetbrains.exposed` and `kotlin` + listOf( + "ch.qos.logback", + "club.minnced.discord", + "club.minnced.opus", + "co.touchlab.stately", + "com.arkivanov", + "com.charleskorn.kaml", + "com.fasterxml", + "com.ibm.icu", + "com.neovisionaries", + "dev.icerock", + "gnu.trove", + "google.protobuf", + "io.github.reactivecircus", + "it.krzeminski", + "it.krzeminski.snakeyaml", +// "javax.xml", // Is present + "kotlinx", + "net.dv8tion", + "net.kyori", + "net.thauvin", + "okhttp3", + "okio", + "org.apache", + "org.h2", + "org.intellij", + "org.jetbrains.annotations", + "org.jetbrains.exposed", // Don't relocate +// "org.jetbrains.kotlin", // Don't relocate + "org.jetbrains.kotlinx", + "org.json", + "org.json", +// "org.slf4j", // Is present + "org.sqlite", + "org.telegram", + "org.telegram.telegrambots", + "org.w3c.css", + "org.w3c.dom", +// "org.xml.sax", // Is present + "ru.astrainteractive.astralibs", + "ru.astrainteractive.klibs", + "tomp2p.opuswrapper", + ).forEach { pattern -> relocate(pattern, "${requireProjectInfo.group}.shade.$pattern") } +} + +dependencies { + compileOnly(libs.minecraft.neoforgeversion) +} diff --git a/instances/neoforge/gradle.properties b/instances/neoforge/gradle.properties new file mode 100644 index 0000000..4de3651 --- /dev/null +++ b/instances/neoforge/gradle.properties @@ -0,0 +1 @@ +klibs.java.source=21 diff --git a/instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/ForgeEntryPoint.kt b/instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/ForgeEntryPoint.kt new file mode 100644 index 0000000..abca934 --- /dev/null +++ b/instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/ForgeEntryPoint.kt @@ -0,0 +1,55 @@ +@file:Suppress("UnusedPrivateMember") + +package ru.astrainteractive.astratemplate + +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import net.minecraftforge.event.RegisterCommandsEvent +import net.minecraftforge.event.server.ServerStartedEvent +import net.minecraftforge.event.server.ServerStoppingEvent +import net.minecraftforge.eventbus.api.EventPriority +import net.minecraftforge.fml.common.Mod +import ru.astrainteractive.astralibs.event.flowEvent +import ru.astrainteractive.astralibs.lifecycle.Lifecycle +import ru.astrainteractive.astratemplate.di.RootModule +import ru.astrainteractive.klibs.mikro.core.logging.JUtiltLogger +import ru.astrainteractive.klibs.mikro.core.logging.Logger +import javax.annotation.ParametersAreNonnullByDefault + +@Mod(BuildKonfig.id) +@ParametersAreNonnullByDefault +class ForgeEntryPoint : + Lifecycle, + Logger by JUtiltLogger("ForgeEntryPoint") { + private val rootModule: RootModule = RootModule() + + override fun onEnable() { + rootModule.lifecycle.onEnable() + } + + override fun onDisable() { + info { "#onDisable" } + rootModule.lifecycle.onDisable() + } + + override fun onReload() { + rootModule.lifecycle.onReload() + } + + val serverStartedEvent = flowEvent(EventPriority.HIGHEST) + .onEach { + info { "#serverStartedEvent" } + onEnable() + }.launchIn(rootModule.coreModule.ioScope) + + val serverStoppingEvent = flowEvent(EventPriority.HIGHEST) + .onEach { + info { "#serverStoppingEvent" } + onDisable() + }.launchIn(rootModule.coreModule.ioScope) + + val registerCommandsEvent = flowEvent(EventPriority.HIGHEST) + .onEach { e -> + info { "#registerCommandsEvent" } + }.launchIn(rootModule.coreModule.ioScope) +} diff --git a/instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/command/di/CommandModule.kt b/instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/command/di/CommandModule.kt new file mode 100644 index 0000000..9c0bb86 --- /dev/null +++ b/instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/command/di/CommandModule.kt @@ -0,0 +1,19 @@ +package ru.astrainteractive.astratemplate.command.di + +import ru.astrainteractive.astralibs.command.registrar.ForgeCommandRegistrarContext +import ru.astrainteractive.astralibs.lifecycle.Lifecycle +import ru.astrainteractive.astratemplate.command.helloworld.HelloCommandRegistrar + +class CommandModule( + private val commandRegistrarContext: ForgeCommandRegistrarContext +) { + private val nodes = buildList { + HelloCommandRegistrar().createNode().run(::add) + } + + val lifecycle: Lifecycle = Lifecycle.Lambda( + onEnable = { + nodes.onEach(commandRegistrarContext::registerWhenReady) + } + ) +} diff --git a/instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/command/helloworld/HelloCommandRegistrar.kt b/instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/command/helloworld/HelloCommandRegistrar.kt new file mode 100644 index 0000000..3554c1d --- /dev/null +++ b/instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/command/helloworld/HelloCommandRegistrar.kt @@ -0,0 +1,18 @@ +package ru.astrainteractive.astratemplate.command.helloworld + +import com.mojang.brigadier.builder.LiteralArgumentBuilder +import net.minecraft.commands.CommandSourceStack +import net.minecraft.network.chat.Component +import ru.astrainteractive.astralibs.command.util.command +import ru.astrainteractive.astralibs.command.util.runs + +class HelloCommandRegistrar { + fun createNode(): LiteralArgumentBuilder { + return command("helloworld") { + runs { ctx -> + val component = Component.literal("Hello world!") + ctx.source.source.sendSystemMessage(component) + } + } + } +} diff --git a/instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/di/RootModule.kt b/instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/di/RootModule.kt new file mode 100644 index 0000000..b652cf5 --- /dev/null +++ b/instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/di/RootModule.kt @@ -0,0 +1,72 @@ +package ru.astrainteractive.astratemplate.di + +import kotlinx.coroutines.CoroutineDispatcher +import net.minecraftforge.fml.loading.FMLPaths +import ru.astrainteractive.astralibs.command.registrar.ForgeCommandRegistrarContext +import ru.astrainteractive.astralibs.coroutine.ForgeMainDispatcher +import ru.astrainteractive.astralibs.lifecycle.Lifecycle +import ru.astrainteractive.astratemplate.api.local.di.ApiLocalModule +import ru.astrainteractive.astratemplate.api.remote.di.ApiRemoteModule +import ru.astrainteractive.astratemplate.command.di.CommandModule +import ru.astrainteractive.astratemplate.core.di.CoreModule +import ru.astrainteractive.astratemplate.event.di.EventModule +import ru.astrainteractive.klibs.mikro.core.dispatchers.DefaultKotlinDispatchers +import ru.astrainteractive.klibs.mikro.core.dispatchers.KotlinDispatchers + +class RootModule { + + val coreModule: CoreModule by lazy { + CoreModule( + dataFolder = FMLPaths.CONFIGDIR.get() + .resolve("AstraTemplate") + .toAbsolutePath() + .toFile(), + dispatchers = object : KotlinDispatchers by DefaultKotlinDispatchers { + override val Main: CoroutineDispatcher = ForgeMainDispatcher + } + ) + } + + val apiLocalModule: ApiLocalModule by lazy { + ApiLocalModule( + configFlow = coreModule.configKrate.cachedStateFlow, + ioScope = coreModule.ioScope + ) + } + + val apiRemoteModule: ApiRemoteModule by lazy { + ApiRemoteModule() + } + + val commandModule by lazy { + CommandModule( + commandRegistrarContext = ForgeCommandRegistrarContext( + mainScope = coreModule.mainScope + ) + ) + } + + val eventsModule: EventModule by lazy { + EventModule(coreModule = coreModule) + } + + private val lifecycles: List + get() = listOf( + eventsModule.lifecycle, + commandModule.lifecycle + ) + + val lifecycle: Lifecycle by lazy { + Lifecycle.Lambda( + onEnable = { + lifecycles.forEach(Lifecycle::onEnable) + }, + onDisable = { + lifecycles.forEach(Lifecycle::onDisable) + }, + onReload = { + lifecycles.forEach(Lifecycle::onReload) + } + ) + } +} diff --git a/instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/event/TickEvent.kt b/instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/event/TickEvent.kt new file mode 100644 index 0000000..9679a8f --- /dev/null +++ b/instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/event/TickEvent.kt @@ -0,0 +1,18 @@ +package ru.astrainteractive.astratemplate.event + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import net.minecraftforge.event.TickEvent +import ru.astrainteractive.astralibs.event.flowEvent +import ru.astrainteractive.klibs.mikro.core.logging.JUtiltLogger +import ru.astrainteractive.klibs.mikro.core.logging.Logger + +class TickEvent( + mainScope: CoroutineScope +) : Logger by JUtiltLogger("AstraTemplate-TickEvent") { + + val serverStartedEvent = flowEvent() + .onEach { info { "#serverStartedEvent" } } + .launchIn(mainScope) +} diff --git a/instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/event/di/EventModule.kt b/instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/event/di/EventModule.kt new file mode 100644 index 0000000..992ddf9 --- /dev/null +++ b/instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/event/di/EventModule.kt @@ -0,0 +1,11 @@ +package ru.astrainteractive.astratemplate.event.di + +import ru.astrainteractive.astralibs.lifecycle.Lifecycle +import ru.astrainteractive.astratemplate.core.di.CoreModule +import ru.astrainteractive.astratemplate.event.TickEvent + +class EventModule(coreModule: CoreModule) { + @Suppress("UnusedPrivateProperty") + private val tickEvent = TickEvent(coreModule.mainScope) + val lifecycle: Lifecycle = Lifecycle.Empty +} diff --git a/instances/neoforge/src/main/resources/META-INF/mods.toml b/instances/neoforge/src/main/resources/META-INF/mods.toml new file mode 100644 index 0000000..96a5ab0 --- /dev/null +++ b/instances/neoforge/src/main/resources/META-INF/mods.toml @@ -0,0 +1,10 @@ +license="MIT" +modLoader="javafml" +loaderVersion="[34,)" +[[mods]] +modId="${modId}" +version="${version}" +displayName="${displayName}" +authors="${authors}" +logoFile="icon.png" +description="${description}" \ No newline at end of file diff --git a/instances/neoforge/src/main/resources/icon.png b/instances/neoforge/src/main/resources/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..00201e8ab8644cdad7eccc7a95d063f38db59eb4 GIT binary patch literal 5036 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"shadowJar") -shadowJar.configure { - - val projectInfo = requireProjectInfo - isReproducibleFileOrder = true - mergeServiceFiles() - dependsOn(configurations) - archiveClassifier.set(null as String?) - - minimize { - exclude(dependency(libs.exposed.jdbc.get())) - exclude(dependency(libs.exposed.dao.get())) - } - archiveVersion.set(projectInfo.versionString) - archiveBaseName.set("${projectInfo.name}-velocity") - destinationDirectory = rootDir.resolve("build") - .resolve("velocity") - .resolve("plugins") - .takeIf(File::exists) - ?: File(rootDir, "jars").also(File::mkdirs) - - relocate("org.bstats", projectInfo.group) - listOf( - "co.touchlab", - "com.mysql", - "google.protobuf", - "io.github.reactivecircus", - "ch.qos.logback", - "com.charleskorn.kaml", - "com.ibm.icu", - "it.krzeminski.snakeyaml", - "net.thauvin.erik", - "okio", - "org.apache", - "org.intellij", - "org.slf4j", - "org.jetbrains.annotations", - "ru.astrainteractive.klibs", - "ru.astrainteractive.astralibs" - ).forEach { pattern -> relocate(pattern, "${projectInfo.group}.$pattern") } - listOf( - "org.jetbrains.exposed", - "kotlinx", - ).forEach { pattern -> - relocate(pattern, "${projectInfo.group}.$pattern") { - exclude("kotlin/kotlin.kotlin_builtins") - } - } -} diff --git a/instances/velocity/src/main/kotlin/ru/astrainteractive/astratemplate/AstraTemplate.kt b/instances/velocity/src/main/kotlin/ru/astrainteractive/astratemplate/AstraTemplate.kt deleted file mode 100644 index 1e8c41e..0000000 --- a/instances/velocity/src/main/kotlin/ru/astrainteractive/astratemplate/AstraTemplate.kt +++ /dev/null @@ -1,69 +0,0 @@ -@file:Suppress("UnusedPrivateMember") - -package ru.astrainteractive.astratemplate - -import com.google.inject.Inject -import com.google.inject.Injector -import com.velocitypowered.api.event.Subscribe -import com.velocitypowered.api.event.proxy.ProxyInitializeEvent -import com.velocitypowered.api.plugin.Plugin -import com.velocitypowered.api.plugin.annotation.DataDirectory -import com.velocitypowered.api.proxy.ProxyServer -import ru.astrainteractive.astralibs.lifecycle.Lifecycle -import ru.astrainteractive.astratemplate.command.api.VelocityCommandRegistryContext -import ru.astrainteractive.astratemplate.command.reload.ReloadCommandRegistry -import ru.astrainteractive.astratemplate.di.RootModule -import ru.astrainteractive.klibs.mikro.core.logging.JUtiltLogger -import ru.astrainteractive.klibs.mikro.core.logging.Logger -import java.nio.file.Path -import org.slf4j.Logger as Slf4jLogger - -@Plugin( - id = BuildKonfig.id, - name = BuildKonfig.name, - version = BuildKonfig.version, - url = BuildKonfig.url, - description = BuildKonfig.description, - authors = [BuildKonfig.author_0], - dependencies = [] -) -class AstraTemplate @Inject constructor( - private val injector: Injector, - private val server: ProxyServer, - private val logger: Slf4jLogger, - @DataDirectory - private val dataDirectory: Path -) : Logger by JUtiltLogger("AstraTemplate").withoutParentHandlers() { - private val rootModule = RootModule() - private val lifecycles: List - get() = listOf( - rootModule.coreModule.lifecycle, - ) - - @Subscribe - fun onProxyInitialization(event: ProxyInitializeEvent?) { - // Do some operation demanding access to the Velocity API here. - // For instance, we could register an event: - rootModule.velocityModule.apply { - this.injector = (this@AstraTemplate.injector) - this.server = (this@AstraTemplate.server) - this.logger = (this@AstraTemplate.logger) - this.dataDirectory = (this@AstraTemplate.dataDirectory) - this.plugin = (this@AstraTemplate) - } - - info { "Hello there! I made my first plugin with Velocity" } - info { "Here's your configuration: ${rootModule.coreModule.configKrate}." } - - ReloadCommandRegistry( - registryContext = VelocityCommandRegistryContext( - proxyServer = rootModule.velocityModule.server, - plugin = rootModule.velocityModule.plugin - ) - ).register() - } - - fun reload() { - lifecycles.forEach(Lifecycle::onReload) - } -} diff --git a/instances/velocity/src/main/kotlin/ru/astrainteractive/astratemplate/command/api/VelocityCommandRegistry.kt b/instances/velocity/src/main/kotlin/ru/astrainteractive/astratemplate/command/api/VelocityCommandRegistry.kt deleted file mode 100644 index d18d6f7..0000000 --- a/instances/velocity/src/main/kotlin/ru/astrainteractive/astratemplate/command/api/VelocityCommandRegistry.kt +++ /dev/null @@ -1,22 +0,0 @@ -package ru.astrainteractive.astratemplate.command.api - -import com.velocitypowered.api.command.SimpleCommand - -fun VelocityCommandRegistryContext.registerCommand( - alias: String, - parse: (SimpleCommand.Invocation) -> Result, - onSuccess: (T) -> Unit, - onFailure: (SimpleCommand.Invocation, Throwable) -> Unit = { _, _ -> } -) { - val commandMeta = this.proxyServer.commandManager - .metaBuilder(alias) - .aliases(alias) - .plugin(this.plugin) - .build() - val velocityCommand = SimpleCommand { ctx -> - parse.invoke(ctx) - .onFailure { throwable -> onFailure.invoke(ctx, throwable) } - .onSuccess { result -> onSuccess.invoke(result) } - } - proxyServer.commandManager.register(commandMeta, velocityCommand) -} diff --git a/instances/velocity/src/main/kotlin/ru/astrainteractive/astratemplate/command/api/VelocityCommandRegistryContext.kt b/instances/velocity/src/main/kotlin/ru/astrainteractive/astratemplate/command/api/VelocityCommandRegistryContext.kt deleted file mode 100644 index 9cd7b9d..0000000 --- a/instances/velocity/src/main/kotlin/ru/astrainteractive/astratemplate/command/api/VelocityCommandRegistryContext.kt +++ /dev/null @@ -1,9 +0,0 @@ -package ru.astrainteractive.astratemplate.command.api - -import com.velocitypowered.api.proxy.ProxyServer -import ru.astrainteractive.astratemplate.AstraTemplate - -class VelocityCommandRegistryContext( - val proxyServer: ProxyServer, - val plugin: AstraTemplate -) diff --git a/instances/velocity/src/main/kotlin/ru/astrainteractive/astratemplate/command/reload/ReloadCommandRegistry.kt b/instances/velocity/src/main/kotlin/ru/astrainteractive/astratemplate/command/reload/ReloadCommandRegistry.kt deleted file mode 100644 index c6aa8b5..0000000 --- a/instances/velocity/src/main/kotlin/ru/astrainteractive/astratemplate/command/reload/ReloadCommandRegistry.kt +++ /dev/null @@ -1,62 +0,0 @@ -package ru.astrainteractive.astratemplate.command.reload - -import com.velocitypowered.api.command.CommandSource -import com.velocitypowered.api.command.SimpleCommand -import net.kyori.adventure.text.Component -import ru.astrainteractive.astralibs.command.api.exception.CommandException -import ru.astrainteractive.astratemplate.command.api.VelocityCommandRegistryContext -import ru.astrainteractive.astratemplate.command.api.registerCommand -import ru.astrainteractive.astratemplate.core.plugin.PluginPermission - -class ReloadCommandRegistry(private val registryContext: VelocityCommandRegistryContext) { - - private interface ReloadCommand { - sealed interface Result { - data class Success(val source: CommandSource) : Result - } - - sealed class ReloadException(message: String) : CommandException(message) { - class WrongUsage : ReloadException("WrongUsage") - class NoPermission : ReloadException("NoPermission") - } - } - - private fun execute(result: ReloadCommand.Result) { - if (result !is ReloadCommand.Result.Success) return - result.source.sendMessage(Component.text("Success")) - registryContext.plugin.reload() - } - - private fun parse(ctx: SimpleCommand.Invocation): Result { - return runCatching { - if (!ctx.source().hasPermission(PluginPermission.Reload.value)) { - throw ReloadCommand.ReloadException.NoPermission() - } - if (ctx.arguments().isNotEmpty()) { - throw ReloadCommand.ReloadException.WrongUsage() - } - ReloadCommand.Result.Success(ctx.source()) - } - } - - private fun handle(ctx: SimpleCommand.Invocation, throwable: Throwable) { - when (throwable) { - is ReloadCommand.ReloadException.NoPermission -> { - ctx.source().sendMessage(Component.text("No permission")) - } - - is ReloadCommand.ReloadException.WrongUsage -> { - ctx.source().sendMessage(Component.text("Wrong usage")) - } - } - } - - fun register() { - registryContext.registerCommand( - alias = "reload", - parse = ::parse, - onSuccess = ::execute, - onFailure = ::handle - ) - } -} diff --git a/instances/velocity/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt b/instances/velocity/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt deleted file mode 100644 index d2351a1..0000000 --- a/instances/velocity/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt +++ /dev/null @@ -1,15 +0,0 @@ -package ru.astrainteractive.astratemplate.di - -import ru.astrainteractive.astratemplate.core.di.CoreModule -import ru.astrainteractive.klibs.mikro.core.dispatchers.DefaultKotlinDispatchers - -class RootModule { - val velocityModule = VelocityModule() - - val coreModule: CoreModule by lazy { - CoreModule( - dataFolder = velocityModule.dataDirectory.toFile(), - dispatchers = DefaultKotlinDispatchers - ) - } -} diff --git a/instances/velocity/src/main/kotlin/ru/astrainteractive/astratemplate/di/VelocityModule.kt b/instances/velocity/src/main/kotlin/ru/astrainteractive/astratemplate/di/VelocityModule.kt deleted file mode 100644 index 1bf152e..0000000 --- a/instances/velocity/src/main/kotlin/ru/astrainteractive/astratemplate/di/VelocityModule.kt +++ /dev/null @@ -1,15 +0,0 @@ -package ru.astrainteractive.astratemplate.di - -import com.google.inject.Injector -import com.velocitypowered.api.proxy.ProxyServer -import org.slf4j.Logger -import ru.astrainteractive.astratemplate.AstraTemplate -import java.nio.file.Path - -class VelocityModule { - lateinit var injector: Injector - lateinit var server: ProxyServer - lateinit var plugin: AstraTemplate - lateinit var logger: Logger - lateinit var dataDirectory: Path -} diff --git a/instances/velocity/src/main/resources/velocity-plugin.json b/instances/velocity/src/main/resources/velocity-plugin.json deleted file mode 100644 index 576630e..0000000 --- a/instances/velocity/src/main/resources/velocity-plugin.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "id": "${id}", - "name": "${name}", - "version": "${version}", - "url": "${url}", - "authors": [ - "${authors}" - ], - "dependencies": [ - "${dependencies}" - ], - "main": "${main}" -} \ No newline at end of file diff --git a/modules/api-local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/di/ApiLocalModule.kt b/modules/api-local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/di/ApiLocalModule.kt deleted file mode 100644 index 0b6a420..0000000 --- a/modules/api-local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/di/ApiLocalModule.kt +++ /dev/null @@ -1,68 +0,0 @@ -package ru.astrainteractive.astratemplate.api.local.di - -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.firstOrNull -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.launch -import org.jetbrains.exposed.sql.Database -import org.jetbrains.exposed.sql.SchemaUtils -import org.jetbrains.exposed.sql.Slf4jSqlDebugLogger -import org.jetbrains.exposed.sql.addLogger -import org.jetbrains.exposed.sql.transactions.TransactionManager -import org.jetbrains.exposed.sql.transactions.transaction -import ru.astrainteractive.astralibs.lifecycle.Lifecycle -import ru.astrainteractive.astratemplate.api.local.dao.LocalDao -import ru.astrainteractive.astratemplate.api.local.dao.LocalDaoImpl -import ru.astrainteractive.astratemplate.api.local.entity.UserRatingTable -import ru.astrainteractive.astratemplate.api.local.entity.UserTable -import ru.astrainteractive.astratemplate.core.plugin.PluginConfiguration -import ru.astrainteractive.klibs.mikro.core.coroutines.mapCached -import ru.astrainteractive.klibs.mikro.exposed.model.DatabaseConfiguration -import ru.astrainteractive.klibs.mikro.exposed.util.connect -import java.io.File - -class ApiLocalModule( - dataFolder: File, - configFlow: Flow, - scope: CoroutineScope -) { - private val databaseFlow = configFlow - .map { it.database } - .distinctUntilChanged() - .mapCached(scope) { config, previous: Database? -> - previous?.connector?.invoke()?.close() - previous?.run(TransactionManager::closeAndUnregister) - val database = dataFolder.resolve("users_db").absolutePath - .let(DatabaseConfiguration::H2) - .connect() - TransactionManager.manager.defaultIsolationLevel = java.sql.Connection.TRANSACTION_SERIALIZABLE - transaction(database) { - addLogger(Slf4jSqlDebugLogger) - SchemaUtils.create( - UserRatingTable, - UserTable - ) - } - database - } - - val localDao: LocalDao = LocalDaoImpl( - databaseFlow = databaseFlow, - ) - - val lifecycle: Lifecycle by lazy { - Lifecycle.Lambda( - onDisable = { - GlobalScope.launch { - databaseFlow.firstOrNull()?.let { database -> - database.connector.invoke().close() - database.run(TransactionManager::closeAndUnregister) - } - } - } - ) - } -} diff --git a/modules/api-remote/build.gradle.kts b/modules/api-remote/build.gradle.kts deleted file mode 100644 index c1abea4..0000000 --- a/modules/api-remote/build.gradle.kts +++ /dev/null @@ -1,10 +0,0 @@ -plugins { - kotlin("jvm") - alias(libs.plugins.kotlin.serialization) -} - -dependencies { - implementation(libs.kotlin.coroutines.core) - implementation(libs.kotlin.serialization.json) - implementation(libs.kotlin.serialization.kaml) -} diff --git a/modules/api-local/build.gradle.kts b/modules/api/local/build.gradle.kts similarity index 62% rename from modules/api-local/build.gradle.kts rename to modules/api/local/build.gradle.kts index 267b141..d458285 100644 --- a/modules/api-local/build.gradle.kts +++ b/modules/api/local/build.gradle.kts @@ -1,5 +1,8 @@ plugins { - kotlin("jvm") + id("org.jetbrains.kotlin.jvm") + id("org.jetbrains.kotlin.plugin.serialization") + id("ru.astrainteractive.gradleplugin.detekt") + id("ru.astrainteractive.gradleplugin.java.version") } dependencies { @@ -14,6 +17,8 @@ dependencies { implementation(libs.klibs.mikro.extensions) implementation(libs.exposed.core) + implementation(libs.exposed.dao) + implementation(libs.exposed.jdbc) implementation(projects.modules.core) } diff --git a/modules/api-local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/dao/LocalDao.kt b/modules/api/local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/dao/LocalDao.kt similarity index 100% rename from modules/api-local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/dao/LocalDao.kt rename to modules/api/local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/dao/LocalDao.kt diff --git a/modules/api-local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/dao/LocalDaoImpl.kt b/modules/api/local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/dao/LocalDaoImpl.kt similarity index 88% rename from modules/api-local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/dao/LocalDaoImpl.kt rename to modules/api/local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/dao/LocalDaoImpl.kt index bb8e7ac..a574d50 100644 --- a/modules/api-local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/dao/LocalDaoImpl.kt +++ b/modules/api/local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/dao/LocalDaoImpl.kt @@ -1,19 +1,19 @@ package ru.astrainteractive.astratemplate.api.local.dao +import java.util.UUID import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.first -import org.jetbrains.exposed.sql.Database -import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq -import org.jetbrains.exposed.sql.deleteWhere -import org.jetbrains.exposed.sql.insertAndGetId -import org.jetbrains.exposed.sql.selectAll -import org.jetbrains.exposed.sql.transactions.transaction -import org.jetbrains.exposed.sql.update +import org.jetbrains.exposed.v1.core.eq +import org.jetbrains.exposed.v1.jdbc.Database +import org.jetbrains.exposed.v1.jdbc.deleteWhere +import org.jetbrains.exposed.v1.jdbc.insertAndGetId +import org.jetbrains.exposed.v1.jdbc.selectAll +import org.jetbrains.exposed.v1.jdbc.transactions.transaction +import org.jetbrains.exposed.v1.jdbc.update import ru.astrainteractive.astratemplate.api.local.entity.UserRatingTable import ru.astrainteractive.astratemplate.api.local.entity.UserTable import ru.astrainteractive.astratemplate.api.local.model.RatingModel import ru.astrainteractive.astratemplate.api.local.model.UserModel -import java.util.UUID internal class LocalDaoImpl( private val databaseFlow: Flow, diff --git a/modules/api/local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/di/ApiLocalModule.kt b/modules/api/local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/di/ApiLocalModule.kt new file mode 100644 index 0000000..506f77e --- /dev/null +++ b/modules/api/local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/di/ApiLocalModule.kt @@ -0,0 +1,49 @@ +package ru.astrainteractive.astratemplate.api.local.di + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.firstOrNull +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.launch +import ru.astrainteractive.astralibs.lifecycle.Lifecycle +import ru.astrainteractive.astratemplate.api.local.dao.LocalDao +import ru.astrainteractive.astratemplate.api.local.dao.LocalDaoImpl +import ru.astrainteractive.astratemplate.api.local.entity.UserRatingTable +import ru.astrainteractive.astratemplate.api.local.entity.UserTable +import ru.astrainteractive.astratemplate.core.plugin.PluginConfiguration +import java.io.File +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.flatMapLatest +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.shareIn +import org.jetbrains.exposed.v1.jdbc.SchemaUtils +import org.jetbrains.exposed.v1.jdbc.transactions.TransactionManager +import org.jetbrains.exposed.v1.jdbc.transactions.transaction +import ru.astrainteractive.klibs.mikro.exposed.util.connectAsFlow + +class ApiLocalModule( + configFlow: Flow, + ioScope: CoroutineScope +) { + private val databaseFlow = configFlow + .map { pluginConfiguration -> pluginConfiguration.database } + .distinctUntilChanged() + .flatMapLatest { configuration -> configuration.connectAsFlow() } + .onEach { database -> + TransactionManager.manager.defaultIsolationLevel = java.sql.Connection.TRANSACTION_SERIALIZABLE + transaction(database) { + SchemaUtils.create(UserRatingTable, UserTable) + } + } + .shareIn(ioScope, SharingStarted.Eagerly, 1) + + val localDao: LocalDao = LocalDaoImpl( + databaseFlow = databaseFlow, + ) + + val lifecycle: Lifecycle by lazy { + Lifecycle.Lambda() + } +} diff --git a/modules/api-local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/entity/UserRatingTable.kt b/modules/api/local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/entity/UserRatingTable.kt similarity index 77% rename from modules/api-local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/entity/UserRatingTable.kt rename to modules/api/local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/entity/UserRatingTable.kt index 69f92e4..15ffaf4 100644 --- a/modules/api-local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/entity/UserRatingTable.kt +++ b/modules/api/local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/entity/UserRatingTable.kt @@ -1,6 +1,6 @@ package ru.astrainteractive.astratemplate.api.local.entity -import org.jetbrains.exposed.dao.id.IntIdTable +import org.jetbrains.exposed.v1.core.dao.id.IntIdTable internal object UserRatingTable : IntIdTable("rating") { val userID = integer("user_id") diff --git a/modules/api-local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/entity/UserTable.kt b/modules/api/local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/entity/UserTable.kt similarity index 78% rename from modules/api-local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/entity/UserTable.kt rename to modules/api/local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/entity/UserTable.kt index 8ada3da..3de3c8e 100644 --- a/modules/api-local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/entity/UserTable.kt +++ b/modules/api/local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/entity/UserTable.kt @@ -1,6 +1,6 @@ package ru.astrainteractive.astratemplate.api.local.entity -import org.jetbrains.exposed.dao.id.IntIdTable +import org.jetbrains.exposed.v1.core.dao.id.IntIdTable internal object UserTable : IntIdTable("users") { val discordId = text("discord_id") diff --git a/modules/api-local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/model/RatingModel.kt b/modules/api/local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/model/RatingModel.kt similarity index 100% rename from modules/api-local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/model/RatingModel.kt rename to modules/api/local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/model/RatingModel.kt diff --git a/modules/api-local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/model/UserModel.kt b/modules/api/local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/model/UserModel.kt similarity index 100% rename from modules/api-local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/model/UserModel.kt rename to modules/api/local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/model/UserModel.kt diff --git a/modules/api/remote/build.gradle.kts b/modules/api/remote/build.gradle.kts new file mode 100644 index 0000000..f1907ab --- /dev/null +++ b/modules/api/remote/build.gradle.kts @@ -0,0 +1,12 @@ +plugins { + id("org.jetbrains.kotlin.jvm") + id("org.jetbrains.kotlin.plugin.serialization") + id("ru.astrainteractive.gradleplugin.detekt") + id("ru.astrainteractive.gradleplugin.java.version") +} + +dependencies { + implementation(libs.kotlin.coroutines.core) + implementation(libs.kotlin.serialization.json) + implementation(libs.kotlin.serialization.kaml) +} diff --git a/modules/api-remote/src/main/kotlin/ru/astrainteractive/astratemplate/api/remote/RickMortyApi.kt b/modules/api/remote/src/main/kotlin/ru/astrainteractive/astratemplate/api/remote/api/RickMortyApi.kt similarity index 81% rename from modules/api-remote/src/main/kotlin/ru/astrainteractive/astratemplate/api/remote/RickMortyApi.kt rename to modules/api/remote/src/main/kotlin/ru/astrainteractive/astratemplate/api/remote/api/RickMortyApi.kt index 736daf8..cf90067 100644 --- a/modules/api-remote/src/main/kotlin/ru/astrainteractive/astratemplate/api/remote/RickMortyApi.kt +++ b/modules/api/remote/src/main/kotlin/ru/astrainteractive/astratemplate/api/remote/api/RickMortyApi.kt @@ -1,4 +1,4 @@ -package ru.astrainteractive.astratemplate.api.remote +package ru.astrainteractive.astratemplate.api.remote.api import ru.astrainteractive.astratemplate.api.remote.model.RMResponse diff --git a/modules/api-remote/src/main/kotlin/ru/astrainteractive/astratemplate/api/remote/RickMortyApiImpl.kt b/modules/api/remote/src/main/kotlin/ru/astrainteractive/astratemplate/api/remote/api/RickMortyApiImpl.kt similarity index 87% rename from modules/api-remote/src/main/kotlin/ru/astrainteractive/astratemplate/api/remote/RickMortyApiImpl.kt rename to modules/api/remote/src/main/kotlin/ru/astrainteractive/astratemplate/api/remote/api/RickMortyApiImpl.kt index 049f996..34a31e1 100644 --- a/modules/api-remote/src/main/kotlin/ru/astrainteractive/astratemplate/api/remote/RickMortyApiImpl.kt +++ b/modules/api/remote/src/main/kotlin/ru/astrainteractive/astratemplate/api/remote/api/RickMortyApiImpl.kt @@ -1,6 +1,5 @@ -package ru.astrainteractive.astratemplate.api.remote +package ru.astrainteractive.astratemplate.api.remote.api -import kotlinx.serialization.decodeFromString import kotlinx.serialization.json.Json import ru.astrainteractive.astratemplate.api.remote.model.RMResponse import java.net.URI @@ -19,7 +18,7 @@ internal class RickMortyApiImpl( isLenient = true } - override suspend fun getRandomCharacter(id: Int): Result = kotlin.runCatching { + override suspend fun getRandomCharacter(id: Int): Result = runCatching { val request: HttpRequest = HttpRequest.newBuilder() .uri(URI("https://rickandmortyapi.com/api/character/$id")) .GET() diff --git a/modules/api-remote/src/main/kotlin/ru/astrainteractive/astratemplate/api/remote/di/ApiRemoteModule.kt b/modules/api/remote/src/main/kotlin/ru/astrainteractive/astratemplate/api/remote/di/ApiRemoteModule.kt similarity index 66% rename from modules/api-remote/src/main/kotlin/ru/astrainteractive/astratemplate/api/remote/di/ApiRemoteModule.kt rename to modules/api/remote/src/main/kotlin/ru/astrainteractive/astratemplate/api/remote/di/ApiRemoteModule.kt index 2773ab4..bf46912 100644 --- a/modules/api-remote/src/main/kotlin/ru/astrainteractive/astratemplate/api/remote/di/ApiRemoteModule.kt +++ b/modules/api/remote/src/main/kotlin/ru/astrainteractive/astratemplate/api/remote/di/ApiRemoteModule.kt @@ -1,7 +1,7 @@ package ru.astrainteractive.astratemplate.api.remote.di -import ru.astrainteractive.astratemplate.api.remote.RickMortyApi -import ru.astrainteractive.astratemplate.api.remote.RickMortyApiImpl +import ru.astrainteractive.astratemplate.api.remote.api.RickMortyApi +import ru.astrainteractive.astratemplate.api.remote.api.RickMortyApiImpl import java.net.http.HttpClient class ApiRemoteModule { diff --git a/modules/api-remote/src/main/kotlin/ru/astrainteractive/astratemplate/api/remote/model/RMResponse.kt b/modules/api/remote/src/main/kotlin/ru/astrainteractive/astratemplate/api/remote/model/RMResponse.kt similarity index 100% rename from modules/api-remote/src/main/kotlin/ru/astrainteractive/astratemplate/api/remote/model/RMResponse.kt rename to modules/api/remote/src/main/kotlin/ru/astrainteractive/astratemplate/api/remote/model/RMResponse.kt diff --git a/modules/build-konfig/build.gradle.kts b/modules/build-konfig/build.gradle.kts index 278f4df..ebe873c 100644 --- a/modules/build-konfig/build.gradle.kts +++ b/modules/build-konfig/build.gradle.kts @@ -1,7 +1,10 @@ -import ru.astrainteractive.gradleplugin.property.extension.ModelPropertyValueExt.requireProjectInfo +import ru.astrainteractive.gradleplugin.property.util.requireProjectInfo plugins { - kotlin("jvm") + id("org.jetbrains.kotlin.jvm") + id("org.jetbrains.kotlin.plugin.serialization") + id("ru.astrainteractive.gradleplugin.detekt") + id("ru.astrainteractive.gradleplugin.java.version") alias(libs.plugins.gradle.buildconfig) } diff --git a/modules/core/build.gradle.kts b/modules/core/build.gradle.kts index 9de3469..c673eb2 100644 --- a/modules/core/build.gradle.kts +++ b/modules/core/build.gradle.kts @@ -1,6 +1,8 @@ plugins { - kotlin("jvm") - alias(libs.plugins.kotlin.serialization) + id("org.jetbrains.kotlin.jvm") + id("org.jetbrains.kotlin.plugin.serialization") + id("ru.astrainteractive.gradleplugin.detekt") + id("ru.astrainteractive.gradleplugin.java.version") } dependencies { diff --git a/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/di/CoreModule.kt b/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/di/CoreModule.kt index 508195e..1c02395 100644 --- a/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/di/CoreModule.kt +++ b/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/di/CoreModule.kt @@ -1,34 +1,59 @@ package ru.astrainteractive.astratemplate.core.di +import com.charleskorn.kaml.PolymorphismStyle +import com.charleskorn.kaml.Yaml +import java.io.File +import kotlinx.coroutines.CoroutineExceptionHandler +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.cancel -import ru.astrainteractive.astralibs.async.withTimings +import kotlinx.serialization.StringFormat +import ru.astrainteractive.astralibs.coroutines.withTimings import ru.astrainteractive.astralibs.lifecycle.Lifecycle import ru.astrainteractive.astralibs.util.YamlStringFormat import ru.astrainteractive.astralibs.util.parseOrWriteIntoDefault import ru.astrainteractive.astratemplate.core.plugin.PluginConfiguration import ru.astrainteractive.astratemplate.core.plugin.PluginTranslation +import ru.astrainteractive.klibs.kstorage.api.asCachedKrate +import ru.astrainteractive.klibs.kstorage.api.asStateFlowKrate import ru.astrainteractive.klibs.kstorage.api.impl.DefaultMutableKrate -import ru.astrainteractive.klibs.kstorage.util.asCachedKrate -import ru.astrainteractive.klibs.kstorage.util.asStateFlowKrate import ru.astrainteractive.klibs.mikro.core.coroutines.CoroutineFeature import ru.astrainteractive.klibs.mikro.core.dispatchers.KotlinDispatchers -import java.io.File +import ru.astrainteractive.klibs.mikro.core.logging.JUtiltLogger class CoreModule( val dataFolder: File, val dispatchers: KotlinDispatchers ) { - val yamlStringFormat = YamlStringFormat() + private val coroutineExceptionHandler = CoroutineExceptionHandler { _, throwable -> + val logger = JUtiltLogger("CoroutineExceptionHandler-AspeKt") + logger.error(throwable) { "Error happened inside global coroutine scope!" } + } + + val ioScope = CoroutineFeature + .Default(dispatchers.IO + SupervisorJob() + coroutineExceptionHandler) + .withTimings() + + val mainScope: CoroutineScope = CoroutineFeature + .Default(dispatchers.Main + SupervisorJob() + coroutineExceptionHandler) + .withTimings() - val ioScope = CoroutineFeature.IO.withTimings() - val mainScope = CoroutineFeature - .Default(dispatchers.Main) + val unconfinedScope = CoroutineFeature + .Default(dispatchers.Unconfined + SupervisorJob() + coroutineExceptionHandler) .withTimings() + val yamlFormat: StringFormat = YamlStringFormat( + configuration = Yaml.default.configuration.copy( + encodeDefaults = true, + strictMode = false, + polymorphismStyle = PolymorphismStyle.Property + ), + ) + val translationKrate = DefaultMutableKrate( factory = ::PluginTranslation, loader = { - yamlStringFormat.parseOrWriteIntoDefault( + yamlFormat.parseOrWriteIntoDefault( file = dataFolder.resolve("translation.yml"), default = ::PluginTranslation ) @@ -38,7 +63,7 @@ class CoreModule( val configKrate = DefaultMutableKrate( factory = ::PluginConfiguration, loader = { - yamlStringFormat.parseOrWriteIntoDefault( + yamlFormat.parseOrWriteIntoDefault( file = dataFolder.resolve("translation.yml"), default = ::PluginConfiguration ) @@ -53,6 +78,8 @@ class CoreModule( }, onDisable = { ioScope.cancel() + unconfinedScope.cancel() + mainScope.cancel() } ) } diff --git a/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/plugin/PluginConfiguration.kt b/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/plugin/PluginConfiguration.kt index f99b311..e1193bb 100644 --- a/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/plugin/PluginConfiguration.kt +++ b/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/plugin/PluginConfiguration.kt @@ -1,6 +1,7 @@ package ru.astrainteractive.astratemplate.core.plugin import com.charleskorn.kaml.YamlComment +import java.io.Serial import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import ru.astrainteractive.klibs.mikro.exposed.model.DatabaseConfiguration @@ -8,21 +9,29 @@ import ru.astrainteractive.klibs.mikro.exposed.model.DatabaseConfiguration @Serializable data class PluginConfiguration( @YamlComment("First line description for config1", "Second line description for config2") + @SerialName("config_1") val config1: String = "NONE", @YamlComment("Some description for config2") + @SerialName("config_2") val config2: Int = 0, + @SerialName("config_3") val config3: Boolean = false, + @SerialName("section") val section: Section = Section(), + @SerialName("list") val list: List = listOf(), @SerialName("another_list") @YamlComment("Description for list") val anotherList: List
= listOf(), + @SerialName("database") val database: DatabaseConfiguration = DatabaseConfiguration.H2("db") ) { @Serializable data class Section( @YamlComment("Description for value1") + @SerialName("value_1") val value1: String = "NONE", + @SerialName("value_2") val value2: Int = -1 ) } diff --git a/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/plugin/PluginPermission.kt b/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/plugin/PluginPermission.kt index 6f70e86..61bb30e 100644 --- a/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/plugin/PluginPermission.kt +++ b/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/plugin/PluginPermission.kt @@ -1,6 +1,6 @@ package ru.astrainteractive.astratemplate.core.plugin -import ru.astrainteractive.astralibs.permission.Permission +import ru.astrainteractive.astralibs.server.permission.Permission sealed class PluginPermission(override val value: String) : Permission { data object Reload : PluginPermission("astra_template.reload") diff --git a/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/plugin/PluginTranslation.kt b/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/plugin/PluginTranslation.kt index 4769307..447b95a 100644 --- a/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/plugin/PluginTranslation.kt +++ b/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/plugin/PluginTranslation.kt @@ -5,7 +5,9 @@ package ru.astrainteractive.astratemplate.core.plugin import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import ru.astrainteractive.astralibs.string.StringDesc +import ru.astrainteractive.astralibs.string.plus import ru.astrainteractive.astralibs.string.replace +import ru.astrainteractive.astralibs.string.toRaw /** * All translation stored here @@ -13,42 +15,63 @@ import ru.astrainteractive.astralibs.string.replace */ @Serializable class PluginTranslation( + @SerialName("database") val database: Database = Database(), + @SerialName("menu") val menu: Menu = Menu(), + @SerialName("custom") val custom: Custom = Custom(), + @SerialName("general") val general: General = General(), + @SerialName("fault") val fault: Fault = Fault() ) { @Serializable data class Fault( @SerialName("no_permission") - val noPermission: StringDesc.Raw = StringDesc.Raw("&#db2c18У вас нет прав!"), + val noPermission: StringDesc.Raw = PREFIX + .plus("&#db2c18У вас нет прав!") + .toRaw(), @SerialName("not_player") - val notPlayer: StringDesc.Raw = StringDesc.Raw("&#db2c18Вы не игрок"), + val notPlayer: StringDesc.Raw = PREFIX + .plus("&#db2c18Вы не игрок") + .toRaw(), @SerialName("player_not_exists") - val playerNotExists: StringDesc.Raw = StringDesc.Raw("&#db2c18Игрока нет!"), + val playerNotExists: StringDesc.Raw = PREFIX + .plus("&#db2c18Игрока нет!") + .toRaw(), @SerialName("item_not_found") - val itemNotFound: StringDesc.Raw = StringDesc.Raw("&#db2c18Предмет не найден"), + val itemNotFound: StringDesc.Raw = PREFIX + .plus("&#db2c18Предмет не найден") + .toRaw(), ) @Serializable class Database( @SerialName("success") - val dbSuccess: StringDesc.Raw = StringDesc.Raw("dbd1Успешно подключено к базе данных"), + val dbSuccess: StringDesc.Raw = PREFIX + .plus("dbd1Успешно подключено к базе данных") + .toRaw(), @SerialName("fail") - val dbFail: StringDesc.Raw = StringDesc.Raw("&#db2c18Нет подключения к базе данных"), + val dbFail: StringDesc.Raw = PREFIX + .plus("&#db2c18Нет подключения к базе данных") + .toRaw(), ) @Serializable class General( - @SerialName("prefix") - val prefix: StringDesc.Raw = StringDesc.Raw("dbd1[EmpireItems]"), @SerialName("reload") - val reload: StringDesc.Raw = StringDesc.Raw("&#dbbb18Перезагрузка плагина"), + val reload: StringDesc.Raw = PREFIX + .plus("&#dbbb18Перезагрузка плагина") + .toRaw(), @SerialName("reload_complete") - val reloadComplete: StringDesc.Raw = StringDesc.Raw("*f596Перезагрузка успешно завершена"), + val reloadComplete: StringDesc.Raw = PREFIX + .plus("*f596Перезагрузка успешно завершена") + .toRaw(), @SerialName("getByByCheck") - val getByByCheck: StringDesc.Raw = StringDesc.Raw("&#db2c18getByByCheck") + val getByByCheck: StringDesc.Raw = PREFIX + .plus(StringDesc.Raw("&#db2c18getByByCheck")) + .toRaw() ) @Serializable @@ -74,14 +97,24 @@ class PluginTranslation( @Serializable class Custom( @SerialName("block_placed") - val blockPlaced: StringDesc.Raw = StringDesc.Raw("dbd1Блок поставлен!"), + val blockPlaced: StringDesc.Raw = PREFIX + .plus("dbd1Блок поставлен!") + .toRaw(), @SerialName("no_player_name") - val noPlayerName: StringDesc.Raw = StringDesc.Raw("&#db2c18Вы не ввели имя игрока!"), + val noPlayerName: StringDesc.Raw = PREFIX + .plus("&#db2c18Вы не ввели имя игрока!") + .toRaw(), @SerialName("damaged") - private val damaged: StringDesc.Raw = StringDesc.Raw("&#db2c18Вас продамажил игрок %player%!"), + private val damaged: StringDesc.Raw = PREFIX + .plus("&#db2c18Вас продамажил игрок %player%!") + .toRaw(), @SerialName("damage_hint") val damageHint: StringDesc.Raw = StringDesc.Raw("") ) { fun damaged(player: String) = damaged.replace("%player%", player) } + + companion object { + private val PREFIX = StringDesc.Raw("&7[&#DBB72BTEMPLATE&7] ") + } } diff --git a/settings.gradle.kts b/settings.gradle.kts index 9732805..42a24f8 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,49 +1,48 @@ pluginManagement { repositories { - maven("https://maven.fabricmc.net/") { name = "Fabric" } - maven("https://files.minecraftforge.net/maven") - maven("https://dist.creeper.host/Sponge/maven") - maven("https://maven.minecraftforge.net/") - maven("https://plugins.gradle.org/m2/") - maven("https://jitpack.io") - gradlePluginPortal() - mavenCentral() mavenLocal() - google() - } -} - -buildscript { - repositories { - maven("https://files.minecraftforge.net/maven") - maven("https://dist.creeper.host/Sponge/maven") - maven("https://maven.minecraftforge.net/") - maven("https://plugins.gradle.org/m2/") mavenCentral() - mavenLocal() + gradlePluginPortal() + maven("https://repo.extendedclip.com/content/repositories/placeholderapi/") + maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots/") + maven("https://papermc.io/repo/repository/maven-public/") + maven("https://repo.papermc.io/repository/maven-public/") + maven("https://oss.sonatype.org/content/groups/public/") + maven("https://nexus.scarsz.me/content/groups/public/") + maven("https://repo.dmulloy2.net/repository/public/") + maven("https://repo.essentialsx.net/snapshots/") + maven("https://files.minecraftforge.net/maven") + maven("https://repo.maven.apache.org/maven2/") + maven("https://maven.neoforged.net/releases") + maven("https://maven.enginehub.org/repo/") + maven("https://maven.minecraftforge.net") + maven("https://repo1.maven.org/maven2/") + maven("https://maven.fabricmc.net/") + maven("https://maven.playpro.com") + maven("https://jitpack.io") } } dependencyResolutionManagement { repositories { - gradlePluginPortal() - mavenCentral() mavenLocal() - maven("https://mvn.lumine.io/repository/maven-public/") { metadataSources { artifact() } } + mavenCentral() maven("https://repo.extendedclip.com/content/repositories/placeholderapi/") maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots/") + maven("https://papermc.io/repo/repository/maven-public/") + maven("https://repo.papermc.io/repository/maven-public/") + maven("https://oss.sonatype.org/content/groups/public/") maven("https://nexus.scarsz.me/content/groups/public/") - maven { - name = "papermc" - url = uri("https://repo.papermc.io/repository/maven-public/") - } maven("https://repo.dmulloy2.net/repository/public/") maven("https://repo.essentialsx.net/snapshots/") + maven("https://repo.essentialsx.net/releases/") + maven("https://files.minecraftforge.net/maven") maven("https://repo.maven.apache.org/maven2/") - maven("https://maven.minecraftforge.net/") maven("https://maven.enginehub.org/repo/") - maven("https://m2.dv8tion.net/releases") + maven("https://maven.minecraftforge.net/") + maven("https://libraries.minecraft.net/") maven("https://repo1.maven.org/maven2/") + maven("https://maven.fabricmc.net/") maven("https://maven.playpro.com") maven("https://jitpack.io") } @@ -52,13 +51,11 @@ dependencyResolutionManagement { enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") rootProject.name = "AstraTemplate" -// Shared -include("modules:api-remote") -include("modules:api-local") -include("modules:core") -include("modules:build-konfig") -// Instances include(":instances:bukkit") -include(":instances:fabric") -include(":instances:velocity") include(":instances:forge") +include(":instances:neoforge") + +include("modules:api:remote") +include("modules:api:local") +include("modules:core") +include("modules:build-konfig") From 7cd5b27e36f5f88d0f98718332a1b9d98f7595a3 Mon Sep 17 00:00:00 2001 From: Roman Makeev Date: Sat, 30 May 2026 20:05:14 +0300 Subject: [PATCH 02/16] [REFACTOR] Move command --- .gitignore | 12 ++-------- instances/bukkit/build.gradle.kts | 1 + .../astratemplate/di/RootModule.kt | 3 +-- modules/feature-command/build.gradle.kts | 23 +++++++++++++++++++ .../command/additem/AddItemCommand.kt | 2 +- .../command/additem/AddItemCommandRegistry.kt | 4 ++-- .../command/additem/AddItemExecutor.kt | 2 +- .../feature}/command/common/CommonCommands.kt | 2 +- .../command/common/CommonCommandsRegistry.kt | 2 +- .../command/damage/DamageCommandRegistry.kt | 5 ++-- .../feature}/command/di/CommandModule.kt | 18 +++++++-------- .../errorhandler/DefaultErrorHandler.kt | 5 ++-- .../command/gui/GuiCommandRegistry.kt | 4 ++-- .../command/reload/ReloadCommandRegistry.kt | 5 ++-- .../rickmorty/RickMortyCommandRegistrar.kt | 4 ++-- settings.gradle.kts | 1 + 16 files changed, 53 insertions(+), 40 deletions(-) create mode 100644 modules/feature-command/build.gradle.kts rename {instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate => modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature}/command/additem/AddItemCommand.kt (87%) rename {instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate => modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature}/command/additem/AddItemCommandRegistry.kt (94%) rename {instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate => modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature}/command/additem/AddItemExecutor.kt (78%) rename {instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate => modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature}/command/common/CommonCommands.kt (54%) rename {instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate => modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature}/command/common/CommonCommandsRegistry.kt (94%) rename {instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate => modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature}/command/damage/DamageCommandRegistry.kt (93%) rename {instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate => modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature}/command/di/CommandModule.kt (76%) rename {instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate => modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature}/command/errorhandler/DefaultErrorHandler.kt (92%) rename {instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate => modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature}/command/gui/GuiCommandRegistry.kt (87%) rename {instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate => modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature}/command/reload/ReloadCommandRegistry.kt (88%) rename {instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate => modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature}/command/rickmorty/RickMortyCommandRegistrar.kt (93%) diff --git a/.gitignore b/.gitignore index f8c8b9c..7a93ec7 100644 --- a/.gitignore +++ b/.gitignore @@ -4,14 +4,6 @@ .kotlin astra.properties local.properties -build +**/build/* +**/runs/* jars -# modules -modules/api-local/build -modules/api-remote/build -modules/dto/build -# instances -instances/fabric/build -instances/forge/build -instances/plugin/build -instances/velocity/build \ No newline at end of file diff --git a/instances/bukkit/build.gradle.kts b/instances/bukkit/build.gradle.kts index 9492265..7497468 100644 --- a/instances/bukkit/build.gradle.kts +++ b/instances/bukkit/build.gradle.kts @@ -37,6 +37,7 @@ dependencies { shadow(projects.modules.api.remote) shadow(projects.modules.buildKonfig) shadow(projects.modules.core) + shadow(projects.modules.featureCommand) testImplementation(libs.tests.kotlin.test) } diff --git a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt b/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt index aadab38..02f06f8 100644 --- a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt +++ b/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt @@ -1,12 +1,11 @@ package ru.astrainteractive.astratemplate.di -import ru.astrainteractive.astralibs.async.DefaultBukkitDispatchers import ru.astrainteractive.astralibs.coroutines.DefaultBukkitDispatchers import ru.astrainteractive.astralibs.lifecycle.Lifecycle import ru.astrainteractive.astratemplate.AstraTemplate import ru.astrainteractive.astratemplate.api.local.di.ApiLocalModule import ru.astrainteractive.astratemplate.api.remote.di.ApiRemoteModule -import ru.astrainteractive.astratemplate.command.di.CommandModule +import ru.astrainteractive.astratemplate.feature.command.di.CommandModule import ru.astrainteractive.astratemplate.core.di.CoreModule import ru.astrainteractive.astratemplate.event.di.EventModule import ru.astrainteractive.astratemplate.gui.di.GuiModule diff --git a/modules/feature-command/build.gradle.kts b/modules/feature-command/build.gradle.kts new file mode 100644 index 0000000..e0f03c3 --- /dev/null +++ b/modules/feature-command/build.gradle.kts @@ -0,0 +1,23 @@ +plugins { + id("org.jetbrains.kotlin.jvm") + id("org.jetbrains.kotlin.plugin.serialization") + id("ru.astrainteractive.gradleplugin.detekt") + id("ru.astrainteractive.gradleplugin.java.version") +} + +dependencies { + compileOnly(libs.guava) + compileOnly(libs.minecraft.brigadier) + compileOnly(libs.minecraft.kyori.plain) + + implementation(libs.klibs.kstorage) + implementation(libs.klibs.mikro.core) + implementation(libs.klibs.mikro.extensions) + implementation(libs.kotlin.coroutines.core) + implementation(libs.kotlin.serialization.json) + implementation(libs.minecraft.astralibs.command) + implementation(libs.minecraft.astralibs.core) + + testImplementation(libs.kotlin.coroutines.test) + testImplementation(libs.tests.kotlin.test) +} diff --git a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/command/additem/AddItemCommand.kt b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/additem/AddItemCommand.kt similarity index 87% rename from instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/command/additem/AddItemCommand.kt rename to modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/additem/AddItemCommand.kt index a3dae44..9d03aa6 100644 --- a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/command/additem/AddItemCommand.kt +++ b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/additem/AddItemCommand.kt @@ -1,4 +1,4 @@ -package ru.astrainteractive.astratemplate.command.additem +package ru.astrainteractive.astratemplate.feature.command.additem import org.bukkit.Material import org.bukkit.entity.Player diff --git a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/command/additem/AddItemCommandRegistry.kt b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/additem/AddItemCommandRegistry.kt similarity index 94% rename from instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/command/additem/AddItemCommandRegistry.kt rename to modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/additem/AddItemCommandRegistry.kt index d1db451..7e551e8 100644 --- a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/command/additem/AddItemCommandRegistry.kt +++ b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/additem/AddItemCommandRegistry.kt @@ -1,4 +1,4 @@ -package ru.astrainteractive.astratemplate.command.additem +package ru.astrainteractive.astratemplate.feature.command.additem import com.mojang.brigadier.arguments.IntegerArgumentType import com.mojang.brigadier.arguments.StringArgumentType @@ -14,7 +14,7 @@ import ru.astrainteractive.astralibs.command.api.util.requireArgument import ru.astrainteractive.astralibs.command.api.util.runs import ru.astrainteractive.astralibs.kyori.KyoriComponentSerializer import ru.astrainteractive.astralibs.kyori.unwrap -import ru.astrainteractive.astratemplate.command.errorhandler.DefaultErrorHandler +import ru.astrainteractive.astratemplate.feature.command.errorhandler.DefaultErrorHandler import ru.astrainteractive.klibs.kstorage.api.CachedKrate internal class AddItemCommandRegistry( diff --git a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/command/additem/AddItemExecutor.kt b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/additem/AddItemExecutor.kt similarity index 78% rename from instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/command/additem/AddItemExecutor.kt rename to modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/additem/AddItemExecutor.kt index 5c55c80..6fa2c78 100644 --- a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/command/additem/AddItemExecutor.kt +++ b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/additem/AddItemExecutor.kt @@ -1,4 +1,4 @@ -package ru.astrainteractive.astratemplate.command.additem +package ru.astrainteractive.astratemplate.feature.command.additem import org.bukkit.inventory.ItemStack diff --git a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/command/common/CommonCommands.kt b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/common/CommonCommands.kt similarity index 54% rename from instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/command/common/CommonCommands.kt rename to modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/common/CommonCommands.kt index 060ddac..75a7928 100644 --- a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/command/common/CommonCommands.kt +++ b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/common/CommonCommands.kt @@ -1,4 +1,4 @@ -package ru.astrainteractive.astratemplate.command.common +package ru.astrainteractive.astratemplate.feature.command.common internal interface CommonCommands { data object Stub : CommonCommands diff --git a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/command/common/CommonCommandsRegistry.kt b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/common/CommonCommandsRegistry.kt similarity index 94% rename from instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/command/common/CommonCommandsRegistry.kt rename to modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/common/CommonCommandsRegistry.kt index fca9ef8..a432709 100644 --- a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/command/common/CommonCommandsRegistry.kt +++ b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/common/CommonCommandsRegistry.kt @@ -1,4 +1,4 @@ -package ru.astrainteractive.astratemplate.command.common +package ru.astrainteractive.astratemplate.feature.command.common import com.mojang.brigadier.tree.LiteralCommandNode import io.papermc.paper.command.brigadier.CommandSourceStack diff --git a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/command/damage/DamageCommandRegistry.kt b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/damage/DamageCommandRegistry.kt similarity index 93% rename from instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/command/damage/DamageCommandRegistry.kt rename to modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/damage/DamageCommandRegistry.kt index 8653fb9..06a0d7f 100644 --- a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/command/damage/DamageCommandRegistry.kt +++ b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/damage/DamageCommandRegistry.kt @@ -1,4 +1,4 @@ -package ru.astrainteractive.astratemplate.command.damage +package ru.astrainteractive.astratemplate.feature.command.damage import com.mojang.brigadier.arguments.DoubleArgumentType import com.mojang.brigadier.arguments.StringArgumentType @@ -13,11 +13,10 @@ import ru.astrainteractive.astralibs.command.api.util.requirePermission import ru.astrainteractive.astralibs.command.api.util.runs import ru.astrainteractive.astralibs.kyori.KyoriComponentSerializer import ru.astrainteractive.astralibs.kyori.unwrap -import ru.astrainteractive.astratemplate.command.errorhandler.DefaultErrorHandler +import ru.astrainteractive.astratemplate.feature.command.errorhandler.DefaultErrorHandler import ru.astrainteractive.astratemplate.core.plugin.PluginPermission import ru.astrainteractive.astratemplate.core.plugin.PluginTranslation import ru.astrainteractive.klibs.kstorage.api.CachedKrate -import ru.astrainteractive.klibs.kstorage.util.getValue internal class DamageCommandRegistry( translationKrate: CachedKrate, diff --git a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/command/di/CommandModule.kt b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/di/CommandModule.kt similarity index 76% rename from instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/command/di/CommandModule.kt rename to modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/di/CommandModule.kt index 1eb3906..619d2e6 100644 --- a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/command/di/CommandModule.kt +++ b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/di/CommandModule.kt @@ -1,16 +1,16 @@ -package ru.astrainteractive.astratemplate.command.di +package ru.astrainteractive.astratemplate.feature.command.di import ru.astrainteractive.astralibs.command.api.registrar.PaperCommandRegistrarContext import ru.astrainteractive.astralibs.lifecycle.Lifecycle import ru.astrainteractive.astratemplate.api.remote.di.ApiRemoteModule -import ru.astrainteractive.astratemplate.command.additem.AddItemCommandRegistry -import ru.astrainteractive.astratemplate.command.additem.AddItemExecutor -import ru.astrainteractive.astratemplate.command.common.CommonCommandsRegistry -import ru.astrainteractive.astratemplate.command.damage.DamageCommandRegistry -import ru.astrainteractive.astratemplate.command.errorhandler.DefaultErrorHandler -import ru.astrainteractive.astratemplate.command.gui.GuiCommandRegistry -import ru.astrainteractive.astratemplate.command.reload.ReloadCommandRegistry -import ru.astrainteractive.astratemplate.command.rickmorty.RickMortyCommandRegistrar +import ru.astrainteractive.astratemplate.feature.command.additem.AddItemCommandRegistry +import ru.astrainteractive.astratemplate.feature.command.additem.AddItemExecutor +import ru.astrainteractive.astratemplate.feature.command.common.CommonCommandsRegistry +import ru.astrainteractive.astratemplate.feature.command.damage.DamageCommandRegistry +import ru.astrainteractive.astratemplate.feature.command.errorhandler.DefaultErrorHandler +import ru.astrainteractive.astratemplate.feature.command.gui.GuiCommandRegistry +import ru.astrainteractive.astratemplate.feature.command.reload.ReloadCommandRegistry +import ru.astrainteractive.astratemplate.feature.command.rickmorty.RickMortyCommandRegistrar import ru.astrainteractive.astratemplate.core.di.CoreModule import ru.astrainteractive.astratemplate.di.BukkitModule import ru.astrainteractive.astratemplate.gui.di.GuiModule diff --git a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/command/errorhandler/DefaultErrorHandler.kt b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/errorhandler/DefaultErrorHandler.kt similarity index 92% rename from instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/command/errorhandler/DefaultErrorHandler.kt rename to modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/errorhandler/DefaultErrorHandler.kt index f7a2365..4a076db 100644 --- a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/command/errorhandler/DefaultErrorHandler.kt +++ b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/errorhandler/DefaultErrorHandler.kt @@ -1,4 +1,4 @@ -package ru.astrainteractive.astratemplate.command.errorhandler +package ru.astrainteractive.astratemplate.feature.command.errorhandler import com.mojang.brigadier.context.CommandContext import io.papermc.paper.command.brigadier.CommandSourceStack @@ -9,10 +9,9 @@ import ru.astrainteractive.astralibs.command.api.exception.NoPlayerException import ru.astrainteractive.astralibs.command.api.exception.NoPotionEffectTypeException import ru.astrainteractive.astralibs.kyori.KyoriComponentSerializer import ru.astrainteractive.astralibs.kyori.unwrap -import ru.astrainteractive.astratemplate.command.additem.AddItemCommand +import ru.astrainteractive.astratemplate.feature.command.additem.AddItemCommand import ru.astrainteractive.astratemplate.core.plugin.PluginTranslation import ru.astrainteractive.klibs.kstorage.api.CachedKrate -import ru.astrainteractive.klibs.kstorage.util.getValue import ru.astrainteractive.klibs.mikro.core.logging.JUtiltLogger import ru.astrainteractive.klibs.mikro.core.logging.Logger diff --git a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/command/gui/GuiCommandRegistry.kt b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/gui/GuiCommandRegistry.kt similarity index 87% rename from instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/command/gui/GuiCommandRegistry.kt rename to modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/gui/GuiCommandRegistry.kt index b32411e..6c6a1c9 100644 --- a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/command/gui/GuiCommandRegistry.kt +++ b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/gui/GuiCommandRegistry.kt @@ -1,4 +1,4 @@ -package ru.astrainteractive.astratemplate.command.gui +package ru.astrainteractive.astratemplate.feature.command.gui import com.mojang.brigadier.tree.LiteralCommandNode import io.papermc.paper.command.brigadier.CommandSourceStack @@ -7,7 +7,7 @@ import ru.astrainteractive.astralibs.command.api.util.requirePlayer import ru.astrainteractive.astralibs.command.api.util.runs import ru.astrainteractive.astralibs.kyori.KyoriComponentSerializer import ru.astrainteractive.astralibs.kyori.unwrap -import ru.astrainteractive.astratemplate.command.errorhandler.DefaultErrorHandler +import ru.astrainteractive.astratemplate.feature.command.errorhandler.DefaultErrorHandler import ru.astrainteractive.astratemplate.gui.router.Router import ru.astrainteractive.klibs.kstorage.api.CachedKrate diff --git a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/command/reload/ReloadCommandRegistry.kt b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/reload/ReloadCommandRegistry.kt similarity index 88% rename from instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/command/reload/ReloadCommandRegistry.kt rename to modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/reload/ReloadCommandRegistry.kt index 19b65c9..e78ba0c 100644 --- a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/command/reload/ReloadCommandRegistry.kt +++ b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/reload/ReloadCommandRegistry.kt @@ -1,4 +1,4 @@ -package ru.astrainteractive.astratemplate.command.reload +package ru.astrainteractive.astratemplate.feature.command.reload import com.mojang.brigadier.tree.LiteralCommandNode import io.papermc.paper.command.brigadier.CommandSourceStack @@ -8,11 +8,10 @@ import ru.astrainteractive.astralibs.command.api.util.runs import ru.astrainteractive.astralibs.kyori.KyoriComponentSerializer import ru.astrainteractive.astralibs.kyori.unwrap import ru.astrainteractive.astralibs.lifecycle.LifecyclePlugin -import ru.astrainteractive.astratemplate.command.errorhandler.DefaultErrorHandler +import ru.astrainteractive.astratemplate.feature.command.errorhandler.DefaultErrorHandler import ru.astrainteractive.astratemplate.core.plugin.PluginPermission import ru.astrainteractive.astratemplate.core.plugin.PluginTranslation import ru.astrainteractive.klibs.kstorage.api.CachedKrate -import ru.astrainteractive.klibs.kstorage.util.getValue internal class ReloadCommandRegistry( translationKrate: CachedKrate, diff --git a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/command/rickmorty/RickMortyCommandRegistrar.kt b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/rickmorty/RickMortyCommandRegistrar.kt similarity index 93% rename from instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/command/rickmorty/RickMortyCommandRegistrar.kt rename to modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/rickmorty/RickMortyCommandRegistrar.kt index 9adeec0..9a63596 100644 --- a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/command/rickmorty/RickMortyCommandRegistrar.kt +++ b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/rickmorty/RickMortyCommandRegistrar.kt @@ -1,4 +1,4 @@ -package ru.astrainteractive.astratemplate.command.rickmorty +package ru.astrainteractive.astratemplate.feature.command.rickmorty import com.mojang.brigadier.arguments.IntegerArgumentType import com.mojang.brigadier.tree.LiteralCommandNode @@ -12,7 +12,7 @@ import ru.astrainteractive.astralibs.command.api.util.literal import ru.astrainteractive.astralibs.command.api.util.requireArgument import ru.astrainteractive.astralibs.command.api.util.runs import ru.astrainteractive.astratemplate.api.remote.api.RickMortyApi -import ru.astrainteractive.astratemplate.command.errorhandler.DefaultErrorHandler +import ru.astrainteractive.astratemplate.feature.command.errorhandler.DefaultErrorHandler import ru.astrainteractive.klibs.mikro.core.dispatchers.KotlinDispatchers import kotlin.random.Random diff --git a/settings.gradle.kts b/settings.gradle.kts index 42a24f8..dfc25ac 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -59,3 +59,4 @@ include("modules:api:remote") include("modules:api:local") include("modules:core") include("modules:build-konfig") +include("modules:feature-command") From b84bb3775d9b513ea5c347022873db1814266505 Mon Sep 17 00:00:00 2001 From: Roman Makeev Date: Sat, 30 May 2026 20:18:50 +0300 Subject: [PATCH 03/16] [REFACTOR] Move menu module --- instances/bukkit/build.gradle.kts | 2 + .../astratemplate/di/BukkitModule.kt | 13 ---- .../astratemplate/di/RootModule.kt | 2 +- .../astratemplate/gui/router/Router.kt | 11 ---- .../astratemplate/gui/router/RouterImpl.kt | 49 --------------- .../astratemplate/core/di/CoreModule.kt | 6 ++ modules/feature-gui/api/build.gradle.kts | 10 +++ .../feature/gui/router/Router.kt | 11 ++++ modules/feature-gui/bukkit/build.gradle.kts | 24 +++++++ .../feature}/gui/api/ItemStackSpigotAPI.kt | 2 +- .../feature}/gui/di/GuiModule.kt | 16 +++-- .../gui/domain/GetRandomColorUseCase.kt | 4 +- .../gui/domain/SetDisplayNameUseCase.kt | 6 +- .../feature/gui/router/RouterImpl.kt | 62 +++++++++++++++++++ .../feature/DefaultSampleGUIComponent.kt | 12 ++-- .../gui/sample/feature/SampleGuiComponent.kt | 2 +- .../feature}/gui/sample/gui/SampleGUI.kt | 29 ++++----- settings.gradle.kts | 2 + 18 files changed, 150 insertions(+), 113 deletions(-) delete mode 100644 instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/di/BukkitModule.kt delete mode 100644 instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/gui/router/Router.kt delete mode 100644 instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/gui/router/RouterImpl.kt create mode 100644 modules/feature-gui/api/build.gradle.kts create mode 100644 modules/feature-gui/api/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/router/Router.kt create mode 100644 modules/feature-gui/bukkit/build.gradle.kts rename {instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate => modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature}/gui/api/ItemStackSpigotAPI.kt (87%) rename {instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate => modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature}/gui/di/GuiModule.kt (57%) rename {instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate => modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature}/gui/domain/GetRandomColorUseCase.kt (70%) rename {instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate => modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature}/gui/domain/SetDisplayNameUseCase.kt (77%) create mode 100644 modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/router/RouterImpl.kt rename {instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate => modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature}/gui/sample/feature/DefaultSampleGUIComponent.kt (90%) rename {instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate => modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature}/gui/sample/feature/SampleGuiComponent.kt (91%) rename {instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate => modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature}/gui/sample/gui/SampleGUI.kt (83%) diff --git a/instances/bukkit/build.gradle.kts b/instances/bukkit/build.gradle.kts index 7497468..9bad7a6 100644 --- a/instances/bukkit/build.gradle.kts +++ b/instances/bukkit/build.gradle.kts @@ -38,6 +38,8 @@ dependencies { shadow(projects.modules.buildKonfig) shadow(projects.modules.core) shadow(projects.modules.featureCommand) + shadow(projects.modules.featureGui.api) + shadow(projects.modules.featureGui.bukkit) testImplementation(libs.tests.kotlin.test) } diff --git a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/di/BukkitModule.kt b/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/di/BukkitModule.kt deleted file mode 100644 index 902dcea..0000000 --- a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/di/BukkitModule.kt +++ /dev/null @@ -1,13 +0,0 @@ -package ru.astrainteractive.astratemplate.di - -import ru.astrainteractive.astralibs.kyori.KyoriComponentSerializer -import ru.astrainteractive.astratemplate.AstraTemplate -import ru.astrainteractive.klibs.kstorage.api.impl.DefaultMutableKrate -import ru.astrainteractive.klibs.kstorage.util.asCachedKrate - -class BukkitModule(val plugin: AstraTemplate) { - val kyoriKrate = DefaultMutableKrate( - loader = { null }, - factory = { KyoriComponentSerializer.Legacy } - ).asCachedKrate() -} diff --git a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt b/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt index 02f06f8..c3aa04b 100644 --- a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt +++ b/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt @@ -8,7 +8,7 @@ import ru.astrainteractive.astratemplate.api.remote.di.ApiRemoteModule import ru.astrainteractive.astratemplate.feature.command.di.CommandModule import ru.astrainteractive.astratemplate.core.di.CoreModule import ru.astrainteractive.astratemplate.event.di.EventModule -import ru.astrainteractive.astratemplate.gui.di.GuiModule +import ru.astrainteractive.astratemplate.feature.gui.di.GuiModule internal class RootModule(plugin: AstraTemplate) { diff --git a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/gui/router/Router.kt b/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/gui/router/Router.kt deleted file mode 100644 index 83f0045..0000000 --- a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/gui/router/Router.kt +++ /dev/null @@ -1,11 +0,0 @@ -package ru.astrainteractive.astratemplate.gui.router - -import org.bukkit.entity.Player - -internal interface Router { - sealed interface Route { - data object Sample : Route - } - - fun open(player: Player, route: Route) -} diff --git a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/gui/router/RouterImpl.kt b/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/gui/router/RouterImpl.kt deleted file mode 100644 index 3e1d45f..0000000 --- a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/gui/router/RouterImpl.kt +++ /dev/null @@ -1,49 +0,0 @@ -package ru.astrainteractive.astratemplate.gui.router - -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import org.bukkit.entity.Player -import ru.astrainteractive.astralibs.kyori.KyoriComponentSerializer -import ru.astrainteractive.astratemplate.api.local.dao.LocalDao -import ru.astrainteractive.astratemplate.core.plugin.PluginTranslation -import ru.astrainteractive.astratemplate.gui.api.ItemStackSpigotAPI -import ru.astrainteractive.astratemplate.gui.domain.GetRandomColorUseCase -import ru.astrainteractive.astratemplate.gui.domain.SetDisplayNameUseCase -import ru.astrainteractive.astratemplate.gui.sample.feature.DefaultSampleGUIComponent -import ru.astrainteractive.astratemplate.gui.sample.gui.SampleGUI -import ru.astrainteractive.klibs.kstorage.api.CachedKrate -import ru.astrainteractive.klibs.mikro.core.dispatchers.KotlinDispatchers - -@Suppress("LongParameterList") -internal class RouterImpl( - private val ioScope: CoroutineScope, - private val dispatchers: KotlinDispatchers, - private val kyoriKrate: CachedKrate, - private val translationKrate: CachedKrate, - private val localDao: LocalDao, - private val itemStackSpigotAPi: ItemStackSpigotAPI, - private val getRandomColorUseCase: GetRandomColorUseCase, - private val setDisplayNameUseCase: SetDisplayNameUseCase -) : Router { - private fun buildRoute(player: Player, route: Router.Route) = when (route) { - Router.Route.Sample -> SampleGUI( - player = player, - kyoriKrate = kyoriKrate, - translationKrate = translationKrate, - sampleComponent = DefaultSampleGUIComponent( - localDao = localDao, - itemStackSpigotAPi = itemStackSpigotAPi, - getRandomColorUseCase = getRandomColorUseCase, - setDisplayNameUseCase = setDisplayNameUseCase - ) - ) - } - - override fun open(player: Player, route: Router.Route) { - ioScope.launch { - val gui = buildRoute(player, route) - withContext(dispatchers.Main) { gui.open() } - } - } -} diff --git a/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/di/CoreModule.kt b/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/di/CoreModule.kt index 1c02395..16cee0f 100644 --- a/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/di/CoreModule.kt +++ b/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/di/CoreModule.kt @@ -9,6 +9,7 @@ import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.cancel import kotlinx.serialization.StringFormat import ru.astrainteractive.astralibs.coroutines.withTimings +import ru.astrainteractive.astralibs.kyori.KyoriComponentSerializer import ru.astrainteractive.astralibs.lifecycle.Lifecycle import ru.astrainteractive.astralibs.util.YamlStringFormat import ru.astrainteractive.astralibs.util.parseOrWriteIntoDefault @@ -70,6 +71,11 @@ class CoreModule( } ).asStateFlowKrate() + val kyoriKrate = DefaultMutableKrate( + loader = { null }, + factory = { KyoriComponentSerializer.Legacy } + ).asCachedKrate() + val lifecycle: Lifecycle by lazy { Lifecycle.Lambda( onReload = { diff --git a/modules/feature-gui/api/build.gradle.kts b/modules/feature-gui/api/build.gradle.kts new file mode 100644 index 0000000..4f690ff --- /dev/null +++ b/modules/feature-gui/api/build.gradle.kts @@ -0,0 +1,10 @@ +plugins { + id("org.jetbrains.kotlin.jvm") + id("org.jetbrains.kotlin.plugin.serialization") + id("ru.astrainteractive.gradleplugin.detekt") + id("ru.astrainteractive.gradleplugin.java.version") +} + +dependencies { + implementation(libs.minecraft.astralibs.core) +} \ No newline at end of file diff --git a/modules/feature-gui/api/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/router/Router.kt b/modules/feature-gui/api/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/router/Router.kt new file mode 100644 index 0000000..f715707 --- /dev/null +++ b/modules/feature-gui/api/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/router/Router.kt @@ -0,0 +1,11 @@ +package ru.astrainteractive.astratemplate.feature.gui.router + +import ru.astrainteractive.astralibs.server.player.OnlineKPlayer + +interface Router { + sealed interface Route { + data object Sample : Route + } + + fun open(player: OnlineKPlayer, route: Route) +} \ No newline at end of file diff --git a/modules/feature-gui/bukkit/build.gradle.kts b/modules/feature-gui/bukkit/build.gradle.kts new file mode 100644 index 0000000..e23aeaa --- /dev/null +++ b/modules/feature-gui/bukkit/build.gradle.kts @@ -0,0 +1,24 @@ +plugins { + id("org.jetbrains.kotlin.jvm") + id("org.jetbrains.kotlin.plugin.serialization") + id("ru.astrainteractive.gradleplugin.detekt") + id("ru.astrainteractive.gradleplugin.java.version") +} + +dependencies { + compileOnly(libs.minecraft.paper.api) + compileOnly(libs.minecraft.vaultapi) + + implementation(libs.klibs.kstorage) + implementation(libs.klibs.mikro.core) + implementation(libs.klibs.mikro.extensions) + implementation(libs.kotlin.coroutines.core) + implementation(libs.kotlin.serialization.json) + implementation(libs.minecraft.astralibs.menu.bukkit) + implementation(libs.minecraft.astralibs.core) + implementation(libs.minecraft.astralibs.core.bukkit) + + implementation(projects.modules.featureGui.api) + implementation(projects.modules.core) + implementation(projects.modules.api.local) +} diff --git a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/gui/api/ItemStackSpigotAPI.kt b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/api/ItemStackSpigotAPI.kt similarity index 87% rename from instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/gui/api/ItemStackSpigotAPI.kt rename to modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/api/ItemStackSpigotAPI.kt index 759f282..48cc2a7 100644 --- a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/gui/api/ItemStackSpigotAPI.kt +++ b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/api/ItemStackSpigotAPI.kt @@ -1,4 +1,4 @@ -package ru.astrainteractive.astratemplate.gui.api +package ru.astrainteractive.astratemplate.feature.gui.api import org.bukkit.Material import org.bukkit.inventory.ItemStack diff --git a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/gui/di/GuiModule.kt b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/di/GuiModule.kt similarity index 57% rename from instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/gui/di/GuiModule.kt rename to modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/di/GuiModule.kt index a2383ad..24ed884 100644 --- a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/gui/di/GuiModule.kt +++ b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/di/GuiModule.kt @@ -1,24 +1,22 @@ -package ru.astrainteractive.astratemplate.gui.di +package ru.astrainteractive.astratemplate.feature.gui.di import ru.astrainteractive.astratemplate.api.local.di.ApiLocalModule import ru.astrainteractive.astratemplate.core.di.CoreModule -import ru.astrainteractive.astratemplate.di.BukkitModule -import ru.astrainteractive.astratemplate.gui.api.ItemStackSpigotAPI -import ru.astrainteractive.astratemplate.gui.domain.GetRandomColorUseCaseImpl -import ru.astrainteractive.astratemplate.gui.domain.SetDisplayNameUseCaseImpl -import ru.astrainteractive.astratemplate.gui.router.Router -import ru.astrainteractive.astratemplate.gui.router.RouterImpl +import ru.astrainteractive.astratemplate.feature.gui.api.ItemStackSpigotAPI +import ru.astrainteractive.astratemplate.feature.gui.domain.GetRandomColorUseCaseImpl +import ru.astrainteractive.astratemplate.feature.gui.domain.SetDisplayNameUseCaseImpl +import ru.astrainteractive.astratemplate.feature.gui.router.Router +import ru.astrainteractive.astratemplate.feature.gui.router.RouterImpl internal class GuiModule( coreModule: CoreModule, - bukkitModule: BukkitModule, apiLocalModule: ApiLocalModule ) { private val getRandomColorUseCase = GetRandomColorUseCaseImpl() val router: Router = RouterImpl( ioScope = coreModule.ioScope, dispatchers = coreModule.dispatchers, - kyoriKrate = bukkitModule.kyoriKrate, + kyoriKrate = coreModule.kyoriKrate, translationKrate = coreModule.translationKrate, localDao = apiLocalModule.localDao, itemStackSpigotAPi = ItemStackSpigotAPI, diff --git a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/gui/domain/GetRandomColorUseCase.kt b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/domain/GetRandomColorUseCase.kt similarity index 70% rename from instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/gui/domain/GetRandomColorUseCase.kt rename to modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/domain/GetRandomColorUseCase.kt index 4e34036..17b1f88 100644 --- a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/gui/domain/GetRandomColorUseCase.kt +++ b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/domain/GetRandomColorUseCase.kt @@ -1,7 +1,7 @@ -package ru.astrainteractive.astratemplate.gui.domain +package ru.astrainteractive.astratemplate.feature.gui.domain import org.bukkit.ChatColor -import ru.astrainteractive.astratemplate.gui.domain.GetRandomColorUseCase.Output +import ru.astrainteractive.astratemplate.feature.gui.domain.GetRandomColorUseCase.Output import kotlin.random.Random internal interface GetRandomColorUseCase { diff --git a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/gui/domain/SetDisplayNameUseCase.kt b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/domain/SetDisplayNameUseCase.kt similarity index 77% rename from instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/gui/domain/SetDisplayNameUseCase.kt rename to modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/domain/SetDisplayNameUseCase.kt index 2263f3d..c6990ba 100644 --- a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/gui/domain/SetDisplayNameUseCase.kt +++ b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/domain/SetDisplayNameUseCase.kt @@ -1,8 +1,8 @@ -package ru.astrainteractive.astratemplate.gui.domain +package ru.astrainteractive.astratemplate.feature.gui.domain import org.bukkit.inventory.ItemStack -import ru.astrainteractive.astratemplate.gui.domain.SetDisplayNameUseCase.Input -import ru.astrainteractive.astratemplate.gui.domain.SetDisplayNameUseCase.Output +import ru.astrainteractive.astratemplate.feature.gui.domain.SetDisplayNameUseCase.Input +import ru.astrainteractive.astratemplate.feature.gui.domain.SetDisplayNameUseCase.Output internal interface SetDisplayNameUseCase { class Input(val items: List, val index: Int) diff --git a/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/router/RouterImpl.kt b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/router/RouterImpl.kt new file mode 100644 index 0000000..a096bb6 --- /dev/null +++ b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/router/RouterImpl.kt @@ -0,0 +1,62 @@ +package ru.astrainteractive.astratemplate.feature.gui.router + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import org.bukkit.entity.Player +import org.bukkit.inventory.Inventory +import ru.astrainteractive.astralibs.kyori.KyoriComponentSerializer +import ru.astrainteractive.astralibs.server.player.BukkitOnlineKPlayer +import ru.astrainteractive.astralibs.server.player.OnlineKPlayer +import ru.astrainteractive.astratemplate.api.local.dao.LocalDao +import ru.astrainteractive.astratemplate.core.plugin.PluginTranslation +import ru.astrainteractive.astratemplate.feature.gui.api.ItemStackSpigotAPI +import ru.astrainteractive.astratemplate.feature.gui.domain.GetRandomColorUseCase +import ru.astrainteractive.astratemplate.feature.gui.domain.SetDisplayNameUseCase +import ru.astrainteractive.astratemplate.feature.gui.sample.feature.DefaultSampleGUIComponent +import ru.astrainteractive.astratemplate.feature.gui.sample.gui.SampleGUI +import ru.astrainteractive.klibs.kstorage.api.CachedKrate +import ru.astrainteractive.klibs.mikro.core.dispatchers.KotlinDispatchers +import ru.astrainteractive.klibs.mikro.core.logging.JUtiltLogger +import ru.astrainteractive.klibs.mikro.core.logging.Logger +import ru.astrainteractive.klibs.mikro.core.util.tryCast + +@Suppress("LongParameterList") +internal class RouterImpl( + private val ioScope: CoroutineScope, + private val dispatchers: KotlinDispatchers, + private val kyoriKrate: CachedKrate, + private val translationKrate: CachedKrate, + private val localDao: LocalDao, + private val itemStackSpigotAPi: ItemStackSpigotAPI, + private val getRandomColorUseCase: GetRandomColorUseCase, + private val setDisplayNameUseCase: SetDisplayNameUseCase +) : Router, Logger by JUtiltLogger("Router") { + private fun buildRoute(player: Player, route: Router.Route): Inventory { + return when (route) { + Router.Route.Sample -> SampleGUI( + player = player, + kyoriKrate = kyoriKrate, + translationKrate = translationKrate, + sampleComponent = DefaultSampleGUIComponent( + localDao = localDao, + itemStackSpigotAPi = itemStackSpigotAPi, + getRandomColorUseCase = getRandomColorUseCase, + setDisplayNameUseCase = setDisplayNameUseCase + ) + ).inventory + } + } + + override fun open(player: OnlineKPlayer, route: Router.Route) { + ioScope.launch { + val bukkitPlayer = player.tryCast()?.instance + if (bukkitPlayer == null) { + error { "#open Could not cast OnlineKPlayer to BukkitOnlineKPlayer" } + return@launch + } + val inventory = buildRoute(bukkitPlayer, route) + withContext(dispatchers.Main) { bukkitPlayer.openInventory(inventory) } + } + } +} diff --git a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/gui/sample/feature/DefaultSampleGUIComponent.kt b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/sample/feature/DefaultSampleGUIComponent.kt similarity index 90% rename from instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/gui/sample/feature/DefaultSampleGUIComponent.kt rename to modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/sample/feature/DefaultSampleGUIComponent.kt index 3ff7ca7..e623f69 100644 --- a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/gui/sample/feature/DefaultSampleGUIComponent.kt +++ b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/sample/feature/DefaultSampleGUIComponent.kt @@ -1,5 +1,6 @@ -package ru.astrainteractive.astratemplate.gui.sample.feature +package ru.astrainteractive.astratemplate.feature.gui.sample.feature +import kotlin.random.Random import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableStateFlow @@ -7,16 +8,15 @@ import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import org.bukkit.ChatColor import org.bukkit.event.inventory.ClickType -import ru.astrainteractive.astralibs.async.withTimings +import ru.astrainteractive.astralibs.coroutines.withTimings import ru.astrainteractive.astratemplate.api.local.dao.LocalDao import ru.astrainteractive.astratemplate.api.local.model.UserModel -import ru.astrainteractive.astratemplate.gui.api.ItemStackSpigotAPI -import ru.astrainteractive.astratemplate.gui.domain.GetRandomColorUseCase -import ru.astrainteractive.astratemplate.gui.domain.SetDisplayNameUseCase +import ru.astrainteractive.astratemplate.feature.gui.api.ItemStackSpigotAPI +import ru.astrainteractive.astratemplate.feature.gui.domain.GetRandomColorUseCase +import ru.astrainteractive.astratemplate.feature.gui.domain.SetDisplayNameUseCase import ru.astrainteractive.klibs.mikro.core.coroutines.CoroutineFeature import ru.astrainteractive.klibs.mikro.core.logging.JUtiltLogger import ru.astrainteractive.klibs.mikro.core.logging.Logger -import kotlin.random.Random /** * MVVM/MVI technique diff --git a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/gui/sample/feature/SampleGuiComponent.kt b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/sample/feature/SampleGuiComponent.kt similarity index 91% rename from instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/gui/sample/feature/SampleGuiComponent.kt rename to modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/sample/feature/SampleGuiComponent.kt index b49a715..b3bb307 100644 --- a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/gui/sample/feature/SampleGuiComponent.kt +++ b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/sample/feature/SampleGuiComponent.kt @@ -1,4 +1,4 @@ -package ru.astrainteractive.astratemplate.gui.sample.feature +package ru.astrainteractive.astratemplate.feature.gui.sample.feature import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.StateFlow diff --git a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/gui/sample/gui/SampleGUI.kt b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/sample/gui/SampleGUI.kt similarity index 83% rename from instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/gui/sample/gui/SampleGUI.kt rename to modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/sample/gui/SampleGUI.kt index bb10c67..ab340b0 100644 --- a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/gui/sample/gui/SampleGUI.kt +++ b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/sample/gui/SampleGUI.kt @@ -1,4 +1,4 @@ -package ru.astrainteractive.astratemplate.gui.sample.gui +package ru.astrainteractive.astratemplate.feature.gui.sample.gui import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.launchIn @@ -12,36 +12,31 @@ import ru.astrainteractive.astralibs.kyori.KyoriComponentSerializer import ru.astrainteractive.astralibs.kyori.unwrap import ru.astrainteractive.astralibs.menu.holder.DefaultPlayerHolder import ru.astrainteractive.astralibs.menu.holder.PlayerHolder -import ru.astrainteractive.astralibs.menu.inventory.PaginatedInventoryMenu +import ru.astrainteractive.astralibs.menu.inventory.api.InventoryMenu import ru.astrainteractive.astralibs.menu.inventory.model.InventorySize -import ru.astrainteractive.astralibs.menu.inventory.model.PageContext -import ru.astrainteractive.astralibs.menu.inventory.util.PageContextExt.getIndex -import ru.astrainteractive.astralibs.menu.inventory.util.PageContextExt.isLastPage -import ru.astrainteractive.astralibs.menu.inventory.util.PaginatedInventoryMenuExt.showNextPage -import ru.astrainteractive.astralibs.menu.inventory.util.PaginatedInventoryMenuExt.showPrevPage +import ru.astrainteractive.astralibs.menu.paginator.api.DefaultPaginator import ru.astrainteractive.astralibs.menu.slot.InventorySlot -import ru.astrainteractive.astralibs.menu.slot.util.InventorySlotBuilderExt.setDisplayName -import ru.astrainteractive.astralibs.menu.slot.util.InventorySlotBuilderExt.setIndex -import ru.astrainteractive.astralibs.menu.slot.util.InventorySlotBuilderExt.setItemStack -import ru.astrainteractive.astralibs.menu.slot.util.InventorySlotBuilderExt.setLore -import ru.astrainteractive.astralibs.menu.slot.util.InventorySlotBuilderExt.setMaterial -import ru.astrainteractive.astralibs.menu.slot.util.InventorySlotBuilderExt.setOnClickListener +import ru.astrainteractive.astralibs.menu.slot.setDisplayName +import ru.astrainteractive.astralibs.menu.slot.setIndex +import ru.astrainteractive.astralibs.menu.slot.setMaterial +import ru.astrainteractive.astralibs.menu.slot.setOnClickListener import ru.astrainteractive.astratemplate.api.local.model.UserModel import ru.astrainteractive.astratemplate.core.plugin.PluginTranslation -import ru.astrainteractive.astratemplate.gui.sample.feature.SampleGuiComponent +import ru.astrainteractive.astratemplate.feature.gui.sample.feature.SampleGuiComponent import ru.astrainteractive.klibs.kstorage.api.CachedKrate -import ru.astrainteractive.klibs.kstorage.util.getValue +import ru.astrainteractive.klibs.kstorage.api.getValue internal class SampleGUI( player: Player, kyoriKrate: CachedKrate, translationKrate: CachedKrate, private val sampleComponent: SampleGuiComponent -) : PaginatedInventoryMenu(), - KyoriComponentSerializer by kyoriKrate.unwrap() { +) : InventoryMenu(), + KyoriComponentSerializer by kyoriKrate.unwrap(), { override val childComponents: List get() = listOf(sampleComponent) private val translation by translationKrate + private val paginator = DefaultPaginator() override val playerHolder: PlayerHolder = DefaultPlayerHolder(player) override var title: Component = translation.menu.menuTitle.let(::toComponent) diff --git a/settings.gradle.kts b/settings.gradle.kts index dfc25ac..01bbde7 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -60,3 +60,5 @@ include("modules:api:local") include("modules:core") include("modules:build-konfig") include("modules:feature-command") +include("modules:feature-gui:api") +include("modules:feature-gui:bukkit") From 002694268dac33446855405fe709ad33129a955e Mon Sep 17 00:00:00 2001 From: Roman Makeev Date: Sat, 30 May 2026 20:22:20 +0300 Subject: [PATCH 04/16] [REFACTOR] Move event module --- instances/bukkit/build.gradle.kts | 1 + .../astratemplate/di/RootModule.kt | 2 +- .../astratemplate/event/di/EventModule.kt | 39 ------------------- .../event/event/MultipleEventsDSL.kt | 24 ------------ modules/feature-event/bukkit/build.gradle.kts | 24 ++++++++++++ .../feature/event/di/EventModule.kt | 38 ++++++++++++++++++ .../event/event/BetterAnotherEvent.kt | 5 ++- .../feature}/event/event/TemplateEvent.kt | 8 ++-- settings.gradle.kts | 1 + 9 files changed, 71 insertions(+), 71 deletions(-) delete mode 100644 instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/event/di/EventModule.kt delete mode 100644 instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/event/event/MultipleEventsDSL.kt create mode 100644 modules/feature-event/bukkit/build.gradle.kts create mode 100644 modules/feature-event/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/EventModule.kt rename {instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate => modules/feature-event/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature}/event/event/BetterAnotherEvent.kt (73%) rename {instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate => modules/feature-event/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature}/event/event/TemplateEvent.kt (84%) diff --git a/instances/bukkit/build.gradle.kts b/instances/bukkit/build.gradle.kts index 9bad7a6..4d9cc00 100644 --- a/instances/bukkit/build.gradle.kts +++ b/instances/bukkit/build.gradle.kts @@ -40,6 +40,7 @@ dependencies { shadow(projects.modules.featureCommand) shadow(projects.modules.featureGui.api) shadow(projects.modules.featureGui.bukkit) + shadow(projects.modules.featureEvent.bukkit) testImplementation(libs.tests.kotlin.test) } diff --git a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt b/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt index c3aa04b..c1588d6 100644 --- a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt +++ b/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt @@ -7,7 +7,7 @@ import ru.astrainteractive.astratemplate.api.local.di.ApiLocalModule import ru.astrainteractive.astratemplate.api.remote.di.ApiRemoteModule import ru.astrainteractive.astratemplate.feature.command.di.CommandModule import ru.astrainteractive.astratemplate.core.di.CoreModule -import ru.astrainteractive.astratemplate.event.di.EventModule +import ru.astrainteractive.astratemplate.feature.event.di.EventModule import ru.astrainteractive.astratemplate.feature.gui.di.GuiModule internal class RootModule(plugin: AstraTemplate) { diff --git a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/event/di/EventModule.kt b/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/event/di/EventModule.kt deleted file mode 100644 index 8138be0..0000000 --- a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/event/di/EventModule.kt +++ /dev/null @@ -1,39 +0,0 @@ -package ru.astrainteractive.astratemplate.event.di - -import org.bukkit.event.HandlerList -import ru.astrainteractive.astralibs.event.EventListener -import ru.astrainteractive.astralibs.lifecycle.Lifecycle -import ru.astrainteractive.astralibs.menu.event.DefaultInventoryClickEvent -import ru.astrainteractive.astratemplate.di.RootModule -import ru.astrainteractive.astratemplate.event.event.BetterAnotherEvent -import ru.astrainteractive.astratemplate.event.event.MultipleEventsDSL -import ru.astrainteractive.astratemplate.event.event.TemplateEvent - -internal class EventModule(rootModule: RootModule) { - val eventListener: EventListener = EventListener.Default() - val inventoryClickListener: EventListener = DefaultInventoryClickEvent() - - private val events = buildList { - eventListener.run(::add) - inventoryClickListener.run(::add) - TemplateEvent( - kyoriKrate = rootModule.bukkitModule.kyoriKrate, - translationKrate = rootModule.coreModule.translationKrate - ).run(::add) - BetterAnotherEvent().run(::add) - } - - val lifecycle: Lifecycle = Lifecycle.Lambda( - onEnable = { - events.forEach { it.onEnable(rootModule.bukkitModule.plugin) } - MultipleEventsDSL( - eventListener = eventListener, - plugin = rootModule.bukkitModule.plugin - ) - }, - onDisable = { - events.forEach(EventListener::onDisable) - HandlerList.unregisterAll(rootModule.bukkitModule.plugin) - } - ) -} diff --git a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/event/event/MultipleEventsDSL.kt b/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/event/event/MultipleEventsDSL.kt deleted file mode 100644 index fb67a75..0000000 --- a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/event/event/MultipleEventsDSL.kt +++ /dev/null @@ -1,24 +0,0 @@ -package ru.astrainteractive.astratemplate.event.event - -import org.bukkit.event.block.BlockBreakEvent -import org.bukkit.event.entity.EntityDamageEvent -import org.bukkit.plugin.java.JavaPlugin -import ru.astrainteractive.astralibs.event.EventListener -import ru.astrainteractive.astralibs.event.inlineEvent - -/** - * This is a most convenient way to use bukkit events in kotlin - */ -internal class MultipleEventsDSL( - eventListener: EventListener, - plugin: JavaPlugin -) { - - val blockBreakEvent = inlineEvent(eventListener, plugin) { - println("DSLEvent: blockBreakEvent ${it.player.name}") - } - - val entityDamageEvent = inlineEvent(eventListener, plugin) { - println("DSLEvent: entityDamageEvent ${it.entity.name}") - } -} diff --git a/modules/feature-event/bukkit/build.gradle.kts b/modules/feature-event/bukkit/build.gradle.kts new file mode 100644 index 0000000..e23aeaa --- /dev/null +++ b/modules/feature-event/bukkit/build.gradle.kts @@ -0,0 +1,24 @@ +plugins { + id("org.jetbrains.kotlin.jvm") + id("org.jetbrains.kotlin.plugin.serialization") + id("ru.astrainteractive.gradleplugin.detekt") + id("ru.astrainteractive.gradleplugin.java.version") +} + +dependencies { + compileOnly(libs.minecraft.paper.api) + compileOnly(libs.minecraft.vaultapi) + + implementation(libs.klibs.kstorage) + implementation(libs.klibs.mikro.core) + implementation(libs.klibs.mikro.extensions) + implementation(libs.kotlin.coroutines.core) + implementation(libs.kotlin.serialization.json) + implementation(libs.minecraft.astralibs.menu.bukkit) + implementation(libs.minecraft.astralibs.core) + implementation(libs.minecraft.astralibs.core.bukkit) + + implementation(projects.modules.featureGui.api) + implementation(projects.modules.core) + implementation(projects.modules.api.local) +} diff --git a/modules/feature-event/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/EventModule.kt b/modules/feature-event/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/EventModule.kt new file mode 100644 index 0000000..36be009 --- /dev/null +++ b/modules/feature-event/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/EventModule.kt @@ -0,0 +1,38 @@ +package ru.astrainteractive.astratemplate.feature.event.di + +import org.bukkit.event.HandlerList +import org.bukkit.plugin.java.JavaPlugin +import ru.astrainteractive.astralibs.event.EventListener +import ru.astrainteractive.astralibs.lifecycle.Lifecycle +import ru.astrainteractive.astralibs.menu.event.DefaultInventoryClickEvent +import ru.astrainteractive.astratemplate.core.di.CoreModule +import ru.astrainteractive.astratemplate.feature.event.event.BetterAnotherEvent +import ru.astrainteractive.astratemplate.feature.event.event.TemplateEvent + +internal class EventModule( + coreModule: CoreModule, + plugin: JavaPlugin +) { + val eventListener: EventListener = EventListener.Default() + val inventoryClickListener: EventListener = DefaultInventoryClickEvent() + + private val events = buildList { + eventListener.run(::add) + inventoryClickListener.run(::add) + TemplateEvent( + kyoriKrate = coreModule.kyoriKrate, + translationKrate = coreModule.translationKrate + ).run(::add) + BetterAnotherEvent().run(::add) + } + + val lifecycle: Lifecycle = Lifecycle.Lambda( + onEnable = { + events.forEach { listener -> listener.onEnable(plugin) } + }, + onDisable = { + events.forEach(EventListener::onDisable) + HandlerList.unregisterAll(plugin) + } + ) +} diff --git a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/event/event/BetterAnotherEvent.kt b/modules/feature-event/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/event/BetterAnotherEvent.kt similarity index 73% rename from instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/event/event/BetterAnotherEvent.kt rename to modules/feature-event/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/event/BetterAnotherEvent.kt index 2c1b995..a7e306b 100644 --- a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/event/event/BetterAnotherEvent.kt +++ b/modules/feature-event/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/event/BetterAnotherEvent.kt @@ -1,5 +1,6 @@ -package ru.astrainteractive.astratemplate.event.event +package ru.astrainteractive.astratemplate.feature.event.event +import org.bukkit.event.EventHandler import org.bukkit.event.block.BlockBreakEvent import ru.astrainteractive.astralibs.event.EventListener @@ -7,7 +8,7 @@ import ru.astrainteractive.astralibs.event.EventListener * This is a more convenient way with base class */ internal class BetterAnotherEvent : EventListener { - @org.bukkit.event.EventHandler + @EventHandler fun blockBreakEvent(e: BlockBreakEvent) { println("blockBreakEvent ${e.player.name}") } diff --git a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/event/event/TemplateEvent.kt b/modules/feature-event/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/event/TemplateEvent.kt similarity index 84% rename from instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/event/event/TemplateEvent.kt rename to modules/feature-event/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/event/TemplateEvent.kt index f4cd935..dc72060 100644 --- a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/event/event/TemplateEvent.kt +++ b/modules/feature-event/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/event/TemplateEvent.kt @@ -1,4 +1,4 @@ -package ru.astrainteractive.astratemplate.event.event +package ru.astrainteractive.astratemplate.feature.event.event import org.bukkit.event.EventHandler import org.bukkit.event.HandlerList @@ -6,14 +6,12 @@ import org.bukkit.event.block.BlockPlaceEvent import ru.astrainteractive.astralibs.event.EventListener import ru.astrainteractive.astralibs.kyori.KyoriComponentSerializer import ru.astrainteractive.astralibs.kyori.unwrap -import ru.astrainteractive.astratemplate.AstraTemplate import ru.astrainteractive.astratemplate.core.plugin.PluginTranslation import ru.astrainteractive.klibs.kstorage.api.CachedKrate -import ru.astrainteractive.klibs.kstorage.util.getValue +import ru.astrainteractive.klibs.kstorage.api.getValue /** * Template event class - * @see [MultipleEventsDSL] */ internal class TemplateEvent( kyoriKrate: CachedKrate, @@ -34,7 +32,7 @@ internal class TemplateEvent( /** * As said in EventHandler, every Event must have onDisable method, which disabling events * Here BlockPlaceEvent is unregistering - * It's okay to not write anything here, since you call [HandlerList.unregister] in [AstraTemplate.onDisable] + * It's okay to not write anything here, since you call [HandlerList.unregister] in [ru.astrainteractive.astralibs.lifecycle.Lifecycle.onDisable] */ public override fun onDisable() { super.onDisable() diff --git a/settings.gradle.kts b/settings.gradle.kts index 01bbde7..56d0dde 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -62,3 +62,4 @@ include("modules:build-konfig") include("modules:feature-command") include("modules:feature-gui:api") include("modules:feature-gui:bukkit") +include("modules:feature-event:bukkit") From ee36e1ba66a82dfe895753483581073d1aae26ae Mon Sep 17 00:00:00 2001 From: Roman Makeev Date: Sat, 30 May 2026 20:23:48 +0300 Subject: [PATCH 05/16] [REFACTOR] Clear bukkit instance module --- .../ru/astrainteractive/astratemplate/di/RootModule.kt | 8 ++------ instances/bukkit/src/main/resources/plugin.yml | 6 +++--- .../astratemplate/feature/command/di/CommandModule.kt | 3 +-- .../astratemplate/feature/event/di/EventModule.kt | 2 +- .../astratemplate/feature/gui/di/GuiModule.kt | 2 +- 5 files changed, 8 insertions(+), 13 deletions(-) diff --git a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt b/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt index c1588d6..1068722 100644 --- a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt +++ b/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt @@ -12,10 +12,8 @@ import ru.astrainteractive.astratemplate.feature.gui.di.GuiModule internal class RootModule(plugin: AstraTemplate) { - val bukkitModule: BukkitModule = BukkitModule(plugin) - val coreModule: CoreModule = CoreModule( - dataFolder = bukkitModule.plugin.dataFolder, + dataFolder = plugin.dataFolder, dispatchers = DefaultBukkitDispatchers(plugin) ) @@ -26,15 +24,13 @@ internal class RootModule(plugin: AstraTemplate) { val apiRemoteModule: ApiRemoteModule = ApiRemoteModule() - val eventModule: EventModule = EventModule(this) + val eventModule: EventModule = EventModule(coreModule, plugin) val guiModule: GuiModule = GuiModule( coreModule = coreModule, - bukkitModule = bukkitModule, apiLocalModule = apiLocalModule ) val commandModule: CommandModule = CommandModule( coreModule = coreModule, - bukkitModule = bukkitModule, apiRemoteModule = apiRemoteModule, guiModule = guiModule ) diff --git a/instances/bukkit/src/main/resources/plugin.yml b/instances/bukkit/src/main/resources/plugin.yml index e9a683e..189b985 100644 --- a/instances/bukkit/src/main/resources/plugin.yml +++ b/instances/bukkit/src/main/resources/plugin.yml @@ -4,12 +4,12 @@ description: '${description}' name: '${name}' version: '${version}' authors: [ "${authors}" ] -#author: "${author}" +author: "${author}" website: "${url}" api-version: 1.18 -softdepend: [ ] +softdepend: [ DiscordSRV, LuckPerms, Vault, Esssentials, Towny, PlaceholderAPI, packetevents ] depend: [ ] -loadbefore: [ ] +loadbefore: [ Towny ] libraries: ${libraries} commands: add: diff --git a/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/di/CommandModule.kt b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/di/CommandModule.kt index 619d2e6..d948871 100644 --- a/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/di/CommandModule.kt +++ b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/di/CommandModule.kt @@ -15,9 +15,8 @@ import ru.astrainteractive.astratemplate.core.di.CoreModule import ru.astrainteractive.astratemplate.di.BukkitModule import ru.astrainteractive.astratemplate.gui.di.GuiModule -internal class CommandModule( +class CommandModule( coreModule: CoreModule, - bukkitModule: BukkitModule, guiModule: GuiModule, apiRemoteModule: ApiRemoteModule, ) { diff --git a/modules/feature-event/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/EventModule.kt b/modules/feature-event/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/EventModule.kt index 36be009..ed4fcc2 100644 --- a/modules/feature-event/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/EventModule.kt +++ b/modules/feature-event/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/EventModule.kt @@ -9,7 +9,7 @@ import ru.astrainteractive.astratemplate.core.di.CoreModule import ru.astrainteractive.astratemplate.feature.event.event.BetterAnotherEvent import ru.astrainteractive.astratemplate.feature.event.event.TemplateEvent -internal class EventModule( +class EventModule( coreModule: CoreModule, plugin: JavaPlugin ) { diff --git a/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/di/GuiModule.kt b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/di/GuiModule.kt index 24ed884..5569a8c 100644 --- a/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/di/GuiModule.kt +++ b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/di/GuiModule.kt @@ -8,7 +8,7 @@ import ru.astrainteractive.astratemplate.feature.gui.domain.SetDisplayNameUseCas import ru.astrainteractive.astratemplate.feature.gui.router.Router import ru.astrainteractive.astratemplate.feature.gui.router.RouterImpl -internal class GuiModule( +class GuiModule( coreModule: CoreModule, apiLocalModule: ApiLocalModule ) { From 2f069013077b783bffcf701fe7e766e281d4f690 Mon Sep 17 00:00:00 2001 From: Roman Makeev Date: Sat, 30 May 2026 20:29:30 +0300 Subject: [PATCH 06/16] [REFACTOR] Add forge event into events --- .../astratemplate/command/di/CommandModule.kt | 19 -------- .../helloworld/HelloCommandRegistrar.kt | 18 -------- .../astratemplate/ForgeEntryPoint.kt | 0 .../astratemplate/di/RootModule.kt | 0 modules/feature-event/forge/build.gradle.kts | 44 +++++++++++++++++++ .../feature/event/di}/di/EventModule.kt | 4 +- .../feature/event/di}/event/TickEvent.kt | 13 +++--- settings.gradle.kts | 1 + 8 files changed, 52 insertions(+), 47 deletions(-) delete mode 100644 instances/forge/src/main/java/ru/astrainteractive/astratemplate/command/di/CommandModule.kt delete mode 100644 instances/forge/src/main/java/ru/astrainteractive/astratemplate/command/helloworld/HelloCommandRegistrar.kt rename instances/forge/src/main/{java => kotlin}/ru/astrainteractive/astratemplate/ForgeEntryPoint.kt (100%) rename instances/forge/src/main/{java => kotlin}/ru/astrainteractive/astratemplate/di/RootModule.kt (100%) create mode 100644 modules/feature-event/forge/build.gradle.kts rename {instances/forge/src/main/java/ru/astrainteractive/astratemplate/event => modules/feature-event/forge/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di}/di/EventModule.kt (69%) rename {instances/forge/src/main/java/ru/astrainteractive/astratemplate => modules/feature-event/forge/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di}/event/TickEvent.kt (50%) diff --git a/instances/forge/src/main/java/ru/astrainteractive/astratemplate/command/di/CommandModule.kt b/instances/forge/src/main/java/ru/astrainteractive/astratemplate/command/di/CommandModule.kt deleted file mode 100644 index 9c0bb86..0000000 --- a/instances/forge/src/main/java/ru/astrainteractive/astratemplate/command/di/CommandModule.kt +++ /dev/null @@ -1,19 +0,0 @@ -package ru.astrainteractive.astratemplate.command.di - -import ru.astrainteractive.astralibs.command.registrar.ForgeCommandRegistrarContext -import ru.astrainteractive.astralibs.lifecycle.Lifecycle -import ru.astrainteractive.astratemplate.command.helloworld.HelloCommandRegistrar - -class CommandModule( - private val commandRegistrarContext: ForgeCommandRegistrarContext -) { - private val nodes = buildList { - HelloCommandRegistrar().createNode().run(::add) - } - - val lifecycle: Lifecycle = Lifecycle.Lambda( - onEnable = { - nodes.onEach(commandRegistrarContext::registerWhenReady) - } - ) -} diff --git a/instances/forge/src/main/java/ru/astrainteractive/astratemplate/command/helloworld/HelloCommandRegistrar.kt b/instances/forge/src/main/java/ru/astrainteractive/astratemplate/command/helloworld/HelloCommandRegistrar.kt deleted file mode 100644 index 3554c1d..0000000 --- a/instances/forge/src/main/java/ru/astrainteractive/astratemplate/command/helloworld/HelloCommandRegistrar.kt +++ /dev/null @@ -1,18 +0,0 @@ -package ru.astrainteractive.astratemplate.command.helloworld - -import com.mojang.brigadier.builder.LiteralArgumentBuilder -import net.minecraft.commands.CommandSourceStack -import net.minecraft.network.chat.Component -import ru.astrainteractive.astralibs.command.util.command -import ru.astrainteractive.astralibs.command.util.runs - -class HelloCommandRegistrar { - fun createNode(): LiteralArgumentBuilder { - return command("helloworld") { - runs { ctx -> - val component = Component.literal("Hello world!") - ctx.source.source.sendSystemMessage(component) - } - } - } -} diff --git a/instances/forge/src/main/java/ru/astrainteractive/astratemplate/ForgeEntryPoint.kt b/instances/forge/src/main/kotlin/ru/astrainteractive/astratemplate/ForgeEntryPoint.kt similarity index 100% rename from instances/forge/src/main/java/ru/astrainteractive/astratemplate/ForgeEntryPoint.kt rename to instances/forge/src/main/kotlin/ru/astrainteractive/astratemplate/ForgeEntryPoint.kt diff --git a/instances/forge/src/main/java/ru/astrainteractive/astratemplate/di/RootModule.kt b/instances/forge/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt similarity index 100% rename from instances/forge/src/main/java/ru/astrainteractive/astratemplate/di/RootModule.kt rename to instances/forge/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt diff --git a/modules/feature-event/forge/build.gradle.kts b/modules/feature-event/forge/build.gradle.kts new file mode 100644 index 0000000..14eeba2 --- /dev/null +++ b/modules/feature-event/forge/build.gradle.kts @@ -0,0 +1,44 @@ +plugins { + id("org.jetbrains.kotlin.jvm") + id("org.jetbrains.kotlin.plugin.serialization") + id("ru.astrainteractive.gradleplugin.detekt") + id("ru.astrainteractive.gradleplugin.java.version") +} + +dependencies { + implementation(libs.klibs.kstorage) + implementation(libs.klibs.mikro.core) + implementation(libs.klibs.mikro.extensions) + implementation(libs.kotlin.coroutines.core) + implementation(libs.kotlin.serialization.json) + implementation(libs.minecraft.astralibs.core) + implementation(libs.minecraft.astralibs.core.forge) + + implementation(projects.modules.featureGui.api) + implementation(projects.modules.core) + implementation(projects.modules.api.local) +} + + +dependencies { + // We use this because forge plugin waste a lot of resources when enabled + compileOnly( + files( + rootProject + .file(".gradle") + .resolve("mavenizer") + .resolve("repo") + .resolve("net") + .resolve("minecraftforge") + .resolve("forge") + .resolve(libs.versions.minecraft.forgeversion.get()) + .resolve("forge-${libs.versions.minecraft.forgeversion.get()}.jar") + ) + ) + compileOnly(libs.minecraft.brigadier) + compileOnly(libs.minecraft.authlib) + compileOnly(libs.minecraft.forgeversion) + compileOnly(libs.minecraft.datafixerupper) + compileOnly(libs.minecraft.forge.bus) + compileOnly(libs.joml) +} diff --git a/instances/forge/src/main/java/ru/astrainteractive/astratemplate/event/di/EventModule.kt b/modules/feature-event/forge/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/di/EventModule.kt similarity index 69% rename from instances/forge/src/main/java/ru/astrainteractive/astratemplate/event/di/EventModule.kt rename to modules/feature-event/forge/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/di/EventModule.kt index 992ddf9..ea9397e 100644 --- a/instances/forge/src/main/java/ru/astrainteractive/astratemplate/event/di/EventModule.kt +++ b/modules/feature-event/forge/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/di/EventModule.kt @@ -1,8 +1,8 @@ -package ru.astrainteractive.astratemplate.event.di +package ru.astrainteractive.astratemplate.feature.event.di.di import ru.astrainteractive.astralibs.lifecycle.Lifecycle import ru.astrainteractive.astratemplate.core.di.CoreModule -import ru.astrainteractive.astratemplate.event.TickEvent +import ru.astrainteractive.astratemplate.feature.event.di.event.TickEvent class EventModule(coreModule: CoreModule) { @Suppress("UnusedPrivateProperty") diff --git a/instances/forge/src/main/java/ru/astrainteractive/astratemplate/event/TickEvent.kt b/modules/feature-event/forge/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/event/TickEvent.kt similarity index 50% rename from instances/forge/src/main/java/ru/astrainteractive/astratemplate/event/TickEvent.kt rename to modules/feature-event/forge/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/event/TickEvent.kt index 9679a8f..81ee33f 100644 --- a/instances/forge/src/main/java/ru/astrainteractive/astratemplate/event/TickEvent.kt +++ b/modules/feature-event/forge/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/event/TickEvent.kt @@ -1,18 +1,15 @@ -package ru.astrainteractive.astratemplate.event +package ru.astrainteractive.astratemplate.feature.event.di.event import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import net.minecraftforge.event.TickEvent -import ru.astrainteractive.astralibs.event.flowEvent import ru.astrainteractive.klibs.mikro.core.logging.JUtiltLogger import ru.astrainteractive.klibs.mikro.core.logging.Logger -class TickEvent( - mainScope: CoroutineScope -) : Logger by JUtiltLogger("AstraTemplate-TickEvent") { +class TickEvent(mainScope: CoroutineScope) : Logger by JUtiltLogger("AstraTemplate-TickEvent") { - val serverStartedEvent = flowEvent() - .onEach { info { "#serverStartedEvent" } } + val tickEvent = flowEvent() + .onEach { info { "#tickEvent -> flow onEach" } } .launchIn(mainScope) -} +} \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 56d0dde..a7bab5f 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -63,3 +63,4 @@ include("modules:feature-command") include("modules:feature-gui:api") include("modules:feature-gui:bukkit") include("modules:feature-event:bukkit") +include("modules:feature-event:forge") From 0b2d067ce57e7b22279a01cdf59b390de1e5093a Mon Sep 17 00:00:00 2001 From: Roman Makeev Date: Sat, 30 May 2026 20:29:39 +0300 Subject: [PATCH 07/16] [REFACTOR] Add forge event into events --- .../astratemplate/feature/event/di/event/TickEvent.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/feature-event/forge/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/event/TickEvent.kt b/modules/feature-event/forge/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/event/TickEvent.kt index 81ee33f..78ae1aa 100644 --- a/modules/feature-event/forge/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/event/TickEvent.kt +++ b/modules/feature-event/forge/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/event/TickEvent.kt @@ -4,6 +4,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import net.minecraftforge.event.TickEvent +import ru.astrainteractive.astralibs.event.flowEvent import ru.astrainteractive.klibs.mikro.core.logging.JUtiltLogger import ru.astrainteractive.klibs.mikro.core.logging.Logger From c3b9e26baded01c710863a1ecc6782a7f2c9eedc Mon Sep 17 00:00:00 2001 From: Roman Makeev Date: Sat, 30 May 2026 20:32:36 +0300 Subject: [PATCH 08/16] [REFACTOR] Add neoforge event into events --- .../feature/event/di/event/TickEvent.kt | 1 - .../feature-event/neoforge/build.gradle.kts | 44 +++++++++++++++++++ .../feature/event/di/di/EventModule.kt | 11 +++++ .../feature/event/di/event/TickEvent.kt | 15 +++++++ settings.gradle.kts | 1 + 5 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 modules/feature-event/neoforge/build.gradle.kts create mode 100644 modules/feature-event/neoforge/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/di/EventModule.kt create mode 100644 modules/feature-event/neoforge/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/event/TickEvent.kt diff --git a/modules/feature-event/forge/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/event/TickEvent.kt b/modules/feature-event/forge/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/event/TickEvent.kt index 78ae1aa..31c6c93 100644 --- a/modules/feature-event/forge/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/event/TickEvent.kt +++ b/modules/feature-event/forge/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/event/TickEvent.kt @@ -9,7 +9,6 @@ import ru.astrainteractive.klibs.mikro.core.logging.JUtiltLogger import ru.astrainteractive.klibs.mikro.core.logging.Logger class TickEvent(mainScope: CoroutineScope) : Logger by JUtiltLogger("AstraTemplate-TickEvent") { - val tickEvent = flowEvent() .onEach { info { "#tickEvent -> flow onEach" } } .launchIn(mainScope) diff --git a/modules/feature-event/neoforge/build.gradle.kts b/modules/feature-event/neoforge/build.gradle.kts new file mode 100644 index 0000000..e78996b --- /dev/null +++ b/modules/feature-event/neoforge/build.gradle.kts @@ -0,0 +1,44 @@ +plugins { + id("org.jetbrains.kotlin.jvm") + id("org.jetbrains.kotlin.plugin.serialization") + id("ru.astrainteractive.gradleplugin.detekt") + id("ru.astrainteractive.gradleplugin.java.version") +} + +dependencies { + implementation(libs.klibs.kstorage) + implementation(libs.klibs.mikro.core) + implementation(libs.klibs.mikro.extensions) + implementation(libs.kotlin.coroutines.core) + implementation(libs.kotlin.serialization.json) + implementation(libs.minecraft.astralibs.core) + implementation(libs.minecraft.astralibs.core.neoforge) + + implementation(projects.modules.featureGui.api) + implementation(projects.modules.core) + implementation(projects.modules.api.local) +} + + +dependencies { + // We use this because forge plugin waste a lot of resources when enabled + compileOnly( + files( + rootProject.project(projects.instances.neoforge.path) + .file(".gradle") + .resolve("repositories") + .resolve("ng_dummy_ng") + .resolve("net") + .resolve("neoforged") + .resolve("neoforge") + .resolve(libs.versions.minecraft.neoforgeversion.get()) + .resolve("neoforge-${libs.versions.minecraft.neoforgeversion.get()}.jar") + ) + ) + compileOnly(libs.minecraft.neoforgeversion) + compileOnly(libs.joml) + compileOnly(libs.minecraft.datafixerupper) + compileOnly(libs.minecraft.brigadier) + compileOnly(libs.minecraft.neoforged.bus) + compileOnly(libs.minecraft.authlib) +} diff --git a/modules/feature-event/neoforge/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/di/EventModule.kt b/modules/feature-event/neoforge/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/di/EventModule.kt new file mode 100644 index 0000000..ea9397e --- /dev/null +++ b/modules/feature-event/neoforge/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/di/EventModule.kt @@ -0,0 +1,11 @@ +package ru.astrainteractive.astratemplate.feature.event.di.di + +import ru.astrainteractive.astralibs.lifecycle.Lifecycle +import ru.astrainteractive.astratemplate.core.di.CoreModule +import ru.astrainteractive.astratemplate.feature.event.di.event.TickEvent + +class EventModule(coreModule: CoreModule) { + @Suppress("UnusedPrivateProperty") + private val tickEvent = TickEvent(coreModule.mainScope) + val lifecycle: Lifecycle = Lifecycle.Empty +} diff --git a/modules/feature-event/neoforge/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/event/TickEvent.kt b/modules/feature-event/neoforge/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/event/TickEvent.kt new file mode 100644 index 0000000..0a2f3e6 --- /dev/null +++ b/modules/feature-event/neoforge/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/event/TickEvent.kt @@ -0,0 +1,15 @@ +package ru.astrainteractive.astratemplate.feature.event.di.event + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import net.neoforged.neoforge.event.tick.ServerTickEvent +import ru.astrainteractive.astralibs.event.flowEvent +import ru.astrainteractive.klibs.mikro.core.logging.JUtiltLogger +import ru.astrainteractive.klibs.mikro.core.logging.Logger + +class TickEvent(mainScope: CoroutineScope) : Logger by JUtiltLogger("AstraTemplate-TickEvent") { + val tickEvent = flowEvent() + .onEach { info { "#tickEvent -> flow onEach" } } + .launchIn(mainScope) +} \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index a7bab5f..24e98e7 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -64,3 +64,4 @@ include("modules:feature-gui:api") include("modules:feature-gui:bukkit") include("modules:feature-event:bukkit") include("modules:feature-event:forge") +include("modules:feature-event:neoforge") From 6abb3d663857a602e68d2d1ca6c2af3cc039466f Mon Sep 17 00:00:00 2001 From: Roman Makeev Date: Sat, 30 May 2026 20:45:31 +0300 Subject: [PATCH 09/16] [REFACTOR] Clear forge/neoforge modules --- .../astratemplate/di/RootModule.kt | 4 +- instances/fabric/build.gradle.kts | 145 ------------------ .../astratemplate/ClientEntryPoint.kt | 16 -- .../astratemplate/FabricEntryPoint.kt | 20 --- .../astratemplate/command/core/Command.kt | 9 -- .../command/core/CommandRegistry.kt | 5 - .../command/core/DefaultCommandRegistry.kt | 28 ---- .../astratemplate/command/core/DslCommand.kt | 14 -- .../astratemplate/command/di/CommandModule.kt | 30 ---- .../command/helloworld/HelloWorldCommand.kt | 11 -- .../command/rickmorty/RickMortyCommand.kt | 22 --- .../astratemplate/di/FabricModule.kt | 11 -- .../astratemplate/mixin/FabricMixin.kt | 17 -- .../src/main/resources/assets/modid/icon.png | Bin 5036 -> 0 bytes .../main/resources/astratemplate.mixins.json | 14 -- .../fabric/src/main/resources/fabric.mod.json | 48 ------ instances/forge/build.gradle.kts | 2 + .../astratemplate/ForgeEntryPoint.kt | 41 ++--- .../astratemplate/di/RootModule.kt | 45 +++--- .../src/main/resources/META-INF/mods.toml | 30 +++- instances/forge/src/main/resources/icon.png | Bin 5036 -> 0 bytes .../forge/src/main/resources/pack.mcmeta | 7 - instances/neoforge/build.gradle.kts | 4 +- .../astratemplate/ForgeEntryPoint.kt | 55 ------- .../astratemplate/command/di/CommandModule.kt | 19 --- .../helloworld/HelloCommandRegistrar.kt | 18 --- .../astratemplate/di/RootModule.kt | 72 --------- .../astratemplate/event/TickEvent.kt | 18 --- .../astratemplate/event/di/EventModule.kt | 11 -- .../astratemplate/NeoForgeEntryPoint.kt | 32 ++++ .../astratemplate/di/RootModule.kt | 44 +++--- .../src/main/resources/META-INF/mods.toml | 31 ++-- .../neoforge/src/main/resources/icon.png | Bin 5036 -> 0 bytes .../neoforge/src/main/resources/pack.mcmeta | 7 - .../astratemplate/core/di/CoreModule.kt | 2 +- modules/feature-command/build.gradle.kts | 6 + .../feature/command/di/CommandModule.kt | 7 +- .../astratemplate/feature/gui/di/GuiModule.kt | 7 + .../di/{GuiModule.kt => BukkitGuiModule.kt} | 6 +- 39 files changed, 158 insertions(+), 700 deletions(-) delete mode 100644 instances/fabric/build.gradle.kts delete mode 100644 instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/ClientEntryPoint.kt delete mode 100644 instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/FabricEntryPoint.kt delete mode 100644 instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/command/core/Command.kt delete mode 100644 instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/command/core/CommandRegistry.kt delete mode 100644 instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/command/core/DefaultCommandRegistry.kt delete mode 100644 instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/command/core/DslCommand.kt delete mode 100644 instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/command/di/CommandModule.kt delete mode 100644 instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/command/helloworld/HelloWorldCommand.kt delete mode 100644 instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/command/rickmorty/RickMortyCommand.kt delete mode 100644 instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/di/FabricModule.kt delete mode 100644 instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/mixin/FabricMixin.kt delete mode 100644 instances/fabric/src/main/resources/assets/modid/icon.png delete mode 100644 instances/fabric/src/main/resources/astratemplate.mixins.json delete mode 100644 instances/fabric/src/main/resources/fabric.mod.json delete mode 100644 instances/forge/src/main/resources/icon.png delete mode 100644 instances/forge/src/main/resources/pack.mcmeta delete mode 100644 instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/ForgeEntryPoint.kt delete mode 100644 instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/command/di/CommandModule.kt delete mode 100644 instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/command/helloworld/HelloCommandRegistrar.kt delete mode 100644 instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/di/RootModule.kt delete mode 100644 instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/event/TickEvent.kt delete mode 100644 instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/event/di/EventModule.kt create mode 100755 instances/neoforge/src/main/kotlin/ru/astrainteractive/astratemplate/NeoForgeEntryPoint.kt rename instances/{fabric => neoforge}/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt (51%) delete mode 100644 instances/neoforge/src/main/resources/icon.png delete mode 100644 instances/neoforge/src/main/resources/pack.mcmeta create mode 100644 modules/feature-gui/api/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/di/GuiModule.kt rename modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/di/{GuiModule.kt => BukkitGuiModule.kt} (92%) diff --git a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt b/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt index 1068722..a0dea3a 100644 --- a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt +++ b/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt @@ -8,7 +8,7 @@ import ru.astrainteractive.astratemplate.api.remote.di.ApiRemoteModule import ru.astrainteractive.astratemplate.feature.command.di.CommandModule import ru.astrainteractive.astratemplate.core.di.CoreModule import ru.astrainteractive.astratemplate.feature.event.di.EventModule -import ru.astrainteractive.astratemplate.feature.gui.di.GuiModule +import ru.astrainteractive.astratemplate.feature.gui.di.BukkitGuiModule internal class RootModule(plugin: AstraTemplate) { @@ -25,7 +25,7 @@ internal class RootModule(plugin: AstraTemplate) { val apiRemoteModule: ApiRemoteModule = ApiRemoteModule() val eventModule: EventModule = EventModule(coreModule, plugin) - val guiModule: GuiModule = GuiModule( + val guiModule: BukkitGuiModule = BukkitGuiModule( coreModule = coreModule, apiLocalModule = apiLocalModule ) diff --git a/instances/fabric/build.gradle.kts b/instances/fabric/build.gradle.kts deleted file mode 100644 index 41824da..0000000 --- a/instances/fabric/build.gradle.kts +++ /dev/null @@ -1,145 +0,0 @@ -import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar -import net.fabricmc.loom.task.RemapJarTask -import ru.astrainteractive.gradleplugin.property.extension.ModelPropertyValueExt.requireProjectInfo - -plugins { - kotlin("jvm") - alias(libs.plugins.fabric.loom) - alias(libs.plugins.klibs.gradle.java.core) - alias(libs.plugins.klibs.minecraft.resource.processor) - alias(libs.plugins.gradle.shadow) -} - -dependencies { - minecraft(libs.minecraft.fabric.mojang.get()) - mappings("net.fabricmc:yarn:${libs.versions.minecraft.fabric.yarn.get()}:v2") - modImplementation(libs.minecraft.fabric.kotlin.get()) - modImplementation(libs.minecraft.fabric.loader.get()) - modImplementation(libs.minecraft.fabric.api.get()) - // AstraLibs - implementation(libs.minecraft.astralibs.core) - implementation(libs.minecraft.astralibs.command) - // klibs - implementation(libs.klibs.kstorage) - implementation(libs.klibs.mikro.core) - // Kotlin - implementation(libs.kotlin.coroutines.core) - implementation(libs.kotlin.serialization.json) - implementation(libs.kotlin.serialization.kaml) - // Driver - implementation(libs.driver.jdbc) - // Local - implementation(projects.modules.api.local) - implementation(projects.modules.api.remote) - implementation(projects.modules.core) -} - -minecraftProcessResource { - fabric() -} - -val destination = rootDir.resolve("build") - .resolve("fabric") - .resolve("mods") - .takeIf { it.exists() } - ?: File(rootDir, "jars") - -val shadowJar by tasks.getting(ShadowJar::class) { - mergeServiceFiles() -// mustRunAfter(minecraftProcessResource.task) -// dependsOn(minecraftProcessResource.task) - configurations = listOf(project.configurations.shadow.get()) - isReproducibleFileOrder = true - archiveClassifier = null as String? - archiveVersion = requireProjectInfo.versionString - archiveBaseName = "${requireProjectInfo.name}-fabric" - dependencies { - // deps - exclude(dependency("org.jetbrains:annotations")) - // deps paths - exclude("co/touchlab/stately/**") - exclude("club/minnced/opus/**") - exclude("com/google/**") - exclude("com/sun/**") - exclude("google/protobuf/**") - exclude("io/github/**") - exclude("io/javalin/**") - exclude("jakarta/servlet/**") - exclude("javax/annotation/**") - exclude("javax/servlet/**") - exclude("natives/**") - exclude("nl/altindag/**") - exclude("org/eclipse/**") - exclude("org/bouncycastle/**") - exclude("org/checkerframework/**") - exclude("org/conscrypt/**") - exclude("tomp2p/opuswrapper/**") - exclude("DebugProbesKt.bin") - exclude("_COROUTINE/**") - // meta -// exclude("META-INF/services/**") - exclude("META-INF/*.kotlin_module") - exclude("META-INF/com.android.tools/**") - exclude("META-INF/gradle-plugins/**") - exclude("META-INF/maven/**") - exclude("META-INF/proguard/**") - exclude("META-INF/versions/**") - exclude("META-INF/native/**") - exclude("META-INF/**LICENCE**") - } - // Be sure to relocate EXACT PACKAGES!! - // For example, relocate org.some.package instead of org - // Becuase relocation org will break other non-relocated dependencies such as org.minecraft - listOf( - "com.fasterxml", - "net.kyori", - "org.h2", - "com.neovisionaries", - "gnu.trove", - "org.json", - "org.apache", - "org.telegram", - "okhttp3", - "net.dv8tion", - "okio", - "org.slf4j", - "kotlin", - "kotlinx", - "it.krzeminski", - "net.thauvin", - "org.jetbrains.exposed.dao", - "org.jetbrains.exposed.exceptions", - "org.jetbrains.exposed.sql", - "org.jetbrains.exposed.jdbc", - "org.jetbrains.kotlin", - "org.jetbrains.kotlinx", - "com.charleskorn.kaml", - "ru.astrainteractive.klibs", - "ru.astrainteractive.astralibs", - "club.minnced.discord", - "club.minnced.opus" - ).forEach { pattern -> relocate(pattern, "${requireProjectInfo.group}.shade.$pattern") } -} - -val remapJar = tasks.getByName("remapJar") { - dependsOn(shadowJar) - mustRunAfter(shadowJar) - inputFile = shadowJar.archiveFile - addNestedDependencies.set(true) - archiveBaseName.set("${requireProjectInfo.name}-fabric") - destinationDirectory.set(destination) - archiveVersion = requireProjectInfo.versionString -} - -tasks.assemble { - dependsOn(remapJar) -} - -artifacts { - archives(remapJar) - shadow(shadowJar) -} - -minecraftProcessResource { - fabric() -} diff --git a/instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/ClientEntryPoint.kt b/instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/ClientEntryPoint.kt deleted file mode 100644 index 3647d1d..0000000 --- a/instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/ClientEntryPoint.kt +++ /dev/null @@ -1,16 +0,0 @@ -package ru.astrainteractive.astratemplate - -import net.fabricmc.api.ClientModInitializer -import ru.astrainteractive.astratemplate.di.RootModule - -class ClientEntryPoint : ClientModInitializer { - - private val rootModule: RootModule by lazy { - RootModule() - } - - override fun onInitializeClient() { - println("AstraTemplate: onInitializeClient") - rootModule.lifecycle.onEnable() - } -} diff --git a/instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/FabricEntryPoint.kt b/instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/FabricEntryPoint.kt deleted file mode 100644 index 4a39dd5..0000000 --- a/instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/FabricEntryPoint.kt +++ /dev/null @@ -1,20 +0,0 @@ -package ru.astrainteractive.astratemplate - -import net.fabricmc.api.ModInitializer -import ru.astrainteractive.astratemplate.di.RootModule - -class FabricEntryPoint : ModInitializer { - - private val rootModule: RootModule by lazy { - RootModule() - } - - override fun onInitialize() { - println("AstraTemplate: onInitialize") - rootModule.lifecycle.onEnable() - } - - fun reload() { - rootModule.lifecycle.onReload() - } -} diff --git a/instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/command/core/Command.kt b/instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/command/core/Command.kt deleted file mode 100644 index 218acf4..0000000 --- a/instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/command/core/Command.kt +++ /dev/null @@ -1,9 +0,0 @@ -package ru.astrainteractive.astratemplate.command.core - -import com.mojang.brigadier.context.CommandContext -import net.minecraft.server.command.ServerCommandSource - -interface Command { - val alias: String - fun onCommand(commandContext: CommandContext): Int -} diff --git a/instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/command/core/CommandRegistry.kt b/instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/command/core/CommandRegistry.kt deleted file mode 100644 index a23559b..0000000 --- a/instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/command/core/CommandRegistry.kt +++ /dev/null @@ -1,5 +0,0 @@ -package ru.astrainteractive.astratemplate.command.core - -interface CommandRegistry { - fun register(command: Command) -} diff --git a/instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/command/core/DefaultCommandRegistry.kt b/instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/command/core/DefaultCommandRegistry.kt deleted file mode 100644 index 4a398ed..0000000 --- a/instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/command/core/DefaultCommandRegistry.kt +++ /dev/null @@ -1,28 +0,0 @@ -package ru.astrainteractive.astratemplate.command.core - -import com.mojang.brigadier.CommandDispatcher -import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback -import net.minecraft.command.CommandRegistryAccess -import net.minecraft.server.command.CommandManager -import net.minecraft.server.command.ServerCommandSource - -object DefaultCommandRegistry : CommandRegistry { - - private class CommandRegistrationCallbackImpl( - private val literal: String, - private val command: Command - ) : CommandRegistrationCallback { - override fun register( - dispatcher: CommandDispatcher?, - registryAccess: CommandRegistryAccess?, - environment: CommandManager.RegistrationEnvironment? - ) { - dispatcher?.register(CommandManager.literal(literal).executes(command::onCommand)) - } - } - - override fun register(command: Command) { - val callback = CommandRegistrationCallbackImpl(literal = command.alias, command = command) - CommandRegistrationCallback.EVENT.register(callback) - } -} diff --git a/instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/command/core/DslCommand.kt b/instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/command/core/DslCommand.kt deleted file mode 100644 index 876b97f..0000000 --- a/instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/command/core/DslCommand.kt +++ /dev/null @@ -1,14 +0,0 @@ -package ru.astrainteractive.astratemplate.command.core - -import com.mojang.brigadier.context.CommandContext -import net.minecraft.server.command.ServerCommandSource - -class DslCommand( - override val alias: String, - private val block: (commandContext: CommandContext) -> Unit -) : Command { - override fun onCommand(commandContext: CommandContext): Int { - block.invoke(commandContext) - return 1 - } -} diff --git a/instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/command/di/CommandModule.kt b/instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/command/di/CommandModule.kt deleted file mode 100644 index 53279e7..0000000 --- a/instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/command/di/CommandModule.kt +++ /dev/null @@ -1,30 +0,0 @@ -package ru.astrainteractive.astratemplate.command.di - -import ru.astrainteractive.astralibs.lifecycle.Lifecycle -import ru.astrainteractive.astratemplate.api.remote.di.ApiRemoteModule -import ru.astrainteractive.astratemplate.command.core.Command -import ru.astrainteractive.astratemplate.command.core.DefaultCommandRegistry -import ru.astrainteractive.astratemplate.command.helloworld.HelloWorldCommand -import ru.astrainteractive.astratemplate.command.rickmorty.RickMortyCommand -import ru.astrainteractive.astratemplate.core.di.CoreModule - -class CommandModule( - private val coreModule: CoreModule, - private val apiRemoteModule: ApiRemoteModule -) { - private val commands: List = listOf( - HelloWorldCommand(), - RickMortyCommand( - rickMortyApi = apiRemoteModule.rickMortyApi, - ioScope = coreModule.ioScope, - dispatchers = coreModule.dispatchers - ) - ) - val lifecycle: Lifecycle by lazy { - Lifecycle.Lambda( - onEnable = { - commands.forEach(DefaultCommandRegistry::register) - } - ) - } -} diff --git a/instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/command/helloworld/HelloWorldCommand.kt b/instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/command/helloworld/HelloWorldCommand.kt deleted file mode 100644 index df4657d..0000000 --- a/instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/command/helloworld/HelloWorldCommand.kt +++ /dev/null @@ -1,11 +0,0 @@ -package ru.astrainteractive.astratemplate.command.helloworld - -import ru.astrainteractive.astratemplate.command.core.Command -import ru.astrainteractive.astratemplate.command.core.DslCommand - -class HelloWorldCommand : Command by DslCommand( - alias = "helloworld", - block = { - println("Hello world") - } -) diff --git a/instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/command/rickmorty/RickMortyCommand.kt b/instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/command/rickmorty/RickMortyCommand.kt deleted file mode 100644 index b7fe9d9..0000000 --- a/instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/command/rickmorty/RickMortyCommand.kt +++ /dev/null @@ -1,22 +0,0 @@ -package ru.astrainteractive.astratemplate.command.rickmorty - -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.launch -import ru.astrainteractive.astratemplate.api.remote.RickMortyApi -import ru.astrainteractive.astratemplate.command.core.Command -import ru.astrainteractive.astratemplate.command.core.DslCommand -import ru.astrainteractive.klibs.mikro.core.dispatchers.KotlinDispatchers - -class RickMortyCommand( - private val rickMortyApi: RickMortyApi, - private val ioScope: CoroutineScope, - private val dispatchers: KotlinDispatchers -) : Command by DslCommand( - alias = "rickmorty", - block = { - ioScope.launch(dispatchers.IO) { - println("Getting character...") - println(rickMortyApi.getRandomCharacter(1)) - } - } -) diff --git a/instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/di/FabricModule.kt b/instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/di/FabricModule.kt deleted file mode 100644 index 8e40211..0000000 --- a/instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/di/FabricModule.kt +++ /dev/null @@ -1,11 +0,0 @@ -package ru.astrainteractive.astratemplate.di - -import net.fabricmc.loader.api.FabricLoader -import java.io.File - -class FabricModule { - val fabricLoader: FabricLoader - get() = FabricLoader.getInstance() - val configDir: File - get() = fabricLoader.configDir.toFile() -} diff --git a/instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/mixin/FabricMixin.kt b/instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/mixin/FabricMixin.kt deleted file mode 100644 index 8072c08..0000000 --- a/instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/mixin/FabricMixin.kt +++ /dev/null @@ -1,17 +0,0 @@ -@file:Suppress("UnusedPrivateMember") - -package ru.astrainteractive.astratemplate.mixin - -import net.minecraft.client.gui.screen.TitleScreen -import org.spongepowered.asm.mixin.Mixin -import org.spongepowered.asm.mixin.injection.At -import org.spongepowered.asm.mixin.injection.Inject -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo - -@Mixin(TitleScreen::class) -class FabricMixin { - @Inject(at = [At("HEAD")], method = ["init()V"]) - private fun init(info: CallbackInfo) { - println("This line is printed by an example mod mixin!") - } -} diff --git a/instances/fabric/src/main/resources/assets/modid/icon.png b/instances/fabric/src/main/resources/assets/modid/icon.png deleted file mode 100644 index 00201e8ab8644cdad7eccc7a95d063f38db59eb4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5036 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.14.24", - "fabric": "*", - "minecraft": "1.20.x", - "java": ">=17", - "fabric-language-kotlin": ">=1.10.17+kotlin.1.9.22" - }, - "suggests": { - "another-mod": "*" - } -} \ No newline at end of file diff --git a/instances/forge/build.gradle.kts b/instances/forge/build.gradle.kts index dcc055b..f3e17e7 100644 --- a/instances/forge/build.gradle.kts +++ b/instances/forge/build.gradle.kts @@ -38,6 +38,8 @@ dependencies { shadow(projects.modules.api.remote) shadow(projects.modules.buildKonfig) shadow(projects.modules.core) + shadow(projects.modules.featureEvent.forge) + shadow(projects.modules.featureCommand) } minecraftProcessResource { diff --git a/instances/forge/src/main/kotlin/ru/astrainteractive/astratemplate/ForgeEntryPoint.kt b/instances/forge/src/main/kotlin/ru/astrainteractive/astratemplate/ForgeEntryPoint.kt index abca934..33668dd 100644 --- a/instances/forge/src/main/kotlin/ru/astrainteractive/astratemplate/ForgeEntryPoint.kt +++ b/instances/forge/src/main/kotlin/ru/astrainteractive/astratemplate/ForgeEntryPoint.kt @@ -1,29 +1,22 @@ -@file:Suppress("UnusedPrivateMember") - package ru.astrainteractive.astratemplate -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach -import net.minecraftforge.event.RegisterCommandsEvent -import net.minecraftforge.event.server.ServerStartedEvent -import net.minecraftforge.event.server.ServerStoppingEvent -import net.minecraftforge.eventbus.api.EventPriority -import net.minecraftforge.fml.common.Mod -import ru.astrainteractive.astralibs.event.flowEvent -import ru.astrainteractive.astralibs.lifecycle.Lifecycle -import ru.astrainteractive.astratemplate.di.RootModule +import ru.astrainteractive.astralibs.lifecycle.ForgeLifecycleServer import ru.astrainteractive.klibs.mikro.core.logging.JUtiltLogger import ru.astrainteractive.klibs.mikro.core.logging.Logger import javax.annotation.ParametersAreNonnullByDefault +import net.minecraftforge.fml.common.Mod +import ru.astrainteractive.aspekt.BuildKonfig +import ru.astrainteractive.astratemplate.di.RootModule @Mod(BuildKonfig.id) @ParametersAreNonnullByDefault class ForgeEntryPoint : - Lifecycle, - Logger by JUtiltLogger("ForgeEntryPoint") { - private val rootModule: RootModule = RootModule() + Logger by JUtiltLogger("${BuildKonfig.id}-ForgeEntryPoint"), + ForgeLifecycleServer() { + private val rootModule = RootModule() override fun onEnable() { + info { "#onEnable" } rootModule.lifecycle.onEnable() } @@ -33,23 +26,7 @@ class ForgeEntryPoint : } override fun onReload() { + info { "#onReaload" } rootModule.lifecycle.onReload() } - - val serverStartedEvent = flowEvent(EventPriority.HIGHEST) - .onEach { - info { "#serverStartedEvent" } - onEnable() - }.launchIn(rootModule.coreModule.ioScope) - - val serverStoppingEvent = flowEvent(EventPriority.HIGHEST) - .onEach { - info { "#serverStoppingEvent" } - onDisable() - }.launchIn(rootModule.coreModule.ioScope) - - val registerCommandsEvent = flowEvent(EventPriority.HIGHEST) - .onEach { e -> - info { "#registerCommandsEvent" } - }.launchIn(rootModule.coreModule.ioScope) } diff --git a/instances/forge/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt b/instances/forge/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt index b652cf5..11fcc69 100644 --- a/instances/forge/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt +++ b/instances/forge/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt @@ -1,59 +1,54 @@ package ru.astrainteractive.astratemplate.di -import kotlinx.coroutines.CoroutineDispatcher +import java.io.File import net.minecraftforge.fml.loading.FMLPaths import ru.astrainteractive.astralibs.command.registrar.ForgeCommandRegistrarContext -import ru.astrainteractive.astralibs.coroutine.ForgeMainDispatcher +import ru.astrainteractive.astralibs.coroutines.MinecraftDispatchers import ru.astrainteractive.astralibs.lifecycle.Lifecycle import ru.astrainteractive.astratemplate.api.local.di.ApiLocalModule import ru.astrainteractive.astratemplate.api.remote.di.ApiRemoteModule -import ru.astrainteractive.astratemplate.command.di.CommandModule import ru.astrainteractive.astratemplate.core.di.CoreModule -import ru.astrainteractive.astratemplate.event.di.EventModule -import ru.astrainteractive.klibs.mikro.core.dispatchers.DefaultKotlinDispatchers -import ru.astrainteractive.klibs.mikro.core.dispatchers.KotlinDispatchers +import ru.astrainteractive.astratemplate.feature.event.di.di.EventModule class RootModule { - val coreModule: CoreModule by lazy { - CoreModule( - dataFolder = FMLPaths.CONFIGDIR.get() - .resolve("AstraTemplate") - .toAbsolutePath() - .toFile(), - dispatchers = object : KotlinDispatchers by DefaultKotlinDispatchers { - override val Main: CoroutineDispatcher = ForgeMainDispatcher - } - ) - } + private val dataFolder = FMLPaths.CONFIGDIR.get() + .resolve("AspeKt") + .toAbsolutePath() + .toFile() + .also(File::mkdirs) + private val coreModule: CoreModule = CoreModule( + dataFolder = dataFolder, + dispatchers = MinecraftDispatchers() + ) + private val commandRegistrarContext = ForgeCommandRegistrarContext(coreModule.mainScope) - val apiLocalModule: ApiLocalModule by lazy { + private val apiLocalModule: ApiLocalModule by lazy { ApiLocalModule( configFlow = coreModule.configKrate.cachedStateFlow, ioScope = coreModule.ioScope ) } - val apiRemoteModule: ApiRemoteModule by lazy { + private val apiRemoteModule: ApiRemoteModule by lazy { ApiRemoteModule() } - val commandModule by lazy { + private val commandModule by lazy { CommandModule( - commandRegistrarContext = ForgeCommandRegistrarContext( - mainScope = coreModule.mainScope - ) + commandRegistrarContext = commandRegistrarContext ) } - val eventsModule: EventModule by lazy { + val eventsModule by lazy { EventModule(coreModule = coreModule) } private val lifecycles: List get() = listOf( + coreModule.lifecycle, eventsModule.lifecycle, - commandModule.lifecycle + commandModule.lifecycle, ) val lifecycle: Lifecycle by lazy { diff --git a/instances/forge/src/main/resources/META-INF/mods.toml b/instances/forge/src/main/resources/META-INF/mods.toml index 96a5ab0..b87a680 100644 --- a/instances/forge/src/main/resources/META-INF/mods.toml +++ b/instances/forge/src/main/resources/META-INF/mods.toml @@ -1,10 +1,24 @@ -license="MIT" modLoader="javafml" -loaderVersion="[34,)" +loaderVersion="[47,)" +license="${mod_license}" + [[mods]] -modId="${modId}" -version="${version}" -displayName="${displayName}" -authors="${authors}" -logoFile="icon.png" -description="${description}" \ No newline at end of file +modId="${mod_id}" +version="${mod_version}" +displayName="${mod_name}" +authors="${mod_authors}" +description='''${mod_description}''' + +[[dependencies.${mod_id}]] +modId="forge" +mandatory=true +versionRange="[${forge_version},)" +ordering="NONE" +side="BOTH" + +[[dependencies.${mod_id}]] +modId="minecraft" +mandatory=true +versionRange="[${minecraft_version},)" +ordering="NONE" +side="BOTH" diff --git a/instances/forge/src/main/resources/icon.png b/instances/forge/src/main/resources/icon.png deleted file mode 100644 index 00201e8ab8644cdad7eccc7a95d063f38db59eb4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5036 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.HIGHEST) - .onEach { - info { "#serverStartedEvent" } - onEnable() - }.launchIn(rootModule.coreModule.ioScope) - - val serverStoppingEvent = flowEvent(EventPriority.HIGHEST) - .onEach { - info { "#serverStoppingEvent" } - onDisable() - }.launchIn(rootModule.coreModule.ioScope) - - val registerCommandsEvent = flowEvent(EventPriority.HIGHEST) - .onEach { e -> - info { "#registerCommandsEvent" } - }.launchIn(rootModule.coreModule.ioScope) -} diff --git a/instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/command/di/CommandModule.kt b/instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/command/di/CommandModule.kt deleted file mode 100644 index 9c0bb86..0000000 --- a/instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/command/di/CommandModule.kt +++ /dev/null @@ -1,19 +0,0 @@ -package ru.astrainteractive.astratemplate.command.di - -import ru.astrainteractive.astralibs.command.registrar.ForgeCommandRegistrarContext -import ru.astrainteractive.astralibs.lifecycle.Lifecycle -import ru.astrainteractive.astratemplate.command.helloworld.HelloCommandRegistrar - -class CommandModule( - private val commandRegistrarContext: ForgeCommandRegistrarContext -) { - private val nodes = buildList { - HelloCommandRegistrar().createNode().run(::add) - } - - val lifecycle: Lifecycle = Lifecycle.Lambda( - onEnable = { - nodes.onEach(commandRegistrarContext::registerWhenReady) - } - ) -} diff --git a/instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/command/helloworld/HelloCommandRegistrar.kt b/instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/command/helloworld/HelloCommandRegistrar.kt deleted file mode 100644 index 3554c1d..0000000 --- a/instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/command/helloworld/HelloCommandRegistrar.kt +++ /dev/null @@ -1,18 +0,0 @@ -package ru.astrainteractive.astratemplate.command.helloworld - -import com.mojang.brigadier.builder.LiteralArgumentBuilder -import net.minecraft.commands.CommandSourceStack -import net.minecraft.network.chat.Component -import ru.astrainteractive.astralibs.command.util.command -import ru.astrainteractive.astralibs.command.util.runs - -class HelloCommandRegistrar { - fun createNode(): LiteralArgumentBuilder { - return command("helloworld") { - runs { ctx -> - val component = Component.literal("Hello world!") - ctx.source.source.sendSystemMessage(component) - } - } - } -} diff --git a/instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/di/RootModule.kt b/instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/di/RootModule.kt deleted file mode 100644 index b652cf5..0000000 --- a/instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/di/RootModule.kt +++ /dev/null @@ -1,72 +0,0 @@ -package ru.astrainteractive.astratemplate.di - -import kotlinx.coroutines.CoroutineDispatcher -import net.minecraftforge.fml.loading.FMLPaths -import ru.astrainteractive.astralibs.command.registrar.ForgeCommandRegistrarContext -import ru.astrainteractive.astralibs.coroutine.ForgeMainDispatcher -import ru.astrainteractive.astralibs.lifecycle.Lifecycle -import ru.astrainteractive.astratemplate.api.local.di.ApiLocalModule -import ru.astrainteractive.astratemplate.api.remote.di.ApiRemoteModule -import ru.astrainteractive.astratemplate.command.di.CommandModule -import ru.astrainteractive.astratemplate.core.di.CoreModule -import ru.astrainteractive.astratemplate.event.di.EventModule -import ru.astrainteractive.klibs.mikro.core.dispatchers.DefaultKotlinDispatchers -import ru.astrainteractive.klibs.mikro.core.dispatchers.KotlinDispatchers - -class RootModule { - - val coreModule: CoreModule by lazy { - CoreModule( - dataFolder = FMLPaths.CONFIGDIR.get() - .resolve("AstraTemplate") - .toAbsolutePath() - .toFile(), - dispatchers = object : KotlinDispatchers by DefaultKotlinDispatchers { - override val Main: CoroutineDispatcher = ForgeMainDispatcher - } - ) - } - - val apiLocalModule: ApiLocalModule by lazy { - ApiLocalModule( - configFlow = coreModule.configKrate.cachedStateFlow, - ioScope = coreModule.ioScope - ) - } - - val apiRemoteModule: ApiRemoteModule by lazy { - ApiRemoteModule() - } - - val commandModule by lazy { - CommandModule( - commandRegistrarContext = ForgeCommandRegistrarContext( - mainScope = coreModule.mainScope - ) - ) - } - - val eventsModule: EventModule by lazy { - EventModule(coreModule = coreModule) - } - - private val lifecycles: List - get() = listOf( - eventsModule.lifecycle, - commandModule.lifecycle - ) - - val lifecycle: Lifecycle by lazy { - Lifecycle.Lambda( - onEnable = { - lifecycles.forEach(Lifecycle::onEnable) - }, - onDisable = { - lifecycles.forEach(Lifecycle::onDisable) - }, - onReload = { - lifecycles.forEach(Lifecycle::onReload) - } - ) - } -} diff --git a/instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/event/TickEvent.kt b/instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/event/TickEvent.kt deleted file mode 100644 index 9679a8f..0000000 --- a/instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/event/TickEvent.kt +++ /dev/null @@ -1,18 +0,0 @@ -package ru.astrainteractive.astratemplate.event - -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach -import net.minecraftforge.event.TickEvent -import ru.astrainteractive.astralibs.event.flowEvent -import ru.astrainteractive.klibs.mikro.core.logging.JUtiltLogger -import ru.astrainteractive.klibs.mikro.core.logging.Logger - -class TickEvent( - mainScope: CoroutineScope -) : Logger by JUtiltLogger("AstraTemplate-TickEvent") { - - val serverStartedEvent = flowEvent() - .onEach { info { "#serverStartedEvent" } } - .launchIn(mainScope) -} diff --git a/instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/event/di/EventModule.kt b/instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/event/di/EventModule.kt deleted file mode 100644 index 992ddf9..0000000 --- a/instances/neoforge/src/main/java/ru/astrainteractive/astratemplate/event/di/EventModule.kt +++ /dev/null @@ -1,11 +0,0 @@ -package ru.astrainteractive.astratemplate.event.di - -import ru.astrainteractive.astralibs.lifecycle.Lifecycle -import ru.astrainteractive.astratemplate.core.di.CoreModule -import ru.astrainteractive.astratemplate.event.TickEvent - -class EventModule(coreModule: CoreModule) { - @Suppress("UnusedPrivateProperty") - private val tickEvent = TickEvent(coreModule.mainScope) - val lifecycle: Lifecycle = Lifecycle.Empty -} diff --git a/instances/neoforge/src/main/kotlin/ru/astrainteractive/astratemplate/NeoForgeEntryPoint.kt b/instances/neoforge/src/main/kotlin/ru/astrainteractive/astratemplate/NeoForgeEntryPoint.kt new file mode 100755 index 0000000..33fbf35 --- /dev/null +++ b/instances/neoforge/src/main/kotlin/ru/astrainteractive/astratemplate/NeoForgeEntryPoint.kt @@ -0,0 +1,32 @@ +package ru.astrainteractive.astratemplate + +import net.neoforged.fml.common.Mod +import ru.astrainteractive.astralibs.lifecycle.ForgeLifecycleServer +import ru.astrainteractive.klibs.mikro.core.logging.JUtiltLogger +import ru.astrainteractive.klibs.mikro.core.logging.Logger +import javax.annotation.ParametersAreNonnullByDefault +import ru.astrainteractive.aspekt.BuildKonfig +import ru.astrainteractive.astratemplate.di.RootModule + +@Mod(BuildKonfig.id) +@ParametersAreNonnullByDefault +class NeoForgeEntryPoint : + Logger by JUtiltLogger("${BuildKonfig.id}-NeoForgeEntryPoint"), + ForgeLifecycleServer() { + private val rootModule = RootModule() + + override fun onEnable() { + info { "#onEnable" } + rootModule.lifecycle.onEnable() + } + + override fun onDisable() { + info { "#onDisable" } + rootModule.lifecycle.onDisable() + } + + override fun onReload() { + info { "#onReaload" } + rootModule.lifecycle.onReload() + } +} diff --git a/instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt b/instances/neoforge/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt similarity index 51% rename from instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt rename to instances/neoforge/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt index ec639c1..3c3468f 100644 --- a/instances/fabric/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt +++ b/instances/neoforge/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt @@ -1,29 +1,31 @@ package ru.astrainteractive.astratemplate.di +import java.io.File +import net.neoforged.fml.loading.FMLPaths +import ru.astrainteractive.astralibs.command.registrar.NeoForgeCommandRegistrarContext +import ru.astrainteractive.astralibs.coroutines.MinecraftDispatchers import ru.astrainteractive.astralibs.lifecycle.Lifecycle import ru.astrainteractive.astratemplate.api.local.di.ApiLocalModule import ru.astrainteractive.astratemplate.api.remote.di.ApiRemoteModule -import ru.astrainteractive.astratemplate.command.di.CommandModule import ru.astrainteractive.astratemplate.core.di.CoreModule -import ru.astrainteractive.klibs.mikro.core.dispatchers.DefaultKotlinDispatchers +import ru.astrainteractive.astratemplate.feature.event.di.di.EventModule class RootModule { - val fabricModule: FabricModule by lazy { - FabricModule() - } - - val coreModule: CoreModule by lazy { - CoreModule( - dataFolder = fabricModule.configDir, - dispatchers = DefaultKotlinDispatchers - ) - } + private val dataFolder = FMLPaths.CONFIGDIR.get() + .resolve("AspeKt") + .toAbsolutePath() + .toFile() + .also(File::mkdirs) + private val coreModule: CoreModule = CoreModule( + dataFolder = dataFolder, + dispatchers = MinecraftDispatchers() + ) + private val commandRegistrarContext = NeoForgeCommandRegistrarContext(coreModule.mainScope) val apiLocalModule: ApiLocalModule by lazy { ApiLocalModule( - dataFolder = fabricModule.configDir, configFlow = coreModule.configKrate.cachedStateFlow, - scope = coreModule.ioScope + ioScope = coreModule.ioScope ) } @@ -31,16 +33,22 @@ class RootModule { ApiRemoteModule() } - val commandModule: CommandModule by lazy { + + private val commandModule by lazy { CommandModule( - coreModule = coreModule, - apiRemoteModule = apiRemoteModule + commandRegistrarContext = commandRegistrarContext ) } + private val eventsModule by lazy { + EventModule(coreModule = coreModule) + } + private val lifecycles: List get() = listOf( - commandModule.lifecycle + coreModule.lifecycle, + eventsModule.lifecycle, + commandModule.lifecycle, ) val lifecycle: Lifecycle by lazy { diff --git a/instances/neoforge/src/main/resources/META-INF/mods.toml b/instances/neoforge/src/main/resources/META-INF/mods.toml index 96a5ab0..2c93186 100644 --- a/instances/neoforge/src/main/resources/META-INF/mods.toml +++ b/instances/neoforge/src/main/resources/META-INF/mods.toml @@ -1,10 +1,23 @@ -license="MIT" -modLoader="javafml" -loaderVersion="[34,)" +modLoader = "javafml" +loaderVersion = "[1,)" + [[mods]] -modId="${modId}" -version="${version}" -displayName="${displayName}" -authors="${authors}" -logoFile="icon.png" -description="${description}" \ No newline at end of file +modId = "${mod_id}" +version = "${mod_version}" +displayName = "${mod_name}" +authors = "[${mod_authors}]" +description = '''${mod_description}''' + +[[dependencies.${ mod_id }]] +modId = "neoforge" +type = "required" +versionRange = "${neo_version_range}" +ordering = "NONE" +side = "BOTH" + +[[dependencies.${ mod_id }]] +modId = "minecraft" +type = "required" +versionRange = "[${minecraft_version_range}]" +ordering = "NONE" +side = "BOTH" diff --git a/instances/neoforge/src/main/resources/icon.png b/instances/neoforge/src/main/resources/icon.png deleted file mode 100644 index 00201e8ab8644cdad7eccc7a95d063f38db59eb4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5036 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 - val logger = JUtiltLogger("CoroutineExceptionHandler-AspeKt") + val logger = JUtiltLogger("${BuildKonfig.id}-CoroutineExceptionHandler") logger.error(throwable) { "Error happened inside global coroutine scope!" } } diff --git a/modules/feature-command/build.gradle.kts b/modules/feature-command/build.gradle.kts index e0f03c3..7e758bf 100644 --- a/modules/feature-command/build.gradle.kts +++ b/modules/feature-command/build.gradle.kts @@ -18,6 +18,12 @@ dependencies { implementation(libs.minecraft.astralibs.command) implementation(libs.minecraft.astralibs.core) + implementation(projects.modules.core) + implementation(projects.modules.featureGui.api) + implementation(projects.modules.api.remote) + implementation(projects.modules.api.local) + implementation(projects.modules.buildKonfig) + testImplementation(libs.kotlin.coroutines.test) testImplementation(libs.tests.kotlin.test) } diff --git a/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/di/CommandModule.kt b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/di/CommandModule.kt index d948871..6adf271 100644 --- a/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/di/CommandModule.kt +++ b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/di/CommandModule.kt @@ -1,5 +1,6 @@ package ru.astrainteractive.astratemplate.feature.command.di +import ru.astrainteractive.astralibs.command.api.registrar.CommandRegistrarContext import ru.astrainteractive.astralibs.command.api.registrar.PaperCommandRegistrarContext import ru.astrainteractive.astralibs.lifecycle.Lifecycle import ru.astrainteractive.astratemplate.api.remote.di.ApiRemoteModule @@ -13,17 +14,15 @@ import ru.astrainteractive.astratemplate.feature.command.reload.ReloadCommandReg import ru.astrainteractive.astratemplate.feature.command.rickmorty.RickMortyCommandRegistrar import ru.astrainteractive.astratemplate.core.di.CoreModule import ru.astrainteractive.astratemplate.di.BukkitModule +import ru.astrainteractive.astratemplate.feature.gui.di.GuiModule import ru.astrainteractive.astratemplate.gui.di.GuiModule class CommandModule( coreModule: CoreModule, guiModule: GuiModule, apiRemoteModule: ApiRemoteModule, + commandRegistrarContext: CommandRegistrarContext ) { - private val commandRegistrarContext = PaperCommandRegistrarContext( - coreModule.mainScope, - bukkitModule.plugin - ) private val nodes = buildList { val errorHandler = DefaultErrorHandler( translationKrate = coreModule.translationKrate, diff --git a/modules/feature-gui/api/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/di/GuiModule.kt b/modules/feature-gui/api/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/di/GuiModule.kt new file mode 100644 index 0000000..3bda80b --- /dev/null +++ b/modules/feature-gui/api/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/di/GuiModule.kt @@ -0,0 +1,7 @@ +package ru.astrainteractive.astratemplate.feature.gui.di + +import ru.astrainteractive.astratemplate.feature.gui.router.Router + +interface GuiModule { + val router: Router +} \ No newline at end of file diff --git a/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/di/GuiModule.kt b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/di/BukkitGuiModule.kt similarity index 92% rename from modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/di/GuiModule.kt rename to modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/di/BukkitGuiModule.kt index 5569a8c..5f1ea84 100644 --- a/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/di/GuiModule.kt +++ b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/di/BukkitGuiModule.kt @@ -8,12 +8,12 @@ import ru.astrainteractive.astratemplate.feature.gui.domain.SetDisplayNameUseCas import ru.astrainteractive.astratemplate.feature.gui.router.Router import ru.astrainteractive.astratemplate.feature.gui.router.RouterImpl -class GuiModule( +class BukkitGuiModule( coreModule: CoreModule, apiLocalModule: ApiLocalModule -) { +) : GuiModule { private val getRandomColorUseCase = GetRandomColorUseCaseImpl() - val router: Router = RouterImpl( + override val router: Router = RouterImpl( ioScope = coreModule.ioScope, dispatchers = coreModule.dispatchers, kyoriKrate = coreModule.kyoriKrate, From 6205bed6f47394fa6e7637e270c7614816c3075b Mon Sep 17 00:00:00 2001 From: Roman Makeev Date: Sat, 30 May 2026 21:28:23 +0300 Subject: [PATCH 10/16] [REFACTOR] Update commands and GUI --- .../astratemplate/di/RootModule.kt | 13 +- modules/core/build.gradle.kts | 2 + .../astratemplate/core/di/CoreModule.kt | 1 + .../feature/command/additem/AddItemCommand.kt | 7 +- .../command/additem/AddItemCommandRegistry.kt | 42 ++- .../command/additem/AddItemExecutor.kt | 7 +- .../command/common/CommonCommandsRegistry.kt | 27 +- .../command/damage/DamageCommandRegistry.kt | 47 ++- .../feature/command/di/CommandModule.kt | 109 +++---- .../errorhandler/DefaultErrorHandler.kt | 58 ++-- .../feature/command/gui/GuiCommandRegistry.kt | 31 +- .../command/reload/ReloadCommandRegistry.kt | 39 ++- .../rickmorty/RickMortyCommandRegistrar.kt | 62 ++-- .../feature/gui/button/AddUserButton.kt | 20 ++ .../feature/gui/button/BackButton.kt | 20 ++ .../feature/gui/button/BorderButton.kt | 14 + .../feature/gui/button/ChangeModeButton.kt | 21 ++ .../feature/gui/button/ContentSlotButton.kt | 47 +++ .../feature/gui/button/NextPageButton.kt | 20 ++ .../feature/gui/button/PrevPageButton.kt | 20 ++ .../feature/gui/button/di/ButtonContext.kt | 20 ++ .../feature/gui/di/BukkitGuiModule.kt | 6 +- .../DefaultSampleInventoryLayoutFactory.kt | 57 ++++ .../feature/gui/layout/SampleSlotKey.kt | 12 + .../feature/gui/router/RouterImpl.kt | 17 +- .../feature/gui/sample/gui/SampleGUI.kt | 273 +++++++++--------- 26 files changed, 630 insertions(+), 362 deletions(-) create mode 100644 modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/button/AddUserButton.kt create mode 100644 modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/button/BackButton.kt create mode 100644 modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/button/BorderButton.kt create mode 100644 modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/button/ChangeModeButton.kt create mode 100644 modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/button/ContentSlotButton.kt create mode 100644 modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/button/NextPageButton.kt create mode 100644 modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/button/PrevPageButton.kt create mode 100644 modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/button/di/ButtonContext.kt create mode 100644 modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/layout/DefaultSampleInventoryLayoutFactory.kt create mode 100644 modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/layout/SampleSlotKey.kt diff --git a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt b/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt index a0dea3a..020c5f6 100644 --- a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt +++ b/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt @@ -1,12 +1,15 @@ package ru.astrainteractive.astratemplate.di +import ru.astrainteractive.astralibs.command.api.brigadier.command.MultiplatformCommand +import ru.astrainteractive.astralibs.command.api.brigadier.command.PaperMultiplatformCommands +import ru.astrainteractive.astralibs.command.api.registrar.PaperCommandRegistrarContext import ru.astrainteractive.astralibs.coroutines.DefaultBukkitDispatchers import ru.astrainteractive.astralibs.lifecycle.Lifecycle import ru.astrainteractive.astratemplate.AstraTemplate import ru.astrainteractive.astratemplate.api.local.di.ApiLocalModule import ru.astrainteractive.astratemplate.api.remote.di.ApiRemoteModule -import ru.astrainteractive.astratemplate.feature.command.di.CommandModule import ru.astrainteractive.astratemplate.core.di.CoreModule +import ru.astrainteractive.astratemplate.feature.command.di.CommandModule import ru.astrainteractive.astratemplate.feature.event.di.EventModule import ru.astrainteractive.astratemplate.feature.gui.di.BukkitGuiModule @@ -32,7 +35,13 @@ internal class RootModule(plugin: AstraTemplate) { val commandModule: CommandModule = CommandModule( coreModule = coreModule, apiRemoteModule = apiRemoteModule, - guiModule = guiModule + guiModule = guiModule, + lifecyclePlugin = plugin, + commandRegistrarContext = PaperCommandRegistrarContext( + mainScope = coreModule.mainScope, + plugin = plugin + ), + multiplatformCommand = MultiplatformCommand(PaperMultiplatformCommands()) ) private val lifecycles: List diff --git a/modules/core/build.gradle.kts b/modules/core/build.gradle.kts index c673eb2..3267469 100644 --- a/modules/core/build.gradle.kts +++ b/modules/core/build.gradle.kts @@ -15,4 +15,6 @@ dependencies { implementation(libs.klibs.mikro.core) implementation(libs.klibs.mikro.extensions) api(libs.klibs.kstorage) + + implementation(projects.modules.buildKonfig) } diff --git a/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/di/CoreModule.kt b/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/di/CoreModule.kt index f956411..2c8a880 100644 --- a/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/di/CoreModule.kt +++ b/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/di/CoreModule.kt @@ -8,6 +8,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.cancel import kotlinx.serialization.StringFormat +import ru.astrainteractive.aspekt.BuildKonfig import ru.astrainteractive.astralibs.coroutines.withTimings import ru.astrainteractive.astralibs.kyori.KyoriComponentSerializer import ru.astrainteractive.astralibs.lifecycle.Lifecycle diff --git a/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/additem/AddItemCommand.kt b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/additem/AddItemCommand.kt index 9d03aa6..470eeb8 100644 --- a/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/additem/AddItemCommand.kt +++ b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/additem/AddItemCommand.kt @@ -1,14 +1,13 @@ package ru.astrainteractive.astratemplate.feature.command.additem -import org.bukkit.Material -import org.bukkit.entity.Player import ru.astrainteractive.astralibs.command.api.exception.CommandException +import ru.astrainteractive.astralibs.server.player.OnlineKPlayer internal interface AddItemCommand { class Result( - val player: Player, + val player: OnlineKPlayer, val amount: Int, - val item: Material + val itemName: String ) sealed class Error(message: String) : CommandException(message) { diff --git a/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/additem/AddItemCommandRegistry.kt b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/additem/AddItemCommandRegistry.kt index 7e551e8..cae8bad 100644 --- a/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/additem/AddItemCommandRegistry.kt +++ b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/additem/AddItemCommandRegistry.kt @@ -2,16 +2,10 @@ package ru.astrainteractive.astratemplate.feature.command.additem import com.mojang.brigadier.arguments.IntegerArgumentType import com.mojang.brigadier.arguments.StringArgumentType -import com.mojang.brigadier.tree.LiteralCommandNode -import io.papermc.paper.command.brigadier.CommandSourceStack -import org.bukkit.Bukkit -import org.bukkit.Material +import com.mojang.brigadier.builder.LiteralArgumentBuilder import ru.astrainteractive.astralibs.command.api.argumenttype.ArgumentConverter -import ru.astrainteractive.astralibs.command.api.exception.NoPlayerException -import ru.astrainteractive.astralibs.command.api.util.argument -import ru.astrainteractive.astralibs.command.api.util.command -import ru.astrainteractive.astralibs.command.api.util.requireArgument -import ru.astrainteractive.astralibs.command.api.util.runs +import ru.astrainteractive.astralibs.command.api.brigadier.command.MultiplatformCommand +import ru.astrainteractive.astralibs.command.api.registrar.CommandRegistrarContext import ru.astrainteractive.astralibs.kyori.KyoriComponentSerializer import ru.astrainteractive.astralibs.kyori.unwrap import ru.astrainteractive.astratemplate.feature.command.errorhandler.DefaultErrorHandler @@ -19,38 +13,42 @@ import ru.astrainteractive.klibs.kstorage.api.CachedKrate internal class AddItemCommandRegistry( kyoriKrate: CachedKrate, + private val registrarContext: CommandRegistrarContext, + private val multiplatformCommand: MultiplatformCommand, private val errorHandler: DefaultErrorHandler, private val executor: AddItemExecutor ) : KyoriComponentSerializer by kyoriKrate.unwrap() { - private object MaterialArgumentConverter : ArgumentConverter { - override fun transform(argument: String): Material { - return Material.getMaterial(argument) ?: throw AddItemCommand.Error.ItemNotfound() + + private object ItemNameArgumentConverter : ArgumentConverter { + override fun transform(argument: String): String { + return argument.takeIf { it.isNotBlank() } ?: throw AddItemCommand.Error.ItemNotfound() } } - fun createNode(): LiteralCommandNode { - return command("add") { - argument("player", StringArgumentType.word()) { playerArg -> + private fun createNode(): LiteralArgumentBuilder<*> { + return with(multiplatformCommand) { + command("add") { argument("material", StringArgumentType.word()) { materialArg -> argument("amount", IntegerArgumentType.integer(1, 64)) { amountArg -> runs(errorHandler::handle) { ctx -> - val playerName = ctx.requireArgument(playerArg) - val player = Bukkit.getPlayerExact(playerName) ?: throw NoPlayerException(playerName) - - val material = ctx.requireArgument(materialArg, MaterialArgumentConverter) - + val player = ctx.requirePlayer() + val itemName = ctx.requireArgument(materialArg, ItemNameArgumentConverter) val amount = ctx.requireArgument(amountArg) executor.execute( AddItemCommand.Result( player = player, amount = amount, - item = material + itemName = itemName ) ) } } } } - }.build() + } + } + + fun register() { + registrarContext.registerWhenReady(createNode()) } } diff --git a/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/additem/AddItemExecutor.kt b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/additem/AddItemExecutor.kt index 6fa2c78..f304b85 100644 --- a/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/additem/AddItemExecutor.kt +++ b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/additem/AddItemExecutor.kt @@ -1,10 +1,11 @@ package ru.astrainteractive.astratemplate.feature.command.additem -import org.bukkit.inventory.ItemStack +import net.kyori.adventure.text.Component internal class AddItemExecutor { fun execute(input: AddItemCommand.Result) { - val itemStack = ItemStack(input.item, input.amount) - input.player.inventory.addItem(itemStack) + input.player.sendMessage( + Component.text("Added ${input.amount}x ${input.itemName}") + ) } } diff --git a/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/common/CommonCommandsRegistry.kt b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/common/CommonCommandsRegistry.kt index a432709..1981649 100644 --- a/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/common/CommonCommandsRegistry.kt +++ b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/common/CommonCommandsRegistry.kt @@ -1,9 +1,8 @@ package ru.astrainteractive.astratemplate.feature.command.common -import com.mojang.brigadier.tree.LiteralCommandNode -import io.papermc.paper.command.brigadier.CommandSourceStack -import ru.astrainteractive.astralibs.command.api.util.command -import ru.astrainteractive.astralibs.command.api.util.runs +import com.mojang.brigadier.builder.LiteralArgumentBuilder +import ru.astrainteractive.astralibs.command.api.brigadier.command.MultiplatformCommand +import ru.astrainteractive.astralibs.command.api.registrar.CommandRegistrarContext import ru.astrainteractive.astralibs.kyori.KyoriComponentSerializer import ru.astrainteractive.astralibs.kyori.unwrap import ru.astrainteractive.astratemplate.core.plugin.PluginTranslation @@ -12,15 +11,23 @@ import ru.astrainteractive.klibs.kstorage.util.getValue internal class CommonCommandsRegistry( translationKrate: CachedKrate, - kyoriKrate: CachedKrate + kyoriKrate: CachedKrate, + private val registrarContext: CommandRegistrarContext, + private val multiplatformCommand: MultiplatformCommand ) : KyoriComponentSerializer by kyoriKrate.unwrap() { private val translation by translationKrate - fun createNode(): LiteralCommandNode { - return command("translation") { - runs { ctx -> - ctx.source.sender.sendMessage(translation.general.getByByCheck.component) + private fun createNode(): LiteralArgumentBuilder<*> { + return with(multiplatformCommand) { + command("translation") { + runs { ctx -> + ctx.getSender().sendMessage(translation.general.getByByCheck.component) + } } - }.build() + } + } + + fun register() { + registrarContext.registerWhenReady(createNode()) } } diff --git a/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/damage/DamageCommandRegistry.kt b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/damage/DamageCommandRegistry.kt index 06a0d7f..bd5cf06 100644 --- a/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/damage/DamageCommandRegistry.kt +++ b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/damage/DamageCommandRegistry.kt @@ -1,53 +1,48 @@ package ru.astrainteractive.astratemplate.feature.command.damage import com.mojang.brigadier.arguments.DoubleArgumentType -import com.mojang.brigadier.arguments.StringArgumentType -import com.mojang.brigadier.tree.LiteralCommandNode -import io.papermc.paper.command.brigadier.CommandSourceStack -import org.bukkit.Bukkit -import ru.astrainteractive.astralibs.command.api.exception.NoPlayerException -import ru.astrainteractive.astralibs.command.api.util.argument -import ru.astrainteractive.astralibs.command.api.util.command -import ru.astrainteractive.astralibs.command.api.util.requireArgument -import ru.astrainteractive.astralibs.command.api.util.requirePermission -import ru.astrainteractive.astralibs.command.api.util.runs +import com.mojang.brigadier.builder.LiteralArgumentBuilder +import ru.astrainteractive.astralibs.command.api.brigadier.command.MultiplatformCommand +import ru.astrainteractive.astralibs.command.api.registrar.CommandRegistrarContext import ru.astrainteractive.astralibs.kyori.KyoriComponentSerializer import ru.astrainteractive.astralibs.kyori.unwrap -import ru.astrainteractive.astratemplate.feature.command.errorhandler.DefaultErrorHandler import ru.astrainteractive.astratemplate.core.plugin.PluginPermission import ru.astrainteractive.astratemplate.core.plugin.PluginTranslation +import ru.astrainteractive.astratemplate.feature.command.errorhandler.DefaultErrorHandler import ru.astrainteractive.klibs.kstorage.api.CachedKrate +import ru.astrainteractive.klibs.kstorage.api.getValue internal class DamageCommandRegistry( translationKrate: CachedKrate, kyoriKrate: CachedKrate, + private val registrarContext: CommandRegistrarContext, + private val multiplatformCommand: MultiplatformCommand, private val errorHandler: DefaultErrorHandler ) : KyoriComponentSerializer by kyoriKrate.unwrap() { private val translation by translationKrate - fun createNode(): LiteralCommandNode { - return command("adamage") { - argument("player", StringArgumentType.word()) { playerArg -> + private fun createNode(): LiteralArgumentBuilder<*> { + return with(multiplatformCommand) { + command("adamage") { runs(errorHandler::handle) { ctx -> ctx.requirePermission(PluginPermission.Damage) - - val playerName = ctx.requireArgument(playerArg) - val player = Bukkit.getPlayerExact(playerName) ?: throw NoPlayerException(playerName) - player.sendMessage(translation.custom.damaged(ctx.source.sender.name).component) - player.damage(0.0) + val player = ctx.requirePlayer() + player.sendMessage(translation.custom.damaged(player.name).component) } argument("damage", DoubleArgumentType.doubleArg(0.0)) { damageArg -> runs(errorHandler::handle) { ctx -> ctx.requirePermission(PluginPermission.Damage) - - val playerName = ctx.requireArgument(playerArg) - val player = Bukkit.getPlayerExact(playerName) ?: throw NoPlayerException(playerName) - val damage = ctx.requireArgument(damageArg) - player.sendMessage(translation.custom.damaged(ctx.source.sender.name).component) - player.damage(damage) + val player = ctx.requirePlayer() + ctx.requireArgument(damageArg) + player.sendMessage(translation.custom.damaged(player.name).component) + player.sendMessage(translation.custom.damageHint.component) } } } - }.build() + } + } + + fun register() { + registrarContext.registerWhenReady(createNode()) } } diff --git a/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/di/CommandModule.kt b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/di/CommandModule.kt index 6adf271..c545f5e 100644 --- a/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/di/CommandModule.kt +++ b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/di/CommandModule.kt @@ -1,9 +1,10 @@ package ru.astrainteractive.astratemplate.feature.command.di +import ru.astrainteractive.astralibs.command.api.brigadier.command.MultiplatformCommand import ru.astrainteractive.astralibs.command.api.registrar.CommandRegistrarContext -import ru.astrainteractive.astralibs.command.api.registrar.PaperCommandRegistrarContext import ru.astrainteractive.astralibs.lifecycle.Lifecycle import ru.astrainteractive.astratemplate.api.remote.di.ApiRemoteModule +import ru.astrainteractive.astratemplate.core.di.CoreModule import ru.astrainteractive.astratemplate.feature.command.additem.AddItemCommandRegistry import ru.astrainteractive.astratemplate.feature.command.additem.AddItemExecutor import ru.astrainteractive.astratemplate.feature.command.common.CommonCommandsRegistry @@ -12,59 +13,69 @@ import ru.astrainteractive.astratemplate.feature.command.errorhandler.DefaultErr import ru.astrainteractive.astratemplate.feature.command.gui.GuiCommandRegistry import ru.astrainteractive.astratemplate.feature.command.reload.ReloadCommandRegistry import ru.astrainteractive.astratemplate.feature.command.rickmorty.RickMortyCommandRegistrar -import ru.astrainteractive.astratemplate.core.di.CoreModule -import ru.astrainteractive.astratemplate.di.BukkitModule import ru.astrainteractive.astratemplate.feature.gui.di.GuiModule -import ru.astrainteractive.astratemplate.gui.di.GuiModule class CommandModule( - coreModule: CoreModule, - guiModule: GuiModule, - apiRemoteModule: ApiRemoteModule, - commandRegistrarContext: CommandRegistrarContext + private val coreModule: CoreModule, + private val guiModule: GuiModule, + private val apiRemoteModule: ApiRemoteModule, + private val lifecyclePlugin: Lifecycle, + private val commandRegistrarContext: CommandRegistrarContext, + private val multiplatformCommand: MultiplatformCommand ) { - private val nodes = buildList { - val errorHandler = DefaultErrorHandler( - translationKrate = coreModule.translationKrate, - kyoriKrate = bukkitModule.kyoriKrate - ) - AddItemCommandRegistry( - kyoriKrate = bukkitModule.kyoriKrate, - errorHandler = errorHandler, - executor = AddItemExecutor() - ).createNode().run(::add) - CommonCommandsRegistry( - kyoriKrate = bukkitModule.kyoriKrate, + private val errorHandler by lazy { + DefaultErrorHandler( + multiplatformCommand = multiplatformCommand, translationKrate = coreModule.translationKrate, - ).createNode().run(::add) - DamageCommandRegistry( - errorHandler = errorHandler, - kyoriKrate = bukkitModule.kyoriKrate, - translationKrate = coreModule.translationKrate, - ).createNode().run(::add) - GuiCommandRegistry( - router = guiModule.router, - kyoriKrate = bukkitModule.kyoriKrate, - errorHandler = errorHandler, - ).createNode().run(::add) - ReloadCommandRegistry( - plugin = bukkitModule.plugin, - translationKrate = coreModule.translationKrate, - kyoriKrate = bukkitModule.kyoriKrate, - errorHandler = errorHandler, - ).createNode().run(::add) - RickMortyCommandRegistrar( - scope = coreModule.ioScope, - dispatchers = coreModule.dispatchers, - rmApi = apiRemoteModule.rickMortyApi, - errorHandler = errorHandler, - ).createNode().run(::add) - } - val lifecycle: Lifecycle by lazy { - Lifecycle.Lambda( - onEnable = { - nodes.forEach(commandRegistrarContext::registerWhenReady) - } + kyoriKrate = coreModule.kyoriKrate ) } + + val lifecycle: Lifecycle = Lifecycle.Lambda( + onEnable = { + AddItemCommandRegistry( + kyoriKrate = coreModule.kyoriKrate, + registrarContext = commandRegistrarContext, + multiplatformCommand = multiplatformCommand, + errorHandler = errorHandler, + executor = AddItemExecutor() + ).register() + CommonCommandsRegistry( + kyoriKrate = coreModule.kyoriKrate, + translationKrate = coreModule.translationKrate, + registrarContext = commandRegistrarContext, + multiplatformCommand = multiplatformCommand + ).register() + DamageCommandRegistry( + kyoriKrate = coreModule.kyoriKrate, + translationKrate = coreModule.translationKrate, + registrarContext = commandRegistrarContext, + multiplatformCommand = multiplatformCommand, + errorHandler = errorHandler + ).register() + GuiCommandRegistry( + kyoriKrate = coreModule.kyoriKrate, + registrarContext = commandRegistrarContext, + multiplatformCommand = multiplatformCommand, + router = guiModule.router, + errorHandler = errorHandler + ).register() + ReloadCommandRegistry( + kyoriKrate = coreModule.kyoriKrate, + translationKrate = coreModule.translationKrate, + lifecyclePlugin = lifecyclePlugin, + registrarContext = commandRegistrarContext, + multiplatformCommand = multiplatformCommand, + errorHandler = errorHandler + ).register() + RickMortyCommandRegistrar( + scope = coreModule.ioScope, + dispatchers = coreModule.dispatchers, + rmApi = apiRemoteModule.rickMortyApi, + registrarContext = commandRegistrarContext, + multiplatformCommand = multiplatformCommand, + errorHandler = errorHandler + ).register() + } + ) } diff --git a/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/errorhandler/DefaultErrorHandler.kt b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/errorhandler/DefaultErrorHandler.kt index 4a076db..011e4ee 100644 --- a/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/errorhandler/DefaultErrorHandler.kt +++ b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/errorhandler/DefaultErrorHandler.kt @@ -1,57 +1,53 @@ package ru.astrainteractive.astratemplate.feature.command.errorhandler import com.mojang.brigadier.context.CommandContext -import io.papermc.paper.command.brigadier.CommandSourceStack +import ru.astrainteractive.astralibs.command.api.brigadier.command.MultiplatformCommand import ru.astrainteractive.astralibs.command.api.exception.ArgumentConverterException import ru.astrainteractive.astralibs.command.api.exception.BadArgumentException import ru.astrainteractive.astralibs.command.api.exception.NoPermissionException -import ru.astrainteractive.astralibs.command.api.exception.NoPlayerException import ru.astrainteractive.astralibs.command.api.exception.NoPotionEffectTypeException import ru.astrainteractive.astralibs.kyori.KyoriComponentSerializer import ru.astrainteractive.astralibs.kyori.unwrap -import ru.astrainteractive.astratemplate.feature.command.additem.AddItemCommand import ru.astrainteractive.astratemplate.core.plugin.PluginTranslation +import ru.astrainteractive.astratemplate.feature.command.additem.AddItemCommand import ru.astrainteractive.klibs.kstorage.api.CachedKrate +import ru.astrainteractive.klibs.kstorage.api.getValue import ru.astrainteractive.klibs.mikro.core.logging.JUtiltLogger import ru.astrainteractive.klibs.mikro.core.logging.Logger internal class DefaultErrorHandler( + private val multiplatformCommand: MultiplatformCommand, translationKrate: CachedKrate, kyoriKrate: CachedKrate ) : Logger by JUtiltLogger("AstraTemplate-DefaultErrorHandler"), KyoriComponentSerializer by kyoriKrate.unwrap() { private val translation by translationKrate - fun handle(ctx: CommandContext, throwable: Throwable) { - when (throwable) { - is AddItemCommand.Error -> { - when (throwable) { - is AddItemCommand.Error.ItemNotfound -> { - ctx.source.sender.sendMessage(translation.fault.itemNotFound.component) - } - - is AddItemCommand.Error.SenderNotPlayer -> { - ctx.source.sender.sendMessage(translation.fault.notPlayer.component) + fun handle(ctx: CommandContext, throwable: Throwable) { + with(multiplatformCommand) { + val sender = ctx.getSender() + when (throwable) { + is AddItemCommand.Error -> { + when (throwable) { + is AddItemCommand.Error.ItemNotfound -> { + sender.sendMessage(translation.fault.itemNotFound.component) + } + is AddItemCommand.Error.SenderNotPlayer -> { + sender.sendMessage(translation.fault.notPlayer.component) + } } } - } - - is NoPlayerException -> { - ctx.source.sender.sendMessage(translation.fault.playerNotExists.component) - } - - is NoPermissionException -> { - ctx.source.sender.sendMessage(translation.fault.noPermission.component) - } - - is NoPotionEffectTypeException, - is BadArgumentException, - is ArgumentConverterException -> { - error { "#handle intentionally unhandled error: $throwable" } - } - - else -> { - error { "#handle unhandled error: $throwable" } + is NoPermissionException -> { + sender.sendMessage(translation.fault.noPermission.component) + } + is NoPotionEffectTypeException, + is BadArgumentException, + is ArgumentConverterException -> { + error { "#handle intentionally unhandled error: $throwable" } + } + else -> { + error { "#handle unhandled error: $throwable" } + } } } } diff --git a/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/gui/GuiCommandRegistry.kt b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/gui/GuiCommandRegistry.kt index 6c6a1c9..313fb57 100644 --- a/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/gui/GuiCommandRegistry.kt +++ b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/gui/GuiCommandRegistry.kt @@ -1,29 +1,34 @@ package ru.astrainteractive.astratemplate.feature.command.gui -import com.mojang.brigadier.tree.LiteralCommandNode -import io.papermc.paper.command.brigadier.CommandSourceStack -import ru.astrainteractive.astralibs.command.api.util.command -import ru.astrainteractive.astralibs.command.api.util.requirePlayer -import ru.astrainteractive.astralibs.command.api.util.runs +import com.mojang.brigadier.builder.LiteralArgumentBuilder +import ru.astrainteractive.astralibs.command.api.brigadier.command.MultiplatformCommand +import ru.astrainteractive.astralibs.command.api.registrar.CommandRegistrarContext import ru.astrainteractive.astralibs.kyori.KyoriComponentSerializer import ru.astrainteractive.astralibs.kyori.unwrap import ru.astrainteractive.astratemplate.feature.command.errorhandler.DefaultErrorHandler -import ru.astrainteractive.astratemplate.gui.router.Router +import ru.astrainteractive.astratemplate.feature.gui.router.Router import ru.astrainteractive.klibs.kstorage.api.CachedKrate internal class GuiCommandRegistry( kyoriKrate: CachedKrate, + private val registrarContext: CommandRegistrarContext, + private val multiplatformCommand: MultiplatformCommand, private val router: Router, private val errorHandler: DefaultErrorHandler ) : KyoriComponentSerializer by kyoriKrate.unwrap() { - fun createNode(): LiteralCommandNode { - return command("atempgui") { - runs(errorHandler::handle) { ctx -> - val player = ctx.requirePlayer() - val route = Router.Route.Sample - router.open(player, route) + private fun createNode(): LiteralArgumentBuilder<*> { + return with(multiplatformCommand) { + command("atempgui") { + runs(errorHandler::handle) { ctx -> + val player = ctx.requirePlayer() + router.open(player, Router.Route.Sample) + } } - }.build() + } + } + + fun register() { + registrarContext.registerWhenReady(createNode()) } } diff --git a/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/reload/ReloadCommandRegistry.kt b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/reload/ReloadCommandRegistry.kt index e78ba0c..c53181d 100644 --- a/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/reload/ReloadCommandRegistry.kt +++ b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/reload/ReloadCommandRegistry.kt @@ -1,34 +1,41 @@ package ru.astrainteractive.astratemplate.feature.command.reload -import com.mojang.brigadier.tree.LiteralCommandNode -import io.papermc.paper.command.brigadier.CommandSourceStack -import ru.astrainteractive.astralibs.command.api.util.command -import ru.astrainteractive.astralibs.command.api.util.requirePermission -import ru.astrainteractive.astralibs.command.api.util.runs +import com.mojang.brigadier.builder.LiteralArgumentBuilder +import ru.astrainteractive.astralibs.command.api.brigadier.command.MultiplatformCommand +import ru.astrainteractive.astralibs.command.api.registrar.CommandRegistrarContext import ru.astrainteractive.astralibs.kyori.KyoriComponentSerializer import ru.astrainteractive.astralibs.kyori.unwrap -import ru.astrainteractive.astralibs.lifecycle.LifecyclePlugin -import ru.astrainteractive.astratemplate.feature.command.errorhandler.DefaultErrorHandler +import ru.astrainteractive.astralibs.lifecycle.Lifecycle import ru.astrainteractive.astratemplate.core.plugin.PluginPermission import ru.astrainteractive.astratemplate.core.plugin.PluginTranslation +import ru.astrainteractive.astratemplate.feature.command.errorhandler.DefaultErrorHandler import ru.astrainteractive.klibs.kstorage.api.CachedKrate +import ru.astrainteractive.klibs.kstorage.api.getValue internal class ReloadCommandRegistry( translationKrate: CachedKrate, kyoriKrate: CachedKrate, - private val plugin: LifecyclePlugin, + private val lifecyclePlugin: Lifecycle, + private val registrarContext: CommandRegistrarContext, + private val multiplatformCommand: MultiplatformCommand, private val errorHandler: DefaultErrorHandler ) : KyoriComponentSerializer by kyoriKrate.unwrap() { private val translation by translationKrate - fun createNode(): LiteralCommandNode { - return command("atempreload") { - runs(errorHandler::handle) { ctx -> - ctx.requirePermission(PluginPermission.Damage) - ctx.source.sender.sendMessage(translation.general.reload.component) - plugin.onReload() - ctx.source.sender.sendMessage(translation.general.reloadComplete.component) + private fun createNode(): LiteralArgumentBuilder<*> { + return with(multiplatformCommand) { + command("atempreload") { + runs(errorHandler::handle) { ctx -> + ctx.requirePermission(PluginPermission.Reload) + ctx.getSender().sendMessage(translation.general.reload.component) + lifecyclePlugin.onReload() + ctx.getSender().sendMessage(translation.general.reloadComplete.component) + } } - }.build() + } + } + + fun register() { + registrarContext.registerWhenReady(createNode()) } } diff --git a/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/rickmorty/RickMortyCommandRegistrar.kt b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/rickmorty/RickMortyCommandRegistrar.kt index 9a63596..7c98dc5 100644 --- a/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/rickmorty/RickMortyCommandRegistrar.kt +++ b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/rickmorty/RickMortyCommandRegistrar.kt @@ -1,16 +1,12 @@ package ru.astrainteractive.astratemplate.feature.command.rickmorty import com.mojang.brigadier.arguments.IntegerArgumentType -import com.mojang.brigadier.tree.LiteralCommandNode -import io.papermc.paper.command.brigadier.CommandSourceStack +import com.mojang.brigadier.builder.LiteralArgumentBuilder import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch -import org.bukkit.command.CommandSender -import ru.astrainteractive.astralibs.command.api.util.argument -import ru.astrainteractive.astralibs.command.api.util.command -import ru.astrainteractive.astralibs.command.api.util.literal -import ru.astrainteractive.astralibs.command.api.util.requireArgument -import ru.astrainteractive.astralibs.command.api.util.runs +import ru.astrainteractive.astralibs.command.api.brigadier.command.MultiplatformCommand +import ru.astrainteractive.astralibs.command.api.brigadier.sender.KCommandSender +import ru.astrainteractive.astralibs.command.api.registrar.CommandRegistrarContext import ru.astrainteractive.astratemplate.api.remote.api.RickMortyApi import ru.astrainteractive.astratemplate.feature.command.errorhandler.DefaultErrorHandler import ru.astrainteractive.klibs.mikro.core.dispatchers.KotlinDispatchers @@ -20,42 +16,38 @@ internal class RickMortyCommandRegistrar( private val scope: CoroutineScope, private val dispatchers: KotlinDispatchers, private val rmApi: RickMortyApi, + private val registrarContext: CommandRegistrarContext, + private val multiplatformCommand: MultiplatformCommand, private val errorHandler: DefaultErrorHandler ) { - - private fun send(sender: CommandSender, number: Int) { + private fun send(sender: KCommandSender, number: Int) { scope.launch(dispatchers.IO) { - val result = rmApi.getRandomCharacter(number) - result.onSuccess { - sender.sendMessage("Got response: $it") - } - result.onFailure { - it.printStackTrace() - sender.sendMessage("Fail: ${it.message}") - } + rmApi.getRandomCharacter(number) + .onSuccess { sender.sendMessage(net.kyori.adventure.text.Component.text("Got response: $it")) } + .onFailure { sender.sendMessage(net.kyori.adventure.text.Component.text("Fail: ${it.message}")) } } } - fun createNode(): LiteralCommandNode { - return command("rickandmorty") { - literal("random") { - runs(errorHandler::handle) { ctx -> - send( - sender = ctx.source.sender, - number = Random.nextInt(0, 100) - ) - } - } - literal("specific") { - argument("number", IntegerArgumentType.integer()) { numberArg -> + private fun createNode(): LiteralArgumentBuilder<*> { + return with(multiplatformCommand) { + command("rickandmorty") { + literal("random") { runs(errorHandler::handle) { ctx -> - send( - sender = ctx.source.sender, - number = ctx.requireArgument(numberArg) - ) + send(ctx.getSender(), Random.nextInt(0, 100)) + } + } + literal("specific") { + argument("number", IntegerArgumentType.integer()) { numberArg -> + runs(errorHandler::handle) { ctx -> + send(ctx.getSender(), ctx.requireArgument(numberArg)) + } } } } - }.build() + } + } + + fun register() { + registrarContext.registerWhenReady(createNode()) } } diff --git a/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/button/AddUserButton.kt b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/button/AddUserButton.kt new file mode 100644 index 0000000..35db909 --- /dev/null +++ b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/button/AddUserButton.kt @@ -0,0 +1,20 @@ +package ru.astrainteractive.astratemplate.feature.gui.button + +import org.bukkit.Material +import ru.astrainteractive.astralibs.menu.clicker.Click +import ru.astrainteractive.astralibs.menu.slot.InventorySlot +import ru.astrainteractive.astralibs.menu.slot.setDisplayName +import ru.astrainteractive.astralibs.menu.slot.setIndex +import ru.astrainteractive.astralibs.menu.slot.setMaterial +import ru.astrainteractive.astralibs.menu.slot.setOnClickListener +import ru.astrainteractive.astratemplate.feature.gui.button.di.ButtonContext + +internal fun ButtonContext.addUser( + index: Int, + click: Click +) = InventorySlot.Builder() + .setIndex(index) + .setMaterial(Material.EMERALD) + .setDisplayName(toComponent(translation.menu.menuAddPlayer)) + .setOnClickListener(click) + .build() diff --git a/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/button/BackButton.kt b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/button/BackButton.kt new file mode 100644 index 0000000..6ec0425 --- /dev/null +++ b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/button/BackButton.kt @@ -0,0 +1,20 @@ +package ru.astrainteractive.astratemplate.feature.gui.button + +import org.bukkit.Material +import ru.astrainteractive.astralibs.menu.clicker.Click +import ru.astrainteractive.astralibs.menu.slot.InventorySlot +import ru.astrainteractive.astralibs.menu.slot.setDisplayName +import ru.astrainteractive.astralibs.menu.slot.setIndex +import ru.astrainteractive.astralibs.menu.slot.setMaterial +import ru.astrainteractive.astralibs.menu.slot.setOnClickListener +import ru.astrainteractive.astratemplate.feature.gui.button.di.ButtonContext + +internal fun ButtonContext.back( + index: Int, + click: Click +) = InventorySlot.Builder() + .setIndex(index) + .setMaterial(Material.BARRIER) + .setDisplayName(toComponent(translation.menu.menuBack)) + .setOnClickListener(click) + .build() diff --git a/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/button/BorderButton.kt b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/button/BorderButton.kt new file mode 100644 index 0000000..3b22fc9 --- /dev/null +++ b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/button/BorderButton.kt @@ -0,0 +1,14 @@ +package ru.astrainteractive.astratemplate.feature.gui.button + +import org.bukkit.Material +import ru.astrainteractive.astralibs.menu.slot.InventorySlot +import ru.astrainteractive.astralibs.menu.slot.setDisplayName +import ru.astrainteractive.astralibs.menu.slot.setIndex +import ru.astrainteractive.astralibs.menu.slot.setMaterial +import ru.astrainteractive.astratemplate.feature.gui.button.di.ButtonContext + +internal fun ButtonContext.border(index: Int) = InventorySlot.Builder() + .setIndex(index) + .setMaterial(Material.GRAY_STAINED_GLASS_PANE) + .setDisplayName(" ") + .build() diff --git a/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/button/ChangeModeButton.kt b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/button/ChangeModeButton.kt new file mode 100644 index 0000000..77afbb4 --- /dev/null +++ b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/button/ChangeModeButton.kt @@ -0,0 +1,21 @@ +package ru.astrainteractive.astratemplate.feature.gui.button + +import org.bukkit.Material +import ru.astrainteractive.astralibs.menu.clicker.Click +import ru.astrainteractive.astralibs.menu.slot.InventorySlot +import ru.astrainteractive.astralibs.menu.slot.setDisplayName +import ru.astrainteractive.astralibs.menu.slot.setIndex +import ru.astrainteractive.astralibs.menu.slot.setMaterial +import ru.astrainteractive.astralibs.menu.slot.setOnClickListener +import ru.astrainteractive.astratemplate.feature.gui.button.di.ButtonContext + +internal fun ButtonContext.changeMode( + index: Int, + label: String, + click: Click +) = InventorySlot.Builder() + .setIndex(index) + .setMaterial(Material.SUNFLOWER) + .setDisplayName(label) + .setOnClickListener(click) + .build() diff --git a/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/button/ContentSlotButton.kt b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/button/ContentSlotButton.kt new file mode 100644 index 0000000..8ddcda0 --- /dev/null +++ b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/button/ContentSlotButton.kt @@ -0,0 +1,47 @@ +package ru.astrainteractive.astratemplate.feature.gui.button + +import net.kyori.adventure.text.Component +import org.bukkit.ChatColor +import org.bukkit.Material +import org.bukkit.inventory.ItemStack +import ru.astrainteractive.astralibs.menu.clicker.Click +import ru.astrainteractive.astralibs.menu.slot.InventorySlot +import ru.astrainteractive.astralibs.menu.slot.setDisplayName +import ru.astrainteractive.astralibs.menu.slot.setIndex +import ru.astrainteractive.astralibs.menu.slot.setItemStack +import ru.astrainteractive.astralibs.menu.slot.setLore +import ru.astrainteractive.astralibs.menu.slot.setMaterial +import ru.astrainteractive.astralibs.menu.slot.setOnClickListener +import ru.astrainteractive.astratemplate.api.local.model.UserModel +import ru.astrainteractive.astratemplate.feature.gui.button.di.ButtonContext + +internal fun ButtonContext.itemSlot( + index: Int, + itemStack: ItemStack, + click: Click +) = InventorySlot.Builder() + .setIndex(index) + .setItemStack(itemStack) + .setOnClickListener(click) + .build() + +internal fun ButtonContext.userSlot( + index: Int, + user: UserModel, + randomColor: ChatColor, + click: Click +) = InventorySlot.Builder() + .setIndex(index) + .setMaterial(Material.PLAYER_HEAD) + .setDisplayName(user.id.toString()) + .setLore( + listOf( + "${randomColor}discordID: ${user.discordId}", + "${randomColor}minecraftUUID: ${user.minecraftUUID}", + "${randomColor}Press LeftClick to delete user", + "${randomColor}Press MiddleClick to update user", + "${randomColor}Press RightClick to add relation" + ).map(Component::text) + ) + .setOnClickListener(click) + .build() diff --git a/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/button/NextPageButton.kt b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/button/NextPageButton.kt new file mode 100644 index 0000000..07aa792 --- /dev/null +++ b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/button/NextPageButton.kt @@ -0,0 +1,20 @@ +package ru.astrainteractive.astratemplate.feature.gui.button + +import org.bukkit.Material +import ru.astrainteractive.astralibs.menu.clicker.Click +import ru.astrainteractive.astralibs.menu.slot.InventorySlot +import ru.astrainteractive.astralibs.menu.slot.setDisplayName +import ru.astrainteractive.astralibs.menu.slot.setIndex +import ru.astrainteractive.astralibs.menu.slot.setMaterial +import ru.astrainteractive.astralibs.menu.slot.setOnClickListener +import ru.astrainteractive.astratemplate.feature.gui.button.di.ButtonContext + +internal fun ButtonContext.nextPage( + index: Int, + click: Click +) = InventorySlot.Builder() + .setIndex(index) + .setMaterial(Material.PAPER) + .setDisplayName(toComponent(translation.menu.menuNextPage)) + .setOnClickListener(click) + .build() diff --git a/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/button/PrevPageButton.kt b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/button/PrevPageButton.kt new file mode 100644 index 0000000..501aca8 --- /dev/null +++ b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/button/PrevPageButton.kt @@ -0,0 +1,20 @@ +package ru.astrainteractive.astratemplate.feature.gui.button + +import org.bukkit.Material +import ru.astrainteractive.astralibs.menu.clicker.Click +import ru.astrainteractive.astralibs.menu.slot.InventorySlot +import ru.astrainteractive.astralibs.menu.slot.setDisplayName +import ru.astrainteractive.astralibs.menu.slot.setIndex +import ru.astrainteractive.astralibs.menu.slot.setMaterial +import ru.astrainteractive.astralibs.menu.slot.setOnClickListener +import ru.astrainteractive.astratemplate.feature.gui.button.di.ButtonContext + +internal fun ButtonContext.prevPage( + index: Int, + click: Click +) = InventorySlot.Builder() + .setIndex(index) + .setMaterial(Material.PAPER) + .setDisplayName(toComponent(translation.menu.menuPrevPage)) + .setOnClickListener(click) + .build() diff --git a/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/button/di/ButtonContext.kt b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/button/di/ButtonContext.kt new file mode 100644 index 0000000..9c87393 --- /dev/null +++ b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/button/di/ButtonContext.kt @@ -0,0 +1,20 @@ +package ru.astrainteractive.astratemplate.feature.gui.button.di + +import ru.astrainteractive.astralibs.kyori.KyoriComponentSerializer +import ru.astrainteractive.astratemplate.core.di.CoreModule +import ru.astrainteractive.astratemplate.core.plugin.PluginTranslation +import ru.astrainteractive.klibs.kstorage.api.getValue +import ru.astrainteractive.klibs.mikro.core.logging.JUtiltLogger +import ru.astrainteractive.klibs.mikro.core.logging.Logger + +internal interface ButtonContext : KyoriComponentSerializer, Logger { + val translation: PluginTranslation + + class Default( + coreModule: CoreModule + ) : ButtonContext, + Logger by JUtiltLogger("AstraTemplate-ButtonContext"), + KyoriComponentSerializer by coreModule.kyoriKrate.cachedValue { + override val translation by coreModule.translationKrate + } +} diff --git a/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/di/BukkitGuiModule.kt b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/di/BukkitGuiModule.kt index 5f1ea84..10c6217 100644 --- a/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/di/BukkitGuiModule.kt +++ b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/di/BukkitGuiModule.kt @@ -3,6 +3,7 @@ package ru.astrainteractive.astratemplate.feature.gui.di import ru.astrainteractive.astratemplate.api.local.di.ApiLocalModule import ru.astrainteractive.astratemplate.core.di.CoreModule import ru.astrainteractive.astratemplate.feature.gui.api.ItemStackSpigotAPI +import ru.astrainteractive.astratemplate.feature.gui.button.di.ButtonContext import ru.astrainteractive.astratemplate.feature.gui.domain.GetRandomColorUseCaseImpl import ru.astrainteractive.astratemplate.feature.gui.domain.SetDisplayNameUseCaseImpl import ru.astrainteractive.astratemplate.feature.gui.router.Router @@ -13,11 +14,12 @@ class BukkitGuiModule( apiLocalModule: ApiLocalModule ) : GuiModule { private val getRandomColorUseCase = GetRandomColorUseCaseImpl() + private val buttonContext = ButtonContext.Default(coreModule) + override val router: Router = RouterImpl( ioScope = coreModule.ioScope, dispatchers = coreModule.dispatchers, - kyoriKrate = coreModule.kyoriKrate, - translationKrate = coreModule.translationKrate, + buttonContext = buttonContext, localDao = apiLocalModule.localDao, itemStackSpigotAPi = ItemStackSpigotAPI, getRandomColorUseCase = getRandomColorUseCase, diff --git a/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/layout/DefaultSampleInventoryLayoutFactory.kt b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/layout/DefaultSampleInventoryLayoutFactory.kt new file mode 100644 index 0000000..1031e32 --- /dev/null +++ b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/layout/DefaultSampleInventoryLayoutFactory.kt @@ -0,0 +1,57 @@ +package ru.astrainteractive.astratemplate.feature.gui.layout + +import ru.astrainteractive.astralibs.menu.layout.slotInventoryLayout + +@Suppress("MagicNumber") +internal object DefaultSampleInventoryLayoutFactory { + + private fun createCompactLayout() = slotInventoryLayout { + repeat(5) { + row(9, SampleSlotKey.CONTENT_ITEM) + } + row( + SampleSlotKey.PREV_PAGE, + SampleSlotKey.EMPTY, + SampleSlotKey.EMPTY, + SampleSlotKey.ADD_USER, + SampleSlotKey.BACK, + SampleSlotKey.CHANGE_MODE, + SampleSlotKey.EMPTY, + SampleSlotKey.EMPTY, + SampleSlotKey.NEXT_PAGE + ) + } + + private fun createBorderedLayout() = slotInventoryLayout { + row(9, SampleSlotKey.BORDER) + repeat(4) { + row( + SampleSlotKey.BORDER, + SampleSlotKey.CONTENT_ITEM, + SampleSlotKey.CONTENT_ITEM, + SampleSlotKey.CONTENT_ITEM, + SampleSlotKey.CONTENT_ITEM, + SampleSlotKey.CONTENT_ITEM, + SampleSlotKey.CONTENT_ITEM, + SampleSlotKey.CONTENT_ITEM, + SampleSlotKey.BORDER + ) + } + row( + SampleSlotKey.BORDER, + SampleSlotKey.PREV_PAGE, + SampleSlotKey.EMPTY, + SampleSlotKey.ADD_USER, + SampleSlotKey.BACK, + SampleSlotKey.CHANGE_MODE, + SampleSlotKey.EMPTY, + SampleSlotKey.NEXT_PAGE, + SampleSlotKey.BORDER + ) + } + + fun create(isCompact: Boolean) = when { + isCompact -> createCompactLayout() + else -> createBorderedLayout() + } +} diff --git a/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/layout/SampleSlotKey.kt b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/layout/SampleSlotKey.kt new file mode 100644 index 0000000..bff5e7f --- /dev/null +++ b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/layout/SampleSlotKey.kt @@ -0,0 +1,12 @@ +package ru.astrainteractive.astratemplate.feature.gui.layout + +internal enum class SampleSlotKey { + BORDER, + PREV_PAGE, + NEXT_PAGE, + BACK, + CHANGE_MODE, + ADD_USER, + CONTENT_ITEM, + EMPTY +} diff --git a/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/router/RouterImpl.kt b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/router/RouterImpl.kt index a096bb6..e1da5a1 100644 --- a/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/router/RouterImpl.kt +++ b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/router/RouterImpl.kt @@ -3,19 +3,16 @@ package ru.astrainteractive.astratemplate.feature.gui.router import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import org.bukkit.entity.Player import org.bukkit.inventory.Inventory -import ru.astrainteractive.astralibs.kyori.KyoriComponentSerializer import ru.astrainteractive.astralibs.server.player.BukkitOnlineKPlayer import ru.astrainteractive.astralibs.server.player.OnlineKPlayer import ru.astrainteractive.astratemplate.api.local.dao.LocalDao -import ru.astrainteractive.astratemplate.core.plugin.PluginTranslation import ru.astrainteractive.astratemplate.feature.gui.api.ItemStackSpigotAPI +import ru.astrainteractive.astratemplate.feature.gui.button.di.ButtonContext import ru.astrainteractive.astratemplate.feature.gui.domain.GetRandomColorUseCase import ru.astrainteractive.astratemplate.feature.gui.domain.SetDisplayNameUseCase import ru.astrainteractive.astratemplate.feature.gui.sample.feature.DefaultSampleGUIComponent import ru.astrainteractive.astratemplate.feature.gui.sample.gui.SampleGUI -import ru.astrainteractive.klibs.kstorage.api.CachedKrate import ru.astrainteractive.klibs.mikro.core.dispatchers.KotlinDispatchers import ru.astrainteractive.klibs.mikro.core.logging.JUtiltLogger import ru.astrainteractive.klibs.mikro.core.logging.Logger @@ -25,19 +22,17 @@ import ru.astrainteractive.klibs.mikro.core.util.tryCast internal class RouterImpl( private val ioScope: CoroutineScope, private val dispatchers: KotlinDispatchers, - private val kyoriKrate: CachedKrate, - private val translationKrate: CachedKrate, + private val buttonContext: ButtonContext, private val localDao: LocalDao, private val itemStackSpigotAPi: ItemStackSpigotAPI, private val getRandomColorUseCase: GetRandomColorUseCase, private val setDisplayNameUseCase: SetDisplayNameUseCase ) : Router, Logger by JUtiltLogger("Router") { - private fun buildRoute(player: Player, route: Router.Route): Inventory { + private fun buildRoute(route: Router.Route): Inventory { return when (route) { Router.Route.Sample -> SampleGUI( - player = player, - kyoriKrate = kyoriKrate, - translationKrate = translationKrate, + buttonContext = buttonContext, + dispatchers = dispatchers, sampleComponent = DefaultSampleGUIComponent( localDao = localDao, itemStackSpigotAPi = itemStackSpigotAPi, @@ -55,7 +50,7 @@ internal class RouterImpl( error { "#open Could not cast OnlineKPlayer to BukkitOnlineKPlayer" } return@launch } - val inventory = buildRoute(bukkitPlayer, route) + val inventory = buildRoute(route) withContext(dispatchers.Main) { bukkitPlayer.openInventory(inventory) } } } diff --git a/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/sample/gui/SampleGUI.kt b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/sample/gui/SampleGUI.kt index ab340b0..8422497 100644 --- a/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/sample/gui/SampleGUI.kt +++ b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/sample/gui/SampleGUI.kt @@ -4,110 +4,159 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import net.kyori.adventure.text.Component -import org.bukkit.Material -import org.bukkit.entity.Player import org.bukkit.event.inventory.InventoryClickEvent -import org.bukkit.inventory.ItemStack +import org.bukkit.event.inventory.InventoryOpenEvent +import ru.astrainteractive.astralibs.coroutines.withTimings import ru.astrainteractive.astralibs.kyori.KyoriComponentSerializer -import ru.astrainteractive.astralibs.kyori.unwrap -import ru.astrainteractive.astralibs.menu.holder.DefaultPlayerHolder -import ru.astrainteractive.astralibs.menu.holder.PlayerHolder +import ru.astrainteractive.astralibs.menu.core.setInventorySlot import ru.astrainteractive.astralibs.menu.inventory.api.InventoryMenu import ru.astrainteractive.astralibs.menu.inventory.model.InventorySize +import ru.astrainteractive.astralibs.menu.layout.mapSlotsNotNullIndexed import ru.astrainteractive.astralibs.menu.paginator.api.DefaultPaginator +import ru.astrainteractive.astralibs.menu.paginator.api.context +import ru.astrainteractive.astralibs.menu.paginator.api.openNextPage +import ru.astrainteractive.astralibs.menu.paginator.api.openPrevPage +import ru.astrainteractive.astralibs.menu.paginator.api.setMaxItems +import ru.astrainteractive.astralibs.menu.paginator.model.indexOfSlot +import ru.astrainteractive.astralibs.menu.paginator.model.isFirstPage +import ru.astrainteractive.astralibs.menu.paginator.model.isLastPage import ru.astrainteractive.astralibs.menu.slot.InventorySlot -import ru.astrainteractive.astralibs.menu.slot.setDisplayName -import ru.astrainteractive.astralibs.menu.slot.setIndex -import ru.astrainteractive.astralibs.menu.slot.setMaterial -import ru.astrainteractive.astralibs.menu.slot.setOnClickListener -import ru.astrainteractive.astratemplate.api.local.model.UserModel -import ru.astrainteractive.astratemplate.core.plugin.PluginTranslation +import ru.astrainteractive.astratemplate.feature.gui.button.addUser +import ru.astrainteractive.astratemplate.feature.gui.button.back +import ru.astrainteractive.astratemplate.feature.gui.button.border +import ru.astrainteractive.astratemplate.feature.gui.button.changeMode +import ru.astrainteractive.astratemplate.feature.gui.button.di.ButtonContext +import ru.astrainteractive.astratemplate.feature.gui.button.itemSlot +import ru.astrainteractive.astratemplate.feature.gui.button.nextPage +import ru.astrainteractive.astratemplate.feature.gui.button.prevPage +import ru.astrainteractive.astratemplate.feature.gui.button.userSlot +import ru.astrainteractive.astratemplate.feature.gui.layout.DefaultSampleInventoryLayoutFactory +import ru.astrainteractive.astratemplate.feature.gui.layout.SampleSlotKey import ru.astrainteractive.astratemplate.feature.gui.sample.feature.SampleGuiComponent -import ru.astrainteractive.klibs.kstorage.api.CachedKrate -import ru.astrainteractive.klibs.kstorage.api.getValue +import ru.astrainteractive.klibs.mikro.core.coroutines.CoroutineFeature +import ru.astrainteractive.klibs.mikro.core.dispatchers.KotlinDispatchers internal class SampleGUI( - player: Player, - kyoriKrate: CachedKrate, - translationKrate: CachedKrate, + private val buttonContext: ButtonContext, + private val dispatchers: KotlinDispatchers, private val sampleComponent: SampleGuiComponent ) : InventoryMenu(), - KyoriComponentSerializer by kyoriKrate.unwrap(), { + KyoriComponentSerializer by buttonContext { + override val childComponents: List get() = listOf(sampleComponent) - private val translation by translationKrate - private val paginator = DefaultPaginator() - override val playerHolder: PlayerHolder = DefaultPlayerHolder(player) - override var title: Component = translation.menu.menuTitle.let(::toComponent) + override val title: Component = toComponent(buttonContext.translation.menu.menuTitle) override val inventorySize: InventorySize = InventorySize.XL - override var pageContext: PageContext = PageContext( - page = 0, - maxItemsPerPage = inventorySize.size - InventorySize.XXS.size, - maxItems = 0 + + override val menuScope: CoroutineScope = CoroutineFeature + .Default(dispatchers.Main) + .withTimings() + + private val inventoryMap by lazy { + DefaultSampleInventoryLayoutFactory.create(isCompact = true) + } + + private val paginator = DefaultPaginator( + maxItemsPerPage = inventoryMap.count(SampleSlotKey.CONTENT_ITEM) ) + private val borderButtons: List + get() = inventoryMap.mapSlotsNotNull( + key = SampleSlotKey.BORDER, + transform = buttonContext::border + ) + + private val nextPageButton: InventorySlot + get() = buttonContext.nextPage( + index = inventoryMap.firstIndexOf(SampleSlotKey.NEXT_PAGE), + click = { onNextPageClicked() } + ) + + private val prevPageButton: InventorySlot + get() = buttonContext.prevPage( + index = inventoryMap.firstIndexOf(SampleSlotKey.PREV_PAGE), + click = { onPrevPageClicked() } + ) + private val changeModeButton: InventorySlot - get() = InventorySlot.Builder() - .setIndex(50) - .setMaterial(Material.SUNFLOWER) - .setDisplayName( - when (sampleComponent.model.value) { - is SampleGuiComponent.Model.Items -> "Items" - SampleGuiComponent.Model.Loading -> "Loading" - is SampleGuiComponent.Model.Users -> "Users" - } + get() { + val label = when (sampleComponent.model.value) { + is SampleGuiComponent.Model.Items -> "Items" + is SampleGuiComponent.Model.Users -> "Users" + SampleGuiComponent.Model.Loading -> "Loading" + } + return buttonContext.changeMode( + index = inventoryMap.firstIndexOf(SampleSlotKey.CHANGE_MODE), + label = label, + click = { sampleComponent.onModeChange() } ) - .setOnClickListener { sampleComponent.onModeChange() } - .build() + } private val addUserButton: InventorySlot - get() = InventorySlot.Builder() - .setIndex(48) - .setMaterial(Material.EMERALD) - .setDisplayName(translation.menu.menuAddPlayer.let(::toComponent)) - .setOnClickListener { sampleComponent.onAddUserClicked() } - .build() - - private val backPageButton: InventorySlot - get() = InventorySlot.Builder() - .setIndex(49) - .setMaterial(Material.PAPER) - .setDisplayName(translation.menu.menuClose.let(::toComponent)) - .setOnClickListener { inventory.close() } - .build() - - override val nextPageButton: InventorySlot - get() = InventorySlot.Builder() - .setIndex(53) - .setMaterial(Material.PAPER) - .setDisplayName(translation.menu.menuNextPage.let(::toComponent)) - .setOnClickListener { showNextPage() } - .build() - - override val prevPageButton: InventorySlot - get() = InventorySlot.Builder() - .setIndex(45) - .setMaterial(Material.PAPER) - .setDisplayName(translation.menu.menuPrevPage.let(::toComponent)) - .setOnClickListener { showPrevPage() } - .build() - - override fun onInventoryClicked(e: InventoryClickEvent) { - super.onInventoryClicked(e) + get() = buttonContext.addUser( + index = inventoryMap.firstIndexOf(SampleSlotKey.ADD_USER), + click = { sampleComponent.onAddUserClicked() } + ) + + private val backButton: InventorySlot + get() = buttonContext.back( + index = inventoryMap.firstIndexOf(SampleSlotKey.BACK), + click = { e -> e.whoClicked.closeInventory() } + ) + + private val contentSlots: List + get() { + val state = sampleComponent.model.value + return inventoryMap.mapSlotsNotNullIndexed(SampleSlotKey.CONTENT_ITEM) { iterIndex, slotIndex -> + val dataIndex = paginator.context.indexOfSlot(iterIndex) + when (state) { + is SampleGuiComponent.Model.Items -> state.items.getOrNull(dataIndex)?.let { item -> + buttonContext.itemSlot( + index = slotIndex, + itemStack = item, + click = { sampleComponent.onItemClicked(dataIndex, it.click) } + ) + } + is SampleGuiComponent.Model.Users -> state.users.getOrNull(dataIndex)?.let { user -> + buttonContext.userSlot( + index = slotIndex, + user = user, + randomColor = sampleComponent.randomColor, + click = { sampleComponent.onItemClicked(dataIndex, it.click) } + ) + } + SampleGuiComponent.Model.Loading -> null + } + } + } + + private fun onNextPageClicked() { + paginator.openNextPage() + render() + } + + private fun onPrevPageClicked() { + paginator.openPrevPage() + render() + } + + override fun onInventoryClickEvent(e: InventoryClickEvent) { + super.onInventoryClickEvent(e) e.isCancelled = true } - override fun onInventoryCreated() { + override fun onInventoryOpenEvent(e: InventoryOpenEvent) { sampleComponent.onUiCreated() sampleComponent.model .onEach { state -> - val maxItems = when (state) { - is SampleGuiComponent.Model.Items -> state.items.size - is SampleGuiComponent.Model.Users -> state.users.size - SampleGuiComponent.Model.Loading -> 0 - } - pageContext = pageContext.copy(maxItems = maxItems) + paginator.setMaxItems( + when (state) { + is SampleGuiComponent.Model.Items -> state.items.size + is SampleGuiComponent.Model.Users -> state.users.size + SampleGuiComponent.Model.Loading -> 0 + } + ) } .onEach { render() } .launchIn(menuScope) @@ -115,67 +164,15 @@ internal class SampleGUI( override fun render() { super.render() - val state: SampleGuiComponent.Model = sampleComponent.model.value - inventory.clear() - changeModeButton.setInventorySlot() - prevPageButton.setInventorySlotIf { pageContext.page > 0 } - nextPageButton.setInventorySlotIf { !pageContext.isLastPage } - backPageButton.setInventorySlot() - - when (state) { - is SampleGuiComponent.Model.Items -> { - setItemStacks(state.items) - } - - is SampleGuiComponent.Model.Users -> { - addUserButton.setInventorySlot() - setUsers(state.users) - } - - SampleGuiComponent.Model.Loading -> Unit - } - } - - private fun setUsers(list: List) { - for (i in 0 until pageContext.maxItemsPerPage) { - val index = pageContext.getIndex(i) - if (index >= list.size) { - continue - } - val user = list[index] - - InventorySlot.Builder() - .setIndex(i) - .setMaterial(Material.PLAYER_HEAD) - .setDisplayName(user.id.toString()) - .setLore( - listOf( - "${sampleComponent.randomColor}discordID: ${user.discordId}", - "${sampleComponent.randomColor}minecraftUUID: ${user.minecraftUUID}", - "${sampleComponent.randomColor}Press LeftClick to delete user", - "${sampleComponent.randomColor}Press MiddleClick to delete user", - "${sampleComponent.randomColor}Press RightClick to Add Relation" - ).map(Component::text) - ) - .setOnClickListener { sampleComponent.onItemClicked(index, it.click) } - .build() - .setInventorySlot() - } - } - - private fun setItemStacks(list: List) { - for (i in 0 until pageContext.maxItemsPerPage) { - val index = pageContext.getIndex(i) - if (index >= list.size) { - continue - } - val itemStack = list[index] - InventorySlot.Builder() - .setIndex(i) - .setItemStack(itemStack) - .setOnClickListener { sampleComponent.onItemClicked(index, it.click) } - .build() - .setInventorySlot() + setInventorySlot(borderButtons) + setInventorySlot(changeModeButton) + setInventorySlot(backButton) + if (!paginator.context.isFirstPage) setInventorySlot(prevPageButton) + if (!paginator.context.isLastPage) setInventorySlot(nextPageButton) + val state = sampleComponent.model.value + if (state is SampleGuiComponent.Model.Users) { + setInventorySlot(addUserButton) } + setInventorySlot(contentSlots) } } From 2605739ae2f852fde4da6ecc8732fb932adccab0 Mon Sep 17 00:00:00 2001 From: Roman Makeev Date: Sat, 30 May 2026 21:34:17 +0300 Subject: [PATCH 11/16] [FIX] Fix build --- gradle.properties | 10 +++++----- instances/forge/build.gradle.kts | 1 + .../astratemplate/ForgeEntryPoint.kt | 8 ++++---- .../astratemplate/di/RootModule.kt | 17 ++++++++++++++--- instances/neoforge/build.gradle.kts | 1 + .../astratemplate/NeoForgeEntryPoint.kt | 6 +++--- .../astratemplate/di/RootModule.kt | 19 ++++++++++++++----- .../api/local/dao/LocalDaoImpl.kt | 2 +- .../api/local/di/ApiLocalModule.kt | 18 +++++++----------- .../astratemplate/core/di/CoreModule.kt | 2 +- .../core/plugin/PluginConfiguration.kt | 1 - .../command/common/CommonCommandsRegistry.kt | 2 +- modules/feature-event/forge/build.gradle.kts | 1 - .../feature/event/di/event/TickEvent.kt | 2 +- .../feature-event/neoforge/build.gradle.kts | 1 - .../feature/event/di/event/TickEvent.kt | 2 +- modules/feature-gui/api/build.gradle.kts | 2 +- .../astratemplate/feature/gui/di/GuiModule.kt | 2 +- .../feature/gui/di/StubGuiModule.kt | 13 +++++++++++++ .../feature/gui/router/Router.kt | 2 +- .../feature/DefaultSampleGUIComponent.kt | 2 +- 21 files changed, 71 insertions(+), 43 deletions(-) create mode 100644 modules/feature-gui/api/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/di/StubGuiModule.kt diff --git a/gradle.properties b/gradle.properties index 12d2e53..e4427f4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,10 +11,10 @@ klibs.java.source=8 klibs.java.target=21 klibs.java.ktarget=21 # Project -klibs.project.name=AspeKt -klibs.project.group=ru.astrainteractive.aspekt -klibs.project.version.string=2.55.0 -klibs.project.description=Essentials plugin for EmpireProjekt +klibs.project.name=AstraTemplate +klibs.project.group=ru.astrainteractive.astratemplate +klibs.project.version.string=9.0.0 +klibs.project.description=Template plugin for EmpireProjekt klibs.project.developers=makeevrserg|Makeev Roman|makeevrserg@gmail.com -klibs.project.url=https://empireprojekt.ru +klibs.project.url=https://github.com/Astra-Interactive/AstraTemplate klibs.publish.developers=makeevrserg|Makeev Roman|makeevrserg@gmail.com diff --git a/instances/forge/build.gradle.kts b/instances/forge/build.gradle.kts index f3e17e7..f483fb2 100644 --- a/instances/forge/build.gradle.kts +++ b/instances/forge/build.gradle.kts @@ -40,6 +40,7 @@ dependencies { shadow(projects.modules.core) shadow(projects.modules.featureEvent.forge) shadow(projects.modules.featureCommand) + shadow(projects.modules.featureGui.api) } minecraftProcessResource { diff --git a/instances/forge/src/main/kotlin/ru/astrainteractive/astratemplate/ForgeEntryPoint.kt b/instances/forge/src/main/kotlin/ru/astrainteractive/astratemplate/ForgeEntryPoint.kt index 33668dd..8f98e1a 100644 --- a/instances/forge/src/main/kotlin/ru/astrainteractive/astratemplate/ForgeEntryPoint.kt +++ b/instances/forge/src/main/kotlin/ru/astrainteractive/astratemplate/ForgeEntryPoint.kt @@ -1,19 +1,19 @@ package ru.astrainteractive.astratemplate +import net.minecraftforge.fml.common.Mod +import ru.astrainteractive.aspekt.BuildKonfig import ru.astrainteractive.astralibs.lifecycle.ForgeLifecycleServer +import ru.astrainteractive.astratemplate.di.RootModule import ru.astrainteractive.klibs.mikro.core.logging.JUtiltLogger import ru.astrainteractive.klibs.mikro.core.logging.Logger import javax.annotation.ParametersAreNonnullByDefault -import net.minecraftforge.fml.common.Mod -import ru.astrainteractive.aspekt.BuildKonfig -import ru.astrainteractive.astratemplate.di.RootModule @Mod(BuildKonfig.id) @ParametersAreNonnullByDefault class ForgeEntryPoint : Logger by JUtiltLogger("${BuildKonfig.id}-ForgeEntryPoint"), ForgeLifecycleServer() { - private val rootModule = RootModule() + private val rootModule = RootModule(this) override fun onEnable() { info { "#onEnable" } diff --git a/instances/forge/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt b/instances/forge/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt index 11fcc69..e2fbca7 100644 --- a/instances/forge/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt +++ b/instances/forge/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt @@ -1,16 +1,21 @@ package ru.astrainteractive.astratemplate.di -import java.io.File import net.minecraftforge.fml.loading.FMLPaths +import ru.astrainteractive.astralibs.command.api.brigadier.command.MultiplatformCommand +import ru.astrainteractive.astralibs.command.brigadier.command.MinecraftMultiplatformCommands import ru.astrainteractive.astralibs.command.registrar.ForgeCommandRegistrarContext import ru.astrainteractive.astralibs.coroutines.MinecraftDispatchers +import ru.astrainteractive.astralibs.lifecycle.ForgeLifecycleServer import ru.astrainteractive.astralibs.lifecycle.Lifecycle import ru.astrainteractive.astratemplate.api.local.di.ApiLocalModule import ru.astrainteractive.astratemplate.api.remote.di.ApiRemoteModule import ru.astrainteractive.astratemplate.core.di.CoreModule +import ru.astrainteractive.astratemplate.feature.command.di.CommandModule import ru.astrainteractive.astratemplate.feature.event.di.di.EventModule +import ru.astrainteractive.astratemplate.feature.gui.di.StubGuiModule +import java.io.File -class RootModule { +class RootModule(forgeLifecycleServer: ForgeLifecycleServer) { private val dataFolder = FMLPaths.CONFIGDIR.get() .resolve("AspeKt") @@ -33,10 +38,16 @@ class RootModule { private val apiRemoteModule: ApiRemoteModule by lazy { ApiRemoteModule() } + private val guiModule = StubGuiModule() private val commandModule by lazy { CommandModule( - commandRegistrarContext = commandRegistrarContext + coreModule = coreModule, + guiModule = guiModule, + apiRemoteModule = apiRemoteModule, + lifecyclePlugin = forgeLifecycleServer, + commandRegistrarContext = commandRegistrarContext, + multiplatformCommand = MultiplatformCommand(MinecraftMultiplatformCommands()) ) } diff --git a/instances/neoforge/build.gradle.kts b/instances/neoforge/build.gradle.kts index 9605e78..b8879f4 100644 --- a/instances/neoforge/build.gradle.kts +++ b/instances/neoforge/build.gradle.kts @@ -33,6 +33,7 @@ dependencies { shadow(projects.modules.core) shadow(projects.modules.featureEvent.neoforge) shadow(projects.modules.featureCommand) + shadow(projects.modules.featureGui.api) } minecraftProcessResource { diff --git a/instances/neoforge/src/main/kotlin/ru/astrainteractive/astratemplate/NeoForgeEntryPoint.kt b/instances/neoforge/src/main/kotlin/ru/astrainteractive/astratemplate/NeoForgeEntryPoint.kt index 33fbf35..ddce2b3 100755 --- a/instances/neoforge/src/main/kotlin/ru/astrainteractive/astratemplate/NeoForgeEntryPoint.kt +++ b/instances/neoforge/src/main/kotlin/ru/astrainteractive/astratemplate/NeoForgeEntryPoint.kt @@ -1,19 +1,19 @@ package ru.astrainteractive.astratemplate import net.neoforged.fml.common.Mod +import ru.astrainteractive.aspekt.BuildKonfig import ru.astrainteractive.astralibs.lifecycle.ForgeLifecycleServer +import ru.astrainteractive.astratemplate.di.RootModule import ru.astrainteractive.klibs.mikro.core.logging.JUtiltLogger import ru.astrainteractive.klibs.mikro.core.logging.Logger import javax.annotation.ParametersAreNonnullByDefault -import ru.astrainteractive.aspekt.BuildKonfig -import ru.astrainteractive.astratemplate.di.RootModule @Mod(BuildKonfig.id) @ParametersAreNonnullByDefault class NeoForgeEntryPoint : Logger by JUtiltLogger("${BuildKonfig.id}-NeoForgeEntryPoint"), ForgeLifecycleServer() { - private val rootModule = RootModule() + private val rootModule = RootModule(this) override fun onEnable() { info { "#onEnable" } diff --git a/instances/neoforge/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt b/instances/neoforge/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt index 3c3468f..1c83a0c 100644 --- a/instances/neoforge/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt +++ b/instances/neoforge/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt @@ -1,16 +1,21 @@ package ru.astrainteractive.astratemplate.di -import java.io.File import net.neoforged.fml.loading.FMLPaths +import ru.astrainteractive.astralibs.command.api.brigadier.command.MultiplatformCommand +import ru.astrainteractive.astralibs.command.brigadier.command.MinecraftMultiplatformCommands import ru.astrainteractive.astralibs.command.registrar.NeoForgeCommandRegistrarContext import ru.astrainteractive.astralibs.coroutines.MinecraftDispatchers +import ru.astrainteractive.astralibs.lifecycle.ForgeLifecycleServer import ru.astrainteractive.astralibs.lifecycle.Lifecycle import ru.astrainteractive.astratemplate.api.local.di.ApiLocalModule import ru.astrainteractive.astratemplate.api.remote.di.ApiRemoteModule import ru.astrainteractive.astratemplate.core.di.CoreModule +import ru.astrainteractive.astratemplate.feature.command.di.CommandModule import ru.astrainteractive.astratemplate.feature.event.di.di.EventModule +import ru.astrainteractive.astratemplate.feature.gui.di.StubGuiModule +import java.io.File -class RootModule { +class RootModule(forgeLifecycleServer: ForgeLifecycleServer) { private val dataFolder = FMLPaths.CONFIGDIR.get() .resolve("AspeKt") .toAbsolutePath() @@ -32,11 +37,15 @@ class RootModule { val apiRemoteModule: ApiRemoteModule by lazy { ApiRemoteModule() } - - + private val guiModule = StubGuiModule() private val commandModule by lazy { CommandModule( - commandRegistrarContext = commandRegistrarContext + coreModule = coreModule, + guiModule = guiModule, + apiRemoteModule = apiRemoteModule, + lifecyclePlugin = forgeLifecycleServer, + commandRegistrarContext = commandRegistrarContext, + multiplatformCommand = MultiplatformCommand(MinecraftMultiplatformCommands()) ) } diff --git a/modules/api/local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/dao/LocalDaoImpl.kt b/modules/api/local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/dao/LocalDaoImpl.kt index a574d50..1b0028a 100644 --- a/modules/api/local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/dao/LocalDaoImpl.kt +++ b/modules/api/local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/dao/LocalDaoImpl.kt @@ -1,6 +1,5 @@ package ru.astrainteractive.astratemplate.api.local.dao -import java.util.UUID import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.first import org.jetbrains.exposed.v1.core.eq @@ -14,6 +13,7 @@ import ru.astrainteractive.astratemplate.api.local.entity.UserRatingTable import ru.astrainteractive.astratemplate.api.local.entity.UserTable import ru.astrainteractive.astratemplate.api.local.model.RatingModel import ru.astrainteractive.astratemplate.api.local.model.UserModel +import java.util.UUID internal class LocalDaoImpl( private val databaseFlow: Flow, diff --git a/modules/api/local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/di/ApiLocalModule.kt b/modules/api/local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/di/ApiLocalModule.kt index 506f77e..073f2e8 100644 --- a/modules/api/local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/di/ApiLocalModule.kt +++ b/modules/api/local/src/main/kotlin/ru/astrainteractive/astratemplate/api/local/di/ApiLocalModule.kt @@ -1,26 +1,22 @@ package ru.astrainteractive.astratemplate.api.local.di import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.firstOrNull +import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.map -import kotlinx.coroutines.launch +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.shareIn +import org.jetbrains.exposed.v1.jdbc.SchemaUtils +import org.jetbrains.exposed.v1.jdbc.transactions.TransactionManager +import org.jetbrains.exposed.v1.jdbc.transactions.transaction import ru.astrainteractive.astralibs.lifecycle.Lifecycle import ru.astrainteractive.astratemplate.api.local.dao.LocalDao import ru.astrainteractive.astratemplate.api.local.dao.LocalDaoImpl import ru.astrainteractive.astratemplate.api.local.entity.UserRatingTable import ru.astrainteractive.astratemplate.api.local.entity.UserTable import ru.astrainteractive.astratemplate.core.plugin.PluginConfiguration -import java.io.File -import kotlinx.coroutines.flow.SharingStarted -import kotlinx.coroutines.flow.flatMapLatest -import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.flow.shareIn -import org.jetbrains.exposed.v1.jdbc.SchemaUtils -import org.jetbrains.exposed.v1.jdbc.transactions.TransactionManager -import org.jetbrains.exposed.v1.jdbc.transactions.transaction import ru.astrainteractive.klibs.mikro.exposed.util.connectAsFlow class ApiLocalModule( diff --git a/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/di/CoreModule.kt b/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/di/CoreModule.kt index 2c8a880..a3550cf 100644 --- a/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/di/CoreModule.kt +++ b/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/di/CoreModule.kt @@ -2,7 +2,6 @@ package ru.astrainteractive.astratemplate.core.di import com.charleskorn.kaml.PolymorphismStyle import com.charleskorn.kaml.Yaml -import java.io.File import kotlinx.coroutines.CoroutineExceptionHandler import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.SupervisorJob @@ -22,6 +21,7 @@ import ru.astrainteractive.klibs.kstorage.api.impl.DefaultMutableKrate import ru.astrainteractive.klibs.mikro.core.coroutines.CoroutineFeature import ru.astrainteractive.klibs.mikro.core.dispatchers.KotlinDispatchers import ru.astrainteractive.klibs.mikro.core.logging.JUtiltLogger +import java.io.File class CoreModule( val dataFolder: File, diff --git a/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/plugin/PluginConfiguration.kt b/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/plugin/PluginConfiguration.kt index e1193bb..e39c884 100644 --- a/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/plugin/PluginConfiguration.kt +++ b/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/plugin/PluginConfiguration.kt @@ -1,7 +1,6 @@ package ru.astrainteractive.astratemplate.core.plugin import com.charleskorn.kaml.YamlComment -import java.io.Serial import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import ru.astrainteractive.klibs.mikro.exposed.model.DatabaseConfiguration diff --git a/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/common/CommonCommandsRegistry.kt b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/common/CommonCommandsRegistry.kt index 1981649..54bbcd2 100644 --- a/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/common/CommonCommandsRegistry.kt +++ b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/common/CommonCommandsRegistry.kt @@ -7,7 +7,7 @@ import ru.astrainteractive.astralibs.kyori.KyoriComponentSerializer import ru.astrainteractive.astralibs.kyori.unwrap import ru.astrainteractive.astratemplate.core.plugin.PluginTranslation import ru.astrainteractive.klibs.kstorage.api.CachedKrate -import ru.astrainteractive.klibs.kstorage.util.getValue +import ru.astrainteractive.klibs.kstorage.api.getValue internal class CommonCommandsRegistry( translationKrate: CachedKrate, diff --git a/modules/feature-event/forge/build.gradle.kts b/modules/feature-event/forge/build.gradle.kts index 14eeba2..3067543 100644 --- a/modules/feature-event/forge/build.gradle.kts +++ b/modules/feature-event/forge/build.gradle.kts @@ -19,7 +19,6 @@ dependencies { implementation(projects.modules.api.local) } - dependencies { // We use this because forge plugin waste a lot of resources when enabled compileOnly( diff --git a/modules/feature-event/forge/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/event/TickEvent.kt b/modules/feature-event/forge/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/event/TickEvent.kt index 31c6c93..33d0b80 100644 --- a/modules/feature-event/forge/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/event/TickEvent.kt +++ b/modules/feature-event/forge/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/event/TickEvent.kt @@ -12,4 +12,4 @@ class TickEvent(mainScope: CoroutineScope) : Logger by JUtiltLogger("AstraTempla val tickEvent = flowEvent() .onEach { info { "#tickEvent -> flow onEach" } } .launchIn(mainScope) -} \ No newline at end of file +} diff --git a/modules/feature-event/neoforge/build.gradle.kts b/modules/feature-event/neoforge/build.gradle.kts index e78996b..9ba8540 100644 --- a/modules/feature-event/neoforge/build.gradle.kts +++ b/modules/feature-event/neoforge/build.gradle.kts @@ -19,7 +19,6 @@ dependencies { implementation(projects.modules.api.local) } - dependencies { // We use this because forge plugin waste a lot of resources when enabled compileOnly( diff --git a/modules/feature-event/neoforge/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/event/TickEvent.kt b/modules/feature-event/neoforge/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/event/TickEvent.kt index 0a2f3e6..1e066e5 100644 --- a/modules/feature-event/neoforge/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/event/TickEvent.kt +++ b/modules/feature-event/neoforge/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/event/TickEvent.kt @@ -12,4 +12,4 @@ class TickEvent(mainScope: CoroutineScope) : Logger by JUtiltLogger("AstraTempla val tickEvent = flowEvent() .onEach { info { "#tickEvent -> flow onEach" } } .launchIn(mainScope) -} \ No newline at end of file +} diff --git a/modules/feature-gui/api/build.gradle.kts b/modules/feature-gui/api/build.gradle.kts index 4f690ff..5a08eb3 100644 --- a/modules/feature-gui/api/build.gradle.kts +++ b/modules/feature-gui/api/build.gradle.kts @@ -7,4 +7,4 @@ plugins { dependencies { implementation(libs.minecraft.astralibs.core) -} \ No newline at end of file +} diff --git a/modules/feature-gui/api/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/di/GuiModule.kt b/modules/feature-gui/api/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/di/GuiModule.kt index 3bda80b..4f84d03 100644 --- a/modules/feature-gui/api/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/di/GuiModule.kt +++ b/modules/feature-gui/api/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/di/GuiModule.kt @@ -4,4 +4,4 @@ import ru.astrainteractive.astratemplate.feature.gui.router.Router interface GuiModule { val router: Router -} \ No newline at end of file +} diff --git a/modules/feature-gui/api/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/di/StubGuiModule.kt b/modules/feature-gui/api/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/di/StubGuiModule.kt new file mode 100644 index 0000000..39c5bbc --- /dev/null +++ b/modules/feature-gui/api/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/di/StubGuiModule.kt @@ -0,0 +1,13 @@ +package ru.astrainteractive.astratemplate.feature.gui.di + +import ru.astrainteractive.astralibs.server.player.OnlineKPlayer +import ru.astrainteractive.astratemplate.feature.gui.router.Router + +class StubGuiModule : GuiModule { + override val router: Router = object : Router { + override fun open( + player: OnlineKPlayer, + route: Router.Route + ) = Unit + } +} diff --git a/modules/feature-gui/api/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/router/Router.kt b/modules/feature-gui/api/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/router/Router.kt index f715707..ea3ea48 100644 --- a/modules/feature-gui/api/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/router/Router.kt +++ b/modules/feature-gui/api/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/router/Router.kt @@ -8,4 +8,4 @@ interface Router { } fun open(player: OnlineKPlayer, route: Route) -} \ No newline at end of file +} diff --git a/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/sample/feature/DefaultSampleGUIComponent.kt b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/sample/feature/DefaultSampleGUIComponent.kt index e623f69..ce43b5b 100644 --- a/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/sample/feature/DefaultSampleGUIComponent.kt +++ b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/sample/feature/DefaultSampleGUIComponent.kt @@ -1,6 +1,5 @@ package ru.astrainteractive.astratemplate.feature.gui.sample.feature -import kotlin.random.Random import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableStateFlow @@ -17,6 +16,7 @@ import ru.astrainteractive.astratemplate.feature.gui.domain.SetDisplayNameUseCas import ru.astrainteractive.klibs.mikro.core.coroutines.CoroutineFeature import ru.astrainteractive.klibs.mikro.core.logging.JUtiltLogger import ru.astrainteractive.klibs.mikro.core.logging.Logger +import kotlin.random.Random /** * MVVM/MVI technique From 26d1d4b33a713662769c13f6d694fdd55e9e9fe8 Mon Sep 17 00:00:00 2001 From: Roman Makeev Date: Sat, 30 May 2026 21:35:12 +0300 Subject: [PATCH 12/16] [FIX] Detekt --- .../feature/command/additem/AddItemCommandRegistry.kt | 1 + .../feature/command/rickmorty/RickMortyCommandRegistrar.kt | 1 + .../feature/gui/sample/feature/DefaultSampleGUIComponent.kt | 2 ++ 3 files changed, 4 insertions(+) diff --git a/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/additem/AddItemCommandRegistry.kt b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/additem/AddItemCommandRegistry.kt index cae8bad..1898527 100644 --- a/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/additem/AddItemCommandRegistry.kt +++ b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/additem/AddItemCommandRegistry.kt @@ -25,6 +25,7 @@ internal class AddItemCommandRegistry( } } + @Suppress("MagicNumber") private fun createNode(): LiteralArgumentBuilder<*> { return with(multiplatformCommand) { command("add") { diff --git a/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/rickmorty/RickMortyCommandRegistrar.kt b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/rickmorty/RickMortyCommandRegistrar.kt index 7c98dc5..1f8fa79 100644 --- a/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/rickmorty/RickMortyCommandRegistrar.kt +++ b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/rickmorty/RickMortyCommandRegistrar.kt @@ -28,6 +28,7 @@ internal class RickMortyCommandRegistrar( } } + @Suppress("MagicNumber") private fun createNode(): LiteralArgumentBuilder<*> { return with(multiplatformCommand) { command("rickandmorty") { diff --git a/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/sample/feature/DefaultSampleGUIComponent.kt b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/sample/feature/DefaultSampleGUIComponent.kt index ce43b5b..1ec84b3 100644 --- a/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/sample/feature/DefaultSampleGUIComponent.kt +++ b/modules/feature-gui/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/feature/gui/sample/feature/DefaultSampleGUIComponent.kt @@ -35,6 +35,7 @@ internal class DefaultSampleGUIComponent( override val randomColor: ChatColor get() = getRandomColorUseCase.invoke().color + @Suppress("MagicNumber") private fun getRandomUser(): UserModel { return UserModel( id = -1, @@ -110,6 +111,7 @@ internal class DefaultSampleGUIComponent( override fun onUiCreated() { launch(Dispatchers.IO) { + @Suppress("MagicNumber") delay(1000) loadItemsModel() } From bb3195c2c75f1c5cc89d7ba4b0cdc343f51e69d8 Mon Sep 17 00:00:00 2001 From: Roman Makeev Date: Sat, 30 May 2026 21:40:39 +0300 Subject: [PATCH 13/16] [FIX] Fix translation --- .../astratemplate/ForgeEntryPoint.kt | 1 - .../astratemplate/NeoForgeEntryPoint.kt | 1 - .../astratemplate/core/di/CoreModule.kt | 2 +- .../core/plugin/PluginTranslation.kt | 20 ++++++++++++++++++- .../command/additem/AddItemExecutor.kt | 15 +++++++++++--- .../feature/command/di/CommandModule.kt | 9 +++++++-- .../rickmorty/RickMortyCommandRegistrar.kt | 17 ++++++++++++---- 7 files changed, 52 insertions(+), 13 deletions(-) diff --git a/instances/forge/src/main/kotlin/ru/astrainteractive/astratemplate/ForgeEntryPoint.kt b/instances/forge/src/main/kotlin/ru/astrainteractive/astratemplate/ForgeEntryPoint.kt index 8f98e1a..633bf36 100644 --- a/instances/forge/src/main/kotlin/ru/astrainteractive/astratemplate/ForgeEntryPoint.kt +++ b/instances/forge/src/main/kotlin/ru/astrainteractive/astratemplate/ForgeEntryPoint.kt @@ -1,7 +1,6 @@ package ru.astrainteractive.astratemplate import net.minecraftforge.fml.common.Mod -import ru.astrainteractive.aspekt.BuildKonfig import ru.astrainteractive.astralibs.lifecycle.ForgeLifecycleServer import ru.astrainteractive.astratemplate.di.RootModule import ru.astrainteractive.klibs.mikro.core.logging.JUtiltLogger diff --git a/instances/neoforge/src/main/kotlin/ru/astrainteractive/astratemplate/NeoForgeEntryPoint.kt b/instances/neoforge/src/main/kotlin/ru/astrainteractive/astratemplate/NeoForgeEntryPoint.kt index ddce2b3..9df2130 100755 --- a/instances/neoforge/src/main/kotlin/ru/astrainteractive/astratemplate/NeoForgeEntryPoint.kt +++ b/instances/neoforge/src/main/kotlin/ru/astrainteractive/astratemplate/NeoForgeEntryPoint.kt @@ -1,7 +1,6 @@ package ru.astrainteractive.astratemplate import net.neoforged.fml.common.Mod -import ru.astrainteractive.aspekt.BuildKonfig import ru.astrainteractive.astralibs.lifecycle.ForgeLifecycleServer import ru.astrainteractive.astratemplate.di.RootModule import ru.astrainteractive.klibs.mikro.core.logging.JUtiltLogger diff --git a/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/di/CoreModule.kt b/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/di/CoreModule.kt index a3550cf..b405340 100644 --- a/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/di/CoreModule.kt +++ b/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/di/CoreModule.kt @@ -7,12 +7,12 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.cancel import kotlinx.serialization.StringFormat -import ru.astrainteractive.aspekt.BuildKonfig import ru.astrainteractive.astralibs.coroutines.withTimings import ru.astrainteractive.astralibs.kyori.KyoriComponentSerializer import ru.astrainteractive.astralibs.lifecycle.Lifecycle import ru.astrainteractive.astralibs.util.YamlStringFormat import ru.astrainteractive.astralibs.util.parseOrWriteIntoDefault +import ru.astrainteractive.astratemplate.BuildKonfig import ru.astrainteractive.astratemplate.core.plugin.PluginConfiguration import ru.astrainteractive.astratemplate.core.plugin.PluginTranslation import ru.astrainteractive.klibs.kstorage.api.asCachedKrate diff --git a/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/plugin/PluginTranslation.kt b/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/plugin/PluginTranslation.kt index 447b95a..0c26b8e 100644 --- a/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/plugin/PluginTranslation.kt +++ b/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/plugin/PluginTranslation.kt @@ -109,9 +109,27 @@ class PluginTranslation( .plus("&#db2c18Вас продамажил игрок %player%!") .toRaw(), @SerialName("damage_hint") - val damageHint: StringDesc.Raw = StringDesc.Raw("") + val damageHint: StringDesc.Raw = StringDesc.Raw(""), + @SerialName("add_item_success") + private val addItemSuccess: StringDesc.Raw = PREFIX + .plus("dbd1Добавлено %amount%x %item%!") + .toRaw(), + @SerialName("rick_morty_success") + private val rickMortySuccess: StringDesc.Raw = PREFIX + .plus("dbd1Получен ответ: %result%") + .toRaw(), + @SerialName("rick_morty_fail") + private val rickMortyFail: StringDesc.Raw = PREFIX + .plus("&#db2c18Ошибка: %error%") + .toRaw() ) { fun damaged(player: String) = damaged.replace("%player%", player) + fun addItemSuccess(amount: Int, item: String) = addItemSuccess + .replace("%amount%", amount.toString()) + .replace("%item%", item) + + fun rickMortySuccess(result: String) = rickMortySuccess.replace("%result%", result) + fun rickMortyFail(error: String) = rickMortyFail.replace("%error%", error) } companion object { diff --git a/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/additem/AddItemExecutor.kt b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/additem/AddItemExecutor.kt index f304b85..cae1114 100644 --- a/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/additem/AddItemExecutor.kt +++ b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/additem/AddItemExecutor.kt @@ -1,11 +1,20 @@ package ru.astrainteractive.astratemplate.feature.command.additem -import net.kyori.adventure.text.Component +import ru.astrainteractive.astralibs.kyori.KyoriComponentSerializer +import ru.astrainteractive.astralibs.kyori.unwrap +import ru.astrainteractive.astratemplate.core.plugin.PluginTranslation +import ru.astrainteractive.klibs.kstorage.api.CachedKrate +import ru.astrainteractive.klibs.kstorage.api.getValue + +internal class AddItemExecutor( + translationKrate: CachedKrate, + kyoriKrate: CachedKrate +) : KyoriComponentSerializer by kyoriKrate.unwrap() { + private val translation by translationKrate -internal class AddItemExecutor { fun execute(input: AddItemCommand.Result) { input.player.sendMessage( - Component.text("Added ${input.amount}x ${input.itemName}") + translation.custom.addItemSuccess(input.amount, input.itemName).component ) } } diff --git a/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/di/CommandModule.kt b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/di/CommandModule.kt index c545f5e..9e3b125 100644 --- a/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/di/CommandModule.kt +++ b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/di/CommandModule.kt @@ -38,7 +38,10 @@ class CommandModule( registrarContext = commandRegistrarContext, multiplatformCommand = multiplatformCommand, errorHandler = errorHandler, - executor = AddItemExecutor() + executor = AddItemExecutor( + translationKrate = coreModule.translationKrate, + kyoriKrate = coreModule.kyoriKrate + ) ).register() CommonCommandsRegistry( kyoriKrate = coreModule.kyoriKrate, @@ -74,7 +77,9 @@ class CommandModule( rmApi = apiRemoteModule.rickMortyApi, registrarContext = commandRegistrarContext, multiplatformCommand = multiplatformCommand, - errorHandler = errorHandler + errorHandler = errorHandler, + translationKrate = coreModule.translationKrate, + kyoriKrate = coreModule.kyoriKrate ).register() } ) diff --git a/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/rickmorty/RickMortyCommandRegistrar.kt b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/rickmorty/RickMortyCommandRegistrar.kt index 1f8fa79..55492c6 100644 --- a/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/rickmorty/RickMortyCommandRegistrar.kt +++ b/modules/feature-command/src/main/kotlin/ru/astrainteractive/astratemplate/feature/command/rickmorty/RickMortyCommandRegistrar.kt @@ -7,8 +7,13 @@ import kotlinx.coroutines.launch import ru.astrainteractive.astralibs.command.api.brigadier.command.MultiplatformCommand import ru.astrainteractive.astralibs.command.api.brigadier.sender.KCommandSender import ru.astrainteractive.astralibs.command.api.registrar.CommandRegistrarContext +import ru.astrainteractive.astralibs.kyori.KyoriComponentSerializer +import ru.astrainteractive.astralibs.kyori.unwrap import ru.astrainteractive.astratemplate.api.remote.api.RickMortyApi +import ru.astrainteractive.astratemplate.core.plugin.PluginTranslation import ru.astrainteractive.astratemplate.feature.command.errorhandler.DefaultErrorHandler +import ru.astrainteractive.klibs.kstorage.api.CachedKrate +import ru.astrainteractive.klibs.kstorage.api.getValue import ru.astrainteractive.klibs.mikro.core.dispatchers.KotlinDispatchers import kotlin.random.Random @@ -18,13 +23,17 @@ internal class RickMortyCommandRegistrar( private val rmApi: RickMortyApi, private val registrarContext: CommandRegistrarContext, private val multiplatformCommand: MultiplatformCommand, - private val errorHandler: DefaultErrorHandler -) { + private val errorHandler: DefaultErrorHandler, + translationKrate: CachedKrate, + kyoriKrate: CachedKrate +) : KyoriComponentSerializer by kyoriKrate.unwrap() { + private val translation by translationKrate + private fun send(sender: KCommandSender, number: Int) { scope.launch(dispatchers.IO) { rmApi.getRandomCharacter(number) - .onSuccess { sender.sendMessage(net.kyori.adventure.text.Component.text("Got response: $it")) } - .onFailure { sender.sendMessage(net.kyori.adventure.text.Component.text("Fail: ${it.message}")) } + .onSuccess { sender.sendMessage(translation.custom.rickMortySuccess(it.toString()).component) } + .onFailure { sender.sendMessage(translation.custom.rickMortyFail(it.message.orEmpty()).component) } } } From 90ffe48d0c965f47bbabc6468c97d9758e8fcebe Mon Sep 17 00:00:00 2001 From: Roman Makeev Date: Sat, 30 May 2026 21:42:22 +0300 Subject: [PATCH 14/16] [FIX] Update CI --- .github/workflows/call-build-project.yml | 14 +++--- .github/workflows/call-detekt-validation.yml | 4 +- .../call-gradle-wrapper-validation.yml | 2 +- .github/workflows/call-tests-validation.yml | 4 +- .github/workflows/call-upload-artifacts.yml | 20 ++++----- .../workflows/call-upload-github-release.yml | 29 +++++------- .../call-upload-modrinth-release.yml | 16 +++---- .github/workflows/release-master.yml | 6 --- docker-compose.yml | 45 +++++++++++-------- 9 files changed, 63 insertions(+), 77 deletions(-) diff --git a/.github/workflows/call-build-project.yml b/.github/workflows/call-build-project.yml index 0e961df..6d3b553 100644 --- a/.github/workflows/call-build-project.yml +++ b/.github/workflows/call-build-project.yml @@ -8,19 +8,17 @@ jobs: strategy: matrix: include: - - id: "fabric" - task: ":instances:fabric:build" - - id: "forge" - task: ":instances:forge:build" - - id: "velocity" - task: ":instances:velocity:build" - id: "bukkit" task: ":instances:bukkit:build" + - id: "forge" + task: ":instances:forge:build" + - id: "neoforge" + task: ":instances:neoforge:build" steps: - name: Checkout Git repo - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Set up JDK 21 - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: 'adopt' java-version: 21 diff --git a/.github/workflows/call-detekt-validation.yml b/.github/workflows/call-detekt-validation.yml index a4c6a43..56134ee 100644 --- a/.github/workflows/call-detekt-validation.yml +++ b/.github/workflows/call-detekt-validation.yml @@ -6,9 +6,9 @@ jobs: name: "Check project by detekt" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Set up JDK 21 - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: 'temurin' java-version: '21' diff --git a/.github/workflows/call-gradle-wrapper-validation.yml b/.github/workflows/call-gradle-wrapper-validation.yml index 40b9686..29cb46a 100644 --- a/.github/workflows/call-gradle-wrapper-validation.yml +++ b/.github/workflows/call-gradle-wrapper-validation.yml @@ -7,6 +7,6 @@ jobs: name: "Gradle Wrapper Validation" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Validate Gradle Wrapper uses: gradle/wrapper-validation-action@v3 \ No newline at end of file diff --git a/.github/workflows/call-tests-validation.yml b/.github/workflows/call-tests-validation.yml index 9db21c0..f27ce31 100644 --- a/.github/workflows/call-tests-validation.yml +++ b/.github/workflows/call-tests-validation.yml @@ -7,9 +7,9 @@ jobs: name: "Run tests" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Set up JDK 21 - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: 'adopt' java-version: '21' diff --git a/.github/workflows/call-upload-artifacts.yml b/.github/workflows/call-upload-artifacts.yml index 0cadab0..ebf433d 100644 --- a/.github/workflows/call-upload-artifacts.yml +++ b/.github/workflows/call-upload-artifacts.yml @@ -8,24 +8,22 @@ jobs: strategy: matrix: include: - - id: "fabric" - task: ":instances:fabric:assemble" - - id: "forge" - task: ":instances:forge:shadowJar" - - id: "velocity" - task: ":instances:velocity:shadowJar" - id: "bukkit" task: ":instances:bukkit:shadowJar" + - id: "forge" + task: ":instances:forge:shadowJar" + - id: "neoforge" + task: ":instances:neoforge:shadowJar" steps: - name: Checkout Git repo - uses: actions/checkout@v4 + uses: actions/checkout@v6 - uses: christian-draeger/read-properties@1.1.1 id: properties with: path: './gradle.properties' - properties: 'makeevrserg.project.name' + properties: 'klibs.project.name' - name: Set up JDK 21 - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: 'adopt' java-version: 21 @@ -35,8 +33,8 @@ jobs: uses: gradle/gradle-build-action@v3 with: arguments: ${{ matrix.task }} --stacktrace - - uses: actions/upload-artifact@184d73b71b93c222403b2e7f1ffebe4508014249 + - uses: actions/upload-artifact@6027e3dd177782cd8ab9af838c04fd81a07f1d47 name: "Upload ${{ matrix.id }}" with: name: ${{ matrix.id }} - path: ./jars/${{ steps.properties.outputs.makeevrserg-project-name }}-${{ matrix.id }}*.jar \ No newline at end of file + path: ./jars/${{ steps.properties.outputs.klibs-project-name }}-${{ matrix.id }}*.jar \ No newline at end of file diff --git a/.github/workflows/call-upload-github-release.yml b/.github/workflows/call-upload-github-release.yml index faca993..f73e692 100644 --- a/.github/workflows/call-upload-github-release.yml +++ b/.github/workflows/call-upload-github-release.yml @@ -10,33 +10,28 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout Git repo - uses: actions/checkout@v4 + uses: actions/checkout@v6 - uses: christian-draeger/read-properties@1.1.1 id: properties with: path: './gradle.properties' - properties: 'makeevrserg.project.name makeevrserg.project.version.string' + properties: 'klibs.project.name klibs.project.version.string' - - uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e - name: "Download velocity" + - uses: actions/download-artifact@d0ce8fd1167ed839810201de977912a090ab10a7 + name: "Download bukkit" with: - name: velocity + name: bukkit path: ./jars - - uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e + - uses: actions/download-artifact@d0ce8fd1167ed839810201de977912a090ab10a7 name: "Download forge" with: - name: forge - path: ./jars - - uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e - name: "Download fabric" - with: - name: fabric + name: bungee path: ./jars - - uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e - name: "Download bukkit" + - uses: actions/download-artifact@d0ce8fd1167ed839810201de977912a090ab10a7 + name: "Download neoforge" with: - name: bukkit + name: bungee path: ./jars - name: Create release @@ -47,7 +42,7 @@ jobs: with: files: | ./jars/*.jar - tag_name: ${{ steps.properties.outputs.makeevrserg-project-version-string }} - name: ${{ steps.properties.outputs.makeevrserg-project-name }} - ${{ steps.properties.outputs.makeevrserg-project-version-string }} + tag_name: ${{ steps.properties.outputs.klibs-project-version-string }} + name: ${{ steps.properties.outputs.klibs-project-name }} - ${{ steps.properties.outputs.klibs-project-version-string }} draft: false prerelease: false diff --git a/.github/workflows/call-upload-modrinth-release.yml b/.github/workflows/call-upload-modrinth-release.yml index fd7c4aa..b562c7e 100644 --- a/.github/workflows/call-upload-modrinth-release.yml +++ b/.github/workflows/call-upload-modrinth-release.yml @@ -11,25 +11,19 @@ jobs: strategy: matrix: include: - - id: "fabric" - task: ":instances:fabric:assemble" - - id: "forge" - task: ":instances:forge:shadowJar" - - id: "velocity" - task: ":instances:velocity:shadowJar" - id: "bukkit" task: ":instances:bukkit:shadowJar" steps: - name: Checkout Git repo - uses: actions/checkout@v4 + uses: actions/checkout@v6 - uses: christian-draeger/read-properties@1.1.1 id: properties with: path: './gradle.properties' - properties: 'makeevrserg.project.name makeevrserg.project.version.string' + properties: 'klibs.project.name klibs.project.version.string' - - uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e + - uses: actions/download-artifact@d0ce8fd1167ed839810201de977912a090ab10a7 name: "Download ${{ matrix.id }}" with: name: ${{ matrix.id }} @@ -40,8 +34,8 @@ jobs: # your assets on Modrinth. modrinth-id: 6NpNwzA1 modrinth-token: ${{ secrets.MODRINTH_TOKEN }} - name: ${{ steps.properties.outputs.makeevrserg-project-name }}-${{ matrix.id }} - version: ${{ steps.properties.outputs.makeevrserg-project-version-string }} + name: ${{ steps.properties.outputs.klibs-project-name }}-${{ matrix.id }} + version: ${{ steps.properties.outputs.klibs-project-version-string }} changelog: ${{ join(github.event.commits.*.message, '\n') }} version_type: beta java: | diff --git a/.github/workflows/release-master.yml b/.github/workflows/release-master.yml index 82fa4bc..7cd59b6 100644 --- a/.github/workflows/release-master.yml +++ b/.github/workflows/release-master.yml @@ -14,9 +14,3 @@ jobs: uses: ./.github/workflows/call-upload-github-release.yml secrets: ACTIONS_TOKEN: ${{ secrets.ACTIONS_TOKEN }} - - upload_modrinth_artifacts: - needs: [ upload_artifacts ] - uses: ./.github/workflows/call-upload-modrinth-release.yml - secrets: - MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }} diff --git a/docker-compose.yml b/docker-compose.yml index 58fc43c..8bd05d0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,29 +1,36 @@ services: - # For command call use `docker exec mc_docker rcon-cli ` - mc_docker: + # For command call use `docker exec mc_docker_astratemplate rcon-cli ` + mc_docker_astratemplate: restart: no - container_name: mc_docker + container_name: mc_docker_astratemplate image: itzg/minecraft-server # https://github.com/itzg/docker-minecraft-server tty: true stdin_open: true ports: - "25565:25565" environment: + LEVEL_TYPE: FLAT + EXISTING_OPS_FILE: MERGE + OPS: | + RomaRoman EULA: true - # Forge -# TYPE: FORGE -# VERSION: "1.20.1" -# FORGE_VERSION: "47.2.20" - # Custom server - TYPE: PAPER - #CUSTOM_SERVER: https://api.papermc.io/v2/projects/paper/versions/1.21.1/builds/121/downloads/paper-1.21.1-121.jar - VERSION: 1.21.4 + ONLINE_MODE: false + # NeoForge -------------------- + # TYPE: NEOFORGE + # VERSION: "1.20.1" + # NEOFORGE_VERSION: "21.1.129" + # Forge -------------------- + TYPE: FORGE + VERSION: "1.20.1" + FORGE_VERSION: "47.4.12" + # Paper -------------------- + # TYPE: PAPER + # VERSION: 1.21.8 + # Custom ------------------- + # CUSTOM_SERVER: https://api.papermc.io/v2/projects/paper/versions/1.21.1/builds/121/downloads/paper-1.21.1-121.jar volumes: - # Forge -# - ./build/forge:/data - # Bukkit/Paper/Spigot - - ./build/bukkit:/data - # Velocity -# - ./build/velocity:/data - # Fabric -# - ./build/fabric:/data \ No newline at end of file + - ./build/forge:/data # Forge +# - ./build/neoforge:/data # NeoForge +# - ./build/bukkit:/data # Bukkit/Paper/Spigot +# - ./build/velocity:/data # Velocity +# - ./build/fabric:/data # Fabric \ No newline at end of file From 8891e0eeffe7ca017788843943f9f3c6b76c20d9 Mon Sep 17 00:00:00 2001 From: Roman Makeev Date: Sat, 30 May 2026 21:58:15 +0300 Subject: [PATCH 15/16] [FEAT] Update README.md --- README.md | 406 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 247 insertions(+), 159 deletions(-) diff --git a/README.md b/README.md index 0935419..ec1f27e 100644 --- a/README.md +++ b/README.md @@ -1,220 +1,308 @@ -[![kotlin_version](https://img.shields.io/badge/kotlin-1.9.0-blueviolet?style=flat-square)](https://github.com/Astra-Interactive/AstraLibs) -[![kotlin_version](https://img.shields.io/badge/java-17-blueviolet?style=flat-square)](https://github.com/Astra-Interactive/AstraLibs) -[![minecraft_version](https://img.shields.io/badge/minecraft-1.19.2-green?style=flat-square)](https://github.com/Astra-Interactive/AstraLibs) -[![platforms](https://img.shields.io/badge/platform-spigot%7Cvelocity-blue?style=flat-square)](https://github.com/Astra-Interactive/AstraLibs) - -# AstraTemplate v7.0.0 - -### MultiPlatform (Plugin-first) Spigot/Velocity/Fabric/Forge plugin - -This is a Minecraft Multiplatform template that provides architecture and various tools you'll need to create new -Spigot/Velocity/Fabric/Forge server-plugins as fast as possible - -

☄️ Plugins based on AstraTemplate☄️

- -

- - spigot - - - spigot - - - spigot - - - spigot - - - spigot - -

+[![paper](https://img.shields.io/badge/platform-paper-4e9a38?style=flat-square)](https://papermc.io) +[![forge](https://img.shields.io/badge/platform-forge-c6934a?style=flat-square)](https://files.minecraftforge.net) +[![neoforge](https://img.shields.io/badge/platform-neoforge-c6934a?style=flat-square)](https://neoforged.net) -## Not for novice developers +# AstraTemplate -This project can be very difficult for novice developers. Especially for those who were working with java. +A production-grade Minecraft plugin/mod template written in Kotlin. Provides a modular, lifecycle-driven architecture that runs across Paper, Forge, and NeoForge from a single shared codebase. -## Overview +--- -AstraTemplate and it's libs design after more than 3 years of developing spigot plugins and android applications. -It contains powerful and scalable architecture template which will help in your development. +## Plugins built on this template -## 1. Directory structure +

+ + + + + +

- ├── modules - │ ├── api-local # Local api with runtime reloadable SQLite - │ ├── api-remote # Remote sample RickMorty API - │ ├── build-konfig # Compile-time constants - │ └── core # Core multiplatform module - ├── instances - │ ├── bukkit # Paper API plugin - │ ├── forge # Forge server mod - │ ├── fabric # Fabric server mod - └── └── velocity # Velocity plugin +--- -## 2. Gradle plugin +## Project structure -Build convention is great, but it's a lot of boilerplate when you have different projects. +``` +AstraTemplate/ +├── instances/ +│ ├── bukkit/ ← Paper entry point + platform wiring +│ ├── forge/ ← Forge entry point + platform wiring +│ └── neoforge/ ← NeoForge entry point + platform wiring +└── modules/ + ├── api/ + │ ├── local/ ← Database (Exposed ORM, platform-agnostic) + │ └── remote/ ← REST client (Ktor, platform-agnostic) + ├── core/ ← Config, translations, coroutine scopes + ├── build-konfig/ ← Compile-time constants (id, version, etc.) + ├── feature-command/ ← All commands (platform-agnostic!) + ├── feature-gui/ + │ ├── api/ ← GUI interfaces (Router, GuiModule) + │ └── bukkit/ ← Bukkit chest-GUI implementation + └── feature-event/ + ├── bukkit/ ← Bukkit event listeners + ├── forge/ ← Forge event listeners + └── neoforge/ ← NeoForge event listeners +``` -Because of this I've made a decision to implement my gradle plugin into AstraTemplate +Each `instances/` builds a fat jar via ShadowJar and is the only place that knows about a specific platform. Everything in `modules/` is either fully platform-agnostic or has a clearly named platform variant. -My gradle plugin is well-documented and easy to use. [Please, see it](https://github.com/makeevrserg/gradle-plugin) +## Modules -## 3. Modules overview +
+modules/core — config, translations, coroutine scopes -#### 3.1 `api-local` +The foundation every other module depends on. Provides: -This module contains local API with sqlite database. It's Jvm only. Due to this factor, you can easily share this module -between your spigot/velocity plugin or fabric/forge. +- **Config** — `PluginConfiguration` is a `@Serializable` data class written to `config.yml`. Reloaded on `/atempreload` via `StateFlowKrate`. +- **Translations** — `PluginTranslation` works the same way with `translation.yml`. Every string has a default value so the plugin works out of the box with no files present. +- **Coroutine scopes** — `ioScope`, `mainScope`, and `unconfinedScope` backed by `KotlinDispatchers` (platform-provided abstraction over `Dispatchers.IO` / main thread / etc.). All scopes are cancelled in `onDisable`. -With this module you will be only dependent on LocalApi, which is an interface. +
-Currently Exposed is used for SQLite api-local, but you can replace it with anything you want. -Only implementation will be changed, but LocalApi will be untouched, also as other functionality of your plugin/mod +
+modules/api/local — local database via Exposed ORM -#### 3.2 `api-remote` +Local database access via [Jetbrains Exposed](https://github.com/JetBrains/Exposed) ORM. The `LocalDao` interface exposes suspend functions for CRUD operations on `UserTable` and `UserRatingTable`. The underlying database connection is derived reactively from the config flow, so switching from H2 to MySQL is a one-line config change and a reload. -This module contains remote api with RickMortyApi. It will return random character with suspend async response. -Like `api-local`, this module also contains only jvm dependencies, so can be used in spigot/fabrict and others. +Supported drivers (configured in `libs.versions.toml`): **H2**, **SQLite**, **MySQL**, **MariaDB**. -#### 3.3 `build-konfig` +
-Sometimes you need to share constants generated at compile-time between other modules, so this module exactly what you -need. +
+modules/api/remote — REST API client via Ktor + +REST API client built with [Ktor](https://ktor.io). Demonstrates fetching data from an external HTTP endpoint (the Rick & Morty API). The `RickMortyApi` interface returns `Result` — errors are never thrown, always returned explicitly. -#### 3.4 `core` +
-Usually this module contains shared translation/configuration or utilities. +
+modules/build-konfig — compile-time constants + +Generates compile-time constants (`id`, `version`, etc.) via the BuildConfig Gradle plugin. Import from any module that needs to reference the plugin's identity at runtime without hardcoding strings. + +
-## 4. Velocity/Fabric/Forge +
+modules/feature-command — cross-platform commands (no platform imports) -I've not been working with this loaders too much, but th modules contains basic functionality with plugin -information generation. +All commands in one place, with **no platform imports**. Uses the Brigadier DSL from AstraLibs to define commands that compile and run identically on Paper, Forge, and NeoForge. The platform-specific `MultiplatformCommand` adapter is injected at the `RootModule` level. -## 5. Quick overview +
-This plugin contains advanced and powerful spigot functionality +
+modules/feature-gui — chest GUI (Bukkit, with stub for other platforms) -- GUI -- Commands -- Events -- Translation -- DI -- Permissions -- Configuration -- ORM(database) -- Reloading +Split into `api` (the `Router` interface + `GuiModule`) and `bukkit` (the implementation). The Bukkit implementation provides a paginated chest inventory driven by `StateFlow` — the GUI re-renders automatically whenever the underlying data changes. On Forge/NeoForge a `StubGuiModule` satisfies the interface so the shared command module compiles without pulling in Bukkit. -## 6. Architecture overview +
- (Click to expand) Lifecycle diagram +modules/feature-event — platform-specific event listeners -With this hierarchy its' possible to create independent modules +Platform-specific event listeners, one submodule per platform. The Bukkit variant listens to `BlockPlaceEvent`; Forge and NeoForge variants listen to the server tick. Each submodule exposes a `Lifecycle` so `RootModule` can register and unregister listeners cleanly. -Each Module contains Lifecycle which is handled by it's parent module +
+ +--- -Each Lifecycle contains three methods: +## Architecture -- onEnable -- onDisable -- onReload +### Lifecycle tree -In this example, we have `RootPlugin` which is `JavaPlugin`. -`RootPlugin` contains list of child lifecycles. -Child lifecycles called when RootPlugins's lifecycle methods is called. +Every module exposes a `Lifecycle` with three callbacks: `onEnable`, `onDisable`, `onReload`. The plugin entry point creates a `RootModule`, chains all child lifecycles, and delegates to them: -RootPlugin doesn't go beyond it's area of responsibility. -All children handle it's own lifecycles. +```kotlin +// instances/bukkit — AstraTemplate.kt +class AstraTemplate : LifecyclePlugin() { + private val rootModule = RootModule(this) + + override fun onEnable() = rootModule.lifecycle.onEnable() + override fun onDisable() = rootModule.lifecycle.onDisable() + override fun onReload() = rootModule.lifecycle.onReload() +} +``` + +```kotlin +// instances/bukkit — RootModule.kt +class RootModule(plugin: AstraTemplate) { + val coreModule = CoreModule(plugin.dataFolder, DefaultBukkitDispatchers(plugin)) + val apiLocalModule = ApiLocalModule(coreModule.configKrate.cachedStateFlow, coreModule.ioScope) + val apiRemoteModule = ApiRemoteModule() + val eventModule = EventModule(coreModule, plugin) + val guiModule = BukkitGuiModule(coreModule, apiLocalModule) + val commandModule = CommandModule(coreModule, apiRemoteModule, guiModule, ...) + + val lifecycle = Lifecycle.Lambda( + onEnable = { listOf(coreModule, eventModule, apiLocalModule, commandModule).forEach(Lifecycle::onEnable) }, + onDisable = { /* same list, reversed */ }, + onReload = { /* same list */ } + ) +} +``` + +This makes the plugin **reloadable at runtime** — `/atempreload` walks the same chain in reverse and re-enables it, picking up any config or translation changes on the fly. ```mermaid -classDiagram - class RootPlugin { - lifecycles - onEnable() - onDisable() - onReload() - } +graph TD + Plugin --> RootModule + RootModule --> CoreModule + RootModule --> ApiLocalModule + RootModule --> ApiRemoteModule + RootModule --> EventModule + RootModule --> CommandModule + EventModule --> TemplateEvent + EventModule --> BetterAnotherEvent +``` - RootPlugin ..> CoreModule: Child - RootPlugin ..> EventModule: Child - RootPlugin ..> DatabaseModule: Child - EventModule ..> MoveEventModule: Child +### Dependency injection - class MoveEventModule { - lifecycle: Lifecycle - onEnable() - onDisable() - } - class EventModule { - lifecycle: Lifecycle - onEnable() - onDisable() +There is no DI framework. Each module is a plain class whose constructor receives other module interfaces it depends on. `RootModule` is the composition root and instantiates everything in the right order, using `lazy {}` where initialization must be deferred. + +```kotlin +// Pass the whole module interface, not individual services extracted from it +val commandModule = CommandModule( + coreModule = coreModule, + guiModule = guiModule, + apiRemoteModule = apiRemoteModule, + ... +) +``` + +This keeps coupling explicit and avoids hidden runtime failures from missing bindings. + +--- + +## Cross-platform commands + +Commands live in `modules/feature-command` — a plain Kotlin module with **zero platform dependencies**. They use the Brigadier DSL from AstraLibs, which abstracts over Paper's and Forge's native Brigadier adapters. + +```kotlin +// Works on Paper, Forge, and NeoForge without any changes +command("rickandmorty") { + literal("random") { + runs { ctx -> + scope.launch(dispatchers.IO) { + rmApi.getRandomCharacter(Random.nextInt(0, 100)) + .onSuccess { ctx.getSender().sendMessage(...) } + .onFailure { ctx.getSender().sendMessage(...) } + } + } } - class CoreModule { - lifecycle: Lifecycle - onReload() + literal("specific") { + argument("number", IntegerArgumentType.integer()) { numberArg -> + runs { ctx -> send(ctx.getSender(), ctx.requireArgument(numberArg)) } + } } - class DatabaseModule { - lifecycle: Lifecycle - onEnable() - onDisable() +} +``` + +On each platform the `RootModule` provides a `MultiplatformCommand` backed by the right adapter (`PaperMultiplatformCommands`, `MinecraftMultiplatformCommands`). The shared command code never needs to change. + +### Available commands + +| Command | Description | +|-------------------------------------|------------------------------------------------------| +| `/add [amount]` | Add item to a player's inventory | +| `/translation` | Show current translation value (useful after reload) | +| `/adamage ` | Deal damage to a player | +| `/atempgui` | Open the sample paginated GUI | +| `/rickandmorty random` | Fetch a random Rick & Morty character via REST | +| `/rickandmorty specific ` | Fetch a specific character by id | +| `/atempreload` | Reload config, translations, and database connection | + +--- + +## Configuration + +Config and translations are plain `@Serializable` data classes serialized to YAML via [kaml](https://github.com/charleskorn/kaml). Inline doc-comments render directly in the generated YAML file: + +```kotlin +@Serializable +data class PluginConfiguration( + @YamlComment("First line description for config1", "Second line description for config2") + @SerialName("config_1") + val config1: String = "NONE", + + @SerialName("database") + val database: DatabaseConfiguration = DatabaseConfiguration.H2("db") +) +``` + +Both config and translations are stored as `StateFlowKrate` / `CachedKrate`. Any module that reads them always sees the latest value after a reload — no manual propagation needed. + +--- + +## Local database + +`modules/api/local` uses [Jetbrains Exposed](https://github.com/JetBrains/Exposed) as the ORM. The database connection is derived reactively from the config flow — when the config is reloaded with a new database URL, the connection is replaced automatically: + +```kotlin +private val databaseFlow = configFlow + .map { it.database } + .distinctUntilChanged() + .flatMapLatest { configuration -> configuration.connectAsFlow() } + .onEach { db -> + transaction(db) { SchemaUtils.create(UserRatingTable, UserTable) } } + .shareIn(ioScope, SharingStarted.Eagerly, 1) ``` - +Supported drivers (swap in `libs.versions.toml`): **H2**, **SQLite**, **MySQL**, **MariaDB**. -## 7.1 Plugin usage +--- -| Command | Permission | Description | -|:------------------------------------|:-----------|:----------------------------------------------| -| `/add [amount]` | `-` | `Add item to player inventory` | -| `/atemp translation` | `-` | `Show translation change after /atempreload` | -| `/adamage ` | `-` | `Damage player` | -| `/atempgui` | `-` | `Open sample gui` | -| `/rickandmorty ` | `-` | `Send to executor random RickMorty character` | +## Remote API -## 7.1 Fabric mod usage +`modules/api/remote` shows how to call an external REST endpoint using Ktor. The interface is minimal: -| Command | Permission | Description | -|:--------------|:-----------|:-------------------------------| -| `/rickmorty` | `-` | `Rick morty character println` | -| `/helloworld` | `-` | `Hello world println` | +```kotlin +interface RickMortyApi { + suspend fun getRandomCharacter(id: Int): Result +} +``` -## 7.2 Forge mod usage +Errors are returned as `Result` — never thrown — so callers handle failures explicitly. -| Command | Permission | Description | -|:--------------|:-----------|:----------------------| -| `/helloworld` | `-` | `Hello world println` | +--- -### Platforms +## GUI (Bukkit) -- [x] Spigot/Paper -- [x] Fabric - Pre Alpha state -- [x] Forge - Pre-Alpha state -- [x] Velocity +The GUI layer sits behind a `Router` interface defined in `modules/feature-gui/api`. The Bukkit implementation provides a paginated chest inventory with reactive state via Kotlin `StateFlow`: -### Build jar executables +- `SampleGuiComponent` owns state (`Loading` / `Items` / `Users`) +- `SampleGUI` observes state and re-renders on every emission +- Navigation (next/prev page, change mode, add user, back/close) is handled by dedicated button objects -Firstly, change gradle/libs.versions.toml destination-xxx to your folder +On Forge/NeoForge a `StubGuiModule` satisfies the `GuiModule` interface so the shared `CommandModule` compiles without a Bukkit dependency. - $ ./gradlew :plugin:shadowJar # assemble the plugin .jar - $ ./gradlew :velocity:shadowJar # assemble the plugin .jar - $ ./gradlew :fabric:build # assemble the fabric .jar - $ ./gradlew :forge:shadowJar # assemble the forge .jar +--- -### Test server +## Building -There's located [docker-compose.yml](docker-compose.yml) which can launch any server you need for testing purposes. +```bash +# Paper plugin +./gradlew :instances:bukkit:shadowJar -Also, checkout [AstraLearner](https://play.google.com/store/apps/details?id=com.makeevrserg.astralearner) - it will help -you to learn foreign words easily! +# Forge mod +./gradlew :instances:forge:shadowJar -### Afterword +# NeoForge mod +./gradlew :instances:neoforge:shadowJar -AstraTemplate highly dependent on self-written open source libraries +# Run all tests +./gradlew allTests +``` + +Output jars land in each instance's `build/libs/` directory and are optionally copied to a remote server by the FTP Gradle plugin (configure the destination in `libs.versions.toml`). + +--- + +## Test server (Docker) -- [AstraLibs](https://github.com/Astra-Interactive/AstraLibs) - Minecraft development -- [klibs.mikro](https://github.com/makeevrserg/klibs.mikro) - Mapper, UseCase, Dispatchers interface -- [klibs.kstorage](https://github.com/makeevrserg/klibs.kstorage) - Key-value storage wrapper -- [klibs.kdi](https://github.com/makeevrserg/klibs.kdi) - Manual DI +`docker-compose.yml` at the project root starts a local test server using [itzg/minecraft-server](https://github.com/itzg/docker-minecraft-server). + +Before running, **manually edit `docker-compose.yml`** to uncomment the block for your target platform (Forge, NeoForge, or Paper) and comment out the others. Each block sets the `TYPE`, `VERSION`, and platform-specific version variables, and the matching `volumes` entry below it. + +```bash +docker compose up +``` From c8c443aeea1ffcb3ed2c6f5fba8ac370ffd5937a Mon Sep 17 00:00:00 2001 From: Roman Makeev Date: Sun, 31 May 2026 14:09:58 +0300 Subject: [PATCH 16/16] [FEAT] Fix startup --- docker-compose.yml | 4 ++-- .../astratemplate/di/RootModule.kt | 15 +++++++++------ .../astratemplate/di/RootModule.kt | 11 ++++++----- .../astratemplate/di/RootModule.kt | 8 ++++---- modules/core/build.gradle.kts | 1 + .../astratemplate/core/di/CoreModule.kt | 15 +++++++++++---- .../feature/event/di/event/TickEvent.kt | 5 ++++- 7 files changed, 37 insertions(+), 22 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 8bd05d0..af1303e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -24,8 +24,8 @@ services: VERSION: "1.20.1" FORGE_VERSION: "47.4.12" # Paper -------------------- - # TYPE: PAPER - # VERSION: 1.21.8 +# TYPE: PAPER +# VERSION: 1.21.8 # Custom ------------------- # CUSTOM_SERVER: https://api.papermc.io/v2/projects/paper/versions/1.21.1/builds/121/downloads/paper-1.21.1-121.jar volumes: diff --git a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt b/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt index 020c5f6..a62707b 100644 --- a/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt +++ b/instances/bukkit/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt @@ -17,7 +17,13 @@ internal class RootModule(plugin: AstraTemplate) { val coreModule: CoreModule = CoreModule( dataFolder = plugin.dataFolder, - dispatchers = DefaultBukkitDispatchers(plugin) + dispatchers = DefaultBukkitDispatchers(plugin), + commandRegistrarContextFactory = { mainScope -> + PaperCommandRegistrarContext( + mainScope = mainScope, + plugin = plugin + ) + } ) val apiLocalModule: ApiLocalModule = ApiLocalModule( @@ -37,10 +43,7 @@ internal class RootModule(plugin: AstraTemplate) { apiRemoteModule = apiRemoteModule, guiModule = guiModule, lifecyclePlugin = plugin, - commandRegistrarContext = PaperCommandRegistrarContext( - mainScope = coreModule.mainScope, - plugin = plugin - ), + commandRegistrarContext = coreModule.commandRegistrarContext, multiplatformCommand = MultiplatformCommand(PaperMultiplatformCommands()) ) @@ -53,7 +56,7 @@ internal class RootModule(plugin: AstraTemplate) { ) val lifecycle = Lifecycle.Lambda( onEnable = { lifecycles.forEach(Lifecycle::onEnable) }, - onDisable = { lifecycles.forEach(Lifecycle::onDisable) }, + onDisable = { lifecycles.reversed().forEach(Lifecycle::onDisable) }, onReload = { lifecycles.forEach(Lifecycle::onReload) } ) } diff --git a/instances/forge/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt b/instances/forge/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt index e2fbca7..20de9bc 100644 --- a/instances/forge/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt +++ b/instances/forge/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt @@ -18,15 +18,15 @@ import java.io.File class RootModule(forgeLifecycleServer: ForgeLifecycleServer) { private val dataFolder = FMLPaths.CONFIGDIR.get() - .resolve("AspeKt") + .resolve("AstraTemplate") .toAbsolutePath() .toFile() .also(File::mkdirs) private val coreModule: CoreModule = CoreModule( dataFolder = dataFolder, - dispatchers = MinecraftDispatchers() + dispatchers = MinecraftDispatchers(), + commandRegistrarContextFactory = ::ForgeCommandRegistrarContext ) - private val commandRegistrarContext = ForgeCommandRegistrarContext(coreModule.mainScope) private val apiLocalModule: ApiLocalModule by lazy { ApiLocalModule( @@ -46,7 +46,7 @@ class RootModule(forgeLifecycleServer: ForgeLifecycleServer) { guiModule = guiModule, apiRemoteModule = apiRemoteModule, lifecyclePlugin = forgeLifecycleServer, - commandRegistrarContext = commandRegistrarContext, + commandRegistrarContext = coreModule.commandRegistrarContext, multiplatformCommand = MultiplatformCommand(MinecraftMultiplatformCommands()) ) } @@ -60,6 +60,7 @@ class RootModule(forgeLifecycleServer: ForgeLifecycleServer) { coreModule.lifecycle, eventsModule.lifecycle, commandModule.lifecycle, + apiLocalModule.lifecycle ) val lifecycle: Lifecycle by lazy { @@ -68,7 +69,7 @@ class RootModule(forgeLifecycleServer: ForgeLifecycleServer) { lifecycles.forEach(Lifecycle::onEnable) }, onDisable = { - lifecycles.forEach(Lifecycle::onDisable) + lifecycles.reversed().forEach(Lifecycle::onDisable) }, onReload = { lifecycles.forEach(Lifecycle::onReload) diff --git a/instances/neoforge/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt b/instances/neoforge/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt index 1c83a0c..2436b50 100644 --- a/instances/neoforge/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt +++ b/instances/neoforge/src/main/kotlin/ru/astrainteractive/astratemplate/di/RootModule.kt @@ -17,15 +17,15 @@ import java.io.File class RootModule(forgeLifecycleServer: ForgeLifecycleServer) { private val dataFolder = FMLPaths.CONFIGDIR.get() - .resolve("AspeKt") + .resolve("AstraTemplate") .toAbsolutePath() .toFile() .also(File::mkdirs) private val coreModule: CoreModule = CoreModule( dataFolder = dataFolder, - dispatchers = MinecraftDispatchers() + dispatchers = MinecraftDispatchers(), + commandRegistrarContextFactory = ::NeoForgeCommandRegistrarContext ) - private val commandRegistrarContext = NeoForgeCommandRegistrarContext(coreModule.mainScope) val apiLocalModule: ApiLocalModule by lazy { ApiLocalModule( @@ -44,7 +44,7 @@ class RootModule(forgeLifecycleServer: ForgeLifecycleServer) { guiModule = guiModule, apiRemoteModule = apiRemoteModule, lifecyclePlugin = forgeLifecycleServer, - commandRegistrarContext = commandRegistrarContext, + commandRegistrarContext = coreModule.commandRegistrarContext, multiplatformCommand = MultiplatformCommand(MinecraftMultiplatformCommands()) ) } diff --git a/modules/core/build.gradle.kts b/modules/core/build.gradle.kts index 3267469..77d9efc 100644 --- a/modules/core/build.gradle.kts +++ b/modules/core/build.gradle.kts @@ -11,6 +11,7 @@ dependencies { implementation(libs.kotlin.serialization.kaml) implementation(libs.minecraft.astralibs.core) + implementation(libs.minecraft.astralibs.command) implementation(libs.klibs.mikro.core) implementation(libs.klibs.mikro.extensions) diff --git a/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/di/CoreModule.kt b/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/di/CoreModule.kt index b405340..7108aba 100644 --- a/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/di/CoreModule.kt +++ b/modules/core/src/main/kotlin/ru/astrainteractive/astratemplate/core/di/CoreModule.kt @@ -7,6 +7,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.cancel import kotlinx.serialization.StringFormat +import ru.astrainteractive.astralibs.command.api.registrar.CommandRegistrarContext import ru.astrainteractive.astralibs.coroutines.withTimings import ru.astrainteractive.astralibs.kyori.KyoriComponentSerializer import ru.astrainteractive.astralibs.lifecycle.Lifecycle @@ -25,7 +26,8 @@ import java.io.File class CoreModule( val dataFolder: File, - val dispatchers: KotlinDispatchers + val dispatchers: KotlinDispatchers, + commandRegistrarContextFactory: (mainScope: CoroutineScope) -> CommandRegistrarContext ) { private val coroutineExceptionHandler = CoroutineExceptionHandler { _, throwable -> val logger = JUtiltLogger("${BuildKonfig.id}-CoroutineExceptionHandler") @@ -36,14 +38,19 @@ class CoreModule( .Default(dispatchers.IO + SupervisorJob() + coroutineExceptionHandler) .withTimings() - val mainScope: CoroutineScope = CoroutineFeature - .Default(dispatchers.Main + SupervisorJob() + coroutineExceptionHandler) - .withTimings() + // Main dispatcher is initialized later after server onCreate + val mainScope: CoroutineScope by lazy { + CoroutineFeature + .Default(dispatchers.Main + SupervisorJob() + coroutineExceptionHandler) + .withTimings() + } val unconfinedScope = CoroutineFeature .Default(dispatchers.Unconfined + SupervisorJob() + coroutineExceptionHandler) .withTimings() + val commandRegistrarContext = commandRegistrarContextFactory.invoke(unconfinedScope) + val yamlFormat: StringFormat = YamlStringFormat( configuration = Yaml.default.configuration.copy( encodeDefaults = true, diff --git a/modules/feature-event/forge/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/event/TickEvent.kt b/modules/feature-event/forge/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/event/TickEvent.kt index 33d0b80..5d4f003 100644 --- a/modules/feature-event/forge/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/event/TickEvent.kt +++ b/modules/feature-event/forge/src/main/kotlin/ru/astrainteractive/astratemplate/feature/event/di/event/TickEvent.kt @@ -1,15 +1,18 @@ package ru.astrainteractive.astratemplate.feature.event.di.event import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import net.minecraftforge.event.TickEvent import ru.astrainteractive.astralibs.event.flowEvent import ru.astrainteractive.klibs.mikro.core.logging.JUtiltLogger import ru.astrainteractive.klibs.mikro.core.logging.Logger +import kotlin.time.Duration.Companion.seconds class TickEvent(mainScope: CoroutineScope) : Logger by JUtiltLogger("AstraTemplate-TickEvent") { val tickEvent = flowEvent() - .onEach { info { "#tickEvent -> flow onEach" } } + .debounce(1.seconds) + .onEach { info { "#tickEvent -> flow onEach with 1.second debounce" } } .launchIn(mainScope) }