#!/usr/bin/python # -*- coding: GBK -*- #------------------------------------------------------------------------------- # ##@package PlayerFBHelpBattle # # @todo:¸±±¾Öúսϵͳ # @author hxp # @date 2018-11-24 # @version 1.0 # # ÏêϸÃèÊö: ¸±±¾Öúսϵͳ # #------------------------------------------------------------------------------- #"""Version = 2018-11-24 22:30""" #------------------------------------------------------------------------------- import PlayerFriend import PlayerViewCache import IpyGameDataPY import PyGameData import GameWorld import random import time import IPY_GameServer import PlayerControl import ChConfig import ChPyNetSendPack import NetPackCommon MaxRobotID = 100 # ×î´ó»úÆ÷ÈËNPC¶¨ÒåID ## ÖúÕ½Íæ¼Ò¼òÒªÐÅÏ¢ class HelpBattlePlayer(): def __init__(self, playerID): self.playerID = playerID self.job = 0 self.playerName = "" self.playerLV = 0 self.realmLV = 0 self.fightPower = 0 self.familyID = 0 self.vipLV = 0 self.checkInCount = 0 self.checkInTime = 0 self.todayHelpCountDict = {} # ½ñÌìÒÑÖúÕ½´ÎÊý {(mapID, lineID):count, ...}, ͨÓôÎÊýʱlineIDĬÈÏΪ0 self.todayXianyuanCoin = 0 # ½ñÈÕÒÑ»ñµÃÏÉÔµ±Ò return ## ÖúÕ½¼Ç¼ - Ŀǰֻ¼ÇÂ¼Î´Í¨ÖªÍæ¼ÒµÄÖúÕ½ÐÅÏ¢ class FBHelpBattleRecord(): def __init__(self): self.callPlayerID = 0 # ÕÙ»½ËûµÄÍæ¼ÒID self.callPlayerName = "" self.mapID = 0 self.funcLineID = 0 self.xianyuanCoinAdd = 0 # 0´ú±íµ½´ïÉÏÏÞ self.relation = 0 # µ±Ê±µÄ¹ØÏµ self.vipLV = 0 # µ±Ê±µÄVIPµÈ¼¶ self.recordTime = 0 # ¼Ç¼µÄʱ¼ä return ## ÊÇ·ñÔÚÖúÕ½µÇ¼ÇÁбíÀï def IsInHelpBattleCheckInList(playerID): return playerID in PyGameData.g_fbHelpBattleCheckInPlayerDict def MapServer_FBHelpBattle(curPlayer, msgList): ## µØÍ¼Íæ¼ÒÇëÇóÖúÕ½Ïà¹Ø²Ù×÷ GameWorld.DebugLog("MapServer_FBHelpBattle %s" % str(msgList), curPlayer.GetPlayerID()) if not msgList: return "" cmd = msgList[0] result = [] # µÇ¼Ç if cmd == "CheckIn": result = __DoPlayerFBHelpBattleCheckIn(curPlayer, msgList) # Ë¢ÐÂÖúÕ½Áбí elif cmd == "Refresh": result = __DoFBHelpBattleRefresh(curPlayer, msgList) # ÕÙ»½ elif cmd == "Call": result = __DoFBHelpBattleCall(curPlayer, msgList) if result == None: return return msgList + result def __DoPlayerFBHelpBattleCheckIn(curPlayer, msgList): ## Íæ¼ÒµÇ¼Ç checkInCount, fightPower = msgList[1:] curTime = int(time.time()) playerID = curPlayer.GetPlayerID() curCache = PlayerViewCache.ViewCacheMgr.FindCache(playerID) haveViewCache = 1 if curCache else 0 todayXianyuanCoin = PlayerControl.GetTodayXianyuanCoin(curPlayer) helpBattlePlayer = PyGameData.g_fbHelpBattleCheckInPlayerDict.get(playerID) if not helpBattlePlayer: helpBattlePlayer = HelpBattlePlayer(playerID) PyGameData.g_fbHelpBattleCheckInPlayerDict[playerID] = helpBattlePlayer helpBattlePlayer.playerName = curPlayer.GetName() helpBattlePlayer.playerLV = curPlayer.GetLV() helpBattlePlayer.job = curPlayer.GetJob() helpBattlePlayer.realmLV = curPlayer.GetOfficialRank() helpBattlePlayer.fightPower = fightPower helpBattlePlayer.familyID = curPlayer.GetFamilyID() helpBattlePlayer.vipLV = curPlayer.GetVIPLv() helpBattlePlayer.checkInCount = checkInCount + 1 helpBattlePlayer.checkInTime = curTime helpBattlePlayer.todayXianyuanCoin = todayXianyuanCoin isOK = 1 # ĬÈϳɹ¦ GameWorld.Log("Íæ¼ÒÖúÕ½µÇ¼Ç: playerLV=%s,fightPower=%s,familyID=%s,vipLV=%s,todayXianyuanCoin=%s,checkInCount=%s,haveViewCache=%s" % (curPlayer.GetLV(), fightPower, curPlayer.GetFamilyID(), curPlayer.GetVIPLv(), todayXianyuanCoin, checkInCount + 1, haveViewCache), playerID) return [isOK, haveViewCache] def UpdateCheckInPlayerInfo(playerID, fightPower, familyID): ## ¸üеǼǵÄÖúÕ½Íæ¼ÒµÈ¼¶Õ½Á¦ if playerID not in PyGameData.g_fbHelpBattleCheckInPlayerDict: return helpBattlePlayer = PyGameData.g_fbHelpBattleCheckInPlayerDict[playerID] helpBattlePlayer.fightPower = fightPower helpBattlePlayer.familyID = familyID GameWorld.DebugLog("¸üÐÂÖúÕ½Íæ¼ÒµÈ¼¶Õ½Á¦: fightPower=%s,familyID=%s" % (fightPower, familyID), playerID) return def UpdateCheckInPlayerInfoByRefresh(curPlayer, refreshType, value): ## ¸üеǼǵÄÖúÕ½Íæ¼ÒÏÉÃËID playerID = curPlayer.GetPlayerID() if playerID not in PyGameData.g_fbHelpBattleCheckInPlayerDict: return helpBattlePlayer = PyGameData.g_fbHelpBattleCheckInPlayerDict[playerID] if refreshType == IPY_GameServer.CDBPlayerRefresh_LV: helpBattlePlayer.playerLV = value elif refreshType == IPY_GameServer.CDBPlayerRefresh_ExAttr11: helpBattlePlayer.todayXianyuanCoin = value elif refreshType == IPY_GameServer.CDBPlayerRefresh_VIPLv: helpBattlePlayer.vipLV = value else: return GameWorld.DebugLog("¸üÐÂÖúÕ½Íæ¼ÒÐÅÏ¢: refreshType=%s,value=%s" % (refreshType, value), playerID) return def __DoFBHelpBattleRefresh(curPlayer, msgList): ## ÖúÕ½ÁбíˢРmapID, funcLineID, isClientRefresh, costMoneyList, calledPlayerIDDict = msgList[1:] helpBattlePlayerDict = {} # ͬ²½¸øµØÍ¼·þÎñÆ÷µÄ´ýÑ¡ÖúÕ½Íæ¼ÒÁбíÐÅÏ¢ ipyData = IpyGameDataPY.GetIpyGameData("FBHelpBattle", mapID, funcLineID) if not ipyData: return [helpBattlePlayerDict] fightPowerMin = ipyData.GetFightPowerMin() fightPowerMax = ipyData.GetFightPowerMax() limitLV = ipyData.GetLVLimit() dayFreeHelpCountInfo = ipyData.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() GameWorld.Log("Ë¢ÐÂÖúÕ½Áбí: mapID=%s,funcLineID=%s,helpCountLineID=%s,isClientRefresh=%s,costMoneyList=%s,calledPlayerIDDict=%s" % (mapID, funcLineID, helpCountLineID, isClientRefresh, costMoneyList, calledPlayerIDDict), playerID) goldCallCount = 0 #ÒѾ­ÕÙ»½µÄ±£Áô for calledPlayerID, callInfo in calledPlayerIDDict.items(): needGoldCall, job, relation = callInfo # Íæ¼Ò¾µÏñ if calledPlayerID in PyGameData.g_fbHelpBattleCheckInPlayerDict: helpBattlePlayer = PyGameData.g_fbHelpBattleCheckInPlayerDict[calledPlayerID] helpBattlePlayerDict[calledPlayerID] = __GetNotifyMapServerHelpPlayerInfoDict(helpBattlePlayer, needGoldCall, job, relation) if needGoldCall: goldCallCount += 1 # »úÆ÷ÈËNPC elif 1 <= calledPlayerID <= MaxRobotID: helpBattlePlayerDict[calledPlayerID] = __GetNotifyMapServerHelpPlayerInfoDict(None, False, job) else: GameWorld.ErrLog("ÒÑÕÙ»½µÄÖúÕ½Íæ¼ÒÕÒ²»µ½¾µÏñ»º´æ£¡ÀíÂÛÉϲ»´æÔÚ¸ÃÇé¿ö£¬¾µÏñ»º´æÊÍ·Å»á±ÈµÇ¼ÇÓÐЧʱ³¤¶à°ëСʱ£¡") continue if helpBattlePlayerDict: GameWorld.Log("ÒÑÕÙ»½µÄÖúÕ½: %s" % str(helpBattlePlayerDict), playerID) curTime = int(time.time()) maxHelpPlayerSelectCount = IpyGameDataPY.GetFuncCfg("HelpBattleCall", 1) # ×î´ó¿ÉÒÔÑ¡ÔñÖúÕ½µÄÍæ¼Ò¸öÊý maxGoldHelpPlayerCount = IpyGameDataPY.GetFuncCfg("HelpBattleCall", 3) # ×î´ó¸¶·ÑÕÙ»½ÈËÊý checkInValidHours = IpyGameDataPY.GetFuncCfg("HelpBattleCheckIn", 1) # µÇ¼ÇÓÐЧʱ³¤£¬Ð¡Ê± checkInValidSeconds = checkInValidHours * 3600 checkInPlayerIDList = PyGameData.g_fbHelpBattleCheckInPlayerDict.keys() random.shuffle(checkInPlayerIDList) # ˢд¿Ëæ»ú GameWorld.Log(" µÇ¼ÇÖúÕ½ÈËÊý=%s" % (len(checkInPlayerIDList)), playerID) 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)) 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²¹×ã openJobList = IpyGameDataPY.GetFuncEvalCfg("OpenJob", 1) # ¿ª·ÅµÄÖ°Òµ lackCount = maxHelpPlayerSelectCount - 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 __GetHelpBattleRelation(curPlayer, helpBattlePlayer): ## »ñÈ¡ÖúÕ½Éç½»¹ØÏµ 0-ÎÞ£¬1-ºÃÓÑ£¬2-ÃËÓÑ if not helpBattlePlayer: return 0 playerID = curPlayer.GetPlayerID() tagPlayerID = helpBattlePlayer.playerID tagFamilyID = helpBattlePlayer.familyID relationList = IpyGameDataPY.GetFuncEvalCfg("HelpBattlePoint", 3, []) # Éç½»¹ØÏµÓÅÏȼ¶ for checkRelation in relationList: if checkRelation == 1: if PlayerFriend.IsFriend(playerID, tagPlayerID): return checkRelation if checkRelation == 2: if curPlayer.GetFamilyID() == tagFamilyID: return checkRelation return 0 def __GetNotifyMapServerHelpPlayerInfoDict(helpBattlePlayer, needGoldCall, job, relation=0): ## »ñȡͬ²½¸øµØÍ¼µÄÖúÕ½Íæ¼Ò¼òÒªÐÅÏ¢ helpPlayerDict = {"Job":job} if not helpBattlePlayer: return helpPlayerDict if needGoldCall: helpPlayerDict["NeedGoldCall"] = 1 helpPlayerDict["Name"] = helpBattlePlayer.playerName helpPlayerDict["LV"] = helpBattlePlayer.playerLV #helpPlayerDict["Job"] = helpBattlePlayer.job helpPlayerDict["RealmLV"] = helpBattlePlayer.realmLV helpPlayerDict["FightPower"] = helpBattlePlayer.fightPower helpPlayerDict["Relation"] = relation return helpPlayerDict def __DoFBHelpBattleCall(curPlayer, msgList): ''' ÖúÕ½ÕÙ»½£¬²»¹Ü×îÖÕ¹ý¹ØÓë·ñ£¬±»ÕÙ»½·½¶¼Ö±½ÓËãÖúÕ½³É¹¦£¬ÕâÀï´¦Àí±»ÕÙ»½µÄ£¬Ö÷¶¯·½ÔÚµØÍ¼Ö±½Ó´¦Àí ''' 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 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) 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 return def SendMapServer_FBHelpBattleRecord(curPlayer, syncHelpRecordList): if not syncHelpRecordList: return helpRecordList = [] 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]) curPlayer.MapServer_QueryPlayerResult(0, 0, 'FBHelpBattle', addXianyuanCoinMsg, len(addXianyuanCoinMsg)) GameWorld.DebugLog(" MapServer_QueryPlayerResult %s" % addXianyuanCoinMsg, curPlayer.GetPlayerID()) return