diff --git a/DramaidProvider/src/main/kotlin/com/hexated/DramaidProvider.kt b/DramaidProvider/src/main/kotlin/com/hexated/DramaidProvider.kt index 17f9b7e1..522b388f 100644 --- a/DramaidProvider/src/main/kotlin/com/hexated/DramaidProvider.kt +++ b/DramaidProvider/src/main/kotlin/com/hexated/DramaidProvider.kt @@ -93,11 +93,9 @@ open class DramaidProvider : MainAPI() { val episodes = document.select(".eplister > ul > li").mapNotNull { val name = it.selectFirst("a > .epl-title")?.text() val link = fixUrl(it.selectFirst("a")?.attr("href") ?: return@mapNotNull null) - val epNum = it.selectFirst(".epl-num")?.text()?.toIntOrNull() Episode( link, name, - episode = epNum ) }.reversed() diff --git a/DramaidProvider/src/main/kotlin/com/hexated/Oppadrama.kt b/DramaidProvider/src/main/kotlin/com/hexated/Oppadrama.kt index 21a0aeb7..8d8734e0 100644 --- a/DramaidProvider/src/main/kotlin/com/hexated/Oppadrama.kt +++ b/DramaidProvider/src/main/kotlin/com/hexated/Oppadrama.kt @@ -3,7 +3,7 @@ package com.hexated import com.lagradost.cloudstream3.extractors.Filesim class Oppadrama : DramaidProvider() { - override var mainUrl = "http://185.217.95.34" + override var mainUrl = "http://185.217.95.30" override var name = "Oppadrama" } diff --git a/Gomov/build.gradle.kts b/Gomov/build.gradle.kts index 9aa3966a..5ef214de 100644 --- a/Gomov/build.gradle.kts +++ b/Gomov/build.gradle.kts @@ -1,7 +1,7 @@ import org.jetbrains.kotlin.konan.properties.Properties // use an integer for version numbers -version = 17 +version = 18 android { defaultConfig { diff --git a/Gomov/src/main/kotlin/com/hexated/Extractors.kt b/Gomov/src/main/kotlin/com/hexated/Extractors.kt index 039b639b..fe627ba9 100644 --- a/Gomov/src/main/kotlin/com/hexated/Extractors.kt +++ b/Gomov/src/main/kotlin/com/hexated/Extractors.kt @@ -25,6 +25,11 @@ class FilelionsTo : Filesim() { override var mainUrl = "https://filelions.to" } +class FilelionsOn : Filesim() { + override val name = "Filelions" + override var mainUrl = "https://filelions.online" +} + class Lylxan : Filesim() { override val name = "Lylxan" override var mainUrl = "https://lylxan.com" diff --git a/Gomov/src/main/kotlin/com/hexated/GomovPlugin.kt b/Gomov/src/main/kotlin/com/hexated/GomovPlugin.kt index 8ee692f2..517fee2a 100644 --- a/Gomov/src/main/kotlin/com/hexated/GomovPlugin.kt +++ b/Gomov/src/main/kotlin/com/hexated/GomovPlugin.kt @@ -21,5 +21,6 @@ class GomovPlugin: Plugin() { registerExtractorAPI(Embedwish()) registerExtractorAPI(Doods()) registerExtractorAPI(Lylxan()) + registerExtractorAPI(FilelionsOn()) } } \ No newline at end of file diff --git a/NontonAnimeIDProvider/build.gradle.kts b/NontonAnimeIDProvider/build.gradle.kts index 7cefbfbb..10f41f92 100644 --- a/NontonAnimeIDProvider/build.gradle.kts +++ b/NontonAnimeIDProvider/build.gradle.kts @@ -1,5 +1,5 @@ // use an integer for version numbers -version = 18 +version = 19 cloudstream { diff --git a/NontonAnimeIDProvider/src/main/kotlin/com/hexated/NontonAnimeIDProvider.kt b/NontonAnimeIDProvider/src/main/kotlin/com/hexated/NontonAnimeIDProvider.kt index e3949a64..1735efe3 100644 --- a/NontonAnimeIDProvider/src/main/kotlin/com/hexated/NontonAnimeIDProvider.kt +++ b/NontonAnimeIDProvider/src/main/kotlin/com/hexated/NontonAnimeIDProvider.kt @@ -44,46 +44,24 @@ class NontonAnimeIDProvider : MainAPI() { } } + override val mainPage = mainPageOf( + "" to "Latest Update", + "ongoing-list/" to " Ongoing List", + "popular-series/" to "Popular Series", + ) + override suspend fun getMainPage(page: Int, request : MainPageRequest): HomePageResponse { - val document = app.get(mainUrl).document - - val homePageList = ArrayList() - - document.select("section#postbaru").forEach { block -> - val header = block.selectFirst("h2")!!.text().trim() - val animes = block.select("article.animeseries").mapNotNull { - it.toSearchResult() - } - if (animes.isNotEmpty()) homePageList.add(HomePageList(header, animes)) + val document = app.get("$mainUrl/${request.data}").document + val home = document.select(".animeseries").mapNotNull { + it.toSearchResult() } - - document.select("aside#sidebar_right > div.side").forEach { block -> - val header = block.selectFirst("h3")!!.ownText().trim() - val animes = block.select("div.bor").mapNotNull { - it.toSearchResultPopular() - } - if (animes.isNotEmpty()) homePageList.add(HomePageList(header, animes)) - } - - return HomePageResponse(homePageList) + return newHomePageResponse(request.name, home, hasNext = false) } - private fun Element.toSearchResult(): AnimeSearchResponse? { + private fun Element.toSearchResult(): AnimeSearchResponse { val href = fixUrl(this.selectFirst("a")!!.attr("href")) - val title = this.selectFirst("h3.title")?.text() ?: return null - val posterUrl = fixUrl(this.select("img").attr("src")) - - return newAnimeSearchResponse(title, href, TvType.Anime) { - this.posterUrl = posterUrl - addDubStatus(dubExist = false, subExist = true) - } - - } - - private fun Element.toSearchResultPopular(): AnimeSearchResponse? { - val href = fixUrl(this.selectFirst("a")!!.attr("href")) - val title = this.selectFirst("h4")?.text()?.trim() ?: return null - val posterUrl = fixUrl(this.select("img").attr("src")) + val title = this.selectFirst(".title")?.text() ?: "" + val posterUrl = fixUrlNull(this.selectFirst("img")?.attr("data-src")) return newAnimeSearchResponse(title, href, TvType.Anime) { this.posterUrl = posterUrl @@ -207,7 +185,6 @@ class NontonAnimeIDProvider : MainAPI() { ): Boolean { val document = app.get(data).document - val sources = ArrayList() document.select(".container1 > ul > li:not(.boxtab)").apmap { val dataPost = it.attr("data-post") @@ -220,17 +197,14 @@ class NontonAnimeIDProvider : MainAPI() { "action" to "player_ajax", "post" to dataPost, "nume" to dataNume, - "type" to dataType + "type" to dataType, + "nonce" to "e4dd8e45c2" ), referer = data, headers = mapOf("X-Requested-With" to "XMLHttpRequest") - ).document.select("iframe").attr("src") + ).document.selectFirst("iframe")?.attr("src") - sources.add(fixUrl(iframe)) - } - - sources.apmap { - loadExtractor(it, "$mainUrl/", subtitleCallback, callback) + loadExtractor(iframe ?: return@apmap , "$mainUrl/", subtitleCallback, callback) } return true @@ -255,3 +229,15 @@ class KotakAnimeid2 : Hxfile() { override val mainUrl = "https://embed2.kotakanimeid.com" override val requiresReferer = true } + +class KotakAnimeidCom : Hxfile() { + override val name = "KotakAnimeid" + override val mainUrl = "https://nontonanimeid.com" + override val requiresReferer = true +} + +class EmbedKotakAnimeid : Hxfile() { + override val name = "EmbedKotakAnimeid" + override val mainUrl = "https://embed2.kotakanimeid.com" + override val requiresReferer = true +} diff --git a/NontonAnimeIDProvider/src/main/kotlin/com/hexated/NontonAnimeIDProviderPlugin.kt b/NontonAnimeIDProvider/src/main/kotlin/com/hexated/NontonAnimeIDProviderPlugin.kt index 7c445f7f..763e337e 100644 --- a/NontonAnimeIDProvider/src/main/kotlin/com/hexated/NontonAnimeIDProviderPlugin.kt +++ b/NontonAnimeIDProvider/src/main/kotlin/com/hexated/NontonAnimeIDProviderPlugin.kt @@ -11,5 +11,7 @@ class NontonAnimeIDProviderPlugin: Plugin() { // All providers should be added in this manner. Please don't edit the providers list directly. registerMainAPI(NontonAnimeIDProvider()) registerExtractorAPI(KotakAnimeid2()) + registerExtractorAPI(KotakAnimeidCom()) + registerExtractorAPI(EmbedKotakAnimeid()) } } \ No newline at end of file diff --git a/OtakudesuProvider/build.gradle.kts b/OtakudesuProvider/build.gradle.kts index fd37451e..5f46e097 100644 --- a/OtakudesuProvider/build.gradle.kts +++ b/OtakudesuProvider/build.gradle.kts @@ -1,5 +1,5 @@ // use an integer for version numbers -version = 15 +version = 16 cloudstream { diff --git a/OtakudesuProvider/src/main/kotlin/com/hexated/OtakudesuProvider.kt b/OtakudesuProvider/src/main/kotlin/com/hexated/OtakudesuProvider.kt index 6d2b473e..f8215c33 100644 --- a/OtakudesuProvider/src/main/kotlin/com/hexated/OtakudesuProvider.kt +++ b/OtakudesuProvider/src/main/kotlin/com/hexated/OtakudesuProvider.kt @@ -282,3 +282,8 @@ class DesuBeta : JWPlayer() { override val name = "DesuBeta" override val mainUrl = "https://desustream.me/beta/" } + +class Desudesuhd : JWPlayer() { + override val name = "Desudesuhd" + override val mainUrl = "https://desustream.me/desudesuhd/" +} diff --git a/OtakudesuProvider/src/main/kotlin/com/hexated/OtakudesuProviderPlugin.kt b/OtakudesuProvider/src/main/kotlin/com/hexated/OtakudesuProviderPlugin.kt index 462f0bee..0fe85784 100644 --- a/OtakudesuProvider/src/main/kotlin/com/hexated/OtakudesuProviderPlugin.kt +++ b/OtakudesuProvider/src/main/kotlin/com/hexated/OtakudesuProviderPlugin.kt @@ -12,5 +12,6 @@ class OtakudesuProviderPlugin: Plugin() { registerMainAPI(OtakudesuProvider()) registerExtractorAPI(Moedesu()) registerExtractorAPI(DesuBeta()) + registerExtractorAPI(Desudesuhd()) } } \ No newline at end of file diff --git a/Samehadaku/src/main/kotlin/com/hexated/Samehadaku.kt b/Samehadaku/src/main/kotlin/com/hexated/Samehadaku.kt index ce686341..6e1fd705 100644 --- a/Samehadaku/src/main/kotlin/com/hexated/Samehadaku.kt +++ b/Samehadaku/src/main/kotlin/com/hexated/Samehadaku.kt @@ -14,7 +14,7 @@ import org.jsoup.Jsoup import org.jsoup.nodes.Element class Samehadaku : MainAPI() { - override var mainUrl = "https://samehadaku.bond" + override var mainUrl = "https://samehadaku.help" override var name = "Samehadaku" override val hasMainPage = true override var lang = "id" diff --git a/SoraStream/build.gradle.kts b/SoraStream/build.gradle.kts index b2d711ac..a3522600 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 = 175 +version = 176 android { defaultConfig { diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt b/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt index 9f0547ee..7a52b533 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt @@ -1653,15 +1653,12 @@ object SoraExtractor : SoraStream() { "$rStreamAPI/e/?tmdb=$id&s=$season&e=$episode" } - val res = app.get(url).text + val res = app.get(url, referer = "https://watcha.movie/").text val link = Regex("\"file\":\"(http.*?)\"").find(res)?.groupValues?.getOrNull(1) ?: return - delay(1000) - if (!app.get(link, referer = rStreamAPI).isSuccessful) return - callback.invoke( ExtractorLink( - "RStream", "RStream", link, rStreamAPI, Qualities.P720.value, link.contains(".m3u8") + "RStream", "RStream", link, rStreamAPI, Qualities.P720.value, INFER_TYPE ) ) } @@ -2057,7 +2054,7 @@ object SoraExtractor : SoraStream() { ) } - suspend fun invokePrimewire( + suspend fun invokeGomovies( title: String? = null, year: Int? = null, season: Int? = null, @@ -2070,10 +2067,10 @@ object SoraExtractor : SoraStream() { season, episode, callback, - primewireAPI, - "Primewire", - "RvnMfoxhgm", - "vvqUtffkId" + gomoviesAPI, + "Gomovies", + "_smQamBQsETb", + "_sBWcqbTBMaT" ) } @@ -2175,7 +2172,6 @@ object SoraExtractor : SoraStream() { suspend fun invokeWatchOnline( imdbId: String? = null, - tmdbId: Int? = null, title: String? = null, year: Int? = null, season: Int? = null, @@ -2186,98 +2182,59 @@ object SoraExtractor : SoraStream() { val id = imdbId?.removePrefix("tt") val slug = title.createSlug() val url = if (season == null) { - "$watchOnlineAPI/movies/view/$id-$slug-$year" + "$watchOnlineAPI/movies/play/$id-$slug-$year" } else { - "$watchOnlineAPI/shows/view/$id-$slug-$year" + "$watchOnlineAPI/shows/play/$id-$slug-$year" } var res = app.get(url) if (res.code == 403) return - if (!res.isSuccessful) res = searchWatchOnline(title, season, imdbId, tmdbId) ?: return + if (!res.isSuccessful) res = searchWatchOnline(title, season, year) ?: return val doc = res.document - val episodeId = if (season == null) { - doc.selectFirst("div.movie__buttons-items a")?.attr("data-watch-list-media-id") - } else { - doc.select("ul[data-season-episodes=$season] li").find { - it.select("div.episodes__number").text().equals("Episode $episode", true) - }?.attr("data-id-episode") - } ?: return - argamap({ - invokeMonster(res.url.substringAfterLast("/"), episodeId, season, callback) - }, { - val videoUrl = if (season == null) { - "$watchOnlineAPI/api/v1/security/movie-access?id_movie=$episodeId" - } else { - "$watchOnlineAPI/api/v1/security/episode-access?id=$episodeId" - } - - val json = app.get(videoUrl, referer = url).parsedSafe() - - json?.streams?.mapKeys { source -> - callback.invoke( - ExtractorLink( - "WatchOnline", - "WatchOnline", - source.value, - "$watchOnlineAPI/", - getQualityFromName(source.key), - true - ) - ) - } - val subtitles = json?.subtitles as ArrayList> - subtitles.map { sub -> - subtitleCallback.invoke( - SubtitleFile( - sub["language"] ?: return@map, - fixUrl(sub["url"] ?: return@map, watchOnlineAPI) - ) - ) - } - }) - - } - - private suspend fun invokeMonster( - urlSlug: String? = null, - episodeId: String? = null, - season: Int? = null, - callback: (ExtractorLink) -> Unit, - ) { - val monsterMainUrl = "https://lookmovie.foundation" - val viewSlug = if (season == null) { - "movies/view/$urlSlug" - } else { - "shows/view/$urlSlug" - } - val streamUrl = - app.get("$monsterMainUrl/$viewSlug").document.select("a.round-button:first-child") - .attr("href") - val res = app.get(fixUrl(streamUrl, monsterMainUrl)).document - val script = res.selectFirst("script:containsData(hash:)")?.data() + val script = doc.selectFirst("script:containsData(hash:)")?.data() val hash = Regex("hash:\\s*['\"](\\S+)['\"]").find(script ?: return)?.groupValues?.get(1) val expires = Regex("expires:\\s*(\\d+)").find(script)?.groupValues?.get(1) + val episodeId = (if(season == null) { + """id_movie:\s*(\d+)""" + } else { + """episode:\s*['"]$episode['"],[\n\s]+id_episode:\s*(\d+),[\n\s]+season:\s*['"]$season['"]""" + }).let { it.toRegex().find(script)?.groupValues?.get(1) } val videoUrl = if (season == null) { - "$monsterMainUrl/api/v1/security/movie-access?id_movie=$episodeId&hash=$hash&expires=$expires" + "$watchOnlineAPI/api/v1/security/movie-access?id_movie=$episodeId&hash=$hash&expires=$expires" } else { - "$monsterMainUrl/api/v1/security/episode-access?id_episode=$episodeId&hash=$hash&expires=$expires" + "$watchOnlineAPI/api/v1/security/episode-access?id_episode=$episodeId&hash=$hash&expires=$expires" } - app.get( - videoUrl, referer = streamUrl, headers = mapOf("X-Requested-With" to "XMLHttpRequest") - ).parsedSafe()?.streams?.mapKeys { source -> + val sources = app.get( + videoUrl, + referer = url, + headers = mapOf("X-Requested-With" to "XMLHttpRequest") + ).parsedSafe() + + sources?.streams?.mapKeys { source -> callback.invoke( ExtractorLink( "WatchOnline", "WatchOnline", source.value, - "$monsterMainUrl/", + "$watchOnlineAPI/", getQualityFromName(source.key), true ) ) } + + sources?.subtitles?.map { sub -> + val file = sub.file.toString() + subtitleCallback.invoke( + SubtitleFile( + sub.language ?: return@map, + if(file.startsWith("[")) return@map else fixUrl(file, watchOnlineAPI), + ) + ) + } + } suspend fun invokeNinetv( diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraParser.kt b/SoraStream/src/main/kotlin/com/hexated/SoraParser.kt index 88eaabe4..53540acf 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraParser.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraParser.kt @@ -195,19 +195,25 @@ data class JikanResponse( @JsonProperty("data") val data: JikanData? = null, ) -data class WatchOnlineItems( +data class WatchOnlineResults( @JsonProperty("slug") val slug: String? = null, - @JsonProperty("tmdb_id") val tmdb_id: Int? = null, - @JsonProperty("imdb_id") val imdb_id: String? = null, + @JsonProperty("title") val title: String? = null, + @JsonProperty("year") val year: String? = null, ) + data class WatchOnlineSearch( - @JsonProperty("items") val items: ArrayList? = arrayListOf(), + @JsonProperty("result") val result: ArrayList? = arrayListOf(), +) + +data class WatchOnlineSubtitles( + @JsonProperty("language") val language: String? = null, + @JsonProperty("file") val file: Any? = null, ) data class WatchOnlineResponse( @JsonProperty("streams") val streams: HashMap? = null, - @JsonProperty("subtitles") val subtitles: Any? = null, + @JsonProperty("subtitles") val subtitles: ArrayList? = arrayListOf(), ) data class CryMoviesProxyHeaders( diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt b/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt index 7817bd61..c2131aba 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt @@ -42,7 +42,7 @@ import com.hexated.SoraExtractor.invokeMultimovies import com.hexated.SoraExtractor.invokeNetflix import com.hexated.SoraExtractor.invokeNetmovies import com.hexated.SoraExtractor.invokePobmovies -import com.hexated.SoraExtractor.invokePrimewire +import com.hexated.SoraExtractor.invokeGomovies import com.hexated.SoraExtractor.invokePutactor import com.hexated.SoraExtractor.invokeTvMovies import com.hexated.SoraExtractor.invokeUhdmovies @@ -109,7 +109,7 @@ open class SoraStream : TmdbProvider() { const val flixonAPI = "https://flixon.lol" const val smashyStreamAPI = "https://embed.smashystream.com" const val watchSomuchAPI = "https://watchsomuch.tv" // sub only - const val watchOnlineAPI = "https://watchonline.ag" + const val watchOnlineAPI = "https://lookmovie.foundation" const val nineTvAPI = "https://moviesapi.club" const val nowTvAPI = "https://myfilestorage.xyz" const val gokuAPI = "https://goku.sx" @@ -121,7 +121,6 @@ open class SoraStream : TmdbProvider() { const val netmoviesAPI = "https://netmovies.to" const val momentAPI = "https://moment-explanation-i-244.site" const val doomoviesAPI = "https://doomovies.net" - const val primewireAPI = "https://real-primewire.club" const val vidsrctoAPI = "https://vidsrc.to" const val dramadayAPI = "https://dramaday.me" const val animetoshoAPI = "https://animetosho.org" @@ -132,6 +131,7 @@ open class SoraStream : TmdbProvider() { const val netflixAPI = "https://m.netflixmirror.com" const val hdmovies4uAPI = "https://hdmovies4u.name" const val watchflxAPI = "https://watchflx.tv" + const val gomoviesAPI = "https://gomovies-online.cam" const val dotmoviesAPI = "https://dotmovies.today" // INDEX SITE @@ -585,7 +585,7 @@ open class SoraStream : TmdbProvider() { ) }, { - if (!res.isAnime) invokePrimewire(res.title, res.year, res.season, res.episode, callback) + if (!res.isAnime) invokeGomovies(res.title, res.year, res.season, res.episode, callback) }, { if (!res.isAnime) invokePutactor(res.title, res.year, res.season, res.episode, callback) @@ -604,7 +604,6 @@ open class SoraStream : TmdbProvider() { { invokeWatchOnline( res.imdbId, - res.id, res.title, res.airedYear ?: res.year, res.season, diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraStreamLite.kt b/SoraStream/src/main/kotlin/com/hexated/SoraStreamLite.kt index a54b76ca..da2244c5 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraStreamLite.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraStreamLite.kt @@ -27,7 +27,7 @@ import com.hexated.SoraExtractor.invokeMoment import com.hexated.SoraExtractor.invokeMultimovies import com.hexated.SoraExtractor.invokeNetflix import com.hexated.SoraExtractor.invokeNetmovies -import com.hexated.SoraExtractor.invokePrimewire +import com.hexated.SoraExtractor.invokeGomovies import com.hexated.SoraExtractor.invokePutactor import com.hexated.SoraExtractor.invokeVidSrc import com.hexated.SoraExtractor.invokeVidsrcto @@ -207,7 +207,7 @@ class SoraStreamLite : SoraStream() { if (!res.isAnime) invokeFlixon(res.id, res.imdbId, res.season, res.episode, callback) }, { - if (!res.isAnime) invokePrimewire(res.title, res.year, res.season, res.episode, callback) + if (!res.isAnime) invokeGomovies(res.title, res.year, res.season, res.episode, callback) }, { if (!res.isAnime) invokePutactor(res.title, res.year, res.season, res.episode, callback) @@ -215,7 +215,6 @@ class SoraStreamLite : SoraStream() { { invokeWatchOnline( res.imdbId, - res.id, res.title, res.airedYear ?: 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 58bb6573..e662b0c2 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraUtils.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraUtils.kt @@ -841,26 +841,25 @@ fun Document.findTvMoviesIframe(): String? { suspend fun searchWatchOnline( title: String? = null, season: Int? = null, - imdbId: String? = null, - tmdbId: Int? = null, + year: Int? = null, ): NiceResponse? { val wTitle = title?.dropLast(1) // weird but this will make search working val mediaId = app.get( if (season == null) { - "${watchOnlineAPI}/api/v1/movies?filters[q]=$wTitle" + "${watchOnlineAPI}/api/v1/do-search/?q=$wTitle" } else { - "${watchOnlineAPI}/api/v1/shows?filters[q]=$wTitle" + "${watchOnlineAPI}/api/v1/do-search/?q=$wTitle" } - ).parsedSafe()?.items?.find { - it.imdb_id == imdbId || it.tmdb_id == tmdbId || it.imdb_id == imdbId?.removePrefix("tt") + ).parsedSafe()?.result?.find { + it.title.equals(title, true) && it.year.equals("$year") }?.slug return app.get( fixUrl( mediaId ?: return null, if (season == null) { - "${watchOnlineAPI}/movies/view" + "${watchOnlineAPI}/movies/play" } else { - "${watchOnlineAPI}/shows/view" + "${watchOnlineAPI}/shows/play" } ) )