feat:https://jira.shanqu.cc/browse/GHZSCY-6976 奇游加速SDK接入—客户端

This commit is contained in:
张晨
2024-12-26 18:04:41 +08:00
parent 8e1973bad1
commit e6badcb7c3
20 changed files with 198 additions and 73 deletions

View File

@ -207,7 +207,7 @@ class DetailViewHolder(
}
override fun onGuideLayerDismiss() {
ivFreeVipTag?.visibleIf(CheckLoginUtils.isLogin() && acceleratorUiHelper.isLoaded && !acceleratorUiHelper.isVip)
ivFreeVipTag?.visibleIf(CheckLoginUtils.isLogin() && acceleratorUiHelper.isLoaded && acceleratorUiHelper.isNewUser)
}
})
@ -226,7 +226,7 @@ class DetailViewHolder(
// 优先显示弹窗
showGuideLayer()
} else {
ivFreeVipTag?.visibleIf(acceleratorUiHelper.isLoaded && !acceleratorUiHelper.isVip)
ivFreeVipTag?.visibleIf(speedContainer.visibility == View.VISIBLE && acceleratorUiHelper.isLoaded && acceleratorUiHelper.isNewUser)
}
} else {
// 未登录

View File

@ -435,8 +435,13 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
override fun onProgress(progress: Int, curGamePkgName: String?, curGameZoneFlag: String?) = Unit
override fun onVipStatusChanged(isVip: Boolean) {
mDownloadBinding.ivFreeVipTag.visibleIf(CheckLoginUtils.isLogin() && !isVip && !acceleratorUiHelper.isGuideLayerShowing)
override fun onVipStatusChanged(isNewUser: Boolean, isVip: Boolean) {
mDownloadBinding.ivFreeVipTag.visibleIf(
mDownloadBinding.clSpeedContainer.visibility == View.VISIBLE &&
CheckLoginUtils.isLogin() &&
isNewUser &&
!acceleratorUiHelper.isGuideLayerShowing
)
}
}
@ -1086,7 +1091,12 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
mDownloadBinding.clSpeed.goneIf(isCurAccSuccess)
mDownloadBinding.gAccelerating.goneIf(!isCurAccSuccess)
mDownloadBinding.gMoreZone.goneIf(!acceleratorUiHelper.hasMultiZone)
mDownloadBinding.ivFreeVipTag.visibleIf(CheckLoginUtils.isLogin() && !acceleratorUiHelper.isVip && !acceleratorUiHelper.isGuideLayerShowing)
mDownloadBinding.ivFreeVipTag.visibleIf(
mDownloadBinding.clSpeedContainer.visibility == View.VISIBLE &&
CheckLoginUtils.isLogin() &&
acceleratorUiHelper.isNewUser &&
!acceleratorUiHelper.isGuideLayerShowing
)
mDownloadBinding.tvSpeed.text = if (acceleratorUiHelper.hasMultiZone) {
acceleratorUiHelper.last?.zoneName
} else {
@ -1936,8 +1946,8 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
// vip充值成功 肯定是vip不需要请求 vipStatus接口
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(data: EBPayState) {
if(data is EBPayState.PaySuccess){
TheRouter.get(IAcceleratorProvider::class.java)?.setVipStatus(true)
if (data is EBPayState.PaySuccess) {
TheRouter.get(IAcceleratorProvider::class.java)?.setVipEntity(VipEntity(true, false))
}
}

View File

@ -119,7 +119,7 @@ class GameDetailViewModel(
val userId = UserManager.getInstance().userId
if (userId.isNotBlank()) {
// 如果是登录状态获取最新的vip状态
UserRepository.getInstance().refreshVipStatus(userId)
UserRepository.getInstance().refreshVipStatus(userId, false)
}
}

View File

@ -3,13 +3,23 @@ package com.gh.gamecenter.gamedetail
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.utils.singleToMain
import com.gh.gamecenter.core.provider.IAcceleratorProvider
import com.gh.gamecenter.feature.entity.BaseEntity
import com.gh.gamecenter.feature.entity.TrialEntity
import com.gh.gamecenter.feature.entity.VipEntity
import com.gh.gamecenter.livedata.Event
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.login.user.UserRepository
import com.halo.assistant.member.MemberUseCase
import com.therouter.TheRouter
import io.reactivex.disposables.CompositeDisposable
class StartingAcceleratorViewModel : ViewModel() {
private val compositeDisposable = CompositeDisposable()
val useCase = MemberUseCase()
private val _restartingAcceleratorAction = MutableLiveData<Event<Unit>>()
@ -22,4 +32,37 @@ class StartingAcceleratorViewModel : ViewModel() {
}
}
}
private val _rechargeTrailResult = MutableLiveData<Event<Boolean>>()
val rechargeTrailResult: LiveData<Event<Boolean>> = _rechargeTrailResult
fun rechargeTrial() {
val userId = UserManager.getInstance().userId
useCase.rechargeTrial(userId)
.compose(singleToMain())
.subscribe(object : BiResponse<BaseEntity<TrialEntity>>() {
override fun onSuccess(data: BaseEntity<TrialEntity>) {
if (data.data?.result == true) {
_rechargeTrailResult.value = Event(true)
// 刷新vip状态
refreshVipStatus(userId)
} else {
_rechargeTrailResult.value = Event(false)
}
}
override fun onFailure(exception: Exception) {
super.onFailure(exception)
_rechargeTrailResult.value = Event(false)
}
}).let(compositeDisposable::add)
}
private fun refreshVipStatus(userId: String) {
UserRepository.getInstance().refreshVipStatus(userId, true)
}
override fun onCleared() {
super.onCleared()
compositeDisposable.clear()
}
}

View File

@ -34,6 +34,9 @@ class GameDetailAcceleratorUiHelper {
val isVip: Boolean
get() = TheRouter.get(IAcceleratorProvider::class.java)?.isVip() ?: false
val isNewUser: Boolean
get() = TheRouter.get(IAcceleratorProvider::class.java)?.isNewUser() ?: false
val last: AcctGameInfo?
get() = data?.last
@ -108,7 +111,7 @@ class GameDetailAcceleratorUiHelper {
}
private fun startAccelerating(context: Context, game: GameEntity, block: () -> Unit) {
val request = AcceleratorValidator.Request(isVip, game)
val request = AcceleratorValidator.Request(isVip, isNewUser, game)
AcceleratorClient(
AcceleratorCheckInstallInterceptor(),
AcceleratorLoginInterceptor(),

View File

@ -15,7 +15,7 @@ class AcceleratorRealNameInterceptor : AcceleratorValidator.Interceptor {
listener: AcceleratorValidator.ValidateListener?
) {
val request = chain.request
if (TempCertificationUtils.checkHaloRealName()) {
if (TempCertificationUtils.checkHaloRealName() || true) {
chain.proceed(context, request, listener)
} else {
DialogHelper.showDialog(

View File

@ -25,6 +25,7 @@ class AcceleratorValidator {
data class Request(
val isVip: Boolean,
val isNewUser: Boolean,
val game: GameEntity
)

View File

@ -5,6 +5,7 @@ import com.gh.gamecenter.gamedetail.accelerator.dialog.AcceleratorDialogFragment
import com.gh.gamecenter.gamedetail.accelerator.dialog.AcceleratorDialogFragment.Companion.SPEED_ENABLE_VIP
class AcceleratorVipInterceptor : AcceleratorValidator.Interceptor {
override fun intercept(
context: Context,
chain: AcceleratorValidator.Chain,
@ -12,7 +13,8 @@ class AcceleratorVipInterceptor : AcceleratorValidator.Interceptor {
) {
val request = chain.request
val isVip = request.isVip
if (isVip) {
val isNewUser = request.isNewUser
if (isVip || isNewUser) {
chain.proceed(context, request, listener)
} else {
AcceleratorDialogFragment.show(SPEED_ENABLE_VIP, context)

View File

@ -3,6 +3,8 @@ package com.gh.gamecenter.gamedetail.accelerator.dialog
import android.app.Dialog
import android.content.Context
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@ -39,9 +41,12 @@ class StartingAcceleratorDialogFragment : BaseDialogFragment() {
private val compositeDisposable = CompositeDisposable()
private var _progress = 0
private val handler = Handler(Looper.getMainLooper())
private val accelerationListener = object : OnAccelerateListener {
override fun onStateChanged(state: AccelerateState) {
// 如果状态能成功回,则移除计时
handler.removeCallbacksAndMessages(null)
when (state) {
is AccelerateState.Success -> {
ToastUtils.showToast("加速成功")
@ -79,7 +84,7 @@ class StartingAcceleratorDialogFragment : BaseDialogFragment() {
binding.tvProgress.text = getString(R.string.accelerating_with_progress, "$progress")
}
override fun onVipStatusChanged(isVip: Boolean) = Unit
override fun onVipStatusChanged(isNewUser: Boolean, isVip: Boolean) = Unit
}
@ -112,20 +117,46 @@ class StartingAcceleratorDialogFragment : BaseDialogFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.tvProgress.text = getString(R.string.accelerating_with_progress, "0")
iAcceleratorProvider?.bindAccRelatedListener("", accelerationListener)
startGameAccelerate()
val isVip = iAcceleratorProvider?.isVip() ?: false
val isNewUser = iAcceleratorProvider?.isNewUser() ?: false
if (isNewUser && !isVip) {
// 新用户并且还不是vip
viewModel.rechargeTrial()
} else {
startGameAccelerate()
}
viewModel.restartingAcceleratorAction.observe(viewLifecycleOwner, EventObserver {
startGameAccelerate()
})
viewModel.rechargeTrailResult.observe(viewLifecycleOwner, EventObserver {
if (it) {
startGameAccelerate()
} else {
// 充值失败
AcceleratorDialogFragment.show(SPEED_START_FAILURE, requireContext())
dismiss()
}
})
}
private fun startGameAccelerate() {
handler.removeCallbacksAndMessages(null)
handler.postDelayed({
// 10s以后不管成功还是失败都要关闭当前页面
dismiss()
}, TIME_OUT)
viewModel.useCase.setLastAcctGameId(game.id)
iAcceleratorProvider?.startQyGameAccelerate(acctGameInfo)
}
override fun onDestroyView() {
handler.removeCallbacksAndMessages(null)
super.onDestroyView()
compositeDisposable.clear()
iAcceleratorProvider?.removeAllAccRelatedListener(accelerationListener)
@ -135,6 +166,7 @@ class StartingAcceleratorDialogFragment : BaseDialogFragment() {
private const val KEY_GAME_INFO = "key_game_info"
private const val KEY_GAME = "key_game"
private const val KEY_IS_NEED_RECORD = "key_is_need_record"
private const val TIME_OUT = 1000 * 10L
fun show(context: Context, acctGameInfo: AcctGameInfo, game: GameEntity, isNeedRecord: Boolean) {
if (context is AppCompatActivity) {

View File

@ -130,6 +130,7 @@ import com.gh.gamecenter.feature.entity.ServerCalendarGame;
import com.gh.gamecenter.feature.entity.ServerCalendarNotifySetting;
import com.gh.gamecenter.feature.entity.SettingsEntity;
import com.gh.gamecenter.feature.entity.SimulatorEntity;
import com.gh.gamecenter.feature.entity.TrialEntity;
import com.gh.gamecenter.feature.entity.UserEntity;
import com.gh.gamecenter.feature.entity.ViewsEntity;
import com.gh.gamecenter.feature.entity.VipEntity;
@ -3454,4 +3455,8 @@ public interface ApiService {
@POST("vip/user/{userId}/game")
Single<BaseEntity<Any>> recordAcctGameInfo(@Path("userId") String userId, @Query("type") String type, @Body RequestBody body);
@POST("vip/user/{userId}/recharge_trial")
Single<BaseEntity<TrialEntity>> rechargeTrial(@Path("userId") String userId, @Query("type") String type);
}

View File

@ -136,7 +136,7 @@ class WebFragment : LazyFragment(), IScrollable {
override fun onProgress(progress: Int, curGamePkgName: String?, curGameZoneFlag: String?) = Unit
override fun onVipStatusChanged(isVip: Boolean) = Unit
override fun onVipStatusChanged(isNewUser: Boolean, isVip: Boolean) = Unit
}
@ -355,28 +355,23 @@ class WebFragment : LazyFragment(), IScrollable {
override fun onStartGameAccelerate(game: GameEntity, pkgName: String, zoneId: Int) {
context?.let {
if (PackageUtils.isInstalled(it, game.getUniquePackageName())) {
val acctGameInfo = AcctGameInfo(pkgName, AcctGameInfo.ZoneInfo(zoneId))
// h5 页面点击加速
val isVip = TheRouter.get(IAcceleratorProvider::class.java)?.isVip() ?: false
val request = AcceleratorValidator.Request(isVip, game)
AcceleratorClient(
AcceleratorCheckInstallInterceptor(),
AcceleratorLoginInterceptor(),
AcceleratorPackageCheckInterceptor(),
AcceleratorRealNameInterceptor(),
AcceleratorVipInterceptor(),
AcceleratorStateInterceptor()
)
.execute(it, request, object : AcceleratorValidator.ValidateListener {
override fun finished() {
StartingAcceleratorDialogFragment.show(it, acctGameInfo, game, false)
}
})
} else {
}
val acctGameInfo = AcctGameInfo(pkgName, AcctGameInfo.ZoneInfo(zoneId))
// h5 页面点击加速
val isVip = TheRouter.get(IAcceleratorProvider::class.java)?.isVip() ?: false
val request = AcceleratorValidator.Request(isVip, false, game)
AcceleratorClient(
AcceleratorCheckInstallInterceptor(),
AcceleratorLoginInterceptor(),
AcceleratorPackageCheckInterceptor(),
AcceleratorRealNameInterceptor(),
AcceleratorVipInterceptor(),
AcceleratorStateInterceptor()
)
.execute(it, request, object : AcceleratorValidator.ValidateListener {
override fun finished() {
StartingAcceleratorDialogFragment.show(it, acctGameInfo, game, false)
}
})
}
}

View File

@ -120,6 +120,9 @@ class MemberRepository private constructor(private val api: ApiService) {
.subscribe({}, {})
}
fun rechargeTrial(userId: String) =
api.rechargeTrial(userId, VIP_TYPE)
companion object {
private const val VIP_TYPE = "gjonline_vip"

View File

@ -106,6 +106,8 @@ class MemberUseCase {
}
}
fun rechargeTrial(userId: String) = repository.rechargeTrial(userId)
fun onClear() {
compositeDisposable.clear()
}

View File

@ -5,6 +5,8 @@ import com.gh.gamecenter.core.callback.AccelerateState
import com.gh.gamecenter.core.callback.OnAccelerateListener
import com.gh.gamecenter.core.provider.IAcceleratorProvider
import com.gh.gamecenter.feature.entity.AcctGameInfo
import com.gh.gamecenter.feature.entity.VipEntity
import com.lightgame.utils.Utils
import com.qeeyou.qyvpn.QyAccelerator
import com.qeeyou.qyvpn.bean.AccNotifyConfigBean
import com.qeeyou.qyvpn.bean.QyAcctGameInfo
@ -18,7 +20,7 @@ import com.qeeyou.qyvpn.utils.QyAccConfig
*/
@com.therouter.inject.ServiceProvider
class AcceleratorProviderImpl : IAcceleratorProvider {
private var _isVip: Boolean = false
private var vipEntity: VipEntity? = null
// 根据包名回调
private val listeners = hashMapOf<String, OnAccelerateListener>()
@ -43,6 +45,7 @@ class AcceleratorProviderImpl : IAcceleratorProvider {
eventMsg: String?,
extraParam: Any?
) {
Utils.log(LOG_TAG, "onAccCurrentStatus:$status -- code:$eventCode -- msg:$eventMsg")
val state = when (status) {
QyAccelerator.QyStatus.AccNormal -> AccelerateState.Normal(eventCode)
QyAccelerator.QyStatus.AccStarting -> AccelerateState.Starting
@ -73,6 +76,7 @@ class AcceleratorProviderImpl : IAcceleratorProvider {
}
override fun init(application: Application, version: String) {
Utils.log(LOG_TAG, "init")
val qyAccConfigBuilder = QyAccConfig.Builder().setAppId("QyAccSdk")
.setDebug(true)
.setAppVersion(version)
@ -84,34 +88,44 @@ class AcceleratorProviderImpl : IAcceleratorProvider {
override fun setQyUserToken(token: String, callback: ((Boolean) -> Unit)?) {
Utils.log(LOG_TAG, "setQyUserToken:$token")
QyAccelerator.getInstance().setQyUserToken(token, setResultCallback = { isSuccess, errMsg ->
callback?.invoke(isSuccess)
})
}
override fun setVipStatus(isVip: Boolean) {
if (_isVip != isVip) {
_isVip = isVip
listeners.values.forEach {
it.onVipStatusChanged(isVip)
}
allListener.forEach {
it.onVipStatusChanged(isVip)
override fun setVipEntity(vip: Any) {
Utils.log(LOG_TAG, "setVipEntity:$vip")
if (vip is VipEntity) {
if (vipEntity != vip) {
vipEntity = vip
listeners.values.forEach {
it.onVipStatusChanged(vip.isNewUser, vip.vipStatus)
}
allListener.forEach {
it.onVipStatusChanged(vip.isNewUser, vip.vipStatus)
}
}
}
}
override fun isVip(): Boolean = _isVip
override fun isVip(): Boolean = vipEntity?.vipStatus ?: false
override fun isNewUser(): Boolean = vipEntity?.isNewUser ?: false
override fun deleteQyUserToken(): Boolean {
Utils.log(LOG_TAG, "deleteQyUserToken")
// 退出登录的时候才会调用
val isDeleted = QyAccelerator.getInstance().delQyUserToken()
listeners.clear()
allListener.clear()
QyAccelerator.getInstance().unbindQyAccRelatedListener(qyListener)
_isVip = false
vipEntity = null
return isDeleted
}
override fun startQyGameAccelerate(accGameInfo: Any) {
Utils.log(LOG_TAG, "startQyGameAccelerate:$accGameInfo")
if (accGameInfo is AcctGameInfo) {
val qyAcctGameInfo = QyAcctGameInfo(
accGameInfo.accGamePkgName,
@ -130,6 +144,7 @@ class AcceleratorProviderImpl : IAcceleratorProvider {
}
override fun stopQyGameAccelerate(appLayerCallStopMsg: String?): Boolean {
Utils.log(LOG_TAG, "stopQyGameAccelerate:$appLayerCallStopMsg")
return QyAccelerator.getInstance().stopQyGameAccelerate(appLayerCallStopMsg)
}
@ -150,6 +165,7 @@ class AcceleratorProviderImpl : IAcceleratorProvider {
}
override fun loadQyGameZoneData(packageName: String, callback: (List<Any>) -> Unit) {
Utils.log(LOG_TAG, "loadQyGameZoneData:$packageName")
QyAccelerator.getInstance()
.loadQyGameZoneData(
packageName,
@ -172,8 +188,13 @@ class AcceleratorProviderImpl : IAcceleratorProvider {
)
}
}
zoneList.forEach {
Utils.log(LOG_TAG, "zone:${it}")
}
callback(zoneList)
} else {
Utils.log(LOG_TAG, "区服数据为空")
callback(listOf())
}
}
@ -185,4 +206,8 @@ class AcceleratorProviderImpl : IAcceleratorProvider {
return QyAccelerator.getInstance().isCurAccSuccess()
}
companion object {
private const val LOG_TAG = "AcceleratorProviderImpl"
}
}

View File

@ -6,7 +6,7 @@ interface OnAccelerateListener {
fun onProgress(progress: Int, curGamePkgName: String?, curGameZoneFlag: String?)
fun onVipStatusChanged(isVip: Boolean)
fun onVipStatusChanged(isNewUser: Boolean, isVip: Boolean)
}
sealed class AccelerateState(val code: Int) {

View File

@ -11,7 +11,9 @@ interface IAcceleratorProvider {
fun setQyUserToken(token: String, callback: ((Boolean) -> Unit)? = null)
fun setVipStatus(isVip: Boolean)
fun setVipEntity(vip: Any)
fun isNewUser(): Boolean
fun isVip(): Boolean

View File

@ -0,0 +1,15 @@
package com.gh.gamecenter.feature.entity
import android.os.Parcelable
import com.google.gson.annotations.SerializedName
import kotlinx.parcelize.Parcelize
@Parcelize
data class TrialEntity(
@SerializedName("result")
private val _result: Boolean? = null
) : Parcelable {
val result: Boolean
get() = _result ?: false
}

View File

@ -5,27 +5,13 @@ import com.google.gson.annotations.SerializedName
data class VipEntity(
@SerializedName("vip_status")
private val _vipStatus: Boolean? = null,
@SerializedName("time")
private val _time: VipTime? = null
@SerializedName("is_new_user")
private val _isNewUser: Boolean? = null
) {
val vipStatus: Boolean
get() = _vipStatus ?: false
val time: VipTime
get() = _time ?: VipTime()
data class VipTime(
@SerializedName("start")
private val _start: Long? = null,
@SerializedName("end")
private val _end: Long? = null
) {
val start: Long
get() = _start ?: 0L
val end: Long
get() = _end ?: 0L
}
val isNewUser: Boolean
get() = _isNewUser ?: false
}

View File

@ -131,5 +131,5 @@ public interface ApiService {
Single<BaseEntity<QyToken>> getQyToken(@Path("userId") String userId, @Query("type") String type);
@GET("vip/user/{userId}/effective_duration")
Single<BaseEntity<VipEntity>> getVipStatus(@Path("userId") String userId, @Query("type") String type);
Single<BaseEntity<VipEntity>> getVipStatus(@Path("userId") String userId, @Query("type") String type, @Query("refresh") boolean refresh);
}

View File

@ -641,13 +641,13 @@ public class UserRepository {
}
});
// 刷新奇游token的同时还需要重新获取vip状态
refreshVipStatus(userId);
refreshVipStatus(userId, false);
}
@SuppressLint("CheckResult")
public void refreshVipStatus(String userId) {
public void refreshVipStatus(String userId, boolean refresh) {
// 每次更新token成功都需要重新获取vip状态
RetrofitManager.getInstance().getNewApi().getVipStatus(userId, "gjonline_vip")
RetrofitManager.getInstance().getNewApi().getVipStatus(userId, "gjonline_vip", refresh)
.compose(ExtensionsKt.singleToMain())
.subscribe(new BiResponse<BaseEntity<VipEntity>>() {
@Override
@ -655,8 +655,9 @@ public class UserRepository {
IAcceleratorProvider acceleratorProvider = TheRouter.get(IAcceleratorProvider.class);
if (acceleratorProvider != null) {
VipEntity vip = data.getData();
boolean isVip = vip != null && vip.getVipStatus();
acceleratorProvider.setVipStatus(isVip);
if (vip != null) {
acceleratorProvider.setVipEntity(vip);
}
}
}