@@ -5,11 +5,16 @@ import com.lagradost.cloudstream3.utils.*
55import com.lagradost.cloudstream3.utils.AppUtils.parseJson
66import com.lagradost.cloudstream3.utils.AppUtils.toJson
77import com.lagradost.cloudstream3.network.CloudflareKiller
8+ import com.lagradost.cloudstream3.network.WebViewResolver
89import com.fasterxml.jackson.annotation.JsonProperty
910import java.net.ServerSocket
1011import java.net.Socket
1112import kotlin.concurrent.thread
1213import kotlinx.coroutines.runBlocking
14+ import kotlinx.coroutines.withContext
15+ import kotlinx.coroutines.Dispatchers
16+ import kotlin.coroutines.suspendCoroutine
17+ import kotlin.coroutines.resume
1318
1419class BinTVProvider : MainAPI () {
1520
@@ -123,6 +128,86 @@ class BinTVProvider : MainAPI() {
123128 }
124129 }
125130
131+ private suspend fun loadUrlViaWebView (url : String ): String? {
132+ val ctx = context ? : return null
133+ return withContext(Dispatchers .Main ) {
134+ suspendCoroutine { continuation ->
135+ try {
136+ val webView = android.webkit.WebView (ctx)
137+ val settings = webView.settings
138+ settings.javaScriptEnabled = true
139+ settings.domStorageEnabled = true
140+ settings.databaseEnabled = true
141+ settings.userAgentString = " Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Mobile Safari/537.36"
142+
143+ var resumed = false
144+
145+ webView.webViewClient = object : android.webkit.WebViewClient () {
146+ override fun onPageFinished (view : android.webkit.WebView ? , pageUrl : String? ) {
147+ super .onPageFinished(view, pageUrl)
148+ if (resumed) return
149+
150+ android.os.Handler (android.os.Looper .getMainLooper()).postDelayed({
151+ if (! resumed) {
152+ webView.evaluateJavascript(" (function() { return document.body ? document.body.innerText : document.documentElement.outerHTML; })()" ) { result ->
153+ if (! resumed) {
154+ resumed = true
155+ val cleanedResult = if (result != null && result.startsWith(" \" " ) && result.endsWith(" \" " )) {
156+ try {
157+ com.fasterxml.jackson.databind.ObjectMapper ().readValue(result, String ::class .java)
158+ } catch (e: Exception ) {
159+ result
160+ }
161+ } else {
162+ result
163+ }
164+
165+ try {
166+ webView.destroy()
167+ } catch (e: Exception ) {}
168+ continuation.resume(cleanedResult)
169+ }
170+ }
171+ }
172+ }, 500 )
173+ }
174+
175+ override fun onReceivedError (
176+ view : android.webkit.WebView ? ,
177+ request : android.webkit.WebResourceRequest ? ,
178+ error : android.webkit.WebResourceError ?
179+ ) {
180+ super .onReceivedError(view, request, error)
181+ if (resumed) return
182+ resumed = true
183+ try {
184+ webView.destroy()
185+ } catch (e: Exception ) {}
186+ continuation.resume(null )
187+ }
188+ }
189+
190+ webView.loadUrl(url)
191+
192+ android.os.Handler (android.os.Looper .getMainLooper()).postDelayed({
193+ if (! resumed) {
194+ resumed = true
195+ try {
196+ webView.destroy()
197+ } catch (e: Exception ) {}
198+ continuation.resume(null )
199+ }
200+ }, 8000 )
201+ } catch (e: Exception ) {
202+ println (" BinTV: loadUrlViaWebView exception: ${e.message} " )
203+ try {
204+ continuation.resume(null )
205+ } catch (ex: Exception ) {}
206+ }
207+ }
208+ }
209+ }
210+
126211 override suspend fun getMainPage (
127212 page : Int ,
128213 request : MainPageRequest
@@ -204,36 +289,19 @@ class BinTVProvider : MainAPI() {
204289
205290 // Fetch PPV matches
206291 val ppvMatches = mutableListOf<EventLoadData >()
207- val ppvUrls = listOf (
208- " https://api.ppv.cx/api/streams" ,
209- " https://old.ppv.to/api/streams" ,
210- " https://api.ppv.to/api/streams"
211- )
212292 val ppvHeaders = mapOf (
213293 " User-Agent" to " Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Mobile Safari/537.36" ,
214294 " Referer" to " https://www.bintv.net/" ,
215295 " Origin" to " https://www.bintv.net"
216296 )
217297
218- var ppvText = " "
219- for (url in ppvUrls) {
220- try {
221- val res = if (url.contains(" api.ppv.cx" )) {
222- app.get(url, headers = ppvHeaders, interceptor = cfInterceptor, timeout = 20L )
223- } else {
224- try {
225- app.get(url, headers = ppvHeaders, timeout = 15L )
226- } catch (e: Exception ) {
227- app.get(url, headers = ppvHeaders, interceptor = cfInterceptor, timeout = 20L )
228- }
229- }
230- if (res.code == 200 && res.text.isNotBlank()) {
231- ppvText = res.text
232- break
233- }
234- } catch (e: Exception ) {
235- println (" BinTV: failed to load PPV matches from $url - ${e.message} " )
236- }
298+ println (" BinTV: Fetching PPV matches via loadUrlViaWebView..." )
299+ val ppvText = loadUrlViaWebView(" https://api.ppv.to/api/streams" ) ? : " "
300+ println (" BinTV: loadUrlViaWebView response length: ${ppvText.length} " )
301+ if (ppvText.length > 500 ) {
302+ println (" BinTV: loadUrlViaWebView response snippet: ${ppvText.substring(0 , 500 )} " )
303+ } else {
304+ println (" BinTV: loadUrlViaWebView response snippet: $ppvText " )
237305 }
238306
239307 if (ppvText.isNotBlank()) {
@@ -626,6 +694,7 @@ class BinTVProvider : MainAPI() {
626694 }
627695
628696 companion object {
697+ var context: android.content.Context ? = null
629698 private val cfInterceptor = CloudflareKiller ()
630699 private var serverSocket: ServerSocket ? = null
631700 private var port: Int = 0
0 commit comments