mirror of
https://github.com/hexated/cloudstream-extensions-hexated.git
synced 2024-08-15 00:03:22 +00:00
parent
36e77332c5
commit
86f2735502
9 changed files with 207 additions and 187 deletions
|
@ -6,10 +6,9 @@ import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer
|
||||||
import com.lagradost.cloudstream3.extractors.Filesim
|
import com.lagradost.cloudstream3.extractors.Filesim
|
||||||
import com.lagradost.cloudstream3.utils.*
|
import com.lagradost.cloudstream3.utils.*
|
||||||
import org.jsoup.nodes.Element
|
import org.jsoup.nodes.Element
|
||||||
import java.net.URLDecoder
|
|
||||||
|
|
||||||
class LayarKacaProvider : MainAPI() {
|
class LayarKacaProvider : MainAPI() {
|
||||||
override var mainUrl = "https://tv3.lk21official.pro"
|
override var mainUrl = "https://tv.lk21official.wiki"
|
||||||
private var seriesUrl = "https://tv1.nontondrama.click"
|
private var seriesUrl = "https://tv1.nontondrama.click"
|
||||||
override var name = "LayarKaca"
|
override var name = "LayarKaca"
|
||||||
override val hasMainPage = true
|
override val hasMainPage = true
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import org.jetbrains.kotlin.konan.properties.Properties
|
import org.jetbrains.kotlin.konan.properties.Properties
|
||||||
|
|
||||||
// use an integer for version numbers
|
// use an integer for version numbers
|
||||||
version = 169
|
version = 170
|
||||||
|
|
||||||
android {
|
android {
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
|
|
|
@ -186,11 +186,6 @@ open class VCloud : ExtractorApi() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class HubcloudLol : VCloud() {
|
|
||||||
override val name = "Hubcloud"
|
|
||||||
override val mainUrl = "https://hubcloud.lol"
|
|
||||||
}
|
|
||||||
|
|
||||||
class Hubcloud : VCloud() {
|
class Hubcloud : VCloud() {
|
||||||
override val name = "Hubcloud"
|
override val name = "Hubcloud"
|
||||||
override val mainUrl = "https://hubcloud.in"
|
override val mainUrl = "https://hubcloud.in"
|
||||||
|
|
|
@ -580,6 +580,56 @@ object SoraExtractor : SoraStream() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun invokeWatchflx(
|
||||||
|
tmdbId: Int? = null,
|
||||||
|
season: Int? = null,
|
||||||
|
episode: Int? = null,
|
||||||
|
callback: (ExtractorLink) -> Unit
|
||||||
|
) {
|
||||||
|
val epsSlug = getEpisodeSlug(season, episode)
|
||||||
|
val cookies = getWatchflxCookies()
|
||||||
|
val url = if (season == null) {
|
||||||
|
"$watchflxAPI/browse/playmovie/$tmdbId/directplay"
|
||||||
|
} else {
|
||||||
|
"$watchflxAPI/Playseries/series/$tmdbId/directplay"
|
||||||
|
}
|
||||||
|
val res = app.get(url, cookies = cookies).document
|
||||||
|
|
||||||
|
val showUrl = if (season == null) {
|
||||||
|
res.selectFirst("iframe.movie_player")?.attr("src")
|
||||||
|
} else {
|
||||||
|
val seasonUrl =
|
||||||
|
res.select("ul.nav.nav-tabs.tabs-left li:matches(Season $season\$) a").attr("href")
|
||||||
|
val episodeUrl = app.get(
|
||||||
|
seasonUrl,
|
||||||
|
cookies = cookies
|
||||||
|
).document.select("div.thumb-nail-list a:contains(${epsSlug.second}:)").attr("href")
|
||||||
|
app.get(episodeUrl, cookies = cookies).document.selectFirst("iframe.movie_player")
|
||||||
|
?.attr("src")
|
||||||
|
}
|
||||||
|
val iframe = app.get(
|
||||||
|
showUrl ?: return, referer = "$watchflxAPI/"
|
||||||
|
).document.selectFirst("div#the_frame iframe")?.attr("src")
|
||||||
|
?.let { fixUrl(it, getBaseUrl(showUrl)) } ?: return
|
||||||
|
|
||||||
|
val video = app.get(iframe.replace("/loc/", "/pro/"), referer = iframe).text.let {
|
||||||
|
"""mp4_url\s*=\s*["'](.*)["'];""".toRegex().find(it)?.groupValues?.getOrNull(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
callback.invoke(
|
||||||
|
ExtractorLink(
|
||||||
|
"Watchflx",
|
||||||
|
"Watchflx",
|
||||||
|
video ?: return,
|
||||||
|
"$watchflxAPI/",
|
||||||
|
Qualities.P1080.value,
|
||||||
|
INFER_TYPE
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun invokeKimcartoon(
|
suspend fun invokeKimcartoon(
|
||||||
title: String? = null,
|
title: String? = null,
|
||||||
season: Int? = null,
|
season: Int? = null,
|
||||||
|
@ -1144,7 +1194,13 @@ object SoraExtractor : SoraStream() {
|
||||||
val aTag = if (season == null) "Download Now" else "V-Cloud"
|
val aTag = if (season == null) "Download Now" else "V-Cloud"
|
||||||
res.select("div.entry-content > $hTag:matches(1080p|2160p)").apmap {
|
res.select("div.entry-content > $hTag:matches(1080p|2160p)").apmap {
|
||||||
val tags = """(?:1080p|2160p)(.*)""".toRegex().find(it.text())?.groupValues?.get(1)?.trim()
|
val tags = """(?:1080p|2160p)(.*)""".toRegex().find(it.text())?.groupValues?.get(1)?.trim()
|
||||||
val href = it.nextElementSibling()?.select("a:contains($aTag)")?.attr("href")
|
val href = it.nextElementSibling()?.select("a:contains($aTag)")?.attr("href")?.let { url ->
|
||||||
|
app.post(
|
||||||
|
"${getBaseUrl(url)}/red.php",
|
||||||
|
data = mapOf("link" to url),
|
||||||
|
referer = "$vegaMoviesAPI/"
|
||||||
|
).text.substringAfter("location.href = \"").substringBefore("\"")
|
||||||
|
}
|
||||||
val selector = if (season == null) "p a:contains(V-Cloud)" else "h4:matches(0?$episode) + p a:contains(V-Cloud)"
|
val selector = if (season == null) "p a:contains(V-Cloud)" else "h4:matches(0?$episode) + p a:contains(V-Cloud)"
|
||||||
val server = app.get(href ?: return@apmap).document.selectFirst("div.entry-content > $selector")
|
val server = app.get(href ?: return@apmap).document.selectFirst("div.entry-content > $selector")
|
||||||
?.attr("href")
|
?.attr("href")
|
||||||
|
@ -1233,6 +1289,45 @@ object SoraExtractor : SoraStream() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun invokeHdmovies4u(
|
||||||
|
title: String? = null,
|
||||||
|
imdbId: String? = null,
|
||||||
|
season: Int? = null,
|
||||||
|
episode: Int? = null,
|
||||||
|
subtitleCallback: (SubtitleFile) -> Unit,
|
||||||
|
callback: (ExtractorLink) -> Unit
|
||||||
|
) {
|
||||||
|
fun String.decodeLink(): String {
|
||||||
|
return base64Decode(this.substringAfterLast("/"))
|
||||||
|
}
|
||||||
|
val (seasonSlug, episodeSlug) = getEpisodeSlug(season, episode)
|
||||||
|
val media = app.get("$hdmovies4uAPI/?s=${if (season == null) imdbId else title}").document
|
||||||
|
.let {
|
||||||
|
val selector = if (season == null) "a" else "a:matches((?i)$title.*Season $season)"
|
||||||
|
it.selectFirst("div.gridxw.gridxe $selector")?.attr("href")
|
||||||
|
}
|
||||||
|
val selector = if (season == null) "1080p|2160p" else "(?i)Episode.*(?:1080p|2160p)"
|
||||||
|
app.get(
|
||||||
|
media ?: return
|
||||||
|
).document.select("section h4:matches($selector)").apmap { ele ->
|
||||||
|
val (tags, size) = ele.select("span").map {
|
||||||
|
it.text()
|
||||||
|
}.let { it[it.lastIndex - 1] to it.last().substringAfter("-").trim() }
|
||||||
|
val link = ele.nextElementSibling()?.select("a:contains(DriveTOT)")?.attr("href")
|
||||||
|
val iframe = bypassBqrecipes(link?.decodeLink() ?: return@apmap).let {
|
||||||
|
if (it?.contains("/pack/") == true) {
|
||||||
|
val href =
|
||||||
|
app.get(it).document.select("table tbody tr:contains(S${seasonSlug}E${episodeSlug}) a")
|
||||||
|
.attr("href")
|
||||||
|
bypassBqrecipes(href.decodeLink())
|
||||||
|
} else {
|
||||||
|
it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
invokeDrivetot(iframe ?: return@apmap, tags, size, subtitleCallback, callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun invokeFwatayako(
|
suspend fun invokeFwatayako(
|
||||||
imdbId: String? = null,
|
imdbId: String? = null,
|
||||||
season: Int? = null,
|
season: Int? = null,
|
||||||
|
@ -1859,25 +1954,12 @@ object SoraExtractor : SoraStream() {
|
||||||
invokeSmashyFfix(it.second, it.first, url, callback)
|
invokeSmashyFfix(it.second, it.first, url, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
it.first.contains("/gtop") -> {
|
it.second.equals("Player FM", true) && !isAnime -> invokeSmashyFm(
|
||||||
invokeSmashyGtop(it.second, it.first, callback)
|
it.second,
|
||||||
}
|
it.first,
|
||||||
|
url,
|
||||||
it.first.contains("/dude_tv") -> {
|
callback
|
||||||
invokeSmashyDude(it.second, it.first, callback)
|
)
|
||||||
}
|
|
||||||
|
|
||||||
it.first.contains("/rip") -> {
|
|
||||||
invokeSmashyRip(it.second, it.first, subtitleCallback, callback)
|
|
||||||
}
|
|
||||||
|
|
||||||
it.first.contains("/im.php") && !isAnime -> {
|
|
||||||
invokeSmashyIm(it.second, it.first, subtitleCallback, callback)
|
|
||||||
}
|
|
||||||
|
|
||||||
it.first.contains("/rw.php") && !isAnime -> {
|
|
||||||
invokeSmashyRw(it.second, it.first, subtitleCallback, callback)
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> return@apmap
|
else -> return@apmap
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,16 +141,6 @@ data class FDAds(
|
||||||
@JsonProperty("linkr") val linkr: String? = null,
|
@JsonProperty("linkr") val linkr: String? = null,
|
||||||
)
|
)
|
||||||
|
|
||||||
data class Smashy1Tracks(
|
|
||||||
@JsonProperty("file") val file: String? = null,
|
|
||||||
@JsonProperty("label") val label: String? = null,
|
|
||||||
)
|
|
||||||
|
|
||||||
data class Smashy1Source(
|
|
||||||
@JsonProperty("file") val file: String? = null,
|
|
||||||
@JsonProperty("tracks") val tracks: ArrayList<Smashy1Tracks>? = arrayListOf(),
|
|
||||||
)
|
|
||||||
|
|
||||||
data class WatchsomuchTorrents(
|
data class WatchsomuchTorrents(
|
||||||
@JsonProperty("id") val id: Int? = null,
|
@JsonProperty("id") val id: Int? = null,
|
||||||
@JsonProperty("movieId") val movieId: Int? = null,
|
@JsonProperty("movieId") val movieId: Int? = null,
|
||||||
|
@ -240,11 +230,6 @@ data class CryMoviesResponse(
|
||||||
@JsonProperty("streams") val streams: List<CryMoviesStream>? = null,
|
@JsonProperty("streams") val streams: List<CryMoviesStream>? = null,
|
||||||
)
|
)
|
||||||
|
|
||||||
data class DudetvSources(
|
|
||||||
@JsonProperty("file") val file: String? = null,
|
|
||||||
@JsonProperty("title") val title: String? = null,
|
|
||||||
)
|
|
||||||
|
|
||||||
data class FmoviesResponses(
|
data class FmoviesResponses(
|
||||||
@JsonProperty("result") val result: FmoviesResult? = null,
|
@JsonProperty("result") val result: FmoviesResult? = null,
|
||||||
)
|
)
|
||||||
|
|
|
@ -38,6 +38,7 @@ import com.hexated.SoraExtractor.invokeSmashyStream
|
||||||
import com.hexated.SoraExtractor.invokeDumpStream
|
import com.hexated.SoraExtractor.invokeDumpStream
|
||||||
import com.hexated.SoraExtractor.invokeEmovies
|
import com.hexated.SoraExtractor.invokeEmovies
|
||||||
import com.hexated.SoraExtractor.invokeFourCartoon
|
import com.hexated.SoraExtractor.invokeFourCartoon
|
||||||
|
import com.hexated.SoraExtractor.invokeHdmovies4u
|
||||||
import com.hexated.SoraExtractor.invokeJump1
|
import com.hexated.SoraExtractor.invokeJump1
|
||||||
import com.hexated.SoraExtractor.invokeMoment
|
import com.hexated.SoraExtractor.invokeMoment
|
||||||
import com.hexated.SoraExtractor.invokeMultimovies
|
import com.hexated.SoraExtractor.invokeMultimovies
|
||||||
|
@ -50,6 +51,7 @@ import com.hexated.SoraExtractor.invokeUhdmovies
|
||||||
import com.hexated.SoraExtractor.invokeVegamovies
|
import com.hexated.SoraExtractor.invokeVegamovies
|
||||||
import com.hexated.SoraExtractor.invokeVidsrcto
|
import com.hexated.SoraExtractor.invokeVidsrcto
|
||||||
import com.hexated.SoraExtractor.invokeWatchOnline
|
import com.hexated.SoraExtractor.invokeWatchOnline
|
||||||
|
import com.hexated.SoraExtractor.invokeWatchflx
|
||||||
import com.hexated.SoraExtractor.invokeWatchsomuch
|
import com.hexated.SoraExtractor.invokeWatchsomuch
|
||||||
import com.lagradost.cloudstream3.LoadResponse.Companion.addImdbId
|
import com.lagradost.cloudstream3.LoadResponse.Companion.addImdbId
|
||||||
import com.lagradost.cloudstream3.LoadResponse.Companion.addTMDbId
|
import com.lagradost.cloudstream3.LoadResponse.Companion.addTMDbId
|
||||||
|
@ -134,6 +136,8 @@ open class SoraStream : TmdbProvider() {
|
||||||
const val jump1API = "https://ca.jump1.net"
|
const val jump1API = "https://ca.jump1.net"
|
||||||
const val vegaMoviesAPI = "https://vegamovies.im"
|
const val vegaMoviesAPI = "https://vegamovies.im"
|
||||||
const val netflixAPI = "https://m.netflixmirror.com"
|
const val netflixAPI = "https://m.netflixmirror.com"
|
||||||
|
const val hdmovies4uAPI = "https://hdmovies4u.name"
|
||||||
|
const val watchflxAPI = "https://watchflx.tv"
|
||||||
|
|
||||||
// INDEX SITE
|
// INDEX SITE
|
||||||
const val dahmerMoviesAPI = "https://edytjedhgmdhm.abfhaqrhbnf.workers.dev"
|
const val dahmerMoviesAPI = "https://edytjedhgmdhm.abfhaqrhbnf.workers.dev"
|
||||||
|
@ -748,6 +752,19 @@ open class SoraStream : TmdbProvider() {
|
||||||
res.episode,
|
res.episode,
|
||||||
callback
|
callback
|
||||||
)
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
if (!res.isAnime) invokeHdmovies4u(
|
||||||
|
res.title,
|
||||||
|
res.imdbId,
|
||||||
|
res.season,
|
||||||
|
res.episode,
|
||||||
|
subtitleCallback,
|
||||||
|
callback
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
if (!res.isAnime) invokeWatchflx(res.id, res.season, res.episode, callback)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ import com.hexated.SoraExtractor.invokePrimewire
|
||||||
import com.hexated.SoraExtractor.invokeVidSrc
|
import com.hexated.SoraExtractor.invokeVidSrc
|
||||||
import com.hexated.SoraExtractor.invokeVidsrcto
|
import com.hexated.SoraExtractor.invokeVidsrcto
|
||||||
import com.hexated.SoraExtractor.invokeWatchOnline
|
import com.hexated.SoraExtractor.invokeWatchOnline
|
||||||
|
import com.hexated.SoraExtractor.invokeWatchflx
|
||||||
import com.hexated.SoraExtractor.invokeWatchsomuch
|
import com.hexated.SoraExtractor.invokeWatchsomuch
|
||||||
import com.lagradost.cloudstream3.SubtitleFile
|
import com.lagradost.cloudstream3.SubtitleFile
|
||||||
import com.lagradost.cloudstream3.argamap
|
import com.lagradost.cloudstream3.argamap
|
||||||
|
@ -320,6 +321,14 @@ class SoraStreamLite : SoraStream() {
|
||||||
callback
|
callback
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
if (!res.isAnime) invokeWatchflx(
|
||||||
|
res.id,
|
||||||
|
res.season,
|
||||||
|
res.episode,
|
||||||
|
callback
|
||||||
|
)
|
||||||
|
},
|
||||||
{
|
{
|
||||||
if(!res.isAnime) invoke2embed(
|
if(!res.isAnime) invoke2embed(
|
||||||
res.imdbId,
|
res.imdbId,
|
||||||
|
|
|
@ -21,6 +21,5 @@ class SoraStreamPlugin: Plugin() {
|
||||||
registerExtractorAPI(VCloud())
|
registerExtractorAPI(VCloud())
|
||||||
registerExtractorAPI(Pixeldra())
|
registerExtractorAPI(Pixeldra())
|
||||||
registerExtractorAPI(Hubcloud())
|
registerExtractorAPI(Hubcloud())
|
||||||
registerExtractorAPI(HubcloudLol())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -9,10 +9,12 @@ import com.hexated.SoraStream.Companion.crunchyrollAPI
|
||||||
import com.hexated.SoraStream.Companion.filmxyAPI
|
import com.hexated.SoraStream.Companion.filmxyAPI
|
||||||
import com.hexated.SoraStream.Companion.fmoviesAPI
|
import com.hexated.SoraStream.Companion.fmoviesAPI
|
||||||
import com.hexated.SoraStream.Companion.gdbot
|
import com.hexated.SoraStream.Companion.gdbot
|
||||||
|
import com.hexated.SoraStream.Companion.hdmovies4uAPI
|
||||||
import com.hexated.SoraStream.Companion.malsyncAPI
|
import com.hexated.SoraStream.Companion.malsyncAPI
|
||||||
import com.hexated.SoraStream.Companion.smashyStreamAPI
|
import com.hexated.SoraStream.Companion.smashyStreamAPI
|
||||||
import com.hexated.SoraStream.Companion.tvMoviesAPI
|
import com.hexated.SoraStream.Companion.tvMoviesAPI
|
||||||
import com.hexated.SoraStream.Companion.watchOnlineAPI
|
import com.hexated.SoraStream.Companion.watchOnlineAPI
|
||||||
|
import com.hexated.SoraStream.Companion.watchflxAPI
|
||||||
import com.hexated.SoraStream.Companion.watchhubApi
|
import com.hexated.SoraStream.Companion.watchhubApi
|
||||||
import com.lagradost.cloudstream3.*
|
import com.lagradost.cloudstream3.*
|
||||||
import com.lagradost.cloudstream3.APIHolder.getCaptchaToken
|
import com.lagradost.cloudstream3.APIHolder.getCaptchaToken
|
||||||
|
@ -43,6 +45,8 @@ import javax.crypto.spec.SecretKeySpec
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
|
var watchflxCookies: Map<String, String>? = null
|
||||||
|
var filmxyCookies: Map<String,String>? = null
|
||||||
val bflixChipperKey = base64DecodeAPI("Yjc=ejM=TzA=YTk=WHE=WnU=bXU=RFo=")
|
val bflixChipperKey = base64DecodeAPI("Yjc=ejM=TzA=YTk=WHE=WnU=bXU=RFo=")
|
||||||
const val bflixKey = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
|
const val bflixKey = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
|
||||||
val encodedIndex = arrayOf(
|
val encodedIndex = arrayOf(
|
||||||
|
@ -484,158 +488,29 @@ suspend fun invokeSmashyFfix(
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun invokeSmashyGtop(
|
suspend fun invokeSmashyFm(
|
||||||
name: String,
|
name: String,
|
||||||
url: String,
|
url: String,
|
||||||
callback: (ExtractorLink) -> Unit
|
ref: String,
|
||||||
) {
|
|
||||||
val doc = app.get(url).document
|
|
||||||
val script = doc.selectFirst("script:containsData(var secret)")?.data() ?: return
|
|
||||||
val secret =
|
|
||||||
script.substringAfter("secret = \"").substringBefore("\";").let { base64Decode(it) }
|
|
||||||
val key = script.substringAfter("token = \"").substringBefore("\";")
|
|
||||||
val source = app.get(
|
|
||||||
"$secret$key",
|
|
||||||
headers = mapOf(
|
|
||||||
"X-Requested-With" to "XMLHttpRequest"
|
|
||||||
)
|
|
||||||
).parsedSafe<Smashy1Source>() ?: return
|
|
||||||
|
|
||||||
val videoUrl = base64Decode(source.file ?: return)
|
|
||||||
if (videoUrl.contains("/bug")) return
|
|
||||||
val quality =
|
|
||||||
Regex("(\\d{3,4})[Pp]").find(videoUrl)?.groupValues?.getOrNull(1)?.toIntOrNull()
|
|
||||||
?: Qualities.P720.value
|
|
||||||
callback.invoke(
|
|
||||||
ExtractorLink(
|
|
||||||
"Smashy [$name]",
|
|
||||||
"Smashy [$name]",
|
|
||||||
videoUrl,
|
|
||||||
"",
|
|
||||||
quality,
|
|
||||||
videoUrl.contains(".m3u8")
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun invokeSmashyDude(
|
|
||||||
name: String,
|
|
||||||
url: String,
|
|
||||||
callback: (ExtractorLink) -> Unit
|
|
||||||
) {
|
|
||||||
val script =
|
|
||||||
app.get(url).document.selectFirst("script:containsData(player =)")?.data() ?: return
|
|
||||||
|
|
||||||
val source = Regex("file:\\s*(\\[.*]),").find(script)?.groupValues?.get(1) ?: return
|
|
||||||
|
|
||||||
tryParseJson<ArrayList<DudetvSources>>(source)?.filter { it.title == "English" }?.map {
|
|
||||||
M3u8Helper.generateM3u8(
|
|
||||||
"Smashy [Player 2]",
|
|
||||||
it.file ?: return@map,
|
|
||||||
""
|
|
||||||
).forEach(callback)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun invokeSmashyRip(
|
|
||||||
name: String,
|
|
||||||
url: String,
|
|
||||||
subtitleCallback: (SubtitleFile) -> Unit,
|
|
||||||
callback: (ExtractorLink) -> Unit,
|
callback: (ExtractorLink) -> Unit,
|
||||||
) {
|
) {
|
||||||
val script =
|
fun String.removeProxy(): String {
|
||||||
app.get(url).document.selectFirst("script:containsData(player =)")?.data() ?: return
|
return if (this.contains("proxy")) {
|
||||||
|
"https${this.substringAfterLast("https")}"
|
||||||
val source = Regex("file:\\s*\"([^\"]+)").find(script)?.groupValues?.get(1)
|
} else {
|
||||||
val subtitle = Regex("subtitle:\\s*\"([^\"]+)").find(script)?.groupValues?.get(1)
|
this
|
||||||
|
}
|
||||||
source?.split(",")?.map { links ->
|
|
||||||
val quality = Regex("\\[(\\d+)]").find(links)?.groupValues?.getOrNull(1)?.trim()
|
|
||||||
val link = links.removePrefix("[$quality]").substringAfter("dev/").trim()
|
|
||||||
if (link.isEmpty()) return@map
|
|
||||||
callback.invoke(
|
|
||||||
ExtractorLink(
|
|
||||||
"Smashy [$name]",
|
|
||||||
"Smashy [$name]",
|
|
||||||
link,
|
|
||||||
"",
|
|
||||||
quality?.toIntOrNull() ?: return@map,
|
|
||||||
isM3u8 = true,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
subtitle?.replace("<br>", "")?.split(",")?.map { sub ->
|
val res = app.get(url, referer = ref).text
|
||||||
val lang = Regex("\\[(.*?)]").find(sub)?.groupValues?.getOrNull(1)?.trim()
|
val source = Regex("['\"]?file['\"]?:\\s*\"([^\"]+)").find(res)?.groupValues?.get(1) ?: return
|
||||||
val link = sub.removePrefix("[$lang]")
|
|
||||||
subtitleCallback.invoke(
|
|
||||||
SubtitleFile(
|
|
||||||
lang.orEmpty().ifEmpty { return@map },
|
|
||||||
link
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun invokeSmashyIm(
|
|
||||||
name: String,
|
|
||||||
url: String,
|
|
||||||
subtitleCallback: (SubtitleFile) -> Unit,
|
|
||||||
callback: (ExtractorLink) -> Unit,
|
|
||||||
) {
|
|
||||||
val script =
|
|
||||||
app.get(url).document.selectFirst("script:containsData(player =)")?.data() ?: return
|
|
||||||
|
|
||||||
val sources =
|
|
||||||
Regex("['\"]?file['\"]?:\\s*\"([^\"]+)").find(script)?.groupValues?.get(1) ?: return
|
|
||||||
val subtitles =
|
|
||||||
Regex("['\"]?subtitle['\"]?:\\s*\"([^\"]+)").find(script)?.groupValues?.get(1) ?: return
|
|
||||||
|
|
||||||
M3u8Helper.generateM3u8(
|
M3u8Helper.generateM3u8(
|
||||||
"Smashy [$name]",
|
"Smashy [$name]",
|
||||||
sources,
|
source.removeProxy(),
|
||||||
""
|
"https://vidstream.pro/"
|
||||||
).forEach(callback)
|
).forEach(callback)
|
||||||
|
|
||||||
subtitles.split(",").map { sub ->
|
|
||||||
val lang = Regex("\\[(.*?)]").find(sub)?.groupValues?.getOrNull(1)?.trim()
|
|
||||||
val trimmedSubLink = sub.removePrefix("[$lang]").trim().substringAfter("?url=")
|
|
||||||
subtitleCallback.invoke(
|
|
||||||
SubtitleFile(
|
|
||||||
lang.takeIf { !it.isNullOrEmpty() } ?: return@map,
|
|
||||||
trimmedSubLink
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun invokeSmashyRw(
|
|
||||||
name: String,
|
|
||||||
url: String,
|
|
||||||
subtitleCallback: (SubtitleFile) -> Unit,
|
|
||||||
callback: (ExtractorLink) -> Unit,
|
|
||||||
) {
|
|
||||||
val res = app.get(url).document
|
|
||||||
val video = res.selectFirst("media-player")?.attr("src")
|
|
||||||
|
|
||||||
M3u8Helper.generateM3u8(
|
|
||||||
"Smashy [$name]",
|
|
||||||
video ?: return,
|
|
||||||
""
|
|
||||||
).forEach(callback)
|
|
||||||
|
|
||||||
res.select("track").map { track ->
|
|
||||||
subtitleCallback.invoke(
|
|
||||||
SubtitleFile(
|
|
||||||
track.attr("label"),
|
|
||||||
track.attr("src"),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getDumpIdAndType(title: String?, year: Int?, season: Int?): Pair<String?, Int?> {
|
suspend fun getDumpIdAndType(title: String?, year: Int?, season: Int?): Pair<String?, Int?> {
|
||||||
|
@ -696,6 +571,52 @@ suspend fun fetchDumpEpisodes(id: String, type: String, episode: Int?): EpisodeV
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun invokeDrivetot(
|
||||||
|
url: String,
|
||||||
|
tags: String? = null,
|
||||||
|
size: String? = null,
|
||||||
|
subtitleCallback: (SubtitleFile) -> Unit,
|
||||||
|
callback: (ExtractorLink) -> Unit,
|
||||||
|
) {
|
||||||
|
val res = app.get(url)
|
||||||
|
val data = res.document.select("form input").associate { it.attr("name") to it.attr("value") }
|
||||||
|
app.post(res.url, data = data, cookies = res.cookies).document.select("div.card-body a").apmap { ele ->
|
||||||
|
val href = base64Decode(ele.attr("href").substringAfterLast("/")).let {
|
||||||
|
if(it.contains("hubcloud.lol")) it.replace("hubcloud.lol", "hubcloud.in") else it
|
||||||
|
}
|
||||||
|
loadExtractor(href, "$hdmovies4uAPI/", subtitleCallback) { link ->
|
||||||
|
callback.invoke(
|
||||||
|
ExtractorLink(
|
||||||
|
link.source,
|
||||||
|
"${link.name} $tags [$size]",
|
||||||
|
link.url,
|
||||||
|
link.referer,
|
||||||
|
link.quality,
|
||||||
|
link.type,
|
||||||
|
link.headers,
|
||||||
|
link.extractorData
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun bypassBqrecipes(url: String): String? {
|
||||||
|
var res = app.get(url)
|
||||||
|
var location = res.text.substringAfter(".replace('").substringBefore("');")
|
||||||
|
var cookies = res.cookies
|
||||||
|
res = app.get(location, cookies = cookies)
|
||||||
|
cookies = cookies + res.cookies
|
||||||
|
val document = res.document
|
||||||
|
location = document.select("form#recaptcha").attr("action")
|
||||||
|
val data =
|
||||||
|
document.select("form#recaptcha input").associate { it.attr("name") to it.attr("value") }
|
||||||
|
res = app.post(location, data = data, cookies = cookies)
|
||||||
|
location = res.document.selectFirst("a#messagedown")?.attr("href") ?: return null
|
||||||
|
cookies = (cookies + res.cookies).minus("var")
|
||||||
|
return app.get(location, cookies = cookies, allowRedirects = false).headers["location"]
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun bypassOuo(url: String?): String? {
|
suspend fun bypassOuo(url: String?): String? {
|
||||||
var res = session.get(url ?: return null)
|
var res = session.get(url ?: return null)
|
||||||
run lit@{
|
run lit@{
|
||||||
|
@ -915,8 +836,6 @@ suspend fun getTvMoviesServer(url: String, season: Int?, episode: Int?): Pair<St
|
||||||
}.lastOrNull()
|
}.lastOrNull()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var filmxyCookies: Map<String,String>? = null
|
|
||||||
suspend fun getFilmxyCookies(url: String) = filmxyCookies ?: fetchFilmxyCookies(url).also { filmxyCookies = it }
|
suspend fun getFilmxyCookies(url: String) = filmxyCookies ?: fetchFilmxyCookies(url).also { filmxyCookies = it }
|
||||||
suspend fun fetchFilmxyCookies(url: String): Map<String, String> {
|
suspend fun fetchFilmxyCookies(url: String): Map<String, String> {
|
||||||
|
|
||||||
|
@ -957,6 +876,21 @@ suspend fun fetchFilmxyCookies(url: String): Map<String, String> {
|
||||||
return cookieJar.plus(defaultCookies)
|
return cookieJar.plus(defaultCookies)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun getWatchflxCookies() = watchflxCookies ?: fetchWatchflxCookies().also { watchflxCookies = it }
|
||||||
|
|
||||||
|
suspend fun fetchWatchflxCookies(): Map<String, String> {
|
||||||
|
session.get(watchflxAPI)
|
||||||
|
val cookies = session.baseClient.cookieJar.loadForRequest(watchflxAPI.toHttpUrl())
|
||||||
|
.associate { it.name to it.value }
|
||||||
|
val loginUrl = "$watchflxAPI/cookie-based-login"
|
||||||
|
session.post(
|
||||||
|
loginUrl, data = mapOf(
|
||||||
|
"continue_as_temp" to "true"
|
||||||
|
), cookies = cookies, headers = mapOf("X-Requested-With" to "XMLHttpRequest")
|
||||||
|
)
|
||||||
|
return session.baseClient.cookieJar.loadForRequest(loginUrl.toHttpUrl()).associate { it.name to it.value }
|
||||||
|
}
|
||||||
|
|
||||||
fun Document.findTvMoviesIframe(): String? {
|
fun Document.findTvMoviesIframe(): String? {
|
||||||
return this.selectFirst("script:containsData(var seconds)")?.data()?.substringAfter("href='")
|
return this.selectFirst("script:containsData(var seconds)")?.data()?.substringAfter("href='")
|
||||||
?.substringBefore("'>")
|
?.substringBefore("'>")
|
||||||
|
|
Loading…
Reference in a new issue