feat: 从 API 获取 client_id

This commit is contained in:
HuanCheng65 2023-01-24 13:37:09 +08:00
parent ffb20dc817
commit 6d543869d4
No known key found for this signature in database
GPG Key ID: E9031EF91A805148
11 changed files with 171 additions and 32 deletions

View File

@ -18,7 +18,6 @@ import androidx.annotation.RequiresApi
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.app.AppCompatDelegate
import com.github.gzuliyujiang.oaid.DeviceID import com.github.gzuliyujiang.oaid.DeviceID
import com.github.gzuliyujiang.oaid.DeviceIdentifier
import com.github.gzuliyujiang.oaid.IGetter import com.github.gzuliyujiang.oaid.IGetter
import com.github.panpf.sketch.Sketch import com.github.panpf.sketch.Sketch
import com.github.panpf.sketch.SketchFactory 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.ui.common.theme.utils.ThemeUtils
import com.huanchengfly.tieba.post.utils.AccountUtil import com.huanchengfly.tieba.post.utils.AccountUtil
import com.huanchengfly.tieba.post.utils.AppIconUtil 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.EmoticonManager
import com.huanchengfly.tieba.post.utils.SharedPreferencesUtil import com.huanchengfly.tieba.post.utils.SharedPreferencesUtil
import com.huanchengfly.tieba.post.utils.ThemeUtil 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.UpdateAction
import com.microsoft.appcenter.distribute.UpdateTrack import com.microsoft.appcenter.distribute.UpdateTrack
import dagger.hilt.android.HiltAndroidApp import dagger.hilt.android.HiltAndroidApp
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.litepal.LitePal import org.litepal.LitePal
@ -96,7 +99,6 @@ class App : Application(), IApp, IGetter, SketchFactory {
super.onCreate() super.onCreate()
LitePal.initialize(this) LitePal.initialize(this)
AccountUtil.init(this) AccountUtil.init(this)
DeviceIdentifier.register(this)
DeviceID.getOAID(this, this) DeviceID.getOAID(this, this)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
setWebViewPath(this) setWebViewPath(this)
@ -114,8 +116,15 @@ class App : Application(), IApp, IGetter, SketchFactory {
ThemeUtils.init(ThemeDelegate) ThemeUtils.init(ThemeDelegate)
AppIconUtil.setIcon() AppIconUtil.setIcon()
registerActivityLifecycleCallbacks(ClipBoardLinkDetector) registerActivityLifecycleCallbacks(ClipBoardLinkDetector)
EmoticonManager.init(this)
PluginManager.init(this) PluginManager.init(this)
CoroutineScope(Dispatchers.IO).apply {
launch {
EmoticonManager.init(this@App)
}
launch {
ClientUtils.init(this@App)
}
}
} }
//解决魅族 Flyme 系统夜间模式强制反色 //解决魅族 Flyme 系统夜间模式强制反色

View File

@ -143,3 +143,12 @@ internal inline fun Array<out ParamExpression>.forEachNonNull(action: (String, S
} }
} }
} }
internal inline fun List<ParamExpression>.forEachNonNull(action: (String, String) -> Unit) {
forEach { (name, valueExpression) ->
val value = valueExpression()
if (value != null) {
action(name, value)
}
}
}

View File

@ -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.api.retrofit.body.MyMultipartBody
import com.huanchengfly.tieba.post.toJson import com.huanchengfly.tieba.post.toJson
import com.huanchengfly.tieba.post.utils.AccountUtil 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.CuidUtils
import com.huanchengfly.tieba.post.utils.MobileInfoUtil import com.huanchengfly.tieba.post.utils.MobileInfoUtil
import com.huanchengfly.tieba.post.utils.UIDUtil import com.huanchengfly.tieba.post.utils.UIDUtil
@ -70,7 +71,7 @@ fun buildCommonRequest(
): CommonRequest { ): CommonRequest {
return CommonRequest( return CommonRequest(
BDUSS = AccountUtil.getBduss(), BDUSS = AccountUtil.getBduss(),
_client_id = RetrofitTiebaApi.clientId, _client_id = ClientUtils.clientId ?: RetrofitTiebaApi.randomClientId,
_client_type = 2, _client_type = 2,
_client_version = clientVersion, _client_version = clientVersion,
_os_version = "${Build.VERSION.SDK_INT}", _os_version = "${Build.VERSION.SDK_INT}",

View File

@ -1,12 +1,9 @@
package com.huanchengfly.tieba.post.api package com.huanchengfly.tieba.post.api
import com.huanchengfly.tieba.post.App
import com.huanchengfly.tieba.post.App.ScreenInfo import com.huanchengfly.tieba.post.App.ScreenInfo
import com.huanchengfly.tieba.post.api.models.protos.ThreadInfo import com.huanchengfly.tieba.post.api.models.protos.ThreadInfo
import com.huanchengfly.tieba.post.utils.StatusBarUtil
fun getScreenHeight(): Int = fun getScreenHeight(): Int = ScreenInfo.EXACT_SCREEN_HEIGHT
ScreenInfo.EXACT_SCREEN_HEIGHT - StatusBarUtil.getStatusBarHeight(App.INSTANCE)
fun getScreenWidth(): Int = ScreenInfo.EXACT_SCREEN_WIDTH fun getScreenWidth(): Int = ScreenInfo.EXACT_SCREEN_WIDTH

View File

@ -1189,4 +1189,6 @@ interface ITiebaApi {
sortType: Int, sortType: Int,
threadIds: String = "", threadIds: String = "",
): Flow<ThreadListResponse> ): Flow<ThreadListResponse>
fun syncFlow(clientId: String? = null): Flow<Sync>
} }

View File

@ -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.SearchUserBean
import com.huanchengfly.tieba.post.api.models.SignResultBean import com.huanchengfly.tieba.post.api.models.SignResultBean
import com.huanchengfly.tieba.post.api.models.SubFloorListBean 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.ThreadContentBean
import com.huanchengfly.tieba.post.api.models.ThreadStoreBean import com.huanchengfly.tieba.post.api.models.ThreadStoreBean
import com.huanchengfly.tieba.post.api.models.UserLikeForumBean import com.huanchengfly.tieba.post.api.models.UserLikeForumBean
@ -939,4 +940,7 @@ object MixedTiebaApiImpl : ITiebaApi {
) )
) )
} }
override fun syncFlow(clientId: String?): Flow<Sync> =
RetrofitTiebaApi.OFFICIAL_TIEBA_API.sync(clientId)
} }

View File

@ -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
)
}

View File

@ -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.api.retrofit.interfaces.WebTiebaApi
import com.huanchengfly.tieba.post.toJson import com.huanchengfly.tieba.post.toJson
import com.huanchengfly.tieba.post.utils.AccountUtil 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.CuidUtils
import com.huanchengfly.tieba.post.utils.MobileInfoUtil import com.huanchengfly.tieba.post.utils.MobileInfoUtil
import com.huanchengfly.tieba.post.utils.UIDUtil import com.huanchengfly.tieba.post.utils.UIDUtil
@ -42,13 +43,13 @@ object RetrofitTiebaApi {
private const val WRITE_TIMEOUT = 60L private const val WRITE_TIMEOUT = 60L
private val initTime = System.currentTimeMillis() 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 stParamInterceptor = StParamInterceptor()
private val connectionPool = ConnectionPool(32, 5, TimeUnit.MINUTES) private val connectionPool = ConnectionPool(32, 5, TimeUnit.MINUTES)
private val defaultCommonParamInterceptor = CommonParamInterceptor( private val defaultCommonParamInterceptor = CommonParamInterceptor(
Param.BDUSS to { AccountUtil.getBduss() }, Param.BDUSS to { AccountUtil.getBduss() },
Param.CLIENT_ID to { clientId }, Param.CLIENT_ID to { ClientUtils.clientId },
Param.CLIENT_TYPE to { "2" }, Param.CLIENT_TYPE to { "2" },
Param.OS_VERSION to { Build.VERSION.SDK_INT.toString() }, Param.OS_VERSION to { Build.VERSION.SDK_INT.toString() },
Param.MODEL to { Build.MODEL }, Param.MODEL to { Build.MODEL },
@ -66,19 +67,20 @@ object RetrofitTiebaApi {
private val sortAndSignInterceptor = SortAndSignInterceptor("tiebaclient!!!") private val sortAndSignInterceptor = SortAndSignInterceptor("tiebaclient!!!")
val NEW_TIEBA_API: NewTiebaApi by lazy { val NEW_TIEBA_API: NewTiebaApi by lazy {
createJsonApi<NewTiebaApi>("http://c.tieba.baidu.com/", createJsonApi<NewTiebaApi>(
"http://c.tieba.baidu.com/",
defaultCommonHeaderInterceptor, defaultCommonHeaderInterceptor,
CommonHeaderInterceptor( CommonHeaderInterceptor(
Header.USER_AGENT to { "bdtb for Android 8.2.2" }, Header.USER_AGENT to { "bdtb for Android 8.2.2" },
Header.CUID to { UIDUtil.getFinalCUID() } Header.CUID to { UIDUtil.getFinalCUID() }
), ),
defaultCommonParamInterceptor, defaultCommonParamInterceptor + CommonParamInterceptor(
stParamInterceptor,
CommonParamInterceptor(
Param.CUID to { UIDUtil.getFinalCUID() }, Param.CUID to { UIDUtil.getFinalCUID() },
Param.FROM to { "baidu_appstore" }, Param.FROM to { "baidu_appstore" },
Param.CLIENT_VERSION to { "8.2.2" } Param.CLIENT_VERSION to { "8.2.2" }
)) ),
stParamInterceptor,
)
} }
val WEB_TIEBA_API: WebTiebaApi by lazy { val WEB_TIEBA_API: WebTiebaApi by lazy {
@ -92,26 +94,28 @@ object RetrofitTiebaApi {
} }
val MINI_TIEBA_API: MiniTiebaApi by lazy { val MINI_TIEBA_API: MiniTiebaApi by lazy {
createJsonApi<MiniTiebaApi>("http://c.tieba.baidu.com/", createJsonApi<MiniTiebaApi>(
"http://c.tieba.baidu.com/",
defaultCommonHeaderInterceptor, defaultCommonHeaderInterceptor,
CommonHeaderInterceptor( CommonHeaderInterceptor(
Header.USER_AGENT to { "bdtb for Android 7.2.0.0" }, Header.USER_AGENT to { "bdtb for Android 7.2.0.0" },
Header.CUID to { UIDUtil.getFinalCUID() }, Header.CUID to { UIDUtil.getFinalCUID() },
Header.CUID_GALAXY2 to { UIDUtil.getFinalCUID() } Header.CUID_GALAXY2 to { UIDUtil.getFinalCUID() }
), ),
defaultCommonParamInterceptor, defaultCommonParamInterceptor + CommonParamInterceptor(
stParamInterceptor,
CommonParamInterceptor(
Param.CUID to { UIDUtil.getFinalCUID() }, Param.CUID to { UIDUtil.getFinalCUID() },
Param.CUID_GALAXY2 to { UIDUtil.getFinalCUID() }, Param.CUID_GALAXY2 to { UIDUtil.getFinalCUID() },
Param.FROM to { "1021636m" }, Param.FROM to { "1021636m" },
Param.CLIENT_VERSION to { "7.2.0.0" }, Param.CLIENT_VERSION to { "7.2.0.0" },
Param.SUBAPP_TYPE to { "mini" } Param.SUBAPP_TYPE to { "mini" }
)) ),
stParamInterceptor,
)
} }
val OFFICIAL_TIEBA_API: OfficialTiebaApi by lazy { val OFFICIAL_TIEBA_API: OfficialTiebaApi by lazy {
createJsonApi<OfficialTiebaApi>("http://c.tieba.baidu.com/", createJsonApi<OfficialTiebaApi>(
"http://c.tieba.baidu.com/",
CommonHeaderInterceptor( CommonHeaderInterceptor(
Header.USER_AGENT to { "bdtb for Android 12.25.1.0" }, Header.USER_AGENT to { "bdtb for Android 12.25.1.0" },
Header.CUID to { CuidUtils.getNewCuid() }, Header.CUID to { CuidUtils.getNewCuid() },
@ -121,9 +125,7 @@ object RetrofitTiebaApi {
Header.CLIENT_TYPE to { "2" }, Header.CLIENT_TYPE to { "2" },
Header.CHARSET to { "UTF-8" }, Header.CHARSET to { "UTF-8" },
), ),
defaultCommonParamInterceptor, defaultCommonParamInterceptor + CommonParamInterceptor(
stParamInterceptor,
CommonParamInterceptor(
Param.CUID to { CuidUtils.getNewCuid() }, Param.CUID to { CuidUtils.getNewCuid() },
Param.CUID_GALAXY2 to { CuidUtils.getNewCuid() }, Param.CUID_GALAXY2 to { CuidUtils.getNewCuid() },
Param.CUID_GID to { "" }, Param.CUID_GID to { "" },
@ -131,11 +133,14 @@ object RetrofitTiebaApi {
Param.CLIENT_VERSION to { "12.25.1.0" }, Param.CLIENT_VERSION to { "12.25.1.0" },
Param.CUID_GALAXY3 to { UIDUtil.getAid() }, Param.CUID_GALAXY3 to { UIDUtil.getAid() },
Param.OAID to { OAID(App.oaid).toJson() }, Param.OAID to { OAID(App.oaid).toJson() },
)) ),
stParamInterceptor,
)
} }
val OFFICIAL_PROTOBUF_TIEBA_API: OfficialProtobufTiebaApi by lazy { val OFFICIAL_PROTOBUF_TIEBA_API: OfficialProtobufTiebaApi by lazy {
createProtobufApi<OfficialProtobufTiebaApi>("http://c.tieba.baidu.com/", createProtobufApi<OfficialProtobufTiebaApi>(
"http://c.tieba.baidu.com/",
CommonHeaderInterceptor( CommonHeaderInterceptor(
Header.CHARSET to { "UTF-8" }, Header.CHARSET to { "UTF-8" },
Header.CLIENT_TYPE to { "2" }, Header.CLIENT_TYPE to { "2" },
@ -148,9 +153,7 @@ object RetrofitTiebaApi {
Header.USER_AGENT to { "bdtb for Android 11.10.8.6" }, Header.USER_AGENT to { "bdtb for Android 11.10.8.6" },
Header.X_BD_DATA_TYPE to { "protobuf" }, Header.X_BD_DATA_TYPE to { "protobuf" },
), ),
defaultCommonParamInterceptor, defaultCommonParamInterceptor + CommonParamInterceptor(
stParamInterceptor,
CommonParamInterceptor(
Param.CUID to { CuidUtils.getNewCuid() }, Param.CUID to { CuidUtils.getNewCuid() },
Param.CUID_GALAXY2 to { CuidUtils.getNewCuid() }, Param.CUID_GALAXY2 to { CuidUtils.getNewCuid() },
Param.CUID_GID to { "" }, Param.CUID_GID to { "" },
@ -158,7 +161,9 @@ object RetrofitTiebaApi {
Param.CLIENT_VERSION to { "11.10.8.6" }, Param.CLIENT_VERSION to { "11.10.8.6" },
Param.CUID_GALAXY3 to { UIDUtil.getAid() }, Param.CUID_GALAXY3 to { UIDUtil.getAid() },
Param.OAID to { OAID(App.oaid).toJson() }, Param.OAID to { OAID(App.oaid).toJson() },
)) ),
stParamInterceptor,
)
} }
private inline fun <reified T : Any> createJsonApi( private inline fun <reified T : Any> createJsonApi(

View File

@ -1,12 +1,26 @@
package com.huanchengfly.tieba.post.api.retrofit.interceptors 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 com.huanchengfly.tieba.post.api.retrofit.body.MyMultipartBody
import okhttp3.FormBody import okhttp3.FormBody
import okhttp3.Interceptor import okhttp3.Interceptor
import okhttp3.Response import okhttp3.Response
class CommonParamInterceptor(private vararg val additionParams: ParamExpression) : Interceptor { class CommonParamInterceptor(private val additionParams: List<ParamExpression>) : 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 { override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request() val request = chain.request()
var headers = request.headers var headers = request.headers

View File

@ -1,5 +1,6 @@
package com.huanchengfly.tieba.post.api.retrofit.interfaces package com.huanchengfly.tieba.post.api.retrofit.interfaces
import android.os.Build
import com.huanchengfly.tieba.post.App.ScreenInfo import com.huanchengfly.tieba.post.App.ScreenInfo
import com.huanchengfly.tieba.post.api.Header import com.huanchengfly.tieba.post.api.Header
import com.huanchengfly.tieba.post.api.Param 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(Header.USER_AGENT) user_agent: String = "bdtb for Android $client_version",
@retrofit2.http.Header("client_user_token") client_user_token: String? = user_id, @retrofit2.http.Header("client_user_token") client_user_token: String? = user_id,
): Flow<CommonResponse> ): Flow<CommonResponse>
@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<Sync>
} }

View File

@ -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)
}
}
}