1+ package app.revanced.twitch.api
2+
3+ import app.revanced.twitch.adblock.IAdblockService
4+ import app.revanced.twitch.adblock.IAdblockService.Companion.channelName
5+ import app.revanced.twitch.adblock.IAdblockService.Companion.isVod
6+ import app.revanced.twitch.adblock.PurpleAdblockService
7+ import app.revanced.twitch.adblock.TTVLolService
8+ import app.revanced.twitch.settings.SettingsEnum
9+ import app.revanced.twitch.utils.LogHelper
10+ import app.revanced.twitch.utils.ReVancedUtils
11+ import okhttp3.*
12+
13+ class RequestInterceptor : Interceptor {
14+ private var activeService: IAdblockService ? = null
15+
16+ private fun updateActiveService () {
17+ val current = SettingsEnum .BLOCK_EMBEDDED_ADS .string
18+ activeService = if (current == ReVancedUtils .getString(" key_revanced_proxy_ttv_lol" ) && activeService !is TTVLolService )
19+ TTVLolService ()
20+ else if (current == ReVancedUtils .getString(" key_revanced_proxy_purpleadblock" ) && activeService !is PurpleAdblockService )
21+ PurpleAdblockService ()
22+ else if (current == ReVancedUtils .getString(" key_revanced_proxy_disabled" ))
23+ null
24+ else
25+ activeService
26+ }
27+
28+ override fun intercept (chain : Interceptor .Chain ): Response {
29+ val originalRequest = chain.request()
30+ LogHelper .debug(" Intercepted request to URL: %s" , originalRequest.url.toString())
31+
32+ // Skip if not HLS manifest request
33+ if (! originalRequest.url.host.contains(" usher.ttvnw.net" )) {
34+ return chain.proceed(originalRequest)
35+ }
36+
37+ LogHelper .debug(" Found HLS manifest request. Is VOD? %s; Channel: %s" ,
38+ if (originalRequest.isVod()) " yes" else " no" , originalRequest.channelName())
39+
40+ // None of the services support VODs currently
41+ if (originalRequest.isVod())
42+ return chain.proceed(originalRequest)
43+
44+ updateActiveService()
45+
46+ activeService?.let {
47+ val available = it.isAvailable()
48+ val rewritten = it.rewriteHlsRequest(originalRequest)
49+
50+ if (! available || rewritten == null ) {
51+ ReVancedUtils .toast(
52+ String .format(ReVancedUtils .getString(" revanced_embedded_ads_service_unavailable" ), it.friendlyName()),
53+ true
54+ )
55+ return chain.proceed(originalRequest)
56+ }
57+
58+ LogHelper .debug(" Rewritten HLS stream URL: %s" , rewritten.url.toString())
59+
60+ val maxAttempts = it.maxAttempts()
61+ for (i in 1 .. maxAttempts) {
62+ // Execute rewritten request and close body to allow multiple proceed() calls
63+ val response = chain.proceed(rewritten).apply { close() }
64+ if (! response.isSuccessful) {
65+ LogHelper .error(" Request failed (attempt %d/%d): HTTP error %d (%s)" ,
66+ i, maxAttempts, response.code, response.message)
67+ Thread .sleep(50 )
68+ }
69+ else {
70+ // Accept response from ad blocker
71+ LogHelper .debug(" Ad-blocker used" )
72+ return chain.proceed(rewritten)
73+ }
74+ }
75+
76+ // maxAttempts exceeded; giving up on using the ad blocker
77+ ReVancedUtils .toast(
78+ String .format(ReVancedUtils .getString(" revanced_embedded_ads_service_failed" ), it.friendlyName()),
79+ true
80+ )
81+ }
82+
83+ // Adblock disabled
84+ return chain.proceed(originalRequest)
85+ }
86+ }
0 commit comments