diff --git a/AnimeIndoProvider/build.gradle.kts b/AnimeIndoProvider/build.gradle.kts
new file mode 100644
index 00000000..22c29da9
--- /dev/null
+++ b/AnimeIndoProvider/build.gradle.kts
@@ -0,0 +1,27 @@
+// use an integer for version numbers
+version = 1
+
+
+cloudstream {
+ language = "id"
+ // All of these properties are optional, you can safely remove them
+
+ // description = "Lorem Ipsum"
+ authors = listOf("Hexated")
+
+ /**
+ * Status int as the following:
+ * 0: Down
+ * 1: Ok
+ * 2: Slow
+ * 3: Beta only
+ * */
+ status = 1 // will be 3 if unspecified
+ tvTypes = listOf(
+ "AnimeMovie",
+ "OVA",
+ "Anime",
+ )
+
+ iconUrl = "https://www.google.com/s2/favicons?domain=animeindo.sbs&sz=%size%"
+}
\ No newline at end of file
diff --git a/AnimeIndoProvider/src/main/AndroidManifest.xml b/AnimeIndoProvider/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..874740e3
--- /dev/null
+++ b/AnimeIndoProvider/src/main/AndroidManifest.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/AnimeIndoProvider/src/main/kotlin/com/hexated/AnimeIndoProvider.kt b/AnimeIndoProvider/src/main/kotlin/com/hexated/AnimeIndoProvider.kt
new file mode 100644
index 00000000..6957da14
--- /dev/null
+++ b/AnimeIndoProvider/src/main/kotlin/com/hexated/AnimeIndoProvider.kt
@@ -0,0 +1,192 @@
+package com.hexated
+
+import com.lagradost.cloudstream3.*
+import com.lagradost.cloudstream3.APIHolder.getCaptchaToken
+import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer
+import com.lagradost.cloudstream3.utils.ExtractorLink
+import com.lagradost.cloudstream3.utils.loadExtractor
+import com.lagradost.nicehttp.NiceResponse
+import org.jsoup.Jsoup
+import org.jsoup.nodes.Element
+
+class AnimeIndoProvider : MainAPI() {
+ override var mainUrl = "https://animeindo.sbs"
+ override var name = "AnimeIndo"
+ override val hasMainPage = true
+ override var lang = "id"
+ override val hasDownloadSupport = true
+
+ override val supportedTypes = setOf(
+ TvType.Anime,
+ TvType.AnimeMovie,
+ TvType.OVA
+ )
+
+ companion object {
+ fun getType(t: String): TvType {
+ return if (t.contains("OVA") || t.contains("Special")) TvType.OVA
+ else if (t.contains("Movie")) TvType.AnimeMovie
+ else TvType.Anime
+ }
+
+ fun getStatus(t: String): ShowStatus {
+ return when (t) {
+ "Finished Airing" -> ShowStatus.Completed
+ "Currently Airing" -> ShowStatus.Ongoing
+ else -> ShowStatus.Completed
+ }
+ }
+
+ private suspend fun request(url: String): NiceResponse {
+ val req = app.get(
+ url,
+ cookies = mapOf("recaptcha_cookie" to "#Asia/Jakarta#-420#win32#Windows#0,false,false#Google Inc. (Intel)~ANGLE (Intel, Intel(R) HD Graphics 400 Direct3D11 vs_5_0 ps_5_0)")
+ )
+ if (req.isSuccessful) {
+ return req
+ } else {
+ val document = app.get(url).document
+ val captchaKey =
+ document.select("script[src*=https://www.google.com/recaptcha/api.js?render=]")
+ .attr("src").substringAfter("render=").substringBefore("&")
+ val token = getCaptchaToken(url, captchaKey)
+ return app.post(
+ url,
+ data = mapOf(
+ "action" to "recaptcha_for_all",
+ "token" to "$token",
+ "sitekey" to captchaKey
+ )
+ )
+ }
+ }
+ }
+
+ override val mainPage = mainPageOf(
+ "$mainUrl/anime-terbaru/page/" to "Anime Terbaru",
+ "$mainUrl/donghua-terbaru/page/" to "Donghua Terbaru"
+ )
+
+ override suspend fun getMainPage(
+ page: Int,
+ request: MainPageRequest
+ ): HomePageResponse {
+ val document = request(request.data + page).document
+ val home = document.select("div.post-show > article").mapNotNull {
+ it.toSearchResult()
+ }
+ return newHomePageResponse(request.name, home)
+ }
+
+ private fun getProperAnimeLink(uri: String): String {
+ return if (uri.contains("/anime/")) {
+ uri
+ } else {
+ var title = uri.substringAfter("$mainUrl/")
+ title = when {
+ (title.contains("-episode")) && !(title.contains("-movie")) -> Regex("(.+)-episode").find(
+ title
+ )?.groupValues?.get(1).toString()
+ (title.contains("-movie")) -> Regex("(.+)-movie").find(title)?.groupValues?.get(
+ 1
+ ).toString()
+ else -> title
+ }
+ "$mainUrl/anime/$title"
+ }
+ }
+
+ private fun Element.toSearchResult(): AnimeSearchResponse? {
+ val title = this.selectFirst("div.title")?.text()?.trim() ?: return null
+ val href = getProperAnimeLink(this.selectFirst("a")!!.attr("href"))
+ val posterUrl = this.select("img[itemprop=image]").attr("src").toString()
+ val type = getType(this.select("div.type").text().trim())
+ val epNum =
+ this.selectFirst("span.episode")?.ownText()?.replace(Regex("[^0-9]"), "")?.trim()
+ ?.toIntOrNull()
+ return newAnimeSearchResponse(title, href, type) {
+ this.posterUrl = posterUrl
+ addSub(epNum)
+ }
+
+ }
+
+ override suspend fun search(query: String): List {
+ val link = "$mainUrl/?s=$query"
+ val document = request(link).document
+
+ return document.select(".site-main.relat > article").map {
+ val title = it.selectFirst("div.title > h2")!!.ownText().trim()
+ val href = it.selectFirst("a")!!.attr("href")
+ val posterUrl = it.selectFirst("img")!!.attr("src").toString()
+ val type = getType(it.select("div.type").text().trim())
+ newAnimeSearchResponse(title, href, type) {
+ this.posterUrl = posterUrl
+ }
+ }
+ }
+
+ override suspend fun load(url: String): LoadResponse {
+ val document = request(url).document
+
+ val title = document.selectFirst("h1.entry-title")?.text().toString().trim()
+ val poster = document.selectFirst("div.thumb > img[itemprop=image]")?.attr("src")
+ val tags = document.select("div.genxed > a").map { it.text() }
+ val type = getType(
+ document.selectFirst("div.info-content > div.spe > span:nth-child(6)")?.ownText()
+ .toString()
+ )
+ val year = Regex("\\d, ([0-9]*)").find(
+ document.select("div.info-content > div.spe > span:nth-child(9) > time").text()
+ )?.groupValues?.get(1)?.toIntOrNull()
+ val status = getStatus(
+ document.selectFirst("div.info-content > div.spe > span:nth-child(1)")!!.ownText()
+ .trim()
+ )
+ val description = document.select("div[itemprop=description] > p").text()
+ val trailer = document.selectFirst("div.player-embed iframe")?.attr("src")
+ val episodes = document.select("div.lstepsiode.listeps ul li").mapNotNull {
+ val header = it.selectFirst("span.lchx > a") ?: return@mapNotNull null
+ val name = header.text().trim()
+ val episode = header.text().trim().replace("Episode", "").trim().toIntOrNull()
+ val link = fixUrl(header.attr("href"))
+ Episode(link, name = name, episode = episode)
+ }.reversed()
+
+ return newAnimeLoadResponse(title, url, type) {
+ engName = title
+ posterUrl = poster
+ this.year = year
+ addEpisodes(DubStatus.Subbed, episodes)
+ showStatus = status
+ plot = description
+ this.tags = tags
+ addTrailer(trailer)
+ }
+ }
+
+ override suspend fun loadLinks(
+ data: String,
+ isCasting: Boolean,
+ subtitleCallback: (SubtitleFile) -> Unit,
+ callback: (ExtractorLink) -> Unit
+ ): Boolean {
+
+ val document = request(data).document
+ document.select("div.itemleft > .mirror > option").mapNotNull {
+ fixUrl(Jsoup.parse(base64Decode(it.attr("value"))).select("iframe").attr("src"))
+ }.apmap {
+ if (it.startsWith("https://uservideo.xyz")) {
+ app.get(it, referer = "$mainUrl/").document.select("iframe").attr("src")
+ } else {
+ it
+ }
+ }.apmap {
+ loadExtractor(it, data, subtitleCallback, callback)
+ }
+
+ return true
+ }
+
+
+}
\ No newline at end of file
diff --git a/AnimeIndoProvider/src/main/kotlin/com/hexated/AnimeIndoProviderPlugin.kt b/AnimeIndoProvider/src/main/kotlin/com/hexated/AnimeIndoProviderPlugin.kt
new file mode 100644
index 00000000..7f4d0a0d
--- /dev/null
+++ b/AnimeIndoProvider/src/main/kotlin/com/hexated/AnimeIndoProviderPlugin.kt
@@ -0,0 +1,14 @@
+
+package com.hexated
+
+import com.lagradost.cloudstream3.plugins.CloudstreamPlugin
+import com.lagradost.cloudstream3.plugins.Plugin
+import android.content.Context
+
+@CloudstreamPlugin
+class AnimeIndoProviderPlugin: Plugin() {
+ override fun load(context: Context) {
+ // All providers should be added in this manner. Please don't edit the providers list directly.
+ registerMainAPI(AnimeIndoProvider())
+ }
+}
\ No newline at end of file
diff --git a/AnimeSailProvider/build.gradle.kts b/AnimeSailProvider/build.gradle.kts
new file mode 100644
index 00000000..7fcac9c3
--- /dev/null
+++ b/AnimeSailProvider/build.gradle.kts
@@ -0,0 +1,27 @@
+// use an integer for version numbers
+version = 2
+
+
+cloudstream {
+ language = "id"
+ // All of these properties are optional, you can safely remove them
+
+ // description = "Lorem Ipsum"
+ authors = listOf("Hexated")
+
+ /**
+ * Status int as the following:
+ * 0: Down
+ * 1: Ok
+ * 2: Slow
+ * 3: Beta only
+ * */
+ status = 1 // will be 3 if unspecified
+ tvTypes = listOf(
+ "AnimeMovie",
+ "Anime",
+ "OVA",
+ )
+
+ iconUrl = "https://www.google.com/s2/favicons?domain=111.90.143.42&sz=%size%"
+}
\ No newline at end of file
diff --git a/AnimeSailProvider/src/main/AndroidManifest.xml b/AnimeSailProvider/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..874740e3
--- /dev/null
+++ b/AnimeSailProvider/src/main/AndroidManifest.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/AnimeSailProvider/src/main/kotlin/com/hexated/AnimeSailProvider.kt b/AnimeSailProvider/src/main/kotlin/com/hexated/AnimeSailProvider.kt
new file mode 100644
index 00000000..fc0e11ca
--- /dev/null
+++ b/AnimeSailProvider/src/main/kotlin/com/hexated/AnimeSailProvider.kt
@@ -0,0 +1,195 @@
+package com.hexated
+
+import com.lagradost.cloudstream3.*
+import com.lagradost.cloudstream3.mvvm.safeApiCall
+import com.lagradost.cloudstream3.utils.ExtractorLink
+import com.lagradost.cloudstream3.utils.Qualities
+import com.lagradost.cloudstream3.utils.loadExtractor
+import com.lagradost.nicehttp.NiceResponse
+import org.jsoup.Jsoup
+import org.jsoup.nodes.Element
+
+class AnimeSailProvider : MainAPI() {
+ override var mainUrl = "https://111.90.143.42"
+ override var name = "AnimeSail"
+ override val hasMainPage = true
+ override var lang = "id"
+ override val hasDownloadSupport = true
+
+ override val supportedTypes = setOf(
+ TvType.Anime,
+ TvType.AnimeMovie,
+ TvType.OVA
+ )
+
+ companion object {
+ fun getType(t: String): TvType {
+ return if (t.contains("OVA") || t.contains("Special")) TvType.OVA
+ else if (t.contains("Movie")) TvType.AnimeMovie
+ else TvType.Anime
+ }
+
+ fun getStatus(t: String): ShowStatus {
+ return when (t) {
+ "Completed" -> ShowStatus.Completed
+ "Ongoing" -> ShowStatus.Ongoing
+ else -> ShowStatus.Completed
+ }
+ }
+ }
+
+ private suspend fun request(url: String, ref: String? = null): NiceResponse {
+ return app.get(
+ url,
+ headers = mapOf("Accept" to "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8"),
+ cookies = mapOf("_as_ipin_ct" to "ID"),
+ referer = ref
+ )
+ }
+
+ override val mainPage = mainPageOf(
+ "$mainUrl/page/" to "Episode Terbaru",
+ "$mainUrl/movie-terbaru/page/" to "Movie Terbaru",
+ "$mainUrl/genres/donghua/page/" to "Donghua"
+ )
+
+ override suspend fun getMainPage(page: Int, request: MainPageRequest): HomePageResponse {
+ val document = request(request.data + page).document
+ val home = document.select("article").map {
+ it.toSearchResult()
+ }
+ return newHomePageResponse(request.name, home)
+ }
+
+ private fun getProperAnimeLink(uri: String): String {
+ return if (uri.contains("/anime/")) {
+ uri
+ } else {
+ var title = uri.substringAfter("$mainUrl/")
+ title = when {
+ (title.contains("-episode")) && !(title.contains("-movie")) -> title.substringBefore(
+ "-episode"
+ )
+ (title.contains("-movie")) -> title.substringBefore("-movie")
+ else -> title
+ }
+
+ "$mainUrl/anime/$title"
+ }
+ }
+
+ private fun Element.toSearchResult(): AnimeSearchResponse {
+ val href = getProperAnimeLink(fixUrlNull(this.selectFirst("a")?.attr("href")).toString())
+ val title = this.select(".tt > h2").text().trim()
+ val posterUrl = fixUrlNull(this.selectFirst("div.limit img")?.attr("src"))
+ val epNum = this.selectFirst(".tt > h2")?.text()?.let {
+ Regex("Episode\\s?([0-9]+)").find(it)?.groupValues?.getOrNull(1)?.toIntOrNull()
+ }
+ return newAnimeSearchResponse(title, href, TvType.Anime) {
+ this.posterUrl = posterUrl
+ addSub(epNum)
+ }
+
+ }
+
+ override suspend fun search(query: String): List {
+ val link = "$mainUrl/?s=$query"
+ val document = request(link).document
+
+ return document.select("div.listupd article").map {
+ it.toSearchResult()
+ }
+ }
+
+ override suspend fun load(url: String): LoadResponse {
+ val document = request(url).document
+
+ val title = document.selectFirst("h1.entry-title")?.text().toString().trim()
+ val type = getType(
+ document.select("tbody th:contains(Tipe)").next().text()
+ )
+ val episodes = document.select("ul.daftar > li").map {
+ val header = it.select("a").text().trim()
+ val name =
+ Regex("(Episode\\s?[0-9]+)").find(header)?.groupValues?.getOrNull(0) ?: header
+ val link = fixUrl(it.select("a").attr("href"))
+ Episode(link, name = name)
+ }.reversed()
+
+ return newAnimeLoadResponse(title, url, type) {
+ posterUrl = document.selectFirst("div.entry-content > img")?.attr("src")
+ this.year =
+ document.select("tbody th:contains(Dirilis)").next().text().trim().toIntOrNull()
+ addEpisodes(DubStatus.Subbed, episodes)
+ showStatus =
+ getStatus(document.select("tbody th:contains(Status)").next().text().trim())
+ plot = document.selectFirst("div.entry-content > p")?.text()
+ this.tags =
+ document.select("tbody th:contains(Genre)").next().select("a").map { it.text() }
+ }
+ }
+
+ override suspend fun loadLinks(
+ data: String,
+ isCasting: Boolean,
+ subtitleCallback: (SubtitleFile) -> Unit,
+ callback: (ExtractorLink) -> Unit
+ ): Boolean {
+
+ val document = request(data).document
+
+ document.select(".mobius > .mirror > option").apmap {
+ safeApiCall {
+ val iframe = fixUrl(
+ Jsoup.parse(base64Decode(it.attr("data-em"))).select("iframe").attr("src")
+ ?: throw ErrorLoadingException("No iframe found")
+ )
+
+ when {
+ iframe.startsWith("$mainUrl/utils/player/arch/") || iframe.startsWith(
+ "$mainUrl/utils/player/race/"
+ ) -> request(iframe, ref = data).document.select("source").attr("src")
+ .let { link ->
+ val source =
+ when {
+ iframe.contains("/arch/") -> "Arch"
+ iframe.contains("/race/") -> "Race"
+ else -> this.name
+ }
+ val quality =
+ Regex("\\.([0-9]{3,4})\\.").find(link)?.groupValues?.get(1)
+ callback.invoke(
+ ExtractorLink(
+ source = source,
+ name = source,
+ url = link,
+ referer = mainUrl,
+ quality = quality?.toIntOrNull() ?: Qualities.Unknown.value
+ )
+ )
+ }
+// skip for now
+// iframe.startsWith("$mainUrl/utils/player/fichan/") -> ""
+// iframe.startsWith("$mainUrl/utils/player/blogger/") -> ""
+ iframe.startsWith("https://aghanim.xyz/tools/redirect/") -> {
+ val link = "https://rasa-cintaku-semakin-berantai.xyz/v/${iframe.substringAfter("id=").substringBefore("&token")}"
+ loadExtractor(link, mainUrl, subtitleCallback, callback)
+ }
+ iframe.startsWith("$mainUrl/utils/player/framezilla/") || iframe.startsWith("https://uservideo.xyz") -> {
+ request(iframe, ref = data).document.select("iframe").attr("src")
+ .let { link ->
+ loadExtractor(fixUrl(link), mainUrl, subtitleCallback, callback)
+ }
+ }
+ else -> {
+ loadExtractor(iframe, mainUrl, subtitleCallback, callback)
+ }
+ }
+ }
+ }
+
+ return true
+ }
+
+
+}
\ No newline at end of file
diff --git a/AnimeSailProvider/src/main/kotlin/com/hexated/AnimeSailProviderPlugin.kt b/AnimeSailProvider/src/main/kotlin/com/hexated/AnimeSailProviderPlugin.kt
new file mode 100644
index 00000000..dfdc4c0c
--- /dev/null
+++ b/AnimeSailProvider/src/main/kotlin/com/hexated/AnimeSailProviderPlugin.kt
@@ -0,0 +1,14 @@
+
+package com.hexated
+
+import com.lagradost.cloudstream3.plugins.CloudstreamPlugin
+import com.lagradost.cloudstream3.plugins.Plugin
+import android.content.Context
+
+@CloudstreamPlugin
+class AnimeSailProviderPlugin: Plugin() {
+ override fun load(context: Context) {
+ // All providers should be added in this manner. Please don't edit the providers list directly.
+ registerMainAPI(AnimeSailProvider())
+ }
+}
\ No newline at end of file
diff --git a/Anizm/build.gradle.kts b/Anizm/build.gradle.kts
new file mode 100644
index 00000000..6c69805d
--- /dev/null
+++ b/Anizm/build.gradle.kts
@@ -0,0 +1,27 @@
+// use an integer for version numbers
+version = 1
+
+
+cloudstream {
+ language = "tr"
+ // All of these properties are optional, you can safely remove them
+
+ // description = "Lorem Ipsum"
+ authors = listOf("Hexated")
+
+ /**
+ * Status int as the following:
+ * 0: Down
+ * 1: Ok
+ * 2: Slow
+ * 3: Beta only
+ * */
+ status = 1 // will be 3 if unspecified
+ tvTypes = listOf(
+ "AnimeMovie",
+ "Anime",
+ "OVA",
+ )
+
+ iconUrl = "https://www.google.com/s2/favicons?domain=anizm.net&sz=%size%"
+}
\ No newline at end of file
diff --git a/Anizm/src/main/AndroidManifest.xml b/Anizm/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..874740e3
--- /dev/null
+++ b/Anizm/src/main/AndroidManifest.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/Anizm/src/main/kotlin/com/hexated/Anizm.kt b/Anizm/src/main/kotlin/com/hexated/Anizm.kt
new file mode 100644
index 00000000..1d5fb8c0
--- /dev/null
+++ b/Anizm/src/main/kotlin/com/hexated/Anizm.kt
@@ -0,0 +1,195 @@
+package com.hexated
+
+import android.util.Log
+import com.fasterxml.jackson.annotation.JsonProperty
+import com.lagradost.cloudstream3.*
+import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer
+import com.lagradost.cloudstream3.mvvm.safeApiCall
+import com.lagradost.cloudstream3.utils.*
+import org.jsoup.Jsoup
+import org.jsoup.nodes.Element
+
+
+class Anizm : MainAPI() {
+ override var mainUrl = "https://anizm.net"
+ override var name = "Anizm"
+ override val hasMainPage = true
+ override var lang = "tr"
+ override val hasDownloadSupport = true
+
+ override val supportedTypes = setOf(
+ TvType.Anime,
+ TvType.AnimeMovie,
+ TvType.OVA
+ )
+
+ companion object {
+ private const val mainServer = "https://anizmplayer.com"
+ }
+
+ override val mainPage = mainPageOf(
+ "$mainUrl/anime-izle?sayfa=" to "Son Eklenen Animeler",
+ )
+
+ override suspend fun getMainPage(
+ page: Int,
+ request: MainPageRequest
+ ): HomePageResponse {
+ val document = app.get(request.data + page).document
+ val home = document.select("div.restrictedWidth div#episodesMiddle").mapNotNull {
+ it.toSearchResult()
+ }
+ return newHomePageResponse(request.name, home)
+ }
+
+ private fun getProperAnimeLink(uri: String): String {
+ return if (uri.contains("-bolum")) {
+ "$mainUrl/${uri.substringAfter("$mainUrl/").replace(Regex("-[0-9]+-bolum.*"), "")}"
+ } else {
+ uri
+ }
+ }
+
+ private fun Element.toSearchResult(): AnimeSearchResponse? {
+ val href = getProperAnimeLink(this.selectFirst("a")!!.attr("href"))
+ val title = this.selectFirst("div.title, h5.animeTitle a")?.text() ?: return null
+ val posterUrl = fixUrlNull(this.selectFirst("img")?.attr("src"))
+ val episode = this.selectFirst("div.truncateText")?.text()?.let {
+ Regex("([0-9]+).\\s?Bölüm").find(it)?.groupValues?.getOrNull(1)?.toIntOrNull()
+ }
+
+ return newAnimeSearchResponse(title, href, TvType.Anime) {
+ this.posterUrl = posterUrl
+ addSub(episode)
+ }
+ }
+
+ override suspend fun search(query: String): List {
+ val document = app.get(
+ "$mainUrl/fullViewSearch?search=$query&skip=0",
+ headers = mapOf("X-Requested-With" to "XMLHttpRequest")
+ ).document
+
+ return document.select("div.searchResultItem").mapNotNull {
+ it.toSearchResult()
+ }
+ }
+
+ override suspend fun load(url: String): LoadResponse {
+ val document = app.get(url).document
+
+ val title = document.selectFirst("h2.anizm_pageTitle a")!!.text().trim()
+ val type =
+ if (document.select("div.ui.grid div.four.wide").size == 1) TvType.Movie else TvType.Anime
+ val trailer = document.select("div.yt-hd-thumbnail-inner-container iframe").attr("src")
+ val episodes = document.select("div.ui.grid div.four.wide").map {
+ val name = it.select("div.episodeBlock").text()
+ val link = fixUrl(it.selectFirst("a")?.attr("href").toString())
+ Episode(link, name)
+ }
+ return newAnimeLoadResponse(title, url, type) {
+ posterUrl = fixUrlNull(document.selectFirst("div.infoPosterImg > img")?.attr("src"))
+ this.year = document.select("div.infoSta ul li:first-child").text().trim().toIntOrNull()
+ addEpisodes(DubStatus.Subbed, episodes)
+ plot = document.select("div.infoDesc").text().trim()
+ this.tags = document.select("span.dataValue span.ui.label").map { it.text() }
+ addTrailer(trailer)
+ }
+ }
+
+ private suspend fun invokeLokalSource(
+ url: String,
+ translator: String,
+ sourceCallback: (ExtractorLink) -> Unit
+ ) {
+ app.get(url, referer = "$mainUrl/").document.select("script").find { script ->
+ script.data().contains("eval(function(p,a,c,k,e,d)")
+ }?.let {
+ val key = getAndUnpack(it.data()).substringAfter("FirePlayer(\"").substringBefore("\",")
+ val referer = "$mainServer/video/$key"
+ val link = "$mainServer/player/index.php?data=$key&do=getVideo"
+ Log.i("hexated", link)
+ app.post(
+ link,
+ data = mapOf("hash" to key, "r" to "$mainUrl/"),
+ referer = referer,
+ headers = mapOf(
+ "Accept" to "*/*",
+ "Origin" to mainServer,
+ "Content-Type" to "application/x-www-form-urlencoded; charset=UTF-8",
+ "X-Requested-With" to "XMLHttpRequest"
+ )
+ ).parsedSafe