Skip to content

Commit

Permalink
fix(src/es): Pelisplushd and Hackstore fixes and Voeextractor
Browse files Browse the repository at this point in the history
  • Loading branch information
Dark25 committed Aug 3, 2024
1 parent bec3e2d commit b416818
Show file tree
Hide file tree
Showing 11 changed files with 145 additions and 291 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package eu.kanade.tachiyomi.lib.voeextractor

import android.webkit.CookieManager
import eu.kanade.tachiyomi.network.GET
import okhttp3.Cookie
import okhttp3.HttpUrl
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Response

class DdosGuardInterceptor(private val client: OkHttpClient) : Interceptor {

private val cookieManager by lazy { CookieManager.getInstance() }

override fun intercept(chain: Interceptor.Chain): Response {
val originalRequest = chain.request()
val response = chain.proceed(originalRequest)

// Check if DDos-GUARD is on
if (response.code !in ERROR_CODES || response.header("Server") !in SERVER_CHECK) {
return response
}

response.close()
val cookies = cookieManager.getCookie(originalRequest.url.toString())
val oldCookie = if (cookies != null && cookies.isNotEmpty()) {
cookies.split(";").mapNotNull { Cookie.parse(originalRequest.url, it) }
} else {
emptyList()
}

val ddg2Cookie = oldCookie.firstOrNull { it.name == "__ddg2_" }
if (!ddg2Cookie?.value.isNullOrEmpty()) {
return chain.proceed(originalRequest)
}

val newCookie = getNewCookie(originalRequest.url) ?: return chain.proceed(originalRequest)
val newCookieHeader = buildString {
(oldCookie + newCookie).forEachIndexed { index, cookie ->
if (index > 0) append("; ")
append(cookie.name).append('=').append(cookie.value)
}
}

return chain.proceed(originalRequest.newBuilder().addHeader("cookie", newCookieHeader).build())
}

fun getNewCookie(url: HttpUrl): Cookie? {
val cookies = cookieManager.getCookie(url.toString())
val oldCookie = if (cookies != null && cookies.isNotEmpty()) {
cookies.split(";").mapNotNull { Cookie.parse(url, it) }
} else {
emptyList()
}
val ddg2Cookie = oldCookie.firstOrNull { it.name == "__ddg2_" }
if (!ddg2Cookie?.value.isNullOrEmpty()) {
return ddg2Cookie
}
val wellKnown = client.newCall(GET("https://check.ddos-guard.net/check.js"))
.execute().body.string()
.substringAfter("'", "")
.substringBefore("'", "")
val checkUrl = "${url.scheme}://${url.host + wellKnown}"
return client.newCall(GET(checkUrl)).execute().header("set-cookie")?.let {
Cookie.parse(url, it)
}
}

companion object {
private val ERROR_CODES = listOf(403)
private val SERVER_CHECK = listOf("ddos-guard")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ class VoeExtractor(private val client: OkHttpClient) {

private val json: Json by injectLazy()

private val playlistUtils by lazy { PlaylistUtils(client) }
private val clientDdos by lazy { client.newBuilder().addInterceptor(DdosGuardInterceptor(client)).build() }

private val playlistUtils by lazy { PlaylistUtils(clientDdos) }

private val linkRegex = "(http|https)://([\\w_-]+(?:\\.[\\w_-]+)+)([\\w.,@?^=%&:/~+#-]*[\\w@?^=%&/~+#-])".toRegex()

Expand All @@ -24,7 +26,16 @@ class VoeExtractor(private val client: OkHttpClient) {
data class VideoLinkDTO(val file: String)

fun videosFromUrl(url: String, prefix: String = ""): List<Video> {
val document = client.newCall(GET(url)).execute().asJsoup()
var document = clientDdos.newCall(GET(url)).execute().asJsoup()

if (document.selectFirst("script")?.data()?.contains("if (typeof localStorage !== 'undefined')") == true) {
val originalUrl = document.selectFirst("script")?.data()
?.substringAfter("window.location.href = '")
?.substringBefore("';") ?: return emptyList()

document = clientDdos.newCall(GET(originalUrl)).execute().asJsoup()
}

val script = document.selectFirst("script:containsData(const sources), script:containsData(var sources), script:containsData(wc0)")
?.data()
?: return emptyList()
Expand All @@ -43,7 +54,7 @@ class VoeExtractor(private val client: OkHttpClient) {
else -> return emptyList()
}
return playlistUtils.extractFromHls(playlistUrl,
videoNameGen = { quality -> "${prefix}Voe: $quality" }
videoNameGen = { quality -> "${prefix}Voe:$quality" }
)
}
}
2 changes: 1 addition & 1 deletion src/es/hackstore/build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
ext {
extName = 'Hackstore'
extClass = '.Hackstore'
extVersionCode = 11
extVersionCode = 12
}

apply from: "$rootDir/common.gradle"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,8 @@ class Hackstore : ConfigurableAnimeSource, ParsedAnimeHttpSource() {

override fun episodeListParse(response: Response): List<SEpisode> {
val document = response.asJsoup()
val ismovie = response.request.url.toString().contains("/peliculas/")
return if (ismovie) {
val isMovie = response.request.url.toString().contains("/peliculas/")
return if (isMovie) {
listOf(
SEpisode.create().apply {
name = "PELÍCULA"
Expand All @@ -142,14 +142,14 @@ class Hackstore : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
},
)
} else {
document.select(".movie-thumbnail").map { thumbnail ->
document.select(".movie-thumbnail").mapIndexed { idx, thumbnail ->
val episodeLink = thumbnail.select("a").attr("href")
val seasonMatch = Regex("-(\\d+)x(\\d+)/$").find(episodeLink)
val seasonNumber = seasonMatch?.groups?.get(1)?.value?.toInt() ?: 0
val episodeNumber = seasonMatch?.groups?.get(2)?.value?.toInt() ?: 0
SEpisode.create().apply {
name = "T$seasonNumber - E$episodeNumber"
episode_number = episodeNumber.toFloat()
episode_number = idx + 1f
setUrlWithoutDomain(episodeLink)
}
}
Expand Down Expand Up @@ -196,7 +196,7 @@ class Hackstore : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
server.contains("streamtape") || server.contains("stp") || server.contains("stape") -> {
listOf(streamTapeExtractor.videoFromUrl(url, quality = "$prefix StreamTape")!!)
}
server.contains("voe") -> voeExtractor.videosFromUrl(url, prefix)
server.contains("voe") -> voeExtractor.videosFromUrl(url, "$prefix ")
server.contains("filemoon") -> filemoonExtractor.videosFromUrl(url, prefix = "$prefix Filemoon:")
server.contains("wishembed") || server.contains("streamwish") || server.contains("strwish") || server.contains("wish") -> {
streamWishExtractor.videosFromUrl(url, videoNameGen = { "$prefix StreamWish:$it" })
Expand Down
3 changes: 2 additions & 1 deletion src/es/pelisplushd/build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
ext {
extName = 'Pelisplushd'
extClass = '.PelisplushdFactory'
extVersionCode = 56
extVersionCode = 57
}

apply from: "$rootDir/common.gradle"
Expand All @@ -22,5 +22,6 @@ dependencies {
implementation(project(':lib:burstcloud-extractor'))
implementation(project(':lib:fastream-extractor'))
implementation(project(':lib:upstream-extractor'))
implementation(project(':lib:streamhidevid-extractor'))
implementation libs.jsunpacker
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import android.content.SharedPreferences
import android.util.Base64
import androidx.preference.ListPreference
import androidx.preference.PreferenceScreen
import eu.kanade.tachiyomi.animeextension.es.pelisplushd.extractors.StreamHideExtractor
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
import eu.kanade.tachiyomi.animesource.model.AnimeFilter
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
Expand All @@ -19,6 +18,7 @@ import eu.kanade.tachiyomi.lib.fastreamextractor.FastreamExtractor
import eu.kanade.tachiyomi.lib.filemoonextractor.FilemoonExtractor
import eu.kanade.tachiyomi.lib.mp4uploadextractor.Mp4uploadExtractor
import eu.kanade.tachiyomi.lib.okruextractor.OkruExtractor
import eu.kanade.tachiyomi.lib.streamhidevidextractor.StreamHideVidExtractor
import eu.kanade.tachiyomi.lib.streamlareextractor.StreamlareExtractor
import eu.kanade.tachiyomi.lib.streamtapeextractor.StreamTapeExtractor
import eu.kanade.tachiyomi.lib.streamwishextractor.StreamWishExtractor
Expand All @@ -28,6 +28,7 @@ import eu.kanade.tachiyomi.lib.voeextractor.VoeExtractor
import eu.kanade.tachiyomi.lib.youruploadextractor.YourUploadExtractor
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.util.asJsoup
import eu.kanade.tachiyomi.util.parallelCatchingFlatMapBlocking
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.Request
import okhttp3.Response
Expand Down Expand Up @@ -109,48 +110,52 @@ open class Pelisplushd(override val name: String, override val baseUrl: String)
val apiUrl = data?.substringAfter("video[1] = '", "")?.substringBefore("';", "")
val alternativeServers = document.select("ul.TbVideoNv.nav.nav-tabs li:not(:first-child)")
if (!apiUrl.isNullOrEmpty()) {
val apiResponse = client.newCall(GET(apiUrl)).execute().asJsoup()
val regIsUrl = "https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_\\+.~#?&//=]*)".toRegex()
val encryptedList = apiResponse.select("#PlayerDisplay div[class*=\"OptionsLangDisp\"] div[class*=\"ODDIV\"] div[class*=\"OD\"] li")
encryptedList.flatMap {
val url = it.attr("onclick")
.substringAfter("go_to_player('")
.substringAfter("go_to_playerVast('")
.substringBefore("?cover_url=")
.substringBefore("')")
.substringBefore("',")
.substringBefore("?poster")
.substringBefore("?c_poster=")
.substringBefore("?thumb=")
.substringBefore("#poster=")

val realUrl = if (!regIsUrl.containsMatchIn(url)) {
String(Base64.decode(url, Base64.DEFAULT))
} else if (url.contains("?data=")) {
val apiPageSoup = client.newCall(GET(url)).execute().asJsoup()
apiPageSoup.selectFirst("iframe")?.attr("src") ?: ""
} else {
url
}

serverVideoResolver(realUrl)
}.also(videoList::addAll)
val apiResponse = client.newCall(GET(apiUrl)).execute()
val docResponse = apiResponse.asJsoup()
if (apiResponse.isSuccessful) {
val regIsUrl = "https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_\\+.~#?&//=]*)".toRegex()
val encryptedList = docResponse.select("#PlayerDisplay div[class*=\"OptionsLangDisp\"] div[class*=\"ODDIV\"] div[class*=\"OD\"] li")
encryptedList.flatMap {
runCatching {
val url = it.attr("onclick")
.substringAfter("go_to_player('")
.substringAfter("go_to_playerVast('")
.substringBefore("?cover_url=")
.substringBefore("')")
.substringBefore("',")
.substringBefore("?poster")
.substringBefore("?c_poster=")
.substringBefore("?thumb=")
.substringBefore("#poster=")

val realUrl = if (!regIsUrl.containsMatchIn(url)) {
String(Base64.decode(url, Base64.DEFAULT))
} else if (url.contains("?data=")) {
val apiPageSoup = client.newCall(GET(url)).execute().asJsoup()
apiPageSoup.selectFirst("iframe")?.attr("src") ?: ""
} else {
url
}

serverVideoResolver(realUrl)
}.getOrNull() ?: emptyList()
}.also(videoList::addAll)
}
}

// verifier for old series
if (!apiUrl.isNullOrEmpty() && !apiUrl.contains("/video/") || alternativeServers.any()) {
document.select("ul.TbVideoNv.nav.nav-tabs li").flatMap { id ->
document.select("ul.TbVideoNv.nav.nav-tabs li").parallelCatchingFlatMapBlocking { id ->
val serverName = id.select("a").text().lowercase()
val serverId = id.attr("data-id")
var serverUrl = data?.substringAfter("video[$serverId] = '", "")?.substringBefore("';", "")
if (serverUrl != null && serverUrl.contains("api.mycdn.moe")) {
val urlId = serverUrl.substringAfter("id=")
print("Server not found $urlId")
serverUrl = when (serverName) {
"sbfast" -> { "https://sbfull.com/e/$urlId" }
"plusto" -> { "https://owodeuwu.xyz/v/$urlId" }
"doodstream" -> { "https://dood.to/e/$urlId" }
"upload", "uqload" -> { "https://uqload.ws/embed-$urlId.html" }
"upload", "uqload" -> { "https://uqload.com/embed-$urlId.html" }
else -> ""
}
}
Expand Down Expand Up @@ -210,7 +215,8 @@ open class Pelisplushd(override val name: String, override val baseUrl: String)
embedUrl.contains("fastream") -> FastreamExtractor(client, headers).videosFromUrl(url, prefix = "Fastream:")
embedUrl.contains("upstream") -> UpstreamExtractor(client).videosFromUrl(url)
embedUrl.contains("streamtape") || embedUrl.contains("stp") || embedUrl.contains("stape") -> listOf(StreamTapeExtractor(client).videoFromUrl(url, quality = "StreamTape")!!)
embedUrl.contains("ahvsh") || embedUrl.contains("streamhide") || embedUrl.contains("guccihide") || embedUrl.contains("streamvid") -> StreamHideExtractor(client).videosFromUrl(url, "StreamHide")
embedUrl.contains("ahvsh") || embedUrl.contains("streamhide") || embedUrl.contains("guccihide") ||
embedUrl.contains("streamvid") || embedUrl.contains("vidhide") -> StreamHideVidExtractor(client).videosFromUrl(url)
else -> emptyList()
}
}.getOrNull() ?: emptyList()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import eu.kanade.tachiyomi.animesource.AnimeSourceFactory

class PelisplushdFactory : AnimeSourceFactory {
override fun createSources(): List<AnimeSource> = listOf(
Pelisplushd("PelisPlusHD", "https://pelisplushd.nz"),
Pelisplushd("PelisPlusHD", "https://pelisplushd.bz"),
Pelisplusto("PelisPlusTo", "https://ww3.pelisplus.to"),
Pelisplusph("PelisPlusPh", "https://www.pelisplushd.ph"),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package eu.kanade.tachiyomi.animeextension.es.pelisplushd

import androidx.preference.ListPreference
import androidx.preference.PreferenceScreen
import eu.kanade.tachiyomi.animeextension.es.pelisplushd.extractors.StreamHideExtractor
import eu.kanade.tachiyomi.animesource.model.AnimeFilter
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
import eu.kanade.tachiyomi.animesource.model.SAnime
Expand All @@ -14,6 +13,7 @@ import eu.kanade.tachiyomi.lib.fastreamextractor.FastreamExtractor
import eu.kanade.tachiyomi.lib.filemoonextractor.FilemoonExtractor
import eu.kanade.tachiyomi.lib.mp4uploadextractor.Mp4uploadExtractor
import eu.kanade.tachiyomi.lib.okruextractor.OkruExtractor
import eu.kanade.tachiyomi.lib.streamhidevidextractor.StreamHideVidExtractor
import eu.kanade.tachiyomi.lib.streamlareextractor.StreamlareExtractor
import eu.kanade.tachiyomi.lib.streamtapeextractor.StreamTapeExtractor
import eu.kanade.tachiyomi.lib.streamwishextractor.StreamWishExtractor
Expand All @@ -23,6 +23,7 @@ import eu.kanade.tachiyomi.lib.voeextractor.VoeExtractor
import eu.kanade.tachiyomi.lib.youruploadextractor.YourUploadExtractor
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.util.asJsoup
import eu.kanade.tachiyomi.util.parallelCatchingFlatMapBlocking
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.Request
import okhttp3.Response
Expand Down Expand Up @@ -129,7 +130,7 @@ class Pelisplusph(override val name: String, override val baseUrl: String) : Pel

override fun videoListParse(response: Response): List<Video> {
val document = response.asJsoup()
return document.select("[class*=server-item-]").flatMap { serverItem ->
return document.select("[class*=server-item-]").parallelCatchingFlatMapBlocking { serverItem ->
val langIdx = getNumberFromString(serverItem.attr("class").substringAfter("server-item-"))
val langItem = document.select("li[data-id=\"$langIdx\"] a").text()
val lang = if (langItem.contains("Subtitulado")) "[SUB]" else if (langItem.contains("Latino")) "[LAT]" else "[CAST]"
Expand Down Expand Up @@ -173,7 +174,8 @@ class Pelisplusph(override val name: String, override val baseUrl: String) : Pel
embedUrl.contains("fastream") -> FastreamExtractor(client, headers).videosFromUrl(url, prefix = "$prefix Fastream:")
embedUrl.contains("upstream") -> UpstreamExtractor(client).videosFromUrl(url, prefix = prefix)
embedUrl.contains("streamtape") || embedUrl.contains("stp") || embedUrl.contains("stape") -> listOf(StreamTapeExtractor(client).videoFromUrl(url, quality = "$prefix StreamTape")!!)
embedUrl.contains("ahvsh") || embedUrl.contains("streamhide") || embedUrl.contains("guccihide") || embedUrl.contains("streamvid") -> StreamHideExtractor(client).videosFromUrl(url, "$prefix StreamHide")
embedUrl.contains("ahvsh") || embedUrl.contains("streamhide") || embedUrl.contains("guccihide") ||
embedUrl.contains("streamvid") || embedUrl.contains("vidhide") -> StreamHideVidExtractor(client).videosFromUrl(url, "$prefix ")
else -> emptyList()
}
}.getOrNull() ?: emptyList()
Expand Down
Loading

0 comments on commit b416818

Please sign in to comment.