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