@@ -30,24 +30,25 @@ import org.jsoup.Jsoup
3030import org.jsoup.nodes.Element
3131
3232class TurnstileInterceptor (private val targetCookie : String = " _as_turnstile" ) : Interceptor {
33+
3334 @SuppressLint(" SetJavaScriptEnabled" )
3435 override fun intercept (chain : Interceptor .Chain ): Response {
3536 val originalRequest = chain.request()
3637 val url = originalRequest.url.toString()
37-
3838 val domainUrl = " ${originalRequest.url.scheme} ://${originalRequest.url.host} "
3939 val cookieManager = CookieManager .getInstance()
4040
41+ cookieManager.setAcceptCookie(true )
42+
4143 var currentCookies = cookieManager.getCookie(domainUrl) ? : " "
4244 var userAgent = originalRequest.header(" User-Agent" ) ? : " "
43-
4445 var needsRefresh = false
4546 var initialResponse: Response ? = null
4647
4748 if (currentCookies.contains(targetCookie)) {
4849 val requestBuilder = originalRequest.newBuilder()
4950 .header(" Cookie" , currentCookies)
50-
51+
5152 initialResponse = chain.proceed(requestBuilder.build())
5253
5354 if (initialResponse.code == 403 || initialResponse.code == 503 ) {
@@ -69,28 +70,38 @@ class TurnstileInterceptor(private val targetCookie: String = "_as_turnstile") :
6970 handler.post {
7071 val newWebView = WebView (context)
7172 webView = newWebView
72-
73+
74+ cookieManager.setAcceptCookie(true )
75+ cookieManager.setAcceptThirdPartyCookies(newWebView, true )
76+
7377 newWebView.settings.apply {
7478 javaScriptEnabled = true
7579 domStorageEnabled = true
80+ databaseEnabled = true
81+ loadWithOverviewMode = true
82+ useWideViewPort = true
7683 userAgentString = userAgent.ifBlank { userAgentString }
7784 }
7885 userAgent = newWebView.settings.userAgentString ? : userAgent
7986
80- newWebView.webViewClient = WebViewClient ()
87+ newWebView.webViewClient = object : WebViewClient () {
88+ override fun onPageFinished (view : WebView ? , url : String? ) {
89+ super .onPageFinished(view, url)
90+ cookieManager.flush()
91+ }
92+ }
8193
82- cookieManager.setCookie(domainUrl, " $targetCookie =; Max-Age=0 " )
94+ cookieManager.removeAllCookies( null )
8395 cookieManager.flush()
8496
8597 newWebView.loadUrl(url)
8698 }
8799
88100 var attempts = 0
89- val maxAttempts = 15
101+ val maxAttempts = 60
90102 while (attempts < maxAttempts) {
91- Thread .sleep(1000 )
103+ Thread .sleep(1000 )
92104 val checkCookies = cookieManager.getCookie(domainUrl) ? : " "
93-
94105 if (checkCookies.contains(targetCookie)) {
95106 cookieManager.flush()
96107 break
@@ -101,14 +112,15 @@ class TurnstileInterceptor(private val targetCookie: String = "_as_turnstile") :
101112 handler.post {
102113 webView?.stopLoading()
103114 webView?.destroy()
115+ webView = null
104116 }
105117 }
106118
107119 currentCookies = cookieManager.getCookie(domainUrl) ? : " "
108120 val newRequestBuilder = originalRequest.newBuilder()
109121 .header(" User-Agent" , userAgent)
110122 .header(" Cookie" , currentCookies)
111-
123+
112124 return chain.proceed(newRequestBuilder.build())
113125 }
114126
@@ -130,8 +142,8 @@ class AnimeSailProvider : MainAPI() {
130142 )
131143
132144 companion object {
133- private val mapper: ObjectMapper by lazy {
134- ObjectMapper ().configure(DeserializationFeature .FAIL_ON_UNKNOWN_PROPERTIES , false )
145+ private val mapper: ObjectMapper by lazy {
146+ ObjectMapper ().configure(DeserializationFeature .FAIL_ON_UNKNOWN_PROPERTIES , false )
135147 }
136148
137149 fun getType (t : String ): TvType {
@@ -157,7 +169,7 @@ class AnimeSailProvider : MainAPI() {
157169 interceptor = turnstileInterceptor,
158170 headers = mapOf (
159171 " Accept" to " text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8" ,
160- " User-Agent" to " Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Mobile Safari/537.36"
172+ " User-Agent" to " Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Mobile Safari/537.36" ,
161173 ),
162174 referer = ref
163175 )
@@ -194,9 +206,9 @@ class AnimeSailProvider : MainAPI() {
194206 private fun Element.toSearchResult (): AnimeSearchResponse {
195207 val rawHref = fixUrlNull(this .selectFirst(" a" )?.attr(" href" )).toString()
196208 val href = getProperAnimeLink(rawHref)
197-
209+
198210 val rawTitle = this .selectFirst(" .tt > h2" )?.text() ? : " "
199-
211+
200212 val title = rawTitle.replace(Regex (" (?i)Episode\\ s?\\ d+" ), " " )
201213 .replace(Regex (" (?i)Subtitle Indonesia" ), " " )
202214 .replace(Regex (" (?i)Sub Indo" ), " " )
@@ -205,9 +217,9 @@ class AnimeSailProvider : MainAPI() {
205217 .trim()
206218
207219 val posterUrl = fixUrlNull(this .selectFirst(" div.limit img" )?.attr(" src" ))
208-
220+
209221 val epNum = Regex (" (?i)Episode\\ s?(\\ d+)" ).find(rawTitle)?.groupValues?.getOrNull(1 )?.toIntOrNull()
210-
222+
211223 val typeText = this .selectFirst(" .tt > span" )?.text() ? : " "
212224 val type = if (typeText.contains(" Movie" , ignoreCase = true )) TvType .AnimeMovie else TvType .Anime
213225
@@ -269,13 +281,13 @@ class AnimeSailProvider : MainAPI() {
269281 val episodes = document.select(" ul.daftar > li" ).amap {
270282 val link = fixUrl(it.select(" a" ).attr(" href" ))
271283 val name = it.select(" a" ).text()
272-
284+
273285 var episodeNum = Regex (" Episode\\ s?(\\ d+)" ).find(name)?.groupValues?.getOrNull(1 )?.toIntOrNull()
274-
286+
275287 if (type == TvType .AnimeMovie && episodeNum == null ) {
276288 episodeNum = 1
277289 }
278-
290+
279291 val episodeKey = episodeNum?.toString()
280292 val metaEp = if (episodeKey != null ) animeMetaData?.episodes?.get(episodeKey) else null
281293
@@ -286,14 +298,14 @@ class AnimeSailProvider : MainAPI() {
286298 " Synopsis not yet available."
287299 }
288300
289- newEpisode(link) {
301+ newEpisode(link) {
290302 this .name = if (type == TvType .AnimeMovie ) {
291303 animeMetaData?.titles?.get(" en" ) ? : animeMetaData?.titles?.get(" ja" ) ? : title
292304 } else {
293305 metaEp?.title?.get(" en" ) ? : metaEp?.title?.get(" ja" ) ? : name
294306 }
295-
296- this .episode = episodeNum
307+
308+ this .episode = episodeNum
297309 this .score = Score .from10(metaEp?.rating)
298310 this .posterUrl = metaEp?.image ? : animeMetaData?.images?.firstOrNull()?.url ? : " "
299311 this .description = finalOverview
@@ -304,7 +316,7 @@ class AnimeSailProvider : MainAPI() {
304316
305317 val apiDescription = animeMetaData?.description?.replace(Regex (" <.*?>" ), " " )
306318 val rawPlot = apiDescription ? : animeMetaData?.episodes?.get(" 1" )?.overview
307-
319+
308320 val finalPlot = if (! rawPlot.isNullOrBlank()) {
309321 rawPlot
310322 } else {
@@ -316,7 +328,7 @@ class AnimeSailProvider : MainAPI() {
316328 this .japName = animeMetaData?.titles?.get(" ja" ) ? : animeMetaData?.titles?.get(" x-jat" )
317329 this .posterUrl = tracker?.image ? : poster
318330 this .backgroundPosterUrl = backgroundposter
319- try { this .logoUrl = logoUrl } catch (_: Throwable ){}
331+ try { this .logoUrl = logoUrl } catch (_: Throwable ) {}
320332 this .year = year
321333 this .duration = getDurationFromString(durationText)
322334 addEpisodes(DubStatus .Subbed , episodes)
@@ -325,7 +337,7 @@ class AnimeSailProvider : MainAPI() {
325337 this .tags = tagsList
326338 addMalId(malId)
327339 addAniListId(tracker?.aniId?.toIntOrNull())
328- try { addKitsuId(kitsuid) } catch (_: Throwable ){}
340+ try { addKitsuId(kitsuid) } catch (_: Throwable ) {}
329341 }
330342 }
331343
@@ -348,9 +360,9 @@ class AnimeSailProvider : MainAPI() {
348360
349361 val rawText = element.text().trim()
350362 val quality = getIndexQuality(rawText)
351-
352- val serverName = rawText.split(" " ).firstOrNull()?.replaceFirstChar {
353- if (it.isLowerCase()) it.titlecase() else it.toString()
363+
364+ val serverName = rawText.split(" " ).firstOrNull()?.replaceFirstChar {
365+ if (it.isLowerCase()) it.titlecase() else it.toString()
354366 } ? : name
355367
356368 when {
@@ -379,7 +391,7 @@ class AnimeSailProvider : MainAPI() {
379391 iframe.contains(" player-kodir.aghanim.xyz" ) || iframe.contains(" ${playerPath} kodir2" ) -> {
380392 val res = request(iframe, ref = data).text
381393 var link = Jsoup .parse(res.substringAfter(" = `" , " " ).substringBefore(" `;" , " " )).select(" source" ).last()?.attr(" src" )
382-
394+
383395 if (link.isNullOrBlank()) {
384396 link = Jsoup .parse(res).select(" source" ).attr(" src" )
385397 }
@@ -392,7 +404,7 @@ class AnimeSailProvider : MainAPI() {
392404 url = link,
393405 type = INFER_TYPE
394406 ) {
395- referer = iframe
407+ referer = iframe
396408 this .quality = quality
397409 }
398410 )
@@ -424,7 +436,7 @@ class AnimeSailProvider : MainAPI() {
424436 url = link,
425437 type = INFER_TYPE
426438 ) {
427- referer = iframe
439+ referer = iframe
428440 this .quality = quality
429441 }
430442 )
@@ -450,14 +462,14 @@ class AnimeSailProvider : MainAPI() {
450462 ) {
451463 loadExtractor(url, referer, subtitleCallback) { link ->
452464 val finalName = if (serverName.equals(link.name, ignoreCase = true )) link.name else " $serverName - ${link.name} "
453-
465+
454466 runBlocking {
455467 callback.invoke(
456468 newExtractorLink(
457469 source = link.name,
458470 name = finalName,
459471 url = link.url,
460- type = link.type
472+ type = link.type
461473 ) {
462474 this .referer = referer ? : mainUrl
463475 this .quality = if (link.type == ExtractorLinkType .M3U8 ) link.quality else quality ? : Qualities .Unknown .value
0 commit comments