From 4e98d22cd12ed08cd1a2859141373afeca9e6bb2 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期一, 18 九月 2023 14:39:54 +0800
Subject: [PATCH] 9887 【主干】【骨折1、2】【小7】【1元】【BT10】本服与跨服竞技场PK公式优化(PVP木桩None防范)
---
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerAssist.py | 746 ++++++++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 610 insertions(+), 136 deletions(-)
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerAssist.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerAssist.py
index a7f6694..384e068 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerAssist.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerAssist.py
@@ -19,6 +19,7 @@
import PyDataManager
import IpyGameDataPY
import NetPackCommon
+import CrossRealmMsg
import PyGameDataStruct
import PlayerFBHelpBattle
import ChPyNetSendPack
@@ -30,6 +31,7 @@
import ChConfig
import uuid
+import time
# 协助类型
(
@@ -38,91 +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
@@ -133,22 +193,45 @@
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) # 发布玩家离线时间戳
assistType = AssistType_Unknown
if dbData.NPCID:
@@ -218,10 +301,14 @@
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
@@ -238,6 +325,15 @@
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
+
# 设定协助必须离开队伍
tagMap = GameWorld.GetMap(mapID)
if not tagMap:
@@ -308,7 +404,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)
@@ -322,17 +419,133 @@
tagPlayerName = tagPlayer.GetName()
tagTeamID = tagPlayer.GetTeamID()
isFriend = PlayerFriend.IsFriend(assistPlayerID, tagPlayerID)
- assistData = [mapID, "Start", assistGUID, assistPlayerID, assistPlayerName, isFriend, tagPlayerID, tagPlayerName, tagTeamID, lineID, objID, npcID]
+ 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
+ assistPack = ChPyNetSendPack.tagGCAssistingInfo()
+ assistPack.AssistGUID = assistGUID
+ NetPackCommon.SendFakePack(assistPlayer, assistPack)
+ return
+
+def CrossServerMsg_AddAssistBossPlayerOK(queryType, queryData):
+ ## 收到跨服服务器 - 添加协助boss成功
+ assistGUID, assistPlayerID, 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)
@@ -362,8 +575,8 @@
elif queryType == "OnCancelBossRequestAssist":
mapID, lineID, npcID, objID, reason = queryData
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.MapID == mapID and assistObj.LineID == lineID and assistObj.NPCID == npcID and assistObj.ObjID == objID:
OnCancelPlayerRequestAssist(assistObj, reason, False)
@@ -427,45 +640,143 @@
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, npcLV = 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
- PlayerControl.FamilyNotify(familyID, "AssistBossRequest%s" % notifyNum, [curPlayer.GetName(), mapID, npcLV, npcID])
+
+ 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):
@@ -474,33 +785,33 @@
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")
# 广播仙盟请求
@@ -512,10 +823,12 @@
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
@@ -532,22 +845,17 @@
assistObj.ExDataLen = len(exData)
# 以下是非DB字段属性
- OnInitAssistData(assistObj, isSaveDB)
+ OnInitAssistData(assistObj, isSaveDB, serverGroupID)
assistObj.ObjID = objID
#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
@@ -595,22 +903,18 @@
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)
@@ -634,8 +938,48 @@
# 暂不需要处理
pass
- # 放最后
- SyncFamilyClearAssist(familyID, assistGUID)
+ # 放最后
+ 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):
@@ -659,6 +1003,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)
@@ -698,22 +1043,69 @@
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.playerNoSaveDBAssistDict:
+ if noAssistPlayerID not in assistMgr.playerAssistDict:
continue
- playerAssistList = assistMgr.playerNoSaveDBAssistDict[noAssistPlayerID]
+ 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)
- break
+ # 跨服服务器同步到子服结算奖励
+ 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
# 新增感谢数据
@@ -726,13 +1118,48 @@
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.playerNoSaveDBAssistDict:
+ if noAssistPlayerID not in assistMgr.playerAssistDict:
return
- playerAssistList = assistMgr.playerNoSaveDBAssistDict[noAssistPlayerID]
+ playerAssistList = assistMgr.playerAssistDict[noAssistPlayerID]
for assistObj in playerAssistList:
if assistObj.MapID == mapID and assistObj.LineID == lineID:
OnCancelPlayerRequestAssist(assistObj, "FBAssistOver", False)
@@ -793,23 +1220,29 @@
playerID = curPlayer.GetPlayerID()
assistThanksMgr = PyDataManager.GetPlayerAssistThanksPyManager()
+ useThanks = None
if playerID not in assistThanksMgr.playerThanksDict:
GameWorld.ErrLog("玩家没有可使用的协助感谢礼盒!", playerID)
- return
- useThanks = None
- playerThanksList = assistThanksMgr.playerThanksDict[playerID]
- for thanks in playerThanksList:
- if itemID == thanks.ItemID:
- useThanks = thanks
- break
+ 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)
- return
+ #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
@@ -834,11 +1267,14 @@
ipyData = IpyGameDataPY.GetIpyGameData("AssistThanksGift", itemID)
if not ipyData:
return
-
- useThanks.ThanksState = 1 # 设置为已感谢
- playerThanksList.remove(useThanks) # 移除已感谢
+
queryData = [itemID]
QueryPlayerResult_PlayerAssist(curPlayer, "UseAssistThanksGift", queryData)
+
+ if not useThanks:
+ return
+ useThanks.ThanksState = 1 # 设置为已感谢
+ playerThanksList.remove(useThanks) # 移除已感谢
# 通知协助玩家可接收的感谢个数
playerMgr = GameWorld.GetPlayerManager()
@@ -972,7 +1408,11 @@
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))
@@ -985,3 +1425,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