hxp
2025-10-20 7060867c004c3312f409a320623b40b42186f9af
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerActivity.py
@@ -2,974 +2,194 @@
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
#-------------------------------------------------------------------------------
#
##@package Player.PlayerActivity
#
# @todo:玩家每日活跃度
# @author xdh
# @date 2014-07-14
# @todo:日常活跃任务
# @author hxp
# @date 2025-10-16
# @version 1.0
#
# 详细描述: 玩家每日活跃度、每日活动
#---------------------------------------------------------------------
#"""Version = 2017-02-25 11:30"""
#---------------------------------------------------------------------
# 详细描述: 日常活跃任务
#
#-------------------------------------------------------------------------------
#"""Version = 2025-10-16 19:30"""
#-------------------------------------------------------------------------------
import ChConfig
import ChPyNetSendPack
import NetPackCommon
import ShareDefine
import GameWorld
import ItemCommon
import IPY_GameWorld
import NetPackCommon
import PlayerControl
import ChPyNetSendPack
import PlayerZhanling
import ItemControler
import IpyGameDataPY
import PyGameData
import GameFuncComm
import PlayerPet
import datetime
import time
import FormulaControl
import PlayerBossReborn
import PlayerTongTianLing
import PlayerActTask
import PlayerSuccess
import GameWorld
import DBDataMgr
import ObjPool
#关联类型
(
RelatedType_1,  # 1关联日常活动表
RelatedType_2,  # 2关联副本总表
) = range(1, 3)
def OnWeek(curPlayer, onWeekType):
    actionIDInfo = []
def OnDay(curPlayer):
    CheckResetWeekActivity(curPlayer)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActivityTotal, 0)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActivityAward, 0)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DailyTaskState, 0)
    syncTaskCondList = []
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for i in xrange(ipyDataMgr.GetDailyActionCount()):
        ipyData = ipyDataMgr.GetDailyActionByIndex(i)
        weekTimesLimit = ipyData.GetWeekTimes()
        if not weekTimesLimit:
    for index in range(ipyDataMgr.GetDailyTaskCount()):
        ipyData = ipyDataMgr.GetDailyTaskByIndex(index)
        taskType = ipyData.GetTaskType()
        conds = ipyData.GetTaskConds()
        tcList = [taskType, conds]
        if tcList in syncTaskCondList:
            continue
        # 重置类型不同的不处理
        if ipyData.GetWeekResetType() != onWeekType:
        if not GetDailyTaskValue(curPlayer, taskType, conds):
            continue
        key = ChConfig.Def_PDict_DailyActionWeekTimes % ipyData.GetDailyID()
        __SetPDictValue(curPlayer, key, 0)
        actionIDInfo.append(ipyData.GetDailyID())
    if actionIDInfo:
        SyncDailyActionInfo(curPlayer, actionIDInfo)
        SetDailyTaskValue(curPlayer, taskType, conds, 0)
        syncTaskCondList.append(tcList)
    SyncDailyTaskInfo(curPlayer, isAll=True)
    return
## OnDay
#  @param curPlayer 玩家实例
#  @return
def OnDay(curPlayer, onEventType):
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    if onEventType == ShareDefine.Def_OnEventTypeEx:
        # 重置完成次数
        for i in xrange(ipyDataMgr.GetDailyQuestCount()):
            ipyData = ipyDataMgr.GetDailyQuestByIndex(i)
            key = ChConfig.Def_PDict_Activity_FinishCnt % ipyData.GetID()
            curPBCnt = __GetPDictValue(curPlayer, key)  #单次进度值
            if curPBCnt:
                __SetPDictValue(curPlayer, key, 0)
            key = ChConfig.Def_PDict_Activity_AddTotal % ipyData.GetID()
            if __GetPDictValue(curPlayer, key):
                __SetPDictValue(curPlayer, key, 0)
        #总活跃度重置
        __SetPDictValue(curPlayer, ChConfig.Def_PDict_Activity_TotalPoint, 0)
        # 重置领奖记录
        __SetPDictValue(curPlayer, ChConfig.Def_PDict_ActivityAwardRecord, 0)
        #重置额外获得修行点数
        __SetPDictValue(curPlayer, ChConfig.Def_PDict_Activity_ExtraRealmPoint, 0)
        #重新计算奖励阶段
        __CalcAwardStage(curPlayer)
        SyncDailyActivityInfo(curPlayer)
        # 记录昨日活跃吸纳经验
        todayExp = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActivityPlaceTodayExp)
        todayExpPoint = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActivityPlaceTodayExpPoint)
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActivityPlaceTodayExp, 0)
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActivityPlaceTodayExpPoint, 0)
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActivityPlaceYestorDayExp, todayExp)
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActivityPlaceYestorDayExpPoint, todayExpPoint)
        #活跃放置
        Sync_ActivityPlaceInfo(curPlayer)
    #else:
    #    SendDayActionMail(curPlayer)
    #日常活动重置
    actionIDInfo = []
    for i in xrange(ipyDataMgr.GetDailyActionCount()):
        ipyData = ipyDataMgr.GetDailyActionByIndex(i)
        dayTimesLimit = GetMaxDayTimes(ipyData)  #ipyData.GetDayTimes()
        if not dayTimesLimit:
            continue
        # 重置类型不同的不处理
        if ipyData.GetDayResetType() != onEventType:
            continue
        dailyID = ipyData.GetDailyID()
        __SetPDictValue(curPlayer, ChConfig.Def_PDict_DailyActionDayTimes % dailyID, 0)
        __SetPDictValue(curPlayer, ChConfig.Def_PDict_DailyActionDayBuyTimes % dailyID, 0)
        __SetPDictValue(curPlayer, ChConfig.Def_PDict_DailyActionDayItemTimes % dailyID, 0)
        actionIDInfo.append(ipyData.GetDailyID())
    if actionIDInfo:
        SyncDailyActionInfo(curPlayer, actionIDInfo)
def OnPlayerLogin(curPlayer):
    CheckResetWeekActivity(curPlayer)
    SyncDailyTaskInfo(curPlayer, isAll=True)
    return
def SendDayActionMail(curPlayer):
    ##发送每日活动邮件
    #if curPlayer.GetLV() >= IpyGameDataPY.GetFuncCfg('DailyQuestMailLvLimit'):
    #    PlayerControl.SendMailByKey('TodayDailyTask', [curPlayer.GetID()], [])
def CheckResetWeekActivity(curPlayer):
    ## 检查重置每周活跃奖励战令
    playerActivityWeek = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActivityWeek)
    serverDay = DBDataMgr.GetEventTrigMgr().GetValue(ShareDefine.Def_ServerDay) + 1
    nowActivityWeek = (serverDay - 1) / 7 # 暂定7天一轮,按开服天算
    GameWorld.DebugLog("检查重置周活跃奖励战令! serverDay=%s,nowActivityWeek=%s,playerActivityWeek=%s"
                       % (serverDay, nowActivityWeek, playerActivityWeek), curPlayer.GetPlayerID())
    if nowActivityWeek and playerActivityWeek != nowActivityWeek:
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActivityWeek, nowActivityWeek)
        PlayerZhanling.ResetZhanling(curPlayer, PlayerZhanling.ZhanlingType_WeekActivity)
    return
def AddDailyTaskValue(curPlayer, taskType, addValue=1, conds=[]):
    ## 增加任务进度
    ipyDataList = IpyGameDataPY.GetIpyGameDataListNotLog("DailyTask", taskType)
    if not ipyDataList:
        return
    maxValue = 0
    for ipyData in ipyDataList:
        taskConds = ipyData.GetTaskConds()
        if conds or taskConds:
            # 可按任务类型扩展不同的条件验证方式
            if taskConds != conds:
                continue
        needValue = ipyData.GetNeedValue()
        maxValue = max(maxValue, needValue)
    curValue = GetDailyTaskValue(curPlayer, taskType, conds)
    if curValue >= maxValue:
        return
    updValue = min(curValue + addValue, maxValue)
    SetDailyTaskValue(curPlayer, taskType, conds, updValue)
    SyncDailyTaskInfo(curPlayer, taskType, conds)
    return
#重新计算奖励阶段
def __CalcAwardStage(curPlayer):
    realmLV = curPlayer.GetOfficialRank()
    ipyData = IpyGameDataPY.IPY_Data().GetDailyLivenessRewardByIndex(0)
def GetDailyTaskValue(curPlayer, taskType, conds=[]):
    ##获取完成度
    condition = "" if not conds else str(conds).replace(" ", "")[1:-1]
    return curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DailyTaskValue % (taskType, condition))
def SetDailyTaskValue(curPlayer, taskType, conds, value):
    ##设置完成度
    condition = "" if not conds else str(conds).replace(" ", "")[1:-1]
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DailyTaskValue % (taskType, condition), value)
    GameWorld.DebugLog("更新每日任务进度值: taskType=%s,conds=%s,value=%s" % (taskType, condition, value), curPlayer.GetPlayerID())
    return
def GetDailyTaskAward(curPlayer, taskID):
    playerID = curPlayer.GetPlayerID()
    ipyData = IpyGameDataPY.GetIpyGameDataByCondition("DailyTask", {"TaskID":taskID})
    if not ipyData:
        return
    stageLVList = ipyData.GetStageLV()
    curStage = 0
    for i, lv in enumerate(stageLVList):
        if realmLV < lv:
            break
        if realmLV >= lv:
            curStage = i
    __SetPDictValue(curPlayer, ChConfig.Def_PDict_Activity_AwardStage, curStage)
    GameWorld.DebugLog('    重新计算活跃奖励阶段 curStage=%s,realmLV=%s' % (curStage, realmLV))
    return
## OnLogin
#  @param curPlayer 玩家实例
#  @return
def OnLogin(curPlayer):
    # 同步完成度及领奖记录
    SyncDailyActivityInfo(curPlayer)
    #同步日常活动次数
    SyncDailyActionInfo(curPlayer)
    #活跃放置
    Sync_ActivityPlaceInfo(curPlayer)
    return
## 获取活跃度玩家数据库字典信息值
#  @param curPlayer 玩家实例
#  @param key 字典key
#  @param defaultValue 默认值
#  @return
def __GetPDictValue(curPlayer, key, defaultValue=0):
    return curPlayer.NomalDictGetProperty(key, defaultValue)
## 设置活跃度玩家数据库字典信息值
#  @param curPlayer 玩家实例
#  @param key 字典key
#  @param value 设置的值
#  @return
def __SetPDictValue(curPlayer, key, value):
    PlayerControl.NomalDictSetProperty(curPlayer, key, value)
    return
## 扣除货币获得活跃度
#  @param curPlayer 玩家实例
#  @param type_Price
#  @param price
#  @return
def OnPayMoneyActivity(curPlayer, type_Price, price):
    #金子支付
#    if type_Price == IPY_GameWorld.TYPE_Price_Gold_Money:
#        AddActivityFinishCnt(curPlayer, ShareDefine.ActivityNum_UseGoldCnt)
#    #金票支付
#    elif type_Price == IPY_GameWorld.TYPE_Price_Gold_Paper:
#        AddActivityFinishCnt(curPlayer, ShareDefine.ActivityNum_UseGoldPaperCnt)
    return
## 摸NPC获得活跃度
#  @param atkObj
#  @param curNPC
#  @return
def OnAttackNPCActivity(atkObj, curNPC):
    atkObjType = atkObj.GetGameObjType()
    
    # 不是玩家暂不处理
    if atkObjType != IPY_GameWorld.gotPlayer:
        return
    # 击杀boss
#    if curNPC.GetIsBoss():
#        canAddBossIDList = ReadChConfig.GetEvalChConfig("Activity_BossID")
#
#        if curNPC.GetNPCID() in canAddBossIDList:
#            AddActivityFinishCnt(atkObj, ShareDefine.ActivityNum_KillBoss)
    return
## 增加完成活跃度次数
#  @param curPlayer 玩家实例
#  @param activityNum 活跃度编号
#  @param finishCnt 已完成次数
#  @param addCnt 增加次数,默认1
#  @return
def AddActivityFinishCnt(curPlayer, activityNum, finishCnt, addCnt):
    dailyQuestData = IpyGameDataPY.GetIpyGameDataNotLog('DailyQuest', activityNum)
    if not dailyQuestData:
    taskState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DailyTaskState)
    if taskState&pow(2, taskID):
        GameWorld.DebugLog("每日任务已经领取过奖励! taskID=%s,taskState=%s" % (taskID, taskState), playerID)
        return
    
    maxActiveValue = dailyQuestData.GetTotalActiveValue()
    onceActivity = dailyQuestData.GetOnceActivity()
    onceActivityTime = dailyQuestData.GetOnceActivityTime()
    if not onceActivity:
        return
    curAddTotal = None
    if maxActiveValue:
        if dailyQuestData.GetRelatedType() == RelatedType_1 and dailyQuestData.GetRelatedID() in [ShareDefine.DailyActionID_CrossBattlefield]:
            curAddTotal = __GetPDictValue(curPlayer, ChConfig.Def_PDict_Activity_AddTotal % activityNum)  #单次进度值
            if curAddTotal >= maxActiveValue:
                GameWorld.DebugLog("活跃度可完成次数已达到上限,activityNum=%s,curAddTotal=%s >= %s" % (activityNum, curAddTotal, maxActiveValue))
                return
        else:
            if finishCnt > maxActiveValue / onceActivity * onceActivityTime:
                #GameWorld.DebugLog("活跃度可完成次数已达到上限,activityNum=%s" % (activityNum))
                return
    key = ChConfig.Def_PDict_Activity_FinishCnt % activityNum
    curPBCnt = __GetPDictValue(curPlayer, key)  #单次进度值
    addValue = (addCnt + curPBCnt) / onceActivityTime * onceActivity  #增加的活跃度
    addPbCnt = (addCnt + curPBCnt) % onceActivityTime
    __SetPDictValue(curPlayer, key, addPbCnt)
    if curAddTotal != None:
        curAddTotal += addValue
        __SetPDictValue(curPlayer, ChConfig.Def_PDict_Activity_AddTotal % activityNum, curAddTotal)
    #
    DoAddActivity(curPlayer, addValue, True)
    return
def DoAddActivityByLV(curPlayer, befLV, aftLV):
    ##升级增加活跃点
    perLVAddPoint = IpyGameDataPY.GetFuncCfg('ImmortalDomainActivePoint', 3)
    skillTypeID, perAddLV, addPoint, maxPoint = IpyGameDataPY.GetFuncEvalCfg('ImmortalDomainActivePoint', 4)
    learnSkillList, passiveSkillList = PlayerPet.GetPetLearnSkill(curPlayer)
    addValue = (aftLV-befLV)*perLVAddPoint
    if skillTypeID in passiveSkillList:
        for lv in xrange(befLV+1, aftLV+1):
            addValue += min(((lv-1)/perAddLV+1) * addPoint, maxPoint)
    DoAddActivity(curPlayer, addValue, False, True)
    return
def AddActivityByLVOnLearnSkill(curPlayer, skillID):
    ## 获得技能时,处理增加升级获得活跃点效果
    skillTypeID, perAddLV, addPoint, maxPoint = IpyGameDataPY.GetFuncEvalCfg('ImmortalDomainActivePoint', 4)
    if skillID != skillTypeID:
        return
    curLV = curPlayer.GetLV()
    addValue = 0
    for lv in xrange(2, curLV+1):
        addValue += min(((lv-1)/perAddLV+1) * addPoint, maxPoint)
    DoAddActivity(curPlayer, addValue, False, True)
    return
def DoAddActivity(curPlayer, addValue, isMultiple=False, isLVUp=False):
    if not addValue:
        return
    multiple = 1
    addExtraPoint = 0
    if isMultiple:
        multiple, extraPointLimit = __GetActionAddPer(curPlayer)
        curExtraPoint = __GetPDictValue(curPlayer, ChConfig.Def_PDict_Activity_ExtraRealmPoint)
        addExtraPoint = max(0, min(addValue * (multiple - 1),
                                   extraPointLimit - curExtraPoint)) if extraPointLimit else addValue * (multiple - 1)
        __SetPDictValue(curPlayer, ChConfig.Def_PDict_Activity_ExtraRealmPoint, curExtraPoint + addExtraPoint)
        addValue = addValue + addExtraPoint
    curTotalPoint = __GetPDictValue(curPlayer, ChConfig.Def_PDict_Activity_TotalPoint)
    __SetPDictValue(curPlayer, ChConfig.Def_PDict_Activity_TotalPoint, curTotalPoint + addValue)
    __AddCanCostActivityPoint(curPlayer, addValue, isLVUp)
    PlayerTongTianLing.AddTongTianTaskValue(curPlayer, ChConfig.TTLTaskType_Activity, addValue)
    PlayerActTask.AddActTaskValue(curPlayer, ChConfig.ActTaskType_Activity, addValue)
    #PlayerControl.NotifyCode(curPlayer, "GetActivity", [addValue])
    SyncDailyActivityInfo(curPlayer)
    GameWorld.DebugLog("增加活跃度,addValue=%s,multiple=%s,addExtraPoint=%s,isLVUp=%s"
                       % (addValue, multiple, addExtraPoint, isLVUp), curPlayer.GetPlayerID())
    return
def __GetActionAddPer(curPlayer):
    multiple, extraPointLimit = 1, 0  #倍数、额外可获得修行点上限
    actRealmPointInfo = PyGameData.g_operationActionDict.get(ShareDefine.OperationActionName_RealmPoint, {})  # 多倍修行点活动
    if not actRealmPointInfo:
        return multiple, extraPointLimit
    if not actRealmPointInfo.get(ShareDefine.ActKey_State):
        return multiple, extraPointLimit
    actRealmPointIpyData = IpyGameDataPY.GetIpyGameData("ActRealmPoint", actRealmPointInfo.get(ShareDefine.ActKey_CfgID, 0))
    if not actRealmPointIpyData:
        return multiple, extraPointLimit
    if curPlayer.GetLV() < actRealmPointIpyData.GetLVLimit():
        return multiple, extraPointLimit
    return actRealmPointIpyData.GetMultiple(), actRealmPointIpyData.GetPointLimit()
def __AddCanCostActivityPoint(curPlayer, addValue, isLVUp):
    # 增加可消耗的活跃点
    curPoint = __GetPDictValue(curPlayer, ChConfig.Def_PDict_ActivityCanCostTotalPoint)
    if isLVUp:
        updPoint = min(ChConfig.Def_UpperLimit_DWord, curPoint + addValue)
    else:
        maxPoint = IpyGameDataPY.GetFuncCfg('ActivityPlace', 1)
        if maxPoint and curPoint >= maxPoint:
            GameWorld.DebugLog("可消耗的活跃点超出上限,不增加! curPoint=%s,maxPoint=%s" % (curPoint, maxPoint))
            return
        updPoint = curPoint + addValue
    __SetPDictValue(curPlayer, ChConfig.Def_PDict_ActivityCanCostTotalPoint, updPoint)
    return
def CostActivityPoint(curPlayer, costPoint, isOnlyCheck=False):
    # 消耗活跃点
    curPoint = __GetPDictValue(curPlayer, ChConfig.Def_PDict_ActivityCanCostTotalPoint)
    if curPoint < costPoint:
        return
    if not isOnlyCheck:
        __SetPDictValue(curPlayer, ChConfig.Def_PDict_ActivityCanCostTotalPoint,
                        curPoint - costPoint)
        SyncDailyActivityInfo(curPlayer)
    return True
## 同步活跃度信息
#  @param curPlayer
#  @param syncNum 默认-1时全部同步
#  @return None
def SyncDailyActivityInfo(curPlayer):
    sendPack = ChPyNetSendPack.tagMCDailyActivityInfoList()
    sendPack.Clear()
    sendPack.CurValue = __GetPDictValue(curPlayer, ChConfig.Def_PDict_Activity_TotalPoint)
    sendPack.StageIndex = __GetPDictValue(curPlayer, ChConfig.Def_PDict_Activity_AwardStage)
    sendPack.AwardRecord = __GetPDictValue(curPlayer, ChConfig.Def_PDict_ActivityAwardRecord)
    sendPack.RealmPoint = __GetPDictValue(curPlayer, ChConfig.Def_PDict_ActivityCanCostTotalPoint)
    sendPack.ExtraPoint = __GetPDictValue(curPlayer, ChConfig.Def_PDict_Activity_ExtraRealmPoint)
    NetPackCommon.SendFakePack(curPlayer, sendPack)
    return
## 领取活跃度奖励
#  @param curPlayer
#  @param awardIndex
#  @return None
def GetActivityAward(curPlayer, awardIndex):
    rewardCount = IpyGameDataPY.IPY_Data().GetDailyLivenessRewardCount()
    if awardIndex < 0 or awardIndex >= rewardCount:
        GameWorld.ErrLog("活跃度奖励索引不合法,index=%s,Len=%s" % (awardIndex, rewardCount))
    taskType = ipyData.GetTaskType()
    conds = ipyData.GetTaskConds()
    needValue = ipyData.GetNeedValue()
    curValue = GetDailyTaskValue(curPlayer, taskType, conds)
    if curValue < needValue:
        GameWorld.DebugLog("每日任务进度不足,无法领奖! taskID=%s,taskType=%s,conds=%s,curValue=%s < %s" % (taskID, taskType, conds, curValue, needValue), playerID)
        return
    
    # 判断是否已领取
    getAwardRecord = __GetPDictValue(curPlayer, ChConfig.Def_PDict_ActivityAwardRecord)
    if getAwardRecord & pow(2, awardIndex):
        GameWorld.Log("已经领取过该活跃度奖励,index=%s" % (awardIndex))
    updState = taskState|pow(2, taskID)
    GameWorld.DebugLog("每日任务领奖! taskID=%s,updState=%s" % (taskID, updState), playerID)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DailyTaskState, updState)
    DoAddActivity(curPlayer, ipyData.GetAwardLiveness())
    return
def DoAddActivity(curPlayer, addValue):
    ## 增加活跃值
    updValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActivityTotal) + addValue
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActivityTotal, updValue)
    SyncDailyTaskInfo(curPlayer)
    GameWorld.DebugLog("增加活跃度: addValue=%s,updValue=%s" % (addValue, updValue), curPlayer.GetPlayerID())
    PlayerZhanling.AddZhanlingValue(curPlayer, PlayerZhanling.ZhanlingType_WeekActivity, addValue)
    return updValue
def GetActivityAward(curPlayer, awardID):
    ## 领取活跃度奖励
    playerID = curPlayer.GetPlayerID()
    ipyData = IpyGameDataPY.GetIpyGameData("DailyLivenessReward", awardID)
    if not ipyData:
        return
    
    ipyData = IpyGameDataPY.IPY_Data().GetDailyLivenessRewardByIndex(awardIndex)
    needActivity = ipyData.GetLiveness()
    totalActivity = __GetPDictValue(curPlayer, ChConfig.Def_PDict_Activity_TotalPoint)
    awardState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActivityAward)
    if awardState&pow(2, awardID):
        GameWorld.DebugLog("活跃奖励ID已领取! awardID=%s,awardState=%s" % (awardID, awardState), playerID)
        return
    needActivity = ipyData.GetNeedLiveness()
    activityTotal = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActivityTotal)
    # 判断活跃度
    if totalActivity < needActivity:
        GameWorld.Log("领奖活跃度不足,index=%s,needActivity=%s,totalActivity=%s"
                      % (awardIndex, needActivity, totalActivity))
    if activityTotal < needActivity:
        GameWorld.DebugLog("领奖活跃度不足! awardID=%s,activityTotal=%s < %s" % (awardID, activityTotal, needActivity), playerID)
        return
    
    awardStage = __GetPDictValue(curPlayer, ChConfig.Def_PDict_Activity_AwardStage)
    itemIDList = ipyData.GetItemID()
    itemCntList = ipyData.GetItemCount()
    itemIsBindList = ipyData.GetItemBind()
    if awardStage >= len(itemIDList) or awardStage >= len(itemCntList) or awardStage >= len(itemIsBindList):
        return
    itemID = itemIDList[awardStage]
    itemCnt = itemCntList[awardStage]
    isBind = itemIsBindList[awardStage]
    # 检查背包
    packSpace = ItemCommon.GetItemPackSpace(curPlayer, IPY_GameWorld.rptItem)
    if 1 > packSpace:
        PlayerControl.NotifyCode(curPlayer, "GeRen_chenxin_998371")
        return
    # 给物品
    ItemControler.GivePlayerItem(curPlayer, itemID, itemCnt, 0, [IPY_GameWorld.rptItem])
    # 更新已领取成功标记
    updAwardRecord = getAwardRecord | (1 << awardIndex)
    __SetPDictValue(curPlayer, ChConfig.Def_PDict_ActivityAwardRecord, updAwardRecord)
    SyncDailyActivityInfo(curPlayer)
    GameWorld.DebugLog("领取活跃度奖励OK!awardStage=%s, index=%s,needActivity=%s,totalActivity=%s,awardRecord=%s"
                       % (awardStage, awardIndex, needActivity, totalActivity, updAwardRecord))
    awardItemList = ipyData.GetAwardItemList()
    updState = awardState|pow(2, awardID)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActivityAward, updState)
    GameWorld.DebugLog("领奖活跃度! awardID=%s,updState=%s,awardItemList=%s" % (awardID, updState, awardItemList), playerID)
    ItemControler.GivePlayerItemOrMail(curPlayer, awardItemList, event=["ActivityAward", False, {}])
    SyncDailyTaskInfo(curPlayer)
    return
def GetActivityNum(relatedType, relatedID):
    ## 获取日常任务ID(活跃ID)
    ipyData = IpyGameDataPY.GetIpyGameDataByCondition('DailyQuest', {"RelatedID":relatedID, "RelatedType":relatedType}, False, False)
    if not ipyData:
        return 0
    return ipyData.GetID()
#########################################日常活动###########################################
def GetDailyActionOpenEndTime(dailyID):
    ## 获取日常活动开启结束时间点
    ipyData = IpyGameDataPY.GetIpyGameData('DailyAction', dailyID)
    if not ipyData:
        return
    openTimeDict = ipyData.GetOpenTimeDict()
    duration = ipyData.GetDuration()
    if not openTimeDict or not duration:
        return
    allOpenTimeList = openTimeDict.values()
    if not allOpenTimeList:
        return
    openTimeList = allOpenTimeList[0] # 这边默认为每日的开启时间段一样,直接取第一日
    if len(openTimeList) == 1:
        openHour, openMinute = openTimeList[0]
    else:
        #openHour, openMinute =
        # 每天多个时间段的再说,暂时没用到
        return
    curDateTime = GameWorld.GetCurrentTime()
    openTimeStr = "%d-%d-%d %02d:%02d:00" % (curDateTime.year, curDateTime.month, curDateTime.day, openHour, openMinute)
    openDateTime = datetime.datetime.strptime(openTimeStr, ChConfig.TYPE_Time_Format)
    endDateTime = openDateTime + datetime.timedelta(minutes=duration)
    return openDateTime, endDateTime
def GetDailyActionRemainSeconds(dailyID):
    ## 获取日常活动当前剩余秒数
    openEndTimeInfo = GetDailyActionOpenEndTime(dailyID)
    if not openEndTimeInfo:
        return 0
    openDateTime, endDateTime = openEndTimeInfo
    curDateTime = GameWorld.GetCurrentTime()
    if curDateTime < openDateTime or curDateTime >= endDateTime:
        return 0
    remainDateTime = endDateTime - curDateTime
    return remainDateTime.seconds
def AddDailyActionFinishCnt(curPlayer, dailyID, addCnt=1):
    ##增加日常活动完成次数
    ipyData = IpyGameDataPY.GetIpyGameData('DailyAction', dailyID)
    if not ipyData:
        return
    # 由GameServer决定
    # 目前跨服PK暂不需要判断,因为跨服PK次数结算在本服,玩家可能上次未结算离线,等非匹配期间上线,也需要加上,所以暂不判断
    if dailyID not in [ShareDefine.DailyActionID_CrossReamPK, ShareDefine.DailyActionID_CrossBattlefield]:
        if not GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_DailyActionState % dailyID):
            GameWorld.DebugLog("日常活动未开启!dailyID=%s" % dailyID)
            return
    dayTimesLimit = GetMaxDayTimes(ipyData)  #ipyData.GetDayTimes()
    weekTimesLimit = ipyData.GetWeekTimes()
    if not dayTimesLimit and not weekTimesLimit:
        return
    #对应的日常任务表ID
    activityNum = GetActivityNum(RelatedType_1, dailyID)
    dailyQuestData = IpyGameDataPY.GetIpyGameDataNotLog('DailyQuest', activityNum)
    unLimitCnt = dailyQuestData and not dailyQuestData.GetTotalActiveValue()
    funcID = dailyQuestData.GetUnLockFuncID() if dailyQuestData else 0
    #封魔坛活跃不判断功能开启 特殊处理
    if funcID and dailyID != ShareDefine.DailyActionID_SealDemon and not GameFuncComm.GetFuncCanUse(curPlayer, funcID) :
        return
def SyncDailyTaskInfo(curPlayer, taskType=0, conds=[], isAll=False):
    clientPack = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagSCDailyTaskInfo)
    clientPack.ActivityTotal = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActivityTotal)
    clientPack.ActivityAward = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActivityAward)
    clientPack.DailyTaskState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DailyTaskState)
    syncTaskCondList = []
    if isAll:
        ipyDataMgr = IpyGameDataPY.IPY_Data()
        for index in range(ipyDataMgr.GetDailyTaskCount()):
            ipyData = ipyDataMgr.GetDailyTaskByIndex(index)
            taskType = ipyData.GetTaskType()
            conds = ipyData.GetTaskConds()
            tcList = [taskType, conds]
            if tcList in syncTaskCondList:
                continue
            syncTaskCondList.append(tcList)
    elif taskType:
        syncTaskCondList = [[taskType, conds]]
        
    updDayTimes = 0
    if dayTimesLimit:
        key = ChConfig.Def_PDict_DailyActionDayTimes % dailyID
        curDayTimes = curPlayer.NomalDictGetProperty(key)
        curDayBuyTimes = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DailyActionDayBuyTimes % dailyID)
        curDayItemTimes = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DailyActionDayItemTimes % dailyID)
        if not unLimitCnt and curDayTimes >= dayTimesLimit + curDayBuyTimes + curDayItemTimes:
            return
        updDayTimes = curDayTimes + addCnt if unLimitCnt else min(dayTimesLimit + curDayBuyTimes + curDayItemTimes, curDayTimes + addCnt)
        addCnt = updDayTimes - curDayTimes
        PlayerControl.NomalDictSetProperty(curPlayer, key, updDayTimes)
        GameWorld.DebugLog('增加日常活动完成次数 dailyID=%s, curDayTimes=%s, updDayTimes=%s' % (dailyID, curDayTimes, updDayTimes))
    updWeekTimes = 0
    if weekTimesLimit:
        key = ChConfig.Def_PDict_DailyActionWeekTimes % dailyID
        curWeekTimes = curPlayer.NomalDictGetProperty(key)
        if not unLimitCnt and curWeekTimes >= weekTimesLimit:
            return
        updWeekTimes = curWeekTimes + addCnt if unLimitCnt else min(weekTimesLimit, curWeekTimes + addCnt)
        addCnt = updWeekTimes - curWeekTimes
        PlayerControl.NomalDictSetProperty(curPlayer, key, updWeekTimes)
        GameWorld.DebugLog('增加日常活动完成次数 dailyID=%s, curWeekTimes=%s, updWeekTimes=%s' % (dailyID, curWeekTimes, updWeekTimes))
    SyncDailyActionInfo(curPlayer, [dailyID])
    #对应的日常任务表ID
    updTimes = updDayTimes or updWeekTimes
    if addCnt and updTimes and dailyQuestData:
        AddActivityFinishCnt(curPlayer, activityNum, updTimes, addCnt)
    return True
def GetDailyActionFinishCnt(curPlayer, dailyID):
    key = ChConfig.Def_PDict_DailyActionDayTimes % dailyID
    curDayTimes = __GetPDictValue(curPlayer, key)
    ipyData = IpyGameDataPY.GetIpyGameData('DailyAction', dailyID)
    if not ipyData:
        return 0, 0
    dayTimesLimit = GetMaxDayTimes(ipyData)  #ipyData.GetDayTimes()
    return curDayTimes, dayTimesLimit
def GetDailyActionrRemainCnt(curPlayer, dailyID):
    ##获取活动剩余次数
    curDayTimes = __GetPDictValue(curPlayer, ChConfig.Def_PDict_DailyActionDayTimes % dailyID)
    curDayBuyTimes = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DailyActionDayBuyTimes % dailyID)
    curDayItemTimes = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DailyActionDayItemTimes % dailyID)
    ipyData = IpyGameDataPY.GetIpyGameData('DailyAction', dailyID)
    dayTimesLimit = GetMaxDayTimes(ipyData)
    return max(0, dayTimesLimit+curDayBuyTimes+curDayItemTimes-curDayTimes)
def GetMaxDayTimes(ipyData):
    dayTimesLimit = ipyData.GetDayTimes()
    if ipyData.GetDailyID() == ShareDefine.DailyActionID_TowerSD:
        dayTimesLimit += IpyGameDataPY.GetFuncCfg('RuneTowerSweepBuy')
    return dayTimesLimit
#// A5 25 购买日常活动次数 #tagCMBuyDailyActionCnt
#
#struct    tagCMBuyDailyActionCnt
#{
#    tagHead        Head;
#    DWORD    ActionID;    // ID
#    BYTE    AddType;    // 0-花仙玉 1-用物品
#};
def OnDailyActionBuyCnt(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    dailyID = clientData.ActionID
    addType = clientData.AddType  #0花仙玉 1使用物品
    ipyData = IpyGameDataPY.GetIpyGameData('DailyAction', dailyID)
    if not ipyData:
        return
    curDayTimes = __GetPDictValue(curPlayer, ChConfig.Def_PDict_DailyActionDayTimes % dailyID)
    curDayBuyTimes = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DailyActionDayBuyTimes % dailyID)
    curDayItemTimes = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DailyActionDayItemTimes % dailyID)
    if curDayBuyTimes + curDayItemTimes - curDayTimes >= 0:
        GameWorld.DebugLog('剩余次数已达上限,不可增加!')
        return
    if addType == 0:
        dayBuyTimesLimit = ipyData.GetDayBuyTimes()
        moneyType = ipyData.GetMoneyType()
        buyNeedMoneyList = ipyData.GetBuyNeedMoney()
        if not dayBuyTimesLimit or not buyNeedMoneyList:
            GameWorld.DebugLog("无法购买! dayBuyTimesLimit=%s,buyNeedMoneyList=%s" % (dayBuyTimesLimit, buyNeedMoneyList))
            return
        if curDayBuyTimes >= dayBuyTimesLimit:
            GameWorld.DebugLog('今日购买次数已达上限,不可增加!')
            return
        buyNeedMoney = buyNeedMoneyList[curDayBuyTimes] if len(buyNeedMoneyList) > curDayBuyTimes else buyNeedMoneyList[-1]
        if not PlayerControl.PayMoney(curPlayer, moneyType, buyNeedMoney, ChConfig.Def_Cost_BuyDailyActionCnt, {'dailyID':dailyID, 'curDayBuyTimes':curDayBuyTimes}):
            return
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DailyActionDayBuyTimes % dailyID, curDayBuyTimes + 1)
    elif addType == 1:
        dayItemAddTimesLimit = ipyData.GetDayItemAddTimes()
        dayItemID = ipyData.GetDayItemID()
        if not dayItemAddTimesLimit or not dayItemID:
            return
        if curDayItemTimes >= dayItemAddTimesLimit:
            GameWorld.DebugLog('今日使用物品增加次数已达上限,不可增加!')
            return
        itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
        enough, indexList, hasBind, lackCnt = ItemCommon.GetItem_FromPack_ByID_ExEx(dayItemID, itemPack, 1)
        if not enough:
            return
        ItemCommon.ReduceItem(curPlayer, itemPack, indexList, 1, False, "DailyActionCnt")
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DailyActionDayItemTimes % dailyID, curDayItemTimes + 1)
    else:
        return
    SyncDailyActionInfo(curPlayer, [dailyID])
    clientPack.TaskList = []
    for taskType, conds in syncTaskCondList:
        task = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagSCDailyTask)
        task.TaskType = taskType
        task.Conds = conds
        task.CLen = len(task.Conds)
        task.CurValue = GetDailyTaskValue(curPlayer, taskType, conds)
        clientPack.TaskList.append(task)
    clientPack.TaskCount = len(clientPack.TaskList)
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return
## 同步活跃度信息
#  @param curPlayer
#  @param syncNum 默认-1时全部同步
#  @return None
def SyncDailyActionInfo(curPlayer, syncNumList=[]):
    sendPack = ChPyNetSendPack.tagMCDailyActionCnt()
    sendPack.Clear()
    sendPack.ActionInfo = []
    syncNumList = syncNumList if syncNumList else ShareDefine.DailyActionIDList
    for activityNum in syncNumList:
        activityInfo = ChPyNetSendPack.tagMCDailyActionInfo()
        activityInfo.Clear()
        activityInfo.ActionID = activityNum
        activityInfo.DayFinishCnt = __GetPDictValue(curPlayer, ChConfig.Def_PDict_DailyActionDayTimes % activityNum)
        activityInfo.DayBuyTimes = __GetPDictValue(curPlayer, ChConfig.Def_PDict_DailyActionDayBuyTimes % activityNum)
        activityInfo.DayItemTimes = __GetPDictValue(curPlayer, ChConfig.Def_PDict_DailyActionDayItemTimes % activityNum)
        activityInfo.WeekFinishCnt = __GetPDictValue(curPlayer, ChConfig.Def_PDict_DailyActionWeekTimes % activityNum)
        sendPack.ActionInfo.append(activityInfo)
    sendPack.Count = len(sendPack.ActionInfo)
    NetPackCommon.SendFakePack(curPlayer, sendPack)
    return
##################################副本类增加活跃##########################################
## 参加副本获得活跃度
#  @param curPlayer 玩家实例
#  @param tick
#  @return
def OnEnterFBActivity(curPlayer, mapID, curDayTimes, addCount):
    activityNum = GetActivityNum(RelatedType_2, mapID)
    if activityNum:
        AddActivityFinishCnt(curPlayer, activityNum, curDayTimes, addCount)
    return
################################## 活跃放置 ##############################################
#// B0 29 活跃放置明细查询 #tagCMActivityPlaceQuery
#
#struct    tagCMActivityPlaceQuery
#{
#    tagHead        Head;
#};
def OnActivityPlaceQuery(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    Sync_ActivityPlaceInfo(curPlayer)
    return
#// B0 27 活跃放置启动 #tagCMActivityPlaceStart
#
#struct    tagCMActivityPlaceStart
#{
#    tagHead        Head;
#};
def OnActivityPlaceStart(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    maxRewardCount = IpyGameDataPY.GetFuncCfg("ActivityPlace", 4) # 最大累计放置奖励次数
    remainCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActivityPlaceRemainCount)
    rewardCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActivityPlaceRewardCount)
    maxCanStartCount = maxRewardCount - remainCount - rewardCount
    if maxCanStartCount <= 0:
        GameWorld.DebugLog("活跃放置奖励累计次数已达上限,无法启动!remainCount=%s + rewardCount=%s >= maxRewardCount=%s"
                           % (remainCount, rewardCount, maxRewardCount))
        return
    costPoint = IpyGameDataPY.GetFuncCfg("ActivityPlace", 2) # 单次放置消耗的活跃点数
    canUseActivityPoint = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActivityCanCostTotalPoint)
    pointCanUseCount = canUseActivityPoint / costPoint
    startCount = min(maxCanStartCount, pointCanUseCount)
    if startCount <= 0:
        GameWorld.DebugLog("可用活跃不足,无法添加次数启动!canUseActivityPoint=%s,costPoint=%s" % (canUseActivityPoint, costPoint))
        return
    updRemainCount = remainCount + startCount
    GameWorld.DebugLog("添加活跃放置次数: startCount=%s,rewardCount=%s,remainCount=%s,updRemainCount=%s"
                       % (startCount, rewardCount, remainCount, updRemainCount))
    costPointTotal = costPoint * startCount
    CostActivityPoint(curPlayer, costPointTotal)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActivityPlaceRemainCount, updRemainCount)
    if not remainCount:
        curTime = int(time.time())
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActivityPlaceStartTime, curTime)
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActivityPlaceExpCount, 0)
        GameWorld.DebugLog("    没有剩余次数,更新启动时间: %s" % curTime)
    Sync_ActivityPlaceInfo(curPlayer)
    return
#// B0 28 活跃放置快速完成 #tagCMActivityPlaceQuickFinish
#
#struct    tagCMActivityPlaceQuickFinish
#{
#    tagHead        Head;
#    BYTE        FinishCount;    //完成次数
#};
def OnActivityPlaceQuickFinish(index, clientData, tick):
    ## 经验改为实时获取,暂屏蔽快速完成
    return
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    finishCount = clientData.FinishCount
    remainCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActivityPlaceRemainCount)
    if not remainCount:
        GameWorld.DebugLog("没有剩余活跃放置次数,无法快速完成!")
        return
    finishCount = min(finishCount, remainCount)
    if not finishCount:
        return
    costItemID, costGoldParper = IpyGameDataPY.GetFuncEvalCfg("ActivityPlace", 5)
    costItemCount = finishCount # 每次扣一个
    costItemIndexList, bindCnt, unBindCnt = ItemCommon.GetPackItemBindStateIndexInfo(curPlayer, costItemID, costItemCount)
    lackCnt = costItemCount - bindCnt - unBindCnt
    delItemCount = costItemCount
    if lackCnt > 0:
        costGoldParperTotal = costGoldParper * lackCnt
        if not PlayerControl.PayMoney(curPlayer, IPY_GameWorld.TYPE_Price_Gold_Paper, costGoldParperTotal, ChConfig.Def_Cost_ActivityPlace):
            return
        delItemCount -= lackCnt
    if delItemCount > 0:
        ItemCommon.DelCostItemByBind(curPlayer, costItemIndexList, bindCnt, unBindCnt, delItemCount, ChConfig.ItemDel_ActivityPlace)
    __DoActivityPlaceRewardEnd(curPlayer, finishCount, isQuick=True)
    return
def ProcessActivityPlace(curPlayer):
    ## 活跃放置定时处理
    remainCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActivityPlaceRemainCount)
    if remainCount <= 0:
        #GameWorld.DebugLog("没有剩余放置次数不处理!")
        return
    curTime = int(time.time())
    startTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActivityPlaceStartTime)
    if not startTime:
        startTime = curTime
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActivityPlaceStartTime, curTime)
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActivityPlaceExpCount, 0)
    needSeconds = IpyGameDataPY.GetFuncCfg("ActivityPlace", 3) # 单次放置奖励持续时间,秒
    expSeconds = IpyGameDataPY.GetFuncCfg("ActivityPlaceExp", 1) # 活跃放置获得经验多少秒一次
    passTime = curTime - startTime
    endCount = passTime / needSeconds
    endCount = min(endCount, remainCount)
    expCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActivityPlaceExpCount)
    maxExpCount = needSeconds / expSeconds # 单次放置最多可获得经验次数
    # 由于结算时重置了开启下次的时间及经验次数,所以如果有需要结算,则溢出时间不计,放置多算经验次数
    if endCount >= 1:
        maxExpCount *= endCount
    canGetExpCount = min(maxExpCount, passTime / expSeconds)
    addExpCount = canGetExpCount - expCount
    if addExpCount > 0:
        #GameWorld.DebugLog("活跃放置定时处理 : curTime=%s,startTime=%s,passTime=%s,endCount=%s,expCount=%s,canGetExpCount=%s,maxExpCount=%s,addExpCount=%s"
        #                   % (curTime, startTime, passTime, endCount, expCount, canGetExpCount, maxExpCount, addExpCount))
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActivityPlaceExpCount, expCount + addExpCount)
        lv = curPlayer.GetLV()
        reExp = PlayerControl.GetPlayerReExp(curPlayer)
        expLV, expFormat = 0, ""
        lvFormatList = IpyGameDataPY.GetFuncEvalCfg("ActivityPlaceExp", 2) # [[小于等于等级, "公式"],...]
        for eLV, eFormat in lvFormatList:
            if lv <= eLV:
                expLV, expFormat = eLV, eFormat
                break
        if not expLV:
            expLV, expFormat = lvFormatList[-1]
        addExp = eval(FormulaControl.GetCompileFormula("ActivityPlaceExp_%s" % expLV, expFormat)) * expSeconds * addExpCount
        playerControl = PlayerControl.PlayerControl(curPlayer)
        addExp = playerControl.AddExp(addExp, ShareDefine.Def_ViewExpType_Activity)
        todayExp = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActivityPlaceTodayExp)
        todayExpPoint = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActivityPlaceTodayExpPoint)
        todayTotalExp = todayExpPoint * ChConfig.Def_PerPointValue + todayExp + addExp
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActivityPlaceTodayExp, todayTotalExp % ChConfig.Def_PerPointValue)
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActivityPlaceTodayExpPoint, todayTotalExp / ChConfig.Def_PerPointValue)
        #GameWorld.DebugLog("passTime=%s,canGetExpCount=%s,expCount=%s,addExpCount=%s,addExp=%s,todayTotalExp=%s"
        #                   % (passTime, canGetExpCount, expCount, addExpCount, addExp, todayTotalExp))
    if endCount > 0:
        __DoActivityPlaceRewardEnd(curPlayer, endCount)
    return
def __DoActivityPlaceRewardEnd(curPlayer, endCount, isQuick=False):
    ## 放置活跃奖励结算
    remainCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActivityPlaceRemainCount)
    endCount = min(endCount, remainCount)
    if endCount <= 0:
        return
    countDataDict = {}
    lvDataDict = {}
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for index in xrange(ipyDataMgr.GetActivityPlaceRewardCount()):
        ipyData = ipyDataMgr.GetActivityPlaceRewardByIndex(index)
        placeCount = ipyData.GetPlaceCount()
        placeMaxLV = ipyData.GetPlaceMaxLV()
        if placeCount:
            countDataDict[placeCount] = ipyData
        else:
            lvDataDict[placeMaxLV] = ipyData
    lvRewardIpyData = None
    playerLV = curPlayer.GetLV()
    lvList = sorted(lvDataDict.keys())
    for lv in lvList:
        if playerLV <= lv:
            lvRewardIpyData = lvDataDict[lv]
            break
    if not lvRewardIpyData:
        lvRewardIpyData = lvDataDict[lvList[-1]]
    maxAppointCount = max(countDataDict) # 最大定制奖励次数
    rewardCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActivityPlaceRewardCount)
    rewardTotalCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActivityPlaceRewardTotalCount)
    rewardItemDict = {}
    GameWorld.DebugLog("结算放置活跃奖励: remainCount=%s,rewardCount=%s,endCount=%s,maxAppointCount=%s" % (remainCount, rewardCount, endCount, maxAppointCount))
    for _ in xrange(endCount):
        rewardIpyData = None
        # 加奖励次数
        remainCount -= 1
        rewardCount += 1
        if rewardTotalCount < maxAppointCount:
            rewardTotalCount += 1
            if rewardTotalCount in countDataDict:
                rewardIpyData = countDataDict[rewardTotalCount]
                #GameWorld.DebugLog("    取定制次数奖励: rewardTotalCount=%s" % rewardTotalCount)
        if not rewardIpyData:
            rewardIpyData = lvRewardIpyData
            #GameWorld.DebugLog("    取等级奖励: maxLV=%s" % rewardIpyData.GetPlaceMaxLV())
        # 固定奖励
        for itemID, itemCount in rewardIpyData.GetFixedItemRewardList():
            rewardItemDict[itemID] = rewardItemDict.get(itemID, 0) + itemCount
        # 饼图库A
        for _ in xrange(rewardIpyData.GetRandItemCountA()):
            itemID = GameWorld.GetResultByRandomList(rewardIpyData.GetRandItemRewardListA())
            if itemID:
                rewardItemDict[itemID] = rewardItemDict.get(itemID, 0) + 1
        # 饼图库B
        for _ in xrange(rewardIpyData.GetRandItemCountB()):
            itemID = GameWorld.GetResultByRandomList(rewardIpyData.GetRandItemRewardListB())
            if itemID:
                rewardItemDict[itemID] = rewardItemDict.get(itemID, 0) + 1
        GameWorld.DebugLog("    remainCount=%s,rewardCount=%s,rewardTotalCount=%s, %s" % (remainCount, rewardCount, rewardTotalCount, rewardItemDict))
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActivityPlaceRemainCount, remainCount)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActivityPlaceRewardCount, rewardCount)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActivityPlaceRewardTotalCount, rewardTotalCount)
    if remainCount > 0:
        nextStartTime = int(time.time())
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActivityPlaceStartTime, nextStartTime)
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActivityPlaceExpCount, 0)
        GameWorld.DebugLog("    还有剩余次数,更新启动时间: %s" % (nextStartTime))
    # 存储奖励
    rewardItemCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActivityPlaceRewardItem)
    for i in xrange(rewardItemCount):
        itemID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActivityPlaceRewardItemID % i)
        if itemID not in rewardItemDict:
            continue
        addCount = rewardItemDict.pop(itemID)
        itemCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActivityPlaceRewardItemCount % i)
        updCount = itemCount + addCount
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActivityPlaceRewardItemCount % i, updCount)
        #GameWorld.DebugLog("    更新探索奖励: itemID=%s,itemCount=%s,addCount=%s,updCount=%s" % (itemID, itemCount, addCount, updCount))
    for itemID, itemCount in rewardItemDict.items():
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActivityPlaceRewardItemID % rewardItemCount, itemID)
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActivityPlaceRewardItemCount % rewardItemCount, itemCount)
        rewardItemCount += 1
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActivityPlaceRewardItem, rewardItemCount)
        #GameWorld.DebugLog("    新增探索奖励: itemID=%s,itemCount=%s,rewardItemCount=%s" % (itemID, itemCount, rewardItemCount))
    if isQuick:
        PlayerControl.NotifyCode(curPlayer, "ActivityPlaceQuickFinishOK")
    Sync_ActivityPlaceInfo(curPlayer)
    PlayerBossReborn.AddBossRebornActionCnt(curPlayer, ChConfig.Def_BRAct_ActivityPlace, endCount)
    return
def GetActivityPlaceReward(curPlayer):
    ## 领取活跃放置奖励
    rewardItemCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActivityPlaceRewardItem)
    if not rewardItemCount:
        GameWorld.DebugLog("没有活跃放置奖励,无法领取!")
        return
    rewardCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActivityPlaceRewardCount)
    isAppointItem = 0
    rewardItemList = []
    for i in xrange(rewardItemCount):
        itemID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActivityPlaceRewardItemID % i)
        itemCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActivityPlaceRewardItemCount % i)
        if not itemID or not itemCount:
            break
        rewardItemList.append([itemID, itemCount, isAppointItem])
        # 领取后需要重置为0
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActivityPlaceRewardItemID % i, 0)
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActivityPlaceRewardItemCount % i, 0)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActivityPlaceRewardItem, 0)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActivityPlaceRewardCount, 0)
    totalCount = min(curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActivityCountTotal) + rewardCount, ChConfig.Def_UpperLimit_DWord)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ActivityCountTotal, totalCount)
    GameWorld.DebugLog("领取活跃放置奖励: totalCount=%s,rewardCount=%s,rewardItemCount=%s,rewardItemList=%s" % (totalCount, rewardCount, rewardItemCount, rewardItemList))
    ItemControler.GivePlayerItemOrMail(curPlayer, rewardItemList, event=["ActivityPlace", False, {}])
    PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_ActivityPlace, rewardCount)
    Sync_ActivityPlaceInfo(curPlayer)
    return
def Sync_ActivityPlaceInfo(curPlayer):
    ## 同步活跃放置信息
    rewardItemInfo = []
    rewardItemCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActivityPlaceRewardItem)
    for i in xrange(rewardItemCount):
        itemID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActivityPlaceRewardItemID % i)
        itemCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActivityPlaceRewardItemCount % i)
        rewardItemInfo.append([itemID, itemCount])
    placeInfo = ChPyNetSendPack.tagMCActivityPlaceInfo()
    placeInfo.StartTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActivityPlaceStartTime)
    placeInfo.PlaceCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActivityPlaceRemainCount)
    placeInfo.RewardCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActivityPlaceRewardCount)
    placeInfo.RewardInfo = str(rewardItemInfo)
    placeInfo.RewardLen = len(placeInfo.RewardInfo)
    placeInfo.TodayExp = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActivityPlaceTodayExp)
    placeInfo.TodayExpPoint = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActivityPlaceTodayExpPoint)
    placeInfo.YestordayExp = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActivityPlaceYestorDayExp)
    placeInfo.YestordayExpPoint = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActivityPlaceYestorDayExpPoint)
    placeInfo.TotalCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ActivityCountTotal)
    NetPackCommon.SendFakePack(curPlayer, placeInfo)
    return
#########################################################################################