hxp
2019-01-29 5300950136a7d0556945fbd0cb953b331ee79f2c
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamilyRedPacket.py
@@ -31,16 +31,22 @@
import time
import random
import datetime
'''
红包暂定有效期24小时,过天清除过期的红包,如果是玩家发放的返还未领取的货币
上线同步所有红包信息,红包变化实时广播全服在线玩家
'''
#Def_UniversalGameRecType_FamilyRedPacketAllRecord
#value1    红包唯一ID
#value2    家族ID
#Time      创建红包时间,非红包实际开放领取时间,如果红包表有配置系统发放时间,则该时间存配表时间,没有的话存创建时的服务器时间
#value1    红包唯一ID,该ID为实例ID,非配表的红包ID
#value2    家族ID,0代表全服红包
#value3    总额度*10+金钱类型
#value4    ״̬
#value5    时间,用来判断是否过期删除的
#strValue1 创建者ID|创建者名字|创建者职业|获得途径
#value5    时间,用来判断是否过期删除的,实际开放该红包领取的时间
#strValue1 创建者ID|创建者名字|创建者职业|获得途径(红包类型)
#strValue2 可抢总个数
#strValue3 祝福语
#strValue3 祝福语,玩家自己编辑的内容
#Def_UniversalGameRecType_FamilyRedPacketGrabRecord
#value1    红包唯一ID
@@ -59,7 +65,10 @@
g_allRecordDict = {} #{红包ID:recData, ...}
g_grabDataDict = {} #{红包ID:{playerid:[抢到的钱,名字,job]}, ...}
g_osRedCnt = 0 #开服红包个数
g_redPackCountDict = {} #有限制最大红包个数的类型对应当前红包数 {类型组对应记录编号:当前个数, ...}
DBKey_RedPacketSend = "RedPacketSend_%s" # 系统定时红包是否已发放, 参数红包ID
## 玩家登录
#  @param None
#  @return None
@@ -76,14 +85,157 @@
    
    return
##---------------------------------------- 节日红包 -----------------------------------------------
def OnResetFeastRedPacket(ipyData):
    ## 重置节日红包状态
    if not ipyData:
        return
    dayRedPackIDList = ipyData.GetRedPacketIDList()
    GameWorld.DebugLog("重置红包发放状态: dayRedPackIDList=%s" % dayRedPackIDList)
    for redPackIDList in dayRedPackIDList:
        for redPackID in redPackIDList:
            if PlayerDBGSEvent.GetDBGSTrig_ByKey(DBKey_RedPacketSend % redPackID):
                PlayerDBGSEvent.SetDBGSTrig_ByKey(DBKey_RedPacketSend % redPackID, 0)
    return
def __GetTodayRedPacketByTimeList():
    key = "TodayRedPacketByTime"
    openServerDay = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_ServerDay) + 1
    TodayRedPacketByTimeInfo = IpyGameDataPY.GetConfigEx(key)
    if TodayRedPacketByTimeInfo and TodayRedPacketByTimeInfo[0] == openServerDay:
        #GameWorld.DebugLog("已经加载过本日系统定时发放的红包! openServerDay=%s" % openServerDay)
        return TodayRedPacketByTimeInfo[1]
    redPacketByTimeList = []
    serverTime = GameWorld.GetServerTime()
    GameWorld.Log("===== 加载今天系统定时发放红包信息 ===== openServerDay=%s" % openServerDay)
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for index in xrange(ipyDataMgr.GetFamilyRedPackCount()):
        ipyData = ipyDataMgr.GetFamilyRedPackByIndex(index)
        redPackID = ipyData.GetID()
        openTimeStr = ipyData.GetPacketOpenTime()
        if not openTimeStr:
            #GameWorld.DebugLog("非定时发放的红包!redPackID=%s" % (redPackID))
            continue
        openDateTime = datetime.datetime.strptime("%s:00" % openTimeStr, ChConfig.TYPE_Time_Format)
        if openDateTime.year != serverTime.year or openDateTime.month != serverTime.month or openDateTime.day != serverTime.day:
            #GameWorld.DebugLog("非今日定时发放的红包!redPackID=%s" % (redPackID))
            continue
        endDateTime = None
        validMinutes = ipyData.GetValidMinutes()
        if validMinutes:
            endDateTime = openDateTime +  + datetime.timedelta(minutes=validMinutes)
        redPacketByTimeList.append([redPackID, openDateTime, endDateTime])
        GameWorld.Log("    增加本日定时发放系统红包信息: redPackID=%s, %s" % (redPackID, openTimeStr))
    TodayRedPacketByTimeInfo = IpyGameDataPY.SetConfigEx(key, [openServerDay, redPacketByTimeList])
    GameWorld.Log("本日系统定时发放的红包加载完毕!")
    GameWorld.Log("=============================================================")
    return TodayRedPacketByTimeInfo[1]
def OnRedPacketMinuteProcess():
    ## 每分钟处理,定时发放系统红包
    todayRedPacketByTimeList = __GetTodayRedPacketByTimeList()
    if not todayRedPacketByTimeList:
        return
    serverTime = GameWorld.GetServerTime()
    for redPacketOpenInfo in todayRedPacketByTimeList:
        redPackID, openDateTime, endDateTime = redPacketOpenInfo
        if serverTime < openDateTime or (endDateTime and serverTime >= endDateTime):
            #GameWorld.DebugLog("非红包发放时段!  redPackID=%s, openDateTime=%s, endDateTime=%s" % (redPackID, openDateTime, endDateTime))
            continue
        if PlayerDBGSEvent.GetDBGSTrig_ByKey(DBKey_RedPacketSend % redPackID):
            #GameWorld.DebugLog("红包已发放过! redPackID=%s" % (redPackID))
            continue
        CreateSystemRedPacket(redPackID)
    return
def Sync_FeastRedPacket(ipyData, curPlayer=None):
    ## 同步节日红包活动信息
    if not ipyData:
        return
    openServerDay = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_ServerDay) + 1
    feastPack = ChPyNetSendPack.tagGCFeastRedPacketInfo()
    feastPack.StartDate = GameWorld.GetOperationActionDateStr(ipyData.GetStartDate(), openServerDay)
    feastPack.EndtDate = GameWorld.GetOperationActionDateStr(ipyData.GetEndDate(), openServerDay)
    feastPack.LimitLV = ipyData.GetLVLimit()
    feastPack.ResetType = ipyData.GetResetType()
    feastPack.RedPacketDayList = []
    for redPacketIDList in ipyData.GetRedPacketIDList():
        dayInfo = ChPyNetSendPack.tagGCFeastRedPacketDay()
        dayInfo.RedPacketIDList = redPacketIDList
        dayInfo.RedPacketCount = len(dayInfo.RedPacketIDList)
        feastPack.RedPacketDayList.append(dayInfo)
    feastPack.RedPacketDays = len(feastPack.RedPacketDayList)
    if not curPlayer:
        # 全服广播在线玩家
        playerManager = GameWorld.GetPlayerManager()
        for i in xrange(playerManager.GetActivePlayerCount()):
            curPlayer = playerManager.GetActivePlayerAt(i)
            if curPlayer == None or not curPlayer.GetInitOK():
                continue
            NetPackCommon.SendFakePack(curPlayer, feastPack)
    else:
        NetPackCommon.SendFakePack(curPlayer, feastPack)
    return
##--------------------------------------------------------------------------------------------------
def CreateSystemRedPacket(redPackID):
    ## 发放系统红包
    ipyData = IpyGameDataPY.GetIpyGameData('FamilyRedPack', redPackID)
    if not ipyData:
        return
    getType = ipyData.GetGetType()
    moneyType = ipyData.GetMoneyType()
    outputNum = ipyData.GetMoneyNum()
    packetCnt = ipyData.GetPacketCnt()
    openTime = ipyData.GetPacketOpenTime() # 如果有指定发放时间的
    sysCreateTime = GameWorld.ChangeTimeStrToNum("%s:00" % openTime) if openTime else None
    state = State_NoGot # 暂直接设定已发放
    if ipyData.GetPacketOpenTime():
        PlayerDBGSEvent.SetDBGSTrig_ByKey(DBKey_RedPacketSend % redPackID, 1)
        GameWorld.DebugLog("定时发放的红包,设置已发放! redPackID=%s" % redPackID)
    job = 0
    jobRank = 0
    playerName = ""
    playerID = 0
    familyID = 0
    family = None
    redPacketRecData = __SaveNewRedRecord(familyID, playerID, playerName, job, jobRank, getType, moneyType, outputNum, packetCnt, state, sysCreateTime=sysCreateTime)
    #֪ͨ
    __NotifyFamilyRedPacketInfo(family, redPacketRecData, [])
    return
## 生成新红包
def CreatFamilyRedPacket(msgList):
    playerID, getType, packetCnt, moneyType, outputNum, wishStr, state, data = msgList
def MapServer_CreatRedPacket(msgList):
    playerID, getType, packetCnt, moneyType, outputNum, wishStr, state, data, isFamilyRedPacket = msgList
    curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
    if not curPlayer:
        return
    if getType == IpyGameDataPY.GetFuncCfg('OpenServerRedPacketType'):
    if not isFamilyRedPacket:
        familyID = 0
        family = None
    else:
@@ -113,7 +265,10 @@
            elif data in IpyGameDataPY.GetFuncEvalCfg('OSRSuccess'):
                PlayerControl.WorldNotify(0, 'OpenRedBag3', [playerName, data, outputNum])
            #大于200额度的红包
            if outputNum >= IpyGameDataPY.GetFuncCfg('OpenServerRedPacketRain'):
            getTypeRainDict = IpyGameDataPY.GetFuncEvalCfg('OpenServerRedPacketRain', 2, {})
            if str(getType) in getTypeRainDict:
                PlayerControl.WorldNotify(0, getTypeRainDict[str(getType)])
            elif outputNum >= IpyGameDataPY.GetFuncCfg('OpenServerRedPacketRain'):
                PlayerControl.WorldNotify(0, 'OSRedpackSfx')
    return
@@ -144,19 +299,21 @@
    return
## 记录新红包数据
def __SaveNewRedRecord(familyID, ownerid, playerName, job, jobRank, getType, moneyType, outputNum, packetCnt,state=State_NoSend, wishStr=''):
def __SaveNewRedRecord(familyID, ownerid, playerName, job, jobRank, getType, moneyType, outputNum, packetCnt,state=State_NoSend, wishStr='', sysCreateTime=None):
    global g_allRecordDict
    global g_osRedCnt
    global g_redPackCountDict
    job = job + jobRank * 10   #个位是job 十位百位是jobrank
    recordType = ShareDefine.Def_UniversalGameRecType_FamilyRedPacketAllRecord
    universalRecMgr = GameWorld.GetUniversalRecMgr()
    recordList = universalRecMgr.GetTypeList(recordType)
    if getType == IpyGameDataPY.GetFuncCfg('OpenServerRedPacketType'):
        if not __CheckOSRedPacketCnt(recordList):
            return
        if g_osRedCnt:
            g_osRedCnt += 1
    for maxCountKeyNum, getTypeList in ShareDefine.RedPackMaxCountDict.items():
        if getType in getTypeList:
            if not __CheckOSRedPacketCnt(recordList, maxCountKeyNum, getTypeList):
                return
            g_redPackCountDict[maxCountKeyNum] = g_redPackCountDict.get(maxCountKeyNum, 0) + 1
            GameWorld.DebugLog("当前红包数: g_redPackCountDict=%s" % g_redPackCountDict)
            break
    recData = recordList.AddRec()
    
    
@@ -169,29 +326,29 @@
    PlayerDBGSEvent.SetDBGSTrig_ByKey(DB_RedPacketID, redPacketID)
    
    curTimeNum = int(time.time())
    recData.SetTime(curTimeNum)
    recData.SetTime(sysCreateTime if sysCreateTime else curTimeNum) # 为方便前端对比配表设置的发放红包时间,如果有配置的时间,则创建时间默认取配表的
    recData.SetValue1(redPacketID) #红包唯一ID
    recData.SetValue2(familyID)  #家族ID   
    recData.SetValue3(moneyType + outputNum * 10) #总额度*10+金钱类型
    recData.SetValue4(state) #是否已发
    recData.SetValue5(curTimeNum)
    recData.SetValue5(curTimeNum) #该时间为开放领取的时间,不一定等于创建时间
    recData.SetStrValue1('%s|%s|%s|%s'%(ownerid,playerName,job,getType)) #创建者ID|创建者名字|创建者职业|途径
    recData.SetStrValue2(str(packetCnt))#可抢总个数
    recData.SetStrValue3(wishStr)#祝福语
    g_allRecordDict[redPacketID] = recData
    GameWorld.Log("    生成新的红包familyID=%s, redPacketID =%s!ownerid=%s, ownername=%s,getType=%s,moneyType=%s,outputNum=%s,packetCnt=%s" % (familyID, redPacketID, ownerid, playerName, getType, moneyType, outputNum, packetCnt))
    GameWorld.Log("生成新的红包: familyID=%s,redPacketID=%s,ownerid=%s,ownername=%s,getType=%s,moneyType=%s,outputNum=%s,packetCnt=%s" % (familyID, redPacketID, ownerid, playerName, getType, moneyType, outputNum, packetCnt))
    return recData
def __CheckOSRedPacketCnt(recordList):
def __CheckOSRedPacketCnt(recordList, maxCountKeyNum, getTypeList):
    global g_grabDataDict
    global g_allRecordDict
    global g_osRedCnt
    global g_redPackCountDict
    ##开服红包个数是否达上限
    openServerRedPacketCnt = IpyGameDataPY.GetFuncCfg('OpenServerRedPacketCnt')
    if g_osRedCnt and g_osRedCnt < openServerRedPacketCnt + 10:
    curRedCnt = g_redPackCountDict.get(maxCountKeyNum, 0)
    openServerRedPacketCnt = IpyGameDataPY.GetFuncCfg('OpenServerRedPacketCnt', 1) # 直接用开服红包这个配置作为通用配置
    if curRedCnt and curRedCnt < openServerRedPacketCnt + 10:
        return True
    OpenServerRedPacketType = IpyGameDataPY.GetFuncCfg('OpenServerRedPacketType')
    allCnt = recordList.Count()
    curCnt = 0
@@ -201,20 +358,20 @@
        strValue1 = universalRecData.GetStrValue1()
        strValue1List = strValue1.split('|')
        getWay = int(strValue1List[3])
        if getWay != OpenServerRedPacketType:
        if getWay not in getTypeList:
            continue
        redPacketID = universalRecData.GetValue1()
        curCnt += 1
        if len(delRedPacketIDList) < 10:
            delRedPacketIDList.append(redPacketID)
        elif g_osRedCnt:
        elif curRedCnt:
            break
    if not delRedPacketIDList:
        return True
    if not g_osRedCnt:
        g_osRedCnt = curCnt
    if not curRedCnt:
        curRedCnt = curCnt
    if g_osRedCnt < openServerRedPacketCnt + 10:
    if curRedCnt < openServerRedPacketCnt + 10:
        return True
    delCnt = 0
@@ -227,7 +384,7 @@
            delCnt +=1
            g_grabDataDict.pop(delRedPacketID, 0)
            g_allRecordDict.pop(delRedPacketID, 0)
    g_osRedCnt -= delCnt
    curRedCnt -= delCnt
    
        
    recordType = ShareDefine.Def_UniversalGameRecType_FamilyRedPacketGrabRecord
@@ -276,7 +433,7 @@
def SendFamilyRedPacket(msgList):
    '''发系统赠送的红包'''
    '''发系统赠送的红包,该红包已存在,只是状态未发放,由归属玩家自由选择发放时机'''
    playerID, redPacketID, packetCnt = msgList
    curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
    if not curPlayer:
@@ -326,7 +483,7 @@
## 抢红包
def DoGrabFamilyRedPacket(curPlayer, msgList):
    global g_grabDataDict
    redPacketID, OSCanGrabCnt = msgList
    redPacketID, reqGetWay, canGrabCnt = msgList
    
    playerID= curPlayer.GetPlayerID()
    job = curPlayer.GetJob()
@@ -374,15 +531,19 @@
    getWay = int(strValue1List[3])
    owerID = int(strValue1List[0])
    isSelf = owerID == playerID
    if getWay == IpyGameDataPY.GetFuncCfg('OpenServerRedPacketType'):
        #开服红包需要判断次数
        if not isSelf and OSCanGrabCnt <= 0:
            GameWorld.DebugLog('    抢开服红包,次数不足!!')
            return
    if not isSelf and canGrabCnt != -1 and canGrabCnt <= 0:
        GameWorld.DebugLog('    抢开服红包,次数不足!!')
        return
    if reqGetWay != getWay:
        GameWorld.ErrLog("领取的红包类型不一致,无法领取! reqGetWay=%s,getWay=%s" % (reqGetWay, getWay))
        return
    if getWay == ShareDefine.RedPackType_OpenServer:
        getNumformula = IpyGameDataPY.GetFuncCompileCfg('OpenRedRacketOutNum')
    elif getWay in ShareDefine.FeastRedPackType:
        getNumformula = IpyGameDataPY.GetFuncCompileCfg('FeastRedPacket', 2)
    else:
        getNumformula = IpyGameDataPY.GetFuncCompileCfg('FamilyRedRacketOutNum')
    getMoney = eval(getNumformula) if remainPacketCnt > 1 else remainNum
    GameWorld.DebugLog("    该玩家抢到红包=%s!"%getMoney, playerID)
    grabRecordDict[playerID] = [getMoney, playerName, job]
@@ -451,8 +612,8 @@
def __CheckGrabRecData():
    global g_grabDataDict
    global g_allRecordDict
    global g_osRedCnt
    g_osRedCnt = 0
    global g_redPackCountDict
    g_redPackCountDict = {}
    universalRecMgr = GameWorld.GetUniversalRecMgr()
    allRecordList = universalRecMgr.GetTypeList(ShareDefine.Def_UniversalGameRecType_FamilyRedPacketAllRecord)
    allCnt = allRecordList.Count()