add new source: animetitans , and fix streamsbextractor (#869)

* Update build.gradle

* add new source

* fix versions

* update
This commit is contained in:
Ahmed gamal
2022-09-17 22:10:48 +02:00
committed by GitHub
parent dceb71c7c8
commit fee171c158
63 changed files with 884 additions and 57 deletions

View File

@ -5,7 +5,7 @@ ext {
extName = 'AnimeLek'
pkgNameSuffix = 'ar.animelek'
extClass = '.AnimeLek'
extVersionCode = 9
extVersionCode = 10
libVersion = '13'
}

View File

@ -115,7 +115,7 @@ class AnimeLek : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
.set("Referer", url)
.set("User-Agent", "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:96.0) Gecko/20100101 Firefox/96.0")
.set("Accept-Language", "en-US,en;q=0.5")
.set("watchsb", "streamsb")
.set("watchsb", "sbstream")
.build()
val videos = StreamSBExtractor(client).videosFromUrl(url, headers)
videoList.addAll(videos)

View File

@ -29,7 +29,7 @@ class StreamSBExtractor(private val client: OkHttpClient) {
val id = url.substringAfter("e/")
val bytes = id.toByteArray()
val bytesToHex = bytesToHex(bytes)
val master = "$sbUrl/sources43/566d337678566f743674494a7c7c${bytesToHex}7c7c346b6767586d6934774855537c7c73747265616d7362/6565417268755339773461447c7c346133383438333436313335376136323337373433383634376337633465366534393338373136643732373736343735373237613763376334363733353737303533366236333463353333363534366137633763373337343732363536313664373336327c7c6b586c3163614468645a47617c7c73747265616d7362"
val master = "$sbUrl/sources48/625a364258615242766475327c7c${bytesToHex}7c7c4761574550654f7461566d347c7c73747265616d7362"
// "https://sbplay2.com/sourcesx38/4f395a53447166635a3836787c7c${bytesToHex}7c7c7965344f61436d467845586c7c7c73747265616d7362/6e56314c77564e6a6c6631737c7c333735383537363836633662373635323636376133343637376337633335346334343332353735343333366633343635346336383763376334313561373633343761346133303665363837363537353937633763373337343732363536313664373336327c7c395239444c3961626d634e6a7c7c73747265616d7362"
val json = Json.decodeFromString<JsonObject>(
client.newCall(GET(master, headers))

View File

@ -5,7 +5,7 @@ ext {
extName = 'Animerco'
pkgNameSuffix = 'ar.animerco'
extClass = '.Animerco'
extVersionCode = 11
extVersionCode = 12
libVersion = '13'
}

View File

@ -195,7 +195,7 @@ class Animerco : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
.set("Referer", embedUrl)
.set("User-Agent", "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:96.0) Gecko/20100101 Firefox/96.0")
.set("Accept-Language", "en-US,en;q=0.5")
.set("watchsb", "streamsb")
.set("watchsb", "sbstream")
.build()
val videos = StreamSBExtractor(client).videosFromUrl(embedUrl, headers)
videoList.addAll(videos)

View File

@ -29,7 +29,7 @@ class StreamSBExtractor(private val client: OkHttpClient) {
val id = url.substringAfter("e/").substringBefore(".html")
val bytes = id.toByteArray()
val bytesToHex = bytesToHex(bytes)
val master = "$sbUrl/sources43/566d337678566f743674494a7c7c${bytesToHex}7c7c346b6767586d6934774855537c7c73747265616d7362/6565417268755339773461447c7c346133383438333436313335376136323337373433383634376337633465366534393338373136643732373736343735373237613763376334363733353737303533366236333463353333363534366137633763373337343732363536313664373336327c7c6b586c3163614468645a47617c7c73747265616d7362"
val master = "$sbUrl/sources48/625a364258615242766475327c7c${bytesToHex}7c7c4761574550654f7461566d347c7c73747265616d7362"
val json = Json.decodeFromString<JsonObject>(
client.newCall(GET(master, headers))
.execute().body!!.string()

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="eu.kanade.tachiyomi.animeextension" />

View File

@ -0,0 +1,12 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
ext {
extName = 'AnimeTitans'
pkgNameSuffix = 'ar.animetitans'
extClass = '.AnimeTitans'
extVersionCode = 1
libVersion = '13'
}
apply from: "$rootDir/common.gradle"

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

View File

@ -0,0 +1,586 @@
package eu.kanade.tachiyomi.animeextension.ar.animetitans
import android.app.Application
import android.content.SharedPreferences
import android.util.Log
import androidx.preference.ListPreference
import androidx.preference.PreferenceScreen
import eu.kanade.tachiyomi.animeextension.ar.animetitans.extractors.AnimeTitansExtractor
import eu.kanade.tachiyomi.animeextension.ar.animetitans.extractors.FembedExtractor
import eu.kanade.tachiyomi.animeextension.ar.animetitans.extractors.SharedExtractor
import eu.kanade.tachiyomi.animeextension.ar.animetitans.extractors.StreamSBExtractor
import eu.kanade.tachiyomi.animeextension.ar.animetitans.extractors.VidBomExtractor
import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
import eu.kanade.tachiyomi.animesource.model.AnimeFilter
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
import eu.kanade.tachiyomi.animesource.model.AnimesPage
import eu.kanade.tachiyomi.animesource.model.SAnime
import eu.kanade.tachiyomi.animesource.model.SEpisode
import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.animesource.online.ParsedAnimeHttpSource
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import rx.Observable
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.lang.Exception
import java.text.SimpleDateFormat
import java.util.Base64
import java.util.Locale
class AnimeTitans : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
override val name = "AnimeTitans"
override val baseUrl = "https://animetitans.com"
override val lang = "ar"
override val supportsLatest = true
private val AnimeUrlDirectory: String = "/anime"
private val dateFormat: SimpleDateFormat = SimpleDateFormat("MMM d, yyy", Locale.US)
override val client: OkHttpClient = network.cloudflareClient
private val preferences: SharedPreferences by lazy {
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
}
// Popular (Search with popular order and nothing else)
override fun popularAnimeRequest(page: Int) = searchAnimeRequest(page, "", AnimeFilterList(OrderByFilter("popular")))
override fun popularAnimeParse(response: Response) = searchAnimeParse(response)
// Latest (Search with update order and nothing else)
override fun latestUpdatesRequest(page: Int) = searchAnimeRequest(page, "", AnimeFilterList(OrderByFilter("update")))
override fun latestUpdatesParse(response: Response) = searchAnimeParse(response)
// Episodes
override fun episodeListSelector() = "ul li[data-index]"
private fun parseEpisodeDate(date: String): Long {
return SimpleDateFormat("MMM d, yyy", Locale("ar")).parse(date)?.time ?: 0L
}
override fun episodeFromElement(element: Element): SEpisode {
val episode = SEpisode.create()
val epNum = getNumberFromEpsString(element.select(".epl-num").text())
val urlElements = element.select("a")
episode.setUrlWithoutDomain(urlElements.attr("href"))
episode.name = element.select(".epl-title").text().ifBlank { urlElements.first().text() }
episode.episode_number = when {
(epNum.isNotEmpty()) -> epNum.toFloat()
else -> 1F
}
episode.date_upload = element.select(".epl-date").first()?.text()?.let { parseEpisodeDate(it) } ?: 0L
return episode
}
private fun getNumberFromEpsString(epsStr: String): String {
return epsStr.filter { it.isDigit() }
}
// Video urls
override fun videoListParse(response: Response): List<Video> {
val document = response.asJsoup()
return videosFromElement(document)
}
override fun videoListSelector() = "select.mirror option"
private fun videosFromElement(document: Document): List<Video> {
val videoList = mutableListOf<Video>()
val elements = document.select(videoListSelector())
for (element in elements) {
val location = element.ownerDocument().location()
val videoEncode = element.attr("value")
val qualityy = element.text()
val decoder: Base64.Decoder = Base64.getDecoder()
val decoded = String(decoder.decode(videoEncode))
val embedUrl = decoded.substringAfter("src=\"").substringBefore("\"")
Log.i("embedUrl", "$embedUrl")
when {
embedUrl.contains("animetitans.net")
-> {
val headers = headers.newBuilder()
.set("Referer", "$baseUrl/")
.set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36")
.set("Accept", "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8")
.set("Accept-Language", "en-US,en;q=0.5")
.set("Accept-Encoding", "gzip, deflate, br")
.build()
val videos = AnimeTitansExtractor(client).videosFromUrl(embedUrl, headers)
videoList.addAll(videos)
}
embedUrl.contains("sbembed.com") || embedUrl.contains("sbembed1.com") || embedUrl.contains("sbplay.org") ||
embedUrl.contains("sbvideo.net") || embedUrl.contains("streamsb.net") || embedUrl.contains("sbplay.one") ||
embedUrl.contains("cloudemb.com") || embedUrl.contains("playersb.com") || embedUrl.contains("tubesb.com") ||
embedUrl.contains("sbplay1.com") || embedUrl.contains("embedsb.com") || embedUrl.contains("watchsb.com") ||
embedUrl.contains("sbplay2.com") || embedUrl.contains("japopav.tv") || embedUrl.contains("viewsb.com") ||
embedUrl.contains("sbfast") || embedUrl.contains("sbfull.com") || embedUrl.contains("javplaya.com") ||
embedUrl.contains("ssbstream.net") || embedUrl.contains("p1ayerjavseen.com") || embedUrl.contains("sbthe.com") ||
embedUrl.contains("vidmovie.xyz") || embedUrl.contains("sbspeed.com") || embedUrl.contains("streamsss.net") ||
embedUrl.contains("sblanh.com")
-> {
val headers = headers.newBuilder()
// .set("Referer", embedUrl)
.set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36")
.set("Accept", "application/json, text/plain, */*")
.set("Accept-Language", "en-US,en;q=0.5")
.set("watchsb", "sbstream")
.build()
Log.i("animetitansstreamsb", "$embedUrl")
val videos = StreamSBExtractor(client).videosFromUrl(embedUrl, headers)
Log.i("animetitansstreamsb", "$videos")
videoList.addAll(videos)
}
embedUrl.contains("fembed") ||
embedUrl.contains("anime789.com") || embedUrl.contains("24hd.club") || embedUrl.contains("fembad.org") ||
embedUrl.contains("vcdn.io") || embedUrl.contains("sharinglink.club") || embedUrl.contains("moviemaniac.org") ||
embedUrl.contains("votrefiles.club") || embedUrl.contains("femoload.xyz") || embedUrl.contains("albavido.xyz") ||
embedUrl.contains("feurl.com") || embedUrl.contains("dailyplanet.pw") || embedUrl.contains("ncdnstm.com") ||
embedUrl.contains("jplayer.net") || embedUrl.contains("xstreamcdn.com") || embedUrl.contains("fembed-hd.com") ||
embedUrl.contains("gcloud.live") || embedUrl.contains("vcdnplay.com") || embedUrl.contains("superplayxyz.club") ||
embedUrl.contains("vidohd.com") || embedUrl.contains("vidsource.me") || embedUrl.contains("cinegrabber.com") ||
embedUrl.contains("votrefile.xyz") || embedUrl.contains("zidiplay.com") || embedUrl.contains("ndrama.xyz") ||
embedUrl.contains("fcdn.stream") || embedUrl.contains("mediashore.org") || embedUrl.contains("suzihaza.com") ||
embedUrl.contains("there.to") || embedUrl.contains("femax20.com") || embedUrl.contains("javstream.top") ||
embedUrl.contains("viplayer.cc") || embedUrl.contains("sexhd.co") || embedUrl.contains("fembed.net") ||
embedUrl.contains("mrdhan.com") || embedUrl.contains("votrefilms.xyz") || // embedUrl.contains("") ||
embedUrl.contains("embedsito.com") || embedUrl.contains("dutrag.com") || // embedUrl.contains("") ||
embedUrl.contains("youvideos.ru") || embedUrl.contains("streamm4u.club") || // embedUrl.contains("") ||
embedUrl.contains("moviepl.xyz") || embedUrl.contains("asianclub.tv") || // embedUrl.contains("") ||
embedUrl.contains("vidcloud.fun") || embedUrl.contains("fplayer.info") || // embedUrl.contains("") ||
embedUrl.contains("diasfem.com") || embedUrl.contains("javpoll.com") || embedUrl.contains("reeoov.tube") ||
embedUrl.contains("suzihaza.com") || embedUrl.contains("ezsubz.com") || embedUrl.contains("vidsrc.xyz") ||
embedUrl.contains("diampokusy.com") || embedUrl.contains("diampokusy.com") || embedUrl.contains("i18n.pw") ||
embedUrl.contains("vanfem.com") || embedUrl.contains("fembed9hd.com") || embedUrl.contains("votrefilms.xyz") || embedUrl.contains("watchjavnow.xyz")
-> {
val videos = FembedExtractor(client).videosFromUrl(embedUrl)
videoList.addAll(videos)
}
embedUrl.contains("animetitans.net")
-> {
val headers = headers.newBuilder()
.set("Referer", "$baseUrl/")
.set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36")
.set("Accept", "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8")
.set("Accept-Language", "en-US,en;q=0.5")
.set("Accept-Encoding", "gzip, deflate, br")
.build()
val videos = AnimeTitansExtractor(client).videosFromUrl(embedUrl, headers)
videoList.addAll(videos)
}
embedUrl.contains("4shared") -> {
val video = SharedExtractor(client).videoFromUrl(embedUrl, qualityy)
if (video != null) {
videoList.add(video)
}
}
/*embedUrl.contains("mp4upload") -> {
val headers = headers.newBuilder().set("referer", "https://mp4upload.com/").build()
val video = Mp4uploadExtractor().getVideoFromUrl(embedUrl, headers)
videoList.add(video)
}*/
embedUrl.contains("vidbom.com") ||
embedUrl.contains("vidbem.com") || embedUrl.contains("vidbm.com") || embedUrl.contains("vedpom.com") ||
embedUrl.contains("vedbom.com") || embedUrl.contains("vedbom.org") || embedUrl.contains("vadbom.com") ||
embedUrl.contains("vidbam.org") || embedUrl.contains("myviid.com") || embedUrl.contains("myviid.net") ||
embedUrl.contains("myvid.com") || embedUrl.contains("vidshare.com") || embedUrl.contains("vedsharr.com") ||
embedUrl.contains("vedshar.com") || embedUrl.contains("vedshare.com") || embedUrl.contains("vadshar.com") || embedUrl.contains("vidshar.org")
-> {
val videos = VidBomExtractor(client).videosFromUrl(embedUrl)
videoList.addAll(videos)
}
}
}
return videoList
}
override fun videoFromElement(element: Element) = throw Exception("not used")
override fun videoUrlParse(document: Document) = throw Exception("not used")
override fun List<Video>.sort(): List<Video> {
val quality = preferences.getString("preferred_quality", null)
if (quality != null) {
val newList = mutableListOf<Video>()
var preferred = 0
for (video in this) {
if (video.quality.contains(quality)) {
newList.add(preferred, video)
preferred++
} else {
newList.add(video)
}
}
return newList
}
return this
}
// Search
override fun fetchSearchAnime(page: Int, query: String, filters: AnimeFilterList): Observable<AnimesPage> {
if (query.startsWith(URL_SEARCH_PREFIX).not()) return super.fetchSearchAnime(page, query, filters)
val AnimePath = try {
animePathFromUrl(query.substringAfter(URL_SEARCH_PREFIX))
?: return Observable.just(AnimesPage(emptyList(), false))
} catch (e: Exception) {
return Observable.error(e)
}
return fetchAnimeDetails(
SAnime.create()
.apply { this.url = "$AnimeUrlDirectory/$AnimePath" }
)
.map {
// Isn't set in returned Anime
it.url = "$AnimeUrlDirectory/$id"
AnimesPage(listOf(it), false)
}
}
override fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request {
val url = baseUrl.toHttpUrl().newBuilder()
if (query.isNotEmpty()) {
url.addPathSegments("page/$page/").addQueryParameter("s", query)
} else {
url.addPathSegment(AnimeUrlDirectory.substring(1)).addPathSegments("page/$page/")
filters.forEach { filter ->
when (filter) {
is AuthorFilter -> {
url.addQueryParameter("author", filter.state)
}
is YearFilter -> {
url.addQueryParameter("yearx", filter.state)
}
is StatusFilter -> {
url.addQueryParameter("status", filter.selectedValue())
}
is TypeFilter -> {
url.addQueryParameter("type", filter.selectedValue())
}
is OrderByFilter -> {
url.addQueryParameter("order", filter.selectedValue())
}
is GenreListFilter -> {
filter.state
.filter { it.state != AnimeFilter.TriState.STATE_IGNORE }
.forEach {
val value = if (it.state == AnimeFilter.TriState.STATE_EXCLUDE) "-${it.value}" else it.value
url.addQueryParameter("genre[]", value)
}
}
is SeasonListFilter -> {
filter.state
.filter { it.state != AnimeFilter.TriState.STATE_IGNORE }
.forEach {
val value = if (it.state == AnimeFilter.TriState.STATE_EXCLUDE) "-${it.value}" else it.value
url.addQueryParameter("season[]", value)
}
}
is StudioListFilter -> {
filter.state
.filter { it.state != AnimeFilter.TriState.STATE_IGNORE }
.forEach {
val value = if (it.state == AnimeFilter.TriState.STATE_EXCLUDE) "-${it.value}" else it.value
url.addQueryParameter("studio[]", value)
}
}
else -> { /* Do Nothing */ }
}
}
}
return GET(url.toString())
}
override fun searchAnimeParse(response: Response): AnimesPage {
if (genrelist == null) {
genrelist = parseGenres(response.asJsoup(response.peekBody(Long.MAX_VALUE).string()))
seasonlist = parseSeasons(response.asJsoup(response.peekBody(Long.MAX_VALUE).string()))
studiolist = parseStudios(response.asJsoup(response.peekBody(Long.MAX_VALUE).string()))
}
return super.searchAnimeParse(response)
}
override fun searchAnimeSelector() = ".utao .uta .imgu, .listupd .bs .bsx, .listo .bs .bsx"
override fun searchAnimeFromElement(element: Element) = SAnime.create().apply {
thumbnail_url = element.select("img").attr("src")
title = element.select("a").attr("title")
setUrlWithoutDomain(element.select("a").attr("href"))
}
override fun searchAnimeNextPageSelector() = "div.pagination .next, div.hpage .r"
// Anime details
open val seriesDetailsSelector = "div.bigcontent, div.animefull, div.main-info, div.postbody"
open val seriesTitleSelector = "h1.entry-title"
open val seriesArtistSelector = "span:contains(الاستديو) a"
open val seriesAuthorSelector = "span:contains(المخرج) a"
open val seriesDescriptionSelector = ".entry-content[itemprop=description]"
open val seriesAltNameSelector = ".alter"
open val seriesGenreSelector = ".genxed a"
open val seriesTypeSelector = "span:contains(النوع)"
open val seriesStatusSelector = "span:contains(الحالة)"
open val seriesThumbnailSelector = ".thumb img"
open val altNamePrefix = " :أسماء أخرى"
override fun animeDetailsParse(document: Document) = SAnime.create().apply {
document.selectFirst(seriesDetailsSelector)?.let { seriesDetails ->
title = seriesDetails.selectFirst(seriesTitleSelector)?.text().orEmpty()
artist = seriesDetails.selectFirst(seriesArtistSelector)?.ownText().removeEmptyPlaceholder()
author = seriesDetails.selectFirst(seriesAuthorSelector)?.ownText().removeEmptyPlaceholder()
description = seriesDetails.select(seriesDescriptionSelector).joinToString("\n") { it.text() }
// Add alternative name to Anime description
val altName = seriesDetails.selectFirst(seriesAltNameSelector)?.ownText().takeIf { it.isNullOrBlank().not() }
altName?.let {
description = "$description\n\n$altName$altNamePrefix".trim()
}
val genres = seriesDetails.select(seriesGenreSelector).map { it.text() }.toMutableList()
// Add series type (Anime/manhwa/manhua/other) to genre
seriesDetails.selectFirst(seriesTypeSelector)?.ownText().takeIf { it.isNullOrBlank().not() }?.let { genres.add(it) }
genre = genres.map { genre ->
genre.lowercase(Locale.forLanguageTag(lang)).replaceFirstChar { char ->
if (char.isLowerCase()) char.titlecase(Locale.forLanguageTag(lang))
else char.toString()
}
}
.joinToString { it.trim() }
status = seriesDetails.selectFirst(seriesStatusSelector)?.text().parseStatus()
thumbnail_url = seriesDetails.select(seriesThumbnailSelector).attr("src")
}
}
private fun String?.removeEmptyPlaceholder(): String? {
return if (this.isNullOrBlank() || this == "-" || this == "N/A") null else this
}
open fun String?.parseStatus(): Int = when {
this == null -> SAnime.UNKNOWN
listOf("مستمر", "publishing").any { this.contains(it, ignoreCase = true) } -> SAnime.ONGOING
this.contains("مكتمل", ignoreCase = true) -> SAnime.COMPLETED
// this.contains("مؤجل", ignoreCase = true) -> SAnime.HIATUS
else -> SAnime.UNKNOWN
}
// Filters
private class AuthorFilter : AnimeFilter.Text("Author")
private class YearFilter : AnimeFilter.Text("Year")
open class SelectFilter(
displayName: String,
val vals: Array<Pair<String, String>>,
defaultValue: String? = null
) : AnimeFilter.Select<String>(
displayName,
vals.map { it.first }.toTypedArray(),
vals.indexOfFirst { it.second == defaultValue }.takeIf { it != -1 } ?: 0
) {
fun selectedValue() = vals[state].second
}
protected class StatusFilter : SelectFilter(
"Status",
arrayOf(
Pair("All", ""),
Pair("Ongoing", "ongoing"),
Pair("Completed", "completed"),
Pair("Hiatus", "hiatus"),
Pair("UpComing", "upcoming")
)
)
protected class TypeFilter : SelectFilter(
"Type",
arrayOf(
Pair("All", ""),
Pair("Anime", "tv"),
Pair("Movie", "movie"),
Pair("OVA", "ova"),
Pair("ONA", "ona"),
Pair("Special", "special")
)
)
protected class OrderByFilter(defaultOrder: String? = null) : SelectFilter(
"Sort By",
arrayOf(
Pair("Default", ""),
Pair("A-Z", "title"),
Pair("Z-A", "titlereverse"),
Pair("Latest Update", "update"),
Pair("Latest Added", "latest"),
Pair("Popular", "popular")
),
defaultOrder
)
protected class Genre(name: String, val value: String) : AnimeFilter.TriState(name)
protected class GenreListFilter(genres: List<Genre>) : AnimeFilter.Group<Genre>("Genre", genres)
private var genrelist: List<Genre>? = null
protected open fun getGenreList(): List<Genre> {
// Filters are fetched immediately once an extension loads
// We're only able to get filters after a loading the Anime directory,
// and resetting the filters is the only thing that seems to reinflate the view
return genrelist ?: listOf(Genre("Press reset to attempt to fetch genres", ""))
}
protected class Season(name: String, val value: String) : AnimeFilter.TriState(name)
protected class SeasonListFilter(seasons: List<Season>) : AnimeFilter.Group<Season>("Season", seasons)
private var seasonlist: List<Season>? = null
protected open fun getSeasonList(): List<Season> {
return seasonlist ?: listOf(Season("Press reset to attempt to fetch Seasons", ""))
}
protected class Studio(name: String, val value: String) : AnimeFilter.TriState(name)
protected class StudioListFilter(studios: List<Studio>) : AnimeFilter.Group<Studio>("Studio", studios)
private var studiolist: List<Studio>? = null
protected open fun getStudioList(): List<Studio> {
return studiolist ?: listOf(Studio("Press reset to attempt to fetch Studios", ""))
}
override fun getFilterList(): AnimeFilterList {
val filters = mutableListOf<AnimeFilter<*>>(
AnimeFilter.Separator(),
AuthorFilter(),
YearFilter(),
StatusFilter(),
TypeFilter(),
OrderByFilter(),
AnimeFilter.Header("Genre exclusion is not available for all sources"),
GenreListFilter(getGenreList()),
SeasonListFilter(getSeasonList()),
StudioListFilter(getStudioList()),
)
return AnimeFilterList(filters)
}
// Helpers
/**
* Given some string which represents an http urlString, returns path for a Anime
* which can be used to fetch its details at "$baseUrl$AnimeUrlDirectory/$AnimePath"
*
* @param urlString: String
*
* @returns Path of a Anime, or null if none could be found
*/
private fun animePathFromUrl(urlString: String): String? {
val baseAnimeUrl = "$baseUrl$AnimeUrlDirectory".toHttpUrl()
val url = urlString.toHttpUrlOrNull() ?: return null
val isAnimeUrl = (baseAnimeUrl.host == url.host && pathLengthIs(url, 2) && url.pathSegments[0] == baseAnimeUrl.pathSegments[0])
if (isAnimeUrl) return url.pathSegments[1]
val potentiallyChapterUrl = pathLengthIs(url, 1)
if (potentiallyChapterUrl) {
val response = client.newCall(GET(urlString, headers)).execute()
if (response.isSuccessful.not()) {
response.close()
throw IllegalStateException("HTTP error ${response.code}")
} else if (response.isSuccessful) {
val links = response.asJsoup().select("a[itemprop=item]")
// near the top of page: home > Anime > current chapter
if (links.size == 3) {
return links[1].attr("href").toHttpUrlOrNull()?.encodedPath
}
}
}
return null
}
private fun pathLengthIs(url: HttpUrl, n: Int, strict: Boolean = false): Boolean {
return url.pathSegments.size == n && url.pathSegments[n - 1].isNotEmpty() ||
(!strict && url.pathSegments.size == n + 1 && url.pathSegments[n].isEmpty())
}
private fun parseGenres(document: Document): List<Genre>? {
return document.selectFirst("div.filter:contains(التصنيف) ul.scrollz")?.select("li")?.map { li ->
Genre(
li.selectFirst("label").text(),
li.selectFirst("input[type=checkbox]").attr("value")
)
}
}
private fun parseSeasons(document: Document): List<Season>? {
return document.selectFirst("div.filter:contains(الموسم) ul.scrollz")?.select("li")?.map { li ->
Season(
li.selectFirst("label").text(),
li.selectFirst("input[type=checkbox]").attr("value")
)
}
}
private fun parseStudios(document: Document): List<Studio>? {
return document.selectFirst("div.filter:contains(الاستديو) ul.scrollz")?.select("li")?.map { li ->
Studio(
li.selectFirst("label").text(),
li.selectFirst("input[type=checkbox]").attr("value")
)
}
}
// Unused
override fun popularAnimeSelector(): String = throw UnsupportedOperationException("Not used")
override fun popularAnimeFromElement(element: Element): SAnime = throw UnsupportedOperationException("Not used")
override fun popularAnimeNextPageSelector(): String? = throw UnsupportedOperationException("Not used")
override fun latestUpdatesSelector(): String = throw UnsupportedOperationException("Not used")
override fun latestUpdatesFromElement(element: Element): SAnime = throw UnsupportedOperationException("Not used")
override fun latestUpdatesNextPageSelector(): String? = throw UnsupportedOperationException("Not used")
companion object {
const val URL_SEARCH_PREFIX = "url:"
// More info: https://issuetracker.google.com/issues/36970498
@Suppress("RegExpRedundantEscape")
private val ANIME_PAGE_ID_REGEX = "post_id\\s*:\\s*(\\d+)\\}".toRegex()
private val CHAPTER_PAGE_ID_REGEX = "chapter_id\\s*=\\s*(\\d+);".toRegex()
val JSON_IMAGE_LIST_REGEX = "\"images\"\\s*:\\s*(\\[.*?])".toRegex()
}
// Preferences
override fun setupPreferenceScreen(screen: PreferenceScreen) {
val videoQualityPref = ListPreference(screen.context).apply {
key = "preferred_quality"
title = "Preferred quality"
entries = arrayOf("1080p", "720p", "480p", "360p", "Doodstream", "4shared")
entryValues = arrayOf("1080", "720", "480", "360", "Doodstream", "4shared")
setDefaultValue("1080")
summary = "%s"
setOnPreferenceChangeListener { _, newValue ->
val selected = newValue as String
val index = findIndexOfValue(selected)
val entry = entryValues[index] as String
preferences.edit().putString(key, entry).commit()
}
}
screen.addPreference(videoQualityPref)
}
}

View File

@ -0,0 +1,23 @@
package eu.kanade.tachiyomi.animeextension.ar.animetitans.extractors
import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.Headers
import okhttp3.OkHttpClient
class AnimeTitansExtractor(private val client: OkHttpClient) {
fun videosFromUrl(url: String, headers: Headers): List<Video> {
val callPlayer = client.newCall(GET(url)).execute().asJsoup()
val masterUrl = callPlayer.data().substringAfter("source: \"").substringBefore("\",")
val domain = masterUrl.substringBefore("/videowl") // .replace("https", "http")
val masterPlaylist = client.newCall(GET(masterUrl)).execute().body!!.string()
val videoList = mutableListOf<Video>()
masterPlaylist.substringAfter("#EXT-X-STREAM-INF:").split("#EXT-X-STREAM-INF:").forEach {
val quality = "AnimeTitans: " + it.substringAfter("RESOLUTION=").substringAfter("x").substringBefore("\n") + "p"
val videoUrl = "$domain" + it.substringAfter("\n").substringBefore("\n")
videoList.add(Video(videoUrl, quality, videoUrl, headers = headers))
}
return videoList
}
}

View File

@ -0,0 +1,43 @@
package eu.kanade.tachiyomi.animeextension.ar.animetitans.extractors
import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.network.POST
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonObject
import okhttp3.OkHttpClient
class FembedExtractor(private val client: OkHttpClient) {
fun videosFromUrl(url: String): List<Video> {
val videoApi = url.replace("/v/", "/api/source/")
val jsonR = Json.decodeFromString<JsonObject>(
client.newCall(POST(videoApi)).execute().body!!.string()
)
val videoList = mutableListOf<Video>()
if (jsonR["success"].toString() == "true") {
val videoList = mutableListOf<Video>()
jsonR["data"]!!.jsonArray.forEach() {
val videoUrl = it.jsonObject["file"].toString().trim('"')
val quality = "Fembed:" + it.jsonObject["label"].toString().trim('"')
videoList.add(Video(videoUrl, quality, videoUrl))
}
/*val jsonArray = json.getJSONArray("data")
Log.i("jsoon", "$jsonArray")
for (i in 0 until jsonArray.length()) {
val `object` = jsonArray.getJSONObject(i)
val videoUrl = `object`.getString("file")
val quality = "Fembed:" + `object`.getString("label")
videoList.add(Video(videoUrl, quality, videoUrl))
}*/
return videoList
} else {
val videoUrl = "not used"
val quality = "Video taken down for dmca"
videoList.add(Video(videoUrl, quality, videoUrl))
}
return videoList
}
}

View File

@ -0,0 +1,28 @@
package eu.kanade.tachiyomi.animeextension.ar.animetitans.extractors
import eu.kanade.tachiyomi.animesource.model.Video
import okhttp3.Headers
import org.jsoup.Connection
import org.jsoup.Jsoup
class Mp4uploadExtractor {
fun getVideoFromUrl(url: String, headers: Headers): Video {
val id = url.substringAfterLast("embed-").substringBeforeLast(".html")
return try {
val videoUrl = Jsoup.connect(url).data(
mutableMapOf(
"op" to "download2",
"id" to id,
"rand" to "",
"referer" to url,
"method_free" to "+",
"method_premiun" to "",
)
).method(Connection.Method.POST).ignoreContentType(true)
.ignoreHttpErrors(true).execute().url().toString()
Video(videoUrl, "Mp4Upload", videoUrl, headers)
} catch (e: Exception) {
Video("", "", "")
}
}
}

View File

@ -0,0 +1,19 @@
package eu.kanade.tachiyomi.animeextension.ar.animetitans.extractors
import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.OkHttpClient
class SharedExtractor(private val client: OkHttpClient) {
fun videoFromUrl(url: String, quality: String): Video? {
val document = client.newCall(GET(url)).execute().asJsoup()
val check = document.select("div.error4shared").text()
val videoUrl = document.select("source").attr("src")
return if (check.contains("This file is not available any more")) {
Video(url, "no 1video", "https")
} else {
Video(url, quality, videoUrl)
}
}
}

View File

@ -0,0 +1,48 @@
package eu.kanade.tachiyomi.animeextension.ar.animetitans.extractors
import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.network.GET
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.jsonObject
import okhttp3.Headers
import okhttp3.OkHttpClient
class StreamSBExtractor(private val client: OkHttpClient) {
private val hexArray = "0123456789ABCDEF".toCharArray()
private fun bytesToHex(bytes: ByteArray): String {
val hexChars = CharArray(bytes.size * 2)
for (j in bytes.indices) {
val v = bytes[j].toInt() and 0xFF
hexChars[j * 2] = hexArray[v ushr 4]
hexChars[j * 2 + 1] = hexArray[v and 0x0F]
}
return String(hexChars)
}
fun videosFromUrl(url: String, headers: Headers): List<Video> {
val sbUrl = url.substringBefore("/e")
val id = url.substringAfter("e/").substringBefore(".html")
val bytes = id.toByteArray()
val bytesToHex = bytesToHex(bytes)
val master = "$sbUrl/sources48/625a364258615242766475327c7c${bytesToHex}7c7c4761574550654f7461566d347c7c73747265616d7362"
// val master = "$sbUrl/sources48/${bytesToHex("||$id||||streamsb".toByteArray())}/"
val json = Json.decodeFromString<JsonObject>(
client.newCall(GET(master, headers))
.execute().body!!.string()
)
val masterUrl = json["stream_data"]!!.jsonObject["file"].toString().trim('"')
val masterPlaylist = client.newCall(GET(masterUrl, headers)).execute().body!!.string()
val videoList = mutableListOf<Video>()
masterPlaylist.substringAfter("#EXT-X-STREAM-INF:").split("#EXT-X-STREAM-INF:").forEach {
val quality = "StreamSB:" + it.substringAfter("RESOLUTION=").substringAfter("x").substringBefore(",") + "p"
val videoUrl = it.substringAfter("\n").substringBefore("\n")
videoList.add(Video(videoUrl, quality, videoUrl, headers = headers))
}
return videoList
}
}

View File

@ -0,0 +1,19 @@
package eu.kanade.tachiyomi.animeextension.ar.animetitans.extractors
import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.OkHttpClient
class StreamTapeExtractor(private val client: OkHttpClient) {
fun videoFromUrl(url: String): Video? {
val document = client.newCall(GET(url)).execute().asJsoup()
val script = document.select("script:containsData(document.getElementById('robotlink'))")
.firstOrNull()?.data()?.substringAfter("document.getElementById('robotlink').innerHTML = '")
?: return Video(url, "no video", "videoUrl")
val videoUrl = "https:" + script.substringBefore("'") +
script.substringAfter("+ ('xcd").substringBefore("'")
val quality = "StreamTape"
return Video(url, quality, videoUrl)
}
}

View File

@ -0,0 +1,54 @@
package eu.kanade.tachiyomi.animeextension.ar.animetitans.extractors
import eu.kanade.tachiyomi.animesource.model.Video
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.OkHttpClient
class VidBomExtractor(private val client: OkHttpClient) {
fun videosFromUrl(url: String): List<Video> {
val doc = client.newCall(GET(url)).execute().asJsoup()
val script = doc.selectFirst("script:containsData(sources)")
val data = script.data().substringAfter("sources: [").substringBefore("],")
val sources = data.split("file:\"").drop(1)
val videoList = mutableListOf<Video>()
for (source in sources) {
val src = source.substringBefore("\"")
val quality = "Vidbom:" + source.substringAfter("label:\"").substringBefore("\"") // .substringAfter("format: '")
val video = Video(src, quality, src)
videoList.add(video)
}
return videoList
/*Log.i("looool", "$js")
val json = JSONObject(js)
Log.i("looool", "$json")
val videoList = mutableListOf<Video>()
val jsonArray = json.getJSONArray("sources")
for (i in 0 until jsonArray.length()) {
val `object` = jsonArray.getJSONObject(i)
val videoUrl = `object`.getString("file")
Log.i("looool", videoUrl)
val quality = "Vidbom:" + `object`.getString("label")
videoList.add(Video(videoUrl, quality, videoUrl))
}
return videoList*/
/*if (jas.contains("sources")) {
val js = script.data()
val json = JSONObject(js)
val videoList = mutableListOf<Video>()
val jsonArray = json.getJSONArray("sources")
for (i in 0 until jsonArray.length()) {
val `object` = jsonArray.getJSONObject(i)
val videoUrl = `object`.getString("file")
Log.i("lol", videoUrl)
val quality = "Vidbom:" + `object`.getString("label")
videoList.add(Video(videoUrl, quality, videoUrl))
}
return videoList
} else {
val videoList = mutableListOf<Video>()
videoList.add(Video(url, "no 2video", null))
return videoList
}*/
}
}

View File

@ -5,7 +5,7 @@ ext {
extName = 'WIT ANIME'
pkgNameSuffix = 'ar.witanime'
extClass = '.WitAnime'
extVersionCode = 19
extVersionCode = 20
libVersion = '13'
}

View File

@ -115,7 +115,7 @@ class WitAnime : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
.set("Referer", server)
.set("User-Agent", "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:96.0) Gecko/20100101 Firefox/96.0")
.set("Accept-Language", "en-US,en;q=0.5")
.set("watchsb", "streamsb")
.set("watchsb", "sbstream")
.build()
val videos = StreamSBExtractor(client).videosFromUrl(server, headers)
videoList.addAll(videos)

View File

@ -29,7 +29,7 @@ class StreamSBExtractor(private val client: OkHttpClient) {
val id = url.substringAfter("e/").substringBefore(".html")
val bytes = id.toByteArray()
val bytesToHex = bytesToHex(bytes)
val master = "$sbUrl/sources40/566d337678566f743674494a7c7c${bytesToHex}7c7c346b6767586d6934774855537c7c73747265616d7362/6565417268755339773461447c7c346133383438333436313335376136323337373433383634376337633465366534393338373136643732373736343735373237613763376334363733353737303533366236333463353333363534366137633763373337343732363536313664373336327c7c6b586c3163614468645a47617c7c73747265616d7362"
val master = "$sbUrl/sources48/625a364258615242766475327c7c${bytesToHex}7c7c4761574550654f7461566d347c7c73747265616d7362"
val json = Json.decodeFromString<JsonObject>(
client.newCall(GET(master, headers))
.execute().body!!.string()

View File

@ -6,7 +6,7 @@ ext {
extName = 'Kinoking'
pkgNameSuffix = 'de.kinoking'
extClass = '.Kinoking'
extVersionCode = 1
extVersionCode = 2
libVersion = '13'
}

View File

@ -35,13 +35,13 @@ class StreamSBExtractor(private val client: OkHttpClient) {
"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:96.0) Gecko/20100101 Firefox/96.0"
)
.set("Accept-Language", "en-US,en;q=0.5")
.set("watchsb", "streamsb")
.set("watchsb", "sbstream")
.build()
val sbUrl = url.substringBefore("/e")
val id = url.substringAfter("e/").substringBefore(".html")
val bytes = id.toByteArray()
val bytesToHex = bytesToHex(bytes)
val master = "$sbUrl/sources43/7a6b4d4d6970595145434f707c7c${bytesToHex}7c7c795651787857676c463134447c7c73747265616d7362/7373566465444f45326b64487c7c363536663634333034353633363935383338343437373664376337633339343137393739366334623335366537613736363834313763376334643431366336653663363737353333376134323537353737633763373337343732363536313664373336327c7c713168506f467931717763437c7c73747265616d7362"
val master = "$sbUrl/sources48/625a364258615242766475327c7c${bytesToHex}7c7c4761574550654f7461566d347c7c73747265616d7362"
val json = Json.decodeFromString<JsonObject>(
client.newCall(GET(master, sbHeaders))
.execute().body!!.string()

View File

@ -5,7 +5,7 @@ ext {
extName = 'GenoAnime'
pkgNameSuffix = 'en.genoanime'
extClass = '.GenoAnime'
extVersionCode = 15
extVersionCode = 16
libVersion = '13'
}

View File

@ -134,7 +134,7 @@ class GenoAnime : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
.set("Referer", url)
.set("User-Agent", "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:96.0) Gecko/20100101 Firefox/96.0")
.set("Accept-Language", "en-US,en;q=0.5")
.set("watchsb", "streamsb")
.set("watchsb", "sbstream")
.build()
val videos = StreamSBExtractor(client).videosFromUrl(url, headers)
videoList.addAll(videos)

View File

@ -29,7 +29,7 @@ class StreamSBExtractor(private val client: OkHttpClient) {
val id = url.substringAfter("e/")
val bytes = id.toByteArray()
val bytesToHex = bytesToHex(bytes)
val master = "$sbUrl/sources43/566d337678566f743674494a7c7c${bytesToHex}7c7c346b6767586d6934774855537c7c73747265616d7362/6565417268755339773461447c7c346133383438333436313335376136323337373433383634376337633465366534393338373136643732373736343735373237613763376334363733353737303533366236333463353333363534366137633763373337343732363536313664373336327c7c6b586c3163614468645a47617c7c73747265616d7362"
val master = "$sbUrl/sources48/625a364258615242766475327c7c${bytesToHex}7c7c4761574550654f7461566d347c7c73747265616d7362"
val json = Json.decodeFromString<JsonObject>(
client.newCall(GET(master, headers))
.execute().body!!.string()

View File

@ -5,7 +5,7 @@ ext {
extName = 'Gogoanime'
pkgNameSuffix = 'en.gogoanime'
extClass = '.GogoAnime'
extVersionCode = 47
extVersionCode = 48
libVersion = '13'
}

View File

@ -35,13 +35,13 @@ class StreamSBExtractor(private val client: OkHttpClient) {
"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:96.0) Gecko/20100101 Firefox/96.0"
)
.set("Accept-Language", "en-US,en;q=0.5")
.set("watchsb", "streamsb")
.set("watchsb", "sbstream")
.build()
val sbUrl = url.substringBefore("/e")
val id = url.substringAfter("e/").substringBefore("?")
val bytes = id.toByteArray()
val bytesToHex = bytesToHex(bytes)
val master = "$sbUrl/sources43/566d337678566f743674494a7c7c${bytesToHex}7c7c346b6767586d6934774855537c7c73747265616d7362/6565417268755339773461447c7c346133383438333436313335376136323337373433383634376337633465366534393338373136643732373736343735373237613763376334363733353737303533366236333463353333363534366137633763373337343732363536313664373336327c7c6b586c3163614468645a47617c7c73747265616d7362"
val master = "$sbUrl/sources48/625a364258615242766475327c7c${bytesToHex}7c7c4761574550654f7461566d347c7c73747265616d7362"
val json = Json.decodeFromString<JsonObject>(
client.newCall(GET(master, sbHeaders))
.execute().body!!.string()

View File

@ -5,7 +5,7 @@ ext {
extName = 'KickAssAnime'
pkgNameSuffix = 'en.kickassanime'
extClass = '.KickAssAnime'
extVersionCode = 8
extVersionCode = 9
libVersion = '13'
}

View File

@ -35,13 +35,13 @@ class StreamSBExtractor(private val client: OkHttpClient) {
"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:96.0) Gecko/20100101 Firefox/96.0"
)
.set("Accept-Language", "en-US,en;q=0.5")
.set("watchsb", "streamsb")
.set("watchsb", "sbstream")
.build()
val sbUrl = url.substringBefore("/e")
val id = url.substringAfter("e/").substringBefore("?")
val bytes = id.toByteArray()
val bytesToHex = bytesToHex(bytes)
val master = "$sbUrl/sources43/566d337678566f743674494a7c7c${bytesToHex}7c7c346b6767586d6934774855537c7c73747265616d7362/6565417268755339773461447c7c346133383438333436313335376136323337373433383634376337633465366534393338373136643732373736343735373237613763376334363733353737303533366236333463353333363534366137633763373337343732363536313664373336327c7c6b586c3163614468645a47617c7c73747265616d7362"
val master = "$sbUrl/sources48/625a364258615242766475327c7c${bytesToHex}7c7c4761574550654f7461566d347c7c73747265616d7362"
val json = Json.decodeFromString<JsonObject>(
client.newCall(GET(master, sbHeaders))
.execute().body!!.string()

View File

@ -5,7 +5,7 @@ ext {
extName = 'Vidembed'
pkgNameSuffix = 'en.vidembed'
extClass = '.Vidembed'
extVersionCode = 15
extVersionCode = 16
libVersion = '13'
}

View File

@ -121,7 +121,7 @@ class Vidembed : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
.set("Referer", url)
.set("User-Agent", "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:96.0) Gecko/20100101 Firefox/96.0")
.set("Accept-Language", "en-US,en;q=0.5")
.set("watchsb", "streamsb")
.set("watchsb", "sbstream")
.build()
val videos = StreamSBExtractor(client).videosFromUrl(newUrl, headers)
videoList.addAll(videos)

View File

@ -29,7 +29,7 @@ class StreamSBExtractor(private val client: OkHttpClient) {
val id = url.substringAfter("e/").substringBefore("?")
val bytes = id.toByteArray()
val bytesToHex = bytesToHex(bytes)
val master = "$sbUrl/sources43/566d337678566f743674494a7c7c${bytesToHex}7c7c346b6767586d6934774855537c7c73747265616d7362/6565417268755339773461447c7c346133383438333436313335376136323337373433383634376337633465366534393338373136643732373736343735373237613763376334363733353737303533366236333463353333363534366137633763373337343732363536313664373336327c7c6b586c3163614468645a47617c7c73747265616d7362"
val master = "$sbUrl/sources48/625a364258615242766475327c7c${bytesToHex}7c7c4761574550654f7461566d347c7c73747265616d7362"
val json = Json.decodeFromString<JsonObject>(
client.newCall(GET(master, headers))
.execute().body!!.string()

View File

@ -5,7 +5,7 @@ ext {
extName = 'Animefenix'
pkgNameSuffix = 'es.animefenix'
extClass = '.Animefenix'
extVersionCode = 10
extVersionCode = 11
libVersion = '13'
}

View File

@ -141,7 +141,7 @@ class Animefenix : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36"
)
.set("Accept-Language", "es-MX,es-419;q=0.9,es;q=0.8,en;q=0.7")
.set("watchsb", "streamsb")
.set("watchsb", "sbstream")
.set("authority", "embedsb.com")
.build()
StreamSBExtractor(client).videosFromUrl(realUrl, headers).map { videoList.add(it) }

View File

@ -30,8 +30,7 @@ class StreamSBExtractor(private val client: OkHttpClient) {
val id = url.substringAfter("/e/").substringBefore(".html")
val bytes = id.toByteArray()
val bytesToHex = bytesToHex(bytes)
val master =
"$sbUrl/sources43/416f794d637048744d4565577c7c${bytesToHex}7c7c776e6c7a365964385a484b767c7c73747265616d7362/656d5a62394f713230524a667c7c373635353537333734623561373634613330353134633631376337633339353037343631363934393335363434333730373633363763376337613737353836323434353534363431343633323533376137633763373337343732363536313664373336327c7c59304b7778506d424c4c32767c7c73747265616d7362"
val master = "$sbUrl/sources48/625a364258615242766475327c7c${bytesToHex}7c7c4761574550654f7461566d347c7c73747265616d7362"
val json = Json.decodeFromString<JsonObject>(
client.newCall(GET(master, headers))
.execute().body!!.string()

View File

@ -5,7 +5,7 @@ ext {
extName = 'AnimeFLV'
pkgNameSuffix = 'es.animeflv'
extClass = '.AnimeFlv'
extVersionCode = 28
extVersionCode = 29
libVersion = '13'
}

View File

@ -123,7 +123,7 @@ class AnimeFlv : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36"
)
.set("Accept-Language", "es-MX,es-419;q=0.9,es;q=0.8,en;q=0.7")
.set("watchsb", "streamsb")
.set("watchsb", "sbstream")
.set("authority", "embedsb.com")
.build()
StreamSBExtractor(client).videosFromUrl(url, headers).map { videoList.add(it) }

View File

@ -30,8 +30,7 @@ class StreamSBExtractor(private val client: OkHttpClient) {
val id = url.substringAfter("/e/").substringBefore(".html")
val bytes = id.toByteArray()
val bytesToHex = bytesToHex(bytes)
val master =
"$sbUrl/sources43/416f794d637048744d4565577c7c${bytesToHex}7c7c776e6c7a365964385a484b767c7c73747265616d7362/656d5a62394f713230524a667c7c373635353537333734623561373634613330353134633631376337633339353037343631363934393335363434333730373633363763376337613737353836323434353534363431343633323533376137633763373337343732363536313664373336327c7c59304b7778506d424c4c32767c7c73747265616d7362"
val master = "$sbUrl/sources48/625a364258615242766475327c7c${bytesToHex}7c7c4761574550654f7461566d347c7c73747265616d7362"
val json = Json.decodeFromString<JsonObject>(
client.newCall(GET(master, headers))
.execute().body!!.string()

View File

@ -5,7 +5,7 @@ ext {
extName = 'AnimeLatinoHD'
pkgNameSuffix = 'es.animelatinohd'
extClass = '.AnimeLatinoHD'
extVersionCode = 6
extVersionCode = 7
libVersion = '13'
}

View File

@ -168,7 +168,7 @@ class AnimeLatinoHD : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:96.0) Gecko/20100101 Firefox/96.0"
)
.set("Accept-Language", "en-US,en;q=0.5")
.set("watchsb", "streamsb")
.set("watchsb", "sbstream")
.build()
val videos = StreamSBExtractor(client).videosFromUrl(url, headers, language)
videoList.addAll(videos)

View File

@ -30,8 +30,7 @@ class StreamSBExtractor(private val client: OkHttpClient) {
val id = url.substringAfter("/e/").substringBefore(".html")
val bytes = id.toByteArray()
val bytesToHex = bytesToHex(bytes)
val master =
"$sbUrl/sources43/416f794d637048744d4565577c7c${bytesToHex}7c7c776e6c7a365964385a484b767c7c73747265616d7362/656d5a62394f713230524a667c7c373635353537333734623561373634613330353134633631376337633339353037343631363934393335363434333730373633363763376337613737353836323434353534363431343633323533376137633763373337343732363536313664373336327c7c59304b7778506d424c4c32767c7c73747265616d7362"
val master = "$sbUrl/sources48/625a364258615242766475327c7c${bytesToHex}7c7c4761574550654f7461566d347c7c73747265616d7362"
val json = Json.decodeFromString<JsonObject>(
client.newCall(GET(master, headers))
.execute().body!!.string()

View File

@ -5,7 +5,7 @@ ext {
extName = 'AnimeonlineNinja'
pkgNameSuffix = 'es.animeonlineninja'
extClass = '.AnimeonlineNinja'
extVersionCode = 9
extVersionCode = 10
libVersion = '13'
}

View File

@ -158,7 +158,7 @@ class AnimeonlineNinja : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36"
)
.set("Accept-Language", "es-MX,es-419;q=0.9,es;q=0.8,en;q=0.7")
.set("watchsb", "streamsb")
.set("watchsb", "sbstream")
.set("authority", "embedsb.com")
.build()

View File

@ -30,8 +30,7 @@ class StreamSBExtractor(private val client: OkHttpClient) {
val id = url.substringAfter("/e/").substringBefore(".html")
val bytes = id.toByteArray()
val bytesToHex = bytesToHex(bytes)
val master =
"$sbUrl/sources43/416f794d637048744d4565577c7c${bytesToHex}7c7c776e6c7a365964385a484b767c7c73747265616d7362/656d5a62394f713230524a667c7c373635353537333734623561373634613330353134633631376337633339353037343631363934393335363434333730373633363763376337613737353836323434353534363431343633323533376137633763373337343732363536313664373336327c7c59304b7778506d424c4c32767c7c73747265616d7362"
val master = "$sbUrl/sources48/625a364258615242766475327c7c${bytesToHex}7c7c4761574550654f7461566d347c7c73747265616d7362"
val json = Json.decodeFromString<JsonObject>(
client.newCall(GET(master, headers))
.execute().body!!.string()

View File

@ -5,7 +5,7 @@ ext {
extName = 'AsiaLiveAction'
pkgNameSuffix = 'es.asialiveaction'
extClass = '.AsiaLiveAction'
extVersionCode = 6
extVersionCode = 7
libVersion = '13'
}

View File

@ -110,7 +110,7 @@ class AsiaLiveAction : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:96.0) Gecko/20100101 Firefox/96.0"
)
.set("Accept-Language", "en-US,en;q=0.5")
.set("watchsb", "sbfull")
.set("watchsb", "sbstream")
.build()
val videos = StreamSBExtractor(client).videosFromUrl(url, headers)
videoList.addAll(videos)

View File

@ -30,7 +30,7 @@ class StreamSBExtractor(private val client: OkHttpClient) {
val id = url.substringAfter("/e/").substringBefore(".html")
val bytes = id.toByteArray()
val bytesToHex = bytesToHex(bytes)
val master = "$sbUrl/sources43/674a44656e7654507975614b7c7c${bytesToHex}7c7c4a6d665478704f786e5a464f7c7c73747265616d7362/384c6d46545332726b3171787c7c373637333438343737393661363735343538366434353730376337633734353037393332353734333638363436643730363637373763376336363631346634353732366333323635343933343537346637633763373337343732363536313664373336327c7c5154416f774c34306d4877387c7c73747265616d7362"
val master = "$sbUrl/sources48/625a364258615242766475327c7c${bytesToHex}7c7c4761574550654f7461566d347c7c73747265616d7362"
val json = Json.decodeFromString<JsonObject>(
client.newCall(GET(master, headers))
.execute().body!!.string()

View File

@ -5,7 +5,7 @@ ext {
extName = 'Pelisplushd'
pkgNameSuffix = 'es.pelisplushd'
extClass = '.Pelisplushd'
extVersionCode = 18
extVersionCode = 19
libVersion = '13'
}

View File

@ -153,7 +153,7 @@ class Pelisplushd : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
.set("Referer", url)
.set("User-Agent", "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:96.0) Gecko/20100101 Firefox/96.0")
.set("Accept-Language", "en-US,en;q=0.5")
.set("watchsb", "streamsb")
.set("watchsb", "sbstream")
.build()
val video = try { StreamSBExtractor(client).videosFromUrl(url, headers) } catch (e: Exception) { null }
if (video != null) {

View File

@ -30,8 +30,7 @@ class StreamSBExtractor(private val client: OkHttpClient) {
val id = url.substringAfter("/e/").substringBefore(".html")
val bytes = id.toByteArray()
val bytesToHex = bytesToHex(bytes)
val master =
"$sbUrl/sources43/416f794d637048744d4565577c7c${bytesToHex}7c7c776e6c7a365964385a484b767c7c73747265616d7362/656d5a62394f713230524a667c7c373635353537333734623561373634613330353134633631376337633339353037343631363934393335363434333730373633363763376337613737353836323434353534363431343633323533376137633763373337343732363536313664373336327c7c59304b7778506d424c4c32767c7c73747265616d7362"
val master = "$sbUrl/sources48/625a364258615242766475327c7c${bytesToHex}7c7c4761574550654f7461566d347c7c73747265616d7362"
val json = Json.decodeFromString<JsonObject>(
client.newCall(GET(master, headers))
.execute().body!!.string()

View File

@ -5,7 +5,7 @@ ext {
extName = 'AnimeWorld (experimental)'
pkgNameSuffix = 'hi.animeWorld'
extClass = '.AnimeWorld'
extVersionCode = 10
extVersionCode = 11
libVersion = '13'
}

View File

@ -168,7 +168,7 @@ class AnimeWorld : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
.set("Referer", url)
.set("User-Agent", "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:96.0) Gecko/20100101 Firefox/96.0")
.set("Accept-Language", "en-US,en;q=0.5")
.set("watchsb", "streamsb")
.set("watchsb", "sbstream")
.build()
val videos = StreamSBExtractor(client).videosFromUrl(url, newheaders, language)
videoList.addAll(videos)

View File

@ -30,7 +30,7 @@ class StreamSBExtractor(private val client: OkHttpClient) {
val id = url.substringAfter("e/").substringBefore(".html")
val bytes = id.toByteArray()
val bytesToHex = bytesToHex(bytes)
val master = "$sbUrl/sources43/566d337678566f743674494a7c7c${bytesToHex}7c7c346b6767586d6934774855537c7c73747265616d7362/6565417268755339773461447c7c346133383438333436313335376136323337373433383634376337633465366534393338373136643732373736343735373237613763376334363733353737303533366236333463353333363534366137633763373337343732363536313664373336327c7c6b586c3163614468645a47617c7c73747265616d7362"
val master = "$sbUrl/sources48/625a364258615242766475327c7c${bytesToHex}7c7c4761574550654f7461566d347c7c73747265616d7362"
val json = Json.decodeFromString<JsonObject>(
client.newCall(GET(master, headers))
.execute().body!!.string()

View File

@ -5,7 +5,7 @@ ext {
extName = 'ANIMEWORLD.tv'
pkgNameSuffix = 'it.animeworld'
extClass = '.ANIMEWORLD'
extVersionCode = 11
extVersionCode = 12
libVersion = '13'
}

View File

@ -111,7 +111,7 @@ class ANIMEWORLD : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
.set("Referer", url)
.set("User-Agent", "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:96.0) Gecko/20100101 Firefox/96.0")
.set("Accept-Language", "en-US,en;q=0.5")
.set("watchsb", "streamsb")
.set("watchsb", "sbstream")
.build()
val videos = StreamSBExtractor(client).videosFromUrl(url.replace("/d/", "/e/"), headers)
videoList.addAll(videos)

View File

@ -29,8 +29,7 @@ class StreamSBExtractor(private val client: OkHttpClient) {
val id = url.substringAfter("e/").substringBefore(".html")
val bytes = id.toByteArray()
val bytesToHex = bytesToHex(bytes)
val master =
"$sbUrl/sources43/566d337678566f743674494a7c7c${bytesToHex}7c7c346b6767586d6934774855537c7c73747265616d7362/6565417268755339773461447c7c346133383438333436313335376136323337373433383634376337633465366534393338373136643732373736343735373237613763376334363733353737303533366236333463353333363534366137633763373337343732363536313664373336327c7c6b586c3163614468645a47617c7c73747265616d7362"
val master = "$sbUrl/sources48/625a364258615242766475327c7c${bytesToHex}7c7c4761574550654f7461566d347c7c73747265616d7362"
val json = Json.decodeFromString<JsonObject>(
client.newCall(GET(master, headers))
.execute().body!!.string()

View File

@ -5,7 +5,7 @@ ext {
extName = 'Pi Fansubs'
pkgNameSuffix = 'pt.pifansubs'
extClass = '.PiFansubs'
extVersionCode = 3
extVersionCode = 4
libVersion = '13'
containsNsfw = true
}

View File

@ -30,8 +30,7 @@ class StreamSBExtractor(private val client: OkHttpClient) {
val id = url.substringAfter("e/").substringBefore(".html")
val bytes = id.toByteArray()
val bytesToHex = bytesToHex(bytes)
val master =
"$sbUrl/sources43/566d337678566f743674494a7c7c${bytesToHex}7c7c346b6767586d6934774855537c7c73747265616d7362/6565417268755339773461447c7c346133383438333436313335376136323337373433383634376337633465366534393338373136643732373736343735373237613763376334363733353737303533366236333463353333363534366137633763373337343732363536313664373336327c7c6b586c3163614468645a47617c7c73747265616d7362"
val master = "$sbUrl/sources48/625a364258615242766475327c7c${bytesToHex}7c7c4761574550654f7461566d347c7c73747265616d7362"
val json = Json.decodeFromString<JsonObject>(
client.newCall(GET(master, headers))
.execute().body!!.string()