ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerVip.py
@@ -15,613 +15,8 @@
#---------------------------------------------------------------------
#"""Version = 2017-10-23 16:40"""
#---------------------------------------------------------------------
import PlayerControl
import GameWorld
import ChConfig
import NetPackCommon
import ChPyNetSendPack
import ItemControler
import IPY_GameWorld
import PlayerDienstgrad
import PlayerMagicWeapon
import PlayerSuccess
import ShareDefine
import ItemCommon
import DataRecordPack
import IpyGameDataPY
import NPCCommon
import EventReport
import EventShell
import PassiveBuffEffMng
import PlayerFamilyRedPacket
import GameFuncComm
import PlayerTeam
import ChPlayer
import time
#---------------------------------------------------------------------
#获取vip升级所需累计经验字典 key-等级,value-经验
def GetVIPLvUpExp():
    return IpyGameDataPY.GetFuncEvalCfg("VIPLV", 1, {})
#获取VIP每日经验
def GetVIPDayExp():
    return IpyGameDataPY.GetFuncCfg("VIPLV", 2)
#获取vip价格
def GetVIPPrice(cardType):
    priceDict = IpyGameDataPY.GetFuncEvalCfg("VIPPrice", 1, {})
    return priceDict.get(cardType, 0)
#获取VIP卡对应的时间(小时)
def GetVIPTime(cardType):
    timeDict = IpyGameDataPY.GetFuncEvalCfg("VIPPrice", 2, {})
    return timeDict.get(cardType, 0)
#获取VIP等级对应的称号
def GetVIPTitle():
    titleDict = IpyGameDataPY.GetFuncEvalCfg("VIPTitle", 1, {})
    return titleDict
#获取VIP时间的上限
def GetVIPMaxTime():
    maxDay = IpyGameDataPY.GetFuncCfg("VIPLimit", 1)
    maxHour = maxDay * 24
    return GetSeconds(maxHour)
#根据小时获得秒
def GetSeconds(hour):
    return hour * 60 * 60
#获取邮件的格式和天数
def GetMailMessage():
    maxDay = IpyGameDataPY.GetFuncCfg("VIPLimit", 2)
    return maxDay
#获取首次买卡获得的经验
def GetFirstBuyExp(cardType):
    buyDict = IpyGameDataPY.GetFuncEvalCfg("VIPLimit", 4, {})
    return buyDict.get(cardType, 0)
## A8 01 封包
## 购买VIP时间
#  @param None
#  @return None
#struct tagCMBuyVipLV
#{
#    tagHead    Head;
#    BYTE VipType;    // vip卡类型
#};
def BuyVipLV(index, clientPack, tick):
    return
#    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
#    buyType = clientPack.VipType
#    price = GetVIPPrice(buyType)
#    if not price:
#        return
#    vipTime = GetVIPTime(buyType)
#    if not vipTime:
#        return
#
#    haveVipTime = GetCurVIPTime(curPlayer)
#    maxTime = GetVIPMaxTime()
#    if haveVipTime >= maxTime:
#        GameWorld.DebugLog("VIP时间已经到达最大上限,不可继续购买--time:%s" % haveVipTime)
#        return
#    #有道具扣道具,没有道具扣钱
#    vipCardItemIDDict = IpyGameDataPY.GetFuncEvalCfg('VIPCard', 1)
#    needItemID = vipCardItemIDDict.get(buyType)
#    if not needItemID:
#        return
#    itemPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptItem)
#    hasEnough, itemList = ItemCommon.GetItem_FromPack_ByID(needItemID, itemPack, 1)
#    if hasEnough:
#        ItemCommon.ReduceItem(curPlayer, itemPack, itemList, 1, False)
#        PlayerControl.NotifyCode(curPlayer, 'VipCardHint3', [needItemID])
#    else:
#        infoDict = {"VIPType":buyType}
#        if not PlayerControl.PayMoney(curPlayer, IPY_GameWorld.TYPE_Price_Gold_Money, price, ChConfig.Def_Cost_OpenNoble, infoDict):
#            GameWorld.DebugLog("仙玉不足!costGold=%s" % price)
#            return
#
#    record = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_VipBuyRecord)
#    hasBuy = record & pow(2, buyType)
#    if not hasBuy:
#        addExp = GetFirstBuyExp(buyType)
#        AddVIPExp(curPlayer, addExp)
#        GameWorld.DebugLog("首次买卡--type:%s" % buyType)
#        record = record|(1 << buyType)
#        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_VipBuyRecord, record)
#    addTime = GetSeconds(vipTime)
#    AddVIPTime(curPlayer, addTime, "buyVIPCard")
#    return
##检查VIP称号
#  @param curPlayer
#  @return None
def CheckVIPDienstgrad(curPlayer):
    playerVIPLV = curPlayer.GetVIPLv()
    if playerVIPLV <= 0:
        return
    vipDienstgradDict = GetVIPTitle()
    for vipLV, dienstgradID in vipDienstgradDict.items():
        if playerVIPLV < vipLV:
            break
        curDienstgrad = curPlayer.GetDienstgradManager().GetDienstgrad(dienstgradID)
        # 不存在该VIP称号则添加
        if curDienstgrad == None:
            PlayerDienstgrad.PlayerAddDienstgrad(curPlayer, dienstgradID)
            GameWorld.DebugLog("CheckVIPDienstgrad playerVIPLV=%s,vipLV=%s,dienstgradID=%s"
                               % (playerVIPLV, vipLV, dienstgradID), curPlayer.GetPlayerID())
    return
## 购买消费VIP礼包
#  @param index
#  @param clientPack <VIPLV-VIP等级>
#  @param tick
#  @return
def BuyVIPItem(index, clientPack, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    vipLV = clientPack.VIPLV
    awardMsg = IpyGameDataPY.GetIpyGameData('VIPAward', vipLV)
    if not awardMsg:
        GameWorld.DebugLog("没有vip等级为%s的礼包" % vipLV)
        return
    curVipLV = curPlayer.GetVIPLv()
    if curVipLV < vipLV:
        GameWorld.DebugLog("VIP等级不足--VIPLV:%s" % curVipLV)
        return
    record = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_VipAwardRecord)
    hasBuy = record & pow(2, vipLV)
    if hasBuy:
        GameWorld.DebugLog("vip等级为%s的礼包已经购买过,不能重复购买" % vipLV)
        return
    tatalItemDict = awardMsg.GetItemID()
    playerJob = str(curPlayer.GetJob())
    if playerJob not in tatalItemDict:
        GameWorld.DebugLog("没有该职业的礼包信息-职业:%s--%s" % (playerJob, str(tatalItemDict)))
        return
    itemList = tatalItemDict[playerJob]
    needSpace = len(itemList)
    packSpace = ItemCommon.GetItemPackSpace(curPlayer, IPY_GameWorld.rptItem, needSpace)
    if needSpace > packSpace:
        PlayerControl.NotifyCode(curPlayer, "GeRen_chenxin_676165", [IPY_GameWorld.rptItem])
        return
    itemPrice = awardMsg.GetPrice()
    infoDict = {"VIPLV":vipLV}
    if not PlayerControl.PayMoney(curPlayer, IPY_GameWorld.TYPE_Price_Gold_Money, itemPrice, ChConfig.Def_Cost_BuyVIPItem, infoDict):
        GameWorld.DebugLog("仙玉不足!costGold=%s" % itemPrice)
        return
    record = record|(1 << vipLV)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_VipAwardRecord, record)
    EventShell.EventResponse_BuyVIPItem(curPlayer, vipLV)
    GameWorld.DebugLog("vip礼包-%s" % itemList)
    for itemid, cnt, isBind in itemList:
        ItemControler.GivePlayerItem(curPlayer, int(itemid), int(cnt), 0, [IPY_GameWorld.rptItem, IPY_GameWorld.rptAnyWhere],
                                     event=["BuyVIPGift", False, {"VIPLV":vipLV}])
#    else:
#        __AwardToPlayerByMail(curPlayer, itemList)
    ItemControler.NotifyGiveAwardInfo(curPlayer, itemList, "BuyVIPGift")
    openuiid = IpyGameDataPY.GetFuncEvalCfg('VIPPanel', 1, {}).get(vipLV, 0)
    PlayerControl.WorldNotify(0, 'BuyVIPGift', [curPlayer.GetName(), vipLV, itemList[0][0], openuiid])
    Sycn_VIPAwardRecord(curPlayer)
    return
#发邮件
def __AwardToPlayerByMail(curPlayer, mailItemInfoList):
    MailMessage = GetMailMessage()
    content = ShareDefine.Def_MailFormat % (MailMessage[0], '')
    getDays = MailMessage[1]
    PlayerControl.SendMail('', content, getDays, [curPlayer.GetPlayerID()], mailItemInfoList)
##VIP登录处理
#  @param curPlayer
#  @return None
def DoOnLogin(curPlayer, tick):
    #记录登陆时间
    Sycn_VIPMsg(curPlayer)
    Sycn_VIPAwardRecord(curPlayer)
    Sycn_VIPTime(curPlayer, True)
    SyncVIPKillNPCLVInfo(curPlayer)
    return
#-------------------------------------------------------------------------------
#VIP每日处理
def VipOnDay(curPlayer):
    return
#    vipTime = PlayerControl.GetVIPExpireTime(curPlayer)
#    if not vipTime:
#        return
#    vipStr = GameWorld.ChangeTimeNumToStr(vipTime, timeFormat=ChConfig.TYPE_Time_Format)
#    vipZeroTime = GetZeroTime(vipStr)
#    curZeroTime = GetZeroTime(GameWorld.GetCurrentDataTimeStr())
#    lastTime = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_VIPLastTime)
#    if lastTime == 0:
#        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_VIPLastTime, curZeroTime)
#
#    if vipZeroTime >= curZeroTime:
#        n = (curZeroTime - lastTime) / (24 * 60 * 60)
#    elif vipZeroTime > lastTime:
#        n = (vipZeroTime - lastTime) / (24 * 60 * 60)
#    else:
#        n = 0
#    AddVIPExp(curPlayer, GetVIPDayExp() * n)
#    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_VIPLastTime, curZeroTime)
#根据时间获得当天的零点时间
def GetZeroTime(strTick):
    tickList = strTick.split(' ')
    newStrTick = tickList[0] + ' ' + '00:00:00'
    return GameWorld.ChangeTimeStrToNum(newStrTick)
## 直升VIP等级
def UpgradeVIPLV(curPlayer, tagVIPLV):
    befVIPLV = curPlayer.GetVIPLv()
    if befVIPLV >= tagVIPLV:
        GameWorld.DebugLog("已经达到该VIP等级!不需要处理")
        return True, 0
    vipExpDict = GetVIPLvUpExp()
    if tagVIPLV not in vipExpDict:
        GameWorld.ErrLog("没有该VIP等级,无法直升! tagVIPLV=", tagVIPLV);
        return False, 0
    tagVIPExp = vipExpDict[tagVIPLV]
    vipExp = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_VipExp)
    addExp = tagVIPExp - vipExp
    return AddVIPExp(curPlayer, addExp), addExp
#VIP经验增加入口
def AddVIPExp(curPlayer, exp):
    if exp <= 0:
        return
    vipExp = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_VipExp) + exp
    preVIPLV = curPlayer.GetVIPLv()
    vipLV = preVIPLV + 1
    vipExpDict = GetVIPLvUpExp()
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_VipExp, vipExp)
    if vipLV not in vipExpDict:
        GameWorld.DebugLog("vip已经满级--vipLV:%s" % (vipLV - 1))
        Sycn_VIPMsg(curPlayer)
        return
    while vipLV in vipExpDict and vipExp >= vipExpDict[vipLV]:
        curPlayer.SetVIPLv(vipLV)
        PlayerControl.SetVIPLVUpTime(curPlayer, int(time.time()))
        OnChangeVIPLv(curPlayer, vipLV) ##当VIP等级变更,触发的方法写在这里
        PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_VIPLV, 1, [vipLV])
        vipLV += 1
    GameWorld.DebugLog("VIP等级--%s,addExp--%s,经验--%s" % (curPlayer.GetVIPLv(), exp, vipExp))
    Sycn_VIPMsg(curPlayer)
    if not preVIPLV:
        Sycn_VIPTime(curPlayer)
    DataRecordPack.DR_VIPChange(curPlayer, "addVIPExp", {"Viplv":curPlayer.GetVIPLv(), 'VipExp':vipExp})
    return True
##当VIP等级变更,触发的方法写在这里
# @param curPlayer 玩家
# @return None
def OnChangeVIPLv(curPlayer, vipLV):
    #vip等级改变触发任务
    EventShell.EventResponse_OnVipLvUp(curPlayer, vipLV)
    CheckVIPDienstgrad(curPlayer)
    #删除VIP体验卡物品
    #__DelVIPExperienceItem(curPlayer)
    RefreshVIPAttr(curPlayer)
    EventReport.WriteEvent_VIP(curPlayer)
    #红包奖励
    redPacketID = IpyGameDataPY.GetFuncEvalCfg('VIPRedPackAward', 1, {}).get(vipLV, 0)
    if redPacketID:
        PlayerFamilyRedPacket.CreatRedPacketByID(curPlayer, redPacketID)
    GameFuncComm.DoFuncOpenLogic(curPlayer)
    if not curPlayer.GetTeam():
        PlayerTeam.RefreshTeamVIPBuff_OnNoTeam(curPlayer, GameWorld.GetGameWorld().GetTick())
    return
#通知玩家购买礼包纪录
def Sycn_VIPAwardRecord(curPlayer):
    pack = ChPyNetSendPack.tagMCVIPAwardMsg()
    pack.AwardMsg = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_VipAwardRecord)
    GameWorld.DebugLog("领取记录!--%s" % pack.AwardMsg)
    NetPackCommon.SendFakePack(curPlayer, pack)
#通知vip经验和等级
#Exp  --vip经验
#BuyState --vip等级
def Sycn_VIPMsg(curPlayer):
    pack = ChPyNetSendPack.tagMCVIPInfo()
    pack.Exp = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_VipExp)
    pack.VIPLV = curPlayer.GetVIPLv()
    NetPackCommon.SendFakePack(curPlayer, pack)
#通知VIP剩余时间
def Sycn_VIPTime(curPlayer, islogin=False, isForce=False):
    pack = ChPyNetSendPack.tagMCNotifyVipTime()
    pack.Time = GetCurVIPTime(curPlayer, islogin)
    pack.ExperienceTime = GetVIPExperienceTime(curPlayer, islogin)
    if pack.Time > 0 or pack.ExperienceTime > 0 or isForce:
        NetPackCommon.SendFakePack(curPlayer, pack)
#唯一获取实时的VIP时间的方法,不能直接通过 PlayerControl.GetVIPExpireTime(curPlayer) 获取
def GetCurVIPTime(curPlayer, islogin=False):
    return 1
#    vipTime = PlayerControl.GetVIPExpireTime(curPlayer)
#    curTime = GameWorld.ChangeTimeStrToNum(GameWorld.GetCurrentDataTimeStr())
#    if vipTime <= curTime:
#        if vipTime:
#            timeoutRecord = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_VipTimeOutRecord)
#            # 常规过期处理
#            if not timeoutRecord:
#                GameWorld.DebugLog("VIP过期处理: vipTime=%s,curTime=%s" % (vipTime, curTime), curPlayer.GetPlayerID())
#                # 过期变更处理
#                PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_VipTimeOutRecord, 1)
#                #Operate_EquipStone.OnVIPTimeOut(curPlayer)
#                RefreshVIPAttr(curPlayer)
#
#            # 登录状态下额外处理
#            if islogin and timeoutRecord != 2:
#                GameWorld.DebugLog("VIP过期登录处理: vipTime=%s,curTime=%s" % (vipTime, curTime), curPlayer.GetPlayerID())
#                PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_VipTimeOutRecord, 2)
#                PlayerControl.NotifyCode(curPlayer, 'Vip_Timeout')
#        return 0
#    else:
#        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_VipTimeOutRecord, 0)
#        return vipTime - curTime
#    return vipTime
#增加VIP时间
# addTime 单位秒
def AddVIPTime(curPlayer, addTime, addType="buyVIPTime"):
#    isReActivate = False # 是否重新激活的
#    haveVipTime = GetCurVIPTime(curPlayer)
#    if not haveVipTime:
#        isReActivate = True
#        curZeroTime = GetZeroTime(GameWorld.GetCurrentDataTimeStr())
#        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_VIPLastTime, curZeroTime)
#    haveVipTime += addTime
#    if haveVipTime > ShareDefine.Def_UpperLimit_DWord:
#        haveVipTime = ShareDefine.Def_UpperLimit_DWord
#    curTime = GameWorld.ChangeTimeStrToNum(GameWorld.GetCurrentDataTimeStr())
#    totalTime = curTime + haveVipTime
#    PlayerControl.SetVIPExpireTime(curPlayer, totalTime)
#    timeDict = {"oldTime":haveVipTime, "newTime":totalTime, "addTime":addTime, "addType":addType}
#    DataRecordPack.DR_VIPTimeChange(curPlayer, "addVIPTime", timeDict)
#    GameWorld.DebugLog("到期时间--%s" % GameWorld.ChangeTimeNumToStr(totalTime, timeFormat=ChConfig.TYPE_Time_Format))
#    Sycn_VIPTime(curPlayer)
#    if isReActivate:
#        RefreshVIPAttr(curPlayer)
    return True
#def __DelVIPExperienceItem(curPlayer):
#    ## VIP变更时删除背包和仓库的vip体验卡
#    for packIndex in [IPY_GameWorld.rptItem, IPY_GameWorld.rptWarehouse]:
#        curPack = curPlayer.GetItemManager().GetPack(packIndex)
#        for i in range(0, curPack.GetCount()):
#            curItem = curPack.GetAt(i)
#            if not curItem:
#                continue
#
#            if curItem.GetItemTypeID() != ChConfig.Def_ItemID_VIPExperience:
#                continue
#
#            itemCount = curItem.GetCount()
#            ItemCommon.DelItem(curPlayer, curItem, itemCount, True, "DelVIPExperienceItem")
#
#    return
def UseItemVIPExperience(curPlayer):
    ## 使用vip体验卡
    if curPlayer.GetVIPLv():
        PlayerControl.NotifyCode(curPlayer, 'VipCardHint2')
        return
    #学习龙凤镯技能,失效后再删除
    PlayerMagicWeapon.GiveSkill(curPlayer, ChConfig.Def_SkillID_LFZ, GameWorld.GetGameWorld().GetTick(), False)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_VipExperienceStartTime, int(time.time()))
    Sycn_VIPTime(curPlayer)
    PlayerControl.NotifyCode(curPlayer, 'VipCardHint1')
    return True
def CheckVIPExperience(curPlayer, tick):
    ## 检查vip体验是否结束
    startTime = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_VipExperienceStartTime)
    if not startTime:
        return
    if not GameWorld.CheckPlayerTick(curPlayer, ChConfig.TYPE_Player_Tick_VIPExperience, tick):
        return
    if not GetVIPExperienceTime(curPlayer):
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_VipExperienceStartTime, 0)
        if curPlayer.GetVIPLv() == 0:
            PlayerControl.NotifyCode(curPlayer, 'VipTiyan_Timeout')
        Sycn_VIPTime(curPlayer, isForce=True)
        GameWorld.DebugLog('    VIP体验卡结束!', curPlayer.GetID())
        #删除体验技能
        skillManager = curPlayer.GetSkillManager()
        if skillManager.FindSkillBySkillTypeID(ChConfig.Def_SkillID_LFZ):
            skillManager.DeleteSkillBySkillTypeID(ChConfig.Def_SkillID_LFZ)
            # 重刷被动技能
            PassiveBuffEffMng.GetPassiveEffManager().RegistPassiveEff(curPlayer)
            # 重刷技能战力
            PlayerControl.PlayerControl(curPlayer).RefreshAllSkill()
            return True
    return
def GetVIPExperienceTime(curPlayer, isLogin=False):
    ## 是否VIP体验中
    startTime = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_VipExperienceStartTime)
    if not startTime:
        return 0
    if curPlayer.GetVIPLv():
        return 0
    curTime = int(time.time())
    experienceTime = IpyGameDataPY.GetFuncCfg('VIPExperience', 2)
    if curTime - startTime >= experienceTime:
        return 0
    return experienceTime - (curTime - startTime)
#根据特权ID 和 VIP等级获得特权值
#tequanID   特权ID
#playerVipLv 玩家VIP等级,获得对应vip等级的特权值,-1时获得玩家VIP等级对应的特权值
def GetPrivilegeValue(curPlayer, privilegeID, playerVipLv=-1, isCheckTime=True):
    #if privilegeID not in ChConfig.VIPPrivilegeList:
    #    return 0
    if not privilegeID:
        return 0
    isExperience = False
    if playerVipLv != -1:
        vipLV = playerVipLv
    elif GetVIPExperienceTime(curPlayer):
        isExperience = True
        VIPExperiencePrivilegeDict = IpyGameDataPY.GetFuncCfg('VIPExperience', 1)
        vipLV = VIPExperiencePrivilegeDict.get(privilegeID, 0)
    else:
        vipLV = curPlayer.GetVIPLv()
    vipMsg = IpyGameDataPY.GetIpyGameData('VipPrivilege', privilegeID)
    if not vipMsg:
        return 0
    priVlaue = getattr(vipMsg, 'GetVIP%d' % vipLV)()
    if not isCheckTime:
        return priVlaue
    if vipLV and GetCurVIPTime(curPlayer) <= 0 and playerVipLv == -1 and not isExperience:
        priVlaue = vipMsg.GetVIP0()
    return priVlaue
#获取VIP特权表特权数据
def GetVipPrivilegeData(privilegeID):
    return IpyGameDataPY.GetIpyGameData('VipPrivilege', privilegeID)
#---------------------------------------------------------------------
##获取当前储值应该拥有的VIP等级
def RefreshVIPAttr(curPlayer):
    CalcVIPAttr(curPlayer)
    PlayerControl.PlayerControl(curPlayer).RefreshPlayerAttrState()
    return
def CalcVIPAttr(curPlayer):
    allAttrList = [{} for _ in range(4)]
    # 属性需要判断是否过期
    #if GetPrivilegeValue(curPlayer, ChConfig.VIPPrivilege_VIPKillNPCAddAtk):
    mwID = IpyGameDataPY.GetFuncCfg("VIPAddAtkEXP", 2) # VIP杀怪加属性所需激活法宝
    if PlayerMagicWeapon.GetIsActiveMagicWeapon(curPlayer, mwID):
        killLV = GetVIPKillNPCLV(curPlayer)
        killLVIpyData = IpyGameDataPY.GetIpyGameData("VIPKillNPC", killLV)
        if killLVIpyData:
            PlayerControl.CalcAttrDict_Type(ShareDefine.Def_Effect_MinAtk, killLVIpyData.GetAddMinAtk(), allAttrList)
            PlayerControl.CalcAttrDict_Type(ShareDefine.Def_Effect_MaxAtk, killLVIpyData.GetAddMaxAtk(), allAttrList)
    PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_VIP, allAttrList)
    return
#// A8 05 VIP杀怪等级信息同步开关 #tagCMVIPKillNPCLVInfoSwitch
#
#struct    tagCMVIPKillNPCLVInfoSwitch
#{
#    tagHead        Head;
#    BYTE        IsOn;    // 是否开启同步
#};
def OnVIPKillNPCLVInfoSwitch(index, clientPack, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    isOn = clientPack.IsOn
    curPlayer.SetDict(ChConfig.Def_PlayerKey_SyncVIPKillNPCLVInfo, isOn)
    if isOn:
        SyncVIPKillNPCLVInfo(curPlayer)
    GameWorld.DebugLog("VIP杀怪等级信息同步开关, isOn=%s" % isOn, curPlayer.GetPlayerID())
    return
def DoAddVIPKillLVExp(curPlayer, npcLV, killCount=1):
    ''' 击杀NPC增加VIP杀怪等级经验,只算击杀的,队员击杀无效
    '''
    # 过期时也有效
    #if not GetPrivilegeValue(curPlayer, ChConfig.VIPPrivilege_VIPKillNPCAddAtk, isCheckTime=False):
    #    return
    mwID = IpyGameDataPY.GetFuncCfg("VIPAddAtkEXP", 2) # VIP杀怪加属性所需激活法宝
    if not mwID or not PlayerMagicWeapon.GetIsActiveMagicWeapon(curPlayer, mwID):
        return
    addExp = eval(IpyGameDataPY.GetFuncCompileCfg("VIPAddAtkEXP", 1))
    addExp *= killCount
    if not addExp:
        return
    totalKillLVExp = GetVIPKillNPCLVExp(curPlayer) + addExp
    # 满级也继续加
    befKillLV = GetVIPKillNPCLV(curPlayer)
    maxKillLV = IpyGameDataPY.IPY_Data().GetVIPKillNPCCount()
    aftKillLV = befKillLV
    # 非满级才处理升级逻辑
    if befKillLV < maxKillLV:
        aftKillLV, totalKillLVExp = __DoVIPKillNPCLVUp(curPlayer, befKillLV, maxKillLV, totalKillLVExp)
    totalKillLVExp = SetVIPKillNPCLVExp(curPlayer, totalKillLVExp)
    #GameWorld.DebugLog("杀怪增加VIP杀怪等级经验: npcLV=%s,addExp=%s,totalKillLVExp=%s,befKillLV=%s,aftKillLV=%s,maxKillLV=%s"
    #                   % (npcLV, addExp, totalKillLVExp, befKillLV, aftKillLV, maxKillLV), curPlayer.GetPlayerID())
    #同步客户端
    if curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_SyncVIPKillNPCLVInfo) or befKillLV != aftKillLV:
        SyncVIPKillNPCLVInfo(curPlayer)
    return
def __DoVIPKillNPCLVUp(curPlayer, befKillLV, maxKillLV, totalKillLVExp):
    ## 处理VIP击杀NPC等级升级
    aftKillLV = befKillLV
    killLVIpyData = IpyGameDataPY.GetIpyGameData("VIPKillNPC", aftKillLV)
    if killLVIpyData:
        lvUPNeedExp = killLVIpyData.GetLVExpPoint() * ChConfig.Def_PerPointValue + killLVIpyData.GetLVExp()
        while killLVIpyData and totalKillLVExp >= lvUPNeedExp:
            totalKillLVExp -= lvUPNeedExp
            aftKillLV += 1
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_VIPKillLV, aftKillLV)
            if aftKillLV >= maxKillLV:
                break
            killLVIpyData = IpyGameDataPY.GetIpyGameData("VIPKillNPC", aftKillLV)
            if killLVIpyData:
                lvUPNeedExp = killLVIpyData.GetLVExpPoint() * ChConfig.Def_PerPointValue + killLVIpyData.GetLVExp()
    if befKillLV != aftKillLV:
        RefreshVIPAttr(curPlayer)
    return aftKillLV, totalKillLVExp
def GetVIPKillNPCLV(curPlayer): return max(1, curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_VIPKillLV))
def GetVIPKillNPCLVExp(curPlayer):
    exp = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_VIPKillLVExp)
    expPoint = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_VIPKillLVExpPoint)
    return expPoint * ChConfig.Def_PerPointValue + exp
def SetVIPKillNPCLVExp(curPlayer, totalKillLVExp):
    totalKillLVExp = min(totalKillLVExp, ChConfig.Def_HugeValue)
    updExp = totalKillLVExp % ChConfig.Def_PerPointValue
    updExpPoint = totalKillLVExp / ChConfig.Def_PerPointValue
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_VIPKillLVExp, updExp)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_VIPKillLVExpPoint, updExpPoint)
    return totalKillLVExp
def SyncVIPKillNPCLVInfo(curPlayer):
    killLVInfo =ChPyNetSendPack.tagMCVIPKillNPCLVInfo()
    killLVInfo.KillLV = GetVIPKillNPCLV(curPlayer)
    killLVInfo.KillLVExpPoint = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_VIPKillLVExpPoint)
    killLVInfo.KillLVExp = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_VIPKillLVExp)
    NetPackCommon.SendFakePack(curPlayer, killLVInfo)
    return
#===============================================================================
# // A8 06 查询充值结果 #tagCMQueryRecharge