From 164b1a9e2eb3f9908e95e0050de828f0e35cb74b Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期一, 23 五月 2022 16:38:31 +0800
Subject: [PATCH] 9415 【BT5】【后端】古神战场(初版:包含战场副本外的所有功能;副本中暂仅支持击杀玩家玩法)
---
ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/test_OnWeek.py | 31
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBattlefield.py | 1120 +++++++++++++++
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerActivity.py | 25
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py | 356 ++++
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py | 180 ++
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py | 333 ++++
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerEventCounter.py | 5
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py | 2
ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py | 180 ++
ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py | 333 ++++
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/CrossBattle.py | 118 +
ServerPython/CoreServerGroup/GameServer/Script/GameWorld.py | 18
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerViewCache.py | 9
ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py | 3
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py | 2
ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/CrossFB.py | 212 ++
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldProcess.py | 6
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py | 27
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_CrossBattlefield.py | 48
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerCompensation.py | 4
ServerPython/CoreServerGroup/GameServer/PyNetPack.ini | 15
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldActionControl.py | 4
ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py | 10
ServerPython/CoreServerGroup/GameServer/Script/Player/CrossRealmPlayer.py | 34
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/FBCommon.py | 11
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py | 31
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCrossBattlefield.py | 232 +++
ServerPython/CoreServerGroup/GameServer/Script/PyGameData.py | 4
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossBattlefield.py | 890 ++++++++++++
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini | 12
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py | 4
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py | 9
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBillboard.py | 6
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py | 10
ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/test_OnDay.py | 45
35 files changed, 4,201 insertions(+), 128 deletions(-)
diff --git a/ServerPython/CoreServerGroup/GameServer/PyNetPack.ini b/ServerPython/CoreServerGroup/GameServer/PyNetPack.ini
index 875d8e5..5d94c14 100644
--- a/ServerPython/CoreServerGroup/GameServer/PyNetPack.ini
+++ b/ServerPython/CoreServerGroup/GameServer/PyNetPack.ini
@@ -364,6 +364,21 @@
PacketSubCMD_1=0x05
PacketCallFunc_1=OnQueryNotifyEquipDetailInfo
+[CrossBattlefield]
+ScriptName = GameWorldLogic\CrossBattlefield.py
+Writer = hxp
+Releaser = hxp
+RegType = 0
+RegisterPackCount = 2
+
+PacketCMD_1=0xC0
+PacketSubCMD_1=0x07
+PacketCallFunc_1=OnCrossBattlefieldJoinByCall
+
+PacketCMD_2=0xC0
+PacketSubCMD_2=0x08
+PacketCallFunc_2=OnCrossBattlefieldCallKick
+
[CrossRealmPK]
ScriptName = GameWorldLogic\CrossRealmPK.py
Writer = hxp
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py b/ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py
index 7a8650d..8b8846e 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ChConfig.py
@@ -702,6 +702,8 @@
Def_FBMapID_CrossGrasslandLing = 32040
#跨服仙草园
Def_FBMapID_CrossGrasslandXian = 32050
+#跨服战场
+Def_FBMapID_CrossBattlefield = 32060
#情缘副本
Def_FBMapID_Love = 31300
@@ -717,6 +719,7 @@
Def_FBMapID_CrossDemonKing:"CrossZonePK",
Def_FBMapID_CrossGrasslandLing:"CrossZonePK",
Def_FBMapID_CrossGrasslandXian:"CrossZonePK",
+ Def_FBMapID_CrossBattlefield:"CrossZonePK",
}
#跨服分区对应地图配置表名 - 仅适用于固定地图及虚拟分线的跨服玩法
Def_CrossZoneMapTableName = {Def_FBMapID_CrossPenglai:"CrossPenglaiZoneMap",
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
index 96ef755..f1a2139 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
@@ -3987,6 +3987,126 @@
#------------------------------------------------------
+# C0 08 跨服战场召集场次踢人 #tagCGCrossBattlefieldCallKick
+
+class tagCGCrossBattlefieldCallKick(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ("Cmd", c_ubyte),
+ ("SubCmd", c_ubyte),
+ ("Hour", c_ubyte), #战场开启时
+ ("Minute", c_ubyte), #战场开启分
+ ("TagPlayerID", c_int), #目标玩家ID,即要被踢出去的玩家ID
+ ]
+
+ def __init__(self):
+ self.Clear()
+ self.Cmd = 0xC0
+ self.SubCmd = 0x08
+ return
+
+ def ReadData(self, stringData, _pos=0, _len=0):
+ self.Clear()
+ memmove(addressof(self), stringData[_pos:], self.GetLength())
+ return _pos + self.GetLength()
+
+ def Clear(self):
+ self.Cmd = 0xC0
+ self.SubCmd = 0x08
+ self.Hour = 0
+ self.Minute = 0
+ self.TagPlayerID = 0
+ return
+
+ def GetLength(self):
+ return sizeof(tagCGCrossBattlefieldCallKick)
+
+ def GetBuffer(self):
+ return string_at(addressof(self), self.GetLength())
+
+ def OutputString(self):
+ DumpString = '''// C0 08 跨服战场召集场次踢人 //tagCGCrossBattlefieldCallKick:
+ Cmd:%s,
+ SubCmd:%s,
+ Hour:%d,
+ Minute:%d,
+ TagPlayerID:%d
+ '''\
+ %(
+ self.Cmd,
+ self.SubCmd,
+ self.Hour,
+ self.Minute,
+ self.TagPlayerID
+ )
+ return DumpString
+
+
+m_NAtagCGCrossBattlefieldCallKick=tagCGCrossBattlefieldCallKick()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCGCrossBattlefieldCallKick.Cmd,m_NAtagCGCrossBattlefieldCallKick.SubCmd))] = m_NAtagCGCrossBattlefieldCallKick
+
+
+#------------------------------------------------------
+# C0 07 跨服战场加入召集场次 #tagCGCrossBattlefieldJoinByCall
+
+class tagCGCrossBattlefieldJoinByCall(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ("Cmd", c_ubyte),
+ ("SubCmd", c_ubyte),
+ ("Hour", c_ubyte), #战场开启时
+ ("Minute", c_ubyte), #战场开启分
+ ("BuyPlayerID", c_int), #加入目标玩家的召集队伍,即购买召集场的玩家ID
+ ]
+
+ def __init__(self):
+ self.Clear()
+ self.Cmd = 0xC0
+ self.SubCmd = 0x07
+ return
+
+ def ReadData(self, stringData, _pos=0, _len=0):
+ self.Clear()
+ memmove(addressof(self), stringData[_pos:], self.GetLength())
+ return _pos + self.GetLength()
+
+ def Clear(self):
+ self.Cmd = 0xC0
+ self.SubCmd = 0x07
+ self.Hour = 0
+ self.Minute = 0
+ self.BuyPlayerID = 0
+ return
+
+ def GetLength(self):
+ return sizeof(tagCGCrossBattlefieldJoinByCall)
+
+ def GetBuffer(self):
+ return string_at(addressof(self), self.GetLength())
+
+ def OutputString(self):
+ DumpString = '''// C0 07 跨服战场加入召集场次 //tagCGCrossBattlefieldJoinByCall:
+ Cmd:%s,
+ SubCmd:%s,
+ Hour:%d,
+ Minute:%d,
+ BuyPlayerID:%d
+ '''\
+ %(
+ self.Cmd,
+ self.SubCmd,
+ self.Hour,
+ self.Minute,
+ self.BuyPlayerID
+ )
+ return DumpString
+
+
+m_NAtagCGCrossBattlefieldJoinByCall=tagCGCrossBattlefieldJoinByCall()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCGCrossBattlefieldJoinByCall.Cmd,m_NAtagCGCrossBattlefieldJoinByCall.SubCmd))] = m_NAtagCGCrossBattlefieldJoinByCall
+
+
+#------------------------------------------------------
# C0 03 强制退出跨服状态 #tagCGForceQuitCrossState
class tagCGForceQuitCrossState(Structure):
@@ -18941,6 +19061,66 @@
#------------------------------------------------------
+# C1 09 跨服战场购买开启场次 #tagCMCrossBattlefieldBuyOpen
+
+class tagCMCrossBattlefieldBuyOpen(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ("Cmd", c_ubyte),
+ ("SubCmd", c_ubyte),
+ ("Hour", c_ubyte), #战场开启时
+ ("Minute", c_ubyte), #战场开启分
+ ("Faction", c_ubyte), #阵营 1-红;2-蓝
+ ]
+
+ def __init__(self):
+ self.Clear()
+ self.Cmd = 0xC1
+ self.SubCmd = 0x09
+ return
+
+ def ReadData(self, stringData, _pos=0, _len=0):
+ self.Clear()
+ memmove(addressof(self), stringData[_pos:], self.GetLength())
+ return _pos + self.GetLength()
+
+ def Clear(self):
+ self.Cmd = 0xC1
+ self.SubCmd = 0x09
+ self.Hour = 0
+ self.Minute = 0
+ self.Faction = 0
+ return
+
+ def GetLength(self):
+ return sizeof(tagCMCrossBattlefieldBuyOpen)
+
+ def GetBuffer(self):
+ return string_at(addressof(self), self.GetLength())
+
+ def OutputString(self):
+ DumpString = '''// C1 09 跨服战场购买开启场次 //tagCMCrossBattlefieldBuyOpen:
+ Cmd:%s,
+ SubCmd:%s,
+ Hour:%d,
+ Minute:%d,
+ Faction:%d
+ '''\
+ %(
+ self.Cmd,
+ self.SubCmd,
+ self.Hour,
+ self.Minute,
+ self.Faction
+ )
+ return DumpString
+
+
+m_NAtagCMCrossBattlefieldBuyOpen=tagCMCrossBattlefieldBuyOpen()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMCrossBattlefieldBuyOpen.Cmd,m_NAtagCMCrossBattlefieldBuyOpen.SubCmd))] = m_NAtagCMCrossBattlefieldBuyOpen
+
+
+#------------------------------------------------------
# C1 06 跨服NPC对话 #tagCMCrossNPCTalk
class tagCMCrossNPCTalk(Structure):
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
index 7d369cc..6a91da3 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
@@ -12288,6 +12288,283 @@
#------------------------------------------------------
+# C0 09 跨服战场玩家购买战场信息 #tagGCCrossBattlefieldBuyInfo
+
+class tagGCCrossBattlefieldPlayer(Structure):
+ PlayerID = 0 #(DWORD PlayerID)
+ PlayerName = "" #(char PlayerName[33])
+ Job = 0 #(BYTE Job)
+ LV = 0 #(WORD LV)//等级
+ RealmLV = 0 #(WORD RealmLV)//境界
+ FightPower = 0 #(DWORD FightPower)//战力求余亿部分
+ FightPowerEx = 0 #(DWORD FightPowerEx)//战力整除亿部分
+ data = None
+
+ def __init__(self):
+ self.Clear()
+ return
+
+ def ReadData(self, _lpData, _pos=0, _Len=0):
+ self.Clear()
+ self.PlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+ self.PlayerName,_pos = CommFunc.ReadString(_lpData, _pos,33)
+ self.Job,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+ self.LV,_pos = CommFunc.ReadWORD(_lpData, _pos)
+ self.RealmLV,_pos = CommFunc.ReadWORD(_lpData, _pos)
+ self.FightPower,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+ self.FightPowerEx,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+ return _pos
+
+ def Clear(self):
+ self.PlayerID = 0
+ self.PlayerName = ""
+ self.Job = 0
+ self.LV = 0
+ self.RealmLV = 0
+ self.FightPower = 0
+ self.FightPowerEx = 0
+ return
+
+ def GetLength(self):
+ length = 0
+ length += 4
+ length += 33
+ length += 1
+ length += 2
+ length += 2
+ length += 4
+ length += 4
+
+ return length
+
+ def GetBuffer(self):
+ data = ''
+ data = CommFunc.WriteDWORD(data, self.PlayerID)
+ data = CommFunc.WriteString(data, 33, self.PlayerName)
+ data = CommFunc.WriteBYTE(data, self.Job)
+ data = CommFunc.WriteWORD(data, self.LV)
+ data = CommFunc.WriteWORD(data, self.RealmLV)
+ data = CommFunc.WriteDWORD(data, self.FightPower)
+ data = CommFunc.WriteDWORD(data, self.FightPowerEx)
+ return data
+
+ def OutputString(self):
+ DumpString = '''
+ PlayerID:%d,
+ PlayerName:%s,
+ Job:%d,
+ LV:%d,
+ RealmLV:%d,
+ FightPower:%d,
+ FightPowerEx:%d
+ '''\
+ %(
+ self.PlayerID,
+ self.PlayerName,
+ self.Job,
+ self.LV,
+ self.RealmLV,
+ self.FightPower,
+ self.FightPowerEx
+ )
+ return DumpString
+
+
+class tagGCCrossBattlefieldBuyPlayer(Structure):
+ BuyPlayerID = 0 #(DWORD BuyPlayerID)//购买的玩家ID,即召集人
+ Faction = 0 #(BYTE Faction)//阵营 1-红;2-蓝
+ FactionPlayerCount = 0 #(BYTE FactionPlayerCount)
+ FactionPlayerList = list() #(vector<tagGCCrossBattlefieldPlayer> FactionPlayerList)//阵营所有玩家列表,包含召集人
+ data = None
+
+ def __init__(self):
+ self.Clear()
+ return
+
+ def ReadData(self, _lpData, _pos=0, _Len=0):
+ self.Clear()
+ self.BuyPlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+ self.Faction,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+ self.FactionPlayerCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+ for i in range(self.FactionPlayerCount):
+ temFactionPlayerList = tagGCCrossBattlefieldPlayer()
+ _pos = temFactionPlayerList.ReadData(_lpData, _pos)
+ self.FactionPlayerList.append(temFactionPlayerList)
+ return _pos
+
+ def Clear(self):
+ self.BuyPlayerID = 0
+ self.Faction = 0
+ self.FactionPlayerCount = 0
+ self.FactionPlayerList = list()
+ return
+
+ def GetLength(self):
+ length = 0
+ length += 4
+ length += 1
+ length += 1
+ for i in range(self.FactionPlayerCount):
+ length += self.FactionPlayerList[i].GetLength()
+
+ return length
+
+ def GetBuffer(self):
+ data = ''
+ data = CommFunc.WriteDWORD(data, self.BuyPlayerID)
+ data = CommFunc.WriteBYTE(data, self.Faction)
+ data = CommFunc.WriteBYTE(data, self.FactionPlayerCount)
+ for i in range(self.FactionPlayerCount):
+ data = CommFunc.WriteString(data, self.FactionPlayerList[i].GetLength(), self.FactionPlayerList[i].GetBuffer())
+ return data
+
+ def OutputString(self):
+ DumpString = '''
+ BuyPlayerID:%d,
+ Faction:%d,
+ FactionPlayerCount:%d,
+ FactionPlayerList:%s
+ '''\
+ %(
+ self.BuyPlayerID,
+ self.Faction,
+ self.FactionPlayerCount,
+ "..."
+ )
+ return DumpString
+
+
+class tagGCCrossBattlefieldBuyHM(Structure):
+ Hour = 0 #(BYTE Hour)//战场开启时
+ Minute = 0 #(BYTE Minute)//战场开启分
+ BuyPlayerCount = 0 #(BYTE BuyPlayerCount)
+ BuyPlayerList = list() #(vector<tagGCCrossBattlefieldBuyPlayer> BuyPlayerList)//购买本场次的玩家信息列表
+ data = None
+
+ def __init__(self):
+ self.Clear()
+ return
+
+ def ReadData(self, _lpData, _pos=0, _Len=0):
+ self.Clear()
+ self.Hour,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+ self.Minute,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+ self.BuyPlayerCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+ for i in range(self.BuyPlayerCount):
+ temBuyPlayerList = tagGCCrossBattlefieldBuyPlayer()
+ _pos = temBuyPlayerList.ReadData(_lpData, _pos)
+ self.BuyPlayerList.append(temBuyPlayerList)
+ return _pos
+
+ def Clear(self):
+ self.Hour = 0
+ self.Minute = 0
+ self.BuyPlayerCount = 0
+ self.BuyPlayerList = list()
+ return
+
+ def GetLength(self):
+ length = 0
+ length += 1
+ length += 1
+ length += 1
+ for i in range(self.BuyPlayerCount):
+ length += self.BuyPlayerList[i].GetLength()
+
+ return length
+
+ def GetBuffer(self):
+ data = ''
+ data = CommFunc.WriteBYTE(data, self.Hour)
+ data = CommFunc.WriteBYTE(data, self.Minute)
+ data = CommFunc.WriteBYTE(data, self.BuyPlayerCount)
+ for i in range(self.BuyPlayerCount):
+ data = CommFunc.WriteString(data, self.BuyPlayerList[i].GetLength(), self.BuyPlayerList[i].GetBuffer())
+ return data
+
+ def OutputString(self):
+ DumpString = '''
+ Hour:%d,
+ Minute:%d,
+ BuyPlayerCount:%d,
+ BuyPlayerList:%s
+ '''\
+ %(
+ self.Hour,
+ self.Minute,
+ self.BuyPlayerCount,
+ "..."
+ )
+ return DumpString
+
+
+class tagGCCrossBattlefieldBuyInfo(Structure):
+ Head = tagHead()
+ HMCount = 0 #(BYTE HMCount)// 为0时清空重置,其他为增量更新
+ HMBuyList = list() #(vector<tagGCCrossBattlefieldBuyHM> HMBuyList)//购买场次列表
+ data = None
+
+ def __init__(self):
+ self.Clear()
+ self.Head.Cmd = 0xC0
+ self.Head.SubCmd = 0x09
+ return
+
+ def ReadData(self, _lpData, _pos=0, _Len=0):
+ self.Clear()
+ _pos = self.Head.ReadData(_lpData, _pos)
+ self.HMCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+ for i in range(self.HMCount):
+ temHMBuyList = tagGCCrossBattlefieldBuyHM()
+ _pos = temHMBuyList.ReadData(_lpData, _pos)
+ self.HMBuyList.append(temHMBuyList)
+ return _pos
+
+ def Clear(self):
+ self.Head = tagHead()
+ self.Head.Clear()
+ self.Head.Cmd = 0xC0
+ self.Head.SubCmd = 0x09
+ self.HMCount = 0
+ self.HMBuyList = list()
+ return
+
+ def GetLength(self):
+ length = 0
+ length += self.Head.GetLength()
+ length += 1
+ for i in range(self.HMCount):
+ length += self.HMBuyList[i].GetLength()
+
+ return length
+
+ def GetBuffer(self):
+ data = ''
+ data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+ data = CommFunc.WriteBYTE(data, self.HMCount)
+ for i in range(self.HMCount):
+ data = CommFunc.WriteString(data, self.HMBuyList[i].GetLength(), self.HMBuyList[i].GetBuffer())
+ return data
+
+ def OutputString(self):
+ DumpString = '''
+ Head:%s,
+ HMCount:%d,
+ HMBuyList:%s
+ '''\
+ %(
+ self.Head.OutputString(),
+ self.HMCount,
+ "..."
+ )
+ return DumpString
+
+
+m_NAtagGCCrossBattlefieldBuyInfo=tagGCCrossBattlefieldBuyInfo()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCCrossBattlefieldBuyInfo.Head.Cmd,m_NAtagGCCrossBattlefieldBuyInfo.Head.SubCmd))] = m_NAtagGCCrossBattlefieldBuyInfo
+
+
+#------------------------------------------------------
# C0 07 跨服排行榜信息 #tagGCCrossBillboardInfo
class tagGCCrossBillboardData(Structure):
@@ -40971,6 +41248,62 @@
#------------------------------------------------------
+# C1 07 跨服战场玩家信息 #tagMCCrossBattlefieldPlayerInfo
+
+class tagMCCrossBattlefieldPlayerInfo(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ("Cmd", c_ubyte),
+ ("SubCmd", c_ubyte),
+ ("BuyOpenCountToday", c_ubyte), # 今日已购买开启战场次数
+ ("HighScoreToday", c_int), # 今日最高积分
+ ]
+
+ def __init__(self):
+ self.Clear()
+ self.Cmd = 0xC1
+ self.SubCmd = 0x07
+ return
+
+ def ReadData(self, stringData, _pos=0, _len=0):
+ self.Clear()
+ memmove(addressof(self), stringData[_pos:], self.GetLength())
+ return _pos + self.GetLength()
+
+ def Clear(self):
+ self.Cmd = 0xC1
+ self.SubCmd = 0x07
+ self.BuyOpenCountToday = 0
+ self.HighScoreToday = 0
+ return
+
+ def GetLength(self):
+ return sizeof(tagMCCrossBattlefieldPlayerInfo)
+
+ def GetBuffer(self):
+ return string_at(addressof(self), self.GetLength())
+
+ def OutputString(self):
+ DumpString = '''// C1 07 跨服战场玩家信息 //tagMCCrossBattlefieldPlayerInfo:
+ Cmd:%s,
+ SubCmd:%s,
+ BuyOpenCountToday:%d,
+ HighScoreToday:%d
+ '''\
+ %(
+ self.Cmd,
+ self.SubCmd,
+ self.BuyOpenCountToday,
+ self.HighScoreToday
+ )
+ return DumpString
+
+
+m_NAtagMCCrossBattlefieldPlayerInfo=tagMCCrossBattlefieldPlayerInfo()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCCrossBattlefieldPlayerInfo.Cmd,m_NAtagMCCrossBattlefieldPlayerInfo.SubCmd))] = m_NAtagMCCrossBattlefieldPlayerInfo
+
+
+#------------------------------------------------------
# C1 02 跨服PK玩家奖励记录 #tagMCCrossRealmPKAwardState
class tagMCCrossRealmPKAwardState(Structure):
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/CrossFB.py b/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/CrossFB.py
new file mode 100644
index 0000000..c30a19c
--- /dev/null
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/CrossFB.py
@@ -0,0 +1,212 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package GM.Commands.CrossFB
+#
+# @todo:跨服副本
+# @author hxp
+# @date 2022-01-06
+# @version 1.0
+#
+# 详细描述: 跨服副本
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2022-01-06 20:30"""
+#-------------------------------------------------------------------------------
+
+import GameWorld
+import PyGameData
+import IpyGameDataPY
+import PlayerFB
+
+#---------------------------------------------------------------------
+#逻辑实现
+## 执行逻辑
+# @param curPlayer 当前玩家
+# @param gmList [cmdIndex gmAccID msg]
+# @return None
+# @remarks 函数详细说明.
+def OnExec(curPlayer, gmList):
+ ## 本服处理
+ GameWorld.DebugAnswer(curPlayer, "----------------------------")
+ if not gmList:
+ GameWorld.DebugAnswer(curPlayer, "输出人数: CrossFB mapID")
+ GameWorld.DebugAnswer(curPlayer, "虚拟进入: CrossFB mapID 功能线路 人数 等级")
+ GameWorld.DebugAnswer(curPlayer, "添加人数: CrossFB 1 场景ID 虚拟线路 在线 离线")
+ GameWorld.DebugAnswer(curPlayer, "扣除人数: CrossFB 2 场景ID 虚拟线路 在线 离线")
+ return
+
+def OnMergeServerExec(gmList, tick):
+ ## 跨服处理
+
+ serverGroupID = gmList[-2]
+ playerID = gmList[-1]
+
+ dynamicLineMapDict = IpyGameDataPY.GetFuncEvalCfg("CrossDynamicLineMap", 1, {})
+ gmList = gmList[:-2]
+ if not gmList:
+ GameWorld.DebugAnswerCross(playerID, serverGroupID, "---以下为可分流场景虚拟线路条数")
+ for mapID, mapIDList in dynamicLineMapDict.items():
+ gameMap = GameWorld.GetMap(mapID)
+ if not gameMap:
+ continue
+ GameWorld.DebugAnswerCross(playerID, serverGroupID, "动态分流: %s【mapID:%s】" % (gameMap.GetMapName(), mapID))
+ for realMapID in mapIDList:
+ GameWorld.DebugAnswerCross(playerID, serverGroupID, " 分流场景虚拟线路数:%s\t%s"
+ % (realMapID, PyGameData.g_crossMapCopyMapCountDict.get(realMapID, 0)))
+ return
+
+ value0 = gmList[0]
+ mapID = value0
+ if value0 in [1, 2]:
+ if len(gmList) != 5:
+ GameWorld.DebugAnswerCross(playerID, serverGroupID, "参数不足,请重新输入")
+ return
+ realMapID, copyMapID, fbPlayerCount, offlineCount = gmList[1:]
+
+ key = (realMapID, copyMapID)
+ if key not in PyGameData.g_crossDynamicLineCopyMapInfo:
+ GameWorld.DebugAnswerCross(playerID, serverGroupID, "不存在该场景线路或未开启!realMapID=%s,copyMapID=%s" % (realMapID, copyMapID))
+ return
+ copyMapObj = PyGameData.g_crossDynamicLineCopyMapInfo[key] # CrossCopyMapInfo
+
+ mapID = __GetMapIDByRealMapID(dynamicLineMapDict, realMapID)
+ if mapID not in dynamicLineMapDict:
+ GameWorld.DebugAnswerCross(playerID, serverGroupID, "分流场景地图错误")
+ return
+
+ # 添加
+ if value0 == 1:
+ robotID = __GetMapRobotID(dynamicLineMapDict[mapID])
+ for _ in xrange(fbPlayerCount):
+ robotID += 1
+ copyMapObj.fbPlayerDict[robotID] = serverGroupID
+
+ for _ in xrange(offlineCount):
+ robotID += 1
+ copyMapObj.offlinePlayerDict[robotID] = serverGroupID
+
+ GameWorld.DebugAnswerCross(playerID, serverGroupID, "场景%s线%s:添加在线(%s),离线(%s)" % (realMapID, copyMapID, fbPlayerCount, offlineCount))
+
+ # 扣除
+ else:
+ delFBPlayerCount, delOfflinePlayerCount = 0, 0
+ fbPlayerIDList = copyMapObj.fbPlayerDict.keys()
+ for pID in fbPlayerIDList:
+ if pID < 10000:
+ copyMapObj.fbPlayerDict.pop(pID, 0)
+ delFBPlayerCount += 1
+ if delFBPlayerCount >= fbPlayerCount:
+ break
+
+ offlinePlayerIDList = copyMapObj.offlinePlayerDict.keys()
+ for pID in offlinePlayerIDList:
+ if pID < 10000:
+ copyMapObj.offlinePlayerDict.pop(pID, 0)
+ delOfflinePlayerCount += 1
+ if delOfflinePlayerCount >= offlineCount:
+ break
+
+ GameWorld.DebugAnswerCross(playerID, serverGroupID, "场景%s线%s:删除在线(%s),离线(%s)" % (realMapID, copyMapID, delFBPlayerCount, delOfflinePlayerCount))
+
+ waitPlayerCount, fbPlayerCount, offlinePlayerCount = len(copyMapObj.waitPlayerDict), len(copyMapObj.fbPlayerDict), len(copyMapObj.offlinePlayerDict)
+ GameWorld.DebugAnswerCross(playerID, serverGroupID, " %s,功能区-线-场:%s-%s-%s,等待%s,副本%s,离线%s"
+ % (copyMapID, copyMapObj.zoneID, copyMapObj.funcLineID, copyMapObj.newFuncLineNum,
+ waitPlayerCount, fbPlayerCount, offlinePlayerCount))
+
+ # 虚拟玩家进入: CrossFB mapID funcLineID 等级 人数
+ elif len(gmList) >= 4:
+ mapID, funcLineID, enterCount, lv = gmList
+ if mapID not in dynamicLineMapDict:
+ GameWorld.DebugAnswerCross(playerID, serverGroupID, "mapID错误")
+ return
+
+ robotID = __GetMapRobotID(dynamicLineMapDict[mapID])
+
+ GameWorld.DebugLog("mapID=%s,robotID=%s" % (mapID, robotID))
+ okCount = 0
+ copyMapObj = None
+ for _ in xrange(enterCount):
+ robotID += 1
+ msgData = {"PlayerID":robotID, "MapID":mapID, "FuncLineID":funcLineID, "LV":lv}
+ copyMapObj = PlayerFB.ClientServerMsg_EnterFB(serverGroupID, msgData, tick)
+ if not copyMapObj:
+ GameWorld.DebugAnswerCross(playerID, serverGroupID, "进入失败,查看跨服GameServer日志")
+ break
+ okCount += 1
+ copyMapObj.waitPlayerDict.pop(robotID, None)
+ copyMapObj.offlinePlayerDict.pop(robotID, None)
+ copyMapObj.fbPlayerDict[robotID] = serverGroupID
+
+ if copyMapObj:
+ GameWorld.DebugAnswerCross(playerID, serverGroupID, "虚拟进入:%s - %s, LV:(%s), 个数(%s), 成功(%s)" % (mapID, funcLineID, lv, enterCount, okCount))
+ waitPlayerCount, fbPlayerCount, offlinePlayerCount = len(copyMapObj.waitPlayerDict), len(copyMapObj.fbPlayerDict), len(copyMapObj.offlinePlayerDict)
+ GameWorld.DebugAnswerCross(playerID, serverGroupID, " %s,功能区-线-场:%s-%s-%s,等待%s,副本%s,离线%s"
+ % (copyMapObj.copyMapID, copyMapObj.zoneID, copyMapObj.funcLineID, copyMapObj.newFuncLineNum,
+ waitPlayerCount, fbPlayerCount, offlinePlayerCount))
+
+ elif len(gmList) == 1:
+ pass
+ else:
+ GameWorld.DebugAnswerCross(playerID, serverGroupID, "参数个数错误!")
+ return
+
+ gameMap = GameWorld.GetMap(mapID)
+ if mapID not in dynamicLineMapDict or not gameMap:
+ GameWorld.DebugAnswerCross(playerID, serverGroupID, "不存在该分流副本地图! %s" % mapID)
+ return
+
+ GameWorld.DebugAnswerCross(playerID, serverGroupID, "---分流场景明细: %s【mapID:%s】" % (gameMap.GetMapName(), mapID))
+ dynamicMapIDList = dynamicLineMapDict[mapID]
+ for realMapID in dynamicMapIDList:
+ copyMapCount = PyGameData.g_crossMapCopyMapCountDict.get(realMapID, 0)
+ GameWorld.DebugAnswerCross(playerID, serverGroupID, "分流场景【%s】虚拟线路数%s条" % (realMapID, copyMapCount))
+
+ playerCountTotal = 0
+ for copyMapID in xrange(copyMapCount):
+ key = (realMapID, copyMapID)
+ if key not in PyGameData.g_crossDynamicLineCopyMapInfo:
+ continue
+ copyMapObj = PyGameData.g_crossDynamicLineCopyMapInfo[key] # CrossCopyMapInfo
+
+ waitPlayerCount, fbPlayerCount, offlinePlayerCount = len(copyMapObj.waitPlayerDict), len(copyMapObj.fbPlayerDict), len(copyMapObj.offlinePlayerDict)
+ playerCount = waitPlayerCount + fbPlayerCount + offlinePlayerCount
+ #if not playerCount:
+ # continue
+
+ playerCountTotal += playerCount
+ GameWorld.DebugAnswerCross(playerID, serverGroupID, " %s,功能区-线-场:%s-%s-%s,等待%s,副本%s,离线%s"
+ % (copyMapID, copyMapObj.zoneID, copyMapObj.funcLineID, copyMapObj.newFuncLineNum,
+ waitPlayerCount, fbPlayerCount, offlinePlayerCount))
+
+ if not playerCountTotal:
+ GameWorld.DebugAnswerCross(playerID, serverGroupID, " 该分流场景地图没人!")
+
+ return
+
+def OnGetMergeParam(curPlayer):
+ playerID = curPlayer.GetPlayerID()
+ serverGroupID = GameWorld.GetServerGroupID()
+ return [serverGroupID, playerID]
+
+def __GetMapIDByRealMapID(dynamicLineMapDict, realMapID):
+ for mapID, mapIDList in dynamicLineMapDict.items():
+ if realMapID in mapIDList:
+ return mapID
+ return 0
+
+def __GetMapRobotID(dynamicMapIDList):
+ robotID = 0
+ for realMapID in dynamicMapIDList:
+ copyMapCount = PyGameData.g_crossMapCopyMapCountDict.get(realMapID, 0)
+ for copyMapID in xrange(copyMapCount):
+ key = (realMapID, copyMapID)
+ if key not in PyGameData.g_crossDynamicLineCopyMapInfo:
+ continue
+ copyMapObj = PyGameData.g_crossDynamicLineCopyMapInfo[key] # CrossCopyMapInfo
+ playerIDList = list(set(copyMapObj.waitPlayerDict.keys() + copyMapObj.fbPlayerDict.keys() + copyMapObj.offlinePlayerDict.keys()))
+ for playerID in playerIDList:
+ if playerID < 10000 and playerID > robotID:
+ robotID = playerID
+ return robotID
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/test_OnDay.py b/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/test_OnDay.py
index 4b0c18e..41fce87 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/test_OnDay.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/test_OnDay.py
@@ -33,22 +33,16 @@
# @return None
# @remarks 函数详细说明. 有的任务一天只能做限定次数,或有的操作一天只能做一次
# 用来刷新任务状态或其它
-def OnExec(curPlayer,playerList):
+def OnExec(curPlayer, gmList):
+ __DoExecOnDay(gmList)
+ return
+
+def __DoExecOnDay(gmList):
timeStr = GameWorld.GetCurrentDataTimeStr()
tick = GameWorld.GetGameWorld().GetTick()
-
- if len(playerList) == 0:
- DoLogic_GM_OnDay( timeStr , tick )
- return
-
- count = playerList[0]
-
- if count > 5:
- return
-
- for i in range( count ):
- DoLogic_GM_OnDay( timeStr , tick )
-
+ count = 1 if not gmList else min(gmList[0], 5)
+ for _ in xrange(count):
+ DoLogic_GM_OnDay(timeStr , tick)
return
## 世界服务器执行 test_OnHour test_OnDay 一次 并通知在线所有玩家
@@ -56,25 +50,34 @@
# @param tick 当前tick
# @return 无返回值
# @remarks 函数详细说明:世界服务器执行 test_OnHour test_OnDay 一次
-def DoLogic_GM_OnDay( timeStr , tick ):
+def DoLogic_GM_OnDay(timeStr , tick):
playerManager = GameWorld.GetPlayerManager()
- for i in range( 0, playerManager.GetPlayerCount() ):
- curPlayer = playerManager.GetPlayerByIndex( i )
+ for i in range(0, playerManager.GetPlayerCount()):
+ curPlayer = playerManager.GetPlayerByIndex(i)
if not curPlayer or curPlayer.IsEmpty():
continue
- mapID = GameWorld.GetQueryPlayerMapID( curPlayer )
+ mapID = GameWorld.GetQueryPlayerMapID(curPlayer)
if not mapID:
continue
- playerManager.MapServer_QueryPlayer( 0, 0, curPlayer.GetID(), mapID, 'GMDateTime', 'GMOnDay', len("GMOnDay"))
+ playerManager.MapServer_QueryPlayer(0, 0, curPlayer.GetID(), mapID, 'GMDateTime', 'GMOnDay', len("GMOnDay"))
GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_OnDayEx, 0)
- GameWorldProcess.OnHour( timeStr , tick )
- GameWorldProcess.OnDay( timeStr , tick )
+ GameWorldProcess.OnHour(timeStr , tick)
+ GameWorldProcess.OnDay(timeStr , tick)
GameWorldProcess.OnDayEx(tick)
return
+
+def OnGetMergeParam(curPlayer):
+ ## 跨服命令额外参数
+ return []
+
+def OnMergeServerExec(gmList, tick):
+ ## 跨服执行命令
+ __DoExecOnDay(gmList)
+ return
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/test_OnWeek.py b/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/test_OnWeek.py
index baca40c..0c500b1 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/test_OnWeek.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/test_OnWeek.py
@@ -31,22 +31,16 @@
# @param playerList 命令执行的次数 小于=于3
# @return None
# @remarks 函数详细说明. 世界服务器执行OnWeek
-def OnExec(curPlayer,playerList):
+def OnExec(curPlayer, gmList):
+ __DoExecOnWeek(gmList)
+ return
+
+def __DoExecOnWeek(gmList):
timeStr = GameWorld.GetCurrentDataTimeStr()
tick = GameWorld.GetGameWorld().GetTick()
-
- if len(playerList) == 0:
- DoLogic_GM_OnWeek( timeStr , tick )
- return
-
- count = playerList[0]
-
- if count > 3:
- return
-
- for i in range( count ):
- DoLogic_GM_OnWeek( timeStr, tick )
-
+ count = 1 if not gmList else min(gmList[0], 5)
+ for _ in xrange(count):
+ DoLogic_GM_OnWeek(timeStr , tick)
return
## 全局函数简要说明:世界服务器执行 test_OnWeek 一次 并通知在线所有玩家
@@ -79,3 +73,12 @@
GameWorldProcess.OnWeek( timeStr , tick )
GameWorldProcess.OnWeekEx(tick)
return
+
+def OnGetMergeParam(curPlayer):
+ ## 跨服命令额外参数
+ return []
+
+def OnMergeServerExec(gmList, tick):
+ ## 跨服执行命令
+ __DoExecOnWeek(gmList)
+ return
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorld.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorld.py
index 256d3c3..ce05c72 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorld.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorld.py
@@ -1126,6 +1126,24 @@
curPlayer.DebugAnswer(text)
return
+def CrossServerMsg_DebugAnswer(msgData):
+ playerID, text = msgData
+ curPlayer = GetPlayerManager().FindPlayerByID(playerID)
+ if not curPlayer:
+ return
+ curPlayer.DebugAnswer(text)
+ return
+
+def DebugAnswerCross(playerID, serverGroupID, text):
+ DebugLog(text)
+ text = text.decode(ShareDefine.Def_Game_Character_Encoding).encode(GetCharacterEncoding())
+
+ import CrossRealmMsg
+ dataMsg = [playerID, text]
+ serverGroupIDList = [serverGroupID]
+ CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_DebugAnswer, dataMsg, serverGroupIDList)
+ return
+
def GetMap(mapID): return IpyGameDataPY.GetIpyGameData("ChinMap", mapID)
def GetNPCData(npcID): return IpyGameDataPY.GetIpyGameData("ChinNPC", npcID)
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBattlefield.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBattlefield.py
new file mode 100644
index 0000000..0521929
--- /dev/null
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBattlefield.py
@@ -0,0 +1,1120 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package CrossBattlefield
+#
+# @todo:跨服战场
+# @author hxp
+# @date 2022-01-06
+# @version 1.0
+#
+# 详细描述: 跨服战场
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2022-01-06 20:30"""
+#-------------------------------------------------------------------------------
+
+import datetime
+import PyGameData
+import CrossRealmPK
+import CrossRealmMsg
+import PlayerControl
+import PyDataManager
+import ChPyNetSendPack
+import CrossRealmPlayer
+import PlayerCompensation
+import PlayerViewCache
+import CrossBillboard
+import IpyGameDataPY
+import NetPackCommon
+import ShareDefine
+import GameWorld
+import PlayerFB
+import ChConfig
+
+import operator
+import time
+
+'''
+热更配置
+修改开启时间,只能等当天都结束了才能更新,即隔天生效,不然可能导致已购买场次的玩家购买数据丢失
+其他配置暂无影响,可直接热更
+
+合服
+开放时间同跨服PK一样,赛季结束期间不可购买,不可开启,给分区调整腾出空间,功能不考虑分区变更带来的问题
+'''
+
+Def_RecType_CrossBattlefieldBuy = ShareDefine.Def_UniversalGameRecType_CrossBattlefieldBuy
+'''
+玩家开启的跨服战场
+ShareDefine.Def_UniversalGameRecType_CrossBattlefieldBuy
+time:time 购买时间
+value1:zoneID 分区ID
+value2:hmNum 时分场次编号
+value3:playerID 购买的玩家ID
+value4:factionID 所选择的阵营ID
+
+StrValue3:[callPlayerID,...] 召集来的玩家ID,包含自己
+'''
+
+class CrossBattlefieldBuy():
+ ''' 跨服战场购买记录
+ '''
+ def __init__(self):
+ self.Clear()
+ return
+
+ def Clear(self):
+ self.buyTime = 0
+ self.hmNum = 0
+ self.zoneID = 0
+ self.playerID = 0
+ self.factionID = 0
+ self.callPlayerIDList = []
+
+ # 子服用,跨服服务器同步数据时负值; 不存库,玩家属性缓存信息,本服玩家取自己服务器最新缓存
+ self.callPlayerDict = {} # {playerID:{attrName:value, ...}, ...}
+ return
+
+ def GetSyncClientServerString(self):
+ self.callPlayerDict = {}
+ for playerID in self.callPlayerIDList:
+ curCache = PlayerViewCache.FindViewCache(playerID)
+ if not curCache:
+ continue
+ cacheDict = PlayerViewCache.GetCachePropDataDict(curCache)
+ self.callPlayerDict[playerID] = {"Name":cacheDict["Name"], "Job":cacheDict["Job"], "LV":cacheDict["LV"],
+ "RealmLV":cacheDict["RealmLV"], "FightPower":cacheDict["FightPower"]}
+
+ return {"buyTime":self.buyTime, "hmNum":self.hmNum, "zoneID":self.zoneID, "playerID":self.playerID, "factionID":self.factionID,
+ "callPlayerIDList":self.callPlayerIDList, "callPlayerDict":self.callPlayerDict}
+
+ def SetAttr(self, attrDict):
+ for k, v in attrDict.items():
+ setattr(self, k, v)
+ return
+
+def OnServerStart():
+
+ if not GameWorld.IsCrossServer():
+ return
+
+ PyGameData.g_crossBattlefieldBuyInfo = {}
+
+ universalRecMgr = GameWorld.GetUniversalRecMgr()
+ recDataList = universalRecMgr.GetTypeList(Def_RecType_CrossBattlefieldBuy)
+ GameWorld.Log("加载跨服战场购买记录! %s" % recDataList.Count())
+
+ for index in xrange(recDataList.Count()):
+ recData = recDataList.At(index)
+ zoneID = recData.GetValue1()
+ hmNum = recData.GetValue2()
+ playerID = recData.GetValue3()
+ factionID = recData.GetValue4()
+
+ strValue3 = recData.GetStrValue3()
+
+ buyRec = CrossBattlefieldBuy()
+ buyRec.buyTime = recData.GetTime()
+ buyRec.zoneID = zoneID
+ buyRec.hmNum = hmNum
+ buyRec.playerID = playerID
+ buyRec.factionID = factionID
+ buyRec.callPlayerIDList = eval(strValue3) if strValue3 else []
+
+ buyPlayerInfo = GetBuyPlayerInfo(zoneID, hmNum)
+ buyPlayerInfo[playerID] = buyRec
+
+ GameWorld.Log(" %s" % buyRec.GetSyncClientServerString())
+
+ return
+
+def OnServerClose():
+ if not GameWorld.IsCrossServer():
+ return
+
+ universalRecMgr = GameWorld.GetUniversalRecMgr()
+ universalRecMgr.Delete(Def_RecType_CrossBattlefieldBuy)
+
+ GameWorld.Log("保存跨服战场购买记录!")
+
+ recDataList = universalRecMgr.GetTypeList(Def_RecType_CrossBattlefieldBuy)
+ for _, buyHMInfo in PyGameData.g_crossBattlefieldBuyInfo.items():
+ for _, buyPlayerInfo in buyHMInfo.items():
+ for buyRec in buyPlayerInfo.values():
+ GameWorld.Log(" %s" % buyRec.GetSyncClientServerString())
+
+ recData = recDataList.AddRec()
+ recData.SetTime(buyRec.buyTime)
+
+ recData.SetValue1(buyRec.zoneID)
+ recData.SetValue2(buyRec.hmNum)
+ recData.SetValue3(buyRec.playerID)
+ recData.SetValue4(buyRec.factionID)
+
+ recData.SetStrValue3(str(buyRec.callPlayerIDList).replace(" ", ""))
+
+ return
+
+def GetHMNum(openHour, openMinute): return openHour * 100 + openMinute
+def GetHMByNum(hmNum): return hmNum / 100, hmNum % 100
+
+def OnPlayerLogin(curPlayer):
+ serverGroupID = GameWorld.GetServerGroupID()
+ zoneIpyData = CrossRealmPK.GetCrossPKServerGroupZone(serverGroupID)
+ if not zoneIpyData:
+ return
+ zoneID = zoneIpyData.GetZoneID()
+ SyncCrossBattlefieldBuyInfo(None, zoneID)
+ return
+
+def DoOnDayEx():
+ if not GameWorld.IsCrossServer():
+ return
+ PyGameData.g_crossBattlefieldBuyInfo = {}
+ Sync_CrossBattlefieldDataToClientServer()
+ return
+
+def DoOnWeekEx():
+ if not GameWorld.IsCrossServer():
+ return
+
+ enterWeekOrderAwardDict = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldBillboard", 3, {}) # 周参与榜名次对应奖励物品列表 {"名次":[[物品ID,个数,是否拍品], ...], ...} , 名次配置支持段配置
+ callWeekOrderAwardDict = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldBillboard", 4, {}) # 周召集榜名次对应奖励物品列表 {"名次":[[物品ID,个数,是否拍品], ...], ...} , 名次配置支持段配置
+ scoreWeekOrderAwardDict = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldBillboard", 5, {}) # 周参与榜名次对应奖励物品列表 {"名次":[[物品ID,个数,是否拍品], ...], ...} , 名次配置支持段配置
+
+ enterWeekOrderIntAwardDict = {int(k):v for k, v in enterWeekOrderAwardDict.items()}
+ callWeekOrderIntAwardDict = {int(k):v for k, v in callWeekOrderAwardDict.items()}
+ scoreWeekOrderIntAwardDict = {int(k):v for k, v in scoreWeekOrderAwardDict.items()}
+
+ billboardDict = {
+ ShareDefine.Def_CBT_BattlefieldWJoin:[enterWeekOrderIntAwardDict, "CrossBattlefieldEnterOrderWeek"],
+ ShareDefine.Def_CBT_BattlefieldWCall:[callWeekOrderIntAwardDict, "CrossBattlefieldCallOrderWeek"],
+ ShareDefine.Def_CBT_BattlefieldWScore:[scoreWeekOrderIntAwardDict, "CrossBattlefieldScoreOrderWeek"],
+ }
+ # 结算周榜
+ billboardMgr = PyDataManager.GetCrossBillboardManager()
+ for billboardType, doInfo in billboardDict.items():
+ awardDict, mailKey = doInfo
+ groupList = billboardMgr.GetBillboardGroupList(billboardType)
+ GameWorld.Log("过周结算跨服战场周榜奖励: billboardType=%s,groupList=%s" % (billboardType, groupList))
+ for billboardType, groupValue1, groupValue2 in groupList:
+ billboardObj = billboardMgr.GetCrossBillboard(billboardType, groupValue1, groupValue2)
+ if not billboardObj:
+ continue
+ billboardObj.SortData()
+ for i in xrange(billboardObj.GetCount()):
+ billboardData = billboardObj.At(i)
+ if not billboardData:
+ continue
+ playerID = billboardData.ID
+ rank = i + 1
+ awardItemList = GameWorld.GetOrderValueByDict(awardDict, rank)
+ paramList = [rank]
+ PlayerCompensation.SendMailByKey(mailKey, [playerID], awardItemList, paramList, crossMail=True)
+
+ billboardObj.ClearData()
+
+ return
+
+def GetCrossBattlefieldState():
+ return GameWorld.GetGameWorld().GetDictByKey(ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_CrossBattlefield)
+
+def IsBattlefieldCallPlayer(playerID):
+ ## 是否战场召集玩家,包含被召集玩家
+ for buyHMInfo in PyGameData.g_crossBattlefieldBuyInfo.values():
+ for buyPlayerInfo in buyHMInfo.values():
+ for buyRec in buyPlayerInfo.values():
+ if playerID in buyRec.callPlayerIDList:
+ return True
+ return False
+
+def GetBuyPlayerInfo(zoneID, hmNum):
+ ## 获取战场购买召集场次玩家信息
+ ## @return: buyPlayerInfo={playerID:CrossBattlefieldBuy, ...}
+ if zoneID not in PyGameData.g_crossBattlefieldBuyInfo:
+ PyGameData.g_crossBattlefieldBuyInfo[zoneID] = {}
+ buyHMInfo = PyGameData.g_crossBattlefieldBuyInfo[zoneID]
+ if hmNum not in buyHMInfo:
+ buyHMInfo[hmNum] = {}
+ buyPlayerInfo = buyHMInfo[hmNum]
+ return buyPlayerInfo
+
+def Sync_CrossBattlefieldDataToClientServer(serverGroupID=0):
+ ''' 同步跨服战场数据到子服务器
+ @param serverGroupID: 为0时同步所有子服
+ '''
+
+ GameWorld.Log("同步给子服跨服战场数据: syncServerGroupID=%s" % (serverGroupID))
+ if serverGroupID:
+ ipyData = CrossRealmPK.GetCrossPKServerGroupZone(serverGroupID)
+ if not ipyData:
+ return
+ crossZoneList = [ipyData]
+ else:
+ crossZoneName = GameWorld.GetCrossZoneName()
+ crossZoneList = IpyGameDataPY.GetIpyGameDataByCondition("CrossZonePK", {"CrossZoneName":crossZoneName}, True)
+
+ if not crossZoneList:
+ return
+
+ # 通知状态 - 全区一致
+ battlefieldState = GetCrossBattlefieldState()
+ dataMsg = {"battlefieldState":battlefieldState}
+ CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_BattlefieldState, dataMsg)
+
+ for zoneIpyData in crossZoneList:
+ zoneID = zoneIpyData.GetZoneID()
+ serverGroupIDList = [serverGroupID] if serverGroupID else zoneIpyData.GetServerGroupIDList()
+
+ # 通知购买信息
+ Send_CrossServerMsg_BattlefieldBuy(zoneID, serverGroupIDList)
+
+ return
+
+def Send_CrossServerMsg_BattlefieldBuy(zoneID, serverGroupIDList, opData=None):
+ # 通知子服购买信息
+
+ buyHMInfo = PyGameData.g_crossBattlefieldBuyInfo.get(zoneID, {})
+ if opData:
+ hmNum = GetHMNum(opData["openHour"], opData["openMinute"])
+ hmNumList = [hmNum]
+ else:
+ hmNumList = buyHMInfo.keys()
+
+ syncBuyHMInfo = {}
+ for hmNum in hmNumList:
+ if hmNum not in buyHMInfo:
+ continue
+ buyPlayerInfo = buyHMInfo[hmNum]
+
+ syncBuyPlayerInfo = {}
+ for playerID, buyRec in buyPlayerInfo.items():
+ syncBuyPlayerInfo[playerID] = buyRec.GetSyncClientServerString()
+ syncBuyHMInfo[hmNum] = syncBuyPlayerInfo
+
+ sendMsg = {"zoneID":zoneID, "syncBuyHMInfo":syncBuyHMInfo, "opData":opData}
+ CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_BattlefieldBuy, sendMsg, serverGroupIDList)
+ return
+
+def OnMapServerInitOK():
+ # 通知地图服务器状态
+ SyncMapServerCrossBattlefieldBuyInfo()
+ return
+
+def SyncMapServerCrossBattlefieldBuyInfo():
+ #if not GameWorld.IsCrossServer():
+ # return
+ syncMapBuyInfo = {}
+ for zoneID, buyHMInfo in PyGameData.g_crossBattlefieldBuyInfo.items():
+ syncMapBuyInfo[zoneID] = {}
+ for hmNum, buyPlayerInfo in buyHMInfo.items():
+ buyInfo = {}
+ for playerID, buyRec in buyPlayerInfo.items():
+ buyInfo[playerID] = {"callPlayerIDList":buyRec.callPlayerIDList, "factionID":buyRec.factionID}
+ syncMapBuyInfo[zoneID][hmNum] = buyInfo
+ GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_CrossBattlefieldCallTeamInfo, syncMapBuyInfo)
+ return
+
+def OnMinuteProcess():
+ if not GameWorld.IsCrossServer():
+ return
+
+ Dispose_CrossBattlefieldState()
+ return
+
+def __GetCrossBattlefieldTime(isRefreshState=True):
+
+ key = "CrossBattlefieldTimeInfo"
+ CrossBattlefieldTimeInfo = IpyGameDataPY.GetConfigEx(key)
+ serverTime = GameWorld.GetServerTime()
+ reloadSign = "%d-%d-%d" % (serverTime.year, serverTime.month, serverTime.day)
+ if CrossBattlefieldTimeInfo and CrossBattlefieldTimeInfo[0] == reloadSign:
+ GameWorld.DebugLog("已经加载过本日跨服战场时间状态信息!reloadSign=%s" % reloadSign)
+ return False, CrossBattlefieldTimeInfo[1]
+
+ sysOpenHMList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldOpen", 1)
+ callOpenHMList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldOpen", 2)
+ allOpenHMList = sysOpenHMList + callOpenHMList
+ dailyIpyData = IpyGameDataPY.GetIpyGameData("DailyAction", ShareDefine.DailyActionID_CrossBattlefield)
+ fbTotalMinutes = dailyIpyData.GetDuration() if dailyIpyData else 10
+
+ openNotifyMinuteList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldOpen", 3)
+
+ battleTimeInfoList = []
+
+ startDateStr = "%d-%d-%d" % (serverTime.year, serverTime.month, serverTime.day)
+ for openHour, openMinute in allOpenHMList:
+
+ openDateTime = datetime.datetime.strptime("%s %02d:%02d:00" % (startDateStr, openHour, openMinute), ChConfig.TYPE_Time_Format)
+ closeDateTime = openDateTime + datetime.timedelta(minutes=fbTotalMinutes)
+
+ notifyOpenTimeDict = {}
+ for notifyOpenMinute in openNotifyMinuteList:
+ notifyOpenDateTime = openDateTime + datetime.timedelta(minutes=-notifyOpenMinute)
+ notifyOpenTimeDict[notifyOpenDateTime] = notifyOpenMinute
+
+ battleTimeInfoList.append([openHour, openMinute, openDateTime, closeDateTime, notifyOpenTimeDict])
+
+ CrossBattlefieldTimeInfo = IpyGameDataPY.SetConfigEx(key, [reloadSign, battleTimeInfoList])
+
+ GameWorld.Log("本日跨服战场时间状态信息加载完毕!reloadSign=%s,isRefreshState=%s" % (reloadSign, isRefreshState))
+ GameWorld.Log(" allOpenHMList=%s,fbTotalMinutes=%s" % (allOpenHMList, fbTotalMinutes))
+ GameWorld.Log("=============================================================")
+ if isRefreshState:
+ Dispose_CrossBattlefieldState(True)
+
+ return True, CrossBattlefieldTimeInfo[1]
+
+def Dispose_CrossBattlefieldState(reloadRefresh=False):
+
+ isReload, battlefieldTimeList = __GetCrossBattlefieldTime(False)
+ isReload = isReload or reloadRefresh
+
+ # 这里时间需精确到分钟,不然后面的比较会匹配不到
+ curDateTime = GameWorld.GetServerTime()
+ curDateTime = datetime.datetime.strptime("%d-%d-%d %d:%d:00" % (curDateTime.year, curDateTime.month, curDateTime.day,
+ curDateTime.hour, curDateTime.minute), ChConfig.TYPE_Time_Format)
+
+ battlefieldState = 0
+ for openHour, openMinute, openDateTime, closeDateTime, notifyOpenTimeDict in battlefieldTimeList:
+
+ # 全服广播提示信息
+ if curDateTime in notifyOpenTimeDict:
+ notifyOpenMinute = notifyOpenTimeDict[curDateTime]
+ __DoBattlefieldOpenNotify(openHour, openMinute, notifyOpenMinute)
+
+ if openDateTime <= curDateTime < closeDateTime:
+ battlefieldState = openHour * 100 + openMinute
+
+ stateKey = ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_CrossBattlefield
+ gameWorld = GameWorld.GetGameWorld()
+ beforeState = gameWorld.GetDictByKey(stateKey)
+
+ if not isReload and beforeState == battlefieldState:
+ #已经是这个状态了
+ return
+
+ GameWorld.SendMapServerMsgEx(stateKey, battlefieldState) #通知Mapserver,设置字典
+ gameWorld.SetDict(stateKey, battlefieldState) #更新字典值
+ GameWorld.Log("跨服战场状态变更: beforeState=%s,battlefieldState=%s" % (beforeState, battlefieldState))
+
+ # 开启副本
+ if battlefieldState and beforeState != battlefieldState:
+ # 移除已经存在的副本线路
+ PyGameData.g_crossDynamicLineInfo.pop(ChConfig.Def_FBMapID_CrossBattlefield, None)
+
+ crossZoneName = GameWorld.GetCrossZoneName()
+ crossZoneList = IpyGameDataPY.GetIpyGameDataByCondition("CrossZonePK", {"CrossZoneName":crossZoneName}, True)
+ if not crossZoneList:
+ crossZoneList = []
+
+ hmNum = battlefieldState
+ openHour, openMinute = GetHMByNum(hmNum)
+ sysOpenHMList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldOpen", 1)
+
+ for zoneIpyData in crossZoneList:
+ zoneID = zoneIpyData.GetZoneID()
+
+ seasonState = gameWorld.GetDictByKey(ChConfig.Def_WorldKey_CrossPKZoneSeasonState % zoneID)
+ if seasonState != 1:
+ GameWorld.Log(" 跨服PK赛季未开启中,跨服战场不开启! zoneID=%s" % zoneID)
+ continue
+
+ # 系统局确保每个等级段都有一场
+ if [openHour, openMinute] in sysOpenHMList:
+ dynamicLineLVRangeDict = IpyGameDataPY.GetFuncEvalCfg("CrossDynamicLineMap", 4, {})
+ lvRangeInfoList = dynamicLineLVRangeDict.get(ChConfig.Def_FBMapID_CrossBattlefield, [])
+ GameWorld.Log(" 开启战场系统局,确保每个等级段都有一场: zoneID=%s,lvRangeInfoList=%s" % (zoneID, lvRangeInfoList))
+ if lvRangeInfoList:
+ funcLineIDList = range(len(lvRangeInfoList))
+ PlayerFB.OpenCrossDynamicLineBySys(zoneID, ChConfig.Def_FBMapID_CrossBattlefield, funcLineIDList, True)
+
+ # 有购买的场次默认只开一场
+ else:
+ buyHMInfo = PyGameData.g_crossBattlefieldBuyInfo.get(zoneID, {})
+ if hmNum in buyHMInfo and len(buyHMInfo[hmNum]) > 0:
+ GameWorld.Log(" 有召集的场次开启分区战场! zoneID=%s" % (zoneID))
+ funcLineIDList = [0]
+ PlayerFB.OpenCrossDynamicLineBySys(zoneID, ChConfig.Def_FBMapID_CrossBattlefield, funcLineIDList, True)
+ else:
+ GameWorld.Log(" 无召集的场次不开分区战场! zoneID=%s" % (zoneID))
+
+ # 同步子服务器
+ dataMsg = {"battlefieldState":battlefieldState}
+ CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_BattlefieldState, dataMsg)
+ return
+
+def __DoBattlefieldOpenNotify(openHour, openMinute, notifyOpenMinute):
+ ''' 执行跨服战场开启广播
+ 跨服PK赛季未开启状态下,跨服战场同步关闭,故也不广播
+ 还要限制开服天开启
+ '''
+
+ gameWorld = GameWorld.GetGameWorld()
+ sysOpenHMList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldOpen", 1)
+ if [openHour, openMinute] in sysOpenHMList:
+
+ crossZoneName = GameWorld.GetCrossZoneName()
+ crossZoneList = IpyGameDataPY.GetIpyGameDataByCondition("CrossZonePK", {"CrossZoneName":crossZoneName}, True)
+ if not crossZoneList:
+ return
+
+ for zoneIpyData in crossZoneList:
+ zoneID = zoneIpyData.GetZoneID()
+
+ seasonState = gameWorld.GetDictByKey(ChConfig.Def_WorldKey_CrossPKZoneSeasonState % zoneID)
+ if seasonState != 1:
+ GameWorld.DebugLog("跨服PK赛季未开启中,跨服战场系统开启广播不处理!")
+ continue
+
+ notifyKey = "CrossBattlefieldOpenSys"
+ paramList = [notifyOpenMinute]
+ country = 0
+ serverGroupIDList = []
+ crossNotifyList = []
+ crossNotifyList.append([ShareDefine.CrossNotify_World, [country, notifyKey, paramList]])
+ PlayerControl.CrossNotifyEx(serverGroupIDList, crossNotifyList)
+
+ return
+
+ curHMNum = GetHMNum(openHour, openMinute)
+
+ for zoneID, buyHMInfo in PyGameData.g_crossBattlefieldBuyInfo.items():
+
+ seasonState = gameWorld.GetDictByKey(ChConfig.Def_WorldKey_CrossPKZoneSeasonState % zoneID)
+ if seasonState != 1:
+ GameWorld.DebugLog("跨服PK赛季未开启中,跨服战场玩家开启广播不处理!")
+ continue
+
+ zoneIpyData = CrossRealmPlayer.GetCrossZoneIpyDataByZoneID(ChConfig.Def_FBMapID_CrossBattlefield, zoneID)
+ if zoneIpyData:
+ continue
+ serverGroupIDList = zoneIpyData.GetServerGroupIDList()
+
+ if curHMNum not in buyHMInfo:
+ continue
+
+ buyPlayerInfo = buyHMInfo[curHMNum]
+ if not buyPlayerInfo:
+ continue
+
+ matchTickSortList = sorted(buyPlayerInfo.values(), key=operator.attrgetter("buyTime"))
+ buyRec = matchTickSortList[0]
+
+ notifyKey = "CrossBattlefieldOpenPlayer"
+ paramList = [buyRec.playerName, notifyOpenMinute]
+ country = 0
+ crossNotifyList = []
+ crossNotifyList.append([ShareDefine.CrossNotify_World, [country, notifyKey, paramList]])
+ PlayerControl.CrossNotifyEx(serverGroupIDList, crossNotifyList)
+
+ return
+
+def GetCrossBattlefieldOpenTime(zoneID):
+ ## 获取跨服战场副本当前是否开放的时间点
+ # @return: None-当前未开放;
+ # @return: hour, minute - 当前开放中的时间时分,可进入
+
+ gameWorld = GameWorld.GetGameWorld()
+ hmNum = GetCrossBattlefieldState()
+ if not hmNum:
+ return
+
+ seasonState = gameWorld.GetDictByKey(ChConfig.Def_WorldKey_CrossPKZoneSeasonState % zoneID)
+ if seasonState != 1:
+ return
+
+ openHour, openMinute = GetHMByNum(hmNum)
+ sysOpenHMList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldOpen", 1)
+ isCallBattle = [openHour, openMinute] not in sysOpenHMList
+ if isCallBattle:
+ if zoneID not in PyGameData.g_crossBattlefieldBuyInfo:
+ GameWorld.DebugLog("该分区没有使用召集令! zoneID=%s" % zoneID)
+ return
+ buyHMInfo = PyGameData.g_crossBattlefieldBuyInfo[zoneID]
+ if hmNum not in buyHMInfo:
+ GameWorld.DebugLog("该时段还未使用召集令! zoneID=%s,hmNum=%s" % (zoneID, hmNum))
+ return
+
+ return isCallBattle, openHour, openMinute
+
+def GetCallPlayerCopymapObj(playerID, serverGroupID, mapID, funcLineID, zoneID, copyMapPlayerMax, includeOffline, tick):
+ ## 获取玩家召集令队伍对应的副本分线
+ ## @return tagCopyMapObj
+
+ hmNum = GetCrossBattlefieldState()
+ if not hmNum:
+ return
+
+ if mapID not in PyGameData.g_crossDynamicLineInfo:
+ PyGameData.g_crossDynamicLineInfo[mapID] = {}
+ zoneLineDict = PyGameData.g_crossDynamicLineInfo[mapID] # 跨服动态线路信息 {dataMapID:{(zoneID, funcLineID):[CrossFuncLineInfo, CrossFuncLineInfo, ...], ...}, ...}
+ zoneLineKey = (zoneID, funcLineID)
+ if zoneLineKey not in zoneLineDict:
+ zoneLineDict[zoneLineKey] = []
+ funcLineObjList = zoneLineDict[zoneLineKey]
+ if not funcLineObjList:
+ return
+
+ # 召集令场次,每个分区固定只有一场
+ for _, funcLineObj in enumerate(funcLineObjList, 1):
+ realMapID, copyMapID = funcLineObj.realMapID, funcLineObj.copyMapID
+ if not realMapID:
+ continue
+ key = (realMapID, copyMapID)
+ if key not in PyGameData.g_crossDynamicLineCopyMapInfo:
+ continue
+ copyMapObj = PyGameData.g_crossDynamicLineCopyMapInfo[key]
+
+ if copyMapObj.zoneID != zoneID:
+ continue
+
+ # 召集令成员不受人数限制
+ buyHMInfo = PyGameData.g_crossBattlefieldBuyInfo.get(zoneID, {})
+ if hmNum not in buyHMInfo:
+ continue
+ buyPlayerInfo = buyHMInfo[hmNum]
+ for buyRec in buyPlayerInfo.values():
+ if playerID in buyRec.callPlayerIDList:
+ GameWorld.DebugLog("召集令成员不受人数限制,可进入! playerID=%s" % playerID)
+ return copyMapObj
+
+ canEnter = copyMapObj.OnRequestEnterCrossCopyMap(playerID, tick, copyMapPlayerMax, includeOffline)
+ if canEnter:
+ return copyMapObj
+
+ return
+
+def ClientServerMsg_BattlefieldBuyOpen(serverGroupID, msgData):
+
+ if not GameWorld.IsCrossServer():
+ return
+
+ zoneIpyData = CrossRealmPK.GetCrossPKServerGroupZone(serverGroupID)
+ if not zoneIpyData:
+ return
+ zoneID = zoneIpyData.GetZoneID()
+
+ gameWorld = GameWorld.GetGameWorld()
+ seasonState = gameWorld.GetDictByKey(ChConfig.Def_WorldKey_CrossPKZoneSeasonState % zoneID)
+ if seasonState != 1:
+ GameWorld.Log("跨服PK赛季未开启中,跨服战场也不能开启,无法购买!")
+ return
+
+ playerID = msgData["playerID"] # 角色ID
+ playerName = msgData["playerName"] # 玩家名
+ job = msgData["playerJob"] # 职业
+ playerLV = msgData["playerLV"] # 职业
+ realmLV = msgData["realmLV"] # 境界
+ fightPower = msgData["fightPower"] # 战斗力
+ buyOpenCountWeek = msgData["buyOpenCountWeek"] # 本周已购买召集场次
+
+ openHour = msgData["openHour"]
+ openMinute = msgData["openMinute"]
+ faction = msgData["faction"]
+
+ hmNum = GetHMNum(openHour, openMinute)
+
+ if zoneID not in PyGameData.g_crossBattlefieldBuyInfo:
+ PyGameData.g_crossBattlefieldBuyInfo[zoneID] = {}
+ buyHMInfo = PyGameData.g_crossBattlefieldBuyInfo[zoneID]
+ if hmNum not in buyHMInfo:
+ buyHMInfo[hmNum] = {}
+ buyPlayerInfo = buyHMInfo[hmNum]
+
+ if playerID in buyPlayerInfo:
+ GameWorld.Log("玩家已经购买过该召集场次! zoneID=%s,openHour=%s,openMinute=%s" % (zoneID, openHour, openMinute), playerID)
+ return
+
+ curFactionCount, othFactionCount = 0, 0
+ for callPlayerID, buyRec in buyPlayerInfo.items():
+ if buyRec.factionID == faction:
+ curFactionCount += 1
+ else:
+ othFactionCount += 1
+
+ if playerID in buyRec.callPlayerIDList:
+ GameWorld.Log("玩家已经在该召集场次阵营里! zoneID=%s,openHour=%s,openMinute=%s,callPlayerID=%s,callPlayerIDList=%s"
+ % (zoneID, openHour, openMinute, callPlayerID, buyRec.callPlayerIDList), playerID)
+ return
+
+ if curFactionCount > othFactionCount:
+ GameWorld.Log("阵营平衡限制,不可再购买该跨服战场阵营! zoneID=%s,openHour=%s,openMinute=%s,faction=%s,curFactionCount(%s) > othFactionCount(%s)"
+ % (zoneID, openHour, openMinute, faction, curFactionCount, othFactionCount), playerID)
+ return
+
+ # ================ 可以购买,以下执行添加购买场次阵营逻辑 ================
+
+ # 更新缓存
+ curCache = PlayerViewCache.FindViewCache(playerID, True)
+ if curCache:
+ cacheDict = PlayerViewCache.GetCachePropDataDict(curCache)
+ cacheDict["Name"] = playerName
+ cacheDict["Job"] = job
+ cacheDict["LV"] = playerLV
+ cacheDict["RealmLV"] = realmLV
+ cacheDict["FightPower"] = fightPower
+
+ # 新增场次购买记录
+ buyTime = int(time.time())
+ buyRec = CrossBattlefieldBuy()
+ buyRec.buyTime = buyTime
+ buyRec.zoneID = zoneID
+ buyRec.hmNum = hmNum
+ buyRec.playerID = playerID
+ buyRec.factionID = faction
+ buyRec.callPlayerIDList = [playerID]
+ buyPlayerInfo[playerID] = buyRec
+
+ # 上榜
+ billboardCallCountLimit = IpyGameDataPY.GetFuncCfg("CrossBattlefieldBillboard", 2) # 周召集榜上榜至少次数
+ groupValue1, dataID, name1, name2 = zoneID, playerID, playerName, ""
+ type2, value1, value2 = job, realmLV, 0
+ cmpValue = buyOpenCountWeek + 1
+ if cmpValue >= billboardCallCountLimit:
+ CrossBillboard.UpdCrossBillboard(ShareDefine.Def_CBT_BattlefieldWCall, groupValue1, dataID, name1, name2, type2, value1, value2, cmpValue)
+
+ SyncMapServerCrossBattlefieldBuyInfo()
+
+ # 通知子服
+ serverGroupIDList = zoneIpyData.GetServerGroupIDList()
+ msgData.update({"opType":"BuyOpen", "buyTime":buyTime})
+ Send_CrossServerMsg_BattlefieldBuy(zoneID, serverGroupIDList, msgData)
+ return
+
+def ClientServerMsg_BattlefieldCallJoin(serverGroupID, msgData):
+ # "openHour":openHour, "openMinute":openMinute, "buyPlayerID":buyPlayerID, "tagPlayerID":tagPlayerID, "playerID":playerID
+
+ openHour = msgData["openHour"]
+ openMinute = msgData["openMinute"]
+ buyPlayerID = msgData["buyPlayerID"]
+ tagPlayerID = msgData["tagPlayerID"]
+ playerID = msgData["playerID"]
+
+ zoneIpyData = CrossRealmPK.GetCrossPKServerGroupZone(serverGroupID)
+ if not zoneIpyData:
+ return
+ zoneID = zoneIpyData.GetZoneID()
+
+ hmNum = GetHMNum(openHour, openMinute)
+ buyPlayerInfo = GetBuyPlayerInfo(zoneID, hmNum)
+ if buyPlayerID not in buyPlayerInfo:
+ GameWorld.ErrLog("跨服战场不存在该玩家的召集队伍! hmNum=%s,buyPlayerID=%s" % (hmNum, buyPlayerID), playerID)
+ return
+ buyRec = buyPlayerInfo[buyPlayerID]
+
+ callTeamMemMax = IpyGameDataPY.GetFuncCfg("CrossBattlefieldCall", 1)
+ if len(buyRec.callPlayerIDList) >= callTeamMemMax:
+ GameWorld.ErrLog("跨服战场召集人数已满! hmNum=%s,buyPlayerID=%s,callPlayerIDList=%s" % (hmNum, buyPlayerID, buyRec.callPlayerIDList), playerID)
+ return
+
+ if tagPlayerID not in buyRec.callPlayerIDList:
+ buyRec.callPlayerIDList.append(tagPlayerID)
+
+ SyncMapServerCrossBattlefieldBuyInfo()
+
+ serverGroupIDList = zoneIpyData.GetServerGroupIDList()
+ msgData.update({"opType":"CallJoin"})
+ Send_CrossServerMsg_BattlefieldBuy(zoneID, serverGroupIDList, msgData)
+ return
+
+def ClientServerMsg_BattlefieldCallKick(serverGroupID, msgData):
+ # "openHour":openHour, "openMinute":openMinute, "buyPlayerID":buyPlayerID, "tagPlayerID":tagPlayerID, "playerID":playerID
+
+ openHour = msgData["openHour"]
+ openMinute = msgData["openMinute"]
+ buyPlayerID = msgData["buyPlayerID"]
+ tagPlayerID = msgData["tagPlayerID"]
+ playerID = msgData["playerID"]
+
+ zoneIpyData = CrossRealmPK.GetCrossPKServerGroupZone(serverGroupID)
+ if not zoneIpyData:
+ return
+ zoneID = zoneIpyData.GetZoneID()
+
+ hmNum = GetHMNum(openHour, openMinute)
+ buyPlayerInfo = GetBuyPlayerInfo(zoneID, hmNum)
+ if buyPlayerID not in buyPlayerInfo:
+ GameWorld.ErrLog("跨服战场不存在该玩家的召集队伍! hmNum=%s,buyPlayerID=%s" % (hmNum, buyPlayerID), playerID)
+ return
+ buyRec = buyPlayerInfo[buyPlayerID]
+
+ if tagPlayerID not in buyRec.callPlayerIDList:
+ GameWorld.ErrLog("跨服战场召集队伍没有该玩家! hmNum=%s,buyPlayerID=%s,tagPlayerID=%s not in callPlayerIDList=%s"
+ % (hmNum, buyPlayerID, tagPlayerID, buyRec.callPlayerIDList), playerID)
+ return
+ buyRec.callPlayerIDList.remove(tagPlayerID)
+
+ SyncMapServerCrossBattlefieldBuyInfo()
+
+ serverGroupIDList = zoneIpyData.GetServerGroupIDList()
+ msgData.update({"opType":"CallKick"})
+ Send_CrossServerMsg_BattlefieldBuy(zoneID, serverGroupIDList, msgData)
+ return
+
+def MapServer_CrossBattlefieldOver(msgList):
+ ## 跨服战场地图结算
+ overTime = int(time.time())
+ hmNum = GetCrossBattlefieldState()
+ fbPropertyID, zoneID, funcLineID, winnerFaction, superItemInfo, superItemPlayerID, superItemPlayerName, scoreKingID, scoreKingName, battlePlayerList = msgList
+ GameWorld.Log("跨服战场地图同步结果: hmNum=%s,zoneID=%s,funcLineID=%s,winnerFaction=%s,superItemInfo=%s,superItemPlayerID=%s,scoreKingID=%s,battlePlayerCount=%s"
+ % (hmNum, zoneID, funcLineID, winnerFaction, superItemInfo, superItemPlayerID, scoreKingID, len(battlePlayerList)), fbPropertyID)
+
+ winnerOrderAwardDict = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldAward", 2, {}) # 胜利方名次对应奖励物品列表 {"名次":[[物品ID,个数,是否拍品], ...], ...} , 名次配置支持段配置
+ loserOrderAwardDict = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldAward", 3, {}) # 失败方名次对应奖励物品列表 {"名次":[[物品ID,个数,是否拍品], ...], ...} , 名次配置支持段配置
+ winnerAwardList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldAward", 4) # 胜利方固定结算奖励列表 [[物品ID,个数,是否拍品], ...]
+ loserAwardList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldAward", 5) # 失败方固定结算奖励列表 [[物品ID,个数,是否拍品], ...]
+
+ winnerOrderIntAwardDict = {int(k):v for k, v in winnerOrderAwardDict.items()}
+ loserOrderIntAwardDict = {int(k):v for k, v in loserOrderAwardDict.items()}
+
+ billboardEnterCountLimit = IpyGameDataPY.GetFuncCfg("CrossBattlefieldBillboard", 1) # 周参与榜上榜至少次数
+
+ syncPlayerDataInfo = {}
+ winnerPlayerIDList, loserPlayerIDList = [], []
+ for playerInfo in battlePlayerList:
+ faction, rank, playerID, job, realmLV, name, score, highScoreToday, highScoreWeekTotal, enterCountWeek, isCallEnter = playerInfo
+
+ isWinner = 0
+ paramList = [rank]
+ if faction == winnerFaction:
+ isWinner = 1
+ winnerPlayerIDList.append(playerID)
+ orderAwardMailKey = "CrossBattlefieldOrderWin"
+ orderAwardItemList = GameWorld.GetOrderValueByDict(winnerOrderIntAwardDict, rank)
+ GameWorld.Log(" 获胜阵营玩家: faction=%s,rank=%s,playerID=%s" % (faction, rank, playerID), fbPropertyID)
+ else:
+ loserPlayerIDList.append(playerID)
+ orderAwardMailKey = "CrossBattlefieldOrderLose"
+ orderAwardItemList = GameWorld.GetOrderValueByDict(loserOrderIntAwardDict, rank)
+ GameWorld.Log(" 失败阵营玩家: faction=%s,rank=%s,playerID=%s" % (faction, rank, playerID), fbPropertyID)
+
+ # 排名奖励邮件
+ PlayerCompensation.SendMailByKey(orderAwardMailKey, [playerID], orderAwardItemList, paramList, crossMail=True)
+
+ # 更新周参与榜单
+ groupValue1, dataID, name1, name2 = zoneID, playerID, name, ""
+ type2, value1, value2 = job, realmLV, 0
+ enterCountWeek += 1
+ cmpValue = enterCountWeek
+ if cmpValue >= billboardEnterCountLimit:
+ CrossBillboard.UpdCrossBillboard(ShareDefine.Def_CBT_BattlefieldWJoin, groupValue1, dataID, name1, name2, type2, value1, value2, cmpValue)
+
+ # 更新周高分榜单
+ if score > highScoreToday:
+ highScoreWeekTotal += (score - highScoreToday)
+ highScoreToday = score
+ cmpValue = highScoreWeekTotal
+ CrossBillboard.UpdCrossBillboard(ShareDefine.Def_CBT_BattlefieldWScore, groupValue1, dataID, name1, name2, type2, value1, value2, cmpValue)
+
+ GameWorld.Log(" 战场阵营玩家: faction=%s,isWinner=%s,rank=%s,playerID=%s,score=%s,highScoreToday=%s,highScoreWeekTotal=%s,enterCountWeek=%s,isCallEnter=%s"
+ % (faction, isWinner, rank, playerID, score, highScoreToday, highScoreWeekTotal, enterCountWeek, isCallEnter), fbPropertyID)
+
+ syncPlayerDataInfo[playerID] = [highScoreToday, highScoreWeekTotal, enterCountWeek, isCallEnter]
+
+ # 参与奖励邮件
+ if winnerPlayerIDList:
+ PlayerCompensation.SendMailByKey("CrossBattlefieldJoinWin", winnerPlayerIDList, winnerAwardList, crossMail=True)
+ if loserPlayerIDList:
+ PlayerCompensation.SendMailByKey("CrossBattlefieldJoinLose", loserPlayerIDList, loserAwardList, crossMail=True)
+
+ # 大奖获得者邮件
+ superItemID, superItemCount = 0, 0
+ if superItemPlayerID and superItemInfo and len(superItemInfo) == 3:
+ superItemID, superItemCount = superItemInfo[0], superItemInfo[1]
+ PlayerCompensation.SendMailByKey("CrossBattlefieldSuperAward", [superItemPlayerID], [superItemInfo], crossMail=True)
+
+ crossZoneName = GameWorld.GetCrossZoneName()
+ zoneIpyData = IpyGameDataPY.GetIpyGameData("CrossZonePK", crossZoneName, zoneID)
+ serverGroupIDList = zoneIpyData.GetServerGroupIDList() if zoneIpyData else []
+
+ # 通知子服更新参与玩家数据
+ sendMsg = {"zoneID":zoneID, "overTime":overTime, "syncPlayerDataInfo":syncPlayerDataInfo}
+ CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_BattlefieldOver, sendMsg, serverGroupIDList)
+
+ # 结算广播
+ nextBattleTimeStr = ""
+ openHour, openMinute = GetHMByNum(hmNum)
+ sysOpenHMList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldOpen", 1)
+ callOpenHMList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldOpen", 2)
+ allOpenHMList = sysOpenHMList + callOpenHMList
+ allOpenHMList.sort()
+ if [openHour, openMinute] in allOpenHMList:
+ nextOpenIndex = allOpenHMList.index([openHour, openMinute]) + 1
+ nextOpenHour, nextOpenMinute = allOpenHMList[nextOpenIndex] if len(allOpenHMList) > nextOpenIndex else allOpenHMList[0]
+ nextBattleTimeStr = "%02d:%02d" % (nextOpenHour, nextOpenMinute)
+
+ # 本分区全服:XX阵营胜利,xxx为本场积分王,xxx获得了古神大奖XXX,下个场次预计将在XX点开放。
+ if battlePlayerList:
+ msgParamList = [winnerFaction, scoreKingName, superItemPlayerName, superItemID, superItemCount, nextBattleTimeStr]
+ PlayerControl.WorldNotifyCross(serverGroupIDList, 0, "CrossBattlefieldOver", msgParamList)
+ return
+
+####################################################################################################
+
+def CrossServerMsg_BattlefieldState(msgData):
+ battlefieldState = msgData["battlefieldState"]
+
+ gameWorld = GameWorld.GetGameWorld()
+
+ seasonState = gameWorld.GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKSeasonState)
+ beforeState = GetCrossBattlefieldState()
+ beforeState = beforeState if (beforeState and seasonState == 1) else 0
+
+ realBattlefieldState = battlefieldState if (battlefieldState and seasonState == 1) else 0
+
+ GameWorld.DebugLog("收到跨服服务器同步的战场状态: battlefieldState=%s,seasonState=%s,beforeState=%s,realBattlefieldState=%s"
+ % (battlefieldState, seasonState, beforeState, realBattlefieldState))
+
+ key = ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_CrossBattlefield
+ gameWorld.SetDict(key, realBattlefieldState)
+ GameWorld.SendMapServerMsgEx(key, realBattlefieldState)
+ return
+
+def CrossServerMsg_BattlefieldOver(msgData):
+ GameWorld.DebugLog("收到跨服服务器同步的战场结算信息: %s" % msgData)
+
+ zoneID = msgData["zoneID"]
+ overTime = msgData["overTime"]
+ syncPlayerDataInfo = msgData["syncPlayerDataInfo"]
+
+ gameWorld = GameWorld.GetGameWorld()
+ pkZoneID = gameWorld.GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKZoneID)
+ if zoneID != pkZoneID:
+ GameWorld.ErrLog("非本服所属分区的跨服战场购买信息! pkZoneID(%s) != zoneID(%s) %s" % (pkZoneID, zoneID, str(msgData)))
+ return
+
+ for playerID, playerData in syncPlayerDataInfo.items():
+ highScoreToday, highScoreWeekTotal, enterCountWeek, isCallEnter = playerData
+ if PlayerControl.GetDBPlayerAccIDByID(playerID):
+ msgInfo = ["BattlefieldOver", [overTime, highScoreToday, highScoreWeekTotal, enterCountWeek, isCallEnter]]
+ CrossRealmPlayer.MapServer_QueryCrossPlayerResult(playerID, "CrossBattlefield", msgInfo)
+
+ return
+
+def CrossServerMsg_BattlefieldBuy(msgData):
+ GameWorld.DebugLog("收到跨服服务器同步的战场购买信息: %s" % msgData)
+
+ zoneID = msgData["zoneID"]
+ syncBuyHMInfo = msgData["syncBuyHMInfo"]
+ opData = msgData.get("opData", {})
+
+ gameWorld = GameWorld.GetGameWorld()
+ pkZoneID = gameWorld.GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossPKZoneID)
+ if zoneID != pkZoneID:
+ GameWorld.ErrLog("非本服所属分区的跨服战场购买信息! pkZoneID(%s) != zoneID(%s) %s" % (pkZoneID, zoneID, str(msgData)))
+ return
+
+ if not syncBuyHMInfo:
+ PyGameData.g_crossBattlefieldBuyInfo.pop(zoneID, None)
+
+ # 更新数据
+ for hmNum, syncBuyPlayerInfo in syncBuyHMInfo.items():
+ buyPlayerInfo = GetBuyPlayerInfo(zoneID, hmNum)
+ for buyPlayerID, attrDict in syncBuyPlayerInfo.items():
+ buyRec = CrossBattlefieldBuy()
+ buyRec.SetAttr(attrDict)
+ buyPlayerInfo[buyPlayerID] = buyRec
+
+ SyncMapServerCrossBattlefieldBuyInfo()
+
+ if not opData or "opType" not in opData:
+ SyncCrossBattlefieldBuyInfo(None, zoneID)
+ return
+ opType = opData["opType"]
+ openHour = opData["openHour"]
+ openMinute = opData["openMinute"]
+ hmNum = GetHMNum(openHour, openMinute)
+ SyncCrossBattlefieldBuyInfo(None, zoneID, hmNum)
+
+ if opType == "BuyOpen":
+ playerID = opData["playerID"]
+ playerName = opData["playerName"]
+ PlayerControl.WorldNotify(0, "CrossBattlefieldBuyOpen", [playerName, "%d:%02d" % (openHour, openMinute)])
+
+ if PlayerControl.GetDBPlayerAccIDByID(playerID):
+ faction = opData["faction"]
+ buyTime = opData["buyTime"]
+ todayBuyOpenCount = opData["todayBuyOpenCount"]
+ msgInfo = ["BattlefieldBuy", [openHour, openMinute, faction, todayBuyOpenCount, buyTime]]
+ CrossRealmPlayer.MapServer_QueryCrossPlayerResult(playerID, "CrossBattlefield", msgInfo)
+
+ elif opType == "CallJoin":
+ pass
+
+ elif opType == "CallKick":
+ pass
+
+ return
+
+def SyncCrossBattlefieldBuyInfo(curPlayer, zoneID, hmNum=None):
+ ## 通知战场召集场次购买信息
+
+ buyHMInfo = PyGameData.g_crossBattlefieldBuyInfo.get(zoneID, {})
+ hmNumList = [hmNum] if hmNum != None else buyHMInfo.keys()
+
+ clientPack = ChPyNetSendPack.tagGCCrossBattlefieldBuyInfo()
+ clientPack.HMBuyList = []
+ for hmNum in hmNumList:
+ h, m = GetHMByNum(hmNum)
+ hmPack = ChPyNetSendPack.tagGCCrossBattlefieldBuyHM()
+ hmPack.Hour = h
+ hmPack.Minute = m
+ hmPack.BuyPlayerList = []
+
+ buyPlayerInfo = GetBuyPlayerInfo(zoneID, hmNum)
+ for buyPlayerID, buyRec in buyPlayerInfo.items():
+ buyPlayerPack = ChPyNetSendPack.tagGCCrossBattlefieldBuyPlayer()
+ buyPlayerPack.BuyPlayerID = buyPlayerID
+ buyPlayerPack.Faction = buyRec.factionID
+ buyPlayerPack.FactionPlayerList = []
+
+ for callPlayerID in buyRec.callPlayerIDList:
+ playerPack = ChPyNetSendPack.tagGCCrossBattlefieldPlayer()
+ playerPack.PlayerID = callPlayerID
+ if callPlayerID in buyRec.callPlayerDict:
+ factionPlayerInfo = buyRec.callPlayerDict[callPlayerID]
+ fightPower = factionPlayerInfo["FightPower"]
+ playerPack.PlayerName = factionPlayerInfo["Name"]
+ playerPack.Job = factionPlayerInfo["Job"]
+ playerPack.LV = factionPlayerInfo["LV"]
+ playerPack.RealmLV = factionPlayerInfo["RealmLV"]
+ playerPack.FightPower = fightPower % ShareDefine.Def_PerPointValue
+ playerPack.FightPowerEx = fightPower / ShareDefine.Def_PerPointValue
+ buyPlayerPack.FactionPlayerList.append(playerPack)
+ buyPlayerPack.FactionPlayerCount = len(buyPlayerPack.FactionPlayerList)
+
+ hmPack.BuyPlayerList.append(buyPlayerPack)
+ hmPack.BuyPlayerCount = len(hmPack.BuyPlayerList)
+
+ clientPack.HMBuyList.append(hmPack)
+ clientPack.HMCount = len(clientPack.HMBuyList)
+
+ if curPlayer:
+ NetPackCommon.SendFakePack(curPlayer, clientPack)
+ else:
+ # 广播全服玩家
+ playerManager = GameWorld.GetPlayerManager()
+ for i in xrange(playerManager.GetPlayerCount()):
+ curPlayer = playerManager.GetPlayerByIndex(i)
+ if curPlayer == None or not curPlayer.GetInitOK() or PlayerControl.GetIsTJG(curPlayer):
+ continue
+ NetPackCommon.SendFakePack(curPlayer, clientPack)
+ return
+
+#// C0 07 跨服战场加入召集场次 #tagCGCrossBattlefieldJoinByCall
+#
+#struct tagCGCrossBattlefieldJoinByCall
+#{
+# tagHead Head;
+# BYTE Hour; //战场开启时
+# BYTE Minute; //战场开启分
+# DWORD BuyPlayerID; //加入目标玩家的召集队伍,即购买召集场的玩家ID
+#};
+def OnCrossBattlefieldJoinByCall(index, clientData, tick):
+ if GameWorld.IsCrossServer():
+ return
+
+ curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+ playerID = curPlayer.GetPlayerID()
+ openHour = clientData.Hour
+ openMinute = clientData.Minute
+ buyPlayerID = clientData.BuyPlayerID
+ tagPlayerID = playerID
+
+ closeBuyMinute = IpyGameDataPY.GetFuncCfg("CrossBattlefieldOpen", 4) # 开启前X分钟后关闭购买
+ crossServerTimeStr = GameWorld.GetCrossServerTimeStr()
+ crossServerDateTime = GameWorld.ChangeStrToDatetime(crossServerTimeStr)
+
+ startTimeStr = "%s-%s-%s %s:%s:00" % (crossServerDateTime.year, crossServerDateTime.month, crossServerDateTime.day, openHour, openMinute)
+ startDateTime = GameWorld.ChangeStrToDatetime(startTimeStr)
+ endBuyDateTime = startDateTime + datetime.timedelta(minutes=-closeBuyMinute)
+ if crossServerDateTime >= endBuyDateTime:
+ GameWorld.Log("该时间点战场已关闭召集,不能再召集加入! openHour=%s,openMinute=%s,crossServerDateTime(%s) >= endBuyDateTime(%s)"
+ % (openHour, openMinute, crossServerDateTime, endBuyDateTime), playerID)
+ return
+
+ serverGroupID = GameWorld.GetServerGroupID()
+ zoneIpyData = CrossRealmPK.GetCrossPKServerGroupZone(serverGroupID)
+ if not zoneIpyData:
+ return
+ zoneID = zoneIpyData.GetZoneID()
+
+ hmNum = GetHMNum(openHour, openMinute)
+ buyPlayerInfo = GetBuyPlayerInfo(zoneID, hmNum)
+ if buyPlayerID not in buyPlayerInfo:
+ GameWorld.ErrLog("不存在该玩家的跨服战场召集队伍! hmNum=%s,buyPlayerID=%s" % (hmNum, buyPlayerID), playerID)
+ return
+ buyRec = buyPlayerInfo[buyPlayerID]
+
+ callTeamMemMax = IpyGameDataPY.GetFuncCfg("CrossBattlefieldCall", 1)
+ if len(buyRec.callPlayerIDList) >= callTeamMemMax:
+ GameWorld.DebugLog("召集人数已满! hmNum=%s,buyPlayerID=%s,callPlayerIDList=%s" % (hmNum, buyPlayerID, buyRec.callPlayerIDList), playerID)
+ return
+
+ # 请求查询跨服服务器
+ dataMsg = {"openHour":openHour, "openMinute":openMinute, "buyPlayerID":buyPlayerID, "tagPlayerID":tagPlayerID, "playerID":playerID}
+ CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_BattlefieldCallJoin, dataMsg)
+ return
+
+
+#// C0 08 跨服战场召集场次踢人 #tagCGCrossBattlefieldCallKick
+#
+#struct tagCGCrossBattlefieldCallKick
+#{
+# tagHead Head;
+# BYTE Hour; //战场开启时
+# BYTE Minute; //战场开启分
+# DWORD TagPlayerID; //目标玩家ID,即要被踢出去的玩家ID
+#};
+def OnCrossBattlefieldCallKick(index, clientData, tick):
+ if GameWorld.IsCrossServer():
+ return
+
+ curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+ playerID = curPlayer.GetPlayerID()
+ openHour = clientData.Hour
+ openMinute = clientData.Minute
+ tagPlayerID = clientData.TagPlayerID
+ buyPlayerID = playerID
+
+ if buyPlayerID == tagPlayerID:
+ return
+
+ closeBuyMinute = IpyGameDataPY.GetFuncCfg("CrossBattlefieldOpen", 4) # 开启前X分钟后关闭购买
+ crossServerTimeStr = GameWorld.GetCrossServerTimeStr()
+ crossServerDateTime = GameWorld.ChangeStrToDatetime(crossServerTimeStr)
+
+ startTimeStr = "%s-%s-%s %s:%s:00" % (crossServerDateTime.year, crossServerDateTime.month, crossServerDateTime.day, openHour, openMinute)
+ startDateTime = GameWorld.ChangeStrToDatetime(startTimeStr)
+ endBuyDateTime = startDateTime + datetime.timedelta(minutes= -closeBuyMinute)
+ if crossServerDateTime >= endBuyDateTime:
+ GameWorld.Log("该时间点战场已关闭召集,不能再召集踢人! openHour=%s,openMinute=%s,crossServerDateTime(%s) >= endBuyDateTime(%s)"
+ % (openHour, openMinute, crossServerDateTime, endBuyDateTime), playerID)
+ return
+
+ serverGroupID = GameWorld.GetServerGroupID()
+ zoneIpyData = CrossRealmPK.GetCrossPKServerGroupZone(serverGroupID)
+ if not zoneIpyData:
+ return
+ zoneID = zoneIpyData.GetZoneID()
+
+ hmNum = GetHMNum(openHour, openMinute)
+ buyPlayerInfo = GetBuyPlayerInfo(zoneID, hmNum)
+ if buyPlayerID not in buyPlayerInfo:
+ GameWorld.ErrLog("不存在该玩家的跨服战场召集队伍! hmNum=%s,buyPlayerID=%s" % (hmNum, buyPlayerID), playerID)
+ return
+ buyRec = buyPlayerInfo[buyPlayerID]
+
+ if tagPlayerID not in buyRec.callPlayerIDList:
+ GameWorld.DebugLog("该召集队伍没有该玩家! hmNum=%s,buyPlayerID=%s,tagPlayerID=%s not in callPlayerIDList=%s"
+ % (hmNum, buyPlayerID, tagPlayerID, buyRec.callPlayerIDList), playerID)
+ return
+
+ # 请求查询跨服服务器
+ dataMsg = {"openHour":openHour, "openMinute":openMinute, "buyPlayerID":buyPlayerID, "tagPlayerID":tagPlayerID, "playerID":playerID}
+ CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_BattlefieldCallKick, dataMsg)
+ return
+
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBillboard.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBillboard.py
index e76c9ef..9d1c297 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBillboard.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossBillboard.py
@@ -282,10 +282,14 @@
SyncCrossBillboardToClientServer(billboardType, groupValue1, groupValue2, [serverGroupID], queryData)
return
-def SyncCrossBillboardToClientServer(billboardType, groupValue1, groupValue2, serverGroupIDList=[], queryData={}):
+def SyncCrossBillboardToClientServer(billboardType, groupValue1, groupValue2, serverGroupIDList=None, queryData=None):
## 同步跨服榜单到子服
if not GameWorld.IsCrossServer():
return
+ if serverGroupIDList == None:
+ serverGroupIDList = []
+ if queryData == None:
+ queryData = {}
billboardMgr = PyDataManager.GetCrossBillboardManager()
billboardObj = billboardMgr.GetCrossBillboard(billboardType, groupValue1, groupValue2)
crossServerDataVer = billboardObj.GetCrossServerDataVer()
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py
index ae35d95..dd90ae3 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py
@@ -23,6 +23,7 @@
import CrossRealmPlayer
import PlayerCompensation
import CrossActionControl
+import CrossBattlefield
import CrossBillboard
import GameWorldBoss
import CrossRealmPK
@@ -120,6 +121,15 @@
elif msgType == ShareDefine.ClientServerMsg_AddBuff:
MapServer_CrossAddBuff(msgData)
+ elif msgType == ShareDefine.ClientServerMsg_BattlefieldBuyOpen:
+ CrossBattlefield.ClientServerMsg_BattlefieldBuyOpen(serverGroupID, msgData)
+
+ elif msgType == ShareDefine.ClientServerMsg_BattlefieldCallJoin:
+ CrossBattlefield.ClientServerMsg_BattlefieldCallJoin(serverGroupID, msgData)
+
+ elif msgType == ShareDefine.ClientServerMsg_BattlefieldCallKick:
+ CrossBattlefield.ClientServerMsg_BattlefieldCallKick(serverGroupID, msgData)
+
# 需要发送到地图服务器处理的
elif msgType in [ShareDefine.ClientServerMsg_Reborn, ShareDefine.ClientServerMsg_CollectNPC]:
MapServer_CrossServerReceiveMsg(msgType, msgData, serverGroupID)
@@ -149,6 +159,7 @@
'''
CrossRealmPlayer.Sync_CrossCommInitDataToClientServer(serverGroupID)
CrossRealmPK.Sync_CrossPKInitDataToClientServer(tick, serverGroupID)
+ CrossBattlefield.Sync_CrossBattlefieldDataToClientServer(serverGroupID)
CrossBoss.Sync_CrossBossInitDataToClientServer(serverGroupID)
CrossActionControl.Sync_CrossActInfoToClientServer(serverGroupID)
CrossLuckyCloudBuy.Sync_LuckyCloudBuyDataToClientServer(tick, serverGroupID)
@@ -195,7 +206,7 @@
return
## ================================================================================================
-def SendMsgToClientServer(msgType, dataMsg, serverGroupIDList=[]):
+def SendMsgToClientServer(msgType, dataMsg, serverGroupIDList=None):
''' 广播信息到子服务器上
@param serverGroupIDList: 发送指定的服务器组ID列表,内部已经针对列表中组ID去重,
所以外部逻辑可直接添加,不用考虑组ID重复问题,没有指定服务器组ID时,默认广播所有子服
@@ -204,7 +215,9 @@
return
if not dataMsg:
return
-
+ if serverGroupIDList == None:
+ serverGroupIDList = []
+
srcMsg = {"MsgType":msgType, "Data":dataMsg, "CrossServerTime":GameWorld.GetCurrentDataTimeStr()}
sendMsg = cPickle.dumps(srcMsg, 2)
if not GameWorld.GetGameWorld().GetDictByKey(ChConfig.Def_WorldKey_GameWorldInitOK):
@@ -289,6 +302,15 @@
elif msgType == ShareDefine.CrossServerMsg_LuckyCloudBuyNum:
CrossLuckyCloudBuy.CrossServerMsg_LuckyCloudBuyNum(msgData)
+ elif msgType == ShareDefine.CrossServerMsg_BattlefieldState:
+ CrossBattlefield.CrossServerMsg_BattlefieldState(msgData)
+
+ elif msgType == ShareDefine.CrossServerMsg_BattlefieldBuy:
+ CrossBattlefield.CrossServerMsg_BattlefieldBuy(msgData)
+
+ elif msgType == ShareDefine.CrossServerMsg_BattlefieldOver:
+ CrossBattlefield.CrossServerMsg_BattlefieldOver(msgData)
+
elif msgType == ShareDefine.CrossServerMsg_SyncBillboard:
CrossBillboard.CrossServerMsg_SyncBillboard(msgData, tick)
@@ -342,7 +364,10 @@
tagPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
if tagPlayer:
GameWorld.DebugAnswer(tagPlayer, "跨服服务器时间: %s" % GameWorld.GetCrossServerTimeStr())
-
+
+ elif msgType == ShareDefine.CrossServerMsg_DebugAnswer:
+ GameWorld.CrossServerMsg_DebugAnswer(msgData)
+
else:
GameWorld.ErrLog("没有该信息类型逻辑处理!")
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldActionControl.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldActionControl.py
index 7ed6e28..bc415ec 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldActionControl.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldActionControl.py
@@ -975,6 +975,10 @@
dailyIpyData = ipyDataMgr.GetDailyActionByIndex(i)
dailyID = dailyIpyData.GetDailyID()
+ if dailyID in [ShareDefine.DailyActionID_CrossBattlefield]:
+ GameWorld.Log(" 不需要处理的日常活动! dailyID=%s" % dailyID)
+ continue
+
# 是当天开服天定制活动的不处理常规活动
if dailyID in customDailyIDList:
GameWorld.Log(" 常规活动ID配置是今天的定制活动ID,不处理!: dailyID=%s" % dailyID)
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/CrossRealmPlayer.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/CrossRealmPlayer.py
index f700782..76ded9f 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/CrossRealmPlayer.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/CrossRealmPlayer.py
@@ -428,6 +428,40 @@
PyGameData.g_crossSetPlayerAttr = {}
return
+def OnPlayerLogin(curPlayer):
+ if not IsCrossServerOpen():
+ return
+
+ LoginDoUnNotifyCrossMsg(curPlayer)
+ return
+
+def MapServer_QueryCrossPlayerResult(playerID, callName, msgInfo):
+ ## 同步地图跨服玩家处理信息,玩家可能不在线,缓存后等玩家上线处理,暂不考虑存档问题,服务器维护后未处理的命令将失效
+
+ curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
+ if curPlayer:
+ msgInfo = str(msgInfo)
+ curPlayer.MapServer_QueryPlayerResult(0, 0, callName, msgInfo, len(msgInfo))
+ else:
+ # 缓存起来,等上线后处理
+ if playerID not in PyGameData.g_unNotifyPlayerCrossMsgDict:
+ PyGameData.g_unNotifyPlayerCrossMsgDict[playerID] = []
+ msgList = PyGameData.g_unNotifyPlayerCrossMsgDict[playerID]
+ msgList.append([callName, msgInfo])
+ GameWorld.Log("玩家不在线,添加未通知的跨服命令: %s, msgInfo=%s" % (callName, msgInfo), playerID)
+
+ return
+
+def LoginDoUnNotifyCrossMsg(curPlayer):
+ playerID = curPlayer.GetPlayerID()
+ msgList = PyGameData.g_unNotifyPlayerCrossMsgDict.pop(playerID, [])
+ if not msgList:
+ return
+ for callName, msgInfo in msgList:
+ GameWorld.Log("上线处理未通知的跨服命令: %s, msgInfo=%s" % (callName, msgInfo), playerID)
+ msgInfo = str(msgInfo)
+ curPlayer.MapServer_QueryPlayerResult(0, 0, callName, msgInfo, len(msgInfo))
+ return
\ No newline at end of file
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerCompensation.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerCompensation.py
index 0d7d64e..ae36d67 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerCompensation.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerCompensation.py
@@ -309,7 +309,7 @@
def SendPersonalItemMailBatch(batchMailInfoList):
## 批量发送邮件
- mailTypeKey, batchPlayerIDList, batchAddItemList, batchParamList, batchGold, batchGoldPaper, batchSilver, batchDetail, moneySource = batchMailInfoList
+ mailTypeKey, batchPlayerIDList, batchAddItemList, batchParamList, batchGold, batchGoldPaper, batchSilver, batchDetail, moneySource, crossMail = batchMailInfoList
lenPlayerID = len(batchPlayerIDList)
lenItem = len(batchAddItemList)
@@ -334,7 +334,7 @@
silver = batchSilver[i] if lenSilver == lenPlayerID else 0
detail = batchDetail[i] if lenDetail == lenPlayerID else ""
content = "<MailTemplate>%s</MailTemplate>%s" % (mailTypeKey, str(paramList))
- SendPersonalItemMail(title, content, limitTime, playerIDList, addItemList, gold, goldPaper, silver, detail=detail, moneySource=moneySource)
+ SendPersonalItemMail(title, content, limitTime, playerIDList, addItemList, gold, goldPaper, silver, detail=detail, moneySource=moneySource, crossMail=crossMail)
return
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerEventCounter.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerEventCounter.py
index 24c18df..c03779b 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerEventCounter.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerEventCounter.py
@@ -32,6 +32,7 @@
import NetPackCommon
import PlayerDuJie
import PlayerCharm
+import CrossBattlefield
#---------------------------------------------------------------------
#---------------------------------------------------------------------
@@ -87,6 +88,8 @@
PlayerFairyDomain.OnDayEx()
#竞技场
GameWorldArena.OnDayEx()
+ #跨服战场
+ CrossBattlefield.DoOnDayEx()
playerManager = GameWorld.GetPlayerManager()
for i in xrange(playerManager.GetPlayerCount()):
curPlayer = playerManager.GetPlayerByIndex(i)
@@ -126,6 +129,8 @@
# 竞技场
GameWorldArena.OnWeekEx()
+ # 跨服战场
+ CrossBattlefield.DoOnWeekEx()
playerManager = GameWorld.GetPlayerManager()
for i in xrange(playerManager.GetPlayerCount()):
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py
index a8d5e9e..48853d9 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerFB.py
@@ -31,19 +31,26 @@
import GameWorld
import ChConfig
import IPY_PlayerDefine
+import CrossBattlefield
import CrossRealmPlayer
import CrossRealmMsg
import ShareDefine
import CrossBoss
+import time
+DynamicShuntType_No = 0 # 不分流
+DynamicShuntType_Fill = 1 # 填满式分流,按存在的线路人数多的优先填充,都满后开启新线路
+DynamicShuntType_Equally = 2 # 均摊式分流,按存在的线路人数少的优先填充,都满后开启新线路
#---------------------------------------------------------------------
## 跨服地图动态分配的功能线路,如果有人数上限的,则同分区同地图玩法的可能同时存在多个相同功能线路的数据
+## {dataMapID:{(zoneID, funcLineID):[CrossFuncLineInfo, CrossFuncLineInfo, ...], ...}, ...}
class CrossFuncLineInfo():
def __init__(self):
self.realMapID = 0
self.copyMapID = 0
+ self.newFuncLineNum = 0
self.funcLineDataCache = None # 功能线路自定义缓存数据
return
@@ -52,37 +59,48 @@
self.copyMapID = 0
return
-## 跨服地图动态分配的虚拟线路信息
+## 跨服地图动态分配的虚拟线路信息 {(mapID, copyMapID):CrossCopyMapInfo, ...}
class CrossCopyMapInfo():
def __init__(self, zoneID, funcLineID):
self.zoneID = zoneID
self.funcLineID = funcLineID
+ self.newFuncLineNum = 0
+ self.realMapID = 0
+ self.copyMapID = 0
self.openState = IPY_PlayerDefine.fbosClosed
self.fbPlayerDict = {} # 副本中的玩家信息 {playerID:serverGroupID, ...}
self.waitPlayerDict = {} # 等待进入的玩家信息 {playerID:[serverGroupID, tick], ...}
self.offlinePlayerDict = {} # 掉线的玩家信息,非主动退出的 {playerID:serverGroupID, ...}
+ self.enterPlayerIDList = [] # 有进入过此分线的玩家ID列表,不会清除 [playerID, ...]
return
- def OnRequestEnterCrossCopyMap(self, playerID, serverGroupID, tick, copyMapPlayerMax):
- # 已经在请求队列里,可进入
- if playerID in self.waitPlayerDict or not copyMapPlayerMax:
- self.waitPlayerDict[playerID] = [serverGroupID, tick]
- return True
+ def GetCopyMapPlayerCount(self, includeOffline, tick):
+ ## 获取该分线玩家数
+ # @param includeOffline: 是否包含离线玩家
# 移除请求进入超时的玩家
for waitPlayerID, playerInfo in self.waitPlayerDict.items():
- serverGroupID, requestTick = playerInfo
+ _, requestTick = playerInfo
if tick - requestTick > 60000: # 请求进入时间保留1分钟
self.waitPlayerDict.pop(waitPlayerID)
# 判断是否超过人数上限
fbPlayerCount, waitPlayerCount = len(self.fbPlayerDict), len(self.waitPlayerDict)
- if fbPlayerCount + waitPlayerCount >= copyMapPlayerMax:
- return False
+ totalPlayerCount = fbPlayerCount + waitPlayerCount
+ if includeOffline:
+ totalPlayerCount += len(self.offlinePlayerDict)
+
+ return totalPlayerCount
+
+ def IsMustCopyMapPlayer(self, playerID):
+ ## 是否必定在此分线的玩家, 在请求队列里 或 曾经进入到该分线的,都强制认为属于该分线的玩家
+ return playerID in self.waitPlayerDict or playerID in self.enterPlayerIDList
- self.waitPlayerDict[playerID] = [serverGroupID, tick]
- return True
+ def OnRequestEnterCrossCopyMap(self, playerID, tick, copyMapPlayerMax, includeOffline):
+ if not copyMapPlayerMax or self.IsMustCopyMapPlayer(playerID):
+ return True
+ return self.GetCopyMapPlayerCount(includeOffline, tick) < copyMapPlayerMax
#---------------------------------------------------------------------
def GetFBLineIpyData(mapID, lineID, isDefaultLine=True):
@@ -127,37 +145,127 @@
playerID = msgData["PlayerID"]
mapID = msgData["MapID"]
funcLineID = msgData["FuncLineID"]
+ playerLV = msgData["LV"]
zoneIpyData = CrossRealmPlayer.GetCrossZoneIpyDataByServerGroupID(mapID, serverGroupID)
if not zoneIpyData:
return
zoneID = zoneIpyData.GetZoneID()
- dynamicLineMaxPlayerCountDict = IpyGameDataPY.GetFuncEvalCfg("CrossDynamicLineMap", 2)
- copyMapPlayerMax = dynamicLineMaxPlayerCountDict.get(mapID, 0) # 0为不限制人数,默认不限制
+ openHour, openMinute = None, None
+ dynamicShuntType = DynamicShuntType_Fill
+ includeOffline = False
+ tagCopyMapObj = None
+
+ # 基础验证是否可进入等 及 数据准备
if mapID == ChConfig.Def_FBMapID_CrossDemonKing:
bossID = msgData["BossID"]
if not CrossBoss.GetCrossBossIsAliveOrCanReborn(zoneID, bossID):
- GameWorld.DebugLog("当前跨服妖王死亡状态,不可进入! serverGroupID=%s,funcLineID=%s,zoneID=%s,bossID=%s" % (serverGroupID, funcLineID, zoneID, bossID))
+ GameWorld.ErrLog("当前跨服妖王死亡状态,不可进入! funcLineID=%s,zoneID=%s,bossID=%s" % (funcLineID, zoneID, bossID), playerID)
return
elif mapID in [ChConfig.Def_FBMapID_CrossGrasslandLing, ChConfig.Def_FBMapID_CrossGrasslandXian]:
pass
-
+
+ elif mapID == ChConfig.Def_FBMapID_CrossBattlefield:
+ openTimeInfo = CrossBattlefield.GetCrossBattlefieldOpenTime(zoneID)
+ if not openTimeInfo:
+ PlayerControl.NotifyCodeCross(serverGroupID, playerID, "FBIsNotOpen")
+ GameWorld.ErrLog("非活动时间或未开启! funcLineID=%s,zoneID=%s" % (funcLineID, zoneID), playerID)
+ return
+ dynamicShuntType = DynamicShuntType_Equally
+ isCallBattle, openHour, openMinute = openTimeInfo
+ if isCallBattle:
+ # 召集场次默认 funcLineID 为0,不分等级,不分流
+ funcLineID = 0
+ dynamicShuntType = DynamicShuntType_No
+ includeOffline = True
else:
return
- mapCopyLineInfo = __GetCrossDynamicLineInfo(playerID, serverGroupID, mapID, funcLineID, zoneID, copyMapPlayerMax, tick)
- if not mapCopyLineInfo:
+ dynamicLineMaxPlayerCountDict = IpyGameDataPY.GetFuncEvalCfg("CrossDynamicLineMap", 2)
+ copyMapPlayerMin, copyMapPlayerMax = dynamicLineMaxPlayerCountDict.get(mapID, [0, 0]) # 0为不限制人数,默认不限制
+
+ # 除个别地图外,最优先进入上次进入的未关闭分线
+ if mapID not in []:
+ for _, copyMapObj in PyGameData.g_crossDynamicLineCopyMapInfo.items():
+ if copyMapObj.IsMustCopyMapPlayer(playerID):
+ tagCopyMapObj = copyMapObj
+ break
+
+ # 如果没有进入过,则按功能看是否有特殊指定规则
+ if tagCopyMapObj == None:
+ if mapID == ChConfig.Def_FBMapID_CrossBattlefield:
+ if isCallBattle:
+ copyMapPlayerMax = IpyGameDataPY.GetFuncCfg("CrossBattlefieldCall", 2)
+ tagCopyMapObj = CrossBattlefield.GetCallPlayerCopymapObj(playerID, serverGroupID, mapID, funcLineID, zoneID, copyMapPlayerMax, includeOffline, tick)
+
+ # 如果还没有取到对应的分流线,则按默认规则处理
+ if tagCopyMapObj == None and dynamicShuntType:
+ # 非特殊动态规则,走常规逻辑
+ dynamicLineLVRangeDict = IpyGameDataPY.GetFuncEvalCfg("CrossDynamicLineMap", 4)
+ if mapID in dynamicLineLVRangeDict:
+ lvRangeList = dynamicLineLVRangeDict[mapID]
+ for lvFuncLineID, lvRange in enumerate(lvRangeList):
+ if lvRange[0] <= playerLV <= lvRange[1]:
+ funcLineID = lvFuncLineID
+ copyMapPlayerMin, copyMapPlayerMax = lvRange[2], lvRange[3]
+ GameWorld.DebugLog("进入跨服地图等级自动适配功能线路ID: mapID=%s,playerLV=%s,funcLineID=%s,copyMapPlayerMin=%s,copyMapPlayerMax=%s"
+ % (mapID, playerLV, funcLineID, copyMapPlayerMin, copyMapPlayerMax))
+ break
+
+ shuntPlayerMax = copyMapPlayerMax
+
+ minCountTimeDict = IpyGameDataPY.GetFuncEvalCfg("CrossDynamicLineMap", 3) # 分流下限人数有效时间配置,单位秒,{dataMapID:秒, ...}
+ if mapID in minCountTimeDict:
+ playerMinTimeSet = minCountTimeDict[mapID]
+ curTime = GameWorld.GetServerTime()
+ if openHour == None or openMinute == None:
+ GameWorld.ErrLog("副本开启时间未知! mapID=%s,funcLineID=%s,zoneID=%s" % (mapID, funcLineID, zoneID), playerID)
+ return
+
+ openDateTimeStr = "%d-%02d-%02d %02d:%02d:00" % (curTime.year, curTime.month, curTime.day, openHour, openMinute)
+ openDateTime = GameWorld.ChangeStrToDatetime(openDateTimeStr)
+ passTime = curTime - openDateTime
+ '''
+ 在线(包含请求中) <= 单场下限值
+ 在线(包含请求中)+ 离线 <= 单场上限值
+
+ 前X秒大于 单场下限值 开新一场
+ 任意时刻大于 单场上限值 必开新一场
+ '''
+ if passTime.seconds <= playerMinTimeSet:
+ shuntPlayerMax = copyMapPlayerMin
+ includeOffline = False
+ else:
+ shuntPlayerMax = copyMapPlayerMax
+ includeOffline = True
+
+ tagCopyMapObj = __GetCrossDynamicLineInfo(playerID, serverGroupID, mapID, funcLineID, zoneID,
+ shuntPlayerMax, copyMapPlayerMax, includeOffline, tick, dynamicShuntType)
+
+ if not tagCopyMapObj:
+ PlayerControl.NotifyCodeCross(serverGroupID, playerID, "CrossFBFull")
+ GameWorld.ErrLog("找不到可分流的副本线路! mapID=%s,funcLineID=%s,zoneID=%s" % (mapID, funcLineID, zoneID), playerID)
return
- realMapID, copyMapID, openState = mapCopyLineInfo
- if openState != IPY_PlayerDefine.fbosOpen:
+
+ realMapID, copyMapID, openState = tagCopyMapObj.realMapID, tagCopyMapObj.copyMapID, tagCopyMapObj.openState
+
+ if openState == IPY_PlayerDefine.fbosWaitForClose:
+ PlayerControl.NotifyCodeCross(serverGroupID, playerID, "CrossFBClose")
+ GameWorld.ErrLog("分流的副本线路关闭中! mapID=%s,funcLineID=%s,zoneID=%s,realMapID=%s,copyMapID=%s,openState=%s"
+ % (mapID, funcLineID, zoneID, realMapID, copyMapID, openState), playerID)
return
- playerIDList = [playerID]
- retInfo = [playerIDList, mapID, realMapID, copyMapID, funcLineID]
- CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_EnterFBRet, retInfo, [serverGroupID])
- return
+ tagCopyMapObj.waitPlayerDict[playerID] = [serverGroupID, tick]
+ GameWorld.DebugLog(" 分配进入跨服场景: realMapID=%s, copyMapID=%s, openState=%s" % (realMapID, copyMapID, openState), playerID)
+ if openState == IPY_PlayerDefine.fbosOpen:
+ funcLineID = tagCopyMapObj.funcLineID
+ playerIDList = [playerID]
+ retInfo = [playerIDList, mapID, realMapID, copyMapID, funcLineID]
+ CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_EnterFBRet, retInfo, [serverGroupID])
+
+ return tagCopyMapObj
def CrossServerMsg_EnterFBRet(msgData, tick):
## 收到跨服服务器动态分配的跨服副本进入信息
@@ -172,26 +280,50 @@
return
-def __GetCrossDynamicLineInfo(playerID, serverGroupID, mapID, funcLineID, zoneID, copyMapPlayerMax, tick):
+def __GetCrossDynamicLineInfo(playerID, serverGroupID, mapID, funcLineID, zoneID, shuntPlayerMax, copyMapPlayerMax, includeOffline, tick, dynamicShuntType):
'''获取跨服分区对应动态分配的副本地图虚拟线路信息, 由于需要支持多地图分流,所以直接由GameServer管理分配
每个功能线路支持按人数分流,超过最大人数后可开启一条相同功能线路的虚拟线路进行分流,所以同一分区同一地图的功能线路ID可能对应多条虚拟线路
+ 分流方式:
+ DynamicShuntType_Fill = 1 # 填满式分流,按存在的线路人数多的优先填充,都满后开启新线路
+ DynamicShuntType_Equally = 2 # 均摊式分流,按存在的线路人数少的优先填充,都满后开启新线路
+ 分流规则:
+ 时间仅决定分流人数,不影响常规分配逻辑
+ 1. 优先分配到人数小于分流人数的场次
+ 2. 超过分流人数的场次依次往人数少的场次分配
+ 3. 当当前已开放的场次都达到人数分流人数,则开启新场次,没有空闲的场,则往未达到人数上限的场次依次分配,直到达到所有场次上限
+
+ 关于 shuntPlayerMax 的选择: 可根据副本规则制定
+ 如前X分钟内可设定一个小于 copyMapPlayerMax 的分流人数值快速铺满各分流场次
+ 当大于X分钟后则可设置 shuntPlayerMax = copyMapPlayerMax 进行饱和分流
+
+ 当所有分流场次达到 shuntPlayerMax 后,可尝试开启新分流线路,进行分流
+ shuntPlayerMax < copyMapPlayerMax 的情况,如果没有办法开启新分流线路,则可继续强制根据分流类型分配线路,只要未达到 copyMapPlayerMax 人数,还是可以进入副本的
+ shuntPlayerMax >= copyMapPlayerMax 的情况,如果没有办法开启新分流线路,则标识副本所有线路已达到饱和状态,不能再进入副本了
+
+ 当 shuntPlayerMax 为 0 时,达标不限制人数上限,及不分流,都在同一条线路,一般跨服副本不建议设置为0,人数太多,不合理
+
+ @param shuntPlayerMax: 分流最大人数限制
+ @param copyMapPlayerMax: 实际最大可容纳的人数限制,一般大于等于分流人数限制
+ @param includeOffline: 是否包含本线路离线玩家
+ @param dynamicShuntType: 分流类型,可选择 填满式分流 或 均摊式分流
'''
zoneLineKey = (zoneID, funcLineID)
- if mapID not in PyGameData.g_crossDynamicLineInfo:
- PyGameData.g_crossDynamicLineInfo[mapID] = {}
- zoneLineDict = PyGameData.g_crossDynamicLineInfo[mapID] # 跨服动态线路信息 {dataMapID:{(zoneID, funcLineID):[CrossFuncLineInfo, CrossFuncLineInfo, ...], ...}, ...}
- if zoneLineKey not in zoneLineDict:
- zoneLineDict[zoneLineKey] = []
- funcLineObjList = zoneLineDict[zoneLineKey]
+ zoneLineDict = PyGameData.g_crossDynamicLineInfo.get(mapID, {})
+ funcLineObjList = zoneLineDict.get(zoneLineKey, [])
+ isPlayerFullMax = (shuntPlayerMax >= copyMapPlayerMax)
- newFuncLineNum = None
- newFuncLineObj = None
- for index, funcLineObj in enumerate(funcLineObjList, 1):
+ GameWorld.DebugLog("获取动态分流线路: serverGroupID=%s,mapID=%s,funcLineID=%s,zoneID=%s,shuntPlayerMax=%s,copyMapPlayerMax=%s,includeOffline=%s,dynamicShuntType=%s"
+ % (serverGroupID, mapID, funcLineID, zoneID, shuntPlayerMax, copyMapPlayerMax, includeOffline, dynamicShuntType), playerID)
+ #GameWorld.DebugLog(" funcLineObjList=%s" % funcLineObjList, playerID)
+
+ canUseShuntLine = False # 是否直接使用分流线路,如果否的话,当人数未达到真正饱和时,则还可直接分配对应分流类型的线路
+ minPlayerCount, maxPlayerCount = 0, 0
+ minCopyMapObj, maxCopyMapObj = None, None
+ for _, funcLineObj in enumerate(funcLineObjList, 1):
realMapID, copyMapID = funcLineObj.realMapID, funcLineObj.copyMapID
+ #GameWorld.DebugLog(" realMapID=%s, copyMapID=%s" % (realMapID, copyMapID))
if not realMapID:
- if not newFuncLineObj:
- newFuncLineNum, newFuncLineObj = index, funcLineObj
continue
key = (realMapID, copyMapID)
@@ -203,59 +335,161 @@
copyMapObj = PyGameData.g_crossDynamicLineCopyMapInfo[key]
openState = copyMapObj.openState
if openState == IPY_PlayerDefine.fbosWaitForClose:
- if not copyMapPlayerMax:
- PlayerControl.CrossNotifyCode(serverGroupID, playerID, "HazyRegionClose")
+ # 没有限制分流人数的情况,代表都在同一场,这种情况下当副本已经在关闭的状态下,则代表已经结束了,不可再进入
+ if not shuntPlayerMax:
+ PlayerControl.NotifyCodeCross(serverGroupID, playerID, "CrossFBClose")
return
- #GameWorld.DebugLog(" 虚拟线路等待关闭中! index=%s,realMapID=%s,copyMapID=%s" % (index, realMapID, copyMapID))
+ #GameWorld.DebugLog(" 虚拟线路等待关闭中! realMapID=%s,copyMapID=%s" % (realMapID, copyMapID))
continue
- canEnter = copyMapObj.OnRequestEnterCrossCopyMap(playerID, serverGroupID, tick, copyMapPlayerMax)
- if canEnter:
- #GameWorld.DebugLog("可进入动态分布的虚拟线路! realMapID=%s,copyMapID=%s,openState=%s" % (realMapID, copyMapID, openState))
- #GameWorld.DebugLog(" 副本中的玩家ID: %s" % copyMapObj.fbPlayerDict)
- #GameWorld.DebugLog(" 等待中的玩家ID: %s" % copyMapObj.waitPlayerDict)
- return realMapID, copyMapID, openState
+ if not shuntPlayerMax or copyMapObj.IsMustCopyMapPlayer(playerID):
+ return copyMapObj
+ playerCount = copyMapObj.GetCopyMapPlayerCount(includeOffline, tick)
+ if minCopyMapObj == None or playerCount < minPlayerCount:
+ minPlayerCount = playerCount
+ minCopyMapObj = copyMapObj
+
+ if maxCopyMapObj == None or playerCount > maxPlayerCount:
+ maxPlayerCount = playerCount
+ maxCopyMapObj = copyMapObj
+
+ # 存在线路未达到规定的分流人数,则可直接使用分流线路
+ if playerCount < shuntPlayerMax:
+ canUseShuntLine = True
+
+ #GameWorld.DebugLog(" isPlayerFullMax=%s,canUseShuntLine=%s" % (isPlayerFullMax, canUseShuntLine))
+ dynamicShuntCopyMap = None # 分流类型决定的分流线路
+
+ # 均摊式
+ if dynamicShuntType == DynamicShuntType_Equally:
+ dynamicShuntCopyMap = minCopyMapObj
+ # 填满式
+ elif dynamicShuntType == DynamicShuntType_Fill:
+ dynamicShuntCopyMap = maxCopyMapObj
+ else:
+ return
+
+ shuntCopyMap = None
+ if canUseShuntLine:
+ shuntCopyMap = dynamicShuntCopyMap
+
+ #GameWorld.DebugLog(" shuntCopyMap=%s" % shuntCopyMap)
+ if not shuntCopyMap:
+ isLog = isPlayerFullMax
+ shuntCopyMap = __OpenNewFuncLine(mapID, zoneID, funcLineID, isLog)
+
+ # 即 shuntPlayerMax < copyMapPlayerMax 的情况
+ if not shuntCopyMap and not isPlayerFullMax:
+ shuntCopyMap = dynamicShuntCopyMap
+
+ if not shuntCopyMap:
+ return
+
+ shuntCopyMap.waitPlayerDict[playerID] = [serverGroupID, tick]
+
+ return shuntCopyMap
+
+def __OpenNewFuncLine(mapID, zoneID, funcLineID, isLog=True):
+ ## 新开功能线路分流
+
+ if mapID not in PyGameData.g_crossDynamicLineInfo:
+ PyGameData.g_crossDynamicLineInfo[mapID] = {}
+ zoneLineDict = PyGameData.g_crossDynamicLineInfo[mapID] # 跨服动态线路信息 {dataMapID:{(zoneID, funcLineID):[CrossFuncLineInfo, CrossFuncLineInfo, ...], ...}, ...}
+ zoneLineKey = (zoneID, funcLineID)
+ if zoneLineKey not in zoneLineDict:
+ zoneLineDict[zoneLineKey] = []
+ funcLineObjList = zoneLineDict[zoneLineKey]
+
dynamicLineMapDict = IpyGameDataPY.GetFuncEvalCfg("CrossDynamicLineMap", 1)
dynamicMapIDList = dynamicLineMapDict.get(mapID, [mapID])
openMapID, openCopyMapID = 0, 0
- for realMapID in dynamicMapIDList:
- maxCopyMapCount = PyGameData.g_crossMapCopyMapCountDict.get(realMapID, 0)
- for copyMapID in xrange(maxCopyMapCount):
+ maxCopyMapCount = PyGameData.g_crossMapCopyMapCountDict.get(dynamicMapIDList[0], 0)
+ # 外层为虚拟线路总数遍历,内层为分流地图,这样可以均匀分流到各个分流地图,减少单地图压力
+ for copyMapID in xrange(maxCopyMapCount):
+ for realMapID in dynamicMapIDList:
+ if copyMapID >= PyGameData.g_crossMapCopyMapCountDict.get(realMapID, 0):
+ continue
if (realMapID, copyMapID) not in PyGameData.g_crossDynamicLineCopyMapInfo:
openMapID, openCopyMapID = realMapID, copyMapID
break
if openMapID:
break
+
if not openMapID:
- GameWorld.ErrLog("没有空余的虚拟线路,无法动态开启跨服副本!mapID=%s, funcLineID=%s, zoneID=%s, dynamicMapIDList=%s"
- % (mapID, funcLineID, zoneID, dynamicMapIDList))
+ if isLog:
+ GameWorld.ErrLog("没有空余的虚拟线路,无法动态开启跨服副本! mapID=%s,zoneID=%s,funcLineID=%s,dynamicMapIDList=%s"
+ % (mapID, zoneID, funcLineID, dynamicMapIDList))
return
+ realMapID, copyMapID = openMapID, openCopyMapID
+
+ newFuncLineObj = None
+ for funcLineObj in funcLineObjList:
+ if not funcLineObj.realMapID:
+ newFuncLineObj = funcLineObj
+ break
+
if newFuncLineObj == None:
newFuncLineObj = CrossFuncLineInfo()
funcLineObjList.append(newFuncLineObj)
- newFuncLineNum = len(funcLineObjList)
- realMapID, copyMapID = openMapID, openCopyMapID
+
+ newFuncLineNum = 1
+ lineNumList = [lineObj.newFuncLineNum for lineObj in funcLineObjList]
+ for num in xrange(1, len(lineNumList) + 1):
+ if num not in lineNumList:
+ newFuncLineNum = num
+ break
+ GameWorld.DebugLog(" lineNumList=%s,newFuncLineNum=%s" % (lineNumList, newFuncLineNum))
+
newFuncLineObj.realMapID = realMapID
newFuncLineObj.copyMapID = copyMapID
- funcLineDataCache = newFuncLineObj.funcLineDataCache
+ newFuncLineObj.newFuncLineNum = newFuncLineNum
+
+ copyMapObj = CrossCopyMapInfo(zoneID, funcLineID)
+ copyMapObj.realMapID = realMapID
+ copyMapObj.copyMapID = copyMapID
+ copyMapObj.newFuncLineNum = newFuncLineNum
key = (realMapID, copyMapID)
- copyMapObj = CrossCopyMapInfo(zoneID, funcLineID)
PyGameData.g_crossDynamicLineCopyMapInfo[key] = copyMapObj
- copyMapObj.waitPlayerDict[playerID] = [serverGroupID, tick]
- openState = copyMapObj.openState
- propertyID = int("%d%03d%d" % (zoneID, funcLineID, newFuncLineNum))
- GameWorld.DebugLog("不存在该分区功能线路ID,重新分配: zoneID=%s,funcLineID=%s,realMapID=%s,copyMapID=%s,propertyID=%s"
- % (zoneID, funcLineID, realMapID, copyMapID, propertyID))
+ propertyID = int("%d%03d%02d" % (zoneID, funcLineID, newFuncLineNum))
+ GameWorld.Log(" 新开分区动态副本功能线路: zoneID=%s,funcLineID=%s,newFuncLineNum=%s,realMapID=%s,copyMapID=%s,propertyID=%s"
+ % (zoneID, funcLineID, newFuncLineNum, realMapID, copyMapID, propertyID))
# 通知地图开启新的地图虚拟分线
+ funcLineDataCache = newFuncLineObj.funcLineDataCache
msgInfo = str([copyMapID, propertyID, funcLineDataCache])
GameWorld.GetPlayerManager().MapServer_QueryPlayer(0, 0, 0, realMapID, "OpenFB", msgInfo, len(msgInfo))
- return realMapID, copyMapID, openState
+ return copyMapObj
+
+def OpenCrossDynamicLineBySys(zoneID, mapID, funcLineIDList, checkExist):
+ ## 系统开启跨服动态线路
+
+ GameWorld.Log(" 系统开启跨服动态线路: zoneID=%s, mapID=%s, funcLineIDList=%s, checkExist=%s" % (zoneID, mapID, funcLineIDList, checkExist))
+
+ for funcLineID in funcLineIDList:
+
+ if checkExist:
+ fincLineObj = None
+ zoneLineKey = (zoneID, funcLineID)
+ zoneLineDict = PyGameData.g_crossDynamicLineInfo.get(mapID, {})
+ funcLineObjList = zoneLineDict.get(zoneLineKey, [])
+ for funcLineObj in funcLineObjList:
+ if funcLineObj.realMapID:
+ fincLineObj = funcLineObj
+ break
+
+ if fincLineObj:
+ GameWorld.ErrLog("已经存在开放中的线路,不重复开启动态副本线路! mapID=%s, funcLineID=%s, zoneID=%s, realMapID=%s, copyMapID=%s"
+ % (mapID, funcLineID, zoneID, funcLineObj.realMapID, funcLineObj.copyMapID))
+ continue
+
+ __OpenNewFuncLine(mapID, zoneID, funcLineID)
+
+ return
def GetCrossDynamicLineZoneID(mapID, realMapID, copyMapID):
## 获取跨服动态分配的虚拟线路对应分区ID
@@ -345,6 +579,8 @@
funcLineObj.OnCopyMapClose()
zoneID, funcLineID = key
GameWorld.Log(" 分区对应功能线路虚拟分线关闭: zoneID=%s,dataMapID%s,funcLineID=%s" % (zoneID, dataMapID, funcLineID))
+ if not funcLineObj.funcLineDataCache:
+ funcLineObjList.remove(funcLineObj)
break
key = (mapID, copyMapID)
@@ -401,6 +637,8 @@
copyMapObj.waitPlayerDict.pop(playerID, None)
copyMapObj.offlinePlayerDict.pop(playerID, None)
copyMapObj.fbPlayerDict[playerID] = serverGroupID
+ if playerID not in copyMapObj.enterPlayerIDList:
+ copyMapObj.enterPlayerIDList.append(playerID)
#GameWorld.DebugLog("玩家登录动态分配的跨服地图: GetMapID=%s,GetRealMapID=%s,GetFBID()=%s,serverGroupID=%s"
# % (curPlayer.GetMapID(), mapID, copyMapID, serverGroupID), playerID)
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py
index e3a8409..4d45f72 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py
@@ -70,6 +70,7 @@
import CrossRealmPlayer
import CrossRealmMsg
import CrossRealmPK
+import CrossBattlefield
import ChPyNetSendPack
import NetPackCommon
import AuctionHouse
@@ -508,10 +509,10 @@
return
if callName == "SendMail":
- title, content, getDays, playerIDList, addItemList, gold, goldPaper, silver, detail, moneySource = eval(resultName)
+ title, content, getDays, playerIDList, addItemList, gold, goldPaper, silver, detail, moneySource, crossMail = eval(resultName)
limitTime = str(GameWorld.GetDatetimeByDiffDays(getDays))
limitTime = limitTime.split(".")[0]
- PlayerCompensation.SendPersonalItemMail(title, content, limitTime, playerIDList, addItemList, gold, goldPaper, silver, detail=detail, moneySource=moneySource)
+ PlayerCompensation.SendPersonalItemMail(title, content, limitTime, playerIDList, addItemList, gold, goldPaper, silver, detail=detail, moneySource=moneySource, crossMail=crossMail)
return
if callName == "SendMailBatch":
@@ -649,6 +650,11 @@
CrossRealmPlayer.OnCrossRealmRegOK(srcPlayerID, eval(resultName), tick)
return
+ # 跨服战场结算
+ if callName =="CrossBattlefieldOver":
+ CrossBattlefield.MapServer_CrossBattlefieldOver(eval(resultName))
+ return
+
#py喇叭聊天
if callName == 'PYSpeaker':
curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(srcPlayerID)
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerViewCache.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerViewCache.py
index 3e4270a..322b1a8 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerViewCache.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerViewCache.py
@@ -24,6 +24,7 @@
import GameWorldArena
import ChPyNetSendPack
import PlayerFBHelpBattle
+import CrossBattlefield
import PyGameDataStruct
import IpyGameDataPY
import PyDataManager
@@ -44,6 +45,9 @@
if GameWorldArena.IsArenaBattlePlayer(playerID):
return True
+ if CrossBattlefield.IsBattlefieldCallPlayer(playerID):
+ return True
+
SaveDBLimitLV = IpyGameDataPY.GetFuncCfg("PlayerViewCache", 1)
#校验玩家等级
if playerLV < SaveDBLimitLV:
@@ -58,6 +62,9 @@
return True
if GameWorldArena.IsArenaBattlePlayer(playerID):
+ return True
+
+ if CrossBattlefield.IsBattlefieldCallPlayer(playerID):
return True
NeedCheckBillBoardType = IpyGameDataPY.GetFuncEvalCfg("PlayerViewCache", 2)
@@ -116,7 +123,7 @@
## 获取缓存基础属性字典信息
if not hasattr(curCache, "PropDataDict"):
curCache.PropDataDict = {}
- if not curCache.PropDataDict:
+ if not curCache.PropDataDict and curCache.PropData:
curCache.PropDataDict = eval(curCache.PropData)
return curCache.PropDataDict
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/PyGameData.py b/ServerPython/CoreServerGroup/GameServer/Script/PyGameData.py
index dce06af..3e9c217 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/PyGameData.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/PyGameData.py
@@ -139,6 +139,10 @@
g_crossFBFuncLinePlayerCountInfo = {} # 跨服副本功能线路人数信息,本服缓存 {mapID:{funcLineID:[playerCount], ...}, ...}
+g_unNotifyPlayerCrossMsgDict = {} # 未通知玩家的跨服命令 {playerID:{msgType:[msgInfo], ...}, ...}
+
+g_crossBattlefieldBuyInfo = {} # 跨服战场购买记录 {zoneID:{hmNum:{playerID:CrossBattlefieldBuy, ...}, ...}, ...}
+
g_familyTalkCache = {} #{familyID:[[time,content,extras],..]}
g_worldTalkCache = [] #[[time,name, playerID, content,extras],..]
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
index b64d1b7..8d8ad16 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
@@ -650,6 +650,18 @@
PacketSubCMD_1=0x10
PacketCallFunc_1=OnLuckyCloudBuy
+;跨服战场
+[PlayerCrossBattlefield]
+ScriptName = Player\PlayerCrossBattlefield.py
+Writer = hxp
+Releaser = hxp
+RegType = 0
+RegisterPackCount = 1
+
+PacketCMD_1=0xC1
+PacketSubCMD_1=0x09
+PacketCallFunc_1=OnCrossBattlefieldBuyOpen
+
;改名功能
[UpdatePlayerName]
ScriptName = Player\UpdatePlayerName.py
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
index 96ef755..f1a2139 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
@@ -3987,6 +3987,126 @@
#------------------------------------------------------
+# C0 08 跨服战场召集场次踢人 #tagCGCrossBattlefieldCallKick
+
+class tagCGCrossBattlefieldCallKick(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ("Cmd", c_ubyte),
+ ("SubCmd", c_ubyte),
+ ("Hour", c_ubyte), #战场开启时
+ ("Minute", c_ubyte), #战场开启分
+ ("TagPlayerID", c_int), #目标玩家ID,即要被踢出去的玩家ID
+ ]
+
+ def __init__(self):
+ self.Clear()
+ self.Cmd = 0xC0
+ self.SubCmd = 0x08
+ return
+
+ def ReadData(self, stringData, _pos=0, _len=0):
+ self.Clear()
+ memmove(addressof(self), stringData[_pos:], self.GetLength())
+ return _pos + self.GetLength()
+
+ def Clear(self):
+ self.Cmd = 0xC0
+ self.SubCmd = 0x08
+ self.Hour = 0
+ self.Minute = 0
+ self.TagPlayerID = 0
+ return
+
+ def GetLength(self):
+ return sizeof(tagCGCrossBattlefieldCallKick)
+
+ def GetBuffer(self):
+ return string_at(addressof(self), self.GetLength())
+
+ def OutputString(self):
+ DumpString = '''// C0 08 跨服战场召集场次踢人 //tagCGCrossBattlefieldCallKick:
+ Cmd:%s,
+ SubCmd:%s,
+ Hour:%d,
+ Minute:%d,
+ TagPlayerID:%d
+ '''\
+ %(
+ self.Cmd,
+ self.SubCmd,
+ self.Hour,
+ self.Minute,
+ self.TagPlayerID
+ )
+ return DumpString
+
+
+m_NAtagCGCrossBattlefieldCallKick=tagCGCrossBattlefieldCallKick()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCGCrossBattlefieldCallKick.Cmd,m_NAtagCGCrossBattlefieldCallKick.SubCmd))] = m_NAtagCGCrossBattlefieldCallKick
+
+
+#------------------------------------------------------
+# C0 07 跨服战场加入召集场次 #tagCGCrossBattlefieldJoinByCall
+
+class tagCGCrossBattlefieldJoinByCall(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ("Cmd", c_ubyte),
+ ("SubCmd", c_ubyte),
+ ("Hour", c_ubyte), #战场开启时
+ ("Minute", c_ubyte), #战场开启分
+ ("BuyPlayerID", c_int), #加入目标玩家的召集队伍,即购买召集场的玩家ID
+ ]
+
+ def __init__(self):
+ self.Clear()
+ self.Cmd = 0xC0
+ self.SubCmd = 0x07
+ return
+
+ def ReadData(self, stringData, _pos=0, _len=0):
+ self.Clear()
+ memmove(addressof(self), stringData[_pos:], self.GetLength())
+ return _pos + self.GetLength()
+
+ def Clear(self):
+ self.Cmd = 0xC0
+ self.SubCmd = 0x07
+ self.Hour = 0
+ self.Minute = 0
+ self.BuyPlayerID = 0
+ return
+
+ def GetLength(self):
+ return sizeof(tagCGCrossBattlefieldJoinByCall)
+
+ def GetBuffer(self):
+ return string_at(addressof(self), self.GetLength())
+
+ def OutputString(self):
+ DumpString = '''// C0 07 跨服战场加入召集场次 //tagCGCrossBattlefieldJoinByCall:
+ Cmd:%s,
+ SubCmd:%s,
+ Hour:%d,
+ Minute:%d,
+ BuyPlayerID:%d
+ '''\
+ %(
+ self.Cmd,
+ self.SubCmd,
+ self.Hour,
+ self.Minute,
+ self.BuyPlayerID
+ )
+ return DumpString
+
+
+m_NAtagCGCrossBattlefieldJoinByCall=tagCGCrossBattlefieldJoinByCall()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCGCrossBattlefieldJoinByCall.Cmd,m_NAtagCGCrossBattlefieldJoinByCall.SubCmd))] = m_NAtagCGCrossBattlefieldJoinByCall
+
+
+#------------------------------------------------------
# C0 03 强制退出跨服状态 #tagCGForceQuitCrossState
class tagCGForceQuitCrossState(Structure):
@@ -18941,6 +19061,66 @@
#------------------------------------------------------
+# C1 09 跨服战场购买开启场次 #tagCMCrossBattlefieldBuyOpen
+
+class tagCMCrossBattlefieldBuyOpen(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ("Cmd", c_ubyte),
+ ("SubCmd", c_ubyte),
+ ("Hour", c_ubyte), #战场开启时
+ ("Minute", c_ubyte), #战场开启分
+ ("Faction", c_ubyte), #阵营 1-红;2-蓝
+ ]
+
+ def __init__(self):
+ self.Clear()
+ self.Cmd = 0xC1
+ self.SubCmd = 0x09
+ return
+
+ def ReadData(self, stringData, _pos=0, _len=0):
+ self.Clear()
+ memmove(addressof(self), stringData[_pos:], self.GetLength())
+ return _pos + self.GetLength()
+
+ def Clear(self):
+ self.Cmd = 0xC1
+ self.SubCmd = 0x09
+ self.Hour = 0
+ self.Minute = 0
+ self.Faction = 0
+ return
+
+ def GetLength(self):
+ return sizeof(tagCMCrossBattlefieldBuyOpen)
+
+ def GetBuffer(self):
+ return string_at(addressof(self), self.GetLength())
+
+ def OutputString(self):
+ DumpString = '''// C1 09 跨服战场购买开启场次 //tagCMCrossBattlefieldBuyOpen:
+ Cmd:%s,
+ SubCmd:%s,
+ Hour:%d,
+ Minute:%d,
+ Faction:%d
+ '''\
+ %(
+ self.Cmd,
+ self.SubCmd,
+ self.Hour,
+ self.Minute,
+ self.Faction
+ )
+ return DumpString
+
+
+m_NAtagCMCrossBattlefieldBuyOpen=tagCMCrossBattlefieldBuyOpen()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMCrossBattlefieldBuyOpen.Cmd,m_NAtagCMCrossBattlefieldBuyOpen.SubCmd))] = m_NAtagCMCrossBattlefieldBuyOpen
+
+
+#------------------------------------------------------
# C1 06 跨服NPC对话 #tagCMCrossNPCTalk
class tagCMCrossNPCTalk(Structure):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
index 7d369cc..6a91da3 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
@@ -12288,6 +12288,283 @@
#------------------------------------------------------
+# C0 09 跨服战场玩家购买战场信息 #tagGCCrossBattlefieldBuyInfo
+
+class tagGCCrossBattlefieldPlayer(Structure):
+ PlayerID = 0 #(DWORD PlayerID)
+ PlayerName = "" #(char PlayerName[33])
+ Job = 0 #(BYTE Job)
+ LV = 0 #(WORD LV)//等级
+ RealmLV = 0 #(WORD RealmLV)//境界
+ FightPower = 0 #(DWORD FightPower)//战力求余亿部分
+ FightPowerEx = 0 #(DWORD FightPowerEx)//战力整除亿部分
+ data = None
+
+ def __init__(self):
+ self.Clear()
+ return
+
+ def ReadData(self, _lpData, _pos=0, _Len=0):
+ self.Clear()
+ self.PlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+ self.PlayerName,_pos = CommFunc.ReadString(_lpData, _pos,33)
+ self.Job,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+ self.LV,_pos = CommFunc.ReadWORD(_lpData, _pos)
+ self.RealmLV,_pos = CommFunc.ReadWORD(_lpData, _pos)
+ self.FightPower,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+ self.FightPowerEx,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+ return _pos
+
+ def Clear(self):
+ self.PlayerID = 0
+ self.PlayerName = ""
+ self.Job = 0
+ self.LV = 0
+ self.RealmLV = 0
+ self.FightPower = 0
+ self.FightPowerEx = 0
+ return
+
+ def GetLength(self):
+ length = 0
+ length += 4
+ length += 33
+ length += 1
+ length += 2
+ length += 2
+ length += 4
+ length += 4
+
+ return length
+
+ def GetBuffer(self):
+ data = ''
+ data = CommFunc.WriteDWORD(data, self.PlayerID)
+ data = CommFunc.WriteString(data, 33, self.PlayerName)
+ data = CommFunc.WriteBYTE(data, self.Job)
+ data = CommFunc.WriteWORD(data, self.LV)
+ data = CommFunc.WriteWORD(data, self.RealmLV)
+ data = CommFunc.WriteDWORD(data, self.FightPower)
+ data = CommFunc.WriteDWORD(data, self.FightPowerEx)
+ return data
+
+ def OutputString(self):
+ DumpString = '''
+ PlayerID:%d,
+ PlayerName:%s,
+ Job:%d,
+ LV:%d,
+ RealmLV:%d,
+ FightPower:%d,
+ FightPowerEx:%d
+ '''\
+ %(
+ self.PlayerID,
+ self.PlayerName,
+ self.Job,
+ self.LV,
+ self.RealmLV,
+ self.FightPower,
+ self.FightPowerEx
+ )
+ return DumpString
+
+
+class tagGCCrossBattlefieldBuyPlayer(Structure):
+ BuyPlayerID = 0 #(DWORD BuyPlayerID)//购买的玩家ID,即召集人
+ Faction = 0 #(BYTE Faction)//阵营 1-红;2-蓝
+ FactionPlayerCount = 0 #(BYTE FactionPlayerCount)
+ FactionPlayerList = list() #(vector<tagGCCrossBattlefieldPlayer> FactionPlayerList)//阵营所有玩家列表,包含召集人
+ data = None
+
+ def __init__(self):
+ self.Clear()
+ return
+
+ def ReadData(self, _lpData, _pos=0, _Len=0):
+ self.Clear()
+ self.BuyPlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
+ self.Faction,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+ self.FactionPlayerCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+ for i in range(self.FactionPlayerCount):
+ temFactionPlayerList = tagGCCrossBattlefieldPlayer()
+ _pos = temFactionPlayerList.ReadData(_lpData, _pos)
+ self.FactionPlayerList.append(temFactionPlayerList)
+ return _pos
+
+ def Clear(self):
+ self.BuyPlayerID = 0
+ self.Faction = 0
+ self.FactionPlayerCount = 0
+ self.FactionPlayerList = list()
+ return
+
+ def GetLength(self):
+ length = 0
+ length += 4
+ length += 1
+ length += 1
+ for i in range(self.FactionPlayerCount):
+ length += self.FactionPlayerList[i].GetLength()
+
+ return length
+
+ def GetBuffer(self):
+ data = ''
+ data = CommFunc.WriteDWORD(data, self.BuyPlayerID)
+ data = CommFunc.WriteBYTE(data, self.Faction)
+ data = CommFunc.WriteBYTE(data, self.FactionPlayerCount)
+ for i in range(self.FactionPlayerCount):
+ data = CommFunc.WriteString(data, self.FactionPlayerList[i].GetLength(), self.FactionPlayerList[i].GetBuffer())
+ return data
+
+ def OutputString(self):
+ DumpString = '''
+ BuyPlayerID:%d,
+ Faction:%d,
+ FactionPlayerCount:%d,
+ FactionPlayerList:%s
+ '''\
+ %(
+ self.BuyPlayerID,
+ self.Faction,
+ self.FactionPlayerCount,
+ "..."
+ )
+ return DumpString
+
+
+class tagGCCrossBattlefieldBuyHM(Structure):
+ Hour = 0 #(BYTE Hour)//战场开启时
+ Minute = 0 #(BYTE Minute)//战场开启分
+ BuyPlayerCount = 0 #(BYTE BuyPlayerCount)
+ BuyPlayerList = list() #(vector<tagGCCrossBattlefieldBuyPlayer> BuyPlayerList)//购买本场次的玩家信息列表
+ data = None
+
+ def __init__(self):
+ self.Clear()
+ return
+
+ def ReadData(self, _lpData, _pos=0, _Len=0):
+ self.Clear()
+ self.Hour,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+ self.Minute,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+ self.BuyPlayerCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+ for i in range(self.BuyPlayerCount):
+ temBuyPlayerList = tagGCCrossBattlefieldBuyPlayer()
+ _pos = temBuyPlayerList.ReadData(_lpData, _pos)
+ self.BuyPlayerList.append(temBuyPlayerList)
+ return _pos
+
+ def Clear(self):
+ self.Hour = 0
+ self.Minute = 0
+ self.BuyPlayerCount = 0
+ self.BuyPlayerList = list()
+ return
+
+ def GetLength(self):
+ length = 0
+ length += 1
+ length += 1
+ length += 1
+ for i in range(self.BuyPlayerCount):
+ length += self.BuyPlayerList[i].GetLength()
+
+ return length
+
+ def GetBuffer(self):
+ data = ''
+ data = CommFunc.WriteBYTE(data, self.Hour)
+ data = CommFunc.WriteBYTE(data, self.Minute)
+ data = CommFunc.WriteBYTE(data, self.BuyPlayerCount)
+ for i in range(self.BuyPlayerCount):
+ data = CommFunc.WriteString(data, self.BuyPlayerList[i].GetLength(), self.BuyPlayerList[i].GetBuffer())
+ return data
+
+ def OutputString(self):
+ DumpString = '''
+ Hour:%d,
+ Minute:%d,
+ BuyPlayerCount:%d,
+ BuyPlayerList:%s
+ '''\
+ %(
+ self.Hour,
+ self.Minute,
+ self.BuyPlayerCount,
+ "..."
+ )
+ return DumpString
+
+
+class tagGCCrossBattlefieldBuyInfo(Structure):
+ Head = tagHead()
+ HMCount = 0 #(BYTE HMCount)// 为0时清空重置,其他为增量更新
+ HMBuyList = list() #(vector<tagGCCrossBattlefieldBuyHM> HMBuyList)//购买场次列表
+ data = None
+
+ def __init__(self):
+ self.Clear()
+ self.Head.Cmd = 0xC0
+ self.Head.SubCmd = 0x09
+ return
+
+ def ReadData(self, _lpData, _pos=0, _Len=0):
+ self.Clear()
+ _pos = self.Head.ReadData(_lpData, _pos)
+ self.HMCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+ for i in range(self.HMCount):
+ temHMBuyList = tagGCCrossBattlefieldBuyHM()
+ _pos = temHMBuyList.ReadData(_lpData, _pos)
+ self.HMBuyList.append(temHMBuyList)
+ return _pos
+
+ def Clear(self):
+ self.Head = tagHead()
+ self.Head.Clear()
+ self.Head.Cmd = 0xC0
+ self.Head.SubCmd = 0x09
+ self.HMCount = 0
+ self.HMBuyList = list()
+ return
+
+ def GetLength(self):
+ length = 0
+ length += self.Head.GetLength()
+ length += 1
+ for i in range(self.HMCount):
+ length += self.HMBuyList[i].GetLength()
+
+ return length
+
+ def GetBuffer(self):
+ data = ''
+ data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+ data = CommFunc.WriteBYTE(data, self.HMCount)
+ for i in range(self.HMCount):
+ data = CommFunc.WriteString(data, self.HMBuyList[i].GetLength(), self.HMBuyList[i].GetBuffer())
+ return data
+
+ def OutputString(self):
+ DumpString = '''
+ Head:%s,
+ HMCount:%d,
+ HMBuyList:%s
+ '''\
+ %(
+ self.Head.OutputString(),
+ self.HMCount,
+ "..."
+ )
+ return DumpString
+
+
+m_NAtagGCCrossBattlefieldBuyInfo=tagGCCrossBattlefieldBuyInfo()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCCrossBattlefieldBuyInfo.Head.Cmd,m_NAtagGCCrossBattlefieldBuyInfo.Head.SubCmd))] = m_NAtagGCCrossBattlefieldBuyInfo
+
+
+#------------------------------------------------------
# C0 07 跨服排行榜信息 #tagGCCrossBillboardInfo
class tagGCCrossBillboardData(Structure):
@@ -40971,6 +41248,62 @@
#------------------------------------------------------
+# C1 07 跨服战场玩家信息 #tagMCCrossBattlefieldPlayerInfo
+
+class tagMCCrossBattlefieldPlayerInfo(Structure):
+ _pack_ = 1
+ _fields_ = [
+ ("Cmd", c_ubyte),
+ ("SubCmd", c_ubyte),
+ ("BuyOpenCountToday", c_ubyte), # 今日已购买开启战场次数
+ ("HighScoreToday", c_int), # 今日最高积分
+ ]
+
+ def __init__(self):
+ self.Clear()
+ self.Cmd = 0xC1
+ self.SubCmd = 0x07
+ return
+
+ def ReadData(self, stringData, _pos=0, _len=0):
+ self.Clear()
+ memmove(addressof(self), stringData[_pos:], self.GetLength())
+ return _pos + self.GetLength()
+
+ def Clear(self):
+ self.Cmd = 0xC1
+ self.SubCmd = 0x07
+ self.BuyOpenCountToday = 0
+ self.HighScoreToday = 0
+ return
+
+ def GetLength(self):
+ return sizeof(tagMCCrossBattlefieldPlayerInfo)
+
+ def GetBuffer(self):
+ return string_at(addressof(self), self.GetLength())
+
+ def OutputString(self):
+ DumpString = '''// C1 07 跨服战场玩家信息 //tagMCCrossBattlefieldPlayerInfo:
+ Cmd:%s,
+ SubCmd:%s,
+ BuyOpenCountToday:%d,
+ HighScoreToday:%d
+ '''\
+ %(
+ self.Cmd,
+ self.SubCmd,
+ self.BuyOpenCountToday,
+ self.HighScoreToday
+ )
+ return DumpString
+
+
+m_NAtagMCCrossBattlefieldPlayerInfo=tagMCCrossBattlefieldPlayerInfo()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCCrossBattlefieldPlayerInfo.Cmd,m_NAtagMCCrossBattlefieldPlayerInfo.SubCmd))] = m_NAtagMCCrossBattlefieldPlayerInfo
+
+
+#------------------------------------------------------
# C1 02 跨服PK玩家奖励记录 #tagMCCrossRealmPKAwardState
class tagMCCrossRealmPKAwardState(Structure):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/CrossBattle.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/CrossBattle.py
new file mode 100644
index 0000000..6fe7508
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/CrossBattle.py
@@ -0,0 +1,118 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package GM.Commands.CrossBattle
+#
+# @todo:跨服战场
+# @author hxp
+# @date 2022-01-06
+# @version 1.0
+#
+# 详细描述: 跨服战场
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2022-01-06 20:30"""
+#-------------------------------------------------------------------------------
+
+import GameWorld
+import GameLogic_CrossBattlefield
+import ShareDefine
+import ChConfig
+import FBCommon
+
+
+## 逻辑实现
+# @param curPlayer
+# @param cmdList 参数列表
+# @return None
+def OnExec(curPlayer, cmdList):
+
+ if not cmdList:
+ GameWorld.DebugAnswer(curPlayer, "--------------------------------")
+ GameWorld.DebugAnswer(curPlayer, "设置玩家击杀: CrossBattle 1 击杀数 [可选玩家ID]")
+ GameWorld.DebugAnswer(curPlayer, "设置玩家积分: CrossBattle 2 总积分 [可选玩家ID]")
+ GameWorld.DebugAnswer(curPlayer, "设置阵营击杀: CrossBattle 3 击杀数 [可选阵营ID]")
+ GameWorld.DebugAnswer(curPlayer, "设置阵营积分: CrossBattle 4 总积分 [可选阵营ID]")
+ GameWorld.DebugAnswer(curPlayer, "重置大奖信息: CrossBattle 5 [可选是否重新随机]")
+ GameWorld.DebugAnswer(curPlayer, "可选玩家/阵营ID没填则默认自身")
+ return
+
+ tick = GameWorld.GetGameWorld().GetTick()
+ playerID = curPlayer.GetPlayerID()
+ mapID = FBCommon.GetRecordMapID(GameWorld.GetMap().GetMapID())
+ value1 = cmdList[0]
+ if value1 in [1, 2, 3, 4, 5, 6] and not GameWorld.IsCrossServer() or mapID != ChConfig.Def_FBMapID_CrossBattlefield:
+ GameWorld.DebugAnswer(curPlayer, "该命令需在跨服战场使用CrossServer发送")
+ return
+
+ # 设置玩家击杀
+ if value1 == 1:
+ setCount = cmdList[1] if len(cmdList) > 1 else 1
+ tagPlayerID = cmdList[2] if len(cmdList) > 2 else playerID
+ battleObj = GameLogic_CrossBattlefield.GetBattlePlayerObj(tagPlayerID)
+ battleObj.killCount = setCount
+ GameWorld.DebugAnswer(curPlayer, "玩家(%s)击杀数: %s" % (tagPlayerID, battleObj.killCount))
+ FBCommon.NotifyCopyMapPlayerFBHelp(tick, GameLogic_CrossBattlefield.DoFBHelp, 0, GameLogic_CrossBattlefield.refreshFactionPlayer) # 触发刷新FBHelp
+ return
+
+ # 设置玩家积分
+ if value1 == 2:
+ setScore = cmdList[1] if len(cmdList) > 1 else 1
+ tagPlayerID = cmdList[2] if len(cmdList) > 2 else playerID
+ battleObj = GameLogic_CrossBattlefield.GetBattlePlayerObj(tagPlayerID)
+ battleObj.score = setScore
+ GameWorld.DebugAnswer(curPlayer, "玩家(%s)积分: %s" % (tagPlayerID, battleObj.score))
+ FBCommon.NotifyCopyMapPlayerFBHelp(tick, GameLogic_CrossBattlefield.DoFBHelp, 0, GameLogic_CrossBattlefield.refreshFactionPlayer) # 触发刷新FBHelp
+ return
+
+ # 设置阵营击杀
+ if value1 == 3:
+ setCount = cmdList[1] if len(cmdList) > 1 else 1
+ tagFaction = cmdList[2] if len(cmdList) > 2 else 0
+ if not tagFaction or tagFaction not in ShareDefine.CampTypeList:
+ battleObj = GameLogic_CrossBattlefield.GetBattlePlayerObj(playerID)
+ tagFaction = battleObj.faction
+ factionObj = GameLogic_CrossBattlefield.GetBattleFactionObj(tagFaction)
+ factionObj.killCount = setCount
+ GameWorld.DebugAnswer(curPlayer, "阵营(%s)击杀数: %s" % (tagFaction, factionObj.killCount))
+ FBCommon.NotifyCopyMapPlayerFBHelp(tick, GameLogic_CrossBattlefield.DoFBHelp, 0, GameLogic_CrossBattlefield.refreshFactionPlayer) # 触发刷新FBHelp
+ return
+
+ # 设置阵营积分
+ if value1 == 4:
+ setScore = cmdList[1] if len(cmdList) > 1 else 1
+ tagFaction = cmdList[2] if len(cmdList) > 2 else 0
+ if not tagFaction or tagFaction not in ShareDefine.CampTypeList:
+ battleObj = GameLogic_CrossBattlefield.GetBattlePlayerObj(playerID)
+ tagFaction = battleObj.faction
+ factionObj = GameLogic_CrossBattlefield.GetBattleFactionObj(tagFaction)
+ factionObj.score = setScore
+ GameWorld.DebugAnswer(curPlayer, "阵营(%s)积分: %s" % (tagFaction, factionObj.score))
+ FBCommon.NotifyCopyMapPlayerFBHelp(tick, GameLogic_CrossBattlefield.DoFBHelp, 0, GameLogic_CrossBattlefield.refreshFactionPlayer) # 触发刷新FBHelp
+ return
+
+ # 重置大奖信息
+ if value1 == 5:
+ isRand = cmdList[1] if len(cmdList) > 1 else 1
+ worldObj = GameLogic_CrossBattlefield.GetBattleWorld()
+ worldObj.superItemPlayerID = 0
+ worldObj.superItemPlayerName = ""
+ if isRand:
+ worldObj.RandSuperTask()
+ for faction in ShareDefine.CampTypeList:
+ if not faction:
+ continue
+ factionObj = GameLogic_CrossBattlefield.GetBattleFactionObj(faction)
+ factionObj.superTaskValue = 0
+ factionObj.superTaskFinishCount = 0
+ factionObj.setSuperTaskValueMax(worldObj)
+ for battleObj in factionObj.factionPlayerDict.values():
+ battleObj.superTaskValue = 0
+ battleObj.superTaskFinishCount = 0
+ battleObj.setSuperTaskValueMax(worldObj)
+ GameWorld.DebugAnswer(curPlayer, "重置大奖信息OK!")
+ FBCommon.NotifyCopyMapPlayerFBHelp(tick, GameLogic_CrossBattlefield.DoFBHelp, 0, GameLogic_CrossBattlefield.refreshFactionPlayer) # 触发刷新FBHelp
+ return
+
+ return
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py
index 57ac0d1..4a1a011 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py
@@ -1766,6 +1766,15 @@
#DebugLog("日期相差天数大于1,不同一天!")
return False
+def CheckTimeIsSameWeek(checkTime):
+ '''判断指定time值与当天时间对比是否为游戏内的同一周;特殊时间点过天后才算不同天
+ @return: 是否同一周
+ '''
+ checkDate = ChangeTimeNumToDatetime(checkTime)
+ checkWeek = datetime.datetime.isocalendar(checkDate)[1]
+ curWeek = GetWeekOfYear()
+ return checkWeek == curWeek
+
## 获取玩家的区服名,仅在跨服有效
# @param curPlayer 玩家实例
# @return: 区服名
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/FBCommon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/FBCommon.py
index 1957e35..5c8e794 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/FBCommon.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/FBCommon.py
@@ -917,7 +917,7 @@
gameFB = GameWorld.GetGameFB()
gameFB.SetFBStep(step)
gameFB.SetFBStepTick(tick)
- GameWorld.Log("SetFBStep %s, tick=%s" % (step, tick))
+ GameWorld.Log("SetFBStep %s, tick=%s" % (step, tick), GameWorld.GetGameWorld().GetPropertyID())
return
#---------------------------------------------------------------------
## 给客户端弹消息
@@ -2595,13 +2595,16 @@
def GetFBAreaRewardTechPoint(gameWorld, playerID):
return gameWorld.GetGameWorldDictByKey(ChConfig.Map_Player_AreaReward_GetTechPoint%playerID)
-def NotifyCopyMapPlayerFBHelp(tick, fbHelpFunc, interval=10000):
+def NotifyCopyMapPlayerFBHelp(tick, fbHelpFunc, interval=10000, befLogicFunc=None):
gameFB = GameWorld.GetGameFB()
lastTick = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_NotifyFBHelpTick)
if tick - lastTick < interval:
return
gameFB.SetGameFBDict(ChConfig.Def_FB_NotifyFBHelpTick, tick)
+ if befLogicFunc:
+ befLogicFunc(tick)
+
playerManager = GameWorld.GetMapCopyPlayerManager()
for index in xrange(playerManager.GetPlayerCount()):
curPlayer = playerManager.GetPlayerByIndex(index)
@@ -2612,9 +2615,9 @@
def GetCrossDynamicLineMapZoneID():
## 获取跨服动态线路地图本线路跨服分区
- return GameWorld.GetGameWorld().GetPropertyID() / 10000
+ return GameWorld.GetGameWorld().GetPropertyID() / 100000
def GetCrossDynamicLineMapFuncLineID():
## 获取跨服动态线路地图本线路功能线路ID
- return GameWorld.GetGameWorld().GetPropertyID() % 10000 / 10
+ return GameWorld.GetGameWorld().GetPropertyID() % 100000 / 100
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossBattlefield.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossBattlefield.py
new file mode 100644
index 0000000..5db11ee
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_CrossBattlefield.py
@@ -0,0 +1,890 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package GameWorldLogic.FBProcess.GameLogic_CrossBattlefield
+#
+# @todo:跨服战场
+# @author hxp
+# @date 2022-01-06
+# @version 1.0
+#
+# 详细描述: 跨服战场
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2022-01-06 20:30"""
+#-------------------------------------------------------------------------------
+
+import FBCommon
+import GameWorld
+import NPCCommon
+import PyGameData
+import IPY_GameWorld
+import IpyGameDataPY
+import PlayerActivity
+import GameWorldProcess
+import PlayerControl
+import ShareDefine
+import SkillCommon
+import BuffSkill
+import ChConfig
+import GameMap
+
+import operator
+import random
+import time
+
+#当前副本地图的状态
+(
+FB_Step_Open, # 地图开启
+FB_Step_Prepare, # 地图准备
+FB_Step_Fighting, # 战斗中
+FB_Step_LeaveTime, # 自由时间
+FB_Step_Over, # 副本关闭
+) = range(5)
+
+(
+Time_Prepare, # 副本准备时间 0
+Time_Fight, # 副本战斗时间 1
+Time_Leave, # 副本离开时间 2
+) = range(3)
+
+# 大奖任务类型
+SuperTaskList = (
+SuperTaskType_Kill, # 击杀 1
+SuperTaskType_Score, # 积分 2
+) = range(1, 1 + 2)
+
+GameFBData_BattleWorld = "BattleWorld"
+GameFBData_FactionInfo = "FactionInfo"
+GameFBData_PlayerInfo = "PlayerInfo"
+
+## 战场公共世界管理类
+class BattleWorld():
+
+ def __init__(self):
+ self.superItemInfo = [] # 大奖信息 [物品ID,个数,是否拍品]
+ self.superItemPlayerID = 0 # 大奖中奖者玩家ID
+ self.superItemPlayerName = "" # 大奖中奖者玩家名
+ self.superTaskType = 0 # 大奖任务类型
+ self.RandSuperTask()
+ return
+
+ def RandSuperTask(self):
+ # 随机生成大奖任务
+ fbPropertyID = GameWorld.GetGameWorld().GetPropertyID()
+ superItemWeightList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldAwardSuper", 1)
+ superItemInfo = GameWorld.GetResultByWeightList(superItemWeightList)
+ self.superItemInfo = superItemInfo if superItemInfo else []
+ self.superTaskType = random.choice(SuperTaskList)
+ GameWorld.Log("随机战场大奖: superTaskType=%s,superItemInfo=%s" % (self.superTaskType, self.superItemInfo), fbPropertyID)
+ return
+
+
+## 战斗实体基类
+class BattleBase(object):
+
+ BattleType_Player = "Player"
+ BattleType_Faction = "Faction"
+
+ def __init__(self, ID):
+ self.fbPropertyID = GameWorld.GetGameWorld().GetPropertyID()
+ self.battleType = ""
+ self.ID = ID
+ self.name = ""
+ self.score = 0 # 积分
+ self.scoreSortTime = 0 # 积分变更排序time值,用于同积分时,先到排名靠前
+ self.superTaskValue = 0 # 大奖任务当前进度
+ self.superTaskValueMax = 0 # 大奖任务完成需要的进度值
+ self.superTaskFinishCount = 0 # 大奖任务完成次数
+ self.killCount = 0 # 击杀数
+ self.continueKillCount = 0 # 连杀数
+ self.beKilledCount = 0 # 被击杀数
+ return
+
+ def addScore(self, worldObj, addValue):
+ self.score += addValue
+ calcTime = 3471264000 #GameWorld.ChangeTimeStrToNum("2080-01-01 00:00:00")
+ self.scoreSortTime = max(0, calcTime - int(time.time()))
+ GameWorld.DebugLog(" 增加积分: battleType=%s,ID=%s,addValue=%s,updScore=%s" % (self.battleType, self.ID, addValue, self.score), self.fbPropertyID)
+ self.addSuperTaskValue(worldObj, SuperTaskType_Score, addValue)
+ return
+
+ def addKillCount(self, worldObj, addCount):
+ self.killCount += addCount
+ self.continueKillCount += addCount # 同步增加连杀
+ self.addSuperTaskValue(worldObj, SuperTaskType_Kill, addCount)
+ return
+
+ def addBeKilledCount(self, addCount):
+ self.beKilledCount += addCount
+ self.continueKillCount = 0 # 被击杀时,连杀重置
+ return
+
+ def setSuperTaskValueMax(self, worldObj):
+ if worldObj == None:
+ worldObj = GetBattleWorld()
+ taskType = worldObj.superTaskType
+ if taskType == SuperTaskType_Kill:
+ superTaskValueMaxList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldAwardSuper2", 1)
+ elif taskType == SuperTaskType_Score:
+ superTaskValueMaxList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldAwardSuper2", 2)
+ else:
+ return
+
+ if self.battleType == self.BattleType_Player:
+ curValueMaxList = superTaskValueMaxList[0]
+ elif self.battleType == self.BattleType_Faction:
+ curValueMaxList = superTaskValueMaxList[1]
+ else:
+ return
+
+ if not curValueMaxList:
+ return
+
+ if self.superTaskFinishCount >= len(curValueMaxList):
+ valueMax = curValueMaxList[-1]
+ else:
+ valueMax = curValueMaxList[self.superTaskFinishCount]
+ self.superTaskValueMax = valueMax
+ GameWorld.Log(" 更新大奖任务进度完成所需值! battleType=%s,ID=%s,taskType=%s,superTaskFinishCount=%s,superTaskValueMax=%s"
+ % (self.battleType, self.ID, taskType, self.superTaskFinishCount, self.superTaskValueMax), self.fbPropertyID)
+ return
+
+ def addSuperTaskValue(self, worldObj, taskType, addValue):
+ if taskType != worldObj.superTaskType:
+ #GameWorld.DebugLog(" 非战场大奖任务类型,不处理! taskType=%s != superTaskType(%s)" % (taskType, worldObj.superTaskType), self.fbPropertyID)
+ return
+
+ if len(worldObj.superItemInfo) != 3:
+ GameWorld.ErrLog("大奖任务物品异常,不处理! taskType=%s,superItemInfo=%s" % (taskType, worldObj.superItemInfo), self.fbPropertyID)
+ return
+
+ if worldObj.superItemPlayerID:
+ GameWorld.DebugLog(" 大奖已经产出,不再处理! superItemPlayerID=%s" % worldObj.superItemPlayerID, self.fbPropertyID)
+ return
+
+ if not self.superTaskValueMax:
+ self.setSuperTaskValueMax(worldObj)
+ if not self.superTaskValueMax:
+ return
+
+ self.superTaskValue += addValue
+ if self.superTaskValue < self.superTaskValueMax:
+ GameWorld.DebugLog(" 更新大奖进度! battleType=%s,ID=%s,taskType=%s,addValue=%s,superTaskValue=%s < %s"
+ % (self.battleType, self.ID, taskType, addValue, self.superTaskValue, self.superTaskValueMax), self.fbPropertyID)
+ return
+ self.superTaskValue -= self.superTaskValueMax
+ self.superTaskFinishCount += 1
+ GameWorld.Log(" 完成大奖任务! battleType=%s,ID=%s,taskType=%s,superTaskFinishCount=%s"
+ % (self.battleType, self.ID, taskType, self.superTaskFinishCount), self.fbPropertyID)
+ self.setSuperTaskValueMax(worldObj)
+
+ superRate = self.getSuperItemRate()
+ tick = GameWorld.GetGameWorld().GetTick()
+ if not GameWorld.CanHappen(superRate):
+ GameWorld.Log(" 大奖没有中奖! battleType=%s,ID=%s,taskType=%s,superRate=%s"
+ % (self.battleType, self.ID, taskType, superRate), self.fbPropertyID)
+ FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0, refreshFactionPlayer)
+ return
+
+ superItemPlayerID = self.getSuperItemPlayerID()
+ GameWorld.Log(" 大奖中奖! battleType=%s,ID=%s,taskType=%s,superRate=%s,superItemPlayerID=%s"
+ % (self.battleType, self.ID, taskType, superRate, superItemPlayerID), self.fbPropertyID)
+ if not superItemPlayerID:
+ return
+ worldObj.superItemPlayerID = superItemPlayerID
+ itemID, itemCount = worldObj.superItemInfo[0], worldObj.superItemInfo[1]
+ battleObj = GetBattlePlayerObj(superItemPlayerID)
+ worldObj.superItemPlayerName = battleObj.name
+ PlayerControl.FBNotify("CrossBattlefieldSuperItemPlayer", [battleObj.faction, battleObj.name, itemID, itemCount])
+ FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0, refreshFactionPlayer)
+ return
+
+ def getSuperItemRate(self): return 0
+ def getSuperItemPlayerID(self): return 0
+
+## 战场阵营类
+class BattleFaction(BattleBase):
+
+ def __init__(self, faction):
+ super(BattleFaction, self).__init__(faction)
+ self.faction = faction
+ self.battleType = self.BattleType_Faction
+ self.factionPlayerDict = {} # {playerID:BattlePlayer, ...}
+ self.battlePlayerSortList = [] # 阵营积分排名玩家列表 [BattlePlayer, ...]
+ self.scoreKingIDList = [] # 前x名积分王ID列表 [playerID, ...] ,只算在线的,所以不一定是积分排名前x名
+
+ self.onlineFightPowerTotal = 0 # 在线人数总战力
+ self.onlinePlayerIDList = [] # 在线玩家ID列表 [playerID, ...]
+ self.setSuperTaskValueMax(None)
+ return
+
+ def getSuperItemRate(self):
+ single = IpyGameDataPY.GetFuncCfg("CrossBattlefieldAwardSuper", 3)
+ return single * len(self.onlinePlayerIDList)
+ def getSuperItemPlayerID(self):
+ if not self.onlinePlayerIDList:
+ return 0
+ return random.choice(self.onlinePlayerIDList)
+
+ def addScore(self, worldObj, addValue):
+ super(BattleFaction, self).addScore(worldObj, addValue)
+
+ battleOverScore = IpyGameDataPY.GetFuncCfg("CrossBattlefieldFB", 2)
+ if self.score < battleOverScore:
+ return
+
+ GameWorld.Log("阵营积分达到获胜积分,获胜! faction=%s,updScore=%s" % (self.faction, self.score), self.fbPropertyID)
+ tick = GameWorld.GetGameWorld().GetTick()
+ DoOver(self.faction, tick)
+ return
+
+## 战场玩家类
+class BattlePlayer(BattleBase):
+
+ def __init__(self, playerID):
+ super(BattlePlayer, self).__init__(playerID)
+ self.battleType = self.BattleType_Player
+ self.faction = 0
+ self.accID = ""
+ self.job = 1
+ self.realmLV = 0
+ self.fightPower = 0
+ self.highScoreToday = 0 # 本日最高积分
+ self.highScoreWeekTotal = 0 # 本周每日最高分累计
+ self.enterCountWeek = 0 # 本周累计进入次数
+ self.onlineCalcTick = 0 # 在线统计tick
+ self.onlineTimes = 0 # 活动累计在线时长,毫秒
+ self.setSuperTaskValueMax(None)
+ return
+
+ def getSuperItemRate(self): return IpyGameDataPY.GetFuncCfg("CrossBattlefieldAwardSuper", 2)
+ def getSuperItemPlayerID(self): return self.ID
+
+def GetBattleWorld():
+ worldObj = FBCommon.GetGameFBData(GameFBData_BattleWorld)
+ if not worldObj:
+ worldObj = BattleWorld()
+ FBCommon.SetGameFBData(GameFBData_BattleWorld, worldObj)
+ return worldObj
+
+def GetBattleFactionObj(faction):
+ factionObj = None
+ factionInfoDict = FBCommon.GetGameFBData(GameFBData_FactionInfo)
+ if faction in factionInfoDict:
+ factionObj = factionInfoDict[faction]
+ else:
+ factionObj = BattleFaction(faction)
+ factionInfoDict[faction] = factionObj
+ return factionObj
+
+def GetBattlePlayerObj(playerID):
+ playerObj = None
+ playerInfoDict = FBCommon.GetGameFBData(GameFBData_PlayerInfo)
+ if playerID in playerInfoDict:
+ playerObj = playerInfoDict[playerID]
+ else:
+ playerObj = BattlePlayer(playerID)
+ playerInfoDict[playerID] = playerObj
+ return playerObj
+
+def GetBFStepTime(): return IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldFB", 1) # 阶段时间
+
+def OnOpenFB(tick):
+ #fbPropertyID = GameWorld.GetGameWorld().GetPropertyID()
+ FBCommon.SetGameFBData(GameFBData_BattleWorld, None)
+ FBCommon.SetGameFBData(GameFBData_FactionInfo, {})
+ FBCommon.SetGameFBData(GameFBData_PlayerInfo, {})
+
+ GetBattleWorld()
+ GetBattleFactionObj(ShareDefine.CampType_Justice)
+ GetBattleFactionObj(ShareDefine.CampType_Evil)
+
+ FBCommon.SetFBStep(FB_Step_Prepare, tick)
+ return
+
+def OnCloseFB(tick):
+ GameWorld.GetGameWorld().SetPropertyID(0)
+ FBCommon.SetGameFBData(GameFBData_BattleWorld, None)
+ FBCommon.SetGameFBData(GameFBData_FactionInfo, None)
+ FBCommon.SetGameFBData(GameFBData_PlayerInfo, None)
+ return
+
+def OnEnterFBEvent(curPlayer, mapID, lineID, tick):
+ if GameWorld.IsCrossServer():
+ return True
+
+ playerID = curPlayer.GetPlayerID()
+ hmNum = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_CrossBattlefield)
+ for zoneID, hmCallTeamInfo in PyGameData.g_crossBattlefieldCallTeamInfo.items():
+ callTeamInfo = hmCallTeamInfo.get(hmNum, {})
+ for buyPlayerID, callTeam in callTeamInfo.items():
+ if playerID in callTeam["callPlayerIDList"]:
+ GameWorld.DebugLog(" 在战场召集队伍里,免费进入! zoneID=%s,hmNum=%s,buyPlayerID=%s,callPlayerIDList=%s"
+ % (zoneID, hmNum, buyPlayerID, callTeam["callPlayerIDList"]), playerID)
+ return True
+
+ remainCnt = PlayerActivity.GetDailyActionrRemainCnt(curPlayer, ShareDefine.DailyActionID_CrossBattlefield)
+ GameWorld.DebugLog(" 战场剩余可进入次数! hmNum=%s,remainCnt=%s" % (hmNum, remainCnt), playerID)
+ return remainCnt > 0
+
+def OnChangeMapAsk(ask, tick):
+ return IPY_GameWorld.cmeAccept
+
+##副本玩家进入点, 玩家分散在半径3格范围
+def OnGetFBEnterPos(curPlayer, mapID, lineId, ipyEnterPosInfo, tick):
+ return random.choice(IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldPos", 1))
+
+def DoEnterFB(curPlayer, tick):
+ gameFB = GameWorld.GetGameFB()
+ fbStep = gameFB.GetFBStep()
+ playerID = curPlayer.GetPlayerID()
+ fbPropertyID = GameWorld.GetGameWorld().GetPropertyID()
+
+ if fbStep not in [FB_Step_Prepare, FB_Step_Fighting]:
+ GameWorld.Log("DoEnterFB... fbPropertyID=%s,fbStep=%s PlayerLeaveFB" % (fbPropertyID, fbStep), playerID)
+ PlayerControl.PlayerLeaveFB(curPlayer)
+ return
+
+ fightPower = PlayerControl.GetFightPower(curPlayer)
+ battleObj = GetBattlePlayerObj(playerID)
+ battleObj.job = curPlayer.GetJob()
+ battleObj.accID = curPlayer.GetAccID()
+ battleObj.name = curPlayer.GetPlayerName()
+ battleObj.realmLV = curPlayer.GetOfficialRank()
+ battleObj.fightPower = fightPower
+ battleObj.highScoreToday = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Battlefield_HighScoreToday)
+ battleObj.highScoreWeekTotal = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Battlefield_HighScoreTotalWeek)
+ battleObj.enterCountWeek = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Battlefield_EnterCountWeek)
+
+ GameWorld.Log("DoEnterFB... fbPropertyID=%s,fbStep=%s,faction=%s" % (fbPropertyID, fbStep, battleObj.faction), playerID)
+
+ if fbStep == FB_Step_Prepare:
+ notify_tick = GetBFStepTime()[Time_Prepare] * 1000 - (tick - GameWorld.GetGameFB().GetFBStepTick())
+ curPlayer.Sync_TimeTick(IPY_GameWorld.tttWaitStart, 0, max(notify_tick, 0), True)
+
+ elif fbStep == FB_Step_Fighting:
+ notify_tick = GetBFStepTime()[Time_Fight] * 1000 - (tick - GameWorld.GetGameFB().GetFBStepTick())
+ curPlayer.Sync_TimeTick(IPY_GameWorld.tttTowerTake, 0, max(notify_tick, 0), True)
+ isToSafePos = not battleObj.faction
+ allotPlayerFaction(playerID, fightPower, curPlayer, isToSafePos, tick)
+
+ return
+
+##获得副本帮助信息, 用于通知阵营比分条
+def DoFBHelp(curPlayer, tick):
+ #gameWorld = GameWorld.GetGameWorld()
+ playerID = curPlayer.GetPlayerID()
+
+ worldObj = GetBattleWorld()
+ battleObj = GetBattlePlayerObj(playerID)
+
+ playerInfo = {"score":battleObj.score, "superTaskValue":battleObj.superTaskValue,
+ "superTaskValueMax":battleObj.superTaskValueMax, "superTaskFinishCount":battleObj.superTaskFinishCount}
+
+ factionInfo = {}
+ for faction in [ShareDefine.CampType_Justice, ShareDefine.CampType_Evil]:
+ factionObj = GetBattleFactionObj(faction)
+ factionInfo[str(faction)] = {"score":factionObj.score, "superTaskValue":factionObj.superTaskValue,
+ "superTaskValueMax":factionObj.superTaskValueMax, "superTaskFinishCount":factionObj.superTaskFinishCount}
+
+ worldInfo = {"superTaskType":worldObj.superTaskType, "superItemPlayerName":worldObj.superItemPlayerName, "superItemInfo":worldObj.superItemInfo}
+
+ helpDict = {"playerInfo":playerInfo, "factionInfo":factionInfo, "worldInfo":worldInfo}
+ #GameWorld.DebugLog("DoFBHelp %s" % helpDict, playerID)
+ FBCommon.Notify_FBHelp(curPlayer, helpDict)
+ return
+
+##玩家退出副本
+def DoExitFB(curPlayer, tick):
+ gameFB = GameWorld.GetGameFB()
+ fbStep = gameFB.GetFBStep()
+ if fbStep != FB_Step_Fighting:
+ return
+
+ playerID = curPlayer.GetPlayerID()
+ faction = curPlayer.GetFaction()
+ fightPower = PlayerControl.GetFightPower(curPlayer)
+
+ fbPropertyID = GameWorld.GetGameWorld().GetPropertyID()
+ GameWorld.Log("DoExitFB... playerID=%s,faction=%s,fightPower=%s,fbStep=%s"
+ % (playerID, faction, fightPower, fbStep), fbPropertyID)
+
+ battleObj = GetBattlePlayerObj(playerID)
+ battleObj.onlineCalcTick = 0
+
+ if not faction:
+ return
+
+ factionObj = GetBattleFactionObj(faction)
+ factionObj.onlineFightPowerTotal = max(0, factionObj.onlineFightPowerTotal - fightPower)
+ if playerID in factionObj.onlinePlayerIDList:
+ factionObj.onlinePlayerIDList.remove(playerID)
+
+ GameWorld.Log(" faction=%s,onlineFightPowerTotal=%s,onlinePlayerIDList=%s"
+ % (faction, factionObj.onlineFightPowerTotal, factionObj.onlinePlayerIDList), fbPropertyID)
+ return
+
+##玩家主动离开副本.
+def DoPlayerLeaveFB(curPlayer, tick):
+ return
+
+##副本总逻辑计时器
+# @param tick 时间戳
+# @return 无意义
+# @remarks 副本总逻辑计时器
+def OnProcess(tick):
+ fbStep = GameWorld.GetGameFB().GetFBStep()
+
+ # 副本准备
+ if fbStep == FB_Step_Prepare:
+ __DoLogic_FB_Prepare(tick)
+
+ # 副本进行中
+ elif fbStep == FB_Step_Fighting:
+ __DoLogic_FB_Fighting(tick)
+
+ # 副本结束
+ elif fbStep == FB_Step_LeaveTime:
+ __DoLogic_FB_Over(tick)
+
+ return
+
+def __DoLogic_FB_Prepare(tick):
+
+ remaindTick = GetBFStepTime()[Time_Prepare] * 1000 - (tick - GameWorld.GetGameFB().GetFBStepTick())
+ if remaindTick > 0:
+ return
+
+ FBCommon.SetFBStep(FB_Step_Fighting, tick)
+
+ playerInfoDict = {}
+ playerInfoList = []
+ fightTime = GetBFStepTime()[Time_Fight] * 1000
+ playerManager = GameWorld.GetMapCopyPlayerManager()
+ for index in xrange(playerManager.GetPlayerCount()):
+ curPlayer = playerManager.GetPlayerByIndex(index)
+ playerID = curPlayer.GetPlayerID()
+ if not playerID:
+ continue
+ curPlayer.Sync_TimeTick(IPY_GameWorld.tttTowerTake, 0, fightTime, True)
+
+ fightPower = PlayerControl.GetFightPower(curPlayer)
+
+ playerInfo = {"playerID":playerID, "fightPower":fightPower, "curPlayer":curPlayer}
+ playerInfoList.append(playerInfo)
+ playerInfoDict[playerID] = playerInfo
+
+# ##--------- 山寨分配测试代码 --------------
+# for i in xrange(15):
+# playerID = i + 1
+# fightPower = random.randint(100000, 10000000000)
+# playerInfoList.append({"playerID":playerID, "fightPower":fightPower, "curPlayer":None})
+# ##--------- 山寨分配测试代码 --------------
+
+ # 按战力排序
+ # 当超过副本下限人数时,往人数低的阵营划分; 否则 往战力低的阵营划分
+ playerInfoList.sort(key=operator.itemgetter("fightPower"), reverse=True)
+
+ isToSafePos = True
+
+ # 先分配召集队伍
+ fbPropertyID = GameWorld.GetGameWorld().GetPropertyID()
+ zoneID = FBCommon.GetCrossDynamicLineMapZoneID()
+ hmNum = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_CrossBattlefield)
+ hmCallTeamInfo = PyGameData.g_crossBattlefieldCallTeamInfo.get(zoneID, {})
+ callTeamInfo = hmCallTeamInfo.get(hmNum, {})
+
+ GameWorld.Log("准备开始战斗,分配阵营: zoneID=%s,hmNum=%s,callTeamInfo=%s,playerCountTotal=%s" % (zoneID, hmNum, callTeamInfo, len(playerInfoList)), fbPropertyID)
+ callPlayerIDList = []
+ for callTeam in callTeamInfo.values():
+ for playerID in callTeam["callPlayerIDList"]:
+ callPlayerIDList.append(playerID)
+ if playerID not in playerInfoDict:
+ continue
+ playerInfo = playerInfoDict[playerID]
+ playerID = playerInfo["playerID"]
+ fightPower = playerInfo["fightPower"]
+ curPlayer = playerInfo["curPlayer"]
+ allotPlayerFaction(playerID, fightPower, curPlayer, isToSafePos, tick)
+
+ for playerInfo in playerInfoList:
+ playerID = playerInfo["playerID"]
+ fightPower = playerInfo["fightPower"]
+ curPlayer = playerInfo["curPlayer"]
+ if playerID in callPlayerIDList:
+ continue
+ allotPlayerFaction(playerID, fightPower, curPlayer, isToSafePos, tick)
+
+ return
+
+def allotPlayerFaction(playerID, fightPower, curPlayer, isToSafePos, tick):
+ ## 分配玩家阵营
+
+ zoneID = FBCommon.GetCrossDynamicLineMapZoneID()
+ hmNum = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_CrossBattlefield)
+ hmCallTeamInfo = PyGameData.g_crossBattlefieldCallTeamInfo.get(zoneID, {})
+ callTeamInfo = hmCallTeamInfo.get(hmNum, {})
+
+ callFaction = None
+ for callTeam in callTeamInfo.values():
+ if playerID in callTeam["callPlayerIDList"]:
+ callFaction = callTeam["factionID"]
+ break
+
+ fbPropertyID = GameWorld.GetGameWorld().GetPropertyID()
+ battleObj = GetBattlePlayerObj(playerID)
+ faction = battleObj.faction
+ if callFaction:
+ faction = callFaction # 召集阵营为固定阵营
+
+ if not faction:
+ jFactionObj = GetBattleFactionObj(ShareDefine.CampType_Justice)
+ eFactionObj = GetBattleFactionObj(ShareDefine.CampType_Evil)
+
+ onlinePlayerTotal = len(jFactionObj.onlinePlayerIDList) + len(eFactionObj.onlinePlayerIDList)
+ fbPlayerCountSet = IpyGameDataPY.GetFuncCfg("CrossBattlefieldFB", 3) # 副本下限人数设定
+
+ # 当超过副本下限人数时,往人数低的阵营划分; 否则 往战力低的阵营划分
+ if onlinePlayerTotal > fbPlayerCountSet:
+ faction = ShareDefine.CampType_Justice if len(jFactionObj.onlinePlayerIDList) <= len(eFactionObj.onlinePlayerIDList) else ShareDefine.CampType_Evil
+ else:
+ faction = ShareDefine.CampType_Justice if jFactionObj.onlineFightPowerTotal <= eFactionObj.onlineFightPowerTotal else ShareDefine.CampType_Evil
+
+ battleObj.faction = faction
+ battleObj.onlineCalcTick = tick
+
+ factionObj = GetBattleFactionObj(faction)
+
+ if playerID not in factionObj.factionPlayerDict:
+ factionObj.factionPlayerDict[playerID] = battleObj
+
+ # 在线才会添加,所以处理在线相关
+ factionObj.onlineFightPowerTotal += fightPower
+ if playerID not in factionObj.onlinePlayerIDList:
+ factionObj.onlinePlayerIDList.append(playerID)
+
+ GameWorld.Log(" 分配阵营: callFaction=%s,faction=%s,playerID=%s,fightPower=%s,onlineFightPowerTotal=%s,onlinePlayerIDList=%s,isToSafePos=%s"
+ % (callFaction, faction, playerID, fightPower, factionObj.onlineFightPowerTotal, factionObj.onlinePlayerIDList, isToSafePos), fbPropertyID)
+
+ if curPlayer:
+ curPlayer.SetFaction(faction)
+ if isToSafePos:
+ __RandFactionSafeArea(curPlayer)
+
+ return
+
+## 重置副本复活玩家坐标点
+def OnResetFBRebornPlacePos(curPlayer, rebornPlace, tick):
+ __RandFactionSafeArea(curPlayer)
+ return
+
+def __RandFactionSafeArea(curPlayer):
+ faction = curPlayer.GetFaction()
+ factionSafeAreaRandPosList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldPos", 2)
+ if faction and faction <= len(factionSafeAreaRandPosList):
+ safePosX, safePosY, radius = random.choice(factionSafeAreaRandPosList[faction - 1])
+ posPoint = GameMap.GetEmptyPlaceInArea(safePosX, safePosY, radius)
+ posX, posY = posPoint.GetPosX(), posPoint.GetPosY()
+ else:
+ posX, posY = curPlayer.GetPosX(), curPlayer.GetPosY()
+ curPlayer.ResetPos(posX, posY)
+ return
+
+def __DoLogic_FB_Fighting(tick):
+
+ remaindTick = GetBFStepTime()[Time_Fight] * 1000 - (tick - GameWorld.GetGameFB().GetFBStepTick())
+ if remaindTick > 0:
+ FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 5000, refreshFactionPlayer)
+ return
+
+ jFactionObj = GetBattleFactionObj(ShareDefine.CampType_Justice)
+ eFactionObj = GetBattleFactionObj(ShareDefine.CampType_Evil)
+ jFactionScore = jFactionObj.score
+ eFactionScore = eFactionObj.score
+
+ winnerFaction = ShareDefine.CampType_Justice if jFactionScore >= eFactionScore else ShareDefine.CampType_Evil
+ fbPropertyID = GameWorld.GetGameWorld().GetPropertyID()
+ GameWorld.Log("副本时间到,积分高的阵营获胜! winnerFaction=%s,jFactionScore=%s,eFactionScore=%s"
+ % (winnerFaction, jFactionScore, eFactionScore), fbPropertyID)
+ DoOver(winnerFaction, tick)
+ return
+
+def __DoLogic_FB_Over(tick):
+ remaindTick = GetBFStepTime()[Time_Leave] * 1000 - (tick - GameWorld.GetGameFB().GetFBStepTick())
+ if remaindTick > 0:
+ return
+
+ GameWorldProcess.CloseFB(tick)
+ FBCommon.SetFBStep(FB_Step_Over, tick)
+ return
+
+##处理副本中杀死玩家逻辑
+def DoFBOnKill_Player(curPlayer, defender, tick):
+ playerID = curPlayer.GetPlayerID()
+ tagPlayerID = defender.GetPlayerID()
+ faction = curPlayer.GetFaction()
+ tagFaction = defender.GetFaction()
+ curBattleObj = GetBattlePlayerObj(playerID)
+ tagBattleObj = GetBattlePlayerObj(tagPlayerID)
+ if not faction or not tagFaction:
+ GameWorld.ErrLog("击杀玩家没有阵营! playerID=%s,faction=%s,tagPlayerID=%s,tagFaction=%s"
+ % (playerID, faction, tagPlayerID, tagFaction), playerID)
+ return
+
+ worldObj = GetBattleWorld()
+ curFactionObj = GetBattleFactionObj(faction)
+ tagFactionObj = GetBattleFactionObj(tagFaction)
+
+ GameWorld.DebugLog("击杀玩家! playerID=%s,faction=%s,tagPlayerID=%s,tagFaction=%s"
+ % (playerID, faction, tagPlayerID, tagFaction), playerID)
+
+ # 1. 处理玩家
+ killPlayerScore = IpyGameDataPY.GetFuncCfg("CrossBattlefieldKill", 1)
+ addPlayerScore = 0
+ addPlayerScore += killPlayerScore
+ #addPlayerScore += ... # 其他加分
+ curBattleObj.addScore(worldObj, addPlayerScore)
+ curBattleObj.addKillCount(worldObj, 1)
+ tagBattleObj.addBeKilledCount(1)
+
+ # 2. 处理阵营
+ addFactionScore = 0
+ addFactionScore += addPlayerScore # 阵营积分同步增加玩家得分
+ # 击杀积分王,阵营积分额外增加
+ for index, kingID in enumerate(tagFactionObj.scoreKingIDList):
+ if kingID == tagPlayerID:
+ killScoreKingScoreList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldScoreKing", 3)
+ if index < len(killScoreKingScoreList):
+ kingScore = killScoreKingScoreList[index]
+ addFactionScore += kingScore
+ GameWorld.DebugLog(" 对方是积分王,阵营额外获得积分: index=%s,kingScore=%s" % (index, kingScore), playerID)
+
+ killScoreKingNotifyList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldScoreKing", 4)
+ if index < len(killScoreKingNotifyList):
+ msgMark = killScoreKingNotifyList[index]
+ defMapID = defender.GetMapID()
+ defPosX = defender.GetPosX()
+ defPosY = defender.GetPosY()
+ PlayerControl.FBNotify(msgMark, [faction, curPlayer.GetPlayerName(), tagFaction, defender.GetPlayerName(), defMapID, defPosX, defPosY])
+
+ break
+ #addFactionScore += ... # 其他加分
+ curFactionObj.addScore(worldObj, addFactionScore)
+ curFactionObj.addKillCount(worldObj, 1)
+ tagFactionObj.addBeKilledCount(1)
+ return True
+
+def refreshFactionPlayer(tick):
+ ## 刷新阵营玩家相关
+
+ scoreKingScoreMin = IpyGameDataPY.GetFuncCfg("CrossBattlefieldScoreKing", 1)
+ scoreKingBuffIDList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldScoreKing", 2)
+ scoreKingCount = len(scoreKingBuffIDList)
+
+ copyMapMgr = GameWorld.GetMapCopyPlayerManager()
+ for faction in [ShareDefine.CampType_Justice, ShareDefine.CampType_Evil]:
+ factionObj = GetBattleFactionObj(faction)
+
+ befKingIDList = factionObj.scoreKingIDList
+
+ factionObj.battlePlayerSortList = factionObj.factionPlayerDict.values()
+ factionObj.battlePlayerSortList.sort(key=operator.attrgetter("score", "scoreSortTime"), reverse=True)
+
+ aftKingIDList = []
+ aftKingObjList = []
+ for batObj in factionObj.battlePlayerSortList:
+ playerID = batObj.ID
+ curPlayer = copyMapMgr.FindPlayerByID(playerID)
+ if not curPlayer:
+ continue
+
+ if batObj.onlineCalcTick:
+ batObj.onlineTimes += max(0, tick - batObj.onlineCalcTick)
+ batObj.onlineCalcTick = tick
+
+ if batObj.score < scoreKingScoreMin:
+ continue
+
+ if len(aftKingIDList) < scoreKingCount:
+ aftKingIDList.append(playerID)
+ aftKingObjList.append([curPlayer, batObj])
+
+ if befKingIDList == aftKingIDList:
+ #GameWorld.DebugLog(" 阵营积分王不变: faction=%s,befKingIDList=%s,aftKingIDList=%s" % (faction, befKingIDList, aftKingIDList))
+ continue
+
+ GameWorld.DebugLog(" 阵营积分王变更: faction=%s,befKingIDList=%s,aftKingIDList=%s" % (faction, befKingIDList, aftKingIDList))
+
+ # 更新buff
+ for index, objInfo in enumerate(aftKingObjList):
+ curPlayer, batObj = objInfo
+
+ playerID = curPlayer.GetPlayerID()
+
+ addBuffID = scoreKingBuffIDList[index] if index < len(scoreKingBuffIDList) else 0
+
+ if playerID in befKingIDList:
+ befIndex = befKingIDList.index(playerID)
+ if index == befIndex:
+ GameWorld.DebugLog(" 积分王名次不变,不需要变更buff! index=%s" % index, playerID)
+ continue
+ delBuffID = scoreKingBuffIDList[befIndex] if befIndex < len(scoreKingBuffIDList) else 0
+ if delBuffID:
+ GameWorld.DebugLog(" 积分王名次变更! 删除旧buff! befIndex=%s,delBuffID=%s" % (befIndex, delBuffID), playerID)
+ BuffSkill.DelBuffBySkillID(curPlayer, delBuffID, tick)
+
+ if addBuffID:
+ GameWorld.DebugLog(" 积分王名次变更! 添加新buff! index=%s,addBuffID=%s" % (index, addBuffID), playerID)
+ SkillCommon.AddBuffBySkillType_NoRefurbish(curPlayer, addBuffID, tick)
+
+ for befIndex, playerID in enumerate(befKingIDList):
+ if playerID in aftKingIDList:
+ continue
+ delBuffID = scoreKingBuffIDList[befIndex] if befIndex < len(scoreKingBuffIDList) else 0
+ if delBuffID:
+ GameWorld.DebugLog(" 积分王被挤掉! 删除旧buff! befIndex=%s,delBuffID=%s" % (befIndex, delBuffID), playerID)
+ BuffSkill.DelBuffBySkillID(curPlayer, delBuffID, tick)
+
+ factionObj.scoreKingIDList = aftKingIDList
+
+ return
+
+def DoOver(winnerFaction, tick):
+ fbPropertyID = GameWorld.GetGameWorld().GetPropertyID()
+ zoneID = FBCommon.GetCrossDynamicLineMapZoneID()
+ funcLineID = FBCommon.GetCrossDynamicLineMapFuncLineID()
+ GameWorld.Log("跨服战场结算! zoneID=%s,funcLineID=%s,winnerFaction=%s" % (zoneID, funcLineID, winnerFaction), fbPropertyID)
+
+ FBCommon.NotifyCopyMapPlayerFBHelp(tick, DoFBHelp, 0, refreshFactionPlayer) # 结算前强刷一次
+
+ #awardOnlineTimes = IpyGameDataPY.GetFuncCfg("CrossBattlefieldAward", 1) # 结算奖励需参与活动时长,秒钟
+
+ #gameFB = GameWorld.GetGameFB()
+ worldObj = GetBattleWorld()
+ leaveTime = GetBFStepTime()[Time_Leave] * 1000
+ copyMapMgr = GameWorld.GetMapCopyPlayerManager()
+
+ superItemPlayerID = worldObj.superItemPlayerID
+ superItemPlayerName = worldObj.superItemPlayerName
+ # 没人中奖则随机给其中一位在线的玩家
+ if not superItemPlayerID:
+ onlinePlayerIDList = []
+ for index in xrange(copyMapMgr.GetPlayerCount()):
+ curPlayer = copyMapMgr.GetPlayerByIndex(index)
+ playerID = curPlayer.GetPlayerID()
+ if not playerID:
+ continue
+ onlinePlayerIDList.append(playerID)
+ if onlinePlayerIDList:
+ superItemPlayerID = random.choice(onlinePlayerIDList)
+ superPlayerObj = GetBattlePlayerObj(superItemPlayerID)
+ superItemPlayerName = superPlayerObj.name
+ worldObj.superItemPlayerID = superItemPlayerID
+ worldObj.superItemPlayerName = superItemPlayerName
+ GameWorld.Log("没人中大奖,则随机其中一位在线玩家! superItemPlayerID=%s,onlinePlayerIDList=%s"
+ % (superItemPlayerID, onlinePlayerIDList), fbPropertyID)
+
+ GameWorld.Log("大奖获奖信息: superItemInfo=%s,superItemPlayerID=%s" % (worldObj.superItemInfo, superItemPlayerID), fbPropertyID)
+
+ hmNum = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_DailyActionState % ShareDefine.DailyActionID_CrossBattlefield)
+ hmCallTeamInfo = PyGameData.g_crossBattlefieldCallTeamInfo.get(zoneID, {})
+ callTeamInfo = hmCallTeamInfo.get(hmNum, {})
+ allCallPlayerIDList = []
+ for callTeam in callTeamInfo.values():
+ allCallPlayerIDList.extend(callTeam["callPlayerIDList"])
+
+ scoreKingID, scoreKingName = 0, "" # 本场积分王: 获胜方在线第一名积分
+ battlePlayerList = []
+ for faction in [ShareDefine.CampType_Justice, ShareDefine.CampType_Evil]:
+ factionObj = GetBattleFactionObj(faction)
+ factionScore = factionObj.score
+ isWinner = (faction == winnerFaction)
+ scoreKingIDList = factionObj.scoreKingIDList
+ GameWorld.Log("结算阵营! faction=%s,factionScore=%s,isWinner=%s,playerCount=%s,onlineFightPowerTotal=%s,onlinePlayerIDList=%s,scoreKingIDList=%s"
+ % (faction, factionScore, isWinner, len(factionObj.battlePlayerSortList), factionObj.onlineFightPowerTotal, factionObj.onlinePlayerIDList, scoreKingIDList), fbPropertyID)
+ if isWinner and scoreKingIDList:
+ scoreKingID = scoreKingIDList[0]
+ scoreKingObj = GetBattlePlayerObj(scoreKingID)
+ scoreKingName = scoreKingObj.name
+
+ rankPlayerList = []
+ for battleObj in factionObj.battlePlayerSortList[:20]:
+ rankPlayerList.append({"Name":battleObj.name, "Job":battleObj.job, "Score":battleObj.score})
+
+ overDict = {"rankPlayerList":rankPlayerList, "faction":faction, "superItemPlayerName":superItemPlayerName, "scoreKingName":scoreKingName}
+ for rank, battleObj in enumerate(factionObj.battlePlayerSortList, 1):
+ playerID = battleObj.ID
+ score = battleObj.score
+ job = battleObj.job
+ realmLV = battleObj.realmLV
+ name = battleObj.name
+ highScoreToday = battleObj.highScoreToday
+ highScoreWeekTotal = battleObj.highScoreWeekTotal
+ enterCountWeek = battleObj.enterCountWeek
+ onlineTimes = battleObj.onlineTimes / 1000
+ GameWorld.Log(" rank=%s,playerID=%s,score=%s,fightPower=%s,onlineTimes=%s,accID=%s"
+ % (rank, playerID, score, battleObj.fightPower, onlineTimes, battleObj.accID), fbPropertyID)
+
+ #服务端暂不做参与时长奖励限制
+ #if onlineTimes < awardOnlineTimes:
+ # GameWorld.Log(" 活动时长不足,不给奖励! faction=%s,playerID=%s,isWinner=%s" % (faction, playerID, isWinner), fbPropertyID)
+ # continue
+
+ isCallEnter = 1 if playerID in allCallPlayerIDList else 0 # 是否召集进入的
+ playerInfo = [faction, rank, playerID, job, realmLV, name, score, highScoreToday, highScoreWeekTotal, enterCountWeek, isCallEnter]
+ battlePlayerList.append(playerInfo)
+
+ player = copyMapMgr.FindPlayerByID(playerID)
+ if not player:
+ continue
+ player.Sync_TimeTick(IPY_GameWorld.tttLeaveMap, 0, leaveTime, True)
+
+ lineID = 0
+ overDict.update({FBCommon.Over_rank:rank, "score":score, "highScoreToday":highScoreToday, "onlineTimes":onlineTimes})
+ FBCommon.NotifyFBOver(player, ChConfig.Def_FBMapID_CrossBattlefield, lineID, isWinner, overDict)
+
+ GameWorld.Log("本场最终结算积分王: scoreKingID=%s" % scoreKingID, fbPropertyID)
+
+ # 同步GameServer 比赛结果
+ superItemInfo = worldObj.superItemInfo
+ msgInfo = str([fbPropertyID, zoneID, funcLineID, winnerFaction, superItemInfo, superItemPlayerID, superItemPlayerName, scoreKingID, scoreKingName, battlePlayerList])
+ GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "CrossBattlefieldOver", msgInfo, len(msgInfo))
+
+ FBCommon.SetFBStep(FB_Step_LeaveTime, tick)
+ return
+
+## 执行副本杀怪逻辑
+def DoFB_Player_KillNPC(curPlayer, curNPC, tick):
+ #curNPC.SetDict(ChConfig.Def_NPC_Dict_Faction, 0)
+ npcFaction = NPCCommon.GetFaction(curNPC)
+ if npcFaction:
+ __OnPlayerKillOtherFactionRobot(curPlayer, npcFaction, tick)
+ else:
+ __OnPlayerKillNeutralNPC(curPlayer, curNPC, tick)
+ return
+
+def __OnPlayerKillOtherFactionRobot(curPlayer, npcFaction, tick):
+ ## 玩家击杀其他阵营机器人玩家
+ return
+
+def __OnPlayerKillNeutralNPC(curPlayer, curNPC, tick):
+ ## 玩家击杀中立怪物
+ return
+
+## 检查是否可攻击, 主判定不可攻击的情况,其他逻辑由外层决定
+def CheckCanAttackTagObjInFB(attacker, defender):
+ gameFB = GameWorld.GetGameFB()
+ if gameFB.GetFBStep() != FB_Step_Fighting:
+ return False
+ return True
+
+## 玩家攻击玩家是否有惩罚
+def DoFBAttackHasPunish(atkPlayer, defPlayer):
+ return False
+
+## 是否副本复活
+def OnPlayerReborn():
+ return True
+
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldProcess.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldProcess.py
index bfea990..2fa2745 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldProcess.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldProcess.py
@@ -184,7 +184,8 @@
return
def GameServer_DynamicLineMapStateChange(gameWorld, state):
- if gameWorld.GetMapID() not in ChConfig.Def_CrossDynamicLineMap:
+ mapID = FBCommon.GetRecordMapID(gameWorld.GetMapID())
+ if mapID not in ChConfig.Def_CrossDynamicLineMap:
return
realMapID, copyMapID = gameWorld.GetRealMapID(), gameWorld.GetCopyMapID()
@@ -620,7 +621,8 @@
msgInfo = str([gameWorld.GetMapID(), gameWorld.GetLineID(), gameWorld.GetRealMapID(), gameWorld.GetCopyMapID()])
GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "CommMapServerInitOK", msgInfo, len(msgInfo))
- if gameWorld.GetMapID() in ChConfig.Def_CrossDynamicLineMap and gameWorld.GetCopyMapID() == gameWorld.GetGameWorldCount() - 1:
+ dataMapID = FBCommon.GetRecordMapID(gameWorld.GetMapID())
+ if dataMapID in ChConfig.Def_CrossDynamicLineMap and gameWorld.GetCopyMapID() == gameWorld.GetGameWorldCount() - 1:
msgInfo = str([gameWorld.GetRealMapID(), gameWorld.GetGameWorldCount()])
GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "DynamicLineMapInitOK", msgInfo, len(msgInfo))
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
index 40400c8..5eda952 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NPC/NPCCommon.py
@@ -135,7 +135,9 @@
def SetSuppressFightPower(curNPC, value): return curNPC.SetThunderDef(min(value, ShareDefine.Def_UpperLimit_DWord))
def GetCommendFightPower(curNPC): return curNPC.GetFireDef() # 火防代表推荐战力
def GetDropOwnerType(curNPC): return curNPC.GetThunderAtk() # 雷攻代表掉落归属类型
-def GetFaction(curNPC): return curNPC.GetCountry()
+def GetFaction(curNPC):
+ faction = curNPC.GetDictByKey(ChConfig.Def_NPC_Dict_Faction)
+ return faction if faction else curNPC.GetCountry()
def GetSkillAtkRate(curNPC): return curNPC.GetPoisionAtk() # 毒攻代表NPC技能伤害加成万分率
def GetFinalHurt(curNPC): return curNPC.GetFireAtk() # 火攻代表NPC最终固定伤害加成, 普攻也有效果
def SetFinalHurt(curNPC, hurt): return curNPC.SetFireAtk(hurt) # 火攻代表NPC最终固定伤害加成, 普攻也有效果
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
index 827d9b2..f6781a1 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
@@ -73,6 +73,7 @@
import PlayerGatherSoul
import PlayerFairyDomain
import PlayerCrossRealmPK
+import PlayerCrossBattlefield
import GameFuncComm
import PlayerMagicWeapon
import GameLogic_TrialTower
@@ -713,6 +714,7 @@
# 跨服PK
PlayerCrossRealmPK.DoPlayerLogin(curPlayer)
+ PlayerCrossBattlefield.DoPlayerLogin(curPlayer)
# 幸运云购
PlayerLuckyCloudBuy.OnPlayerLogin(curPlayer)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerActivity.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerActivity.py
index 827fb21..419d510 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerActivity.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerActivity.py
@@ -82,6 +82,9 @@
curPBCnt = __GetPDictValue(curPlayer, key) #单次进度值
if curPBCnt:
__SetPDictValue(curPlayer, key, 0)
+ key = ChConfig.Def_PDict_Activity_AddTotal % ipyData.GetID()
+ if __GetPDictValue(curPlayer, key):
+ __SetPDictValue(curPlayer, key, 0)
#总活跃度重置
__SetPDictValue(curPlayer, ChConfig.Def_PDict_Activity_TotalPoint, 0)
# 重置领奖记录
@@ -238,10 +241,18 @@
onceActivityTime = dailyQuestData.GetOnceActivityTime()
if not onceActivity:
return
- if maxActiveValue and finishCnt > maxActiveValue / onceActivity * onceActivityTime:
- #GameWorld.DebugLog("活跃度可完成次数已达到上限,activityNum=%s" % (activityNum))
- return
-
+ curAddTotal = None
+ if maxActiveValue:
+ if dailyQuestData.GetRelatedType() == RelatedType_1 and dailyQuestData.GetRelatedID() in [ShareDefine.DailyActionID_CrossBattlefield]:
+ curAddTotal = __GetPDictValue(curPlayer, ChConfig.Def_PDict_Activity_AddTotal % activityNum) #单次进度值
+ if curAddTotal >= maxActiveValue:
+ GameWorld.DebugLog("活跃度可完成次数已达到上限,activityNum=%s,curAddTotal=%s >= %s" % (activityNum, curAddTotal, maxActiveValue))
+ return
+ else:
+ if finishCnt > maxActiveValue / onceActivity * onceActivityTime:
+ #GameWorld.DebugLog("活跃度可完成次数已达到上限,activityNum=%s" % (activityNum))
+ return
+
key = ChConfig.Def_PDict_Activity_FinishCnt % activityNum
curPBCnt = __GetPDictValue(curPlayer, key) #单次进度值
@@ -250,6 +261,10 @@
__SetPDictValue(curPlayer, key, addPbCnt)
+ if curAddTotal != None:
+ curAddTotal += addValue
+ __SetPDictValue(curPlayer, ChConfig.Def_PDict_Activity_AddTotal % activityNum, curAddTotal)
+
#
DoAddActivity(curPlayer, addValue, True)
return
@@ -476,7 +491,7 @@
# 由GameServer决定
# 目前跨服PK暂不需要判断,因为跨服PK次数结算在本服,玩家可能上次未结算离线,等非匹配期间上线,也需要加上,所以暂不判断
- if dailyID not in [ShareDefine.DailyActionID_CrossReamPK]:
+ if dailyID not in [ShareDefine.DailyActionID_CrossReamPK, ShareDefine.DailyActionID_CrossBattlefield]:
if not GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_DailyActionState % dailyID):
GameWorld.DebugLog("日常活动未开启!dailyID=%s" % dailyID)
return
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
index 575ba44..41301f6 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
@@ -328,7 +328,7 @@
return
#---------------------------------------------------------------------
-def SendMailBatch(mailTypeKey, batchPlayerIDList, batchAddItemList=[], batchParamList=[], batchGold=[], batchGoldPaper=[], batchSilver=[], batchDetail=[], moneySource=ChConfig.Def_GiveMoney_Mail):
+def SendMailBatch(mailTypeKey, batchPlayerIDList, batchAddItemList=[], batchParamList=[], batchGold=[], batchGoldPaper=[], batchSilver=[], batchDetail=[], moneySource=ChConfig.Def_GiveMoney_Mail, crossMail=False):
'''批量发送邮件, 用于瞬间需要发送多封(大量)邮件的,比如一些公共副本活动等结算时
@param mailTypeKey: 邮件模板key
@param batchPlayerIDList: [playerIDList, playerIDList, ...]
@@ -352,17 +352,17 @@
bGoldPaper = [batchGoldPaper[i]] if len(batchGoldPaper) > i else []
bSilver = [batchSilver[i]] if len(batchSilver) > i else []
bDetail = [batchDetail[i]] if len(batchDetail) > i else []
- AddUnLoginOKPlayerMailCache(playerID, "ByMailTemplate", [mailTypeKey, bAddItemList, bParamList, bGold, bGoldPaper, bSilver, bDetail, moneySource])
+ AddUnLoginOKPlayerMailCache(playerID, "ByMailTemplate", [mailTypeKey, bAddItemList, bParamList, bGold, bGoldPaper, bSilver, bDetail, moneySource, crossMail])
playerIDList.pop(playerIDList.index(playerID))
continue
- msgInfo = str([mailTypeKey, batchPlayerIDList, batchAddItemList, batchParamList, batchGold, batchGoldPaper, batchSilver, batchDetail, moneySource])
+ msgInfo = str([mailTypeKey, batchPlayerIDList, batchAddItemList, batchParamList, batchGold, batchGoldPaper, batchSilver, batchDetail, moneySource, crossMail])
GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "SendMailBatch", msgInfo, len(msgInfo))
GameWorld.Log("SendMailBatch %s, batchPlayerIDList=%s, batchAddItemList=%s, batchParamList=%s, batchGold=%s, batchGoldPaper=%s, batchSilver=%s"
% (mailTypeKey, batchPlayerIDList, batchAddItemList, batchParamList, batchGold, batchGoldPaper, batchSilver))
return
-def SendMailByKey(mailTypeKey, playerIDList, addItemList, paramList=[], gold=0, goldPaper=0, silver=0, detail="", moneySource=ChConfig.Def_GiveMoney_Mail):
+def SendMailByKey(mailTypeKey, playerIDList, addItemList, paramList=[], gold=0, goldPaper=0, silver=0, detail="", moneySource=ChConfig.Def_GiveMoney_Mail, crossMail=False):
'''
@param detail: 记录邮件流向用
'''
@@ -370,7 +370,7 @@
mailTypeKey = ShareDefine.DefaultLackSpaceMailType
content = "<MailTemplate>%s</MailTemplate>%s" % (mailTypeKey, json.dumps(paramList, ensure_ascii=False))
- SendMail("", content, 30, playerIDList, addItemList, gold, goldPaper, silver, detail, moneySource)
+ SendMail("", content, 30, playerIDList, addItemList, gold, goldPaper, silver, detail, moneySource, crossMail)
return
def SendCrossMail(serverGroupID, mailTypeKey, playerIDList, addItemList, paramList=[]):
@@ -412,7 +412,7 @@
## 功能发放物品补偿/奖励邮件
# @param addItemList [(itemID, itemCnt, 是否拍品), {或物品信息字典}, ...]
# @return
-def SendMail(title, content, getDays, playerIDList, addItemList, gold=0, goldPaper=0, silver=0, detail="", moneySource=ChConfig.Def_GiveMoney_Mail):
+def SendMail(title, content, getDays, playerIDList, addItemList, gold=0, goldPaper=0, silver=0, detail="", moneySource=ChConfig.Def_GiveMoney_Mail, crossMail=False):
if not playerIDList:
return
@@ -424,7 +424,7 @@
return
# 跨服服务器不允许发送邮件
- if GameWorld.IsCrossServer():
+ if GameWorld.IsCrossServer() and not crossMail:
return
sendPlayerIDList = []
@@ -437,7 +437,7 @@
sendPlayerIDList.append(playerID)
combineItemList = CombineMailItem(addItemList)
- cmdList = [title, content, getDays, sendPlayerIDList, combineItemList, gold, goldPaper, silver, detail, moneySource]
+ cmdList = [title, content, getDays, sendPlayerIDList, combineItemList, gold, goldPaper, silver, detail, moneySource, crossMail]
GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "SendMail", '%s' % (cmdList), len(str(cmdList)))
return True
@@ -476,8 +476,8 @@
title, content, getDays, addItemList, gold, goldPaper, silver, detail, moneySource = mailInfo
SendMail(title, content, getDays, playerIDList, addItemList, gold, goldPaper, silver, detail, moneySource)
elif cacheType == "ByMailTemplate":
- mailTypeKey, bAddItemList, bParamList, bGold, bGoldPaper, bSilver, bDetail, moneySource = mailInfo
- SendMailBatch(mailTypeKey, [playerIDList], bAddItemList, bParamList, bGold, bGoldPaper, bSilver, bDetail, moneySource)
+ mailTypeKey, bAddItemList, bParamList, bGold, bGoldPaper, bSilver, bDetail, moneySource, crossMail = mailInfo
+ SendMailBatch(mailTypeKey, [playerIDList], bAddItemList, bParamList, bGold, bGoldPaper, bSilver, bDetail, moneySource, crossMail)
return
def CombineMailItem(addItemList):
@@ -1785,7 +1785,10 @@
if not FBLogic.OnEnterFBEvent(curPlayer, mapID, lineID, tick):
GameWorld.DebugLog(" OnEnterFBEvent False!", curPlayer.GetPlayerID())
- NotifyCode(curPlayer, "SingleEnterDefaul")
+ if mapID in [ChConfig.Def_FBMapID_CrossBattlefield]:
+ NotifyCode(curPlayer, "GeRen_chenxin_268121")
+ else:
+ NotifyCode(curPlayer, "SingleEnterDefaul")
return
# 需要动态分布线路的地图,发送到跨服服务器进行分配
@@ -1797,7 +1800,7 @@
return
extendInfo["BossID"] = bossID
- msgDict = {"PlayerID":curPlayer.GetPlayerID(), "MapID":mapID, "FuncLineID":lineID}
+ msgDict = {"PlayerID":curPlayer.GetPlayerID(), "MapID":mapID, "FuncLineID":lineID, "LV":curPlayer.GetLV()}
if extendInfo:
msgDict.update(extendInfo)
GameWorld.SendMsgToCrossServer(ShareDefine.ClientServerMsg_EnterFB, msgDict)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCrossBattlefield.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCrossBattlefield.py
new file mode 100644
index 0000000..79a64da
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCrossBattlefield.py
@@ -0,0 +1,232 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package Player.PlayerCrossBattlefield
+#
+# @todo:跨服战场
+# @author hxp
+# @date 2022-01-06
+# @version 1.0
+#
+# 详细描述: 跨服战场
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2022-01-06 20:30"""
+#-------------------------------------------------------------------------------
+import GameWorld
+import ShareDefine
+import PlayerControl
+import IpyGameDataPY
+import datetime
+import CrossRealmPlayer
+import ChConfig
+import ItemCommon
+import IPY_GameWorld
+import ChPyNetSendPack
+import NetPackCommon
+import ItemControler
+import PlayerActivity
+
+
+def DoPlayerLogin(curPlayer):
+ if GameWorld.IsCrossServer():
+ return
+ SyncCrossBattlefieldPlayerInfo(curPlayer)
+ return
+
+def DoPlayerOnDay(curPlayer):
+ if GameWorld.IsCrossServer():
+ return
+
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_Battlefield_HighScoreToday, 0)
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_Battlefield_BuyOpenCountToday, 0)
+
+ SyncCrossBattlefieldPlayerInfo(curPlayer)
+ return
+
+def DoPlayerOnWeek(curPlayer):
+ if GameWorld.IsCrossServer():
+ return
+
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_Battlefield_EnterCountWeek, 0)
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_Battlefield_BuyOpenCountWeek, 0)
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_Battlefield_HighScoreTotalWeek, 0)
+ return
+
+#// C1 09 跨服战场购买开启场次 #tagCMCrossBattlefieldBuyOpen
+#
+#struct tagCMCrossBattlefieldBuyOpen
+#{
+# tagHead Head;
+# BYTE Hour; //战场开启时
+# BYTE Minute; //战场开启分
+# BYTE Faction; //阵营 1-红;2-蓝
+#};
+def OnCrossBattlefieldBuyOpen(index, clientData, tick):
+ curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+ playerID = curPlayer.GetPlayerID()
+ hour = clientData.Hour
+ minute = clientData.Minute
+ faction = clientData.Faction
+
+ if GameWorld.IsCrossServer():
+ GameWorld.DebugLog("跨服服务器无法发起匹配!", playerID)
+ return
+
+ if not CrossRealmPlayer.IsCrossServerOpen():
+ PlayerControl.NotifyCode(curPlayer, "CrossMatching18")
+ return
+
+ if faction not in [ChConfig.CampType_Justice, ChConfig.CampType_Evil]:
+ GameWorld.DebugLog("没有该战场阵营选择! faction=%s" % faction, playerID)
+ return
+
+ callOpenHMList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldOpen", 2)
+ if [hour, minute] not in callOpenHMList:
+ GameWorld.Log("非可召集的战场场次! hour=%s,minute=%s,callOpenHMList=%s" % (hour, minute, callOpenHMList), playerID)
+ return
+
+ closeBuyMinute = IpyGameDataPY.GetFuncCfg("CrossBattlefieldOpen", 4) # 开启前X分钟后关闭购买
+ crossServerTimeStr = GameWorld.GetCrossServerTimeStr()
+ crossServerDateTime = GameWorld.ChangeStrToDatetime(crossServerTimeStr)
+
+ startTimeStr = "%s-%s-%s %s:%s:00" % (crossServerDateTime.year, crossServerDateTime.month, crossServerDateTime.day, hour, minute)
+ startDateTime = GameWorld.ChangeStrToDatetime(startTimeStr)
+ endBuyDateTime = startDateTime + datetime.timedelta(minutes= -closeBuyMinute)
+ if crossServerDateTime >= endBuyDateTime:
+ GameWorld.Log("该时间点战场已关闭召集,不能再召集! hour=%s,minute=%s,crossServerDateTime(%s) >= endBuyDateTime(%s)"
+ % (hour, minute, crossServerDateTime, endBuyDateTime), playerID)
+ return
+
+ moneyBuyMaxCount, moneyType, moneyCount = 0, 0, 0
+ todayBuyOpenCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Battlefield_BuyOpenCountToday)
+ buyOpenMoneyInfo = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldBuyOpen", 1)
+ if len(buyOpenMoneyInfo) == 3:
+ moneyBuyMaxCount, moneyType, moneyCount = buyOpenMoneyInfo
+
+ # 购买消耗货币
+ if todayBuyOpenCount < moneyBuyMaxCount:
+ if not PlayerControl.HaveMoney(curPlayer, moneyType, moneyCount):
+ GameWorld.DebugLog("跨服战场召集开启货币不足! moneyType=%s,moneyCount=%s" % (moneyType, moneyCount), playerID)
+ return
+ else:
+ costItemID = IpyGameDataPY.GetFuncCfg("CrossBattlefieldBuyOpen", 2)
+ costItem = ItemCommon.FindItemInPackByItemID(curPlayer, costItemID, IPY_GameWorld.rptItem)
+ if not ItemCommon.CheckItemCanUse(costItem):
+ GameWorld.DebugLog("跨服战场召集开启道具不足! costItemID=%s" % costItemID, playerID)
+ return
+
+ if not GameWorld.SetPlayerTickTime(curPlayer, ChConfig.TYPE_Player_Tick_Battlefield, tick):
+ PlayerControl.NotifyCode(curPlayer, "RequestLater")
+ return
+
+ dataMsg = {"openHour":hour, "openMinute":minute, "faction":faction, "todayBuyOpenCount":todayBuyOpenCount,
+ "accID":curPlayer.GetAccID(),
+ "playerID":playerID,
+ "playerName":CrossRealmPlayer.GetCrossPlayerName(curPlayer),
+ "playerJob":curPlayer.GetJob(),
+ "playerLV":curPlayer.GetLV(),
+ "realmLV":curPlayer.GetOfficialRank(),
+ "fightPower":PlayerControl.GetFightPower(curPlayer),
+ "buyOpenCountWeek":curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Battlefield_BuyOpenCountWeek)
+ }
+ GameWorld.SendMsgToCrossServer(ShareDefine.ClientServerMsg_BattlefieldBuyOpen, dataMsg)
+ return
+
+def GameServer_CrossBattlefield_DoResult(curPlayer, msgData):
+ msgType, dataMsg = msgData[:2]
+ #ret = msgData[2] if len(msgData) > 2 else None
+
+ ## 战场购买开启场次
+ if msgType == "BattlefieldBuy":
+ __DoBattlefieldBuy(curPlayer, dataMsg)
+
+ elif msgType == "BattlefieldOver":
+ __DoBattlefieldOver(curPlayer, dataMsg)
+
+ return
+
+def __DoBattlefieldBuy(curPlayer, dataMsg):
+
+ playerID = curPlayer.GetPlayerID()
+ openHour, openMinute, faction, todayBuyOpenCount, buyTime = dataMsg
+ updTodayBuyOpenCount, updWeekBuyOpenCount = 0, 0
+
+ isToday = GameWorld.CheckTimeIsSameServerDayEx(buyTime)
+ if isToday:
+ todayBuyOpenCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Battlefield_BuyOpenCountToday)
+ updTodayBuyOpenCount = todayBuyOpenCount + 1
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_Battlefield_BuyOpenCountToday, updTodayBuyOpenCount)
+ SyncCrossBattlefieldPlayerInfo(curPlayer)
+
+ isSameWeek = GameWorld.CheckTimeIsSameWeek(buyTime)
+ if isSameWeek:
+ weekBuyOpenCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Battlefield_BuyOpenCountWeek)
+ updWeekBuyOpenCount = weekBuyOpenCount + 1
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_Battlefield_BuyOpenCountWeek, updWeekBuyOpenCount)
+
+ GameWorld.Log("购买召集跨服战场结果: openHour=%s,openMinute=%s,faction=%s,updTodayBuyOpenCount=%s,updWeekBuyOpenCount=%s,buyTime=%s,isToday=%s,isSameWeek=%s"
+ % (openHour, openMinute, faction, updTodayBuyOpenCount, updWeekBuyOpenCount, GameWorld.ChangeTimeNumToStr(buyTime), isToday, isSameWeek), playerID)
+
+ moneyBuyMaxCount, moneyType, moneyCount = 0, 0, 0
+ buyOpenMoneyInfo = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldBuyOpen", 1)
+ if len(buyOpenMoneyInfo) == 3:
+ moneyBuyMaxCount, moneyType, moneyCount = buyOpenMoneyInfo
+
+ infoDict = {ChConfig.Def_Cost_Reason_SonKey:"BattlefieldBuyOpen", "buyTime":buyTime, "isToday":isToday, "isSameWeek":isSameWeek,
+ "updTodayBuyOpenCount":updTodayBuyOpenCount, "updWeekBuyOpenCount":updWeekBuyOpenCount}
+ # 购买消耗货币
+ if todayBuyOpenCount < moneyBuyMaxCount:
+ if not PlayerControl.PayMoney(curPlayer, moneyType, moneyCount, ChConfig.Def_Cost_CrossBattlefield, infoDict):
+ return
+ else:
+ costItemID = IpyGameDataPY.GetFuncCfg("CrossBattlefieldBuyOpen", 2)
+ costItem = ItemCommon.FindItemInPackByItemID(curPlayer, costItemID, IPY_GameWorld.rptItem)
+ if not ItemCommon.CheckItemCanUse(costItem):
+ costItem = ItemCommon.FindItemInPackByItemID(curPlayer, costItemID, IPY_GameWorld.rptWarehouse)
+ if not ItemCommon.CheckItemCanUse(costItem):
+ return
+ ItemCommon.DelItem(curPlayer, costItem, 1, True, "CrossBattlefield", infoDict)
+
+ # 固定礼包
+ buyAwardItemList = IpyGameDataPY.GetFuncEvalCfg("CrossBattlefieldBuyOpen", 3)
+ ItemControler.GivePlayerItemOrMail(curPlayer, buyAwardItemList)
+ return
+
+def __DoBattlefieldOver(curPlayer, dataMsg):
+
+ playerID = curPlayer.GetPlayerID()
+ overTime, highScoreToday, highScoreWeekTotal, enterCountWeek, isCallEnter = dataMsg
+
+ isToday = GameWorld.CheckTimeIsSameServerDayEx(overTime)
+ isSameWeek = GameWorld.CheckTimeIsSameWeek(overTime)
+ GameWorld.Log("跨服战场结算玩家结果: highScoreToday=%s,highScoreWeekTotal=%s,enterCountWeek=%s,isCallEnter=%s,overTime=%s,isToday=%s,isSameWeek=%s"
+ % (highScoreToday, highScoreWeekTotal, enterCountWeek, isCallEnter, GameWorld.ChangeTimeNumToStr(overTime), isToday, isSameWeek), playerID)
+
+ if isToday:
+ addCnt = 1
+ # 非召集进入的需要增加日常次数
+ if not isCallEnter:
+ PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_CrossBattlefield, addCnt)
+ # 召集进入由于是免费进入,不许要增加日常次数,直接增加日常活跃
+ else:
+ activityNum = PlayerActivity.GetActivityNum(PlayerActivity.RelatedType_1, ShareDefine.DailyActionID_CrossBattlefield)
+ PlayerActivity.AddActivityFinishCnt(curPlayer, activityNum, None, addCnt)
+
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_Battlefield_HighScoreToday, highScoreToday)
+ SyncCrossBattlefieldPlayerInfo(curPlayer)
+
+ if isSameWeek:
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_Battlefield_EnterCountWeek, enterCountWeek)
+ PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_Battlefield_HighScoreTotalWeek, highScoreWeekTotal)
+
+ return
+
+def SyncCrossBattlefieldPlayerInfo(curPlayer):
+ clientPack = ChPyNetSendPack.tagMCCrossBattlefieldPlayerInfo()
+ clientPack.BuyOpenCountToday = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Battlefield_BuyOpenCountToday)
+ clientPack.HighScoreToday = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_Battlefield_HighScoreToday)
+ NetPackCommon.SendFakePack(curPlayer, clientPack)
+ return
+
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
index 2e585d3..60852d6 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
@@ -61,6 +61,7 @@
import PlayerGoldInvest
import PlayerNewGuyCard
import PlayerCrossRealmPK
+import PlayerCrossBattlefield
import PlayerPet
import BossHurtMng
import PlayerRecover
@@ -576,6 +577,8 @@
FBHelpBattle.DoPlayerOnDay(curPlayer)
#跨服竞技场
PlayerCrossRealmPK.DoPlayerOnDay(curPlayer)
+ #跨服战场
+ PlayerCrossBattlefield.DoPlayerOnDay(curPlayer)
#缥缈仙域
PlayerFairyDomain.OnDay(curPlayer)
#仙盟宴会
@@ -716,7 +719,8 @@
#竞技场
PlayerArena.OnWeekEx(curPlayer)
PlayerFamily.OnWeekEx(curPlayer)
-
+ PlayerCrossBattlefield.DoPlayerOnWeek(curPlayer)
+
# 以下为支持两种重置模式切换配置的
FBCommon.FBOnWeek(curPlayer, onEventType)
@@ -1490,6 +1494,10 @@
PlayerLuckyCloudBuy.OnLuckyCloudBuyChange()
return
+ if key == ShareDefine.Def_Notify_WorldKey_CrossBattlefieldCallTeamInfo:
+ PyGameData.g_crossBattlefieldCallTeamInfo = eval(msgValue)
+ return
+
if msgValue.isdigit():
value = int(msgValue)
else:
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_CrossBattlefield.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_CrossBattlefield.py
new file mode 100644
index 0000000..b25ab78
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_CrossBattlefield.py
@@ -0,0 +1,48 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package Player.RemoteQuery.GY_Query_CrossBattlefield
+#
+# @todo:跨服战场
+# @author hxp
+# @date 2022-01-06
+# @version 1.0
+#
+# 详细描述: 跨服战场
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2022-01-06 20:30"""
+#-------------------------------------------------------------------------------
+
+import GameWorld
+import ChConfig
+import PlayerCrossBattlefield
+
+#------------------------------------------------------------------------------
+## 执行逻辑
+# @param query_Type 请求类型
+# @param query_ID 请求的玩家ID
+# @param packCMDList 发包命令
+# @param tick 当前时间
+# @return "True" or "False" or ""
+# @remarks 函数详细说明.
+def DoLogic(query_Type, query_ID, packCMDList, tick):
+ return
+
+#------------------------------------------------------------------------------
+## 执行结果
+# @param curPlayer 发出请求的玩家
+# @param callFunName 功能名称
+# @param funResult 查询的结果
+# @param tick 当前时间
+# @return None
+# @remarks 函数详细说明.
+def DoResult(curPlayer, callFunName, funResult, tick):
+ curPlayer.SetTickByType(ChConfig.TYPE_Player_Tick_Battlefield, 0)
+ msgData = eval(funResult)
+ playerID = curPlayer.GetPlayerID()
+ GameWorld.Log("GameServer_CrossBattlefield_DoResult msgData=%s" % (msgData), playerID)
+ PlayerCrossBattlefield.GameServer_CrossBattlefield_DoResult(curPlayer, msgData)
+ return
+
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
index cb0f2eb..b7da1e1 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
@@ -101,6 +101,8 @@
g_crossPlayerItemsChangeInfo = {} #跨服玩家物品变化信息 {playerID:{"背包类型-物品位":itemMD5, ...}, ...}
g_crossPlayerSkillsChangeInfo = {} #跨服玩家技能变化信息 {playerID:[技能ID], ...}
+g_crossBattlefieldCallTeamInfo = {} # 跨服战场召集队伍信息 {zoneID:{hmNum:{playerID:[召集队伍玩家ID列表], ...}, ...}, ...}
+
g_ZhuXianBossPlayerHurtDict = {} #诛仙BOSS玩家伤害排行信息
g_Qudao_DoubleBill = {} # 渠道删档充值返利
--
Gitblit v1.8.0