diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 03dfcad..e315c4d 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -1,5 +1,6 @@ name: Check Develop on: + merge_group: pull_request: branches: - 'develop' diff --git a/README.md b/README.md index 15f3ebd..90c8cd3 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,16 @@ # Auction plugin for EmpireProjekt.ru -## No-Lag and free! +## No-Lag, Free, Live Database reload during server runtime without lags! + +

+ drawing +

+ Advantages: -- [x] Sorting: Name,Date,Type,Player +- [x] Sorting: Name, Date, Type, Player +- [x] Grouping by players - [x] Min and Max prices - [x] Max amount per player - [x] Broadcast when auction created @@ -12,6 +18,8 @@ Advantages: - [x] Permissions - [x] Customizable buttons - [x] Fully translatable +- [x] Runtime config and database reload +- [x] Custom currency support | Command | Description | Permission | |:----------------------------------|:------------------------------------------------|:------------------------| @@ -23,5 +31,80 @@ Advantages: | ️- | Allows player to sell up to N items at one time | astra_market.sell_max.N | | ️`/amarketreload` | reload plugin | astra_market.reload | +### Configuring configs + +At first launch there will be created config.yml + +If plugin can't read config there will be created config.default.yml. The error also will be displayed in console, so +you will understand why the config couldn't be parsed. + +```yaml +auction: + use_compact_design: true + max_auction_per_player: 5 + min_price: 10 + max_price: 1000000 + tax_percent: 0 + announce: true + max_time_seconds: 604800000 + # The vault id of currency you want to use + currency_id: null +sounds: + open: "ui.button.click" + close: "ui.button.click" + click: "ui.button.click" + fail: "entity.villager.no" + success: "block.note_block.chime" + sold: "block.note_block.chime" +buttons: + back: + material: "IRON_DOOR" + custom_model_data: 0 + previous: + material: "PAPER" + custom_model_data: 0 + next: + material: "PAPER" + custom_model_data: 0 + sort: + material: "SUNFLOWER" + custom_model_data: 0 + aauc: + material: "DIAMOND" + custom_model_data: 0 + expred: + material: "EMERALD" + custom_model_data: 0 + border: + material: "BLACK_STAINED_GLASS_PANE" + custom_model_data: 0 + players_slots: + material: "PLAYER_HEAD" + custom_model_data: 0 +``` + +### Configuring database + +The database can be changed in runtime after reloading plugin. + +```yaml +# There's 3 types of database +configuration: + type: "MySql" + host: "0.0.0.0" + port: 3006 + user: "user_name" + password: "password" + name: "rating_database" +# Or +configuration: + type: "H2" + name: "file_name" +# Or +configuration: + type: "SQLite" + name: "file_name" +``` + More plugins from AstraInteractive [AstraInteractive](https://github.com/Astra-Interactive) diff --git a/build.gradle.kts b/build.gradle.kts index dfc269d..5c5b78b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -14,8 +14,8 @@ plugins { alias(libs.plugins.klibs.gradle.publication) apply false alias(libs.plugins.klibs.gradle.rootinfo) apply false // klibs - minecraft - alias(libs.plugins.klibs.gradle.minecraft.empty) apply false - alias(libs.plugins.klibs.gradle.minecraft.multiplatform) apply false + alias(libs.plugins.klibs.minecraft.shadow) apply false + alias(libs.plugins.klibs.minecraft.resource.processor) apply false } apply(plugin = "ru.astrainteractive.gradleplugin.dokka.root") diff --git a/gradle.properties b/gradle.properties index b6c17d7..8735257 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,7 @@ makeevrserg.java.ktarget=21 # Project makeevrserg.project.name=AstraMarket makeevrserg.project.group=ru.astrainteractive.astramarket -makeevrserg.project.version.string=1.16.15 +makeevrserg.project.version.string=1.17.0 makeevrserg.project.description=Market plugin for EmpireSMP makeevrserg.project.developers=makeevrserg|Makeev Roman|makeevrserg@gmail.com makeevrserg.project.url=https://empireprojekt.ru diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 9ff7cb9..8c780f5 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -10,9 +10,10 @@ driver-jdbc = "3.46.1.3" # https://github.com/xerial/sqlite-jdbc driver-mysql = "8.0.33" # https://github.com/mysql/mysql-connector-j # klibs -klibs-gradleplugin = "1.3.4" # https://github.com/makeevrserg/gradle-plugin +klibs-gradleplugin = "1.4.0" # https://github.com/makeevrserg/gradle-plugin klibs-mikro = "1.8.8" # https://github.com/makeevrserg/klibs.mikro klibs-kdi = "1.4.8" # https://github.com/makeevrserg/klibs.kdi +klibs-kstorage = "3.1.3" # https://github.com/makeevrserg/klibs.kstorage # Minecraft minecraft-velocity = "4.0.0-SNAPSHOT" # https://github.com/PaperMC/Velocity @@ -20,16 +21,22 @@ minecraft-spigot = "1.21-R0.1-SNAPSHOT" # https://github.com/PaperMC/Paper minecraft-papi = "2.11.6" # https://github.com/PlaceholderAPI/PlaceholderAPI minecraft-protocollib = "5.1.0" # https://github.com/dmulloy2/ProtocolLib minecraft-vault = "1.7.1" # https://github.com/MilkBowl/VaultAPI -minecraft-astralibs = "3.14.1" # https://github.com/Astra-Interactive/AstraLibs +minecraft-astralibs = "3.15.0" # https://github.com/Astra-Interactive/AstraLibs minecraft-bstats = "3.1.0" # https://github.com/Bastian/bStats minecraft-mockbukkit = "3.129.1" #https://github.com/MockBukkit/MockBukkit +# Exposed +ktor = "2.3.12" + # Shadow gradle-shadow = "7.1.2" # https://github.com/johnrengelman/shadow # BuildConfig gradle-buildconfig = "5.5.0" # https://github.com/gmazzo/gradle-buildconfig-plugin +# Exposed +exposed = "0.55.0" # https://github.com/JetBrains/Exposed + [libraries] # Kotlin kotlin-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlin-coroutines" } @@ -39,6 +46,12 @@ kotlin-serializationJson = { module = "org.jetbrains.kotlinx:kotlinx-serializati kotlin-serializationKaml = { module = "com.charleskorn.kaml:kaml", version.ref = "kotlin-kaml" } kotlin-gradle = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin-version" } +# 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" } +exposed-dao = { module = "org.jetbrains.exposed:exposed-dao", version.ref = "exposed" } +exposed-core = { module = "org.jetbrains.exposed:exposed-core", version.ref = "exposed" } + # Shadow gradle-shadow = { module = "gradle.plugin.com.github.johnrengelman:shadow", version.ref = "gradle-shadow" } @@ -63,9 +76,11 @@ minecraft-mockbukkit = { module = "com.github.MockBukkit:MockBukkit", version.re # klibs klibs-mikro-core = { module = "ru.astrainteractive.klibs:mikro-core", version.ref = "klibs-mikro" } klibs-kdi = { module = "ru.astrainteractive.klibs:kdi", version.ref = "klibs-kdi" } +klibs-kstorage = { module = "ru.astrainteractive.klibs:kstorage", version.ref = "klibs-kstorage" } + # AstraLibs -minecraft-astralibs-orm = { module = "ru.astrainteractive.astralibs:orm", version.ref = "minecraft-astralibs" } +minecraft-astralibs-exposed = { module = "ru.astrainteractive.astralibs:exposed", version.ref = "minecraft-astralibs" } minecraft-astralibs-core = { module = "ru.astrainteractive.astralibs:core", version.ref = "minecraft-astralibs" } minecraft-astralibs-menu-bukkit = { module = "ru.astrainteractive.astralibs:menu-bukkit", version.ref = "minecraft-astralibs" } minecraft-astralibs-core-bukkit = { module = "ru.astrainteractive.astralibs:core-bukkit", version.ref = "minecraft-astralibs" } @@ -73,11 +88,11 @@ minecraft-astralibs-command = { module = "ru.astrainteractive.astralibs:command" minecraft-astralibs-command-bukkit = { module = "ru.astrainteractive.astralibs:command-bukkit", version.ref = "minecraft-astralibs" } [bundles] +exposed = ["exposed-java-time", "exposed-jdbc", "exposed-dao", "exposed-core"] minecraft-bukkit = ["minecraft-paper-api", "minecraft-spigot-api", "minecraft-spigot-core", "minecraft-vaultapi", "minecraft-papi"] testing-kotlin = ["kotlin-coroutines-core", "kotlin-coroutines-coreJvm", "driver-jdbc", "driver-mysql", "kotlin-serialization", "kotlin-serializationJson"] kotlin = ["kotlin-coroutines-core", "kotlin-coroutines-coreJvm", "kotlin-serialization", "kotlin-serializationJson", "kotlin-serializationKaml", "kotlin-gradle"] - [plugins] # Kotlin @@ -100,5 +115,5 @@ klibs-gradle-publication = { id = "ru.astrainteractive.gradleplugin.publication" klibs-gradle-rootinfo = { id = "ru.astrainteractive.gradleplugin.root.info", version.ref = "klibs-gradleplugin" } # klibs - minecraft -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-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" } \ No newline at end of file diff --git a/media/market.png b/media/market.png new file mode 100644 index 0000000..d29ce00 Binary files /dev/null and b/media/market.png differ diff --git a/modules/api-market/build.gradle.kts b/modules/api-market/build.gradle.kts index a4c8467..a90fec8 100644 --- a/modules/api-market/build.gradle.kts +++ b/modules/api-market/build.gradle.kts @@ -7,10 +7,13 @@ dependencies { implementation(libs.bundles.kotlin) // AstraLibs implementation(libs.minecraft.astralibs.core) - implementation(libs.minecraft.astralibs.orm) - implementation(libs.klibs.kdi) + implementation(libs.minecraft.astralibs.exposed) implementation(libs.klibs.mikro.core) + implementation(libs.bundles.exposed) // Test testImplementation(libs.bundles.testing.kotlin) testImplementation(libs.tests.kotlin.test) + testImplementation("com.h2database:h2:2.2.224") + // Local + implementation(projects.modules.core) } diff --git a/modules/api-market/src/main/kotlin/ru/astrainteractive/astramarket/api/market/MarketApi.kt b/modules/api-market/src/main/kotlin/ru/astrainteractive/astramarket/api/market/MarketApi.kt index a95469e..ccce3ea 100644 --- a/modules/api-market/src/main/kotlin/ru/astrainteractive/astramarket/api/market/MarketApi.kt +++ b/modules/api-market/src/main/kotlin/ru/astrainteractive/astramarket/api/market/MarketApi.kt @@ -2,6 +2,7 @@ package ru.astrainteractive.astramarket.api.market import ru.astrainteractive.astramarket.api.market.model.MarketSlot import ru.astrainteractive.astramarket.api.market.model.PlayerAndSlots +import java.util.UUID interface MarketApi { /** @@ -52,10 +53,20 @@ interface MarketApi { * @throws Exception */ suspend fun countPlayerSlots(uuid: String): Int? +} - /** - * @return uuid of player who currently have active/expired slots - * @throws Exception - */ - suspend fun findPlayersWithSlots(isExpired: Boolean): List +/** + * @return uuid of player who currently have active/expired slots + * @throws Exception + */ +suspend fun MarketApi.findPlayersWithSlots(isExpired: Boolean): List { + return getSlots(isExpired) + .orEmpty() + .groupBy(MarketSlot::minecraftUuid) + .map { (uuid, slots) -> + PlayerAndSlots( + minecraftUUID = UUID.fromString(uuid), + slots = slots + ) + } } diff --git a/modules/api-market/src/main/kotlin/ru/astrainteractive/astramarket/api/market/impl/ExposedMarketApi.kt b/modules/api-market/src/main/kotlin/ru/astrainteractive/astramarket/api/market/impl/ExposedMarketApi.kt index e06aee8..c64200f 100644 --- a/modules/api-market/src/main/kotlin/ru/astrainteractive/astramarket/api/market/impl/ExposedMarketApi.kt +++ b/modules/api-market/src/main/kotlin/ru/astrainteractive/astramarket/api/market/impl/ExposedMarketApi.kt @@ -1,28 +1,34 @@ package ru.astrainteractive.astramarket.api.market.impl import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.first import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.withContext +import org.jetbrains.exposed.sql.Database +import org.jetbrains.exposed.sql.ResultRow +import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq +import org.jetbrains.exposed.sql.and +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 ru.astrainteractive.astralibs.encoding.model.EncodedObject import ru.astrainteractive.astralibs.logging.JUtiltLogger import ru.astrainteractive.astralibs.logging.Logger -import ru.astrainteractive.astralibs.orm.Database import ru.astrainteractive.astramarket.api.market.MarketApi -import ru.astrainteractive.astramarket.api.market.mapping.AuctionMapper import ru.astrainteractive.astramarket.api.market.model.MarketSlot -import ru.astrainteractive.astramarket.api.market.model.PlayerAndSlots -import ru.astrainteractive.astramarket.db.market.entity.Auction import ru.astrainteractive.astramarket.db.market.entity.AuctionTable import ru.astrainteractive.klibs.mikro.core.dispatchers.KotlinDispatchers -import java.util.UUID import kotlin.coroutines.CoroutineContext internal class ExposedMarketApi( - private val database: Database, - private val auctionMapper: AuctionMapper, + private val databaseFlow: Flow, private val dispatchers: KotlinDispatchers ) : MarketApi, - Logger by JUtiltLogger("SqlMarketApi") { + Logger by JUtiltLogger("AstraMarket-ExposedMarketApi") { private val mutex = Mutex() private suspend fun runCatchingWithContext( @@ -32,26 +38,41 @@ internal class ExposedMarketApi( mutex.withLock { withContext(context, block) } }.onFailure { throwable -> error(throwable) { "Error during execution" } } + private fun toMarketSlot(resultRow: ResultRow): MarketSlot { + return MarketSlot( + id = resultRow[AuctionTable.id].value, + time = resultRow[AuctionTable.time], + minecraftUuid = resultRow[AuctionTable.minecraftUuid], + item = EncodedObject.ByteArray(resultRow[AuctionTable.item]), + price = resultRow[AuctionTable.price], + expired = resultRow[AuctionTable.expired] + ) + } + override suspend fun insertSlot( marketSlot: MarketSlot - ): Int? = runCatchingWithContext(dispatchers.IO) { - AuctionTable.insert(database) { - this[AuctionTable.minecraftUuid] = marketSlot.minecraftUuid - this[AuctionTable.time] = marketSlot.time - this[AuctionTable.item] = marketSlot.item.value - this[AuctionTable.price] = marketSlot.price - this[AuctionTable.expired] = if (marketSlot.expired) 1 else 0 + ) = runCatchingWithContext(dispatchers.IO) { + transaction(databaseFlow.first()) { + AuctionTable.insertAndGetId { + it[AuctionTable.minecraftUuid] = marketSlot.minecraftUuid + it[AuctionTable.time] = marketSlot.time + it[AuctionTable.item] = marketSlot.item.value + it[AuctionTable.price] = marketSlot.price + it[AuctionTable.expired] = marketSlot.expired + }.value } }.getOrNull() override suspend fun expireSlot( marketSlot: MarketSlot ): Unit? = runCatchingWithContext(dispatchers.IO) { - AuctionTable.find(database, constructor = Auction) { - AuctionTable.id.eq(marketSlot.id) - }.firstOrNull()?.let { - it.expired = 1 - AuctionTable.update(database, entity = it) + transaction(databaseFlow.first()) { + AuctionTable.update( + where = { AuctionTable.id.eq(marketSlot.id) }, + body = { + it[AuctionTable.expired] = true + } + ) } Unit }.getOrNull() @@ -60,66 +81,67 @@ internal class ExposedMarketApi( uuid: String, isExpired: Boolean ): List? = runCatchingWithContext(dispatchers.IO) { - AuctionTable.find(database, constructor = Auction) { - AuctionTable.minecraftUuid.eq(uuid).and( - AuctionTable.expired.eq(if (isExpired) 1 else 0) - ) - }.map(auctionMapper::toDTO) + transaction(databaseFlow.first()) { + AuctionTable + .selectAll() + .where { + AuctionTable.minecraftUuid + .eq(uuid) + .and(AuctionTable.expired.eq(isExpired)) + }.map(::toMarketSlot) + } }.getOrNull() override suspend fun getSlots( isExpired: Boolean ): List? = runCatchingWithContext(dispatchers.IO) { - AuctionTable.find(database, constructor = Auction) { - AuctionTable.expired.eq(if (isExpired) 1 else 0) - }.map(auctionMapper::toDTO) + transaction(databaseFlow.first()) { + AuctionTable.selectAll() + .where { AuctionTable.expired.eq(isExpired) } + .map(::toMarketSlot) + } }.getOrNull() override suspend fun getSlotsOlderThan( millis: Long ): List? = runCatchingWithContext(dispatchers.IO) { - val currentTime = System.currentTimeMillis() - val time = currentTime - millis - AuctionTable.find(database, constructor = Auction) { - AuctionTable.time.less(time) - }.map(auctionMapper::toDTO) + transaction(databaseFlow.first()) { + val currentTime = System.currentTimeMillis() + val time = currentTime - millis + AuctionTable.selectAll() + .where { AuctionTable.time.less(time) } + .map(::toMarketSlot) + } }.getOrNull() override suspend fun getSlot( id: Int ): MarketSlot? = runCatchingWithContext(dispatchers.IO) { - AuctionTable.find(database, constructor = Auction) { - AuctionTable.id.eq(id) - }.map(auctionMapper::toDTO).first() + transaction(databaseFlow.first()) { + AuctionTable.selectAll() + .where { AuctionTable.id.eq(id) } + .map(::toMarketSlot) + .firstOrNull() + } }.getOrNull() override suspend fun deleteSlot( marketSlot: MarketSlot ): Unit? = runCatchingWithContext(dispatchers.IO) { - AuctionTable.delete(database) { - AuctionTable.id.eq(marketSlot.id) + transaction(databaseFlow.first()) { + AuctionTable.deleteWhere { AuctionTable.id.eq(marketSlot.id) } } + Unit }.getOrNull() override suspend fun countPlayerSlots( uuid: String ): Int? = runCatchingWithContext(dispatchers.IO) { - AuctionTable.count(database) { - AuctionTable.minecraftUuid.eq(uuid) + transaction(databaseFlow.first()) { + AuctionTable.selectAll() + .where { AuctionTable.minecraftUuid.eq(uuid) } + .count() + .toInt() } }.getOrNull() - - override suspend fun findPlayersWithSlots( - isExpired: Boolean - ): List = runCatchingWithContext(dispatchers.IO) { - AuctionTable.all(database, Auction) - .map(auctionMapper::toDTO) - .groupBy(MarketSlot::minecraftUuid) - .map { (uuid, slots) -> - PlayerAndSlots( - minecraftUUID = UUID.fromString(uuid), - slots = slots - ) - } - }.getOrNull().orEmpty() } diff --git a/modules/api-market/src/main/kotlin/ru/astrainteractive/astramarket/api/market/mapping/AuctionMapper.kt b/modules/api-market/src/main/kotlin/ru/astrainteractive/astramarket/api/market/mapping/AuctionMapper.kt deleted file mode 100644 index 1fd58bd..0000000 --- a/modules/api-market/src/main/kotlin/ru/astrainteractive/astramarket/api/market/mapping/AuctionMapper.kt +++ /dev/null @@ -1,21 +0,0 @@ -package ru.astrainteractive.astramarket.api.market.mapping - -import ru.astrainteractive.astralibs.encoding.model.EncodedObject -import ru.astrainteractive.astramarket.api.market.model.MarketSlot -import ru.astrainteractive.astramarket.db.market.entity.Auction - -internal interface AuctionMapper { - fun toDTO(it: Auction): MarketSlot -} - -internal class AuctionMapperImpl : AuctionMapper { - override fun toDTO(it: Auction): MarketSlot = - MarketSlot( - id = it.id, - minecraftUuid = it.minecraftUuid, - time = it.time, - item = EncodedObject.ByteArray(it.item), - price = it.price, - expired = it.expired == 1 - ) -} diff --git a/modules/api-market/src/main/kotlin/ru/astrainteractive/astramarket/db/market/entity/AuctionTable.kt b/modules/api-market/src/main/kotlin/ru/astrainteractive/astramarket/db/market/entity/AuctionTable.kt index 1a0906b..a277342 100644 --- a/modules/api-market/src/main/kotlin/ru/astrainteractive/astramarket/db/market/entity/AuctionTable.kt +++ b/modules/api-market/src/main/kotlin/ru/astrainteractive/astramarket/db/market/entity/AuctionTable.kt @@ -1,27 +1,11 @@ package ru.astrainteractive.astramarket.db.market.entity -import ru.astrainteractive.astralibs.orm.database.Column -import ru.astrainteractive.astralibs.orm.database.Constructable -import ru.astrainteractive.astralibs.orm.database.Entity -import ru.astrainteractive.astralibs.orm.database.Table +import org.jetbrains.exposed.dao.id.IntIdTable -internal object AuctionTable : Table("auctions") { - override val id: Column = integer("id").primaryKey().autoIncrement() - val discordId = text("discord_id").nullable() +internal object AuctionTable : IntIdTable("auctions") { val minecraftUuid = text("minecraft_uuid") - val time = bigint("time") - val item = byteArray("item", 6132) + val time = long("time") + val item = binary("item", 6132) val price = float("price") val expired = bool("expired") } - -internal class Auction : Entity(AuctionTable) { - val id by AuctionTable.id - val discordId by AuctionTable.discordId - val minecraftUuid by AuctionTable.minecraftUuid - val time by AuctionTable.time - val item by AuctionTable.item - val price by AuctionTable.price - var expired by AuctionTable.expired - companion object : Constructable(::Auction) -} diff --git a/modules/api-market/src/main/kotlin/ru/astrainteractive/astramarket/di/ApiMarketModule.kt b/modules/api-market/src/main/kotlin/ru/astrainteractive/astramarket/di/ApiMarketModule.kt index e4a15a9..f918ef4 100644 --- a/modules/api-market/src/main/kotlin/ru/astrainteractive/astramarket/di/ApiMarketModule.kt +++ b/modules/api-market/src/main/kotlin/ru/astrainteractive/astramarket/di/ApiMarketModule.kt @@ -1,54 +1,83 @@ package ru.astrainteractive.astramarket.di +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.cancel +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.map import kotlinx.coroutines.runBlocking +import kotlinx.serialization.StringFormat +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.async.CoroutineFeature +import ru.astrainteractive.astralibs.exposed.factory.DatabaseFactory import ru.astrainteractive.astralibs.lifecycle.Lifecycle -import ru.astrainteractive.astralibs.orm.DBConnection -import ru.astrainteractive.astralibs.orm.DBSyntax -import ru.astrainteractive.astralibs.orm.Database +import ru.astrainteractive.astralibs.util.FlowExt.mapCached import ru.astrainteractive.astramarket.api.market.MarketApi import ru.astrainteractive.astramarket.api.market.impl.ExposedMarketApi -import ru.astrainteractive.astramarket.api.market.mapping.AuctionMapper -import ru.astrainteractive.astramarket.api.market.mapping.AuctionMapperImpl -import ru.astrainteractive.astramarket.di.factory.DatabaseFactory -import ru.astrainteractive.klibs.kdi.Provider -import ru.astrainteractive.klibs.kdi.getValue +import ru.astrainteractive.astramarket.core.di.factory.ConfigKrateFactory +import ru.astrainteractive.astramarket.db.market.entity.AuctionTable +import ru.astrainteractive.astramarket.model.DatabaseConfig import ru.astrainteractive.klibs.mikro.core.dispatchers.KotlinDispatchers +import java.io.File interface ApiMarketModule { val lifecycle: Lifecycle - val database: Database val marketApi: MarketApi class Default( - dbConnection: DBConnection, - dbSyntax: DBSyntax, - dispatchers: KotlinDispatchers + dispatchers: KotlinDispatchers, + yamlStringFormat: StringFormat, + dataFolder: File, ) : ApiMarketModule { - override val database: Database by lazy { - DatabaseFactory( - dbConnection = dbConnection, - dbSyntax = dbSyntax - ).create() - } - private val auctionMapper: AuctionMapper by Provider { - AuctionMapperImpl() - } + private val scope = CoroutineFeature.Default(Dispatchers.IO) + + private val dbConfig = ConfigKrateFactory.create( + fileNameWithoutExtension = "database", + stringFormat = yamlStringFormat, + dataFolder = dataFolder, + factory = ::DatabaseConfig + ) + + private val databaseFlow: Flow = dbConfig.cachedStateFlow + .map { it.configuration } + .distinctUntilChanged() + .mapCached(scope) { dbConfig, previous -> + previous?.run(TransactionManager::closeAndUnregister) + val database = DatabaseFactory(dataFolder).create(dbConfig) + TransactionManager.manager.defaultIsolationLevel = java.sql.Connection.TRANSACTION_SERIALIZABLE + transaction(database) { + addLogger(Slf4jSqlDebugLogger) + SchemaUtils.create( + AuctionTable, + ) + } + database + } + + override val marketApi: MarketApi = ExposedMarketApi( + databaseFlow = databaseFlow, + dispatchers = dispatchers + ) - override val marketApi: MarketApi by Provider { - ExposedMarketApi( - database = database, - auctionMapper = auctionMapper, - dispatchers = dispatchers - ) - } override val lifecycle: Lifecycle by lazy { Lifecycle.Lambda( onEnable = { - runBlocking { database.openConnection() } }, onDisable = { - runBlocking { database.closeConnection() } + runBlocking { + databaseFlow.first().run(TransactionManager::closeAndUnregister) + } + scope.cancel() + }, + onReload = { + dbConfig.loadAndGet() } ) } diff --git a/modules/api-market/src/main/kotlin/ru/astrainteractive/astramarket/di/factory/DatabaseFactory.kt b/modules/api-market/src/main/kotlin/ru/astrainteractive/astramarket/di/factory/DatabaseFactory.kt deleted file mode 100644 index 7148e16..0000000 --- a/modules/api-market/src/main/kotlin/ru/astrainteractive/astramarket/di/factory/DatabaseFactory.kt +++ /dev/null @@ -1,23 +0,0 @@ -package ru.astrainteractive.astramarket.di.factory - -import kotlinx.coroutines.runBlocking -import ru.astrainteractive.astralibs.orm.DBConnection -import ru.astrainteractive.astralibs.orm.DBSyntax -import ru.astrainteractive.astralibs.orm.Database -import ru.astrainteractive.astralibs.orm.DefaultDatabase -import ru.astrainteractive.astramarket.db.market.entity.AuctionTable -import ru.astrainteractive.klibs.kdi.Factory - -internal class DatabaseFactory( - private val dbConnection: DBConnection, - private val dbSyntax: DBSyntax, -) : Factory { - override fun create(): Database { - return runBlocking { - val database = DefaultDatabase(dbConnection, dbSyntax) - database.openConnection() - AuctionTable.create(database) - database - } - } -} diff --git a/modules/api-market/src/main/kotlin/ru/astrainteractive/astramarket/model/DatabaseConfig.kt b/modules/api-market/src/main/kotlin/ru/astrainteractive/astramarket/model/DatabaseConfig.kt new file mode 100644 index 0000000..178981b --- /dev/null +++ b/modules/api-market/src/main/kotlin/ru/astrainteractive/astramarket/model/DatabaseConfig.kt @@ -0,0 +1,9 @@ +package ru.astrainteractive.astramarket.model + +import kotlinx.serialization.Serializable +import ru.astrainteractive.astralibs.exposed.model.DatabaseConfiguration + +@Serializable +internal class DatabaseConfig( + val configuration: DatabaseConfiguration = DatabaseConfiguration.H2("MARKET") +) diff --git a/modules/api-market/src/test/java/ru/astrainteractive/astramarket/api/market/MarketApiTest.kt b/modules/api-market/src/test/java/ru/astrainteractive/astramarket/api/market/MarketApiTest.kt index 063e7fb..f24759b 100644 --- a/modules/api-market/src/test/java/ru/astrainteractive/astramarket/api/market/MarketApiTest.kt +++ b/modules/api-market/src/test/java/ru/astrainteractive/astramarket/api/market/MarketApiTest.kt @@ -2,9 +2,8 @@ package ru.astrainteractive.astramarket.api.market import kotlinx.coroutines.runBlocking import ru.astrainteractive.astralibs.encoding.model.EncodedObject -import ru.astrainteractive.astralibs.orm.DBConnection -import ru.astrainteractive.astralibs.orm.DBSyntax -import ru.astrainteractive.astramarket.db.market.entity.AuctionTable +import ru.astrainteractive.astralibs.serialization.YamlStringFormat +import ru.astrainteractive.astramarket.api.market.model.MarketSlot import ru.astrainteractive.astramarket.di.ApiMarketModule import ru.astrainteractive.klibs.mikro.core.dispatchers.DefaultKotlinDispatchers import java.io.File @@ -16,19 +15,13 @@ import kotlin.test.Test import kotlin.test.assertEquals class MarketApiTest { - private val moduleFactory = { - ApiMarketModule.Default( - dispatchers = DefaultKotlinDispatchers, - dbSyntax = DBSyntax.SQLite, - dbConnection = DBConnection.SQLite("db.db") - ) - } + private var module: ApiMarketModule? = null private val marketApi: MarketApi get() = module?.marketApi ?: error("Module is null") - private val randomAuction: ru.astrainteractive.astramarket.api.market.model.MarketSlot - get() = ru.astrainteractive.astramarket.api.market.model.MarketSlot( + private val randomAuction: MarketSlot + get() = MarketSlot( id = -1, minecraftUuid = UUID.randomUUID().toString(), time = System.currentTimeMillis(), @@ -39,16 +32,20 @@ class MarketApiTest { @BeforeTest fun setup(): Unit = runBlocking { - File("db.db").delete() - val module = moduleFactory.invoke() - module.database.openConnection() - AuctionTable.create(module.database) + File("./test").deleteRecursively() + val module = ApiMarketModule.Default( + dispatchers = DefaultKotlinDispatchers, + yamlStringFormat = YamlStringFormat(), + dataFolder = File("./test").also { it.deleteOnExit() }, + ) + module.lifecycle.onEnable() this@MarketApiTest.module = module } @AfterTest fun destroy(): Unit = runBlocking { - module?.database?.closeConnection() + File("./test").deleteRecursively() + module?.lifecycle?.onDisable() module = null } diff --git a/modules/command-bukkit/build.gradle.kts b/modules/command-bukkit/build.gradle.kts index ca4de87..1801f70 100644 --- a/modules/command-bukkit/build.gradle.kts +++ b/modules/command-bukkit/build.gradle.kts @@ -9,7 +9,6 @@ dependencies { // AstraLibs implementation(libs.minecraft.astralibs.core) implementation(libs.minecraft.astralibs.core.bukkit) - implementation(libs.klibs.kdi) implementation(libs.klibs.mikro.core) implementation(libs.minecraft.astralibs.command) implementation(libs.minecraft.astralibs.command.bukkit) diff --git a/modules/command-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/command/auction/AuctionCommandExecutor.kt b/modules/command-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/command/auction/AuctionCommandExecutor.kt index 00a751f..ebfbf70 100644 --- a/modules/command-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/command/auction/AuctionCommandExecutor.kt +++ b/modules/command-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/command/auction/AuctionCommandExecutor.kt @@ -17,7 +17,7 @@ internal class AuctionCommandExecutor( private val dependencies: AuctionCommandDependencies ) : CommandExecutor, AuctionCommandDependencies by dependencies, - Logger by JUtiltLogger("AuctionCommandExecutor") { + Logger by JUtiltLogger("AstraMarket-AuctionCommandExecutor") { private val mutex = Mutex() override fun execute(input: AuctionCommand.Result) { diff --git a/modules/command-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/command/auction/di/AuctionCommandDependencies.kt b/modules/command-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/command/auction/di/AuctionCommandDependencies.kt index bf071ef..fb86532 100644 --- a/modules/command-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/command/auction/di/AuctionCommandDependencies.kt +++ b/modules/command-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/command/auction/di/AuctionCommandDependencies.kt @@ -8,12 +8,11 @@ import ru.astrainteractive.astramarket.core.Translation import ru.astrainteractive.astramarket.core.di.BukkitCoreModule import ru.astrainteractive.astramarket.core.di.CoreModule import ru.astrainteractive.astramarket.core.itemstack.ItemStackEncoder +import ru.astrainteractive.astramarket.core.util.getValue import ru.astrainteractive.astramarket.gui.router.GuiRouter import ru.astrainteractive.astramarket.gui.router.di.RouterModule -import ru.astrainteractive.astramarket.market.di.MarketModule +import ru.astrainteractive.astramarket.market.di.MarketViewModule import ru.astrainteractive.astramarket.market.domain.usecase.CreateAuctionUseCase -import ru.astrainteractive.klibs.kdi.Provider -import ru.astrainteractive.klibs.kdi.getValue import ru.astrainteractive.klibs.mikro.core.dispatchers.KotlinDispatchers internal interface AuctionCommandDependencies { @@ -31,20 +30,16 @@ internal interface AuctionCommandDependencies { coreModule: CoreModule, bukkitCoreModule: BukkitCoreModule, routerModule: RouterModule, - marketModule: MarketModule + marketViewModule: MarketViewModule ) : AuctionCommandDependencies { - override val plugin: JavaPlugin by bukkitCoreModule.plugin + override val plugin: JavaPlugin = bukkitCoreModule.plugin override val kyoriComponentSerializer by bukkitCoreModule.kyoriComponentSerializer - override val translation: Translation by coreModule.translation - override val router: GuiRouter by Provider { - routerModule.router - } + override val translation: Translation by coreModule.translationKrate + override val router: GuiRouter = routerModule.router override val itemStackEncoder = bukkitCoreModule.itemStackEncoder - override val scope: CoroutineScope by coreModule.scope + override val scope: CoroutineScope = coreModule.scope override val dispatchers: KotlinDispatchers = coreModule.dispatchers - override val createAuctionUseCase: CreateAuctionUseCase by Provider { - marketModule.marketDomainModule.createAuctionUseCase - } + override val createAuctionUseCase = marketViewModule.marketViewDomainModule.createAuctionUseCase override val limitedIoDispatcher: CoroutineDispatcher = dispatchers.IO.limitedParallelism(1) } } diff --git a/modules/command-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/command/common/di/CommonCommandDependencies.kt b/modules/command-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/command/common/di/CommonCommandDependencies.kt index 0cab45a..2042448 100644 --- a/modules/command-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/command/common/di/CommonCommandDependencies.kt +++ b/modules/command-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/command/common/di/CommonCommandDependencies.kt @@ -1,14 +1,14 @@ package ru.astrainteractive.astramarket.command.common.di import ru.astrainteractive.astralibs.kyori.KyoriComponentSerializer -import ru.astrainteractive.astramarket.core.AstraMarketPlugin +import ru.astrainteractive.astramarket.core.LifecyclePlugin import ru.astrainteractive.astramarket.core.Translation import ru.astrainteractive.astramarket.core.di.BukkitCoreModule import ru.astrainteractive.astramarket.core.di.CoreModule -import ru.astrainteractive.klibs.kdi.getValue +import ru.astrainteractive.astramarket.core.util.getValue internal interface CommonCommandDependencies { - val plugin: AstraMarketPlugin + val plugin: LifecyclePlugin val translation: Translation val kyoriComponentSerializer: KyoriComponentSerializer @@ -16,8 +16,8 @@ internal interface CommonCommandDependencies { bukkitCoreModule: BukkitCoreModule, coreModule: CoreModule ) : CommonCommandDependencies { - override val plugin: AstraMarketPlugin by bukkitCoreModule.plugin - override val translation: Translation by coreModule.translation + override val plugin: LifecyclePlugin = bukkitCoreModule.plugin + override val translation: Translation by coreModule.translationKrate override val kyoriComponentSerializer by bukkitCoreModule.kyoriComponentSerializer } } diff --git a/modules/command-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/command/di/CommandModule.kt b/modules/command-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/command/di/CommandModule.kt index f3c4c24..4a48865 100644 --- a/modules/command-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/command/di/CommandModule.kt +++ b/modules/command-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/command/di/CommandModule.kt @@ -8,7 +8,7 @@ import ru.astrainteractive.astramarket.command.common.di.CommonCommandDependenci import ru.astrainteractive.astramarket.core.di.BukkitCoreModule import ru.astrainteractive.astramarket.core.di.CoreModule import ru.astrainteractive.astramarket.gui.router.di.RouterModule -import ru.astrainteractive.astramarket.market.di.MarketModule +import ru.astrainteractive.astramarket.market.di.MarketViewModule interface CommandModule { val lifecycle: Lifecycle @@ -17,7 +17,7 @@ interface CommandModule { coreModule: CoreModule, bukkitCoreModule: BukkitCoreModule, routerModule: RouterModule, - marketModule: MarketModule + marketViewModule: MarketViewModule ) : CommandModule { override val lifecycle: Lifecycle by lazy { Lifecycle.Lambda( @@ -32,7 +32,7 @@ interface CommandModule { dependencies = AuctionCommandDependencies.Default( coreModule = coreModule, bukkitCoreModule = bukkitCoreModule, - marketModule = marketModule, + marketViewModule = marketViewModule, routerModule = routerModule ) ).register() diff --git a/modules/core-bukkit/build.gradle.kts b/modules/core-bukkit/build.gradle.kts index 90a81a5..7b19a2e 100644 --- a/modules/core-bukkit/build.gradle.kts +++ b/modules/core-bukkit/build.gradle.kts @@ -9,11 +9,12 @@ dependencies { // AstraLibs implementation(libs.minecraft.astralibs.core) implementation(libs.minecraft.astralibs.core.bukkit) - implementation(libs.klibs.kdi) implementation(libs.minecraft.astralibs.menu.bukkit) + implementation(libs.klibs.mikro.core) // Spigot dependencies compileOnly(libs.minecraft.paper.api) implementation(libs.minecraft.bstats) + implementation(libs.minecraft.vaultapi) // Local implementation(projects.modules.core) } diff --git a/modules/core-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/core/AstraMarketPlugin.kt b/modules/core-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/core/LifecyclePlugin.kt similarity index 85% rename from modules/core-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/core/AstraMarketPlugin.kt rename to modules/core-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/core/LifecyclePlugin.kt index 34fadd2..125c6a3 100644 --- a/modules/core-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/core/AstraMarketPlugin.kt +++ b/modules/core-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/core/LifecyclePlugin.kt @@ -3,7 +3,7 @@ package ru.astrainteractive.astramarket.core import org.bukkit.plugin.java.JavaPlugin import ru.astrainteractive.astralibs.lifecycle.Lifecycle -abstract class AstraMarketPlugin : JavaPlugin(), Lifecycle { +abstract class LifecyclePlugin : JavaPlugin(), Lifecycle { override fun onEnable() { super.onEnable() super.onEnable() diff --git a/modules/core-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/core/di/BukkitCoreModule.kt b/modules/core-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/core/di/BukkitCoreModule.kt index da7864d..8481c6c 100644 --- a/modules/core-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/core/di/BukkitCoreModule.kt +++ b/modules/core-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/core/di/BukkitCoreModule.kt @@ -1,63 +1,96 @@ package ru.astrainteractive.astramarket.core.di +import com.charleskorn.kaml.PolymorphismStyle +import com.charleskorn.kaml.Yaml +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.cancel +import kotlinx.serialization.StringFormat import org.bstats.bukkit.Metrics +import ru.astrainteractive.astralibs.async.CoroutineFeature +import ru.astrainteractive.astralibs.async.DefaultBukkitDispatchers import ru.astrainteractive.astralibs.encoding.encoder.BukkitObjectEncoder import ru.astrainteractive.astralibs.encoding.encoder.ObjectEncoder import ru.astrainteractive.astralibs.event.EventListener import ru.astrainteractive.astralibs.kyori.KyoriComponentSerializer import ru.astrainteractive.astralibs.lifecycle.Lifecycle import ru.astrainteractive.astralibs.menu.event.DefaultInventoryClickEvent -import ru.astrainteractive.astramarket.core.AstraMarketPlugin +import ru.astrainteractive.astralibs.serialization.YamlStringFormat +import ru.astrainteractive.astramarket.core.LifecyclePlugin +import ru.astrainteractive.astramarket.core.PluginConfig +import ru.astrainteractive.astramarket.core.Translation +import ru.astrainteractive.astramarket.core.di.factory.ConfigKrateFactory +import ru.astrainteractive.astramarket.core.di.factory.CurrencyEconomyProviderFactory import ru.astrainteractive.astramarket.core.itemstack.ItemStackEncoder import ru.astrainteractive.astramarket.core.itemstack.ItemStackEncoderImpl -import ru.astrainteractive.klibs.kdi.Factory -import ru.astrainteractive.klibs.kdi.Lateinit -import ru.astrainteractive.klibs.kdi.Reloadable -import ru.astrainteractive.klibs.kdi.Single -import ru.astrainteractive.klibs.kdi.getValue +import ru.astrainteractive.klibs.kstorage.api.Krate +import ru.astrainteractive.klibs.kstorage.api.impl.DefaultMutableKrate -interface BukkitCoreModule { - val lifecycle: Lifecycle +interface BukkitCoreModule : CoreModule { - val plugin: Lateinit + val plugin: LifecyclePlugin val itemStackEncoder: ItemStackEncoder + val inventoryClickEventListener: EventListener + val kyoriComponentSerializer: Krate - val inventoryClickEventListener: Single - val kyoriComponentSerializer: Reloadable + class Default(override val plugin: LifecyclePlugin) : BukkitCoreModule { - class Default : BukkitCoreModule { + private val encoder: ObjectEncoder = BukkitObjectEncoder() - override val plugin: Lateinit = Lateinit() + override val itemStackEncoder: ItemStackEncoder = ItemStackEncoderImpl(encoder) - private val encoder: ObjectEncoder by lazy { - BukkitObjectEncoder() - } + override val inventoryClickEventListener = DefaultInventoryClickEvent() - override val itemStackEncoder: ItemStackEncoder by lazy { - ItemStackEncoderImpl(encoder) - } + override val kyoriComponentSerializer = DefaultMutableKrate( + factory = { KyoriComponentSerializer.Legacy }, + loader = { null } + ) - override val inventoryClickEventListener: Single = Single { - DefaultInventoryClickEvent() - } + private fun createBStats() = Metrics(plugin, 15771) - override val kyoriComponentSerializer: Reloadable = Reloadable { - KyoriComponentSerializer.Legacy - } + override val yamlStringFormat: StringFormat = YamlStringFormat( + configuration = Yaml.default.configuration.copy( + encodeDefaults = true, + strictMode = false, + polymorphismStyle = PolymorphismStyle.Property + ), + ) - private val bStatsFactory = Factory { - val plugin by plugin - Metrics(plugin, 15771) - } + override val configKrate: Krate = ConfigKrateFactory.create( + fileNameWithoutExtension = "config", + stringFormat = yamlStringFormat, + dataFolder = plugin.dataFolder, + factory = ::PluginConfig + ) + + override val translationKrate: Krate = ConfigKrateFactory.create( + fileNameWithoutExtension = "translations", + stringFormat = yamlStringFormat, + dataFolder = plugin.dataFolder, + factory = ::Translation + ) + + override val scope: CoroutineScope = CoroutineFeature.Default(Dispatchers.IO) + + override val dispatchers = DefaultBukkitDispatchers(plugin) + + override val economyProviderFactory: CurrencyEconomyProviderFactory = + BukkitCurrencyEconomyProviderFactory(plugin) override val lifecycle: Lifecycle by lazy { Lifecycle.Lambda( onEnable = { - bStatsFactory.create() - inventoryClickEventListener.value.onEnable(plugin.value) + createBStats() + inventoryClickEventListener.onEnable(plugin) }, onDisable = { - inventoryClickEventListener.value.onEnable(plugin.value) + inventoryClickEventListener.onDisable() + scope.cancel() + }, + onReload = { + kyoriComponentSerializer.loadAndGet() + configKrate.loadAndGet() + translationKrate.loadAndGet() } ) } diff --git a/modules/core-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/core/di/BukkitCurrencyEconomyProviderFactory.kt b/modules/core-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/core/di/BukkitCurrencyEconomyProviderFactory.kt new file mode 100644 index 0000000..20a38ca --- /dev/null +++ b/modules/core-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/core/di/BukkitCurrencyEconomyProviderFactory.kt @@ -0,0 +1,41 @@ +package ru.astrainteractive.astramarket.core.di + +import net.milkbowl.vault.economy.Economy +import org.bukkit.Bukkit +import org.bukkit.plugin.java.JavaPlugin +import ru.astrainteractive.astralibs.economy.EconomyFacade +import ru.astrainteractive.astralibs.economy.EssentialsEconomyFacade +import ru.astrainteractive.astralibs.economy.VaultEconomyFacade +import ru.astrainteractive.astralibs.logging.JUtiltLogger +import ru.astrainteractive.astralibs.logging.Logger +import ru.astrainteractive.astramarket.core.di.factory.CurrencyEconomyProviderFactory + +internal class BukkitCurrencyEconomyProviderFactory( + private val plugin: JavaPlugin, +) : CurrencyEconomyProviderFactory, + Logger by JUtiltLogger("AstraMarket-CurrencyEconomyProviderFactory") { + override fun findByCurrencyId(currencyId: String): EconomyFacade? { + val registrations = Bukkit.getServer().servicesManager.getRegistrations(Economy::class.java) + info { "#findEconomyProviderByCurrency registrations: ${registrations.size}" } + val specificEconomyProvider = registrations + .firstOrNull { it.provider.currencyNameSingular() == currencyId } + ?.provider + ?.let(::VaultEconomyFacade) + if (specificEconomyProvider == null) { + error { "#economyProvider could not find economy with currency: $currencyId" } + } + return specificEconomyProvider + } + + override fun findDefault(): EconomyFacade? { + return kotlin.runCatching { + VaultEconomyFacade(plugin) + }.getOrNull() ?: kotlin.runCatching { + if (!Bukkit.getServer().pluginManager.isPluginEnabled("Essentials")) { + error("Essentials not enabled") + } else { + EssentialsEconomyFacade + } + }.getOrNull() + } +} diff --git a/modules/core/build.gradle.kts b/modules/core/build.gradle.kts index c09ff4c..3aed48a 100644 --- a/modules/core/build.gradle.kts +++ b/modules/core/build.gradle.kts @@ -8,6 +8,6 @@ dependencies { implementation(libs.bundles.kotlin) // AstraLibs implementation(libs.minecraft.astralibs.core) - implementation(libs.klibs.kdi) implementation(libs.klibs.mikro.core) + api(libs.klibs.kstorage) } diff --git a/modules/core/src/main/kotlin/ru/astrainteractive/astramarket/core/PluginConfig.kt b/modules/core/src/main/kotlin/ru/astrainteractive/astramarket/core/PluginConfig.kt index 37cc110..1907276 100644 --- a/modules/core/src/main/kotlin/ru/astrainteractive/astramarket/core/PluginConfig.kt +++ b/modules/core/src/main/kotlin/ru/astrainteractive/astramarket/core/PluginConfig.kt @@ -7,65 +7,76 @@ import kotlin.time.Duration.Companion.days @Serializable data class PluginConfig( + @SerialName("auction") val auction: Auction = Auction(), + @SerialName("sounds") val sounds: Sounds = Sounds(), + @SerialName("buttons") val buttons: Buttons = Buttons(), - val connection: Connection = Connection() ) { - @Serializable - class Connection( - val sqlite: Boolean = true, - val mysql: MySqlConnection? = MySqlConnection() - ) { - @Serializable - class MySqlConnection( - val database: String = "SAMPLE_DATABASE", - val ip: String = "127.0.0.1", - val port: Int = 8080, - val username: String = "USERNAME", - val password: String = "PASSWORD", - val sessionVariables: List = listOf("autoReconnect=true", "useSSL=false") - ) - } @Serializable data class Auction( + @SerialName("use_compact_design") val useCompactDesign: Boolean = true, + @SerialName("max_auction_per_player") val maxAuctionPerPlayer: Int = 5, + @SerialName("min_price") val minPrice: Int = 10, + @SerialName("max_price") val maxPrice: Int = 1000000, + @SerialName("tax_percent") val taxPercent: Int = 0, + @SerialName("announce") val announce: Boolean = true, + @SerialName("max_time_seconds") val maxTimeSeconds: Long = 7.days.inWholeMilliseconds, // 1*24*60*60*1000 @SerialName("currency_id") - @YamlComment("The id of currency you want to use") + @YamlComment("The vault id of currency you want to use") val currencyId: String? = null ) @Serializable data class Sounds( + @SerialName("open") val open: String = "ui.button.click", + @SerialName("close") val close: String = "ui.button.click", + @SerialName("click") val click: String = "ui.button.click", + @SerialName("fail") val fail: String = "entity.villager.no", + @SerialName("success") val success: String = "block.note_block.chime", + @SerialName("sold") val sold: String = "block.note_block.chime" ) @Serializable data class Buttons( + @SerialName("back") val back: Button = Button("IRON_DOOR"), + @SerialName("previous") val previous: Button = Button("PAPER"), + @SerialName("next") val next: Button = Button("PAPER"), + @SerialName("sort") val sort: Button = Button("SUNFLOWER"), + @SerialName("aauc") val aauc: Button = Button("DIAMOND"), + @SerialName("expred") val expired: Button = Button("EMERALD"), - val border: Button = Button("BLACK_STAINED_GLASS_PANE") + @SerialName("border") + val border: Button = Button("BLACK_STAINED_GLASS_PANE"), + @SerialName("players_slots") + val playersSlots: Button = Button("PLAYER_HEAD") ) @Serializable data class Button( + @SerialName("material") val material: String, + @SerialName("custom_model_data") val customModelData: Int = 0 ) } diff --git a/modules/core/src/main/kotlin/ru/astrainteractive/astramarket/core/Translation.kt b/modules/core/src/main/kotlin/ru/astrainteractive/astramarket/core/Translation.kt index f9444bb..27d60fa 100644 --- a/modules/core/src/main/kotlin/ru/astrainteractive/astramarket/core/Translation.kt +++ b/modules/core/src/main/kotlin/ru/astrainteractive/astramarket/core/Translation.kt @@ -33,6 +33,10 @@ data class Translation( val prev: StringDesc.Raw = StringDesc.Raw("dbd1Раньше"), @SerializedName("sort") val sort: StringDesc.Raw = StringDesc.Raw("dbd1Сортировка"), + @SerializedName("player_slots") + val playerSlots: StringDesc.Raw = StringDesc.Raw("dbd1Групировка по игрокам"), + @SerializedName("all_slots") + val allSlots: StringDesc.Raw = StringDesc.Raw("dbd1Все слоты"), ) @Serializable diff --git a/modules/core/src/main/kotlin/ru/astrainteractive/astramarket/core/di/CoreModule.kt b/modules/core/src/main/kotlin/ru/astrainteractive/astramarket/core/di/CoreModule.kt index 25709df..afe08d0 100644 --- a/modules/core/src/main/kotlin/ru/astrainteractive/astramarket/core/di/CoreModule.kt +++ b/modules/core/src/main/kotlin/ru/astrainteractive/astramarket/core/di/CoreModule.kt @@ -1,73 +1,21 @@ package ru.astrainteractive.astramarket.core.di -import ru.astrainteractive.astralibs.async.AsyncComponent -import ru.astrainteractive.astralibs.economy.EconomyProvider +import kotlinx.coroutines.CoroutineScope +import kotlinx.serialization.StringFormat import ru.astrainteractive.astralibs.lifecycle.Lifecycle -import ru.astrainteractive.astralibs.serialization.StringFormatExt.parse -import ru.astrainteractive.astralibs.serialization.StringFormatExt.writeIntoFile -import ru.astrainteractive.astralibs.serialization.YamlStringFormat import ru.astrainteractive.astramarket.core.PluginConfig import ru.astrainteractive.astramarket.core.Translation -import ru.astrainteractive.klibs.kdi.Dependency -import ru.astrainteractive.klibs.kdi.Reloadable -import ru.astrainteractive.klibs.kdi.Single +import ru.astrainteractive.astramarket.core.di.factory.CurrencyEconomyProviderFactory +import ru.astrainteractive.klibs.kstorage.api.Krate import ru.astrainteractive.klibs.mikro.core.dispatchers.KotlinDispatchers -import java.io.File interface CoreModule { val lifecycle: Lifecycle - val config: Dependency - val translation: Dependency - val scope: Dependency - val dispatchers: KotlinDispatchers - val economyProvider: EconomyProvider - - class Default( - dataFolder: File, - override val dispatchers: KotlinDispatchers, - private val getEconomyProvider: (id: String?) -> EconomyProvider - ) : CoreModule { - - override val translation: Reloadable = Reloadable { - val file = dataFolder.resolve("translations.yml") - if (!file.parentFile.exists()) file.parentFile.mkdirs() - if (!file.exists()) file.createNewFile() - val serializer = YamlStringFormat() - serializer.parse(file) - .onFailure(Throwable::printStackTrace) - .getOrElse { Translation() } - .also { serializer.writeIntoFile(it, file) } - } - - override val config: Reloadable = Reloadable { - val file = dataFolder.resolve("config.yml") - if (!file.parentFile.exists()) file.parentFile.mkdirs() - if (!file.exists()) file.createNewFile() - val serializer = YamlStringFormat() - serializer.parse(file) - .onFailure(Throwable::printStackTrace) - .getOrElse { PluginConfig() } - .also { serializer.writeIntoFile(it, file) } - } - override val economyProvider: EconomyProvider by lazy { - getEconomyProvider.invoke(config.value.auction.currencyId) - } - - override val scope: Dependency = Single { - AsyncComponent.Default() - } - - override val lifecycle: Lifecycle by lazy { - Lifecycle.Lambda( - onReload = { - config.reload() - translation.reload() - }, - onDisable = { - scope.value.close() - } - ) - } - } + val configKrate: Krate + val translationKrate: Krate + val scope: CoroutineScope + val dispatchers: KotlinDispatchers + val yamlStringFormat: StringFormat + val economyProviderFactory: CurrencyEconomyProviderFactory } diff --git a/modules/core/src/main/kotlin/ru/astrainteractive/astramarket/core/di/factory/ConfigKrateFactory.kt b/modules/core/src/main/kotlin/ru/astrainteractive/astramarket/core/di/factory/ConfigKrateFactory.kt new file mode 100644 index 0000000..693a7dd --- /dev/null +++ b/modules/core/src/main/kotlin/ru/astrainteractive/astramarket/core/di/factory/ConfigKrateFactory.kt @@ -0,0 +1,39 @@ +package ru.astrainteractive.astramarket.core.di.factory + +import kotlinx.serialization.StringFormat +import ru.astrainteractive.astralibs.logging.JUtiltLogger +import ru.astrainteractive.astralibs.logging.Logger +import ru.astrainteractive.astralibs.serialization.StringFormatExt.parse +import ru.astrainteractive.astralibs.serialization.StringFormatExt.writeIntoFile +import ru.astrainteractive.klibs.kstorage.api.impl.DefaultStateFlowMutableKrate +import ru.astrainteractive.klibs.kstorage.api.value.ValueFactory +import java.io.File + +object ConfigKrateFactory : Logger by JUtiltLogger("AstraMarket-ConfigKrateFactory") { + inline fun create( + fileNameWithoutExtension: String, + stringFormat: StringFormat, + dataFolder: File, + factory: ValueFactory + ): DefaultStateFlowMutableKrate { + return DefaultStateFlowMutableKrate( + factory = factory, + loader = { + val file = dataFolder.resolve("$fileNameWithoutExtension.yml") + stringFormat.parse(file) + .onFailure { + stringFormat.writeIntoFile( + value = factory.create(), + file = when { + !file.exists() || file.length() == 0L -> file + else -> dataFolder.resolve("$fileNameWithoutExtension.default.yml") + } + ) + error { "Could not read $fileNameWithoutExtension.yml! Loaded default. Error -> ${it.message}" } + } + .onSuccess { stringFormat.writeIntoFile(it, file) } + .getOrElse { factory.create() } + } + ) + } +} diff --git a/modules/core/src/main/kotlin/ru/astrainteractive/astramarket/core/di/factory/CurrencyEconomyProviderFactory.kt b/modules/core/src/main/kotlin/ru/astrainteractive/astramarket/core/di/factory/CurrencyEconomyProviderFactory.kt new file mode 100644 index 0000000..73961e7 --- /dev/null +++ b/modules/core/src/main/kotlin/ru/astrainteractive/astramarket/core/di/factory/CurrencyEconomyProviderFactory.kt @@ -0,0 +1,8 @@ +package ru.astrainteractive.astramarket.core.di.factory + +import ru.astrainteractive.astralibs.economy.EconomyFacade + +interface CurrencyEconomyProviderFactory { + fun findByCurrencyId(currencyId: String): EconomyFacade? + fun findDefault(): EconomyFacade? +} diff --git a/modules/core/src/main/kotlin/ru/astrainteractive/astramarket/core/util/KrateExt.kt b/modules/core/src/main/kotlin/ru/astrainteractive/astramarket/core/util/KrateExt.kt new file mode 100644 index 0000000..6eff50d --- /dev/null +++ b/modules/core/src/main/kotlin/ru/astrainteractive/astramarket/core/util/KrateExt.kt @@ -0,0 +1,8 @@ +package ru.astrainteractive.astramarket.core.util + +import ru.astrainteractive.klibs.kstorage.api.cache.CacheOwner +import kotlin.reflect.KProperty + +operator fun CacheOwner.getValue(thisRef: Any, property: KProperty<*>): T { + return this.cachedValue +} diff --git a/modules/gui-bukkit/build.gradle.kts b/modules/gui-bukkit/build.gradle.kts index b81d387..27c108d 100644 --- a/modules/gui-bukkit/build.gradle.kts +++ b/modules/gui-bukkit/build.gradle.kts @@ -9,7 +9,6 @@ dependencies { // AstraLibs implementation(libs.minecraft.astralibs.core) implementation(libs.minecraft.astralibs.core.bukkit) - implementation(libs.klibs.kdi) implementation(libs.klibs.mikro.core) implementation(libs.minecraft.astralibs.menu.bukkit) // Spigot dependencies diff --git a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/AaucButton.kt b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/AaucButton.kt new file mode 100644 index 0000000..a7d04eb --- /dev/null +++ b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/AaucButton.kt @@ -0,0 +1,20 @@ +package ru.astrainteractive.astramarket.gui.button + +import ru.astrainteractive.astralibs.menu.clicker.Click +import ru.astrainteractive.astralibs.menu.slot.InventorySlot +import ru.astrainteractive.astralibs.menu.slot.util.InventorySlotBuilderExt.editMeta +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.setOnClickListener +import ru.astrainteractive.astramarket.gui.button.di.ButtonContext +import ru.astrainteractive.astramarket.gui.util.ItemStackExt.toItemStack + +internal fun ButtonContext.aauc( + index: Int, + click: Click +) = InventorySlot.Builder() + .setIndex(index) + .setItemStack(config.buttons.aauc.toItemStack()) + .editMeta { displayName(translation.menu.market.component) } + .setOnClickListener(click) + .build() diff --git a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/AaucButtonFactory.kt b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/AaucButtonFactory.kt deleted file mode 100644 index 382162b..0000000 --- a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/AaucButtonFactory.kt +++ /dev/null @@ -1,27 +0,0 @@ -package ru.astrainteractive.astramarket.gui.button - -import ru.astrainteractive.astralibs.kyori.KyoriComponentSerializer -import ru.astrainteractive.astralibs.menu.clicker.Click -import ru.astrainteractive.astralibs.menu.slot.InventorySlot -import ru.astrainteractive.astralibs.menu.slot.util.InventorySlotBuilderExt.editMeta -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.setOnClickListener -import ru.astrainteractive.astramarket.gui.button.di.ButtonFactoryDependency -import ru.astrainteractive.astramarket.gui.util.ItemStackExt.toItemStack - -internal class AaucButtonFactory( - dependency: ButtonFactoryDependency -) : ButtonFactoryDependency by dependency, - KyoriComponentSerializer by dependency.kyoriComponentSerializer { - - fun render( - index: Int, - click: Click - ) = InventorySlot.Builder() - .setIndex(index) - .setItemStack(config.buttons.aauc.toItemStack()) - .editMeta { displayName(translation.menu.market.component) } - .setOnClickListener(click) - .build() -} diff --git a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/AuctionSortButton.kt b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/AuctionSortButton.kt new file mode 100644 index 0000000..5a32600 --- /dev/null +++ b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/AuctionSortButton.kt @@ -0,0 +1,27 @@ +package ru.astrainteractive.astramarket.gui.button + +import ru.astrainteractive.astralibs.menu.clicker.Click +import ru.astrainteractive.astralibs.menu.slot.InventorySlot +import ru.astrainteractive.astralibs.menu.slot.util.InventorySlotBuilderExt.editMeta +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.setOnClickListener +import ru.astrainteractive.astralibs.string.StringDesc +import ru.astrainteractive.astramarket.gui.button.di.ButtonContext +import ru.astrainteractive.astramarket.gui.util.ItemStackExt.toItemStack +import ru.astrainteractive.astramarket.market.domain.model.AuctionSort + +internal fun ButtonContext.auctionSort( + index: Int, + sortType: AuctionSort, + click: Click +) = InventorySlot.Builder() + .setIndex(index) + .setItemStack(config.buttons.sort.toItemStack()) + .editMeta { + val sortDesc = auctionSortTranslationMapping.translate(sortType).raw + val desc = StringDesc.Raw("${translation.menu.sort.raw} $sortDesc") + displayName(desc.component) + } + .setOnClickListener(click) + .build() diff --git a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/AuctionSortButtonFactory.kt b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/AuctionSortButtonFactory.kt deleted file mode 100644 index 9888942..0000000 --- a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/AuctionSortButtonFactory.kt +++ /dev/null @@ -1,34 +0,0 @@ -package ru.astrainteractive.astramarket.gui.button - -import ru.astrainteractive.astralibs.kyori.KyoriComponentSerializer -import ru.astrainteractive.astralibs.menu.clicker.Click -import ru.astrainteractive.astralibs.menu.slot.InventorySlot -import ru.astrainteractive.astralibs.menu.slot.util.InventorySlotBuilderExt.editMeta -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.setOnClickListener -import ru.astrainteractive.astralibs.string.StringDesc -import ru.astrainteractive.astramarket.gui.button.di.ButtonFactoryDependency -import ru.astrainteractive.astramarket.gui.util.ItemStackExt.toItemStack -import ru.astrainteractive.astramarket.market.domain.model.AuctionSort - -internal class AuctionSortButtonFactory( - dependency: ButtonFactoryDependency -) : ButtonFactoryDependency by dependency, - KyoriComponentSerializer by dependency.kyoriComponentSerializer { - - fun render( - index: Int, - sortType: AuctionSort, - click: Click - ) = InventorySlot.Builder() - .setIndex(index) - .setItemStack(config.buttons.sort.toItemStack()) - .editMeta { - val sortDesc = auctionSortTranslationMapping.translate(sortType).raw - val desc = StringDesc.Raw("${translation.menu.sort.raw} $sortDesc") - displayName(desc.component) - } - .setOnClickListener(click) - .build() -} diff --git a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/BackButton.kt b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/BackButton.kt new file mode 100644 index 0000000..39fda01 --- /dev/null +++ b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/BackButton.kt @@ -0,0 +1,20 @@ +package ru.astrainteractive.astramarket.gui.button + +import ru.astrainteractive.astralibs.menu.clicker.Click +import ru.astrainteractive.astralibs.menu.slot.InventorySlot +import ru.astrainteractive.astralibs.menu.slot.util.InventorySlotBuilderExt.editMeta +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.setOnClickListener +import ru.astrainteractive.astramarket.gui.button.di.ButtonContext +import ru.astrainteractive.astramarket.gui.util.ItemStackExt.toItemStack + +internal fun ButtonContext.back( + index: Int, + click: Click +) = InventorySlot.Builder() + .setIndex(index) + .setItemStack(config.buttons.back.toItemStack()) + .editMeta { displayName(translation.menu.back.component) } + .setOnClickListener(click) + .build() diff --git a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/BackButtonFactory.kt b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/BackButtonFactory.kt deleted file mode 100644 index be578cb..0000000 --- a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/BackButtonFactory.kt +++ /dev/null @@ -1,27 +0,0 @@ -package ru.astrainteractive.astramarket.gui.button - -import ru.astrainteractive.astralibs.kyori.KyoriComponentSerializer -import ru.astrainteractive.astralibs.menu.clicker.Click -import ru.astrainteractive.astralibs.menu.slot.InventorySlot -import ru.astrainteractive.astralibs.menu.slot.util.InventorySlotBuilderExt.editMeta -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.setOnClickListener -import ru.astrainteractive.astramarket.gui.button.di.ButtonFactoryDependency -import ru.astrainteractive.astramarket.gui.util.ItemStackExt.toItemStack - -internal class BackButtonFactory( - dependency: ButtonFactoryDependency -) : ButtonFactoryDependency by dependency, - KyoriComponentSerializer by dependency.kyoriComponentSerializer { - - fun render( - index: Int, - click: Click - ) = InventorySlot.Builder() - .setIndex(index) - .setItemStack(config.buttons.back.toItemStack()) - .editMeta { displayName(translation.menu.back.component) } - .setOnClickListener(click) - .build() -} diff --git a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/BorderButton.kt b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/BorderButton.kt new file mode 100644 index 0000000..c7605b1 --- /dev/null +++ b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/BorderButton.kt @@ -0,0 +1,14 @@ +package ru.astrainteractive.astramarket.gui.button + +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.astramarket.gui.button.di.ButtonContext +import ru.astrainteractive.astramarket.gui.util.ItemStackExt.toItemStack + +internal fun ButtonContext.border(index: Int) = InventorySlot.Builder() + .setIndex(index) + .setItemStack(config.buttons.border.toItemStack()) + .setDisplayName(" ") + .build() diff --git a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/BorderButtonFactory.kt b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/BorderButtonFactory.kt deleted file mode 100644 index 43b3757..0000000 --- a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/BorderButtonFactory.kt +++ /dev/null @@ -1,21 +0,0 @@ -package ru.astrainteractive.astramarket.gui.button - -import ru.astrainteractive.astralibs.kyori.KyoriComponentSerializer -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.astramarket.gui.button.di.ButtonFactoryDependency -import ru.astrainteractive.astramarket.gui.util.ItemStackExt.toItemStack - -internal class BorderButtonFactory( - dependency: ButtonFactoryDependency -) : ButtonFactoryDependency by dependency, - KyoriComponentSerializer by dependency.kyoriComponentSerializer { - - fun render(index: Int) = InventorySlot.Builder() - .setIndex(index) - .setItemStack(config.buttons.border.toItemStack()) - .setDisplayName(" ") - .build() -} diff --git a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/ExpiredButton.kt b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/ExpiredButton.kt new file mode 100644 index 0000000..6f5b29c --- /dev/null +++ b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/ExpiredButton.kt @@ -0,0 +1,27 @@ +package ru.astrainteractive.astramarket.gui.button + +import ru.astrainteractive.astralibs.menu.clicker.Click +import ru.astrainteractive.astralibs.menu.slot.InventorySlot +import ru.astrainteractive.astralibs.menu.slot.util.InventorySlotBuilderExt.editMeta +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.setOnClickListener +import ru.astrainteractive.astramarket.gui.button.di.ButtonContext +import ru.astrainteractive.astramarket.gui.util.ItemStackExt.toItemStack + +internal fun ButtonContext.expiredSlots( + index: Int, + isExpired: Boolean, + click: Click +) = InventorySlot.Builder() + .setIndex(index) + .setItemStack(config.buttons.expired.toItemStack()) + .editMeta { + if (isExpired) { + displayName(translation.menu.expired.component) + } else { + displayName(translation.menu.new.component) + } + } + .setOnClickListener(click) + .build() diff --git a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/ExpiredButtonFactory.kt b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/ExpiredButtonFactory.kt deleted file mode 100644 index 2658394..0000000 --- a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/ExpiredButtonFactory.kt +++ /dev/null @@ -1,34 +0,0 @@ -package ru.astrainteractive.astramarket.gui.button - -import ru.astrainteractive.astralibs.kyori.KyoriComponentSerializer -import ru.astrainteractive.astralibs.menu.clicker.Click -import ru.astrainteractive.astralibs.menu.slot.InventorySlot -import ru.astrainteractive.astralibs.menu.slot.util.InventorySlotBuilderExt.editMeta -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.setOnClickListener -import ru.astrainteractive.astramarket.gui.button.di.ButtonFactoryDependency -import ru.astrainteractive.astramarket.gui.util.ItemStackExt.toItemStack - -internal class ExpiredButtonFactory( - dependency: ButtonFactoryDependency -) : ButtonFactoryDependency by dependency, - KyoriComponentSerializer by dependency.kyoriComponentSerializer { - - fun render( - index: Int, - isExpired: Boolean, - click: Click - ) = InventorySlot.Builder() - .setIndex(index) - .setItemStack(config.buttons.expired.toItemStack()) - .editMeta { - if (isExpired) { - displayName(translation.menu.expired.component) - } else { - displayName(translation.menu.new.component) - } - } - .setOnClickListener(click) - .build() -} diff --git a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/ExpiredMarketItemButtonFactory.kt b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/ExpiredMarketItemButtonFactory.kt deleted file mode 100644 index 4b6f3fb..0000000 --- a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/ExpiredMarketItemButtonFactory.kt +++ /dev/null @@ -1,59 +0,0 @@ -package ru.astrainteractive.astramarket.gui.button - -import org.bukkit.Bukkit -import ru.astrainteractive.astralibs.kyori.KyoriComponentSerializer -import ru.astrainteractive.astralibs.menu.clicker.Click -import ru.astrainteractive.astralibs.menu.slot.InventorySlot -import ru.astrainteractive.astralibs.menu.slot.util.InventorySlotBuilderExt.addLore -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.setOnClickListener -import ru.astrainteractive.astramarket.api.market.model.MarketSlot -import ru.astrainteractive.astramarket.gui.button.di.ButtonFactoryDependency -import ru.astrainteractive.astramarket.gui.button.util.InventorySlotBuilderExt.addLore -import ru.astrainteractive.astramarket.gui.util.DurationExt.getTimeFormatted -import java.util.UUID -import kotlin.time.Duration.Companion.milliseconds - -internal class ExpiredMarketItemButtonFactory( - dependency: ButtonFactoryDependency -) : ButtonFactoryDependency by dependency, - KyoriComponentSerializer by dependency.kyoriComponentSerializer { - - @Suppress("LongParameterList") - fun render( - index: Int, - click: Click, - auctionItem: MarketSlot, - isOwner: Boolean, - hasExpirePermission: Boolean, - hasRemovePermission: Boolean - ) = InventorySlot.Builder() - .setIndex(index) - .setItemStack(itemStackEncoder.toItemStack(auctionItem.item)) - .apply { - if (hasExpirePermission) addLore(translation.auction.expireSlot.component) - if (hasRemovePermission || (auctionItem.expired && isOwner)) { - addLore(translation.auction.removeSlot.component) - } - addLore(translation.auction.buySlot.component) - } - .apply { - if (!isOwner) return@apply - addLore(translation.auction.removeSlot.component) - } - .addLore { - val ownerUuid = UUID.fromString(auctionItem.minecraftUuid) - val ownerName = Bukkit.getOfflinePlayer(ownerUuid).name ?: "[ДАННЫЕ УДАЛЕНЫ]" - translation.auction.auctionBy(ownerName).component - } - .addLore { - val time = auctionItem.time.milliseconds.getTimeFormatted(translation.general.timeAgoFormat).raw - translation.auction.auctionCreatedAgo(time).component - } - .addLore { - translation.auction.auctionPrice(auctionItem.price).component - } - .setOnClickListener(click) - .build() -} diff --git a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/ExpiredSlotButton.kt b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/ExpiredSlotButton.kt new file mode 100644 index 0000000..e1eefb2 --- /dev/null +++ b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/ExpiredSlotButton.kt @@ -0,0 +1,52 @@ +package ru.astrainteractive.astramarket.gui.button + +import org.bukkit.Bukkit +import ru.astrainteractive.astralibs.menu.clicker.Click +import ru.astrainteractive.astralibs.menu.slot.InventorySlot +import ru.astrainteractive.astralibs.menu.slot.util.InventorySlotBuilderExt.addLore +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.setOnClickListener +import ru.astrainteractive.astramarket.api.market.model.MarketSlot +import ru.astrainteractive.astramarket.gui.button.di.ButtonContext +import ru.astrainteractive.astramarket.gui.button.util.InventorySlotBuilderExt.addLore +import ru.astrainteractive.astramarket.gui.util.DurationExt.getTimeFormatted +import java.util.UUID +import kotlin.time.Duration.Companion.milliseconds + +@Suppress("LongParameterList") +internal fun ButtonContext.expiredSlot( + index: Int, + click: Click, + auctionItem: MarketSlot, + isOwner: Boolean, + hasExpirePermission: Boolean, + hasRemovePermission: Boolean +) = InventorySlot.Builder() + .setIndex(index) + .setItemStack(itemStackEncoder.toItemStack(auctionItem.item)) + .apply { + if (hasExpirePermission) addLore(translation.auction.expireSlot.component) + if (hasRemovePermission || (auctionItem.expired && isOwner)) { + addLore(translation.auction.removeSlot.component) + } + addLore(translation.auction.buySlot.component) + } + .apply { + if (!isOwner) return@apply + addLore(translation.auction.removeSlot.component) + } + .addLore { + val ownerUuid = UUID.fromString(auctionItem.minecraftUuid) + val ownerName = Bukkit.getOfflinePlayer(ownerUuid).name ?: "[ДАННЫЕ УДАЛЕНЫ]" + translation.auction.auctionBy(ownerName).component + } + .addLore { + val time = auctionItem.time.milliseconds.getTimeFormatted(translation.general.timeAgoFormat).raw + translation.auction.auctionCreatedAgo(time).component + } + .addLore { + translation.auction.auctionPrice(auctionItem.price).component + } + .setOnClickListener(click) + .build() diff --git a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/NextPageButton.kt b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/NextPageButton.kt new file mode 100644 index 0000000..aac0d4c --- /dev/null +++ b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/NextPageButton.kt @@ -0,0 +1,20 @@ +package ru.astrainteractive.astramarket.gui.button + +import ru.astrainteractive.astralibs.menu.clicker.Click +import ru.astrainteractive.astralibs.menu.slot.InventorySlot +import ru.astrainteractive.astralibs.menu.slot.util.InventorySlotBuilderExt.editMeta +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.setOnClickListener +import ru.astrainteractive.astramarket.gui.button.di.ButtonContext +import ru.astrainteractive.astramarket.gui.util.ItemStackExt.toItemStack + +internal fun ButtonContext.nextPage( + index: Int, + click: Click +) = InventorySlot.Builder() + .setIndex(index) + .setItemStack(config.buttons.next.toItemStack()) + .editMeta { displayName(translation.menu.next.component) } + .setOnClickListener(click) + .build() diff --git a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/NextPageButtonFactory.kt b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/NextPageButtonFactory.kt deleted file mode 100644 index 884cbc3..0000000 --- a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/NextPageButtonFactory.kt +++ /dev/null @@ -1,27 +0,0 @@ -package ru.astrainteractive.astramarket.gui.button - -import ru.astrainteractive.astralibs.kyori.KyoriComponentSerializer -import ru.astrainteractive.astralibs.menu.clicker.Click -import ru.astrainteractive.astralibs.menu.slot.InventorySlot -import ru.astrainteractive.astralibs.menu.slot.util.InventorySlotBuilderExt.editMeta -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.setOnClickListener -import ru.astrainteractive.astramarket.gui.button.di.ButtonFactoryDependency -import ru.astrainteractive.astramarket.gui.util.ItemStackExt.toItemStack - -internal class NextPageButtonFactory( - dependency: ButtonFactoryDependency -) : ButtonFactoryDependency by dependency, - KyoriComponentSerializer by dependency.kyoriComponentSerializer { - - fun render( - index: Int, - click: Click - ) = InventorySlot.Builder() - .setIndex(index) - .setItemStack(config.buttons.next.toItemStack()) - .editMeta { displayName(translation.menu.next.component) } - .setOnClickListener(click) - .build() -} diff --git a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/PlayerItemButton.kt b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/PlayerItemButton.kt new file mode 100644 index 0000000..44f9f2c --- /dev/null +++ b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/PlayerItemButton.kt @@ -0,0 +1,52 @@ +package ru.astrainteractive.astramarket.gui.button + +import net.kyori.adventure.text.Component +import org.bukkit.Bukkit +import org.bukkit.Material +import org.bukkit.inventory.meta.SkullMeta +import ru.astrainteractive.astralibs.menu.clicker.Click +import ru.astrainteractive.astralibs.menu.slot.InventorySlot +import ru.astrainteractive.astralibs.menu.slot.util.InventorySlotBuilderExt.editMeta +import ru.astrainteractive.astralibs.menu.slot.util.InventorySlotBuilderExt.setIndex +import ru.astrainteractive.astralibs.menu.slot.util.InventorySlotBuilderExt.setMaterial +import ru.astrainteractive.astralibs.menu.slot.util.InventorySlotBuilderExt.setOnClickListener +import ru.astrainteractive.astramarket.api.market.model.PlayerAndSlots +import ru.astrainteractive.astramarket.gui.button.di.ButtonContext +import ru.astrainteractive.astramarket.gui.button.util.InventorySlotBuilderExt.addLore +import ru.astrainteractive.astramarket.gui.util.DurationExt.getTimeFormatted +import kotlin.time.Duration.Companion.milliseconds + +internal fun ButtonContext.playerItem( + index: Int, + click: Click, + isExpired: Boolean, + playerAndSlots: PlayerAndSlots +) = InventorySlot.Builder() + .setIndex(index) + .setMaterial(Material.PLAYER_HEAD) + .editMeta { + this as SkullMeta + val offlinePlayer = Bukkit.getOfflinePlayer(playerAndSlots.minecraftUUID) + if (!offlinePlayer.hasPlayedBefore()) return@editMeta + owningPlayer = offlinePlayer + } + .editMeta { + val ownerUuid = playerAndSlots.minecraftUUID + val ownerName = Bukkit.getOfflinePlayer(ownerUuid).name ?: "[ДАННЫЕ УДАЛЕНЫ]" + displayName(Component.text(ownerName)) + } + .addLore { + val auctionsAmount = playerAndSlots.slots + .filter { it.expired == isExpired } + .size + translation.auction.auctionsAmount(auctionsAmount).component + } + .addLore { + val time = playerAndSlots.slots + .maxBy { it.time } + .time.milliseconds + .getTimeFormatted(translation.general.timeAgoFormat).raw + translation.auction.auctionLast(time).component + } + .setOnClickListener(click) + .build() diff --git a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/PlayerItemButtonFactory.kt b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/PlayerItemButtonFactory.kt deleted file mode 100644 index 165758a..0000000 --- a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/PlayerItemButtonFactory.kt +++ /dev/null @@ -1,59 +0,0 @@ -package ru.astrainteractive.astramarket.gui.button - -import org.bukkit.Bukkit -import org.bukkit.Material -import org.bukkit.inventory.meta.SkullMeta -import ru.astrainteractive.astralibs.kyori.KyoriComponentSerializer -import ru.astrainteractive.astralibs.menu.clicker.Click -import ru.astrainteractive.astralibs.menu.slot.InventorySlot -import ru.astrainteractive.astralibs.menu.slot.util.InventorySlotBuilderExt.addLore -import ru.astrainteractive.astralibs.menu.slot.util.InventorySlotBuilderExt.editMeta -import ru.astrainteractive.astralibs.menu.slot.util.InventorySlotBuilderExt.setIndex -import ru.astrainteractive.astralibs.menu.slot.util.InventorySlotBuilderExt.setMaterial -import ru.astrainteractive.astralibs.menu.slot.util.InventorySlotBuilderExt.setOnClickListener -import ru.astrainteractive.astramarket.api.market.model.PlayerAndSlots -import ru.astrainteractive.astramarket.gui.button.di.ButtonFactoryDependency -import ru.astrainteractive.astramarket.gui.button.util.InventorySlotBuilderExt.addLore -import ru.astrainteractive.astramarket.gui.util.DurationExt.getTimeFormatted -import kotlin.time.Duration.Companion.milliseconds - -internal class PlayerItemButtonFactory( - dependency: ButtonFactoryDependency -) : ButtonFactoryDependency by dependency, - KyoriComponentSerializer by dependency.kyoriComponentSerializer { - - fun render( - index: Int, - click: Click, - isExpired: Boolean, - playerAndSlots: PlayerAndSlots - ) = InventorySlot.Builder() - .setIndex(index) - .setMaterial(Material.PLAYER_HEAD) - .editMeta { - this as SkullMeta - val offlinePlayer = Bukkit.getOfflinePlayer(playerAndSlots.minecraftUUID) - if (!offlinePlayer.hasPlayedBefore()) return@editMeta - owningPlayer = offlinePlayer - } - .editMeta { - val ownerUuid = playerAndSlots.minecraftUUID - val ownerName = Bukkit.getOfflinePlayer(ownerUuid).name ?: "[ДАННЫЕ УДАЛЕНЫ]" - displayName(kyoriComponentSerializer.toComponent(ownerName)) - } - .addLore { - val auctionsAmount = playerAndSlots.slots - .filter { it.expired == isExpired } - .size - translation.auction.auctionsAmount(auctionsAmount).component - } - .addLore { - val time = playerAndSlots.slots - .maxBy { it.time } - .time.milliseconds - .getTimeFormatted(translation.general.timeAgoFormat).raw - translation.auction.auctionLast(time).component - } - .setOnClickListener(click) - .build() -} diff --git a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/PlayersSlots.kt b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/PlayersSlots.kt new file mode 100644 index 0000000..eb6b90b --- /dev/null +++ b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/PlayersSlots.kt @@ -0,0 +1,34 @@ +package ru.astrainteractive.astramarket.gui.button + +import ru.astrainteractive.astralibs.menu.clicker.Click +import ru.astrainteractive.astralibs.menu.slot.InventorySlot +import ru.astrainteractive.astralibs.menu.slot.util.InventorySlotBuilderExt.editMeta +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.setOnClickListener +import ru.astrainteractive.astramarket.gui.button.di.ButtonContext +import ru.astrainteractive.astramarket.gui.util.ItemStackExt.toItemStack + +internal fun ButtonContext.playersSlots( + index: Int, + click: Click +) = InventorySlot.Builder() + .setIndex(index) + .setItemStack(config.buttons.playersSlots.toItemStack()) + .editMeta { + displayName(translation.menu.playerSlots.component) + } + .setOnClickListener(click) + .build() + +internal fun ButtonContext.allSlots( + index: Int, + click: Click +) = InventorySlot.Builder() + .setIndex(index) + .setItemStack(config.buttons.aauc.toItemStack()) + .editMeta { + displayName(translation.menu.allSlots.component) + } + .setOnClickListener(click) + .build() diff --git a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/PlayersSortButton.kt b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/PlayersSortButton.kt new file mode 100644 index 0000000..592b6e7 --- /dev/null +++ b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/PlayersSortButton.kt @@ -0,0 +1,27 @@ +package ru.astrainteractive.astramarket.gui.button + +import ru.astrainteractive.astralibs.menu.clicker.Click +import ru.astrainteractive.astralibs.menu.slot.InventorySlot +import ru.astrainteractive.astralibs.menu.slot.util.InventorySlotBuilderExt.editMeta +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.setOnClickListener +import ru.astrainteractive.astralibs.string.StringDesc +import ru.astrainteractive.astramarket.gui.button.di.ButtonContext +import ru.astrainteractive.astramarket.gui.util.ItemStackExt.toItemStack +import ru.astrainteractive.astramarket.players.model.PlayerSort + +internal fun ButtonContext.playersSort( + index: Int, + sortType: PlayerSort, + click: Click +) = InventorySlot.Builder() + .setIndex(index) + .setItemStack(config.buttons.sort.toItemStack()) + .editMeta { + val sortDesc = playersSortTranslationMapping.translate(sortType).raw + val desc = StringDesc.Raw("${translation.menu.sort.raw} $sortDesc") + displayName(desc.component) + } + .setOnClickListener(click) + .build() diff --git a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/PlayersSortButtonFactory.kt b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/PlayersSortButtonFactory.kt deleted file mode 100644 index 4e84f75..0000000 --- a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/PlayersSortButtonFactory.kt +++ /dev/null @@ -1,34 +0,0 @@ -package ru.astrainteractive.astramarket.gui.button - -import ru.astrainteractive.astralibs.kyori.KyoriComponentSerializer -import ru.astrainteractive.astralibs.menu.clicker.Click -import ru.astrainteractive.astralibs.menu.slot.InventorySlot -import ru.astrainteractive.astralibs.menu.slot.util.InventorySlotBuilderExt.editMeta -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.setOnClickListener -import ru.astrainteractive.astralibs.string.StringDesc -import ru.astrainteractive.astramarket.gui.button.di.ButtonFactoryDependency -import ru.astrainteractive.astramarket.gui.util.ItemStackExt.toItemStack -import ru.astrainteractive.astramarket.players.model.PlayerSort - -internal class PlayersSortButtonFactory( - dependency: ButtonFactoryDependency -) : ButtonFactoryDependency by dependency, - KyoriComponentSerializer by dependency.kyoriComponentSerializer { - - fun render( - index: Int, - sortType: PlayerSort, - click: Click - ) = InventorySlot.Builder() - .setIndex(index) - .setItemStack(config.buttons.sort.toItemStack()) - .editMeta { - val sortDesc = playersSortTranslationMapping.translate(sortType).raw - val desc = StringDesc.Raw("${translation.menu.sort.raw} $sortDesc") - displayName(desc.component) - } - .setOnClickListener(click) - .build() -} diff --git a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/PrevPageButton.kt b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/PrevPageButton.kt new file mode 100644 index 0000000..45edff3 --- /dev/null +++ b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/PrevPageButton.kt @@ -0,0 +1,20 @@ +package ru.astrainteractive.astramarket.gui.button + +import ru.astrainteractive.astralibs.menu.clicker.Click +import ru.astrainteractive.astralibs.menu.slot.InventorySlot +import ru.astrainteractive.astralibs.menu.slot.util.InventorySlotBuilderExt.editMeta +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.setOnClickListener +import ru.astrainteractive.astramarket.gui.button.di.ButtonContext +import ru.astrainteractive.astramarket.gui.util.ItemStackExt.toItemStack + +internal fun ButtonContext.prevPage( + index: Int, + click: Click +) = InventorySlot.Builder() + .setIndex(index) + .setItemStack(config.buttons.previous.toItemStack()) + .editMeta { displayName(translation.menu.prev.component) } + .setOnClickListener(click) + .build() diff --git a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/PrevPageButtonFactory.kt b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/PrevPageButtonFactory.kt deleted file mode 100644 index 9c3c889..0000000 --- a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/PrevPageButtonFactory.kt +++ /dev/null @@ -1,27 +0,0 @@ -package ru.astrainteractive.astramarket.gui.button - -import ru.astrainteractive.astralibs.kyori.KyoriComponentSerializer -import ru.astrainteractive.astralibs.menu.clicker.Click -import ru.astrainteractive.astralibs.menu.slot.InventorySlot -import ru.astrainteractive.astralibs.menu.slot.util.InventorySlotBuilderExt.editMeta -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.setOnClickListener -import ru.astrainteractive.astramarket.gui.button.di.ButtonFactoryDependency -import ru.astrainteractive.astramarket.gui.util.ItemStackExt.toItemStack - -internal class PrevPageButtonFactory( - dependency: ButtonFactoryDependency -) : ButtonFactoryDependency by dependency, - KyoriComponentSerializer by dependency.kyoriComponentSerializer { - - fun render( - index: Int, - click: Click - ) = InventorySlot.Builder() - .setIndex(index) - .setItemStack(config.buttons.previous.toItemStack()) - .editMeta { displayName(translation.menu.prev.component) } - .setOnClickListener(click) - .build() -} diff --git a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/di/ButtonFactoryDependency.kt b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/di/ButtonContext.kt similarity index 59% rename from modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/di/ButtonFactoryDependency.kt rename to modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/di/ButtonContext.kt index 7a1fd94..d7ca559 100644 --- a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/di/ButtonFactoryDependency.kt +++ b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/di/ButtonContext.kt @@ -6,36 +6,34 @@ import ru.astrainteractive.astramarket.core.Translation import ru.astrainteractive.astramarket.core.di.BukkitCoreModule import ru.astrainteractive.astramarket.core.di.CoreModule import ru.astrainteractive.astramarket.core.itemstack.ItemStackEncoder -import ru.astrainteractive.astramarket.market.domain.di.MarketDomainModule +import ru.astrainteractive.astramarket.core.util.getValue +import ru.astrainteractive.astramarket.market.domain.di.MarketViewDomainModule import ru.astrainteractive.astramarket.market.domain.mapping.AuctionSortTranslationMapping -import ru.astrainteractive.astramarket.players.di.PlayersMarketModule +import ru.astrainteractive.astramarket.players.di.PlayersMarketViewModule import ru.astrainteractive.astramarket.players.mapping.PlayerSortTranslationMapping -import ru.astrainteractive.klibs.kdi.Provider -import ru.astrainteractive.klibs.kdi.getValue -internal interface ButtonFactoryDependency { +internal interface ButtonContext : KyoriComponentSerializer { val auctionSortTranslationMapping: AuctionSortTranslationMapping val playersSortTranslationMapping: PlayerSortTranslationMapping val config: PluginConfig val translation: Translation - val kyoriComponentSerializer: KyoriComponentSerializer val itemStackEncoder: ItemStackEncoder class Default( coreModule: CoreModule, - marketDomainModule: MarketDomainModule, + marketViewDomainModule: MarketViewDomainModule, bukkitCoreModule: BukkitCoreModule, - playersMarketModule: PlayersMarketModule - ) : ButtonFactoryDependency { - override val auctionSortTranslationMapping: AuctionSortTranslationMapping by Provider { - marketDomainModule.auctionSortTranslationMapping + playersMarketViewModule: PlayersMarketViewModule + ) : ButtonContext, + KyoriComponentSerializer by bukkitCoreModule.kyoriComponentSerializer.cachedValue { + override val auctionSortTranslationMapping: AuctionSortTranslationMapping by lazy { + marketViewDomainModule.auctionSortTranslationMapping } - override val playersSortTranslationMapping: PlayerSortTranslationMapping by Provider { - playersMarketModule.playerSortTranslationMapping + override val playersSortTranslationMapping: PlayerSortTranslationMapping by lazy { + playersMarketViewModule.playerSortTranslationMapping } - override val config: PluginConfig by coreModule.config - override val translation: Translation by coreModule.translation - override val kyoriComponentSerializer: KyoriComponentSerializer by bukkitCoreModule.kyoriComponentSerializer + override val config: PluginConfig by coreModule.configKrate + override val translation: Translation by coreModule.translationKrate override val itemStackEncoder = bukkitCoreModule.itemStackEncoder } } diff --git a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/di/MenuDrawerContext.kt b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/di/MenuDrawerContext.kt deleted file mode 100644 index 106c229..0000000 --- a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/button/di/MenuDrawerContext.kt +++ /dev/null @@ -1,53 +0,0 @@ -package ru.astrainteractive.astramarket.gui.button.di - -import ru.astrainteractive.astramarket.core.di.BukkitCoreModule -import ru.astrainteractive.astramarket.core.di.CoreModule -import ru.astrainteractive.astramarket.gui.button.AaucButtonFactory -import ru.astrainteractive.astramarket.gui.button.AuctionSortButtonFactory -import ru.astrainteractive.astramarket.gui.button.BackButtonFactory -import ru.astrainteractive.astramarket.gui.button.BorderButtonFactory -import ru.astrainteractive.astramarket.gui.button.ExpiredButtonFactory -import ru.astrainteractive.astramarket.gui.button.ExpiredMarketItemButtonFactory -import ru.astrainteractive.astramarket.gui.button.NextPageButtonFactory -import ru.astrainteractive.astramarket.gui.button.PlayerItemButtonFactory -import ru.astrainteractive.astramarket.gui.button.PlayersSortButtonFactory -import ru.astrainteractive.astramarket.gui.button.PrevPageButtonFactory -import ru.astrainteractive.astramarket.market.domain.di.MarketDomainModule -import ru.astrainteractive.astramarket.players.di.PlayersMarketModule - -internal interface MenuDrawerContext { - val borderButtonRenderer: BorderButtonFactory - val nextPageButtonFactory: NextPageButtonFactory - val prevPageButtonFactory: PrevPageButtonFactory - val expiredButtonFactory: ExpiredButtonFactory - val aaucButtonFactory: AaucButtonFactory - val auctionSortButtonFactory: AuctionSortButtonFactory - val expiredMarketItemButtonFactory: ExpiredMarketItemButtonFactory - val playersSortButtonFactory: PlayersSortButtonFactory - val playerItemButtonFactory: PlayerItemButtonFactory - val backButtonFactory: BackButtonFactory - - class Default( - coreModule: CoreModule, - marketDomainModule: MarketDomainModule, - bukkitCoreModule: BukkitCoreModule, - playersMarketModule: PlayersMarketModule - ) : MenuDrawerContext { - private val dependency: ButtonFactoryDependency = ButtonFactoryDependency.Default( - coreModule = coreModule, - marketDomainModule = marketDomainModule, - bukkitCoreModule = bukkitCoreModule, - playersMarketModule = playersMarketModule - ) - override val borderButtonRenderer = BorderButtonFactory(dependency) - override val nextPageButtonFactory = NextPageButtonFactory(dependency) - override val prevPageButtonFactory = PrevPageButtonFactory(dependency) - override val expiredButtonFactory = ExpiredButtonFactory(dependency) - override val aaucButtonFactory = AaucButtonFactory(dependency) - override val auctionSortButtonFactory = AuctionSortButtonFactory(dependency) - override val expiredMarketItemButtonFactory = ExpiredMarketItemButtonFactory(dependency) - override val playersSortButtonFactory = PlayersSortButtonFactory(dependency) - override val playerItemButtonFactory = PlayerItemButtonFactory(dependency) - override val backButtonFactory = BackButtonFactory(dependency) - } -} diff --git a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/di/AuctionGuiDependencies.kt b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/di/AuctionGuiDependencies.kt index ec20f68..aac6a6c 100644 --- a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/di/AuctionGuiDependencies.kt +++ b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/di/AuctionGuiDependencies.kt @@ -6,11 +6,10 @@ import ru.astrainteractive.astramarket.core.Translation import ru.astrainteractive.astramarket.core.di.BukkitCoreModule import ru.astrainteractive.astramarket.core.di.CoreModule import ru.astrainteractive.astramarket.core.itemstack.ItemStackEncoder +import ru.astrainteractive.astramarket.core.util.getValue import ru.astrainteractive.astramarket.gui.router.GuiRouter -import ru.astrainteractive.astramarket.market.domain.di.MarketDomainModule +import ru.astrainteractive.astramarket.market.domain.di.MarketViewDomainModule import ru.astrainteractive.astramarket.market.domain.mapping.AuctionSortTranslationMapping -import ru.astrainteractive.klibs.kdi.Provider -import ru.astrainteractive.klibs.kdi.getValue import ru.astrainteractive.klibs.mikro.core.dispatchers.KotlinDispatchers internal interface AuctionGuiDependencies { @@ -24,17 +23,16 @@ internal interface AuctionGuiDependencies { class Default( coreModule: CoreModule, - marketDomainModule: MarketDomainModule, + marketViewDomainModule: MarketViewDomainModule, bukkitCoreModule: BukkitCoreModule, override val router: GuiRouter ) : AuctionGuiDependencies { - override val config: PluginConfig by coreModule.config - override val translation: Translation by coreModule.translation + override val config: PluginConfig by coreModule.configKrate + override val translation: Translation by coreModule.translationKrate + override val kyoriComponentSerializer by bukkitCoreModule.kyoriComponentSerializer + override val dispatchers: KotlinDispatchers = coreModule.dispatchers - override val sortTranslationMapping: AuctionSortTranslationMapping by Provider { - marketDomainModule.auctionSortTranslationMapping - } + override val sortTranslationMapping = marketViewDomainModule.auctionSortTranslationMapping override val itemStackEncoder = bukkitCoreModule.itemStackEncoder - override val kyoriComponentSerializer: KyoriComponentSerializer by bukkitCoreModule.kyoriComponentSerializer } } diff --git a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/invmap/AuctionInventoryMap.kt b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/invmap/AuctionInventoryMap.kt index bd5deed..c6a4606 100644 --- a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/invmap/AuctionInventoryMap.kt +++ b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/invmap/AuctionInventoryMap.kt @@ -25,6 +25,9 @@ internal interface AuctionInventoryMap : InventoryMap { // Auction item AI, + // Group by player or all slots + GR, + // Empty EM } diff --git a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/invmap/DefaultAuctionInventoryMap.kt b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/invmap/DefaultAuctionInventoryMap.kt index a6f774d..4be658b 100644 --- a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/invmap/DefaultAuctionInventoryMap.kt +++ b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/invmap/DefaultAuctionInventoryMap.kt @@ -10,6 +10,6 @@ internal object DefaultAuctionInventoryMap : AuctionInventoryMap { arrayOf(AuctionSlotKey.AI, AuctionSlotKey.AI, AuctionSlotKey.AI, AuctionSlotKey.AI, AuctionSlotKey.AI, AuctionSlotKey.AI, AuctionSlotKey.AI, AuctionSlotKey.AI, AuctionSlotKey.AI), arrayOf(AuctionSlotKey.AI, AuctionSlotKey.AI, AuctionSlotKey.AI, AuctionSlotKey.AI, AuctionSlotKey.AI, AuctionSlotKey.AI, AuctionSlotKey.AI, AuctionSlotKey.AI, AuctionSlotKey.AI), arrayOf(AuctionSlotKey.AI, AuctionSlotKey.AI, AuctionSlotKey.AI, AuctionSlotKey.AI, AuctionSlotKey.AI, AuctionSlotKey.AI, AuctionSlotKey.AI, AuctionSlotKey.AI, AuctionSlotKey.AI), - arrayOf(AuctionSlotKey.PR, AuctionSlotKey.EM, AuctionSlotKey.EM, AuctionSlotKey.AU, AuctionSlotKey.BA, AuctionSlotKey.FI, AuctionSlotKey.EM, AuctionSlotKey.EM, AuctionSlotKey.NE), + arrayOf(AuctionSlotKey.PR, AuctionSlotKey.EM, AuctionSlotKey.GR, AuctionSlotKey.AU, AuctionSlotKey.BA, AuctionSlotKey.FI, AuctionSlotKey.EM, AuctionSlotKey.EM, AuctionSlotKey.NE), ) } diff --git a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/players/PlayersGui.kt b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/players/PlayersGui.kt index 60f0130..fca2645 100644 --- a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/players/PlayersGui.kt +++ b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/players/PlayersGui.kt @@ -18,7 +18,14 @@ import ru.astrainteractive.astralibs.menu.inventory.util.PaginatedInventoryMenuE import ru.astrainteractive.astralibs.menu.inventory.util.PaginatedInventoryMenuExt.showPage import ru.astrainteractive.astralibs.menu.inventory.util.PaginatedInventoryMenuExt.showPrevPage import ru.astrainteractive.astralibs.menu.slot.InventorySlot -import ru.astrainteractive.astramarket.gui.button.di.MenuDrawerContext +import ru.astrainteractive.astramarket.gui.button.allSlots +import ru.astrainteractive.astramarket.gui.button.back +import ru.astrainteractive.astramarket.gui.button.di.ButtonContext +import ru.astrainteractive.astramarket.gui.button.expiredSlots +import ru.astrainteractive.astramarket.gui.button.nextPage +import ru.astrainteractive.astramarket.gui.button.playerItem +import ru.astrainteractive.astramarket.gui.button.playersSort +import ru.astrainteractive.astramarket.gui.button.prevPage import ru.astrainteractive.astramarket.gui.di.AuctionGuiDependencies import ru.astrainteractive.astramarket.gui.invmap.AuctionInventoryMap import ru.astrainteractive.astramarket.gui.invmap.AuctionInventoryMap.AuctionSlotKey @@ -34,11 +41,10 @@ internal class PlayersGui( private val playersMarketComponent: PlayersMarketComponent, player: Player, dependencies: AuctionGuiDependencies, - menuDrawerContext: MenuDrawerContext + private val buttonContext: ButtonContext ) : PaginatedInventoryMenu(), AuctionGuiDependencies by dependencies, - KyoriComponentSerializer by dependencies.kyoriComponentSerializer, - MenuDrawerContext by menuDrawerContext { + KyoriComponentSerializer by dependencies.kyoriComponentSerializer { override val inventorySize: InventorySize = InventorySize.XL private val inventoryMap: AuctionInventoryMap @@ -55,7 +61,7 @@ internal class PlayersGui( ) override val prevPageButton: InventorySlot - get() = prevPageButtonFactory.render( + get() = buttonContext.prevPage( index = inventoryMap.indexOf(AuctionSlotKey.PR), click = { playerHolder.player.playSound(config.sounds.open) @@ -64,7 +70,7 @@ internal class PlayersGui( ) override val nextPageButton: InventorySlot - get() = nextPageButtonFactory.render( + get() = buttonContext.nextPage( index = inventoryMap.indexOf(AuctionSlotKey.NE), click = { playerHolder.player.playSound(config.sounds.open) @@ -73,7 +79,7 @@ internal class PlayersGui( ) private val sortButton: InventorySlot - get() = playersSortButtonFactory.render( + get() = buttonContext.playersSort( index = inventoryMap.indexOf(AuctionSlotKey.FI), sortType = playersMarketComponent.model.value.sort, click = { @@ -86,7 +92,7 @@ internal class PlayersGui( ) private val expiredButton: InventorySlot - get() = expiredButtonFactory.render( + get() = buttonContext.expiredSlots( index = inventoryMap.indexOf(AuctionSlotKey.AU), isExpired = playersMarketComponent.model.value.isExpired, click = { @@ -95,8 +101,21 @@ internal class PlayersGui( } ) + private val allSlots: InventorySlot + get() = buttonContext.allSlots( + index = inventoryMap.indexOf(AuctionSlotKey.GR), + click = { + val route = GuiRouter.Route.Slots( + player = playerHolder.player, + isExpired = playersMarketComponent.model.value.isExpired, + targetPlayerUUID = null + ) + router.navigate(route) + } + ) + private val closeButton: InventorySlot - get() = backButtonFactory.render( + get() = buttonContext.back( index = inventoryMap.indexOf(AuctionSlotKey.BA), click = { playerHolder.player.closeInventory() } ) @@ -113,7 +132,7 @@ internal class PlayersGui( .playersAndSlots .filter { it.slots.any { slot -> slot.expired == isExpired } } .getOrNull(index) ?: return@withKeySlot null - playerItemButtonFactory.render( + buttonContext.playerItem( playerAndSlots = items, index = slotIndex, isExpired = playersMarketComponent.model.value.isExpired, @@ -149,6 +168,7 @@ internal class PlayersGui( sortButton.setInventorySlot() expiredButton.setInventorySlot() closeButton.setInventorySlot() + allSlots.setInventorySlot() slots.forEach { it.setInventorySlot() } } diff --git a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/router/GuiRouterImpl.kt b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/router/GuiRouterImpl.kt index 77baeb6..6060009 100644 --- a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/router/GuiRouterImpl.kt +++ b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/router/GuiRouterImpl.kt @@ -4,43 +4,41 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import ru.astrainteractive.astramarket.core.di.BukkitCoreModule import ru.astrainteractive.astramarket.core.di.CoreModule -import ru.astrainteractive.astramarket.gui.button.di.MenuDrawerContext +import ru.astrainteractive.astramarket.gui.button.di.ButtonContext import ru.astrainteractive.astramarket.gui.di.AuctionGuiDependencies import ru.astrainteractive.astramarket.gui.players.PlayersGui import ru.astrainteractive.astramarket.gui.slots.SlotsGui -import ru.astrainteractive.astramarket.market.di.MarketModule -import ru.astrainteractive.astramarket.players.di.PlayersMarketModule +import ru.astrainteractive.astramarket.market.di.MarketViewModule +import ru.astrainteractive.astramarket.players.di.PlayersMarketViewModule internal class GuiRouterImpl( private val coreModule: CoreModule, - private val marketModule: MarketModule, + private val marketViewModule: MarketViewModule, private val bukkitCoreModule: BukkitCoreModule, - private val playersMarketModule: PlayersMarketModule + private val playersMarketViewModule: PlayersMarketViewModule ) : GuiRouter { - private val scope = coreModule.scope.value - private val dispatchers = coreModule.dispatchers private val dependencies = AuctionGuiDependencies.Default( coreModule = coreModule, - marketDomainModule = marketModule.marketDomainModule, + marketViewDomainModule = marketViewModule.marketViewDomainModule, bukkitCoreModule = bukkitCoreModule, router = this@GuiRouterImpl ) - private val menuDrawerContext = MenuDrawerContext.Default( + private val buttonContext = ButtonContext.Default( coreModule = coreModule, - marketDomainModule = marketModule.marketDomainModule, + marketViewDomainModule = marketViewModule.marketViewDomainModule, bukkitCoreModule = bukkitCoreModule, - playersMarketModule = playersMarketModule + playersMarketViewModule = playersMarketViewModule ) override fun navigate(route: GuiRouter.Route) { - scope.launch(dispatchers.IO) { + coreModule.scope.launch { val gui = when (route) { is GuiRouter.Route.Slots -> { SlotsGui( player = route.player, dependencies = dependencies, - menuDrawerContext = menuDrawerContext, - auctionComponent = marketModule.createAuctionComponent( + buttonContext = buttonContext, + auctionComponent = marketViewModule.createAuctionComponent( playerUUID = route.player.uniqueId, isExpired = route.isExpired, targetPlayerUUID = route.targetPlayerUUID @@ -52,8 +50,8 @@ internal class GuiRouterImpl( PlayersGui( player = route.player, dependencies = dependencies, - menuDrawerContext = menuDrawerContext, - playersMarketComponent = playersMarketModule.createPlayersMarketComponent( + buttonContext = buttonContext, + playersMarketComponent = playersMarketViewModule.createPlayersMarketComponent( isExpired = route.isExpired ) ) diff --git a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/router/di/RouterModule.kt b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/router/di/RouterModule.kt index 92dec57..384003f 100644 --- a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/router/di/RouterModule.kt +++ b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/router/di/RouterModule.kt @@ -4,24 +4,24 @@ import ru.astrainteractive.astramarket.core.di.BukkitCoreModule import ru.astrainteractive.astramarket.core.di.CoreModule import ru.astrainteractive.astramarket.gui.router.GuiRouter import ru.astrainteractive.astramarket.gui.router.GuiRouterImpl -import ru.astrainteractive.astramarket.market.di.MarketModule -import ru.astrainteractive.astramarket.players.di.PlayersMarketModule +import ru.astrainteractive.astramarket.market.di.MarketViewModule +import ru.astrainteractive.astramarket.players.di.PlayersMarketViewModule interface RouterModule { val router: GuiRouter @Suppress("LongParameterList") class Default( - private val coreModule: CoreModule, - private val marketModule: MarketModule, - private val bukkitCoreModule: BukkitCoreModule, - private val playersMarketModule: PlayersMarketModule + coreModule: CoreModule, + marketViewModule: MarketViewModule, + bukkitCoreModule: BukkitCoreModule, + playersMarketViewModule: PlayersMarketViewModule ) : RouterModule { override val router: GuiRouter = GuiRouterImpl( coreModule = coreModule, - marketModule = marketModule, + marketViewModule = marketViewModule, bukkitCoreModule = bukkitCoreModule, - playersMarketModule = playersMarketModule + playersMarketViewModule = playersMarketViewModule ) } } diff --git a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/slots/SlotsGui.kt b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/slots/SlotsGui.kt index 33e4e88..0ce12c3 100644 --- a/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/slots/SlotsGui.kt +++ b/modules/gui-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/gui/slots/SlotsGui.kt @@ -1,5 +1,6 @@ package ru.astrainteractive.astramarket.gui.slots +import kotlinx.coroutines.cancel import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach @@ -23,7 +24,16 @@ import ru.astrainteractive.astralibs.menu.inventory.util.PaginatedInventoryMenuE import ru.astrainteractive.astralibs.menu.slot.InventorySlot import ru.astrainteractive.astralibs.permission.BukkitPermissibleExt.toPermissible import ru.astrainteractive.astramarket.core.PluginPermission -import ru.astrainteractive.astramarket.gui.button.di.MenuDrawerContext +import ru.astrainteractive.astramarket.gui.button.aauc +import ru.astrainteractive.astramarket.gui.button.auctionSort +import ru.astrainteractive.astramarket.gui.button.back +import ru.astrainteractive.astramarket.gui.button.border +import ru.astrainteractive.astramarket.gui.button.di.ButtonContext +import ru.astrainteractive.astramarket.gui.button.expiredSlot +import ru.astrainteractive.astramarket.gui.button.expiredSlots +import ru.astrainteractive.astramarket.gui.button.nextPage +import ru.astrainteractive.astramarket.gui.button.playersSlots +import ru.astrainteractive.astramarket.gui.button.prevPage import ru.astrainteractive.astramarket.gui.di.AuctionGuiDependencies import ru.astrainteractive.astramarket.gui.invmap.AuctionInventoryMap import ru.astrainteractive.astramarket.gui.invmap.AuctionInventoryMap.AuctionSlotKey @@ -38,12 +48,11 @@ import ru.astrainteractive.astramarket.market.presentation.AuctionComponent internal class SlotsGui( player: Player, dependencies: AuctionGuiDependencies, - menuDrawerContext: MenuDrawerContext, + private val buttonContext: ButtonContext, private val auctionComponent: AuctionComponent ) : PaginatedInventoryMenu(), AuctionGuiDependencies by dependencies, - KyoriComponentSerializer by dependencies.kyoriComponentSerializer, - MenuDrawerContext by menuDrawerContext { + KyoriComponentSerializer by dependencies.kyoriComponentSerializer { override val playerHolder = DefaultPlayerHolder(player) override val title: Component = let { val playerNameComponent = auctionComponent.model.value @@ -68,23 +77,23 @@ internal class SlotsGui( private val borderButtons: List get() = inventoryMap.withKeySlot( key = AuctionSlotKey.BO, - transform = borderButtonRenderer::render + transform = buttonContext::border ) override val nextPageButton: InventorySlot - get() = nextPageButtonFactory.render( + get() = buttonContext.nextPage( index = inventoryMap.indexOf(AuctionSlotKey.NE), click = { onNextPageClicked() } ) override val prevPageButton: InventorySlot - get() = prevPageButtonFactory.render( + get() = buttonContext.prevPage( index = inventoryMap.indexOf(AuctionSlotKey.PR), click = { onPrevPageClicked() } ) private val sortButton: InventorySlot - get() = auctionSortButtonFactory.render( + get() = buttonContext.auctionSort( index = inventoryMap.indexOf(AuctionSlotKey.FI), sortType = auctionComponent.model.value.sortType, click = { @@ -93,8 +102,8 @@ internal class SlotsGui( } ) - private val expiredButton: InventorySlot - get() = expiredButtonFactory.render( + private val expiredSlotsButton: InventorySlot + get() = buttonContext.expiredSlots( index = inventoryMap.indexOf(AuctionSlotKey.AU), isExpired = true, click = { @@ -104,13 +113,13 @@ internal class SlotsGui( ) private val aaucButton: InventorySlot - get() = aaucButtonFactory.render( + get() = buttonContext.aauc( index = inventoryMap.indexOf(AuctionSlotKey.AU), click = { auctionComponent.toggleExpired() } ) private val openPlayersButton: InventorySlot - get() = backButtonFactory.render( + get() = buttonContext.back( index = inventoryMap.indexOf(AuctionSlotKey.BA), click = { val route = GuiRouter.Route.Players( @@ -121,8 +130,20 @@ internal class SlotsGui( } ) + private val playerSlots: InventorySlot + get() = buttonContext.playersSlots( + index = inventoryMap.indexOf(AuctionSlotKey.GR), + click = { + val route = GuiRouter.Route.Players( + player = playerHolder.player, + isExpired = auctionComponent.model.value.isExpired + ) + router.navigate(route) + } + ) + private val closeButton: InventorySlot - get() = backButtonFactory.render( + get() = buttonContext.back( index = inventoryMap.indexOf(AuctionSlotKey.BA), click = { playerHolder.player.closeInventory() } ) @@ -155,7 +176,7 @@ internal class SlotsGui( .getOrNull(index) ?: return@withKeySlot null val permissible = playerHolder.player.toPermissible() - expiredMarketItemButtonFactory.render( + buttonContext.expiredSlot( auctionItem = auctionItem, index = slotIndex, click = { onAuctionItemClicked(index, it.click) }, @@ -169,7 +190,7 @@ internal class SlotsGui( override fun onInventoryClosed(it: InventoryCloseEvent) { super.onInventoryClosed(it) playerHolder.player.playSound(config.sounds.close) - auctionComponent.close() + auctionComponent.cancel() } private fun onAuctionItemClicked(i: Int, clickType: ClickType) { @@ -195,7 +216,7 @@ internal class SlotsGui( super.render() when (auctionComponent.model.value.isExpired) { true -> aaucButton.setInventorySlot() - false -> expiredButton.setInventorySlot() + false -> expiredSlotsButton.setInventorySlot() } if (!pageContext.isFirstPage) prevPageButton.setInventorySlot() if (!pageContext.isLastPage) nextPageButton.setInventorySlot() @@ -203,6 +224,7 @@ internal class SlotsGui( openPlayersButton.setInventorySlot() } else { closeButton.setInventorySlot() + playerSlots.setInventorySlot() } borderButtons.forEach { it.setInventorySlot() } sortButton.setInventorySlot() diff --git a/modules/market-players/build.gradle.kts b/modules/market-players/build.gradle.kts index 7912df5..1f10727 100644 --- a/modules/market-players/build.gradle.kts +++ b/modules/market-players/build.gradle.kts @@ -11,8 +11,7 @@ dependencies { implementation(libs.minecraft.astralibs.core) implementation(libs.minecraft.astralibs.core.bukkit) implementation(libs.minecraft.astralibs.menu.bukkit) - implementation(libs.minecraft.astralibs.orm) - implementation(libs.klibs.kdi) + implementation(libs.minecraft.astralibs.exposed) implementation(libs.klibs.mikro.core) implementation(libs.minecraft.bstats) // Test diff --git a/modules/market-players/src/main/kotlin/ru/astrainteractive/astramarket/players/di/PlayersMarketModule.kt b/modules/market-players/src/main/kotlin/ru/astrainteractive/astramarket/players/di/PlayersMarketViewModule.kt similarity index 86% rename from modules/market-players/src/main/kotlin/ru/astrainteractive/astramarket/players/di/PlayersMarketModule.kt rename to modules/market-players/src/main/kotlin/ru/astrainteractive/astramarket/players/di/PlayersMarketViewModule.kt index b95c201..b9c93eb 100644 --- a/modules/market-players/src/main/kotlin/ru/astrainteractive/astramarket/players/di/PlayersMarketModule.kt +++ b/modules/market-players/src/main/kotlin/ru/astrainteractive/astramarket/players/di/PlayersMarketViewModule.kt @@ -7,7 +7,7 @@ import ru.astrainteractive.astramarket.players.mapping.PlayerSortTranslationMapp import ru.astrainteractive.astramarket.players.presentation.DefaultPlayersMarketComponent import ru.astrainteractive.astramarket.players.presentation.PlayersMarketComponent -interface PlayersMarketModule { +interface PlayersMarketViewModule { val playerSortTranslationMapping: PlayerSortTranslationMapping fun createPlayersMarketComponent(isExpired: Boolean): PlayersMarketComponent @@ -15,9 +15,11 @@ interface PlayersMarketModule { class Default( private val coreModule: CoreModule, private val apiMarketModule: ApiMarketModule - ) : PlayersMarketModule { + ) : PlayersMarketViewModule { override val playerSortTranslationMapping: PlayerSortTranslationMapping by lazy { - PlayerSortTranslationMappingImpl(coreModule.translation.value) + PlayerSortTranslationMappingImpl( + translationKrate = coreModule.translationKrate + ) } override fun createPlayersMarketComponent(isExpired: Boolean): PlayersMarketComponent { diff --git a/modules/market-players/src/main/kotlin/ru/astrainteractive/astramarket/players/mapping/PlayerSortTranslationMapping.kt b/modules/market-players/src/main/kotlin/ru/astrainteractive/astramarket/players/mapping/PlayerSortTranslationMapping.kt index 44de33c..1ca7006 100644 --- a/modules/market-players/src/main/kotlin/ru/astrainteractive/astramarket/players/mapping/PlayerSortTranslationMapping.kt +++ b/modules/market-players/src/main/kotlin/ru/astrainteractive/astramarket/players/mapping/PlayerSortTranslationMapping.kt @@ -2,15 +2,19 @@ package ru.astrainteractive.astramarket.players.mapping import ru.astrainteractive.astralibs.string.StringDesc import ru.astrainteractive.astramarket.core.Translation +import ru.astrainteractive.astramarket.core.util.getValue import ru.astrainteractive.astramarket.players.model.PlayerSort +import ru.astrainteractive.klibs.kstorage.api.Krate interface PlayerSortTranslationMapping { fun translate(playerSort: PlayerSort): StringDesc.Raw } internal class PlayerSortTranslationMappingImpl( - private val translation: Translation + translationKrate: Krate ) : PlayerSortTranslationMapping { + private val translation by translationKrate + override fun translate(playerSort: PlayerSort): StringDesc.Raw = when (playerSort) { PlayerSort.NAME_ASC -> translation.auction.sortNameAsc PlayerSort.NAME_DESC -> translation.auction.sortNameDesc diff --git a/modules/market-players/src/main/kotlin/ru/astrainteractive/astramarket/players/presentation/DefaultPlayersMarketComponent.kt b/modules/market-players/src/main/kotlin/ru/astrainteractive/astramarket/players/presentation/DefaultPlayersMarketComponent.kt index dc47ca6..b81dec9 100644 --- a/modules/market-players/src/main/kotlin/ru/astrainteractive/astramarket/players/presentation/DefaultPlayersMarketComponent.kt +++ b/modules/market-players/src/main/kotlin/ru/astrainteractive/astramarket/players/presentation/DefaultPlayersMarketComponent.kt @@ -1,10 +1,12 @@ package ru.astrainteractive.astramarket.players.presentation +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch -import ru.astrainteractive.astralibs.async.AsyncComponent +import ru.astrainteractive.astralibs.async.CoroutineFeature import ru.astrainteractive.astramarket.api.market.MarketApi +import ru.astrainteractive.astramarket.api.market.findPlayersWithSlots import ru.astrainteractive.astramarket.players.model.PlayerSort import ru.astrainteractive.klibs.mikro.core.dispatchers.KotlinDispatchers import ru.astrainteractive.klibs.mikro.core.util.next @@ -14,7 +16,7 @@ internal class DefaultPlayersMarketComponent( private val marketApi: MarketApi, private val dispatchers: KotlinDispatchers, isExpired: Boolean -) : PlayersMarketComponent, AsyncComponent() { +) : PlayersMarketComponent, CoroutineFeature by CoroutineFeature.Default(Dispatchers.IO) { override val model = MutableStateFlow(PlayersMarketComponent.Model(isExpired = isExpired)) private fun sortPlayersAndSlots() { diff --git a/modules/market-view-bukkit/build.gradle.kts b/modules/market-view-bukkit/build.gradle.kts index 38eb75e..632d181 100644 --- a/modules/market-view-bukkit/build.gradle.kts +++ b/modules/market-view-bukkit/build.gradle.kts @@ -11,7 +11,6 @@ dependencies { implementation(libs.minecraft.astralibs.core) implementation(libs.minecraft.astralibs.core.bukkit) implementation(libs.minecraft.astralibs.menu.bukkit) - implementation(libs.klibs.kdi) implementation(libs.klibs.mikro.core) // Bukkit implementation(libs.minecraft.paper.api) diff --git a/modules/market-view-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/market/data/di/BukkitMarketDataModule.kt b/modules/market-view-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/market/data/di/BukkitMarketDataModule.kt index c3fe275..5062144 100644 --- a/modules/market-view-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/market/data/di/BukkitMarketDataModule.kt +++ b/modules/market-view-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/market/data/di/BukkitMarketDataModule.kt @@ -6,19 +6,17 @@ import ru.astrainteractive.astramarket.market.data.bridge.AuctionsBridge import ru.astrainteractive.astramarket.market.data.bridge.BukkitAuctionsBridge import ru.astrainteractive.astramarket.market.data.bridge.BukkitPlayerInteractionBridge import ru.astrainteractive.astramarket.market.data.bridge.PlayerInteractionBridge -import ru.astrainteractive.klibs.kdi.Provider -import ru.astrainteractive.klibs.kdi.getValue class BukkitMarketDataModule( itemStackEncoder: ItemStackEncoder, stringSerializer: KyoriComponentSerializer, ) : MarketDataModule { - override val auctionBridge: AuctionsBridge by Provider { + override val auctionBridge: AuctionsBridge by lazy { BukkitAuctionsBridge( itemStackEncoder = itemStackEncoder, ) } - override val playerInteractionBridge: PlayerInteractionBridge by Provider { + override val playerInteractionBridge: PlayerInteractionBridge by lazy { BukkitPlayerInteractionBridge( stringSerializer = stringSerializer ) diff --git a/modules/market-view-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/market/domain/di/BukkitMarketDomainModule.kt b/modules/market-view-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/market/domain/di/BukkitMarketDomainModule.kt index a66cd69..def91f7 100644 --- a/modules/market-view-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/market/domain/di/BukkitMarketDomainModule.kt +++ b/modules/market-view-bukkit/src/main/kotlin/ru/astrainteractive/astramarket/market/domain/di/BukkitMarketDomainModule.kt @@ -3,11 +3,9 @@ package ru.astrainteractive.astramarket.market.domain.di import ru.astrainteractive.astramarket.core.itemstack.ItemStackEncoder import ru.astrainteractive.astramarket.market.domain.usecase.BukkitSortAuctionsUseCase import ru.astrainteractive.astramarket.market.domain.usecase.SortAuctionsUseCase -import ru.astrainteractive.klibs.kdi.Provider -import ru.astrainteractive.klibs.kdi.getValue class BukkitMarketDomainModule(itemStackEncoder: ItemStackEncoder) : PlatformMarketDomainModule { - override val sortAuctionsUseCase: SortAuctionsUseCase by Provider { + override val sortAuctionsUseCase: SortAuctionsUseCase by lazy { BukkitSortAuctionsUseCase( itemStackEncoder = itemStackEncoder ) diff --git a/modules/market-view/build.gradle.kts b/modules/market-view/build.gradle.kts index df9cd7f..b109095 100644 --- a/modules/market-view/build.gradle.kts +++ b/modules/market-view/build.gradle.kts @@ -9,8 +9,7 @@ dependencies { implementation(libs.bundles.kotlin) // AstraLibs implementation(libs.minecraft.astralibs.core) - implementation(libs.minecraft.astralibs.orm) - implementation(libs.klibs.kdi) + implementation(libs.minecraft.astralibs.exposed) implementation(libs.klibs.mikro.core) implementation(libs.minecraft.bstats) // Test diff --git a/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/di/MarketModule.kt b/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/di/MarketViewModule.kt similarity index 60% rename from modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/di/MarketModule.kt rename to modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/di/MarketViewModule.kt index 9d33315..67134f6 100644 --- a/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/di/MarketModule.kt +++ b/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/di/MarketViewModule.kt @@ -3,16 +3,16 @@ package ru.astrainteractive.astramarket.market.di import ru.astrainteractive.astramarket.core.di.CoreModule import ru.astrainteractive.astramarket.di.ApiMarketModule import ru.astrainteractive.astramarket.market.data.di.MarketDataModule -import ru.astrainteractive.astramarket.market.domain.di.MarketDomainModule +import ru.astrainteractive.astramarket.market.domain.di.MarketViewDomainModule import ru.astrainteractive.astramarket.market.domain.di.PlatformMarketDomainModule import ru.astrainteractive.astramarket.market.presentation.AuctionComponent import ru.astrainteractive.astramarket.market.presentation.DefaultAuctionComponent import ru.astrainteractive.astramarket.market.presentation.di.AuctionComponentDependencies -import ru.astrainteractive.klibs.kdi.Factory import java.util.UUID -interface MarketModule { - val marketDomainModule: MarketDomainModule +interface MarketViewModule { + val marketViewDomainModule: MarketViewDomainModule + fun createAuctionComponent( playerUUID: UUID, isExpired: Boolean, @@ -22,15 +22,15 @@ interface MarketModule { class Default( private val coreModule: CoreModule, private val apiMarketModule: ApiMarketModule, - marketDataModuleFactory: Factory, - platformMarketDomainModuleFactory: Factory - ) : MarketModule { - override val marketDomainModule: MarketDomainModule by lazy { - MarketDomainModule.Default( + marketDataModule: MarketDataModule, + platformMarketDomainModule: PlatformMarketDomainModule + ) : MarketViewModule { + override val marketViewDomainModule: MarketViewDomainModule by lazy { + MarketViewDomainModule.Default( coreModule = coreModule, apiMarketModule = apiMarketModule, - marketDataModuleFactory = marketDataModuleFactory, - platformMarketDomainModuleFactory = platformMarketDomainModuleFactory + marketDataModule = marketDataModule, + platformMarketDomainModule = platformMarketDomainModule ) } @@ -39,16 +39,15 @@ interface MarketModule { isExpired: Boolean, targetPlayerUUID: UUID? ): AuctionComponent { - val dependencies = AuctionComponentDependencies.Default( - coreModule = coreModule, - apiMarketModule = apiMarketModule, - marketDomainModule = marketDomainModule, - ) return DefaultAuctionComponent( playerUUID = playerUUID, targetPlayerUUID = targetPlayerUUID, isExpired = isExpired, - dependencies = dependencies + dependencies = AuctionComponentDependencies.Default( + coreModule = coreModule, + apiMarketModule = apiMarketModule, + marketViewDomainModule = marketViewDomainModule, + ) ) } } diff --git a/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/domain/di/MarketDomainModule.kt b/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/domain/di/MarketViewDomainModule.kt similarity index 71% rename from modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/domain/di/MarketDomainModule.kt rename to modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/domain/di/MarketViewDomainModule.kt index 38f5aff..57af8ea 100644 --- a/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/domain/di/MarketDomainModule.kt +++ b/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/domain/di/MarketViewDomainModule.kt @@ -13,11 +13,8 @@ import ru.astrainteractive.astramarket.market.domain.usecase.ExpireAuctionUseCas import ru.astrainteractive.astramarket.market.domain.usecase.ExpireAuctionUseCaseImpl import ru.astrainteractive.astramarket.market.domain.usecase.RemoveAuctionUseCase import ru.astrainteractive.astramarket.market.domain.usecase.RemoveAuctionUseCaseImpl -import ru.astrainteractive.klibs.kdi.Factory -import ru.astrainteractive.klibs.kdi.Provider -import ru.astrainteractive.klibs.kdi.getValue -interface MarketDomainModule { +interface MarketViewDomainModule { val marketDataModule: MarketDataModule val platformMarketDomainModule: PlatformMarketDomainModule @@ -33,51 +30,46 @@ interface MarketDomainModule { class Default( coreModule: CoreModule, apiMarketModule: ApiMarketModule, - marketDataModuleFactory: Factory, - platformMarketDomainModuleFactory: Factory - ) : MarketDomainModule { - override val marketDataModule: MarketDataModule by Provider { - marketDataModuleFactory.create() - } - override val platformMarketDomainModule: PlatformMarketDomainModule by Provider { - platformMarketDomainModuleFactory.create() - } - override val auctionSortTranslationMapping: AuctionSortTranslationMapping by Provider { + override val marketDataModule: MarketDataModule, + override val platformMarketDomainModule: PlatformMarketDomainModule + ) : MarketViewDomainModule { + + override val auctionSortTranslationMapping: AuctionSortTranslationMapping by lazy { AuctionSortTranslationMappingImpl( - translation = coreModule.translation.value + translationKrate = coreModule.translationKrate ) } - override val auctionBuyUseCase: AuctionBuyUseCase by Provider { + override val auctionBuyUseCase: AuctionBuyUseCase by lazy { AuctionBuyUseCaseImpl( - translation = coreModule.translation.value, - config = coreModule.config.value, - economyProvider = coreModule.economyProvider, + translationKrate = coreModule.translationKrate, + configKrate = coreModule.configKrate, + economyProviderFactory = coreModule.economyProviderFactory, auctionsBridge = marketDataModule.auctionBridge, playerInteractionBridge = marketDataModule.playerInteractionBridge, marketApi = apiMarketModule.marketApi ) } - override val createAuctionUseCase: CreateAuctionUseCase by Provider { + override val createAuctionUseCase: CreateAuctionUseCase by lazy { CreateAuctionUseCaseImpl( - translation = coreModule.translation.value, - config = coreModule.config.value, + translationKrate = coreModule.translationKrate, + configKrate = coreModule.configKrate, auctionsBridge = marketDataModule.auctionBridge, playerInteractionBridge = marketDataModule.playerInteractionBridge, marketApi = apiMarketModule.marketApi ) } - override val expireAuctionUseCase: ExpireAuctionUseCase by Provider { + override val expireAuctionUseCase: ExpireAuctionUseCase by lazy { ExpireAuctionUseCaseImpl( - translation = coreModule.translation.value, + translationKrate = coreModule.translationKrate, auctionsBridge = marketDataModule.auctionBridge, playerInteractionBridge = marketDataModule.playerInteractionBridge, marketApi = apiMarketModule.marketApi ) } - override val removeAuctionUseCase: RemoveAuctionUseCase by Provider { + override val removeAuctionUseCase: RemoveAuctionUseCase by lazy { RemoveAuctionUseCaseImpl( - translation = coreModule.translation.value, - config = coreModule.config.value, + translationKrate = coreModule.translationKrate, + configKrate = coreModule.configKrate, auctionsBridge = marketDataModule.auctionBridge, playerInteractionBridge = marketDataModule.playerInteractionBridge, marketApi = apiMarketModule.marketApi diff --git a/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/domain/mapping/AuctionSortTranslationMapping.kt b/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/domain/mapping/AuctionSortTranslationMapping.kt index 480d0b9..d948962 100644 --- a/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/domain/mapping/AuctionSortTranslationMapping.kt +++ b/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/domain/mapping/AuctionSortTranslationMapping.kt @@ -2,15 +2,18 @@ package ru.astrainteractive.astramarket.market.domain.mapping import ru.astrainteractive.astralibs.string.StringDesc import ru.astrainteractive.astramarket.core.Translation +import ru.astrainteractive.astramarket.core.util.getValue import ru.astrainteractive.astramarket.market.domain.model.AuctionSort +import ru.astrainteractive.klibs.kstorage.api.Krate interface AuctionSortTranslationMapping { fun translate(auctionSort: AuctionSort): StringDesc.Raw } internal class AuctionSortTranslationMappingImpl( - private val translation: Translation + translationKrate: Krate ) : AuctionSortTranslationMapping { + private val translation by translationKrate override fun translate(auctionSort: AuctionSort): StringDesc.Raw = when (auctionSort) { AuctionSort.MATERIAL_DESC -> translation.auction.sortMaterialDesc AuctionSort.MATERIAL_ASC -> translation.auction.sortMaterialAsc diff --git a/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/domain/usecase/AuctionBuyUseCase.kt b/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/domain/usecase/AuctionBuyUseCase.kt index c7b165a..e444a7a 100644 --- a/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/domain/usecase/AuctionBuyUseCase.kt +++ b/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/domain/usecase/AuctionBuyUseCase.kt @@ -1,14 +1,16 @@ package ru.astrainteractive.astramarket.market.domain.usecase -import ru.astrainteractive.astralibs.economy.EconomyProvider import ru.astrainteractive.astralibs.logging.JUtiltLogger import ru.astrainteractive.astralibs.logging.Logger import ru.astrainteractive.astramarket.api.market.MarketApi import ru.astrainteractive.astramarket.api.market.model.MarketSlot import ru.astrainteractive.astramarket.core.PluginConfig import ru.astrainteractive.astramarket.core.Translation +import ru.astrainteractive.astramarket.core.di.factory.CurrencyEconomyProviderFactory +import ru.astrainteractive.astramarket.core.util.getValue import ru.astrainteractive.astramarket.market.data.bridge.AuctionsBridge import ru.astrainteractive.astramarket.market.data.bridge.PlayerInteractionBridge +import ru.astrainteractive.klibs.kstorage.api.Krate import ru.astrainteractive.klibs.mikro.core.domain.UseCase import java.util.UUID @@ -28,13 +30,16 @@ internal class AuctionBuyUseCaseImpl( private val auctionsBridge: AuctionsBridge, private val marketApi: MarketApi, private val playerInteractionBridge: PlayerInteractionBridge, - private val translation: Translation, - private val config: PluginConfig, - private val economyProvider: EconomyProvider, -) : AuctionBuyUseCase, Logger by JUtiltLogger("AuctionBuyUseCase") { + private val translationKrate: Krate, + private val configKrate: Krate, + private val economyProviderFactory: CurrencyEconomyProviderFactory, +) : AuctionBuyUseCase, Logger by JUtiltLogger("AstraMarket-AuctionBuyUseCase") { + private val config by configKrate + private val translation by translationKrate @Suppress("LongMethod") override suspend operator fun invoke(input: AuctionBuyUseCase.Params): Boolean { + val economyProvider = economyProviderFactory.findDefault() ?: return false val receivedAuction = input.auction val playerUUID = input.playerUUID val playerName = auctionsBridge.playerName(playerUUID) diff --git a/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/domain/usecase/CreateAuctionUseCase.kt b/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/domain/usecase/CreateAuctionUseCase.kt index 44b110e..b9b2997 100644 --- a/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/domain/usecase/CreateAuctionUseCase.kt +++ b/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/domain/usecase/CreateAuctionUseCase.kt @@ -4,8 +4,10 @@ import ru.astrainteractive.astramarket.api.market.MarketApi import ru.astrainteractive.astramarket.api.market.model.MarketSlot import ru.astrainteractive.astramarket.core.PluginConfig import ru.astrainteractive.astramarket.core.Translation +import ru.astrainteractive.astramarket.core.util.getValue import ru.astrainteractive.astramarket.market.data.bridge.AuctionsBridge import ru.astrainteractive.astramarket.market.data.bridge.PlayerInteractionBridge +import ru.astrainteractive.klibs.kstorage.api.Krate import ru.astrainteractive.klibs.mikro.core.domain.UseCase import java.util.UUID @@ -20,9 +22,11 @@ internal class CreateAuctionUseCaseImpl( private val auctionsBridge: AuctionsBridge, private val marketApi: MarketApi, private val playerInteractionBridge: PlayerInteractionBridge, - private val translation: Translation, - private val config: PluginConfig, + translationKrate: Krate, + configKrate: Krate, ) : CreateAuctionUseCase { + private val translation by translationKrate + private val config by configKrate override suspend operator fun invoke(input: CreateAuctionUseCase.Params): Boolean { val playerUUID = input.playerUUID diff --git a/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/domain/usecase/ExpireAuctionUseCase.kt b/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/domain/usecase/ExpireAuctionUseCase.kt index 072fabf..75c6d20 100644 --- a/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/domain/usecase/ExpireAuctionUseCase.kt +++ b/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/domain/usecase/ExpireAuctionUseCase.kt @@ -3,8 +3,10 @@ package ru.astrainteractive.astramarket.market.domain.usecase import ru.astrainteractive.astramarket.api.market.MarketApi import ru.astrainteractive.astramarket.api.market.model.MarketSlot import ru.astrainteractive.astramarket.core.Translation +import ru.astrainteractive.astramarket.core.util.getValue import ru.astrainteractive.astramarket.market.data.bridge.AuctionsBridge import ru.astrainteractive.astramarket.market.data.bridge.PlayerInteractionBridge +import ru.astrainteractive.klibs.kstorage.api.Krate import ru.astrainteractive.klibs.mikro.core.domain.UseCase import java.util.UUID @@ -24,8 +26,9 @@ internal class ExpireAuctionUseCaseImpl( private val auctionsBridge: AuctionsBridge, private val marketApi: MarketApi, private val playerInteractionBridge: PlayerInteractionBridge, - private val translation: Translation, + translationKrate: Krate, ) : ExpireAuctionUseCase { + private val translation by translationKrate override suspend operator fun invoke(input: ExpireAuctionUseCase.Params): Boolean { val playerUUID = input.playerUUID diff --git a/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/domain/usecase/RemoveAuctionUseCase.kt b/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/domain/usecase/RemoveAuctionUseCase.kt index 95fd502..46d5b69 100644 --- a/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/domain/usecase/RemoveAuctionUseCase.kt +++ b/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/domain/usecase/RemoveAuctionUseCase.kt @@ -3,8 +3,10 @@ package ru.astrainteractive.astramarket.market.domain.usecase import ru.astrainteractive.astramarket.api.market.MarketApi import ru.astrainteractive.astramarket.core.PluginConfig import ru.astrainteractive.astramarket.core.Translation +import ru.astrainteractive.astramarket.core.util.getValue import ru.astrainteractive.astramarket.market.data.bridge.AuctionsBridge import ru.astrainteractive.astramarket.market.data.bridge.PlayerInteractionBridge +import ru.astrainteractive.klibs.kstorage.api.Krate import ru.astrainteractive.klibs.mikro.core.domain.UseCase import java.util.UUID @@ -24,9 +26,11 @@ internal class RemoveAuctionUseCaseImpl( private val auctionsBridge: AuctionsBridge, private val marketApi: MarketApi, private val playerInteractionBridge: PlayerInteractionBridge, - private val translation: Translation, - private val config: PluginConfig, + translationKrate: Krate, + configKrate: Krate, ) : RemoveAuctionUseCase { + private val translation by translationKrate + private val config by configKrate override suspend operator fun invoke(input: RemoveAuctionUseCase.Params): Boolean { val receivedAuction = input.auction diff --git a/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/presentation/AuctionComponent.kt b/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/presentation/AuctionComponent.kt index d3d6535..d26ef64 100644 --- a/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/presentation/AuctionComponent.kt +++ b/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/presentation/AuctionComponent.kt @@ -1,17 +1,17 @@ package ru.astrainteractive.astramarket.market.presentation +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.StateFlow import ru.astrainteractive.astramarket.api.market.model.MarketSlot import ru.astrainteractive.astramarket.market.domain.model.AuctionSort import java.util.UUID -interface AuctionComponent { +interface AuctionComponent : CoroutineScope { val model: StateFlow fun onAuctionItemClicked(i: Int, clickType: ClickType) fun onSortButtonClicked(isRightClick: Boolean) fun toggleExpired() - fun close() data class Model( val items: List = emptyList(), diff --git a/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/presentation/DefaultAuctionComponent.kt b/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/presentation/DefaultAuctionComponent.kt index 861e797..71c734e 100644 --- a/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/presentation/DefaultAuctionComponent.kt +++ b/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/presentation/DefaultAuctionComponent.kt @@ -1,9 +1,10 @@ package ru.astrainteractive.astramarket.market.presentation +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.update import kotlinx.coroutines.sync.Mutex -import ru.astrainteractive.astralibs.async.AsyncComponent +import ru.astrainteractive.astralibs.async.CoroutineFeature import ru.astrainteractive.astramarket.api.market.model.MarketSlot import ru.astrainteractive.astramarket.core.CoroutineExt.launchWithLock import ru.astrainteractive.astramarket.market.domain.model.AuctionSort @@ -23,7 +24,7 @@ internal class DefaultAuctionComponent( isExpired: Boolean, private val dependencies: AuctionComponentDependencies ) : AuctionComponent, - AsyncComponent(), + CoroutineFeature by CoroutineFeature.Default(Dispatchers.IO), AuctionComponentDependencies by dependencies { private val mutex = Mutex() @@ -45,7 +46,7 @@ internal class DefaultAuctionComponent( } private fun sort() { - componentScope.launchWithLock(mutex, dispatchers.IO) { + launchWithLock(mutex, dispatchers.IO) { model.update { model -> val input = SortAuctionsUseCase.Input(model.sortType, model.items) val sortedItems = sortAuctionsUseCase.invoke(input) @@ -80,7 +81,7 @@ internal class DefaultAuctionComponent( } private fun loadItems() { - componentScope.launchWithLock(mutex, dispatchers.IO) { + launchWithLock(mutex, dispatchers.IO) { val items = when { targetPlayerUUID != null -> { marketApi.getUserSlots( @@ -98,7 +99,7 @@ internal class DefaultAuctionComponent( override fun onAuctionItemClicked(i: Int, clickType: AuctionComponent.ClickType) { val auction = model.value.items.getOrNull(i) ?: return - componentScope.launchWithLock(mutex, dispatchers.IO) { + launchWithLock(mutex, dispatchers.IO) { val result = when (model.value.isExpired) { true -> { if (auction.minecraftUuid == playerUUID.toString()) { diff --git a/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/presentation/di/AuctionComponentDependencies.kt b/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/presentation/di/AuctionComponentDependencies.kt index fdc4e8a..8648fbf 100644 --- a/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/presentation/di/AuctionComponentDependencies.kt +++ b/modules/market-view/src/main/kotlin/ru/astrainteractive/astramarket/market/presentation/di/AuctionComponentDependencies.kt @@ -3,14 +3,14 @@ package ru.astrainteractive.astramarket.market.presentation.di import ru.astrainteractive.astramarket.api.market.MarketApi import ru.astrainteractive.astramarket.core.PluginConfig import ru.astrainteractive.astramarket.core.di.CoreModule +import ru.astrainteractive.astramarket.core.util.getValue import ru.astrainteractive.astramarket.di.ApiMarketModule import ru.astrainteractive.astramarket.market.data.bridge.PlayerInteractionBridge -import ru.astrainteractive.astramarket.market.domain.di.MarketDomainModule +import ru.astrainteractive.astramarket.market.domain.di.MarketViewDomainModule import ru.astrainteractive.astramarket.market.domain.usecase.AuctionBuyUseCase import ru.astrainteractive.astramarket.market.domain.usecase.ExpireAuctionUseCase import ru.astrainteractive.astramarket.market.domain.usecase.RemoveAuctionUseCase import ru.astrainteractive.astramarket.market.domain.usecase.SortAuctionsUseCase -import ru.astrainteractive.klibs.kdi.getValue import ru.astrainteractive.klibs.mikro.core.dispatchers.KotlinDispatchers internal interface AuctionComponentDependencies { @@ -26,15 +26,15 @@ internal interface AuctionComponentDependencies { class Default( coreModule: CoreModule, apiMarketModule: ApiMarketModule, - marketDomainModule: MarketDomainModule, + marketViewDomainModule: MarketViewDomainModule, ) : AuctionComponentDependencies { - override val config: PluginConfig by coreModule.config + override val config: PluginConfig by coreModule.configKrate override val dispatchers: KotlinDispatchers = coreModule.dispatchers override val marketApi: MarketApi = apiMarketModule.marketApi - override val auctionBuyUseCase: AuctionBuyUseCase = marketDomainModule.auctionBuyUseCase - override val expireAuctionUseCase: ExpireAuctionUseCase = marketDomainModule.expireAuctionUseCase - override val removeAuctionUseCase: RemoveAuctionUseCase = marketDomainModule.removeAuctionUseCase - override val playerInteractionBridge = marketDomainModule.marketDataModule.playerInteractionBridge - override val sortAuctionsUseCase = marketDomainModule.platformMarketDomainModule.sortAuctionsUseCase + override val auctionBuyUseCase: AuctionBuyUseCase = marketViewDomainModule.auctionBuyUseCase + override val expireAuctionUseCase: ExpireAuctionUseCase = marketViewDomainModule.expireAuctionUseCase + override val removeAuctionUseCase: RemoveAuctionUseCase = marketViewDomainModule.removeAuctionUseCase + override val playerInteractionBridge = marketViewDomainModule.marketDataModule.playerInteractionBridge + override val sortAuctionsUseCase = marketViewDomainModule.platformMarketDomainModule.sortAuctionsUseCase } } diff --git a/modules/periodic/build.gradle.kts b/modules/periodic/build.gradle.kts index a59fb4d..d89bbc9 100644 --- a/modules/periodic/build.gradle.kts +++ b/modules/periodic/build.gradle.kts @@ -8,7 +8,6 @@ dependencies { implementation(libs.bundles.kotlin) // AstraLibs implementation(libs.minecraft.astralibs.core) - implementation(libs.klibs.kdi) implementation(libs.klibs.mikro.core) // Local implementation(projects.modules.apiMarket) diff --git a/modules/periodic/src/main/kotlin/ru/astrainteractive/astramarket/worker/Worker.kt b/modules/periodic/src/main/kotlin/ru/astrainteractive/astramarket/worker/Worker.kt index cf54538..1c5f480 100644 --- a/modules/periodic/src/main/kotlin/ru/astrainteractive/astramarket/worker/Worker.kt +++ b/modules/periodic/src/main/kotlin/ru/astrainteractive/astramarket/worker/Worker.kt @@ -2,9 +2,10 @@ package ru.astrainteractive.astramarket.worker import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.cancel import kotlinx.coroutines.launch -import ru.astrainteractive.astralibs.async.AsyncComponent +import ru.astrainteractive.astralibs.async.CoroutineFeature import java.util.Timer import kotlin.time.Duration @@ -21,7 +22,7 @@ internal abstract class Worker(val key: String) { fun start() { if (scope != null) error("Scope already exists!") if (scheduler != null) error("Scheduler already exists!") - val currentScope = AsyncComponent.Default() + val currentScope = CoroutineFeature.Default(Dispatchers.IO) scope = currentScope scheduler = kotlin.concurrent.timer( name = key, diff --git a/modules/periodic/src/main/kotlin/ru/astrainteractive/astramarket/worker/di/WorkerModule.kt b/modules/periodic/src/main/kotlin/ru/astrainteractive/astramarket/worker/di/WorkerModule.kt index 429fe5e..48f6b3b 100644 --- a/modules/periodic/src/main/kotlin/ru/astrainteractive/astramarket/worker/di/WorkerModule.kt +++ b/modules/periodic/src/main/kotlin/ru/astrainteractive/astramarket/worker/di/WorkerModule.kt @@ -17,7 +17,7 @@ interface WorkerModule { ExpireWorker( marketApi = apiMarketModule.marketApi, dispatchers = coreModule.dispatchers, - config = coreModule.config + configKrate = coreModule.configKrate ) } override val lifecycle: Lifecycle = Lifecycle.Lambda( diff --git a/modules/periodic/src/main/kotlin/ru/astrainteractive/astramarket/worker/expireworker/ExpireWorker.kt b/modules/periodic/src/main/kotlin/ru/astrainteractive/astramarket/worker/expireworker/ExpireWorker.kt index 06db5e5..018b141 100644 --- a/modules/periodic/src/main/kotlin/ru/astrainteractive/astramarket/worker/expireworker/ExpireWorker.kt +++ b/modules/periodic/src/main/kotlin/ru/astrainteractive/astramarket/worker/expireworker/ExpireWorker.kt @@ -6,8 +6,9 @@ import kotlinx.coroutines.awaitAll import kotlinx.coroutines.coroutineScope import ru.astrainteractive.astramarket.api.market.MarketApi import ru.astrainteractive.astramarket.core.PluginConfig +import ru.astrainteractive.astramarket.core.util.getValue import ru.astrainteractive.astramarket.worker.Worker -import ru.astrainteractive.klibs.kdi.Dependency +import ru.astrainteractive.klibs.kstorage.api.Krate import ru.astrainteractive.klibs.mikro.core.dispatchers.KotlinDispatchers import kotlin.time.Duration import kotlin.time.Duration.Companion.milliseconds @@ -17,14 +18,15 @@ import kotlin.time.Duration.Companion.seconds internal class ExpireWorker( private val marketApi: MarketApi, dispatchers: KotlinDispatchers, - val config: Dependency + val configKrate: Krate ) : Worker("EXPIRE_WORKER") { override val dispatcher: CoroutineDispatcher = dispatchers.IO.limitedParallelism(1) override val initialDelay: Duration = 5.seconds override val period: Duration = 1.minutes + private val config by configKrate override suspend fun doWork(): Unit = coroutineScope { - val maxAuctionLifeTime = config.value.auction.maxTimeSeconds.seconds + val maxAuctionLifeTime = config.auction.maxTimeSeconds.seconds val currentTime = System.currentTimeMillis().milliseconds marketApi.getSlots(isExpired = false) .orEmpty() diff --git a/spigot/build.gradle.kts b/spigot/build.gradle.kts index f701c75..a1cc734 100644 --- a/spigot/build.gradle.kts +++ b/spigot/build.gradle.kts @@ -1,10 +1,10 @@ -import ru.astrainteractive.gradleplugin.setupSpigotProcessor -import ru.astrainteractive.gradleplugin.setupSpigotShadow +import ru.astrainteractive.gradleplugin.property.extension.ModelPropertyValueExt.requireProjectInfo plugins { kotlin("jvm") kotlin("plugin.serialization") - id("ru.astrainteractive.gradleplugin.minecraft.multiplatform") + alias(libs.plugins.klibs.minecraft.shadow) + alias(libs.plugins.klibs.minecraft.resource.processor) } dependencies { @@ -12,8 +12,7 @@ dependencies { implementation(libs.bundles.kotlin) // AstraLibs implementation(libs.minecraft.astralibs.core) - implementation(libs.minecraft.astralibs.orm) - implementation(libs.klibs.kdi) + implementation(libs.minecraft.astralibs.exposed) implementation(libs.klibs.mikro.core) implementation(libs.minecraft.astralibs.menu.bukkit) implementation(libs.minecraft.astralibs.core.bukkit) @@ -40,10 +39,30 @@ dependencies { implementation(projects.modules.commandBukkit) } -val destination = File("/home/makeevrserg/Desktop/server/data/plugins") - .takeIf(File::exists) - ?: File(rootDir, "jars") +minecraftProcessResource { + spigotResourceProcessor.process() +} + +setupShadow { + requireShadowJarTask { + destination = File("/home/makeevrserg/Desktop/server/data/plugins") + .takeIf { it.exists() } + ?: File(rootDir, "jars") -setupSpigotShadow(destination) + val projectInfo = requireProjectInfo + isReproducibleFileOrder = true + mergeServiceFiles() + dependsOn(configurations) + archiveClassifier.set(null as String?) + relocate("org.bstats", projectInfo.group) -setupSpigotProcessor() + minimize { + exclude(dependency(libs.exposed.jdbc.get())) + exclude(dependency(libs.exposed.dao.get())) + exclude(dependency("org.jetbrains.kotlin:kotlin-stdlib:${libs.versions.kotlin.version.get()}")) + } + archiveVersion.set(projectInfo.versionString) + archiveBaseName.set(projectInfo.name) + destinationDirectory.set(destination.get()) + } +} diff --git a/spigot/src/main/kotlin/ru/astrainteractive/astramarket/AstraMarket.kt b/spigot/src/main/kotlin/ru/astrainteractive/astramarket/AstraMarket.kt index 53e0bbb..2c44742 100644 --- a/spigot/src/main/kotlin/ru/astrainteractive/astramarket/AstraMarket.kt +++ b/spigot/src/main/kotlin/ru/astrainteractive/astramarket/AstraMarket.kt @@ -1,44 +1,22 @@ package ru.astrainteractive.astramarket -import org.bukkit.Bukkit -import org.bukkit.entity.Player -import org.bukkit.event.HandlerList -import ru.astrainteractive.astralibs.lifecycle.Lifecycle import ru.astrainteractive.astralibs.logging.JUtiltLogger import ru.astrainteractive.astralibs.logging.Logger -import ru.astrainteractive.astramarket.core.AstraMarketPlugin +import ru.astrainteractive.astramarket.core.LifecyclePlugin import ru.astrainteractive.astramarket.di.RootModule -/** - * Initial class for your plugin - */ -class AstraMarket : AstraMarketPlugin(), Logger by JUtiltLogger("AstraMarket") { - - private val rootModule = RootModule.Default() - private val lifecycle: List - get() = listOf( - rootModule.coreModule.lifecycle, - rootModule.bukkitCoreModule.lifecycle, - rootModule.apiMarketModule.lifecycle, - rootModule.commandModule.lifecycle, - rootModule.workerModule.lifecycle - ) +class AstraMarket : LifecyclePlugin(), Logger by JUtiltLogger("AstraMarket") { + private val rootModule = RootModule.Default(this) override fun onEnable() { - rootModule.bukkitCoreModule.plugin.initialize(this) - lifecycle.forEach(Lifecycle::onEnable) - // Init economy provider - rootModule.coreModule.economyProvider + rootModule.lifecycle.onEnable() } override fun onDisable() { - Bukkit.getOnlinePlayers().forEach(Player::closeInventory) - HandlerList.unregisterAll(this) - lifecycle.forEach(Lifecycle::onDisable) + rootModule.lifecycle.onDisable() } override fun onReload() { - Bukkit.getOnlinePlayers().forEach(Player::closeInventory) - lifecycle.forEach(Lifecycle::onReload) + rootModule.lifecycle.onReload() } } diff --git a/spigot/src/main/kotlin/ru/astrainteractive/astramarket/di/RootModule.kt b/spigot/src/main/kotlin/ru/astrainteractive/astramarket/di/RootModule.kt index d820c61..cc79180 100644 --- a/spigot/src/main/kotlin/ru/astrainteractive/astramarket/di/RootModule.kt +++ b/spigot/src/main/kotlin/ru/astrainteractive/astramarket/di/RootModule.kt @@ -1,122 +1,100 @@ package ru.astrainteractive.astramarket.di -import net.milkbowl.vault.economy.Economy import org.bukkit.Bukkit -import ru.astrainteractive.astralibs.async.DefaultBukkitDispatchers -import ru.astrainteractive.astralibs.economy.VaultEconomyProvider +import org.bukkit.entity.Player +import org.bukkit.event.HandlerList +import ru.astrainteractive.astralibs.lifecycle.Lifecycle import ru.astrainteractive.astralibs.logging.JUtiltLogger import ru.astrainteractive.astralibs.logging.Logger import ru.astrainteractive.astramarket.command.di.CommandModule +import ru.astrainteractive.astramarket.core.LifecyclePlugin import ru.astrainteractive.astramarket.core.di.BukkitCoreModule -import ru.astrainteractive.astramarket.core.di.CoreModule -import ru.astrainteractive.astramarket.di.util.ConnectionExt.toDBConnection import ru.astrainteractive.astramarket.gui.router.di.RouterModule import ru.astrainteractive.astramarket.market.data.di.BukkitMarketDataModule -import ru.astrainteractive.astramarket.market.di.MarketModule +import ru.astrainteractive.astramarket.market.di.MarketViewModule import ru.astrainteractive.astramarket.market.domain.di.BukkitMarketDomainModule -import ru.astrainteractive.astramarket.players.di.PlayersMarketModule +import ru.astrainteractive.astramarket.players.di.PlayersMarketViewModule import ru.astrainteractive.astramarket.worker.di.WorkerModule -import ru.astrainteractive.klibs.kdi.Provider -import ru.astrainteractive.klibs.kdi.getValue internal interface RootModule { - val coreModule: CoreModule - val bukkitCoreModule: BukkitCoreModule + val lifecycle: Lifecycle + + val coreModule: BukkitCoreModule val apiMarketModule: ApiMarketModule val routerModule: RouterModule - val marketModule: MarketModule + val marketViewModule: MarketViewModule val commandModule: CommandModule - val playersMarketModule: PlayersMarketModule + val playersMarketViewModule: PlayersMarketViewModule val workerModule: WorkerModule - class Default : RootModule, Logger by JUtiltLogger("RootModule") { - override val bukkitCoreModule: BukkitCoreModule by lazy { - BukkitCoreModule.Default() - } + class Default(plugin: LifecyclePlugin) : RootModule, Logger by JUtiltLogger("AstraMarket-RootModule") { + override val coreModule: BukkitCoreModule = BukkitCoreModule.Default(plugin) - override val coreModule: CoreModule by lazy { - CoreModule.Default( - dataFolder = bukkitCoreModule.plugin.value.dataFolder, - dispatchers = DefaultBukkitDispatchers(bukkitCoreModule.plugin.value), - getEconomyProvider = getEconomyProviderById@{ currencyId -> - val registrations = Bukkit.getServer().servicesManager.getRegistrations(Economy::class.java) - if (currencyId == null) { - return@getEconomyProviderById VaultEconomyProvider( - bukkitCoreModule.plugin.value - ) - } - val specificEconomyProvider = registrations - .firstOrNull { it.provider.currencyNameSingular() == currencyId } - ?.provider - ?.let(::VaultEconomyProvider) - if (specificEconomyProvider == null) { - error { "#economyProvider could not find economy with currency: $currencyId" } - } else { - return@getEconomyProviderById specificEconomyProvider - } - error("EconomyProvider could not find economy with currency: $currencyId") - } - ) - } + override val apiMarketModule: ApiMarketModule = ApiMarketModule.Default( + dispatchers = coreModule.dispatchers, + yamlStringFormat = coreModule.yamlStringFormat, + dataFolder = coreModule.plugin.dataFolder + ) - override val apiMarketModule: ApiMarketModule by Provider { - val config by coreModule.config - val (dbConnection, dbSyntax) = config.connection.toDBConnection() - ApiMarketModule.Default( - dbConnection = dbConnection, - dbSyntax = dbSyntax, - dispatchers = coreModule.dispatchers + override val marketViewModule: MarketViewModule = MarketViewModule.Default( + coreModule = coreModule, + apiMarketModule = apiMarketModule, + marketDataModule = BukkitMarketDataModule( + itemStackEncoder = coreModule.itemStackEncoder, + stringSerializer = coreModule.kyoriComponentSerializer.cachedValue + ), + platformMarketDomainModule = BukkitMarketDomainModule( + itemStackEncoder = coreModule.itemStackEncoder, ) - } + ) - override val marketModule: MarketModule by Provider { - MarketModule.Default( - coreModule = coreModule, - apiMarketModule = apiMarketModule, - marketDataModuleFactory = { - BukkitMarketDataModule( - itemStackEncoder = bukkitCoreModule.itemStackEncoder, - stringSerializer = bukkitCoreModule.kyoriComponentSerializer.value - ) - }, - platformMarketDomainModuleFactory = { - BukkitMarketDomainModule( - itemStackEncoder = bukkitCoreModule.itemStackEncoder, - ) - } - ) - } + override val playersMarketViewModule: PlayersMarketViewModule = PlayersMarketViewModule.Default( + coreModule = coreModule, + apiMarketModule = apiMarketModule + ) - override val routerModule: RouterModule by Provider { - RouterModule.Default( - coreModule = coreModule, - marketModule = marketModule, - bukkitCoreModule = bukkitCoreModule, - playersMarketModule = playersMarketModule - ) - } + override val routerModule: RouterModule = RouterModule.Default( + coreModule = coreModule, + marketViewModule = marketViewModule, + bukkitCoreModule = coreModule, + playersMarketViewModule = playersMarketViewModule + ) - override val commandModule: CommandModule by lazy { - CommandModule.Default( - coreModule = coreModule, - bukkitCoreModule = bukkitCoreModule, - routerModule = routerModule, - marketModule = marketModule - ) - } + override val commandModule: CommandModule = CommandModule.Default( + coreModule = coreModule, + bukkitCoreModule = coreModule, + routerModule = routerModule, + marketViewModule = marketViewModule + ) - override val playersMarketModule: PlayersMarketModule by lazy { - PlayersMarketModule.Default( - coreModule = coreModule, - apiMarketModule = apiMarketModule - ) - } + override val workerModule: WorkerModule = WorkerModule.Default( + apiMarketModule = apiMarketModule, + coreModule = coreModule + ) - override val workerModule: WorkerModule by lazy { - WorkerModule.Default( - apiMarketModule = apiMarketModule, - coreModule = coreModule + private val lifecycles: List + get() = listOf( + coreModule.lifecycle, + coreModule.lifecycle, + apiMarketModule.lifecycle, + commandModule.lifecycle, + workerModule.lifecycle ) - } + + override val lifecycle: Lifecycle = Lifecycle.Lambda( + onEnable = { + lifecycles.forEach(Lifecycle::onEnable) + }, + onReload = { + Bukkit.getOnlinePlayers().forEach(Player::closeInventory) + lifecycles.forEach(Lifecycle::onReload) + }, + onDisable = { + Bukkit.getOnlinePlayers().forEach(Player::closeInventory) + HandlerList.unregisterAll(coreModule.plugin) + lifecycles.forEach(Lifecycle::onDisable) + } + + ) } } diff --git a/spigot/src/main/kotlin/ru/astrainteractive/astramarket/di/util/ConnectionExt.kt b/spigot/src/main/kotlin/ru/astrainteractive/astramarket/di/util/ConnectionExt.kt deleted file mode 100644 index 30cf26a..0000000 --- a/spigot/src/main/kotlin/ru/astrainteractive/astramarket/di/util/ConnectionExt.kt +++ /dev/null @@ -1,24 +0,0 @@ -@file:Suppress("Filename") - -package ru.astrainteractive.astramarket.di.util - -import ru.astrainteractive.astralibs.orm.DBConnection -import ru.astrainteractive.astralibs.orm.DBSyntax -import ru.astrainteractive.astramarket.core.PluginConfig - -internal object ConnectionExt { - fun PluginConfig.Connection.toDBConnection(): Pair { - val mysql = this.mysql - val sqlite = this.sqlite - val sqliteConnection = DBConnection.SQLite("dbv2_auction.db") to DBSyntax.SQLite - if (sqlite || mysql == null) return sqliteConnection - return DBConnection.MySQL( - database = mysql.database, - ip = mysql.ip, - port = mysql.port, - username = mysql.username, - password = mysql.password, - sessionVariables = mysql.sessionVariables.toTypedArray() - ) to DBSyntax.MySQL - } -} diff --git a/spigot/src/main/resources/plugin.yml b/spigot/src/main/resources/plugin.yml index fff63cd..d51b12f 100644 --- a/spigot/src/main/resources/plugin.yml +++ b/spigot/src/main/resources/plugin.yml @@ -8,9 +8,11 @@ author: "${author}" website: "${url}" api-version: 1.18 softdepend: [ Vault, EssentialsX, AspeKt ] -#libraries: [ "${libraries}" ] libraries: - - org.bstats:bstats-bukkit:3.0.0 + - "org.bstats:bstats-bukkit:3.0.0" + - "org.xerial:sqlite-jdbc:3.46.1.0" + - "mysql:mysql-connector-java:8.0.33" + - "com.h2database:h2:2.2.224" commands: amarketreload: description: Reload plugin