8901 【BT2】【后端】全服红包(优化红包系统 1.全服红包去除总上限个数,改为限制下发数量,并在领取红包后补充相应的红包数量; 2.全服未开放可领的红包仅个人可见; 3.红包超时间隔改为5分钟检查一次 4.修改封包)

# Conflicts:
# ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py
5个文件已修改
1449 ■■■■■ 已修改文件
ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py 45 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamilyRedPacket.py 1355 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/PyGameData.py 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py 45 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
@@ -1272,7 +1272,8 @@
# A4 05 家族红包抢的信息 #tagGCFamilyRedPacketGrabInfo
class  tagFGrabRedPacketInfo(Structure):
    Name = ""    #(char Name[33])//名字
    NameLen = 0    #(BYTE NameLen)
    Name = ""    #(String Name)//名字
    PlayeJob = 0    #(BYTE PlayeJob)//玩家职业
    MoneyNum = 0    #(DWORD MoneyNum)//金钱数量
    data = None
@@ -1283,12 +1284,14 @@
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        self.Name,_pos = CommFunc.ReadString(_lpData, _pos,33)
        self.NameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.Name,_pos = CommFunc.ReadString(_lpData, _pos,self.NameLen)
        self.PlayeJob,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.MoneyNum,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        return _pos
    def Clear(self):
        self.NameLen = 0
        self.Name = ""
        self.PlayeJob = 0
        self.MoneyNum = 0
@@ -1296,7 +1299,8 @@
    def GetLength(self):
        length = 0
        length += 33
        length += 1
        length += len(self.Name)
        length += 1
        length += 4
@@ -1304,18 +1308,21 @@
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, 33, self.Name)
        data = CommFunc.WriteBYTE(data, self.NameLen)
        data = CommFunc.WriteString(data, self.NameLen, self.Name)
        data = CommFunc.WriteBYTE(data, self.PlayeJob)
        data = CommFunc.WriteDWORD(data, self.MoneyNum)
        return data
    def OutputString(self):
        DumpString = '''
                                NameLen:%d,
                                Name:%s,
                                PlayeJob:%d,
                                MoneyNum:%d
                                '''\
                                %(
                                self.NameLen,
                                self.Name,
                                self.PlayeJob,
                                self.MoneyNum
@@ -1402,7 +1409,8 @@
class  tagFRedPacketInfo(Structure):
    RedPacketID = 0    #(DWORD RedPacketID)//红包唯一ID
    PlayerID = 0    #(DWORD PlayerID)//玩家ID
    Name = ""    #(char Name[33])//玩家名字
    NameLen = 0    #(BYTE NameLen)
    Name = ""    #(String Name)//玩家名字
    Time = 0    #(DWORD Time)//时间
    PlayeJob = 0    #(BYTE PlayeJob)//玩家职业
    MoneyType = 0    #(BYTE MoneyType)//金钱类型
@@ -1410,7 +1418,8 @@
    GetWay = 0    #(BYTE GetWay)//获得途径
    PacketCnt = 0    #(BYTE PacketCnt)//可抢个数
    State = 0    #(BYTE State)//0未发,1未领取,2已领取,3全部领完
    Wish = ""    #(char Wish[33])//祝福语
    WishLen = 0    #(BYTE WishLen)
    Wish = ""    #(String Wish)//祝福语
    IsAnonymous = 0    #(BYTE IsAnonymous)//是否匿名
    data = None
@@ -1422,7 +1431,8 @@
        self.Clear()
        self.RedPacketID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.PlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.Name,_pos = CommFunc.ReadString(_lpData, _pos,33)
        self.NameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.Name,_pos = CommFunc.ReadString(_lpData, _pos,self.NameLen)
        self.Time,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.PlayeJob,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.MoneyType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
@@ -1430,13 +1440,15 @@
        self.GetWay,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.PacketCnt,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.State,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.Wish,_pos = CommFunc.ReadString(_lpData, _pos,33)
        self.WishLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.Wish,_pos = CommFunc.ReadString(_lpData, _pos,self.WishLen)
        self.IsAnonymous,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        return _pos
    def Clear(self):
        self.RedPacketID = 0
        self.PlayerID = 0
        self.NameLen = 0
        self.Name = ""
        self.Time = 0
        self.PlayeJob = 0
@@ -1445,6 +1457,7 @@
        self.GetWay = 0
        self.PacketCnt = 0
        self.State = 0
        self.WishLen = 0
        self.Wish = ""
        self.IsAnonymous = 0
        return
@@ -1453,7 +1466,8 @@
        length = 0
        length += 4
        length += 4
        length += 33
        length += 1
        length += len(self.Name)
        length += 4
        length += 1
        length += 1
@@ -1461,7 +1475,8 @@
        length += 1
        length += 1
        length += 1
        length += 33
        length += 1
        length += len(self.Wish)
        length += 1
        return length
@@ -1470,7 +1485,8 @@
        data = ''
        data = CommFunc.WriteDWORD(data, self.RedPacketID)
        data = CommFunc.WriteDWORD(data, self.PlayerID)
        data = CommFunc.WriteString(data, 33, self.Name)
        data = CommFunc.WriteBYTE(data, self.NameLen)
        data = CommFunc.WriteString(data, self.NameLen, self.Name)
        data = CommFunc.WriteDWORD(data, self.Time)
        data = CommFunc.WriteBYTE(data, self.PlayeJob)
        data = CommFunc.WriteBYTE(data, self.MoneyType)
@@ -1478,7 +1494,8 @@
        data = CommFunc.WriteBYTE(data, self.GetWay)
        data = CommFunc.WriteBYTE(data, self.PacketCnt)
        data = CommFunc.WriteBYTE(data, self.State)
        data = CommFunc.WriteString(data, 33, self.Wish)
        data = CommFunc.WriteBYTE(data, self.WishLen)
        data = CommFunc.WriteString(data, self.WishLen, self.Wish)
        data = CommFunc.WriteBYTE(data, self.IsAnonymous)
        return data
@@ -1486,6 +1503,7 @@
        DumpString = '''
                                RedPacketID:%d,
                                PlayerID:%d,
                                NameLen:%d,
                                Name:%s,
                                Time:%d,
                                PlayeJob:%d,
@@ -1494,12 +1512,14 @@
                                GetWay:%d,
                                PacketCnt:%d,
                                State:%d,
                                WishLen:%d,
                                Wish:%s,
                                IsAnonymous:%d
                                '''\
                                %(
                                self.RedPacketID,
                                self.PlayerID,
                                self.NameLen,
                                self.Name,
                                self.Time,
                                self.PlayeJob,
@@ -1508,6 +1528,7 @@
                                self.GetWay,
                                self.PacketCnt,
                                self.State,
                                self.WishLen,
                                self.Wish,
                                self.IsAnonymous
                                )
ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py
@@ -552,6 +552,8 @@
    AuctionHouse.OnPlayerLeaveServer(curPlayer)
    #协助
    PlayerAssist.OnLeaveServer(curPlayer)
    #红包
    PlayerFamilyRedPacket.OnLeaveServer(curPlayer)
    #------------镖车逻辑
    #TruckPlayerDisconnectProcess(curPlayer, tick)
    
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFamilyRedPacket.py
@@ -18,50 +18,27 @@
#---------------------------------------------------------------------
import GameWorld
import ChPyNetSendPack
import NetPackCommon
import ShareDefine
import NetPackCommon
import IpyGameDataPY
import PlayerDBGSEvent
import PlayerUniversalGameRec
import PlayerControl
import ChConfig
import ChPyNetSendPack
import PlayerCompensation
import PlayerDBGSEvent
import PlayerControl
import PlayerFamily
import PyGameData
import ChConfig
import time
import random
import datetime
'''
红包暂定有效期24小时,过天清除过期的红包,如果是玩家发放的返还未领取的货币
上线同步所有红包信息,红包变化实时广播全服在线玩家
'''
#Def_UniversalGameRecType_FamilyRedPacketAllRecord
#Time      创建红包时间,非红包实际开放领取时间,如果红包表有配置系统发放时间,则该时间存配表时间,没有的话存创建时的服务器时间
#value1    红包唯一ID,该ID为实例ID,非配表的红包ID
#value2    家族ID,0代表全服红包
#value3    总额度*10+金钱类型
#value4    ״̬
#value5    时间,用来判断是否过期删除的,实际开放该红包领取的时间
#strValue1 创建者ID|创建者名字|创建者职业|获得途径(红包类型)
#strValue2 可抢总个数|是否匿名(默认不匿名兼容老数据)
#strValue3 祝福语,玩家自己编辑的内容
#Def_UniversalGameRecType_FamilyRedPacketGrabRecord
#value1    红包唯一ID
#value2    playerID
#value3    job
#value4    moneyType
#value5    getMoney
#strValue1 名字
import random
import time
(
State_NoSend,   #未发
State_NoGot,    #未领取
State_HasGot,   #已领取
State_HasAllGot,#全部领完
)=range(4)
State_NoSend, #未发
State_NoGot, #未领取
State_HasGot, #已领取
State_HasAllGot, #全部领完
) = range(4)
g_allRecordDict = {} #{红包ID:recData, ...}
g_grabDataDict = {} #{红包ID:{playerid:[抢到的钱,名字,job]}, ...}
@@ -70,21 +47,663 @@
DBKey_RedPacketSend = "RedPacketSend_%s" # 系统定时红包是否已发放, 参数红包ID
DBKey_RedPacketSystemDayCount = "RedPacketSystemDayCount" # 全服系统红包已发放个数
## 玩家登录
#  @param None
#  @return None
def OnPlayerLogin(curPlayer):
    NotifyRedPacketInfo(curPlayer)
def __SaveRedpacketRecData(recData, redPacketObj):
    ''' 红包暂定有效期24小时,过天清除过期的红包,如果是玩家发放的返还未领取的货币
            上线同步所有红包信息,红包变化实时广播全服在线玩家
    '''
    #红包数据 Def_UniversalGameRecType_FamilyRedPacketAllRecord
    #Time      创建红包时间,非红包实际开放领取时间,如果红包表有配置系统发放时间,则该时间存配表时间,没有的话存创建时的服务器时间
    #value1    红包唯一ID,该ID为实例ID,非配表的红包ID
    #value2    家族ID,0代表全服红包
    #value3    总额度*10+金钱类型
    #value4    ״̬
    #value5    时间,用来判断是否过期删除的,实际开放该红包领取的时间
    #strValue1 创建者ID|创建者名字|创建者职业|获得途径(红包类型)
    #strValue2 可抢总个数|是否匿名(默认不匿名兼容老数据)
    #strValue3 祝福语,玩家自己编辑的内容
    recData.SetTime(redPacketObj.createTime)
    recData.SetValue1(redPacketObj.redPacketID)
    recData.SetValue2(redPacketObj.familyID)
    recData.SetValue3(redPacketObj.moneyType + redPacketObj.moneyValue * 10)
    recData.SetValue4(redPacketObj.state)
    recData.SetValue5(redPacketObj.calcTime)
    strValue1 = '%s|%s|%s|%s' % (redPacketObj.playerID, redPacketObj.playerName, redPacketObj.playerJob, redPacketObj.getWay)
    recData.SetStrValue1(strValue1)
    recData.SetStrValue2('%s|%s' % (redPacketObj.packetCnt, int(redPacketObj.isAnonymous)))
    recData.SetStrValue3(redPacketObj.wish)
    return
def __SaveRedpacketRecGrabData(recData, grabObj):
    #抢红包记录 Def_UniversalGameRecType_FamilyRedPacketGrabRecord
    #value1    红包唯一ID
    #value2    playerID
    #value3    job
    #value4    moneyType
    #value5    getMoney
    #strValue1 名字
    recData.SetValue1(grabObj.redPacketID)
    recData.SetValue2(grabObj.playerID)
    recData.SetValue3(grabObj.playerJob)
    recData.SetValue4(grabObj.moneyType)
    recData.SetValue5(grabObj.getMoney)
    recData.SetStrValue1(grabObj.playerName)
    return
class RedPacketGrab():
    ## 红包抢记录数据
    def __init__(self, redPacketID, playerID):
        self.redPacketID = redPacketID
        self.playerID = playerID
        self.playerJob = 0
        self.playerName = ""
        self.moneyType = 0
        self.getMoney = 0
        return
class RedPacketData():
    ## 红包数据
    def __init__(self, redPacketID):
        self.redPacketID = redPacketID
        self.familyID = 0
        self.moneyType = 0
        self.moneyValue = 0
        self.state = 0
        self.createTime = 0
        self.calcTime = 0
        self.playerID = 0
        self.playerName = ""
        self.playerJob = 0
        self.getWay = 0
        self.packetCnt = 0
        self.isAnonymous = 0 # 是否匿名
        self.wish = ""
        self.grabDict = {} # 抢红包记录 {playerID:RedPacketGrab, ...}
        return
class RedPacketMgr():
    ''' 红包缓存管理等
    通知玩家红包逻辑:
    由于刚开服时红包大概率会比较多,红包的交互及交叉通知也相对比较密集,所以做些优化,不对所有红包处理
    将红包分为红包总库及通知给玩家的部分红包,假设当前所有红包总数为500个,标记为 T 个
    可配置限制通知给玩家可操作的红包个数如只通知20个,标记为 M 个,可视为热红包,当 M 消化完后可附加通知  N 个
    通知玩家的红包组成:
    非仙盟红包: 归属玩家的未开放红包A + 不限制通知个数的红包B + 限制通知个数的红包C;  不包含其他玩家未开放的
        仙盟红包: 所有玩家未领取过的且未全部领完的红包,包含其他玩家未开放的
    如果 (A + B) >= M 了,则不需要再附加通知 C
    '''
    def __init__(self):
        self.allRedPacketDict = {} # 所有红包信息  {红包ID:RedPacketData, ...}
        self.familyRedPacketDict = {} # 仙盟红包信息,全部同步  {familyID:[红包ID, ...], ...}
        # --- 以下仅针对非仙盟红包 ---
        # 针对红包量比较大的红包类型,有限制同步个数,按类型分组,每组按规则独立同步;如 开服成就红包、节日成就红包、全服红包
        # 同步规则:
        # 比如先同步20个,然后减一个则再从已开放的库中补充;
        # 新增一个开放领取的红包时,如果玩家有可领取的则不需要同步,没有可领取的则需要同步给他
        # 注: 全服红包中,未开放的红包仅玩家自己可见
        self.playerNosendRedPacketIDInfo = {} # 玩家未开放的红包ID信息,针对有同步个数限制的类型 {playerID:{红包类型:[红包ID, ...], ...}, ...}
        # playerCanGetRedPacketIDInfo 的playerID包含所有在线玩家,不含脱机挂
        self.playerCanGetRedPacketIDInfo = {} # 玩家可领取的红包ID信息,针对有同步个数限制的类型 {playerID:{红包类型:[红包ID, ...], ...}, ...}
        self.activeRedPacketIDInfo = {} # 已开放领取的红包ID列表,针对有同步个数限制的类型 {红包类型:[红包ID, ...], ...}
        # 其他全服红包,一般量比较少的,相对固定的,全部同步,如节日定时发送的红包
        self.notifyAllServerRedPacketIDList = [] # 其他没有限制下发同步个数的全服红包ID [红包ID, ...]
        return
    def PrintData(self, sign=""):
        if sign:
            GameWorld.DebugLog("    === %s ===" % sign)
        GameWorld.DebugLog("    所有红包=%s" % self.allRedPacketDict.keys())
        GameWorld.DebugLog("    仙盟红包=%s" % self.familyRedPacketDict)
        GameWorld.DebugLog("    全服同步全部红包=%s" % self.notifyAllServerRedPacketIDList)
        GameWorld.DebugLog("    全服同步活跃红包=%s" % self.activeRedPacketIDInfo)
        GameWorld.DebugLog("    全服个人未开放红包=%s" % self.playerNosendRedPacketIDInfo)
        GameWorld.DebugLog("    全服个人可领取红包=%s" % self.playerCanGetRedPacketIDInfo)
        return
    def GetRedPacketObj(self, redPacketID, createNew):
        ## 获取红包实例
        redPacketObj = None
        if redPacketID in self.allRedPacketDict:
            redPacketObj = self.allRedPacketDict[redPacketID]
        elif createNew:
                redPacketObj = RedPacketData(redPacketID)
                self.allRedPacketDict[redPacketID] = redPacketObj
        return redPacketObj
    def AddFamilyRedPacketID(self, familyID, redPacketID):
        ## 添加红包ID进入仙盟红包ID缓存
        if familyID not in self.familyRedPacketDict:
            self.familyRedPacketDict[familyID] = []
        familyRedpacketIDList = self.familyRedPacketDict[familyID]
        if redPacketID not in familyRedpacketIDList:
            familyRedpacketIDList.append(redPacketID)
        return
    def DelFamilyRedPacketID(self, familyID, redPacketID):
        ## 删除仙盟红包ID缓存
        if familyID not in self.familyRedPacketDict:
            return
        familyRedpacketIDList = self.familyRedPacketDict[familyID]
        if redPacketID not in familyRedpacketIDList:
            return
        familyRedpacketIDList.remove(redPacketID)
        return True
    def AddPlayerNosendRedPacketID(self, playerID, getWay, redPacketID):
        ## 添加玩家未开放的红包ID缓存
        if playerID not in self.playerNosendRedPacketIDInfo:
            self.playerNosendRedPacketIDInfo[playerID] = {}
        playerNosendRedPacketTypeIDInfo = self.playerNosendRedPacketIDInfo[playerID]
        if getWay not in playerNosendRedPacketTypeIDInfo:
            playerNosendRedPacketTypeIDInfo[getWay] = []
        playerNosendRedPacketTypeIDList = playerNosendRedPacketTypeIDInfo[getWay]
        if redPacketID not in playerNosendRedPacketTypeIDList:
            playerNosendRedPacketTypeIDList.append(redPacketID)
        return
    def DelPlayerNosendRedPacketID(self, playerID, getWay, redPacketID):
        ## 删除玩家未开放的红包ID缓存
        if playerID not in self.playerNosendRedPacketIDInfo:
            return
        playerNosendRedPacketTypeIDInfo = self.playerNosendRedPacketIDInfo[playerID]
        if getWay not in playerNosendRedPacketTypeIDInfo:
            return
        playerNosendRedPacketTypeIDList = playerNosendRedPacketTypeIDInfo[getWay]
        if redPacketID not in playerNosendRedPacketTypeIDList:
            return
        playerNosendRedPacketTypeIDList.remove(redPacketID)
        return True
    def AddActiveRedPacketID(self, getWay, redPacketID):
        ## 添加已开放的全服红包ID缓存
        if getWay not in self.activeRedPacketIDInfo:
            self.activeRedPacketIDInfo[getWay] = []
        redPacketIDList = self.activeRedPacketIDInfo[getWay]
        if redPacketID not in redPacketIDList:
            redPacketIDList.append(redPacketID)
        return
    def DelActiveRedPacketID(self, getWay, redPacketID):
        ## 删除已开放的全服红包ID缓存
        if getWay not in self.activeRedPacketIDInfo:
            return
        redPacketIDList = self.activeRedPacketIDInfo[getWay]
        if redPacketID not in redPacketIDList:
            return
        redPacketIDList.remove(redPacketID)
        return True
    def AddPlayerCanGetRedPacketID(self, playerID, getWay, redPacketID):
        ## 添加玩家可领取的红包ID缓存
        if playerID not in self.playerCanGetRedPacketIDInfo:
            self.playerCanGetRedPacketIDInfo[playerID] = {}
        redPacketTypeIDInfo = self.playerCanGetRedPacketIDInfo[playerID]
        if getWay not in redPacketTypeIDInfo:
            redPacketTypeIDInfo[getWay] = []
        redPacketIDList = redPacketTypeIDInfo[getWay]
        if redPacketID not in redPacketIDList:
            redPacketIDList.append(redPacketID)
        return
    def DelPlayerCanGetRedPacketID(self, playerID, getWay, redPacketID):
        ## 删除玩家可领取的红包ID缓存
        if playerID not in self.playerCanGetRedPacketIDInfo:
            return
        redPacketTypeIDInfo = self.playerCanGetRedPacketIDInfo[playerID]
        if getWay not in redPacketTypeIDInfo:
            return
        redPacketIDList = redPacketTypeIDInfo[getWay]
        if redPacketID not in redPacketIDList:
            return
        redPacketIDList.remove(redPacketID)
        # 返回当前类型可用红包ID列表
        return redPacketIDList
def GetRedpacketMgr():
    redPacketMgr = PyGameData.g_redPacketMgr
    if redPacketMgr == None:
        redPacketMgr = RedPacketMgr()
        PyGameData.g_redPacketMgr = redPacketMgr
    return redPacketMgr
def OnServerStart():
    redPacketMgr = GetRedpacketMgr()
    universalRecMgr = GameWorld.GetUniversalRecMgr()
    # 红包数据
    notifyLimitTypeList = IpyGameDataPY.GetFuncEvalCfg("RedPacketSys", 1)
    recordList = universalRecMgr.GetTypeList(ShareDefine.Def_UniversalGameRecType_FamilyRedPacketAllRecord)
    GameWorld.Log("加载红包信息通用记录: count=%s" % recordList.Count())
    for index in xrange(recordList.Count()):
        recData = recordList.At(index)
        state = recData.GetValue4()
        if state == State_HasAllGot:
            # 已全部领完的不处理
            continue
        redPacketID = recData.GetValue1()
        familyID = recData.GetValue2()
        redPacketObj = redPacketMgr.GetRedPacketObj(redPacketID, True)
        redPacketObj.familyID = familyID
        redPacketObj.createTime = recData.GetTime()
        redPacketObj.moneyType = recData.GetValue3() % 10
        redPacketObj.moneyValue = recData.GetValue3() / 10
        redPacketObj.state = recData.GetValue4()
        redPacketObj.calcTime = recData.GetValue5()
        strValue1List = recData.GetStrValue1().split('|')
        playerID, playerName, job, getWay = strValue1List
        redPacketObj.playerID = GameWorld.ToIntDef(playerID)
        redPacketObj.playerName = playerName
        redPacketObj.playerJob = GameWorld.ToIntDef(job)
        redPacketObj.getWay = GameWorld.ToIntDef(getWay)
        strValue2List = recData.GetStrValue2().split('|')
        redPacketObj.packetCnt = GameWorld.ToIntDef(strValue2List[0])
        redPacketObj.isAnonymous = GameWorld.ToIntDef(strValue2List[1]) if len(strValue2List) > 1 else 0
        redPacketObj.wish = recData.GetStrValue3()
        playerID = redPacketObj.playerID
        getWay = redPacketObj.getWay
        # 1. 仙盟的红包
        if familyID:
            redPacketMgr.AddFamilyRedPacketID(familyID, redPacketID)
            continue
        # 以下是面向全服的红包
        # 2. 全服未开放红包
        if state == State_NoSend:
            # 未发放的添加进ID缓存
            redPacketMgr.AddPlayerNosendRedPacketID(playerID, getWay, redPacketID)
            continue
        # 3. 全服不限制下发个数的
        if getWay not in notifyLimitTypeList:
            redPacketMgr.notifyAllServerRedPacketIDList.append(redPacketID)
            continue
        # 4. 有限制通知个数的
        if state == State_NoGot:
            redPacketMgr.AddActiveRedPacketID(getWay, redPacketID)
    # 抢红包记录
    grabRecordList = universalRecMgr.GetTypeList(ShareDefine.Def_UniversalGameRecType_FamilyRedPacketGrabRecord)
    GameWorld.Log("加载红包抢记录信息通用记录: count=%s" % grabRecordList.Count())
    for index in xrange(grabRecordList.Count()):
        recData = grabRecordList.At(index)
        redPacketID = recData.GetValue1()
        playerID = recData.GetValue2()
        redPacketObj = redPacketMgr.GetRedPacketObj(redPacketID, False)
        if not redPacketObj:
            continue
        grabObj = RedPacketGrab(redPacketID, playerID)
        grabObj.playerJob = recData.GetValue3()
        grabObj.playerName = recData.GetStrValue1()
        grabObj.moneyType = recData.GetValue4()
        grabObj.getMoney = recData.GetValue5()
        redPacketObj.grabDict[playerID] = grabObj
    redPacketMgr.PrintData("OnServerStart")
    return
def OnServerClose():
    redPacketMgr = GetRedpacketMgr()
    recMgr = GameWorld.GetUniversalRecMgr()
    recMgr.Delete(ShareDefine.Def_UniversalGameRecType_FamilyRedPacketAllRecord)
    recDataList = recMgr.GetTypeList(ShareDefine.Def_UniversalGameRecType_FamilyRedPacketAllRecord)
    recMgr.Delete(ShareDefine.Def_UniversalGameRecType_FamilyRedPacketGrabRecord)
    grabRecDataList = recMgr.GetTypeList(ShareDefine.Def_UniversalGameRecType_FamilyRedPacketGrabRecord)
    redPacketCount = 0
    grabRecCount = 0
    for redPacketObj in redPacketMgr.allRedPacketDict.values():
        if redPacketObj.state == State_HasAllGot:
            # 已全部抢完的不保存
            continue
        recData = recDataList.AddRec()
        __SaveRedpacketRecData(recData, redPacketObj)
        redPacketCount += 1
        for grabObj in redPacketObj.grabDict.values():
            grabRecData = grabRecDataList.AddRec()
            __SaveRedpacketRecGrabData(grabRecData, grabObj)
            grabRecCount += 1
    GameWorld.Log("保存红包信息通用记录: count=%s" % redPacketCount)
    GameWorld.Log("保存红包抢记录信息通用记录: count=%s" % grabRecCount)
    return
def OnPlayerLogin(curPlayer):
    if not PlayerControl.GetIsTJG(curPlayer):
        redPacketMgr = GetRedpacketMgr()
        playerID = curPlayer.GetPlayerID()
        redPacketMgr.playerCanGetRedPacketIDInfo[playerID] = {}
        redPacketMgr.PrintData("OnPlayerLogin %s" % playerID)
        notifyLimitTypeList = IpyGameDataPY.GetFuncEvalCfg("RedPacketSys", 1)
        maxNotifyCount = IpyGameDataPY.GetFuncCfg("RedPacketSys", 2)
        for getWay in notifyLimitTypeList:
            redPacketMgr.playerCanGetRedPacketIDInfo[playerID][getWay] = [] # 确保 getWay key 一定存在
            nowActiveRedPacketIDList = redPacketMgr.activeRedPacketIDInfo.get(getWay, []) # 当前此类型还可用的公共已开放红包列表
            if not nowActiveRedPacketIDList:
                continue
            nosendIDList = redPacketMgr.playerNosendRedPacketIDInfo.get(playerID, {}).get(getWay, [])
            addCount = maxNotifyCount - len(nosendIDList)
            if addCount <= 0:
                continue
            playerCanGetIDList = []
            for redPacketID in nowActiveRedPacketIDList:
                redPacketObj = redPacketMgr.GetRedPacketObj(redPacketID, False)
                if playerID in redPacketObj.grabDict:
                    continue
                playerCanGetIDList.append(redPacketID)
                addCount -= 1
                if addCount <= 0:
                    break
            redPacketMgr.playerCanGetRedPacketIDInfo[playerID][getWay] = playerCanGetIDList
        redPacketMgr.PrintData("loginOK")
    NotifyRedPacketInfo(curPlayer, isLogin=True)
    return
def OnLeaveServer(curPlayer):
    playerID = curPlayer.GetPlayerID()
    redPacketMgr = GetRedpacketMgr()
    redPacketMgr.playerCanGetRedPacketIDInfo.pop(playerID, None)
    return
## 隔天更新
#  @param None
#  @return None
def DoOnDay():
    __CheckGrabRecData()
    PlayerDBGSEvent.SetDBGSTrig_ByKey(DBKey_RedPacketSystemDayCount, 0) # 重置每日全服系统红包发放个数
    RandTodayServerSystemRedPacketSendTime()
    return
def CheckDelRedpacketData():
    ## 检查红包删除红包,5分钟一次: 1-删除过期红包,2-删除已全部抢完的红包
    curTimeNum = int(time.time())
    rangeTime = IpyGameDataPY.GetFuncCfg("RedPacketSys", 3) * 3600
    backMoneyDict = {}
    delRedPacketIDList = [] # 删除的全服红包 [红包ID, ...]
    delFamilyRedPacketInfo = {} # 删除的仙盟红包 {familyID:[红包ID, ...], ...}
    delNosendRedPacketInfo = {} # 要通知给玩家删除的红包 {playerID:[红包ID, ...], ...}
    redPacketMgr = GetRedpacketMgr()
    for redPacketObj in redPacketMgr.allRedPacketDict.values():
        state = redPacketObj.state
        if state == State_HasAllGot:
            pass
        elif curTimeNum - redPacketObj.calcTime < rangeTime:
            continue
        redPacketID = redPacketObj.redPacketID
        playerID = redPacketObj.playerID
        familyID = redPacketObj.familyID
        getWay = redPacketObj.getWay
        if redPacketID in redPacketMgr.allRedPacketDict:
            redPacketMgr.allRedPacketDict.pop(redPacketID)
        # 返还未领完的玩家主动发放的仙玉红包
        if state != State_HasAllGot and playerID and getWay == ShareDefine.RedPackType_GoldPacket:
            outNum = sum([grabObj.getMoney for grabObj in redPacketObj.grabDict.values()]) #已被抢的钱
            moneyType = redPacketObj.moneyType
            totalMoney = redPacketObj.moneyValue
            remainMoney = totalMoney - outNum #剩余的钱
            if moneyType == 1 and remainMoney:
                backMoneyDict[playerID] = backMoneyDict.get(playerID, 0) + remainMoney
        # 1. 仙盟红包
        if familyID:
            redPacketMgr.DelFamilyRedPacketID(familyID, redPacketID)
            if familyID not in delFamilyRedPacketInfo:
                delFamilyRedPacketInfo[familyID] = []
            defFamilyRedPacketIDList = delFamilyRedPacketInfo[familyID]
            defFamilyRedPacketIDList.append(redPacketID)
            continue
        # 2. 全服红包
        #     2.1 是否玩家私有未开放的全服红包
        if state == State_NoSend:
            redPacketMgr.DelPlayerNosendRedPacketID(playerID, getWay, redPacketID)
            if playerID not in delNosendRedPacketInfo:
                delNosendRedPacketInfo[playerID] = []
            playerNosendRedPacketIDList = delNosendRedPacketInfo[playerID]
            playerNosendRedPacketIDList.append(redPacketID)
            continue
        #     2.2 已开放的全服红包
        redPacketMgr.DelActiveRedPacketID(getWay, redPacketID)
        if redPacketID in redPacketMgr.notifyAllServerRedPacketIDList:
            redPacketMgr.notifyAllServerRedPacketIDList.remove(redPacketID)
        # 这个玩家可领取的可能包含非玩家自己发的红包
        for typeIDDict in redPacketMgr.playerCanGetRedPacketIDInfo.values():
            if getWay not in typeIDDict:
                continue
            redpacketIDList = typeIDDict[getWay]
            if redPacketID not in redpacketIDList:
                continue
            redpacketIDList.remove(redPacketID)
        delRedPacketIDList.append(redPacketID)
    #返回玩家未被领取的仙玉
    if backMoneyDict:
        for playerID, moneyNum in backMoneyDict.items():
            PlayerCompensation.SendMailByKey('RedPackBack', [playerID], [], [], moneyNum)
    playerManager = GameWorld.GetPlayerManager()
    # 同步删除的仙盟红包
    GameWorld.DebugLog("同步删除的仙盟红包: %s" % delFamilyRedPacketInfo)
    for familyID, delIDList in delFamilyRedPacketInfo.items():
        family = GameWorld.GetFamilyManager().FindFamily(familyID)
        if not family:
            return
        sendPack = ChPyNetSendPack.tagGCRedPacketDel()
        sendPack.DelRedPacketID = delIDList
        sendPack.Cnt = len(delIDList)
        for i in xrange(family.GetCount()):
            notifyMember = family.GetAt(i)
            curPlayer = playerManager.FindPlayerByID(notifyMember.GetPlayerID())
            if curPlayer == None or not curPlayer.GetInitOK() or PlayerControl.GetIsTJG(curPlayer):
                continue
            NetPackCommon.SendFakePack(curPlayer, sendPack)
    # 同步删除个人未开放的全服红包
    GameWorld.DebugLog("同步删除个人未开放的全服红包: %s" % delNosendRedPacketInfo)
    for playerID, nosendIDList in delNosendRedPacketInfo.items():
        curPlayer = playerManager.FindPlayerByID(playerID)
        if curPlayer == None or not curPlayer.GetInitOK() or PlayerControl.GetIsTJG(curPlayer):
            continue
        sendPack = ChPyNetSendPack.tagGCRedPacketDel()
        sendPack.DelRedPacketID = nosendIDList
        sendPack.Cnt = len(nosendIDList)
        NetPackCommon.SendFakePack(curPlayer, sendPack)
    # 同步删除已开放的全服红包
    GameWorld.DebugLog("同步删除已开放的全服红包: %s" % delRedPacketIDList)
    if delRedPacketIDList:
        sendPack = ChPyNetSendPack.tagGCRedPacketDel()
        sendPack.Clear()
        sendPack.DelRedPacketID = delRedPacketIDList
        sendPack.Cnt = len(delRedPacketIDList)
        for i in xrange(playerManager.GetActivePlayerCount()):
            curPlayer = playerManager.GetActivePlayerAt(i)
            if curPlayer == None or not curPlayer.GetInitOK() or PlayerControl.GetIsTJG(curPlayer):
                continue
            NetPackCommon.SendFakePack(curPlayer, sendPack)
    return
def OnChangeRedPacketState(family, redPacketObj, beforeState=None):
    ## 红包状态变更处理
    state = redPacketObj.state
    if state == beforeState:
        return
    redPacketMgr = GetRedpacketMgr()
    redPacketID = redPacketObj.redPacketID
    familyID = redPacketObj.familyID
    ownerID = redPacketObj.playerID
    getWay = redPacketObj.getWay
    GameWorld.DebugLog("红包状态变更处理: redPacketID=%s,ownerID=%s,familyID=%s,beforeState=%s,state=%s"
                       % (redPacketID, ownerID, familyID, beforeState, state))
    redPacketMgr.PrintData("a")
    notifyPlayerDict = {ownerID:[redPacketID]} # 通知给指定玩家的信息,每个玩家可能不一样
    # 1. 仙盟红包直接通知该仙盟所有成员
    if family:
        if state in [State_NoSend, State_NoGot]:
            redPacketMgr.AddFamilyRedPacketID(family.GetID(), redPacketID)
    # 2. 全服未开放红包默认只发给个人
    elif state == State_NoSend:
        if not ownerID:
            return
        if beforeState == None:
            redPacketMgr.AddPlayerNosendRedPacketID(ownerID, getWay, redPacketID)
    # 3. 全服不限制下发个数的同步全服玩家
    elif getWay not in IpyGameDataPY.GetFuncEvalCfg("RedPacketSys", 1):
        notifyPlayerDict = None
        if state == State_HasAllGot:
            if redPacketID in redPacketMgr.notifyAllServerRedPacketIDList:
                redPacketMgr.notifyAllServerRedPacketIDList.remove(redPacketID)
        else:
            if redPacketID not in redPacketMgr.notifyAllServerRedPacketIDList:
                redPacketMgr.notifyAllServerRedPacketIDList.append(redPacketID)
    # 4. 其他的要限制下发个数的检查需要同步的玩家即可
    #     4.1 变为  开放领取状态
    elif state == State_NoGot:
        if beforeState != State_NoGot:
            redPacketMgr.DelPlayerNosendRedPacketID(ownerID, getWay, redPacketID) # 移出拥有者私有未开放红包队列
            redPacketMgr.AddPlayerCanGetRedPacketID(ownerID, getWay, redPacketID) # 添加拥有者私有已开放红包队列
            redPacketMgr.AddActiveRedPacketID(getWay, redPacketID) # 添加公共已开放红包队列
            maxNotifyCount = IpyGameDataPY.GetFuncCfg("RedPacketSys", 2)
            # 检查追加该红包记录的玩家
            for playerID, typeRedIDDict in redPacketMgr.playerCanGetRedPacketIDInfo.items():
                if playerID == ownerID:
                    continue
                redIDList = typeRedIDDict.get(getWay, [])
                if redPacketID in redIDList:
                    continue
                nosendTypeRedIDDict = redPacketMgr.playerNosendRedPacketIDInfo.get(playerID, {})
                nosendRedIDList = nosendTypeRedIDDict.get(getWay, [])
                totalCount = len(nosendRedIDList) + len(redIDList) # 玩家当前还可操作领取的红包数
                if totalCount >= maxNotifyCount:
                    continue
                redPacketMgr.AddPlayerCanGetRedPacketID(playerID, getWay, redPacketID) # 添加目标玩家私有已开放红包队列
                notifyPlayerDict[playerID] = [redPacketID]
    #     4.1 变为  全部领取完毕
    elif state == State_HasAllGot:
        if beforeState != State_HasAllGot:
            redPacketMgr.DelActiveRedPacketID(getWay, redPacketID) # 移除公共已开放红包队列
            nowActiveRedPacketIDList = redPacketMgr.activeRedPacketIDInfo.get(getWay, []) # 当前此类型还可用的公共已开放红包列表
            # 检查需要补充红包记录的玩家,采用 减去1  补充1 的模式
            for playerID, typeRedIDDict in redPacketMgr.playerCanGetRedPacketIDInfo.items():
                canGetIDList = redPacketMgr.DelPlayerCanGetRedPacketID(playerID, getWay, redPacketID) # 移出私有已开放红包队列
                if canGetIDList == None:
                    continue
                lastCanGetID = 0 if not canGetIDList else canGetIDList[-1]
                checkIndex = nowActiveRedPacketIDList.index(lastCanGetID) if lastCanGetID in nowActiveRedPacketIDList else 0
                for i in xrange(checkIndex, len(nowActiveRedPacketIDList)):
                    newCanGetRedID = nowActiveRedPacketIDList[i]
                    if newCanGetRedID not in canGetIDList:
                        if redPacketMgr.AddPlayerCanGetRedPacketID(playerID, getWay, newCanGetRedID): # 添加目标玩家私有已开放红包队列
                            notifyPlayerDict[playerID] = [redPacketID, newCanGetRedID]
                            break
    else:
        return
    redPacketMgr.PrintData("b")
    syncRedPacketList = [redPacketID]
    playerManager = GameWorld.GetPlayerManager()
    # 仙盟的直接同步该仙盟所有玩家
    if family:
        for i in xrange(family.GetCount()):
            notifyMember = family.GetAt(i)
            player = playerManager.FindPlayerByID(notifyMember.GetPlayerID())
            if player == None or not player.GetInitOK() or PlayerControl.GetIsTJG(player):
                continue
            NotifyRedPacketInfo(player, syncRedPacketList)
    # 没有指定玩家,则通知全服玩家
    elif notifyPlayerDict == None:
        for i in xrange(playerManager.GetActivePlayerCount()):
            player = playerManager.GetActivePlayerAt(i)
            if player == None or not player.GetInitOK() or PlayerControl.GetIsTJG(player):
                continue
            NotifyRedPacketInfo(player, syncRedPacketList)
    # 通知指定玩家
    else:
        for playerID, syncRedPacketList in notifyPlayerDict.items():
            player = playerManager.FindPlayerByID(playerID)
            if player == None or not player.GetInitOK() or PlayerControl.GetIsTJG(player):
                continue
            NotifyRedPacketInfo(player, syncRedPacketList)
    return
def DelRedPackByFamilyID(delfamilyID):
    ## 删除仙盟的时候才需要删除红包,所以这里不做通知,重新加入仙盟时会重新同步一次 isAll 的情况
    familyID = delfamilyID
    redPacketMgr = GetRedpacketMgr()
    if familyID not in redPacketMgr.familyRedPacketDict:
        return
    familyRedpacketIDList = redPacketMgr.familyRedPacketDict.pop(familyID)
    for redPacketID in familyRedpacketIDList:
        if redPacketID in redPacketMgr.allRedPacketDict:
            redPacketMgr.allRedPacketDict.pop(redPacketID)
    GameWorld.DebugLog("解散仙盟删除仙盟红包! familyID=%s, %s" % (familyID, familyRedpacketIDList))
    return
##---------------------------------------- 节日红包 -----------------------------------------------
@@ -138,7 +757,7 @@
        endDateTime = None
        validMinutes = ipyData.GetValidMinutes()
        if validMinutes:
            endDateTime = openDateTime +  + datetime.timedelta(minutes=validMinutes)
            endDateTime = openDateTime + +datetime.timedelta(minutes=validMinutes)
            
        redPacketByTimeList.append([redPackID, openDateTime, endDateTime])
        
@@ -211,12 +830,13 @@
def RandTodayServerSystemRedPacketSendTime():
    ## 随机生成今日全服系统红包发放时间点
    sendTimeList = []
    sysRedPackketSendCountToday = PlayerDBGSEvent.GetDBGSTrig_ByKey(DBKey_RedPacketSystemDayCount) 
    maxCount = IpyGameDataPY.GetFuncCfg("ServerSysRedPacket", 1)
    if maxCount:
        return
    needSendCount = max(0, maxCount - sysRedPackketSendCountToday)
    GameWorld.Log("随机生成发放全服系统红包时间! maxCount=%s,sysRedPackketSendCountToday=%s,needSendCount=%s" 
                  % (maxCount, sysRedPackketSendCountToday, needSendCount))
    if needSendCount > 0:
@@ -374,23 +994,7 @@
    return
## 记录新红包数据
def __SaveNewRedRecord(family, ownerid, playerName, job, jobRank, getType, moneyType, outputNum, packetCnt,state=State_NoSend, wishStr='', sysCreateTime=None, data=0, isAnonymous=0):
    global g_allRecordDict
    global g_redPackCountDict
    recordType = ShareDefine.Def_UniversalGameRecType_FamilyRedPacketAllRecord
    universalRecMgr = GameWorld.GetUniversalRecMgr()
    recordList = universalRecMgr.GetTypeList(recordType)
    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
    familyID = family.GetID() if family else 0
    recData = recordList.AddRec()
def __SaveNewRedRecord(family, ownerID, playerName, job, jobRank, getType, moneyType, outputNum, packetCnt, state=State_NoSend, wishStr='', sysCreateTime=None, data=0, isAnonymous=0):
    
    #红包唯一ID 从1开始累计 超过20亿则重新开始
    # 红包唯一ID
@@ -400,21 +1004,33 @@
        redPacketID = 1
    PlayerDBGSEvent.SetDBGSTrig_ByKey(DB_RedPacketID, redPacketID)
    
    familyID = family.GetID() if family else 0
    curTimeNum = int(time.time())
    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.SetStrValue1('%s|%s|%s|%s'%(ownerid,playerName,job,getType)) #创建者ID|创建者名字|创建者职业|途径
    recData.SetStrValue2('%s|%s' % (packetCnt, int(isAnonymous)))#可抢总个数|是否匿名
    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))
    redPacketMgr = GetRedpacketMgr()
    redPacketObj = redPacketMgr.GetRedPacketObj(redPacketID, True)
    redPacketObj.redPacketID = redPacketID
    redPacketObj.familyID = familyID
    redPacketObj.moneyType = moneyType
    redPacketObj.moneyValue = outputNum
    redPacketObj.state = state
    redPacketObj.createTime = sysCreateTime if sysCreateTime else curTimeNum
    redPacketObj.calcTime = curTimeNum
    redPacketObj.playerID = ownerID
    redPacketObj.playerName = playerName
    redPacketObj.playerJob = job
    redPacketObj.getWay = getType
    redPacketObj.packetCnt = packetCnt
    redPacketObj.isAnonymous = isAnonymous # 是否匿名
    redPacketObj.wish = wishStr
    redPacketObj.grabDict = {}
    GameWorld.Log("生成新的红包: familyID=%s,redPacketID=%s,ownerID=%s,getType=%s,moneyType=%s,outputNum=%s,packetCnt=%s,state=%s,isAnonymous=%s"
                  % (familyID, redPacketID, ownerID, getType, moneyType, outputNum, packetCnt, state, isAnonymous))
    
    #֪ͨ
    __NotifyFamilyRedPacketInfo(family, recData, [])
    OnChangeRedPacketState(family, redPacketObj, None)
    if getType == ShareDefine.RedPackType_OpenServer:
        if not PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_OSRedPacket):
            PlayerControl.WorldNotify(0, 'OpenRedBag2', [playerName, data, outputNum])
@@ -431,100 +1047,7 @@
            and getType not in [ShareDefine.RedPackType_Server]:
            PlayerControl.WorldNotify(0, 'OSRedpackSfx', [getType])   
            
    return recData
def __CheckOSRedPacketCnt(recordList, maxCountKeyNum, getTypeList):
    global g_grabDataDict
    global g_allRecordDict
    global g_redPackCountDict
    ##开服红包个数是否达上限
    curRedCnt = g_redPackCountDict.get(maxCountKeyNum, 0)
    openServerRedPacketCnt = IpyGameDataPY.GetFuncCfg('OpenServerRedPacketCnt', 1) # 直接用开服红包这个配置作为通用配置
    if curRedCnt and curRedCnt < openServerRedPacketCnt + 10:
        return True
    allCnt = recordList.Count()
    curCnt = 0
    delRedPacketIDList = []
    for index in xrange(allCnt):
        universalRecData = recordList.At(index)
        strValue1 = universalRecData.GetStrValue1()
        strValue1List = strValue1.split('|')
        getWay = int(strValue1List[3])
        if getWay not in getTypeList:
            continue
        redPacketID = universalRecData.GetValue1()
        curCnt += 1
        if len(delRedPacketIDList) < 10:
            delRedPacketIDList.append(redPacketID)
        elif curRedCnt:
            break
    if not delRedPacketIDList:
        return True
    if not curRedCnt:
        curRedCnt = curCnt
    if curRedCnt < openServerRedPacketCnt + 10:
        return True
    delCnt = 0
    for index in xrange(recordList.Count()):
        dataIndex = index - delCnt
        universalRecData = recordList.At(dataIndex)
        delRedPacketID = universalRecData.GetValue1()
        if delRedPacketID in delRedPacketIDList:
            recordList.Delete(dataIndex)
            delCnt +=1
            g_grabDataDict.pop(delRedPacketID, 0)
            g_allRecordDict.pop(delRedPacketID, 0)
    curRedCnt -= delCnt
    recordType = ShareDefine.Def_UniversalGameRecType_FamilyRedPacketGrabRecord
    universalRecMgr = GameWorld.GetUniversalRecMgr()
    recordList = universalRecMgr.GetTypeList(recordType)
    delCnt = 0
    for index in xrange(recordList.Count()):
        dataIndex = index - delCnt
        universalRecData = recordList.At(dataIndex)
        if universalRecData.GetValue1() in delRedPacketIDList:
            recordList.Delete(dataIndex)
            delCnt +=1
    #֪ͨ
    NotifyDelRedPacketInfo(delRedPacketIDList)
    return True
def __DelGrabRecord():
    #删除多余抢信息
    universalRecMgr = GameWorld.GetUniversalRecMgr()
    allRecordList = universalRecMgr.GetTypeList(ShareDefine.Def_UniversalGameRecType_FamilyRedPacketAllRecord)
    allCnt = allRecordList.Count()
    redPacketIDList = []
    for index in xrange(allCnt):
        universalRecData = allRecordList.At(index)
        redPacketID = universalRecData.GetValue1()
        redPacketIDList.append(redPacketID)
    recordType = ShareDefine.Def_UniversalGameRecType_FamilyRedPacketGrabRecord
    recordList = universalRecMgr.GetTypeList(recordType)
    delCnt = 0
    for index in xrange(recordList.Count()):
        dataIndex = index - delCnt
        universalRecData = recordList.At(dataIndex)
        if universalRecData.GetValue1() not in redPacketIDList:
            recordList.Delete(dataIndex)
            delCnt +=1
    GameWorld.Log('    删除多余抢红包信息 delCnt=%s'%delCnt)
    return
isdel = False
if not isdel:
    __DelGrabRecord()
    isdel = True
    return redPacketObj
def SendFamilyRedPacket(msgList):
    '''发系统赠送的红包,该红包已存在,只是状态未发放,由归属玩家自由选择发放时机'''
@@ -533,15 +1056,13 @@
    if not curPlayer:
        return
    
    recDataList = __FindGrabRecData(ShareDefine.Def_UniversalGameRecType_FamilyRedPacketAllRecord,redPacketID)
    if not recDataList:
    redPacketMgr = GetRedpacketMgr()
    redPacketObj = redPacketMgr.GetRedPacketObj(redPacketID, False)
    if not redPacketObj:
        return
    recData=recDataList[0]
    strValue1 = recData.GetStrValue1()
    strValue1List = strValue1.split('|')
    ownID = int(strValue1List[0])
    getWay = int(strValue1List[3])
    ownID = redPacketObj.playerID
    getWay = redPacketObj.getWay
    
    ipyData = IpyGameDataPY.GetIpyGameDataByCondition('FamilyRedPack', {'GetType':getWay})
    if not ipyData:
@@ -551,88 +1072,81 @@
            GameWorld.DebugLog('    发系统赠送的红包 权限不足!', playerID)
            return
        if playerID != ownID:
            strValue1List[0] = str(playerID)
            StrValue1 = '|'.join(strValue1List)
            recData.SetStrValue1(StrValue1)
            redPacketObj.playerID = playerID
            
    elif playerID != ownID:
        GameWorld.DebugLog('    发系统赠送的红包 不是本人!', playerID)
        return
    
    recData.SetValue4(State_NoGot)
    recData.SetStrValue2('%s|%s' % (packetCnt, int(isAnonymous)))
    #更新时间
    curTimeNum = int(time.time())
    recData.SetValue5(curTimeNum)
    if recData.GetValue2() == 0:
    beforeState = redPacketObj.state
    redPacketObj.state = State_NoGot
    redPacketObj.packetCnt = packetCnt
    redPacketObj.isAnonymous = int(isAnonymous)
    redPacketObj.calcTime = int(time.time())
    if redPacketObj.familyID == 0:
        family = None
    else:
        family = curPlayer.GetFamily()
        if family == None:
            return
    __NotifyFamilyRedPacketInfo(family, recData, [])
    OnChangeRedPacketState(family, redPacketObj, beforeState)
    return
## 抢红包
def DoGrabFamilyRedPacket(curPlayer, msgList):
    global g_grabDataDict
    ## 抢红包
    redPacketID, reqGetWay, canGrabCnt = msgList
    
    playerID= curPlayer.GetPlayerID()
    job = curPlayer.GetJob()
    playerName = curPlayer.GetName()
    recDataList = __FindGrabRecData(ShareDefine.Def_UniversalGameRecType_FamilyRedPacketAllRecord, redPacketID)
    if not recDataList:
        GameWorld.Log('    未找到该仙盟红包记录redPacketID=%s'%redPacketID)
    redPacketMgr = GetRedpacketMgr()
    redPacketObj = redPacketMgr.GetRedPacketObj(redPacketID, False)
    if not redPacketObj:
        PlayerControl.NotifyCode(curPlayer, "该红包不存在!")
        return
    redPacketRecData = recDataList[0]
    state = redPacketRecData.GetValue4()
    playerID = curPlayer.GetPlayerID()
    state = redPacketObj.state
    beforeState = state
    if state in [State_NoSend]:
        GameWorld.DebugLog("    该仙盟红包还未发送!",playerID)
        GameWorld.DebugLog("    该红包还未发送!", playerID)
        return
    familyID = redPacketRecData.GetValue2()
    familyID = redPacketObj.familyID
    if familyID:
        curFamily = curPlayer.GetFamily()
        if curFamily == None:
            return
    else:
        curFamily = None
    value3 = redPacketRecData.GetValue3()
    moneyType, totalMoney =value3%10, value3/10
    strValue2 = redPacketRecData.GetStrValue2()
    strValue2List = strValue2.split('|')
    packetCnt = int(strValue2List[0])
    moneyType = redPacketObj.moneyType
    totalMoney = redPacketObj.moneyValue
    packetCnt = redPacketObj.packetCnt
    
    #找该红包的抢信息
    grabRecordDict = __GetGrabRecord(redPacketID)
    grabRecordDict = redPacketObj.grabDict
    if playerID in grabRecordDict:
        GameWorld.DebugLog("    该玩家已抢过此红包!", playerID)
        __NotifyGrabRedPacketInfo(curPlayer, redPacketID, grabRecordDict)
        return
    
    if len(grabRecordDict) >= packetCnt:
    outNum = sum([grabObj.getMoney for grabObj in grabRecordDict.values()]) #已被抢的钱
    remainNum = totalMoney - outNum #剩余的钱
    if len(grabRecordDict) >= packetCnt or remainNum <= 0:
        GameWorld.DebugLog("    红包已被抢完!", playerID)
        if state != State_HasAllGot:
            redPacketRecData.SetValue4(State_HasAllGot)
            redPacketObj.state = State_HasAllGot
            #GameWorld.DebugLog("    纠正红包已抢完状态! state=%s,updState=%s" % (state, State_HasAllGot))
            __NotifyFamilyRedPacketInfo(curFamily, redPacketRecData, grabRecordDict.keys())
            OnChangeRedPacketState(curFamily, redPacketObj, beforeState)
        __NotifyGrabRedPacketInfo(curPlayer, redPacketID, grabRecordDict)
        return
    
    outNum = sum([a[0] for a in grabRecordDict.values()]) #已被抢的钱
    remainNum = totalMoney - outNum #剩余的钱
    remainPacketCnt = packetCnt-len(grabRecordDict)
    if remainNum < remainPacketCnt:
        GameWorld.Log(' 该红包剩余的钱不够发 packetCnt =%s,totalMoney=%s,outNum=%s,remainMoney=%s,grabRecordDict=%s'%(packetCnt, totalMoney,outNum,remainNum, grabRecordDict))
        return
    strValue1 = redPacketRecData.GetStrValue1()
    strValue1List = strValue1.split('|')
    getWay = int(strValue1List[3])
    owerID = int(strValue1List[0])
    remainPacketCnt = packetCnt - len(grabRecordDict)
    getWay = redPacketObj.getWay
    owerID = redPacketObj.playerID
    isSelf = owerID == playerID
    if not isSelf and canGrabCnt != -1 and canGrabCnt <= 0:
        GameWorld.DebugLog('    抢开服红包,次数不足!!')
@@ -640,6 +1154,7 @@
    if reqGetWay != getWay:
        GameWorld.ErrLog("领取的红包类型不一致,无法领取! reqGetWay=%s,getWay=%s" % (reqGetWay, getWay))
        return
    if getWay in [ShareDefine.RedPackType_OpenServer, ShareDefine.RedPackType_Server]:
        getNumformula = IpyGameDataPY.GetFuncCompileCfg('OpenRedRacketOutNum')
    elif getWay in ShareDefine.FeastRedPackType:
@@ -648,23 +1163,25 @@
        getNumformula = IpyGameDataPY.GetFuncCompileCfg('FamilyRedRacketOutNum')
        
    getMoney = eval(getNumformula) if remainPacketCnt > 1 else remainNum
    GameWorld.DebugLog("    该玩家抢到红包=%s!"%getMoney, playerID)
    grabRecordDict[playerID] = [getMoney, playerName, job]
    #新增一条抢的记录
    recType = ShareDefine.Def_UniversalGameRecType_FamilyRedPacketGrabRecord
    valueList = [redPacketID, playerID, job, moneyType, getMoney]
    strValueList = [playerName]
    PlayerUniversalGameRec.MapServer_UniversalGameRec(None, recType, valueList, strValueList)
    #{playerid:[抢到的钱,名字,job]}
    g_grabDataDict[redPacketID] = grabRecordDict
    getMoney = min(getMoney, remainNum)
    remainNum -= getMoney
    GameWorld.DebugLog("    该玩家抢到红包=%s!" % getMoney, playerID)
    
    if len(grabRecordDict) >= packetCnt:
        redPacketRecData.SetValue4(State_HasAllGot)
        #通知该玩家红包抢结果
        __NotifyFamilyRedPacketInfo(curFamily, redPacketRecData, grabRecordDict.keys())
    # 新增抢的记录
    grabObj = RedPacketGrab(redPacketID, playerID)
    grabObj.playerJob = curPlayer.GetJob()
    grabObj.playerName = curPlayer.GetName()
    grabObj.moneyType = moneyType
    grabObj.getMoney = getMoney
    grabRecordDict[playerID] = grabObj
    if len(grabRecordDict) >= packetCnt or remainNum <= 0:
        redPacketObj.state = State_HasAllGot
        OnChangeRedPacketState(curFamily, redPacketObj, beforeState)
    else:
        NotifyRedPacketInfo(curPlayer, [redPacketRecData, grabRecordDict.keys()])
        if getWay in IpyGameDataPY.GetFuncEvalCfg("RedPacketSys", 1):
            redPacketMgr.DelPlayerCanGetRedPacketID(playerID, getWay, redPacketID)
        NotifyRedPacketInfo(curPlayer, [redPacketID])
        
    __NotifyGrabRedPacketInfo(curPlayer, redPacketID, grabRecordDict)
    
@@ -673,289 +1190,103 @@
    curPlayer.MapServer_QueryPlayerResult(0, 0, "GrabFamilyRedPacketResult", result, len(result))
    return getMoney
## 获取抢红包记录
def __GetGrabRecord(redPacketID):
    if redPacketID in g_grabDataDict:
        return g_grabDataDict[redPacketID]
    recDataList = __FindGrabRecData(ShareDefine.Def_UniversalGameRecType_FamilyRedPacketGrabRecord, redPacketID)
    if not recDataList:
        return {}
    grabRecordDict = {}
    for recData in recDataList: #{playerid:[抢到的钱,名字,job]}
        grabRecordDict[recData.GetValue2()] = [recData.GetValue5(), recData.GetStrValue1(), recData.GetValue3()]
    return grabRecordDict
def __FindGrabRecData(recordType, redPacketID):
    global g_allRecordDict
    if recordType == ShareDefine.Def_UniversalGameRecType_FamilyRedPacketAllRecord:
        if redPacketID in g_allRecordDict:
            frecData = g_allRecordDict[redPacketID]
            if frecData:
                return [frecData]
    recDataList = []
    universalRecMgr = GameWorld.GetUniversalRecMgr()
    allRecordList = universalRecMgr.GetTypeList(recordType)
    allCnt = allRecordList.Count()
    for index in xrange(allCnt):
        recData = allRecordList.At(index)
        if recData.GetValue1() == redPacketID:
            recDataList.append(recData)
            if recordType == ShareDefine.Def_UniversalGameRecType_FamilyRedPacketAllRecord:
                g_allRecordDict[redPacketID] = recData
                break
    return recDataList
## 检查红包是否过期
def __CheckGrabRecData():
    global g_grabDataDict
    global g_allRecordDict
    global g_redPackCountDict
    g_redPackCountDict = {}
    universalRecMgr = GameWorld.GetUniversalRecMgr()
    allRecordList = universalRecMgr.GetTypeList(ShareDefine.Def_UniversalGameRecType_FamilyRedPacketAllRecord)
    allCnt = allRecordList.Count()
    curTimeNum = int(time.time())
    rangeTime = 24*60*60
    backMoneyDict = {}
    delRedPacketIDList = []
    familyIDList = []
    delCnt = 0
    for index in xrange(allCnt):
        dataIndex = index - delCnt
        universalRecData = allRecordList.At(dataIndex)
        saveTime = universalRecData.GetValue5()
        GameWorld.DebugLog("    检查红包是否过期 curTime=%s,saveTime=%s,rangeTime=%s,redPacketID=%s"%(curTimeNum, saveTime, curTimeNum -saveTime,universalRecData.GetValue1()))
        if curTimeNum -saveTime > rangeTime:#过期
            redPacketID = universalRecData.GetValue1()
            strValue1 = universalRecData.GetStrValue1()
            strValue1List = strValue1.split('|')
            playerID = strValue1List[0]
            getWay = int(strValue1List[3])
            if playerID and getWay is ShareDefine.RedPackType_GoldPacket:
                playerID = int(playerID)
                grabRecordDict = __GetGrabRecord(redPacketID)
                outNum = sum([a[0] for a in grabRecordDict.values()]) #已被抢的钱
                value3 = universalRecData.GetValue3()
                moneyType, totalMoney =value3%10, value3/10
                remainMoney = totalMoney - outNum #剩余的钱
                #GameWorld.DebugLog('    outNum=%s,remainMoney=%s,moneyType=%s'%(outNum,remainMoney,moneyType))
                if moneyType ==1 and remainMoney:
                    backMoneyDict[playerID] = backMoneyDict.get(playerID, 0) + remainMoney
            delRedPacketIDList.append(redPacketID)
            familyID=universalRecData.GetValue2()
            if familyID not in familyIDList:
                familyIDList.append(familyID)
            allRecordList.Delete(dataIndex)
            delCnt +=1
    if not delRedPacketIDList:
        return
    for redID in delRedPacketIDList:
        g_grabDataDict.pop(redID, 0)
        g_allRecordDict.pop(redID, 0)
    recordType = ShareDefine.Def_UniversalGameRecType_FamilyRedPacketGrabRecord
    recordList = universalRecMgr.GetTypeList(recordType)
    delCnt = 0
    for index in xrange(recordList.Count()):
        dataIndex = index - delCnt
        universalRecData = recordList.At(dataIndex)
        if universalRecData.GetValue1() in delRedPacketIDList:
            recordList.Delete(dataIndex)
            delCnt +=1
    NotifyDelRedPacketInfo(delRedPacketIDList)
    #返回玩家未被领取的仙玉
    if backMoneyDict:
        for playerID, moneyNum in backMoneyDict.items():
            PlayerCompensation.SendMailByKey('RedPackBack', [playerID], [], [], moneyNum)
    return
def DelRedPackByFamilyID(delfamilyID):
    global g_grabDataDict
    global g_allRecordDict
    #删除某个家族的红包记录
    universalRecMgr = GameWorld.GetUniversalRecMgr()
    allRecordList = universalRecMgr.GetTypeList(ShareDefine.Def_UniversalGameRecType_FamilyRedPacketAllRecord)
    allCnt = allRecordList.Count()
    delRedPacketIDList = []
    delCnt = 0
    for index in xrange(allCnt):
        dataIndex = index - delCnt
        universalRecData = allRecordList.At(dataIndex)
        familyID=universalRecData.GetValue2()
        if delfamilyID != familyID:
            continue
        redPacketID = universalRecData.GetValue1()
        delRedPacketIDList.append(redPacketID)
        allRecordList.Delete(dataIndex)
        delCnt +=1
    if not delRedPacketIDList:
        return
    for redID in delRedPacketIDList:
        g_grabDataDict.pop(redID, 0)
        g_allRecordDict.pop(redID, 0)
    recordList = universalRecMgr.GetTypeList(ShareDefine.Def_UniversalGameRecType_FamilyRedPacketGrabRecord)
    delCnt = 0
    for index in xrange(recordList.Count()):
        dataIndex = index - delCnt
        universalRecData = recordList.At(dataIndex)
        if universalRecData.GetValue1() in delRedPacketIDList:
            recordList.Delete(dataIndex)
            delCnt +=1
    #NotifyDelRedPacketInfo(delRedPacketIDList)
    return
## 红包变更通知单个红包给对应战盟所有成员
def __NotifyFamilyRedPacketInfo(family, redPacketRecData, grabHeroIDList):
    syncPacketDataList = [redPacketRecData, grabHeroIDList]
#    recordType = ShareDefine.Def_UniversalGameRecType_FamilyRedPacketAllRecord
#    universalRecMgr = GameWorld.GetUniversalRecMgr()
#    recordList = universalRecMgr.GetTypeList(recordType)
#    for index in xrange(recordList.Count()):
#        recData = recordList.At(index)
#        familyID = recData.GetValue2()
#        if familyID and family and family.GetID() != familyID:
#            continue
#        if redPacketID:
#            if recData.GetValue1() == redPacketID:
#                syncPacketDataList = [recData, grabHeroIDList]
#                break
#        else:
#            syncPacketDataList.append(recData)
    if not syncPacketDataList:
        return
    playerManager = GameWorld.GetPlayerManager()
    if not family:
        for i in xrange(0, playerManager.GetActivePlayerCount()):
            curPlayer = playerManager.GetActivePlayerAt(i)
            if curPlayer == None or not curPlayer.GetInitOK():
                continue
            NotifyRedPacketInfo(curPlayer, syncPacketDataList)
    else:
        for i in xrange(0, family.GetCount()):
            notifyMember = family.GetAt(i)
            notifyPlayer = playerManager.FindPlayerByID(notifyMember.GetPlayerID())
            if notifyPlayer == None:
                continue
            NotifyRedPacketInfo(notifyPlayer, syncPacketDataList)
    return
## 通知红包信息
# 通知玩家本战盟所有红包或单个红包
def NotifyRedPacketInfo(curPlayer, packetDataList=[]):
    if PlayerControl.GetIsTJG(curPlayer):
        return
    if not packetDataList:
        syncPacketDataList = []
        recordType = ShareDefine.Def_UniversalGameRecType_FamilyRedPacketAllRecord
        universalRecMgr = GameWorld.GetUniversalRecMgr()
        recordList = universalRecMgr.GetTypeList(recordType)
        for index in xrange(recordList.Count()):
            recData = recordList.At(index)
            familyID = recData.GetValue2()
            if familyID and curPlayer.GetFamilyID() != familyID:
                continue
            grabRecordDict = __GetGrabRecord(recData.GetValue1())
            syncPacketDataList.append([recData, grabRecordDict.keys()])
    else:
        syncPacketDataList = [packetDataList]
    if not syncPacketDataList:
        return
    joinFamilyTime = PlayerFamily.GetPlayerJoinFamilyTime(curPlayer)
    sendPack = ChPyNetSendPack.tagGCFamilyRedPacketInfo()
    sendPack.Clear()
    sendPack.IsAll = int(packetDataList==[])
    sendPack.RedPacketInfo = []
    for packetData, grabHeroIDList in syncPacketDataList:
        #仙盟红包只通知玩家进入仙盟后生成的红包
        #GameWorld.Log('1111packetData.GetValue2()=%s,joinFamilyTime=%s,packetData.GetValue5()=%s'%(packetData.GetValue2(),joinFamilyTime,packetData.GetValue5()))
        if packetData.GetValue2() and joinFamilyTime and packetData.GetValue5() < joinFamilyTime:
            continue
        packetInfo = ChPyNetSendPack.tagFRedPacketInfo()
        packetInfo.Clear()
        packetInfo.RedPacketID = packetData.GetValue1()
        strValue1 = packetData.GetStrValue1()
        strValue1List = strValue1.split('|')
        if len(strValue1List) != 4:
            return
        playerID, playerName, job, getWay = strValue1List
        packetInfo.PlayerID = int(playerID)
        packetInfo.Name = playerName
        packetInfo.Time = packetData.GetTime()
        packetInfo.PlayeJob = int(job)
        value3 = packetData.GetValue3()
        packetInfo.MoneyType = value3 % 10
        packetInfo.MoneyNum = value3 / 10
        packetInfo.GetWay = int(getWay)
        state = packetData.GetValue4()
        if curPlayer.GetPlayerID() in grabHeroIDList:
            state = State_HasGot
        if sendPack.IsAll and state in [State_HasGot, State_HasAllGot]:
            #GameWorld.DebugLog("已抢或抢完的不发: RedPacketID=%s,state=%s" % (packetInfo.RedPacketID, state))
            continue
        packetInfo.State = state
        strValue2 = packetData.GetStrValue2()
        strValue2List = strValue2.split('|')
        packetInfo.PacketCnt = int(strValue2List[0])
        packetInfo.IsAnonymous = int(strValue2List[1]) if len(strValue2List) > 1 else 0
        packetInfo.Wish = packetData.GetStrValue3()
        sendPack.RedPacketInfo.append(packetInfo)
        if len(sendPack.RedPacketInfo) > 250:
            #GameWorld.DebugLog("红包太多了!")
            break
    sendPack.Count = len(sendPack.RedPacketInfo)
    NetPackCommon.SendFakePack(curPlayer, sendPack)
    #GameWorld.Log('仙盟红包通知 IsAll=%s,Count=%s,syncPacketDataList=%s,redPacketID=%s'%(sendPack.IsAll,sendPack.Count,syncPacketDataList,redPacketID))
    return
def __NotifyGrabRedPacketInfo(curPlayer, redPacketID, grabRecordDict):
    '''通知抢红包信息'''
    sendPack = ChPyNetSendPack.tagGCFamilyRedPacketGrabInfo()
    sendPack.Clear()
    sendPack.RedPacketID = redPacketID
    #grabRecordDict = __GetGrabRecord(redPacketID) #{playerid:[抢到的钱,名字,job]}
    sendPack.Count = len(grabRecordDict)
    sendPack.GrabInfo = []
    for playerID, info in grabRecordDict.items():
        money, name, job = info
    for grabObj in grabRecordDict.values():
        grabInfo = ChPyNetSendPack.tagFGrabRedPacketInfo()
        grabInfo.Name = name
        grabInfo.PlayeJob = job
        grabInfo.MoneyNum = money
        grabInfo.Name = grabObj.playerName
        grabInfo.NameLen = len(grabInfo.Name)
        grabInfo.PlayeJob = grabObj.playerJob
        grabInfo.MoneyNum = grabObj.getMoney
        sendPack.GrabInfo.append(grabInfo)
    sendPack.Count = len(sendPack.GrabInfo)
    NetPackCommon.SendFakePack(curPlayer, sendPack)
    return
def NotifyDelRedPacketInfo(delRedPacketIDList):
    ##通知红包删除信息
    sendPack = ChPyNetSendPack.tagGCRedPacketDel()
    sendPack.Clear()
    sendPack.DelRedPacketID = delRedPacketIDList
    sendPack.Cnt = len(delRedPacketIDList)
    playerManager = GameWorld.GetPlayerManager()
    for i in xrange(0, playerManager.GetActivePlayerCount()):
        curPlayer = playerManager.GetActivePlayerAt(i)
        if curPlayer == None or not curPlayer.GetInitOK():
def NotifyRedPacketInfo(curPlayer, syncRedPacketIDList=None, isLogin=False):
    ## 通知红包信息
    if PlayerControl.GetIsTJG(curPlayer):
        return
    redPacketMgr = GetRedpacketMgr()
    isAll = int(syncRedPacketIDList == None)
    if syncRedPacketIDList == None:
        syncRedPacketIDList = []
        playerID = curPlayer.GetPlayerID()
        family = curPlayer.GetFamily()
        familyID = family.GetID() if family else 0
        syncRedPacketIDList += redPacketMgr.familyRedPacketDict.get(familyID, []) # 1. 仙盟所有(含未开放的)
        syncRedPacketIDList += redPacketMgr.notifyAllServerRedPacketIDList # 2. 全服不限制下发个数
        # 3. 全服私有未开放
        for redIDList in redPacketMgr.playerNosendRedPacketIDInfo.get(playerID, {}).values():
            syncRedPacketIDList += redIDList
        # 4. 全服限制下发个数分配给个人可领取的红包
        for redIDList in redPacketMgr.playerCanGetRedPacketIDInfo.get(playerID, {}).values():
            syncRedPacketIDList += redIDList
    if not syncRedPacketIDList and isLogin:
        return
    redPacketInfo = []
    playerID = curPlayer.GetPlayerID()
    joinFamilyTime = PlayerFamily.GetPlayerJoinFamilyTime(curPlayer)
    GameWorld.DebugLog("通知红包信息: isLogin=%s,isAll=%s,syncRedPacketIDList=%s" % (isLogin, isAll, syncRedPacketIDList), playerID)
    for redPacketID in syncRedPacketIDList:
        redPacketObj = redPacketMgr.GetRedPacketObj(redPacketID, False)
        if not redPacketObj:
            continue
        NetPackCommon.SendFakePack(curPlayer, sendPack)
    return
        #仙盟红包只通知玩家进入仙盟后生成的红包
        if redPacketObj.familyID:
            if joinFamilyTime and redPacketObj.calcTime < joinFamilyTime:
                GameWorld.DebugLog("    加入仙盟之前的红包不发: redPacketID=%s,joinFamilyTime=%s > %s" % (redPacketID, joinFamilyTime, redPacketObj.calcTime))
                continue
        state = redPacketObj.state
        if playerID in redPacketObj.grabDict:
            state = State_HasGot
        if isAll and state in [State_HasGot, State_HasAllGot]:
            GameWorld.DebugLog("    已抢或抢完的不发: redPacketID=%s,state=%s" % (redPacketID, state))
            continue
        packetInfo = ChPyNetSendPack.tagFRedPacketInfo()
        packetInfo.Clear()
        packetInfo.RedPacketID = redPacketObj.redPacketID
        packetInfo.PlayerID = redPacketObj.playerID
        packetInfo.Name = "" if redPacketObj.isAnonymous else redPacketObj.playerName
        packetInfo.NameLen = len(packetInfo.Name)
        packetInfo.Time = redPacketObj.createTime
        packetInfo.PlayeJob = redPacketObj.playerJob
        packetInfo.MoneyType = redPacketObj.moneyType
        packetInfo.MoneyNum = redPacketObj.moneyValue
        packetInfo.GetWay = redPacketObj.getWay
        packetInfo.State = state
        packetInfo.PacketCnt = redPacketObj.packetCnt
        packetInfo.IsAnonymous = int(redPacketObj.isAnonymous)
        packetInfo.Wish = redPacketObj.wish
        packetInfo.WishLen = len(packetInfo.Wish)
        redPacketInfo.append(packetInfo)
        if len(redPacketInfo) > 250:
            #GameWorld.DebugLog("红包太多了!")
            break
    if not redPacketInfo:
        return
    sendPack = ChPyNetSendPack.tagGCFamilyRedPacketInfo()
    sendPack.Clear()
    sendPack.IsAll = isAll
    sendPack.RedPacketInfo = redPacketInfo
    sendPack.Count = len(sendPack.RedPacketInfo)
    NetPackCommon.SendFakePack(curPlayer, sendPack)
    return
ServerPython/CoreServerGroup/GameServer/Script/PyGameData.py
@@ -79,6 +79,8 @@
g_partyheroAnswerDict = {} #仙盟宴会玩家答对题目数量 {playerid:答题数量,..}
g_familyAnswerPlayerIDDict = {} #仙盟宴会玩家参与答题数量  {playerID:[题目ID, ...], ...}
g_redPacketMgr = None # RedPacketMgr
g_bourseItemTradingTimeDict = {} # 物品开始交易的时间记录 {guid:tick}
g_fbHelpBattleCheckInPlayerDict = {} # 副本助战玩家登记缓存 {playerID:HelpBattlePlayer, ...}
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
@@ -1272,7 +1272,8 @@
# A4 05 家族红包抢的信息 #tagGCFamilyRedPacketGrabInfo
class  tagFGrabRedPacketInfo(Structure):
    Name = ""    #(char Name[33])//名字
    NameLen = 0    #(BYTE NameLen)
    Name = ""    #(String Name)//名字
    PlayeJob = 0    #(BYTE PlayeJob)//玩家职业
    MoneyNum = 0    #(DWORD MoneyNum)//金钱数量
    data = None
@@ -1283,12 +1284,14 @@
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        self.Name,_pos = CommFunc.ReadString(_lpData, _pos,33)
        self.NameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.Name,_pos = CommFunc.ReadString(_lpData, _pos,self.NameLen)
        self.PlayeJob,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.MoneyNum,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        return _pos
    def Clear(self):
        self.NameLen = 0
        self.Name = ""
        self.PlayeJob = 0
        self.MoneyNum = 0
@@ -1296,7 +1299,8 @@
    def GetLength(self):
        length = 0
        length += 33
        length += 1
        length += len(self.Name)
        length += 1
        length += 4
@@ -1304,18 +1308,21 @@
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, 33, self.Name)
        data = CommFunc.WriteBYTE(data, self.NameLen)
        data = CommFunc.WriteString(data, self.NameLen, self.Name)
        data = CommFunc.WriteBYTE(data, self.PlayeJob)
        data = CommFunc.WriteDWORD(data, self.MoneyNum)
        return data
    def OutputString(self):
        DumpString = '''
                                NameLen:%d,
                                Name:%s,
                                PlayeJob:%d,
                                MoneyNum:%d
                                '''\
                                %(
                                self.NameLen,
                                self.Name,
                                self.PlayeJob,
                                self.MoneyNum
@@ -1402,7 +1409,8 @@
class  tagFRedPacketInfo(Structure):
    RedPacketID = 0    #(DWORD RedPacketID)//红包唯一ID
    PlayerID = 0    #(DWORD PlayerID)//玩家ID
    Name = ""    #(char Name[33])//玩家名字
    NameLen = 0    #(BYTE NameLen)
    Name = ""    #(String Name)//玩家名字
    Time = 0    #(DWORD Time)//时间
    PlayeJob = 0    #(BYTE PlayeJob)//玩家职业
    MoneyType = 0    #(BYTE MoneyType)//金钱类型
@@ -1410,7 +1418,8 @@
    GetWay = 0    #(BYTE GetWay)//获得途径
    PacketCnt = 0    #(BYTE PacketCnt)//可抢个数
    State = 0    #(BYTE State)//0未发,1未领取,2已领取,3全部领完
    Wish = ""    #(char Wish[33])//祝福语
    WishLen = 0    #(BYTE WishLen)
    Wish = ""    #(String Wish)//祝福语
    IsAnonymous = 0    #(BYTE IsAnonymous)//是否匿名
    data = None
@@ -1422,7 +1431,8 @@
        self.Clear()
        self.RedPacketID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.PlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.Name,_pos = CommFunc.ReadString(_lpData, _pos,33)
        self.NameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.Name,_pos = CommFunc.ReadString(_lpData, _pos,self.NameLen)
        self.Time,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.PlayeJob,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.MoneyType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
@@ -1430,13 +1440,15 @@
        self.GetWay,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.PacketCnt,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.State,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.Wish,_pos = CommFunc.ReadString(_lpData, _pos,33)
        self.WishLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.Wish,_pos = CommFunc.ReadString(_lpData, _pos,self.WishLen)
        self.IsAnonymous,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        return _pos
    def Clear(self):
        self.RedPacketID = 0
        self.PlayerID = 0
        self.NameLen = 0
        self.Name = ""
        self.Time = 0
        self.PlayeJob = 0
@@ -1445,6 +1457,7 @@
        self.GetWay = 0
        self.PacketCnt = 0
        self.State = 0
        self.WishLen = 0
        self.Wish = ""
        self.IsAnonymous = 0
        return
@@ -1453,7 +1466,8 @@
        length = 0
        length += 4
        length += 4
        length += 33
        length += 1
        length += len(self.Name)
        length += 4
        length += 1
        length += 1
@@ -1461,7 +1475,8 @@
        length += 1
        length += 1
        length += 1
        length += 33
        length += 1
        length += len(self.Wish)
        length += 1
        return length
@@ -1470,7 +1485,8 @@
        data = ''
        data = CommFunc.WriteDWORD(data, self.RedPacketID)
        data = CommFunc.WriteDWORD(data, self.PlayerID)
        data = CommFunc.WriteString(data, 33, self.Name)
        data = CommFunc.WriteBYTE(data, self.NameLen)
        data = CommFunc.WriteString(data, self.NameLen, self.Name)
        data = CommFunc.WriteDWORD(data, self.Time)
        data = CommFunc.WriteBYTE(data, self.PlayeJob)
        data = CommFunc.WriteBYTE(data, self.MoneyType)
@@ -1478,7 +1494,8 @@
        data = CommFunc.WriteBYTE(data, self.GetWay)
        data = CommFunc.WriteBYTE(data, self.PacketCnt)
        data = CommFunc.WriteBYTE(data, self.State)
        data = CommFunc.WriteString(data, 33, self.Wish)
        data = CommFunc.WriteBYTE(data, self.WishLen)
        data = CommFunc.WriteString(data, self.WishLen, self.Wish)
        data = CommFunc.WriteBYTE(data, self.IsAnonymous)
        return data
@@ -1486,6 +1503,7 @@
        DumpString = '''
                                RedPacketID:%d,
                                PlayerID:%d,
                                NameLen:%d,
                                Name:%s,
                                Time:%d,
                                PlayeJob:%d,
@@ -1494,12 +1512,14 @@
                                GetWay:%d,
                                PacketCnt:%d,
                                State:%d,
                                WishLen:%d,
                                Wish:%s,
                                IsAnonymous:%d
                                '''\
                                %(
                                self.RedPacketID,
                                self.PlayerID,
                                self.NameLen,
                                self.Name,
                                self.Time,
                                self.PlayeJob,
@@ -1508,6 +1528,7 @@
                                self.GetWay,
                                self.PacketCnt,
                                self.State,
                                self.WishLen,
                                self.Wish,
                                self.IsAnonymous
                                )