9415 【BT5】【后端】古神战场(初版:包含战场副本外的所有功能;副本中暂仅支持击杀玩家玩法)
# Conflicts:
# ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py
# ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py
# ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerControl.py
# ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
# ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
# ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
| | |
| | | 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
|
| | |
| | | Def_FBMapID_CrossGrasslandLing = 32040
|
| | | #跨服仙草园
|
| | | Def_FBMapID_CrossGrasslandXian = 32050
|
| | | #跨服战场
|
| | | Def_FBMapID_CrossBattlefield = 32060
|
| | | #情缘副本
|
| | | Def_FBMapID_Love = 31300
|
| | |
|
| | |
| | | Def_FBMapID_CrossDemonKing:"CrossZonePK",
|
| | | Def_FBMapID_CrossGrasslandLing:"CrossZonePK",
|
| | | Def_FBMapID_CrossGrasslandXian:"CrossZonePK",
|
| | | Def_FBMapID_CrossBattlefield:"CrossZonePK",
|
| | | }
|
| | | #跨服分区对应地图配置表名 - 仅适用于固定地图及虚拟分线的跨服玩法
|
| | | Def_CrossZoneMapTableName = {Def_FBMapID_CrossPenglai:"CrossPenglaiZoneMap",
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # 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):
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # 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):
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # 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):
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # 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):
|
New file |
| | |
| | | #!/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
|
| | |
| | | # @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 一次 并通知在线所有玩家
|
| | |
| | | # @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
|
| | |
| | | # @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 一次 并通知在线所有玩家
|
| | |
| | | GameWorldProcess.OnWeek( timeStr , tick )
|
| | | GameWorldProcess.OnWeekEx(tick)
|
| | | return
|
| | |
|
| | | def OnGetMergeParam(curPlayer):
|
| | | ## 跨服命令额外参数
|
| | | return []
|
| | |
|
| | | def OnMergeServerExec(gmList, tick):
|
| | | ## 跨服执行命令
|
| | | __DoExecOnWeek(gmList)
|
| | | return
|
| | |
| | | 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)
|
New file |
| | |
| | | #!/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
|
| | |
|
| | |
| | | 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()
|
| | |
| | | import CrossRealmPlayer
|
| | | import PlayerCompensation
|
| | | import CrossActionControl
|
| | | import CrossBattlefield
|
| | | import CrossBillboard
|
| | | import GameWorldBoss
|
| | | import CrossRealmPK
|
| | |
| | | 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)
|
| | |
| | | '''
|
| | | 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)
|
| | |
| | | return
|
| | | ## ================================================================================================
|
| | |
|
| | | def SendMsgToClientServer(msgType, dataMsg, serverGroupIDList=[]):
|
| | | def SendMsgToClientServer(msgType, dataMsg, serverGroupIDList=None):
|
| | | ''' 广播信息到子服务器上
|
| | | @param serverGroupIDList: 发送指定的服务器组ID列表,内部已经针对列表中组ID去重,
|
| | | 所以外部逻辑可直接添加,不用考虑组ID重复问题,没有指定服务器组ID时,默认广播所有子服
|
| | |
| | | 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):
|
| | |
| | | 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)
|
| | |
|
| | |
| | | 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("没有该信息类型逻辑处理!")
|
| | |
|
| | |
| | | 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)
|
| | |
| | | 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
|
| | |
|
| | |
|
| | | |
| | |
| | |
|
| | | 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)
|
| | |
| | | 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
|
| | |
|
| | |
| | | import NetPackCommon
|
| | | import PlayerDuJie
|
| | | import PlayerCharm
|
| | | import CrossBattlefield
|
| | | #---------------------------------------------------------------------
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | |
| | | PlayerFairyDomain.OnDayEx()
|
| | | #竞技场
|
| | | GameWorldArena.OnDayEx()
|
| | | #跨服战场
|
| | | CrossBattlefield.DoOnDayEx()
|
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for i in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(i)
|
| | |
| | |
|
| | | # 竞技场
|
| | | GameWorldArena.OnWeekEx()
|
| | | # 跨服战场
|
| | | CrossBattlefield.DoOnWeekEx()
|
| | |
|
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for i in xrange(playerManager.GetPlayerCount()):
|
| | |
| | | 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
|
| | |
|
| | |
| | | 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):
|
| | |
| | | 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):
|
| | | ## 收到跨服服务器动态分配的跨服副本进入信息
|
| | |
| | |
|
| | | 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)
|
| | |
| | | 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
|
| | |
| | | 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)
|
| | |
| | | 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)
|
| | |
| | | import CrossRealmPlayer
|
| | | import CrossRealmMsg
|
| | | import CrossRealmPK
|
| | | import CrossBattlefield
|
| | | import ChPyNetSendPack
|
| | | import NetPackCommon
|
| | | import AuctionHouse
|
| | |
| | | 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":
|
| | |
| | | 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)
|
| | |
| | | import GameWorldArena
|
| | | import ChPyNetSendPack
|
| | | import PlayerFBHelpBattle
|
| | | import CrossBattlefield
|
| | | import PyGameDataStruct
|
| | | import IpyGameDataPY
|
| | | import PyDataManager
|
| | |
| | | if GameWorldArena.IsArenaBattlePlayer(playerID):
|
| | | return True
|
| | |
|
| | | if CrossBattlefield.IsBattlefieldCallPlayer(playerID):
|
| | | return True
|
| | | |
| | | SaveDBLimitLV = IpyGameDataPY.GetFuncCfg("PlayerViewCache", 1)
|
| | | #校验玩家等级
|
| | | if playerLV < SaveDBLimitLV:
|
| | |
| | | return True
|
| | |
|
| | | if GameWorldArena.IsArenaBattlePlayer(playerID):
|
| | | return True
|
| | | |
| | | if CrossBattlefield.IsBattlefieldCallPlayer(playerID):
|
| | | return True
|
| | |
|
| | | NeedCheckBillBoardType = IpyGameDataPY.GetFuncEvalCfg("PlayerViewCache", 2)
|
| | |
| | | ## 获取缓存基础属性字典信息
|
| | | 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
|
| | |
|
| | |
| | |
|
| | | 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],..]
|
| | |
|
| | |
| | | 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
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # 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):
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # 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):
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # 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):
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # 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):
|
New file |
| | |
| | | #!/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
|
| | |
| | | #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: 区服名
|
| | |
| | | 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
|
| | | #---------------------------------------------------------------------
|
| | | ## 给客户端弹消息
|
| | |
| | | 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)
|
| | |
| | |
|
| | | 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
|
| | |
|
New file |
| | |
| | | #!/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
|
| | |
|
| | |
| | | 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()
|
| | |
| | | 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))
|
| | |
|
| | |
| | | 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最终固定伤害加成, 普攻也有效果
|
| | |
| | | import PlayerGatherSoul
|
| | | import PlayerFairyDomain
|
| | | import PlayerCrossRealmPK
|
| | | import PlayerCrossBattlefield
|
| | | import GameFuncComm
|
| | | import PlayerMagicWeapon
|
| | | import GameLogic_TrialTower
|
| | |
| | |
|
| | | # 跨服PK
|
| | | PlayerCrossRealmPK.DoPlayerLogin(curPlayer)
|
| | | PlayerCrossBattlefield.DoPlayerLogin(curPlayer)
|
| | |
|
| | | # 幸运云购
|
| | | PlayerLuckyCloudBuy.OnPlayerLogin(curPlayer)
|
| | |
| | | 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)
|
| | | # 重置领奖记录
|
| | |
| | | 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) #单次进度值
|
| | |
|
| | |
| | |
|
| | | __SetPDictValue(curPlayer, key, addPbCnt)
|
| | |
|
| | | if curAddTotal != None:
|
| | | curAddTotal += addValue
|
| | | __SetPDictValue(curPlayer, ChConfig.Def_PDict_Activity_AddTotal % activityNum, curAddTotal)
|
| | | |
| | | #
|
| | | DoAddActivity(curPlayer, addValue, True)
|
| | | return
|
| | |
| | |
|
| | | # 由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
|
| | |
| | | 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, ...]
|
| | |
| | | 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: 记录邮件流向用
|
| | | '''
|
| | |
| | | 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=[]):
|
| | |
| | | ## 功能发放物品补偿/奖励邮件
|
| | | # @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
|
| | |
|
| | |
| | | return
|
| | |
|
| | | # 跨服服务器不允许发送邮件
|
| | | if GameWorld.IsCrossServer():
|
| | | if GameWorld.IsCrossServer() and not crossMail:
|
| | | return
|
| | |
|
| | | sendPlayerIDList = []
|
| | |
| | | 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
|
| | |
|
| | |
| | | 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):
|
| | |
| | |
|
| | | 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
|
| | |
|
| | | # 需要动态分布线路的地图,发送到跨服服务器进行分配
|
| | |
| | | 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)
|
New file |
| | |
| | | #!/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
|
| | |
|
| | |
| | | import PlayerGoldInvest
|
| | | import PlayerNewGuyCard
|
| | | import PlayerCrossRealmPK
|
| | | import PlayerCrossBattlefield
|
| | | import PlayerPet
|
| | | import BossHurtMng
|
| | | import PlayerRecover
|
| | |
| | | FBHelpBattle.DoPlayerOnDay(curPlayer)
|
| | | #跨服竞技场
|
| | | PlayerCrossRealmPK.DoPlayerOnDay(curPlayer)
|
| | | #跨服战场
|
| | | PlayerCrossBattlefield.DoPlayerOnDay(curPlayer)
|
| | | #缥缈仙域
|
| | | PlayerFairyDomain.OnDay(curPlayer)
|
| | | #仙盟宴会
|
| | |
| | | #竞技场
|
| | | PlayerArena.OnWeekEx(curPlayer)
|
| | | PlayerFamily.OnWeekEx(curPlayer)
|
| | | |
| | | PlayerCrossBattlefield.DoPlayerOnWeek(curPlayer)
|
| | | |
| | | # 以下为支持两种重置模式切换配置的
|
| | | FBCommon.FBOnWeek(curPlayer, onEventType)
|
| | |
|
| | |
| | | PlayerLuckyCloudBuy.OnLuckyCloudBuyChange()
|
| | | return
|
| | |
|
| | | if key == ShareDefine.Def_Notify_WorldKey_CrossBattlefieldCallTeamInfo:
|
| | | PyGameData.g_crossBattlefieldCallTeamInfo = eval(msgValue)
|
| | | return
|
| | | |
| | | if msgValue.isdigit():
|
| | | value = int(msgValue)
|
| | | else:
|
New file |
| | |
| | | #!/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
|
| | |
|
| | |
| | | g_crossPlayerItemsChangeInfo = {} #跨服玩家物品变化信息 {playerID:{"背包类型-物品位":itemMD5, ...}, ...}
|
| | | g_crossPlayerSkillsChangeInfo = {} #跨服玩家技能变化信息 {playerID:[技能ID], ...}
|
| | |
|
| | | g_crossBattlefieldCallTeamInfo = {} # 跨服战场召集队伍信息 {zoneID:{hmNum:{playerID:[召集队伍玩家ID列表], ...}, ...}, ...}
|
| | |
|
| | | g_ZhuXianBossPlayerHurtDict = {} #诛仙BOSS玩家伤害排行信息
|
| | |
|
| | | g_Qudao_DoubleBill = {} # 渠道删档充值返利
|