hxp
6 天以前 0b314dd1d9f0c39e8d86de7e996c62836aa19aca
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerSuccess.py
@@ -2,551 +2,190 @@
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
#-------------------------------------------------------------------------------
#
##@package Player.PlayerSuccess
#
# @todo:成就系统
# @author xdh
# @date 2018-04-23
# @author hxp
# @date 2025-10-17
# @version 1.0
#
#
# 详细描述: 成就系统
#
#---------------------------------------------------------------------
#"""Version = 2018-04-23 11:00"""
#---------------------------------------------------------------------
#-------------------------------------------------------------------------------
#"""Version = 2025-10-17 21:00"""
#-------------------------------------------------------------------------------
import ShareDefine
import ChConfig
import GameWorld
import ChPyNetSendPack
import ShareDefine
import NetPackCommon
import ItemCommon
import IPY_GameWorld
import PlayerControl
import ChPyNetSendPack
import ItemControler
import PlayerMagicWeapon
import PlayerFamilyRedPacket
import PlayerGatherSoul
import IpyGameDataPY
import PyGameData
import EventReport
import ObjPool
import datetime
import time
import math
import ChEquip
import PlayerRune
import Operate_EquipStone
import Operate_EquipWash
import PlayerFeastRedPacket
import PlayerDogz
import DataRecordPack
## 获取成就字典信息值
#  @param curPlayer 玩家实例
#  @return
def GetPDictValue(curPlayer, key, defaultValue=0):
    return curPlayer.NomalDictGetProperty(key, defaultValue, ChConfig.Def_PDictType_Success)
## 设置成就字典信息值
#  @param curPlayer 玩家实例
#  @return
def SetPDictValue(curPlayer, key, value):
    PlayerControl.NomalDictSetProperty(curPlayer, key, value, ChConfig.Def_PDictType_Success)
    return
def GetSuccIsFinish(curPlayer, succID):
    #获取成就是否已完成
    return GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_Success_FinishTime, succID)
def SetSuccFinish(curPlayer, succID, finish=True):
    #设置成就是否完成
    return GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_Success_FinishTime, succID, finish)
#成就奖励是否已领取
def GetSuccHasGot(curPlayer, succID):
    #获取成就奖励是否已领取
    return GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_Success_AwardRecord, succID)
    return GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_SuccessAward, succID)
def SetSuccHasGot(curPlayer, succID, hasGot=True):
    #设置成就奖励领取状态
    if GetSuccHasGot(curPlayer, succID) == hasGot:
        return
    GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_Success_AwardRecord, succID, hasGot)
    if hasGot:
        #已领取的可设置是否已完成为0
        SetSuccFinish(curPlayer, succID, 0)
        Sync_SuccTypeIndexAwardRecord(curPlayer, [succID], True) #设置成未领取的在外层同步
    GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_SuccessAward, succID, hasGot)
    return 
def GetSuccPassportAwardHasGot(curPlayer, succID):
    #获取成就通行证奖励是否已领取
    return GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_Success_PassportAward, succID)
def SetSuccPassportAwardHasGot(curPlayer, succID, hasGot=True):
    #设置成就通行证奖励领取状态
    GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_Success_PassportAward, succID, hasGot)
    if hasGot:
        Sync_SuccTypeIndexAwardRecord(curPlayer, [succID])
    return
    
def SetSuccFinishValue(curPlayer, succType, condition, value):
    #设置成就完成度
    key = ChConfig.Def_PDict_Success_CntValue % (succType, condition)
    SetPDictValue(curPlayer, key, value)
#成就完成进度
def GetSuccValue(curPlayer, succType, conds):
    condition = "" if not conds else str(conds).replace(" ", "")[1:-1]
    return curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_SuccessValue % (succType, condition))
def SetSuccValue(curPlayer, succType, conds, value):
    condition = "" if not conds else str(conds).replace(" ", "")[1:-1]
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_SuccessValue % (succType, condition), value)
    return
def GetSuccFinishValue(curPlayer, succType, condition):
    #获取完成度
    key = ChConfig.Def_PDict_Success_CntValue % (succType, condition)
    return GetPDictValue(curPlayer, key)
## 成就配表数据类
class SuccessData():
    def __init__(self):
        self.succID = 0  #成就ID
        self.succType = 0 # 成就类型
        self.needCnt = 0 # 所以计数数量
        self.preSuccIDList = [] # 前置成就ID
        self.condition = [] # 辅助条件(根据类型自定义配置)
        self.awardItemDict = {} # 完成成就可领取的奖励物品{itemid:itemcnt}
        self.awardItemDict2 = {} # 完成成就可领取的奖励物品,通行证奖励{itemid:itemcnt}
        self.moneyDict = {} # 完成成就获得的金钱 {moneyType:money}
        self.exp = 0 # 完成成就获得的经验
        self.attrDict = {} # 完成成就获得的属性 {attrid:attrvalue}
        self.hasAward = True #是否有奖励
        self.redPacketID = 0 # 红包ID
        self.magicWeaponExp = {} # 法宝升级经验{id:exp}
        return
## 成就数据管理类
class SuccessDataMng():
    ## 构造函数
    #  @param None
    #  @return
    def __init__(self):
        self.succTypeConditionDict = {} #{succType:[condition,..]}
        self.successDataDict = {} # {succType:{index:SuccessData(),...}, ...}
        return
    ## 加载成就数据
    #  @param succType: 成就类型
    #  @return
    def __LoadSuccessData(self, succType):
        if succType in self.successDataDict:
            return
        successDataList = IpyGameDataPY.GetIpyGameDataByCondition('Success', {'Type':succType}, True, False)
        if not successDataList:
            return
        successDataObjDict = {}
        conditionDict = {}
        for successIpyData in successDataList:
            succData = SuccessData()
            succData.succID = successIpyData.GetID()
            succData.succType = succType
            succData.needCnt = successIpyData.GetNeedCnt()
            succData.preSuccIDList = list(successIpyData.GetPreSuccess())
            succData.condition = list(successIpyData.GetCondition())
            succData.awardItemDict = successIpyData.GetAwardItem()
            succData.awardItemDict2 = successIpyData.GetAwardItem2()
            succData.moneyDict = successIpyData.GetMoney()
            succData.exp = successIpyData.GetExp()
            succData.attrDict = successIpyData.GetAwardAttr()
            succData.redPacketID = successIpyData.GetRedPacketID()
            magicWeaponID = successIpyData.GetMagicWeaponID()
            magicWeaponExp = successIpyData.GetMagicWeaponExp()
            if magicWeaponID and magicWeaponExp:
                succData.magicWeaponExp[magicWeaponID] = magicWeaponExp
            succData.hasAward = bool(succData.awardItemDict or succData.moneyDict or succData.exp or succData.attrDict or succData.redPacketID or succData.magicWeaponExp \
                                     or succData.awardItemDict2)
            successDataObjDict[succData.succID]=succData
            if tuple(succData.condition) not in conditionDict:
                conditionDict[tuple(succData.condition)] = [succData.succID]
            else:
                conditionDict[tuple(succData.condition)].append(succData.succID)
        self.successDataDict[succType] = successDataObjDict
        #self.succTypeConditionDict[succType] = conditionDict
        return
    ## 根据成就类型获取该类型所有成就
    #  @param succType: 成就类型
    #  @return: {index:SuccessData(), ...}
    def GetSuccDataByType(self, succType):
        if succType not in self.successDataDict:
            self.__LoadSuccessData(succType)
        return self.successDataDict.get(succType, {}).values()
    ## 根据成就类型获取该类型所有条件
    #  @param succType: 成就类型
    #  @return: {index:SuccessData(), ...}
#    def GetConditionDictByType(self, succType):
#        if succType not in self.succTypeConditionDict:
#            self.__LoadSuccessData(succType)
#        return self.succTypeConditionDict.get(succType, {})
    ## 根据成就类型索引获取某个成就数据
    #  @param succType: 成就类型
    #  @param index: 成就索引
    #  @return: SuccessData() or None
    def GetSuccessData(self, succID):
        succIpyData = IpyGameDataPY.GetIpyGameDataNotLog('Success', succID)
        if not succIpyData:
            return
        succType = succIpyData.GetType()
        if succType not in self.successDataDict:
            self.__LoadSuccessData(succType)
        return self.successDataDict.get(succType, {}).get(succID)
g_succDataMng = SuccessDataMng()
## 获取成就数据管理器
#  @param None
#  @return
def GetSuccDataMng():
    return g_succDataMng
## 成就OnLogin
#  @param curPlayer
#  @return
def SuccOnLogin(curPlayer):
    # 同步成就信息
    Sync_SuccessInfo(curPlayer)
    # 同步成就领奖记录
    Sync_SuccTypeIndexAwardRecord(curPlayer)
    # 检查老玩家
    __CheckOldPlayerSuccess(curPlayer)
    # 检查达成与否(有些可能改过上限,然后玩家可以完成,上线统一做一次检查)
    for succType in ShareDefine.SuccessTypeList:
        succInfoList = GetSuccDataMng().GetSuccDataByType(succType)
        if not succInfoList:
            continue
        __DoCheckSuccessFinish(curPlayer, succType, succInfoList)
    if curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Success_ScoreAward):
        Sync_SuccessScoreAward(curPlayer)
    SyncSuccessInfo(curPlayer)
    SyncSuccessAwardRecord(curPlayer)
    return
## 检查老玩家成就激活情况
#  @param None
#  @return
def __CheckOldPlayerSuccess(curPlayer):
    ''' 成就版本更新老玩家检查  每次启动服务后 玩家第一次上线检查成就完成情况
    '''
    initGameWorldTime = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_InitGameWorldTime)
    # 上线需要检查老玩家成就完成情况类型
    NeedCheckSuccTypeList = [
                             ]
    curCheckVersion = GetPDictValue(curPlayer, ChConfig.Def_PDict_Success_CheckVersion)
    if curCheckVersion == initGameWorldTime:
        GameWorld.DebugLog('    本次开启服务器处理过成就检查,不再处理 ', curPlayer.GetID())
def ResetSuccessByType(curPlayer, succType, ignoreFinish=True):
    #重置某类型成就进度,一般用于先重置次数再重新计数,或者活动类
    ipyDataList = IpyGameDataPY.GetIpyGameDataListNotLog("Success", succType)
    if not ipyDataList:
        return
    GameWorld.DebugLog("更新老玩家上线检查成就curCheckVersion=%s" % (curCheckVersion))
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for succType in NeedCheckSuccTypeList:
        pass
    DataRecordPack.DR_CheckOldPlayerSuccess(curPlayer)
    SetPDictValue(curPlayer, ChConfig.Def_PDict_Success_CheckVersion, initGameWorldTime)
    GameWorld.DebugLog("更新老玩家上线检查成就updCheckVersions=%s" % (initGameWorldTime), curPlayer.GetID())
    for ipyData in ipyDataList:
        succID = ipyData.GetSuccID()
        if ignoreFinish and GetSuccHasGot(curPlayer, succID):
            continue
        conds = ipyData.GetCondition()
        SetSuccValue(curPlayer, succType, conds, 0)
    return
## 成就OnWeek
#  @param curPlayer
#  @return
def OnWeek(curPlayer):
    resetList = []
    weekResetSuccTypeList = IpyGameDataPY.GetFuncEvalCfg('WeekResetSuccType')
    for succType in weekResetSuccTypeList:
        succInfoList = GetSuccDataMng().GetSuccDataByType(succType)
        if not succInfoList:
            continue
        for succDataObj in succInfoList:
            succID = succDataObj.succID
            condition = succDataObj.condition
            if not GetSuccFinishValue(curPlayer, succType, condition):
                continue
            SetSuccFinishValue(curPlayer, succType, condition, 0)
            SetSuccFinish(curPlayer, succID, False)
            SetSuccHasGot(curPlayer, succID, False)
            resetList.append(succID)
            GameWorld.DebugLog("    OnWeek 重置成就类型: succID=%s" % (succID))
    if resetList:
        Sync_SuccTypeIndexAwardRecord(curPlayer, resetList, True)
        Sync_SuccessInfo(curPlayer, resetList, True)
    return
#def UpdateSuccessProgressByConditions(curPlayer, successType, conditionCountDict):
#    ## 根据多种条件更新进度,如装备多品质的
#    ipyDataList = IpyGameDataPY.GetIpyGameDataListNotLog("Success", successType)
#    if not ipyDataList:
#        return
#    updIDList = []
#    updsuccDataList = []
#    updConditionDict = {}
#
#    for condition, newCount in conditionCountDict.items():
#        addCondList = [] # 不同的成就ID条件可能相同,只是最大进度不同,故传入的条件计数针对相同成就条件只能累加一次
#        for ipyData in ipyDataList:
#            succID = ipyData.GetSuccID()
#            conds = ipyData.GetCondition()
#            needCnt = ipyData.GetNeedCnt()
#
#            tupleCond = tuple(conds) # 作为字典key用
#
#            if tupleCond not in updConditionDict:
#                updConditionDict[tupleCond] = [conds, 0, 0] # [条件, 更新值, 最大进度值]
#            updInfo = updConditionDict[tupleCond]
#            if updInfo[2] < needCnt:
#                updInfo[2] = needCnt
#
#            if not __CheckCanAddSuccess(curPlayer, ipyData, list(condition)):
#                continue
#
#            if succID not in updIDList:
#                updIDList.append(succID)
#                updsuccDataList.append(ipyData)
#
#            if tupleCond not in addCondList:
#                addCondList.append(tupleCond)
#                updConditionDict[tupleCond][1] = updConditionDict[tupleCond][1] + newCount # 更新进度值
#
#    # 没有找到更新目标不处理
#    #GameWorld.DebugLog("    updConditionDict=%s" % updConditionDict)
#    #GameWorld.DebugLog("    updIDList=%s" % updIDList)
#    if not updIDList:
#        return
#
#    # 先更新成就记录值后再判断完成与否
#    for cond, updCnt, maxCnt in updConditionDict.values():
#        if not updCnt:
#            continue
#        updCnt = min(maxCnt, updCnt)
#        if GetSuccValue(curPlayer, successType, cond) == updCnt:
#            continue
#        SetSuccValue(curPlayer, successType, cond, updCnt)
#    SyncSuccessInfo(curPlayer, syncTypeCondList)
#    return
def DoResetSuccessIDList(curPlayer, resetSuccIDList):
    ## 重置成就相关数据
    if not resetSuccIDList:
        return
    resetList = []
    for succID in resetSuccIDList:
        succData = GetSuccDataMng().GetSuccessData(succID)
        if not succData:
            continue
        succType = succData.succType
        condition = succData.condition
        #if not GetSuccFinishValue(curPlayer, succType, condition):
        #    continue
        SetSuccFinishValue(curPlayer, succType, condition, 0)
        SetSuccFinish(curPlayer, succID, False)
        SetSuccHasGot(curPlayer, succID, False)
        resetList.append(succID)
        GameWorld.DebugLog("    重置成就类型: succType=%s,succID=%s" % (succType, succID))
    if resetList:
        Sync_SuccTypeIndexAwardRecord(curPlayer, resetList, True)
        Sync_SuccessInfo(curPlayer, resetList, True)
    return
## 成就OnDay
#  @param curPlayer
#  @return
def SuccOnDay(curPlayer):
    resetList = []
    # 重置连续类型断掉的数据
    serverDay = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_ServerDay)
    GameWorld.DebugLog("连续类型成就过天...serverDay=%s" % serverDay)
    for succType in ShareDefine.ContinueSuccessTypeList:
        succInfoList = GetSuccDataMng().GetSuccDataByType(succType)
        if not succInfoList:
            continue
        for succDataObj in succInfoList:
            succID = succDataObj.succID
            condition = succDataObj.condition
            #GameWorld.DebugLog("    succID=%s" % (succID))
            finishTime = GetSuccIsFinish(curPlayer, succID)
            # 已完成的不再检查
            if finishTime > 0 or GetSuccHasGot(curPlayer, succID):
                GameWorld.DebugLog("        已完成的不再检查")
                continue
            if __DoCheckResetContinue(curPlayer, serverDay, succID):
                SetSuccFinishValue(curPlayer, succType, condition, 0)
                resetList.append(succID)
    if resetList:
        Sync_SuccessInfo(curPlayer, resetList, True)
    return
## 检查成就连续天情况
#  @param curPlayer
#  @return True-连续已中断
def __DoCheckResetContinue(curPlayer, serverDay, succID):
    lastDayKey = ChConfig.Def_PDict_Success_LastDay % (succID)
    lastDay = GetPDictValue(curPlayer, lastDayKey)
    # 记录时间从开服天数改成 time.time()
    if lastDay <= 1000:
        #GameWorld.DebugLog("        lastDay <= 0")
        return
    tick = int(time.time())
    serverDay = GameWorld.ChangeTimeNumToDatetime(tick, ChConfig.TYPE_Time_Format_Day)
    lastDay = GameWorld.ChangeTimeNumToDatetime(lastDay, ChConfig.TYPE_Time_Format_Day)
    # 昨天有更新的不处理,证明还是连续状态
    if lastDay == serverDay - datetime.timedelta(1):
        GameWorld.DebugLog("        昨天有更新的不处理,证明还是连续状态")
        return
    SetPDictValue(curPlayer, lastDayKey, 0)
    GameWorld.DebugLog("    重置成就连续类型: succID=%s" % (succID))
    return True
def ResetSuccessByType(curPlayer, succType):
    #重置某类型成就进度(已完成的不重置)
    succInfoList = GetSuccDataMng().GetSuccDataByType(succType)
    if not succInfoList:
        return
    #先重置次数再重新计数
    for succDataObj in succInfoList:
        succID = succDataObj.succID
        condition = succDataObj.condition
        #GameWorld.DebugLog("    succID=%s" % (succID))
        finishTime = GetSuccIsFinish(curPlayer, succID)
        # 已完成的不再检查
        if finishTime > 0 or GetSuccHasGot(curPlayer, succID):
            continue
        SetSuccFinishValue(curPlayer, succType, condition, 0)
    return
def UpdateSuccessProgressByConditions(curPlayer, successType, conditionCountDict):
    if successType not in ShareDefine.SuccessTypeList:
        return
    succInfoList = GetSuccDataMng().GetSuccDataByType(successType)
    if not succInfoList:
        return
    updIDList = []
    updsuccDataList = []
    updConditionDict = {}
    for condition, newCount in conditionCountDict.items():
        addCondList = [] # 不同的成就ID条件可能相同,只是最大进度不同,故传入的条件计数针对相同成就条件只能累加一次
        for succDataObj in succInfoList:
            cond = succDataObj.condition
            tupleCond = tuple(cond) # 作为字典key用
            succID = succDataObj.succID
            needCnt = succDataObj.needCnt
            if tupleCond not in updConditionDict:
                updConditionDict[tupleCond] = [cond, 0, 0] # [条件, 更新值, 最大进度值]
            updInfo = updConditionDict[tupleCond]
            if updInfo[2] < needCnt:
                updInfo[2] = needCnt
            if not __CheckCanAddSuccess(curPlayer, succDataObj, list(condition)):
                continue
            if succID not in updIDList:
                updIDList.append(succID)
                updsuccDataList.append(succDataObj)
            if tupleCond not in addCondList:
                addCondList.append(tupleCond)
                updConditionDict[tupleCond][1] = updConditionDict[tupleCond][1] + newCount # 更新进度值
    # 没有找到更新目标不处理
    #GameWorld.DebugLog("    updConditionDict=%s" % updConditionDict)
    #GameWorld.DebugLog("    updIDList=%s" % updIDList)
    if not updIDList:
        return
    isUpd = False
    # 先更新成就记录值后再判断完成与否
    for cond, updCnt, maxCnt in updConditionDict.values():
        if not updCnt:
            continue
        updCnt = min(maxCnt, updCnt)
        if GetSuccFinishValue(curPlayer, successType, cond) == updCnt:
            continue
        isUpd = True
        SetSuccFinishValue(curPlayer, successType, cond, updCnt)
        #GameWorld.DebugLog("    successType=%s,cond=%s,updCnt=%s,maxCnt=%s"  % (successType, cond, updCnt, maxCnt))
    if not isUpd:
        return
    # 同步更新信息
    Sync_SuccessInfo(curPlayer, updIDList, False)
    # 更新值后检查成就完成情况
    __DoCheckSuccessFinish(curPlayer, successType, updsuccDataList)
    return
## 更新成就完成进度逻辑(外部功能调用,只适用于不重置的成就类型)
#  @param curPlayer
#  @param successType: 成就类型
#  @param newCnt: 新进度值
#  @return
def UptateSuccessProgress(curPlayer, successType, newCnt, condition=[]):
    if successType not in ShareDefine.SuccessTypeList:
    ipyDataList = IpyGameDataPY.GetIpyGameDataListNotLog("Success", successType)
    if not ipyDataList:
        return
    if successType in ShareDefine.FeastRedPackSuccessTypeList:
        if not PlayerFeastRedPacket.GetFeastRedPacketState():
            return
    succInfoList = GetSuccDataMng().GetSuccDataByType(successType)
    if not succInfoList:
        GameWorld.DebugLog("    找不到成就数据successType=%s" % successType)
        return
    curCnt = -1
    for succData in succInfoList:
        if not __CheckCanAddSuccess(curPlayer, succData, condition):
    curCnt = None
    for ipyData in ipyDataList:
        if not __CheckCanAddSuccess(curPlayer, ipyData, condition):
            continue
        curCnt = GetSuccFinishValue(curPlayer, successType, succData.condition)
        curCnt = GetSuccValue(curPlayer, successType, ipyData.GetCondition())
        break
    if curCnt == -1:
    if curCnt == None or newCnt <= curCnt:
        #GameWorld.DebugLog("不需要更新成就值: curCnt=%s" % (curCnt))
        return
    if newCnt > curCnt: #这里需要立即更新!!
        DoAddSuccessProgress(curPlayer, successType, newCnt - curCnt, condition, False)
    #update的需要立即更新!!
    DoAddSuccessProgress(curPlayer, successType, newCnt - curCnt, condition, False)
    return
def __CheckCanAddSuccess(curPlayer, succDataObj, condition):
    successType = succDataObj.succType
    succID = succDataObj.succID
    cond = succDataObj.condition
    if successType in ShareDefine.FeastRedPackSuccessTypeList:
        todayFeastSuccIDList = PlayerFeastRedPacket.GetTodayFeastSuccIDList()
        if not todayFeastSuccIDList or succID not in todayFeastSuccIDList:
            #GameWorld.DebugLog("    非今日节日红包成就,不增加进度! succID=%s,todayFeastSuccIDList=%s" % (succID, todayFeastSuccIDList))
            return
    isUnDownCheck = successType in ShareDefine.UnDownCheckSuccessTypeList
    isContain = successType in ShareDefine.ContainSuccessTypeList
def __CheckCanAddSuccess(curPlayer, ipyData, condition):
    ## 检查可否添加进度
    succID = ipyData.GetSuccID()
    # 已完成的不再检查
    if GetSuccIsFinish(curPlayer, succID) or GetSuccHasGot(curPlayer, succID):
    if GetSuccHasGot(curPlayer, succID):
        return
    #前置成就判断
    preSuccIDList = succDataObj.preSuccIDList
    for preSuccID in preSuccIDList:
        if not GetSuccIsFinish(curPlayer, preSuccID) and not GetSuccHasGot(curPlayer, preSuccID):
            return
    
    # 有辅助条件的, 需判断是否向下检查
    if len(cond) > 0:
        if isContain:
            if condition[0] not in cond:
    successType = ipyData.GetSuccType()
    conds = ipyData.GetCondition()
    if not conds:
        # 无条件的默认可添加
        return True
    if not condition:
        return
    # 传进来的条件满足配置的条件列表中的一个就行的成就类型
    if successType in ShareDefine.ContainSuccessTypeList:
        if condition[0] not in conds:
            return
    # 传进来的条件是配置条件的整数倍的成就类型
    elif successType in ShareDefine.MultipleSuccessTypeList:
        if not (condition[0] / conds[0] and condition[0] % conds[0] == 0):
            #必须是条件的倍数
            return
    else:
        if len(conds) != len(condition):
            return
        # 不向下检查增加进度的, 仅配置值等于该值的可增加进度
        if successType in ShareDefine.UnDownCheckSuccessTypeList:
            if conds != condition:
                return
        elif successType in ShareDefine.MultipleSuccessTypeList:
            if not (condition[0]/cond[0] and condition[0]%cond[0] == 0):
                #必须是条件的倍数
                return
        # 可向下增加进度的, 仅配置值 <= 该值的可增加进度
        else:
            if len(cond) != len(condition):
                return
            # 不向下检查增加进度的, 仅配置值等于该值的可增加进度
            if isUnDownCheck and cond != condition:
                return
            # 可向下增加进度的, 仅配置值 <= 该值的可增加进度
            if not isUnDownCheck:
                isbreak = False
                undowncheckIndexList = [] # 不向下检查的条件索引
                if successType in ShareDefine.PartUnDownCheckSuccessTypeInfo:
                    undowncheckIndexList = ShareDefine.PartUnDownCheckSuccessTypeInfo[successType]
                for i, num in enumerate(cond):
                    if i in undowncheckIndexList:
                        if num != condition[i]:
                            isbreak = True
                            break
                    if num > condition[i]:
            isbreak = False
            undowncheckIndexList = [] # 不向下检查的条件索引
            if successType in ShareDefine.PartUnDownCheckSuccessTypeInfo:
                undowncheckIndexList = ShareDefine.PartUnDownCheckSuccessTypeInfo[successType]
            for i, num in enumerate(conds):
                if i in undowncheckIndexList:
                    if num != condition[i]:
                        isbreak = True
                        break
                if isbreak:
                    return
                if num > condition[i]:
                    isbreak = True
                    break
            if isbreak:
                return
    return True
# 将攻击类的成就一次执行,减少运行量
def FinishDelayAddSuccessProgress(curPlayer, tick, isFinish=True):
    # 将攻击类的成就一次执行,减少运行量
    if not isFinish:
        # 二次延迟处理
@@ -562,408 +201,131 @@
    
    successDict = PyGameData.g_delaySuccessDict.pop(playerID)
    for sucessInfo, cnt in successDict.items():
        DoAddSuccessProgress(curPlayer, sucessInfo[0], cnt, list(sucessInfo[1]), False)
    return
## 增加成就完成进度逻辑(外部功能调用)
#  @param curPlayer
#  @param successType: 成就类型
#  @param addCnt: 增加进度值
#  @param condition: 扩展条件
#  @return
def DoAddSuccessProgress(curPlayer, successType, addCnt, condition=[], delayCalc=True):
    #GameWorld.DebugLog("DoAddSuccessProgress type=%s,addCnt=%s,condition=%s"
    #                   % (successType, addCnt, condition), curPlayer.GetPlayerID())
    if GameWorld.IsCrossServer():
        return
    
    if successType in ShareDefine.FeastRedPackSuccessTypeList:
        if not PlayerFeastRedPacket.GetFeastRedPacketState():
            #GameWorld.DebugLog("非节日红包活动时间,不增加成就!successType=%s" % successType)
            return
    playerID = curPlayer.GetID()
    if delayCalc and successType not in ShareDefine.NeedResetSuccessTypeList:
    if delayCalc:
        if playerID not in PyGameData.g_delaySuccessDict:
            PyGameData.g_delaySuccessDict[playerID] = {}
        # 最终处理减少计算量
        # 最终处理减少计算量,短时间多次累加汇总一次计算
        successTuple = (successType, tuple(condition))
        if successTuple not in PyGameData.g_delaySuccessDict[playerID]:
            PyGameData.g_delaySuccessDict[playerID][successTuple] = addCnt
        else:
            PyGameData.g_delaySuccessDict[playerID][successTuple] = PyGameData.g_delaySuccessDict[playerID][successTuple] + addCnt
        return
    if condition and type(condition) != type([]):
        GameWorld.ErrLog('DoAddSuccessProgress type=%s, condition=%s 错误!'%(type, condition))
        GameWorld.ErrLog('DoAddSuccessProgress type=%s, condition=%s 错误!' % (type, condition))
        return
    if successType not in ShareDefine.SuccessTypeList:
        return
    
    succInfoList = GetSuccDataMng().GetSuccDataByType(successType)
    if not succInfoList:
        GameWorld.DebugLog("    找不到成就数据successType=%s" % successType)
    ipyDataList = IpyGameDataPY.GetIpyGameDataListNotLog("Success", successType)
    if not ipyDataList:
        GameWorld.DebugLog("找不到成就数据successType=%s" % successType)
        return
    
    maxCnt = 0 # 本次可以更新到的最大值
    updConditionList = [] # 需更新进度值的key编号列表
    updIDList = []
    updsuccDataList = []
    tick = int(time.time())
    for succDataObj in succInfoList:
        succID = succDataObj.succID
        needCnt = succDataObj.needCnt
    for ipyData in ipyDataList:
        
        if not __CheckCanAddSuccess(curPlayer, succDataObj, condition):
        if not __CheckCanAddSuccess(curPlayer, ipyData, condition):
            continue
        updIDList.append(succID)
        updsuccDataList.append(succDataObj)
        curCondition = succDataObj.condition
        if curCondition not in updConditionList:
            updConditionList.append(curCondition)
        conds = ipyData.GetCondition()
        if conds not in updConditionList:
            updConditionList.append(conds)
            
        needCnt = ipyData.GetNeedCnt()
        if maxCnt < needCnt:
            maxCnt = needCnt
            
        # 连续类型的, 更新连续时的开服天数
        if successType in ShareDefine.ContinueSuccessTypeList:
            lastDayKey = ChConfig.Def_PDict_Success_LastDay % (succID)
            SetPDictValue(curPlayer, lastDayKey, tick)
    #GameWorld.DebugLog("    updConditionList=%s,maxCnt=%s" % (str(updConditionList), maxCnt))
    # 没有找到更新目标不处理
    if not updConditionList or maxCnt <= 0:
        return
    
    # 先更新成就记录值后再判断完成与否
    for condition in updConditionList:
        curCnt = GetSuccFinishValue(curPlayer, successType, condition)
    syncTypeCondList = []
    for conds in updConditionList:
        curCnt = GetSuccValue(curPlayer, successType, conds)
        updCnt = min(maxCnt, curCnt + addCnt)
        SetSuccFinishValue(curPlayer, successType, condition, updCnt)
#        GameWorld.DebugLog("    successType=%s,condition=%s,curCnt=%s,addCnt=%s,updCnt=%s"
#                           % (successType,condition, curCnt, addCnt, updCnt))
    # 同步更新信息
    Sync_SuccessInfo(curPlayer, updIDList, False)
    # 更新值后检查成就完成情况
    __DoCheckSuccessFinish(curPlayer, successType, updsuccDataList)
        SetSuccValue(curPlayer, successType, conds, updCnt)
        syncTypeCondList.append([successType, conds])
    SyncSuccessInfo(curPlayer, syncTypeCondList)
    return
## 检查成就完成情况
#  @param curPlayer
#  @param successType: 成就类型
#  @param succInfoDict: 该类型所有成就信息字典
#  @param isPub: 进度值是否公共
#  @param updNumList: 有更新进度的编号列表
#  @return
def __DoCheckSuccessFinish(curPlayer, successType, succInfoList):
def GetSuccessAward(curPlayer, succID):
    ipyData = IpyGameDataPY.GetIpyGameDataByCondition("Success", {"SuccID":succID})
    if not ipyData:
        return
    
    isNeedSys = successType in [ShareDefine.SuccType_ElderBattlefieldKill, ShareDefine.SuccType_ElderBattlefieldConKill]
    curTime = GameWorld.ChangeTimeStrToNum(GameWorld.GetCurrentDataTimeStr())
    playerName = curPlayer.GetName()
    for succDataObj in succInfoList:
        succID = succDataObj.succID
        needCnt = succDataObj.needCnt
        finishTime = GetSuccIsFinish(curPlayer, succID)
        # 已完成的不再检查
        if finishTime > 0 or GetSuccHasGot(curPlayer, succID):
            continue
        curCnt = GetSuccFinishValue(curPlayer, successType, succDataObj.condition)
        # 完成成就
        if curCnt >= needCnt:
            # 设置完成时间
            SetSuccFinish(curPlayer, succID)
            # 没有奖励的直接设置已领取
            if not succDataObj.hasAward:
                SetSuccHasGot(curPlayer, succID)
            # 通知客户端完成成就
            Notify_FinishSuccess(curPlayer, succID, curTime)
            if isNeedSys:
                PlayerControl.WorldNotify(0, 'AncientBattlefield_1', [playerName, succID])
            for mwID in succDataObj.magicWeaponExp.keys():
                EventReport.WriteEvent_MWSuccess(curPlayer, mwID, succID, ChConfig.CME_Log_Start)
            GameWorld.DebugLog("    完成成就succID=%s, type=%s,time=%s"
                               % (succID, successType, curTime))
    if GetSuccHasGot(curPlayer, succID):
        GameWorld.DebugLog("该成就奖励已经领取过! succID=%s" % succID)
        return
    
    succType = ipyData.GetSuccType()
    conds = ipyData.GetCondition()
    needCnt = ipyData.GetNeedCnt()
    curValue = GetSuccValue(curPlayer, succType, conds)
    if curValue < needCnt:
        GameWorld.DebugLog("该成就未完成! succID=%s,curValue=%s < %s" % (succID, curValue, needCnt))
        return
    SetSuccHasGot(curPlayer, succID)
    SyncSuccessAwardRecord(curPlayer, [succID], True)
    awardItemList = ipyData.GetAwardItemList()
    if awardItemList:
        ItemControler.GivePlayerItemOrMail(curPlayer, awardItemList, event=["SuccessAward", False, {}])
    return
## 计算成就属性
#  @param curPlayer 玩家
#  @param allAttrList 属性列表
#  @return None
def CalcSuccessAttr(curPlayer):
    allAttrList = [{} for _ in range(4)]
    attrDict = {}
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for i in xrange(ipyDataMgr.GetSuccessCount()):
        ipyData = ipyDataMgr.GetSuccessByIndex(i)
        succID = ipyData.GetID()
        attrAwardDict = ipyData.GetAwardAttr()
        if not attrAwardDict:
            continue
        if not GetSuccHasGot(curPlayer, succID):
            continue
        for attrID, attrValue in attrAwardDict.items():
            attrDict[attrID] = attrDict.get(attrID, 0) + attrValue
    #GameWorld.DebugLog("    成就增加属性 attrDict=%s" % (attrDict))
    for attrID, attrValue in attrDict.items():
        PlayerControl.CalcAttrDict_Type(attrID, attrValue, allAttrList)
    PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_Success, allAttrList)
    return
## 刷新成就属性
def RefreshSuccessAttr(curPlayer):
    CalcSuccessAttr(curPlayer)
    # 不立即刷新
    PlayerControl.PlayerControl(curPlayer).RefreshPlayerAttrState()
    return
## 同步成就信息
#  @param curPlayer:
#  @param syncDict: 指定同步字典
#  @param isSendZero: 是否同步空数据(如连续类型进度值被清空时 or GM命令测试), 数据比较多,空数据默认就不同步了
#  @return
def Sync_SuccessInfo(curPlayer, succIdList=[], isSendZero=False):
    succInfoListPack = ChPyNetSendPack.tagMCSuccessInfoList()
    succInfoListPack.Clear()
    succInfoListPack.SuccessInfoList = []
    if succIdList:
        syncIdList = succIdList
    else:
        syncIdList = []
def SyncSuccessInfo(curPlayer, syncTypeCondList=None, isSendZero=False):
    if not syncTypeCondList:
        syncTypeCondList = []
        ipyDataMgr = IpyGameDataPY.IPY_Data()
        for i in xrange(ipyDataMgr.GetSuccessCount()):
            ipyData = ipyDataMgr.GetSuccessByIndex(i)
            succID = ipyData.GetID()
            syncIdList.append(succID)
        for index in range(ipyDataMgr.GetSuccessCount()):
            ipyData = ipyDataMgr.GetSuccessByIndex(index)
            # 已领取的不发
            if GetSuccHasGot(curPlayer, ipyData.GetSuccID()):
                continue
            succType = ipyData.GetSuccType()
            conds = ipyData.GetCondition()
            tcList = [succType, conds]
            if tcList in syncTypeCondList:
                continue
            syncTypeCondList.append(tcList)
            
    syncTypeDict = {}
    for succID in syncIdList:
        succData = GetSuccDataMng().GetSuccessData(succID)
        if not succData:
            continue
        succType = succData.succType
        condition = succData.condition
        CntValue = GetSuccFinishValue(curPlayer, succType, condition)
        isfinish = GetSuccIsFinish(curPlayer, succID)
    successInfoList = []
    objPoolMgr = ObjPool.GetPoolMgr()
    for succType, conds in syncTypeCondList:
        curValue = GetSuccValue(curPlayer, succType, conds)
        # 不发送为0的数据
        if not isSendZero and CntValue <= 0 and not isfinish:
        if not isSendZero and curValue <= 0:
            continue
        # 已领取的不发
        if GetSuccHasGot(curPlayer, succID):
            continue
        if succType not in syncTypeDict:
            syncTypeDict[succType] = [[condition, CntValue]]
        elif [condition, CntValue] not in syncTypeDict[succType]:
            syncTypeDict[succType].append([condition, CntValue])
        succInfo = objPoolMgr.acquire(ChPyNetSendPack.tagSCSuccessInfo)
        succInfo.SuccType = succType
        succInfo.Conds = conds
        succInfo.CLen = len(succInfo.Conds)
        succInfo.CurValue = curValue
        successInfoList.append(succInfo)
        
    if not syncTypeDict:
    if not successInfoList:
        return
    
    for sType, conditionList in syncTypeDict.items():
        for condition, cntValue in conditionList:
            succInfo = ChPyNetSendPack.tagMCSuccessInfo()
            succInfo.Clear()
            succInfo.SuccType = sType
            succInfo.Condition = str(condition) if condition else '[0]'
            succInfo.Len = len(succInfo.Condition)
            succInfo.CntValue = cntValue
            succInfoListPack.SuccessInfoList.append(succInfo)
    succInfoListPack.count = len(succInfoListPack.SuccessInfoList)
    NetPackCommon.SendFakePack(curPlayer, succInfoListPack)
    clientPack = objPoolMgr.acquire(ChPyNetSendPack.tagSCSuccessInfoList)
    clientPack.SuccessInfoList = successInfoList
    clientPack.Count = len(clientPack.SuccessInfoList)
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return
## 通知完成成就
#  @param None
#  @return
def Notify_FinishSuccess(curPlayer, succID, finishTime):
    succFinishPack = ChPyNetSendPack.tagMCSuccessFinish()
    succFinishPack.Clear()
    succFinishPack.SuccID = succID
    #succFinishPack.FinishTime = finishTime
    NetPackCommon.SendFakePack(curPlayer, succFinishPack)
    return
def GetCanGetAwardSuccByType(curPlayer, successTypeList):
    ##根据类型获取可领取的成就
    succList = []
    for successType in successTypeList:
        succInfoList = GetSuccDataMng().GetSuccDataByType(successType)
        for succDataObj in succInfoList:
            succID = succDataObj.succID
            if GetSuccIsFinish(curPlayer, succID) and not GetSuccHasGot(curPlayer, succID):
                succList.append(succID)
    return succList
def GiveSuccAward(curPlayer, succIDList, isGiveItem=True):
    #给成就奖励
    awardDict = {}
    for succID in succIDList:
        awardItemDict = __DoGetSuccTypeIndexAward(curPlayer, succID, isGiveItem)
        if not awardItemDict:
            continue
        for itemID,itemCnt in awardItemDict.items():
            awardDict[itemID] = awardDict.get(itemID, 0)+itemCnt
    return awardDict
def GetSuccessPassportState(curPlayer):
    ## 成就通行证状态
    return curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CTGGoodsBuyCount % ChConfig.Def_CTGID_SuccessPassport) > 0
#// A5 42 领取成就奖励 #tagMCGetSuccessAward
#
#struct    tagMCGetSuccessAward
#{
#    tagHead        Head;
#    DWORD        SuccID;    //成就ID
#    BYTE        IsPassport;    //是否通行证奖励
#};
def OnGetSuccessAward(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    succID = clientData.SuccID
    isPassport = clientData.IsPassport
    __DoGetSuccTypeIndexAward(curPlayer, succID, isPassport=isPassport)
    return
## 领取某个成就奖励
#  @param None
#  @return
def __DoGetSuccTypeIndexAward(curPlayer, succID, isGiveItem=True, isPassport=False):
    GameWorld.DebugLog("领取成就奖励succID=%s,isPassport=%s" % (succID, isPassport))
    succData = GetSuccDataMng().GetSuccessData(succID)
    if not succData:
        GameWorld.DebugLog("    成就数据不存在!succID=%s" % (succID))
        return
    if not succData.hasAward:
        GameWorld.DebugLog("    该成就没有配置奖励!")
        return
    finishTime = GetSuccIsFinish(curPlayer, succID)
    hasGot = GetSuccHasGot(curPlayer, succID) # 因为普通奖励领取后会重置是否已完成,所以如果已经领取普通奖励也代表已完成
    if finishTime <= 0 and not hasGot:
        GameWorld.DebugLog("    该成就未完成!")
        return
    if isPassport:
        if GetSuccPassportAwardHasGot(curPlayer, succID):
            GameWorld.DebugLog("    该成就通行证奖励已经领取过!")
            return
        if not GetSuccessPassportState(curPlayer):
            GameWorld.DebugLog("    未开通成就通行证,无法领取通行证奖励!")
            return
        itemDict = succData.awardItemDict2
        if not itemDict:
            GameWorld.DebugLog("    该成就没用通行证奖励!")
            return
    else:
        if hasGot:
            GameWorld.DebugLog("    该成就奖励已经领取过!")
            return
        itemDict = succData.awardItemDict
#    if awardItemDict and '[' in str(awardItemDict):
#        #修行成就奖励根据境界等级变
#        curRealmLV = curPlayer.GetOfficialRank()
#        sortLVList=sorted(awardItemDict.keys())
#        findLV = sortLVList[0]
#        for realmlv in sortLVList:
#            if curRealmLV <= int(realmlv):
#                findLV = realmlv
#                break
#        itemDict = dict(awardItemDict[findLV])
#    else:
#        itemDict = awardItemDict
    # 检查背包
    if isGiveItem:
        if not ItemCommon.CheckPackEnough(curPlayer, itemDict):
            return
#        packSpace = ItemCommon.GetItemPackSpace(curPlayer, IPY_GameWorld.rptItem)
#        needSpace = len(itemDict)
#        if needSpace > packSpace:
#            PlayerControl.NotifyCode(curPlayer, "GeRen_chenxin_998371")
#            return
    # 更新领奖记录
    if isPassport:
        SetSuccPassportAwardHasGot(curPlayer, succID)
    else:
        SetSuccHasGot(curPlayer, succID)
    # 给物品
    giveItemList = []
    if isGiveItem:
        for itemID, itemCnt in itemDict.items():
            isPutIn = ItemControler.GivePlayerItem(curPlayer, itemID, itemCnt, 0, [IPY_GameWorld.rptItem, IPY_GameWorld.rptAnyWhere])
            if isPutIn:
                giveItemList.append([itemID, itemCnt])
    if isPassport:
        # 通行证奖励只给物品
        ItemControler.NotifyGiveAwardInfo(curPlayer, giveItemList, "SuccessAward")
        return itemDict
    #给钱
    for moneyType, value in succData.moneyDict.items():
        PlayerControl.GiveMoney(curPlayer, int(moneyType), value)
    #给经验
    if succData.exp:
        PlayerControl.PlayerControl(curPlayer).AddExp(succData.exp)
    #属性
    if succData.attrDict:
        RefreshSuccessAttr(curPlayer)
    #发红包
    if succData.redPacketID:
        PlayerFamilyRedPacket.CreatRedPacketByID(curPlayer, succData.redPacketID, PlayerFamilyRedPacket.State_NoGot, succID)
    #法宝经验
    if succData.magicWeaponExp:
        for mwID, addExp in succData.magicWeaponExp.items():
            PlayerMagicWeapon.AddMagicWeaponUpExp(curPlayer, mwID, addExp)
            EventReport.WriteEvent_MWSuccess(curPlayer, mwID, succID, ChConfig.CME_Log_End, 1)
    GameWorld.DebugLog("    OK! awardItemDict=%s moneyDict=%s" % (itemDict, succData.moneyDict))
    ItemControler.NotifyGiveAwardInfo(curPlayer, giveItemList, "SuccessAward", exp=succData.exp, moneyInfo=succData.moneyDict)
    return itemDict
## 通知成就对应奖励领奖记录
#  @param None
#  @return
def Sync_SuccTypeIndexAwardRecord(curPlayer, succIDList=[], isSyncZero=False):
def SyncSuccessAwardRecord(curPlayer, succIDList=[], isSyncZero=False):
    ## 通知成就对应奖励领奖记录
    if succIDList:
        recordIndexList = []
        for succID in succIDList:
@@ -975,67 +337,25 @@
        succCnt = ipyDataMgr.GetSuccessCount()
        if not succCnt:
            return
        maxSuccid = ipyDataMgr.GetSuccessByIndex(succCnt-1).GetID()
        recordIndexList = xrange(maxSuccid / 31+1)
    succFARPack = ChPyNetSendPack.tagMCSuccessFinishAwardRecordList()
    succFARPack.Clear()
    succFARPack.RecordList = []
        maxSuccID = ipyDataMgr.GetSuccessByIndex(succCnt - 1).GetSuccID()
        recordIndexList = xrange(maxSuccID / 31 + 1)
    objPoolMgr = ObjPool.GetPoolMgr()
    recordList = []
    for i in recordIndexList:
        awardRecord=curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Success_AwardRecord%i)
        passportAwardRecord=curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Success_PassportAward%i)
        if not isSyncZero and not awardRecord and not passportAwardRecord:
        awardRecord = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_SuccessAward % i)
        if not isSyncZero and not awardRecord:
            continue
        recordInfo = ChPyNetSendPack.tagMCSuccessFinishAwardRecord()
        recordInfo = objPoolMgr.acquire(ChPyNetSendPack.tagSCSuccessAwardRecord)
        recordInfo.RecordIndex = i
        recordInfo.Record = awardRecord
        recordInfo.PassportRecord = passportAwardRecord
        succFARPack.RecordList.append(recordInfo)
        recordList.append(recordInfo)
        
    succFARPack.RecordCnt = len(succFARPack.RecordList)
    NetPackCommon.SendFakePack(curPlayer, succFARPack)
    return
def AddEnterFBSuccess(curPlayer, mapID, addCount):
    #进入副本成就相关
    if not recordList:
        return
    
    if mapID == ChConfig.Def_FBMapID_BZZD:
        #仙界秘境
        DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_BZZD, addCount)
    elif mapID == ChConfig.Def_FBMapID_IceLode:
        #冰晶矿脉
        DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_IceLode, addCount)
    return
def GetSuccessScoreAward(curPlayer, awardIndex):
    playerID = curPlayer.GetPlayerID()
    awardDict = IpyGameDataPY.GetFuncEvalCfg("SucceeScore", 1, {})
    if str(awardIndex) not in awardDict:
        return
    awardInfo = awardDict[str(awardIndex)]
    if len(awardInfo) != 2:
        return
    needScore, awardItemList = awardInfo
    if not PlayerControl.HaveMoney(curPlayer, ShareDefine.TYPE_Price_SuccessSocre, needScore):
        GameWorld.Log("成就积分不足,无法领奖! awardIndex=%s,needScore=%s" % (awardIndex, needScore), playerID)
        return
    awardState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Success_ScoreAward)
    if awardState & pow(2, awardIndex):
        GameWorld.DebugLog("已领取过该成就积分奖励! awardIndex=%s" % awardIndex, playerID)
        return
    updAwardState = awardState | pow(2, awardIndex)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_Success_ScoreAward, updAwardState)
    GameWorld.DebugLog("领取成就积分奖励! awardIndex=%s,awardState=%s,updAwardState=%s" % (awardIndex, awardState, updAwardState), playerID)
    Sync_SuccessScoreAward(curPlayer)
    ItemControler.GivePlayerItemOrMail(curPlayer, awardItemList, event=["SuccessScore", False, {}])
    return
def Sync_SuccessScoreAward(curPlayer):
    clientPack = ChPyNetSendPack.tagMCSuccessScoreInfo()
    clientPack.Clear()
    clientPack.ScoreAwardState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Success_ScoreAward)
    clientPack = objPoolMgr.acquire(ChPyNetSendPack.tagSCSuccessAwardRecordList)
    clientPack.RecordList = recordList
    clientPack.RecordCnt = len(clientPack.RecordList)
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return