diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt b/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt index 0768de3e..ccdfc5d7 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt @@ -668,29 +668,16 @@ object SoraExtractor : SoraStream() { season: Int? = null, episode: Int? = null, subtitleCallback: (SubtitleFile) -> Unit, - ) { - val (id, type) = getSoraIdAndType(title, year, season) ?: return - val json = fetchSoraEpisodes(id, type, episode) ?: return - - json.subtitlingList?.map { sub -> - subtitleCallback.invoke( - SubtitleFile( - getVipLanguage(sub.languageAbbr ?: return@map), - sub.subtitlingUrl ?: return@map - ) - ) - } - } - - suspend fun invokeSoraStreamLite( - title: String? = null, - year: Int? = null, - season: Int? = null, - episode: Int? = null, - subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit, ) { - val (id, type) = getSoraIdAndType(title, year, season) ?: return + val (id, type) = getSoraIdAndType(title, year, season) ?: return invokeJustchill( + title, + year, + season, + episode, + subtitleCallback, + callback + ) val json = fetchSoraEpisodes(id, type, episode) ?: return json.subtitlingList?.map { sub -> @@ -721,6 +708,69 @@ object SoraExtractor : SoraStream() { } } + suspend fun invokeJustchill( + title: String? = null, + year: Int? = null, + season: Int? = null, + episode: Int? = null, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit, + ) { + val results = + app.get("$chillAPI/api/search?keyword=$title").parsedSafe()?.data?.results + val media = if (results?.size == 1) { + results.firstOrNull() + } else { + results?.find { + when (season) { + null -> { + it.name.equals( + title, + true + ) && it.releaseTime == "$year" + } + 1 -> { + it.name.contains( + "$title", + true + ) && (it.releaseTime == "$year" || it.name.contains("Season $season", true)) + } + else -> { + it.name.contains(Regex("(?i)$title\\s?($season|${season.toRomanNumeral()}|Season\\s$season)")) && it.releaseTime == "$year" + } + } + } + } ?: return + + val episodeId = app.get("$chillAPI/api/detail?id=${media.id}&category=${media.domainType}").parsedSafe()?.data?.episodeVo?.find { + it.seriesNo == (episode ?: 0) + }?.id ?: return + + val sources = app.get("$chillAPI/api/episode?id=${media.id}&category=${media.domainType}&episode=$episodeId").parsedSafe()?.data + + sources?.qualities?.map { source -> + callback.invoke( + ExtractorLink( + "ChillMovie", + "ChillMovie", + source.url ?: return@map null, + "", + source.quality ?: Qualities.Unknown.value, + true, + ) + ) + } + + sources?.subtitles?.map { sub -> + subtitleCallback.invoke( + SubtitleFile( + getVipLanguage(sub.lang ?: return@map), sub.url?.substringAfter("?url=") ?: return@map + ) + ) + } + + } + suspend fun invokeXmovies( title: String? = null, year: Int? = null, @@ -3193,4 +3243,39 @@ data class WatchOnlineSearch( data class WatchOnlineResponse( @JsonProperty("streams") val streams: HashMap? = null, @JsonProperty("subtitles") val subtitles: Any? = null, +) + +data class ChillQualities( + @JsonProperty("quality") val quality: Int? = null, + @JsonProperty("url") val url: String? = null, +) + +data class ChillSubtitles( + @JsonProperty("lang") val lang: String? = null, + @JsonProperty("language") val language: String? = null, + @JsonProperty("url") val url: String? = null, +) + +data class ChillSource( + @JsonProperty("qualities") val qualities: ArrayList? = arrayListOf(), + @JsonProperty("subtitles") val subtitles: ArrayList? = arrayListOf(), +) + +data class ChillSources( + @JsonProperty("data") val data: ChillSource? = null, +) + +data class ChillResults( + @JsonProperty("id") val id: String, + @JsonProperty("domainType") val domainType: Int, + @JsonProperty("name") val name: String, + @JsonProperty("releaseTime") val releaseTime: String, +) + +data class ChillData( + @JsonProperty("results") val results: ArrayList? = arrayListOf(), +) + +data class ChillSearch( + @JsonProperty("data") val data: ChillData? = null, ) \ No newline at end of file diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt b/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt index 311b7217..c8f3e85b 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt @@ -367,6 +367,7 @@ open class SoraStream : TmdbProvider() { res.season, res.episode, subtitleCallback, + callback ) }, { diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraStreamLite.kt b/SoraStream/src/main/kotlin/com/hexated/SoraStreamLite.kt index 57cdcf2e..7609eec1 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraStreamLite.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraStreamLite.kt @@ -20,7 +20,7 @@ import com.hexated.SoraExtractor.invokeMovieHab import com.hexated.SoraExtractor.invokeRStream import com.hexated.SoraExtractor.invokeSeries9 import com.hexated.SoraExtractor.invokeSmashyStream -import com.hexated.SoraExtractor.invokeSoraStreamLite +import com.hexated.SoraExtractor.invokeSoraStream import com.hexated.SoraExtractor.invokeTwoEmbed import com.hexated.SoraExtractor.invokeUniqueStream import com.hexated.SoraExtractor.invokeVidSrc @@ -54,7 +54,7 @@ class SoraStreamLite : SoraStream() { ) }, { - invokeSoraStreamLite( + invokeSoraStream( res.title, res.year, res.season, diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraUtils.kt b/SoraStream/src/main/kotlin/com/hexated/SoraUtils.kt index c9a9b64b..c22f07a8 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraUtils.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraUtils.kt @@ -42,6 +42,7 @@ import kotlin.collections.ArrayList import kotlin.math.min val soraAPI = base64DecodeAPI("cA==YXA=cy8=Y20=di8=LnQ=b2s=a2w=bG8=aS4=YXA=ZS0=aWw=b2I=LW0=Z2E=Ly8=czo=dHA=aHQ=") +val chillAPI = base64DecodeAPI("dg==LnQ=bGw=aGk=dGM=dXM=Lmo=b2s=a2w=bG8=Ly8=czo=dHA=aHQ=") val soraHeaders = mapOf( "lang" to "en",