From 5300950136a7d0556945fbd0cb953b331ee79f2c Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期二, 29 一月 2019 16:07:46 +0800
Subject: [PATCH] 6087 【后端】【1.5.200】春节红包雨活动(初版)

---
 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamilyRedPacket.py |  245 ++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 203 insertions(+), 42 deletions(-)

diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamilyRedPacket.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamilyRedPacket.py
index 80e0bc0..169174c 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamilyRedPacket.py
+++ b/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()

--
Gitblit v1.8.0