diff --git a/SoraStream/build.gradle.kts b/SoraStream/build.gradle.kts index 04e1985b..aa277d35 100644 --- a/SoraStream/build.gradle.kts +++ b/SoraStream/build.gradle.kts @@ -1,5 +1,5 @@ // use an integer for version numbers -version = 101 +version = 102 cloudstream { diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt b/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt index 763f793f..6b4ba83c 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt @@ -8,6 +8,7 @@ import com.lagradost.nicehttp.Requests import com.lagradost.nicehttp.Session import com.google.gson.JsonParser import com.hexated.RabbitStream.extractRabbitStream +import com.lagradost.cloudstream3.extractors.Filesim import com.lagradost.cloudstream3.extractors.StreamSB import com.lagradost.cloudstream3.extractors.XStreamCdn import com.lagradost.cloudstream3.network.CloudflareKiller @@ -978,10 +979,55 @@ object SoraExtractor : SoraStream() { }, { invokeAnimeKaizoku(malId, epsTitle, season, episode, callback) - } + }, + { + invokeBiliBili(aniId, episode, subtitleCallback, callback) + }, ) } + private suspend fun invokeBiliBili( + aniId: String? = null, + episode: Int? = null, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ) { + val res = app.get("$biliBiliAPI/anime/episodes?id=$aniId&source_id=bilibili") + .parsedSafe()?.episodes?.find { + it.episodeNumber == episode + } ?: return + + val sources = + app.get("$biliBiliAPI/source?episode_id=${res.sourceEpisodeId}&source_media_id=${res.sourceMediaId}&source_id=${res.sourceId}") + .parsedSafe() + + sources?.sources?.apmap { source -> + val quality = app.get(source.file ?: return@apmap null).document.selectFirst("Representation")?.attr("height") + callback.invoke( + ExtractorLink( + "BiliBili", + "BiliBili", + source.file, + "", + quality?.toIntOrNull() ?: Qualities.Unknown.value, + isDash = true + ) + ) + } + + sources?.subtitles?.map { sub -> + subtitleCallback.invoke( + SubtitleFile( + SubtitleHelper.fromTwoLettersToLanguage(sub.lang ?: "") ?: sub.language + ?: return@map null, + sub.file ?: return@map null + ) + ) + } + + + } + private suspend fun invokeZoro( aniId: String? = null, episode: Int? = null, @@ -2675,7 +2721,7 @@ object SoraExtractor : SoraStream() { "Gomovies", video.src.split("360", limit = 3).joinToString(it.toString()), "$gomoviesAPI/", - it + it, ) ) } @@ -2684,6 +2730,33 @@ object SoraExtractor : SoraStream() { } + suspend fun invokeAsk4Movies( + title: String? = null, + year: Int? = null, + season: Int? = null, + episode: Int? = null, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit, + ) { + val slug = title.createSlug() + val url = if (season == null) { + "$ask4MoviesAPI/$slug-$year" + } else { + "$ask4MoviesAPI/$slug-season-$season" + } + + val doc = app.get(url).document + + val iframe = if(season == null) { + doc.select("div#player-embed iframe").attr("data-src") + } else { + doc.select("ul.group-links-list li:nth-child($episode) a").attr("data-embed-src") + } + + loadExtractor(iframe, ask4MoviesAPI, subtitleCallback, callback) + + } + } @@ -2702,6 +2775,11 @@ class Keephealth : StreamSB() { override var mainUrl = "https://keephealth.info" } +class FileMoonIn : Filesim() { + override val mainUrl = "https://filemoon.in" + override val name = "FileMoon" +} + data class TitleSlug( val dotSlug: String? = null, val spaceSlug: String? = null, @@ -3046,4 +3124,32 @@ data class SapphireStreams( data class SapphireSources( @JsonProperty("streams") val streams: ArrayList? = arrayListOf(), @JsonProperty("subtitles") val subtitles: ArrayList? = arrayListOf(), +) + +data class BiliBiliEpisodes( + @JsonProperty("id") val id: Int? = null, + @JsonProperty("sourceId") val sourceId: String? = null, + @JsonProperty("sourceEpisodeId") val sourceEpisodeId: String? = null, + @JsonProperty("sourceMediaId") val sourceMediaId: String? = null, + @JsonProperty("episodeNumber") val episodeNumber: Int? = null, +) + +data class BiliBiliDetails( + @JsonProperty("episodes") val episodes: ArrayList? = arrayListOf(), +) + +data class BiliBiliSubtitles( + @JsonProperty("file") val file: String? = null, + @JsonProperty("lang") val lang: String? = null, + @JsonProperty("language") val language: String? = null, +) + +data class BiliBiliSources( + @JsonProperty("file") val file: String? = null, + @JsonProperty("type") val type: String? = null, +) + +data class BiliBiliSourcesResponse( + @JsonProperty("sources") val sources: ArrayList? = arrayListOf(), + @JsonProperty("subtitles") val subtitles: ArrayList? = arrayListOf(), ) \ No newline at end of file diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt b/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt index 7dde7063..85745469 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt @@ -3,13 +3,13 @@ package com.hexated import com.fasterxml.jackson.annotation.JsonProperty import com.hexated.SoraExtractor.invoke123Movie import com.hexated.SoraExtractor.invokeAnimes +import com.hexated.SoraExtractor.invokeAsk4Movies import com.hexated.SoraExtractor.invokeBlackmovies import com.hexated.SoraExtractor.invokeBollyMaza import com.hexated.SoraExtractor.invokeCodexmovies import com.hexated.SoraExtractor.invokeCrunchyroll import com.hexated.SoraExtractor.invokeDbgo import com.hexated.SoraExtractor.invokeFilmxy -import com.hexated.SoraExtractor.invokeFlixhq import com.hexated.SoraExtractor.invokeHDMovieBox import com.hexated.SoraExtractor.invokeIdlix import com.hexated.SoraExtractor.invokeKimcartoon @@ -32,7 +32,6 @@ import com.hexated.SoraExtractor.invokeGMovies import com.hexated.SoraExtractor.invokeGdbotMovies import com.hexated.SoraExtractor.invokeGomovies import com.hexated.SoraExtractor.invokeJmdkhMovies -import com.hexated.SoraExtractor.invokeKickassanime import com.hexated.SoraExtractor.invokeKisskh import com.hexated.SoraExtractor.invokeLing import com.hexated.SoraExtractor.invokeM4uhd @@ -72,7 +71,7 @@ open class SoraStream : TmdbProvider() { /** AUTHOR : Hexated & Sora */ companion object { - // TOOLS + /** TOOLS */ private const val tmdbAPI = "https://api.themoviedb.org/3" const val tmdb2mal = "https://tmdb2mal.slidemovies.org" const val jikanAPI = "https://api.jikan.moe/v4" @@ -81,7 +80,7 @@ open class SoraStream : TmdbProvider() { private val apiKey = base64DecodeAPI("ZTM=NTg=MjM=MjM=ODc=MzI=OGQ=MmE=Nzk=Nzk=ZjI=NTA=NDY=NDA=MzA=YjA=") // PLEASE DON'T STEAL - // ALL SOURCES + /** ALL SOURCES */ const val twoEmbedAPI = "https://www.2embed.to" const val vidSrcAPI = "https://v2.vidsrc.me" const val dbgoAPI = "https://dbgo.fun" @@ -93,7 +92,7 @@ open class SoraStream : TmdbProvider() { const val idlixAPI = "https://idlixian.com" const val noverseAPI = "https://www.nollyverse.com" const val olgplyAPI = "https://olgply.xyz" // dead - const val uniqueStreamAPI = "https://uniquestreaming.net" + const val uniqueStreamAPI = "https://uniquestream.net" const val filmxyAPI = "https://www.filmxy.vip" const val kimcartoonAPI = "https://kimcartoon.li" const val xMovieAPI = "https://xemovies.to" @@ -119,6 +118,9 @@ open class SoraStream : TmdbProvider() { const val smashyStreamAPI = "https://embed.smashystream.com" const val watchSomuchAPI = "https://watchsomuch.tv" // sub only val gomoviesAPI = base64DecodeAPI("bQ==Y28=ZS4=aW4=bmw=LW8=ZXM=dmk=bW8=Z28=Ly8=czo=dHA=aHQ=") + const val ask4MoviesAPI = "https://ask4movie.mx" + const val biliBiliAPI = "https://api-vn.kaguya.app/server" + // INDEX SITE const val baymoviesAPI = "https://opengatewayindex.pages.dev" // dead const val chillmovies0API = "https://chill.aicirou.workers.dev/0:" // dead const val chillmovies1API = "https://chill.aicirou.workers.dev/1:" // dead @@ -782,6 +784,9 @@ open class SoraStream : TmdbProvider() { callback ) }, + { + invokeAsk4Movies(res.title, res.year, res.season, res.episode, subtitleCallback, callback) + }, ) return true diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraStreamLite.kt b/SoraStream/src/main/kotlin/com/hexated/SoraStreamLite.kt index 774dff71..6082013c 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraStreamLite.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraStreamLite.kt @@ -2,16 +2,15 @@ package com.hexated import com.hexated.SoraExtractor.invoke123Movie import com.hexated.SoraExtractor.invokeAnimes +import com.hexated.SoraExtractor.invokeAsk4Movies import com.hexated.SoraExtractor.invokeCrunchyroll import com.hexated.SoraExtractor.invokeDbgo import com.hexated.SoraExtractor.invokeFilmxy -import com.hexated.SoraExtractor.invokeFlixhq import com.hexated.SoraExtractor.invokeFlixon import com.hexated.SoraExtractor.invokeFwatayako import com.hexated.SoraExtractor.invokeGomovies import com.hexated.SoraExtractor.invokeHDMovieBox import com.hexated.SoraExtractor.invokeIdlix -import com.hexated.SoraExtractor.invokeKickassanime import com.hexated.SoraExtractor.invokeKimcartoon import com.hexated.SoraExtractor.invokeKisskh import com.hexated.SoraExtractor.invokeLing @@ -21,7 +20,6 @@ import com.hexated.SoraExtractor.invokeMovieHab import com.hexated.SoraExtractor.invokeRStream import com.hexated.SoraExtractor.invokeSeries9 import com.hexated.SoraExtractor.invokeSmashyStream -import com.hexated.SoraExtractor.invokeSoraStream import com.hexated.SoraExtractor.invokeSoraStreamLite import com.hexated.SoraExtractor.invokeTwoEmbed import com.hexated.SoraExtractor.invokeUniqueStream @@ -214,6 +212,16 @@ class SoraStreamLite : SoraStream() { { invokeGomovies(res.title, res.year, res.season, res.episode, callback) }, + { + invokeAsk4Movies( + res.title, + res.year, + res.season, + res.episode, + subtitleCallback, + callback + ) + }, ) return true diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraStreamPlugin.kt b/SoraStream/src/main/kotlin/com/hexated/SoraStreamPlugin.kt index 754b2f44..7067fd0c 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraStreamPlugin.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraStreamPlugin.kt @@ -14,5 +14,6 @@ class SoraStreamPlugin: Plugin() { registerExtractorAPI(StreamM4u()) registerExtractorAPI(Sblongvu()) registerExtractorAPI(Keephealth()) + registerExtractorAPI(FileMoonIn()) } } \ No newline at end of file