2025-11-20 09:45:17 +00:00
|
|
|
package com.gamedog.vididin.manager
|
|
|
|
|
|
2025-11-26 06:04:30 +00:00
|
|
|
import com.ama.core.architecture.util.DateUtil
|
2025-11-20 09:45:17 +00:00
|
|
|
import com.ama.core.architecture.util.FileUtil
|
2025-11-26 03:52:09 +00:00
|
|
|
import com.ama.core.architecture.util.SpUtil
|
2025-11-27 03:57:56 +00:00
|
|
|
import com.ama.core.architecture.util.eventbus.NotifyMan
|
|
|
|
|
import com.gamedog.vididin.VididinEvents
|
2025-11-25 11:29:09 +00:00
|
|
|
import com.gamedog.vididin.main.fragments.task.Task
|
2025-11-20 09:45:17 +00:00
|
|
|
import com.gamedog.vididin.main.fragments.task.TaskBean
|
|
|
|
|
import com.google.gson.GsonBuilder
|
|
|
|
|
import kotlinx.coroutines.sync.Mutex
|
|
|
|
|
import kotlinx.coroutines.sync.withLock
|
|
|
|
|
import kotlinx.coroutines.*
|
|
|
|
|
|
|
|
|
|
class TaskManager private constructor() {
|
|
|
|
|
companion object {
|
2025-11-25 11:29:09 +00:00
|
|
|
// 新手任务分类及其子类
|
|
|
|
|
private const val TAG_CATEGORY_NEWBIE_TASK = "newbie_task"
|
|
|
|
|
private const val TAG_TASK_NEWBIE_FIRST_WITHDRAW = "newbie_first_withdraw"
|
|
|
|
|
private const val TAG_TASK_NEWBIE_PUSH_NOTIFY = "newbie_push_notify"
|
|
|
|
|
private const val TAG_TASK_NEWBIE_JOIN_DISCORD = "newbie_join_discord"
|
|
|
|
|
private const val TAG_TASK_NEWBIE_7DAY_CHECKIN = "newbie_7day_checkin"
|
|
|
|
|
|
|
|
|
|
// 日常任务分类及其子类
|
|
|
|
|
private const val TAG_CATEGORY_DAILY_TASK = "daily_task"
|
|
|
|
|
private const val TAG_TASK_DAILY_CHECKIN = "daily_checkin"
|
|
|
|
|
private const val TAG_TASK_DAILY_VIDEO = "daily_video_ladder"
|
|
|
|
|
private const val TAG_TASK_DAILY_AD = "daily_ad_ladder"
|
|
|
|
|
|
2025-11-26 03:52:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Volatile
|
|
|
|
|
private var instance: TaskManager? = null
|
|
|
|
|
|
|
|
|
|
fun instance(): TaskManager {
|
|
|
|
|
return instance ?: synchronized(this) {
|
|
|
|
|
instance ?: TaskManager().also {
|
|
|
|
|
instance = it
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-11-20 09:45:17 +00:00
|
|
|
}
|
|
|
|
|
|
2025-11-26 06:04:30 +00:00
|
|
|
|
2025-11-26 07:31:34 +00:00
|
|
|
private var mCurDayIndexDailySign: Int = 0
|
2025-11-20 09:45:17 +00:00
|
|
|
private val mutex = Mutex()
|
|
|
|
|
|
|
|
|
|
@Volatile
|
|
|
|
|
private var initialized = false
|
2025-11-25 11:29:09 +00:00
|
|
|
private var mTaskConfig: TaskBean? = null
|
2025-11-26 07:31:34 +00:00
|
|
|
private var mDailySignData: DailySignBean = DailySignBean()
|
2025-11-20 09:45:17 +00:00
|
|
|
private val mGson = GsonBuilder().create()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
init {
|
|
|
|
|
loadTaskConfigAsync()
|
2025-11-26 09:06:12 +00:00
|
|
|
|
2025-11-26 10:39:20 +00:00
|
|
|
|
2025-11-26 09:06:12 +00:00
|
|
|
// TODO - remove test code
|
|
|
|
|
if (true) {
|
|
|
|
|
generateTestDailySignTestBean()
|
|
|
|
|
}
|
2025-11-20 09:45:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
suspend fun getTaskConfig(): TaskBean? = mutex.withLock {
|
|
|
|
|
if (!initialized) {
|
|
|
|
|
loadTaskConfigFromAsset()
|
|
|
|
|
}
|
2025-11-25 11:29:09 +00:00
|
|
|
return mTaskConfig
|
2025-11-20 09:45:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun loadTaskConfigAsync() {
|
|
|
|
|
CoroutineScope(Dispatchers.IO).launch {
|
|
|
|
|
mutex.withLock {
|
|
|
|
|
if (!initialized) {
|
|
|
|
|
loadTaskConfigFromAsset()
|
2025-11-26 07:31:34 +00:00
|
|
|
loadTaskStatesFromSp()
|
2025-11-26 10:39:20 +00:00
|
|
|
|
|
|
|
|
initCalculate()
|
2025-11-20 09:45:17 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private suspend fun loadTaskConfigFromAsset() {
|
|
|
|
|
return withContext(Dispatchers.IO) {
|
|
|
|
|
val configStr = FileUtil.readAssetsFile("taskConfig.json")
|
2025-11-25 11:29:09 +00:00
|
|
|
mTaskConfig = mGson.fromJson(configStr, TaskBean::class.java)
|
2025-11-20 09:45:17 +00:00
|
|
|
initialized = true
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-11-25 06:59:50 +00:00
|
|
|
|
2025-11-25 11:29:09 +00:00
|
|
|
|
2025-11-26 07:31:34 +00:00
|
|
|
private suspend fun loadTaskStatesFromSp() {
|
2025-11-26 03:52:09 +00:00
|
|
|
return withContext(Dispatchers.IO) {
|
2025-11-26 07:31:34 +00:00
|
|
|
val taskStateBeanInSp = SpUtil.instance().getObject<DailySignBean>(SpUtil.KEY_TASK_BEAN)
|
2025-11-26 06:04:30 +00:00
|
|
|
if (taskStateBeanInSp == null) {
|
2025-11-26 07:31:34 +00:00
|
|
|
SpUtil.instance().putObject(SpUtil.KEY_TASK_BEAN, mDailySignData)
|
2025-11-26 06:04:30 +00:00
|
|
|
} else {
|
2025-11-26 07:31:34 +00:00
|
|
|
mDailySignData = taskStateBeanInSp
|
2025-11-26 06:04:30 +00:00
|
|
|
}
|
2025-11-26 03:52:09 +00:00
|
|
|
}
|
|
|
|
|
}
|
2025-11-25 11:29:09 +00:00
|
|
|
|
2025-11-26 10:39:20 +00:00
|
|
|
private fun initCalculate() {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-25 11:29:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-11-26 03:52:09 +00:00
|
|
|
//------------------------- Get tasks -------------------------------
|
2025-11-25 11:29:09 +00:00
|
|
|
// 日常任务
|
|
|
|
|
fun getDailyCheckInTask(): Task? {
|
|
|
|
|
return mTaskConfig?.task_module_config?.getTaskCategoryById(TAG_CATEGORY_DAILY_TASK)?.getTaskById(TAG_TASK_DAILY_CHECKIN)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fun getDailyVideoTask(): Task? {
|
|
|
|
|
return mTaskConfig?.task_module_config?.getTaskCategoryById(TAG_CATEGORY_DAILY_TASK)?.getTaskById(TAG_TASK_DAILY_VIDEO)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fun getDailyAdTask(): Task? {
|
|
|
|
|
return mTaskConfig?.task_module_config?.getTaskCategoryById(TAG_CATEGORY_DAILY_TASK)?.getTaskById(TAG_TASK_DAILY_AD)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 新手任务
|
|
|
|
|
fun getNewbieFirstWithdrawTask(): Task? {
|
|
|
|
|
return mTaskConfig?.task_module_config?.getTaskCategoryById(TAG_CATEGORY_NEWBIE_TASK)?.getTaskById(TAG_TASK_NEWBIE_FIRST_WITHDRAW)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fun getNewbieEnableNotifyTask(): Task? {
|
|
|
|
|
return mTaskConfig?.task_module_config?.getTaskCategoryById(TAG_CATEGORY_NEWBIE_TASK)?.getTaskById(TAG_TASK_NEWBIE_PUSH_NOTIFY)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fun getNewbieJoinDiscordTask(): Task? {
|
|
|
|
|
return mTaskConfig?.task_module_config?.getTaskCategoryById(TAG_CATEGORY_NEWBIE_TASK)?.getTaskById(TAG_TASK_NEWBIE_JOIN_DISCORD)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fun getNewbieCheckInTask(): Task? {
|
|
|
|
|
return mTaskConfig?.task_module_config?.getTaskCategoryById(TAG_CATEGORY_NEWBIE_TASK)?.getTaskById(TAG_TASK_NEWBIE_7DAY_CHECKIN)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-11-26 03:52:09 +00:00
|
|
|
//----------------------------- 每日签到 -----------------------------//
|
|
|
|
|
|
|
|
|
|
fun getHomeWatchDurationRewardNum(): Int {
|
|
|
|
|
return 28; // TODO - mTaskConfigBean.xxxx
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2025-11-26 06:04:30 +00:00
|
|
|
fun getCurDayIndexOfDailyCheckIn() : Int {
|
2025-11-26 07:31:34 +00:00
|
|
|
var dayIndexOfPeriod = 0
|
2025-11-26 06:04:30 +00:00
|
|
|
|
2025-11-26 07:31:34 +00:00
|
|
|
val periodStartMs = mDailySignData.startMs
|
2025-11-26 06:04:30 +00:00
|
|
|
if (periodStartMs > 0) {
|
2025-11-26 07:31:34 +00:00
|
|
|
dayIndexOfPeriod = DateUtil.getPassedDayNum(periodStartMs, DateUtil.getCurTimeMs())
|
2025-11-26 06:04:30 +00:00
|
|
|
if (dayIndexOfPeriod > 6) {
|
2025-11-26 07:31:34 +00:00
|
|
|
mDailySignData.startMs = DateUtil.getCurTimeMs()
|
|
|
|
|
SpUtil.instance().putObject(SpUtil.KEY_TASK_BEAN, mDailySignData)
|
2025-11-26 06:04:30 +00:00
|
|
|
}
|
|
|
|
|
} else {
|
2025-11-26 07:31:34 +00:00
|
|
|
mDailySignData.startMs = DateUtil.getCurTimeMs()
|
|
|
|
|
SpUtil.instance().putObject(SpUtil.KEY_TASK_BEAN, mDailySignData)
|
2025-11-26 06:04:30 +00:00
|
|
|
}
|
2025-11-26 07:31:34 +00:00
|
|
|
|
|
|
|
|
mCurDayIndexDailySign = dayIndexOfPeriod
|
|
|
|
|
return dayIndexOfPeriod
|
2025-11-26 03:52:09 +00:00
|
|
|
}
|
|
|
|
|
|
2025-11-26 08:40:28 +00:00
|
|
|
fun getDailySignStateBean(dayIndex: Int): DailySignDayInfoBean {
|
|
|
|
|
return mDailySignData.signStateList[dayIndex]
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-26 10:39:20 +00:00
|
|
|
fun executeDailySign(dayIndex: Int, isDoubleReward: Boolean, isByAd: Boolean) : Boolean {
|
2025-11-26 07:31:34 +00:00
|
|
|
val daySignState = mDailySignData.signStateList[dayIndex]
|
2025-11-26 09:58:57 +00:00
|
|
|
|
2025-11-26 11:21:37 +00:00
|
|
|
if (!daySignState.hasSigned || (dayIndex == mCurDayIndexDailySign && !daySignState.hasWatchedAd)) {
|
2025-11-26 10:39:20 +00:00
|
|
|
val dayReward = getDailyCheckInTask()?.reward_details?.get(dayIndex)?.value ?: 0
|
|
|
|
|
daySignState.hasRewardedNum += if (isDoubleReward) 2*dayReward else dayReward
|
2025-11-26 09:58:57 +00:00
|
|
|
daySignState.hasSigned = true
|
2025-11-26 10:39:20 +00:00
|
|
|
daySignState.hasWatchedAd = isByAd
|
2025-11-26 07:31:34 +00:00
|
|
|
saveDailySignInfo()
|
2025-11-27 03:57:56 +00:00
|
|
|
notifySignStateChanged(Pair(dayIndex, daySignState))
|
2025-11-26 07:31:34 +00:00
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-27 03:57:56 +00:00
|
|
|
private fun notifySignStateChanged(dataPair: Pair<Int, DailySignDayInfoBean>) {
|
|
|
|
|
NotifyMan.instance().sendEvent(VididinEvents.Event_Sign_State_Changed, NotifyMan.NotifyData(dataPair))
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-26 07:31:34 +00:00
|
|
|
private fun saveDailySignInfo() {
|
|
|
|
|
SpUtil.instance().putObject(SpUtil.KEY_DAILY_SIGN, mDailySignData)
|
|
|
|
|
}
|
2025-11-26 03:52:09 +00:00
|
|
|
|
2025-11-26 09:06:12 +00:00
|
|
|
private fun generateTestDailySignTestBean() {
|
|
|
|
|
mDailySignData = DailySignBean().apply {
|
2025-11-26 09:58:57 +00:00
|
|
|
startMs = DateUtil.getCurTimeMs() - 4 * DateUtil.MS_NUM_ONE_DAY
|
2025-11-26 09:06:12 +00:00
|
|
|
signStateList.clear()
|
2025-11-26 09:58:57 +00:00
|
|
|
signStateList.add(DailySignDayInfoBean(hasSigned = true, hasWatchedAd = true))
|
|
|
|
|
signStateList.add(DailySignDayInfoBean(hasSigned = false, hasWatchedAd = false))
|
|
|
|
|
signStateList.add(DailySignDayInfoBean(hasSigned = true, hasWatchedAd = false))
|
|
|
|
|
signStateList.add(DailySignDayInfoBean(hasSigned = false, hasWatchedAd = false))
|
|
|
|
|
signStateList.add(DailySignDayInfoBean(hasSigned = false, hasWatchedAd = false))
|
|
|
|
|
signStateList.add(DailySignDayInfoBean(hasSigned = false, hasWatchedAd = false))
|
|
|
|
|
signStateList.add(DailySignDayInfoBean(hasSigned = false, hasWatchedAd = false))
|
2025-11-26 09:06:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SpUtil.instance().putObject(SpUtil.KEY_TASK_BEAN, mDailySignData)
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-26 09:58:57 +00:00
|
|
|
fun getForgotSignDays(): Int {
|
|
|
|
|
var forgotSignDays = 0
|
2025-11-26 10:39:20 +00:00
|
|
|
val curDayIndex = getCurDayIndexOfDailyCheckIn()
|
|
|
|
|
mDailySignData.signStateList.forEachIndexed { index, item->
|
|
|
|
|
if (!item.hasSigned && index < curDayIndex) {
|
2025-11-26 09:58:57 +00:00
|
|
|
forgotSignDays++
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return forgotSignDays
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-26 11:21:37 +00:00
|
|
|
fun getSignDaysTotal(): Int {
|
|
|
|
|
var signDays = 0
|
|
|
|
|
mDailySignData.signStateList.forEachIndexed { index, item->
|
|
|
|
|
if (item.hasSigned) {
|
|
|
|
|
signDays++
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return signDays
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-26 10:39:20 +00:00
|
|
|
fun getForgotSignFirstDayIndex(): Int {
|
|
|
|
|
val curDayIndex = getCurDayIndexOfDailyCheckIn()
|
|
|
|
|
mDailySignData.signStateList.forEachIndexed { index, item->
|
|
|
|
|
if (!item.hasSigned && index < curDayIndex) {
|
|
|
|
|
return index
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-27 03:06:31 +00:00
|
|
|
|
|
|
|
|
fun getDayStateList(): List<DailySignDayInfoBean> {
|
|
|
|
|
return mDailySignData.signStateList
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fun getRewardNumOfDailySign(dayIndex: Int) : Int {
|
|
|
|
|
return getDailyCheckInTask()?.reward_details?.get(dayIndex)?.value ?: 0
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-27 06:19:20 +00:00
|
|
|
fun isDailySignAllOperationDone(): Boolean {
|
|
|
|
|
val curDayState = getDailySignStateBean(mCurDayIndexDailySign)
|
|
|
|
|
return curDayState.hasSigned && curDayState.hasWatchedAd && getForgotSignFirstDayIndex() <= 0
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-27 03:06:31 +00:00
|
|
|
|
2025-11-20 09:45:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|