mirror of
https://github.com/jie65535/mirai-console-jcf-plugin.git
synced 2025-07-28 19:19:15 +08:00
新增官方API封装,当前仅完成了搜索Mod部分
This commit is contained in:
parent
76d3cf2f9c
commit
7fd31c194b
137
src/main/kotlin/top/jie65535/jcf/CurseforgeApi.kt
Normal file
137
src/main/kotlin/top/jie65535/jcf/CurseforgeApi.kt
Normal file
@ -0,0 +1,137 @@
|
||||
package top.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.*
|
||||
import kotlinx.serialization.json.Json
|
||||
import top.jie65535.jcf.model.mod.*
|
||||
import top.jie65535.jcf.model.request.*
|
||||
import top.jie65535.jcf.model.request.SortOrder.*
|
||||
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
|
||||
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 = "api.curseforge.com"
|
||||
header("accept", "application/json")
|
||||
header("x-api-key", apiKey)
|
||||
}
|
||||
}
|
||||
|
||||
//region Mods
|
||||
|
||||
/**
|
||||
* Get all mods that match the search criteria.
|
||||
* @param gameId Filter by game id.
|
||||
* @param classId Filter by section id (discoverable via Categories)
|
||||
* @param categoryId Filter by category id
|
||||
* @param gameVersion Filter by game version string
|
||||
* @param searchFilter Filter by free text search in the mod name and author
|
||||
* @param sortField Filter by ModsSearchSortField enumeration
|
||||
* @param sortOrder 'asc' if sort is in ascending order, 'desc' if sort is in descending order
|
||||
* @param modLoaderType Filter only mods associated to a given modloader (Forge, Fabric ...). Must be coupled with gameVersion.
|
||||
* @param gameVersionTypeId Filter only mods that contain files tagged with versions of the given gameVersionTypeId
|
||||
* @param slug Filter by slug (coupled with classId will result in a unique result).
|
||||
* @param index A zero based index of the first item to include in the response,
|
||||
* @param pageSize The number of items to include in the response,
|
||||
*/
|
||||
suspend fun searchMods(
|
||||
gameId: Int,
|
||||
classId: Int?,
|
||||
categoryId: Int?,
|
||||
gameVersion: String?,
|
||||
searchFilter: String?,
|
||||
sortField: ModsSearchSortField?,
|
||||
sortOrder: SortOrder?,
|
||||
modLoaderType: ModLoaderType?,
|
||||
gameVersionTypeId: Int?,
|
||||
slug: String?,
|
||||
index: Int?,
|
||||
pageSize: Int?
|
||||
): SearchModsResponse {
|
||||
return json.decodeFromString(
|
||||
http.get("/v1/mods/search") {
|
||||
parameter("gameId", gameId)
|
||||
parameter("classId", classId)
|
||||
parameter("categoryId", categoryId)
|
||||
parameter("gameVersion", gameVersion)
|
||||
parameter("searchFilter", searchFilter)
|
||||
parameter("sortField", sortField)
|
||||
parameter("sortOrder", when(sortOrder){
|
||||
ASC -> "asc"
|
||||
DESC -> "asc"
|
||||
null -> null
|
||||
})
|
||||
parameter("modLoaderType", modLoaderType)
|
||||
parameter("gameVersionTypeId", gameVersionTypeId)
|
||||
parameter("slug", slug)
|
||||
parameter("index", index)
|
||||
parameter("pageSize", pageSize)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a single mod.
|
||||
*/
|
||||
suspend fun getMod(modId: Int): GetModResponse {
|
||||
return json.decodeFromString(
|
||||
http.get("/v1/mods/$modId")
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of mods.
|
||||
*/
|
||||
suspend fun getMods(modIds: IntArray): GetModsResponse {
|
||||
return json.decodeFromString(
|
||||
http.get("/v1/mods") {
|
||||
body = json.encodeToString(GetModsByIdsListRequestBody(modIds))
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of featured, popular and recently updated mods.
|
||||
*/
|
||||
suspend fun getFeaturedMods(
|
||||
gameId: Int,
|
||||
excludedModIds: IntArray,
|
||||
gameVersionTypeId: Int?
|
||||
): GetFeaturedModsResponse {
|
||||
return json.decodeFromString(
|
||||
http.get("/v1/mods/featured") {
|
||||
body = json.encodeToString(GetFeaturedModsRequestBody(gameId, excludedModIds, gameVersionTypeId))
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the full description of a mod in HTML format.
|
||||
*/
|
||||
suspend fun getModDescription(modId: Int): String {
|
||||
return http.get("/v1/mods/$modId/description")
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
}
|
21
src/main/kotlin/top/jie65535/jcf/model/Category.kt
Normal file
21
src/main/kotlin/top/jie65535/jcf/model/Category.kt
Normal file
@ -0,0 +1,21 @@
|
||||
package top.jie65535.jcf.model
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import top.jie65535.jcf.util.OffsetDateTimeSerializer
|
||||
import java.time.OffsetDateTime
|
||||
|
||||
@Serializable
|
||||
class Category(
|
||||
val id: Int,
|
||||
val gameId: Int,
|
||||
val name: String,
|
||||
val slug: String,
|
||||
val url: String,
|
||||
val iconUrl: String,
|
||||
@Serializable(OffsetDateTimeSerializer::class)
|
||||
val dateModified: OffsetDateTime,
|
||||
val isClass: Boolean?,
|
||||
val classId: Int?,
|
||||
val parentCategoryId: Int?,
|
||||
val displayIndex: Int?
|
||||
)
|
9
src/main/kotlin/top/jie65535/jcf/model/Pagination.kt
Normal file
9
src/main/kotlin/top/jie65535/jcf/model/Pagination.kt
Normal file
@ -0,0 +1,9 @@
|
||||
package top.jie65535.jcf.model
|
||||
|
||||
@kotlinx.serialization.Serializable
|
||||
class Pagination(
|
||||
val index: Int,
|
||||
val pageSize: Int,
|
||||
val resultCount: Int,
|
||||
val totalCount: Long,
|
||||
)
|
@ -0,0 +1,30 @@
|
||||
package top.jie65535.jcf.model
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import top.jie65535.jcf.util.OffsetDateTimeSerializer
|
||||
import java.time.OffsetDateTime
|
||||
|
||||
@Serializable
|
||||
class SortableGameVersion(
|
||||
/**
|
||||
* Original version name (e.g. 1.5b)
|
||||
*/
|
||||
val gameVersionName: String,
|
||||
/**
|
||||
* Used for sorting (e.g. 0000000001.0000000005)
|
||||
*/
|
||||
val gameVersionPadded: String,
|
||||
/**
|
||||
* game version clean name (e.g. 1.5)
|
||||
*/
|
||||
val gameVersion: String,
|
||||
/**
|
||||
* Game version release date
|
||||
*/
|
||||
@Serializable(OffsetDateTimeSerializer::class)
|
||||
val gameVersionReleaseDate: OffsetDateTime,
|
||||
/**
|
||||
* Game version type id
|
||||
*/
|
||||
val gameVersionTypeId: Int?
|
||||
)
|
103
src/main/kotlin/top/jie65535/jcf/model/file/File.kt
Normal file
103
src/main/kotlin/top/jie65535/jcf/model/file/File.kt
Normal file
@ -0,0 +1,103 @@
|
||||
package top.jie65535.jcf.model.file
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import top.jie65535.jcf.model.SortableGameVersion
|
||||
import top.jie65535.jcf.util.OffsetDateTimeSerializer
|
||||
import java.time.OffsetDateTime
|
||||
|
||||
@Serializable
|
||||
class File(
|
||||
/**
|
||||
* The file id
|
||||
*/
|
||||
val id: Int,
|
||||
/**
|
||||
* The game id related to the mod that this file belongs to
|
||||
*/
|
||||
val gameId: Int,
|
||||
/**
|
||||
* The mod id
|
||||
*/
|
||||
val modId: Int,
|
||||
/**
|
||||
* Whether the file is available to download
|
||||
*/
|
||||
val isAvailable: Boolean,
|
||||
/**
|
||||
* Display name of the file
|
||||
*/
|
||||
val displayName: String,
|
||||
/**
|
||||
* Exact file name
|
||||
*/
|
||||
val fileName: String,
|
||||
/**
|
||||
* The file release type
|
||||
*/
|
||||
val releaseType: FileReleaseType,
|
||||
/**
|
||||
* Status of the file
|
||||
*/
|
||||
val fileStatus: FileStatus,
|
||||
/**
|
||||
* The file hash (i.e. md5 or sha1)
|
||||
*/
|
||||
val hashes: Array<FileHash>,
|
||||
/**
|
||||
* The file timestamp
|
||||
*/
|
||||
@Serializable(OffsetDateTimeSerializer::class)
|
||||
val fileDate: OffsetDateTime,
|
||||
/**
|
||||
* The file length in bytes
|
||||
*/
|
||||
val fileLength: Long,
|
||||
/**
|
||||
* The number of downloads for the file
|
||||
*/
|
||||
val downloadCount: Long,
|
||||
/**
|
||||
* The file download URL
|
||||
*/
|
||||
val downloadUrl: String,
|
||||
/**
|
||||
* List of game versions this file is relevant for
|
||||
*/
|
||||
val gameVersions: Array<String>,
|
||||
/**
|
||||
* Metadata used for sorting by game versions
|
||||
*/
|
||||
val sortableGameVersions: Array<SortableGameVersion>,
|
||||
/**
|
||||
* List of dependencies files
|
||||
*/
|
||||
val dependencies: Array<FileDependency>,
|
||||
/**
|
||||
* none
|
||||
*/
|
||||
val exposeAsAlternative: Boolean?,
|
||||
/**
|
||||
* none
|
||||
*/
|
||||
val parentProjectFileId: Int?,
|
||||
/**
|
||||
* none
|
||||
*/
|
||||
val alternateFileId: Int?,
|
||||
/**
|
||||
* none
|
||||
*/
|
||||
val isServerPack: Boolean?,
|
||||
/**
|
||||
* none
|
||||
*/
|
||||
val serverPackFileId: Int?,
|
||||
/**
|
||||
* none
|
||||
*/
|
||||
val fileFingerprint: Long,
|
||||
/**
|
||||
* none
|
||||
*/
|
||||
val modules: Array<FileModule>,
|
||||
)
|
@ -0,0 +1,7 @@
|
||||
package top.jie65535.jcf.model.file
|
||||
|
||||
@kotlinx.serialization.Serializable
|
||||
class FileDependency(
|
||||
val modId: Int,
|
||||
val relationType: FileRelationType,
|
||||
)
|
7
src/main/kotlin/top/jie65535/jcf/model/file/FileHash.kt
Normal file
7
src/main/kotlin/top/jie65535/jcf/model/file/FileHash.kt
Normal file
@ -0,0 +1,7 @@
|
||||
package top.jie65535.jcf.model.file
|
||||
|
||||
@kotlinx.serialization.Serializable
|
||||
class FileHash(
|
||||
val value: String,
|
||||
val algo: HashAlgo,
|
||||
)
|
13
src/main/kotlin/top/jie65535/jcf/model/file/FileIndex.kt
Normal file
13
src/main/kotlin/top/jie65535/jcf/model/file/FileIndex.kt
Normal file
@ -0,0 +1,13 @@
|
||||
package top.jie65535.jcf.model.file
|
||||
|
||||
import top.jie65535.jcf.model.mod.ModLoaderType
|
||||
|
||||
@kotlinx.serialization.Serializable
|
||||
class FileIndex(
|
||||
val gameVersion: String,
|
||||
val fileId: Int,
|
||||
val filename: String,
|
||||
val releaseType: FileReleaseType,
|
||||
val gameVersionTypeId: Int?,
|
||||
val modLoader: ModLoaderType,
|
||||
)
|
@ -0,0 +1,7 @@
|
||||
package top.jie65535.jcf.model.file
|
||||
|
||||
@kotlinx.serialization.Serializable
|
||||
class FileModule(
|
||||
val name: String,
|
||||
val fingerprint: Long,
|
||||
)
|
@ -0,0 +1,16 @@
|
||||
package top.jie65535.jcf.model.file
|
||||
|
||||
import kotlinx.serialization.KSerializer
|
||||
import top.jie65535.jcf.util.EnumIndexSerializer
|
||||
|
||||
@kotlinx.serialization.Serializable(with = FileRelationType.IndexSerializer::class)
|
||||
enum class FileRelationType {
|
||||
EmbeddedLibrary,
|
||||
OptionalDependency,
|
||||
RequiredDependency,
|
||||
Tool,
|
||||
Incompatible,
|
||||
Include;
|
||||
|
||||
internal object IndexSerializer : KSerializer<FileRelationType> by EnumIndexSerializer()
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package top.jie65535.jcf.model.file
|
||||
|
||||
import kotlinx.serialization.KSerializer
|
||||
import top.jie65535.jcf.util.EnumIndexSerializer
|
||||
|
||||
@kotlinx.serialization.Serializable(with = FileReleaseType.IndexSerializer::class)
|
||||
enum class FileReleaseType {
|
||||
Release,
|
||||
Beta,
|
||||
Alpha;
|
||||
|
||||
internal object IndexSerializer : KSerializer<FileReleaseType> by EnumIndexSerializer()
|
||||
}
|
25
src/main/kotlin/top/jie65535/jcf/model/file/FileStatus.kt
Normal file
25
src/main/kotlin/top/jie65535/jcf/model/file/FileStatus.kt
Normal file
@ -0,0 +1,25 @@
|
||||
package top.jie65535.jcf.model.file
|
||||
|
||||
import kotlinx.serialization.KSerializer
|
||||
import top.jie65535.jcf.util.EnumIndexSerializer
|
||||
|
||||
@kotlinx.serialization.Serializable(with = FileStatus.IndexSerializer::class)
|
||||
enum class FileStatus{
|
||||
Processing,
|
||||
ChangesRequired,
|
||||
UnderReview,
|
||||
Approved,
|
||||
Rejected,
|
||||
MalwareDetected,
|
||||
Deleted,
|
||||
Archived,
|
||||
Testing,
|
||||
Released,
|
||||
ReadyForReview,
|
||||
Deprecated,
|
||||
Baking,
|
||||
AwaitingPublishing,
|
||||
FailedPublishing;
|
||||
|
||||
internal object IndexSerializer : KSerializer<FileStatus> by EnumIndexSerializer()
|
||||
}
|
12
src/main/kotlin/top/jie65535/jcf/model/file/HashAlgo.kt
Normal file
12
src/main/kotlin/top/jie65535/jcf/model/file/HashAlgo.kt
Normal file
@ -0,0 +1,12 @@
|
||||
package top.jie65535.jcf.model.file
|
||||
|
||||
import kotlinx.serialization.KSerializer
|
||||
import top.jie65535.jcf.util.EnumIndexSerializer
|
||||
|
||||
@kotlinx.serialization.Serializable(with = HashAlgo.IndexSerializer::class)
|
||||
enum class HashAlgo(val value: Int) {
|
||||
Sha1(1),
|
||||
Md5(2);
|
||||
|
||||
internal object IndexSerializer : KSerializer<HashAlgo> by EnumIndexSerializer()
|
||||
}
|
116
src/main/kotlin/top/jie65535/jcf/model/mod/Mod.kt
Normal file
116
src/main/kotlin/top/jie65535/jcf/model/mod/Mod.kt
Normal file
@ -0,0 +1,116 @@
|
||||
package top.jie65535.jcf.model.mod
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import top.jie65535.jcf.model.Category
|
||||
import top.jie65535.jcf.model.file.File
|
||||
import top.jie65535.jcf.model.file.FileIndex
|
||||
import top.jie65535.jcf.util.OffsetDateTimeSerializer
|
||||
import java.time.OffsetDateTime
|
||||
|
||||
@kotlinx.serialization.Serializable
|
||||
class Mod(
|
||||
/**
|
||||
* The mod id
|
||||
*/
|
||||
val id: Int,
|
||||
/**
|
||||
* The game id this mod is for
|
||||
*/
|
||||
val gameId: Int,
|
||||
/**
|
||||
* The name of the mod
|
||||
*/
|
||||
val name: String,
|
||||
/**
|
||||
* The mod slug that would appear in the URL
|
||||
*/
|
||||
val slug: String,
|
||||
/**
|
||||
* Relevant links for the mod such as Issue tracker and Wiki
|
||||
*/
|
||||
val links: ModLinks,
|
||||
/**
|
||||
* Mod summary
|
||||
*/
|
||||
val summary: String,
|
||||
/**
|
||||
* Current mod status
|
||||
*/
|
||||
val status: ModStatus,
|
||||
/**
|
||||
* Number of downloads for the mod
|
||||
*/
|
||||
val downloadCount: Long,
|
||||
/**
|
||||
* Whether the mod is included in the featured mods list
|
||||
*/
|
||||
val isFeatured: Boolean,
|
||||
/**
|
||||
* The main category of the mod as it was chosen by the mod author
|
||||
*/
|
||||
val primaryCategoryId: Int,
|
||||
/**
|
||||
* List of categories that this mod is related to
|
||||
*/
|
||||
val categories: Array<Category>,
|
||||
/**
|
||||
* The class id this mod belongs to
|
||||
*/
|
||||
val classId: Int?,
|
||||
/**
|
||||
* List of the mod's authors
|
||||
*/
|
||||
val authors: Array<ModAuthor>,
|
||||
/**
|
||||
* The mod's logo asset
|
||||
*/
|
||||
val logo: ModAsset,
|
||||
/**
|
||||
* List of screenshots assets
|
||||
*/
|
||||
val screenshots: Array<ModAsset>,
|
||||
/**
|
||||
* The id of the main file of the mod
|
||||
*/
|
||||
val mainFileId: Int,
|
||||
/**
|
||||
* List of latest files of the mod
|
||||
*/
|
||||
val latestFiles: Array<File>,
|
||||
/**
|
||||
* List of file related details for the latest files of the mod
|
||||
*/
|
||||
val latestFilesIndexes: Array<FileIndex>,
|
||||
/**
|
||||
* The creation date of the mod
|
||||
*/
|
||||
@Serializable(OffsetDateTimeSerializer::class)
|
||||
val dateCreated: OffsetDateTime,
|
||||
/**
|
||||
* The last time the mod was modified
|
||||
*/
|
||||
@Serializable(OffsetDateTimeSerializer::class)
|
||||
val dateModified: OffsetDateTime,
|
||||
/**
|
||||
* The release date of the mod
|
||||
*/
|
||||
@Serializable(OffsetDateTimeSerializer::class)
|
||||
val dateReleased: OffsetDateTime,
|
||||
/**
|
||||
* Is mod allowed to be distributed
|
||||
*/
|
||||
val allowModDistribution: Boolean?,
|
||||
/**
|
||||
* The mod popularity rank for the game
|
||||
*/
|
||||
val gamePopularityRank: Int,
|
||||
/**
|
||||
* Is the mod available for search. This can be false when a mod is experimental,
|
||||
* in a deleted state or has only alpha files
|
||||
*/
|
||||
val isAvailable: Boolean,
|
||||
/**
|
||||
* The mod's thumbs up count
|
||||
*/
|
||||
val thumbsUpCount: Int,
|
||||
)
|
11
src/main/kotlin/top/jie65535/jcf/model/mod/ModAsset.kt
Normal file
11
src/main/kotlin/top/jie65535/jcf/model/mod/ModAsset.kt
Normal file
@ -0,0 +1,11 @@
|
||||
package top.jie65535.jcf.model.mod
|
||||
|
||||
@kotlinx.serialization.Serializable
|
||||
class ModAsset(
|
||||
val id: Int,
|
||||
val modId: Int,
|
||||
val title: String,
|
||||
val description: String,
|
||||
val thumbnailUrl: String,
|
||||
val url: String,
|
||||
)
|
8
src/main/kotlin/top/jie65535/jcf/model/mod/ModAuthor.kt
Normal file
8
src/main/kotlin/top/jie65535/jcf/model/mod/ModAuthor.kt
Normal file
@ -0,0 +1,8 @@
|
||||
package top.jie65535.jcf.model.mod
|
||||
|
||||
@kotlinx.serialization.Serializable
|
||||
class ModAuthor(
|
||||
val id: Int,
|
||||
val name: String,
|
||||
val url: String,
|
||||
)
|
9
src/main/kotlin/top/jie65535/jcf/model/mod/ModLinks.kt
Normal file
9
src/main/kotlin/top/jie65535/jcf/model/mod/ModLinks.kt
Normal file
@ -0,0 +1,9 @@
|
||||
package top.jie65535.jcf.model.mod
|
||||
|
||||
@kotlinx.serialization.Serializable
|
||||
class ModLinks(
|
||||
val websiteUrl: String,
|
||||
val wikiUrl: String,
|
||||
val issuesUrl: String,
|
||||
val sourceUrl: String
|
||||
)
|
16
src/main/kotlin/top/jie65535/jcf/model/mod/ModLoaderType.kt
Normal file
16
src/main/kotlin/top/jie65535/jcf/model/mod/ModLoaderType.kt
Normal file
@ -0,0 +1,16 @@
|
||||
package top.jie65535.jcf.model.mod
|
||||
|
||||
import kotlinx.serialization.KSerializer
|
||||
import top.jie65535.jcf.util.EnumIndexSerializer
|
||||
|
||||
@kotlinx.serialization.Serializable(with = ModLoaderType.IndexSerializer::class)
|
||||
enum class ModLoaderType {
|
||||
Any,
|
||||
Forge,
|
||||
Cauldron,
|
||||
LiteLoader,
|
||||
Fabric,
|
||||
Quilt;
|
||||
|
||||
internal object IndexSerializer : KSerializer<ModLoaderType> by EnumIndexSerializer()
|
||||
}
|
20
src/main/kotlin/top/jie65535/jcf/model/mod/ModStatus.kt
Normal file
20
src/main/kotlin/top/jie65535/jcf/model/mod/ModStatus.kt
Normal file
@ -0,0 +1,20 @@
|
||||
package top.jie65535.jcf.model.mod
|
||||
|
||||
import kotlinx.serialization.KSerializer
|
||||
import top.jie65535.jcf.util.EnumIndexSerializer
|
||||
|
||||
@kotlinx.serialization.Serializable(with = ModStatus.IndexSerializer::class)
|
||||
enum class ModStatus {
|
||||
New,
|
||||
ChangesRequired,
|
||||
UnderSoftReview,
|
||||
Approved,
|
||||
Rejected,
|
||||
ChangesMade,
|
||||
Inactive,
|
||||
Abandoned,
|
||||
Deleted,
|
||||
UnderReview;
|
||||
|
||||
internal object IndexSerializer : KSerializer<ModStatus> by EnumIndexSerializer()
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package top.jie65535.jcf.model.request
|
||||
|
||||
@kotlinx.serialization.Serializable
|
||||
class GetFeaturedModsRequestBody(
|
||||
val gameId: Int,
|
||||
val excludedModIds: IntArray,
|
||||
val gameVersionTypeId: Int?,
|
||||
)
|
@ -0,0 +1,6 @@
|
||||
package top.jie65535.jcf.model.request
|
||||
|
||||
@kotlinx.serialization.Serializable
|
||||
class GetModsByIdsListRequestBody(
|
||||
val modIds: IntArray
|
||||
)
|
@ -0,0 +1,18 @@
|
||||
package top.jie65535.jcf.model.request
|
||||
|
||||
import kotlinx.serialization.KSerializer
|
||||
import top.jie65535.jcf.util.EnumIndexSerializer
|
||||
|
||||
@kotlinx.serialization.Serializable(with = ModsSearchSortField.IndexSerializer::class)
|
||||
enum class ModsSearchSortField {
|
||||
Featured,
|
||||
Popularity,
|
||||
LastUpdated,
|
||||
Name,
|
||||
Author,
|
||||
TotalDownloads,
|
||||
Category,
|
||||
GameVersion;
|
||||
|
||||
internal object IndexSerializer : KSerializer<ModsSearchSortField> by EnumIndexSerializer()
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package top.jie65535.jcf.model.request
|
||||
|
||||
@kotlinx.serialization.Serializable
|
||||
enum class SortOrder {
|
||||
ASC,
|
||||
DESC,
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package top.jie65535.jcf.model.response
|
||||
|
||||
import top.jie65535.jcf.model.mod.Mod
|
||||
|
||||
@kotlinx.serialization.Serializable
|
||||
class FeaturedModsResponse(
|
||||
val featured: Array<Mod>,
|
||||
val popular: Array<Mod>,
|
||||
val recentlyUpdated: Array<Mod>,
|
||||
)
|
@ -0,0 +1,6 @@
|
||||
package top.jie65535.jcf.model.response
|
||||
|
||||
@kotlinx.serialization.Serializable
|
||||
class GetFeaturedModsResponse(
|
||||
val data: FeaturedModsResponse
|
||||
)
|
@ -0,0 +1,8 @@
|
||||
package top.jie65535.jcf.model.response
|
||||
|
||||
import top.jie65535.jcf.model.mod.Mod
|
||||
|
||||
@kotlinx.serialization.Serializable
|
||||
class GetModResponse(
|
||||
val data: Mod
|
||||
)
|
@ -0,0 +1,8 @@
|
||||
package top.jie65535.jcf.model.response
|
||||
|
||||
import top.jie65535.jcf.model.mod.Mod
|
||||
|
||||
@kotlinx.serialization.Serializable
|
||||
class GetModsResponse(
|
||||
val data: Array<Mod>
|
||||
)
|
@ -0,0 +1,10 @@
|
||||
package top.jie65535.jcf.model.response
|
||||
|
||||
import top.jie65535.jcf.model.Pagination
|
||||
import top.jie65535.jcf.model.mod.Mod
|
||||
|
||||
@kotlinx.serialization.Serializable
|
||||
class SearchModsResponse(
|
||||
val data: Mod,
|
||||
val pagination: Pagination,
|
||||
)
|
24
src/main/kotlin/top/jie65535/jcf/util/EnumIndexSerializer.kt
Normal file
24
src/main/kotlin/top/jie65535/jcf/util/EnumIndexSerializer.kt
Normal file
@ -0,0 +1,24 @@
|
||||
package top.jie65535.jcf.util
|
||||
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.descriptors.PrimitiveKind
|
||||
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
|
||||
@Suppress("FunctionName")
|
||||
inline fun <reified T : Enum<T>> EnumIndexSerializer(offset: Int = 1): KSerializer<T> {
|
||||
return object : KSerializer<T> {
|
||||
override val descriptor: SerialDescriptor =
|
||||
PrimitiveSerialDescriptor(T::class.qualifiedName!!, PrimitiveKind.INT)
|
||||
|
||||
override fun serialize(encoder: Encoder, value: T) =
|
||||
encoder.encodeInt(value.ordinal + offset)
|
||||
|
||||
override fun deserialize(decoder: Decoder): T =
|
||||
requireNotNull(enumValues<T>().getOrNull(decoder.decodeInt())) {
|
||||
"index: ${decoder.decodeInt()} not in ${enumValues<T>()}"
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package top.jie65535.jcf.util
|
||||
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.descriptors.PrimitiveKind
|
||||
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
import java.time.OffsetDateTime
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
object OffsetDateTimeSerializer : KSerializer<OffsetDateTime> {
|
||||
|
||||
private val formatter: DateTimeFormatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME
|
||||
|
||||
override val descriptor: SerialDescriptor =
|
||||
PrimitiveSerialDescriptor(OffsetDateTime::class.qualifiedName!!, PrimitiveKind.STRING)
|
||||
|
||||
override fun deserialize(decoder: Decoder): OffsetDateTime =
|
||||
OffsetDateTime.parse(decoder.decodeString(), formatter)
|
||||
|
||||
override fun serialize(encoder: Encoder, value: OffsetDateTime) =
|
||||
encoder.encodeString(formatter.format(value))
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user