From 6d543869d48474168b855ad29d29d901842bedc6 Mon Sep 17 00:00:00 2001 From: HuanCheng65 <22636177+HuanCheng65@users.noreply.github.com> Date: Tue, 24 Jan 2023 13:37:09 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BB=8E=20API=20=E8=8E=B7=E5=8F=96=20?= =?UTF-8?q?client=5Fid?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/huanchengfly/tieba/post/App.kt | 15 ++++-- .../huanchengfly/tieba/post/api/Extensions.kt | 9 ++++ .../tieba/post/api/ProtobufRequest.kt | 3 +- .../com/huanchengfly/tieba/post/api/Utils.kt | 5 +- .../tieba/post/api/interfaces/ITiebaApi.kt | 2 + .../api/interfaces/impls/MixedTiebaApiImpl.kt | 4 ++ .../tieba/post/api/models/Sync.kt | 19 +++++++ .../post/api/retrofit/RetrofitTiebaApi.kt | 49 ++++++++++-------- .../interceptors/CommonParamInterceptor.kt | 18 ++++++- .../retrofit/interfaces/OfficialTiebaApi.kt | 28 ++++++++++ .../tieba/post/utils/ClientUtils.kt | 51 +++++++++++++++++++ 11 files changed, 171 insertions(+), 32 deletions(-) create mode 100644 app/src/main/java/com/huanchengfly/tieba/post/api/models/Sync.kt create mode 100644 app/src/main/java/com/huanchengfly/tieba/post/utils/ClientUtils.kt diff --git a/app/src/main/java/com/huanchengfly/tieba/post/App.kt b/app/src/main/java/com/huanchengfly/tieba/post/App.kt index 8367f742..8edb58fb 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/App.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/App.kt @@ -18,7 +18,6 @@ import androidx.annotation.RequiresApi import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatDelegate import com.github.gzuliyujiang.oaid.DeviceID -import com.github.gzuliyujiang.oaid.DeviceIdentifier import com.github.gzuliyujiang.oaid.IGetter import com.github.panpf.sketch.Sketch import com.github.panpf.sketch.SketchFactory @@ -36,6 +35,7 @@ import com.huanchengfly.tieba.post.ui.common.theme.interfaces.ThemeSwitcher import com.huanchengfly.tieba.post.ui.common.theme.utils.ThemeUtils import com.huanchengfly.tieba.post.utils.AccountUtil import com.huanchengfly.tieba.post.utils.AppIconUtil +import com.huanchengfly.tieba.post.utils.ClientUtils import com.huanchengfly.tieba.post.utils.EmoticonManager import com.huanchengfly.tieba.post.utils.SharedPreferencesUtil import com.huanchengfly.tieba.post.utils.ThemeUtil @@ -54,6 +54,9 @@ import com.microsoft.appcenter.distribute.ReleaseDetails import com.microsoft.appcenter.distribute.UpdateAction import com.microsoft.appcenter.distribute.UpdateTrack import dagger.hilt.android.HiltAndroidApp +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import org.litepal.LitePal @@ -96,7 +99,6 @@ class App : Application(), IApp, IGetter, SketchFactory { super.onCreate() LitePal.initialize(this) AccountUtil.init(this) - DeviceIdentifier.register(this) DeviceID.getOAID(this, this) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { setWebViewPath(this) @@ -114,8 +116,15 @@ class App : Application(), IApp, IGetter, SketchFactory { ThemeUtils.init(ThemeDelegate) AppIconUtil.setIcon() registerActivityLifecycleCallbacks(ClipBoardLinkDetector) - EmoticonManager.init(this) PluginManager.init(this) + CoroutineScope(Dispatchers.IO).apply { + launch { + EmoticonManager.init(this@App) + } + launch { + ClientUtils.init(this@App) + } + } } //解决魅族 Flyme 系统夜间模式强制反色 diff --git a/app/src/main/java/com/huanchengfly/tieba/post/api/Extensions.kt b/app/src/main/java/com/huanchengfly/tieba/post/api/Extensions.kt index 0a8e2f4f..19556abf 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/api/Extensions.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/api/Extensions.kt @@ -142,4 +142,13 @@ internal inline fun Array.forEachNonNull(action: (String, S action(name, value) } } +} + +internal inline fun List.forEachNonNull(action: (String, String) -> Unit) { + forEach { (name, valueExpression) -> + val value = valueExpression() + if (value != null) { + action(name, value) + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/huanchengfly/tieba/post/api/ProtobufRequest.kt b/app/src/main/java/com/huanchengfly/tieba/post/api/ProtobufRequest.kt index 75f429cf..0af0ff7e 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/api/ProtobufRequest.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/api/ProtobufRequest.kt @@ -11,6 +11,7 @@ import com.huanchengfly.tieba.post.api.retrofit.RetrofitTiebaApi import com.huanchengfly.tieba.post.api.retrofit.body.MyMultipartBody import com.huanchengfly.tieba.post.toJson import com.huanchengfly.tieba.post.utils.AccountUtil +import com.huanchengfly.tieba.post.utils.ClientUtils import com.huanchengfly.tieba.post.utils.CuidUtils import com.huanchengfly.tieba.post.utils.MobileInfoUtil import com.huanchengfly.tieba.post.utils.UIDUtil @@ -70,7 +71,7 @@ fun buildCommonRequest( ): CommonRequest { return CommonRequest( BDUSS = AccountUtil.getBduss(), - _client_id = RetrofitTiebaApi.clientId, + _client_id = ClientUtils.clientId ?: RetrofitTiebaApi.randomClientId, _client_type = 2, _client_version = clientVersion, _os_version = "${Build.VERSION.SDK_INT}", diff --git a/app/src/main/java/com/huanchengfly/tieba/post/api/Utils.kt b/app/src/main/java/com/huanchengfly/tieba/post/api/Utils.kt index 9ae9fe92..3b1e1432 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/api/Utils.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/api/Utils.kt @@ -1,12 +1,9 @@ package com.huanchengfly.tieba.post.api -import com.huanchengfly.tieba.post.App import com.huanchengfly.tieba.post.App.ScreenInfo import com.huanchengfly.tieba.post.api.models.protos.ThreadInfo -import com.huanchengfly.tieba.post.utils.StatusBarUtil -fun getScreenHeight(): Int = - ScreenInfo.EXACT_SCREEN_HEIGHT - StatusBarUtil.getStatusBarHeight(App.INSTANCE) +fun getScreenHeight(): Int = ScreenInfo.EXACT_SCREEN_HEIGHT fun getScreenWidth(): Int = ScreenInfo.EXACT_SCREEN_WIDTH diff --git a/app/src/main/java/com/huanchengfly/tieba/post/api/interfaces/ITiebaApi.kt b/app/src/main/java/com/huanchengfly/tieba/post/api/interfaces/ITiebaApi.kt index 1133b27a..731e8381 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/api/interfaces/ITiebaApi.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/api/interfaces/ITiebaApi.kt @@ -1189,4 +1189,6 @@ interface ITiebaApi { sortType: Int, threadIds: String = "", ): Flow + + fun syncFlow(clientId: String? = null): Flow } \ No newline at end of file diff --git a/app/src/main/java/com/huanchengfly/tieba/post/api/interfaces/impls/MixedTiebaApiImpl.kt b/app/src/main/java/com/huanchengfly/tieba/post/api/interfaces/impls/MixedTiebaApiImpl.kt index 8bbd65f4..cd939463 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/api/interfaces/impls/MixedTiebaApiImpl.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/api/interfaces/impls/MixedTiebaApiImpl.kt @@ -39,6 +39,7 @@ import com.huanchengfly.tieba.post.api.models.SearchThreadBean import com.huanchengfly.tieba.post.api.models.SearchUserBean import com.huanchengfly.tieba.post.api.models.SignResultBean import com.huanchengfly.tieba.post.api.models.SubFloorListBean +import com.huanchengfly.tieba.post.api.models.Sync import com.huanchengfly.tieba.post.api.models.ThreadContentBean import com.huanchengfly.tieba.post.api.models.ThreadStoreBean import com.huanchengfly.tieba.post.api.models.UserLikeForumBean @@ -939,4 +940,7 @@ object MixedTiebaApiImpl : ITiebaApi { ) ) } + + override fun syncFlow(clientId: String?): Flow = + RetrofitTiebaApi.OFFICIAL_TIEBA_API.sync(clientId) } \ No newline at end of file diff --git a/app/src/main/java/com/huanchengfly/tieba/post/api/models/Sync.kt b/app/src/main/java/com/huanchengfly/tieba/post/api/models/Sync.kt new file mode 100644 index 00000000..f6a59d2a --- /dev/null +++ b/app/src/main/java/com/huanchengfly/tieba/post/api/models/Sync.kt @@ -0,0 +1,19 @@ +package com.huanchengfly.tieba.post.api.models + +import com.google.gson.annotations.SerializedName + +data class Sync( + val client: Client, + @SerializedName("wl_config") + val wlConfig: WlConfig +) { + data class Client( + @SerializedName("client_id") + val clientId: String + ) + + data class WlConfig( + @SerializedName("sample_id") + val sampleId: String + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/huanchengfly/tieba/post/api/retrofit/RetrofitTiebaApi.kt b/app/src/main/java/com/huanchengfly/tieba/post/api/retrofit/RetrofitTiebaApi.kt index 89c435e3..5388e662 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/api/retrofit/RetrofitTiebaApi.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/api/retrofit/RetrofitTiebaApi.kt @@ -24,6 +24,7 @@ import com.huanchengfly.tieba.post.api.retrofit.interfaces.OfficialTiebaApi import com.huanchengfly.tieba.post.api.retrofit.interfaces.WebTiebaApi import com.huanchengfly.tieba.post.toJson import com.huanchengfly.tieba.post.utils.AccountUtil +import com.huanchengfly.tieba.post.utils.ClientUtils import com.huanchengfly.tieba.post.utils.CuidUtils import com.huanchengfly.tieba.post.utils.MobileInfoUtil import com.huanchengfly.tieba.post.utils.UIDUtil @@ -42,13 +43,13 @@ object RetrofitTiebaApi { private const val WRITE_TIMEOUT = 60L private val initTime = System.currentTimeMillis() - internal val clientId = "wappc_${initTime}_${(Math.random() * 1000).roundToInt()}" + internal val randomClientId = "wappc_${initTime}_${(Math.random() * 1000).roundToInt()}" private val stParamInterceptor = StParamInterceptor() private val connectionPool = ConnectionPool(32, 5, TimeUnit.MINUTES) private val defaultCommonParamInterceptor = CommonParamInterceptor( Param.BDUSS to { AccountUtil.getBduss() }, - Param.CLIENT_ID to { clientId }, + Param.CLIENT_ID to { ClientUtils.clientId }, Param.CLIENT_TYPE to { "2" }, Param.OS_VERSION to { Build.VERSION.SDK_INT.toString() }, Param.MODEL to { Build.MODEL }, @@ -66,19 +67,20 @@ object RetrofitTiebaApi { private val sortAndSignInterceptor = SortAndSignInterceptor("tiebaclient!!!") val NEW_TIEBA_API: NewTiebaApi by lazy { - createJsonApi("http://c.tieba.baidu.com/", + createJsonApi( + "http://c.tieba.baidu.com/", defaultCommonHeaderInterceptor, CommonHeaderInterceptor( Header.USER_AGENT to { "bdtb for Android 8.2.2" }, Header.CUID to { UIDUtil.getFinalCUID() } ), - defaultCommonParamInterceptor, - stParamInterceptor, - CommonParamInterceptor( + defaultCommonParamInterceptor + CommonParamInterceptor( Param.CUID to { UIDUtil.getFinalCUID() }, Param.FROM to { "baidu_appstore" }, Param.CLIENT_VERSION to { "8.2.2" } - )) + ), + stParamInterceptor, + ) } val WEB_TIEBA_API: WebTiebaApi by lazy { @@ -92,26 +94,28 @@ object RetrofitTiebaApi { } val MINI_TIEBA_API: MiniTiebaApi by lazy { - createJsonApi("http://c.tieba.baidu.com/", + createJsonApi( + "http://c.tieba.baidu.com/", defaultCommonHeaderInterceptor, CommonHeaderInterceptor( Header.USER_AGENT to { "bdtb for Android 7.2.0.0" }, Header.CUID to { UIDUtil.getFinalCUID() }, Header.CUID_GALAXY2 to { UIDUtil.getFinalCUID() } ), - defaultCommonParamInterceptor, - stParamInterceptor, - CommonParamInterceptor( + defaultCommonParamInterceptor + CommonParamInterceptor( Param.CUID to { UIDUtil.getFinalCUID() }, Param.CUID_GALAXY2 to { UIDUtil.getFinalCUID() }, Param.FROM to { "1021636m" }, Param.CLIENT_VERSION to { "7.2.0.0" }, Param.SUBAPP_TYPE to { "mini" } - )) + ), + stParamInterceptor, + ) } val OFFICIAL_TIEBA_API: OfficialTiebaApi by lazy { - createJsonApi("http://c.tieba.baidu.com/", + createJsonApi( + "http://c.tieba.baidu.com/", CommonHeaderInterceptor( Header.USER_AGENT to { "bdtb for Android 12.25.1.0" }, Header.CUID to { CuidUtils.getNewCuid() }, @@ -121,9 +125,7 @@ object RetrofitTiebaApi { Header.CLIENT_TYPE to { "2" }, Header.CHARSET to { "UTF-8" }, ), - defaultCommonParamInterceptor, - stParamInterceptor, - CommonParamInterceptor( + defaultCommonParamInterceptor + CommonParamInterceptor( Param.CUID to { CuidUtils.getNewCuid() }, Param.CUID_GALAXY2 to { CuidUtils.getNewCuid() }, Param.CUID_GID to { "" }, @@ -131,11 +133,14 @@ object RetrofitTiebaApi { Param.CLIENT_VERSION to { "12.25.1.0" }, Param.CUID_GALAXY3 to { UIDUtil.getAid() }, Param.OAID to { OAID(App.oaid).toJson() }, - )) + ), + stParamInterceptor, + ) } val OFFICIAL_PROTOBUF_TIEBA_API: OfficialProtobufTiebaApi by lazy { - createProtobufApi("http://c.tieba.baidu.com/", + createProtobufApi( + "http://c.tieba.baidu.com/", CommonHeaderInterceptor( Header.CHARSET to { "UTF-8" }, Header.CLIENT_TYPE to { "2" }, @@ -148,9 +153,7 @@ object RetrofitTiebaApi { Header.USER_AGENT to { "bdtb for Android 11.10.8.6" }, Header.X_BD_DATA_TYPE to { "protobuf" }, ), - defaultCommonParamInterceptor, - stParamInterceptor, - CommonParamInterceptor( + defaultCommonParamInterceptor + CommonParamInterceptor( Param.CUID to { CuidUtils.getNewCuid() }, Param.CUID_GALAXY2 to { CuidUtils.getNewCuid() }, Param.CUID_GID to { "" }, @@ -158,7 +161,9 @@ object RetrofitTiebaApi { Param.CLIENT_VERSION to { "11.10.8.6" }, Param.CUID_GALAXY3 to { UIDUtil.getAid() }, Param.OAID to { OAID(App.oaid).toJson() }, - )) + ), + stParamInterceptor, + ) } private inline fun createJsonApi( diff --git a/app/src/main/java/com/huanchengfly/tieba/post/api/retrofit/interceptors/CommonParamInterceptor.kt b/app/src/main/java/com/huanchengfly/tieba/post/api/retrofit/interceptors/CommonParamInterceptor.kt index 55648c26..f5bb4da1 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/api/retrofit/interceptors/CommonParamInterceptor.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/api/retrofit/interceptors/CommonParamInterceptor.kt @@ -1,12 +1,26 @@ package com.huanchengfly.tieba.post.api.retrofit.interceptors -import com.huanchengfly.tieba.post.api.* +import com.huanchengfly.tieba.post.api.Header +import com.huanchengfly.tieba.post.api.Method +import com.huanchengfly.tieba.post.api.ParamExpression +import com.huanchengfly.tieba.post.api.addAllEncoded +import com.huanchengfly.tieba.post.api.addAllParts +import com.huanchengfly.tieba.post.api.contains +import com.huanchengfly.tieba.post.api.containsEncodedName +import com.huanchengfly.tieba.post.api.forEachNonNull +import com.huanchengfly.tieba.post.api.newBuilder import com.huanchengfly.tieba.post.api.retrofit.body.MyMultipartBody import okhttp3.FormBody import okhttp3.Interceptor import okhttp3.Response -class CommonParamInterceptor(private vararg val additionParams: ParamExpression) : Interceptor { +class CommonParamInterceptor(private val additionParams: List) : Interceptor { + constructor(vararg additionParams: ParamExpression) : this(additionParams.toList()) + + operator fun plus(interceptor: CommonParamInterceptor): CommonParamInterceptor { + return CommonParamInterceptor(additionParams + interceptor.additionParams) + } + override fun intercept(chain: Interceptor.Chain): Response { val request = chain.request() var headers = request.headers diff --git a/app/src/main/java/com/huanchengfly/tieba/post/api/retrofit/interfaces/OfficialTiebaApi.kt b/app/src/main/java/com/huanchengfly/tieba/post/api/retrofit/interfaces/OfficialTiebaApi.kt index 143334cb..d1f5ef5b 100644 --- a/app/src/main/java/com/huanchengfly/tieba/post/api/retrofit/interfaces/OfficialTiebaApi.kt +++ b/app/src/main/java/com/huanchengfly/tieba/post/api/retrofit/interfaces/OfficialTiebaApi.kt @@ -1,5 +1,6 @@ package com.huanchengfly.tieba.post.api.retrofit.interfaces +import android.os.Build import com.huanchengfly.tieba.post.App.ScreenInfo import com.huanchengfly.tieba.post.api.Header import com.huanchengfly.tieba.post.api.Param @@ -348,4 +349,31 @@ interface OfficialTiebaApi { @retrofit2.http.Header(Header.USER_AGENT) user_agent: String = "bdtb for Android $client_version", @retrofit2.http.Header("client_user_token") client_user_token: String? = user_id, ): Flow + + @Headers( + "${Header.COOKIE}: ka=open", + "${Header.DROP_HEADERS}: ${Header.CHARSET},${Header.CLIENT_TYPE}", + "${Header.NO_COMMON_PARAMS}: ${Param.OAID},${Param.CLIENT_TYPE}", + ) + @POST("/c/s/sync") + @FormUrlEncoded + fun sync( + @Field(Param.CLIENT_ID) clientId: String? = null, + @Field("_msg_status") msgStatus: String = "1", + @Field("_phone_screen") phoneScreen: String = "${getScreenWidth()},${getScreenHeight()}", + @Field("_pic_quality") picQuality: String = "0", + @Field("board") board: String = Build.BOARD, + @Field("brand") brand: String = Build.BRAND, + @Field("incremental") incremental: String = Build.VERSION.INCREMENTAL, + @Field("md5") md5: String = "E0F995CA7286059FC61F649796A0D757", + @Field("signmd5") signmd5: String = "225172691", + @Field("package") packageName: String = "com.baidu.tieba", + @Field("versioncode") versionCode: String = "185204737", + @Field("scr_dip") scr_dip: String = ScreenInfo.DENSITY.toString(), + @Field("scr_h") scr_h: String = getScreenHeight().toString(), + @Field("scr_w") scr_w: String = getScreenWidth().toString(), + @Field("_client_version") client_version: String = "11.10.8.6", + @retrofit2.http.Header(Header.USER_AGENT) user_agent: String = "bdtb for Android $client_version", + @Field("stoken") sToken: String? = AccountUtil.getSToken(), + ): Flow } \ No newline at end of file diff --git a/app/src/main/java/com/huanchengfly/tieba/post/utils/ClientUtils.kt b/app/src/main/java/com/huanchengfly/tieba/post/utils/ClientUtils.kt new file mode 100644 index 00000000..df5ea9f9 --- /dev/null +++ b/app/src/main/java/com/huanchengfly/tieba/post/utils/ClientUtils.kt @@ -0,0 +1,51 @@ +package com.huanchengfly.tieba.post.utils + +import android.content.Context +import androidx.datastore.preferences.core.edit +import androidx.datastore.preferences.core.stringPreferencesKey +import com.huanchengfly.tieba.post.api.TiebaApi +import com.huanchengfly.tieba.post.dataStore +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.firstOrNull +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +object ClientUtils { + const val CLIENT_ID = "client_id" + const val SAMPLE_ID = "sample_id" + + private val clientIdKey = stringPreferencesKey(CLIENT_ID) + private val sampleIdKey = stringPreferencesKey(SAMPLE_ID) + + var clientId: String? = null + var sampleId: String? = null + + fun init(context: Context) { + CoroutineScope(Dispatchers.IO).launch { + clientId = withContext(Dispatchers.IO) { + context.dataStore.data.map { it[clientIdKey] }.firstOrNull() + } + sampleId = withContext(Dispatchers.IO) { + context.dataStore.data.map { it[sampleIdKey] }.firstOrNull() + } + sync(context) + } + } + + private suspend fun save(context: Context, clientId: String, sampleId: String) { + context.dataStore.edit { + it[clientIdKey] = clientId + it[sampleIdKey] = sampleId + } + } + + private suspend fun sync(context: Context) { + TiebaApi.getInstance().syncFlow(clientId).collect { + clientId = it.client.clientId + sampleId = it.wlConfig.sampleId + save(context, it.client.clientId, it.wlConfig.sampleId) + } + } +} \ No newline at end of file