From 0a1cd70a45fc65759ee1b962ff927e567a18eb86 Mon Sep 17 00:00:00 2001 From: Alessandro Jean Date: Mon, 31 Jan 2022 09:10:20 -0300 Subject: [PATCH] Fix 401 error in Bilibili (closes #10622). (#10631) --- src/all/bilibili/build.gradle | 2 +- .../extension/all/bilibili/BilibiliComics.kt | 31 ++++++++++++------- .../extension/all/bilibili/BilibiliDto.kt | 3 +- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/all/bilibili/build.gradle b/src/all/bilibili/build.gradle index e4aee3ce0..41589e14c 100644 --- a/src/all/bilibili/build.gradle +++ b/src/all/bilibili/build.gradle @@ -6,7 +6,7 @@ ext { extName = 'BILIBILI' pkgNameSuffix = 'all.bilibili' extClass = '.BilibiliFactory' - extVersionCode = 5 + extVersionCode = 6 } dependencies { diff --git a/src/all/bilibili/src/eu/kanade/tachiyomi/extension/all/bilibili/BilibiliComics.kt b/src/all/bilibili/src/eu/kanade/tachiyomi/extension/all/bilibili/BilibiliComics.kt index ac6136062..69f613a35 100644 --- a/src/all/bilibili/src/eu/kanade/tachiyomi/extension/all/bilibili/BilibiliComics.kt +++ b/src/all/bilibili/src/eu/kanade/tachiyomi/extension/all/bilibili/BilibiliComics.kt @@ -29,6 +29,12 @@ abstract class BilibiliComics(lang: String) : Bilibili( override val signedIn: Boolean get() = accessTokenCookie != null + private val globalApiSubDomain: String + get() = GLOBAL_API_SUBDOMAINS[(accessTokenCookie?.area?.toIntOrNull() ?: 1) - 1] + + private val globalApiBaseUrl: String + get() = "https://$globalApiSubDomain.bilibilicomics.com" + private var accessTokenCookie: BilibiliAccessTokenCookie? = null override fun chapterListParse(response: Response): List { @@ -64,7 +70,7 @@ abstract class BilibiliComics(lang: String) : Bilibili( .set("Referer", baseUrl) .build() - val apiUrl = "$GLOBAL_API_URL/$GLOBAL_BASE_API_COMIC_ENDPOINT/GetUserEpisodes".toHttpUrl() + val apiUrl = "$globalApiBaseUrl/$GLOBAL_BASE_API_COMIC_ENDPOINT/GetUserEpisodes".toHttpUrl() .newBuilder() .addCommonParameters() .toString() @@ -74,7 +80,7 @@ abstract class BilibiliComics(lang: String) : Bilibili( private fun userEpisodesParse(response: Response): List { if (!response.isSuccessful) { - throw Exception("HTTP error ${response.code}") + return emptyList() } val result = response.parseAs() @@ -103,7 +109,7 @@ abstract class BilibiliComics(lang: String) : Bilibili( .set("Referer", baseUrl + chapter.url) .build() - val apiUrl = "$GLOBAL_API_URL/$GLOBAL_BASE_API_USER_ENDPOINT/GetCredential".toHttpUrl() + val apiUrl = "$globalApiBaseUrl/$GLOBAL_BASE_API_USER_ENDPOINT/GetCredential".toHttpUrl() .newBuilder() .addCommonParameters() .toString() @@ -117,7 +123,7 @@ abstract class BilibiliComics(lang: String) : Bilibili( } if (!response.isSuccessful) { - throw Exception("HTTP error ${response.code}") + throw Exception(FAILED_TO_GET_CREDENTIAL) } val result = response.parseAs() @@ -137,7 +143,7 @@ abstract class BilibiliComics(lang: String) : Bilibili( var request = chain.request() val requestUrl = request.url.toString() - if (!requestUrl.startsWith(baseUrl) && !requestUrl.startsWith(GLOBAL_API_URL)) { + if (!requestUrl.contains("bilibilicomics.com")) { return chain.proceed(request) } @@ -170,7 +176,7 @@ abstract class BilibiliComics(lang: String) : Bilibili( ) val refreshTokenResponse = chain.proceed(refreshTokenRequest) - accessTokenCookie = refreshTokenParse(refreshTokenResponse) ?: accessTokenCookie + accessTokenCookie = refreshTokenParse(refreshTokenResponse) request = request.newBuilder() .header("Authorization", "Bearer ${accessTokenCookie!!.accessToken}") @@ -190,7 +196,7 @@ abstract class BilibiliComics(lang: String) : Bilibili( .set("Referer", baseUrl) .build() - val apiUrl = "$GLOBAL_API_URL/$GLOBAL_BASE_API_USER_ENDPOINT/RefreshToken".toHttpUrl() + val apiUrl = "$globalApiBaseUrl/$GLOBAL_BASE_API_USER_ENDPOINT/RefreshToken".toHttpUrl() .newBuilder() .addCommonParameters() .toString() @@ -198,7 +204,7 @@ abstract class BilibiliComics(lang: String) : Bilibili( return POST(apiUrl, newHeaders, requestBody) } - private fun refreshTokenParse(response: Response): BilibiliAccessTokenCookie? { + private fun refreshTokenParse(response: Response): BilibiliAccessTokenCookie { if (!response.isSuccessful) { throw IOException(FAILED_TO_REFRESH_TOKEN) } @@ -206,14 +212,15 @@ abstract class BilibiliComics(lang: String) : Bilibili( val result = response.parseAs() if (result.code != 0) { - return null + throw IOException(FAILED_TO_REFRESH_TOKEN) } val accessToken = result.data!! return BilibiliAccessTokenCookie( accessToken.accessToken, - accessToken.refreshToken + accessToken.refreshToken, + accessTokenCookie!!.area ) } @@ -229,11 +236,13 @@ abstract class BilibiliComics(lang: String) : Bilibili( companion object { private const val ACCESS_TOKEN_COOKIE_NAME = "access_token" - private const val GLOBAL_API_URL = "https://us-user.bilibilicomics.com" + private val GLOBAL_API_SUBDOMAINS = arrayOf("us-user", "sg-user") private const val GLOBAL_BASE_API_USER_ENDPOINT = "twirp/global.v1.User" private const val GLOBAL_BASE_API_COMIC_ENDPOINT = "twirp/comic.v1.User" private const val FAILED_TO_REFRESH_TOKEN = "Failed to refresh the token. Open the WebView to fix this error." + private const val FAILED_TO_GET_CREDENTIAL = + "Failed to get the credential to read the chapter." } } diff --git a/src/all/bilibili/src/eu/kanade/tachiyomi/extension/all/bilibili/BilibiliDto.kt b/src/all/bilibili/src/eu/kanade/tachiyomi/extension/all/bilibili/BilibiliDto.kt index c5e23533a..8794fb5e9 100644 --- a/src/all/bilibili/src/eu/kanade/tachiyomi/extension/all/bilibili/BilibiliDto.kt +++ b/src/all/bilibili/src/eu/kanade/tachiyomi/extension/all/bilibili/BilibiliDto.kt @@ -61,7 +61,8 @@ data class BilibiliPageDto( @Serializable data class BilibiliAccessTokenCookie( val accessToken: String, - val refreshToken: String + val refreshToken: String, + val area: String ) @Serializable