8677 【BT】【后端】跨服冲榜活动; 新增跨服活动时间管理模块、跨服榜单;跨服邮件;跨服广播优化;相关GM命令、后台工具;
# Conflicts:
# ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py
# ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
# ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
# ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerCoin.py
# ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
# ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
| | |
| | | WORD LVLimit; //限制等级
|
| | | };
|
| | |
|
| | | //跨服充值排行活动时间表
|
| | |
|
| | | struct tagCrossActCTGBillboard
|
| | | {
|
| | | DWORD _CfgID; //配置ID
|
| | | char ActGroupName; //活动组名(同组活动的名字需相同)
|
| | | list ServerIDRangeList; //活动的账号服务器ID范围列表 [[serverIDA, serverIDB], ...]
|
| | | char StartDate; //开启日期
|
| | | char EndDate; //结束日期
|
| | | dict NotifyInfoStart; //全服提示信息 - 相对开始时间
|
| | | dict NotifyInfoEnd; //全服提示信息 - 相对结束时间
|
| | | list NotifyInfoLoop; //全服提示信息 - 循环广播[循环分钟, 广播key, [广播参数列表可选]]
|
| | | BYTE IsDayReset; //是否每天重置
|
| | | list TemplateIDList; //模板ID列表
|
| | | };
|
| | |
|
| | | //跨服充值排行模板名次奖励表
|
| | |
|
| | | struct tagCrossActCTGBillboardOrder
|
| | | {
|
| | | DWORD _TemplateID; //模板ID
|
| | | WORD OrderA; //名次A
|
| | | WORD OrderB; //至名次B
|
| | | DWORD CTGAtleast; //至少充值RMB
|
| | | list AwardItemList; //奖励物品列表[[物品ID,个数,是否拍品], ...]
|
| | | };
|
| | |
|
| | | //装备升星表
|
| | |
|
| | | struct tagEquipStarUp
|
| | |
| | | DWORD Weight; //权重
|
| | | };
|
| | |
|
| | | //跨服充值排行模板达标奖励表
|
| | |
|
| | | struct tagCrossActCTGBillboardDabiao
|
| | | {
|
| | | DWORD _TemplateID; //模板ID
|
| | | DWORD CTGNeed; //需充值RMB
|
| | | BYTE AwardIndex; //奖励记录索引,从0开始,同个模板不可重复,不可变更
|
| | | list AwardItemList; //奖励物品列表[[物品ID,个数,是否拍品], ...]
|
| | | };
|
| | |
|
| | | //跨服充值排行模板名次奖励表
|
| | |
|
| | | struct tagCrossActCTGBillboardOrder
|
| | | {
|
| | | DWORD _TemplateID; //模板ID
|
| | | WORD OrderA; //名次A
|
| | | WORD OrderB; //至名次B
|
| | | DWORD CTGAtleast; //至少充值RMB
|
| | | list AwardItemList; //奖励物品列表[[物品ID,个数,是否拍品], ...]
|
| | | };
|
| | |
|
| | | //神秘商店表
|
| | |
|
| | | struct tagMysteryShop
|
| | |
| | | PacketSubCMD_2=0x03
|
| | | PacketCallFunc_2=OnForceQuitCrossState
|
| | |
|
| | | [CrossBillboard]
|
| | | ScriptName = GameWorldLogic\CrossBillboard.py
|
| | | Writer = hxp
|
| | | Releaser = hxp
|
| | | RegType = 0
|
| | | RegisterPackCount = 1
|
| | |
|
| | | PacketCMD_1=0xC0
|
| | | PacketSubCMD_1=0x04
|
| | | PacketCallFunc_1=OnViewCrossBillboard
|
| | |
|
| | | [PlayerXMZZ]
|
| | | ScriptName = Player\PlayerXMZZ.py
|
| | | Writer = xdh
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # C0 04 查看跨服排行榜 #tagCGViewCrossBillboard
|
| | |
|
| | | class tagCGViewCrossBillboard(Structure):
|
| | | _pack_ = 1
|
| | | _fields_ = [
|
| | | ("Cmd", c_ubyte),
|
| | | ("SubCmd", c_ubyte),
|
| | | ("Type", c_ubyte), #榜单类型
|
| | | ("GroupValue1", c_ubyte), # 分组值1
|
| | | ("GroupValue2", c_ubyte), # 分组值2,与分组值1组合归为同组榜单数据
|
| | | ]
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Cmd = 0xC0
|
| | | self.SubCmd = 0x04
|
| | | 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 = 0x04
|
| | | self.Type = 0
|
| | | self.GroupValue1 = 0
|
| | | self.GroupValue2 = 0
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | return sizeof(tagCGViewCrossBillboard)
|
| | |
|
| | | def GetBuffer(self):
|
| | | return string_at(addressof(self), self.GetLength())
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''// C0 04 查看跨服排行榜 //tagCGViewCrossBillboard:
|
| | | Cmd:%s,
|
| | | SubCmd:%s,
|
| | | Type:%d,
|
| | | GroupValue1:%d,
|
| | | GroupValue2:%d
|
| | | '''\
|
| | | %(
|
| | | self.Cmd,
|
| | | self.SubCmd,
|
| | | self.Type,
|
| | | self.GroupValue1,
|
| | | self.GroupValue2
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagCGViewCrossBillboard=tagCGViewCrossBillboard()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCGViewCrossBillboard.Cmd,m_NAtagCGViewCrossBillboard.SubCmd))] = m_NAtagCGViewCrossBillboard
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # C0 01 查看跨服竞技场赛季排行榜 #tagCGViewCrossPKBillboard
|
| | |
|
| | | class tagCGViewCrossPKBillboard(Structure):
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # AC 12 跨服运营活动结束 # tagGCCrossActEnd
|
| | |
|
| | | class tagGCCrossActEnd(Structure):
|
| | | Head = tagHead()
|
| | | ActNameLen = 0 #(BYTE ActNameLen)
|
| | | ActName = "" #(String ActName)
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Head.Cmd = 0xAC
|
| | | self.Head.SubCmd = 0x12
|
| | | return
|
| | |
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | _pos = self.Head.ReadData(_lpData, _pos)
|
| | | self.ActNameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.ActName,_pos = CommFunc.ReadString(_lpData, _pos,self.ActNameLen)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.Head = tagHead()
|
| | | self.Head.Clear()
|
| | | self.Head.Cmd = 0xAC
|
| | | self.Head.SubCmd = 0x12
|
| | | self.ActNameLen = 0
|
| | | self.ActName = ""
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | length = 0
|
| | | length += self.Head.GetLength()
|
| | | length += 1
|
| | | length += len(self.ActName)
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | data = ''
|
| | | data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
|
| | | data = CommFunc.WriteBYTE(data, self.ActNameLen)
|
| | | data = CommFunc.WriteString(data, self.ActNameLen, self.ActName)
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''
|
| | | Head:%s,
|
| | | ActNameLen:%d,
|
| | | ActName:%s
|
| | | '''\
|
| | | %(
|
| | | self.Head.OutputString(),
|
| | | self.ActNameLen,
|
| | | self.ActName
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagGCCrossActEnd=tagGCCrossActEnd()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCCrossActEnd.Head.Cmd,m_NAtagGCCrossActEnd.Head.SubCmd))] = m_NAtagGCCrossActEnd
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # AC 09 仙界盛典活动信息 #tagGCFairyCeremonyInfo
|
| | |
|
| | | class tagGCFairyCeremonyInfo(Structure):
|
| | |
| | |
|
| | | m_NAtagGCTeamMemFuncDataList=tagGCTeamMemFuncDataList()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCTeamMemFuncDataList.Head.Cmd,m_NAtagGCTeamMemFuncDataList.Head.SubCmd))] = m_NAtagGCTeamMemFuncDataList
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # C0 07 跨服排行榜信息 #tagGCCrossBillboardInfo
|
| | |
|
| | | class tagGCCrossBillboardData(Structure):
|
| | | ID = 0 #(DWORD ID)
|
| | | Name1 = "" #(char Name1[33])//名字1,用来显示排序对象名字 |
| | | Name2 = "" #(char Name2[33])//名字2
|
| | | Type2 = 0 #(BYTE Type2)//附加类型,用来表示排序对象的类型,比如,玩家所属职业门派,宠物类型等
|
| | | Value1 = 0 #(DWORD Value1)//自定义值1
|
| | | Value2 = 0 #(DWORD Value2)//自定义值2
|
| | | CmpValue = 0 #(DWORD CmpValue)// 比较权值
|
| | | CmpValue2 = 0 #(DWORD CmpValue2)// 比较权值
|
| | | CmpValue3 = 0 #(DWORD CmpValue3)// 比较权值
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | return
|
| | |
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | self.ID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.Name1,_pos = CommFunc.ReadString(_lpData, _pos,33)
|
| | | self.Name2,_pos = CommFunc.ReadString(_lpData, _pos,33)
|
| | | self.Type2,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.Value1,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.Value2,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.CmpValue,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.CmpValue2,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.CmpValue3,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.ID = 0
|
| | | self.Name1 = ""
|
| | | self.Name2 = ""
|
| | | self.Type2 = 0
|
| | | self.Value1 = 0
|
| | | self.Value2 = 0
|
| | | self.CmpValue = 0
|
| | | self.CmpValue2 = 0
|
| | | self.CmpValue3 = 0
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | length = 0
|
| | | length += 4
|
| | | length += 33
|
| | | length += 33
|
| | | length += 1
|
| | | length += 4
|
| | | length += 4
|
| | | length += 4
|
| | | length += 4
|
| | | length += 4
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | data = ''
|
| | | data = CommFunc.WriteDWORD(data, self.ID)
|
| | | data = CommFunc.WriteString(data, 33, self.Name1)
|
| | | data = CommFunc.WriteString(data, 33, self.Name2)
|
| | | data = CommFunc.WriteBYTE(data, self.Type2)
|
| | | data = CommFunc.WriteDWORD(data, self.Value1)
|
| | | data = CommFunc.WriteDWORD(data, self.Value2)
|
| | | data = CommFunc.WriteDWORD(data, self.CmpValue)
|
| | | data = CommFunc.WriteDWORD(data, self.CmpValue2)
|
| | | data = CommFunc.WriteDWORD(data, self.CmpValue3)
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''
|
| | | ID:%d,
|
| | | Name1:%s,
|
| | | Name2:%s,
|
| | | Type2:%d,
|
| | | Value1:%d,
|
| | | Value2:%d,
|
| | | CmpValue:%d,
|
| | | CmpValue2:%d,
|
| | | CmpValue3:%d
|
| | | '''\
|
| | | %(
|
| | | self.ID,
|
| | | self.Name1,
|
| | | self.Name2,
|
| | | self.Type2,
|
| | | self.Value1,
|
| | | self.Value2,
|
| | | self.CmpValue,
|
| | | self.CmpValue2,
|
| | | self.CmpValue3
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | class tagGCCrossBillboardInfo(Structure):
|
| | | Head = tagHead()
|
| | | Type = 0 #(BYTE Type)//榜单类型
|
| | | GroupValue1 = 0 #(BYTE GroupValue1)// 分组值1
|
| | | GroupValue2 = 0 #(BYTE GroupValue2)// 分组值2,与分组值1组合归为同组榜单数据
|
| | | BillboardCount = 0 #(BYTE BillboardCount)
|
| | | CrossBillboardDataList = list() #(vector<tagGCCrossBillboardData> CrossBillboardDataList)
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Head.Cmd = 0xC0
|
| | | self.Head.SubCmd = 0x07
|
| | | return
|
| | |
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | _pos = self.Head.ReadData(_lpData, _pos)
|
| | | self.Type,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.GroupValue1,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.GroupValue2,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.BillboardCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | for i in range(self.BillboardCount):
|
| | | temCrossBillboardDataList = tagGCCrossBillboardData()
|
| | | _pos = temCrossBillboardDataList.ReadData(_lpData, _pos)
|
| | | self.CrossBillboardDataList.append(temCrossBillboardDataList)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.Head = tagHead()
|
| | | self.Head.Clear()
|
| | | self.Head.Cmd = 0xC0
|
| | | self.Head.SubCmd = 0x07
|
| | | self.Type = 0
|
| | | self.GroupValue1 = 0
|
| | | self.GroupValue2 = 0
|
| | | self.BillboardCount = 0
|
| | | self.CrossBillboardDataList = list()
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | length = 0
|
| | | length += self.Head.GetLength()
|
| | | length += 1
|
| | | length += 1
|
| | | length += 1
|
| | | length += 1
|
| | | for i in range(self.BillboardCount):
|
| | | length += self.CrossBillboardDataList[i].GetLength()
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | data = ''
|
| | | data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
|
| | | data = CommFunc.WriteBYTE(data, self.Type)
|
| | | data = CommFunc.WriteBYTE(data, self.GroupValue1)
|
| | | data = CommFunc.WriteBYTE(data, self.GroupValue2)
|
| | | data = CommFunc.WriteBYTE(data, self.BillboardCount)
|
| | | for i in range(self.BillboardCount):
|
| | | data = CommFunc.WriteString(data, self.CrossBillboardDataList[i].GetLength(), self.CrossBillboardDataList[i].GetBuffer())
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''
|
| | | Head:%s,
|
| | | Type:%d,
|
| | | GroupValue1:%d,
|
| | | GroupValue2:%d,
|
| | | BillboardCount:%d,
|
| | | CrossBillboardDataList:%s
|
| | | '''\
|
| | | %(
|
| | | self.Head.OutputString(),
|
| | | self.Type,
|
| | | self.GroupValue1,
|
| | | self.GroupValue2,
|
| | | self.BillboardCount,
|
| | | "..."
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagGCCrossBillboardInfo=tagGCCrossBillboardInfo()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCCrossBillboardInfo.Head.Cmd,m_NAtagGCCrossBillboardInfo.Head.SubCmd))] = m_NAtagGCCrossBillboardInfo
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # AA 32 跨服充值排行活动信息 #tagMCCACTGBillboardInfo
|
| | |
|
| | | class tagMCCACTGBillboardAwardItem(Structure):
|
| | | _pack_ = 1
|
| | | _fields_ = [
|
| | | ("ItemID", c_int), |
| | | ("ItemCount", c_ushort), |
| | | ("IsBind", c_ubyte), # 是否拍品
|
| | | ]
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | 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.ItemID = 0
|
| | | self.ItemCount = 0
|
| | | self.IsBind = 0
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | return sizeof(tagMCCACTGBillboardAwardItem)
|
| | |
|
| | | def GetBuffer(self):
|
| | | return string_at(addressof(self), self.GetLength())
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''// AA 32 跨服充值排行活动信息 //tagMCCACTGBillboardInfo:
|
| | | ItemID:%d,
|
| | | ItemCount:%d,
|
| | | IsBind:%d
|
| | | '''\
|
| | | %(
|
| | | self.ItemID,
|
| | | self.ItemCount,
|
| | | self.IsBind
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | class tagMCCACTGBillboardDabiao(Structure):
|
| | | AwardIndex = 0 #(BYTE AwardIndex)// 奖励索引 0~31
|
| | | NeedRMB = 0 #(DWORD NeedRMB)// 所需充值RMB
|
| | | AwardItemCount = 0 #(BYTE AwardItemCount)// 奖励物品数
|
| | | AwardItemList = list() #(vector<tagMCCACTGBillboardAwardItem> AwardItemList)// 奖励物品信息
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | return
|
| | |
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | self.AwardIndex,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.NeedRMB,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.AwardItemCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | for i in range(self.AwardItemCount):
|
| | | temAwardItemList = tagMCCACTGBillboardAwardItem()
|
| | | _pos = temAwardItemList.ReadData(_lpData, _pos)
|
| | | self.AwardItemList.append(temAwardItemList)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.AwardIndex = 0
|
| | | self.NeedRMB = 0
|
| | | self.AwardItemCount = 0
|
| | | self.AwardItemList = list()
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | length = 0
|
| | | length += 1
|
| | | length += 4
|
| | | length += 1
|
| | | for i in range(self.AwardItemCount):
|
| | | length += self.AwardItemList[i].GetLength()
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | data = ''
|
| | | data = CommFunc.WriteBYTE(data, self.AwardIndex)
|
| | | data = CommFunc.WriteDWORD(data, self.NeedRMB)
|
| | | data = CommFunc.WriteBYTE(data, self.AwardItemCount)
|
| | | for i in range(self.AwardItemCount):
|
| | | data = CommFunc.WriteString(data, self.AwardItemList[i].GetLength(), self.AwardItemList[i].GetBuffer())
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''
|
| | | AwardIndex:%d,
|
| | | NeedRMB:%d,
|
| | | AwardItemCount:%d,
|
| | | AwardItemList:%s
|
| | | '''\
|
| | | %(
|
| | | self.AwardIndex,
|
| | | self.NeedRMB,
|
| | | self.AwardItemCount,
|
| | | "..."
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | class tagMCCACTGBillboardOrder(Structure):
|
| | | OrderA = 0 #(BYTE OrderA)// 名次A
|
| | | OrderB = 0 #(BYTE OrderB)// 至名次B
|
| | | NeedRMB = 0 #(DWORD NeedRMB)// 所需充值RMB,未达标的该名次空,排名后面的玩家向下顺延
|
| | | AwardItemCount = 0 #(BYTE AwardItemCount)// 奖励物品数
|
| | | AwardItemList = list() #(vector<tagMCCACTGBillboardAwardItem> AwardItemList)// 奖励物品信息
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | return
|
| | |
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | self.OrderA,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.OrderB,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.NeedRMB,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.AwardItemCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | for i in range(self.AwardItemCount):
|
| | | temAwardItemList = tagMCCACTGBillboardAwardItem()
|
| | | _pos = temAwardItemList.ReadData(_lpData, _pos)
|
| | | self.AwardItemList.append(temAwardItemList)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.OrderA = 0
|
| | | self.OrderB = 0
|
| | | self.NeedRMB = 0
|
| | | self.AwardItemCount = 0
|
| | | self.AwardItemList = list()
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | length = 0
|
| | | length += 1
|
| | | length += 1
|
| | | length += 4
|
| | | length += 1
|
| | | for i in range(self.AwardItemCount):
|
| | | length += self.AwardItemList[i].GetLength()
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | data = ''
|
| | | data = CommFunc.WriteBYTE(data, self.OrderA)
|
| | | data = CommFunc.WriteBYTE(data, self.OrderB)
|
| | | data = CommFunc.WriteDWORD(data, self.NeedRMB)
|
| | | data = CommFunc.WriteBYTE(data, self.AwardItemCount)
|
| | | for i in range(self.AwardItemCount):
|
| | | data = CommFunc.WriteString(data, self.AwardItemList[i].GetLength(), self.AwardItemList[i].GetBuffer())
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''
|
| | | OrderA:%d,
|
| | | OrderB:%d,
|
| | | NeedRMB:%d,
|
| | | AwardItemCount:%d,
|
| | | AwardItemList:%s
|
| | | '''\
|
| | | %(
|
| | | self.OrderA,
|
| | | self.OrderB,
|
| | | self.NeedRMB,
|
| | | self.AwardItemCount,
|
| | | "..."
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | class tagMCCACTGBillboardTempInfo(Structure):
|
| | | TemplateID = 0 #(BYTE TemplateID)// 活动模板ID
|
| | | DabiaoAwardCount = 0 #(BYTE DabiaoAwardCount)// 达标奖励档数
|
| | | DabiaoAwardInfo = list() #(vector<tagMCCACTGBillboardDabiao> DabiaoAwardInfo)// 达标奖励信息
|
| | | OrderAwardCount = 0 #(BYTE OrderAwardCount)// 排行奖励档数
|
| | | OrderAwardInfo = list() #(vector<tagMCCACTGBillboardOrder> OrderAwardInfo)// 排行奖励信息
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | return
|
| | |
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | self.TemplateID,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.DabiaoAwardCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | for i in range(self.DabiaoAwardCount):
|
| | | temDabiaoAwardInfo = tagMCCACTGBillboardDabiao()
|
| | | _pos = temDabiaoAwardInfo.ReadData(_lpData, _pos)
|
| | | self.DabiaoAwardInfo.append(temDabiaoAwardInfo)
|
| | | self.OrderAwardCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | for i in range(self.OrderAwardCount):
|
| | | temOrderAwardInfo = tagMCCACTGBillboardOrder()
|
| | | _pos = temOrderAwardInfo.ReadData(_lpData, _pos)
|
| | | self.OrderAwardInfo.append(temOrderAwardInfo)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.TemplateID = 0
|
| | | self.DabiaoAwardCount = 0
|
| | | self.DabiaoAwardInfo = list()
|
| | | self.OrderAwardCount = 0
|
| | | self.OrderAwardInfo = list()
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | length = 0
|
| | | length += 1
|
| | | length += 1
|
| | | for i in range(self.DabiaoAwardCount):
|
| | | length += self.DabiaoAwardInfo[i].GetLength()
|
| | | length += 1
|
| | | for i in range(self.OrderAwardCount):
|
| | | length += self.OrderAwardInfo[i].GetLength()
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | data = ''
|
| | | data = CommFunc.WriteBYTE(data, self.TemplateID)
|
| | | data = CommFunc.WriteBYTE(data, self.DabiaoAwardCount)
|
| | | for i in range(self.DabiaoAwardCount):
|
| | | data = CommFunc.WriteString(data, self.DabiaoAwardInfo[i].GetLength(), self.DabiaoAwardInfo[i].GetBuffer())
|
| | | data = CommFunc.WriteBYTE(data, self.OrderAwardCount)
|
| | | for i in range(self.OrderAwardCount):
|
| | | data = CommFunc.WriteString(data, self.OrderAwardInfo[i].GetLength(), self.OrderAwardInfo[i].GetBuffer())
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''
|
| | | TemplateID:%d,
|
| | | DabiaoAwardCount:%d,
|
| | | DabiaoAwardInfo:%s,
|
| | | OrderAwardCount:%d,
|
| | | OrderAwardInfo:%s
|
| | | '''\
|
| | | %(
|
| | | self.TemplateID,
|
| | | self.DabiaoAwardCount,
|
| | | "...",
|
| | | self.OrderAwardCount,
|
| | | "..."
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | class tagMCCACTGBillboardInfo(Structure):
|
| | | Head = tagHead()
|
| | | ServerInfoLen = 0 #(BYTE ServerInfoLen)
|
| | | ServerIDRangeInfo = "" #(String ServerIDRangeInfo)//开放该活动的服务器ID范围列表,json格式 [[IDA, IDB], ...], [] 为全服
|
| | | GroupValue1 = 0 #(BYTE GroupValue1)// 活动榜单分组值1,用于查询对应榜单
|
| | | StartDate = "" #(char StartDate[10])// 开始日期 y-m-d
|
| | | EndtDate = "" #(char EndtDate[10])// 结束日期 y-m-d
|
| | | TemplateID = 0 #(BYTE TemplateID)// 当前活动模板ID
|
| | | TemplateCount = 0 #(BYTE TemplateCount)
|
| | | TempInfo = list() #(vector<tagMCCACTGBillboardTempInfo> TempInfo)// 模板信息
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Head.Cmd = 0xAA
|
| | | self.Head.SubCmd = 0x32
|
| | | return
|
| | |
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | _pos = self.Head.ReadData(_lpData, _pos)
|
| | | self.ServerInfoLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.ServerIDRangeInfo,_pos = CommFunc.ReadString(_lpData, _pos,self.ServerInfoLen)
|
| | | self.GroupValue1,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.StartDate,_pos = CommFunc.ReadString(_lpData, _pos,10)
|
| | | self.EndtDate,_pos = CommFunc.ReadString(_lpData, _pos,10)
|
| | | self.TemplateID,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.TemplateCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | for i in range(self.TemplateCount):
|
| | | temTempInfo = tagMCCACTGBillboardTempInfo()
|
| | | _pos = temTempInfo.ReadData(_lpData, _pos)
|
| | | self.TempInfo.append(temTempInfo)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.Head = tagHead()
|
| | | self.Head.Clear()
|
| | | self.Head.Cmd = 0xAA
|
| | | self.Head.SubCmd = 0x32
|
| | | self.ServerInfoLen = 0
|
| | | self.ServerIDRangeInfo = ""
|
| | | self.GroupValue1 = 0
|
| | | self.StartDate = ""
|
| | | self.EndtDate = ""
|
| | | self.TemplateID = 0
|
| | | self.TemplateCount = 0
|
| | | self.TempInfo = list()
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | length = 0
|
| | | length += self.Head.GetLength()
|
| | | length += 1
|
| | | length += len(self.ServerIDRangeInfo)
|
| | | length += 1
|
| | | length += 10
|
| | | length += 10
|
| | | length += 1
|
| | | length += 1
|
| | | for i in range(self.TemplateCount):
|
| | | length += self.TempInfo[i].GetLength()
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | data = ''
|
| | | data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
|
| | | data = CommFunc.WriteBYTE(data, self.ServerInfoLen)
|
| | | data = CommFunc.WriteString(data, self.ServerInfoLen, self.ServerIDRangeInfo)
|
| | | data = CommFunc.WriteBYTE(data, self.GroupValue1)
|
| | | data = CommFunc.WriteString(data, 10, self.StartDate)
|
| | | data = CommFunc.WriteString(data, 10, self.EndtDate)
|
| | | data = CommFunc.WriteBYTE(data, self.TemplateID)
|
| | | data = CommFunc.WriteBYTE(data, self.TemplateCount)
|
| | | for i in range(self.TemplateCount):
|
| | | data = CommFunc.WriteString(data, self.TempInfo[i].GetLength(), self.TempInfo[i].GetBuffer())
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''
|
| | | Head:%s,
|
| | | ServerInfoLen:%d,
|
| | | ServerIDRangeInfo:%s,
|
| | | GroupValue1:%d,
|
| | | StartDate:%s,
|
| | | EndtDate:%s,
|
| | | TemplateID:%d,
|
| | | TemplateCount:%d,
|
| | | TempInfo:%s
|
| | | '''\
|
| | | %(
|
| | | self.Head.OutputString(),
|
| | | self.ServerInfoLen,
|
| | | self.ServerIDRangeInfo,
|
| | | self.GroupValue1,
|
| | | self.StartDate,
|
| | | self.EndtDate,
|
| | | self.TemplateID,
|
| | | self.TemplateCount,
|
| | | "..."
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagMCCACTGBillboardInfo=tagMCCACTGBillboardInfo()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCCACTGBillboardInfo.Head.Cmd,m_NAtagMCCACTGBillboardInfo.Head.SubCmd))] = m_NAtagMCCACTGBillboardInfo
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # AA 33 跨服充值排行活动玩家信息 #tagMCCACTGBillboardPlayerInfo
|
| | |
|
| | | class tagMCCACTGBillboardPlayerInfo(Structure):
|
| | | _pack_ = 1
|
| | | _fields_ = [
|
| | | ("Cmd", c_ubyte),
|
| | | ("SubCmd", c_ubyte),
|
| | | ("CTGRMBTotal", c_int), # 活动已累计充值RMB
|
| | | ("DabiaoAwardRecord", c_int), # 达标奖励记录,与达标奖励索引位或运算判断是否已领取
|
| | | ]
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Cmd = 0xAA
|
| | | self.SubCmd = 0x33
|
| | | 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 = 0xAA
|
| | | self.SubCmd = 0x33
|
| | | self.CTGRMBTotal = 0
|
| | | self.DabiaoAwardRecord = 0
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | return sizeof(tagMCCACTGBillboardPlayerInfo)
|
| | |
|
| | | def GetBuffer(self):
|
| | | return string_at(addressof(self), self.GetLength())
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''// AA 33 跨服充值排行活动玩家信息 //tagMCCACTGBillboardPlayerInfo:
|
| | | Cmd:%s,
|
| | | SubCmd:%s,
|
| | | CTGRMBTotal:%d,
|
| | | DabiaoAwardRecord:%d
|
| | | '''\
|
| | | %(
|
| | | self.Cmd,
|
| | | self.SubCmd,
|
| | | self.CTGRMBTotal,
|
| | | self.DabiaoAwardRecord
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagMCCACTGBillboardPlayerInfo=tagMCCACTGBillboardPlayerInfo()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCCACTGBillboardPlayerInfo.Cmd,m_NAtagMCCACTGBillboardPlayerInfo.SubCmd))] = m_NAtagMCCACTGBillboardPlayerInfo
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # AA 09 消费返利活动信息 #tagMCCostRebateInfo
|
| | |
|
| | | class tagMCCostRebateAwardItem(Structure):
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package GM.Commands.BillboardDataCross
|
| | | #
|
| | | # @todo:跨服榜单数据
|
| | | # @author hxp
|
| | | # @date 2021-01-13
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 跨服榜单数据
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2021-01-13 17:00"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import GameWorld
|
| | | import ShareDefine
|
| | | import PyDataManager
|
| | | import CrossBillboard
|
| | |
|
| | | def __Help(curPlayer, errInfo=""):
|
| | | GameWorld.DebugAnswer(curPlayer, "---------- %s" % GameWorld.GetCurrentDataTimeStr())
|
| | | if errInfo:
|
| | | GameWorld.DebugAnswer(curPlayer, errInfo)
|
| | | GameWorld.DebugAnswer(curPlayer, "新增跨服榜单假数据: BillboardDataCross 类型 分组值1 分组值2 条数 比较值1 可选参数(比较值2 常规值1 常规值2)")
|
| | | GameWorld.DebugAnswer(curPlayer, "删除跨服榜单假数据: BillboardDataCross 类型 分组值1 分组值2")
|
| | | GameWorld.DebugAnswer(curPlayer, "跨服运营活动榜类型:150-充值")
|
| | | return
|
| | |
|
| | | ## 执行逻辑
|
| | | # @param curPlayer 当前玩家
|
| | | # @param gmList []
|
| | | # @return None
|
| | | def OnExec(curPlayer, gmList):
|
| | | |
| | | paramLen = len(gmList)
|
| | | if paramLen < 3:
|
| | | __Help(curPlayer)
|
| | | return
|
| | | |
| | | billboardType = gmList[0]
|
| | | if billboardType not in ShareDefine.CrossBillboardTypeList:
|
| | | __Help(curPlayer, "榜单类型不存在!")
|
| | | return
|
| | | |
| | | GameWorld.DebugAnswer(curPlayer, "发送完毕,执行结果查看跨服服务器!")
|
| | | return
|
| | |
|
| | | def OnGetMergeParam(curPlayer):
|
| | | ## 跨服命令额外参数
|
| | | return []
|
| | |
|
| | | def OnMergeServerExec(gmList, tick):
|
| | | ## 跨服执行命令
|
| | | |
| | | paramLen = len(gmList)
|
| | | if paramLen < 3:
|
| | | return
|
| | | |
| | | billboardType = gmList[0]
|
| | | groupValue1 = gmList[1]
|
| | | groupValue2 = gmList[2]
|
| | | |
| | | billboardMgr = PyDataManager.GetCrossBillboardManager()
|
| | | billboardObj = billboardMgr.GetCrossBillboard(billboardType, groupValue1, groupValue2)
|
| | | |
| | | curDataCount = billboardObj.GetCount()
|
| | | maxDataCount = billboardObj.GetMaxCount()
|
| | | |
| | | # 清除榜单假数据
|
| | | if paramLen == 3:
|
| | | billboardObj.ClearData()
|
| | | GameWorld.Log("删除跨服榜单(%s-%s-%s): %s 条" % (billboardType, groupValue1, groupValue2, curDataCount))
|
| | | return
|
| | | |
| | | count = gmList[3] if len(gmList) > 3 else 0
|
| | | cmpValue1 = gmList[4] if len(gmList) > 4 else 0
|
| | | cmpValue2 = gmList[5] if len(gmList) > 5 else 0
|
| | | value1 = gmList[6] if len(gmList) > 6 else 0
|
| | | value2 = gmList[7] if len(gmList) > 7 else 0
|
| | | |
| | | id2 = 0
|
| | | type2 = 0
|
| | | name2 = ""
|
| | | cmpValue3 = 0
|
| | | |
| | | count = min(count, maxDataCount - curDataCount)
|
| | | FakeName = "假名字".decode(ShareDefine.Def_Game_Character_Encoding).encode(GameWorld.GetCharacterEncoding())
|
| | | |
| | | for i in xrange(count):
|
| | | dataPlayerID = curDataCount + 1 + i
|
| | | dataPlayerName = "%s%s" % (FakeName, i)
|
| | | dataCmpValue1 = max(0, cmpValue1 - i)
|
| | | dataCmpValue2 = max(0, cmpValue2 - i)
|
| | | |
| | | dataID = dataPlayerID
|
| | | name1 = dataPlayerName
|
| | | cmpValue = dataCmpValue1
|
| | | cmpValue2 = dataCmpValue2
|
| | | CrossBillboard.UpdCrossBillboard(billboardType, groupValue1, dataID, name1, name2, type2, value1, value2, cmpValue, cmpValue2, cmpValue3, groupValue2, id2)
|
| | | |
| | | GameWorld.Log("插入虚假榜单(%s-%s-%s): %s 条" % (billboardType, groupValue1, groupValue2, count))
|
| | | return
|
| | |
|
| | |
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package GM.Commands.GMT_CrossActServerIDChange
|
| | | #
|
| | | # @todo:跨服活动区服ID修改
|
| | | # @author hxp
|
| | | # @date 2021-01-13
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 跨服活动区服ID修改
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2021-01-13 17:00"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import GameWorld
|
| | | import DataRecordPack
|
| | | import CrossActionControl
|
| | | import CrossRealmMsg
|
| | | import ShareDefine
|
| | | import GMCommon
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | |
|
| | | ## 执行逻辑
|
| | | # @param curPlayer 当前玩家
|
| | | # @param gmCmdDict: 命令字典
|
| | | # @return None
|
| | | # @remarks 函数详细说明.
|
| | | def OnExec(orderId, gmCmdDict):
|
| | | |
| | | GameWorld.Log("GMT_CrossActServerIDChange gmCmdDict=%s" % str(gmCmdDict))
|
| | | |
| | | if not GameWorld.IsCrossServer():
|
| | | GMCommon.GMCommandResult(orderId, gmCmdDict, GMCommon.Def_IsNotCrossServer)
|
| | | return
|
| | | |
| | | errInfo = ""
|
| | | doChange = gmCmdDict.get("doChange")
|
| | | if doChange:
|
| | | errInfo = __DoChangeCrossActServerIDRangeList(gmCmdDict)
|
| | | |
| | | crossActInfoDict = CrossActionControl.GetCrossActInfoDict()
|
| | | backMsg = {"crossActInfoDict":crossActInfoDict}
|
| | | if errInfo:
|
| | | backMsg["ErrorInfo"] = errInfo
|
| | | GMCommon.GMCommandResult(orderId, gmCmdDict, GMCommon.Def_ParamErr, backMsg)
|
| | | return
|
| | | |
| | | # 记录流向
|
| | | DataRecordPack.DR_ToolGMOperate(0, '', '', 'GMT_CrossActServerIDChange', str(gmCmdDict))
|
| | | # 回复
|
| | | GMCommon.GMCommandResult(orderId, gmCmdDict, GMCommon.Def_Success, backMsg)
|
| | | return
|
| | | |
| | | def __DoChangeCrossActServerIDRangeList(gmCmdDict):
|
| | | |
| | | crossActInfoDict = CrossActionControl.GetCrossActInfoDict()
|
| | | changeInfoDict = {} # {actName:{cfgID:ServerIDList, ...}, ...}
|
| | | for k, v in gmCmdDict.items():
|
| | | if not k.endswith("_ServerIDRangeList"):
|
| | | continue
|
| | | kspList = k.split("_")
|
| | | if len(kspList) != 3:
|
| | | continue
|
| | | actName, cfgID, _ = kspList
|
| | | try:
|
| | | cfgID = int(cfgID)
|
| | | changeServerIDList = eval(v)
|
| | | # 检查修改格式是否正确
|
| | | for changeList in changeServerIDList:
|
| | | if not (isinstance(changeList, list) |
| | | and len(changeList) == 2 |
| | | and isinstance(changeList[0], int) |
| | | and isinstance(changeList[1], int)
|
| | | ):
|
| | | errInfo = "%s CfgID(%s) error serverIDList(%s)" % (actName, cfgID, changeList)
|
| | | return errInfo
|
| | | except:
|
| | | errInfo = "%s CfgID(%s) error %s" % (actName, cfgID, v)
|
| | | return errInfo
|
| | | |
| | | if actName not in changeInfoDict:
|
| | | changeInfoDict[actName] = {}
|
| | | changeInfoDict[actName][cfgID] = changeServerIDList
|
| | | |
| | | GameWorld.Log(" crossActInfoDict=%s" % crossActInfoDict)
|
| | | GameWorld.Log(" changeInfoDict=%s" % changeInfoDict)
|
| | | if not changeInfoDict:
|
| | | errInfo = "no change info!"
|
| | | return errInfo
|
| | | |
| | | # 检查修改后是否有交叉
|
| | | checkGroupInfo = {} # {actName:{actGroupName:[cfgID, ...], ...}} # 先分组
|
| | | for actName, actInfoDict in crossActInfoDict.items():
|
| | | if actName not in changeInfoDict:
|
| | | # 没有修改的活动不需要检查
|
| | | continue
|
| | | if actName not in checkGroupInfo:
|
| | | checkGroupInfo[actName] = {}
|
| | | actGroupListDict = checkGroupInfo[actName]
|
| | | for cfgID, actInfo in actInfoDict.items():
|
| | | actGroupName = actInfo[ShareDefine.ActKey_IpyDataInfo]["ActGroupName"]
|
| | | if actGroupName not in actGroupListDict:
|
| | | actGroupListDict[actGroupName] = []
|
| | | cfgIDList = actGroupListDict[actGroupName]
|
| | | cfgIDList.append(cfgID)
|
| | | |
| | | GameWorld.Log(" checkGroupInfo: %s" % checkGroupInfo)
|
| | | |
| | | for actName, actGroupListDict in checkGroupInfo.items():
|
| | | actInfoDict = crossActInfoDict[actName]
|
| | | changeInfo = changeInfoDict.get(actName, {})
|
| | | for actGroupName, cfgIDList in actGroupListDict.items():
|
| | | allServerIDRangeList = []
|
| | | for cfgID in cfgIDList:
|
| | | befActInfo = actInfoDict[cfgID]
|
| | | if cfgID in changeInfo:
|
| | | allServerIDRangeList.extend(changeInfo[cfgID])
|
| | | else:
|
| | | befServerIDList = befActInfo[ShareDefine.ActKey_ServerIDRangeList]
|
| | | allServerIDRangeList.extend(befServerIDList)
|
| | | |
| | | GameWorld.Log(" actName=%s,actGroupName=%s,cfgIDList=%s" % (actName, actGroupName, cfgIDList))
|
| | | GameWorld.Log(" allServerIDRangeList=%s" % (allServerIDRangeList))
|
| | | errorServerIDList = []
|
| | | for i in xrange(len(allServerIDRangeList)):
|
| | | checkIDA, checkIDB = allServerIDRangeList[i]
|
| | | for j in xrange(i):
|
| | | serverIDA, serverIDB = allServerIDRangeList[j]
|
| | | if serverIDA <= checkIDA <= serverIDB:
|
| | | errorServerIDList.append(checkIDA)
|
| | | |
| | | if serverIDA <= checkIDB <= serverIDB:
|
| | | errorServerIDList.append(checkIDB)
|
| | | |
| | | GameWorld.Log(" errorServerIDList=%s" % (errorServerIDList))
|
| | | if errorServerIDList:
|
| | | return "%s exist errorServerIDList=%s in actGroupName(%s)" % (actName, errorServerIDList, actGroupName)
|
| | | |
| | | # 检查通过后进行修改
|
| | | sysnCrossActInfoDict = {}
|
| | | GameWorld.Log(" do change...")
|
| | | for actName, changInfo in changeInfoDict.items():
|
| | | for cfgID, changeServerIDRangeList in changInfo.items():
|
| | | if actName not in crossActInfoDict:
|
| | | continue
|
| | | if cfgID not in crossActInfoDict[actName]:
|
| | | continue
|
| | | actInfoDict = crossActInfoDict[actName][cfgID]
|
| | | beforeServerIDRangeList = actInfoDict[ShareDefine.ActKey_ServerIDRangeList]
|
| | | # 直接覆盖替换
|
| | | actInfoDict[ShareDefine.ActKey_ServerIDRangeList] = changeServerIDRangeList
|
| | | |
| | | GameWorld.Log(" actName=%s,cfgID=%s,beforeServerIDRangeList=%s -> %s" |
| | | % (actName, cfgID, beforeServerIDRangeList, changeServerIDRangeList))
|
| | | |
| | | if actName not in sysnCrossActInfoDict:
|
| | | sysnCrossActInfoDict[actName] = {}
|
| | | sysnCrossActInfoDict[actName][cfgID] = actInfoDict
|
| | | |
| | | GameWorld.Log(" changeOK! crossActInfoDict=%s" % crossActInfoDict)
|
| | | |
| | | # 同步子服务器
|
| | | serverGroupIDList = []
|
| | | CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossActInfo, sysnCrossActInfoDict, serverGroupIDList)
|
| | | return ""
|
| | |
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package GM.Commands.GMT_QueryBillboardCross
|
| | | #
|
| | | # @todo:查询跨服排行榜
|
| | | # @author hxp
|
| | | # @date 2021-01-13
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 查询跨服排行榜
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2021-01-13 17:00"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | #导入
|
| | | import GMCommon
|
| | | import ShareDefine
|
| | | import PyDataManager
|
| | | import GameWorld
|
| | |
|
| | |
|
| | | #逻辑实现(这里curPlayer = None)
|
| | | ## 执行逻辑
|
| | | # @param curPlayer 当前玩家
|
| | | # @param gmList [cmdIndex gmAccID forbidAcc]
|
| | | # @return None
|
| | | # @remarks 函数详细说明.
|
| | | def OnExec(orderId, gmCmdDict):
|
| | | |
| | | if not GameWorld.IsCrossServer():
|
| | | GMCommon.GMCommandResult(orderId, gmCmdDict, GMCommon.Def_IsNotCrossServer)
|
| | | return
|
| | | |
| | | billboardType = GameWorld.ToIntDef(gmCmdDict.get('billboardType', ''), None)
|
| | | billType = GameWorld.ToIntDef(gmCmdDict.get('billType', ''), None) # 其他指定类型
|
| | | if billType != None:
|
| | | billboardType = billType
|
| | | |
| | | if billboardType == None or billboardType not in ShareDefine.CrossBillboardTypeList:
|
| | | GMCommon.GMCommandResult(orderId, gmCmdDict, GMCommon.Def_TypeNumErr)
|
| | | return
|
| | | |
| | | groupValue1 = GameWorld.ToIntDef(gmCmdDict.get('groupValue1', ''), None)
|
| | | groupValue2 = GameWorld.ToIntDef(gmCmdDict.get('groupValue2', ''), None)
|
| | | |
| | | billboardMgr = PyDataManager.GetCrossBillboardManager()
|
| | | groupList = billboardMgr.GetBillboardGroupList(billboardType)
|
| | | |
| | | backMsg = {"billboardType":billboardType, "groupList":groupList}
|
| | | |
| | | if groupValue1 != None and groupValue2 != None:
|
| | | billboardObj = billboardMgr.GetCrossBillboard(billboardType, groupValue1, groupValue2)
|
| | | |
| | | billboardInfo = []
|
| | | for i in xrange(billboardObj.GetCount()):
|
| | | billboardData = billboardObj.At(i)
|
| | | if not billboardData:
|
| | | continue
|
| | | billboardDict = {
|
| | | "ID":billboardData.ID,
|
| | | "ID2":billboardData.ID2,
|
| | | "Name1":billboardData.Name1,
|
| | | "Name2":billboardData.Name2,
|
| | | "Type2":billboardData.Type2,
|
| | | "Value1":billboardData.Value1,
|
| | | "Value2":billboardData.Value2,
|
| | | "CmpValue":billboardData.CmpValue,
|
| | | "CmpValue2":billboardData.CmpValue2,
|
| | | "CmpValue3":billboardData.CmpValue3,
|
| | | }
|
| | | |
| | | for k, v in billboardDict.items():
|
| | | if not v:
|
| | | billboardDict.pop(k)
|
| | | |
| | | billboardInfo.append(billboardDict)
|
| | | |
| | | backMsg.update({"billboardInfo":billboardInfo, "groupValue1":groupValue1, "groupValue2":groupValue2})
|
| | | |
| | | #执行成功
|
| | | GMCommon.GMCommandResult(orderId, gmCmdDict, GMCommon.Def_Success, backMsg)
|
| | | return
|
| | |
|
| | | |
| | | |
| | |
| | | GameWorld.Log("###使用GM命令 = %s错误,玩家不是GM"%(callFunName), curPlayer.GetPlayerID())
|
| | | return
|
| | |
|
| | | #把剩余参数转换为整型
|
| | | for i in range(0, len(alist)):
|
| | | if i == 0:
|
| | | continue
|
| | | value = GameWorld.ToIntDef(alist[i], None)
|
| | | if value == None:
|
| | | #GameWorld.DebugAnswer(curPlayer, "参数错误, 参数%s必须为纯数字!" % (i + 1))
|
| | | continue
|
| | | alist[i] = value
|
| | | |
| | | #非跨服服务器下使用跨服GM命令,则发送到跨服
|
| | | if not GameWorld.IsCrossServer():
|
| | | callFunc = GameWorld.GetExecFunc(Commands, "%s.%s"%(callFunName, "OnGetMergeParam"))
|
| | | if callFunc != None:
|
| | | extendParamList = callFunc(curPlayer)
|
| | | alist.extend(extendParamList)
|
| | | CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_GMCMD, alist)
|
| | | CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_GMCMD, alist + extendParamList)
|
| | |
|
| | | callFunc = GameWorld.GetExecFunc(Commands, "%s.%s"%(callFunName, "OnExec"))
|
| | | if callFunc == None:
|
| | |
| | | GameWorld.DebugAnswer(curPlayer, 'no cmd !!!')
|
| | | return
|
| | |
|
| | | #删除命令,只将参数传入
|
| | | del alist[0]
|
| | | #把剩余参数转换为整型
|
| | | for i in range(0, len(alist)):
|
| | | value = GameWorld.ToIntDef(alist[i], None)
|
| | | if value == None:
|
| | | #GameWorld.DebugAnswer(curPlayer, "参数错误, 参数%s必须为纯数字!" % (i + 1))
|
| | | continue
|
| | | alist[i] = value
|
| | | |
| | | callFunc(curPlayer,alist)
|
| | | callFunc(curPlayer, alist[1:])
|
| | |
|
| | | except BaseException:
|
| | | GameWorld.DebugAnswer(curPlayer, "执行GM命令错误, 请查看GameServer日志!")
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package CrossActCTGBillboard
|
| | | #
|
| | | # @todo:跨服运营活动 - 充值排行
|
| | | # @author hxp
|
| | | # @date 2021-01-13
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 跨服运营活动 - 充值排行
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2021-01-13 17:00"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import ShareDefine
|
| | | import PyDataManager
|
| | | import PlayerCompensation
|
| | | import IpyGameDataPY
|
| | | import GameWorld
|
| | |
|
| | | def OnActIDChange(cfgID, dbTemplateID, state):
|
| | | ## 活动ID变更
|
| | | |
| | | # 先结算上期活动
|
| | | __GiveBillboardOrderAward(cfgID, dbTemplateID)
|
| | | |
| | | # 如果有新活动,处理新活动
|
| | | if not state:
|
| | | return
|
| | | |
| | | groupValue1 = cfgID
|
| | | billboardType = ShareDefine.Def_CBT_ActCTG
|
| | | |
| | | billboardMgr = PyDataManager.GetCrossBillboardManager()
|
| | | billboardObj = billboardMgr.GetCrossBillboard(billboardType, groupValue1)
|
| | | billboardObj.ClearData() # 新活动重置榜单数据
|
| | | |
| | | return
|
| | |
|
| | | def __GiveBillboardOrderAward(cfgID, dbTemplateID):
|
| | | ## 结算榜单排名奖励
|
| | | |
| | | groupValue1 = cfgID
|
| | | billboardType = ShareDefine.Def_CBT_ActCTG
|
| | | |
| | | # 先结算上期活动
|
| | | billboardMgr = PyDataManager.GetCrossBillboardManager()
|
| | | billboardObj = billboardMgr.GetCrossBillboard(billboardType, groupValue1)
|
| | | billboardDataCount = billboardObj.GetCount()
|
| | | if not billboardDataCount:
|
| | | GameWorld.Log("跨服充值排行数据为空! billboardType=%s,cfgID=%s" % (billboardType, cfgID))
|
| | | return
|
| | | |
| | | # 结算时排序并保存榜单数据流向
|
| | | billboardObj.SortData()
|
| | | billboardObj.SaveDRData()
|
| | | |
| | | GameWorld.Log("结算跨服充值排行奖励: billboardType=%s,cfgID=%s,dbTemplateID=%s,billboardDataCount=%s" |
| | | % (billboardType, cfgID, dbTemplateID, billboardDataCount))
|
| | | |
| | | orderIpyDataList = IpyGameDataPY.GetIpyGameDataList("CrossActCTGBillboardOrder", dbTemplateID)
|
| | | if not orderIpyDataList:
|
| | | return
|
| | | |
| | | billboardIndex = 0
|
| | | for ipyData in orderIpyDataList:
|
| | | orderA = ipyData.GetOrderA()
|
| | | orderB = ipyData.GetOrderB()
|
| | | ctgAtleast = ipyData.GetCTGAtleast()
|
| | | awardItemList = ipyData.GetAwardItemList()
|
| | | orderCountTotal = orderB - orderA + 1 # 奖励名次数量
|
| | | orderCount = 0
|
| | | |
| | | for index in xrange(billboardIndex, billboardDataCount):
|
| | | if orderCount >= orderCountTotal:
|
| | | break
|
| | | |
| | | billboardData = billboardObj.At(index)
|
| | | playerID = billboardData.ID
|
| | | ctgRMB = billboardData.CmpValue
|
| | | if ctgRMB < ctgAtleast:
|
| | | break
|
| | | |
| | | realOrder = orderA + orderCount
|
| | | paramList = [realOrder]
|
| | | PlayerCompensation.SendMailByKey("CABillboardCTGOrder", [playerID], awardItemList, paramList, crossMail=True)
|
| | | GameWorld.Log(" playerID=%s,榜单名次=%s,实际名次=%s,充值总RMB=%s" % (playerID, index + 1, realOrder, ctgRMB))
|
| | | |
| | | orderCount += 1
|
| | | billboardIndex += 1
|
| | | |
| | | # 结算完清除榜单数据
|
| | | billboardObj.ClearData()
|
| | | return
|
| | |
|
| | |
|
| | |
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package CrossActionControl
|
| | | #
|
| | | # @todo:跨服活动总开关逻辑
|
| | | # @author hxp
|
| | | # @date 2020-01-13
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 跨服活动总开关逻辑
|
| | | # 跨服活动的时间以跨服服务器为准,所有的状态控制由跨服服务器控制并广播子服务器
|
| | | # 子服仅做具体活动逻辑
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2020-01-13 17:00"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import GameWorld
|
| | | import ShareDefine
|
| | | import PlayerControl
|
| | | import IpyGameDataPY
|
| | | import CrossActCTGBillboard
|
| | | import CrossRealmMsg
|
| | | import PyGameData
|
| | | import ChConfig
|
| | |
|
| | | import datetime
|
| | | import time
|
| | |
|
| | | (
|
| | | CrossAct_ReloadSign, # 信息重载标记
|
| | | CrossAct_TodayInfo, # 当日的活动信息
|
| | | ) = range(2)
|
| | |
|
| | | def OnPlayerLogin(curPlayer):
|
| | | return
|
| | |
|
| | | def OnServerClose():
|
| | | if not GameWorld.IsCrossServer():
|
| | | return
|
| | | |
| | | GameWorld.GetUniversalRecMgr().Delete(ShareDefine.Def_UniversalGameRecType_CrossActInfo)
|
| | | |
| | | if not PyGameData.g_crossActInfoDict:
|
| | | return
|
| | | GameWorld.Log("保存跨服运营活动信息通用记录: ")
|
| | | |
| | | # 保存活动中的
|
| | | recDataList = GameWorld.GetUniversalRecMgr().GetTypeList(ShareDefine.Def_UniversalGameRecType_CrossActInfo)
|
| | | for actName, actInfoDict in PyGameData.g_crossActInfoDict.items():
|
| | | for cfgID, actInfo in actInfoDict.items():
|
| | | if not actInfo.get(ShareDefine.ActKey_State):
|
| | | # 非活动中的,已经结算过了,不需要存储
|
| | | continue
|
| | | state = actInfo.get(ShareDefine.ActKey_State, 0)
|
| | | actID = actInfo.get(ShareDefine.ActKey_ID, 0)
|
| | | templateID = actInfo.get(ShareDefine.ActKey_TemplateID, 0)
|
| | | serverIDRangeList = actInfo.get(ShareDefine.ActKey_ServerIDRangeList, "")
|
| | | recData = recDataList.AddRec()
|
| | | recData.SetStrValue1(actName)
|
| | | recData.SetStrValue3(str(serverIDRangeList))
|
| | | recData.SetValue1(cfgID)
|
| | | recData.SetValue2(state)
|
| | | recData.SetValue3(actID)
|
| | | recData.SetValue4(templateID)
|
| | | GameWorld.Log(" actName=%s,cfgID=%s,state=%s,actID=%s,templateID=%s,serverIDRangeList=%s" |
| | | % (actName, cfgID, state, actID, templateID, serverIDRangeList))
|
| | | |
| | | return
|
| | |
|
| | | def GetCrossActInfoDict():
|
| | | if PyGameData.g_crossActInfoDict == None:
|
| | | PyGameData.g_crossActInfoDict = {}
|
| | | |
| | | # 先加载通用记录存储中的活动信息
|
| | | recDataList = GameWorld.GetUniversalRecMgr().GetTypeList(ShareDefine.Def_UniversalGameRecType_CrossActInfo)
|
| | | GameWorld.Log("加载通用记录中的跨服运营活动信息: %s" % recDataList.Count())
|
| | | for index in xrange(recDataList.Count()):
|
| | | recData = recDataList.At(index)
|
| | | actName = recData.GetStrValue1()
|
| | | strValue3 = recData.GetStrValue3()
|
| | | serverIDRangeList = eval(strValue3) if strValue3 else []
|
| | | cfgID = recData.GetValue1()
|
| | | state = recData.GetValue2()
|
| | | actID = recData.GetValue3()
|
| | | templateID = recData.GetValue4()
|
| | | if not state:
|
| | | continue
|
| | | if actName not in PyGameData.g_crossActInfoDict:
|
| | | PyGameData.g_crossActInfoDict[actName] = {}
|
| | | actInfoDict = PyGameData.g_crossActInfoDict[actName]
|
| | | dbInfo = {ShareDefine.ActKey_ID:actID, ShareDefine.ActKey_State:state, ShareDefine.ActKey_TemplateID:templateID} # 活动ID、状态、模板信息单独存储,重置活动判断用
|
| | | actInfo = {ShareDefine.ActKey_CfgID:cfgID, ShareDefine.ActKey_ServerIDRangeList:serverIDRangeList}
|
| | | actInfo.update(dbInfo)
|
| | | actInfo[ShareDefine.ActKey_DBInfo] = dbInfo
|
| | | actInfoDict[cfgID] = actInfo
|
| | | |
| | | GameWorld.Log(" actName=%s,cfgID=%s, %s" % (actName, cfgID, actInfoDict))
|
| | | |
| | | return PyGameData.g_crossActInfoDict
|
| | |
|
| | | def __GetParseIpyDataList(ipyDataMgr, actName, actInfoDict):
|
| | | ## 获取需要处理的合法分组活动配置列表,已经在活动中的必须要处理
|
| | | |
| | | groupInfo = {}
|
| | | actCfgCount = getattr(ipyDataMgr, "Get%sCount" % actName)()
|
| | | for cfgIndex in xrange(actCfgCount):
|
| | | ipyData = getattr(ipyDataMgr, "Get%sByIndex" % actName)(cfgIndex)
|
| | | actGroupName = ipyData.GetActGroupName()
|
| | | if actGroupName not in groupInfo:
|
| | | groupInfo[actGroupName] = []
|
| | | groupIpyDataList = groupInfo[actGroupName]
|
| | | groupIpyDataList.append(ipyData)
|
| | | |
| | | parseIpyDataList = []
|
| | | for actGroupName, groupIpyDataList in groupInfo.items():
|
| | | allOpen = False
|
| | | cfgIDList = []
|
| | | allServerIDRangeList = []
|
| | | for ipyData in groupIpyDataList:
|
| | | cfgID = ipyData.GetCfgID()
|
| | | cfgIDList.append(cfgID)
|
| | | serverIDRangeList = ipyData.GetServerIDRangeList()
|
| | | |
| | | if cfgID in actInfoDict and actInfoDict[cfgID]:
|
| | | actInfo = actInfoDict[cfgID]
|
| | | # 已经在活动中的记录必须要处理
|
| | | parseIpyDataList.append(ipyData)
|
| | | serverIDRangeList = actInfo[ShareDefine.ActKey_ServerIDRangeList]
|
| | | GameWorld.Log(" 使用已经在活动中的记录的区服分组: cfgID=%s,serverIDRangeList=%s" |
| | | % (cfgID, serverIDRangeList))
|
| | | |
| | | # 没配置的全服开放
|
| | | if not serverIDRangeList:
|
| | | allOpen = True
|
| | | else:
|
| | | allServerIDRangeList.extend(serverIDRangeList)
|
| | | |
| | | if allOpen and len(groupIpyDataList) > 1:
|
| | | GameWorld.ErrLog(" 同组活动服务器ID配置异常,有全服开放的,只能配置1条,不处理! actGroupName=%s,cfgIDList=%s" % (actGroupName, cfgIDList))
|
| | | continue
|
| | | |
| | | errorServerIDList = []
|
| | | for i in xrange(len(allServerIDRangeList)):
|
| | | checkIDA, checkIDB = allServerIDRangeList[i]
|
| | | for j in xrange(i):
|
| | | serverIDA, serverIDB = allServerIDRangeList[j]
|
| | | if serverIDA <= checkIDA <= serverIDB:
|
| | | errorServerIDList.append(checkIDA)
|
| | | |
| | | if serverIDA <= checkIDB <= serverIDB:
|
| | | errorServerIDList.append(checkIDB)
|
| | | |
| | | if errorServerIDList:
|
| | | GameWorld.ErrLog(" 同组活动服务器ID配置异常,有交叉,不处理! actGroupName=%s,cfgIDList=%s,errorServerIDList=%s" |
| | | % (actGroupName, cfgIDList, errorServerIDList))
|
| | | continue
|
| | | |
| | | for ipyData in groupIpyDataList:
|
| | | cfgID = ipyData.GetCfgID()
|
| | | if cfgID in actInfoDict and actInfoDict[cfgID]:
|
| | | continue
|
| | | parseIpyDataList.append(ipyData)
|
| | | |
| | | return parseIpyDataList
|
| | |
|
| | | def __GetCrossActInfo(isRefreshState=True):
|
| | | # @return: isReload, CrossActInfo
|
| | | |
| | | key = "CrossActInfo"
|
| | | CrossActInfo = IpyGameDataPY.GetConfigEx(key)
|
| | | serverTime = GameWorld.GetServerTime()
|
| | | curDateStr = "%d-%d-%d" % (serverTime.year, serverTime.month, serverTime.day)
|
| | | curHour = serverTime.hour
|
| | | reloadSignHour = 0 if curHour < 5 else 5
|
| | | reloadSign = "%s %s" % (curDateStr, reloadSignHour)
|
| | | if CrossActInfo and CrossActInfo[CrossAct_ReloadSign] == reloadSign:
|
| | | #GameWorld.DebugLog("已经加载过本日跨服运营活动处理信息!reloadSign=%s" % reloadSign)
|
| | | return False, CrossActInfo
|
| | | |
| | | # 因为后面的时间判断都是精确到分的,而处理此逻辑的时候可能不是0秒,所以这里的datetime取当前时间精确到分的
|
| | | curDateTimeStr = "%s %02d:%02d:00" % (curDateStr, serverTime.hour, serverTime.minute)
|
| | | curDateTime = datetime.datetime.strptime(curDateTimeStr, ChConfig.TYPE_Time_Format)
|
| | | |
| | | actTimeInfoDict = {}
|
| | | ipyDataMgr = IpyGameDataPY.IPY_Data()
|
| | | |
| | | GameWorld.Log("=============================================================")
|
| | | GameWorld.Log("加载本日跨服运营活动信息: %s, reloadSign=%s =====" % (curDateTime, reloadSign))
|
| | | crossActInfoDict = GetCrossActInfoDict()
|
| | | GameWorld.Log(" crossActInfoDict=%s" % crossActInfoDict)
|
| | | |
| | | for actName in ShareDefine.CrossActNameList:
|
| | | |
| | | # 取出本活动所属本服ID的所有配置
|
| | | GameWorld.Log("加载跨服运营活动: actName=%s" % (actName))
|
| | | |
| | | if not hasattr(ipyDataMgr, "Get%sCount" % actName):
|
| | | GameWorld.ErrLog(" 没有该跨服运营活动类型对应活动时间表! actName=%s" % actName)
|
| | | continue
|
| | | |
| | | curActInfoDict = crossActInfoDict.get(actName, {})
|
| | | |
| | | # 验证服务器ID不重复的配置
|
| | | parseIpyDataList = __GetParseIpyDataList(ipyDataMgr, actName, curActInfoDict)
|
| | | for ipyData in parseIpyDataList:
|
| | | cfgID = ipyData.GetCfgID()
|
| | | startDateStr = ipyData.GetStartDate()
|
| | | endDateStr = ipyData.GetEndDate()
|
| | | GameWorld.Log(" cfgID=%s,startDateStr=%s,endDateStr=%s,curDateTime=%s" % (cfgID, startDateStr, endDateStr, curDateTime))
|
| | | if not startDateStr:
|
| | | startDateStr = curDateStr
|
| | | GameWorld.Log(" 开始日期为空,默认每天,今日为: startDateStr=%s" % startDateStr)
|
| | | if not endDateStr:
|
| | | endDateStr = curDateStr
|
| | | GameWorld.Log(" 结束日期为空,默认每天,今日为: endDateStr=%s" % endDateStr)
|
| | | |
| | | if hasattr(ipyData, "GetStartTimeList") and hasattr(ipyData, "GetEndTimeList"):
|
| | | startHMStrList = ipyData.GetStartTimeList()
|
| | | endHMStrList = ipyData.GetEndTimeList()
|
| | | else:
|
| | | startHMStrList = []
|
| | | endHMStrList = []
|
| | | |
| | | notifyInfoDictStart = ipyData.GetNotifyInfoStart() if hasattr(ipyData, "GetNotifyInfoStart") else {}
|
| | | notifyInfoDictEnd = ipyData.GetNotifyInfoEnd() if hasattr(ipyData, "GetNotifyInfoEnd") else {}
|
| | | notifyInfoLoopInfo = ipyData.GetNotifyInfoLoop() if hasattr(ipyData, "GetNotifyInfoLoop") else [] # [循环分钟, 广播key, [广播参数列表可选]]
|
| | | |
| | | if len(startHMStrList) != len(endHMStrList):
|
| | | GameWorld.ErrLog(" 活动配置开始及结束时间个数不匹配! actName=%s,cfgID=%s,startHMStrList=%s,endHMStrList=%s" |
| | | % (actName, cfgID, startHMStrList, endHMStrList))
|
| | | |
| | | resetType = 0 if not hasattr(ipyData, "GetResetType") else ipyData.GetResetType() # 重置类型,0-0点重置;1-5点重置
|
| | | if resetType == 1:
|
| | | startDayDate = datetime.datetime.strptime("%s 05:00:00" % (startDateStr), ChConfig.TYPE_Time_Format)
|
| | | endDayDate = datetime.datetime.strptime("%s 05:00:00" % (endDateStr), ChConfig.TYPE_Time_Format) # 结束日期5点
|
| | | elif resetType == 2:
|
| | | startDayDate = datetime.datetime.strptime("%s 05:00:00" % (startDateStr), ChConfig.TYPE_Time_Format)
|
| | | endDayDate = datetime.datetime.strptime("%s 00:00:00" % (endDateStr), ChConfig.TYPE_Time_Format) + datetime.timedelta(days=1) # 结束日期隔天0点
|
| | | else:
|
| | | startDayDate = datetime.datetime.strptime("%s 00:00:00" % (startDateStr), ChConfig.TYPE_Time_Format)
|
| | | endDayDate = datetime.datetime.strptime("%s 00:00:00" % (endDateStr), ChConfig.TYPE_Time_Format) + datetime.timedelta(days=1) # 结束日期隔天0点
|
| | | |
| | | GameWorld.Log(" resetType=%s,startDayDate=%s,endDayDate=%s,startHMStrList=%s,endHMStrList=%s" |
| | | % (resetType, startDayDate, endDayDate, startHMStrList, endHMStrList))
|
| | | |
| | | if curDateTime < startDayDate or curDateTime >= endDayDate:
|
| | | isActTime = False
|
| | | if cfgID not in curActInfoDict or not curActInfoDict[cfgID]:
|
| | | GameWorld.Log(" 非活动时间!不处理!")
|
| | | continue
|
| | | else:
|
| | | isActTime = True
|
| | | |
| | | GameWorld.Log(" 需要处理的跨服运营活动信息: cfgID=%s,isActTime=%s" % (cfgID, isActTime))
|
| | | |
| | | startList = [] # [startDateTime, ...]
|
| | | endList = [] # [endDateTime, ...]
|
| | | startNotifyDict = {} # {notifyDateTime:notifyInfo, ...}
|
| | | endNotifyDict = {} # {notifyDateTime:notifyInfo, ...}
|
| | | loopNotifyDict = {} # {notifyDateTime:notifyInfo, ...}
|
| | | notifyDict = {}
|
| | | |
| | | # 没配置时分的代表全天
|
| | | if not startHMStrList:
|
| | | startDateTime = startDayDate
|
| | | endDateTime = endDayDate
|
| | | |
| | | startList.append(startDateTime)
|
| | | endList.append(endDateTime)
|
| | | |
| | | # 每天按时段开启的,支持多时段
|
| | | else:
|
| | | for hmIndex, startHMStr in enumerate(startHMStrList):
|
| | | if hmIndex >= len(endHMStrList):
|
| | | break
|
| | | endHMStr = endHMStrList[hmIndex]
|
| | | # 每天开的, 实际开关时间只取今天的日期; 这里有个问题,全服广播的时间不是今天的, 暂不做支持,之后真有这种需求再说
|
| | | startTimeStr = "%d-%d-%d %s:00" % (curDateTime.year, curDateTime.month, curDateTime.day, startHMStr)
|
| | | endTimeStr = "%d-%d-%d %s:00" % (curDateTime.year, curDateTime.month, curDateTime.day, endHMStr)
|
| | | startDateTime = datetime.datetime.strptime(startTimeStr, ChConfig.TYPE_Time_Format)
|
| | | endDateTime = datetime.datetime.strptime(endTimeStr, ChConfig.TYPE_Time_Format)
|
| | | |
| | | startList.append(startDateTime)
|
| | | endList.append(endDateTime)
|
| | | |
| | | GameWorld.Log(" startList=%s" % (startList))
|
| | | GameWorld.Log(" end List=%s" % (endList))
|
| | | |
| | | for dtIndex, startDateTime in enumerate(startList):
|
| | | endDateTime = endList[dtIndex]
|
| | | # 广播 - 相对实际开始时间
|
| | | for notifyMinute, notifyInfo in notifyInfoDictStart.items():
|
| | | notifyDateTime = startDateTime + datetime.timedelta(minutes=notifyMinute)
|
| | | if notifyDateTime.year == curDateTime.year and notifyDateTime.month == curDateTime.month and notifyDateTime.day == curDateTime.day:
|
| | | startNotifyDict[notifyDateTime] = notifyInfo
|
| | | |
| | | # 广播 - 相对实际结束时间
|
| | | for notifyMinute, notifyInfo in notifyInfoDictEnd.items():
|
| | | notifyDateTime = endDateTime + datetime.timedelta(minutes=notifyMinute)
|
| | | if notifyDateTime.year == curDateTime.year and notifyDateTime.month == curDateTime.month and notifyDateTime.day == curDateTime.day:
|
| | | endNotifyDict[notifyDateTime] = notifyInfo
|
| | | |
| | | # 广播 - 循环广播
|
| | | if notifyInfoLoopInfo and len(notifyInfoLoopInfo) >= 2:
|
| | | loopMinutes, loopNotifyKey = notifyInfoLoopInfo[:2]
|
| | | loopNotifyParamList = notifyInfoLoopInfo[2] if len(notifyInfoLoopInfo) > 2 else []
|
| | | notifyInfo = [loopNotifyKey, loopNotifyParamList] # 循环广播的默认无参数
|
| | | loopCount, loopMaxCount = 0, 100
|
| | | while loopMinutes and loopNotifyKey and loopCount < loopMaxCount:
|
| | | loopCount += 1
|
| | | notifyDateTime = curDateTime + datetime.timedelta(minutes=loopMinutes * loopCount)
|
| | | if notifyDateTime >= endDateTime:
|
| | | break
|
| | | if notifyDateTime.year == curDateTime.year and notifyDateTime.month == curDateTime.month and notifyDateTime.day == curDateTime.day:
|
| | | loopNotifyDict[notifyDateTime] = notifyInfo
|
| | | |
| | | if startNotifyDict or endNotifyDict or loopNotifyDict:
|
| | | GameWorld.Log(" startNotifyDict: %s, %s" % (len(startNotifyDict.keys()), sorted(startNotifyDict.keys())))
|
| | | GameWorld.Log(" end NotifyDict: %s, %s" % (len(endNotifyDict.keys()), sorted(endNotifyDict.keys())))
|
| | | GameWorld.Log(" loop NotifyDict: %s, %s" % (len(loopNotifyDict.keys()), sorted(loopNotifyDict.keys())))
|
| | | notifyDict.update(startNotifyDict)
|
| | | notifyDict.update(endNotifyDict)
|
| | | notifyDict.update(loopNotifyDict)
|
| | | |
| | | if actName not in actTimeInfoDict:
|
| | | actTimeInfoDict[actName] = {}
|
| | | actTimeInfoDict[actName][cfgID] = [ipyData, startList, endList, notifyDict]
|
| | | |
| | | if actName not in crossActInfoDict:
|
| | | crossActInfoDict[actName] = {}
|
| | | curActInfoDict = crossActInfoDict[actName]
|
| | | if cfgID not in curActInfoDict:
|
| | | curActInfoDict[cfgID] = {}
|
| | | curCfgActInfoDict = curActInfoDict[cfgID]
|
| | | |
| | | # ipyData 活动时间表信息由跨服服务器同步子服,活动内容取子服自己的
|
| | | ipyDataDict = {}
|
| | | for k, v in ipyData.__dict__.items():
|
| | | if k in ["NotifyInfoStart", "NotifyInfoEnd", "NotifyInfoLoop", "ServerIDRangeList"]:
|
| | | continue
|
| | | ipyDataDict[k] = v
|
| | | ipyDataDict.update({"StartDate":startDateStr, "EndDate":endDateStr})
|
| | | GameWorld.Log(" ipyDataDict=%s" % ipyDataDict)
|
| | | |
| | | curCfgActInfoDict.update({ShareDefine.ActKey_CfgID:cfgID, ShareDefine.ActKey_IpyDataInfo:ipyDataDict})
|
| | | if ShareDefine.ActKey_ServerIDRangeList not in curCfgActInfoDict:
|
| | | # 没有的话则使用配置中的,防止配置修改导致服务器ID分区变动引起的活动数据异常,除非后台工具强制修改
|
| | | curCfgActInfoDict[ShareDefine.ActKey_ServerIDRangeList] = ipyData.GetServerIDRangeList()
|
| | | |
| | | actID, dayIndex, templateID = 0, 0, 0
|
| | | if isActTime:
|
| | | dayIndex = (curDateTime - startDayDate).days
|
| | | actIDDateTime = startDayDate
|
| | | isDayReset = 0 if not hasattr(ipyData, "GetIsDayReset") else ipyData.GetIsDayReset()
|
| | | # 按时段开的默认每天重置
|
| | | if isDayReset or (startHMStrList and endHMStrList):
|
| | | actIDDateTime += datetime.timedelta(days=dayIndex)
|
| | | actID = int(time.mktime(actIDDateTime.timetuple())) # 默认取开始时间点的time值作为活动ID
|
| | | GameWorld.Log(" isDayReset=%s,actIDDateTime=%s,actID=%s" % (isDayReset, actIDDateTime, actID))
|
| | | |
| | | # 模板ID
|
| | | if hasattr(ipyData, "TemplateIDList"):
|
| | | templateIDList = ipyData.GetTemplateIDList()
|
| | | templateID = templateIDList[-1] if dayIndex >= len(templateIDList) else templateIDList[dayIndex]
|
| | | |
| | | # 其他特殊模板ID获取处理,有需要的单独处理即可,根据活动规则自行扩展... |
| | | |
| | | |
| | | curCfgActInfoDict.update({ShareDefine.ActKey_ID:actID, ShareDefine.ActKey_TemplateID:templateID, |
| | | ShareDefine.ActKey_DayIndex:dayIndex})
|
| | | |
| | | CrossActInfo = IpyGameDataPY.SetConfigEx(key, [reloadSign, actTimeInfoDict])
|
| | | |
| | | GameWorld.Log("本日跨服运营活动信息加载完毕!reloadSign=%s,isRefreshState=%s" % (reloadSign, isRefreshState))
|
| | | GameWorld.Log(" actTimeInfoDict=%s" % actTimeInfoDict)
|
| | | GameWorld.Log(" crossActInfoDict=%s" % crossActInfoDict)
|
| | | GameWorld.Log("=============================================================")
|
| | | if isRefreshState:
|
| | | Dispose_CrossActState(True)
|
| | | |
| | | return True, CrossActInfo
|
| | |
|
| | | def Dispose_CrossActState(reloadRefresh=False):
|
| | | |
| | | isReload, CrossActInfo = __GetCrossActInfo(False) # 这里必须传False
|
| | | isReload = isReload or reloadRefresh
|
| | | actTimeInfoDict = CrossActInfo[CrossAct_TodayInfo]
|
| | | |
| | | crossActInfoDict = GetCrossActInfoDict()
|
| | | |
| | | # 这里时间需精确到分钟,不然后面的比较会匹配不到
|
| | | 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)
|
| | | |
| | | sysnCrossActInfoDict = {}
|
| | | for actName in ShareDefine.CrossActNameList:
|
| | | if actName not in actTimeInfoDict or actName not in crossActInfoDict:
|
| | | continue
|
| | | |
| | | for ipyData, startList, endList, notifyDict in actTimeInfoDict[actName].values():
|
| | | |
| | | state = 0 # 默认关闭
|
| | | cfgID = ipyData.GetCfgID()
|
| | | |
| | | if cfgID not in crossActInfoDict[actName]:
|
| | | crossActInfoDict[actName][cfgID] = {}
|
| | | actInfoDict = crossActInfoDict[actName][cfgID]
|
| | | |
| | | # ״̬
|
| | | for dIndex, startDateTime in enumerate(startList):
|
| | | endDateTime = endList[dIndex]
|
| | | if startDateTime <= curDateTime < endDateTime:
|
| | | state = dIndex + 1 # 也是代表第几个时间段
|
| | | break
|
| | | |
| | | # 全服广播提示信息
|
| | | if curDateTime in notifyDict:
|
| | | serverIDRangeList = actInfoDict.get(ShareDefine.ActKey_ServerIDRangeList)
|
| | | if serverIDRangeList != None:
|
| | | notifyKey, paramList = notifyDict[curDateTime]
|
| | | country = 0
|
| | | serverGroupIDList = []
|
| | | crossNotifyList = []
|
| | | crossNotifyList.append([ShareDefine.CrossNotify_CrossAct, [country, notifyKey, paramList], serverIDRangeList])
|
| | | PlayerControl.CrossNotifyEx(serverGroupIDList, crossNotifyList)
|
| | | |
| | | dbInfo = actInfoDict.get(ShareDefine.ActKey_DBInfo, {})
|
| | | dbState = dbInfo.get(ShareDefine.ActKey_State, 0)
|
| | | dbActID = dbInfo.get(ShareDefine.ActKey_ID, 0)
|
| | | dbTemplateID = dbInfo.get(ShareDefine.ActKey_TemplateID, 0)
|
| | | |
| | | actID = actInfoDict.get(ShareDefine.ActKey_ID, 0)
|
| | | templateID = actInfoDict.get(ShareDefine.ActKey_TemplateID, 0)
|
| | | if not isReload and dbState == state and dbActID == actID:
|
| | | #已经是这个状态了
|
| | | continue
|
| | | GameWorld.Log("跨服运营活动变更: actName=%s,cfgID=%s,dbState=%s -> state=%s, dbActID=%s -> actID=%s" |
| | | % (actName, cfgID, dbState, state, dbActID, actID))
|
| | | |
| | | if dbActID != actID:
|
| | | GameWorld.Log(" 活动ID变更: actName=%s,cfgID=%s,dbActID=%s -> actID=%s,dbTemplateID=%s" |
| | | % (actName, cfgID, dbActID, actID, dbTemplateID))
|
| | | |
| | | if actName == ShareDefine.CrossActName_CTGBillboard:
|
| | | CrossActCTGBillboard.OnActIDChange(cfgID, dbTemplateID, state)
|
| | | |
| | | if dbState != state:
|
| | | pass
|
| | | |
| | | # 更新状态
|
| | | actInfoDict[ShareDefine.ActKey_State] = state
|
| | | actInfoDict[ShareDefine.ActKey_DBInfo] = {ShareDefine.ActKey_ID:actID, ShareDefine.ActKey_State:state, ShareDefine.ActKey_TemplateID:templateID}
|
| | | GameWorld.Log(" 活动状态同步信息: actName=%s,cfgID=%s,actInfoDict=%s" % (actName, cfgID, actInfoDict))
|
| | | if actName not in sysnCrossActInfoDict:
|
| | | sysnCrossActInfoDict[actName] = {}
|
| | | sysnCrossActInfoDict[actName][cfgID] = actInfoDict
|
| | | |
| | | # 非活动中的处理完关闭后,最后删除
|
| | | if not state:
|
| | | del crossActInfoDict[actName][cfgID]
|
| | | if not crossActInfoDict[actName]:
|
| | | del crossActInfoDict[actName]
|
| | | GameWorld.DebugLog(" 删除结束的活动: actName=%s,cfgID=%s,crossActInfoDict=%s" % (actName, cfgID, crossActInfoDict))
|
| | | |
| | | # 同步子服务器
|
| | | serverGroupIDList = []
|
| | | CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossActInfo, sysnCrossActInfoDict, serverGroupIDList)
|
| | | return
|
| | |
|
| | | def Sync_CrossActInfoToClientServer(serverGroupID=0):
|
| | | ''' 同步跨服运营活动信息到子服务器
|
| | | @param serverGroupID: 为0时同步所有子服
|
| | | '''
|
| | | |
| | | isReload, _ = __GetCrossActInfo()
|
| | | if isReload:
|
| | | # 如果是重读的,则在内层已经同步了,此处不重复同步
|
| | | return
|
| | | |
| | | # 同步子服务器
|
| | | sysnCrossActInfoDict = GetCrossActInfoDict()
|
| | | serverGroupIDList = [serverGroupID] if serverGroupID else []
|
| | | CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossActInfo, sysnCrossActInfoDict, serverGroupIDList)
|
| | | return
|
| | |
|
| | | ## ================================================================================================
|
| | |
|
| | | def CrossServerMsg_CrossActInfo(sysnCrossActInfoDict):
|
| | | ## 收到跨服服务器同步的跨服运营活动状态
|
| | | |
| | | GameWorld.Log("===== 收到跨服服务器同步的跨服运营活动状态: %s" % sysnCrossActInfoDict)
|
| | | if PyGameData.g_crossActInfoDict == None:
|
| | | PyGameData.g_crossActInfoDict = {}
|
| | | PyGameData.g_crossActInfoDict.update(sysnCrossActInfoDict)
|
| | | |
| | | for actName, actInfoDict in sysnCrossActInfoDict.items():
|
| | | GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_CrossActInfo % actName, actInfoDict)
|
| | | |
| | | # 删除非活动中的
|
| | | for actName, actInfoDict in PyGameData.g_crossActInfoDict.items():
|
| | | for cfgID, actInfo in actInfoDict.items():
|
| | | if not actInfo.get(ShareDefine.ActKey_State, 0):
|
| | | del PyGameData.g_crossActInfoDict[actName][cfgID]
|
| | | |
| | | return
|
| | |
|
| | | def SendMapServerCrossActionState():
|
| | | # 地图启动成功时通知跨服活动相关状态 - 本服地图,跨服地图不需要通知
|
| | | |
| | | if PyGameData.g_crossActInfoDict == None:
|
| | | return
|
| | | |
| | | sysnCrossActInfoDict = PyGameData.g_crossActInfoDict
|
| | | for actName in ShareDefine.CrossActNameList:
|
| | | actInfoDict = sysnCrossActInfoDict.get(actName, {})
|
| | | GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_CrossActInfo % actName, actInfoDict)
|
| | | |
| | | return
|
| | |
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package CrossBillboard
|
| | | #
|
| | | # @todo:跨服排行榜
|
| | | # @author hxp
|
| | | # @date 2020-01-13
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 跨服排行榜
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2020-01-13 17:00"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import CommFunc
|
| | | import ShareDefine
|
| | | import CrossRealmMsg
|
| | | import PyGameDataStruct
|
| | | import ChPyNetSendPack
|
| | | import DataRecordPack
|
| | | import NetPackCommon
|
| | | import PyDataManager
|
| | | import GameWorld
|
| | |
|
| | | import operator
|
| | | import time
|
| | |
|
| | | Def_CrossBillboard_MaxDataCount = 100 # 跨服榜单数据最大条数暂固定最大为100条,如有需要调整需针对实际情况进行评估(如数据同步、同步封包等)
|
| | | |
| | | class CrossBillboardManager(object):
|
| | | ## 跨服排行榜管理,注意该类只处理数据逻辑,功能相关逻辑不要写在该类,不然重读脚本不会生效
|
| | | |
| | | def __init__(self):
|
| | | self.__billboardDict = {} # 排行榜字典 {(billboardType, groupValue1, groupValue2):CrossBillboard, ...}
|
| | | return
|
| | | |
| | | def GetBillboardGroupList(self, bType):
|
| | | ## 根据榜单类型获取该类型所有分组榜单信息
|
| | | ## @return: [(billboardType, groupValue1, groupValue2), ...]
|
| | | groupList = []
|
| | | for billboardType, groupValue1, groupValue2 in self.__billboardDict.keys():
|
| | | if bType == billboardType:
|
| | | groupList.append((billboardType, groupValue1, groupValue2))
|
| | | return groupList
|
| | | |
| | | def GetCrossBillboard(self, billboardType, groupValue1, groupValue2=0):
|
| | | ''' 获取跨服排行榜
|
| | | @param billboardType: 排行榜类型
|
| | | @param groupValue1: 分组值1
|
| | | @param groupValue2: 分组值2,与分组值1组合归为同组榜单数据
|
| | | @return: CrossBillboard
|
| | | '''
|
| | | key = (billboardType, groupValue1, groupValue2)
|
| | | if key in self.__billboardDict:
|
| | | billboardObj = self.__billboardDict[key]
|
| | | else:
|
| | | billboardObj = CrossBillboard(billboardType, groupValue1, groupValue2)
|
| | | self.__billboardDict[key] = billboardObj
|
| | | return billboardObj
|
| | | |
| | | # 保存数据 存数据库和realtimebackup
|
| | | def GetSaveData(self):
|
| | | savaData = ""
|
| | | cntData = ""
|
| | | cnt = 0
|
| | | for billboardType, groupValue1, groupValue2 in self.__billboardDict.keys():
|
| | | billboardObj = self.GetCrossBillboard(billboardType, groupValue1, groupValue2)
|
| | | for i in xrange(billboardObj.GetCount()):
|
| | | billboardData = billboardObj.At(i)
|
| | | cnt += 1
|
| | | savaData += billboardData.getBuffer()
|
| | | |
| | | GameWorld.Log("Save DBCrossBillboard cnt :%s" % cnt)
|
| | | return CommFunc.WriteDWORD(cntData, cnt) + savaData
|
| | | |
| | | # 从数据库载入数据
|
| | | def LoadPyGameData(self, datas, pos, dataslen):
|
| | | cnt, pos = CommFunc.ReadDWORD(datas, pos)
|
| | | GameWorld.Log("Load DBCrossBillboard cnt :%s" % cnt)
|
| | | |
| | | for _ in xrange(cnt):
|
| | | billboardData = PyGameDataStruct.tagDBCrossBillboard()
|
| | | billboardData.clear()
|
| | | pos += billboardData.readData(datas, pos, dataslen)
|
| | | |
| | | billboardType, groupValue1, groupValue2 = billboardData.BillboardType, billboardData.GroupValue1, billboardData.GroupValue2
|
| | | billboardObj = self.GetCrossBillboard(billboardType, groupValue1, groupValue2)
|
| | | billboardObj.AddBillboardData(billboardData)
|
| | | |
| | | # 排序
|
| | | for billboardType, groupValue1, groupValue2 in self.__billboardDict.keys():
|
| | | billboardObj = self.GetCrossBillboard(billboardType, groupValue1, groupValue2)
|
| | | billboardObj.SortData()
|
| | | |
| | | return pos
|
| | | |
| | | class CrossBillboard(object):
|
| | | ''' 对应具体类型排行榜逻辑类
|
| | | '''
|
| | | |
| | | def __init__(self, billboardType, groupValue1=0, groupValue2=0):
|
| | | self.__billboardType = billboardType
|
| | | self.__groupValue1 = groupValue1
|
| | | self.__groupValue2 = groupValue2
|
| | | self.__crossServerDataVer = 0 # 主服榜单数据版本
|
| | | self.__clientServerDataVer = 0 # 子服榜单数据版本
|
| | | self.__billboardList = [] # [tagDBCrossBillboard, ...] |
| | | self.__idOrderDict = {} # {id:名次, ...}
|
| | | return
|
| | | |
| | | def GetBillboardType(self): return self.__billboardType
|
| | | def GetGroupValue1(self): return self.__groupValue1
|
| | | def GetGroupValue2(self): return self.__groupValue2
|
| | | |
| | | def ClearData(self):
|
| | | GameWorld.Log("CrossBillboard ClearData billboardType=%s,groupValue1=%s,groupValue2=%s" |
| | | % (self.__billboardType, self.__groupValue1, self.__groupValue2))
|
| | | self.__billboardList = [] # [tagDBCrossBillboard, ...] |
| | | self.__idOrderDict = {} # {id:名次, ...}
|
| | | |
| | | self.UpdCrossServerDataVer(0)
|
| | | return
|
| | | |
| | | def SortData(self):
|
| | | self.__billboardList.sort(key=operator.attrgetter("CmpValue", "CmpValue2", "CmpValue3"), reverse=True)
|
| | | self.__idOrderDict = {} # 排序后重置,下次查询时更新并缓存
|
| | | self.UpdCrossServerDataVer()
|
| | | return
|
| | | |
| | | def AddBillboardData(self, billboardData):
|
| | | ## 添加榜单数据到该榜
|
| | | # @param billboardData: PyGameDataStruct.tagDBCrossBillboard()
|
| | | # @return: 是否成功
|
| | | if self.IsFull():
|
| | | return False
|
| | | self.__billboardList.append(billboardData)
|
| | | return True
|
| | | |
| | | def FindByID(self, findID):
|
| | | ''' 根据ID查询榜单数据
|
| | | @param findID: 查找的ID
|
| | | @return: None or PyGameDataStruct.tagDBCrossBillboard()
|
| | | '''
|
| | | idOrderDict = self.GetIDOrderDict()
|
| | | if findID not in idOrderDict:
|
| | | return None
|
| | | order = idOrderDict[findID]
|
| | | return self.__billboardList[order - 1]
|
| | | |
| | | def SaveDRData(self):
|
| | | ## 记录流向数据
|
| | | eventTypeName = "CrossBillboard_%s" % (self.__billboardType)
|
| | | drDict = {"BillboardType":self.__billboardType, "GroupValue1":self.__groupValue1, "GroupValue2":self.__groupValue2, |
| | | "DataCount":len(self.__billboardList)}
|
| | | DataRecordPack.SendEventPack(eventTypeName, drDict)
|
| | | for billboardData in self.__billboardList:
|
| | | dataDict = {"BillboardType":billboardData.BillboardType, "GroupValue1":billboardData.GroupValue1, |
| | | "GroupValue2":billboardData.GroupValue2, "Type2":billboardData.Type2,
|
| | | "ID":billboardData.ID, "ID2":billboardData.ID2,
|
| | | "Name1":billboardData.Name1, "Name2":billboardData.Name2,
|
| | | "Value1":billboardData.Value1, "Value2":billboardData.Value2,
|
| | | "CmpValue":billboardData.CmpValue, "CmpValue2":billboardData.CmpValue2, |
| | | "CmpValue3":billboardData.CmpValue3}
|
| | | DataRecordPack.SendEventPack(eventTypeName, dataDict)
|
| | | return
|
| | | |
| | | def GetBillboardDataList(self): return self.__billboardList
|
| | | def GetIDOrderDict(self):
|
| | | ## 获取ID对应名次字典
|
| | | # @return: {ID:名次, ...} 名次从1开始
|
| | | if not self.__idOrderDict:
|
| | | for order, billboardData in enumerate(self.__billboardList, 1):
|
| | | self.__idOrderDict[billboardData.ID] = order
|
| | | return self.__idOrderDict
|
| | | |
| | | def GetCount(self): return len(self.__billboardList)
|
| | | def GetMaxCount(self): return Def_CrossBillboard_MaxDataCount
|
| | | |
| | | def At(self, i): return self.__billboardList[i]
|
| | | def IsFull(self): return len(self.__billboardList) >= Def_CrossBillboard_MaxDataCount
|
| | | |
| | | def UpdCrossServerDataVer(self, version=None):
|
| | | ## 更新跨服榜单数据版本号,用于跨服主服、子服验证数据版本,同步榜单数据用
|
| | | if not GameWorld.IsCrossServer():
|
| | | return
|
| | | if version == None:
|
| | | version = int(time.time())
|
| | | self.__crossServerDataVer = version
|
| | | SyncCrossBillboardToClientServer(self.__billboardType, self.__groupValue1, self.__groupValue2)
|
| | | return
|
| | | def GetCrossServerDataVer(self): return self.__crossServerDataVer
|
| | | |
| | | def CheckClientServerDataVer(self):
|
| | | ## 检查子服榜单数据版本是否需要同步
|
| | | # @return: 是否需要向跨服主服同步最新数据
|
| | | return self.__clientServerDataVer == 0 or self.__clientServerDataVer != self.__crossServerDataVer
|
| | | |
| | | def UpdClientServerBillboard(self, crossServerDataVer, syncBillboardList=None):
|
| | | ## 更新本服的跨服榜单数据
|
| | | |
| | | # 更新跨服数据版本
|
| | | self.__crossServerDataVer = crossServerDataVer
|
| | | # 特殊版本0代表清除数据
|
| | | if crossServerDataVer == 0:
|
| | | self.ClearData()
|
| | | |
| | | # 更新数据
|
| | | if syncBillboardList != None:
|
| | | self.__billboardList = self.__billboardList[:len(syncBillboardList)] # 直接用本服以后的排行数据实例clear后覆盖更新,不足的创建新实例
|
| | | self.__idOrderDict = {}
|
| | | for i, syncData in enumerate(syncBillboardList):
|
| | | ID, ID2, Name1, Name2, Type2, Value1, Value2, CmpValue, CmpValue2, CmpValue3 = syncData
|
| | | if i < len(self.__billboardList):
|
| | | billboardData = self.__billboardList[i]
|
| | | billboardData.clear()
|
| | | else:
|
| | | billboardData = PyGameDataStruct.tagDBCrossBillboard()
|
| | | self.__billboardList.append(billboardData)
|
| | | |
| | | billboardData.GroupValue1 = self.__groupValue1
|
| | | billboardData.GroupValue2 = self.__groupValue2
|
| | | billboardData.BillboardType = self.__billboardType
|
| | | billboardData.ID = ID
|
| | | billboardData.ID2 = ID2
|
| | | billboardData.Name1 = Name1
|
| | | billboardData.Name2 = Name2
|
| | | billboardData.Type2 = Type2
|
| | | billboardData.Value1 = Value1
|
| | | billboardData.Value2 = Value2
|
| | | billboardData.CmpValue = CmpValue
|
| | | billboardData.CmpValue2 = CmpValue2
|
| | | billboardData.CmpValue3 = CmpValue3
|
| | | |
| | | self.__idOrderDict[ID] = i + 1
|
| | | |
| | | self.__clientServerDataVer = crossServerDataVer
|
| | | |
| | | return
|
| | |
|
| | | #// C0 04 查看跨服排行榜 #tagCGViewCrossBillboard
|
| | | #
|
| | | #struct tagCGViewCrossBillboard
|
| | | #{
|
| | | # tagHead Head;
|
| | | # BYTE Type; //榜单类型
|
| | | # BYTE GroupValue1; // 分组值1
|
| | | # BYTE GroupValue2; // 分组值2,与分组值1组合归为同组榜单数据
|
| | | #};
|
| | | def OnViewCrossBillboard(index, clientData, tick):
|
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
| | | if GameWorld.IsCrossServer():
|
| | | return
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | billboardType, groupValue1, groupValue2 = clientData.Type, clientData.GroupValue1, clientData.GroupValue2
|
| | | |
| | | if billboardType not in ShareDefine.CrossBillboardTypeList:
|
| | | return
|
| | | |
| | | billboardMgr = PyDataManager.GetCrossBillboardManager()
|
| | | billboardObj = billboardMgr.GetCrossBillboard(billboardType, groupValue1, groupValue2)
|
| | | |
| | | GameWorld.DebugLog("玩家请求查看跨服排行榜: billboardType=%s,groupValue1=%s,groupValue2=%s" % (billboardType, groupValue1, groupValue2))
|
| | | if not billboardObj.CheckClientServerDataVer():
|
| | | SyncCrossBillboardToPlayer(curPlayer, billboardType, groupValue1, groupValue2, billboardObj.GetBillboardDataList())
|
| | | return
|
| | | |
| | | # 请求查询跨服服务器
|
| | | dataMsg = {"BillboardType":billboardType, "GroupValue1":groupValue1, "GroupValue2":groupValue2,
|
| | | "QueryData":{"EventName":"View", "PlayerID":playerID}}
|
| | | CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_QueryBillboard, dataMsg)
|
| | | return
|
| | |
|
| | | def ClientServerMsg_QueryBillboard(serverGroupID, msgData):
|
| | | ## 收到子服请求查询排行榜信息
|
| | | billboardType = msgData["BillboardType"]
|
| | | groupValue1 = msgData["GroupValue1"]
|
| | | groupValue2 = msgData["GroupValue2"]
|
| | | queryData = msgData.get("QueryData", {}) # 原数据返回子服
|
| | | SyncCrossBillboardToClientServer(billboardType, groupValue1, groupValue2, [serverGroupID], queryData)
|
| | | return
|
| | |
|
| | | def SyncCrossBillboardToClientServer(billboardType, groupValue1, groupValue2, serverGroupIDList=[], queryData={}):
|
| | | ## 同步跨服榜单到子服
|
| | | if not GameWorld.IsCrossServer():
|
| | | return
|
| | | billboardMgr = PyDataManager.GetCrossBillboardManager()
|
| | | billboardObj = billboardMgr.GetCrossBillboard(billboardType, groupValue1, groupValue2)
|
| | | crossServerDataVer = billboardObj.GetCrossServerDataVer()
|
| | | msgData = {"BillboardType":billboardType, "GroupValue1":groupValue1, "GroupValue2":groupValue2,
|
| | | "QueryData":queryData, "CrossServerDataVer":crossServerDataVer}
|
| | | |
| | | # 有查询数据时才同步榜单数据列表,否则只同步数据版本号
|
| | | if queryData:
|
| | | syncBillboardList = []
|
| | | billboardList = billboardObj.GetBillboardDataList()
|
| | | for billboardData in billboardList:
|
| | | ID = billboardData.ID
|
| | | ID2 = billboardData.ID2
|
| | | Name1 = billboardData.Name1
|
| | | Name2 = billboardData.Name2
|
| | | Type2 = billboardData.Type2
|
| | | Value1 = billboardData.Value1
|
| | | Value2 = billboardData.Value2
|
| | | CmpValue = billboardData.CmpValue
|
| | | CmpValue2 = billboardData.CmpValue2
|
| | | CmpValue3 = billboardData.CmpValue3
|
| | | syncBillboardList.append([ID, ID2, Name1, Name2, Type2, Value1, Value2, CmpValue, CmpValue2, CmpValue3])
|
| | | msgData["BillboardDataList"] = syncBillboardList
|
| | | |
| | | CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_SyncBillboard, msgData, serverGroupIDList)
|
| | | return
|
| | |
|
| | | def CrossServerMsg_SyncBillboard(msgData, tick):
|
| | | ## 收到跨服服务器同步的排行榜信息
|
| | | billboardType = msgData["BillboardType"]
|
| | | groupValue1 = msgData["GroupValue1"]
|
| | | groupValue2 = msgData["GroupValue2"]
|
| | | crossServerDataVer = msgData["CrossServerDataVer"]
|
| | | syncBillboardList = msgData.get("BillboardDataList")
|
| | | GameWorld.DebugLog("收到跨服服务器同步的排行榜信息: billboardType=%s,groupValue1=%s,groupValue2=%s,crossServerDataVer=%s" |
| | | % (billboardType, groupValue1, groupValue2, crossServerDataVer))
|
| | | |
| | | billboardMgr = PyDataManager.GetCrossBillboardManager()
|
| | | billboardObj = billboardMgr.GetCrossBillboard(billboardType, groupValue1, groupValue2)
|
| | | billboardObj.UpdClientServerBillboard(crossServerDataVer, syncBillboardList)
|
| | | |
| | | queryData = msgData.get("QueryData")
|
| | | if not queryData:
|
| | | return
|
| | | |
| | | eventName = queryData.get("EventName")
|
| | | eventData = queryData.get("EventData")
|
| | | queryPlayerID = queryData.get("PlayerID", 0)
|
| | | if not eventName or not queryPlayerID:
|
| | | return
|
| | | |
| | | queryPlayer = GameWorld.GetPlayerManager().FindPlayerByID(queryPlayerID)
|
| | | if not queryPlayer:
|
| | | return
|
| | | |
| | | if eventName == "View": |
| | | SyncCrossBillboardToPlayer(queryPlayer, billboardType, groupValue1, groupValue2, billboardObj.GetBillboardDataList())
|
| | | else:
|
| | | idOrderDict = billboardObj.GetIDOrderDict()
|
| | | order = idOrderDict.get(queryPlayerID, 0)
|
| | | sysMsg = str([billboardType, groupValue1, groupValue2, eventName, eventData, order])
|
| | | queryPlayer.MapServer_QueryPlayerResult(0, 0, "CrossBillboardOrder", sysMsg, len(sysMsg))
|
| | | |
| | | return
|
| | |
|
| | | def SyncCrossBillboardToPlayer(curPlayer, billboardType, groupValue1, groupValue2, billboardList):
|
| | | ## 同步给玩家跨服榜单
|
| | | billboardInfo = ChPyNetSendPack.tagGCCrossBillboardInfo()
|
| | | billboardInfo.Type = billboardType
|
| | | billboardInfo.GroupValue1 = groupValue1
|
| | | billboardInfo.GroupValue2 = groupValue2
|
| | | billboardInfo.CrossBillboardDataList = []
|
| | | for billboardData in billboardList:
|
| | | billboardInfoData = ChPyNetSendPack.tagGCCrossBillboardData()
|
| | | billboardInfoData.ID = billboardData.ID
|
| | | billboardInfoData.Name1 = billboardData.Name1
|
| | | billboardInfoData.Name2 = billboardData.Name2
|
| | | billboardInfoData.Type2 = billboardData.Type2
|
| | | billboardInfoData.Value1 = billboardData.Value1
|
| | | billboardInfoData.Value2 = billboardData.Value2
|
| | | billboardInfoData.CmpValue = billboardData.CmpValue
|
| | | billboardInfoData.CmpValue2 = billboardData.CmpValue2
|
| | | billboardInfoData.CmpValue3 = billboardData.CmpValue3
|
| | | billboardInfo.CrossBillboardDataList.append(billboardInfoData)
|
| | | billboardInfo.BillboardCount = len(billboardInfo.CrossBillboardDataList)
|
| | | NetPackCommon.SendFakePack(curPlayer, billboardInfo)
|
| | | return
|
| | |
|
| | | def MapServer_UpdateCrossBillboard(billInfoDict):
|
| | | '''地图更新跨服排行榜, 通用
|
| | | {"Type":bType, "GroupValue1":groupValue1, "Type2":type2, "ID":dataID, "ID2":id2, "Name1":name1, "Name2":name2,
|
| | | "Value1":value1, "Value2":value2, "CmpValue":cmpValue, "CmpValue2":cmpValue2, "CmpValue3":cmpValue3,
|
| | | "GroupValue2":groupValue2}
|
| | | '''
|
| | | |
| | | if GameWorld.IsCrossServer():
|
| | | # 只有子服务器能调用
|
| | | return
|
| | | GameWorld.DebugLog("子服地图更新跨服榜单数据! %s" % billInfoDict)
|
| | | |
| | | billboardType = billInfoDict["Type"]
|
| | | if billboardType not in ShareDefine.CrossBillboardTypeList:
|
| | | return
|
| | | groupValue1 = billInfoDict["GroupValue1"]
|
| | | groupValue2 = billInfoDict["GroupValue2"]
|
| | | dataID = billInfoDict["ID"]
|
| | | if not groupValue1 or not dataID:
|
| | | return
|
| | | |
| | | type2 = billInfoDict["Type2"]
|
| | | id2 = billInfoDict["ID2"]
|
| | | name1 = billInfoDict["Name1"]
|
| | | name2 = billInfoDict["Name2"]
|
| | | value1 = billInfoDict["Value1"]
|
| | | value2 = billInfoDict["Value2"]
|
| | | cmpValue = billInfoDict["CmpValue"]
|
| | | cmpValue2 = billInfoDict["CmpValue2"]
|
| | | cmpValue3 = billInfoDict["CmpValue3"]
|
| | | |
| | | billboardMgr = PyDataManager.GetCrossBillboardManager()
|
| | | billboardObj = billboardMgr.GetCrossBillboard(billboardType, groupValue1, groupValue2)
|
| | | billboardData = billboardObj.FindByID(dataID)
|
| | | if billboardData:
|
| | | if cmpValue == billboardData.CmpValue and cmpValue2 == billboardData.CmpValue2 \
|
| | | and (not cmpValue3 or cmpValue3 == billboardData.CmpValue3) \
|
| | | and value1 == billboardData.Value1 and value2 == billboardData.Value2 \
|
| | | and name1 == billboardData.Name1 and name2 == billboardData.Name2 \
|
| | | and type2 == billboardData.Type2 and id2 == billboardData.ID2:
|
| | | GameWorld.DebugLog(" 榜单值相同,不同步跨服服务器! ")
|
| | | return
|
| | | |
| | | elif billboardObj.IsFull():
|
| | | lastBillBoardData = __CmpLastBillboardData(cmpValue, cmpValue2, cmpValue3, billboardObj)
|
| | | if not lastBillBoardData:
|
| | | GameWorld.DebugLog(" 榜单值不超过最后一名,不同步跨服服务器! ")
|
| | | return
|
| | | |
| | | else:
|
| | | GameWorld.DebugLog(" 本服没有在榜上!")
|
| | | |
| | | # 同步跨服服务器
|
| | | CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_UpdateBillboard, billInfoDict)
|
| | | return
|
| | |
|
| | | def ClientServerMsg_UpdateBillboard(serverGroupID, billInfoDict):
|
| | | GameWorld.Log("收到子服更新跨服榜单数据! serverGroupID=%s, %s" % (serverGroupID, billInfoDict))
|
| | | |
| | | billboardType = billInfoDict["Type"]
|
| | | if billboardType not in ShareDefine.CrossBillboardTypeList:
|
| | | return
|
| | | groupValue1 = billInfoDict["GroupValue1"]
|
| | | groupValue2 = billInfoDict["GroupValue2"]
|
| | | |
| | | type2 = billInfoDict["Type2"]
|
| | | dataID = billInfoDict["ID"]
|
| | | id2 = billInfoDict["ID2"]
|
| | | name1 = billInfoDict["Name1"]
|
| | | name2 = billInfoDict["Name2"]
|
| | | value1 = billInfoDict["Value1"]
|
| | | value2 = billInfoDict["Value2"]
|
| | | cmpValue = billInfoDict["CmpValue"]
|
| | | cmpValue2 = billInfoDict["CmpValue2"]
|
| | | cmpValue3 = billInfoDict["CmpValue3"]
|
| | | |
| | | UpdCrossBillboard(billboardType, groupValue1, dataID, name1, name2, type2, value1, value2,
|
| | | cmpValue, cmpValue2, cmpValue3, groupValue2, id2)
|
| | | return
|
| | |
|
| | | def UpdCrossBillboard(billboardType, groupValue1, dataID, name1, name2, type2, value1, value2, cmpValue,
|
| | | cmpValue2=0, cmpValue3=0, groupValue2=0, id2=0, autoSort=True):
|
| | | ''' 更新跨服排行榜
|
| | | @param billboardType: 排行榜索引类型,同个榜单类型可以有多个分组榜单数据,独立排序
|
| | | @param groupValue1: 榜单分组1
|
| | | @param dataID: 榜单唯一数据ID,如玩家ID等
|
| | | @param name1: 显示名称1,不影响排序
|
| | | @param name2: 显示名称2,不影响排序
|
| | | @param type2: 榜单数据类型2,自定义,一般为职业等二级分类,不影响排序
|
| | | @param value1: 显示值1,不影响排序
|
| | | @param value2: 显示值2,不影响排序
|
| | | @param cmpValue: 比较值1
|
| | | @param cmpValue2: 比较值2
|
| | | @param cmpValue3: 比较值3,没设定的话默认为时间戳比较值
|
| | | @param groupValue1: 榜单分组2
|
| | | @param id2: 扩展数据ID2
|
| | | @param autoSort: 是否排序,默认True
|
| | | @return: 是否上榜更新榜单
|
| | | '''
|
| | | if not GameWorld.IsCrossServer():
|
| | | # 只有跨服服务器能调用
|
| | | return
|
| | | if not groupValue1 or not dataID:
|
| | | return
|
| | | billboardMgr = PyDataManager.GetCrossBillboardManager()
|
| | | billboardObj = billboardMgr.GetCrossBillboard(billboardType, groupValue1, groupValue2)
|
| | | billboardData = billboardObj.FindByID(dataID)
|
| | | isNewData = False
|
| | | if not billboardData:
|
| | | isNewData = True
|
| | | if billboardObj.IsFull():
|
| | | # 与最后一名对比
|
| | | lastBillBoardData = __CmpLastBillboardData(cmpValue, cmpValue2, cmpValue3, billboardObj)
|
| | | if not lastBillBoardData:
|
| | | GameWorld.DebugLog(" 榜单值不超过最后一名,不上榜! ")
|
| | | return
|
| | | billboardData = lastBillBoardData
|
| | | billboardData.clear()
|
| | | else:
|
| | | billboardData = PyGameDataStruct.tagDBCrossBillboard()
|
| | | if not billboardObj.AddBillboardData(billboardData):
|
| | | return
|
| | | |
| | | # 没设置值默认为时间time,先上榜的排前面
|
| | | if cmpValue3 == 0:
|
| | | # 时间权值仅在比较值变更的情况下才更新, 防止其他附属值更新时导致比较值相同的玩家名次间会变动的问题
|
| | | if isNewData or billboardData.CmpValue != cmpValue or billboardData.CmpValue2 != cmpValue2:
|
| | | calcTime = GameWorld.ChangeTimeStrToNum("2090-01-01 00:00:00")
|
| | | cmpValue3 = max(0, calcTime - int(time.time())) # 比较值3如果没指定值则默认存当前更新的time
|
| | | else:
|
| | | cmpValue3 = billboardData.CmpValue3
|
| | | |
| | | cmpValueChange = billboardData.CmpValue != cmpValue or billboardData.CmpValue2 != cmpValue2 or billboardData.CmpValue3 != cmpValue3
|
| | | |
| | | # 更新所有值
|
| | | billboardData.GroupValue1 = groupValue1
|
| | | billboardData.GroupValue2 = groupValue2
|
| | | billboardData.BillboardType = billboardType
|
| | | billboardData.ID = dataID
|
| | | billboardData.ID2 = id2
|
| | | billboardData.Name1 = name1
|
| | | billboardData.Name2 = name2
|
| | | billboardData.Type2 = type2
|
| | | billboardData.Value1 = value1
|
| | | billboardData.Value2 = value2
|
| | | billboardData.CmpValue = cmpValue
|
| | | billboardData.CmpValue2 = cmpValue2
|
| | | billboardData.CmpValue3 = cmpValue3
|
| | | |
| | | GameWorld.DebugLog("更新跨服排行榜值: billboardType=%s,groupValue1=%s,groupValue2=%s,dataID=%s,isNewData=%s,cmpValueChange=%s,type2=%s,value1=%s,value2=%s,cmpValue=%s,cmpValue2=%s,cmpValue3=%s" |
| | | % (billboardType, groupValue1, groupValue2, dataID, isNewData, cmpValueChange,
|
| | | type2, value1, value2, cmpValue, cmpValue2, cmpValue3), dataID)
|
| | | |
| | | if autoSort and cmpValueChange:
|
| | | billboardObj.SortData()
|
| | | else:
|
| | | billboardObj.UpdCrossServerDataVer()
|
| | | return True
|
| | |
|
| | | def __CmpLastBillboardData(cmpValue, cmpValue2, cmpValue3, billboardObj):
|
| | | ## 比较是否超过最后一名
|
| | | # @return: 超过则返回最后一名数据实例,否则返回None
|
| | | if not billboardObj.GetCount():
|
| | | return
|
| | | lastBillBoardData = billboardObj.At(billboardObj.GetCount() - 1)
|
| | | if cmpValue < lastBillBoardData.CmpValue:
|
| | | #无法上榜
|
| | | return
|
| | | elif cmpValue == lastBillBoardData.CmpValue: |
| | | if cmpValue2 < lastBillBoardData.CmpValue2:
|
| | | return
|
| | | elif cmpValue2 == lastBillBoardData.CmpValue2:
|
| | | if cmpValue3 <= lastBillBoardData.CmpValue3:
|
| | | return
|
| | | return lastBillBoardData
|
| | |
|
| | |
| | | import IPY_GameServer
|
| | | import CrossRealmPlayer
|
| | | import PlayerCompensation
|
| | | import CrossActionControl
|
| | | import CrossBillboard
|
| | | import GameWorldBoss
|
| | | import CrossRealmPK
|
| | | import PlayerQuery
|
| | |
| | |
|
| | | elif msgType == ShareDefine.ClientServerMsg_PKBillboard:
|
| | | CrossRealmPK.ClientServerMsg_PKBillboard(serverGroupID, msgData)
|
| | | |
| | | |
| | | elif msgType == ShareDefine.ClientServerMsg_QueryBillboard:
|
| | | CrossBillboard.ClientServerMsg_QueryBillboard(serverGroupID, msgData)
|
| | | |
| | | elif msgType == ShareDefine.ClientServerMsg_UpdateBillboard:
|
| | | CrossBillboard.ClientServerMsg_UpdateBillboard(serverGroupID, msgData)
|
| | | |
| | | elif msgType == ShareDefine.ClientServerMsg_MailContent:
|
| | | PlayerCompensation.ClientServerMsg_MailContent(serverGroupID, msgData, tick)
|
| | | |
| | | elif msgType == ShareDefine.ClientServerMsg_ChatCrossWorld:
|
| | | PlayerTalk.ClientServerMsg_ChatCrossWorld(serverGroupID, msgData, tick)
|
| | |
|
| | |
| | | CrossRealmPlayer.Sync_CrossCommInitDataToClientServer(serverGroupID)
|
| | | CrossRealmPK.Sync_CrossPKInitDataToClientServer(tick, serverGroupID)
|
| | | CrossBoss.Sync_CrossBossInitDataToClientServer(serverGroupID)
|
| | | CrossActionControl.Sync_CrossActInfoToClientServer(serverGroupID)
|
| | | PlayerCompensation.Sync_CrossMailPlayerIDToClientServer(serverGroupID)
|
| | | return
|
| | |
|
| | | def MapServer_CrossServerReceiveMsg(msgType, msgData, serverGroupID):
|
| | |
| | | elif msgType == ShareDefine.CrossServerMsg_PKSyncBillboard:
|
| | | CrossRealmPK.CrossServerMsg_PKSyncBillboard(msgData)
|
| | |
|
| | | elif msgType == ShareDefine.CrossServerMsg_SyncBillboard:
|
| | | CrossBillboard.CrossServerMsg_SyncBillboard(msgData, tick)
|
| | | |
| | | elif msgType == ShareDefine.CrossServerMsg_CrossBossInfo:
|
| | | CrossBoss.CrossServerMsg_CrossBossInfo(msgData)
|
| | |
|
| | | elif msgType == ShareDefine.CrossServerMsg_CrossBossState:
|
| | | CrossBoss.CrossServerMsg_CrossBossState(msgData)
|
| | | |
| | | elif msgType == ShareDefine.CrossServerMsg_CrossActInfo:
|
| | | CrossActionControl.CrossServerMsg_CrossActInfo(msgData)
|
| | |
|
| | | elif msgType == ShareDefine.CrossServerMsg_PutInItem:
|
| | | CrossRealmPlayer.CrossServerMsg_PutInItem(msgData)
|
| | |
| | | elif msgType == ShareDefine.CrossServerMsg_SendMail:
|
| | | PlayerCompensation.CrossServerMsg_SendMail(msgData)
|
| | |
|
| | | elif msgType == ShareDefine.CrossServerMsg_MailPlayerIDList:
|
| | | PlayerCompensation.CrossServerMsg_MailPlayerIDList(msgData)
|
| | | |
| | | elif msgType == ShareDefine.CrossServerMsg_MailContent:
|
| | | PlayerCompensation.CrossServerMsg_MailContent(msgData)
|
| | | |
| | | elif msgType == ShareDefine.CrossServerMsg_FBPlayerCount:
|
| | | PlayerFB.CrossServerMsg_FBPlayerCount(msgData)
|
| | |
|
| | |
| | | import GameWorldAverageLv
|
| | | import PlayerFamilyBoss
|
| | | import PlayerHorsePetBoss
|
| | | import CrossActionControl
|
| | | import GameWorldProcess
|
| | | import ChPyNetSendPack
|
| | | import NetPackCommon
|
| | |
| | | if GameWorld.IsCrossServer():
|
| | | # 跨服不处理运营活动
|
| | | return
|
| | | CrossActionControl.SendMapServerCrossActionState()
|
| | |
|
| | | isReload, OperationActionInfo = __GetOperationActionInfo()
|
| | | mapServerInfoDict = OperationActionInfo[OperationAction_MapServerInfo]
|
| | |
| | |
|
| | | if GameWorld.IsCrossServer():
|
| | | # 跨服不处理运营活动
|
| | | CrossActionControl.Dispose_CrossActState(reloadRefresh)
|
| | | return
|
| | |
|
| | | isReload, OperationActionInfo = __GetOperationActionInfo(False) # 这里必须传False
|
| | |
| | | ("WORD", "LVLimit", 0),
|
| | | ),
|
| | |
|
| | | "CrossActCTGBillboard":(
|
| | | ("DWORD", "CfgID", 1),
|
| | | ("char", "ActGroupName", 0),
|
| | | ("list", "ServerIDRangeList", 0),
|
| | | ("char", "StartDate", 0),
|
| | | ("char", "EndDate", 0),
|
| | | ("dict", "NotifyInfoStart", 0),
|
| | | ("dict", "NotifyInfoEnd", 0),
|
| | | ("list", "NotifyInfoLoop", 0),
|
| | | ("BYTE", "IsDayReset", 0),
|
| | | ("list", "TemplateIDList", 0),
|
| | | ),
|
| | |
|
| | | "CrossActCTGBillboardOrder":(
|
| | | ("DWORD", "TemplateID", 1),
|
| | | ("WORD", "OrderA", 0),
|
| | | ("WORD", "OrderB", 0),
|
| | | ("DWORD", "CTGAtleast", 0),
|
| | | ("list", "AwardItemList", 0),
|
| | | ),
|
| | |
|
| | | "EquipStarUp":(
|
| | | ("BYTE", "ClassLV", 1),
|
| | | ("BYTE", "EquipPlace", 1),
|
| | |
| | | def GetNotifyInfoLoop(self): return self.NotifyInfoLoop # 全服提示信息 - 循环广播[间隔分钟, 广播key]
|
| | | def GetLVLimit(self): return self.LVLimit # 限制等级 |
| | | |
| | | # 跨服充值排行活动时间表 |
| | | class IPY_CrossActCTGBillboard(): |
| | | |
| | | def __init__(self): |
| | | self.CfgID = 0
|
| | | self.ActGroupName = ""
|
| | | self.ServerIDRangeList = []
|
| | | self.StartDate = ""
|
| | | self.EndDate = ""
|
| | | self.NotifyInfoStart = {}
|
| | | self.NotifyInfoEnd = {}
|
| | | self.NotifyInfoLoop = []
|
| | | self.IsDayReset = 0
|
| | | self.TemplateIDList = [] |
| | | return |
| | | |
| | | def GetCfgID(self): return self.CfgID # 配置ID
|
| | | def GetActGroupName(self): return self.ActGroupName # 活动组名(同组活动的名字需相同)
|
| | | def GetServerIDRangeList(self): return self.ServerIDRangeList # 活动的账号服务器ID范围列表 [[serverIDA, serverIDB], ...]
|
| | | def GetStartDate(self): return self.StartDate # 开启日期
|
| | | def GetEndDate(self): return self.EndDate # 结束日期
|
| | | def GetNotifyInfoStart(self): return self.NotifyInfoStart # 全服提示信息 - 相对开始时间
|
| | | def GetNotifyInfoEnd(self): return self.NotifyInfoEnd # 全服提示信息 - 相对结束时间
|
| | | def GetNotifyInfoLoop(self): return self.NotifyInfoLoop # 全服提示信息 - 循环广播[循环分钟, 广播key, [广播参数列表可选]]
|
| | | def GetIsDayReset(self): return self.IsDayReset # 是否每天重置
|
| | | def GetTemplateIDList(self): return self.TemplateIDList # 模板ID列表 |
| | | |
| | | # 跨服充值排行模板名次奖励表 |
| | | class IPY_CrossActCTGBillboardOrder(): |
| | | |
| | | def __init__(self): |
| | | self.TemplateID = 0
|
| | | self.OrderA = 0
|
| | | self.OrderB = 0
|
| | | self.CTGAtleast = 0
|
| | | self.AwardItemList = [] |
| | | return |
| | | |
| | | def GetTemplateID(self): return self.TemplateID # 模板ID
|
| | | def GetOrderA(self): return self.OrderA # 名次A
|
| | | def GetOrderB(self): return self.OrderB # 至名次B
|
| | | def GetCTGAtleast(self): return self.CTGAtleast # 至少充值RMB
|
| | | def GetAwardItemList(self): return self.AwardItemList # 奖励物品列表[[物品ID,个数,是否拍品], ...] |
| | | |
| | | # 装备升星表 |
| | | class IPY_EquipStarUp(): |
| | | |
| | |
| | | self.ipyNewUniquenessArriveLen = len(self.ipyNewUniquenessArriveCache)
|
| | | self.ipyActLuckyTreasureCache = self.__LoadFileData("ActLuckyTreasure", IPY_ActLuckyTreasure)
|
| | | self.ipyActLuckyTreasureLen = len(self.ipyActLuckyTreasureCache)
|
| | | self.ipyCrossActCTGBillboardCache = self.__LoadFileData("CrossActCTGBillboard", IPY_CrossActCTGBillboard)
|
| | | self.ipyCrossActCTGBillboardLen = len(self.ipyCrossActCTGBillboardCache)
|
| | | self.ipyCrossActCTGBillboardOrderCache = self.__LoadFileData("CrossActCTGBillboardOrder", IPY_CrossActCTGBillboardOrder)
|
| | | self.ipyCrossActCTGBillboardOrderLen = len(self.ipyCrossActCTGBillboardOrderCache)
|
| | | self.ipyEquipStarUpCache = self.__LoadFileData("EquipStarUp", IPY_EquipStarUp)
|
| | | self.ipyEquipStarUpLen = len(self.ipyEquipStarUpCache)
|
| | | self.ipyFamilyWarRankAwardCache = self.__LoadFileData("FamilyWarRankAward", IPY_FamilyWarRankAward)
|
| | |
| | | def GetNewUniquenessArriveByIndex(self, index): return self.ipyNewUniquenessArriveCache[index]
|
| | | def GetActLuckyTreasureCount(self): return self.ipyActLuckyTreasureLen
|
| | | def GetActLuckyTreasureByIndex(self, index): return self.ipyActLuckyTreasureCache[index]
|
| | | def GetCrossActCTGBillboardCount(self): return self.ipyCrossActCTGBillboardLen
|
| | | def GetCrossActCTGBillboardByIndex(self, index): return self.ipyCrossActCTGBillboardCache[index]
|
| | | def GetCrossActCTGBillboardOrderCount(self): return self.ipyCrossActCTGBillboardOrderLen
|
| | | def GetCrossActCTGBillboardOrderByIndex(self, index): return self.ipyCrossActCTGBillboardOrderCache[index]
|
| | | def GetEquipStarUpCount(self): return self.ipyEquipStarUpLen
|
| | | def GetEquipStarUpByIndex(self, index): return self.ipyEquipStarUpCache[index]
|
| | | def GetFamilyWarRankAwardCount(self): return self.ipyFamilyWarRankAwardLen
|
| | |
| | | import NetPackCommon
|
| | | import CommFunc
|
| | | import ChPyNetSendPack
|
| | | import PyGameDataStruct
|
| | | import CrossRealmMsg
|
| | | import DataRecordPack
|
| | | import ReadChConfig
|
| | | import PlayerDBOper
|
| | | import EventReport
|
| | | import IpyGameDataPY
|
| | | import PlayerControl
|
| | | import PyDataManager
|
| | | import PyGameData
|
| | | import datetime
|
| | | import uuid
|
| | | import math
|
| | |
| | |
|
| | | Def_RequestState = "CompensationRequestState"
|
| | |
|
| | | #==================================================================================================
|
| | | class CrossPersonalCompensationManager(object):
|
| | | ## 跨服邮件管理,注意该类只处理数据逻辑,功能相关逻辑不要写在该类,不然重读脚本不会生效
|
| | | |
| | | def __init__(self):
|
| | | self.playerMailDict = {} # 玩家补偿列表 {playerID:{GUID:tagDBCrossPersonalCompensation, ...}, ...}
|
| | | return
|
| | | |
| | | # 保存数据 存数据库和realtimebackup
|
| | | def GetSaveData(self):
|
| | | savaData = ""
|
| | | cntData = ""
|
| | | cnt = 0
|
| | | for mailDict in self.playerMailDict.values():
|
| | | for mailObj in mailDict.values():
|
| | | cnt += 1
|
| | | savaData += mailObj.getBuffer()
|
| | | |
| | | GameWorld.Log("Save DBCrossPersonalCompensation cnt :%s" % cnt)
|
| | | return CommFunc.WriteDWORD(cntData, cnt) + savaData
|
| | | |
| | | # 从数据库载入数据
|
| | | def LoadPyGameData(self, datas, pos, dataslen):
|
| | | cnt, pos = CommFunc.ReadDWORD(datas, pos)
|
| | | GameWorld.Log("Load DBCrossPersonalCompensation cnt :%s" % cnt)
|
| | | |
| | | for _ in xrange(cnt):
|
| | | mailObj = PyGameDataStruct.tagDBCrossPersonalCompensation()
|
| | | mailObj.clear()
|
| | | pos += mailObj.readData(datas, pos, dataslen)
|
| | | |
| | | playerID = mailObj.PlayerID
|
| | | guid = mailObj.GUID
|
| | | if playerID not in self.playerMailDict:
|
| | | self.playerMailDict[playerID] = {}
|
| | | mailDict = self.playerMailDict[playerID]
|
| | | mailDict[guid] = mailObj
|
| | | |
| | | return pos
|
| | | |
| | | def Sync_CrossMailPlayerIDToClientServer(serverGroupID=0):
|
| | | ''' 同步有跨服邮件的玩家ID到子服
|
| | | @param serverGroupID: 为0时同步所有子服
|
| | | '''
|
| | | crossMailMgr = PyDataManager.GetCrossPersonalCompensationManager()
|
| | | addMailPlayerIDList = crossMailMgr.playerMailDict.keys()
|
| | | if not addMailPlayerIDList:
|
| | | return
|
| | | # 同步子服务器
|
| | | serverGroupIDList = [serverGroupID] if serverGroupID else []
|
| | | dataMsg = {"IDType":"Add", "PlayerIDList":addMailPlayerIDList}
|
| | | CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_MailPlayerIDList, dataMsg, serverGroupIDList)
|
| | | return
|
| | |
|
| | | def CrossServerMsg_MailPlayerIDList(dataMsg):
|
| | | ## 收到跨服服务器同步有跨服邮件的玩家ID列表
|
| | | idType = dataMsg["IDType"]
|
| | | playerIDList = dataMsg["PlayerIDList"]
|
| | | for playerID in playerIDList:
|
| | | if idType == "Del":
|
| | | if playerID in PyGameData.g_crossMailPlayerDict:
|
| | | PyGameData.g_crossMailPlayerDict.pop(playerID)
|
| | | continue
|
| | | |
| | | if idType == "Add":
|
| | | if playerID in PyGameData.g_crossMailPlayerDict:
|
| | | continue
|
| | | PyGameData.g_crossMailPlayerDict[playerID] = 0
|
| | | |
| | | player = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
|
| | | if not player or not player.GetInitOK():
|
| | | continue
|
| | | RequestToGetCrossMail(player)
|
| | | |
| | | return
|
| | |
|
| | | def RequestToGetCrossMail(curPlayer):
|
| | | ## 请求同步跨服邮件内容
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | if playerID not in PyGameData.g_crossMailPlayerDict:
|
| | | return
|
| | | lastTick = PyGameData.g_crossMailPlayerDict[playerID]
|
| | | tick = GameWorld.GetGameWorld().GetTick()
|
| | | if tick - lastTick <= 30000:
|
| | | return
|
| | | PyGameData.g_crossMailPlayerDict[playerID] = tick
|
| | | dataMsg = {"CMD":"Get", "PlayerID":playerID}
|
| | | CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_MailContent, dataMsg)
|
| | | return
|
| | |
|
| | | def ClientServerMsg_MailContent(serverGroupID, msgData, tick):
|
| | | ## 收到子服玩家请求同步跨服邮件
|
| | | |
| | | GameWorld.Log("收到子服玩家同步个人邮件命令: serverGroupID=%s, %s" % (serverGroupID, msgData))
|
| | | |
| | | reqCMD = msgData["CMD"]
|
| | | playerID = msgData["PlayerID"]
|
| | | guidList = msgData.get("GuidList", [])
|
| | | crossMailMgr = PyDataManager.GetCrossPersonalCompensationManager()
|
| | | if playerID not in crossMailMgr.playerMailDict:
|
| | | return
|
| | | playerMailDict = crossMailMgr.playerMailDict[playerID]
|
| | | |
| | | if reqCMD == "Get":
|
| | | SyncTickAttrKey = "SyncTick"
|
| | | getMailList = []
|
| | | for guid, mailObj in playerMailDict.items():
|
| | | if hasattr(mailObj, SyncTickAttrKey):
|
| | | getTick = getattr(mailObj, SyncTickAttrKey)
|
| | | if tick - getTick <= 30000:
|
| | | GameWorld.DebugLog("短时间内重复请求领取的邮件不同步,防止重复发放! GUID=%s" % guid)
|
| | | continue
|
| | | setattr(mailObj, SyncTickAttrKey, tick)
|
| | | crossMailDict = {"PlayerID":mailObj.PlayerID, "GUID":mailObj.GUID, "LimitTime":mailObj.LimitTime,
|
| | | "Text":mailObj.Text, "ItemInfo":mailObj.ItemInfo, "Detail":mailObj.Detail,
|
| | | "Gold":mailObj.Gold, "GoldPaper":mailObj.GoldPaper, "Silver":mailObj.Silver,
|
| | | "MoneySource":mailObj.MoneySource
|
| | | }
|
| | | getMailList.append(crossMailDict)
|
| | | |
| | | if getMailList:
|
| | | CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_MailContent, getMailList, [serverGroupID])
|
| | | |
| | | elif reqCMD == "GetOK":
|
| | | |
| | | for guid in guidList:
|
| | | playerMailDict.pop(guid, None)
|
| | | DataRecordPack.DR_GiveCompensationSuccess(playerID, guid)
|
| | | |
| | | if not playerMailDict:
|
| | | crossMailMgr.playerMailDict.pop(playerID, None)
|
| | | dataMsg = {"IDType":"Del", "PlayerIDList":[playerID]}
|
| | | CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_MailPlayerIDList, dataMsg, [serverGroupID])
|
| | | |
| | | return
|
| | |
|
| | | def CrossServerMsg_MailContent(getMailList):
|
| | | ## 收到跨服服务器同步的待发送邮件内容
|
| | | |
| | | playerGetGUIDInfo = {}
|
| | | for mailDict in getMailList:
|
| | | GUID = mailDict.get("GUID", "")
|
| | | playerID = mailDict.get("PlayerID", 0)
|
| | | if not GUID or not playerID:
|
| | | continue
|
| | | |
| | | GameWorld.Log("收到跨服个人邮件内容:%s" % mailDict, playerID)
|
| | | |
| | | addItemDictList = eval(mailDict.get("ItemInfo", "[]"))
|
| | | LimitTime = mailDict.get("LimitTime", "")
|
| | | Text = mailDict.get("Text", "")
|
| | | gold = GameWorld.ToIntDef(mailDict.get("Gold"))
|
| | | goldPaper = GameWorld.ToIntDef(mailDict.get("GoldPaper"))
|
| | | silver = GameWorld.ToIntDef(mailDict.get("Silver"))
|
| | | moneySource = GameWorld.ToIntDef(mailDict.get("MoneySource"), ChConfig.Def_GiveMoney_Mail)
|
| | | detail = mailDict.get("Detail", "")
|
| | | |
| | | AddPersonalItem(GUID, addItemDictList, [playerID], LimitTime, Text, gold, goldPaper, silver, detail, moneySource)
|
| | | |
| | | if playerID not in playerGetGUIDInfo:
|
| | | playerGetGUIDInfo[playerID] = []
|
| | | guidList = playerGetGUIDInfo[playerID]
|
| | | guidList.append(GUID)
|
| | | |
| | | for playerID, guidList in playerGetGUIDInfo.items():
|
| | | dataMsg = {"CMD":"GetOK", "PlayerID":playerID, "GuidList":guidList}
|
| | | CrossRealmMsg.SendMsgToCrossServer(ShareDefine.ClientServerMsg_MailContent, dataMsg)
|
| | | |
| | | return
|
| | |
|
| | | def __AddPlayerCrossMail(addItemDictList, PlayerIDList, LimitTime, Text, gold, goldPaper, silver, detail, moneySource):
|
| | | ## 添加跨服玩家个人补偿邮件
|
| | | |
| | | addMailPlayerIDList = []
|
| | | crossMailMgr = PyDataManager.GetCrossPersonalCompensationManager()
|
| | | for playerID in PlayerIDList:
|
| | | GUID = str(uuid.uuid1()) # 由于跨服邮件由每个玩家独自同步个人邮件,所以插入时每个人的邮件单独GUID,防止批量发送同内容邮件时重复插入奖励物品
|
| | | mailObj = PyGameDataStruct.tagDBCrossPersonalCompensation()
|
| | | mailObj.PlayerID = playerID
|
| | | mailObj.GUID = GUID
|
| | | mailObj.LimitTime = LimitTime
|
| | | mailObj.Text = Text
|
| | | mailObj.TextLen = len(mailObj.Text)
|
| | | mailObj.Gold = gold
|
| | | mailObj.GoldPaper = goldPaper
|
| | | mailObj.Silver = silver
|
| | | mailObj.ItemInfo = json.dumps(addItemDictList, ensure_ascii=False)
|
| | | mailObj.ItemLen = len(mailObj.ItemInfo)
|
| | | mailObj.Detail = detail
|
| | | mailObj.DetailLen = len(mailObj.Detail)
|
| | | mailObj.MoneySource = moneySource
|
| | | |
| | | if playerID not in crossMailMgr.playerMailDict:
|
| | | crossMailMgr.playerMailDict[playerID] = {}
|
| | | addMailPlayerIDList.append(playerID)
|
| | | playerMailDict = crossMailMgr.playerMailDict[playerID]
|
| | | playerMailDict[GUID] = mailObj
|
| | | |
| | | #添加流向
|
| | | addDict = {"LimitTime":LimitTime, "Text":Text, "Gold":gold, "GoldPaper":goldPaper, "Silver":silver, |
| | | "ItemListLen":len(addItemDictList), "Detail":detail, "MoneySource":moneySource, "CrossMail":True}
|
| | | DataRecordPack.DR_AddPersonalCompensation(PlayerIDList, GUID, addItemDictList, addDict)
|
| | | |
| | | if addMailPlayerIDList:
|
| | | dataMsg = {"IDType":"Add", "PlayerIDList":addMailPlayerIDList}
|
| | | CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_MailPlayerIDList, dataMsg)
|
| | | |
| | | return
|
| | |
|
| | | #==================================================================================================
|
| | | ## 根据物品信息字典,生成补偿物品实例,用于GM工具添加补偿
|
| | | # @param curItemDict
|
| | | # @return IpyCompensationItem
|
| | |
| | | # @param addItemList [(itemID, itemCnt, 是否拍品), {或物品信息字典}, ...]
|
| | | # @return GUID
|
| | | def SendPersonalItemMailEx(title, content, getDays, playerIDList, addItemList, gold = 0, goldPaper = 0, silver = 0,
|
| | | detail="", moneySource=ChConfig.Def_GiveMoney_Mail):
|
| | | detail="", moneySource=ChConfig.Def_GiveMoney_Mail, crossMail=False):
|
| | | limitTime = str(GameWorld.GetDatetimeByDiffDays(getDays))
|
| | | limitTime = limitTime.split(".")[0]
|
| | | return SendPersonalItemMail(title, content, limitTime, playerIDList, addItemList, gold, goldPaper, silver, detail, moneySource)
|
| | | return SendPersonalItemMail(title, content, limitTime, playerIDList, addItemList, gold, goldPaper, silver, detail, moneySource, crossMail)
|
| | |
|
| | | def SendPersonalItemMailBatch(batchMailInfoList):
|
| | | ## 批量发送邮件
|
| | |
| | | return
|
| | |
|
| | | def SendMailByKey(mailTypeKey, playerIDList, addItemList, paramList=[], gold=0, goldPaper=0, silver=0,
|
| | | detail="", moneySource=ChConfig.Def_GiveMoney_Mail):
|
| | | detail="", moneySource=ChConfig.Def_GiveMoney_Mail, crossMail=False):
|
| | | if not mailTypeKey:
|
| | | mailTypeKey = ShareDefine.DefaultLackSpaceMailType
|
| | | GameWorld.DebugLog("SendMailByKey %s, playerIDList=%s, addItemList=%s, paramList=%s, gold=%s, goldPaper=%s, silver=%s, moneySource=%s"
|
| | | % (mailTypeKey, playerIDList, addItemList, paramList, gold, goldPaper, silver, moneySource))
|
| | | title = ""
|
| | | content = "<MailTemplate>%s</MailTemplate>%s" % (mailTypeKey, json.dumps(paramList, ensure_ascii=False))
|
| | | return SendPersonalItemMailEx(title, content, 30, playerIDList, addItemList, gold, goldPaper, silver, detail, moneySource)
|
| | | return SendPersonalItemMailEx(title, content, 30, playerIDList, addItemList, gold, goldPaper, silver, detail, moneySource, crossMail)
|
| | |
|
| | | def CrossServerMsg_SendMail(msgData):
|
| | | ## 收到跨服服务器同步的发送邮件
|
| | |
| | | # @return GUID
|
| | | # @remarks addItemList支持append字典
|
| | | def SendPersonalItemMail(title, content, limitTime, playerIDList, addItemList, gold = 0, goldPaper = 0, silver = 0,
|
| | | detail="", moneySource=ChConfig.Def_GiveMoney_Mail):
|
| | | detail="", moneySource=ChConfig.Def_GiveMoney_Mail, crossMail=False):
|
| | | if not playerIDList:
|
| | | return ""
|
| | |
|
| | |
| | | GUID = str(uuid.uuid1())
|
| | | AddPersonalItem(GUID, addItemDictList[startIndex:startIndex + perMailItemCnt], playerIDList,
|
| | | limitTime, "%s<$_$>%s<$_$>%s" % (ChConfig.Def_Mail_SenderSys, title, content),
|
| | | gold, goldPaper, silver, detail, moneySource)
|
| | | gold, goldPaper, silver, detail, moneySource, crossMail)
|
| | | return GUID
|
| | |
|
| | | ## 发送纯文字个人补偿
|
| | |
| | | ## 添加个人补偿
|
| | | # @param addItemDict, PlayerIDList, LimitTime, Text
|
| | | # @return None
|
| | | def AddPersonalItem(GUID, addItemDictList, PlayerIDList, LimitTime, Text, gold = 0, goldPaper = 0, silver = 0, detail="", moneySource=ChConfig.Def_GiveMoney_Mail):
|
| | | def AddPersonalItem(GUID, addItemDictList, PlayerIDList, LimitTime, Text, gold = 0, goldPaper = 0, silver = 0, |
| | | detail="", moneySource=ChConfig.Def_GiveMoney_Mail, crossMail=False):
|
| | | if GameWorld.IsCrossServer():
|
| | | if crossMail:
|
| | | __AddPlayerCrossMail(addItemDictList, PlayerIDList, LimitTime, Text, gold, goldPaper, silver, detail, moneySource)
|
| | | return
|
| | | GameWorld.DebugLog("Compensation### AddPersonalItem GUID:%s ItemDict:\n%s "%(GUID, addItemDictList))
|
| | |
|
| | |
| | |
|
| | | # 提取接收邮件下发
|
| | | def NotifyPlayerCompensation(curPlayer):
|
| | | RequestToGetCrossMail(curPlayer)
|
| | | notifyList = SeekPlayerCompensation(curPlayer)
|
| | | SyncQueryCompensationResult(curPlayer, notifyList)
|
| | | return
|
| | |
| | | CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_Notify, crossNotifyList, serverGroupIDList)
|
| | | return
|
| | |
|
| | | def CrossNotifyEx(serverGroupIDList, crossNotifyList):
|
| | | ''' 跨服广播信息提示,支持同步多条,同时也建议多条一起同步
|
| | | @param serverGroupIDList: 需要同步到的目标服务器组ID列表
|
| | | @param crossNotifyList: 信息提示列表,[[notifyType, paramsList, 自定义扩展信息], ...] notifyType 如 ShareDefine.CrossNotify_CrossAct
|
| | | '''
|
| | | CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_Notify, crossNotifyList, serverGroupIDList)
|
| | | return
|
| | |
|
| | | def CrossServerMsg_Notify(crossNotifyList):
|
| | | GameWorld.DebugLog("收到跨服同步的广播提示内容: count=%s" % len(crossNotifyList))
|
| | | for notifyInfo in crossNotifyList:
|
| | | if "Type" not in notifyInfo or "Params" not in notifyInfo:
|
| | | if isinstance(notifyInfo, dict):
|
| | | if "Type" not in notifyInfo or "Params" not in notifyInfo:
|
| | | continue
|
| | | notifyType = notifyInfo["Type"]
|
| | | params = notifyInfo["Params"]
|
| | | elif isinstance(notifyInfo, list) and len(notifyInfo) >= 2:
|
| | | notifyType, params = notifyInfo[:2]
|
| | | else:
|
| | | continue
|
| | | notifyType = notifyInfo["Type"]
|
| | | params = notifyInfo["Params"]
|
| | | |
| | | if notifyType == ShareDefine.CrossNotify_World:
|
| | | country, msgMark, msgParamList = params
|
| | | WorldNotify(country, msgMark, msgParamList)
|
| | | elif notifyType == ShareDefine.CrossNotify_CrossAct:
|
| | | country, msgMark, msgParamList = params
|
| | | serverIDRangeList = notifyInfo[2]
|
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for i in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(i)
|
| | | if curPlayer == None or not curPlayer.GetInitOK() or GetIsTJG(curPlayer):
|
| | | continue
|
| | | if not serverIDRangeList:
|
| | | NotifyCode(curPlayer, msgMark, msgParamList)
|
| | | return
|
| | | playerServerID = GameWorld.GetPlayerServerID(curPlayer)
|
| | | for serverIDA, serverIDB in serverIDRangeList:
|
| | | if serverIDA <= playerServerID <= serverIDB:
|
| | | NotifyCode(curPlayer, msgMark, msgParamList)
|
| | | break
|
| | | |
| | | elif notifyType == ShareDefine.CrossNotify_Family:
|
| | | familyID, msgMark, msgParamList = params
|
| | | FamilyNotify(familyID, msgMark, msgParamList)
|
| | |
| | | # 服务器建盟次数
|
| | | Def_ServerCreatFamilyTimes = "CreatFamilyTimes"
|
| | |
|
| | | #设置跨服运营活动ID的标记
|
| | | Def_CrossActID = 'CAID_%s_%s' #参数为(运营活动名, 活动表配置cfgID)
|
| | | #设置运营活动ID的标记
|
| | | Def_OperationActID = 'OperationActID_%s' #参数为运营活动名
|
| | | #运营活动开启时世界等级,参数为运营活动名
|
| | |
| | | import ChConfig
|
| | | import GMCommon
|
| | | import DirtyList
|
| | | import CrossBillboard
|
| | | import PlayerBillboard
|
| | | import PlayerExam
|
| | | import PlayerControl
|
| | |
| | | if callName == "UpdateBillboard": #地图服务器更新排行榜
|
| | | PlayerBillboard.MapServer_UpdateBillboard(eval(resultName), tick)
|
| | | return
|
| | |
|
| | | if callName == "UpdateCrossBillboard": #地图服务器更新跨服排行榜
|
| | | CrossBillboard.MapServer_UpdateCrossBillboard(eval(resultName))
|
| | | return
|
| | |
|
| | | if callName == 'PyAddFamilyInfoValue': #地图服务器增加战盟信息值
|
| | | curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(srcPlayerID)
|
| | |
| | |
|
| | | import GameWorld
|
| | | import PlayerSocial
|
| | | import CrossBillboard
|
| | | import PlayerFamilyStore
|
| | | import PlayerCompensation
|
| | | import PlayerBourse
|
| | | import GameWorldBoss
|
| | | import PlayerSealDemon
|
| | |
| | |
|
| | | class PyGameDataManager(object):
|
| | | def __init__(self):
|
| | | self.CrossPersonalCompensationManager = PlayerCompensation.CrossPersonalCompensationManager()
|
| | | self.CrossBillboardManager = CrossBillboard.CrossBillboardManager()
|
| | | self.PlayerAssistThanksPyManager = PlayerAssistThanksPyManager()
|
| | | self.PlayerAssistPyManager = PlayerAssistPyManager()
|
| | | self.PlayerViewCachePyManager = PlayerViewCachePyManager()
|
| | |
| | |
|
| | | def GetSaveData(self):
|
| | | buff = ""
|
| | | buff += self.CrossPersonalCompensationManager.GetSaveData()
|
| | | buff += self.CrossBillboardManager.GetSaveData()
|
| | | buff += self.PlayerAssistThanksPyManager.GetSaveData()
|
| | | buff += self.PlayerAssistPyManager.GetSaveData()
|
| | | buff += self.PlayerViewCachePyManager.GetSaveData()
|
| | |
| | | return buff
|
| | |
|
| | | def LoadGameData(self, gameBuffer, pos):
|
| | | pos = self.CrossPersonalCompensationManager.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
|
| | | pos = self.CrossBillboardManager.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
|
| | | pos = self.PlayerAssistThanksPyManager.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
|
| | | pos = self.PlayerAssistPyManager.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
|
| | | pos = self.PlayerViewCachePyManager.LoadPyGameData(gameBuffer, pos, len(gameBuffer))
|
| | |
| | | PyGameData.g_pyGameDataManager = pyGameDataMgr
|
| | | return pyGameDataMgr
|
| | |
|
| | | def GetCrossPersonalCompensationManager():
|
| | | # 跨服个人补偿邮件管理
|
| | | pyGameDataMgr = GetPyGameDataManager()
|
| | | return pyGameDataMgr.CrossPersonalCompensationManager
|
| | |
|
| | | def GetCrossBillboardManager():
|
| | | # 跨服排行榜管理
|
| | | pyGameDataMgr = GetPyGameDataManager()
|
| | | return pyGameDataMgr.CrossBillboardManager
|
| | |
|
| | | def GetPlayerAssistThanksPyManager():
|
| | | # 协助感谢表
|
| | | pyGameDataMgr = GetPyGameDataManager()
|
| | |
| | |
|
| | | g_crossZoneName = "" # 跨服分区名
|
| | |
|
| | | g_crossActInfoDict = None # 跨服运营活动信息 {actName:{actInfoDict}, ...}
|
| | |
|
| | | g_crossMailPlayerDict = {} # 有跨服邮件的玩家ID信息 {playerID:tick, ...}
|
| | |
|
| | | g_crossPlayerViewCache = {} # 查看跨服玩家信息 {playerID:[cacheInfo, updTick], ...}
|
| | |
|
| | | g_crossPKPlayerDict = {} # 跨服PK玩家字典 {playerID:PKPlayer, ...}
|
| | |
| | | from ctypes import (Structure, memset, memmove, sizeof, addressof, create_string_buffer, string_at)
|
| | | import CommFunc
|
| | |
|
| | | # 跨服补偿个人领取表 #tagDBCrossPersonalCompensation
|
| | | class tagDBCrossPersonalCompensation(Structure):
|
| | | _pack_ = 1
|
| | | _fields_ = [
|
| | | ('PlayerID', ctypes.c_ulong),
|
| | | ('GUID', ctypes.c_char * 40),
|
| | | ('LimitTime', ctypes.c_char * 30),
|
| | | ('TextLen', ctypes.c_ulong),
|
| | | ('Text', ctypes.c_char_p),
|
| | | ('Gold', ctypes.c_ulong),
|
| | | ('GoldPaper', ctypes.c_ulong),
|
| | | ('Silver', ctypes.c_ulong),
|
| | | ('ItemLen', ctypes.c_ushort),
|
| | | ('ItemInfo', ctypes.c_char_p),
|
| | | ('DetailLen', ctypes.c_ushort),
|
| | | ('Detail', ctypes.c_char_p),
|
| | | ('MoneySource', ctypes.c_ushort),
|
| | | ('ADOResult', ctypes.c_ulong),
|
| | | ]
|
| | |
|
| | | def __init__(self):
|
| | | Structure.__init__(self)
|
| | | self.clear()
|
| | |
|
| | | def clear(self):
|
| | | self.PlayerID = 0
|
| | | self.GUID = ''
|
| | | self.LimitTime = ''
|
| | | self.TextLen = 0
|
| | | self.Text = ''
|
| | | self.Gold = 0
|
| | | self.GoldPaper = 0
|
| | | self.Silver = 0
|
| | | self.ItemLen = 0
|
| | | self.ItemInfo = ''
|
| | | self.DetailLen = 0
|
| | | self.Detail = ''
|
| | | self.MoneySource = 0
|
| | |
|
| | | def readData(self, buf, pos = 0, length = 0):
|
| | | if not pos <= length:
|
| | | return -1
|
| | | if len(buf) < pos + self.getLength():
|
| | | return -1
|
| | | self.clear()
|
| | | self.PlayerID, pos = CommFunc.ReadDWORD(buf, pos)
|
| | | self.GUID, pos = CommFunc.ReadString(buf, pos, 40)
|
| | | self.LimitTime, pos = CommFunc.ReadString(buf, pos, 30)
|
| | | self.TextLen, pos = CommFunc.ReadDWORD(buf, pos)
|
| | | tmp, pos = CommFunc.ReadString(buf, pos, self.TextLen)
|
| | | self.Text = ctypes.c_char_p(tmp)
|
| | | self.Gold, pos = CommFunc.ReadDWORD(buf, pos)
|
| | | self.GoldPaper, pos = CommFunc.ReadDWORD(buf, pos)
|
| | | self.Silver, pos = CommFunc.ReadDWORD(buf, pos)
|
| | | self.ItemLen, pos = CommFunc.ReadWORD(buf, pos)
|
| | | tmp, pos = CommFunc.ReadString(buf, pos, self.ItemLen)
|
| | | self.ItemInfo = ctypes.c_char_p(tmp)
|
| | | self.DetailLen, pos = CommFunc.ReadWORD(buf, pos)
|
| | | tmp, pos = CommFunc.ReadString(buf, pos, self.DetailLen)
|
| | | self.Detail = ctypes.c_char_p(tmp)
|
| | | self.MoneySource, pos = CommFunc.ReadWORD(buf, pos)
|
| | | return self.getLength()
|
| | |
|
| | | def getBuffer(self):
|
| | | buf = ''
|
| | | buf = CommFunc.WriteDWORD(buf, self.PlayerID)
|
| | | buf = CommFunc.WriteString(buf, sizeof(ctypes.c_char) * 40, self.GUID)
|
| | | buf = CommFunc.WriteString(buf, sizeof(ctypes.c_char) * 30, self.LimitTime)
|
| | | buf = CommFunc.WriteDWORD(buf, self.TextLen)
|
| | | buf = CommFunc.WriteString(buf, self.TextLen, self.Text)
|
| | | buf = CommFunc.WriteDWORD(buf, self.Gold)
|
| | | buf = CommFunc.WriteDWORD(buf, self.GoldPaper)
|
| | | buf = CommFunc.WriteDWORD(buf, self.Silver)
|
| | | buf = CommFunc.WriteWORD(buf, self.ItemLen)
|
| | | buf = CommFunc.WriteString(buf, self.ItemLen, self.ItemInfo)
|
| | | buf = CommFunc.WriteWORD(buf, self.DetailLen)
|
| | | buf = CommFunc.WriteString(buf, self.DetailLen, self.Detail)
|
| | | buf = CommFunc.WriteWORD(buf, self.MoneySource)
|
| | | return buf
|
| | |
|
| | | def getLength(self):
|
| | | length = 0
|
| | | length += sizeof(ctypes.c_ulong)
|
| | | length += sizeof(ctypes.c_char) * 40
|
| | | length += sizeof(ctypes.c_char) * 30
|
| | | length += sizeof(ctypes.c_ulong)
|
| | | length += self.TextLen
|
| | | length += sizeof(ctypes.c_ulong)
|
| | | length += sizeof(ctypes.c_ulong)
|
| | | length += sizeof(ctypes.c_ulong)
|
| | | length += sizeof(ctypes.c_ushort)
|
| | | length += self.ItemLen
|
| | | length += sizeof(ctypes.c_ushort)
|
| | | length += self.DetailLen
|
| | | length += sizeof(ctypes.c_ushort)
|
| | | return length
|
| | |
|
| | | def outputString(self):
|
| | | output = '''// 跨服补偿个人领取表 #tagDBCrossPersonalCompensation:
|
| | | PlayerID = %s,
|
| | | GUID = %s,
|
| | | LimitTime = %s,
|
| | | TextLen = %s,
|
| | | Text = %s,
|
| | | Gold = %s,
|
| | | GoldPaper = %s,
|
| | | Silver = %s,
|
| | | ItemLen = %s,
|
| | | ItemInfo = %s,
|
| | | DetailLen = %s,
|
| | | Detail = %s,
|
| | | MoneySource = %s,
|
| | | ADOResult = %s,
|
| | | '''%(
|
| | | self.PlayerID,
|
| | | self.GUID,
|
| | | self.LimitTime,
|
| | | self.TextLen,
|
| | | self.Text,
|
| | | self.Gold,
|
| | | self.GoldPaper,
|
| | | self.Silver,
|
| | | self.ItemLen,
|
| | | self.ItemInfo,
|
| | | self.DetailLen,
|
| | | self.Detail,
|
| | | self.MoneySource,
|
| | | self.ADOResult,
|
| | | )
|
| | | return output
|
| | |
|
| | | #Char数组类型Set接口,使用该接口对此类型数据赋值,防止赋值的数据过长报错
|
| | | def SetGUID(self,Str):
|
| | | if len(Str)<=40:
|
| | | self.GUID = Str
|
| | | else:
|
| | | self.GUID = Str[:40]
|
| | | |
| | | def SetLimitTime(self,Str):
|
| | | if len(Str)<=30:
|
| | | self.LimitTime = Str
|
| | | else:
|
| | | self.LimitTime = Str[:30]
|
| | | |
| | |
|
| | | # 跨服排行榜 #tagDBCrossBillboard
|
| | | class tagDBCrossBillboard(Structure):
|
| | | _pack_ = 1
|
| | | _fields_ = [
|
| | | ('GroupValue1', ctypes.c_ubyte),
|
| | | ('GroupValue2', ctypes.c_ubyte),
|
| | | ('BillboardType', ctypes.c_ubyte),
|
| | | ('ID', ctypes.c_ulong),
|
| | | ('ID2', ctypes.c_ulong),
|
| | | ('Name1', ctypes.c_char * 33),
|
| | | ('Name2', ctypes.c_char * 33),
|
| | | ('Type2', ctypes.c_ubyte),
|
| | | ('Value1', ctypes.c_ulong),
|
| | | ('Value2', ctypes.c_ulong),
|
| | | ('CmpValue', ctypes.c_ulong),
|
| | | ('CmpValue2', ctypes.c_ulong),
|
| | | ('CmpValue3', ctypes.c_ulong),
|
| | | ('ADOResult', ctypes.c_ulong),
|
| | | ]
|
| | |
|
| | | def __init__(self):
|
| | | Structure.__init__(self)
|
| | | self.clear()
|
| | |
|
| | |
|
| | | def clear(self):
|
| | | memset(addressof(self), 0, self.getLength())
|
| | |
|
| | | def readData(self, buf, pos = 0, length = 0):
|
| | | if not pos <= length:
|
| | | return -1
|
| | | if len(buf) < pos + self.getLength():
|
| | | return -1
|
| | | self.clear()
|
| | | self.GroupValue1, pos = CommFunc.ReadBYTE(buf, pos)
|
| | | self.GroupValue2, pos = CommFunc.ReadBYTE(buf, pos)
|
| | | self.BillboardType, pos = CommFunc.ReadBYTE(buf, pos)
|
| | | self.ID, pos = CommFunc.ReadDWORD(buf, pos)
|
| | | self.ID2, pos = CommFunc.ReadDWORD(buf, pos)
|
| | | self.Name1, pos = CommFunc.ReadString(buf, pos, 33)
|
| | | self.Name2, pos = CommFunc.ReadString(buf, pos, 33)
|
| | | self.Type2, pos = CommFunc.ReadBYTE(buf, pos)
|
| | | self.Value1, pos = CommFunc.ReadDWORD(buf, pos)
|
| | | self.Value2, pos = CommFunc.ReadDWORD(buf, pos)
|
| | | self.CmpValue, pos = CommFunc.ReadDWORD(buf, pos)
|
| | | self.CmpValue2, pos = CommFunc.ReadDWORD(buf, pos)
|
| | | self.CmpValue3, pos = CommFunc.ReadDWORD(buf, pos)
|
| | | return self.getLength()
|
| | |
|
| | |
|
| | | def getBuffer(self):
|
| | | buf = create_string_buffer(self.getLength())
|
| | | memmove(addressof(buf), addressof(self), self.getLength())
|
| | | return string_at(addressof(buf), self.getLength())
|
| | |
|
| | | def getLength(self):
|
| | | return sizeof(tagDBCrossBillboard)
|
| | |
|
| | | def outputString(self):
|
| | | output = '''// 跨服排行榜 #tagDBCrossBillboard:
|
| | | GroupValue1 = %s,
|
| | | GroupValue2 = %s,
|
| | | BillboardType = %s,
|
| | | ID = %s,
|
| | | ID2 = %s,
|
| | | Name1 = %s,
|
| | | Name2 = %s,
|
| | | Type2 = %s,
|
| | | Value1 = %s,
|
| | | Value2 = %s,
|
| | | CmpValue = %s,
|
| | | CmpValue2 = %s,
|
| | | CmpValue3 = %s,
|
| | | ADOResult = %s,
|
| | | '''%(
|
| | | self.GroupValue1,
|
| | | self.GroupValue2,
|
| | | self.BillboardType,
|
| | | self.ID,
|
| | | self.ID2,
|
| | | self.Name1,
|
| | | self.Name2,
|
| | | self.Type2,
|
| | | self.Value1,
|
| | | self.Value2,
|
| | | self.CmpValue,
|
| | | self.CmpValue2,
|
| | | self.CmpValue3,
|
| | | self.ADOResult,
|
| | | )
|
| | | return output
|
| | |
|
| | | #Char数组类型Set接口,使用该接口对此类型数据赋值,防止赋值的数据过长报错
|
| | | def SetName1(self,Str):
|
| | | if len(Str)<=33:
|
| | | self.Name1 = Str
|
| | | else:
|
| | | self.Name1 = Str[:33]
|
| | | |
| | | def SetName2(self,Str):
|
| | | if len(Str)<=33:
|
| | | self.Name2 = Str
|
| | | else:
|
| | | self.Name2 = Str[:33]
|
| | | |
| | |
|
| | | # 协助感谢表 #tagDBAssistThanks
|
| | | class tagDBAssistThanks(Structure):
|
| | | _pack_ = 1
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # C0 04 查看跨服排行榜 #tagCGViewCrossBillboard
|
| | |
|
| | | class tagCGViewCrossBillboard(Structure):
|
| | | _pack_ = 1
|
| | | _fields_ = [
|
| | | ("Cmd", c_ubyte),
|
| | | ("SubCmd", c_ubyte),
|
| | | ("Type", c_ubyte), #榜单类型
|
| | | ("GroupValue1", c_ubyte), # 分组值1
|
| | | ("GroupValue2", c_ubyte), # 分组值2,与分组值1组合归为同组榜单数据
|
| | | ]
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Cmd = 0xC0
|
| | | self.SubCmd = 0x04
|
| | | 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 = 0x04
|
| | | self.Type = 0
|
| | | self.GroupValue1 = 0
|
| | | self.GroupValue2 = 0
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | return sizeof(tagCGViewCrossBillboard)
|
| | |
|
| | | def GetBuffer(self):
|
| | | return string_at(addressof(self), self.GetLength())
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''// C0 04 查看跨服排行榜 //tagCGViewCrossBillboard:
|
| | | Cmd:%s,
|
| | | SubCmd:%s,
|
| | | Type:%d,
|
| | | GroupValue1:%d,
|
| | | GroupValue2:%d
|
| | | '''\
|
| | | %(
|
| | | self.Cmd,
|
| | | self.SubCmd,
|
| | | self.Type,
|
| | | self.GroupValue1,
|
| | | self.GroupValue2
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagCGViewCrossBillboard=tagCGViewCrossBillboard()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCGViewCrossBillboard.Cmd,m_NAtagCGViewCrossBillboard.SubCmd))] = m_NAtagCGViewCrossBillboard
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # C0 01 查看跨服竞技场赛季排行榜 #tagCGViewCrossPKBillboard
|
| | |
|
| | | class tagCGViewCrossPKBillboard(Structure):
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # AC 12 跨服运营活动结束 # tagGCCrossActEnd
|
| | |
|
| | | class tagGCCrossActEnd(Structure):
|
| | | Head = tagHead()
|
| | | ActNameLen = 0 #(BYTE ActNameLen)
|
| | | ActName = "" #(String ActName)
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Head.Cmd = 0xAC
|
| | | self.Head.SubCmd = 0x12
|
| | | return
|
| | |
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | _pos = self.Head.ReadData(_lpData, _pos)
|
| | | self.ActNameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.ActName,_pos = CommFunc.ReadString(_lpData, _pos,self.ActNameLen)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.Head = tagHead()
|
| | | self.Head.Clear()
|
| | | self.Head.Cmd = 0xAC
|
| | | self.Head.SubCmd = 0x12
|
| | | self.ActNameLen = 0
|
| | | self.ActName = ""
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | length = 0
|
| | | length += self.Head.GetLength()
|
| | | length += 1
|
| | | length += len(self.ActName)
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | data = ''
|
| | | data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
|
| | | data = CommFunc.WriteBYTE(data, self.ActNameLen)
|
| | | data = CommFunc.WriteString(data, self.ActNameLen, self.ActName)
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''
|
| | | Head:%s,
|
| | | ActNameLen:%d,
|
| | | ActName:%s
|
| | | '''\
|
| | | %(
|
| | | self.Head.OutputString(),
|
| | | self.ActNameLen,
|
| | | self.ActName
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagGCCrossActEnd=tagGCCrossActEnd()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCCrossActEnd.Head.Cmd,m_NAtagGCCrossActEnd.Head.SubCmd))] = m_NAtagGCCrossActEnd
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # AC 09 仙界盛典活动信息 #tagGCFairyCeremonyInfo
|
| | |
|
| | | class tagGCFairyCeremonyInfo(Structure):
|
| | |
| | |
|
| | | m_NAtagGCTeamMemFuncDataList=tagGCTeamMemFuncDataList()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCTeamMemFuncDataList.Head.Cmd,m_NAtagGCTeamMemFuncDataList.Head.SubCmd))] = m_NAtagGCTeamMemFuncDataList
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # C0 07 跨服排行榜信息 #tagGCCrossBillboardInfo
|
| | |
|
| | | class tagGCCrossBillboardData(Structure):
|
| | | ID = 0 #(DWORD ID)
|
| | | Name1 = "" #(char Name1[33])//名字1,用来显示排序对象名字 |
| | | Name2 = "" #(char Name2[33])//名字2
|
| | | Type2 = 0 #(BYTE Type2)//附加类型,用来表示排序对象的类型,比如,玩家所属职业门派,宠物类型等
|
| | | Value1 = 0 #(DWORD Value1)//自定义值1
|
| | | Value2 = 0 #(DWORD Value2)//自定义值2
|
| | | CmpValue = 0 #(DWORD CmpValue)// 比较权值
|
| | | CmpValue2 = 0 #(DWORD CmpValue2)// 比较权值
|
| | | CmpValue3 = 0 #(DWORD CmpValue3)// 比较权值
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | return
|
| | |
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | self.ID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.Name1,_pos = CommFunc.ReadString(_lpData, _pos,33)
|
| | | self.Name2,_pos = CommFunc.ReadString(_lpData, _pos,33)
|
| | | self.Type2,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.Value1,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.Value2,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.CmpValue,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.CmpValue2,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.CmpValue3,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.ID = 0
|
| | | self.Name1 = ""
|
| | | self.Name2 = ""
|
| | | self.Type2 = 0
|
| | | self.Value1 = 0
|
| | | self.Value2 = 0
|
| | | self.CmpValue = 0
|
| | | self.CmpValue2 = 0
|
| | | self.CmpValue3 = 0
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | length = 0
|
| | | length += 4
|
| | | length += 33
|
| | | length += 33
|
| | | length += 1
|
| | | length += 4
|
| | | length += 4
|
| | | length += 4
|
| | | length += 4
|
| | | length += 4
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | data = ''
|
| | | data = CommFunc.WriteDWORD(data, self.ID)
|
| | | data = CommFunc.WriteString(data, 33, self.Name1)
|
| | | data = CommFunc.WriteString(data, 33, self.Name2)
|
| | | data = CommFunc.WriteBYTE(data, self.Type2)
|
| | | data = CommFunc.WriteDWORD(data, self.Value1)
|
| | | data = CommFunc.WriteDWORD(data, self.Value2)
|
| | | data = CommFunc.WriteDWORD(data, self.CmpValue)
|
| | | data = CommFunc.WriteDWORD(data, self.CmpValue2)
|
| | | data = CommFunc.WriteDWORD(data, self.CmpValue3)
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''
|
| | | ID:%d,
|
| | | Name1:%s,
|
| | | Name2:%s,
|
| | | Type2:%d,
|
| | | Value1:%d,
|
| | | Value2:%d,
|
| | | CmpValue:%d,
|
| | | CmpValue2:%d,
|
| | | CmpValue3:%d
|
| | | '''\
|
| | | %(
|
| | | self.ID,
|
| | | self.Name1,
|
| | | self.Name2,
|
| | | self.Type2,
|
| | | self.Value1,
|
| | | self.Value2,
|
| | | self.CmpValue,
|
| | | self.CmpValue2,
|
| | | self.CmpValue3
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | class tagGCCrossBillboardInfo(Structure):
|
| | | Head = tagHead()
|
| | | Type = 0 #(BYTE Type)//榜单类型
|
| | | GroupValue1 = 0 #(BYTE GroupValue1)// 分组值1
|
| | | GroupValue2 = 0 #(BYTE GroupValue2)// 分组值2,与分组值1组合归为同组榜单数据
|
| | | BillboardCount = 0 #(BYTE BillboardCount)
|
| | | CrossBillboardDataList = list() #(vector<tagGCCrossBillboardData> CrossBillboardDataList)
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Head.Cmd = 0xC0
|
| | | self.Head.SubCmd = 0x07
|
| | | return
|
| | |
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | _pos = self.Head.ReadData(_lpData, _pos)
|
| | | self.Type,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.GroupValue1,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.GroupValue2,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.BillboardCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | for i in range(self.BillboardCount):
|
| | | temCrossBillboardDataList = tagGCCrossBillboardData()
|
| | | _pos = temCrossBillboardDataList.ReadData(_lpData, _pos)
|
| | | self.CrossBillboardDataList.append(temCrossBillboardDataList)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.Head = tagHead()
|
| | | self.Head.Clear()
|
| | | self.Head.Cmd = 0xC0
|
| | | self.Head.SubCmd = 0x07
|
| | | self.Type = 0
|
| | | self.GroupValue1 = 0
|
| | | self.GroupValue2 = 0
|
| | | self.BillboardCount = 0
|
| | | self.CrossBillboardDataList = list()
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | length = 0
|
| | | length += self.Head.GetLength()
|
| | | length += 1
|
| | | length += 1
|
| | | length += 1
|
| | | length += 1
|
| | | for i in range(self.BillboardCount):
|
| | | length += self.CrossBillboardDataList[i].GetLength()
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | data = ''
|
| | | data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
|
| | | data = CommFunc.WriteBYTE(data, self.Type)
|
| | | data = CommFunc.WriteBYTE(data, self.GroupValue1)
|
| | | data = CommFunc.WriteBYTE(data, self.GroupValue2)
|
| | | data = CommFunc.WriteBYTE(data, self.BillboardCount)
|
| | | for i in range(self.BillboardCount):
|
| | | data = CommFunc.WriteString(data, self.CrossBillboardDataList[i].GetLength(), self.CrossBillboardDataList[i].GetBuffer())
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''
|
| | | Head:%s,
|
| | | Type:%d,
|
| | | GroupValue1:%d,
|
| | | GroupValue2:%d,
|
| | | BillboardCount:%d,
|
| | | CrossBillboardDataList:%s
|
| | | '''\
|
| | | %(
|
| | | self.Head.OutputString(),
|
| | | self.Type,
|
| | | self.GroupValue1,
|
| | | self.GroupValue2,
|
| | | self.BillboardCount,
|
| | | "..."
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagGCCrossBillboardInfo=tagGCCrossBillboardInfo()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCCrossBillboardInfo.Head.Cmd,m_NAtagGCCrossBillboardInfo.Head.SubCmd))] = m_NAtagGCCrossBillboardInfo
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # AA 32 跨服充值排行活动信息 #tagMCCACTGBillboardInfo
|
| | |
|
| | | class tagMCCACTGBillboardAwardItem(Structure):
|
| | | _pack_ = 1
|
| | | _fields_ = [
|
| | | ("ItemID", c_int), |
| | | ("ItemCount", c_ushort), |
| | | ("IsBind", c_ubyte), # 是否拍品
|
| | | ]
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | 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.ItemID = 0
|
| | | self.ItemCount = 0
|
| | | self.IsBind = 0
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | return sizeof(tagMCCACTGBillboardAwardItem)
|
| | |
|
| | | def GetBuffer(self):
|
| | | return string_at(addressof(self), self.GetLength())
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''// AA 32 跨服充值排行活动信息 //tagMCCACTGBillboardInfo:
|
| | | ItemID:%d,
|
| | | ItemCount:%d,
|
| | | IsBind:%d
|
| | | '''\
|
| | | %(
|
| | | self.ItemID,
|
| | | self.ItemCount,
|
| | | self.IsBind
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | class tagMCCACTGBillboardDabiao(Structure):
|
| | | AwardIndex = 0 #(BYTE AwardIndex)// 奖励索引 0~31
|
| | | NeedRMB = 0 #(DWORD NeedRMB)// 所需充值RMB
|
| | | AwardItemCount = 0 #(BYTE AwardItemCount)// 奖励物品数
|
| | | AwardItemList = list() #(vector<tagMCCACTGBillboardAwardItem> AwardItemList)// 奖励物品信息
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | return
|
| | |
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | self.AwardIndex,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.NeedRMB,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.AwardItemCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | for i in range(self.AwardItemCount):
|
| | | temAwardItemList = tagMCCACTGBillboardAwardItem()
|
| | | _pos = temAwardItemList.ReadData(_lpData, _pos)
|
| | | self.AwardItemList.append(temAwardItemList)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.AwardIndex = 0
|
| | | self.NeedRMB = 0
|
| | | self.AwardItemCount = 0
|
| | | self.AwardItemList = list()
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | length = 0
|
| | | length += 1
|
| | | length += 4
|
| | | length += 1
|
| | | for i in range(self.AwardItemCount):
|
| | | length += self.AwardItemList[i].GetLength()
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | data = ''
|
| | | data = CommFunc.WriteBYTE(data, self.AwardIndex)
|
| | | data = CommFunc.WriteDWORD(data, self.NeedRMB)
|
| | | data = CommFunc.WriteBYTE(data, self.AwardItemCount)
|
| | | for i in range(self.AwardItemCount):
|
| | | data = CommFunc.WriteString(data, self.AwardItemList[i].GetLength(), self.AwardItemList[i].GetBuffer())
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''
|
| | | AwardIndex:%d,
|
| | | NeedRMB:%d,
|
| | | AwardItemCount:%d,
|
| | | AwardItemList:%s
|
| | | '''\
|
| | | %(
|
| | | self.AwardIndex,
|
| | | self.NeedRMB,
|
| | | self.AwardItemCount,
|
| | | "..."
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | class tagMCCACTGBillboardOrder(Structure):
|
| | | OrderA = 0 #(BYTE OrderA)// 名次A
|
| | | OrderB = 0 #(BYTE OrderB)// 至名次B
|
| | | NeedRMB = 0 #(DWORD NeedRMB)// 所需充值RMB,未达标的该名次空,排名后面的玩家向下顺延
|
| | | AwardItemCount = 0 #(BYTE AwardItemCount)// 奖励物品数
|
| | | AwardItemList = list() #(vector<tagMCCACTGBillboardAwardItem> AwardItemList)// 奖励物品信息
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | return
|
| | |
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | self.OrderA,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.OrderB,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.NeedRMB,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.AwardItemCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | for i in range(self.AwardItemCount):
|
| | | temAwardItemList = tagMCCACTGBillboardAwardItem()
|
| | | _pos = temAwardItemList.ReadData(_lpData, _pos)
|
| | | self.AwardItemList.append(temAwardItemList)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.OrderA = 0
|
| | | self.OrderB = 0
|
| | | self.NeedRMB = 0
|
| | | self.AwardItemCount = 0
|
| | | self.AwardItemList = list()
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | length = 0
|
| | | length += 1
|
| | | length += 1
|
| | | length += 4
|
| | | length += 1
|
| | | for i in range(self.AwardItemCount):
|
| | | length += self.AwardItemList[i].GetLength()
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | data = ''
|
| | | data = CommFunc.WriteBYTE(data, self.OrderA)
|
| | | data = CommFunc.WriteBYTE(data, self.OrderB)
|
| | | data = CommFunc.WriteDWORD(data, self.NeedRMB)
|
| | | data = CommFunc.WriteBYTE(data, self.AwardItemCount)
|
| | | for i in range(self.AwardItemCount):
|
| | | data = CommFunc.WriteString(data, self.AwardItemList[i].GetLength(), self.AwardItemList[i].GetBuffer())
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''
|
| | | OrderA:%d,
|
| | | OrderB:%d,
|
| | | NeedRMB:%d,
|
| | | AwardItemCount:%d,
|
| | | AwardItemList:%s
|
| | | '''\
|
| | | %(
|
| | | self.OrderA,
|
| | | self.OrderB,
|
| | | self.NeedRMB,
|
| | | self.AwardItemCount,
|
| | | "..."
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | class tagMCCACTGBillboardTempInfo(Structure):
|
| | | TemplateID = 0 #(BYTE TemplateID)// 活动模板ID
|
| | | DabiaoAwardCount = 0 #(BYTE DabiaoAwardCount)// 达标奖励档数
|
| | | DabiaoAwardInfo = list() #(vector<tagMCCACTGBillboardDabiao> DabiaoAwardInfo)// 达标奖励信息
|
| | | OrderAwardCount = 0 #(BYTE OrderAwardCount)// 排行奖励档数
|
| | | OrderAwardInfo = list() #(vector<tagMCCACTGBillboardOrder> OrderAwardInfo)// 排行奖励信息
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | return
|
| | |
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | self.TemplateID,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.DabiaoAwardCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | for i in range(self.DabiaoAwardCount):
|
| | | temDabiaoAwardInfo = tagMCCACTGBillboardDabiao()
|
| | | _pos = temDabiaoAwardInfo.ReadData(_lpData, _pos)
|
| | | self.DabiaoAwardInfo.append(temDabiaoAwardInfo)
|
| | | self.OrderAwardCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | for i in range(self.OrderAwardCount):
|
| | | temOrderAwardInfo = tagMCCACTGBillboardOrder()
|
| | | _pos = temOrderAwardInfo.ReadData(_lpData, _pos)
|
| | | self.OrderAwardInfo.append(temOrderAwardInfo)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.TemplateID = 0
|
| | | self.DabiaoAwardCount = 0
|
| | | self.DabiaoAwardInfo = list()
|
| | | self.OrderAwardCount = 0
|
| | | self.OrderAwardInfo = list()
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | length = 0
|
| | | length += 1
|
| | | length += 1
|
| | | for i in range(self.DabiaoAwardCount):
|
| | | length += self.DabiaoAwardInfo[i].GetLength()
|
| | | length += 1
|
| | | for i in range(self.OrderAwardCount):
|
| | | length += self.OrderAwardInfo[i].GetLength()
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | data = ''
|
| | | data = CommFunc.WriteBYTE(data, self.TemplateID)
|
| | | data = CommFunc.WriteBYTE(data, self.DabiaoAwardCount)
|
| | | for i in range(self.DabiaoAwardCount):
|
| | | data = CommFunc.WriteString(data, self.DabiaoAwardInfo[i].GetLength(), self.DabiaoAwardInfo[i].GetBuffer())
|
| | | data = CommFunc.WriteBYTE(data, self.OrderAwardCount)
|
| | | for i in range(self.OrderAwardCount):
|
| | | data = CommFunc.WriteString(data, self.OrderAwardInfo[i].GetLength(), self.OrderAwardInfo[i].GetBuffer())
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''
|
| | | TemplateID:%d,
|
| | | DabiaoAwardCount:%d,
|
| | | DabiaoAwardInfo:%s,
|
| | | OrderAwardCount:%d,
|
| | | OrderAwardInfo:%s
|
| | | '''\
|
| | | %(
|
| | | self.TemplateID,
|
| | | self.DabiaoAwardCount,
|
| | | "...",
|
| | | self.OrderAwardCount,
|
| | | "..."
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | class tagMCCACTGBillboardInfo(Structure):
|
| | | Head = tagHead()
|
| | | ServerInfoLen = 0 #(BYTE ServerInfoLen)
|
| | | ServerIDRangeInfo = "" #(String ServerIDRangeInfo)//开放该活动的服务器ID范围列表,json格式 [[IDA, IDB], ...], [] 为全服
|
| | | GroupValue1 = 0 #(BYTE GroupValue1)// 活动榜单分组值1,用于查询对应榜单
|
| | | StartDate = "" #(char StartDate[10])// 开始日期 y-m-d
|
| | | EndtDate = "" #(char EndtDate[10])// 结束日期 y-m-d
|
| | | TemplateID = 0 #(BYTE TemplateID)// 当前活动模板ID
|
| | | TemplateCount = 0 #(BYTE TemplateCount)
|
| | | TempInfo = list() #(vector<tagMCCACTGBillboardTempInfo> TempInfo)// 模板信息
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Head.Cmd = 0xAA
|
| | | self.Head.SubCmd = 0x32
|
| | | return
|
| | |
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | _pos = self.Head.ReadData(_lpData, _pos)
|
| | | self.ServerInfoLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.ServerIDRangeInfo,_pos = CommFunc.ReadString(_lpData, _pos,self.ServerInfoLen)
|
| | | self.GroupValue1,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.StartDate,_pos = CommFunc.ReadString(_lpData, _pos,10)
|
| | | self.EndtDate,_pos = CommFunc.ReadString(_lpData, _pos,10)
|
| | | self.TemplateID,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | self.TemplateCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | for i in range(self.TemplateCount):
|
| | | temTempInfo = tagMCCACTGBillboardTempInfo()
|
| | | _pos = temTempInfo.ReadData(_lpData, _pos)
|
| | | self.TempInfo.append(temTempInfo)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.Head = tagHead()
|
| | | self.Head.Clear()
|
| | | self.Head.Cmd = 0xAA
|
| | | self.Head.SubCmd = 0x32
|
| | | self.ServerInfoLen = 0
|
| | | self.ServerIDRangeInfo = ""
|
| | | self.GroupValue1 = 0
|
| | | self.StartDate = ""
|
| | | self.EndtDate = ""
|
| | | self.TemplateID = 0
|
| | | self.TemplateCount = 0
|
| | | self.TempInfo = list()
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | length = 0
|
| | | length += self.Head.GetLength()
|
| | | length += 1
|
| | | length += len(self.ServerIDRangeInfo)
|
| | | length += 1
|
| | | length += 10
|
| | | length += 10
|
| | | length += 1
|
| | | length += 1
|
| | | for i in range(self.TemplateCount):
|
| | | length += self.TempInfo[i].GetLength()
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | data = ''
|
| | | data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
|
| | | data = CommFunc.WriteBYTE(data, self.ServerInfoLen)
|
| | | data = CommFunc.WriteString(data, self.ServerInfoLen, self.ServerIDRangeInfo)
|
| | | data = CommFunc.WriteBYTE(data, self.GroupValue1)
|
| | | data = CommFunc.WriteString(data, 10, self.StartDate)
|
| | | data = CommFunc.WriteString(data, 10, self.EndtDate)
|
| | | data = CommFunc.WriteBYTE(data, self.TemplateID)
|
| | | data = CommFunc.WriteBYTE(data, self.TemplateCount)
|
| | | for i in range(self.TemplateCount):
|
| | | data = CommFunc.WriteString(data, self.TempInfo[i].GetLength(), self.TempInfo[i].GetBuffer())
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''
|
| | | Head:%s,
|
| | | ServerInfoLen:%d,
|
| | | ServerIDRangeInfo:%s,
|
| | | GroupValue1:%d,
|
| | | StartDate:%s,
|
| | | EndtDate:%s,
|
| | | TemplateID:%d,
|
| | | TemplateCount:%d,
|
| | | TempInfo:%s
|
| | | '''\
|
| | | %(
|
| | | self.Head.OutputString(),
|
| | | self.ServerInfoLen,
|
| | | self.ServerIDRangeInfo,
|
| | | self.GroupValue1,
|
| | | self.StartDate,
|
| | | self.EndtDate,
|
| | | self.TemplateID,
|
| | | self.TemplateCount,
|
| | | "..."
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagMCCACTGBillboardInfo=tagMCCACTGBillboardInfo()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCCACTGBillboardInfo.Head.Cmd,m_NAtagMCCACTGBillboardInfo.Head.SubCmd))] = m_NAtagMCCACTGBillboardInfo
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # AA 33 跨服充值排行活动玩家信息 #tagMCCACTGBillboardPlayerInfo
|
| | |
|
| | | class tagMCCACTGBillboardPlayerInfo(Structure):
|
| | | _pack_ = 1
|
| | | _fields_ = [
|
| | | ("Cmd", c_ubyte),
|
| | | ("SubCmd", c_ubyte),
|
| | | ("CTGRMBTotal", c_int), # 活动已累计充值RMB
|
| | | ("DabiaoAwardRecord", c_int), # 达标奖励记录,与达标奖励索引位或运算判断是否已领取
|
| | | ]
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Cmd = 0xAA
|
| | | self.SubCmd = 0x33
|
| | | 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 = 0xAA
|
| | | self.SubCmd = 0x33
|
| | | self.CTGRMBTotal = 0
|
| | | self.DabiaoAwardRecord = 0
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | return sizeof(tagMCCACTGBillboardPlayerInfo)
|
| | |
|
| | | def GetBuffer(self):
|
| | | return string_at(addressof(self), self.GetLength())
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''// AA 33 跨服充值排行活动玩家信息 //tagMCCACTGBillboardPlayerInfo:
|
| | | Cmd:%s,
|
| | | SubCmd:%s,
|
| | | CTGRMBTotal:%d,
|
| | | DabiaoAwardRecord:%d
|
| | | '''\
|
| | | %(
|
| | | self.Cmd,
|
| | | self.SubCmd,
|
| | | self.CTGRMBTotal,
|
| | | self.DabiaoAwardRecord
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagMCCACTGBillboardPlayerInfo=tagMCCACTGBillboardPlayerInfo()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCCACTGBillboardPlayerInfo.Cmd,m_NAtagMCCACTGBillboardPlayerInfo.SubCmd))] = m_NAtagMCCACTGBillboardPlayerInfo
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # AA 09 消费返利活动信息 #tagMCCostRebateInfo
|
| | |
|
| | | class tagMCCostRebateAwardItem(Structure):
|
| | |
| | | ("DWORD", "Weight", 0),
|
| | | ),
|
| | |
|
| | | "CrossActCTGBillboardDabiao":(
|
| | | ("DWORD", "TemplateID", 1),
|
| | | ("DWORD", "CTGNeed", 0),
|
| | | ("BYTE", "AwardIndex", 0),
|
| | | ("list", "AwardItemList", 0),
|
| | | ),
|
| | |
|
| | | "CrossActCTGBillboardOrder":(
|
| | | ("DWORD", "TemplateID", 1),
|
| | | ("WORD", "OrderA", 0),
|
| | | ("WORD", "OrderB", 0),
|
| | | ("DWORD", "CTGAtleast", 0),
|
| | | ("list", "AwardItemList", 0),
|
| | | ),
|
| | |
|
| | | "MysteryShop":(
|
| | | ("list", "LVRange", 0),
|
| | | ("DWORD", "GoodsID", 0),
|
| | |
| | | def GetIsBind(self): return self.IsBind # 是否绑定
|
| | | def GetWeight(self): return self.Weight # 权重 |
| | | |
| | | # 跨服充值排行模板达标奖励表 |
| | | class IPY_CrossActCTGBillboardDabiao(): |
| | | |
| | | def __init__(self): |
| | | self.TemplateID = 0
|
| | | self.CTGNeed = 0
|
| | | self.AwardIndex = 0
|
| | | self.AwardItemList = [] |
| | | return |
| | | |
| | | def GetTemplateID(self): return self.TemplateID # 模板ID
|
| | | def GetCTGNeed(self): return self.CTGNeed # 需充值RMB
|
| | | def GetAwardIndex(self): return self.AwardIndex # 奖励记录索引,从0开始,同个模板不可重复,不可变更
|
| | | def GetAwardItemList(self): return self.AwardItemList # 奖励物品列表[[物品ID,个数,是否拍品], ...] |
| | | |
| | | # 跨服充值排行模板名次奖励表 |
| | | class IPY_CrossActCTGBillboardOrder(): |
| | | |
| | | def __init__(self): |
| | | self.TemplateID = 0
|
| | | self.OrderA = 0
|
| | | self.OrderB = 0
|
| | | self.CTGAtleast = 0
|
| | | self.AwardItemList = [] |
| | | return |
| | | |
| | | def GetTemplateID(self): return self.TemplateID # 模板ID
|
| | | def GetOrderA(self): return self.OrderA # 名次A
|
| | | def GetOrderB(self): return self.OrderB # 至名次B
|
| | | def GetCTGAtleast(self): return self.CTGAtleast # 至少充值RMB
|
| | | def GetAwardItemList(self): return self.AwardItemList # 奖励物品列表[[物品ID,个数,是否拍品], ...] |
| | | |
| | | # 神秘商店表 |
| | | class IPY_MysteryShop(): |
| | | |
| | |
| | | self.ipyActLuckyTreasureLen = len(self.ipyActLuckyTreasureCache)
|
| | | self.ipyLuckyTreasureTemplateCache = self.__LoadFileData("LuckyTreasureTemplate", IPY_LuckyTreasureTemplate)
|
| | | self.ipyLuckyTreasureTemplateLen = len(self.ipyLuckyTreasureTemplateCache)
|
| | | self.ipyCrossActCTGBillboardDabiaoCache = self.__LoadFileData("CrossActCTGBillboardDabiao", IPY_CrossActCTGBillboardDabiao)
|
| | | self.ipyCrossActCTGBillboardDabiaoLen = len(self.ipyCrossActCTGBillboardDabiaoCache)
|
| | | self.ipyCrossActCTGBillboardOrderCache = self.__LoadFileData("CrossActCTGBillboardOrder", IPY_CrossActCTGBillboardOrder)
|
| | | self.ipyCrossActCTGBillboardOrderLen = len(self.ipyCrossActCTGBillboardOrderCache)
|
| | | self.ipyMysteryShopCache = self.__LoadFileData("MysteryShop", IPY_MysteryShop)
|
| | | self.ipyMysteryShopLen = len(self.ipyMysteryShopCache)
|
| | | self.ipyEquipPlaceIndexMapCache = self.__LoadFileData("EquipPlaceIndexMap", IPY_EquipPlaceIndexMap)
|
| | |
| | | def GetActLuckyTreasureByIndex(self, index): return self.ipyActLuckyTreasureCache[index]
|
| | | def GetLuckyTreasureTemplateCount(self): return self.ipyLuckyTreasureTemplateLen
|
| | | def GetLuckyTreasureTemplateByIndex(self, index): return self.ipyLuckyTreasureTemplateCache[index]
|
| | | def GetCrossActCTGBillboardDabiaoCount(self): return self.ipyCrossActCTGBillboardDabiaoLen
|
| | | def GetCrossActCTGBillboardDabiaoByIndex(self, index): return self.ipyCrossActCTGBillboardDabiaoCache[index]
|
| | | def GetCrossActCTGBillboardOrderCount(self): return self.ipyCrossActCTGBillboardOrderLen
|
| | | def GetCrossActCTGBillboardOrderByIndex(self, index): return self.ipyCrossActCTGBillboardOrderCache[index]
|
| | | def GetMysteryShopCount(self): return self.ipyMysteryShopLen
|
| | | def GetMysteryShopByIndex(self, index): return self.ipyMysteryShopCache[index]
|
| | | def GetEquipPlaceIndexMapCount(self): return self.ipyEquipPlaceIndexMapLen
|
| | |
| | | import PlayerFeastRedPacket
|
| | | import PlayerLuckyTreasure
|
| | | import Item_ResetAttrPoint
|
| | | import CrossActCTGBillboard
|
| | | import CrossRealmPlayer
|
| | | import ChNetSendPack
|
| | | import FamilyRobBoss
|
| | |
| | | #通知基础属性
|
| | | NotifyPlayerBasePoint(curPlayer)
|
| | |
|
| | | #跨服充值排行
|
| | | CrossActCTGBillboard.OnPlayerLogin(curPlayer)
|
| | | #消费返利
|
| | | PlayerCostRebate.OnPlayerLogin(curPlayer)
|
| | | #累计充值
|
| | |
| | | # 领取节日巡礼积分奖励
|
| | | elif rewardType == ChConfig.Def_RewardType_FeastWeekPartyPoint:
|
| | | PlayerFeastWeekParty.GetFeastWeekPartyPointAward(curPlayer, dataEx, dataExStr)
|
| | | # 领取跨服充值排行活动达标奖励
|
| | | elif rewardType == ChConfig.Def_RewardType_CACTGBillboardDabiao:
|
| | | CrossActCTGBillboard.GetDabiaoAward(curPlayer, dataEx)
|
| | | #缥缈奇遇领取
|
| | | elif rewardType == ChConfig.Def_RewardType_FairyAdventuresAward:
|
| | | PlayerFairyDomain.GetFairyAdventuresAward(curPlayer, dataEx, dataExStr)
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package Player.CrossActCTGBillboard
|
| | | #
|
| | | # @todo:跨服运营活动 - 充值排行
|
| | | # @author hxp
|
| | | # @date 2020-01-13
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 跨服运营活动 - 充值排行
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2020-01-13 17:00"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import ChConfig
|
| | | import ShareDefine
|
| | | import PlayerControl
|
| | | import NetPackCommon
|
| | | import PlayerBillboard
|
| | | import CrossRealmPlayer
|
| | | import ChPyNetSendPack
|
| | | import ItemControler
|
| | | import IPY_GameWorld
|
| | | import IpyGameDataPY
|
| | | import GameWorld
|
| | |
|
| | | def OnPlayerLogin(curPlayer):
|
| | | isReset = __CheckPlayerCrossActCTGBillboard(curPlayer)
|
| | | if not isReset:
|
| | | actInfo = CrossRealmPlayer.GetPlayerCrossActInfo(curPlayer, ShareDefine.CrossActName_CTGBillboard)
|
| | | # 活动中同步活动信息
|
| | | if actInfo.get(ShareDefine.ActKey_State):
|
| | | Sync_CrossActCTGBillboardInfo(curPlayer)
|
| | | Sync_CrossActCTGBillboardPlayerInfo(curPlayer)
|
| | | UpdateCTGRMBCrossBillboard(curPlayer, actInfo)
|
| | | return
|
| | |
|
| | | def RefreshCrossActCTGBillboardInfo():
|
| | | ## 收到GameServer同步的活动信息,刷新活动信息
|
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for index in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(index)
|
| | | if curPlayer.GetID() == 0:
|
| | | continue
|
| | | __CheckPlayerCrossActCTGBillboard(curPlayer)
|
| | | return
|
| | |
|
| | | def __CheckPlayerCrossActCTGBillboard(curPlayer):
|
| | | ## 检查玩家累计充值活动数据信息
|
| | | |
| | | playerID = curPlayer.GetPlayerID()
|
| | | |
| | | actInfo = CrossRealmPlayer.GetPlayerCrossActInfo(curPlayer, ShareDefine.CrossActName_CTGBillboard)
|
| | | cfgID = actInfo.get(ShareDefine.ActKey_CfgID, 0)
|
| | | actID = actInfo.get(ShareDefine.ActKey_ID, 0)
|
| | | state = actInfo.get(ShareDefine.ActKey_State, 0)
|
| | | dayIndex = actInfo.get(ShareDefine.ActKey_DayIndex, 0)
|
| | | templateID = actInfo.get(ShareDefine.ActKey_TemplateID, 0)
|
| | | |
| | | playerActID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CA_CTGBillboardID) # 玩家身上的活动ID
|
| | | playerTemplateID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CA_CTGBillboardTemplateID)
|
| | | |
| | | # 活动ID 相同的话不处理
|
| | | if actID == playerActID:
|
| | | GameWorld.DebugLog("跨服充值排行活动ID不变,不处理!cfgID=%s,dayIndex=%s,templateID=%s" % (cfgID, dayIndex, templateID), playerID)
|
| | | if state:
|
| | | if playerTemplateID != templateID and templateID:
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CA_CTGBillboardTemplateID, templateID)
|
| | | GameWorld.DebugLog(" 活动模板ID变更,更新玩家身上模板ID记录!playerTemplateID=%s,updTemplateID=%s" |
| | | % (playerTemplateID, templateID), playerID)
|
| | | Sync_CrossActCTGBillboardInfo(curPlayer)
|
| | | |
| | | return
|
| | | |
| | | GameWorld.DebugLog("跨服充值排行活动重置! cfgID=%s,actID=%s,playerActID=%s,state=%s" % (cfgID, actID, playerActID, state), playerID)
|
| | | |
| | | if not state:
|
| | | CrossRealmPlayer.NotifyCrossActEnd(curPlayer, ShareDefine.CrossActName_CTGBillboard)
|
| | | |
| | | if playerActID and playerTemplateID:
|
| | | __SendDabiaoAwardMail(curPlayer, playerTemplateID)
|
| | | |
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CA_CTGBillboardID, actID)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CA_CTGBillboardTemplateID, templateID)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CA_CTGBillboardRMB, 0)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CA_CTGBillboardAward, 0)
|
| | | |
| | | Sync_CrossActCTGBillboardInfo(curPlayer)
|
| | | Sync_CrossActCTGBillboardPlayerInfo(curPlayer)
|
| | | return True
|
| | |
|
| | | def __SendDabiaoAwardMail(curPlayer, playerTemplateID):
|
| | | ## 补发未领取的达标奖励
|
| | | |
| | | totalRMB = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CA_CTGBillboardRMB)
|
| | | if not totalRMB:
|
| | | return
|
| | | |
| | | ipyDataList = IpyGameDataPY.GetIpyGameDataList("CrossActCTGBillboardDabiao", playerTemplateID)
|
| | | if not ipyDataList:
|
| | | return
|
| | | |
| | | playerID = curPlayer.GetPlayerID()
|
| | | awardRecord = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CA_CTGBillboardAward)
|
| | | batchPlayerIDList, batchAddItemList, batchParamList = [], [], []
|
| | | for ipyData in ipyDataList:
|
| | | ctgNeed = ipyData.GetCTGNeed()
|
| | | awardIndex = ipyData.GetAwardIndex()
|
| | | if totalRMB < ctgNeed:
|
| | | continue
|
| | | if awardRecord & pow(2, awardIndex):
|
| | | continue
|
| | | batchPlayerIDList.append([playerID])
|
| | | batchAddItemList.append(ipyData.GetAwardItemList())
|
| | | batchParamList.append([ctgNeed])
|
| | | awardRecord = awardRecord | pow(2, awardIndex)
|
| | | |
| | | if not batchPlayerIDList:
|
| | | return
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CA_CTGBillboardAward, awardRecord)
|
| | | |
| | | GameWorld.DebugLog("补发跨服充值排行活动未领取达标奖励!", playerID)
|
| | | PlayerControl.SendMailBatch("CACTGBillboardDabiao", batchPlayerIDList, batchAddItemList, batchParamList)
|
| | | return
|
| | |
|
| | | def GetDabiaoAward(curPlayer, awardIndex):
|
| | | ## 手动领取达标奖励
|
| | | |
| | | actInfo = CrossRealmPlayer.GetPlayerCrossActInfo(curPlayer, ShareDefine.CrossActName_CTGBillboard)
|
| | | state = actInfo.get(ShareDefine.ActKey_State, 0)
|
| | | if not state:
|
| | | GameWorld.DebugLog("非活动中")
|
| | | return
|
| | | |
| | | totalRMB = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CA_CTGBillboardRMB)
|
| | | awardRecord = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CA_CTGBillboardAward)
|
| | | if awardRecord & pow(2, awardIndex):
|
| | | GameWorld.DebugLog("已领取过该奖励! awardIndex=%s" % awardIndex)
|
| | | return
|
| | | |
| | | playerTemplateID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CA_CTGBillboardTemplateID)
|
| | | ipyDataList = IpyGameDataPY.GetIpyGameDataList("CrossActCTGBillboardDabiao", playerTemplateID)
|
| | | if not ipyDataList:
|
| | | return
|
| | | |
| | | awardItemList = []
|
| | | for ipyData in ipyDataList:
|
| | | ctgNeed = ipyData.GetCTGNeed()
|
| | | if awardIndex == ipyData.GetAwardIndex():
|
| | | if totalRMB < ctgNeed:
|
| | | GameWorld.DebugLog("充值额度未达标,无法领取! awardIndex=%s,totalRMB=%s,ctgNeed=%s" |
| | | % (awardIndex, totalRMB, ctgNeed))
|
| | | return
|
| | | awardItemList = ipyData.GetAwardItemList()
|
| | | break
|
| | | |
| | | GameWorld.DebugLog("领取跨服充值活动达标奖励!awardIndex=%s,awardItemList=%s" % (awardIndex, awardItemList))
|
| | | if not awardItemList:
|
| | | return
|
| | | |
| | | if not ItemControler.CheckPackSpaceEnough(curPlayer, awardItemList):
|
| | | return
|
| | | |
| | | updAwardRecord = awardRecord | pow(2, awardIndex)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CA_CTGBillboardAward, updAwardRecord)
|
| | | Sync_CrossActCTGBillboardPlayerInfo(curPlayer)
|
| | | |
| | | for itemID, itemCount, isAuctionItem in awardItemList:
|
| | | ItemControler.GivePlayerItem(curPlayer, itemID, itemCount, isAuctionItem, [IPY_GameWorld.rptItem], |
| | | event=["CrossActCTGBillboard", False, {}])
|
| | | |
| | | return
|
| | |
|
| | | def AddCTGRMB(curPlayer, addRMB):
|
| | | ## 增加活动已累计充值RMB
|
| | | actInfo = CrossRealmPlayer.GetPlayerCrossActInfo(curPlayer, ShareDefine.CrossActName_CTGBillboard) |
| | | if not actInfo:
|
| | | return
|
| | | |
| | | if not actInfo.get(ShareDefine.ActKey_State):
|
| | | GameWorld.DebugLog("玩家区服ID跨服充值排行非活动中!playerServerID=%s" % GameWorld.GetPlayerServerID(curPlayer))
|
| | | return
|
| | | |
| | | totalRMB = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CA_CTGBillboardRMB) + addRMB
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_CA_CTGBillboardRMB, totalRMB)
|
| | | |
| | | GameWorld.DebugLog("跨服充值排行活动增加玩家累计充值RMB: addRMB=%s,totalRMB=%s" % (addRMB, totalRMB), curPlayer.GetPlayerID())
|
| | | Sync_CrossActCTGBillboardPlayerInfo(curPlayer)
|
| | | UpdateCTGRMBCrossBillboard(curPlayer, actInfo)
|
| | | return
|
| | |
|
| | | def UpdateCTGRMBCrossBillboard(curPlayer, actInfo):
|
| | | ## 更新跨服充值活动榜
|
| | | totalRMB = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CA_CTGBillboardRMB)
|
| | | if not totalRMB:
|
| | | return
|
| | | cfgID = actInfo.get(ShareDefine.ActKey_CfgID, 0)
|
| | | if not cfgID:
|
| | | return
|
| | | cmpValue = totalRMB
|
| | | PlayerBillboard.UpdatePlayerCrossBillboard(curPlayer, ShareDefine.Def_CBT_ActCTG, cfgID, cmpValue)
|
| | | return
|
| | |
|
| | | def Sync_CrossActCTGBillboardPlayerInfo(curPlayer):
|
| | | ## 通知活动玩家数据信息
|
| | | playerActInfo = ChPyNetSendPack.tagMCCACTGBillboardPlayerInfo()
|
| | | playerActInfo.CTGRMBTotal = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CA_CTGBillboardRMB)
|
| | | playerActInfo.DabiaoAwardRecord = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CA_CTGBillboardAward)
|
| | | NetPackCommon.SendFakePack(curPlayer, playerActInfo)
|
| | | return
|
| | |
|
| | | def Sync_CrossActCTGBillboardInfo(curPlayer):
|
| | | ## 通知活动信息
|
| | | |
| | | actInfo = CrossRealmPlayer.GetPlayerCrossActInfo(curPlayer, ShareDefine.CrossActName_CTGBillboard)
|
| | | if not actInfo:
|
| | | return
|
| | | |
| | | if not actInfo.get(ShareDefine.ActKey_State):
|
| | | return
|
| | | |
| | | ipyDataDict = actInfo.get(ShareDefine.ActKey_IpyDataInfo, {})
|
| | | if not ipyDataDict:
|
| | | return 0
|
| | | |
| | | templateIDList = ipyDataDict.get("TemplateIDList", [])
|
| | | if not templateIDList:
|
| | | return
|
| | | |
| | | actPack = ChPyNetSendPack.tagMCCACTGBillboardInfo()
|
| | | actPack.ServerIDRangeInfo = str(actInfo.get(ShareDefine.ActKey_ServerIDRangeList, []))
|
| | | actPack.ServerInfoLen = len(actPack.ServerIDRangeInfo)
|
| | | actPack.GroupValue1 = actInfo.get(ShareDefine.ActKey_CfgID, 0)
|
| | | actPack.StartDate = ipyDataDict.get("StartDate", "")
|
| | | actPack.EndtDate = ipyDataDict.get("EndDate", "")
|
| | | actPack.TemplateID = actInfo.get(ShareDefine.ActKey_TemplateID, 0)
|
| | | actPack.TempInfo = []
|
| | | for templateID in templateIDList:
|
| | | tempInfo = ChPyNetSendPack.tagMCCACTGBillboardTempInfo()
|
| | | |
| | | # 达标
|
| | | tempInfo.TemplateID = templateID
|
| | | tempInfo.DabiaoAwardInfo = []
|
| | | dabiaoIpyDataList = IpyGameDataPY.GetIpyGameDataList("CrossActCTGBillboardDabiao", templateID)
|
| | | if dabiaoIpyDataList:
|
| | | for dabiaoIpyData in dabiaoIpyDataList:
|
| | | dabiaoInfo = ChPyNetSendPack.tagMCCACTGBillboardDabiao()
|
| | | dabiaoInfo.NeedRMB = dabiaoIpyData.GetCTGNeed()
|
| | | dabiaoInfo.AwardIndex = dabiaoIpyData.GetAwardIndex()
|
| | | dabiaoInfo.AwardItemList = []
|
| | | for itemID, itemCount, isBind in dabiaoIpyData.GetAwardItemList():
|
| | | itemInfo = ChPyNetSendPack.tagMCCACTGBillboardAwardItem()
|
| | | itemInfo.ItemID = itemID
|
| | | itemInfo.ItemCount = itemCount
|
| | | itemInfo.IsBind = isBind
|
| | | dabiaoInfo.AwardItemList.append(itemInfo)
|
| | | dabiaoInfo.AwardItemCount = len(dabiaoInfo.AwardItemList)
|
| | | tempInfo.DabiaoAwardInfo.append(dabiaoInfo)
|
| | | tempInfo.DabiaoAwardCount = len(tempInfo.DabiaoAwardInfo)
|
| | | |
| | | # 排行
|
| | | tempInfo.OrderAwardInfo = []
|
| | | orderIpyDataList = IpyGameDataPY.GetIpyGameDataList("CrossActCTGBillboardOrder", templateID)
|
| | | if orderIpyDataList:
|
| | | for orderIpyData in orderIpyDataList:
|
| | | orderInfo = ChPyNetSendPack.tagMCCACTGBillboardOrder()
|
| | | orderInfo.OrderA = orderIpyData.GetOrderA()
|
| | | orderInfo.OrderB = orderIpyData.GetOrderB()
|
| | | orderInfo.NeedRMB = orderIpyData.GetCTGAtleast()
|
| | | orderInfo.AwardItemList = []
|
| | | for itemID, itemCount, isBind in orderIpyData.GetAwardItemList():
|
| | | itemInfo = ChPyNetSendPack.tagMCCACTGBillboardAwardItem()
|
| | | itemInfo.ItemID = itemID
|
| | | itemInfo.ItemCount = itemCount
|
| | | itemInfo.IsBind = isBind
|
| | | orderInfo.AwardItemList.append(itemInfo)
|
| | | orderInfo.AwardItemCount = len(orderInfo.AwardItemList)
|
| | | tempInfo.OrderAwardInfo.append(orderInfo)
|
| | | tempInfo.OrderAwardCount = len(tempInfo.OrderAwardInfo)
|
| | | |
| | | actPack.TempInfo.append(tempInfo)
|
| | | |
| | | actPack.TemplateCount = len(actPack.TempInfo)
|
| | | NetPackCommon.SendFakePack(curPlayer, actPack)
|
| | | return
|
| | |
| | | #"""Version = 2018-12-21 18:00"""
|
| | | #-------------------------------------------------------------------------------
|
| | | import GameWorld
|
| | | import PyGameData
|
| | | import ReadChConfig
|
| | | import PlayerControl
|
| | | import IpyGameDataPY
|
| | | import IPY_GameWorld
|
| | | import ChPyNetSendPack
|
| | | import NetPackCommon
|
| | | import ShareDefine
|
| | | import ChConfig
|
| | | import FBLogic
|
| | |
| | | if PlayerControl.GetCrossMapID(curPlayer):
|
| | | PlayerControl.SetCrossMapID(curPlayer, 0)
|
| | | return
|
| | |
|
| | | def GetPlayerCrossActInfo(curPlayer, actName):
|
| | | ## 获取跨服玩家对应的跨服活动信息
|
| | | actInfoDict = PyGameData.g_crossActInfoDict.get(actName, {})
|
| | | if not actInfoDict:
|
| | | return {}
|
| | | playerServerID = GameWorld.GetPlayerServerID(curPlayer)
|
| | | for actInfo in actInfoDict.values():
|
| | | if ShareDefine.ActKey_ServerIDRangeList not in actInfo:
|
| | | continue
|
| | | serverIDRangeList = actInfo[ShareDefine.ActKey_ServerIDRangeList]
|
| | | if not serverIDRangeList:
|
| | | # 全服开启
|
| | | return actInfo
|
| | | for serverIDA, serverIDB in serverIDRangeList:
|
| | | if serverIDA <= playerServerID <= serverIDB:
|
| | | return actInfo
|
| | | return {}
|
| | |
|
| | | def NotifyCrossActEnd(curPlayer, actName):
|
| | | '''通知跨服运营活动结束
|
| | | 防止跨服服务器与子服时间不一致导致可能出现活动实际已关闭
|
| | | 但是前端根据本服服务器时间判断还未关闭,可能引起玩家误以为活动未关闭而引发的一系列问题
|
| | | 前端跨服活动显隐规则:
|
| | | 显示:根据通知的活动包 且 时间>=活动开始日期 才显示
|
| | | 关闭:收到后端通知的活动结束包 或 时间>=活动结束日期 则直接关闭活动界面
|
| | | '''
|
| | | |
| | | clientPack = ChPyNetSendPack.tagGCCrossActEnd()
|
| | | clientPack.ActName = actName
|
| | | clientPack.ActNameLen = len(clientPack.ActName)
|
| | | NetPackCommon.SendFakePack(curPlayer, clientPack)
|
| | | return
|
| | |
|
| | |
| | | import ChConfig
|
| | | import PlayerControl
|
| | | import OpenServerCampaign
|
| | | import CrossRealmPlayer
|
| | | import GameFuncComm
|
| | | import EventReport
|
| | |
|
| | |
| | | sendMsg = "%s" % ({"Type":bType, "Type2":bType2, "ID":bID, "ID2":bID2, "Name1":bName, "Name2":bName2, "ExInfo":exInfo,
|
| | | "Value1":value1, "Value2":value2, "CmpValue":cmpValue, "CmpValue2":cmpValue2, "CmpValue3":cmpValue3})
|
| | | GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "UpdateBillboard", sendMsg, len(sendMsg))
|
| | | GameWorld.DebugLog("同步GameServer排行榜:bType=%s,%s" % (bType, sendMsg))
|
| | | GameWorld.DebugLog("同步GameServer排行榜:bType=%s,cmpValue=%s, %s" % (bType, cmpValue, sendMsg), bID)
|
| | | return
|
| | |
|
| | | def UpdatePlayerCrossBillboard(curPlayer, bType, groupValue1, cmpValue, cmpValue2=0, cmpValue3=0, value1=0, value2=0, |
| | | groupValue2=0):
|
| | | ## 更新玩家跨服排行榜
|
| | | |
| | | #if not cmpValue and not cmpValue2 and not cmpValue3:
|
| | | # return
|
| | | |
| | | #if not __CanPlayerBillboardComm(curPlayer):
|
| | | # return
|
| | | |
| | | playerJob = GetBillboardJob(curPlayer)
|
| | | playerID = curPlayer.GetID()
|
| | | playerName = CrossRealmPlayer.GetCrossPlayerName(curPlayer)
|
| | | playerOpInfo = GetBillboardOperateInfo(curPlayer)
|
| | | if bType in ShareDefine.BTValue1_OfficialRankList:
|
| | | value1 = curPlayer.GetOfficialRank()
|
| | | id2 = 0
|
| | | GameServer_UpdateCrossBillboard(bType, groupValue1, playerID, playerName, playerOpInfo, playerJob, value1, value2, |
| | | cmpValue, cmpValue2, cmpValue3, groupValue2, id2)
|
| | | return
|
| | |
|
| | | def GameServer_UpdateCrossBillboard(bType, groupValue1, dataID, name1, name2, type2, value1, value2, cmpValue, |
| | | cmpValue2=0, cmpValue3=0, groupValue2=0, id2=0):
|
| | | sendMsg = "%s" % ({"Type":bType, "GroupValue1":groupValue1, "Type2":type2, "ID":dataID, "ID2":id2, "Name1":name1, "Name2":name2,
|
| | | "Value1":value1, "Value2":value2, "CmpValue":cmpValue, "CmpValue2":cmpValue2, "CmpValue3":cmpValue3,
|
| | | "GroupValue2":groupValue2}) |
| | | GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "UpdateCrossBillboard", sendMsg, len(sendMsg))
|
| | | GameWorld.DebugLog("同步GameServer跨服排行榜:bType=%s,groupValue1=%s,groupValue2=%s,cmpValue=%s, %s" |
| | | % (bType, groupValue1, groupValue2, cmpValue, sendMsg), dataID)
|
| | | return
|
| | |
|
| | | def UpdatePlayerFPTotalBillboard(curPlayer, isForceUpdate=False, isCheckRule=True):
|
| | |
| | |
|
| | | g_bzzdRefreshNPCListDict = {} # 仙界秘境所需击杀的NPC队列 {lineID:[npcID, npcID, ...], ...}
|
| | |
|
| | | g_operationActionDict = {} # {actName:actInfo, ...}
|
| | | g_operationActionDict = {} # 本服运营活动信息 {actName:actInfo, ...}
|
| | | g_crossActInfoDict = {} # 跨服运营活动信息 {actName:actInfo, ...}
|
| | |
|
| | | g_npcKillerInfo = {} # NPC击杀者信息 {(lineID, objID, npcID):[killerDict, curTeam, hurtType, hurtID], ...}
|
| | |
|