From ff8efc0ccf9fa6d66d873673afd07d2adfd87252 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期三, 18 十二月 2024 15:43:33 +0800
Subject: [PATCH] 10297 【越南】【英语】【砍树】【tqxbqy】轮回殿-服务端(增加GM命令: Lunhui)
---
ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py | 288 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 259 insertions(+), 29 deletions(-)
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py
index 89e82d4..16a2c76 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py
@@ -51,7 +51,6 @@
import PlayerFamilySWRH
import IpyGameDataPY
import PlayerTalk
-import PlayerGeTui
import PlayerStore
import GameWorldActionControl
import GameWorldFamilyWar
@@ -61,11 +60,73 @@
import PyGameData
import GMShell
import IPY_PlayerDefine
+import GameWorldArena
+import CrossLuckyCloudBuy
import CrossRealmPK
+import CrossChampionship
import AuctionHouse
import PlayerAssist
import PlayerFB
+import PlayerLove
+import PlayerCharm
+import CrossRealmPlayer
+import CrossBattlefield
+import CrossActAllRecharge
+import CrossYaomoBoss
+import CrossRealmMsg
+import PlayerViewCache
+import PlayerFuncTeam
+import PyDataManager
+import GameWorldMineArea
+import PlayerPackData
+import PlayerRecData
+import GameWorship
+import GameXiangong
#---------------------------------------------------------------------
+
+#---------------------------------------------------------------------
+
+class OnlinePlayerMgr():
+ ''' 在线玩家管理,子服跨服通用
+ 注:跨服服务器时,玩家不一定在跨服服务器,只是表示有同步到跨服服务器的在线玩家,且不是所有玩家都有同步
+ '''
+
+ def __init__(self):
+ self.onlinePlayerDict = {} # 在线玩家 {playerID:serverGroupID, ...}
+ return
+
+ def IsOnline(self, playerID): return playerID in self.onlinePlayerDict
+
+ def __SetOnline(self, playerID, serverGroupID):
+ self.onlinePlayerDict[playerID] = serverGroupID
+ return
+
+ def __SetOffline(self, playerID, serverGroupID):
+ self.onlinePlayerDict.pop(playerID, None)
+ return
+
+ def SetOnlineState(self, playerID, isOnline, serverGroupID=0):
+ if isOnline:
+ self.__SetOnline(playerID, serverGroupID)
+ else:
+ self.__SetOffline(playerID, serverGroupID)
+ return
+
+ def GetOfflineValue(self, playerID, viewCache=None):
+ ## 离线值:0-在线;1-离线;>1-上次离线时间戳,可用于计算离线多久了;当取不到玩家信息时用1代表已离线;
+ if playerID in self.onlinePlayerDict:
+ return 0
+ offlineValue = 1
+ if viewCache and viewCache.OffTime:
+ offlineValue = viewCache.OffTime
+ return offlineValue
+
+def GetOnlinePlayerMgr():
+ mgr = PyGameData.g_onlinePlayerMgr
+ if mgr == None:
+ mgr = OnlinePlayerMgr()
+ PyGameData.g_onlinePlayerMgr = mgr
+ return mgr
#---------------------------------------------------------------------
@@ -89,9 +150,7 @@
except:
curPlayer.Kick(IPY_PlayerDefine.disWaitForPlayerLoinError)
import traceback
- GameWorld.ErrLog("玩家上线逻辑错误~~~~~\r\n%s" % traceback.format_exc())
- if GameWorld.GetGameWorld().GetDebugLevel():
- raise Exception("玩家上线逻辑错误~~~~\r\n%s" % traceback.format_exc())
+ GameWorld.RaiseException("玩家上线逻辑错误\r\n%s" % traceback.format_exc())
return
#---------------------------------------------------------------------
@@ -122,6 +181,8 @@
if GameWorld.IsCrossServer():
#跨服PK
CrossRealmPK.OnPlayerLoginCrossServer(curPlayer)
+ #协助
+ PlayerAssist.OnPlayerLoginCrossServer(curPlayer)
return
#玩家家族刷新
@@ -129,8 +190,9 @@
PlayerFamily.PlayerLoginRefreshFamily(curPlayer, tick)
#玩家队伍初始化
PlayerTeam.OnPlayerLoginRefreshTeam(curPlayer, tick)
- PlayerCompensation.NotifyPlayerCompensation(curPlayer)
+ #PlayerCompensation.NotifyPlayerCompensation(curPlayer)
__UpdOnedayJobPlayerLoginoffTime(curPlayer)
+ CrossRealmPlayer.OnPlayerLogin(curPlayer)
if not PlayerControl.GetIsTJG(curPlayer):
# 只有通知逻辑的应该放此处减少IO,如有逻辑处理存储等不可放在此处
@@ -170,35 +232,79 @@
PlayerStore.OnPlayerLogin(curPlayer)
#通知世界boss信息
GameWorldBoss.OnPlayerLogin(curPlayer)
- #家族副本boss状态通知
- PlayerFamilyBoss.OnLogin(curPlayer)
#渡劫
PlayerDuJie.OnPlayerLogin(curPlayer)
#守卫人皇
PlayerFamilySWRH.OnLogin(curPlayer)
PlayerTalk.LoginChatMi(curPlayer)
PlayerTalk.NotifyTalkCache(curPlayer)
- #PlayerGeTui.CleanNewGuyCallBackGeTui(curPlayer.GetID())
#活动
GameWorldActionControl.OnPlayerLogin(curPlayer)
#玩家等级记录
PyGameData.g_todayPlayerLVDict[curPlayer.GetID()] = curPlayer.GetLV()
+ #竞技场
+ GameWorldArena.OnPlayerLogin(curPlayer)
#跨服PK
CrossRealmPK.OnPlayerLogin(curPlayer)
+ #幸运云购
+ CrossLuckyCloudBuy.OnPlayerLogin(curPlayer)
#诛仙BOSS
PlayerZhuXianBoss.OnPlayerLogin(curPlayer)
#骑宠boss状态通知
PlayerHorsePetBoss.OnLogin(curPlayer)
#协助
- PlayerAssist.OnPlayerLogin(curPlayer, False)
+ PlayerAssist.OnPlayerLogin(curPlayer)
#天星塔
GameWorldSkyTower.OnPlayerLogin(curPlayer)
+ #福地
+ GameWorldMineArea.OnPlayerLogin(curPlayer)
GMT_CTG.OnPlayerLogin(curPlayer)
else:
- #协助
- PlayerAssist.OnPlayerLogin(curPlayer, True)
+ pass
+ return
+
+def DoPlayerRealLoginOK(curPlayer, loginMsg, tick):
+ ''' 玩家最终登录成功处理, 由 MapServer DoPlayerRealLoginOK 通知
+ 该函数为地图最终登录成功才会执行到,以后一些功能类的登录处理建议均写到这里
+ 旧的功能先不动( __DoPlayerLoginServer 函数中的功能),如果有登录相关的bug再考虑是否移动到此函数
+ '''
+ isMixServerFirstLogin = loginMsg[0]
+ GameWorld.Log("GameServer->DoPlayerRealLoginOK, isMixServerFirstLogin=%s" % isMixServerFirstLogin, curPlayer.GetPlayerID())
+
+ if GameWorld.IsCrossServer():
+ return
+
+ PyGameData.g_dbPlayerIDMap[curPlayer.GetPlayerID()] = curPlayer.GetAccID()
+
+ if not PlayerControl.GetIsTJG(curPlayer):
+ #家族副本boss状态通知
+ PlayerFamilyBoss.OnLogin(curPlayer)
+ #魅力
+ PlayerCharm.OnPlayerLogin(curPlayer)
+ #情缘
+ PlayerLove.OnPlayerLogin(curPlayer)
+ #膜拜
+ GameWorship.OnPlayerLogin(curPlayer)
+ #跨服战场
+ CrossBattlefield.OnPlayerLogin(curPlayer)
+ #跨服排位
+ CrossChampionship.OnPlayerLogin(curPlayer, tick)
+ #跨服全民充值
+ CrossActAllRecharge.OnPlayerLogin(curPlayer)
+ #跨服妖魔boss
+ CrossYaomoBoss.OnPlayerLogin(curPlayer)
+ #玩家记录
+ PlayerRecData.OnPlayerLogin(curPlayer)
+ PlayerPackData.OnPlayerLogin(curPlayer)
+ #在线状态变更,放最后
+ __OnPlayerOnlineStateChange(curPlayer, True)
+
+ if isMixServerFirstLogin:
+ PlayerCharm.OnMixServerFirstLogin(curPlayer)
+
+ PyGameData.g_noPlayerLoginWarningMailState = 2
return
def __UpdOnedayJobPlayerLoginoffTime(curPlayer):
@@ -519,9 +625,7 @@
__Func_PlayerDisconnect(curPlayer, tick)
except:
import traceback
- GameWorld.ErrLog("玩家下线逻辑错误~~~~~\r\n%s" % traceback.format_exc())
- if GameWorld.GetGameWorld().GetDebugLevel():
- raise Exception("玩家下线逻辑错误~~~~\r\n%s" % traceback.format_exc())
+ GameWorld.RaiseException("玩家下线逻辑错误\r\n%s" % traceback.format_exc())
#调用底层下线
curPlayer.DoDisconnect()
return
@@ -535,7 +639,8 @@
if GameWorld.IsCrossServer():
PlayerFB.OnPlayerDisconnectCrossServer(curPlayer)
-
+ return
+
#跨服匹配PK
CrossRealmPK.OnLeaveServer(curPlayer)
@@ -546,20 +651,133 @@
PlayerFriend.OnPlayerDisconnect(curPlayer, tick)
__UpdOnedayJobPlayerLoginoffTime(curPlayer)
- #PlayerGeTui.NewGuyCallBackGeTui(curPlayer, tick)
# 设置家族成员离线时间
SetPlayerOfflineTime(curPlayer)
#拍卖行
AuctionHouse.OnPlayerLeaveServer(curPlayer)
#协助
PlayerAssist.OnLeaveServer(curPlayer)
+ #红包
+ PlayerFamilyRedPacket.OnLeaveServer(curPlayer)
#------------镖车逻辑
#TruckPlayerDisconnectProcess(curPlayer, tick)
if not PlayerControl.GetIsTJG(curPlayer):
playerID = curPlayer.GetPlayerID()
PyGameData.g_unTJLogoffTime[playerID] = int(time.time())
+ PyGameData.g_xiangongCanLikeTimeDict.pop(playerID, None)
+ #在线状态变更,放最后
+ __OnPlayerOnlineStateChange(curPlayer, False)
+ return
+
+def __OnPlayerOnlineStateChange(curPlayer, isOnline):
+ ## 在线状态变更
+ if PlayerControl.GetIsTJG(curPlayer):
+ return
+
+ playerID = curPlayer.GetPlayerID()
+ olMgr = GetOnlinePlayerMgr()
+ olMgr.SetOnlineState(playerID, isOnline)
+
+ #relatedPlayerIDList = [] # 本服相关玩家
+ #offlineValue = olMgr.GetOfflineValue(playerID, PlayerViewCache.FindViewCache(playerID))
+ #SyncRelatedPlayerOnlineState(playerID, offlineValue, relatedPlayerIDList)
+
+ if curPlayer.GetLV() < 50:
+ #GameWorld.DebugLog("跨服相关功能未开启,不同步在线状态到跨服服务器! LV=%s" % curPlayer.GetLV(), curPlayer.GetPlayerID())
+ return
+
+ cacheBase = PlayerViewCache.GetSyncCrossCacheBase(curPlayer)
+ dataMsg = {"playerID":playerID, "isOnline":isOnline, "cacheBase":cacheBase}
+ CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_PlayerLoginout, dataMsg)
+ return
+
+def ClientServerMsg_PlayerLoginout(serverGroupID, msgData):
+ ## 收到子服玩家上下线
+
+ playerID = msgData["playerID"]
+ isOnline = msgData["isOnline"]
+ cacheBase = msgData["cacheBase"]
+
+ isLogout = not isOnline
+ olMgr = GetOnlinePlayerMgr()
+ olMgr.SetOnlineState(playerID, isOnline, cacheBase.get("ServerGroupID", 0))
+
+ PlayerViewCache.UpdCrossCacheBase(playerID, cacheBase, isLogout)
+ serverID = GameWorld.GetAccIDServerID(cacheBase["AccID"])
+
+ # 上线
+ if isOnline:
+ # 需要管理跨服在线状态时,默认需要同步缓存信息
+ syncStateInfo = {"playerID":playerID, "ViewCacheCross":1}
+ packDataMgr = PyDataManager.GetDBPlayerPackDataManager()
+ if playerID in packDataMgr.playerPackDataDict:
+ syncStateInfo["PackDataCross"] = 1
+ CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PlayerPackDataState, syncStateInfo, [serverGroupID])
+
+ GameXiangong.OnPlayerLogin_CrossLogic(serverGroupID, serverID, playerID)
+
+ # 下线
+ else:
+ pass
+
+ SyncCrossPlayerOnlineStateToRelatedPlayer(playerID)
+ return
+
+def SyncCrossPlayerOnlineStateToRelatedPlayer(playerID):
+ ## 同步跨服玩家在线状态给相关玩家
+
+ relatedPlayerIDList = []
+
+ # 功能队伍
+ funcTeamMgr = PyDataManager.GetDBPyFuncTeamManager()
+ playerTeamIDDict = funcTeamMgr.GetPlayerTeamIDDict(playerID)
+ for _, teamID in playerTeamIDDict.items():
+ funcTeam = funcTeamMgr.GetFuncTeam(teamID)
+ if not funcTeam:
+ continue
+ relatedPlayerIDList += funcTeam.GetMemberIDList()
+
+ # 其他...
+
+ # 去重汇总
+ relatedPlayerIDList = list(set(relatedPlayerIDList))
+ if playerID in relatedPlayerIDList:
+ relatedPlayerIDList.remove(playerID)
+ if not relatedPlayerIDList:
+ return
+
+ offlineValue = GetOnlinePlayerMgr().GetOfflineValue(playerID, PlayerViewCache.FindViewCache(playerID))
+ dataMsg = {"loginoutPlayerID":playerID, "offlineValue":offlineValue, "relatedPlayerIDList":relatedPlayerIDList}
+ CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_PlayerLoginout, dataMsg)
+ return
+
+def CrossServerMsg_PlayerLoginout(msgData):
+ ## 收到跨服服务器信息 - 玩家上下线状态变更
+ loginoutPlayerID = msgData["loginoutPlayerID"]
+ offlineValue = msgData["offlineValue"]
+ relatedPlayerIDList = msgData["relatedPlayerIDList"]
+ SyncRelatedPlayerOnlineState(loginoutPlayerID, offlineValue, relatedPlayerIDList, 1)
+ return
+
+def SyncRelatedPlayerOnlineState(loginoutPlayerID, offlineValue, relatedPlayerIDList, isCross=0):
+ clientPack = None
+ playerMgr = GameWorld.GetPlayerManager()
+ for playerID in relatedPlayerIDList:
+ if not PlayerControl.GetDBPlayerAccIDByID(playerID):
+ continue
+ curPlayer = playerMgr.FindPlayerByID(playerID)
+ if not curPlayer or not curPlayer.GetInitOK():
+ continue
+
+ if not clientPack:
+ clientPack = ChPyNetSendPack.tagGCRelatedPlayerOnlineState()
+ clientPack.PlayerID = loginoutPlayerID
+ clientPack.OfflineValue = offlineValue
+ clientPack.IsCross = isCross
+
+ NetPackCommon.SendFakePack(curPlayer, clientPack)
return
## 设置玩家离线时间
@@ -567,8 +785,8 @@
# @return None
# @remarks 函数详细说明.
def SetPlayerOfflineTime(curPlayer):
- if PlayerControl.GetIsTJG(curPlayer):
- return
+ #if PlayerControl.GetIsTJG(curPlayer):
+ # return
curPlayerID = curPlayer.GetPlayerID()
curFamily = curPlayer.GetFamily()
@@ -622,7 +840,9 @@
playerStatePack = IPY_GameServer.IPY_GRefreshPlayerProperty()
packValue = playerStatePack.GetValue()
+ packValueEx = playerStatePack.GetValueEx()
packType = playerStatePack.GetType()
+ #packValueTotal = packValue + packValueEx * ChConfig.Def_PerPointValue
#---特殊逻辑处理---
if packType == ShareDefine.CDBPlayerRefresh_ForbidenTalk:
@@ -632,7 +852,11 @@
if packType == ShareDefine.CDBPlayerRefresh_ExAttr17:
PlayerControl.SetPlayerAccState(curPlayer, packValue)
return
-
+
+ if packType == ShareDefine.CDBPlayerRefresh_ExAttr19:
+ PlayerControl.SetLeaveFamilyTimeEx(curPlayer, packValue)
+ return
+
if packType == IPY_GameServer.CDBPlayerRefresh_State:
# 脱机在线
PlayerControl.SetIsTJG(curPlayer, packValue)
@@ -648,7 +872,7 @@
return
if packType == IPY_GameServer.CDBPlayerRefresh_FightPower:
- curPlayer.SetFightPower(packValue)
+ curPlayer.SetFightPower(packValue, packValueEx)
return
if packType == IPY_GameServer.CDBPlayerRefresh_ExAttr2:
@@ -668,13 +892,14 @@
elif packType == IPY_GameServer.CDBPlayerRefresh_LV:
curPlayer.SetLV(packValue)
- PlayerSocial.UpdateSocialInfo(curPlayer, packType, packValue)
#玩家等级记录
playerID = curPlayer.GetID()
if playerID in PyGameData.g_todayPlayerLVDict:
PyGameData.g_todayPlayerLVDict[playerID] = packValue
elif packType == IPY_GameServer.CDBPlayerRefresh_Job:
+ if packValue != curPlayer.GetJob():
+ PlayerBillboard.DelJobFightPowerBillboard(curPlayer, curPlayer.GetJob())
curPlayer.SetJob(packValue)
# elif packType == IPY_GameServer.CDBPlayerRefresh_CurrentPlayerType:
@@ -702,7 +927,8 @@
PlayerControl.SetCrossMapID(curPlayer, packValue, False)
elif packType == IPY_GameServer.CDBPlayerRefresh_ExAttr9:
- PlayerControl.SetVIPExpireTime(curPlayer, packValue)
+ curPlayer.SetExAttr9(packValue)
+ #PlayerControl.SetVIPExpireTime(curPlayer, packValue)
elif packType == IPY_GameServer.CDBPlayerRefresh_ExAttr10:
PlayerControl.SetChatBubbleBox(curPlayer, packValue)
@@ -715,10 +941,18 @@
elif packType == IPY_GameServer.CDBPlayerRefresh_OfficialRank:
curPlayer.SetOfficialRank(packValue)
- PlayerSocial.UpdateSocialInfo(curPlayer, packType, packValue)
#更新排行榜的境界
PlayerBillboard.UpdateBillboardRealm(curPlayer)
+ elif packType == IPY_GameServer.CDBPlayerRefresh_Face:
+ curPlayer.SetFace(packValue)
+ PlayerBillboard.UpdateBillboardFace(curPlayer)
+ elif packType == IPY_GameServer.CDBPlayerRefresh_HairColor:
+ #c++头像外框 用头发颜色通知 - 遗漏问题
+ curPlayer.SetFacePic(packValue)
+ PlayerBillboard.UpdateBillboardFacePic(curPlayer)
+ #社交信息
+ PlayerSocial.UpdateSocialInfo(curPlayer.GetID(), packType, packValue)
#组队成员刷新
PlayerTeam.PlayerTeamMemberRefresh(curPlayer, packType, packValue, tick)
#家族刷新
@@ -1172,11 +1406,6 @@
# @param tick 时间戳
# @return None
def Sync_PyServerDataTimeToClient(curPlayer, tick):
-
- if not GameWorld.RefurbishPlayerTick(curPlayer, ChConfig.TYPE_Player_Tick_SyncClientTick, tick):
- #间隔未到
- return
-
# 服务器时间
serverTime = GameWorld.GetServerTime()
if not serverTime:
@@ -1190,7 +1419,8 @@
serverDateTime.Hour = serverTime.hour
serverDateTime.Minute = serverTime.minute
serverDateTime.Second = serverTime.second
- serverDateTime.MicSecond = serverTime.microsecond
+ serverDateTime.MicSecond = serverTime.microsecond
+ serverDateTime.CrossServerTime = GameWorld.GetCrossServerTimeStr()
# 通知客户端同步时间
NetPackCommon.SendFakePack(curPlayer, serverDateTime)
--
Gitblit v1.8.0