diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 95b4cb1c..2781af8a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -65,25 +65,41 @@ - + + + + - + - + + + + + - + + + + + + + + + + diff --git a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt index 7761e66a..f86bd2fb 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/MainAPI.kt @@ -74,7 +74,8 @@ object APIHolder { DramaSeeProvider(), WatchAsianProvider(), KdramaHoodProvider(), - AkwamProvider() + AkwamProvider(), + AnimePaheProvider(), ) val restrictedApis = arrayListOf( @@ -194,7 +195,7 @@ object APIHolder { allApis } else { // Filter API depending on preferred media type - val listEnumAnime = listOf(TvType.Anime, TvType.AnimeMovie, TvType.ONA) + val listEnumAnime = listOf(TvType.Anime, TvType.AnimeMovie, TvType.OVA) val listEnumMovieTv = listOf(TvType.Movie, TvType.TvSeries, TvType.Cartoon) val mediaTypeList = if (currentPrefMedia == 1) listEnumMovieTv else listEnumAnime @@ -232,7 +233,7 @@ abstract class MainAPI { TvType.TvSeries, TvType.Cartoon, TvType.Anime, - TvType.ONA, + TvType.OVA, ) open val vpnStatus = VPNStatus.None @@ -386,7 +387,7 @@ enum class TvType { TvSeries, Cartoon, Anime, - ONA, + OVA, Torrent, Documentary, } @@ -398,7 +399,7 @@ fun TvType.isMovieType(): Boolean { // returns if the type has an anime opening fun TvType.isAnimeOp(): Boolean { - return this == TvType.Anime || this == TvType.ONA + return this == TvType.Anime || this == TvType.OVA } data class SubtitleFile(val lang: String, val url: String) @@ -478,7 +479,7 @@ interface LoadResponse { val posterUrl: String? val year: Int? val plot: String? - val rating: Int? // 0-100 + val rating: Int? // 1-1000 val tags: List? var duration: Int? // in minutes val trailerUrl: String? @@ -492,7 +493,7 @@ fun LoadResponse?.isEpisodeBased(): Boolean { fun LoadResponse?.isAnimeBased(): Boolean { if (this == null) return false - return (this.type == TvType.Anime || this.type == TvType.ONA) // && (this is AnimeLoadResponse) + return (this.type == TvType.Anime || this.type == TvType.OVA) // && (this is AnimeLoadResponse) } fun TvType?.isEpisodeBased(): Boolean { diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeFlickProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeFlickProvider.kt index 6b075fba..9ddc9d07 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeFlickProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeFlickProvider.kt @@ -10,7 +10,7 @@ import java.util.* class AnimeFlickProvider : MainAPI() { companion object { fun getType(t: String): TvType { - return if (t.contains("OVA") || t.contains("Special")) TvType.ONA + return if (t.contains("OVA") || t.contains("Special")) TvType.OVA else if (t.contains("Movie")) TvType.AnimeMovie else TvType.Anime } @@ -24,7 +24,7 @@ class AnimeFlickProvider : MainAPI() { override val supportedTypes = setOf( TvType.AnimeMovie, TvType.Anime, - TvType.ONA + TvType.OVA ) override suspend fun search(query: String): ArrayList { diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimePaheProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimePaheProvider.kt index 32fa9c59..e71d1a9a 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimePaheProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimePaheProvider.kt @@ -6,6 +6,7 @@ import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.mvvm.suspendSafeApiCall import com.lagradost.cloudstream3.network.AppResponse import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.JsUnpacker import com.lagradost.cloudstream3.utils.getQualityFromName import org.jsoup.Jsoup import java.util.* @@ -18,7 +19,7 @@ class AnimePaheProvider : MainAPI() { var cookies: Map = mapOf() private fun getType(t: String): TvType { - return if (t.contains("OVA") || t.contains("Special")) TvType.ONA + return if (t.contains("OVA") || t.contains("Special")) TvType.OVA else if (t.contains("Movie")) TvType.AnimeMovie else TvType.Anime } @@ -51,7 +52,7 @@ class AnimePaheProvider : MainAPI() { override val supportedTypes = setOf( TvType.AnimeMovie, TvType.Anime, - TvType.ONA + TvType.OVA ) override suspend fun getMainPage(): HomePageResponse { @@ -428,7 +429,7 @@ class AnimePaheProvider : MainAPI() { @JsonProperty("id") val id: Int?, @JsonProperty("audio") val audio: String?, @JsonProperty("kwik") val kwik: String?, - @JsonProperty("kwik_adfly") val kwikAdfly: String + @JsonProperty("kwik_pahewin") val kwikPahewin: String ) private data class AnimePaheEpisodeLoadLinks( @@ -460,7 +461,25 @@ class AnimePaheProvider : MainAPI() { return decodeAdfly(YTSM.find(adflyContent?.text.toString())!!.destructured.component1()) } - private suspend fun getStreamUrlFromKwik(adflyUri: String): String { + private suspend fun getStreamUrlFromKwik(url: String?): String? { + if (url == null) return null + val response = + app.get( + url, + headers = mapOf("referer" to mainUrl), + cookies = cookies + ).text + Regex("eval((.|\\n)*?)").find(response)?.groupValues?.get(1)?.let { jsEval -> + JsUnpacker("eval$jsEval").unpack()?.let { unPacked -> + Regex("source=\'(.*?)\'").find(unPacked)?.groupValues?.get(1)?.let { link -> + return link + } + } + } + return null + } + + private suspend fun getStreamUrlFromKwikAdfly(adflyUri: String): String { val fContent = app.get( bypassAdfly(adflyUri), @@ -495,7 +514,10 @@ class AnimePaheProvider : MainAPI() { return content?.headers?.values("location").toString() } - private suspend fun extractVideoLinks(episodeLink: String): List { + private suspend fun extractVideoLinks( + episodeLink: String, + callback: (ExtractorLink) -> Unit + ) { var link = episodeLink val headers = mapOf("referer" to "$mainUrl/") @@ -520,23 +542,22 @@ class AnimePaheProvider : MainAPI() { val req = app.get(link, headers = headers).text val data = mapper.readValue(req) - val qualities = ArrayList() - data.data.forEach { - it.entries.forEach { quality -> - qualities.add( - ExtractorLink( - "KWIK", - "KWIK - ${quality.key} [${quality.value.audio ?: "jpn"}]", - getStreamUrlFromKwik(quality.value.kwikAdfly), - "", - getQualityFromName(quality.key), - false + it.entries.toList().apmap { quality -> + getStreamUrlFromKwik(quality.value.kwik)?.let { link -> + callback( + ExtractorLink( + "KWIK", + "KWIK - ${quality.key} [${quality.value.audio ?: "jpn"}]", + link, + "https://kwik.cx/", + getQualityFromName(quality.key), + link.contains(".m3u8") + ) ) - ) + } } } - return qualities } override suspend fun loadLinks( @@ -545,9 +566,7 @@ class AnimePaheProvider : MainAPI() { subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit ): Boolean { - for (server in extractVideoLinks(data)) { - callback.invoke(server) - } + extractVideoLinks(data, callback) return true } } diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeflvProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeflvProvider.kt index 0b3b2d95..b8209e91 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeflvProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/AnimeflvProvider.kt @@ -9,7 +9,7 @@ import kotlin.collections.ArrayList class AnimeflvnetProvider : MainAPI() { companion object { fun getType(t: String): TvType { - return if (t.contains("OVA") || t.contains("Especial")) TvType.ONA + return if (t.contains("OVA") || t.contains("Especial")) TvType.OVA else if (t.contains("PelĂ­cula")) TvType.AnimeMovie else TvType.Anime } @@ -23,7 +23,7 @@ class AnimeflvnetProvider : MainAPI() { override val hasDownloadSupport = true override val supportedTypes = setOf( TvType.AnimeMovie, - TvType.ONA, + TvType.OVA, TvType.Anime, ) diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/GogoanimeProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/GogoanimeProvider.kt index 668f445f..b4837439 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/GogoanimeProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/GogoanimeProvider.kt @@ -14,7 +14,7 @@ import javax.crypto.spec.SecretKeySpec class GogoanimeProvider : MainAPI() { companion object { fun getType(t: String): TvType { - return if (t.contains("OVA") || t.contains("Special")) TvType.ONA + return if (t.contains("OVA") || t.contains("Special")) TvType.OVA else if (t.contains("Movie")) TvType.AnimeMovie else TvType.Anime } @@ -58,7 +58,7 @@ class GogoanimeProvider : MainAPI() { override val supportedTypes = setOf( TvType.AnimeMovie, TvType.Anime, - TvType.ONA + TvType.OVA ) override suspend fun getMainPage(): HomePageResponse { diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/KawaiifuProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/KawaiifuProvider.kt index 2d708a64..38ede9af 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/KawaiifuProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/KawaiifuProvider.kt @@ -12,7 +12,7 @@ class KawaiifuProvider : MainAPI() { override val hasQuickSearch = false override val hasMainPage = true - override val supportedTypes = setOf(TvType.Anime, TvType.AnimeMovie, TvType.ONA) + override val supportedTypes = setOf(TvType.Anime, TvType.AnimeMovie) override suspend fun getMainPage(): HomePageResponse { val items = ArrayList() diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/MonoschinosProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/MonoschinosProvider.kt index 29a01971..4e8fcfb5 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/MonoschinosProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/MonoschinosProvider.kt @@ -11,7 +11,7 @@ import kotlin.collections.ArrayList class MonoschinosProvider : MainAPI() { companion object { fun getType(t: String): TvType { - return if (t.contains("OVA") || t.contains("Especial")) TvType.ONA + return if (t.contains("OVA") || t.contains("Especial")) TvType.OVA else if (t.contains("Pelicula")) TvType.AnimeMovie else TvType.Anime } @@ -25,7 +25,7 @@ class MonoschinosProvider : MainAPI() { override val hasDownloadSupport = true override val supportedTypes = setOf( TvType.AnimeMovie, - TvType.ONA, + TvType.OVA, TvType.Anime, ) diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/TenshiProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/TenshiProvider.kt index 70e0244f..84931e4b 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/TenshiProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/TenshiProvider.kt @@ -20,7 +20,7 @@ class TenshiProvider : MainAPI() { //var cookie: Map = mapOf() fun getType(t: String): TvType { - return if (t.contains("OVA") || t.contains("Special")) TvType.ONA + return if (t.contains("OVA") || t.contains("Special")) TvType.OVA else if (t.contains("Movie")) TvType.AnimeMovie else TvType.Anime } @@ -30,7 +30,7 @@ class TenshiProvider : MainAPI() { override val name = "Tenshi.moe" override val hasQuickSearch = false override val hasMainPage = true - override val supportedTypes = setOf(TvType.Anime, TvType.AnimeMovie, TvType.ONA) + override val supportedTypes = setOf(TvType.Anime, TvType.AnimeMovie, TvType.OVA) private var ddosGuardKiller = DdosGuardKiller(true) /*private fun loadToken(): Boolean { diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WcoProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WcoProvider.kt index 83f77631..7f0f99fd 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WcoProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/WcoProvider.kt @@ -12,7 +12,7 @@ import java.util.* class WcoProvider : MainAPI() { companion object { fun getType(t: String): TvType { - return if (t.contains("OVA") || t.contains("Special")) TvType.ONA + return if (t.contains("OVA") || t.contains("Special")) TvType.OVA else if (t.contains("Movie")) TvType.AnimeMovie else TvType.Anime } @@ -26,7 +26,7 @@ class WcoProvider : MainAPI() { override val supportedTypes = setOf( TvType.AnimeMovie, TvType.Anime, - TvType.ONA + TvType.OVA ) override suspend fun getMainPage(): HomePageResponse { diff --git a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/ZoroProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/ZoroProvider.kt index 0bb0e4f4..a437e509 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/animeproviders/ZoroProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/animeproviders/ZoroProvider.kt @@ -26,12 +26,12 @@ class ZoroProvider : MainAPI() { override val supportedTypes = setOf( TvType.Anime, TvType.AnimeMovie, - TvType.ONA + TvType.OVA ) companion object { fun getType(t: String): TvType { - return if (t.contains("OVA") || t.contains("Special")) TvType.ONA + return if (t.contains("OVA") || t.contains("Special")) TvType.OVA else if (t.contains("Movie")) TvType.AnimeMovie else TvType.Anime } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DoramasYTProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DoramasYTProvider.kt index cd7778ee..1c1c0d1a 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DoramasYTProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/DoramasYTProvider.kt @@ -11,7 +11,7 @@ import kotlin.collections.ArrayList class DoramasYTProvider : MainAPI() { companion object { fun getType(t: String): TvType { - return if (t.contains("OVA") || t.contains("Especial")) TvType.ONA + return if (t.contains("OVA") || t.contains("Especial")) TvType.OVA else if (t.contains("Pelicula")) TvType.Movie else TvType.TvSeries } diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/TrailersTwoProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/TrailersTwoProvider.kt index 54b466ad..c316f38e 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/TrailersTwoProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/TrailersTwoProvider.kt @@ -119,9 +119,9 @@ class TrailersTwoProvider : TmdbProvider() { override val supportedTypes = setOf( TvType.Movie, TvType.TvSeries, - TvType.AnimeMovie, - TvType.Anime, - TvType.Cartoon + //TvType.AnimeMovie, + //TvType.Anime, + //TvType.Cartoon ) override suspend fun loadLinks( diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeFragment.kt index bba25e69..68082bae 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/home/HomeFragment.kt @@ -146,7 +146,7 @@ class HomeFragment : Fragment() { movies: MaterialButton? ): List>> { return listOf( - Pair(anime, listOf(TvType.Anime, TvType.ONA, TvType.AnimeMovie)), + Pair(anime, listOf(TvType.Anime, TvType.OVA, TvType.AnimeMovie)), Pair(cartoons, listOf(TvType.Cartoon)), Pair(tvs, listOf(TvType.TvSeries)), Pair(docs, listOf(TvType.Documentary)), @@ -376,7 +376,7 @@ class HomeFragment : Fragment() { Pair(R.string.tv_series, listOf(TvType.TvSeries)), Pair(R.string.documentaries, listOf(TvType.Documentary)), Pair(R.string.cartoons, listOf(TvType.Cartoon)), - Pair(R.string.anime, listOf(TvType.Anime, TvType.ONA, TvType.AnimeMovie)), + Pair(R.string.anime, listOf(TvType.Anime, TvType.OVA, TvType.AnimeMovie)), Pair(R.string.torrent, listOf(TvType.Torrent)), ).filter { item -> currentApi.supportedTypes.any { type -> item.second.contains(type) } } home_provider_meta_info?.text = diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/player/CS3IPlayer.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/player/CS3IPlayer.kt index 44142e19..86a05abe 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/player/CS3IPlayer.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/player/CS3IPlayer.kt @@ -221,10 +221,11 @@ class CS3IPlayer : IPlayer { } } - private fun releasePlayer() { + private fun releasePlayer(saveTime: Boolean = true) { Log.i(TAG, "releasePlayer") - updatedTime() + if (saveTime) + updatedTime() exoPlayer?.release() simpleCache?.release() @@ -558,7 +559,8 @@ class CS3IPlayer : IPlayer { val invalid = exoPlayer?.duration?.let { duration -> duration < 20000L } ?: false - if(invalid) { + if (invalid) { + releasePlayer(saveTime = false) playerError?.invoke(InvalidFileException("Too short playback")) return } diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt index 7c7c909c..e48d7c72 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/result/ResultFragment.kt @@ -192,7 +192,7 @@ class ResultFragment : Fragment() { updateUIListener?.invoke() } - private var updateUIListener : (() -> Unit)? = null + private var updateUIListener: (() -> Unit)? = null } private var currentLoadingCount = @@ -517,7 +517,7 @@ class ResultFragment : Fragment() { TvType.Movie -> "Movies" TvType.AnimeMovie -> "Movies" TvType.TvSeries -> "TVSeries/$titleName" - TvType.ONA -> "ONA" + TvType.OVA -> "OVA" TvType.Cartoon -> "Cartoons/$titleName" TvType.Torrent -> "Torrent" TvType.Documentary -> "Documentaries" @@ -771,7 +771,7 @@ class ResultFragment : Fragment() { val i = Intent(ACTION_VIEW) i.data = Uri.parse(link.url) startActivity(i) - } catch (e : Exception) { + } catch (e: Exception) { logError(e) } } @@ -1339,6 +1339,22 @@ class ResultFragment : Fragment() { lateFixDownloadButton(false) } + context?.getString( + when (d.type) { + TvType.TvSeries -> R.string.tv_series_singular + TvType.Anime -> R.string.anime_singular + TvType.OVA -> R.string.ova_singular + TvType.AnimeMovie -> R.string.movies_singular + TvType.Cartoon -> R.string.cartoons_singular + TvType.Documentary -> R.string.documentaries_singular + TvType.Movie -> R.string.movies_singular + TvType.Torrent -> R.string.torrent_singular + } + )?.let { + result_meta_type?.text = it + } + + when (d) { is AnimeLoadResponse -> { diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/JsUnpacker.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/JsUnpacker.kt index c4597c36..153dbd3e 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/JsUnpacker.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/JsUnpacker.kt @@ -1,5 +1,6 @@ package com.lagradost.cloudstream3.utils +import com.lagradost.cloudstream3.mvvm.logError import java.util.regex.Pattern import kotlin.math.pow @@ -57,7 +58,7 @@ class JsUnpacker(packedJS: String?) { val word = m.group(0) val x = unbase.unbase(word) var value: String? = null - if (x < symtab.size) { + if (x < symtab.size && x >= 0) { value = symtab[x] } if (value != null && value.isNotEmpty()) { @@ -68,7 +69,7 @@ class JsUnpacker(packedJS: String?) { return decoded.toString() } } catch (e: Exception) { -// logError(e) + logError(e) } return null } diff --git a/app/src/main/res/layout/fragment_result.xml b/app/src/main/res/layout/fragment_result.xml index 18cdd269..d2d47f1f 100644 --- a/app/src/main/res/layout/fragment_result.xml +++ b/app/src/main/res/layout/fragment_result.xml @@ -321,16 +321,16 @@ - @@ -339,8 +339,24 @@ style="@style/SmallBlackButton" android:layout_gravity="center_vertical" tools:text="Gogoanime" /> - + - + Anime Torrents Documentaries + OVA Movie Series Cartoon @string/anime + @string/ova Torrent Documentary