From 1ea73e1885835466265ce788d93556b7030ee0e8 Mon Sep 17 00:00:00 2001 From: hxp <ale99527@vip.qq.com> Date: 星期日, 30 十二月 2018 18:42:00 +0800 Subject: [PATCH] 5424 【后端】【1.4】跨服竞技场开发(GM工具增加子服服务器维护,文字翻译版) --- ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFBHelpBattle.py | 551 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 files changed, 457 insertions(+), 94 deletions(-) diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFBHelpBattle.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFBHelpBattle.py index eb7a34a..1dd2cd0 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFBHelpBattle.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFBHelpBattle.py @@ -16,21 +16,23 @@ #------------------------------------------------------------------------------- import PlayerFriend -import PlayerViewCache import IpyGameDataPY +import PlayerViewCache +import IPY_GameServer +import PlayerControl +import ShareDefine import PyGameData import GameWorld +import ChConfig import random import time -import IPY_GameServer -import PlayerControl -import ChConfig -import ChPyNetSendPack -import NetPackCommon MaxRobotID = 100 # 最大机器人NPC定义ID - + +Def_RecType_CheckInPlayer = ShareDefine.Def_UniversalGameRecType_FBHelpBattleCheckInPlayer +Def_RecType_HelpRecord = ShareDefine.Def_UniversalGameRecType_FBHelpBattleRecord + ## 助战玩家简要信息 class HelpBattlePlayer(): @@ -43,7 +45,7 @@ self.fightPower = 0 self.familyID = 0 self.vipLV = 0 - self.checkInCount = 0 + self.checkInCount = 0 # 累计登记次数 self.checkInTime = 0 self.todayHelpCountDict = {} # 今天已助战次数 {(mapID, lineID):count, ...}, 通用次数时lineID默认为0 self.todayXianyuanCoin = 0 # 今日已获得仙缘币 @@ -62,7 +64,181 @@ self.vipLV = 0 # 当时的VIP等级 self.recordTime = 0 # 记录的时间 return + +def OnServerStart(): + GameWorld.Log("开服加载助战相关信息...") + universalRecMgr = GameWorld.GetUniversalRecMgr() + checkInPlayerRecList = universalRecMgr.GetTypeList(Def_RecType_CheckInPlayer) + for index in xrange(checkInPlayerRecList.Count()): + recData = checkInPlayerRecList.At(index) + playerID = recData.GetValue1() + helpBattlePlayer = HelpBattlePlayer(playerID) + helpBattlePlayer.checkInTime = recData.GetTime() + helpBattlePlayer.fightPower = recData.GetValue2() + helpBattlePlayer.familyID = recData.GetValue3() + helpBattlePlayer.checkInCount = recData.GetValue4() + value5 = recData.GetValue5() + helpBattlePlayer.playerLV = value5 / 100000 + helpBattlePlayer.vipLV = int(str(value5)[-5:-3]) + helpBattlePlayer.realmLV = int(str(value5)[-3:-1]) + helpBattlePlayer.job = value5 % 10 + helpBattlePlayer.playerName = recData.GetStrValue1() + helpBattlePlayer.todayXianyuanCoin = int(recData.GetStrValue2()) + helpCountDictStr = recData.GetStrValue3() + if helpCountDictStr.startswith("{") and helpCountDictStr.endswith("}"): + helpBattlePlayer.todayHelpCountDict = eval(helpCountDictStr) + else: + GameWorld.ErrLog("LoadCheckInPlayerError: helpCountDictStr=%s" % helpCountDictStr, playerID) + PyGameData.g_fbHelpBattleCheckInPlayerDict[playerID] = helpBattlePlayer + GameWorld.Log("加载助战登记玩家记录: %s" % len(PyGameData.g_fbHelpBattleCheckInPlayerDict)) + helpRecordRecList = universalRecMgr.GetTypeList(Def_RecType_HelpRecord) + for index in xrange(helpRecordRecList.Count()): + recData = helpRecordRecList.At(index) + playerID = recData.GetValue1() + + helpRecord = FBHelpBattleRecord() + helpRecord.callPlayerID = int(recData.GetStrValue2()) + helpRecord.callPlayerName = recData.GetStrValue1() + helpRecord.mapID = recData.GetValue2() + helpRecord.funcLineID = recData.GetValue3() + helpRecord.xianyuanCoinAdd = recData.GetValue4() + helpRecord.relation = recData.GetValue5() % 10 + helpRecord.vipLV = recData.GetValue5() / 10 + helpRecord.recordTime = recData.GetTime() + + unNotifyRecordList = PyGameData.g_fbHelpBattleRecord.get(playerID, []) + unNotifyRecordList.append(helpRecord) + PyGameData.g_fbHelpBattleRecord[playerID] = unNotifyRecordList + + GameWorld.Log("加载玩家未同步助战: %s" % len(PyGameData.g_fbHelpBattleRecord)) + for playerID, helpList in PyGameData.g_fbHelpBattleRecord.items(): + GameWorld.Log("加载玩家未同步助战记录: %s" % (len(helpList)), playerID) + return + +def OnServerClose(): + GameWorld.Log("关服保存助战相关信息...") + universalRecMgr = GameWorld.GetUniversalRecMgr() + universalRecMgr.Delete(Def_RecType_CheckInPlayer) + universalRecMgr.Delete(Def_RecType_HelpRecord) + + GameWorld.Log("保存助战登记玩家记录: %s" % len(PyGameData.g_fbHelpBattleCheckInPlayerDict)) + checkInPlayerRecList = universalRecMgr.GetTypeList(Def_RecType_CheckInPlayer) + for playerID, checkInPlayer in PyGameData.g_fbHelpBattleCheckInPlayerDict.items(): + recData = checkInPlayerRecList.AddRec() + recData.SetTime(checkInPlayer.checkInTime) + recData.SetValue1(playerID) + recData.SetValue2(checkInPlayer.fightPower) + recData.SetValue3(checkInPlayer.familyID) + recData.SetValue4(checkInPlayer.checkInCount) + recData.SetValue5(int("%d%02d%02d%d" % (checkInPlayer.playerLV, checkInPlayer.vipLV, checkInPlayer.realmLV, checkInPlayer.job))) + recData.SetStrValue1(checkInPlayer.playerName) + recData.SetStrValue2(str(checkInPlayer.todayXianyuanCoin)) + recData.SetStrValue3(str(checkInPlayer.todayHelpCountDict).replace(" ", "")) + + GameWorld.Log("保存助战未同步记录: %s" % len(PyGameData.g_fbHelpBattleRecord)) + helpRecordRecList = universalRecMgr.GetTypeList(Def_RecType_HelpRecord) + for playerID, helpList in PyGameData.g_fbHelpBattleRecord.items(): + GameWorld.Log("玩家未同步助战记录: %s" % (len(helpList)), playerID) + for helpRecord in helpList: + recData = helpRecordRecList.AddRec() + recData.SetTime(helpRecord.recordTime) + recData.SetValue1(playerID) + recData.SetValue2(helpRecord.mapID) + recData.SetValue3(helpRecord.funcLineID) + recData.SetValue4(helpRecord.xianyuanCoinAdd) + recData.SetValue5(helpRecord.vipLV*10+helpRecord.relation) + recData.SetStrValue1(helpRecord.callPlayerName) + recData.SetStrValue2(str(helpRecord.callPlayerID)) + return + +def HelpBattleOnDay(): + curTime = int(time.time()) + checkInValidHours = IpyGameDataPY.GetFuncCfg("HelpBattleCheckIn", 1) # 登记有效时长,小时 + # 这里延长30分钟清除,防止已经被召唤还没结算的导致找不到登记信息 + checkInValidSeconds = checkInValidHours * 3600 + 30 * 60 + + # 清超时登记,重置信息 + for playerID, checkInPlayer in PyGameData.g_fbHelpBattleCheckInPlayerDict.items(): + checkInTime = checkInPlayer.checkInTime + if curTime - checkInTime > checkInValidSeconds: + PyGameData.g_fbHelpBattleCheckInPlayerDict.pop(playerID) + GameWorld.Log("清除超时助战登记玩家: curTime=%s,checkInTime=%s" % (curTime, checkInTime), playerID) + continue + checkInPlayer.todayHelpCountDict = {} + checkInPlayer.todayXianyuanCoin = 0 + return + +def OnHelpPlayerLogin(curPlayer): + playerID = curPlayer.GetPlayerID() + if playerID not in PyGameData.g_fbHelpBattleRecord: + return + unNotifyRecordList = PyGameData.g_fbHelpBattleRecord.pop(playerID) + SendMapServer_FBHelpBattleRecord(curPlayer, unNotifyRecordList, True) + return + +def OnMinuteProcess(): + ''' 每分钟处理 + 前X次登记后,分别在登记后的第X分钟赠送玩家宗门试炼一层的助战仙缘币,并伪造一份助战记录。 + 助战记录随机从助战登记库里随机挑选1名除自己外的玩家,如果没有玩家,该特殊逻辑不生效 + ''' + + if not PyGameData.g_fbHelpBattleCheckInPlayerDict: + return + helpPlayerIDList = PyGameData.g_fbHelpBattleCheckInPlayerDict.keys() + + curTime = int(time.time()) + + playerManager = GameWorld.GetPlayerManager() + newbieCheckInCount = IpyGameDataPY.GetFuncCfg("HelpBattleCheckIn", 2) # 新手前X次登记特殊逻辑 + sysAutoCallHelpDict = IpyGameDataPY.GetFuncEvalCfg("HelpBattleCheckIn", 3) # 系统自动召唤助战,默认功能线路0, {登记多少分钟后:[随机地图ID, ...], ...} + for playerID, checkInPlayer in PyGameData.g_fbHelpBattleCheckInPlayerDict.items(): + + curPlayer = playerManager.FindPlayerByID(playerID) + + if not curPlayer or PlayerControl.GetIsTJG(curPlayer): + #GameWorld.DebugLog(" 离线或脱机不处理, playerID=%s" % playerID) + continue + + checkInCount = checkInPlayer.checkInCount + if checkInCount > newbieCheckInCount: + #GameWorld.DebugLog(" 超过规定的登记次数,不处理, playerID=%s,checkInCount=%s > newbieCheckInCount=%s" + # % (playerID, checkInCount, newbieCheckInCount)) + continue + + checkInTime = checkInPlayer.checkInTime + checkInMinutes = (curTime - checkInTime) / 60 + if checkInMinutes not in sysAutoCallHelpDict: + #GameWorld.DebugLog(" 签到时间不满足,不处理, playerID=%s,checkInMinutes=%s not in %s" + # % (playerID, checkInMinutes, sysAutoCallHelpDict)) + continue + + randHelpMapList = sysAutoCallHelpDict[checkInMinutes] + # 随机一个不是自己的登记玩家 + for _ in xrange(20): + randPlayerID = random.choice(helpPlayerIDList) + if randPlayerID != playerID: + break + + # 只有自己不处理 + if randPlayerID == playerID: + #GameWorld.DebugLog(" 登记玩家只有自己,不处理, playerID=%s" % (playerID)) + continue + + randHelpMapID = random.choice(randHelpMapList) + lineID = 0 # 默认0 + + helpBattlePlayer = PyGameData.g_fbHelpBattleCheckInPlayerDict[randPlayerID] + relation = __GetHelpBattleRelation(curPlayer, helpBattlePlayer) + calledPlayerID = playerID # 因为这里是系统模拟玩家被召唤助战,所以被召唤玩家就是当前被处理的玩家ID + GameWorld.DebugLog(" 系统模拟召唤新手登记玩家: checkInMinutes=%s,playerID=%s,callPlayerID=%s" % (checkInMinutes, playerID, randPlayerID)) + + calledPlayerDict = {calledPlayerID:relation} + msgList = ["Call", randHelpMapID, lineID, calledPlayerDict] + __DoFBHelpBattleCall(randPlayerID, helpBattlePlayer.playerName, msgList) + + return + ## 是否在助战登记列表里 def IsInHelpBattleCheckInList(playerID): return playerID in PyGameData.g_fbHelpBattleCheckInPlayerDict @@ -85,8 +261,12 @@ # 召唤 elif cmd == "Call": - result = __DoFBHelpBattleCall(curPlayer, msgList) + result = __DoFBHelpBattleCall(curPlayer.GetPlayerID(), curPlayer.GetName(), msgList) + # 扫荡召唤 + elif cmd == "SweepCall": + result = __DoFBHelpBattleSweepCall(curPlayer, msgList) + if result == None: return @@ -121,13 +301,14 @@ % (curPlayer.GetLV(), fightPower, curPlayer.GetFamilyID(), curPlayer.GetVIPLv(), todayXianyuanCoin, checkInCount + 1, haveViewCache), playerID) return [isOK, haveViewCache] -def UpdateCheckInPlayerInfo(playerID, fightPower, familyID): +def UpdateCheckInPlayerInfo(playerID, fightPower, familyID, playerName): ## 更新登记的助战玩家等级战力 if playerID not in PyGameData.g_fbHelpBattleCheckInPlayerDict: return helpBattlePlayer = PyGameData.g_fbHelpBattleCheckInPlayerDict[playerID] helpBattlePlayer.fightPower = fightPower helpBattlePlayer.familyID = familyID + helpBattlePlayer.playerName = playerName GameWorld.DebugLog("更新助战玩家等级战力: fightPower=%s,familyID=%s" % (fightPower, familyID), playerID) return @@ -174,7 +355,12 @@ GameWorld.Log("刷新助战列表: mapID=%s,funcLineID=%s,helpCountLineID=%s,isClientRefresh=%s,costMoneyList=%s,calledPlayerIDDict=%s" % (mapID, funcLineID, helpCountLineID, isClientRefresh, costMoneyList, calledPlayerIDDict), playerID) + onlyFree = False goldCallCount = 0 + nowFreeRelationCount, nowRelationCount = 0, 0 + atleastFreeRelationCount = IpyGameDataPY.GetFuncCfg("HelpBattleCall2", 1) # 至少免费社交人数,无社交则忽略 + atleastRelationCount = IpyGameDataPY.GetFuncCfg("HelpBattleCall2", 2) # 至少社交人数,无社交则忽略(人数包含免费社交人数) + GameWorld.DebugLog(" atleastFreeRelationCount=%s,atleastRelationCount=%s" % (atleastFreeRelationCount, atleastRelationCount)) #已经召唤的保留 for calledPlayerID, callInfo in calledPlayerIDDict.items(): @@ -185,6 +371,10 @@ helpBattlePlayerDict[calledPlayerID] = __GetNotifyMapServerHelpPlayerInfoDict(helpBattlePlayer, needGoldCall, job, relation) if needGoldCall: goldCallCount += 1 + if relation: + nowRelationCount += 1 + if not needGoldCall: + nowFreeRelationCount += 1 # 机器人NPC elif 1 <= calledPlayerID <= MaxRobotID: helpBattlePlayerDict[calledPlayerID] = __GetNotifyMapServerHelpPlayerInfoDict(None, False, job) @@ -202,47 +392,71 @@ checkInValidSeconds = checkInValidHours * 3600 checkInPlayerIDList = PyGameData.g_fbHelpBattleCheckInPlayerDict.keys() - random.shuffle(checkInPlayerIDList) # 刷新纯随机 + random.shuffle(checkInPlayerIDList) GameWorld.Log(" 登记助战人数=%s" % (len(checkInPlayerIDList)), playerID) + + # 1. 至少社交关系人数还不足的,先处理至少社交关系人数 + if nowRelationCount < atleastRelationCount: + relationIDList = [] + friendIDList = PlayerFriend.GetFriendStruct(playerID).GetSocialIDList() + relationIDList += friendIDList + #GameWorld.DebugLog(" 好友ID列表, friendIDList=%s" % friendIDList, playerID) + curFamily = curPlayer.GetFamily() + familyMemList = [] + if curFamily: + for index in xrange(curFamily.GetCount()): + member = curFamily.GetAt(index) + memberID = member.GetPlayerID() + familyMemList.append(memberID) + if memberID != playerID and memberID not in relationIDList: + relationIDList.append(memberID) + #GameWorld.DebugLog(" 盟友ID列表, familyMemList=%s" % familyMemList, playerID) + + random.shuffle(relationIDList) + #GameWorld.DebugLog(" 有社交的ID列表, relationIDList=%s" % relationIDList, playerID) + tempRelationHelpPlayerList = [] + for relationID in relationIDList: + if nowRelationCount >= atleastRelationCount: + break + if relationID not in checkInPlayerIDList: + continue + helpBattlePlayer = PyGameData.g_fbHelpBattleCheckInPlayerDict[relationID] + canHelp, needGoldCall = __CheckCanHelpComm(playerID, helpBattlePlayerDict, relationID, helpBattlePlayer, limitLV, fightPowerMin, fightPowerMax, + checkInValidSeconds, curTime, helpCountKey, dayFreeHelpCount, onlyFree, goldCallCount, maxGoldHelpPlayerCount) + if not canHelp: + continue + + # 免费社交人数不足且免费 or 免费社交人数够了且总社交人数还不够 ; 都直接加入助战列表 + if (nowFreeRelationCount < atleastFreeRelationCount and not needGoldCall) \ + or (nowFreeRelationCount >= atleastFreeRelationCount and nowRelationCount < atleastRelationCount): + goldCallCount, nowRelationCount, nowFreeRelationCount = \ + __AddHelpPlayer(curPlayer, helpBattlePlayer, helpBattlePlayerDict, needGoldCall, goldCallCount, nowRelationCount, nowFreeRelationCount) + else: + lackRelationCount = atleastRelationCount - nowRelationCount + if len(tempRelationHelpPlayerList) < lackRelationCount: + tempRelationHelpPlayerList.append([helpBattlePlayer, needGoldCall]) + + lackRelationCount = atleastRelationCount - nowRelationCount + if lackRelationCount > 0: + for helpBattlePlayer, needGoldCall in tempRelationHelpPlayerList[:lackRelationCount]: + goldCallCount, nowRelationCount, nowFreeRelationCount = \ + __AddHelpPlayer(curPlayer, helpBattlePlayer, helpBattlePlayerDict, needGoldCall, goldCallCount, nowRelationCount, nowFreeRelationCount) + + # 2. 常规添加助战人数 for checkInPlayerID in checkInPlayerIDList: - if checkInPlayerID == playerID: - GameWorld.DebugLog(" 自己不处理, checkInPlayerID=%s" % checkInPlayerID) - continue - if checkInPlayerID in helpBattlePlayerDict: - GameWorld.DebugLog(" 已经在助战里的不处理, checkInPlayerID=%s" % checkInPlayerID) - continue if len(helpBattlePlayerDict) >= maxHelpPlayerSelectCount: GameWorld.DebugLog(" 超过最大个数了不处理, checkInPlayerID=%s" % checkInPlayerID) break helpBattlePlayer = PyGameData.g_fbHelpBattleCheckInPlayerDict[checkInPlayerID] - checkInPlayerLV = helpBattlePlayer.playerLV - checkInPlayerFightPower = helpBattlePlayer.fightPower - checkInTime = helpBattlePlayer.checkInTime - if checkInPlayerLV < limitLV: - GameWorld.DebugLog(" 等级不足, checkInPlayerID=%s,checkInPlayerLV=%s < limitLV=%s" % (checkInPlayerID, checkInPlayerLV, limitLV)) + canHelp, needGoldCall = __CheckCanHelpComm(playerID, helpBattlePlayerDict, checkInPlayerID, helpBattlePlayer, limitLV, fightPowerMin, fightPowerMax, + checkInValidSeconds, curTime, helpCountKey, dayFreeHelpCount, onlyFree, goldCallCount, maxGoldHelpPlayerCount) + if not canHelp: continue - if fightPowerMin and checkInPlayerFightPower < fightPowerMin: - GameWorld.DebugLog(" 战力不足, checkInPlayerID=%s,checkInPlayerFightPower=%s < fightPowerMin=%s" % (checkInPlayerID, checkInPlayerFightPower, fightPowerMin)) - continue - if fightPowerMax and checkInPlayerFightPower > fightPowerMax: - GameWorld.DebugLog(" 战力超出, checkInPlayerID=%s,checkInPlayerFightPower=%s > fightPowerMax=%s" % (checkInPlayerID, checkInPlayerFightPower, fightPowerMax)) - continue - passTime = curTime - checkInTime - if passTime > checkInValidSeconds: - GameWorld.DebugLog(" 登记超时, checkInPlayerID=%s,checkInTime=%s,passTime=%s > checkInValidSeconds=%s" % (checkInPlayerID, checkInTime, passTime, checkInValidSeconds)) - continue - needGoldCall = False - if dayFreeHelpCount: - todayHelpCount = helpBattlePlayer.todayHelpCountDict.get(helpCountKey, 0) - needGoldCall = todayHelpCount >= dayFreeHelpCount - if needGoldCall and goldCallCount >= maxGoldHelpPlayerCount: - GameWorld.DebugLog(" 超过最大付费召唤人数, checkInPlayerID=%s,goldCallCount=%s > maxGoldHelpPlayerCount=%s" % (checkInPlayerID, goldCallCount, maxGoldHelpPlayerCount)) - continue - goldCallCount += 1 - relation = __GetHelpBattleRelation(curPlayer, helpBattlePlayer) - helpBattlePlayerDict[checkInPlayerID] = __GetNotifyMapServerHelpPlayerInfoDict(helpBattlePlayer, needGoldCall, helpBattlePlayer.job, relation) - # 不足的机器人NPC补足 + goldCallCount, nowRelationCount, nowFreeRelationCount = \ + __AddHelpPlayer(curPlayer, helpBattlePlayer, helpBattlePlayerDict, needGoldCall, goldCallCount, nowRelationCount, nowFreeRelationCount) + + # 3. 不足的机器人NPC补足 openJobList = IpyGameDataPY.GetFuncEvalCfg("OpenJob", 1) # 开放的职业 lackCount = maxHelpPlayerSelectCount - len(helpBattlePlayerDict) robotID = 0 # 机器人NPC定义ID从1开始 @@ -257,6 +471,57 @@ GameWorld.Log(" helpBattlePlayerDict=%s" % (helpBattlePlayerDict), playerID) return [helpBattlePlayerDict] +def __CheckCanHelpComm(playerID, helpBattlePlayerDict, checkInPlayerID, helpBattlePlayer, limitLV, fightPowerMin, fightPowerMax, + checkInValidSeconds, curTime, helpCountKey, dayFreeHelpCount, onlyFree=False, goldCallCount=0, maxGoldHelpPlayerCount=0): + ## 常规检查是否满足助战条件 + if checkInPlayerID == playerID: + GameWorld.DebugLog(" 自己不处理, checkInPlayerID=%s" % checkInPlayerID) + return False, False + if checkInPlayerID in helpBattlePlayerDict: + GameWorld.DebugLog(" 已经在助战里的不处理, checkInPlayerID=%s" % checkInPlayerID) + return False, False + checkInPlayerLV = helpBattlePlayer.playerLV + checkInPlayerFightPower = helpBattlePlayer.fightPower + checkInTime = helpBattlePlayer.checkInTime + if checkInPlayerLV < limitLV: + GameWorld.DebugLog(" 等级不足, checkInPlayerID=%s,checkInPlayerLV=%s < limitLV=%s" % (checkInPlayerID, checkInPlayerLV, limitLV)) + return False, False + if fightPowerMin and checkInPlayerFightPower < fightPowerMin: + GameWorld.DebugLog(" 战力不足, checkInPlayerID=%s,checkInPlayerFightPower=%s < fightPowerMin=%s" % (checkInPlayerID, checkInPlayerFightPower, fightPowerMin)) + return False, False + if fightPowerMax and checkInPlayerFightPower > fightPowerMax: + GameWorld.DebugLog(" 战力超出, checkInPlayerID=%s,checkInPlayerFightPower=%s > fightPowerMax=%s" % (checkInPlayerID, checkInPlayerFightPower, fightPowerMax)) + return False, False + passTime = curTime - checkInTime + if passTime > checkInValidSeconds: + GameWorld.DebugLog(" 登记超时, checkInPlayerID=%s,checkInTime=%s,passTime=%s > checkInValidSeconds=%s" % (checkInPlayerID, checkInTime, passTime, checkInValidSeconds)) + return False, False + todayHelpCount = helpBattlePlayer.todayHelpCountDict.get(helpCountKey, 0) + needGoldCall = dayFreeHelpCount and todayHelpCount >= dayFreeHelpCount + if needGoldCall: + if onlyFree: + GameWorld.DebugLog(" 不是免费, checkInPlayerID=%s,todayHelpCount=%s > dayFreeHelpCount=%s" % (checkInPlayerID, todayHelpCount, dayFreeHelpCount)) + return False, needGoldCall + if goldCallCount >= maxGoldHelpPlayerCount: + GameWorld.DebugLog(" 超过最大付费召唤人数, checkInPlayerID=%s,goldCallCount=%s > maxGoldHelpPlayerCount=%s" % (checkInPlayerID, goldCallCount, maxGoldHelpPlayerCount)) + return False, needGoldCall + return True, needGoldCall + +def __AddHelpPlayer(curPlayer, helpBattlePlayer, helpBattlePlayerDict, needGoldCall, goldCallCount, nowRelationCount, nowFreeRelationCount): + ## 添加助战玩家到助战列表 + if needGoldCall: + goldCallCount += 1 + relation = __GetHelpBattleRelation(curPlayer, helpBattlePlayer) + if relation: + nowRelationCount += 1 + if not needGoldCall: + nowFreeRelationCount += 1 + helpPlayerID = helpBattlePlayer.playerID + helpBattlePlayerDict[helpPlayerID] = __GetNotifyMapServerHelpPlayerInfoDict(helpBattlePlayer, needGoldCall, helpBattlePlayer.job, relation) + GameWorld.DebugLog(" 助战列表添加玩家: helpPlayerID=%s,needGoldCall=%s,relation=%s,goldCallCount=%s,nowRelationCount=%s,nowFreeRelationCount=%s" + % (helpPlayerID, needGoldCall, relation, goldCallCount, nowRelationCount, nowFreeRelationCount)) + return goldCallCount, nowRelationCount, nowFreeRelationCount + def __GetHelpBattleRelation(curPlayer, helpBattlePlayer): ## 获取助战社交关系 0-无,1-好友,2-盟友 if not helpBattlePlayer: @@ -270,7 +535,7 @@ if PlayerFriend.IsFriend(playerID, tagPlayerID): return checkRelation if checkRelation == 2: - if curPlayer.GetFamilyID() == tagFamilyID: + if tagFamilyID and curPlayer.GetFamilyID() == tagFamilyID: return checkRelation return 0 @@ -289,73 +554,171 @@ helpPlayerDict["Relation"] = relation return helpPlayerDict -def __DoFBHelpBattleCall(curPlayer, msgList): +def __DoFBHelpBattleSweepCall(curPlayer, msgList): + ''' 扫荡助战列表刷新且直接召唤 + 随机选择免费的玩家、过滤仙缘币已达上限或溢出的玩家 + ''' + mapID, funcLineID = msgList[1:] + + helpBattlePlayerDict = {} # 同步给地图服务器的待选助战玩家列表信息 + + fbFuncIpyData = IpyGameDataPY.GetIpyGameData("FBFunc", mapID) + fbHelpIpyData = IpyGameDataPY.GetIpyGameData("FBHelpBattle", mapID, funcLineID) + if not fbFuncIpyData or not fbHelpIpyData: + return [helpBattlePlayerDict] + + fightPowerMin = fbHelpIpyData.GetFightPowerMin() + fightPowerMax = fbHelpIpyData.GetFightPowerMax() + limitLV = fbHelpIpyData.GetLVLimit() + dayFreeHelpCountInfo = fbHelpIpyData.GetDayFreeHelpCount() # 每日免费助战次数,[每日免费助战次数, 是否所有层通用] + dayFreeHelpCount = 0 # 0为无限制次数 + helpCountLineID = funcLineID # 助战次数所属lineID,当所有层通用时,默认为0 + if dayFreeHelpCountInfo and len(dayFreeHelpCountInfo) == 2: + dayFreeHelpCount, isAllLineCount = dayFreeHelpCountInfo + if isAllLineCount: + helpCountLineID = 0 + helpCountKey = (mapID, helpCountLineID) + + playerID = curPlayer.GetPlayerID() + tagPlayerID = playerID + tagPlayerName = curPlayer.GetName() + GameWorld.Log("扫荡刷新助战列表: mapID=%s,funcLineID=%s,helpCountLineID=%s" % (mapID, funcLineID, helpCountLineID), playerID) + + curTime = int(time.time()) + maxHelpPlayerCount = IpyGameDataPY.GetFuncCfg("HelpBattleCall", 2) # 最大助战人数 + checkInValidHours = IpyGameDataPY.GetFuncCfg("HelpBattleCheckIn", 1) # 登记有效时长,小时 + checkInValidSeconds = checkInValidHours * 3600 + + xianyuanCoinUpper = IpyGameDataPY.GetFuncCfg("HelpBattlePoint", 1) # 每日仙缘币上限 + baseHelpPoint = fbFuncIpyData.GetHelpPoint() # 助战 - 基础仙缘币 + relationCoinAddDict = IpyGameDataPY.GetFuncEvalCfg("HelpBattlePoint", 2, {}) # 社交关系加成 {"社交关系":[过关加成, 助战加成], ...} + + isSweep = True + onlyFree = True + checkInPlayerIDList = PyGameData.g_fbHelpBattleCheckInPlayerDict.keys() + random.shuffle(checkInPlayerIDList) # 刷新纯随机 + GameWorld.Log(" 登记助战人数=%s" % (len(checkInPlayerIDList)), playerID) + for checkInPlayerID in checkInPlayerIDList: + if len(helpBattlePlayerDict) >= maxHelpPlayerCount: + GameWorld.DebugLog(" 超过最大个数了不处理, checkInPlayerID=%s" % checkInPlayerID) + break + helpBattlePlayer = PyGameData.g_fbHelpBattleCheckInPlayerDict[checkInPlayerID] + canHelp, needGoldCall = __CheckCanHelpComm(playerID, helpBattlePlayerDict, checkInPlayerID, helpBattlePlayer, limitLV, fightPowerMin, fightPowerMax, + checkInValidSeconds, curTime, helpCountKey, dayFreeHelpCount, onlyFree) + if not canHelp: + continue + + relation = __GetHelpBattleRelation(curPlayer, helpBattlePlayer) + if not __DoCallHelpPlayer(tagPlayerID, tagPlayerName, helpBattlePlayer, relation, mapID, funcLineID, helpCountKey, isSweep, + curTime, xianyuanCoinUpper, relationCoinAddDict, baseHelpPoint): + continue + + helpBattlePlayerDict[checkInPlayerID] = __GetNotifyMapServerHelpPlayerInfoDict(helpBattlePlayer, needGoldCall, helpBattlePlayer.job, relation) + + # 不足的机器人NPC补足 + openJobList = IpyGameDataPY.GetFuncEvalCfg("OpenJob", 1) # 开放的职业 + lackCount = maxHelpPlayerCount - len(helpBattlePlayerDict) + robotID = 0 # 机器人NPC定义ID从1开始 + while lackCount > 0 and robotID < MaxRobotID: + robotID += 1 + if robotID in helpBattlePlayerDict: + continue + lackCount -= 1 + randJob = random.choice(openJobList) + helpBattlePlayerDict[robotID] = __GetNotifyMapServerHelpPlayerInfoDict(None, False, randJob) + + GameWorld.Log(" helpBattlePlayerDict=%s" % (helpBattlePlayerDict), playerID) + return [helpBattlePlayerDict] + +def __DoCallHelpPlayer(callPlayerID, callPlayerName, helpBattlePlayer, relation, mapID, funcLineID, helpCountKey, isSweep, curTime, + xianyuanCoinUpper, relationCoinAddDict, baseHelpPoint): + + calledPlayerID = helpBattlePlayer.playerID + addCoinRate = 10000 # 基础倍率 + playerXianyuanCoinUpper = xianyuanCoinUpper + relationAddList = relationCoinAddDict.get(str(relation), []) + relationAdd = relationAddList[1] if len(relationAddList) == 2 else 0 + + todayXianyuanCoin = helpBattlePlayer.todayXianyuanCoin # 今日已获得仙缘币 + vipLV = helpBattlePlayer.vipLV + if vipLV: + xianyuanCoinUpperAdd = PlayerControl.GetPrivilegeValue(vipLV, ChConfig.VIPPrivilege_XianyuanCoinUpperAdd) + xianyuanCoinAddPer = PlayerControl.GetPrivilegeValue(vipLV, ChConfig.VIPPrivilege_XianyuanCoinAddPer) + + playerXianyuanCoinUpper += xianyuanCoinUpperAdd + addCoinRate += xianyuanCoinAddPer + + # 仙缘币公式=(通关仙缘币或助战仙缘币+社交关系加成)*VIP倍数 + coinAdd = int((baseHelpPoint + relationAdd) * addCoinRate / 10000.0) + canAddMax = max(playerXianyuanCoinUpper - todayXianyuanCoin, 0) + + # 扫荡不可溢出 + if isSweep and coinAdd > canAddMax: + GameWorld.DebugLog(" 今日仙缘币已达上限, calledPlayerID=%s,coinAdd=%s > canAddMax=%s" % (calledPlayerID, coinAdd, canAddMax)) + return + coinAddReal = min(coinAdd, canAddMax) # 实际加仙缘币 + + todayMapHelpCount = helpBattlePlayer.todayHelpCountDict.get(helpCountKey, 0) + 1 + helpBattlePlayer.todayHelpCountDict[helpCountKey] = todayMapHelpCount + GameWorld.DebugLog(" 助战增加仙缘币: todayXianyuanCoin=%s,coinUpper=%s,canAddMax=%s,coinAdd=%s,coinAddReal=%s,todayMapHelpCount=%s" + % (todayXianyuanCoin, playerXianyuanCoinUpper, canAddMax, coinAdd, coinAddReal, todayMapHelpCount), calledPlayerID) + + # GameServer 直接先加 + helpBattlePlayer.todayXianyuanCoin += coinAddReal + + helpRecord = FBHelpBattleRecord() + helpRecord.callPlayerID = callPlayerID # 召唤他的玩家ID + helpRecord.callPlayerName = callPlayerName + helpRecord.mapID = mapID + helpRecord.funcLineID = funcLineID + helpRecord.xianyuanCoinAdd = coinAddReal + helpRecord.relation = relation + helpRecord.vipLV = vipLV + helpRecord.recordTime = curTime + + calledPlayer = GameWorld.GetPlayerManager().FindPlayerByID(calledPlayerID) + # 非脱机在线直接通知地图 + if calledPlayer and not PlayerControl.GetIsTJG(calledPlayer): + SendMapServer_FBHelpBattleRecord(calledPlayer, [helpRecord]) + else: + unNotifyRecordList = PyGameData.g_fbHelpBattleRecord.get(calledPlayerID, []) + unNotifyRecordList.append(helpRecord) + PyGameData.g_fbHelpBattleRecord[calledPlayerID] = unNotifyRecordList + return True + +def __DoFBHelpBattleCall(callPlayerID, callPlayerName, msgList): ''' 助战召唤,不管最终过关与否,被召唤方都直接算助战成功,这里处理被召唤的,主动方在地图直接处理 ''' + # calledPlayerDict = {} # {被召唤的玩家ID:关系, ...} mapID, funcLineID, calledPlayerDict = msgList[1:] fbFuncIpyData = IpyGameDataPY.GetIpyGameData("FBFunc", mapID) fbHelpIpyData = IpyGameDataPY.GetIpyGameData("FBHelpBattle", mapID, funcLineID) if not fbFuncIpyData or not fbHelpIpyData or not calledPlayerDict: return + helpCountLineID = funcLineID # 助战次数所属lineID,当所有层通用时,默认为0 + dayFreeHelpCountInfo = fbHelpIpyData.GetDayFreeHelpCount() + if dayFreeHelpCountInfo and len(dayFreeHelpCountInfo) == 2: + isAllLineCount = dayFreeHelpCountInfo[1] + if isAllLineCount: + helpCountLineID = 0 + helpCountKey = (mapID, helpCountLineID) + curTime = int(time.time()) - tagPlayerID = curPlayer.GetPlayerID() - tagPlayerName = curPlayer.GetName() - playerMgr = GameWorld.GetPlayerManager() xianyuanCoinUpper = IpyGameDataPY.GetFuncCfg("HelpBattlePoint", 1) # 每日仙缘币上限 baseHelpPoint = fbFuncIpyData.GetHelpPoint() # 助战 - 基础仙缘币 relationCoinAddDict = IpyGameDataPY.GetFuncEvalCfg("HelpBattlePoint", 2, {}) # 社交关系加成 {"社交关系":[过关加成, 助战加成], ...} - GameWorld.DebugLog("召唤助战: mapID=%s, funcLineID=%s, calledPlayerDict=%s" % (mapID, funcLineID, calledPlayerDict), tagPlayerID) - + GameWorld.DebugLog("召唤助战: mapID=%s, funcLineID=%s, helpCountKey=%s, calledPlayerDict=%s" % (mapID, funcLineID, helpCountKey, calledPlayerDict), callPlayerID) + isSweep = False for calledPlayerID, relation in calledPlayerDict.items(): if calledPlayerID not in PyGameData.g_fbHelpBattleCheckInPlayerDict: continue - addCoinRate = 10000 # 基础倍率 - playerXianyuanCoinUpper = xianyuanCoinUpper - relationAddList = relationCoinAddDict.get(str(relation), []) - relationAdd = relationAddList[1] if len(relationAddList) == 2 else 0 - helpBattlePlayer = PyGameData.g_fbHelpBattleCheckInPlayerDict[calledPlayerID] - todayXianyuanCoin = helpBattlePlayer.todayXianyuanCoin # 今日已获得仙缘币 - vipLV = helpBattlePlayer.vipLV - if vipLV: - xianyuanCoinUpperAdd = PlayerControl.GetPrivilegeValue(vipLV, ChConfig.VIPPrivilege_XianyuanCoinUpperAdd) - xianyuanCoinAddPer = PlayerControl.GetPrivilegeValue(vipLV, ChConfig.VIPPrivilege_XianyuanCoinAddPer) - - playerXianyuanCoinUpper += xianyuanCoinUpperAdd - addCoinRate += xianyuanCoinAddPer - - # 仙缘币公式=(通关仙缘币或助战仙缘币+社交关系加成)*VIP倍数 - coinAdd = int((baseHelpPoint + relationAdd) * addCoinRate / 10000.0) - canAddMax = max(playerXianyuanCoinUpper - todayXianyuanCoin, 0) - coinAddReal = min(coinAdd, canAddMax) # 实际加仙缘币 - GameWorld.DebugLog(" 助战增加仙缘币: coinAddReal=%s" % (coinAddReal), calledPlayerID) - - # GameServer 直接先加 - helpBattlePlayer.todayXianyuanCoin += coinAddReal - - helpRecord = FBHelpBattleRecord() - helpRecord.callPlayerID = tagPlayerID # 召唤他的玩家ID - helpRecord.callPlayerName = tagPlayerName - helpRecord.mapID = mapID - helpRecord.funcLineID = funcLineID - helpRecord.xianyuanCoinAdd = coinAddReal - helpRecord.relation = relation - helpRecord.vipLV = vipLV - helpRecord.recordTime = curTime - - calledPlayer = playerMgr.FindPlayerByID(calledPlayerID) - # 非脱机在线直接通知地图 - if calledPlayer and not PlayerControl.GetIsTJG(calledPlayer): - SendMapServer_FBHelpBattleRecord(calledPlayer, [helpRecord]) - else: - unNotifyRecordList = PyGameData.g_fbHelpBattleRecord.get(calledPlayerID, []) - unNotifyRecordList.append(helpRecord) - PyGameData.g_fbHelpBattleRecord[calledPlayerID] = unNotifyRecordList - + __DoCallHelpPlayer(callPlayerID, callPlayerName, helpBattlePlayer, relation, mapID, funcLineID, helpCountKey, isSweep, + curTime, xianyuanCoinUpper, relationCoinAddDict, baseHelpPoint) return -def SendMapServer_FBHelpBattleRecord(curPlayer, syncHelpRecordList): +def SendMapServer_FBHelpBattleRecord(curPlayer, syncHelpRecordList, isLogin=False): if not syncHelpRecordList: return @@ -363,7 +726,7 @@ for record in syncHelpRecordList: helpRecordList.append([record.callPlayerID, record.callPlayerName, record.mapID, record.funcLineID, record.xianyuanCoinAdd, record.relation, record.vipLV, record.recordTime]) - addXianyuanCoinMsg = str(["HelpRecord", helpRecordList]) + addXianyuanCoinMsg = str(["HelpRecord", helpRecordList, isLogin]) curPlayer.MapServer_QueryPlayerResult(0, 0, 'FBHelpBattle', addXianyuanCoinMsg, len(addXianyuanCoinMsg)) GameWorld.DebugLog(" MapServer_QueryPlayerResult %s" % addXianyuanCoinMsg, curPlayer.GetPlayerID()) return -- Gitblit v1.8.0