430 lines
16 KiB
Kotlin
430 lines
16 KiB
Kotlin
package com.gh.common.util
|
|
|
|
import android.annotation.SuppressLint
|
|
import android.content.Context
|
|
import android.text.TextUtils
|
|
import androidx.appcompat.app.AppCompatActivity
|
|
import com.gh.common.DefaultJsApi
|
|
import com.gh.gamecenter.common.constant.Constants
|
|
import com.gh.common.dialog.CertificationDialog
|
|
import com.gh.common.exposure.ExposureEvent
|
|
import com.gh.common.exposure.ExposureManager
|
|
import com.gh.common.exposure.ExposureSource
|
|
import com.gh.common.exposure.ExposureType
|
|
import com.gh.common.history.HistoryHelper
|
|
import com.gh.common.repository.ReservationRepository
|
|
import com.gh.gamecenter.core.runOnUiThread
|
|
import com.gh.gamecenter.common.view.dsbridge.CompletionHandler
|
|
import com.gh.download.DownloadManager
|
|
import com.gh.download.dialog.DownloadDialog
|
|
import com.gh.gamecenter.R
|
|
import com.gh.gamecenter.WebActivity
|
|
import com.gh.gamecenter.common.callback.ConfirmListener
|
|
import com.gh.gamecenter.common.utils.observableToMain
|
|
import com.gh.gamecenter.common.utils.singleToMain
|
|
import com.gh.gamecenter.common.utils.DialogHelper
|
|
import com.gh.gamecenter.core.utils.*
|
|
import com.gh.gamecenter.entity.ApkEntity
|
|
import com.gh.gamecenter.entity.GameEntity
|
|
import com.gh.gamecenter.entity.PluginLocation
|
|
import com.gh.gamecenter.gamedetail.dialog.GamePermissionDialogFragment
|
|
import com.gh.gamecenter.manager.UserManager
|
|
import com.gh.gamecenter.common.retrofit.EmptyResponse
|
|
import com.gh.gamecenter.common.retrofit.Response
|
|
import com.gh.gamecenter.retrofit.RetrofitManager
|
|
import com.gh.gamecenter.teenagermode.TeenagerModeActivity
|
|
import com.gh.gamecenter.common.retrofit.ApiResponse
|
|
import com.gh.gamecenter.common.utils.DataLogUtils
|
|
import com.lightgame.download.FileUtils
|
|
|
|
/**
|
|
* 游戏活动下载辅助类
|
|
*/
|
|
object GameActivityDownloadHelper {
|
|
|
|
private var mTraceEvent: ExposureEvent? = null
|
|
private var mGameEntity: GameEntity? = null
|
|
|
|
fun start(context: Context, event: DefaultJsApi.GameActivityEvent) {
|
|
if (mGameEntity != null && mGameEntity?.id == event.gameId) {
|
|
runOnUiThread {
|
|
handleGameEntity(context, event, mGameEntity!!)
|
|
}
|
|
} else {
|
|
RetrofitManager.getInstance()
|
|
.api
|
|
.getGameDigest(event.gameId)
|
|
.map(ApkActiveUtils.filterMapper)
|
|
.compose(observableToMain())
|
|
.subscribe(object : Response<GameEntity>() {
|
|
override fun onResponse(gameEntity: GameEntity?) {
|
|
mGameEntity = gameEntity
|
|
gameEntity?.let {
|
|
handleGameEntity(context, event, it)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
private fun handleGameEntity(
|
|
context: Context,
|
|
event: DefaultJsApi.GameActivityEvent,
|
|
gameEntity: GameEntity
|
|
) {
|
|
// 青少年模式
|
|
if (isTeenageMode(context)) return
|
|
|
|
val entrance = "(游戏活动[${event.activityTitle}])"
|
|
val location = "游戏活动:${event.activityTitle}-${gameEntity.name}"
|
|
if (mTraceEvent == null) {
|
|
val exposureSources = arrayListOf(
|
|
ExposureSource("游戏活动", "${event.activityTitle}+${event.activityId}")
|
|
)
|
|
mTraceEvent = ExposureEvent.createEvent(gameEntity, exposureSources, null, ExposureType.EXPOSURE)
|
|
}
|
|
|
|
mTraceEvent?.run {
|
|
when {
|
|
// 预约
|
|
gameEntity.isReservable -> reserve(context, gameEntity, entrance, this)
|
|
// 开始玩
|
|
gameEntity.getApk().size == 0 && gameEntity.h5Link != null -> play(context, gameEntity)
|
|
// 下载
|
|
else -> handleDownload(context, event, gameEntity, entrance, location, this)
|
|
}
|
|
}
|
|
}
|
|
|
|
// 青少年模式
|
|
private fun isTeenageMode(context: Context): Boolean {
|
|
if (SPUtils.getBoolean(Constants.SP_TEENAGER_MODE)) {
|
|
DialogHelper.showDialog(
|
|
context,
|
|
"提示",
|
|
"当前处于儿童/青少年模式, \n暂不提供游戏下载",
|
|
"退出青少年模式",
|
|
"关闭",
|
|
{ context.startActivity(TeenagerModeActivity.getIntent(context)) },
|
|
{},
|
|
DialogHelper.Config(
|
|
centerTitle = true,
|
|
centerContent = true
|
|
)
|
|
)
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
// 预约
|
|
private fun reserve(
|
|
context: Context,
|
|
gameEntity: GameEntity,
|
|
entrance: String,
|
|
traceEvent: ExposureEvent
|
|
) {
|
|
if (!ReservationRepository.thisGameHasBeenReserved(gameEntity.id)) {
|
|
CheckLoginUtils.checkLogin(context, entrance) {
|
|
ReservationHelper.reserve(context, gameEntity.id, object : EmptyCallback {
|
|
override fun onCallback() {
|
|
LogUtils.logReservation(gameEntity, traceEvent)
|
|
clear()
|
|
}
|
|
})
|
|
}
|
|
} else {
|
|
ToastUtils.toast("游戏已成功预约")
|
|
}
|
|
}
|
|
|
|
// 开始玩(H5链接)
|
|
private fun play(context: Context, gameEntity: GameEntity) {
|
|
val linkEntity = gameEntity.h5Link
|
|
val isPlay = "play" == linkEntity!!.type // 是否为开始玩
|
|
if (isPlay) {
|
|
HistoryHelper.insertGameEntity(gameEntity)
|
|
}
|
|
val i = WebActivity.getIntentForWebGame(
|
|
context,
|
|
gameEntity.h5Link!!.link,
|
|
gameEntity.name,
|
|
isPlay,
|
|
linkEntity.closeButton
|
|
)
|
|
context.startActivity(i)
|
|
}
|
|
|
|
// 下载
|
|
private fun handleDownload(
|
|
context: Context,
|
|
event: DefaultJsApi.GameActivityEvent,
|
|
gameEntity: GameEntity,
|
|
entrance: String,
|
|
location: String,
|
|
traceEvent: ExposureEvent
|
|
) {
|
|
val apk = getApk(gameEntity, event, true) ?: return
|
|
val downloadEntity = DownloadManager.getInstance().getDownloadEntitySnapshotByUrl(apk.url)
|
|
if (downloadEntity != null) {
|
|
ToastUtils.toast("${gameEntity.name}已加入下载队列")
|
|
} else {
|
|
val str = GameUtils.getDownloadBtnText(context, gameEntity, PluginLocation.only_game)
|
|
if (str == context.getString(R.string.download)) {
|
|
GamePermissionDialogFragment.show((context as AppCompatActivity), gameEntity, gameEntity.info, object : ConfirmListener {
|
|
override fun onConfirm() {
|
|
CertificationDialog.showCertificationDialog(context, gameEntity, object : ConfirmListener {
|
|
override fun onConfirm() {
|
|
DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean ->
|
|
download(context, gameEntity, apk, isSubscribe, entrance, location, traceEvent)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
})
|
|
DataLogUtils.uploadGameLog(context, gameEntity.id, gameEntity.name, entrance)
|
|
} else if (str == context.getString(R.string.attempt)) {
|
|
RealNameHelper.checkIfAuth(context, gameEntity, object : EmptyCallback {
|
|
override fun onCallback() {
|
|
GamePermissionDialogFragment.show((context as AppCompatActivity), gameEntity, gameEntity.info, object : ConfirmListener {
|
|
override fun onConfirm() {
|
|
CertificationDialog.showCertificationDialog(context, gameEntity, object : ConfirmListener {
|
|
override fun onConfirm() {
|
|
DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean ->
|
|
download(context, gameEntity, apk, isSubscribe, entrance, location, traceEvent)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
})
|
|
}
|
|
})
|
|
DataLogUtils.uploadGameLog(context, gameEntity.id, gameEntity.name, entrance)
|
|
} else if (str.contains("化")) {
|
|
if (gameEntity.pluggableCollection != null) {
|
|
DownloadDialog.showDownloadDialog(context, gameEntity, traceEvent, entrance, location)
|
|
} else {
|
|
CertificationDialog.showCertificationDialog(context, gameEntity, object : ConfirmListener {
|
|
override fun onConfirm() {
|
|
DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean ->
|
|
plugin(context, gameEntity, apk, entrance, location, isSubscribe, traceEvent)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
} else if (str == context.getString(R.string.install) || str == context.getString(R.string.launch)) {
|
|
ToastUtils.toast("${gameEntity.name}已加入下载队列")
|
|
} else if (str == context.getString(R.string.update)) {
|
|
DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean ->
|
|
update(context, gameEntity, apk, entrance, location, isSubscribe, traceEvent)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun getApk(
|
|
gameEntity: GameEntity,
|
|
event: DefaultJsApi.GameActivityEvent,
|
|
isRemoveOther: Boolean
|
|
): ApkEntity? {
|
|
return when {
|
|
gameEntity.getApk().isEmpty() -> null
|
|
|
|
gameEntity.getApk().size == 1 -> gameEntity.getApk()[0]
|
|
|
|
// 找出对应平台版本Apk且移除掉其他平台版本Apk
|
|
isRemoveOther -> {
|
|
// 当前游戏为多版本时,只保留活动指定的版本即可,方便之后判断
|
|
var apk: ApkEntity? = null
|
|
val iterator = gameEntity.getApk().iterator()
|
|
while (iterator.hasNext()) {
|
|
val tempApk = iterator.next()
|
|
if (tempApk.getPlatform() == event.platform) {
|
|
apk = tempApk
|
|
} else {
|
|
iterator.remove()
|
|
}
|
|
}
|
|
apk
|
|
}
|
|
|
|
// 找出对应平台版本Apk即可
|
|
else -> {
|
|
var apk: ApkEntity? = null
|
|
run outside@{
|
|
gameEntity.getApk().forEach {
|
|
if (it.getPlatform() == event.platform) {
|
|
apk = it
|
|
return@outside
|
|
}
|
|
}
|
|
}
|
|
apk
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun download(
|
|
context: Context,
|
|
gameEntity: GameEntity,
|
|
apk: ApkEntity,
|
|
isSubscribe: Boolean,
|
|
entrance: String,
|
|
location: String,
|
|
traceEvent: ExposureEvent
|
|
) {
|
|
val msg = FileUtils.isCanDownload(context, apk.size)
|
|
if (TextUtils.isEmpty(msg)) {
|
|
DownloadManager.createDownload(
|
|
context, apk, gameEntity, context.getString(
|
|
R.string.download
|
|
), entrance, location, isSubscribe, traceEvent
|
|
)
|
|
ToastUtils.toast("${gameEntity.name}已加入下载队列")
|
|
} else {
|
|
ToastUtils.toast(msg)
|
|
}
|
|
}
|
|
|
|
// 插件化
|
|
private fun plugin(
|
|
context: Context,
|
|
gameEntity: GameEntity,
|
|
apk: ApkEntity,
|
|
entrance: String,
|
|
location: String,
|
|
isSubscribe: Boolean,
|
|
traceEvent: ExposureEvent?
|
|
) {
|
|
val msg = FileUtils.isCanDownload(context, apk.size)
|
|
if (TextUtils.isEmpty(msg)) {
|
|
DownloadManager.createDownload(context, apk, gameEntity, "插件化", entrance, location, isSubscribe, traceEvent)
|
|
ToastUtils.toast("${gameEntity.name}已加入下载队列")
|
|
} else {
|
|
ToastUtils.toast(msg)
|
|
}
|
|
}
|
|
|
|
// 更新
|
|
private fun update(
|
|
context: Context,
|
|
gameEntity: GameEntity,
|
|
apk: ApkEntity,
|
|
entrance: String,
|
|
location: String,
|
|
isSubscribe: Boolean,
|
|
traceEvent: ExposureEvent?
|
|
) {
|
|
DownloadManager.createDownload(context, apk, gameEntity, "更新", entrance, location, isSubscribe, traceEvent)
|
|
ToastUtils.toast("${gameEntity.name}已加入下载队列")
|
|
}
|
|
|
|
@SuppressLint("CheckResult")
|
|
fun postTaskComplete(gameId: String) {
|
|
val api = RetrofitManager.getInstance().newApi
|
|
val single = if (UserManager.getInstance().isLoggedIn) {
|
|
api.postGameActivityTask(gameId)
|
|
} else {
|
|
api.postGameActivityTaskForNoLogin(gameId)
|
|
}
|
|
single.compose(singleToMain()).subscribe(EmptyResponse())
|
|
}
|
|
|
|
// 判断是否完成任务(预约完成或者已安装且无更新)
|
|
@SuppressLint("CheckResult")
|
|
fun checkTaskComplete(
|
|
context: Context,
|
|
event: DefaultJsApi.GameActivityEvent,
|
|
handler: CompletionHandler<Any>
|
|
) {
|
|
// 预约完成
|
|
if (ReservationRepository.thisGameHasBeenReserved(event.gameId)) {
|
|
postTaskComplete(event.gameId)
|
|
handler.complete(true)
|
|
return
|
|
}
|
|
|
|
if (mGameEntity != null && mGameEntity?.id == event.gameId) {
|
|
handleCheckTaskComplete(context, mGameEntity, event, handler)
|
|
} else {
|
|
RetrofitManager.getInstance()
|
|
.api
|
|
.getGameDigest(event.gameId)
|
|
.map(ApkActiveUtils.filterMapper)
|
|
.compose(observableToMain())
|
|
.subscribe(object : Response<GameEntity>() {
|
|
override fun onResponse(gameEntity: GameEntity?) {
|
|
mGameEntity = gameEntity
|
|
handleCheckTaskComplete(context, gameEntity, event, handler)
|
|
}
|
|
|
|
override fun onApiFailure(e: ApiResponse<GameEntity>?) {
|
|
super.onApiFailure(e)
|
|
handler.complete(false)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
private fun handleCheckTaskComplete(
|
|
context: Context,
|
|
gameEntity: GameEntity?,
|
|
event: DefaultJsApi.GameActivityEvent,
|
|
handler: CompletionHandler<Any>
|
|
) {
|
|
if (gameEntity == null) {
|
|
handler.complete(false)
|
|
} else {
|
|
val apk = getApk(gameEntity, event, false)
|
|
if (apk == null) {
|
|
handler.complete(false)
|
|
} else {
|
|
// 已安装
|
|
if (PackageUtils.isInstalled(context, apk.packageName)) {
|
|
// 是否可更新
|
|
if (PackageUtils.isCanUpdate(apk, event.gameId)
|
|
|| PackageUtils.isNonPluginUpdatable(apk, gameEntity)
|
|
) {
|
|
handler.complete(false)
|
|
} else {
|
|
// 已安装且无更新
|
|
postTaskComplete(event.gameId)
|
|
handler.complete(true)
|
|
}
|
|
} else {
|
|
handler.complete(false)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fun postExposureEvent(event: DefaultJsApi.GameActivityEvent) {
|
|
RetrofitManager.getInstance()
|
|
.api
|
|
.getGameDigest(event.gameId)
|
|
.map(ApkActiveUtils.filterMapper)
|
|
.compose(observableToMain())
|
|
.subscribe(object : Response<GameEntity>() {
|
|
override fun onResponse(gameEntity: GameEntity?) {
|
|
mGameEntity = gameEntity
|
|
gameEntity?.let {
|
|
val exposureSources = arrayListOf(
|
|
ExposureSource("游戏活动", "${event.activityTitle}+${event.activityId}")
|
|
)
|
|
mTraceEvent = ExposureEvent.createEvent(
|
|
gameEntity,
|
|
exposureSources,
|
|
null,
|
|
ExposureType.EXPOSURE
|
|
)
|
|
mTraceEvent?.run { ExposureManager.log(this) }
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
fun clear() {
|
|
mTraceEvent = null
|
|
mGameEntity = null
|
|
}
|
|
} |