From 9de4e22cba3bc310e9e2a54d8334c63bbb9f1c72 Mon Sep 17 00:00:00 2001 From: Luna712 <142361265+Luna712@users.noreply.github.com> Date: Wed, 3 Jun 2026 17:07:59 -0600 Subject: [PATCH 1/3] Make some classes serializable with backward compatibility --- .../com/lagradost/cloudstream3/MainAPI.kt | 60 +++++++++++-------- .../cloudstream3/utils/ExtractorApi.kt | 4 +- 2 files changed, 38 insertions(+), 26 deletions(-) diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/MainAPI.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/MainAPI.kt index 5d4deba2432..1464142489d 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/MainAPI.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/MainAPI.kt @@ -35,9 +35,11 @@ import kotlinx.datetime.format.byUnicodePattern import kotlinx.datetime.format.char import kotlinx.datetime.format.parse import kotlinx.datetime.toInstant +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.Json import java.net.URI import java.util.EnumSet -import kotlinx.serialization.json.Json import kotlin.io.encoding.Base64 import kotlin.io.encoding.ExperimentalEncodingApi import kotlin.math.absoluteValue @@ -384,18 +386,19 @@ const val PROVIDER_STATUS_SLOW = 2 const val PROVIDER_STATUS_OK = 1 const val PROVIDER_STATUS_DOWN = 0 +@Serializable data class ProvidersInfoJson( - @JsonProperty("name") var name: String, - @JsonProperty("url") var url: String, - @JsonProperty("credentials") var credentials: String? = null, - @JsonProperty("status") var status: Int, + @SerialName("name") var name: String, + @SerialName("url") var url: String, + @SerialName("credentials") var credentials: String? = null, + @SerialName("status") var status: Int, ) +@Serializable data class SettingsJson( - @JsonProperty("enableAdult") var enableAdult: Boolean = false, + @SerialName("enableAdult") var enableAdult: Boolean = false, ) - data class MainPageData( val name: String, val data: String, @@ -863,9 +866,10 @@ enum class DubStatus(val id: Int) { * of this as a decimal class specifically for ratings. * */ @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY) +@Serializable class Score private constructor( /** Decimal between [0, 10^9] representing the min score and max score respectively */ - @JsonProperty("data") + @SerialName("data") private val data: Int, ) { override fun hashCode(): Int = this.data.hashCode() @@ -1192,9 +1196,10 @@ suspend fun newSubtitleFile( * @see newAudioFile * */ @ConsistentCopyVisibility +@Serializable data class AudioFile internal constructor( - var url: String, - var headers: Map? = null + @SerialName("url") var url: String, + @SerialName("headers") var headers: Map? = null ) /** Creates an AudioFile with optional initializer for setting additional properties. @@ -2171,6 +2176,7 @@ data class NextAiring( * @param name To be shown next to the season like "Season $displaySeason $name" but if displaySeason is null then "$name" * @param displaySeason What to be displayed next to the season name, if null then the name is the only thing shown. * */ +@Serializable data class SeasonData( val season: Int, val name: String? = null, @@ -2732,32 +2738,38 @@ data class Tracker( val cover: String? = null, ) +@Serializable data class AniSearch( - @JsonProperty("data") var data: Data? = Data() + @SerialName("data") var data: Data? = Data() ) { + @Serializable data class Data( - @JsonProperty("Page") var page: Page? = Page() + @SerialName("Page") @JsonProperty("Page") var page: Page? = Page() ) { + @Serializable data class Page( - @JsonProperty("media") var media: ArrayList = arrayListOf() + @SerialName("media") var media: ArrayList = arrayListOf() ) { + @Serializable data class Media( - @JsonProperty("title") var title: Title? = null, - @JsonProperty("id") var id: Int? = null, - @JsonProperty("idMal") var idMal: Int? = null, - @JsonProperty("seasonYear") var seasonYear: Int? = null, - @JsonProperty("format") var format: String? = null, - @JsonProperty("coverImage") var coverImage: CoverImage? = null, - @JsonProperty("bannerImage") var bannerImage: String? = null, + @SerialName("title") var title: Title? = null, + @SerialName("id") var id: Int? = null, + @SerialName("idMal") var idMal: Int? = null, + @SerialName("seasonYear") var seasonYear: Int? = null, + @SerialName("format") var format: String? = null, + @SerialName("coverImage") var coverImage: CoverImage? = null, + @SerialName("bannerImage") var bannerImage: String? = null, ) { + @Serializable data class CoverImage( - @JsonProperty("extraLarge") var extraLarge: String? = null, - @JsonProperty("large") var large: String? = null, + @SerialName("extraLarge") var extraLarge: String? = null, + @SerialName("large") var large: String? = null, ) + @Serializable data class Title( - @JsonProperty("romaji") var romaji: String? = null, - @JsonProperty("english") var english: String? = null, + @SerialName("romaji") var romaji: String? = null, + @SerialName("english") var english: String? = null, ) { fun isMatchingTitles(title: String?): Boolean { if (title == null) return false diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/utils/ExtractorApi.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/utils/ExtractorApi.kt index f42128b1013..44a20f26348 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/utils/ExtractorApi.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/utils/ExtractorApi.kt @@ -2,7 +2,6 @@ package com.lagradost.cloudstream3.utils -import com.fasterxml.jackson.annotation.JsonIgnore import com.lagradost.cloudstream3.AudioFile import com.lagradost.cloudstream3.IDownloadableMinimum import com.lagradost.cloudstream3.Prerelease @@ -315,6 +314,7 @@ import com.lagradost.cloudstream3.utils.Coroutines.atomicListOf import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.ensureActive +import kotlinx.serialization.Serializable import org.jsoup.Jsoup import java.net.URI import kotlin.coroutines.cancellation.CancellationException @@ -674,6 +674,7 @@ open class DrmExtractorLink private constructor( * @property audioTracks List of separate audio tracks that can be used with this video * @see newExtractorLink * */ +@Serializable open class ExtractorLink @Deprecated("Use newExtractorLink", level = DeprecationLevel.WARNING) constructor( @@ -712,7 +713,6 @@ constructor( return videoSize } - @JsonIgnore fun getAllHeaders(): Map { if (referer.isBlank()) { return headers From f0319f1116ac92f6dc47e36a15839b9c87e783ee Mon Sep 17 00:00:00 2001 From: Luna712 <142361265+Luna712@users.noreply.github.com> Date: Wed, 3 Jun 2026 18:03:45 -0600 Subject: [PATCH 2/3] Add SerialName for consistency --- .../kotlin/com/lagradost/cloudstream3/MainAPI.kt | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/MainAPI.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/MainAPI.kt index 1464142489d..72aac400bd4 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/MainAPI.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/MainAPI.kt @@ -869,8 +869,7 @@ enum class DubStatus(val id: Int) { @Serializable class Score private constructor( /** Decimal between [0, 10^9] representing the min score and max score respectively */ - @SerialName("data") - private val data: Int, + @SerialName("data") private val data: Int, ) { override fun hashCode(): Int = this.data.hashCode() override fun equals(other: Any?): Boolean = other is Score && this.data == other.data @@ -2178,9 +2177,9 @@ data class NextAiring( * */ @Serializable data class SeasonData( - val season: Int, - val name: String? = null, - val displaySeason: Int? = null, // will use season if null + @SerialName("season") val season: Int, + @SerialName("name") val name: String? = null, + @SerialName("displaySeason") val displaySeason: Int? = null, // will use season if null ) /** Abstract interface of EpisodeResponse */ From 7caa7e22f4110968837bbdcf8942d159c589f19c Mon Sep 17 00:00:00 2001 From: Luna712 <142361265+Luna712@users.noreply.github.com> Date: Wed, 3 Jun 2026 18:11:19 -0600 Subject: [PATCH 3/3] Add SerialName for consistency --- .../cloudstream3/utils/ExtractorApi.kt | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/utils/ExtractorApi.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/utils/ExtractorApi.kt index 44a20f26348..82b8f84e81f 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/utils/ExtractorApi.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/utils/ExtractorApi.kt @@ -314,6 +314,7 @@ import com.lagradost.cloudstream3.utils.Coroutines.atomicListOf import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.ensureActive +import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import org.jsoup.Jsoup import java.net.URI @@ -678,17 +679,17 @@ open class DrmExtractorLink private constructor( open class ExtractorLink @Deprecated("Use newExtractorLink", level = DeprecationLevel.WARNING) constructor( - open val source: String, - open val name: String, - override val url: String, - override var referer: String, - open var quality: Int, - override var headers: Map = mapOf(), + @SerialName("source") open val source: String, + @SerialName("name") open val name: String, + @SerialName("url") override val url: String, + @SerialName("referer") override var referer: String, + @SerialName("quality") open var quality: Int, + @SerialName("headers") override var headers: Map = mapOf(), /** Used for getExtractorVerifierJob() */ - open var extractorData: String? = null, - open var type: ExtractorLinkType, + @SerialName("extractorData") open var extractorData: String? = null, + @SerialName("type") open var type: ExtractorLinkType, /** List of separate audio tracks that can be merged with this video */ - open var audioTracks: List = emptyList(), + @SerialName("audioTracks") open var audioTracks: List = emptyList(), ) : IDownloadableMinimum { val isM3u8: Boolean get() = type == ExtractorLinkType.M3U8 val isDash: Boolean get() = type == ExtractorLinkType.DASH