diff --git a/SoraStream/build.gradle.kts b/SoraStream/build.gradle.kts index 65ee9df5..e43f70eb 100644 --- a/SoraStream/build.gradle.kts +++ b/SoraStream/build.gradle.kts @@ -1,7 +1,7 @@ import org.jetbrains.kotlin.konan.properties.Properties // use an integer for version numbers -version = 142 +version = 143 android { defaultConfig { diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt b/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt index 5f105550..754dd9ee 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt @@ -3163,6 +3163,54 @@ object SoraExtractor : SoraStream() { } + suspend fun invokeFourCartoon( + title: String? = null, + year: Int? = null, + season: Int? = null, + episode: Int? = null, + callback: (ExtractorLink) -> Unit + ) { + val fixTitle = title.createSlug() + val headers = mapOf( + "X-Requested-With" to "XMLHttpRequest" + ) + val url = if (season == null) { + "$fourCartoonAPI/movies/$fixTitle-$year" + } else { + "$fourCartoonAPI/episode/$fixTitle-season-$season-episode-$episode" + } + + val document = app.get(url).document + val id = document.selectFirst("input[name=idpost]")?.attr("value") + val server = app.get( + "$fourCartoonAPI/ajax-get-link-stream/?server=streamango&filmId=${id ?: return}", + headers = headers + ).text + val hash = + getAndUnpack(app.get(server, referer = fourCartoonAPI).text).substringAfter("(\"") + .substringBefore("\",") + val iframeUrl = getBaseUrl(server) + val source = app.post( + "$iframeUrl/player/index.php?data=$hash&do=getVideo", data = mapOf( + "hast" to hash, + "r" to "$fourCartoonAPI/", + ), + headers = headers + ).parsedSafe()?.videoSource + + callback.invoke( + ExtractorLink( + "4Cartoon", + "4Cartoon", + source ?: return, + "$iframeUrl/", + Qualities.P720.value, + true, + ) + ) + + } + } diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraParser.kt b/SoraStream/src/main/kotlin/com/hexated/SoraParser.kt index 6651bb7d..9646b846 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraParser.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraParser.kt @@ -500,3 +500,7 @@ data class EMovieTraks( @JsonProperty("file") val file: String? = null, @JsonProperty("label") val label: String? = null, ) + +data class FourCartoonSources( + @JsonProperty("videoSource") val videoSource: String? = null, +) diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt b/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt index faf0f2c7..7aa8b215 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt @@ -50,6 +50,7 @@ import com.hexated.SoraExtractor.invokeShivamhw import com.hexated.SoraExtractor.invokeSmashyStream import com.hexated.SoraExtractor.invokeDumpStream import com.hexated.SoraExtractor.invokeEmovies +import com.hexated.SoraExtractor.invokeFourCartoon import com.hexated.SoraExtractor.invokePobmovies import com.hexated.SoraExtractor.invokeTvMovies import com.hexated.SoraExtractor.invokeUhdmovies @@ -103,7 +104,7 @@ open class SoraStream : TmdbProvider() { const val crunchyrollAPI = "https://beta-api.crunchyroll.com" const val kissKhAPI = "https://kisskh.co" const val lingAPI = "https://ling-online.net" - const val uhdmoviesAPI = "https://uhdmovies.cc" + const val uhdmoviesAPI = "https://uhdmovies.life" const val fwatayakoAPI = "https://5100.svetacdn.in" const val gMoviesAPI = "https://gdrivemovies.xyz" const val fdMoviesAPI = "https://freedrivemovie.lol" @@ -131,6 +132,7 @@ open class SoraStream : TmdbProvider() { const val navyAPI = "https://navy-issue-i-239.site" const val emoviesAPI = "https://emovies.si" const val pobmoviesAPI = "https://pobmovies.cam" + const val fourCartoonAPI = "https://4cartoon.net" // INDEX SITE const val blackMoviesAPI = "https://dl.blacklistedbois.workers.dev/0:" @@ -265,8 +267,7 @@ open class SoraStream : TmdbProvider() { val year = releaseDate?.split("-")?.first()?.toIntOrNull() val rating = res.vote_average.toString().toRatingInt() val genres = res.genres?.mapNotNull { it.name } - val isAnime = - genres?.contains("Animation") == true && (res.original_language == "zh" || res.original_language == "ja") + val isAnime = genres?.contains("Animation") == true && (res.original_language == "zh" || res.original_language == "ja") val keywords = res.keywords?.results?.mapNotNull { it.name }.orEmpty() .ifEmpty { res.keywords?.keywords?.mapNotNull { it.name } } @@ -306,7 +307,7 @@ open class SoraStream : TmdbProvider() { epsTitle = eps.name, jpTitle = res.alternative_titles?.results?.find { it.iso_3166_1 == "JP" }?.title, date = season.airDate, - airedDate = res.releaseDate ?: res.firstAirDate + airedDate = res.releaseDate ?: res.firstAirDate, ).toJson(), name = eps.name + if(isUpcoming(eps.airDate)) " - [UPCOMING]" else "", season = eps.seasonNumber, @@ -350,7 +351,7 @@ open class SoraStream : TmdbProvider() { orgTitle = orgTitle, isAnime = isAnime, jpTitle = res.alternative_titles?.results?.find { it.iso_3166_1 == "JP" }?.title, - airedDate = res.releaseDate ?: res.firstAirDate + airedDate = res.releaseDate ?: res.firstAirDate, ).toJson(), ) { this.posterUrl = poster @@ -497,7 +498,7 @@ open class SoraStream : TmdbProvider() { ) }, { - invokeKimcartoon(res.title, res.season, res.episode, subtitleCallback, callback) + if(!res.isAnime) invokeKimcartoon(res.title, res.season, res.episode, subtitleCallback, callback) }, { invokeXmovies( @@ -812,6 +813,9 @@ open class SoraStream : TmdbProvider() { }, { if(!res.isAnime && res.season == null) invokePobmovies(res.title, res.year, callback) + }, + { + if(!res.isAnime) invokeFourCartoon(res.title, res.year, res.season, res.episode, callback) } ) diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraStreamLite.kt b/SoraStream/src/main/kotlin/com/hexated/SoraStreamLite.kt index 247485ab..6f02e50a 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraStreamLite.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraStreamLite.kt @@ -28,6 +28,7 @@ import com.hexated.SoraExtractor.invokeSeries9 import com.hexated.SoraExtractor.invokeSmashyStream import com.hexated.SoraExtractor.invokeDumpStream import com.hexated.SoraExtractor.invokeEmovies +import com.hexated.SoraExtractor.invokeFourCartoon import com.hexated.SoraExtractor.invokeVidSrc import com.hexated.SoraExtractor.invokeWatchOnline import com.hexated.SoraExtractor.invokeWatchsomuch @@ -187,7 +188,7 @@ class SoraStreamLite : SoraStream() { ) }, { - invokeKimcartoon(res.title, res.season, res.episode, subtitleCallback, callback) + if(!res.isAnime) invokeKimcartoon(res.title, res.season, res.episode, subtitleCallback, callback) }, { invokeSmashyStream( @@ -299,6 +300,15 @@ class SoraStreamLite : SoraStream() { callback ) }, + { + if(!res.isAnime) invokeFourCartoon( + res.title, + res.year, + res.season, + res.episode, + callback + ) + } ) return true