| | |
| | | State_HasAllGot, #全部领完
|
| | | ) = range(4)
|
| | |
|
| | | g_allRecordDict = {} #{红包ID:recData, ...}
|
| | | g_grabDataDict = {} #{红包ID:{playerid:[抢到的钱,名字,job]}, ...}
|
| | | g_redPackCountDict = {} #有限制最大红包个数的类型对应当前红包数 {类型组对应记录编号:当前个数, ...}
|
| | |
|
| | | DBKey_RedPacketSend = "RedPacketSend_%s" # 系统定时红包是否已发放, 参数红包ID
|
| | | DBKey_RedPacketSystemDayCount = "RedPacketSystemDayCount" # 全服系统红包已发放个数
|
| | |
|
| | |
| | | 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
|
| | |
| | |
|
| | | def AddPlayerCanGetRedPacketID(self, playerID, getWay, redPacketID):
|
| | | ## 添加玩家可领取的红包ID缓存
|
| | | if not playerID:
|
| | | return
|
| | | if playerID not in self.playerCanGetRedPacketIDInfo:
|
| | | self.playerCanGetRedPacketIDInfo[playerID] = {}
|
| | | redPacketTypeIDInfo = self.playerCanGetRedPacketIDInfo[playerID]
|
| | |
| | | redPacketIDList = redPacketTypeIDInfo[getWay]
|
| | | if redPacketID not in redPacketIDList:
|
| | | redPacketIDList.append(redPacketID)
|
| | | return redPacketIDList
|
| | | return
|
| | |
|
| | | def DelPlayerCanGetRedPacketID(self, playerID, getWay, redPacketID):
|
| | |
| | | redPacketIDList.remove(redPacketID)
|
| | | # 返回当前类型可用红包ID列表
|
| | | return redPacketIDList
|
| | | |
| | | def PrintRedPacketData(sign=""):
|
| | | redPacketMgr = GetRedpacketMgr()
|
| | | if sign:
|
| | | GameWorld.DebugLog(" === %s ===" % sign)
|
| | | GameWorld.DebugLog(" 所有红包:count=%s,=%s" % (len(redPacketMgr.allRedPacketDict), redPacketMgr.allRedPacketDict.keys()))
|
| | | for familyID, redIDList in redPacketMgr.familyRedPacketDict.items():
|
| | | GameWorld.DebugLog(" 仙盟红包:familyID=%s,count=%s,%s" % (familyID, len(redIDList), redIDList))
|
| | | GameWorld.DebugLog(" 全服全部下发红包=%s" % redPacketMgr.notifyAllServerRedPacketIDList)
|
| | | for getWay, redIDList in redPacketMgr.activeRedPacketIDInfo.items():
|
| | | GameWorld.DebugLog(" 全服公共活跃红包:getWay=%s,count=%s,%s" % (getWay, len(redIDList), redIDList))
|
| | | for playerID, redIDInfo in redPacketMgr.playerNosendRedPacketIDInfo.items():
|
| | | for getWay, redIDList in redIDInfo.items():
|
| | | GameWorld.DebugLog(" 全服个人未开放红包:playerID=%s,getWay=%s,count=%s,%s" % (playerID, getWay, len(redIDList), redIDList))
|
| | | for playerID, redIDInfo in redPacketMgr.playerCanGetRedPacketIDInfo.items():
|
| | | for getWay, redIDList in redIDInfo.items():
|
| | | GameWorld.DebugLog(" 全服个人可领取红包:playerID=%s,getWay=%s,count=%s,%s" % (playerID, getWay, len(redIDList), redIDList))
|
| | | return
|
| | |
|
| | | def GetRedpacketMgr():
|
| | | redPacketMgr = PyGameData.g_redPacketMgr
|
| | |
| | |
|
| | | redPacketObj.grabDict[playerID] = grabObj
|
| | |
|
| | | redPacketMgr.PrintData("OnServerStart")
|
| | | #PrintRedPacketData("OnServerStart")
|
| | | return
|
| | |
|
| | | def OnServerClose():
|
| | |
| | | redPacketMgr = GetRedpacketMgr()
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | redPacketMgr.playerCanGetRedPacketIDInfo[playerID] = {}
|
| | | redPacketMgr.PrintData("OnPlayerLogin %s" % playerID)
|
| | |
|
| | | notifyLimitTypeList = IpyGameDataPY.GetFuncEvalCfg("RedPacketSys", 1)
|
| | | maxNotifyCount = IpyGameDataPY.GetFuncCfg("RedPacketSys", 2)
|
| | |
| | | break
|
| | | redPacketMgr.playerCanGetRedPacketIDInfo[playerID][getWay] = playerCanGetIDList
|
| | |
|
| | | redPacketMgr.PrintData("loginOK")
|
| | | #PrintRedPacketData("OnPlayerLogin %s" % playerID)
|
| | |
|
| | | NotifyRedPacketInfo(curPlayer, isLogin=True)
|
| | | return
|
| | |
| | | playerManager = GameWorld.GetPlayerManager()
|
| | |
|
| | | # 同步删除的仙盟红包
|
| | | GameWorld.DebugLog("同步删除的仙盟红包: %s" % delFamilyRedPacketInfo)
|
| | | #GameWorld.DebugLog("同步删除的仙盟红包: %s" % delFamilyRedPacketInfo)
|
| | | for familyID, delIDList in delFamilyRedPacketInfo.items():
|
| | | family = GameWorld.GetFamilyManager().FindFamily(familyID)
|
| | | if not family:
|
| | |
| | | NetPackCommon.SendFakePack(curPlayer, sendPack)
|
| | |
|
| | | # 同步删除个人未开放的全服红包
|
| | | GameWorld.DebugLog("同步删除个人未开放的全服红包: %s" % delNosendRedPacketInfo)
|
| | | #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):
|
| | |
| | | NetPackCommon.SendFakePack(curPlayer, sendPack)
|
| | |
|
| | | # 同步删除已开放的全服红包
|
| | | GameWorld.DebugLog("同步删除已开放的全服红包: %s" % delRedPacketIDList)
|
| | | #GameWorld.DebugLog("同步删除已开放的全服红包: %s" % delRedPacketIDList)
|
| | | if delRedPacketIDList:
|
| | | sendPack = ChPyNetSendPack.tagGCRedPacketDel()
|
| | | sendPack.Clear()
|
| | |
| | |
|
| | | GameWorld.DebugLog("红包状态变更处理: redPacketID=%s,ownerID=%s,familyID=%s,beforeState=%s,state=%s"
|
| | | % (redPacketID, ownerID, familyID, beforeState, state))
|
| | | redPacketMgr.PrintData("a")
|
| | |
|
| | | notifyPlayerDict = {ownerID:[redPacketID]} # 通知给指定玩家的信息,每个玩家可能不一样
|
| | |
|
| | |
| | | if family:
|
| | | if state in [State_NoSend, State_NoGot]:
|
| | | redPacketMgr.AddFamilyRedPacketID(family.GetID(), redPacketID)
|
| | | |
| | | elif state == State_HasAllGot:
|
| | | redPacketMgr.DelFamilyRedPacketID(familyID, redPacketID)
|
| | | |
| | | # 除仙盟红包外,以下是全服红包的相关处理
|
| | | |
| | | # 2. 全服未开放红包默认只发给个人
|
| | | elif state == State_NoSend:
|
| | | if not ownerID:
|
| | |
| | | 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
|
| | | for playerID in redPacketMgr.playerCanGetRedPacketIDInfo.keys():
|
| | | notifyRedIDList = DoPlayerReductCanGetRedPacket(playerID, redPacketObj, nowActiveRedPacketIDList)
|
| | | if notifyRedIDList:
|
| | | notifyPlayerDict[playerID] = notifyRedIDList
|
| | | else:
|
| | | return
|
| | |
|
| | | redPacketMgr.PrintData("b")
|
| | | #PrintRedPacketData("StateChange")
|
| | |
|
| | | syncRedPacketList = [redPacketID]
|
| | | playerManager = GameWorld.GetPlayerManager()
|
| | |
| | | # 通知指定玩家
|
| | | else:
|
| | | for playerID, syncRedPacketList in notifyPlayerDict.items():
|
| | | if not playerID:
|
| | | continue
|
| | | player = playerManager.FindPlayerByID(playerID)
|
| | | if player == None or not player.GetInitOK() or PlayerControl.GetIsTJG(player):
|
| | | continue
|
| | | NotifyRedPacketInfo(player, syncRedPacketList)
|
| | | return
|
| | |
|
| | | def DoPlayerReductCanGetRedPacket(playerID, redPacketObj, nowActiveRedPacketIDList=None):
|
| | | ## 玩家减少全服限制下发红包可领取个数处理
|
| | | ## @return: 需要通知的红包ID列表
|
| | | |
| | | getWay = redPacketObj.getWay
|
| | | redPacketID = redPacketObj.redPacketID
|
| | | |
| | | redPacketMgr = GetRedpacketMgr()
|
| | | if nowActiveRedPacketIDList == None:
|
| | | nowActiveRedPacketIDList = redPacketMgr.activeRedPacketIDInfo.get(getWay, []) # 当前此类型还可用的公共已开放红包列表
|
| | | |
| | | # 检查需要补充红包记录的玩家,采用 减去1 补充1 的模式
|
| | | canGetIDList = redPacketMgr.DelPlayerCanGetRedPacketID(playerID, getWay, redPacketID) # 移出私有已开放红包队列
|
| | | if canGetIDList == None:
|
| | | return
|
| | | |
| | | lastCanGetID = 0 if not canGetIDList else canGetIDList[-1]
|
| | | checkIndex = nowActiveRedPacketIDList.index(lastCanGetID) if lastCanGetID in nowActiveRedPacketIDList else 0
|
| | | for i in xrange(checkIndex + 1, len(nowActiveRedPacketIDList)):
|
| | | newCanGetRedID = nowActiveRedPacketIDList[i]
|
| | | newRedPacketObj = redPacketMgr.GetRedPacketObj(newCanGetRedID, False)
|
| | | if playerID in newRedPacketObj.grabDict:
|
| | | continue
|
| | | if newCanGetRedID not in canGetIDList:
|
| | | if redPacketMgr.AddPlayerCanGetRedPacketID(playerID, getWay, newCanGetRedID): # 添加目标玩家私有已开放红包队列
|
| | | return [redPacketID, newCanGetRedID]
|
| | | return [redPacketID]
|
| | |
|
| | | def DelRedPackByFamilyID(delfamilyID):
|
| | | ## 删除仙盟的时候才需要删除红包,所以这里不做通知,重新加入仙盟时会重新同步一次 isAll 的情况
|
| | |
| | | # packetCnt = max(packetCnt, commonCntLimit)
|
| | |
|
| | | if outputNum < packetCnt:
|
| | | GameWorld.DebugLog(" 生成新仙盟红包 红包额度不能低于红包个数!outputNum=%s,redCnt=%s" % (outputNum, packetCnt))
|
| | | GameWorld.DebugLog(" 生成新仙盟红包 红包额度不能低该红包个数!outputNum=%s,redCnt=%s" % (outputNum, packetCnt))
|
| | | return
|
| | | job = curPlayer.GetJob()
|
| | | jobRank = 0
|
| | |
| | | return redPacketObj
|
| | |
|
| | | def SendFamilyRedPacket(msgList):
|
| | | '''发系统赠送的红包,该红包已存在,只是状态未发放,由归属玩家自由选择发放时机'''
|
| | | '''开放红包可领取,该红包已存在,只是状态未发放,由归属玩家自由选择发放时机'''
|
| | | playerID, redPacketID, packetCnt, isAnonymous = msgList
|
| | | curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
|
| | | if not curPlayer:
|
| | |
| | | redPacketMgr = GetRedpacketMgr()
|
| | | redPacketObj = redPacketMgr.GetRedPacketObj(redPacketID, False)
|
| | | if not redPacketObj:
|
| | | PlayerControl.NotifyCode(curPlayer, "该红包不存在!")
|
| | | GameWorld.ErrLog("红包不存在!")
|
| | | return
|
| | |
|
| | | playerID = curPlayer.GetPlayerID()
|
| | |
| | | getMoney = eval(getNumformula) if remainPacketCnt > 1 else remainNum
|
| | | getMoney = min(getMoney, remainNum)
|
| | | remainNum -= getMoney
|
| | | GameWorld.DebugLog(" 该玩家抢到红包=%s!" % getMoney, playerID)
|
| | | GameWorld.DebugLog(" 该玩家抢到红包: redPacketID=%s,getWay=%s,getMoney=%s,remainNum=%s" |
| | | % (redPacketID, getWay, getMoney, remainNum), playerID)
|
| | |
|
| | | # 新增抢的记录
|
| | | grabObj = RedPacketGrab(redPacketID, playerID)
|
| | |
| | | OnChangeRedPacketState(curFamily, redPacketObj, beforeState)
|
| | | else:
|
| | | if getWay in IpyGameDataPY.GetFuncEvalCfg("RedPacketSys", 1):
|
| | | redPacketMgr.DelPlayerCanGetRedPacketID(playerID, getWay, redPacketID)
|
| | | NotifyRedPacketInfo(curPlayer, [redPacketID])
|
| | | #PrintRedPacketData("GrabBefore")
|
| | | notifyRedIDList = DoPlayerReductCanGetRedPacket(playerID, redPacketObj)
|
| | | if notifyRedIDList:
|
| | | NotifyRedPacketInfo(curPlayer, notifyRedIDList)
|
| | | #PrintRedPacketData("GrabAfter")
|
| | | else:
|
| | | NotifyRedPacketInfo(curPlayer, [redPacketID])
|
| | |
|
| | | __NotifyGrabRedPacketInfo(curPlayer, redPacketID, grabRecordDict)
|
| | |
|
| | |
| | | redPacketInfo = []
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | joinFamilyTime = PlayerFamily.GetPlayerJoinFamilyTime(curPlayer)
|
| | | GameWorld.DebugLog("通知红包信息: isLogin=%s,isAll=%s,syncRedPacketIDList=%s" % (isLogin, isAll, syncRedPacketIDList), playerID)
|
| | | #GameWorld.DebugLog("通知红包信息: isLogin=%s,isAll=%s,syncRedPacketIDList=%s" % (isLogin, isAll, syncRedPacketIDList), playerID)
|
| | |
|
| | | for redPacketID in syncRedPacketIDList:
|
| | | redPacketObj = redPacketMgr.GetRedPacketObj(redPacketID, False)
|
| | |
| | | #仙盟红包只通知玩家进入仙盟后生成的红包
|
| | | if redPacketObj.familyID:
|
| | | if joinFamilyTime and redPacketObj.calcTime < joinFamilyTime:
|
| | | GameWorld.DebugLog(" 加入仙盟之前的红包不发: redPacketID=%s,joinFamilyTime=%s > %s" % (redPacketID, joinFamilyTime, redPacketObj.calcTime))
|
| | | #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))
|
| | | #GameWorld.DebugLog(" 已抢或抢完的不发: redPacketID=%s,state=%s" % (redPacketID, state))
|
| | | continue
|
| | |
|
| | | packetInfo = ChPyNetSendPack.tagFRedPacketInfo()
|