mirror of
				https://github.com/recloudstream/cloudstream.git
				synced 2024-08-15 01:53:11 +00:00 
			
		
		
		
	fixed Sflix and Zoro
This commit is contained in:
		
							parent
							
								
									2f71fa5664
								
							
						
					
					
						commit
						70c14d116c
					
				
					 4 changed files with 51 additions and 17 deletions
				
			
		|  | @ -250,7 +250,10 @@ class ZoroProvider : MainAPI() { | ||||||
|     private fun getM3u8FromRapidCloud(url: String): String { |     private fun getM3u8FromRapidCloud(url: String): String { | ||||||
|         return get( |         return get( | ||||||
|             "$url&autoPlay=1&oa=0", |             "$url&autoPlay=1&oa=0", | ||||||
|             headers = mapOf("Referer" to "https://zoro.to/", "User-Agent" to "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:94.0) Gecko/20100101 Firefox/94.0"), |             headers = mapOf( | ||||||
|  |                 "Referer" to "https://zoro.to/", | ||||||
|  |                 "User-Agent" to "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:94.0) Gecko/20100101 Firefox/94.0" | ||||||
|  |             ), | ||||||
|             interceptor = WebViewResolver( |             interceptor = WebViewResolver( | ||||||
|                 Regex("""/getSources""") |                 Regex("""/getSources""") | ||||||
|             ) |             ) | ||||||
|  | @ -284,17 +287,35 @@ class ZoroProvider : MainAPI() { | ||||||
|                 Regex("""/getSources""") |                 Regex("""/getSources""") | ||||||
|             ) |             ) | ||||||
|         ) |         ) | ||||||
|  | //        println("RES TEXT ${res.text}") | ||||||
| 
 | 
 | ||||||
|         val recaptchaToken = res.request.url.queryParameter("_token") |         val recaptchaToken = res.request.url.queryParameter("_token") | ||||||
| 
 | 
 | ||||||
|         val responses = servers.map { |         val responses = servers.map { | ||||||
|             val link = "$mainUrl/ajax/v2/episode/sources?id=${it.second}&_token=$recaptchaToken" |             val link = "$mainUrl/ajax/v2/episode/sources?id=${it.second}&_token=$recaptchaToken" | ||||||
|             Pair(it.first, getM3u8FromRapidCloud(mapper.readValue<RapidCloudResponse>(get(link, res.request.headers.toMap()).text).link)) |             Pair( | ||||||
|  |                 it.first, | ||||||
|  |                 getM3u8FromRapidCloud( | ||||||
|  |                     mapper.readValue<RapidCloudResponse>( | ||||||
|  |                         get( | ||||||
|  |                             link, | ||||||
|  |                             res.request.headers.toMap() | ||||||
|  |                         ).text | ||||||
|  |                     ).link | ||||||
|  |                 ) | ||||||
|  |             ) | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         responses.forEach { |         responses.forEach { | ||||||
|             if (it.second.contains("<html")) return@forEach |             if (it.second.contains("<html")) return@forEach | ||||||
|             val mapped = mapper.readValue<SflixProvider.SourceObject>(it.second) |             val mapped = mapper.readValue<SflixProvider.SourceObject>(it.second) | ||||||
|  | 
 | ||||||
|  |             mapped.tracks?.forEach { track -> | ||||||
|  |                 track?.toSubtitleFile()?.let { subtitleFile -> | ||||||
|  |                     subtitleCallback.invoke(subtitleFile) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|             val list = listOf( |             val list = listOf( | ||||||
|                 mapped.sources to "source 1", |                 mapped.sources to "source 1", | ||||||
|                 mapped.sources1 to "source 2", |                 mapped.sources1 to "source 2", | ||||||
|  | @ -307,12 +328,6 @@ class ZoroProvider : MainAPI() { | ||||||
|                     a?.toExtractorLink(this, subList.second + " - ${it.first}")?.forEach(callback) |                     a?.toExtractorLink(this, subList.second + " - ${it.first}")?.forEach(callback) | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 |  | ||||||
|             mapped.tracks?.forEach { track -> |  | ||||||
|                 track?.toSubtitleFile()?.let { subtitleFile -> |  | ||||||
|                     subtitleCallback.invoke(subtitleFile) |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         return true |         return true | ||||||
|  |  | ||||||
|  | @ -297,7 +297,11 @@ class SflixProvider : MainAPI() { | ||||||
|         ).text |         ).text | ||||||
| 
 | 
 | ||||||
|         val mapped = mapper.readValue<SourceObject>(sources) |         val mapped = mapper.readValue<SourceObject>(sources) | ||||||
| 
 |         mapped.tracks?.forEach { | ||||||
|  |             it?.toSubtitleFile()?.let { subtitleFile -> | ||||||
|  |                 subtitleCallback.invoke(subtitleFile) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|         val list = listOf( |         val list = listOf( | ||||||
|             mapped.sources to "source 1", |             mapped.sources to "source 1", | ||||||
|             mapped.sources1 to "source 2", |             mapped.sources1 to "source 2", | ||||||
|  | @ -309,11 +313,6 @@ class SflixProvider : MainAPI() { | ||||||
|                 it?.toExtractorLink(this, subList.second)?.forEach(callback) |                 it?.toExtractorLink(this, subList.second)?.forEach(callback) | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         mapped.tracks?.forEach { |  | ||||||
|             it?.toSubtitleFile()?.let { subtitleFile -> |  | ||||||
|                 subtitleCallback.invoke(subtitleFile) |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         return true |         return true | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -15,7 +15,7 @@ var baseClient = OkHttpClient() | ||||||
| private const val DEFAULT_TIME = 10 | private const val DEFAULT_TIME = 10 | ||||||
| private val DEFAULT_TIME_UNIT = TimeUnit.MINUTES | private val DEFAULT_TIME_UNIT = TimeUnit.MINUTES | ||||||
| private const val DEFAULT_USER_AGENT = USER_AGENT | private const val DEFAULT_USER_AGENT = USER_AGENT | ||||||
| private val DEFAULT_HEADERS = mapOf("User-Agent" to DEFAULT_USER_AGENT) | private val DEFAULT_HEADERS = mapOf("user-agent" to DEFAULT_USER_AGENT) | ||||||
| private val DEFAULT_DATA: Map<String, String> = mapOf() | private val DEFAULT_DATA: Map<String, String> = mapOf() | ||||||
| private val DEFAULT_COOKIES: Map<String, String> = mapOf() | private val DEFAULT_COOKIES: Map<String, String> = mapOf() | ||||||
| private val DEFAULT_REFERER: String? = null | private val DEFAULT_REFERER: String? = null | ||||||
|  |  | ||||||
|  | @ -4,12 +4,14 @@ import android.annotation.SuppressLint | ||||||
| import android.net.http.SslError | import android.net.http.SslError | ||||||
| import android.webkit.* | import android.webkit.* | ||||||
| import com.lagradost.cloudstream3.AcraApplication | import com.lagradost.cloudstream3.AcraApplication | ||||||
|  | import com.lagradost.cloudstream3.USER_AGENT | ||||||
| import com.lagradost.cloudstream3.utils.Coroutines.main | import com.lagradost.cloudstream3.utils.Coroutines.main | ||||||
| import kotlinx.coroutines.delay | import kotlinx.coroutines.delay | ||||||
| import kotlinx.coroutines.runBlocking | import kotlinx.coroutines.runBlocking | ||||||
| import okhttp3.Interceptor | import okhttp3.Interceptor | ||||||
| import okhttp3.Request | import okhttp3.Request | ||||||
| import okhttp3.Response | import okhttp3.Response | ||||||
|  | import java.net.URI | ||||||
| import java.util.concurrent.TimeUnit | import java.util.concurrent.TimeUnit | ||||||
| 
 | 
 | ||||||
| class WebViewResolver(val interceptUrl: Regex) : Interceptor { | class WebViewResolver(val interceptUrl: Regex) : Interceptor { | ||||||
|  | @ -48,6 +50,7 @@ class WebViewResolver(val interceptUrl: Regex) : Interceptor { | ||||||
|                 // Bare minimum to bypass captcha |                 // Bare minimum to bypass captcha | ||||||
|                 settings.javaScriptEnabled = true |                 settings.javaScriptEnabled = true | ||||||
|                 settings.domStorageEnabled = true |                 settings.domStorageEnabled = true | ||||||
|  |                 settings.userAgentString = USER_AGENT | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             webView?.webViewClient = object : WebViewClient() { |             webView?.webViewClient = object : WebViewClient() { | ||||||
|  | @ -56,6 +59,7 @@ class WebViewResolver(val interceptUrl: Regex) : Interceptor { | ||||||
|                     request: WebResourceRequest |                     request: WebResourceRequest | ||||||
|                 ): WebResourceResponse? { |                 ): WebResourceResponse? { | ||||||
|                     val webViewUrl = request.url.toString() |                     val webViewUrl = request.url.toString() | ||||||
|  | //                    println("Loading WebView URL: $webViewUrl") | ||||||
| 
 | 
 | ||||||
|                     if (interceptUrl.containsMatchIn(webViewUrl)) { |                     if (interceptUrl.containsMatchIn(webViewUrl)) { | ||||||
|                         fixedRequest = getRequestCreator( |                         fixedRequest = getRequestCreator( | ||||||
|  | @ -70,12 +74,28 @@ class WebViewResolver(val interceptUrl: Regex) : Interceptor { | ||||||
| 
 | 
 | ||||||
|                         println("Web-view request finished: $webViewUrl") |                         println("Web-view request finished: $webViewUrl") | ||||||
|                         destroyWebView() |                         destroyWebView() | ||||||
|  |                         return null | ||||||
|                     } |                     } | ||||||
| 
 | 
 | ||||||
|  |                     // Suppress image requests as we don't display them anywhere | ||||||
|  |                     // Less data, low chance of causing issues. | ||||||
|  |                     val blacklistedFiles = listOf(".jpg", ".png", ".webp", ".jpeg", ".webm", ".mp4") | ||||||
|  | 
 | ||||||
|  |                     /** NOTE!  request.requestHeaders is not perfect! | ||||||
|  |                      *  They don't contain all the headers the browser actually gives. | ||||||
|  |                      *  Overriding with okhttp might fuck up otherwise working requests, | ||||||
|  |                      *  e.g the recaptcha request. | ||||||
|  |                      * **/ | ||||||
|                     return try { |                     return try { | ||||||
|                         when { |                         when { | ||||||
|                             // suppress favicon requests as we don't display them anywhere |                             blacklistedFiles.any { URI(webViewUrl).path.endsWith(it) } || webViewUrl.endsWith( | ||||||
|                             webViewUrl.endsWith("/favicon.ico") -> WebResourceResponse("image/png", null, null) |                                 "/favicon.ico" | ||||||
|  |                             ) -> WebResourceResponse( | ||||||
|  |                                 "image/png", | ||||||
|  |                                 null, | ||||||
|  |                                 null | ||||||
|  |                             ) | ||||||
|  | 
 | ||||||
|                             webViewUrl.contains("recaptcha") -> super.shouldInterceptRequest(view, request) |                             webViewUrl.contains("recaptcha") -> super.shouldInterceptRequest(view, request) | ||||||
| 
 | 
 | ||||||
|                             request.method == "GET" -> get( |                             request.method == "GET" -> get( | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue