From 388823edfe6308cba6f76ca6dc4f20022c5cb2be Mon Sep 17 00:00:00 2001 From: hxp <ale99527@vip.qq.com> Date: 星期一, 30 六月 2025 19:03:50 +0800 Subject: [PATCH] 10431 【英文】看广告获得限时代金券 --- ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerAssist.py | 1129 +++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 files changed, 982 insertions(+), 147 deletions(-) diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerAssist.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerAssist.py index 91db9e4..0cff408 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerAssist.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerAssist.py @@ -15,9 +15,13 @@ #"""Version = 2019-12-06 21:00""" #------------------------------------------------------------------------------- +import PlayerFriend import PyDataManager +import IpyGameDataPY import NetPackCommon +import CrossRealmMsg import PyGameDataStruct +import PlayerFBHelpBattle import ChPyNetSendPack import PlayerControl import PlayerFamily @@ -27,6 +31,7 @@ import ChConfig import uuid +import time # 协助类型 ( @@ -35,89 +40,149 @@ AssistType_TeamFB, # 组队副本 ) = range(3) +def RemoveOutofdateAssistThanks(): + ## 移除过期的未完结感谢数据 + + timeoutDate = GameWorld.GetDatetimeByDiffDays(-7) + assistThanksMgr = PyDataManager.GetPlayerAssistThanksPyManager() + maxDoCount = len(assistThanksMgr.allAssistThanksList) + syncPlayerIDList = [] + removeCountTotal, delNoThanksCount, delUnGetThanksCount = 0, 0, 0 + doCount = 0 + while doCount < maxDoCount and assistThanksMgr.allAssistThanksList: + doCount += 1 + thanks = assistThanksMgr.allAssistThanksList[0] + thanksDate = GameWorld.ChangeStrToDatetime(thanks.TimeStr) + if thanksDate > timeoutDate: + break + + removeCountTotal += 1 + # 移除过期的感谢数据 + popThanks = assistThanksMgr.allAssistThanksList.pop(0) + playerID = popThanks.PlayerID + GUID = popThanks.GUID + assistPlayerIDList = popThanks.AssistPlayerDict.keys() + + if playerID in assistThanksMgr.playerThanksDict: + playerThanksList = assistThanksMgr.playerThanksDict[playerID] + for i, thanks in enumerate(playerThanksList): + if GUID == thanks.GUID: + delNoThanksCount += 1 + playerThanksList.pop(i) + #GameWorld.DebugLog(" 移除未感谢的数据: i=%s,GUID=%s,len=%s" % (i, thanks.GUID, len(playerThanksList))) + break + + for assistPlayerID in assistPlayerIDList: + if assistPlayerID not in assistThanksMgr.assistPlayerThanksDict: + continue + assistThanksList = assistThanksMgr.assistPlayerThanksDict[assistPlayerID] + for i, thanks in enumerate(assistThanksList): + if GUID == thanks.GUID: + delUnGetThanksCount += 1 + assistThanksList.pop(i) + #GameWorld.DebugLog(" 移除未接受感谢的数据: i=%s,GUID=%s,assistPlayerID=%s,len=%s" % (i, thanks.GUID, assistPlayerID, len(assistThanksList))) + if assistPlayerID not in syncPlayerIDList: + syncPlayerIDList.append(assistPlayerID) + break + + playerMgr = GameWorld.GetPlayerManager() + for playerID in syncPlayerIDList: + assistPlayer = playerMgr.FindPlayerByID(playerID) + if assistPlayer: + SyncCanGetAssistThanksGiftCount(assistPlayer, isForce=True) + + if removeCountTotal: + GameWorld.DebugLog("移除过期的未完结感谢数据: doCount=%s,maxDoCount=%s,removeCountTotal=%s,delNoThanksCount=%s,delUnGetThanksCount=%s,remainCount=%s" + % (doCount, maxDoCount, removeCountTotal, delNoThanksCount, delUnGetThanksCount, len(assistThanksMgr.allAssistThanksList))) + return -def OnPlayerLogin(curPlayer, isTJ=False): +def OnPlayerLoginCrossServer(curPlayer): + # 跨服登录处理 + + playerID = curPlayer.GetPlayerID() + tagPlayerID = PlayerControl.GetAssistTagPlayerID(curPlayer) + if tagPlayerID and not GameWorld.GetPlayerManager().FindPlayerByID(tagPlayerID): + serverGroupID = PlayerControl.GetPlayerServerGroupID(curPlayer) + sendMsg = {"queryType":"ResetPlayerAssist", "queryData":[playerID, tagPlayerID]} + CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossAssist, sendMsg, [serverGroupID]) + + return + +def OnPlayerLogin(curPlayer): ## 玩家上线 - # @param isTJ: 是否脱机上线 + + SyncCanGetAssistThanksGiftCount(curPlayer) familyID = curPlayer.GetFamilyID() playerID = curPlayer.GetPlayerID() - if not familyID: - return assistMgr = PyDataManager.GetPlayerAssistPyManager() - if playerID in assistMgr.playerNoSaveDBAssistDict: - playerNoSaveList = assistMgr.playerNoSaveDBAssistDict[playerID] + + # 将自己发布的重新激活并通知其他玩家 + if playerID in assistMgr.playerAssistDict: + playerAssistList = assistMgr.playerAssistDict[playerID] - # 非脱机上线 - if not isTJ: - GameWorld.DebugLog("玩家上线,恢复协助发布到仙盟列表!", playerID) - if familyID not in assistMgr.familyAssistDict: - assistMgr.familyAssistDict[familyID] = [] - recoverList = [] - familyAssistList = assistMgr.familyAssistDict[familyID] - for assistObj in playerNoSaveList: + serverAssistList, familyAssistList = [], [] + for assistObj in playerAssistList: + assistObj.OffLineTime = 0 # 设置为非离线 + if not assistObj.FamilyID: + serverAssistList.append(assistObj) + elif familyID and familyID == assistObj.FamilyID: familyAssistList.append(assistObj) - recoverList.append(assistObj) - GameWorld.DebugLog(" 恢复: %s" % assistObj.GUID) - if recoverList: - # 通知本盟其他玩家 - PlayerFamily.SendFamilyFakePack(familyID, GetAssistInfoListPack(recoverList), [playerID]) - - # 脱机上线 - else: - GameWorld.DebugLog("玩家脱机上线,强制取消发布的非存库协助!", playerID) - for assistObj in playerNoSaveList: - OnCancelPlayerRequestAssist(assistObj, "TJGLogin", True) - - if not isTJ: - SyncFamilyAssist(curPlayer) + if familyAssistList: + PlayerFamily.SendFamilyFakePack(familyID, GetAssistInfoListPack(familyAssistList), [playerID]) + if serverAssistList: + SyncServerAssist(serverAssistList) + + # 全服服务器协助、仙盟协助 通知自己 + syncAssistList = [] + for assistObj in assistMgr.allAssistDict.values(): + if assistObj.OffLineTime: + continue + if assistObj.FamilyID and assistObj.FamilyID != familyID: + continue + syncAssistList.append(assistObj) + if syncAssistList: + NetPackCommon.SendFakePack(curPlayer, GetAssistInfoListPack(syncAssistList)) # 没有协助中的信息 if playerID in assistMgr.playerAssistingDict: assistObj = assistMgr.playerAssistingDict[playerID] - if not isTJ: - tagPlayerID = assistObj.PlayerID - GameWorld.DebugLog("非脱机上线,继续协助!tagPlayerID=%s" % tagPlayerID, playerID) - - PlayerControl.SetAssistTagPlayerID(curPlayer, tagPlayerID) - assistPack = ChPyNetSendPack.tagGCAssistingInfo() - assistPack.AssistGUID = assistObj.GUID - NetPackCommon.SendFakePack(curPlayer, assistPack) - - # 脱机上线 - else: - OnCancelPlayerAssist(curPlayer, playerID, assistObj, "TJGLogin", True) - + tagPlayerID = assistObj.PlayerID + + GameWorld.DebugLog("非脱机上线,继续协助!tagPlayerID=%s" % tagPlayerID, playerID) + + PlayerControl.SetAssistTagPlayerID(curPlayer, tagPlayerID) + assistPack = ChPyNetSendPack.tagGCAssistingInfo() + assistPack.AssistGUID = assistObj.GUID + NetPackCommon.SendFakePack(curPlayer, assistPack) + return def OnLeaveServer(curPlayer): ## 玩家离线 familyID = curPlayer.GetFamilyID() - if not familyID: - return if PlayerControl.GetAssistTagPlayerID(curPlayer): PlayerControl.SetAssistTagPlayerID(curPlayer, 0) assistMgr = PyDataManager.GetPlayerAssistPyManager() - if familyID not in assistMgr.familyAssistDict: - return - playerID = curPlayer.GetPlayerID() - if playerID not in assistMgr.playerNoSaveDBAssistDict: + if playerID not in assistMgr.playerAssistDict: #GameWorld.DebugLog("玩家没有发布过协助,离线不处理!", playerID) return - playerNoSaveList = assistMgr.playerNoSaveDBAssistDict[playerID] - familyAssistList = assistMgr.familyAssistDict[familyID] + playerAssistList = assistMgr.playerAssistDict[playerID] # 暂时移除离线玩家发布的不存库协助信息,不再让其他盟友继续前往协助,已经在协助的不影响 - for assistObj in playerNoSaveList: - if assistObj not in familyAssistList: + for assistObj in playerAssistList: + if assistObj.IsSaveDB: continue - familyAssistList.remove(assistObj) - SyncFamilyClearAssist(familyID, assistObj.GUID) - GameWorld.DebugLog("玩家下线,暂时从仙盟协助列表移除玩家发布的协助: %s" % assistObj.GUID) + assistObj.OffLineTime = int(time.time()) + if not assistObj.FamilyID: + SyncServerClearAssist(assistObj.GUID) + elif familyID and familyID == assistObj.FamilyID: + SyncFamilyClearAssist(familyID, assistObj.GUID) + GameWorld.DebugLog("玩家下线,暂时从协助列表移除玩家发布的协助: %s" % assistObj.GUID) return @@ -128,22 +193,47 @@ assistMgr = PyDataManager.GetPlayerAssistPyManager() # 玩家发布的 - if leavePlayerID in assistMgr.playerNoSaveDBAssistDict: - playerAssistList = assistMgr.playerNoSaveDBAssistDict[leavePlayerID] + if leavePlayerID in assistMgr.playerAssistDict: + playerAssistList = assistMgr.playerAssistDict[leavePlayerID] for assistObj in playerAssistList[::-1]: - OnCancelPlayerRequestAssist(assistObj, "LeaveFamily", True) + if assistObj.FamilyID: + OnCancelPlayerRequestAssist(assistObj, "LeaveFamily", True) # 玩家协助中的 if leavePlayerID in assistMgr.playerAssistingDict: assistObj = assistMgr.playerAssistingDict[leavePlayerID] - OnCancelPlayerAssist(leavePlayer, leavePlayerID, assistObj, "LeaveFamily", True) + if assistObj.FamilyID: + OnCancelPlayerAssist(leavePlayer, leavePlayerID, assistObj, "LeaveFamily", True) return -def OnInitAssistData(dbData, isSaveDB): +def OnPlayerTeamChange(curPlayer): + ## 玩家队伍变更 + + if curPlayer.GetTeamID(): + return + playerID = curPlayer.GetPlayerID() + + assistMgr = PyDataManager.GetPlayerAssistPyManager() + if playerID not in assistMgr.playerAssistDict: + return + playerAssistList = assistMgr.playerAssistDict[playerID] + + for assistObj in playerAssistList[::-1]: + gameMap = GameWorld.GetMap(assistObj.MapID) + if gameMap and gameMap.GetMapFBType() == ChConfig.fbtTeam: + OnCancelPlayerRequestAssist(assistObj, "LeaveTeam", True) + + return + +def OnInitAssistData(dbData, isSaveDB, serverGroupID=0): ## 加载协助数据额外处理 setattr(dbData, "IsSaveDB", isSaveDB) # 是否保存数据库,离线可协助的需要存库,如挖矿类 setattr(dbData, "ObjID", 0) # NPC实例ID + setattr(dbData, "ServerGroupID", serverGroupID) + setattr(dbData, "OffLineTime", 0) # 发布玩家离线时间戳 + setattr(dbData, "Face", 0) + setattr(dbData, "FacePic", 0) assistType = AssistType_Unknown if dbData.NPCID: @@ -155,6 +245,41 @@ assistType = AssistType_TeamFB setattr(dbData, "AssistType", assistType) # 协助类型 setattr(dbData, "AssistPlayerIDList", []) # 协助中的玩家ID列表 + return + +def OnInitAssistThanksData(thanksMgr, dbData): + ## 初始化协助感谢数据额外处理 + setattr(dbData, "Face", 0) + setattr(dbData, "FacePic", 0) + setattr(dbData, "AssistPlayerDict", {}) + if dbData.AssistPlayer and dbData.AssistPlayer.startswith("{") and dbData.AssistPlayer.endswith("}"): + dbData.AssistPlayerDict = eval(dbData.AssistPlayer) + + thanksMgr.allAssistThanksList.append(dbData) + # 未感谢的 + if not dbData.ThanksState: + playerID = dbData.PlayerID + if playerID not in thanksMgr.playerThanksDict: + thanksMgr.playerThanksDict[playerID] = [] + playerThanksList = thanksMgr.playerThanksDict[playerID] + playerThanksList.append(dbData) + + for assistPlayerID, assistPlayerInfo in dbData.AssistPlayerDict.items(): + if "IsGet" in assistPlayerInfo: + # 已经接受感谢奖励的不再处理 + continue + + if assistPlayerID not in thanksMgr.assistPlayerThanksDict: + thanksMgr.assistPlayerThanksDict[assistPlayerID] = [] + assistPlayerThanksList = thanksMgr.assistPlayerThanksDict[assistPlayerID] + assistPlayerThanksList.append(dbData) + + return + +def OnSaveAssistThanksData(dbData): + ## 协助感谢保存数据额外处理 + dbData.AssistPlayer = str(dbData.AssistPlayerDict) + dbData.AssistPlayerLen = len(dbData.AssistPlayer) return #// B0 12 开始协助Boss #tagCGStartAssistBoss @@ -180,25 +305,44 @@ GameWorld.DebugLog("不能协助自己!") return - if assistObj.FamilyID != curPlayer.GetFamilyID(): - GameWorld.DebugLog("非同盟玩家不能协助!") - return - + isCrossBoss = assistObj.MapID in ChConfig.Def_CrossMapIDList + if isCrossBoss: + pass + else: + if assistObj.FamilyID != curPlayer.GetFamilyID(): + GameWorld.DebugLog("非同盟玩家不能协助!") + return + + playerMapID = curPlayer.GetMapID() mapID = assistObj.MapID lineID = assistObj.LineID - gameMap = GameWorld.GetMap(mapID) - if not gameMap: + playerMap = GameWorld.GetMap(playerMapID) + if not playerMap: return - if gameMap.GetMapFBType() != ChConfig.fbtNull: - playerMapID = curPlayer.GetMapID() - playerLineID = PlayerControl.GetFBFuncLineID(curPlayer) + if playerMap.GetMapFBType() != ChConfig.fbtNull: + if mapID == ChConfig.Def_FBMapID_SealDemon: + playerLineID = PlayerControl.GetFBFuncLineID(curPlayer) + else: + playerLineID = curPlayer.GetFBID() if playerMapID != mapID or playerLineID != lineID: #副本中无法协助 PlayerControl.NotifyCode(curPlayer, "AssistFBLimit") return + if isCrossBoss: + tagPlayerID = assistObj.PlayerID + assistPlayerID = curPlayer.GetPlayerID() + assistPlayerName = curPlayer.GetName() + isFriend = PlayerFriend.IsFriend(assistPlayerID, tagPlayerID) + sendMsg = {"queryType":"StartAssistBoss", "queryData":[assistGUID, assistPlayerID, assistPlayerName, isFriend]} + CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_CrossAssist, sendMsg) + return + # 设定协助必须离开队伍 - if gameMap.GetMapFBType() != ChConfig.fbtTeam: + tagMap = GameWorld.GetMap(mapID) + if not tagMap: + return + if tagMap.GetMapFBType() != ChConfig.fbtTeam: curTeam = curPlayer.GetTeam() if curTeam: PlayerTeam.DoPlayerLeaveTeam(curPlayer, curTeam, tick) @@ -264,7 +408,8 @@ if playerID not in assistObj.AssistPlayerIDList: assistObj.AssistPlayerIDList.append(playerID) - GameWorld.DebugLog("开始协助: tagPlayerID=%s,mapID=%s,lineID=%s,npcID=%s,objID=%s" % (tagPlayerID, mapID, lineID, npcID, objID), playerID) + GameWorld.DebugLog("开始协助: tagPlayerID=%s,mapID=%s,lineID=%s,npcID=%s,objID=%s" + % (tagPlayerID, mapID, lineID, npcID, objID), playerID) # 设置协助 PlayerControl.SetAssistTagPlayerID(curPlayer, tagPlayerID) @@ -277,13 +422,99 @@ tagPlayerName = tagPlayer.GetName() tagTeamID = tagPlayer.GetTeamID() - assistData = [mapID, "Start", assistGUID, assistPlayerID, assistPlayerName, tagPlayerID, tagPlayerName, tagTeamID, lineID, objID, npcID] + isFriend = PlayerFriend.IsFriend(assistPlayerID, tagPlayerID) + serverGroupID = GameWorld.GetServerGroupID() + assistData = [mapID, "Start", assistGUID, assistPlayerID, assistPlayerName, isFriend, tagPlayerID, tagPlayerName, tagTeamID, lineID, objID, npcID, serverGroupID] + GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_AssistBoss, assistData) + return + +def ClientServerMsg_StartAssistBoss(serverGroupID, queryType, queryData): + ## 收到子服消息 - 开始协助boss + ## @return: 是否同步删除GUID + assistGUID, assistPlayerID, assistPlayerName, isFriend = queryData + + assistMgr = PyDataManager.GetPlayerAssistPyManager() + if assistGUID not in assistMgr.allAssistDict: + GameWorld.Log("不存在该协助!assistGUID=%s" % assistGUID) + reason, isGameServer = "AssistGUIDNotExist", True + sendMsg = {"queryType":"CancelPlayerRequestAssist", "queryData":[assistGUID, reason, isGameServer]} + CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossAssist, sendMsg, [serverGroupID]) + return + assistObj = assistMgr.allAssistDict[assistGUID] + if assistObj.AssistType != AssistType_Boss: + return + if assistObj.PlayerID == assistPlayerID: + GameWorld.DebugLog("不能协助自己!") + return + + assistPlayer = GameWorld.GetPlayerManager().FindPlayerByID(assistPlayerID) + # 如果是在跨服服务器 + if assistPlayer: + playerMapID = assistPlayer.GetMapID() + mapID = assistObj.MapID + lineID = assistObj.LineID + playerMap = GameWorld.GetMap(playerMapID) + if not playerMap: + return + if playerMap.GetMapFBType() != ChConfig.fbtNull: + playerLineID = assistPlayer.GetFBID() + if playerMapID != mapID or playerLineID != lineID: + #副本中无法协助 + PlayerControl.NotifyCode(assistPlayer, "AssistFBLimit") + return + + tagPlayerID = assistObj.PlayerID + mapID = assistObj.MapID + lineID = assistObj.LineID + npcID = assistObj.NPCID + objID = assistObj.ObjID + + tagPlayer = GameWorld.GetPlayerManager().FindPlayerByID(tagPlayerID) + if not tagPlayer: + GameWorld.Log("玩家已离线,无法协助!tagPlayerID=%s" % (tagPlayerID)) + OnCancelPlayerRequestAssist(assistObj, "CrossPlayerOffline", True) + return + + if tagPlayer.GetMapID() != mapID: + GameWorld.DebugLog("目标玩家已不在请求协助的地图,无法协助!tagPlayerID=%s" % (tagPlayerID)) + return + + # 设置新协助之前需要先取消正在进行中的协助 + if assistPlayerID in assistMgr.playerAssistingDict: + assistingObj = assistMgr.playerAssistingDict[assistPlayerID] + if assistGUID != assistingObj.GUID: + OnCancelPlayerAssist(assistPlayer, assistPlayerID, assistingObj, "StartNewAssistBoss", True) + assistMgr.playerAssistingDict[assistPlayerID] = assistObj + + if assistPlayerID not in assistObj.AssistPlayerIDList: + assistObj.AssistPlayerIDList.append(assistPlayerID) + + GameWorld.DebugLog("开始协助: tagPlayerID=%s,mapID=%s,lineID=%s,npcID=%s,objID=%s" + % (tagPlayerID, mapID, lineID, npcID, objID), assistPlayerID) + + # 设置协助 + if assistPlayer: + PlayerControl.SetAssistTagPlayerID(assistPlayer, tagPlayerID) + + # 通知目标玩家 + # xxx开始协助你 + PlayerControl.NotifyCode(tagPlayer, "AssistStart", [assistPlayerName]) + + tagPlayerName = tagPlayer.GetName() + tagTeamID = tagPlayer.GetTeamID() + assistData = [mapID, "Start", assistGUID, assistPlayerID, assistPlayerName, isFriend, tagPlayerID, tagPlayerName, tagTeamID, lineID, objID, npcID, serverGroupID] GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_AssistBoss, assistData) return def OnAddAssistBossPlayerOK(queryData): ## 添加协助Boss的玩家成功,通知协助玩家可以前往 - assistGUID, assistPlayerID = queryData + assistGUID, assistPlayerID, tagPlayerID, serverGroupID = queryData + + if GameWorld.IsCrossServer(): + sendMsg = {"queryType":"AddAssistBossPlayerOK", "queryData":[assistGUID, assistPlayerID, tagPlayerID]} + CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossAssist, sendMsg, [serverGroupID]) + return + assistPlayer = GameWorld.GetPlayerManager().FindPlayerByID(assistPlayerID) if not assistPlayer: return @@ -293,11 +524,35 @@ NetPackCommon.SendFakePack(assistPlayer, assistPack) return -def SetPlayerStartAssistTeamFB(curPlayer, queryData): - ## 开始协助组队副本 - 玩家进入副本后才真正进入协助状态 +def CrossServerMsg_AddAssistBossPlayerOK(queryType, queryData): + ## 收到跨服服务器 - 添加协助boss成功 + assistGUID, assistPlayerID, tagPlayerID = queryData - #mapID, lineID, tagPlayerID = queryData + assistPlayer = GameWorld.GetPlayerManager().FindPlayerByID(assistPlayerID) + if not assistPlayer: + return + assistMgr = PyDataManager.GetPlayerAssistPyManager() + if assistGUID not in assistMgr.allAssistDict: + GameWorld.DebugLog("不存在该协助!assistGUID=%s" % assistGUID) + return + assistObj = assistMgr.allAssistDict[assistGUID] + + # 设置协助 + PlayerControl.SetAssistTagPlayerID(assistPlayer, tagPlayerID) + + if assistPlayerID in assistMgr.playerAssistingDict: + assistingObj = assistMgr.playerAssistingDict[assistPlayerID] + if assistGUID != assistingObj.GUID: + OnCancelPlayerAssist(assistPlayer, assistPlayerID, assistingObj, "StartNewAssistBoss", True) + assistMgr.playerAssistingDict[assistPlayerID] = assistObj + + if assistPlayerID not in assistObj.AssistPlayerIDList: + assistObj.AssistPlayerIDList.append(assistPlayerID) + + assistPack = ChPyNetSendPack.tagGCAssistingInfo() + assistPack.AssistGUID = assistGUID + NetPackCommon.SendFakePack(assistPlayer, assistPack) return def MapServer_PlayerAssistLogic(curPlayer, msgList, tick): @@ -322,17 +577,16 @@ # 取消boss协助发布 elif queryType == "OnCancelBossRequestAssist": - mapID, lineID, npcID, objID, reason, cancelPlayerIDList = queryData + mapID, lineID, npcID, objID, reason = queryData assistMgr = PyDataManager.GetPlayerAssistPyManager() - for cancelPlayerID in cancelPlayerIDList: - if cancelPlayerID in assistMgr.playerNoSaveDBAssistDict: - playerAssistList = assistMgr.playerNoSaveDBAssistDict[cancelPlayerID] - for assistObj in playerAssistList: - if assistObj.MapID == mapID and assistObj.LineID == lineID and assistObj.NPCID == npcID and assistObj.ObjID == objID: - OnCancelPlayerRequestAssist(assistObj, reason, False) - break + if playerID in assistMgr.playerAssistDict: + playerAssistList = assistMgr.playerAssistDict[playerID] + for assistObj in playerAssistList: + if assistObj.MapID == mapID and assistObj.LineID == lineID and assistObj.NPCID == npcID and assistObj.ObjID == objID: + OnCancelPlayerRequestAssist(assistObj, reason, False) + break return - + # 取消协助Boss elif queryType == "OnCancelBossAssist": mapID, lineID, npcID, objID, reason = queryData @@ -341,6 +595,16 @@ assistObj = assistMgr.playerAssistingDict[playerID] if assistObj.MapID == mapID and assistObj.LineID == lineID and assistObj.NPCID == npcID and assistObj.ObjID == objID: OnCancelPlayerAssist(curPlayer, playerID, assistObj, reason, False) + return + + # boss协助结束 + elif queryType == "OnBossAssistOver": + __DoBossAssistOver(queryData) + return + + # 副本协助结束 + elif queryType == "OnFBAssistOver": + __DoFBAssistOver(queryData) return ## ------------------------------------------------------------------------------------------- @@ -352,54 +616,171 @@ # 开始协助组队副本 elif queryType == "OnStartAssistTeamFB": - SetPlayerStartAssistTeamFB(curPlayer, queryData) + mapID, lineID, tagPlayerID = queryData + GameWorld.DebugLog(" 开始协助副本: mapID=%s,lineID=%s,tagPlayerID=%s" % (mapID, lineID, tagPlayerID), playerID) + # 副本协助暂时只处理设置协助目标ID + PlayerControl.SetAssistTagPlayerID(curPlayer, tagPlayerID) + return + + # 取消协助组队副本 + elif queryType == "OnCancelAssistTeamFB": + mapID, lineID, reason = queryData + GameWorld.DebugLog(" 开始协助副本: mapID=%s,lineID=%s,reason=%s" % (mapID, lineID, reason), playerID) + # 副本协助暂时只处理设置协助目标ID + PlayerControl.SetAssistTagPlayerID(curPlayer, 0) return #QueryPlayerResult_PlayerAssist(curPlayer, queryType, queryData, result) return -#def QueryPlayerResult_PlayerAssist(curPlayer, queryType, queryData, result=[]): -# if not curPlayer: -# return -# resultMsg = str([queryType, queryData, result]) -# curPlayer.MapServer_QueryPlayerResult(0, 0, "PlayerAssist", resultMsg, len(resultMsg)) -# GameWorld.DebugLog("协助信息发送 MapServer: playerID=%s,queryType=%s,queryData=%s" % (curPlayer.GetPlayerID(), queryType, queryData)) -# return +def QueryPlayerResult_PlayerAssist(curPlayer, queryType, queryData, result=[]): + if not curPlayer: + return + resultMsg = str([queryType, queryData, result]) + curPlayer.MapServer_QueryPlayerResult(0, 0, "PlayerAssist", resultMsg, len(resultMsg)) + GameWorld.DebugLog("协助信息发送 MapServer: playerID=%s,queryType=%s,queryData=%s" % (curPlayer.GetPlayerID(), queryType, queryData)) + return def __DoRequestAssistBoss(curPlayer, queryData): ## 请求协助Boss + isCrossServer = GameWorld.IsCrossServer() familyID = curPlayer.GetFamilyID() - if not familyID: + if not familyID and not isCrossServer: return - mapID, lineID, npcID, objID = queryData + mapID, lineID, npcID, objID, npcLV, serverGroupID = queryData playerID = curPlayer.GetPlayerID() - assistObj = None - addNewAssist = True + reqAssistObj = None + addNewAssist = False assistMgr = PyDataManager.GetPlayerAssistPyManager() - if playerID in assistMgr.playerNoSaveDBAssistDict: - playerAssistList = assistMgr.playerNoSaveDBAssistDict[playerID] + if playerID in assistMgr.playerAssistDict: + playerAssistList = assistMgr.playerAssistDict[playerID] for assistObj in playerAssistList: if assistObj.AssistType != AssistType_Boss: continue if npcID != assistObj.NPCID or lineID != assistObj.LineID or objID != assistObj.ObjID: OnCancelPlayerRequestAssist(assistObj, "RequestNewAssistBoss", True) else: - addNewAssist = False + reqAssistObj = assistObj break - if addNewAssist: - assistObj = __AddNewAssist(assistMgr, curPlayer, mapID, lineID, npcID, objID) + if not reqAssistObj: + addNewAssist = True + reqAssistObj = __AddNewAssist(assistMgr, curPlayer, mapID, lineID, npcID, objID, serverGroupID=serverGroupID) - if not assistObj: + if not reqAssistObj: return - # 通知本仙盟玩家 - PlayerFamily.SendFamilyFakePack(familyID, GetAssistInfoListPack([assistObj])) # 求助信息已发送,请等待盟友支援 PlayerControl.NotifyCode(curPlayer, "AssistRequestOK") + + requestCount = 1 + if not addNewAssist: + requestCount = min(curPlayer.GetDictByKey("AssistBossRequestCount") + 1, 999) + curPlayer.SetDict("AssistBossRequestCount", requestCount) + notifyNum = (requestCount - 1) % 3 + + if isCrossServer: + GUID = reqAssistObj.GUID + sendMsg = {"queryType":"RequestAssistBoss", "queryData":[mapID, lineID, npcID, objID, npcLV, playerID, notifyNum, GUID]} + CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossAssist, sendMsg, [serverGroupID]) + else: + # 通知本仙盟玩家 + PlayerFamily.SendFamilyFakePack(familyID, GetAssistInfoListPack([reqAssistObj])) + # 广播仙盟请求 + PlayerControl.FamilyNotify(familyID, "AssistBossRequest%s" % notifyNum, [curPlayer.GetName(), mapID, npcLV, npcID]) + + return + +def CrossServerMsg_RequestAssistBoss(queryType, queryData): + + mapID, lineID, npcID, objID, npcLV, playerID, notifyNum, GUID = queryData + + curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID) + if not curPlayer: + return + + reqAssistObj = None + addNewAssist = False + assistMgr = PyDataManager.GetPlayerAssistPyManager() + if playerID in assistMgr.playerAssistDict: + playerAssistList = assistMgr.playerAssistDict[playerID] + for assistObj in playerAssistList: + if assistObj.AssistType != AssistType_Boss: + continue + if npcID != assistObj.NPCID or lineID != assistObj.LineID or objID != assistObj.ObjID: + OnCancelPlayerRequestAssist(assistObj, "RequestNewAssistBoss", True) + else: + reqAssistObj = assistObj + break + + if not reqAssistObj: + addNewAssist = True + reqAssistObj = __AddNewAssist(assistMgr, curPlayer, mapID, lineID, npcID, objID, assistGUID=GUID) + + GameWorld.Log("收到跨服请求协助boss: %s mapID=%s,lineID=%s,npcID=%s,objID=%s,addNewAssist=%s,GUID=%s" + % (queryType, mapID, lineID, npcID, objID, addNewAssist, GUID), playerID) + if not reqAssistObj: + return + + # 通知本服玩家 + SyncServerAssist([reqAssistObj]) + + # 广播请求 + PlayerControl.WorldNotify(0, "AssistBossRequest%s" % notifyNum, [curPlayer.GetName(), mapID, npcLV, npcID]) + return + +def CrossServerMsg_CrossAssist(msgData, tick): + ## 收到跨服服务器消息 - 协助信息 + + queryType = msgData["queryType"] + queryData = msgData["queryData"] + + # 请求协助boss + if queryType == "RequestAssistBoss": + CrossServerMsg_RequestAssistBoss(queryType, queryData) + return + + # 添加协助boss成功 + if queryType == "AddAssistBossPlayerOK": + CrossServerMsg_AddAssistBossPlayerOK(queryType, queryData) + return + + # 取消协助请求 + if queryType == "CancelPlayerRequestAssist": + CrossServerMsg_CancelPlayerRequestAssist(queryType, queryData) + return + + # 取消协助 + if queryType == "CancelPlayerAssist": + CrossServerMsg_CancelPlayerAssist(queryType, queryData) + return + + # boss协助结束 + if queryType == "BossAssistOver": + CrossServerMsg_BossAssistOver(queryType, queryData) + return + + # 重置玩家协助 + if queryType == "ResetPlayerAssist": + CrossServerMsg_ResetPlayerAssist(queryType, queryData) + return + + return + +def ClientServerMsg_CrossAssist(serverGroupID, msgData, tick): + ## 收到子服服务器消息 - 协助信息 + + queryType = msgData["queryType"] + queryData = msgData["queryData"] + + # 开始协助boss + if queryType == "StartAssistBoss": + ClientServerMsg_StartAssistBoss(serverGroupID, queryType, queryData) + return + return def __DoRequestAssistTeamFB(curPlayer, queryData): @@ -408,41 +789,50 @@ familyID = curPlayer.GetFamilyID() if not familyID: return - mapID, lineID = queryData + mapID, lineID = queryData playerID = curPlayer.GetPlayerID() - assistObj = None + reqAssistObj = None addNewAssist = False assistMgr = PyDataManager.GetPlayerAssistPyManager() - if playerID in assistMgr.playerNoSaveDBAssistDict: - playerAssistList = assistMgr.playerNoSaveDBAssistDict[playerID] + if playerID in assistMgr.playerAssistDict: + playerAssistList = assistMgr.playerAssistDict[playerID] for assistObj in playerAssistList: if assistObj.AssistType != AssistType_TeamFB: continue if mapID != assistObj.MapID or lineID != assistObj.LineID: OnCancelPlayerRequestAssist(assistObj, "RequestNewAssistTeamFB", True) - addNewAssist = True - break - else: + else: + reqAssistObj = assistObj + break + + if not reqAssistObj: addNewAssist = True + reqAssistObj = __AddNewAssist(assistMgr, curPlayer, mapID, lineID) - if addNewAssist: - assistObj = __AddNewAssist(assistMgr, curPlayer, mapID, lineID) - - if not assistObj: + if not reqAssistObj: return # 通知本仙盟玩家 - PlayerFamily.SendFamilyFakePack(familyID, GetAssistInfoListPack([assistObj])) + PlayerFamily.SendFamilyFakePack(familyID, GetAssistInfoListPack([reqAssistObj])) # 求助信息已发送,请等待盟友支援 PlayerControl.NotifyCode(curPlayer, "AssistRequestOK") + # 广播仙盟请求 + requestCount = 1 + if not addNewAssist: + requestCount = min(curPlayer.GetDictByKey("AssistFBRequestCount") + 1, 999) + curPlayer.SetDict("AssistFBRequestCount", requestCount) + notifyNum = (requestCount - 1) % 3 + PlayerControl.FamilyNotify(familyID, "AssistFBRequest%s" % notifyNum, [curPlayer.GetName(), mapID]) return -def __AddNewAssist(assistMgr, curPlayer, mapID, lineID, npcID=0, objID=0, exData="", isSaveDB=0): +def __AddNewAssist(assistMgr, curPlayer, mapID, lineID, npcID=0, objID=0, exData="", isSaveDB=0, assistGUID="", serverGroupID=0): ## 添加新协助请求 - assistGUID = str(uuid.uuid1()) - familyID = curPlayer.GetFamilyID() + if not assistGUID: + assistGUID = str(uuid.uuid1()) + crossAssist = mapID in ChConfig.Def_CrossMapIDList + familyID = 0 if crossAssist else curPlayer.GetFamilyID() playerID = curPlayer.GetPlayerID() assistObj = PyGameDataStruct.tagDBAssist() assistObj.GUID = assistGUID @@ -459,22 +849,19 @@ assistObj.ExDataLen = len(exData) # 以下是非DB字段属性 - OnInitAssistData(assistObj, isSaveDB) + OnInitAssistData(assistObj, isSaveDB, serverGroupID) assistObj.ObjID = objID + assistObj.Face = curPlayer.GetFace() + assistObj.FacePic = curPlayer.GetFacePic() #assistMgr = PyDataManager.GetPlayerAssistPyManager() assistMgr.allAssistDict[assistGUID] = assistObj - if familyID not in assistMgr.familyAssistDict: - assistMgr.familyAssistDict[familyID] = [] - familyAssistList = assistMgr.familyAssistDict[familyID] - familyAssistList.append(assistObj) - if not isSaveDB: - if playerID not in assistMgr.playerNoSaveDBAssistDict: - assistMgr.playerNoSaveDBAssistDict[playerID] = [] - playerAssistList = assistMgr.playerNoSaveDBAssistDict[playerID] - playerAssistList.append(assistObj) - + if playerID not in assistMgr.playerAssistDict: + assistMgr.playerAssistDict[playerID] = [] + playerAssistList = assistMgr.playerAssistDict[playerID] + playerAssistList.append(assistObj) + GameWorld.DebugLog(" 增加新协助请求: familyID=%s,mapID=%s,lineID=%s,npcID=%s,objID=%s,exData=%s,assistGUID=%s" % (familyID, mapID, lineID, npcID, objID, exData, assistGUID), playerID) return assistObj @@ -485,10 +872,13 @@ for assistObj in familyAssistList: assistInfo = ChPyNetSendPack.tagGCAssistInfo() assistInfo.AssistGUID = assistObj.GUID + assistInfo.PlayerID = assistObj.PlayerID assistInfo.PlayerName = assistObj.PlayerName assistInfo.Job = assistObj.Job assistInfo.LV = assistObj.LV assistInfo.RealmLV = assistObj.RealmLV + assistInfo.Face = assistObj.Face + assistInfo.FacePic = assistObj.FacePic assistInfo.MapID = assistObj.MapID assistInfo.LineID = assistObj.LineID assistInfo.NPCID = assistObj.NPCID @@ -521,27 +911,21 @@ lineID = assistObj.LineID npcID = assistObj.NPCID objID = assistObj.ObjID + serverGroupID = assistObj.ServerGroupID - GameWorld.DebugLog("取消发布的协助请求: mapID=%s,lineID=%s,npcID=%s,objID=%s,reason=%s,isGameServer=%s, %s" - % (mapID, lineID, npcID, objID, reason, isGameServer, assistGUID)) + GameWorld.DebugLog("取消发布的协助请求: mapID=%s,lineID=%s,npcID=%s,objID=%s,reason=%s,isGameServer=%s, %s, serverGroupID=%s" + % (mapID, lineID, npcID, objID, reason, isGameServer, assistGUID, serverGroupID)) assistMgr = PyDataManager.GetPlayerAssistPyManager() if assistGUID not in assistMgr.allAssistDict: return assistMgr.allAssistDict.pop(assistGUID) - if familyID in assistMgr.familyAssistDict: - familyAssistList = assistMgr.familyAssistDict[familyID] - if assistObj in familyAssistList: - familyAssistList.remove(assistObj) - - if playerID in assistMgr.playerNoSaveDBAssistDict: - playerAssistList = assistMgr.playerNoSaveDBAssistDict[playerID] + if playerID in assistMgr.playerAssistDict: + playerAssistList = assistMgr.playerAssistDict[playerID] if assistObj in playerAssistList: playerAssistList.remove(assistObj) - SyncFamilyClearAssist(familyID, assistGUID) - # 取消boss协助 if assistType == AssistType_Boss: @@ -562,6 +946,48 @@ # 暂不需要处理 pass + # 放最后 + if familyID: + SyncFamilyClearAssist(familyID, assistGUID) + + if GameWorld.IsCrossServer() and serverGroupID: + sendMsg = {"queryType":"CancelPlayerRequestAssist", "queryData":[assistGUID, reason, isGameServer]} + CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossAssist, sendMsg, [serverGroupID]) + + return + +def CrossServerMsg_CancelPlayerRequestAssist(queryType, queryData): + ## 收到跨服服务器 - 取消协助请求 + + assistGUID, reason, isGameServer = queryData + + assistMgr = PyDataManager.GetPlayerAssistPyManager() + if assistGUID not in assistMgr.allAssistDict: + return + assistObj = assistMgr.allAssistDict.pop(assistGUID) + playerID = assistObj.PlayerID + assistType = assistObj.AssistType + + GameWorld.Log("收到跨服取消协助boss请求: %s assistGUID=%s,reason=%s,isGameServer=%s" % (queryType, assistGUID, reason, isGameServer), playerID) + + if playerID in assistMgr.playerAssistDict: + playerAssistList = assistMgr.playerAssistDict[playerID] + if assistObj in playerAssistList: + playerAssistList.remove(assistObj) + + # 取消boss协助 + if assistType == AssistType_Boss: + # 强制取消正在协助中的玩家 + playerMgr = GameWorld.GetPlayerManager() + for assPlayerID in assistObj.AssistPlayerIDList[::-1]: + assistObj.AssistPlayerIDList.remove(assPlayerID) + if assPlayerID in assistMgr.playerAssistingDict: + assistingObj = assistMgr.playerAssistingDict[assPlayerID] + if assistingObj.GUID == assistGUID: + assPlayer = playerMgr.FindPlayerByID(assPlayerID) + OnCancelPlayerAssist(assPlayer, assPlayerID, assistObj, reason, isGameServer, isNotify=False) + + SyncServerClearAssist(assistGUID) return def OnCancelPlayerAssist(cancelPlayer, cancelPlayerID, assistObj, reason, isGameServer, isNotify=True): @@ -585,6 +1011,7 @@ lineID = assistObj.LineID npcID = assistObj.NPCID objID = assistObj.ObjID + serverGroupID = assistObj.ServerGroupID GameWorld.DebugLog("取消协助: tagPlayerID=%s,mapID=%s,lineID=%s,npcID=%s,objID=%s,reason=%s,isGameServer=%s, %s" % (tagPlayerID, mapID, lineID, npcID, objID, reason, isGameServer, assistGUID), cancelPlayerID) @@ -597,7 +1024,14 @@ assistObj.AssistPlayerIDList.remove(cancelPlayerID) if cancelPlayer: + isTagPlayerReason = reason.startswith("RequestPlayerCancel_") PlayerControl.SetAssistTagPlayerID(cancelPlayer, 0) + overPack = ChPyNetSendPack.tagGCAssistOver() + overPack.IsTagPlayerReason = isTagPlayerReason + overPack.Reason = reason[len("RequestPlayerCancel_"):] if isTagPlayerReason else reason + overPack.ReasonLen = len(overPack.Reason) + overPack.AssistGUID = assistGUID + NetPackCommon.SendFakePack(cancelPlayer, overPack) # 取消boss协助 if assistObj.AssistType == AssistType_Boss: @@ -617,8 +1051,197 @@ elif assistObj.AssistType == AssistType_TeamFB: pass + if GameWorld.IsCrossServer() and serverGroupID: + sendMsg = {"queryType":"CancelPlayerAssist", "queryData":[assistGUID, reason, isGameServer, cancelPlayerID]} + CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossAssist, sendMsg, [serverGroupID]) + return +def CrossServerMsg_CancelPlayerAssist(queryType, queryData): + ## 收到跨服服务器 - 取消玩家协助 + + assistGUID, reason, isGameServer, cancelPlayerID = queryData + + assistMgr = PyDataManager.GetPlayerAssistPyManager() + if assistGUID not in assistMgr.allAssistDict: + return + + GameWorld.Log("收到跨服取消玩家协助: %s assistGUID=%s,reason=%s,isGameServer=%s" % (queryType, assistGUID, reason, isGameServer), cancelPlayerID) + + cancelPlayer = GameWorld.GetPlayerManager().FindPlayerByID(cancelPlayerID) + if not cancelPlayer: + return + + PlayerControl.SetAssistTagPlayerID(cancelPlayer, 0) + return + +def CrossServerMsg_ResetPlayerAssist(queryType, queryData): + ## 收到跨服服务器 - 重置玩家协助 + ## + + playerID, tagPlayerID = queryData + + GameWorld.Log("收到跨服重置玩家协助: playerID=%s,tagPlayerID=%s" % (playerID, tagPlayerID), playerID) + + curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID) + if not curPlayer: + return + PlayerControl.SetAssistTagPlayerID(curPlayer, 0) + return + +def __DoBossAssistOver(queryData): + ## boss协助结束,一般是boss被击杀 或 被系统 + mapID, lineID, npcID, objID, noAssistPlayerIDList, assistAwardItemID, assistAwardResult = queryData + isCrossServer = GameWorld.IsCrossServer() + assistMgr = PyDataManager.GetPlayerAssistPyManager() + for noAssistPlayerID in noAssistPlayerIDList: + if noAssistPlayerID not in assistMgr.playerAssistDict: + continue + playerAssistList = assistMgr.playerAssistDict[noAssistPlayerID] + for assistObj in playerAssistList: + if assistObj.MapID == mapID and assistObj.LineID == lineID and assistObj.NPCID == npcID and assistObj.ObjID == objID: + OnCancelPlayerRequestAssist(assistObj, "BossAssistOver", False) + + # 跨服服务器同步到子服结算奖励 + if isCrossServer and noAssistPlayerID in assistAwardResult: + assistPlayerDict = assistAwardResult[noAssistPlayerID] + serverGroupID = assistObj.ServerGroupID + sendMsg = {"queryType":"BossAssistOver", "queryData":[mapID, lineID, npcID, noAssistPlayerID, assistAwardItemID, assistPlayerDict]} + CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossAssist, sendMsg, [serverGroupID]) + break + + if not assistAwardItemID or not assistAwardResult: + return + + if isCrossServer: + return + + # 新增感谢数据 + playerMgr = GameWorld.GetPlayerManager() + for playerID, assistPlayerDict in assistAwardResult.items(): + curPlayer = playerMgr.FindPlayerByID(playerID) + if not curPlayer: + continue + AddNewAssistThanks(curPlayer, assistAwardItemID, mapID, lineID, assistPlayerDict, npcID) + + return + +def CrossServerMsg_BossAssistOver(queryType, queryData): + ## 收到跨服服务器 - boss协助结束 + + mapID, lineID, npcID, noAssistPlayerID, assistAwardItemID, assistPlayerDict = queryData + + GameWorld.Log("收到跨服boss协助结束: mapID=%s,lineID=%s,npcID=%s,assistAwardItemID=%s,assistPlayerDict=%s" + % (mapID, lineID, npcID, assistAwardItemID, assistPlayerDict), noAssistPlayerID) + + # 新增感谢数据 + playerMgr = GameWorld.GetPlayerManager() + curPlayer = playerMgr.FindPlayerByID(noAssistPlayerID) + if not curPlayer: + return + + AddNewAssistThanks(curPlayer, assistAwardItemID, mapID, lineID, assistPlayerDict, npcID) + + # 通知地图玩家给 协助礼盒 + queryData = [assistAwardItemID] + QueryPlayerResult_PlayerAssist(curPlayer, "CrossNoAssistPlayerAward", queryData) + + # 通知地图玩家给 活跃积分 + for assistPlayerID, assistInfo in assistPlayerDict.items(): + assistPlayer = playerMgr.FindPlayerByID(assistPlayerID) + if not assistPlayer: + continue + if "AssistMoney" not in assistInfo: + continue + assistMoney = assistInfo["AssistMoney"] + isFriend = assistInfo["IsFriend"] + + queryData = [assistMoney, isFriend] + QueryPlayerResult_PlayerAssist(assistPlayer, "CrossAssistPlayerAward", queryData) + + return + +def __DoFBAssistOver(queryData): + ## 副本协助结束 + mapID, lineID, noAssistPlayerID, assistAwardItemID, assistPlayerDict = queryData + assistMgr = PyDataManager.GetPlayerAssistPyManager() + if noAssistPlayerID not in assistMgr.playerAssistDict: + return + playerAssistList = assistMgr.playerAssistDict[noAssistPlayerID] + for assistObj in playerAssistList: + if assistObj.MapID == mapID and assistObj.LineID == lineID: + OnCancelPlayerRequestAssist(assistObj, "FBAssistOver", False) + break + + if not assistAwardItemID or not assistPlayerDict: + return + + # 新增感谢数据 + curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(noAssistPlayerID) + if curPlayer: + AddNewAssistThanks(curPlayer, assistAwardItemID, mapID, lineID, assistPlayerDict) + + return + +def AddNewAssistThanks(curPlayer, itemID, mapID, lineID, assistPlayerDict, npcID=0, exData=""): + ## 添加协助感谢数据 + + playerID = curPlayer.GetPlayerID() + newThanks = PyGameDataStruct.tagDBAssistThanks() + newThanks.GUID = str(uuid.uuid1()) + newThanks.ItemID = itemID + newThanks.FamilyID = curPlayer.GetFamilyID() + newThanks.PlayerID = playerID + newThanks.PlayerName = curPlayer.GetName() + newThanks.Job = curPlayer.GetJob() + newThanks.LV = curPlayer.GetLV() + newThanks.RealmLV = curPlayer.GetOfficialRank() + newThanks.MapID = mapID + newThanks.LineID = lineID + newThanks.NPCID = npcID + newThanks.ExData = exData + newThanks.ExDataLen = len(exData) + newThanks.DailyDateStr = GameWorld.GetDailyDateStr() + newThanks.TimeStr = GameWorld.GetCurrentDataTimeStr() + newThanks.AssistPlayer = str(assistPlayerDict) + newThanks.AssistPlayerLen = len(newThanks.AssistPlayer) + + assistThanksMgr = PyDataManager.GetPlayerAssistThanksPyManager() + OnInitAssistThanksData(assistThanksMgr, newThanks) + newThanks.Face = curPlayer.GetFace() + newThanks.FacePic = curPlayer.GetFacePic() + + GameWorld.DebugLog("增加协助感谢: itemID=%s,mapID=%s,lineID=%s,npcID=%s,exData=%s" % (itemID, mapID, lineID, npcID, exData), playerID) + return + +def AddNewAssistThanksEx(curPlayer, itemID, assistPlayerDict, mapID=0, lineID=0, npcID=0, exData=""): + ## 添加协助感谢数据,自动更新 TodayGiftCount 及 玩家信息 + DailyDateStr = GameWorld.GetDailyDateStr() + assistThanksMgr = PyDataManager.GetPlayerAssistThanksPyManager() + for assistPlayerID, assistPlayerInfoDict in assistPlayerDict.items(): + + # 查找今日该感谢物品已接受感谢次数 + TodayGiftCount = 0 + assistPlayerThanksList = assistThanksMgr.assistPlayerThanksDict.get(assistPlayerID, []) + for thanks in assistPlayerThanksList: + if DailyDateStr != thanks.DailyDateStr or itemID != thanks.ItemID: + continue + if assistPlayerID not in thanks.AssistPlayerDict: + continue + infoDict = thanks.AssistPlayerDict[assistPlayerID] + TodayGiftCount = infoDict.get("TodayGiftCount", 0) + break + + assistPlayerInfoDict["TodayGiftCount"] = TodayGiftCount + + # 更新玩家信息,之后有需要再扩展,可以从玩家缓存或直接取在线玩家实例赋值 name job 等信息 + + GameWorld.DebugLog("获取今日接受感谢次数: itemID=%s,TodayGiftCount=%s" % (itemID, TodayGiftCount), assistPlayerID) + GameWorld.DebugLog("AddNewAssistThanksEx itemID=%s,assistPlayerDict=%s" % (itemID, assistPlayerDict), curPlayer.GetPlayerID()) + AddNewAssistThanks(curPlayer, itemID, mapID, lineID, assistPlayerDict, npcID, exData) + return + + #// B0 14 使用协助感谢礼盒 #tagCGUseAssistThanksGift # #struct tagCGUseAssistThanksGift @@ -626,34 +1249,212 @@ #{ # tagHead Head; # DWORD ItemID; -# char GiftGUID[40]; //预览时GUID不发,确认使用时需发送预览返回的GUID +# BYTE IsPreview; //是否预览,非预览即确认使用 #}; def OnUseAssistThanksGift(index, clientData, tick): curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index) itemID = clientData.ItemID - giftGUID = clientData.GiftGUID + isPreview = clientData.IsPreview + + playerID = curPlayer.GetPlayerID() + assistThanksMgr = PyDataManager.GetPlayerAssistThanksPyManager() + useThanks = None + if playerID not in assistThanksMgr.playerThanksDict: + GameWorld.ErrLog("玩家没有可使用的协助感谢礼盒!", playerID) + else: + playerThanksList = assistThanksMgr.playerThanksDict[playerID] + for thanks in playerThanksList: + if itemID == thanks.ItemID: + useThanks = thanks + break + if not useThanks: + GameWorld.ErrLog("玩家没有该协助感谢礼盒!itemID=%s" % (itemID), playerID) + #20210226 优化为找不到协助信息也可以使用,防止地图扣除物品失败导致协助礼盒一直留着而无法使用 + #return + + GameWorld.DebugLog("玩家使用协助感谢礼盒!itemID=%s,isPreview=%s" % (itemID, isPreview), playerID) + # 预览 + if isPreview: + previewPack = ChPyNetSendPack.tagGCUseAssistThanksGiftPreview() + if not useThanks: + previewPack.ItemID = itemID + previewPack.MapID = 31140 # 暂随意给一个可协助的地图ID + NetPackCommon.SendFakePack(curPlayer, previewPack) + return + previewPack.ItemID = useThanks.ItemID + previewPack.MapID = useThanks.MapID + previewPack.LineID = useThanks.LineID + previewPack.NPCID = useThanks.NPCID + previewPack.ExData = useThanks.ExData + previewPack.ExDataLen = useThanks.ExDataLen + previewPack.AssistPlayerList = [] + for assistPlayerID, assistPlayerInfoDict in useThanks.AssistPlayerDict.items(): + if "PlayerName" not in assistPlayerInfoDict: + continue + assistPlayerInfo = ChPyNetSendPack.tagGCAssistPlayerInfo() + assistPlayerInfo.PlayerID = assistPlayerID + assistPlayerInfo.PlayerName = assistPlayerInfoDict["PlayerName"] + assistPlayerInfo.Job = assistPlayerInfoDict["Job"] + assistPlayerInfo.LV = assistPlayerInfoDict["LV"] + assistPlayerInfo.RealmLV = assistPlayerInfoDict["RealmLV"] + assistPlayerInfo.Face = assistPlayerInfoDict.get("Face", 0) + assistPlayerInfo.FacePic = assistPlayerInfoDict.get("FacePic", 0) + previewPack.AssistPlayerList.append(assistPlayerInfo) + previewPack.AssistPlayerCount = len(previewPack.AssistPlayerList) + NetPackCommon.SendFakePack(curPlayer, previewPack) + return + + ipyData = IpyGameDataPY.GetIpyGameData("AssistThanksGift", itemID) + if not ipyData: + return + + queryData = [itemID] + QueryPlayerResult_PlayerAssist(curPlayer, "UseAssistThanksGift", queryData) + + if not useThanks: + return + useThanks.ThanksState = 1 # 设置为已感谢 + playerThanksList.remove(useThanks) # 移除已感谢 + + # 通知协助玩家可接收的感谢个数 + playerMgr = GameWorld.GetPlayerManager() + for assistPlayerID in useThanks.AssistPlayerDict.keys(): + assistPlayer = playerMgr.FindPlayerByID(assistPlayerID) + if assistPlayer: + SyncCanGetAssistThanksGiftCount(assistPlayer) return -#// B0 15 领取协助感谢礼物 #tagCGGetAssistThanksGift +#// B0 15 接收协助感谢礼物 #tagCGGetAssistThanksGift # #struct tagCGGetAssistThanksGift # #{ # tagHead Head; -# char GiftGUID[40]; //礼盒GUID +# BYTE IsPreview; //是否预览,非预览即确认领取,无额外奖励确认时也需要回复领取包代表已读 #}; def OnGetAssistThanksGift(index, clientData, tick): curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index) - giftGUID = clientData.GiftGUID + isPreview = clientData.IsPreview + + playerID = curPlayer.GetPlayerID() + assistThanksMgr = PyDataManager.GetPlayerAssistThanksPyManager() + if playerID not in assistThanksMgr.assistPlayerThanksDict: + GameWorld.ErrLog("玩家没有可接收感谢的协助感谢礼盒!", playerID) + return + assistPlayerThanksList = assistThanksMgr.assistPlayerThanksDict[playerID] + getThanks = None + for thanks in assistPlayerThanksList: + if thanks.ThanksState: + getThanks = thanks + break + if not getThanks: + GameWorld.ErrLog("找不到玩家可接收感谢的协助感谢礼盒!", playerID) + return + itemID = getThanks.ItemID + ipyData = IpyGameDataPY.GetIpyGameData("AssistThanksGift", itemID) + if not ipyData: + return + if playerID not in getThanks.AssistPlayerDict: + return + assistPlayerInfoDict = getThanks.AssistPlayerDict[playerID] + todayGiftCount = assistPlayerInfoDict.get("TodayGiftCount", 0) # 该礼盒当日已领取额外奖励次数 + isExtraAward = 1 if todayGiftCount < ipyData.GetAssistAwardCount() else 0 + + GameWorld.DebugLog("接收协助感谢礼物: itemID=%s,isPreview=%s,isExtraAward=%s,DailyDateStr=%s" + % (itemID, isPreview, isExtraAward, getThanks.DailyDateStr), playerID) + + # 预览 + if isPreview: + previewPack = ChPyNetSendPack.tagGCGetAssistThanksGiftPreview() + previewPack.ItemID = getThanks.ItemID + previewPack.PlayerID = getThanks.PlayerID + previewPack.PlayerName = getThanks.PlayerName + previewPack.Job = getThanks.Job + previewPack.LV = getThanks.LV + previewPack.RealmLV = getThanks.RealmLV + previewPack.Face = getThanks.Face + previewPack.FacePic = getThanks.FacePic + previewPack.MapID = getThanks.MapID + previewPack.LineID = getThanks.LineID + previewPack.NPCID = getThanks.NPCID + previewPack.ExData = getThanks.ExData + previewPack.ExDataLen = len(getThanks.ExData) + previewPack.TimeStr = getThanks.TimeStr + previewPack.ExtraAward = isExtraAward + NetPackCommon.SendFakePack(curPlayer, previewPack) + return + + assistPlayerInfoDict["IsGet"] = 1 + isAllGet = True + for playerDict in getThanks.AssistPlayerDict.values(): + if "IsGet" not in playerDict: + isAllGet = False + break + + # 所有人都接收感谢了,删除该协助感谢数据 + if isAllGet: + GameWorld.DebugLog(" 所有人都感谢了,移除该协助感谢!", playerID) + if getThanks in assistThanksMgr.allAssistThanksList: + assistThanksMgr.allAssistThanksList.remove(getThanks) + + assistPlayerThanksList.remove(getThanks) # 移除 + + updateTodayGiftCount = todayGiftCount + 1 + # 更新当天该礼盒ID已领取次数 + for thanks in assistPlayerThanksList: + if getThanks.DailyDateStr != thanks.DailyDateStr or getThanks.ItemID != thanks.ItemID: + continue + if playerID not in thanks.AssistPlayerDict: + continue + assistPlayerInfoDict = thanks.AssistPlayerDict[playerID] + assistPlayerInfoDict["TodayGiftCount"] = updateTodayGiftCount + + SyncCanGetAssistThanksGiftCount(curPlayer, True) + + isCurDailyDate = getThanks.DailyDateStr == GameWorld.GetDailyDateStr() + + # 如果是镜像协助的,更新今日接收感谢礼盒次数 + if isCurDailyDate: + if IpyGameDataPY.GetIpyGameDataNotLog("FBHelpBattle", getThanks.MapID, getThanks.LineID): + PlayerFBHelpBattle.UpdateGetThanksGiftCountDict(curPlayer, itemID, updateTodayGiftCount) + + # 通知地图 + queryData = [itemID, isExtraAward, isCurDailyDate, updateTodayGiftCount] + QueryPlayerResult_PlayerAssist(curPlayer, "GetAssistThanksGift", queryData) return +def SyncCanGetAssistThanksGiftCount(curPlayer, isForce=False): + ## 通知可接收协助感谢礼物个数 + + playerID = curPlayer.GetPlayerID() + assistThanksMgr = PyDataManager.GetPlayerAssistThanksPyManager() + if playerID not in assistThanksMgr.assistPlayerThanksDict: + return + assistPlayerThanksList = assistThanksMgr.assistPlayerThanksDict[playerID] + canGetCount = 0 + for thanks in assistPlayerThanksList: + if thanks.ThanksState: + canGetCount += 1 + + if not canGetCount and not isForce: + return + + countPack = ChPyNetSendPack.tagGCCanGetAssistThanksGiftCount() + countPack.CanGetCount = canGetCount + NetPackCommon.SendFakePack(curPlayer, countPack) + return + def SyncFamilyAssist(curPlayer): ## 同步当前仙盟所有协助请求信息 familyID = curPlayer.GetFamilyID() if not familyID: return assistMgr = PyDataManager.GetPlayerAssistPyManager() - familyAssistList = assistMgr.familyAssistDict.get(familyID, []) + familyAssistList = [] + for assistObj in assistMgr.allAssistDict.values(): + if not assistObj.FamilyID or familyID != assistObj.FamilyID or assistObj.OffLineTime: + continue + familyAssistList.append(assistObj) if not familyAssistList: return NetPackCommon.SendFakePack(curPlayer, GetAssistInfoListPack(familyAssistList)) @@ -666,3 +1467,37 @@ PlayerFamily.SendFamilyFakePack(familyID, clearPack) return +def SyncServerAssist(assistList): + # 通知本服玩家协助请求信息 + funcLimitLV = PlayerControl.GetFuncLimitLV(ShareDefine.GameFuncID_PenglaiBoss) + clientPack = GetAssistInfoListPack(assistList) + playerManager = GameWorld.GetPlayerManager() + for i in xrange(playerManager.GetActivePlayerCount()): + player = playerManager.GetActivePlayerAt(i) + if player == None: + continue + if player.GetLV() < funcLimitLV: + continue + if PlayerControl.GetIsTJG(player): + continue + NetPackCommon.SendFakePack(player, clientPack) + return + +def SyncServerClearAssist(assistGUID): + # 通知本服玩家清除协助 + clearPack = ChPyNetSendPack.tagGCClearAssist() + clearPack.AssistGUID = assistGUID + funcLimitLV = PlayerControl.GetFuncLimitLV(ShareDefine.GameFuncID_PenglaiBoss) + playerManager = GameWorld.GetPlayerManager() + for i in xrange(playerManager.GetActivePlayerCount()): + player = playerManager.GetActivePlayerAt(i) + if player == None: + continue + if player.GetLV() < funcLimitLV: + continue + if PlayerControl.GetIsTJG(player): + continue + NetPackCommon.SendFakePack(player, clearPack) + return + + -- Gitblit v1.8.0