From 37a70e211e2e58474039c62db69d6ac74a1ca6aa Mon Sep 17 00:00:00 2001 From: jie65535 Date: Sun, 19 Jun 2022 11:12:57 +0800 Subject: [PATCH] =?UTF-8?q?[=E9=87=8D=E5=A4=A7=E5=8F=98=E5=8C=96]=20?= =?UTF-8?q?=E6=8F=92=E4=BB=B6=E9=87=8D=E6=9E=84=E5=88=9D=E6=AD=A5=E5=AE=8C?= =?UTF-8?q?=E6=88=90=20=E7=A7=BB=E9=99=A4=E6=97=A7=E4=BB=A3=E7=A0=81=20?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=89=88=E6=9C=AC=E5=88=B0v1.0.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 24 +- build.gradle.kts | 2 +- .../kotlin/me/jie65535/jcf/CurseClient.kt | 229 -------------- .../kotlin/me/jie65535/jcf/JCurseforge.kt | 30 -- src/main/kotlin/me/jie65535/jcf/JcfCommand.kt | 58 ---- .../kotlin/me/jie65535/jcf/MessageHandler.kt | 93 ------ .../me/jie65535/jcf/MinecraftService.kt | 180 ----------- .../me/jie65535/jcf/model/addon/Addon.kt | 52 ---- .../jcf/model/addon/AddonAttachment.kt | 22 -- .../jcf/model/addon/AddonAttachmentStatus.kt | 24 -- .../jie65535/jcf/model/addon/AddonAuthor.kt | 22 -- .../jie65535/jcf/model/addon/AddonCategory.kt | 23 -- .../jcf/model/addon/AddonPackageType.kt | 24 -- .../jcf/model/addon/AddonRepositoryMatch.kt | 17 -- .../model/addon/AddonRestrictFileAccess.kt | 21 -- .../jcf/model/addon/AddonSortMethod.kt | 53 ---- .../jie65535/jcf/model/addon/AddonStatus.kt | 28 -- .../jcf/model/addon/FeaturedAddonType.kt | 21 -- .../jcf/model/addon/SortableGameVersion.kt | 21 -- .../jcf/model/addon/file/AddonFile.kt | 60 ---- .../model/addon/file/AddonFileDependency.kt | 18 -- .../addon/file/AddonFileFingerprintType.kt | 23 -- .../file/AddonFileLatestForGameVersion.kt | 19 -- .../jcf/model/addon/file/AddonFileModule.kt | 19 -- .../model/addon/file/AddonFileRelationType.kt | 24 -- .../model/addon/file/AddonFileReleaseType.kt | 21 -- .../jcf/model/addon/file/AddonFileStatus.kt | 33 -- .../addon/request/FeaturedAddonsRequest.kt | 18 -- .../jie65535/jcf/model/category/Category.kt | 25 -- .../jcf/model/category/CategorySection.kt | 23 -- .../jcf/model/fingerprint/FingerprintMatch.kt | 18 -- .../fingerprint/FingerprintMatchResult.kt | 21 -- .../model/fingerprint/FolderFingerprint.kt | 18 -- .../fingerprint/FuzzyFingerprintMatch.kt | 19 -- .../request/FuzzyMatchesRequest.kt | 17 -- .../kotlin/me/jie65535/jcf/model/game/Game.kt | 41 --- .../jcf/model/game/GameDetectionHint.kt | 21 -- .../jcf/model/game/GameDetectionHintOption.kt | 19 -- .../jcf/model/game/GameDetectionHintType.kt | 21 -- .../me/jie65535/jcf/model/game/GameFile.kt | 20 -- .../jcf/model/game/GameFileParsingRule.kt | 19 -- .../jie65535/jcf/model/game/GameFileType.kt | 22 -- .../jcf/model/game/GamePlatformType.kt | 23 -- .../game/SupportedClientConfiguration.kt | 19 -- .../jcf/model/minecraft/MinecraftVersion.kt | 27 -- .../model/minecraft/MinecraftVersionStatus.kt | 21 -- .../minecraft/MinecraftVersionTypeStatus.kt | 20 -- .../minecraft/modloader/ModloaderIndex.kt | 22 -- .../modloader/ModloaderInstallMethod.kt | 22 -- .../minecraft/modloader/ModloaderType.kt | 22 -- .../minecraft/modloader/ModloaderVersion.kt | 48 --- src/main/kotlin/me/jie65535/jcf/util/Date.kt | 5 - .../kotlin/me/jie65535/jcf/util/HttpUtil.kt | 29 -- .../jcf/util/internal/DateSerializer.kt | 26 -- .../jcf/util/internal/EnumIntSerializer.kt | 25 -- .../jcf/util/internal/FlagSerializer.kt | 36 --- .../jcf/util/internal/PackageNames.kt | 3 - .../kotlin/top/jie65535/jcf/CurseforgeApi.kt | 9 +- .../kotlin/top/jie65535/jcf/MessageHandler.kt | 283 +++++++++++------- .../top/jie65535/jcf/MinecraftService.kt | 18 +- .../kotlin/top/jie65535/jcf/PluginCommands.kt | 23 ++ .../kotlin/top/jie65535/jcf/PluginConfig.kt | 18 +- .../kotlin/top/jie65535/jcf/PluginMain.kt | 6 +- 63 files changed, 246 insertions(+), 1942 deletions(-) delete mode 100644 src/main/kotlin/me/jie65535/jcf/CurseClient.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/JCurseforge.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/JcfCommand.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/MessageHandler.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/MinecraftService.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/addon/Addon.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/addon/AddonAttachment.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/addon/AddonAttachmentStatus.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/addon/AddonAuthor.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/addon/AddonCategory.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/addon/AddonPackageType.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/addon/AddonRepositoryMatch.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/addon/AddonRestrictFileAccess.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/addon/AddonSortMethod.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/addon/AddonStatus.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/addon/FeaturedAddonType.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/addon/SortableGameVersion.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/addon/file/AddonFile.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/addon/file/AddonFileDependency.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/addon/file/AddonFileFingerprintType.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/addon/file/AddonFileLatestForGameVersion.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/addon/file/AddonFileModule.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/addon/file/AddonFileRelationType.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/addon/file/AddonFileReleaseType.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/addon/file/AddonFileStatus.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/addon/request/FeaturedAddonsRequest.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/category/Category.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/category/CategorySection.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/fingerprint/FingerprintMatch.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/fingerprint/FingerprintMatchResult.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/fingerprint/FolderFingerprint.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/fingerprint/FuzzyFingerprintMatch.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/fingerprint/request/FuzzyMatchesRequest.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/game/Game.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/game/GameDetectionHint.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/game/GameDetectionHintOption.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/game/GameDetectionHintType.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/game/GameFile.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/game/GameFileParsingRule.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/game/GameFileType.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/game/GamePlatformType.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/game/SupportedClientConfiguration.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/minecraft/MinecraftVersion.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/minecraft/MinecraftVersionStatus.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/minecraft/MinecraftVersionTypeStatus.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/minecraft/modloader/ModloaderIndex.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/minecraft/modloader/ModloaderInstallMethod.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/minecraft/modloader/ModloaderType.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/model/minecraft/modloader/ModloaderVersion.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/util/Date.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/util/HttpUtil.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/util/internal/DateSerializer.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/util/internal/EnumIntSerializer.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/util/internal/FlagSerializer.kt delete mode 100644 src/main/kotlin/me/jie65535/jcf/util/internal/PackageNames.kt create mode 100644 src/main/kotlin/top/jie65535/jcf/PluginCommands.kt diff --git a/README.md b/README.md index a7fb1a7..2811d22 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # mirai-console-jcf-plugin 基于Mirai Console的Curseforge插件 +# 请注意:本插件需要申请 [Curseforge Api Key](https://console.curseforge.com/) 才可使用!! + ## Introduction 允许用户通过`QQ`对[Curseforge](https://www.curseforge.com/)网站进行搜索查询 @@ -10,12 +12,18 @@ 支持查看文件列表与其下载地址,单独查看文件的更新日志。 ## Usage -- /jcf id # 根据id查找 -- /jcf help # 帮助 -- /jcf ss \ # 直接搜索 -- /jcf sspack \ # 搜索整合包 -- /jcf ssmod \ # 搜索模组 -- /jcf ssres \ # 搜索资源包 +指令 +- /jcf help # 查看帮助 +- /jcf setApiKey # 设置Curseforge API Key + +分类搜索命令(可配置) +- 搜索模组: cfmod \ +- 搜索整合包: cfpack \ +- 搜索资源包: cfres \ +- 搜索存档: cfword \ +- 搜索水桶服插件: cfbukkit \ +- 搜索附加: cfaddon \ +- 搜索定制: cfcustom \ ## Screenshots @@ -33,7 +41,7 @@ - [x] 搜索整合包 - [x] 搜索资源包 - [x] ~~搜索存档~~ - - [x] 根据项目ID搜索 + - [ ] 根据项目ID搜索 --- - [x] 分页选择 - [ ] 获取介绍 @@ -50,5 +58,3 @@ ## 鸣谢 - [Mirai](https://github.com/mamoe/mirai) 提供机器人平台 - [Mirai Console](https://github.com/mamoe/mirai-console) 开放插件接入 -- [Curseforge API](https://github.com/Gaz492/CurseforgeAPI) 提供`Curseforge API` -- [Curseforge API Kotlin library](https://github.com/pearxteam/cursekt) 提供`Curseforge API`的`kotlin`封装 diff --git a/build.gradle.kts b/build.gradle.kts index 23fb57f..9ca5814 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ plugins { id("net.mamoe.mirai-console") version "2.11.1" } -group = "top.jie65535" +group = "top.jie65535.jcf" version = "1.0.0" repositories { diff --git a/src/main/kotlin/me/jie65535/jcf/CurseClient.kt b/src/main/kotlin/me/jie65535/jcf/CurseClient.kt deleted file mode 100644 index a65ac42..0000000 --- a/src/main/kotlin/me/jie65535/jcf/CurseClient.kt +++ /dev/null @@ -1,229 +0,0 @@ -package me.jie65535.jcf - -import io.ktor.client.* -import io.ktor.client.engine.okhttp.* -import io.ktor.client.features.* -import io.ktor.client.request.* -import io.ktor.http.* -import kotlinx.serialization.ExperimentalSerializationApi -import kotlinx.serialization.decodeFromString -import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.Json -import me.jie65535.jcf.model.addon.* -import me.jie65535.jcf.model.addon.file.* -import me.jie65535.jcf.model.addon.request.* -import me.jie65535.jcf.model.category.* -import me.jie65535.jcf.model.fingerprint.* -import me.jie65535.jcf.model.fingerprint.request.* -import me.jie65535.jcf.model.game.* -import me.jie65535.jcf.model.minecraft.* -import me.jie65535.jcf.model.minecraft.modloader.* -import me.jie65535.jcf.util.Date - -@OptIn(ExperimentalSerializationApi::class) -object CurseClient { - private val json = Json { - isLenient = true - ignoreUnknownKeys = true - serializersModule - } - private val http = HttpClient(OkHttp) { - install(HttpTimeout) { - this.requestTimeoutMillis = 30_0000 - this.connectTimeoutMillis = 30_0000 - this.socketTimeoutMillis = 30_0000 - } - defaultRequest { - url.protocol = URLProtocol.HTTPS - url.host = "addons-ecs.forgesvc.net" - header("accept", "*/*") - } - } - - suspend fun getGames(supportsAddons: Boolean = false): List { - return json.decodeFromString( - http.get("api/v2/game") { - parameter("supportsAddons", supportsAddons.toString()) - } - ) - } - - suspend fun getGame(gameId: Int): Game { - return json.decodeFromString(http.get("api/v2/game/$gameId")) - } - - suspend fun getGameDatabaseTimestamp(): Date { - return http.get("api/v2/game/timestamp") - } - - suspend fun getAddon(projectId: Int): Addon { - return json.decodeFromString(http.get("api/v2/addon/$projectId")) - } - - suspend fun getAddons(projectIds: Collection): List { - return json.decodeFromString( - http.post("api/v2/addon") { - contentType(ContentType.Application.Json) - body = json.encodeToString(projectIds) - } - ) - } - - suspend fun getAddons(vararg projectIds: Int): List = getAddons(projectIds.toList()) - - suspend fun getAddonDescription(projectId: Int): String { - return http.get("api/v2/addon/$projectId/description") - } - - suspend fun getAddonFiles(projectId: Int): List { - return json.decodeFromString(http.get("api/v2/addon/$projectId/files")) - } - - suspend fun getAddonFiles(keys: Collection): Map> { - return json.decodeFromString( - http.post("api/v2/addon/files") { - contentType(ContentType.Application.Json) - body = json.encodeToString(keys) - } - ) - } - - suspend fun getAddonFiles(vararg keys: Int): Map> = getAddonFiles(keys.toList()) - - suspend fun getAddonFileDownloadUrl(projectId: Int, fileId: Int): String { - return http.get("api/v2/addon/$projectId/file/$fileId/download-url") - } - - suspend fun getAddonFile(projectId: Int, fileId: Int): AddonFile { - return json.decodeFromString(http.get("api/v2/addon/$projectId/file/$fileId")) - } - - suspend fun searchAddons( - gameId: Int, - sectionId: Int = -1, - categoryId: Int = -1, - sort: AddonSortMethod = AddonSortMethod.FEATURED, - sortDescending: Boolean = true, - gameVersion: String? = null, - index: Int = 0, - pageSize: Int = 10, - searchFilter: String? = null - ): List { - return json.decodeFromString( - http.get("api/v2/addon/search") { - parameter("gameId", gameId) - parameter("sectionId", sectionId) - parameter("categoryId", categoryId) - parameter("gameVersion", gameVersion) - parameter("index", index) - parameter("pageSize", pageSize) - parameter("searchFilter", searchFilter) - parameter("sort", sort) - parameter("sortDescending", sortDescending) - } - ) - } - - suspend fun getFeaturedAddons( - gameId: Int, - featuredCount: Int = 6, - popularCount: Int = 14, - updatedCount: Int = 14, - excludedAddons: Collection = listOf() - ): Map> { - return json.decodeFromString( - http.post("api/v2/addon/featured") { - contentType(ContentType.Application.Json) - body = json.encodeToString(FeaturedAddonsRequest(gameId, featuredCount, popularCount, updatedCount, excludedAddons)) - } - ) - } - - suspend fun getFeaturedAddons( - gameId: Int, - featuredCount: Int = 6, - popularCount: Int = 14, - updatedCount: Int = 14, - vararg excludedAddons: Int - ): Map> = getFeaturedAddons(gameId, featuredCount, popularCount, updatedCount, excludedAddons.toList()) - - suspend fun getCategory(categoryId: Int): Category { - return json.decodeFromString(http.get("api/v2/category/$categoryId")) - } - - suspend fun getCategory(slug: String): List { - return json.decodeFromString( - http.get("api/v2/category") { - parameter("slug", slug) - } - ) - } - - suspend fun getCategorySection(sectionId: Int): List { - return json.decodeFromString(http.get("api/v2/category/section/$sectionId")) - } - - suspend fun getCategories(): List { - return json.decodeFromString(http.get("api/v2/category")) - } - - suspend fun getCategoryDatabaseTimestamp(): Date { - return http.get("api/v2/category/timestamp") - } - - suspend fun getFingerprintMatches(fingerprints: Collection): FingerprintMatchResult { - return json.decodeFromString( - http.post("api/v2/fingerprint") { - contentType(ContentType.Application.Json) - body = json.encodeToString(fingerprints) - } - ) - } - - suspend fun getFingerprintMatches(vararg fingerprints: Long): FingerprintMatchResult = getFingerprintMatches(fingerprints.toList()) - - suspend fun getFuzzyFingerprintMatches(gameId: Int, fingerprints: List): List { - return json.decodeFromString( - http.post("api/v2/fingerprint/fuzzy") { - contentType(ContentType.Application.Json) - body = json.encodeToString(FuzzyMatchesRequest(gameId, fingerprints)) - } - ) - } - - suspend fun getModloader(key: String): ModloaderVersion { - return json.decodeFromString(http.get("api/v2/minecraft/modloader/$key")) - } - - suspend fun getModloaders(): List { - return json.decodeFromString(http.get("api/v2/minecraft/modloader")) - } - - suspend fun getModloaders(gameVersion: String): List { - return json.decodeFromString( - http.get("api/v2/minecraft/modloader") { - parameter("version", gameVersion) - } - ) - } - - suspend fun getModloadersDatabaseTimestamp(): Date { - return http.get("api/v2/minecraft/modloader/timestamp") - } - - suspend fun getMinecraftVersions(): List { - return json.decodeFromString(http.get("api/v2/minecraft/version")) - } - - suspend fun getMinecraftVersion(gameVersion: String): MinecraftVersion { - return json.decodeFromString(http.get("api/v2/minecraft/version/$gameVersion")) - } - - suspend fun getMinecraftVersionsDatabaseTimestamp(): Date { - return http.get("api/v2/minecraft/version/timestamp") - } - - suspend fun getAddonFileChangeLog(addonId: Int, fileId: Int): String { - return http.get("api/v2/addon/${addonId}/file/${fileId}/changelog") - } -} \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/JCurseforge.kt b/src/main/kotlin/me/jie65535/jcf/JCurseforge.kt deleted file mode 100644 index 4ce2eae..0000000 --- a/src/main/kotlin/me/jie65535/jcf/JCurseforge.kt +++ /dev/null @@ -1,30 +0,0 @@ -package me.jie65535.jcf - -import net.mamoe.mirai.console.command.CommandManager.INSTANCE.register -import net.mamoe.mirai.console.command.CommandManager.INSTANCE.unregister -import net.mamoe.mirai.console.plugin.jvm.JvmPluginDescription -import net.mamoe.mirai.console.plugin.jvm.KotlinPlugin -import net.mamoe.mirai.utils.info - -object JCurseforge : KotlinPlugin( - JvmPluginDescription( - id = "me.jie65535.jcf", - name = "J Curseforge Util", - version = "0.1.1", - ) { - author("jie65535") - info(""" - MC Curseforge Util - https://github.com/jie65535/mirai-console-jcf-plugin - """.trimIndent()) - } -) { - override fun onEnable() { - logger.info { "Plugin loaded" } - JcfCommand.register() - } - - override fun onDisable() { - JcfCommand.unregister() - } -} \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/JcfCommand.kt b/src/main/kotlin/me/jie65535/jcf/JcfCommand.kt deleted file mode 100644 index d67e7a5..0000000 --- a/src/main/kotlin/me/jie65535/jcf/JcfCommand.kt +++ /dev/null @@ -1,58 +0,0 @@ -package me.jie65535.jcf - -import net.mamoe.mirai.console.command.CommandSender -import net.mamoe.mirai.console.command.CompositeCommand -import net.mamoe.mirai.console.command.UserCommandSender -import net.mamoe.mirai.console.plugin.author -import net.mamoe.mirai.console.plugin.info -import net.mamoe.mirai.console.plugin.name -import net.mamoe.mirai.console.plugin.version - -object JcfCommand : CompositeCommand( - JCurseforge, "jcf", - description = "Curseforge Util" -) { - @SubCommand - @Description("帮助") - suspend fun CommandSender.help() { - sendMessage("${JCurseforge.name} by ${JCurseforge.author} ${JCurseforge.version}\n" + - "${JCurseforge.info}\n" + usage) - } - - @SubCommand("ss") - @Description("直接搜索") - suspend fun UserCommandSender.search(filter: String) { - MinecraftService.search(this, MinecraftService.ALL, filter) - } - - @SubCommand("ssmod") - @Description("搜索模组") - suspend fun UserCommandSender.searchMods(filter: String) { - MinecraftService.search(this, MinecraftService.SECTION_ID_MODES, filter) - } - - @SubCommand("sspack") - @Description("搜索整合包") - suspend fun UserCommandSender.searchModPacks(filter: String) { - MinecraftService.search(this, MinecraftService.SECTION_ID_MODE_PACKS, filter) - } - - @SubCommand("ssres") - @Description("搜索资源包") - suspend fun UserCommandSender.searchResourcePacks(filter: String) { - MinecraftService.search(this, MinecraftService.SECTION_ID_RESOURCE_PACKS, filter) - } - - // 可能用不上,先注释掉,有需要再说 -// @SubCommand("ssworld") -// @Description("搜索存档") -// suspend fun UserCommandSender.searchWorlds(filter: String) { -// MinecraftService.search(this, MinecraftService.SECTION_ID_WORLDS, filter) -// } - - @SubCommand("id") - @Description("根据id查找") - suspend fun UserCommandSender.getAddonById(projectId: Int) { - MinecraftService.searchAddonByProjectId(this, projectId) - } -} \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/MessageHandler.kt b/src/main/kotlin/me/jie65535/jcf/MessageHandler.kt deleted file mode 100644 index 26b4981..0000000 --- a/src/main/kotlin/me/jie65535/jcf/MessageHandler.kt +++ /dev/null @@ -1,93 +0,0 @@ -package me.jie65535.jcf - -import me.jie65535.jcf.model.addon.Addon -import me.jie65535.jcf.model.addon.file.AddonFile -import me.jie65535.jcf.util.HttpUtil -import net.mamoe.mirai.contact.Contact -import net.mamoe.mirai.message.data.* -import net.mamoe.mirai.utils.ExternalResource.Companion.toExternalResource -import java.text.DecimalFormat -import kotlin.math.min - -object MessageHandler { - - fun parseSearchResult(addons: List, builder: ForwardMessageBuilder, contact: Contact) { - for ((index, addon) in addons.withIndex()) { - builder.add(contact.bot.id, index.toString(), - PlainText(""" - $index | [${addon.name}] by ${addon.authors[0].name} - ${formatCount(addon.downloadCount)} Downloads Updated ${addon.dateModified.toLocalDate()} - ${addon.summary} - ${addon.websiteUrl} - """.trimIndent())) - } - } - - @Suppress("BlockingMethodInNonBlockingContext") - suspend fun parseAddon(addon: Addon, contact: Contact): ForwardMessageBuilder { - val builder = ForwardMessageBuilder(contact) - .add(contact.bot, loadImage(addon.attachments.find{ it.isDefault }!!.thumbnailUrl, contact)) - .add(contact.bot, PlainText(""" - ${addon.name} - 作者:${addon.authors[0].name} - 概括:${addon.summary} - 项目ID:${addon.id} - 创建时间:${addon.dateCreated.toLocalDate()} - 最近更新:${addon.dateModified.toLocalDate()} - 总下载:${addon.downloadCount.toLong()} - 主页:${addon.websiteUrl} - """.trimIndent())) - if (addon.latestFiles.isNotEmpty()) { - builder.add(contact.bot, PlainText("最新文件列表:")) - parseAddonFiles(addon.latestFiles, builder, contact) - } -// JCurseforge.logger.info(addon.latestFiles.toString()) -// JCurseforge.logger.info(addon.gameVersionLatestFiles.toString()) - return builder - } - - fun parseAddonFiles(addonFiles: Collection, builder: ForwardMessageBuilder, contact: Contact) { - for ((index, file) in addonFiles.withIndex()) { - builder.add(contact.bot.id, index.toString(), PlainText(""" - $index | ${file.displayName} [${file.releaseType}] [${file.fileDate.toLocalDate()}] - ${file.downloadUrl} - """.trimIndent())) - // 暂时只允许构造21项 - if (index >= 20) - break - } - } - - private const val ONE_GRP_SIZE = 5000 - private const val ONE_MSG_SIZE = 500 - suspend fun sendLargeMessage(contact: Contact, message: String) { - for (g in message.indices step ONE_GRP_SIZE) { - val builder = ForwardMessageBuilder(contact) - for (i in g until g + min(ONE_GRP_SIZE, message.length-g) step ONE_MSG_SIZE) { - builder.add(contact.bot, PlainText(message.subSequence(i, i+(min(ONE_MSG_SIZE, message.length-i))))) - } - contact.sendMessage(builder.build()) - } - } - - private val singleDecimalFormat = DecimalFormat("0.#") - private fun formatCount(count: Double): String = when { - count < 1000000 -> singleDecimalFormat.format(count / 1000) + "K" - count < 1000000000 -> singleDecimalFormat.format(count / 1000000) + "M" - else -> count.toString() - } - - @Suppress("BlockingMethodInNonBlockingContext") - private suspend fun loadImage(url: String, contact: Contact): Image { - val imgFileName = url.substringAfterLast("/") - val file = JCurseforge.resolveDataFile("cache/$imgFileName") - val res = if (file.exists()) { - file.readBytes().toExternalResource() - } else { - HttpUtil.downloadImage(url, file).toExternalResource() - } - val image = contact.uploadImage(res) - res.close() - return image - } -} \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/MinecraftService.kt b/src/main/kotlin/me/jie65535/jcf/MinecraftService.kt deleted file mode 100644 index 650ef8e..0000000 --- a/src/main/kotlin/me/jie65535/jcf/MinecraftService.kt +++ /dev/null @@ -1,180 +0,0 @@ -package me.jie65535.jcf - -import io.ktor.client.features.* -import io.ktor.http.* -import kotlinx.coroutines.TimeoutCancellationException -import me.jie65535.jcf.model.addon.Addon -import me.jie65535.jcf.model.addon.AddonSortMethod -import me.jie65535.jcf.model.addon.file.AddonFile -import net.mamoe.mirai.console.command.UserCommandSender -import net.mamoe.mirai.event.events.MessageEvent -import net.mamoe.mirai.event.nextEventAsync -import net.mamoe.mirai.message.data.ForwardMessageBuilder -import net.mamoe.mirai.message.data.PlainText -import net.mamoe.mirai.message.data.content -import net.mamoe.mirai.utils.MiraiExperimentalApi -import java.lang.Exception -import java.util.regex.Pattern - -@OptIn(MiraiExperimentalApi::class) -object MinecraftService { - private val curseClient = CurseClient - - private const val GAME_ID_MINECRAFT = 432 - const val SECTION_ID_MODES = 6 - const val SECTION_ID_RESOURCE_PACKS = 12 - const val SECTION_ID_WORLDS = 17 - const val SECTION_ID_MODE_PACKS = 4471 - const val ALL = -1 - - private const val WAIT_REPLY_TIMEOUT_MS = 60000L - private const val PAGE_SIZE = 10 - private const val NEXT_PAGE_KEYWORD = "n" - private const val SHOW_FILES_KEYWORD = "files" - - suspend fun search(sender: UserCommandSender, sectionId: Int, filter: String) { - val addon: Addon - var pageIndex = 0 - while (true) { - val searchResult = doSearch(sectionId, filter, pageIndex++, PAGE_SIZE) - val hasNextPage = searchResult.size == PAGE_SIZE - - if (searchResult.isEmpty()) { - sender.sendMessage("未搜索到结果,请更换关键字重试。") - return - } else if (searchResult.size == 1) { - addon = searchResult[0] - break - } - - val builder = ForwardMessageBuilder(sender.subject) - builder.add(sender.bot, PlainText("${WAIT_REPLY_TIMEOUT_MS/1000}秒内回复编号查看")) - MessageHandler.parseSearchResult(searchResult, builder, sender.subject) - if (hasNextPage) builder.add(sender.bot, PlainText("回复[$NEXT_PAGE_KEYWORD]下一页")) - sender.sendMessage(builder.build()) - - try { - val nextEvent = sender.nextEventAsync( - WAIT_REPLY_TIMEOUT_MS, - coroutineContext = sender.coroutineContext - ) { it.sender == sender.user } .await() - if (hasNextPage && nextEvent.message.contentEquals(NEXT_PAGE_KEYWORD, true)) - continue - addon = searchResult[nextEvent.message.content.toInt()] - break - } catch (e: TimeoutCancellationException) { - sender.sendMessage("等待回复超时,请重新查询。") - } catch (e: NumberFormatException) { - sender.sendMessage("请正确回复序号,此次查询已取消,请重新查询。") - } catch (e: IndexOutOfBoundsException) { - sender.sendMessage("请回复正确的序号,此次查询已取消,请重新查询。") - } catch (e: Exception) { - sender.sendMessage("内部发生异常,此次查询已取消,请重新查询。") - throw e - } - return - } - - // addon handle - showAddon(sender, addon) - } - - /** - * 根据项目ID搜索资源 - */ - suspend fun searchAddonByProjectId(sender: UserCommandSender, projectId: Int) { - try { - val addon = curseClient.getAddon(projectId) - - showAddon(sender, addon) - } catch (e: ClientRequestException) { - if (e.response.status == HttpStatusCode.NotFound) { - sender.sendMessage("未搜索到指定项目ID的资源,请使用正确的项目ID") - } else { - sender.sendMessage("请求异常,错误代码:" + e.response.status) - throw e - } - } catch (e: Throwable) { - sender.sendMessage("内部发生异常,此次查询已取消,请重新查询。") - throw e - } - } - - private suspend fun showAddon(sender: UserCommandSender, addon: Addon) { - val builder = MessageHandler.parseAddon(addon, sender.subject) - if (addon.latestFiles.isNotEmpty()) - builder.add(sender.bot, PlainText("${WAIT_REPLY_TIMEOUT_MS/1000}秒内回复[${SHOW_FILES_KEYWORD}]查看所有文件,回复文件序号查看更新日志")) - sender.sendMessage(builder.build()) - - try { - val nextEvent = sender.nextEventAsync( - WAIT_REPLY_TIMEOUT_MS, - coroutineContext = sender.coroutineContext - ) { it.sender == sender.user } .await() - if (nextEvent.message.contentEquals(SHOW_FILES_KEYWORD, true)) { - showAllFiles(sender, addon) - } else { - val file = addon.latestFiles[nextEvent.message.content.toInt()] - showChangedLog(sender, addon.id, file) - } - } catch (e: TimeoutCancellationException) { - sender.sendMessage("等待回复超时,请重新查询。") - } catch (e: NumberFormatException) { - sender.sendMessage("请正确回复序号,此次查询已取消,请重新查询。") - } catch (e: IndexOutOfBoundsException) { - sender.sendMessage("请回复正确的序号,此次查询已取消,请重新查询。") - } catch (e: Exception) { - sender.sendMessage("内部发生异常,此次查询已取消,请重新查询。") - throw e - } - } - - private suspend fun showAllFiles(sender: UserCommandSender, addon: Addon) { - val files = CurseClient.getAddonFiles(addon.id).sortedByDescending { f -> f.fileDate } - if (files.isEmpty()) { - sender.sendMessage("没有任何文件 :(") - return - } - val builder = ForwardMessageBuilder(sender.subject) - builder.add(sender.bot, PlainText("${WAIT_REPLY_TIMEOUT_MS/1000}秒内回复文件序号查看更新日志")) - MessageHandler.parseAddonFiles(files, builder, sender.subject) - sender.sendMessage(builder.build()) - - try { // cv大法好,回复功能有功夫再封装,先复制粘贴用着 XD - val nextEvent = sender.nextEventAsync( - WAIT_REPLY_TIMEOUT_MS, - coroutineContext = sender.coroutineContext - ) { it.sender == sender.user } .await() - val file = files[nextEvent.message.content.toInt()] - showChangedLog(sender, addon.id, file) - } catch (e: TimeoutCancellationException) { - sender.sendMessage("等待回复超时,请重新查询。") - } catch (e: NumberFormatException) { - sender.sendMessage("请正确回复序号,此次查询已取消,请重新查询。") - } catch (e: IndexOutOfBoundsException) { - sender.sendMessage("请回复正确的序号,此次查询已取消,请重新查询。") - } - } - - private val HTMLPattern = Pattern.compile("<[^>]+>", Pattern.CASE_INSENSITIVE) - private suspend fun showChangedLog(sender: UserCommandSender, addonId: Int, addonFile: AddonFile) { - val changeLogHTML = curseClient.getAddonFileChangeLog(addonId, addonFile.id) - val changeLog = HTMLPattern.matcher(changeLogHTML).replaceAll("") - MessageHandler.sendLargeMessage(sender.subject, changeLog) - } - - private suspend fun doSearch(sectionId: Int, filter: String, pageIndex: Int, pageSize: Int): List { - return curseClient.searchAddons( - gameId = GAME_ID_MINECRAFT, - sectionId = sectionId, - categoryId = -1, - sort = AddonSortMethod.POPULARITY, - sortDescending = true, - gameVersion = null, - index = pageIndex * pageSize, - pageSize = pageSize, - searchFilter = filter, - ) - } - -} \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/addon/Addon.kt b/src/main/kotlin/me/jie65535/jcf/model/addon/Addon.kt deleted file mode 100644 index ecfd19a..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/addon/Addon.kt +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.addon - -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable -import me.jie65535.jcf.model.addon.file.AddonFile -import me.jie65535.jcf.model.addon.file.AddonFileLatestForGameVersion -import me.jie65535.jcf.model.category.CategorySection -import me.jie65535.jcf.util.Date -import me.jie65535.jcf.util.internal.DateSerializer - -@Serializable -data class Addon( - val id: Int, - val name: String, - val authors: List, - val attachments: List, - val websiteUrl: String, - val gameId: Int, - val summary: String, - val defaultFileId: Int, - val downloadCount: Double, - val latestFiles: List, - val categories: List, - val status: AddonStatus, - val primaryCategoryId: Int, - val categorySection: CategorySection, - val slug: String, - val gameVersionLatestFiles: List, - val isFeatured: Boolean, - val popularityScore: Double, - val gamePopularityRank: Int, - val primaryLanguage: String, - val gameSlug: String, - val gameName: String, - val portalName: String, - @Serializable(with = DateSerializer::class) - val dateModified: Date, - @Serializable(with = DateSerializer::class) - val dateCreated: Date, - @Serializable(with = DateSerializer::class) - val dateReleased: Date, - val isAvailable: Boolean, - @SerialName("isExperiemental") - val isExperimental: Boolean -) \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/addon/AddonAttachment.kt b/src/main/kotlin/me/jie65535/jcf/model/addon/AddonAttachment.kt deleted file mode 100644 index 9606ec9..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/addon/AddonAttachment.kt +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.addon - -import kotlinx.serialization.Serializable - -@Serializable -data class AddonAttachment( - val id: Int, - val projectId: Int, - val description: String, - val isDefault: Boolean, - val thumbnailUrl: String, - val title: String, - val url: String, - val status: AddonAttachmentStatus -) \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/addon/AddonAttachmentStatus.kt b/src/main/kotlin/me/jie65535/jcf/model/addon/AddonAttachmentStatus.kt deleted file mode 100644 index 2a0e5e6..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/addon/AddonAttachmentStatus.kt +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.addon - -import kotlinx.serialization.Serializable -import me.jie65535.jcf.util.internal.EnumIntSerializer -import me.jie65535.jcf.util.internal.MODEL_PACKAGE - - -@Serializable(with = AddonAttachmentStatus.Ser::class) -enum class AddonAttachmentStatus { - NORMAL, - DELETED, - UPLOADING, - BANNED, - PENDING_MODERATION; - - internal object Ser : EnumIntSerializer("$MODEL_PACKAGE.addon.AttachmentStatus", values()) -} \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/addon/AddonAuthor.kt b/src/main/kotlin/me/jie65535/jcf/model/addon/AddonAuthor.kt deleted file mode 100644 index 32ec933..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/addon/AddonAuthor.kt +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.addon - -import kotlinx.serialization.Serializable - -@Serializable -data class AddonAuthor( - val name: String, - val url: String, - val projectId: Int, - val id: Int, - val projectTitleId: Int?, - val projectTitleTitle: String?, - val userId: Int, - val twitchId: Int? -) \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/addon/AddonCategory.kt b/src/main/kotlin/me/jie65535/jcf/model/addon/AddonCategory.kt deleted file mode 100644 index 4f3ea12..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/addon/AddonCategory.kt +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.addon - -import kotlinx.serialization.Serializable - -@Serializable -data class AddonCategory( - val categoryId: Int, - val name: String, - val url: String, - val avatarUrl: String?, - val parentId: Int?, - val rootId: Int?, - val projectId: Int, - val avatarId: Int?, - val gameId: Int -) \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/addon/AddonPackageType.kt b/src/main/kotlin/me/jie65535/jcf/model/addon/AddonPackageType.kt deleted file mode 100644 index 9f510cb..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/addon/AddonPackageType.kt +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.addon - -import kotlinx.serialization.Serializable -import me.jie65535.jcf.util.internal.EnumIntSerializer -import me.jie65535.jcf.util.internal.MODEL_PACKAGE - -@Serializable(with = AddonPackageType.Ser::class) -enum class AddonPackageType { - FOLDER, - CTOC, - SINGLE_FILE, - CMOD2, - MOD_PACK, - MOD; - - internal object Ser : EnumIntSerializer("$MODEL_PACKAGE.addon.AddonPackageType", values()) -} \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/addon/AddonRepositoryMatch.kt b/src/main/kotlin/me/jie65535/jcf/model/addon/AddonRepositoryMatch.kt deleted file mode 100644 index c7b3c86..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/addon/AddonRepositoryMatch.kt +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.addon - -import kotlinx.serialization.Serializable -import me.jie65535.jcf.model.addon.file.AddonFile - -@Serializable -data class AddonRepositoryMatch( - val id: Int, - val latestFiles: List -) \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/addon/AddonRestrictFileAccess.kt b/src/main/kotlin/me/jie65535/jcf/model/addon/AddonRestrictFileAccess.kt deleted file mode 100644 index eff9052..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/addon/AddonRestrictFileAccess.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.addon - -import kotlinx.serialization.Serializable -import me.jie65535.jcf.util.internal.EnumIntSerializer -import me.jie65535.jcf.util.internal.MODEL_PACKAGE - -@Serializable(with = AddonRestrictFileAccess.Ser::class) -enum class AddonRestrictFileAccess { - NONE, - ALPHA, - ALPHA_AND_BETA; - - internal object Ser : EnumIntSerializer("$MODEL_PACKAGE.addon.AddonRestrictFileAccess", values()) -} \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/addon/AddonSortMethod.kt b/src/main/kotlin/me/jie65535/jcf/model/addon/AddonSortMethod.kt deleted file mode 100644 index edc24b9..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/addon/AddonSortMethod.kt +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.addon - -/** - * 附加排序方法 - */ -enum class AddonSortMethod { - /** - * 精选 - */ - FEATURED, - - /** - * 人气 - */ - POPULARITY, - - /** - * 最后更新时间 - */ - LAST_UPDATED, - - /** - * 名称 - */ - NAME, - - /** - * 作者 - */ - AUTHOR, - - /** - * 总下载数 - */ - TOTAL_DOWNLOADS, - - /** - * 类别 - */ - CATEGORY, - - /** - * 游戏版本 - */ - GAME_VERSION -} \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/addon/AddonStatus.kt b/src/main/kotlin/me/jie65535/jcf/model/addon/AddonStatus.kt deleted file mode 100644 index 1cd52dc..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/addon/AddonStatus.kt +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.addon - -import kotlinx.serialization.Serializable -import me.jie65535.jcf.util.internal.EnumIntSerializer -import me.jie65535.jcf.util.internal.MODEL_PACKAGE - -@Serializable(with = AddonStatus.Ser::class) -enum class AddonStatus { - NEW, - CHANGES_REQUIRED, - UNDER_SOFT_REVIEW, - APPROVED, - REJECTED, - CHANGES_MADE, - INACTIVE, - ABANDONED, - DELETED, - UNDER_REVIEW; - - internal object Ser : EnumIntSerializer("$MODEL_PACKAGE.addon.AddonStatus", values()) -} \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/addon/FeaturedAddonType.kt b/src/main/kotlin/me/jie65535/jcf/model/addon/FeaturedAddonType.kt deleted file mode 100644 index 4db1fcf..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/addon/FeaturedAddonType.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.addon - -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable - -@Serializable -enum class FeaturedAddonType { - @SerialName("Featured") - FEATURED, - @SerialName("Popular") - POPULAR, - @SerialName("RecentlyUpdated") - RECENTLY_UPDATED; -} \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/addon/SortableGameVersion.kt b/src/main/kotlin/me/jie65535/jcf/model/addon/SortableGameVersion.kt deleted file mode 100644 index 7978fc6..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/addon/SortableGameVersion.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.addon - -import kotlinx.serialization.Serializable -import me.jie65535.jcf.util.Date -import me.jie65535.jcf.util.internal.DateSerializer - -@Serializable -data class SortableGameVersion( - val gameVersionPadded: String, - val gameVersion: String, - @Serializable(with = DateSerializer::class) - val gameVersionReleaseDate: Date, - val gameVersionName: String -) \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/addon/file/AddonFile.kt b/src/main/kotlin/me/jie65535/jcf/model/addon/file/AddonFile.kt deleted file mode 100644 index 8d16c88..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/addon/file/AddonFile.kt +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.addon.file - -import kotlinx.serialization.Serializable -import me.jie65535.jcf.model.addon.AddonPackageType -import me.jie65535.jcf.model.addon.AddonRestrictFileAccess -import me.jie65535.jcf.model.addon.AddonStatus -import me.jie65535.jcf.model.addon.SortableGameVersion -import me.jie65535.jcf.util.Date -import me.jie65535.jcf.util.internal.DateSerializer - -@Serializable -data class AddonFile( - val id: Int, - val displayName: String, - val fileName: String, - @Serializable(with = DateSerializer::class) - val fileDate: Date, - val fileLength: Long, - val releaseType: AddonFileReleaseType, - val fileStatus: AddonFileStatus, - val downloadUrl: String, - val isAlternate: Boolean, - val alternateFileId: Int, - val dependencies: List, - val isAvailable: Boolean, - val modules: List, - val packageFingerprint: Long, - val gameVersion: List, - val sortableGameVersion: List? = null, - val installMetadata: String?, - val changelog: String? = null, - val hasInstallScript: Boolean, - val isCompatibleWithClient: Boolean? = null, - val categorySectionPackageType: AddonPackageType? = null, - val restrictProjectFileAccess: AddonRestrictFileAccess? = null, - val projectStatus: AddonStatus? = null, - val renderCacheId: Int? = null, - val fileLegacyMappingId: Int? = null, - val projectId: Int? = null, - val parentProjectFileId: Int? = null, - val parentFileLegacyMappingId: Int? = null, - val fileTypeId: Int? = null, - val exposeAsAlternative: Boolean? = null, - val packageFingerprintId: Int? = null, - @Serializable(with = DateSerializer::class) - val gameVersionDateReleased: Date?, - val gameVersionMappingId: Int? = null, - val gameVersionId: Int? = null, - val gameId: Int? = null, - val isServerPack: Boolean = false, - val serverPackFileId: Int?, - val gameVersionFlavor: String? -) \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/addon/file/AddonFileDependency.kt b/src/main/kotlin/me/jie65535/jcf/model/addon/file/AddonFileDependency.kt deleted file mode 100644 index e5b1751..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/addon/file/AddonFileDependency.kt +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.addon.file - -import kotlinx.serialization.Serializable - -@Serializable -data class AddonFileDependency( - val id: Int? = null, - val addonId: Int, - val type: AddonFileRelationType, - val fileId: Int? = null -) \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/addon/file/AddonFileFingerprintType.kt b/src/main/kotlin/me/jie65535/jcf/model/addon/file/AddonFileFingerprintType.kt deleted file mode 100644 index 391c18a..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/addon/file/AddonFileFingerprintType.kt +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.addon.file - -import kotlinx.serialization.Serializable -import me.jie65535.jcf.util.internal.EnumIntSerializer -import me.jie65535.jcf.util.internal.MODEL_PACKAGE - -@Serializable(with = AddonFileFingerprintType.Ser::class) -enum class AddonFileFingerprintType { - PACKAGE, - MODULE, - MAIN_MODULE, - FILE, - REFERRENCED_FILE; - - internal object Ser : EnumIntSerializer("$MODEL_PACKAGE.addon.file.AddonFileFingerprintType", values()) -} \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/addon/file/AddonFileLatestForGameVersion.kt b/src/main/kotlin/me/jie65535/jcf/model/addon/file/AddonFileLatestForGameVersion.kt deleted file mode 100644 index 14b2d3b..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/addon/file/AddonFileLatestForGameVersion.kt +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.addon.file - -import kotlinx.serialization.Serializable - -@Serializable -data class AddonFileLatestForGameVersion( - val gameVersion: String, - val projectFileId: Int, - val projectFileName: String, - val fileType: AddonFileReleaseType, - val gameVersionFlavor: String? -) \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/addon/file/AddonFileModule.kt b/src/main/kotlin/me/jie65535/jcf/model/addon/file/AddonFileModule.kt deleted file mode 100644 index 5a2f650..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/addon/file/AddonFileModule.kt +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.addon.file - -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable - -@Serializable -data class AddonFileModule( - @SerialName("foldername") - val folderName: String, - val fingerprint: Long, - val type: AddonFileFingerprintType? = null -) \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/addon/file/AddonFileRelationType.kt b/src/main/kotlin/me/jie65535/jcf/model/addon/file/AddonFileRelationType.kt deleted file mode 100644 index ef0cdc2..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/addon/file/AddonFileRelationType.kt +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.addon.file - -import kotlinx.serialization.Serializable -import me.jie65535.jcf.util.internal.EnumIntSerializer -import me.jie65535.jcf.util.internal.MODEL_PACKAGE - -@Serializable(with = AddonFileRelationType.Ser::class) -enum class AddonFileRelationType { - EMBEDDED_LIBRARY, - OPTIONAL_DEPENDENCY, - REQUIRED_DEPENDENCY, - TOOL, - INCOMPATIBLE, - INCLUDE; - - internal object Ser : EnumIntSerializer("$MODEL_PACKAGE.addon.file.AddonFileRelationType", values()) -} \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/addon/file/AddonFileReleaseType.kt b/src/main/kotlin/me/jie65535/jcf/model/addon/file/AddonFileReleaseType.kt deleted file mode 100644 index 672f61c..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/addon/file/AddonFileReleaseType.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.addon.file - -import kotlinx.serialization.Serializable -import me.jie65535.jcf.util.internal.EnumIntSerializer -import me.jie65535.jcf.util.internal.MODEL_PACKAGE - -@Serializable(with = AddonFileReleaseType.Ser::class) -enum class AddonFileReleaseType { - RELEASE, - BETA, - ALPHA; - - internal object Ser : EnumIntSerializer("$MODEL_PACKAGE.addon.file.AddonFileReleaseType", values()) -} \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/addon/file/AddonFileStatus.kt b/src/main/kotlin/me/jie65535/jcf/model/addon/file/AddonFileStatus.kt deleted file mode 100644 index 7f5e5a8..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/addon/file/AddonFileStatus.kt +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.addon.file - -import kotlinx.serialization.Serializable -import me.jie65535.jcf.util.internal.EnumIntSerializer -import me.jie65535.jcf.util.internal.MODEL_PACKAGE - -@Serializable(with = AddonFileStatus.Ser::class) -enum class AddonFileStatus { - PROCESSING, - CHANGES_REQUIRED, - UNDER_REVIEW, - APPROVED, - REJECTED, - MALWARE_DETECTED, - DELETED, - ARCHIVED, - TESTING, - RELEASED, - READY_FOR_REVIEW, - DEPRECATED, - BAKING, - AWAITING_FOR_PUBLISHING, - FAILED_PUBLISHING; - - internal object Ser : EnumIntSerializer("$MODEL_PACKAGE.addon.file.AddonFileStatus", values()) -} \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/addon/request/FeaturedAddonsRequest.kt b/src/main/kotlin/me/jie65535/jcf/model/addon/request/FeaturedAddonsRequest.kt deleted file mode 100644 index 3d5d2d9..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/addon/request/FeaturedAddonsRequest.kt +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ -package me.jie65535.jcf.model.addon.request - -import kotlinx.serialization.Serializable - -@Serializable -data class FeaturedAddonsRequest( - val gameId: Int, - val featuredCount: Int, - val popularCount: Int, - val updatedCount: Int, - val excludedAddons: Collection -) \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/category/Category.kt b/src/main/kotlin/me/jie65535/jcf/model/category/Category.kt deleted file mode 100644 index 6bb3523..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/category/Category.kt +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.category - -import kotlinx.serialization.Serializable -import me.jie65535.jcf.util.Date -import me.jie65535.jcf.util.internal.DateSerializer - -@Serializable -data class Category( - val id: Int, - val name: String, - val slug: String, - val avatarUrl: String?, - @Serializable(with = DateSerializer::class) - val dateModified: Date, - val parentGameCategoryId: Int?, - val rootGameCategoryId: Int?, - val gameId: Int -) \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/category/CategorySection.kt b/src/main/kotlin/me/jie65535/jcf/model/category/CategorySection.kt deleted file mode 100644 index ea71732..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/category/CategorySection.kt +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.category - -import kotlinx.serialization.Serializable -import me.jie65535.jcf.model.addon.AddonPackageType - -@Serializable -data class CategorySection( - val extraIncludePattern: String?, - val gameCategoryId: Int, - val gameId: Int, - val id: Int, - val initialInclusionPattern: String, - val name: String, - val packageType: AddonPackageType, - val path: String -) \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/fingerprint/FingerprintMatch.kt b/src/main/kotlin/me/jie65535/jcf/model/fingerprint/FingerprintMatch.kt deleted file mode 100644 index d594d6a..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/fingerprint/FingerprintMatch.kt +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.fingerprint - -import kotlinx.serialization.Serializable -import me.jie65535.jcf.model.addon.file.AddonFile - -@Serializable -data class FingerprintMatch( - val id: Int, - val file: AddonFile, - val latestFiles: List -) \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/fingerprint/FingerprintMatchResult.kt b/src/main/kotlin/me/jie65535/jcf/model/fingerprint/FingerprintMatchResult.kt deleted file mode 100644 index 600bf81..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/fingerprint/FingerprintMatchResult.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.fingerprint - -import kotlinx.serialization.Serializable - -@Serializable -data class FingerprintMatchResult( - val isCacheBuilt: Boolean, - val exactMatches: List, - val exactFingerprints: List, - val partialMatches: List, - val partialMatchFingerprints: Map>, - val installedFingerprints: List, - val unmatchedFingerprints: List -) \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/fingerprint/FolderFingerprint.kt b/src/main/kotlin/me/jie65535/jcf/model/fingerprint/FolderFingerprint.kt deleted file mode 100644 index 8950f12..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/fingerprint/FolderFingerprint.kt +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.fingerprint - -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable - -@Serializable -data class FolderFingerprint( - @SerialName("foldername") - val folderName: String, - val fingerprints: List -) \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/fingerprint/FuzzyFingerprintMatch.kt b/src/main/kotlin/me/jie65535/jcf/model/fingerprint/FuzzyFingerprintMatch.kt deleted file mode 100644 index cb08808..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/fingerprint/FuzzyFingerprintMatch.kt +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.fingerprint - -import kotlinx.serialization.Serializable -import me.jie65535.jcf.model.addon.file.AddonFile - -@Serializable -data class FuzzyFingerprintMatch( - val id: Int, - val file: AddonFile, - val latestFiles: List, - val fingerprints: List -) \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/fingerprint/request/FuzzyMatchesRequest.kt b/src/main/kotlin/me/jie65535/jcf/model/fingerprint/request/FuzzyMatchesRequest.kt deleted file mode 100644 index 0832a35..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/fingerprint/request/FuzzyMatchesRequest.kt +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.fingerprint.request - -import kotlinx.serialization.Serializable -import me.jie65535.jcf.model.fingerprint.FolderFingerprint - -@Serializable -data class FuzzyMatchesRequest( - val gameId: Int, - val fingerprints: List -) \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/game/Game.kt b/src/main/kotlin/me/jie65535/jcf/model/game/Game.kt deleted file mode 100644 index e34be44..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/game/Game.kt +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.game - -import kotlinx.serialization.Serializable -import me.jie65535.jcf.model.category.CategorySection -import me.jie65535.jcf.util.Date -import me.jie65535.jcf.util.internal.DateSerializer - -@Serializable -data class Game( - val id: Int, - val name: String, - val slug: String, - @Serializable(with = DateSerializer::class) - val dateModified: Date, - val gameFiles: List, - val gameDetectionHints: List, - val fileParsingRules: List, - val categorySections: List, - val maxFreeStorage: Long, - val maxPremiumStorage: Long, - val maxFileSize: Long, - val addonSettingsFolderFilter: String?, - val addonSettingsStartingFolder: String?, - val addonSettingsFileFilter: String?, - val addonSettingsFileRemovalFilter: String?, - val supportsAddons: Boolean, - val supportsPartnerAddons: Boolean, - @Serializable(with = SupportedClientConfiguration.Ser::class) - val supportedClientConfiguration: Set, - val supportsNotifications: Boolean, - val profilerAddonId: Int, - val twitchGameId: Int, - val clientGameSettingsId: Int -) \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/game/GameDetectionHint.kt b/src/main/kotlin/me/jie65535/jcf/model/game/GameDetectionHint.kt deleted file mode 100644 index ef7b284..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/game/GameDetectionHint.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.game - -import kotlinx.serialization.Serializable - -@Serializable -data class GameDetectionHint( - val id: Int, - val hintType: GameDetectionHintType, - val hintPath: String, - val hintKey: String?, - @Serializable(with = GameDetectionHintOption.Ser::class) - val hintOptions: Set, - val gameId: Int -) \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/game/GameDetectionHintOption.kt b/src/main/kotlin/me/jie65535/jcf/model/game/GameDetectionHintOption.kt deleted file mode 100644 index 9b12174..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/game/GameDetectionHintOption.kt +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.game - -import me.jie65535.jcf.util.internal.FlagSerializer -import me.jie65535.jcf.util.internal.MODEL_PACKAGE - -enum class GameDetectionHintOption { - NONE, - INCLUDE_SUB_FOLDERS, - FOLDER_ONLY; - - internal object Ser : FlagSerializer("$MODEL_PACKAGE.game.GameDetectionHintOption", NONE to 0x1, INCLUDE_SUB_FOLDERS to 0x2, FOLDER_ONLY to 0x4) -} \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/game/GameDetectionHintType.kt b/src/main/kotlin/me/jie65535/jcf/model/game/GameDetectionHintType.kt deleted file mode 100644 index 0f3b641..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/game/GameDetectionHintType.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - - -package me.jie65535.jcf.model.game - -import kotlinx.serialization.Serializable -import me.jie65535.jcf.util.internal.EnumIntSerializer -import me.jie65535.jcf.util.internal.MODEL_PACKAGE - -@Serializable(with = GameDetectionHintType.Ser::class) -enum class GameDetectionHintType { - REGISTRY, - FILE_PATH; - - internal object Ser : EnumIntSerializer("$MODEL_PACKAGE.game.GameDetectionHintType", values()) -} \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/game/GameFile.kt b/src/main/kotlin/me/jie65535/jcf/model/game/GameFile.kt deleted file mode 100644 index 8227241..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/game/GameFile.kt +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.game - -import kotlinx.serialization.Serializable - -@Serializable -data class GameFile( - val id: Int, - val gameId: Int, - val isRequired: Boolean, - val fileName: String, - val fileType: GameFileType, - val platformType: GamePlatformType -) \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/game/GameFileParsingRule.kt b/src/main/kotlin/me/jie65535/jcf/model/game/GameFileParsingRule.kt deleted file mode 100644 index 0ade2fb..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/game/GameFileParsingRule.kt +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.game - -import kotlinx.serialization.Serializable - -@Serializable -data class GameFileParsingRule( - val commentStripPattern: String, - val fileExtension: String, - val inclusionPattern: String, - val gameId: Int, - val id: Int -) \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/game/GameFileType.kt b/src/main/kotlin/me/jie65535/jcf/model/game/GameFileType.kt deleted file mode 100644 index b4c3c70..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/game/GameFileType.kt +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.game - -import kotlinx.serialization.Serializable -import me.jie65535.jcf.util.internal.EnumIntSerializer -import me.jie65535.jcf.util.internal.MODEL_PACKAGE - -@Serializable(with = GameFileType.Ser::class) -enum class GameFileType { - GENERIC, - GAME, - LAUNCHER, - PROFILER_LOCK_CHECK; - - internal object Ser : EnumIntSerializer("$MODEL_PACKAGE.game.GameFileType", values()) -} \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/game/GamePlatformType.kt b/src/main/kotlin/me/jie65535/jcf/model/game/GamePlatformType.kt deleted file mode 100644 index 467ef61..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/game/GamePlatformType.kt +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.game - -import kotlinx.serialization.Serializable -import me.jie65535.jcf.util.internal.EnumIntSerializer -import me.jie65535.jcf.util.internal.MODEL_PACKAGE - -@Serializable(with = GamePlatformType.Ser::class) -enum class GamePlatformType { - GENERIC, - WINDOWS_32, - WINDOWS_64, - WINDOWS, - OSX; - - internal object Ser : EnumIntSerializer("$MODEL_PACKAGE.game.GamePlatformType", values()) -} \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/game/SupportedClientConfiguration.kt b/src/main/kotlin/me/jie65535/jcf/model/game/SupportedClientConfiguration.kt deleted file mode 100644 index 80ad84d..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/game/SupportedClientConfiguration.kt +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.game - -import me.jie65535.jcf.util.internal.FlagSerializer -import me.jie65535.jcf.util.internal.MODEL_PACKAGE - -enum class SupportedClientConfiguration { - DEBUG, - BETA, - RELEASE; - - internal object Ser : FlagSerializer("$MODEL_PACKAGE.game.SupportedClientConfiguration", DEBUG to 0x1, BETA to 0x2, RELEASE to 0x4) -} \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/minecraft/MinecraftVersion.kt b/src/main/kotlin/me/jie65535/jcf/model/minecraft/MinecraftVersion.kt deleted file mode 100644 index f8a3223..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/minecraft/MinecraftVersion.kt +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.minecraft - -import kotlinx.serialization.Serializable -import me.jie65535.jcf.util.Date -import me.jie65535.jcf.util.internal.DateSerializer - -@Serializable -data class MinecraftVersion( - val id: Int, - val gameVersionId: Int, - val versionString: String, - val jarDownloadUrl: String, - val jsonDownloadUrl: String, - val approved: Boolean, - @Serializable(with = DateSerializer::class) - val dateModified: Date, - val gameVersionTypeId: Int, - val gameVersionStatus: MinecraftVersionStatus, - val gameVersionTypeStatus: MinecraftVersionTypeStatus -) \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/minecraft/MinecraftVersionStatus.kt b/src/main/kotlin/me/jie65535/jcf/model/minecraft/MinecraftVersionStatus.kt deleted file mode 100644 index a910ad4..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/minecraft/MinecraftVersionStatus.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.minecraft - -import kotlinx.serialization.Serializable -import me.jie65535.jcf.util.internal.EnumIntSerializer -import me.jie65535.jcf.util.internal.MODEL_PACKAGE - -@Serializable(with = MinecraftVersionStatus.Ser::class) -enum class MinecraftVersionStatus { - APPROVED, - DELETED, - NEW; - - internal object Ser : EnumIntSerializer("$MODEL_PACKAGE.game.MinecraftVersionStatus", values()) -} \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/minecraft/MinecraftVersionTypeStatus.kt b/src/main/kotlin/me/jie65535/jcf/model/minecraft/MinecraftVersionTypeStatus.kt deleted file mode 100644 index 7db0e27..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/minecraft/MinecraftVersionTypeStatus.kt +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.minecraft - -import kotlinx.serialization.Serializable -import me.jie65535.jcf.util.internal.EnumIntSerializer -import me.jie65535.jcf.util.internal.MODEL_PACKAGE - -@Serializable(with = MinecraftVersionTypeStatus.Ser::class) -enum class MinecraftVersionTypeStatus { - NORMAL, - DELETED; - - internal object Ser : EnumIntSerializer("$MODEL_PACKAGE.game.MinecraftVersionTypeStatus", values()) -} \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/minecraft/modloader/ModloaderIndex.kt b/src/main/kotlin/me/jie65535/jcf/model/minecraft/modloader/ModloaderIndex.kt deleted file mode 100644 index d8b5c73..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/minecraft/modloader/ModloaderIndex.kt +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.minecraft.modloader - -import kotlinx.serialization.Serializable -import me.jie65535.jcf.util.Date -import me.jie65535.jcf.util.internal.DateSerializer - -@Serializable -data class ModloaderIndex( - val name: String, - val gameVersion: String, - val latest: Boolean, - val recommended: Boolean, - @Serializable(with = DateSerializer::class) - val dateModified: Date -) \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/minecraft/modloader/ModloaderInstallMethod.kt b/src/main/kotlin/me/jie65535/jcf/model/minecraft/modloader/ModloaderInstallMethod.kt deleted file mode 100644 index 668b8c0..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/minecraft/modloader/ModloaderInstallMethod.kt +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.minecraft.modloader - -import kotlinx.serialization.Serializable -import me.jie65535.jcf.util.internal.EnumIntSerializer -import me.jie65535.jcf.util.internal.MODEL_PACKAGE - -@Serializable(with = ModloaderInstallMethod.Ser::class) -enum class ModloaderInstallMethod { - ANY, - FORGE, - CAULDRON, - LITE_LOADER; - - internal object Ser : EnumIntSerializer("$MODEL_PACKAGE.game.ModloaderInstallMethod", values()) -} \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/minecraft/modloader/ModloaderType.kt b/src/main/kotlin/me/jie65535/jcf/model/minecraft/modloader/ModloaderType.kt deleted file mode 100644 index 0450fbd..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/minecraft/modloader/ModloaderType.kt +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.minecraft.modloader - -import kotlinx.serialization.Serializable -import me.jie65535.jcf.util.internal.EnumIntSerializer -import me.jie65535.jcf.util.internal.MODEL_PACKAGE - -@Serializable(with = ModloaderType.Ser::class) -enum class ModloaderType { - ANY, - FORGE, - CAULDRON, - LITE_LOADER; - - internal object Ser : EnumIntSerializer("$MODEL_PACKAGE.game.ModloaderType", values(), 0) -} \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/model/minecraft/modloader/ModloaderVersion.kt b/src/main/kotlin/me/jie65535/jcf/model/minecraft/modloader/ModloaderVersion.kt deleted file mode 100644 index 7359b0f..0000000 --- a/src/main/kotlin/me/jie65535/jcf/model/minecraft/modloader/ModloaderVersion.kt +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.model.minecraft.modloader - -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable -import me.jie65535.jcf.model.minecraft.MinecraftVersionStatus -import me.jie65535.jcf.model.minecraft.MinecraftVersionTypeStatus -import me.jie65535.jcf.util.Date -import me.jie65535.jcf.util.internal.DateSerializer - -@Serializable -data class ModloaderVersion( - val id: Int, - val gameVersionId: Int, - val minecraftGameVersionId: Int, - val forgeVersion: String, - val name: String, - val type: ModloaderType, - val downloadUrl: String, - @SerialName("filename") - val fileName: String, - val installMethod: ModloaderInstallMethod, - val latest: Boolean, - val recommended: Boolean, - val approved: Boolean, - @Serializable(with = DateSerializer::class) - val dateModified: Date, - val mavenVersionString: String, - val versionJson: String, - val librariesInstallLocation: String, - val minecraftVersion: String, - val additionalFilesJson: String, - val modLoaderGameVersionId: Int, - val modLoaderGameVersionTypeId: Int, - val modLoaderGameVersionStatus: MinecraftVersionStatus, - val modLoaderGameVersionTypeStatus: MinecraftVersionTypeStatus, - val mcGameVersionId: Int, - val mcGameVersionTypeId: Int, - val mcGameVersionStatus: MinecraftVersionStatus, - val mcGameVersionTypeStatus: MinecraftVersionTypeStatus, - val installProfileJson: String -) \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/util/Date.kt b/src/main/kotlin/me/jie65535/jcf/util/Date.kt deleted file mode 100644 index 040f193..0000000 --- a/src/main/kotlin/me/jie65535/jcf/util/Date.kt +++ /dev/null @@ -1,5 +0,0 @@ -package me.jie65535.jcf.util - -import java.time.OffsetDateTime - -typealias Date = OffsetDateTime \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/util/HttpUtil.kt b/src/main/kotlin/me/jie65535/jcf/util/HttpUtil.kt deleted file mode 100644 index d983cbe..0000000 --- a/src/main/kotlin/me/jie65535/jcf/util/HttpUtil.kt +++ /dev/null @@ -1,29 +0,0 @@ -package me.jie65535.jcf.util - -//import okhttp3.MediaType -//import okhttp3.MediaType.Companion.toMediaTypeOrNull -import okhttp3.OkHttpClient -import okhttp3.Request -import java.io.File -import java.util.concurrent.TimeUnit - -object HttpUtil { -// private val JSON: MediaType? = "application/json; charset=utf-8".toMediaTypeOrNull() - private val okHttpClient: OkHttpClient by lazy { - OkHttpClient.Builder() - .readTimeout(10, TimeUnit.SECONDS) - .build() - } - - /** - * ### 下载图片 - */ - fun downloadImage(url: String, file: File): ByteArray { - val request = Request.Builder().url(url).build() - val imageByte = okHttpClient.newCall(request).execute().body!!.bytes() - val fileParent = file.parentFile - if (!fileParent.exists()) fileParent.mkdirs() - file.writeBytes(imageByte) - return imageByte - } -} \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/util/internal/DateSerializer.kt b/src/main/kotlin/me/jie65535/jcf/util/internal/DateSerializer.kt deleted file mode 100644 index f657ab5..0000000 --- a/src/main/kotlin/me/jie65535/jcf/util/internal/DateSerializer.kt +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.util.internal - -import kotlinx.serialization.* -import kotlinx.serialization.descriptors.* -import kotlinx.serialization.encoding.* -import me.jie65535.jcf.util.Date -import java.time.OffsetDateTime - -internal object DateSerializer : KSerializer { - override val descriptor = PrimitiveSerialDescriptor("Date", PrimitiveKind.STRING) - - override fun deserialize(decoder: Decoder): Date { - return OffsetDateTime.parse(decoder.decodeString()) - } - - override fun serialize(encoder: Encoder, value: Date) { - encoder.encodeString(value.toString()) - } -} \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/util/internal/EnumIntSerializer.kt b/src/main/kotlin/me/jie65535/jcf/util/internal/EnumIntSerializer.kt deleted file mode 100644 index 8f8bfa3..0000000 --- a/src/main/kotlin/me/jie65535/jcf/util/internal/EnumIntSerializer.kt +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.util.internal - -import kotlinx.serialization.* -import kotlinx.serialization.descriptors.* -import kotlinx.serialization.encoding.* - -internal open class EnumIntSerializer(private val serialName: String, private val values: Array, private val startFrom: Int = 1) : KSerializer { - override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor(serialName, PrimitiveKind.INT) - - override fun deserialize(decoder: Decoder): T { - val value = decoder.decodeInt() - return values[value - startFrom] ?: throw NoSuchElementException("Can't find $serialName with key $value") - } - - override fun serialize(encoder: Encoder, value: T) { - encoder.encodeInt(values.indexOf(value) + startFrom) - } -} \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/util/internal/FlagSerializer.kt b/src/main/kotlin/me/jie65535/jcf/util/internal/FlagSerializer.kt deleted file mode 100644 index 4cc0959..0000000 --- a/src/main/kotlin/me/jie65535/jcf/util/internal/FlagSerializer.kt +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright © 2020, PearX Team - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at https://mozilla.org/MPL/2.0/. - */ - -package me.jie65535.jcf.util.internal - -import kotlinx.serialization.* -import kotlinx.serialization.descriptors.* -import kotlinx.serialization.encoding.* - -internal open class FlagSerializer>(serialName: String, private val map: Map) : KSerializer> { - constructor(serialName: String, vararg pairs: Pair) : this(serialName, mapOf(*pairs)) - - override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor(serialName, PrimitiveKind.INT) - - override fun serialize(encoder: Encoder, value: Set) { - var bits = 0 - for(flag in value) { - bits = bits or (map[flag] ?: error("")) - } - encoder.encodeInt(bits) - } - - override fun deserialize(decoder: Decoder): Set { - val set = mutableSetOf() - val bits = decoder.decodeInt() - for((flag, shift) in map) { - if(bits and shift == shift) - set += flag - } - return set - } -} \ No newline at end of file diff --git a/src/main/kotlin/me/jie65535/jcf/util/internal/PackageNames.kt b/src/main/kotlin/me/jie65535/jcf/util/internal/PackageNames.kt deleted file mode 100644 index 97afd57..0000000 --- a/src/main/kotlin/me/jie65535/jcf/util/internal/PackageNames.kt +++ /dev/null @@ -1,3 +0,0 @@ -package me.jie65535.jcf.util.internal - -internal const val MODEL_PACKAGE = "me.jie65535.jcf.model" \ No newline at end of file diff --git a/src/main/kotlin/top/jie65535/jcf/CurseforgeApi.kt b/src/main/kotlin/top/jie65535/jcf/CurseforgeApi.kt index 4d3101d..c420ab2 100644 --- a/src/main/kotlin/top/jie65535/jcf/CurseforgeApi.kt +++ b/src/main/kotlin/top/jie65535/jcf/CurseforgeApi.kt @@ -22,9 +22,6 @@ import top.jie65535.jcf.model.response.* */ @OptIn(ExperimentalSerializationApi::class) class CurseforgeApi(apiKey: String) { - companion object { - private const val GAME_ID_MINECRAFT = 432 - } private val json = Json { isLenient = true @@ -34,9 +31,9 @@ class CurseforgeApi(apiKey: String) { private val http = HttpClient(OkHttp) { install(HttpTimeout) { - this.requestTimeoutMillis = 30_0000 - this.connectTimeoutMillis = 30_0000 - this.socketTimeoutMillis = 30_0000 + this.requestTimeoutMillis = 300_000 + this.connectTimeoutMillis = 300_000 + this.socketTimeoutMillis = 300_000 } defaultRequest { url.protocol = URLProtocol.HTTPS diff --git a/src/main/kotlin/top/jie65535/jcf/MessageHandler.kt b/src/main/kotlin/top/jie65535/jcf/MessageHandler.kt index f8e0095..fadaeed 100644 --- a/src/main/kotlin/top/jie65535/jcf/MessageHandler.kt +++ b/src/main/kotlin/top/jie65535/jcf/MessageHandler.kt @@ -1,11 +1,8 @@ package top.jie65535.jcf -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import net.mamoe.mirai.event.Event -import net.mamoe.mirai.event.EventChannel +import kotlinx.coroutines.* +import net.mamoe.mirai.event.* import net.mamoe.mirai.event.events.MessageEvent -import net.mamoe.mirai.event.subscribeMessages import net.mamoe.mirai.message.data.* import net.mamoe.mirai.message.data.MessageSource.Key.quote import net.mamoe.mirai.utils.ExternalResource.Companion.toExternalResource @@ -35,14 +32,15 @@ class MessageHandler( } else { try { val pagedList = service.search(modClass, filter) - val msg = with(pagedList.current()) { - if (size == 1) { + with(pagedList.current()) { + if (isEmpty()) { + subject.sendMessage("未搜索到关键字\"$filter\"相关结果") + } else if (size == 1) { handleShowMod(get(0)) } else { handleModsSearchResult(pagedList) } } - subject.sendMessage(msg) } catch (e: Throwable) { subject.sendMessage(message.quote() + "发生内部错误,请稍后重试") logger.error("消息\"$message\"引发异常", e) @@ -53,86 +51,160 @@ class MessageHandler( } } + /** + * 处理分页列表选择功能,返回用户选中项,返回null表示未选中任何项 + * @param pagedList 分页的列表 + * @param format 格式化方法 + * @return 用户选中项,null表示未选择任何项 + */ + private suspend fun MessageEvent.handlePagedList(pagedList: PagedList, format: (T)->Message): T? { + do { + var isContinue = false + val list = pagedList.current() + val listMessage = subject.sendMessage(buildForwardMessage { + for ((i, it) in list.withIndex()) { + bot.id named i.toString() says format(it) + } + var msg = "$WAIT_REPLY_TIMEOUT_S 秒内回复编号查看" + if (pagedList.hasPrev) + msg += "\n回复 $PAGE_UP_KEYWORD 上一页" + if (pagedList.hasNext) + msg += "\n回复 $PAGE_DOWN_KEYWORD 下一页" + bot says msg + }) + try { + // 获取用户回复 + val next = withTimeout(WAIT_REPLY_TIMEOUT_S * 1000L) { + eventChannel.nextEvent(EventPriority.MONITOR) { it.sender == sender } + } + val nextMessage = next.message.content + if (nextMessage.equals(PAGE_DOWN_KEYWORD, true)) { + pagedList.next() + } else if (nextMessage.equals(PAGE_UP_KEYWORD, true)) { + pagedList.prev() + } else { + return list[nextMessage.toInt()] + } + isContinue = true + } catch (e: TimeoutCancellationException) { + sender.sendMessage("等待回复超时,请重新查询。") + } catch (e: NumberFormatException) { + sender.sendMessage("请回复正确的选项,此次查询已取消,请重新查询。") + } catch (e: IndexOutOfBoundsException) { + sender.sendMessage("请回复正确的序号,此次查询已取消,请重新查询。") + } catch (e: Throwable) { + subject.sendMessage(message.quote() + "发生内部错误,请稍后重试") + logger.warning("回复消息\"$message\"引发意外的异常", e) + } finally { + listMessage.recall() + } + } while (isContinue) + return null + } + /** * 处理mod搜索结果 */ - private suspend fun MessageEvent.handleModsSearchResult(pagedList: PagedList): Message { - val list = pagedList.current() // mod list - val hasNext = pagedList.hasNext // 是否有下一页 - val hasPrev = pagedList.hasPrev // 是否有上一页 - return buildForwardMessage { - bot says "30秒内回复编号查看" - for ((x, mod) in list.withIndex()) { - bot.id named x.toString() says PlainText( - """ - [${mod.name}] by ${mod.authors[0].name} - ${formatCount(mod.downloadCount)} Downloads Updated ${mod.dateModified.toLocalDate()} - ${mod.summary} - ${mod.links.websiteUrl} - """.trimIndent() - ) - } - var tmp = "回复:" - if (hasPrev) tmp += "[P]上一页 " - if (hasNext) tmp += "[N]下一页" - bot says tmp + private suspend fun MessageEvent.handleModsSearchResult(pagedList: PagedList) { + val selectedMod = handlePagedList(pagedList) { mod -> + PlainText( + """ + [${mod.name}] by ${mod.authors[0].name} + ${formatCount(mod.downloadCount)} Downloads Updated ${mod.dateModified.toLocalDate()} + ${mod.summary} + ${mod.links.websiteUrl} + """.trimIndent()) } + selectedMod?.let { handleShowMod(it) } } /** * 处理展示单个mod */ - private suspend fun MessageEvent.handleShowMod(mod: Mod): Message { - return buildForwardMessage { - // logo - mod.logo.thumbnailUrl?.let { - if (it.isNotBlank()) bot says loadImage(it) + private suspend fun MessageEvent.handleShowMod(mod: Mod) { + subject.sendMessage( + buildForwardMessage { + // logo + mod.logo.thumbnailUrl?.let { + if (it.isNotBlank()) bot says loadImage(it) + } + // basic info + bot says PlainText(with(mod) { + """ + $name + 作者:${authors.joinToString { it.name }} + 概括:$summary + 项目ID:$id + 创建时间:${dateCreated.toLocalDate()} + 最近更新:${dateModified.toLocalDate()} + 总下载:$downloadCount + 主页:${mod.links.websiteUrl} + """.trimIndent() + }) + var msg = "$WAIT_REPLY_TIMEOUT_S 秒内回复 $SUBSCRIBE_KEYWORD 订阅模组更新(TODO)" + if (mod.latestFiles.isNotEmpty()) { + msg += "\n回复编号查看文件详细信息\n" + + "回复 $VIEW_FILES_KEYWORD 查看全部历史文件" + } + bot says msg + for ((i, file) in mod.latestFiles.withIndex()) { + bot.id named i.toString() says PlainText( + """ + ${file.displayName} [${file.releaseType}] [${file.fileDate.toLocalDate()}] + ${file.downloadUrl} + """.trimIndent() + ) + } } - // basic info - bot says PlainText(with(mod) { - """ - $name - 作者:${authors[0].name} - 概括:$summary - 项目ID:$id - 创建时间:${dateCreated.toLocalDate()} - 最近更新:${dateModified.toLocalDate()} - 总下载:$downloadCount - """.trimIndent() - }) - // links - bot says PlainText(with(mod.links) { - """ - 主页:$websiteUrl - 支持页:$issuesUrl - wiki:$wikiUrl - 开源页:$sourceUrl - """.trimIndent() - }) + ) + try { + // 获取用户回复 + val next = withTimeout(WAIT_REPLY_TIMEOUT_S * 1000L) { + eventChannel.nextEvent(EventPriority.MONITOR) { it.sender == sender } + } + val nextMessage = next.message.content + if (nextMessage.equals(SUBSCRIBE_KEYWORD, true)) { + // TODO 实现订阅模组更新功能 + subject.sendMessage("订阅更新功能暂未完成,敬请期待") + } else if (mod.latestFiles.isNotEmpty()) { + if (nextMessage.equals(VIEW_FILES_KEYWORD, true)) { + // 查看所有文件 + handleModFileList(service.getModFiles(mod.id)) + } else { + // 查看文件详情 + handleModFile(mod.latestFiles[nextMessage.toInt()]) + } + } + } catch (e: Throwable) { + // 忽略因回复引发的异常,无论是超时、越界还是格式不正确,不提示错误 } } /** * 处理模组文件列表 */ - private suspend fun MessageEvent.handleModFileList(pagedList: PagedList): Message { - val list = pagedList.current() // mod list - val hasNext = pagedList.hasNext // 是否有下一页 - val hasPrev = pagedList.hasPrev // 是否有上一页 - return buildForwardMessage { - bot says "30秒内回复编号查看" - for ((x, file) in list.withIndex()) { - bot.id named x.toString() says PlainText( - """ - ${file.displayName} [${file.releaseType}] [${file.fileDate.toLocalDate()}] - ${file.downloadUrl} - """.trimIndent() - ) - } - var tmp = "回复:" - if (hasPrev) tmp += "[P]上一页 " - if (hasNext) tmp += "[N]下一页" - bot says tmp + private suspend fun MessageEvent.handleModFileList(pagedList: PagedList) { + val selectedFile = handlePagedList(pagedList) { file -> + PlainText( + """ + ${file.displayName} [${file.releaseType}] [${file.fileDate.toLocalDate()}] + ${file.downloadUrl} + """.trimIndent() + ) + } + selectedFile?.let { handleModFile(it) } + } + + /** + * 处理模组文件具体信息展示 + */ + private suspend fun MessageEvent.handleModFile(file: File) { + try { + // 暂时仅展示文件更改日志,可以添加文件依赖相关信息的显示 + subject.sendMessage(handleModFileChangelog(service.getModFileChangelog(file.modId, file.id))) + } catch (e: Throwable) { + logger.warning("获取文件[${file.fileName}]更改日志时异常", e) + subject.sendMessage("获取文件更改日志时异常,请稍后重试") } } @@ -145,39 +217,46 @@ class MessageHandler( return sendLargeMessage(logs) } - private val singleDecimalFormat = DecimalFormat("0.#") + companion object { + private const val WAIT_REPLY_TIMEOUT_S = 60 + private const val PAGE_UP_KEYWORD = "P" + private const val PAGE_DOWN_KEYWORD = "N" + private const val VIEW_FILES_KEYWORD = "ALL" + private const val SUBSCRIBE_KEYWORD = "订阅" + private const val ONE_GRP_SIZE = 5000 + private const val ONE_MSG_SIZE = 500 + private val singleDecimalFormat = DecimalFormat("0.#") - private fun formatCount(count: Long): String = when { - count < 1000000 -> singleDecimalFormat.format(count / 1000) + "K" - count < 1000000000 -> singleDecimalFormat.format(count / 1000000) + "M" - else -> count.toString() - } - - private suspend fun MessageEvent.loadImage(url: String): Image { - val imgFileName = url.substringAfterLast("/") - val file = PluginMain.resolveDataFile("cache/$imgFileName") - val res = if (file.exists()) { - file.readBytes().toExternalResource() - } else { - HttpUtil.downloadImage(url, file).toExternalResource() + private fun formatCount(count: Long): String = when { + count < 1000000 -> singleDecimalFormat.format(count / 1000) + "K" + count < 1000000000 -> singleDecimalFormat.format(count / 1000000) + "M" + else -> count.toString() } - val image = subject.uploadImage(res) - withContext(Dispatchers.IO) { - res.close() - } - return image - } - private val HTMLPattern = Pattern.compile("<[^>]+>", Pattern.CASE_INSENSITIVE) - private val ONE_GRP_SIZE = 5000 - private val ONE_MSG_SIZE = 500 - fun MessageEvent.sendLargeMessage(message: String): Message { - return buildForwardMessage { - for (g in message.indices step ONE_GRP_SIZE) { - for (i in g until g + min(ONE_GRP_SIZE, message.length - g) step ONE_MSG_SIZE) { - bot says PlainText(message.subSequence(i, i + (min(ONE_MSG_SIZE, message.length - i)))) + private suspend fun MessageEvent.loadImage(url: String): Image { + val imgFileName = url.substringAfterLast("/") + val file = PluginMain.resolveDataFile("cache/$imgFileName") + val res = if (file.exists()) { + file.readBytes().toExternalResource() + } else { + HttpUtil.downloadImage(url, file).toExternalResource() + } + val image = subject.uploadImage(res) + withContext(Dispatchers.IO) { + res.close() + } + return image + } + + private val HTMLPattern = Pattern.compile("<[^>]+>", Pattern.CASE_INSENSITIVE) + fun MessageEvent.sendLargeMessage(message: String): Message { + return buildForwardMessage { + for (g in message.indices step ONE_GRP_SIZE) { + for (i in g until g + min(ONE_GRP_SIZE, message.length - g) step ONE_MSG_SIZE) { + bot says PlainText(message.subSequence(i, i + (min(ONE_MSG_SIZE, message.length - i)))) + } } } - } - }// fun + }// fun + } } diff --git a/src/main/kotlin/top/jie65535/jcf/MinecraftService.kt b/src/main/kotlin/top/jie65535/jcf/MinecraftService.kt index 6a0fdce..a8c8fbc 100644 --- a/src/main/kotlin/top/jie65535/jcf/MinecraftService.kt +++ b/src/main/kotlin/top/jie65535/jcf/MinecraftService.kt @@ -9,48 +9,48 @@ import top.jie65535.jcf.util.PagedList class MinecraftService(apiKey: String) { companion object { private const val GAME_ID_MINECRAFT = 432 - private const val DEFAULT_PAGE_SIZE = 20 + private const val DEFAULT_PAGE_SIZE = 10 private val DEFAULT_SORT_FIELD = ModsSearchSortField.Popularity } /** * mod分类 */ - enum class ModClass(val classId: Int) { + enum class ModClass(val className: String, val classId: Int) { /** * 存档 */ - WORLDS(17), + WORLDS("存档",17), /** * 水桶服插件 */ - BUKKIT_PLUGINS(5), + BUKKIT_PLUGINS("水桶服插件", 5), /** * 自定义 */ - CUSTOMIZATION(4546), + CUSTOMIZATION("定制", 4546), /** * 整合包 */ - MODPACKS(4471), + MODPACKS("整合包", 4471), /** * 资源包 */ - RESOURCE_PACKS(12), + RESOURCE_PACKS("资源包", 12), /** * 附加 */ - ADDONS(4559), + ADDONS("附加", 4559), /** * 模组 */ - MODS(6); + MODS("模组", 6); } /** diff --git a/src/main/kotlin/top/jie65535/jcf/PluginCommands.kt b/src/main/kotlin/top/jie65535/jcf/PluginCommands.kt new file mode 100644 index 0000000..e5a1b63 --- /dev/null +++ b/src/main/kotlin/top/jie65535/jcf/PluginCommands.kt @@ -0,0 +1,23 @@ +package top.jie65535.jcf + +import net.mamoe.mirai.console.command.CommandSender +import net.mamoe.mirai.console.command.CompositeCommand + +object PluginCommands : CompositeCommand(PluginMain, "jcf") { + @SubCommand + @Description("设置Curseforge API Key") + suspend fun CommandSender.setApiKey(apiKey: String) { + PluginConfig.apiKey = apiKey + sendMessage("OK! 重启插件生效") + } + + @SubCommand + @Description("查看插件帮助") + suspend fun CommandSender.help() { + val msg = StringBuilder() + for ((modClass, cmd) in PluginConfig.searchCommands) { + msg.appendLine("搜索${modClass.className}: $cmd") + } + sendMessage(msg.toString()) + } +} \ No newline at end of file diff --git a/src/main/kotlin/top/jie65535/jcf/PluginConfig.kt b/src/main/kotlin/top/jie65535/jcf/PluginConfig.kt index 3ad1dfe..1a5baf1 100644 --- a/src/main/kotlin/top/jie65535/jcf/PluginConfig.kt +++ b/src/main/kotlin/top/jie65535/jcf/PluginConfig.kt @@ -4,20 +4,20 @@ import net.mamoe.mirai.console.data.AutoSavePluginConfig import net.mamoe.mirai.console.data.ValueDescription import net.mamoe.mirai.console.data.value -object PluginConfig : AutoSavePluginConfig("jcf") { +object PluginConfig : AutoSavePluginConfig("JCurseforgeConfig") { @ValueDescription("Curseforge API KEY") - val apiKey: String by value() + var apiKey: String by value() @ValueDescription("搜索命令 (MODS,MODPACKS,RESOURCE_PACKS,WORLDS,BUKKIT_PLUGINS,ADDONS,CUSTOMIZATION)") val searchCommands: MutableMap by value( mutableMapOf( - MinecraftService.ModClass.MODS to "jcfmod ", - MinecraftService.ModClass.MODPACKS to "jcfpack ", - MinecraftService.ModClass.RESOURCE_PACKS to "jcfres ", - MinecraftService.ModClass.WORLDS to "jcfword ", - MinecraftService.ModClass.BUKKIT_PLUGINS to "jcfbukkit ", - MinecraftService.ModClass.ADDONS to "jcfaddon ", - MinecraftService.ModClass.CUSTOMIZATION to "jcfcustom ", + MinecraftService.ModClass.MODS to "cfmod ", + MinecraftService.ModClass.MODPACKS to "cfpack ", + MinecraftService.ModClass.RESOURCE_PACKS to "cfres ", + MinecraftService.ModClass.WORLDS to "cfword ", + MinecraftService.ModClass.BUKKIT_PLUGINS to "cfbukkit ", + MinecraftService.ModClass.ADDONS to "cfaddon ", + MinecraftService.ModClass.CUSTOMIZATION to "cfcustom ", ) ) } diff --git a/src/main/kotlin/top/jie65535/jcf/PluginMain.kt b/src/main/kotlin/top/jie65535/jcf/PluginMain.kt index 0f99ccf..e859afa 100644 --- a/src/main/kotlin/top/jie65535/jcf/PluginMain.kt +++ b/src/main/kotlin/top/jie65535/jcf/PluginMain.kt @@ -1,5 +1,6 @@ package top.jie65535.jcf +import net.mamoe.mirai.console.command.CommandManager.INSTANCE.register import net.mamoe.mirai.console.plugin.jvm.JvmPluginDescription import net.mamoe.mirai.console.plugin.jvm.KotlinPlugin import net.mamoe.mirai.event.GlobalEventChannel @@ -19,9 +20,12 @@ object PluginMain: KotlinPlugin( override fun onEnable() { logger.info { "Plugin loaded" } PluginConfig.reload() + PluginCommands.register() if (PluginConfig.apiKey.isBlank()) { - logger.error("必须配置 Curseforge Api Key 才可以使用本插件!") + logger.error("必须配置 Curseforge Api Key 才可以使用本插件!\n" + + "请使用 /jcf setApiKey 命令来设置key\n" + + "Api key 可以在开发者控制台生成:https://console.curseforge.com/") return } val service = MinecraftService(PluginConfig.apiKey)