526 【挑战】PVP群英榜-后端(本服群英榜;优化机器人表支持按功能加载不同的机器人;)
| | |
| | | dict Attr; //属性
|
| | | };
|
| | |
|
| | | //群英榜分区表
|
| | | struct QunyingCross
|
| | | {
|
| | | char _AppID; //AppID
|
| | | WORD _ZoneID; //分区ID
|
| | | DWORD CrossServerID; //跨服服务器ID
|
| | | list ServerIDList; //互通服务器ID列表
|
| | | BYTE SplitServerCnt; //按X个相邻服分割
|
| | | BYTE MatchServerCnt; //分割区服内X个服随机匹配一组
|
| | | };
|
| | |
|
| | | //跨服公会表
|
| | | struct FamilyCross
|
| | | {
|
| | |
| | | {
|
| | | DWORD _ID; //机器人ID,同玩家ID
|
| | | char RobotName;
|
| | | BYTE RealmLV; //指定官职
|
| | | DWORD TempNum; //功能模版
|
| | | DWORD TempValue1; //功能值1
|
| | | DWORD TempValue2; //功能值2
|
| | | char ViewCache; //机器人缓存
|
| | | };
|
| | |
| | | PacketSubCMD_1=0x09
|
| | | PacketCallFunc_1=OnArenaMatch
|
| | |
|
| | | ;群英榜
|
| | | [GameLogic_Qunying]
|
| | | ScriptName = Player\GameLogic_Qunying.py
|
| | | Writer = hxp
|
| | | Releaser = hxp
|
| | | RegType = 0
|
| | | RegisterPackCount = 1
|
| | |
|
| | | PacketCMD_1=0xB2
|
| | | PacketSubCMD_1=0x10
|
| | | PacketCallFunc_1=OnQunyingMatch
|
| | |
|
| | | ;古宝
|
| | | [PlayerGubao]
|
| | | ScriptName = Player\PlayerGubao.py
|
| | |
| | | Def_FBMapID_Tianzi = 30020 # 天子考验
|
| | | Def_FBMapID_Dingjunge = 30030 # 定军阁
|
| | |
|
| | | Def_FBMapID_Qunying = 32000 # 群英榜
|
| | |
|
| | | #线路未过关时免费的地图
|
| | | UnPassFreeMapIDList = [Def_FBMapID_Zhanchui, Def_FBMapID_Dingjunge]
|
| | | #按星级记录过关的地图
|
| | |
| | | ExclusiveBatAttrMapIDList = [Def_FBMapID_Dingjunge]
|
| | | #地图功能专用预设方案,如果没有配置的功能则默认使用主线方案
|
| | | MapAtkBatPresetTypeDict = {}
|
| | | MapDefBatPresetTypeDict = {Def_FBMapID_ArenaBattle:ShareDefine.BatPreset_ArenaDef}
|
| | | MapDefBatPresetTypeDict = {Def_FBMapID_ArenaBattle:ShareDefine.BatPreset_ArenaDef, |
| | | Def_FBMapID_Qunying:ShareDefine.BatPreset_QunyingDef,
|
| | | }
|
| | |
|
| | | #注册上传跨服服务器数据后直接进入跨服服务器的地图
|
| | | RegisterEnter_CrossServerMapIDList = []
|
| | |
| | | 'Zhanchui':[Def_FBMapID_Zhanchui],
|
| | | 'Tianzi':[Def_FBMapID_Tianzi],
|
| | | 'Dingjunge':[Def_FBMapID_Dingjunge],
|
| | | 'Qunying':[Def_FBMapID_Qunying],
|
| | | }
|
| | |
|
| | | #特殊副本ID, 由系统分配, 进入时候不验证IsMapCopyFull
|
| | |
| | | Def_PDict_ArenaScore = "ArenaScore" # 当前积分
|
| | | Def_PDict_ArenaWinCnt = "ArenaWinCnt" # 累计胜利次数
|
| | |
|
| | | #群英榜
|
| | | Def_PDict_QunyingRefreshCnt = "QunyingRefreshCnt" # 本周已刷新匹配次数
|
| | | Def_PDict_QunyingRecoverTime = "QunyingRecoverTime" # 上次恢复挑战令时间戳
|
| | | Def_PDict_QunyingRankHighest = "QunyingRankHighest" # 历史最高名次
|
| | | Def_PDict_QunyingRankSuccAward = "QunyingRankSuccAward" # 历史最高名次成就领奖记录
|
| | |
|
| | | #古宝
|
| | | Def_PDict_GubaoInfo = "Gubao_%s" # 古宝信息,参数(古宝ID),特殊效果层*100000 + 等级*100 + 星级
|
| | |
|
| | |
| | | ntMax
|
| | | ) = range(27)
|
| | |
|
| | | # 机器人功能模版
|
| | | (
|
| | | RobotTempNum_Comm, # 通用模版 0
|
| | | RobotTempNum_Qunying, # 群英榜专用 1
|
| | | ) = range(2)
|
| | |
|
| | | # 回合卡牌
|
| | | (
|
| | |
| | | Def_RewardType_LineupRecommend, # 阵容推荐奖励 4
|
| | | Def_RewardType_LVAward, # 玩家等级奖励5
|
| | | Def_RewardType_BeautyLVAward, # 红颜等级奖励 6
|
| | | Def_RewardType_7, # 每日任务修行点奖励7
|
| | | Def_RewardType_QunyingRankHighest, # 群英榜历史最高名次奖励 7
|
| | | Def_RewardType_FirstCharge, # 首充礼包奖励8
|
| | | Def_RewardType_OSACelebrationPointAward, # 开服庆典积分阶段奖励 9
|
| | | Def_RewardType_ActHeroAppearStarFreeAward, # 武将登场升星计划免费奖励 10
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # B2 10 群英榜匹配玩家 #tagCSQunyingMatch
|
| | |
|
| | | class tagCSQunyingMatch(Structure):
|
| | | _pack_ = 1
|
| | | _fields_ = [
|
| | | ("Cmd", c_ubyte),
|
| | | ("SubCmd", c_ubyte),
|
| | | ("IsRefresh", c_ubyte), # 0-打开界面无匹配数据时查询,1-强制刷新匹配列表
|
| | | ]
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Cmd = 0xB2
|
| | | self.SubCmd = 0x10
|
| | | 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 = 0xB2
|
| | | self.SubCmd = 0x10
|
| | | self.IsRefresh = 0
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | return sizeof(tagCSQunyingMatch)
|
| | |
|
| | | def GetBuffer(self):
|
| | | return string_at(addressof(self), self.GetLength())
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''// B2 10 群英榜匹配玩家 //tagCSQunyingMatch:
|
| | | Cmd:%s,
|
| | | SubCmd:%s,
|
| | | IsRefresh:%d
|
| | | '''\
|
| | | %(
|
| | | self.Cmd,
|
| | | self.SubCmd,
|
| | | self.IsRefresh
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagCSQunyingMatch=tagCSQunyingMatch()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCSQunyingMatch.Cmd,m_NAtagCSQunyingMatch.SubCmd))] = m_NAtagCSQunyingMatch
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # B2 07 重置加点 #tagCMResetAttrPoint
|
| | |
|
| | | class tagCMResetAttrPoint(Structure):
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # A9 24 群英榜匹配玩家列表 #tagSCQunyingMatchList
|
| | |
|
| | | class tagSCQunyingMatchInfo(Structure):
|
| | | Rank = 0 #(WORD Rank)//排名,从1开始
|
| | | PlayerID = 0 #(DWORD PlayerID)//目标玩家ID
|
| | | PlayerName = "" #(char PlayerName[33])
|
| | | LV = 0 #(WORD LV)// 玩家等级
|
| | | RealmLV = 0 #(WORD RealmLV)//境界,机器人读境界表取等级对应境界
|
| | | FightPower = 0 #(DWORD FightPower)//战力求余亿部分
|
| | | FightPowerEx = 0 #(DWORD FightPowerEx)//战力整除亿部分
|
| | | Face = 0 #(DWORD Face)//基本脸型
|
| | | FacePic = 0 #(DWORD FacePic)//头像框
|
| | | TitleID = 0 #(DWORD TitleID)//称号
|
| | | ModelMark = 0 #(DWORD ModelMark)//变形模型mark
|
| | | EquipShowSwitch = 0 #(DWORD EquipShowSwitch)//其他外观信息
|
| | | ServerID = 0 #(DWORD ServerID)
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | return
|
| | |
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | self.Rank,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | | self.PlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.PlayerName,_pos = CommFunc.ReadString(_lpData, _pos,33)
|
| | | self.LV,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | | self.RealmLV,_pos = CommFunc.ReadWORD(_lpData, _pos)
|
| | | self.FightPower,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.FightPowerEx,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.Face,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.FacePic,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.TitleID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.ModelMark,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.EquipShowSwitch,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | self.ServerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.Rank = 0
|
| | | self.PlayerID = 0
|
| | | self.PlayerName = ""
|
| | | self.LV = 0
|
| | | self.RealmLV = 0
|
| | | self.FightPower = 0
|
| | | self.FightPowerEx = 0
|
| | | self.Face = 0
|
| | | self.FacePic = 0
|
| | | self.TitleID = 0
|
| | | self.ModelMark = 0
|
| | | self.EquipShowSwitch = 0
|
| | | self.ServerID = 0
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | length = 0
|
| | | length += 2
|
| | | length += 4
|
| | | length += 33
|
| | | length += 2
|
| | | length += 2
|
| | | length += 4
|
| | | length += 4
|
| | | length += 4
|
| | | length += 4
|
| | | length += 4
|
| | | length += 4
|
| | | length += 4
|
| | | length += 4
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | data = ''
|
| | | data = CommFunc.WriteWORD(data, self.Rank)
|
| | | data = CommFunc.WriteDWORD(data, self.PlayerID)
|
| | | data = CommFunc.WriteString(data, 33, self.PlayerName)
|
| | | data = CommFunc.WriteWORD(data, self.LV)
|
| | | data = CommFunc.WriteWORD(data, self.RealmLV)
|
| | | data = CommFunc.WriteDWORD(data, self.FightPower)
|
| | | data = CommFunc.WriteDWORD(data, self.FightPowerEx)
|
| | | data = CommFunc.WriteDWORD(data, self.Face)
|
| | | data = CommFunc.WriteDWORD(data, self.FacePic)
|
| | | data = CommFunc.WriteDWORD(data, self.TitleID)
|
| | | data = CommFunc.WriteDWORD(data, self.ModelMark)
|
| | | data = CommFunc.WriteDWORD(data, self.EquipShowSwitch)
|
| | | data = CommFunc.WriteDWORD(data, self.ServerID)
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''
|
| | | Rank:%d,
|
| | | PlayerID:%d,
|
| | | PlayerName:%s,
|
| | | LV:%d,
|
| | | RealmLV:%d,
|
| | | FightPower:%d,
|
| | | FightPowerEx:%d,
|
| | | Face:%d,
|
| | | FacePic:%d,
|
| | | TitleID:%d,
|
| | | ModelMark:%d,
|
| | | EquipShowSwitch:%d,
|
| | | ServerID:%d
|
| | | '''\
|
| | | %(
|
| | | self.Rank,
|
| | | self.PlayerID,
|
| | | self.PlayerName,
|
| | | self.LV,
|
| | | self.RealmLV,
|
| | | self.FightPower,
|
| | | self.FightPowerEx,
|
| | | self.Face,
|
| | | self.FacePic,
|
| | | self.TitleID,
|
| | | self.ModelMark,
|
| | | self.EquipShowSwitch,
|
| | | self.ServerID
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | class tagSCQunyingMatchList(Structure):
|
| | | Head = tagHead()
|
| | | MatchCount = 0 #(BYTE MatchCount)
|
| | | MatchList = list() #(vector<tagSCQunyingMatchInfo> MatchList)// 匹配列表,从高分到低分
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Head.Cmd = 0xA9
|
| | | self.Head.SubCmd = 0x24
|
| | | return
|
| | |
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | _pos = self.Head.ReadData(_lpData, _pos)
|
| | | self.MatchCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | for i in range(self.MatchCount):
|
| | | temMatchList = tagSCQunyingMatchInfo()
|
| | | _pos = temMatchList.ReadData(_lpData, _pos)
|
| | | self.MatchList.append(temMatchList)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.Head = tagHead()
|
| | | self.Head.Clear()
|
| | | self.Head.Cmd = 0xA9
|
| | | self.Head.SubCmd = 0x24
|
| | | self.MatchCount = 0
|
| | | self.MatchList = list()
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | length = 0
|
| | | length += self.Head.GetLength()
|
| | | length += 1
|
| | | for i in range(self.MatchCount):
|
| | | length += self.MatchList[i].GetLength()
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | data = ''
|
| | | data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
|
| | | data = CommFunc.WriteBYTE(data, self.MatchCount)
|
| | | for i in range(self.MatchCount):
|
| | | data = CommFunc.WriteString(data, self.MatchList[i].GetLength(), self.MatchList[i].GetBuffer())
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''
|
| | | Head:%s,
|
| | | MatchCount:%d,
|
| | | MatchList:%s
|
| | | '''\
|
| | | %(
|
| | | self.Head.OutputString(),
|
| | | self.MatchCount,
|
| | | "..."
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagSCQunyingMatchList=tagSCQunyingMatchList()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagSCQunyingMatchList.Head.Cmd,m_NAtagSCQunyingMatchList.Head.SubCmd))] = m_NAtagSCQunyingMatchList
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # A9 25 群英榜玩家信息 #tagSCQunyingPlayerInfo
|
| | |
|
| | | class tagSCQunyingPlayerInfo(Structure):
|
| | | _pack_ = 1
|
| | | _fields_ = [
|
| | | ("Cmd", c_ubyte),
|
| | | ("SubCmd", c_ubyte),
|
| | | ("RefreshCnt", c_int), # 本周已刷新匹配次数
|
| | | ("LastRecoverTime", c_int), # 上次免费恢复挑战令时间戳,为0时可不用倒计时
|
| | | ("RankHighest", c_ushort), # 历史最高名次,第1名为最高
|
| | | ("RankSuccAward", c_int), # 历史最高名次成就领奖记录,按奖励记录索引位运算记录是否已领取
|
| | | ]
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Cmd = 0xA9
|
| | | self.SubCmd = 0x25
|
| | | 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 = 0xA9
|
| | | self.SubCmd = 0x25
|
| | | self.RefreshCnt = 0
|
| | | self.LastRecoverTime = 0
|
| | | self.RankHighest = 0
|
| | | self.RankSuccAward = 0
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | return sizeof(tagSCQunyingPlayerInfo)
|
| | |
|
| | | def GetBuffer(self):
|
| | | return string_at(addressof(self), self.GetLength())
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''// A9 25 群英榜玩家信息 //tagSCQunyingPlayerInfo:
|
| | | Cmd:%s,
|
| | | SubCmd:%s,
|
| | | RefreshCnt:%d,
|
| | | LastRecoverTime:%d,
|
| | | RankHighest:%d,
|
| | | RankSuccAward:%d
|
| | | '''\
|
| | | %(
|
| | | self.Cmd,
|
| | | self.SubCmd,
|
| | | self.RefreshCnt,
|
| | | self.LastRecoverTime,
|
| | | self.RankHighest,
|
| | | self.RankSuccAward
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagSCQunyingPlayerInfo=tagSCQunyingPlayerInfo()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagSCQunyingPlayerInfo.Cmd,m_NAtagSCQunyingPlayerInfo.SubCmd))] = m_NAtagSCQunyingPlayerInfo
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | # A9 21 角色改名结果 #tagSCRenameResult
|
| | |
|
| | | class tagSCRenameResult(Structure):
|
| | |
| | | import CommFunc
|
| | |
|
| | | import json
|
| | | import time
|
| | |
|
| | | class BillboardData():
|
| | | ## 榜单数据
|
| | |
| | | copyData.SetTime(self.GetTime())
|
| | | return copyData
|
| | |
|
| | | TempBillData = BillboardData()
|
| | |
|
| | | class Billboard():
|
| | | ## 某个排行榜类
|
| | |
|
| | |
| | | self.__billboardList = [] # [BillboardData, ...]
|
| | | self.__idIndexDict = {} # {id:index, ...}
|
| | | self.__idOrderDict = {} # {id:名次, ...}
|
| | | self.__orderRuleList = None # 指定排名所需值规则列表 [[order, needCmpValue], ...]
|
| | | self.__sortDelay = False # 是否需要延迟排序
|
| | | self.__orderRuleList = None # 指定排名所需值规则列表 [[order, needCmpValue], ...]
|
| | | |
| | | # 【层级模式】机器人填充数据模式,一般如果机器人数据量比较大的情况下实用该模式,如群英榜
|
| | | # 层级模式下,因为机器人数量一般比较大,比如1万,为了节约内存占用及遍历排序等效率,填充的机器人数据不插入实际的 __billboardList 里
|
| | | self.__orderRuleByLayer = False # 按固定层级模式,第1层即第1名,CmpValue直接使用名次值,方便排序用,由功能自行管理好CmpValue值
|
| | | self.__layerIDList = [] # 层级ID列表,顺序即排名,索引0为第1名,ID包含填充的机器人ID,初始的数据由功能按规则设置填充的机器人ID
|
| | | return
|
| | |
|
| | | def GetType(self): return self.__billboardType
|
| | |
| | | def SortData(self):
|
| | | GameWorld.DebugLog("榜单排序: billboardType=%s,groupValue1=%s,groupValue2=%s,dataCount=%s"
|
| | | % (self.__billboardType, self.__groupValue1, self.__groupValue2, len(self.__billboardList)))
|
| | | if self.__orderRuleByLayer:
|
| | | self.__billboardList.sort(key=lambda b: (-b.GetCmpValue(), -b.GetTime()), reverse=True)
|
| | | else:
|
| | | self.__billboardList.sort(key=lambda b: (b.GetCmpValue(), b.GetCmpValue2(), b.GetCmpValue3(), -b.GetTime()), reverse=True)
|
| | | self.__idOrderDict = {} # 排序后重置,下次查询时更新并缓存
|
| | | self.__idIndexDict = {}
|
| | | self.__sortDelay = False
|
| | | if self.__orderRuleByLayer:
|
| | | self.__fixAndFillLayer()
|
| | | return
|
| | |
|
| | | def SetSortDelay(self):
|
| | |
| | | if not self.__sortDelay:
|
| | | return
|
| | | self.SortData()
|
| | | return
|
| | | return True
|
| | |
|
| | | def AddNewBillboardData(self, dataID):
|
| | | newData = None
|
| | |
| | | billboardIndex += 1
|
| | | for order, billboardData in enumerate(self.__billboardList, 1):
|
| | | self.__idIndexDict[billboardData.GetID()] = order - 1
|
| | | # 按层级固定排位的
|
| | | elif self.__orderRuleByLayer:
|
| | | if not self.SortDelayDo():
|
| | | self.__fixAndFillLayer()
|
| | | else:
|
| | | for order, billboardData in enumerate(self.__billboardList, 1):
|
| | | self.__idOrderDict[billboardData.GetID()] = order
|
| | | self.__idIndexDict[billboardData.GetID()] = order - 1
|
| | | return self.__idOrderDict
|
| | |
|
| | | def IsOrderRuleByLayer(self): return self.__orderRuleByLayer
|
| | | def SetOrderRuleByLayer(self, layerRobotIDList):
|
| | | '''设置排名规则为层级模式,即一个名次一个坑位层级,该模式支持机器人填充数据
|
| | | 该模式下 CmpValue 固定为 MaxCount - 名次 + 1
|
| | | @param layerRobotIDList: 填充的机器人ID排名列表
|
| | | '''
|
| | | self.__orderRuleByLayer = True
|
| | | self.__layerIDList = layerRobotIDList
|
| | | self.SortData() # 强制排序处理
|
| | | return
|
| | | def SetLayerIDList(self, layerIDList): self.__layerIDList = layerIDList
|
| | | def GetLayerIDList(self): return self.__layerIDList
|
| | | def __fixAndFillLayer(self):
|
| | | ## 检查修正并填充满最终层级ID顺序
|
| | | maxCount = self.GetMaxCount()
|
| | | layerIDCnt = len(self.__layerIDList)
|
| | | if layerIDCnt < maxCount:
|
| | | self.__layerIDList.extend([0]*(maxCount-layerIDCnt)) # 先用0填充,确保长度一致
|
| | | |
| | | # 先检查修正真实榜单数据的排名值,确保唯一
|
| | | orderIDDict = {}
|
| | | for index, billboardData in enumerate(self.__billboardList):
|
| | | dataID = billboardData.GetID()
|
| | | order = billboardData.GetCmpValue()
|
| | | if order > maxCount:
|
| | | # 超过的默认不上榜,后面的数据不再处理,外层的数据使用替换的模式,故理论上不会有多余的数据,这里暂做个防范
|
| | | break
|
| | | if order <= 0:
|
| | | # 没有名次数据的也不上榜,但先跳过继续处理后面的数据
|
| | | continue
|
| | | |
| | | while 1 <= order <= maxCount:
|
| | | if order not in orderIDDict:
|
| | | orderIDDict[order] = dataID
|
| | | self.__idOrderDict[dataID] = order
|
| | | self.__idIndexDict[dataID] = index
|
| | | break
|
| | | # 重复的数据修正层级比较值,确保唯一
|
| | | order += 1
|
| | | billboardData.SetCmpValue(order)
|
| | | |
| | | for index, layerID in enumerate(self.__layerIDList):
|
| | | order = index + 1
|
| | | dataID = layerID
|
| | | if order in orderIDDict:
|
| | | dataID = orderIDDict[order]
|
| | | self.__layerIDList[index] = dataID
|
| | | |
| | | return
|
| | | |
| | | def SetOrderRuleList(self, orderRuleList):
|
| | | ## 排名所需值规则列表
|
| | | # @param orderRuleList: 排名所需值规则列表 [[order, needCmpValue], ...]
|
| | |
| | | GameWorld.DebugAnswer(curPlayer, "输出排行榜数据: Billboard p 类型 [分组值1 值2 从x名 到x名]")
|
| | | GameWorld.DebugAnswer(curPlayer, "注:如果没有特殊说明,本服榜单分组值均为0,跨服榜单分组值1为分区ID,分组2为0")
|
| | |
|
| | | for billboardType in ShareDefine.BillboardTypeList:
|
| | | for billboardType in ShareDefine.BillboardTypeAllList:
|
| | | bName = ShareDefine.BillboardNameDict.get(billboardType, billboardType)
|
| | | GameWorld.DebugAnswer(curPlayer, "(%s) %s" % (billboardType, bName))
|
| | |
|
| | |
| | | billboardObj = billboardMgr.GetBillboard(billboardType, groupValue1, groupValue2)
|
| | | curDataCount = billboardObj.GetCount()
|
| | | maxDataCount = billboardObj.GetMaxCount()
|
| | | |
| | | isLayerMode = billboardObj.IsOrderRuleByLayer()
|
| | | if isLayerMode:
|
| | | cmpValue1 = min(cmpValue1, maxDataCount)
|
| | | count = min(count, maxDataCount - curDataCount)
|
| | | FakeName = GameWorld.GbkToCode("主公")
|
| | |
|
| | |
| | | name1 = dataPlayerName
|
| | | cmpValue = dataCmpValue1
|
| | | cmpValue2 = dataCmpValue2
|
| | | if isLayerMode:
|
| | | PlayerBillboard.UpdateBillboardLayer(dataID, billboardType, cmpValue, groupValue1, False)
|
| | | else:
|
| | | PlayerBillboard.UpdateBillboard(billboardType, groupValue1, dataID, name1, name2, type2, value1, value2,
|
| | | cmpValue, cmpValue2, cmpValue3, groupValue2, id2, False,
|
| | | value3=value3, value4=value4, value5=value5)
|
| New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package GM.Commands.Qunying
|
| | | #
|
| | | # @todo:群英榜
|
| | | # @author hxp
|
| | | # @date 2026-03-11
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 群英榜
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2026-03-11 19:00"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import GameWorld
|
| | | import ShareDefine
|
| | | import GameLogic_Qunying
|
| | | import PlayerBillboard
|
| | | import PlayerControl
|
| | | import DBDataMgr
|
| | | import ChConfig
|
| | |
|
| | | def OnExec(curPlayer, msgList):
|
| | | if not msgList:
|
| | | GameWorld.DebugAnswer(curPlayer, "重置群英数据: Qunying 0")
|
| | | GameWorld.DebugAnswer(curPlayer, "设置所在名次: Qunying 名次")
|
| | | GameWorld.DebugAnswer(curPlayer, "设置历史最高: Qunying h 名次 [重置奖励]")
|
| | | GameWorld.DebugAnswer(curPlayer, "设置刷新次数: Qunying r 次数")
|
| | | GameWorld.DebugAnswer(curPlayer, "输出名次数据: Qunying p [从x名开始 数量 ]")
|
| | | return
|
| | | |
| | | playerID = curPlayer.GetPlayerID()
|
| | | |
| | | value1 = msgList[0]
|
| | | if value1 == "p":
|
| | | billboardMgr = DBDataMgr.GetBillboardMgr()
|
| | | billBoard = billboardMgr.GetBillboard(ShareDefine.Def_BT_Qunying)
|
| | | if not billBoard:
|
| | | return
|
| | | billBoard.SortDelayDo()
|
| | | layerIDList = billBoard.GetLayerIDList()
|
| | | fromRank = max(1, msgList[1] if len(msgList) > 1 else 1)
|
| | | dataCnt = min(msgList[2] if len(msgList) > 2 else 10, 20)
|
| | | toRank = min(len(layerIDList), fromRank + dataCnt)
|
| | | GameWorld.DebugAnswer(curPlayer, "榜单总数据:%s/%s,idCnt=%s" % (billBoard.GetCount(), billBoard.GetMaxCount(), len(layerIDList)))
|
| | | for rank in range(fromRank, toRank + 1):
|
| | | dataID = layerIDList[rank - 1]
|
| | | GameWorld.DebugAnswer(curPlayer, "名次%s, ID:%s" % (rank, dataID))
|
| | | return
|
| | | |
| | | if value1 <= 0:
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_QunyingRefreshCnt, 0)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_QunyingRankHighest, 0)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_QunyingRankSuccAward, 0)
|
| | | GameWorld.DebugAnswer(curPlayer, "重置成功!")
|
| | | |
| | | elif value1 == "h":
|
| | | rankHighest = msgList[1] if len(msgList) > 1 else 0
|
| | | resetAward = msgList[2] if len(msgList) > 2 else 0
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_QunyingRankHighest, rankHighest)
|
| | | if resetAward:
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_QunyingRankSuccAward, 0)
|
| | | GameWorld.DebugAnswer(curPlayer, "设置历史最高: %s" % rankHighest)
|
| | | |
| | | elif value1 == "r":
|
| | | refreshCnt = msgList[1] if len(msgList) > 1 else 0
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_QunyingRefreshCnt, refreshCnt)
|
| | | GameWorld.DebugAnswer(curPlayer, "设置刷新次数: %s" % refreshCnt)
|
| | | |
| | | elif value1 > 0:
|
| | | cmpValue = value1
|
| | | if PlayerBillboard.UpdateBillboardLayer(playerID, ShareDefine.Def_BT_Qunying, cmpValue):
|
| | | GameWorld.DebugAnswer(curPlayer, "设置所在名次成功: %s" % cmpValue)
|
| | | else:
|
| | | GameWorld.DebugAnswer(curPlayer, "设置所在名次只能为1~最大名次")
|
| | | return
|
| | | |
| | | GameLogic_Qunying.Sync_QunyingInfo(curPlayer)
|
| | | return
|
| | |
| | | PlayerControl.PlayerLeaveFB(curPlayer)
|
| | | return
|
| | |
|
| | | ## 副本每周逻辑
|
| | | # @param tick 当前时间
|
| | | # @return None or False
|
| | | # @remarks 函数详细说明.
|
| | | def OnWeek(tick):
|
| | | do_FBLogic_ID = __GetFBLogic_MapID(GameWorld.GetMap().GetMapID())
|
| | | |
| | | callFunc = GameWorld.GetExecFunc(FBProcess, "GameLogic_%s.%s" % (do_FBLogic_ID, "OnWeek"))
|
| | | |
| | | if callFunc == None:
|
| | | return False
|
| | | |
| | | #执行副本逻辑
|
| | | callFunc(tick)
|
| | | def OnWeek():
|
| | | for key, mapIDList in ChConfig.Def_FB_MapID.items():
|
| | | if not mapIDList:
|
| | | continue
|
| | | callFunc = GameWorld.GetExecFunc(FBProcess, "GameLogic_%s.%s" % (key, "OnWeek"))
|
| | | if callFunc:
|
| | | callFunc()
|
| | | return
|
| | |
|
| | | ## 副本每日逻辑
|
| | | # @param tick 当前时间
|
| | | # @return None or False
|
| | | # @remarks 函数详细说明.
|
| | | def OnDay(tick):
|
| | | do_FBLogic_ID = __GetFBLogic_MapID(GameWorld.GetMap().GetMapID())
|
| | | def OnDay():
|
| | | for key, mapIDList in ChConfig.Def_FB_MapID.items():
|
| | | if not mapIDList:
|
| | | continue
|
| | | callFunc = GameWorld.GetExecFunc(FBProcess, "GameLogic_%s.%s" % (key, "OnDay"))
|
| | | if callFunc:
|
| | | callFunc()
|
| | | return
|
| | |
|
| | | callFunc = GameWorld.GetExecFunc(FBProcess, "GameLogic_%s.%s" % (do_FBLogic_ID, "OnDay"))
|
| | | |
| | | if callFunc == None:
|
| | | #GameWorld.Log("副本逻辑不可使用 GameLogic_%d"%(mapID))
|
| | | return False
|
| | | |
| | | #执行副本逻辑
|
| | | callFunc(tick)
|
| | | ## 副本每周逻辑-玩家, 不管玩家是否在该副本地图中都会触发
|
| | | def OnFBPlayerOnWeek(curPlayer, onWeekType): |
| | | for key, mapIDList in ChConfig.Def_FB_MapID.items():
|
| | | if not mapIDList:
|
| | | continue
|
| | | callFunc = GameWorld.GetExecFunc(FBProcess, "GameLogic_%s.%s" % (key, "OnFBPlayerOnWeek"))
|
| | | if callFunc:
|
| | | callFunc(curPlayer)
|
| | | return
|
| | |
|
| | | ## 副本每日逻辑-玩家, 不管玩家是否在该副本地图中都会触发
|
| | |
| | | return True
|
| | |
|
| | | def FBOnWeek(curPlayer, onWeekType):
|
| | | if onWeekType != ShareDefine.Def_OnEventType:
|
| | | return
|
| | | FBLogic.OnFBPlayerOnWeek(curPlayer, onWeekType)
|
| | | return
|
| | |
|
| | | def FBOnDay(curPlayer, onDayType):
|
| New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package GameWorldLogic.FBProcess.GameLogic_Qunying
|
| | | #
|
| | | # @todo:群英榜
|
| | | # @author hxp
|
| | | # @date 2026-03-11
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 群英榜
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2026-03-11 19:00"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import DBDataMgr
|
| | | import GameWorld
|
| | | import TurnAttack
|
| | | import ShareDefine
|
| | | import PlayerControl
|
| | | import IpyGameDataPY
|
| | | import PlayerBillboard
|
| | | import PlayerViewCache
|
| | | import ChPyNetSendPack
|
| | | import NetPackCommon
|
| | | import ItemControler
|
| | | import GameFuncComm
|
| | | import PyGameData
|
| | | import FBCommon
|
| | | import ChConfig
|
| | |
|
| | | import random
|
| | | import time
|
| | |
|
| | | # 记录攻击类型
|
| | | RecAtkType_Atk = 1 # 发起攻击
|
| | | RecAtkType_Def = 2 # 被攻击的
|
| | |
|
| | | def GetRecAtkType(recData): return recData.GetValue2() # 攻击类型 1-发起攻击的,2-被攻击的
|
| | | def SetRecAtkType(recData, atkType): return recData.SetValue2(atkType)
|
| | | def GetRecTagPlayerID(recData): return recData.GetValue3() # 相对攻击类型的目标玩家ID
|
| | | def SetRecTagPlayerID(recData, tagPlayerID): return recData.SetValue3(tagPlayerID)
|
| | | def GetRecIsWin(recData): return recData.GetValue4() # 是否获胜 1-获胜;2-失败
|
| | | def SetRecIsWin(recData, isWin): return recData.SetValue4(1 if isWin else 0)
|
| | | def GetRecFace(recData): return recData.GetValue5() # 目标头像
|
| | | def SetRecFace(recData, face): return recData.SetValue5(face)
|
| | | def GetRecFacePic(recData): return recData.GetValue6()
|
| | | def SetRecFacePic(recData, facePic): return recData.SetValue6(facePic)
|
| | | def GetRecRealmLV(recData): return recData.GetValue7()
|
| | | def SetRecRealmLV(recData, realmLV): return recData.SetValue7(realmLV)
|
| | | def GetRecLV(recData): return recData.GetValue8()
|
| | | def SetRecLV(recData, tagLV): return recData.SetValue8(tagLV)
|
| | | #SetUserData 名字、自己名次、对方名次
|
| | |
|
| | | def OnWeek():
|
| | | serverDay = DBDataMgr.GetEventTrigMgr().GetValue(ShareDefine.Def_ServerDay) + 1
|
| | | serverDayNeed = IpyGameDataPY.GetFuncCfg("QunyingSet", 1)
|
| | | if serverDayNeed and serverDay < serverDayNeed:
|
| | | GameWorld.DebugLog("开服天不足本周不重置群英榜! serverDay=%s < %s" % (serverDay, serverDayNeed))
|
| | | return
|
| | | DoQunyingReset()
|
| | | return
|
| | |
|
| | | def OnDay():
|
| | | billboardAwardDict = IpyGameDataPY.GetFuncEvalCfg("QunyingAward", 1, {})
|
| | | PlayerBillboard.DoGiveBillboardAwardByMail(ShareDefine.Def_BT_Qunying, "QunyingDay", billboardAwardDict, "QunyingDay", isClearData=False)
|
| | | return
|
| | |
|
| | | def OnServerStart():
|
| | | __fillRobot()
|
| | | return
|
| | |
|
| | | def DoQunyingReset():
|
| | | ''' 赛季重置
|
| | | '''
|
| | | GameWorld.Log("=============== 重置群英榜 ===============")
|
| | | |
| | | PyGameData.g_qunyingPlayerMatchDict = {}
|
| | | |
| | | # 结算上赛季排行奖励
|
| | | billboardAwardDict = IpyGameDataPY.GetFuncEvalCfg("QunyingAward", 2, {})
|
| | | PlayerBillboard.DoGiveBillboardAwardByMail(ShareDefine.Def_BT_Qunying, "QunyingWeek", billboardAwardDict, "QunyingWeek", isClearData=False)
|
| | | |
| | | # 重置排行榜
|
| | | DBDataMgr.GetBillboardMgr().RemoveBillboard(ShareDefine.Def_BT_Qunying)
|
| | | __fillRobot()
|
| | | |
| | | GameWorld.Log("==========================================")
|
| | | return True
|
| | |
|
| | | def __fillRobot():
|
| | | ## 填充满机器人
|
| | | billboardMgr = DBDataMgr.GetBillboardMgr()
|
| | | billBoard = billboardMgr.GetBillboard(ShareDefine.Def_BT_Qunying)
|
| | | maxCount = billBoard.GetMaxCount() # 机器人填充数默认使用榜单最大数
|
| | | |
| | | robotFPSortList = PlayerViewCache.GetRobotFightPowerSortList(ChConfig.RobotTempNum_Qunying)
|
| | | robotDict = {} # {(rankA, rankB):[robotID], ...}
|
| | | for _, robotID in robotFPSortList:
|
| | | robotIpyData = IpyGameDataPY.GetIpyGameData("Robot", robotID)
|
| | | if not robotIpyData:
|
| | | continue
|
| | | tempValue1 = robotIpyData.GetTempValue1()
|
| | | tempValue2 = robotIpyData.GetTempValue2()
|
| | | rankKey = (tempValue1, tempValue2)
|
| | | if rankKey not in robotDict:
|
| | | robotDict[rankKey] = []
|
| | | robotList = robotDict[rankKey]
|
| | | robotList.append(robotIpyData.GetID())
|
| | | |
| | | layerRobotIDList = []
|
| | | robotKeyList = robotDict.keys()
|
| | | robotKeyList.sort() # 按名次排序处理
|
| | | for robotKey in robotKeyList:
|
| | | rankA, rankB = robotKey
|
| | | robotIDList = robotDict[robotKey]
|
| | | random.shuffle(robotIDList)
|
| | | robotCnt = len(robotIDList)
|
| | | needRobotCnt = rankB - rankA + 1
|
| | | for _ in range(needRobotCnt / robotCnt):
|
| | | layerRobotIDList += robotIDList
|
| | | for index in range(needRobotCnt % robotCnt):
|
| | | layerRobotIDList.append(robotIDList[index])
|
| | | layerRobotIDList = layerRobotIDList[:maxCount]
|
| | | GameWorld.DebugLog("填充群英榜机器人: maxCount=%s,fillRobotIDLen=%s" % (maxCount, len(layerRobotIDList)))
|
| | | billBoard.SetOrderRuleByLayer(layerRobotIDList)
|
| | | return
|
| | |
|
| | | ## ------------------------------------------------------------------------------------------------
|
| | |
|
| | | def DoQunyingOpen(curPlayer):
|
| | | storeMax = IpyGameDataPY.GetFuncCfg("QunyingChallenge", 1)
|
| | | PlayerControl.GiveMoney(curPlayer, ShareDefine.TYPE_Price_QunyingTicket, storeMax, "QunyingOpen")
|
| | | Sync_QunyingInfo(curPlayer) # 开启功能
|
| | | return
|
| | |
|
| | | def OnFBPlayerOnWeek(curPlayer):
|
| | | if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Qunying):
|
| | | return
|
| | | serverDay = DBDataMgr.GetEventTrigMgr().GetValue(ShareDefine.Def_ServerDay) + 1
|
| | | serverDayNeed = IpyGameDataPY.GetFuncCfg("QunyingSet", 1)
|
| | | # 玩家重置有个问题,玩家的过周并不一定是周一触发,具体看玩家什么时候登录
|
| | | # 那么可能存在周二玩家才登录,然后满足了重置条件,导致触发了玩家个人的赛季重置
|
| | | # 目前只有刷新次数需要重置,暂时不考虑这个问题,这种情况一般只有新服才可能出现
|
| | | # 【注】如之后有需要重置比较严谨的数据,则需要按赛季ID对比不一样才能重置
|
| | | if serverDayNeed and serverDay < serverDayNeed:
|
| | | GameWorld.DebugLog("开服天不足本周不重置玩家群英榜! serverDay=%s < %s" % (serverDay, serverDayNeed), curPlayer.GetPlayerID())
|
| | | return
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_QunyingRefreshCnt, 0)
|
| | | Sync_QunyingInfo(curPlayer) # 赛季重置
|
| | | return
|
| | |
|
| | | def OnFBPlayerOnLogin(curPlayer):
|
| | | if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Qunying):
|
| | | return
|
| | | Sync_QunyingInfo(curPlayer) # 登录
|
| | | return
|
| | |
|
| | | def __checkAtkQunyingPlayer(curPlayer, tagID, tagRank):
|
| | | '''检查可否攻击目标
|
| | | '''
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | if not tagID or playerID == tagID:
|
| | | return
|
| | | |
| | | matchRankList = PyGameData.g_qunyingPlayerMatchDict.get(playerID, [])
|
| | | if tagRank not in matchRankList:
|
| | | GameWorld.DebugLog("群英榜不可攻击不在匹配列表里的目标名次! tagID=%s not in matchRankList=%s" % (tagID, matchRankList), playerID)
|
| | | return
|
| | | |
| | | # 验证名次是否还与前端的一致
|
| | | billboardMgr = DBDataMgr.GetBillboardMgr()
|
| | | billBoard = billboardMgr.GetBillboard(ShareDefine.Def_BT_Qunying)
|
| | | if not billBoard:
|
| | | return
|
| | | layerIDList = billBoard.GetLayerIDList()
|
| | | |
| | | tagIndex = tagRank - 1
|
| | | tagIDNow = 0 |
| | | if 0 <= tagIndex < len(layerIDList):
|
| | | tagIDNow = layerIDList[tagIndex]
|
| | | if tagID != tagIDNow:
|
| | | GameWorld.DebugLog("群英榜攻击时目标名次玩家ID不一致! tagRank=%s,tagID=%s != tagIDNow=%s" % (tagRank, tagID, tagIDNow), playerID)
|
| | | PlayerControl.NotifyCode(curPlayer, "QunyingTagRankIDErr") # 目标玩家名次已改变
|
| | | DoQunyingMatchRefresh(curPlayer, True, isSys=True)
|
| | | return
|
| | | |
| | | return True
|
| | |
|
| | | def OnTurnFightRequest(curPlayer, mapID, funcLineID, tagType, tagID, valueList):
|
| | | ## 回合战斗请求 |
| | | |
| | | if not valueList:
|
| | | return
|
| | | |
| | | tagRank = valueList[0] # 目标名次
|
| | | quickCnt = valueList[1] if len(valueList) > 1 else 0 # 速战次数
|
| | | |
| | | # 速战
|
| | | if quickCnt > 0:
|
| | | __doQuickFight(curPlayer, mapID, tagID, quickCnt)
|
| | | return
|
| | | |
| | | if not __checkAtkQunyingPlayer(curPlayer, tagID, tagRank):
|
| | | return
|
| | | |
| | | if not PlayerControl.HaveMoney(curPlayer, ShareDefine.TYPE_Price_QunyingTicket, 1):
|
| | | return
|
| | | |
| | | return True, funcLineID
|
| | |
|
| | | def __doQuickFight(curPlayer, mapID, tagID, quickCnt):
|
| | | '''执行速战,必胜、只给固定战斗奖励,名次不变
|
| | | '''
|
| | | GameWorld.DebugLog("群英榜速战: tagID=%s,quickCnt=%s" % (tagID, quickCnt))
|
| | | if quickCnt <= 0:
|
| | | return
|
| | | |
| | | if not PlayerControl.PayMoney(curPlayer, ShareDefine.TYPE_Price_QunyingTicket, quickCnt, "Qunying"):
|
| | | return
|
| | | |
| | | awardItemDict = {}
|
| | | for item in IpyGameDataPY.GetFuncEvalCfg("QunyingChallenge", 3):
|
| | | itemID, itemCount = item[:2]
|
| | | awardItemDict[itemID] = awardItemDict.get(itemID, 0) + itemCount * quickCnt
|
| | | awardItemList = [[itemID, itemCount] for itemID, itemCount in awardItemDict.items()]
|
| | | |
| | | ItemControler.GivePlayerItemOrMail(curPlayer, awardItemList, event=["Qunying", False, {}], isNotifyAward=False)
|
| | | |
| | | lineID = 0
|
| | | isPass = 1
|
| | | jsonItemList = []
|
| | | for itemInfo in awardItemList:
|
| | | itemDict = {"ItemID":itemInfo[0], "Count":itemInfo[1]}
|
| | | jsonItemList.append(itemDict)
|
| | | overDict = {FBCommon.Over_itemInfo:jsonItemList, FBCommon.Over_isSweep:1, "tagID":tagID, "quickCnt":quickCnt}
|
| | | FBCommon.NotifyFBOver(curPlayer, mapID, lineID, isPass, overDict)
|
| | | return
|
| | |
|
| | | def OnTurnFightAward(curPlayer, guid, mapID, funcLineID, winFaction, statMsg, dateStr, reqData, awardDict):
|
| | | ## 回合战斗结算奖励
|
| | | if not curPlayer:
|
| | | return
|
| | | |
| | | playerID = curPlayer.GetPlayerID()
|
| | | tagPlayerID = reqData[1]
|
| | | valueList = reqData[2]
|
| | | tagRank = valueList[0] # 目标名次
|
| | | isWin = winFaction == ChConfig.Def_FactionA
|
| | | |
| | | GameWorld.DebugLog("结算群英榜战斗! isWin=%s,tagPlayerID=%s,tagRank=%s" % (isWin, tagPlayerID, tagRank), playerID)
|
| | | canAtkRet = __checkAtkQunyingPlayer(curPlayer, tagPlayerID, tagRank)
|
| | | if not canAtkRet:
|
| | | return
|
| | | |
| | | billboardMgr = DBDataMgr.GetBillboardMgr()
|
| | | billBoard = billboardMgr.GetBillboard(ShareDefine.Def_BT_Qunying)
|
| | | idRankDict = billBoard.GetIDOrderDict()
|
| | | curRank = idRankDict.get(playerID, 0)
|
| | | |
| | | updRank = 0
|
| | | awardItemList = []
|
| | | if isWin:
|
| | | # 胜利时固定奖励
|
| | | awardItemList = IpyGameDataPY.GetFuncEvalCfg("QunyingChallenge", 3)
|
| | | cmpValue = tagRank
|
| | | if PlayerBillboard.UpdateBillboardLayer(playerID, ShareDefine.Def_BT_Qunying, cmpValue):
|
| | | updRank = tagRank
|
| | | else:
|
| | | GameWorld.DebugLog(" 更新榜单失败", playerID)
|
| | | |
| | | awardDict.update({FBCommon.Over_itemInfo:FBCommon.GetJsonItemList(awardItemList), "tagPlayerID":tagPlayerID, "updRank":updRank, "curRank":curRank})
|
| | | |
| | | GameWorld.DebugLog(" tagPlayerID=%s,isWin=%s,awardItemList=%s" % (tagPlayerID, isWin, awardItemList), playerID)
|
| | | if not PlayerControl.PayMoney(curPlayer, ShareDefine.TYPE_Price_QunyingTicket, 1):
|
| | | return
|
| | | |
| | | if isWin:
|
| | | ItemControler.GivePlayerItemOrMail(curPlayer, awardItemList, event=["Qunying", False, {}], isNotifyAward=False)
|
| | | |
| | | rankHighest = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_QunyingRankHighest)
|
| | | if not rankHighest or (1 <= tagRank < rankHighest):
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_QunyingRankHighest, tagRank)
|
| | | GameWorld.DebugLog(" 更新历史最高排名! tagRank=%s" % tagRank, playerID)
|
| | | Sync_QunyingInfo(curPlayer) # 更新最高排名
|
| | | |
| | | __updQunyingBatRecord(curPlayer, tagPlayerID, isWin, curRank, tagRank)
|
| | | |
| | | # 战斗结束系统强制刷新匹配
|
| | | DoQunyingMatchRefresh(curPlayer, True, isSys=True)
|
| | | return
|
| | |
|
| | | def __updQunyingBatRecord(curPlayer, tagPlayerID, isWin, curRank, tagRank):
|
| | | ## 更新战斗相关日志、榜单等
|
| | | |
| | | playerID = curPlayer.GetPlayerID()
|
| | | maxCount = 20
|
| | | |
| | | tagViewCache = PlayerViewCache.FindViewCache(tagPlayerID)
|
| | | |
| | | gameRecMgr = DBDataMgr.GetGameRecMgr()
|
| | | atkRecMgr = gameRecMgr.GetRecTypeIDMgr(ShareDefine.Def_GameRecType_QunyingRecord, playerID)
|
| | | recData = atkRecMgr.AddRecData(maxCount)
|
| | | SetRecAtkType(recData, RecAtkType_Atk)
|
| | | SetRecTagPlayerID(recData, tagPlayerID)
|
| | | SetRecIsWin(recData, isWin)
|
| | | SetRecFace(recData, tagViewCache.GetFace() if tagViewCache else 0)
|
| | | SetRecFacePic(recData, tagViewCache.GetFacePic() if tagViewCache else 0)
|
| | | SetRecRealmLV(recData, tagViewCache.GetRealmLV() if tagViewCache else 1)
|
| | | SetRecLV(recData, tagViewCache.GetLV() if tagViewCache else 1)
|
| | | # 名字、自己名次、对方名次
|
| | | tagPlayerName = tagViewCache.GetPlayerName() if tagViewCache else ""
|
| | | recData.SetUserData({"Name":tagPlayerName, "CurRank":curRank, "TagRank":tagRank})
|
| | | |
| | | # 被击方
|
| | | if tagPlayerID < ShareDefine.RealPlayerIDStart:
|
| | | #GameWorld.DebugLog("目标非真实玩家不处理! tagPlayerID=%s" % tagPlayerID, playerID)
|
| | | return
|
| | | |
| | | # 由于非榜单上的玩家不会被匹配到,所以被匹配到的可以理解为一定有战斗记录,因为要上榜必须战斗过
|
| | | defRecMgr = gameRecMgr.GetRecTypeIDMgr(ShareDefine.Def_GameRecType_QunyingRecord, tagPlayerID)
|
| | | if not defRecMgr.GetCount():
|
| | | GameWorld.DebugLog("目标没有对战记录不处理! tagPlayerID=%s" % tagPlayerID, playerID)
|
| | | return
|
| | | |
| | | finalRecData = defRecMgr.At(defRecMgr.GetCount() - 1)
|
| | | if not GameWorld.CheckTimeIsSameWeek(finalRecData.GetTime()):
|
| | | GameWorld.DebugLog("目标本周没有对战记录不处理! tagPlayerID=%s" % tagPlayerID, playerID)
|
| | | return
|
| | | |
| | | recData = defRecMgr.AddRecData(maxCount)
|
| | | SetRecAtkType(recData, RecAtkType_Def)
|
| | | SetRecTagPlayerID(recData, playerID)
|
| | | SetRecIsWin(recData, not isWin)
|
| | | SetRecFace(recData, curPlayer.GetFace())
|
| | | SetRecFacePic(recData, curPlayer.GetFacePic())
|
| | | SetRecRealmLV(recData, curPlayer.GetOfficialRank())
|
| | | SetRecLV(recData, curPlayer.GetLV())
|
| | | # 名字、自己名次、对方名次
|
| | | recData.SetUserData({"Name":curPlayer.GetPlayerName(), "CurRank":tagRank, "TagRank":curRank})
|
| | | return
|
| | |
|
| | | def GetQunyingRankHighestAward(curPlayer):
|
| | | rankHighest = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_QunyingRankHighest)
|
| | | awardRecord = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_QunyingRankSuccAward)
|
| | | if not rankHighest:
|
| | | return
|
| | | GameWorld.DebugLog("领取群英榜历史最高排名成就奖励! rankHighest=%s,awardRecord=%s" % (rankHighest, awardRecord))
|
| | | # 首次达到x名成就奖励 {"名次":[[物品ID, 个数], ...], ...}
|
| | | rankAwardDict = IpyGameDataPY.GetFuncEvalCfg("QunyingAward", 3, {})
|
| | | # 首次达到x名成就奖励记录索引 {"名次":记录索引, ...},记录索引从0开始递增,上线后不能修改
|
| | | rankIndexDict = IpyGameDataPY.GetFuncEvalCfg("QunyingAward", 4, {})
|
| | | awardItemDict = {}
|
| | | for rankStr, itemList in rankAwardDict.items():
|
| | | rank = int(rankStr)
|
| | | if rankHighest > rank:
|
| | | GameWorld.DebugLog(" 未达到: rank=%s" % rank)
|
| | | continue
|
| | | if rankStr not in rankIndexDict:
|
| | | continue
|
| | | index = rankIndexDict[rankStr]
|
| | | if awardRecord&pow(2, index):
|
| | | GameWorld.DebugLog(" 已领取: rank=%s" % rank)
|
| | | continue
|
| | | awardRecord |= pow(2, index)
|
| | | for itemInfo in itemList:
|
| | | itemID, itemCount = itemInfo[:2]
|
| | | awardItemDict[itemID] = awardItemDict.get(itemID, 0) + itemCount
|
| | | GameWorld.DebugLog(" 可领取: rank=%s,%s,%s" % (rank, itemList, awardItemDict))
|
| | | awardItemList = [[itemID, itemCount] for itemID, itemCount in awardItemDict.items()]
|
| | | |
| | | GameWorld.DebugLog(" awardRecord=%s,awardRecord=%s" % (awardRecord, awardItemList))
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_QunyingRankSuccAward, awardRecord)
|
| | | ItemControler.GivePlayerItemOrMail(curPlayer, awardItemList, event=["QunyingRankHighest", False, {}])
|
| | | Sync_QunyingInfo(curPlayer) # 领奖
|
| | | return
|
| | |
|
| | | def OnProcess(curPlayer):
|
| | | CheckQunyingTicketRecover(curPlayer)
|
| | | return
|
| | |
|
| | | def CheckQunyingTicketRecover(curPlayer):
|
| | | ## 检查挑战令恢复
|
| | | storeMax = IpyGameDataPY.GetFuncCfg("QunyingChallenge", 1)
|
| | | curTicket = PlayerControl.GetMoney(curPlayer, ShareDefine.TYPE_Price_QunyingTicket)
|
| | | lastRecoverTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_QunyingRecoverTime)
|
| | | if curTicket >= storeMax:
|
| | | if lastRecoverTime:
|
| | | GameWorld.DebugLog("群英挑战令已满!")
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_QunyingRecoverTime, 0)
|
| | | Sync_QunyingInfo(curPlayer) # 挑战令恢复满
|
| | | return
|
| | | |
| | | curTime = int(time.time())
|
| | | passSeconds = curTime - lastRecoverTime
|
| | | if not lastRecoverTime or passSeconds < 0:
|
| | | GameWorld.DebugLog("重设群英挑战令恢复时间!")
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_QunyingRecoverTime, curTime)
|
| | | Sync_QunyingInfo(curPlayer)
|
| | | return
|
| | | |
| | | cdSeconds = IpyGameDataPY.GetFuncCfg("QunyingChallenge", 2) * 60
|
| | | if passSeconds < cdSeconds:
|
| | | #GameWorld.DebugLog("群英挑战令恢复CD中: passSeconds=%s < %s, lastRecoverTime=%s" % (passSeconds, cdSeconds, GameWorld.ChangeTimeNumToStr(lastRecoverTime)))
|
| | | return
|
| | | recoverCnt = passSeconds / cdSeconds
|
| | | recoverCnt = min(recoverCnt, storeMax - curTicket)
|
| | | updRecoverTime = curTime - passSeconds % cdSeconds
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_QunyingRecoverTime, updRecoverTime)
|
| | | GameWorld.DebugLog("恢复群英挑战令: %s,passSeconds=%s,上次恢复:%s" % (recoverCnt, passSeconds, GameWorld.ChangeTimeNumToStr(lastRecoverTime)))
|
| | | PlayerControl.GiveMoney(curPlayer, ShareDefine.TYPE_Price_QunyingTicket, recoverCnt)
|
| | | if PlayerControl.GetMoney(curPlayer, ShareDefine.TYPE_Price_QunyingTicket) >= storeMax:
|
| | | GameWorld.DebugLog("已满!")
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_QunyingRecoverTime, 0)
|
| | | Sync_QunyingInfo(curPlayer)
|
| | | return
|
| | |
|
| | | #// B2 10 群英榜匹配玩家 #tagCSQunyingMatch
|
| | | #
|
| | | #struct tagCSQunyingMatch
|
| | | #{
|
| | | # tagHead Head;
|
| | | # BYTE IsRefresh; // 0-打开界面时查询,1-强制刷新匹配列表
|
| | | #};
|
| | | def OnQunyingMatch(index, clientData, tick):
|
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
| | | isRefresh = clientData.IsRefresh
|
| | | DoQunyingMatchRefresh(curPlayer, isRefresh)
|
| | | return
|
| | |
|
| | | def DoQunyingMatchRefresh(curPlayer, isRefresh, isSys=False):
|
| | | ## 玩家刷新匹配对手
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | GameWorld.DebugLog("群英榜玩家刷新匹配列表: isRefresh=%s,isSys=%s" % (isRefresh, isSys), playerID)
|
| | | |
| | | billboardMgr = DBDataMgr.GetBillboardMgr()
|
| | | billBoard = billboardMgr.GetBillboard(ShareDefine.Def_BT_Qunying)
|
| | | if not billBoard:
|
| | | return
|
| | | layerIDList = billBoard.GetLayerIDList()
|
| | | idRankDict = billBoard.GetIDOrderDict()
|
| | | layerIDCnt = len(layerIDList)
|
| | | playerRank = idRankDict.get(playerID, layerIDCnt + 1) # 未上榜默认最大名次 + 1
|
| | | |
| | | # 匹配对象缓存
|
| | | if playerID not in PyGameData.g_qunyingPlayerMatchDict:
|
| | | PyGameData.g_qunyingPlayerMatchDict[playerID] = []
|
| | | matchRankList = PyGameData.g_qunyingPlayerMatchDict[playerID]
|
| | | if not isRefresh and matchRankList:
|
| | | # 非刷新的并且已经有记录的直接同步
|
| | | GameWorld.DebugLog(" 非刷新且有数据,直接同步! matchRankList=%s" % matchRankList, playerID)
|
| | | __SyncQunyingMatchList(curPlayer, matchRankList, layerIDList)
|
| | | return
|
| | | |
| | | # 匹配可挑战目标规则 {玩家名次:[[名次差值, 匹配x个], ...], ...} 名次差值支持正负
|
| | | matchRuleDict = IpyGameDataPY.GetFuncEvalCfg("QunyingMatch", 1, {})
|
| | | rankList = matchRuleDict.keys()
|
| | | rankList.sort()
|
| | | matchRuleList = []
|
| | | for rank in rankList:
|
| | | if playerRank <= rank:
|
| | | matchRuleList = matchRuleDict[rank]
|
| | | break
|
| | | if not matchRuleList:
|
| | | matchRuleList = matchRuleDict[rankList[-1]] # 没有默认取最后一档
|
| | | |
| | | matchRuleList.sort()
|
| | | GameWorld.DebugLog(" layerIDCnt=%s,playerRank=%s,matchRuleList=%s" % (layerIDCnt, playerRank, matchRuleList), playerID)
|
| | | if not matchRuleList:
|
| | | return
|
| | | |
| | | if isRefresh and not isSys:
|
| | | refreshMax = IpyGameDataPY.GetFuncCfg("QunyingMatch", 3)
|
| | | if refreshMax:
|
| | | refreshCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_QunyingRefreshCnt)
|
| | | if refreshCnt >= refreshMax:
|
| | | GameWorld.DebugLog(" 已达最大刷新次数! refreshCnt=%s >= %s" % (refreshCnt, refreshMax), playerID)
|
| | | return
|
| | | costMoney, moneyValue = IpyGameDataPY.GetFuncEvalCfg("QunyingMatch", 2)
|
| | | if not costMoney or not moneyValue or not PlayerControl.PayMoney(curPlayer, costMoney, moneyValue, "Qunying"):
|
| | | return
|
| | | if refreshMax:
|
| | | refreshCnt += 1
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_QunyingRefreshCnt, refreshCnt)
|
| | | Sync_QunyingInfo(curPlayer) # 刷新匹配
|
| | | |
| | | matchRankList = [] # 因为有填充机器人,机器人ID可能重复,固按名次位置匹配 [rank, ...]
|
| | | if 1 <= playerRank <= layerIDCnt:
|
| | | matchRankList.append(playerRank) # 玩家有上榜时默认要包含玩家自己
|
| | | # [[名次差值, 匹配x个], ...]
|
| | | # 第一名时匹配示例: [[50, 4]]
|
| | | # 未上榜时匹配示例:[[-500, 5]]
|
| | | # 榜单中时匹配示例:[[-300, 1], [-200, 1], [-100, 1],[100, 1]]
|
| | | for mIndex, matchRule in enumerate(matchRuleList):
|
| | | rankDiff, matchCnt = matchRule
|
| | | nextDiff = None
|
| | | if mIndex < len(matchRuleList) - 1:
|
| | | nextDiff = matchRuleList[mIndex + 1][0]
|
| | | |
| | | if mIndex == 0:
|
| | | if rankDiff >= 0: # 第1个就开始匹配后面的,直接从玩家后一名开始,否则直接从与玩家名次的差值开始
|
| | | fromRank = playerRank + 1
|
| | | else:
|
| | | fromRank = playerRank + rankDiff
|
| | | |
| | | # 非最后一档的情况
|
| | | if nextDiff != None:
|
| | | if rankDiff < 0 and nextDiff >= 0:
|
| | | toRank = playerRank - 1 # 差值正负变更,默认以玩家名次分档
|
| | | else:
|
| | | toRank = fromRank + (nextDiff - rankDiff) - 1 # ~ 与下一档的差值
|
| | | |
| | | # 最后一档
|
| | | else:
|
| | | if rankDiff < 0:
|
| | | toRank = layerIDCnt
|
| | | else:
|
| | | toRank = fromRank + rankDiff - 1
|
| | | |
| | | fromRank = max(fromRank, 1)
|
| | | toRank = min(toRank, layerIDCnt)
|
| | | if fromRank > toRank:
|
| | | GameWorld.ErrLog("匹配规则异常! mIndex=%s,fromRank=%s,toRank=%s,%s" % (mIndex, fromRank, toRank, matchRuleList))
|
| | | break
|
| | | |
| | | randRankList = range(fromRank, toRank + 1)
|
| | | random.shuffle(randRankList)
|
| | | rankCnt = len(randRankList)
|
| | | mCnt = 0
|
| | | # 不用验证目标ID,允许匹配重复的ID,只要匹配的目标名次不重复即可
|
| | | for randRank in randRankList:
|
| | | if randRank in matchRankList:
|
| | | continue
|
| | | tagID = layerIDList[randRank - 1]
|
| | | GameWorld.DebugLog(" 匹配名次: %s ~ %s,%s名,randRank=%s,tagID=%s" % (fromRank, toRank, rankCnt, randRank, tagID), playerID)
|
| | | matchRankList.append(randRank)
|
| | | mCnt += 1
|
| | | if mCnt >= matchCnt:
|
| | | break
|
| | | |
| | | if toRank == playerRank - 1:
|
| | | fromRank = toRank + 2
|
| | | else:
|
| | | fromRank = toRank + 1
|
| | | |
| | | if fromRank > layerIDCnt:
|
| | | break
|
| | | |
| | | matchRankList.sort()
|
| | | GameWorld.DebugLog(" 匹配名次结果: matchRankList=%s" % (matchRankList), playerID)
|
| | | PyGameData.g_qunyingPlayerMatchDict[playerID] = matchRankList
|
| | | __SyncQunyingMatchList(curPlayer, matchRankList, layerIDList)
|
| | | return
|
| | |
|
| | | def __SyncQunyingMatchList(curPlayer, matchRankList, layerIDList):
|
| | | ## 同步匹配列表
|
| | | layerIDCnt = len(layerIDList)
|
| | | clientPack = ChPyNetSendPack.tagSCQunyingMatchList()
|
| | | clientPack.MatchList = []
|
| | | for rank in matchRankList:
|
| | | if rank <= 0 or rank > layerIDCnt:
|
| | | continue
|
| | | matchID = layerIDList[rank - 1]
|
| | | viewCache = PlayerViewCache.FindBattleViewCache(matchID)
|
| | | if not viewCache:
|
| | | continue
|
| | | matchInfo = ChPyNetSendPack.tagSCQunyingMatchInfo()
|
| | | matchInfo.Rank = rank
|
| | | matchInfo.PlayerID = matchID
|
| | | if viewCache:
|
| | | fightPower = TurnAttack.GetCacheLineupFightPower(viewCache, ShareDefine.BatPreset_QunyingDef)
|
| | | matchInfo.PlayerName = viewCache.GetPlayerName()
|
| | | matchInfo.RealmLV = viewCache.GetRealmLV()
|
| | | matchInfo.LV = viewCache.GetLV()
|
| | | matchInfo.Face = viewCache.GetFace()
|
| | | matchInfo.FacePic = viewCache.GetFacePic()
|
| | | matchInfo.FightPower = fightPower % ChConfig.Def_PerPointValue
|
| | | matchInfo.FightPowerEx = fightPower / ChConfig.Def_PerPointValue
|
| | | matchInfo.TitleID = viewCache.GetTitleID()
|
| | | matchInfo.ModelMark = viewCache.GetModelMark()
|
| | | matchInfo.EquipShowSwitch = viewCache.GetEquipShowSwitch()
|
| | | matchInfo.ServerID = viewCache.GetServerID()
|
| | | else:
|
| | | matchInfo.PlayerName = "p%s" % matchID
|
| | | clientPack.MatchList.append(matchInfo)
|
| | | clientPack.MatchCount = len(clientPack.MatchList)
|
| | | NetPackCommon.SendFakePack(curPlayer, clientPack)
|
| | | return
|
| | |
|
| | | def Sync_QunyingInfo(curPlayer):
|
| | | clientPack = ChPyNetSendPack.tagSCQunyingPlayerInfo()
|
| | | clientPack.RefreshCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_QunyingRefreshCnt)
|
| | | clientPack.LastRecoverTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_QunyingRecoverTime)
|
| | | clientPack.RankHighest = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_QunyingRankHighest)
|
| | | clientPack.RankSuccAward = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_QunyingRankSuccAward)
|
| | | NetPackCommon.SendFakePack(curPlayer, clientPack)
|
| | | return
|
| | |
| | | import IPY_GameWorld
|
| | | import DataRecordPack
|
| | | import PlayerEventCounter
|
| | | import GameLogic_Qunying
|
| | | import GameWorldAction
|
| | | import PlayerViewCache
|
| | | import PlayerControl
|
| | | import NetPackCommon
|
| | | import PlayerOnline
|
| | |
| | | DBDataMgr.OnServerStart() # 优先加载公共数据
|
| | | #ItemCommon.InitPyItem() # 改为放 InitItem 加载
|
| | | LoadDBPlayer()
|
| | | PlayerViewCache.LoadRobot()
|
| | | #PlayerViewCache.LoadRobot()
|
| | | PyGameData.g_initGameTime = int(time.time()) # 放到加载数据之后
|
| | |
|
| | | # 检查跨服中心唯一性
|
| | |
| | | __DoMixServerInit()
|
| | |
|
| | | # 其他功能初始化
|
| | | |
| | | GameLogic_Qunying.OnServerStart()
|
| | |
|
| | | # 最后触发检查是否完全启动成功
|
| | | PyGameData.g_initGameWorldOK = True
|
| | |
| | | ("dict", "Attr", 0),
|
| | | ),
|
| | |
|
| | | "QunyingCross":(
|
| | | ("char", "AppID", 1),
|
| | | ("WORD", "ZoneID", 1),
|
| | | ("DWORD", "CrossServerID", 0),
|
| | | ("list", "ServerIDList", 0),
|
| | | ("BYTE", "SplitServerCnt", 0),
|
| | | ("BYTE", "MatchServerCnt", 0),
|
| | | ),
|
| | |
|
| | | "FamilyCross":(
|
| | | ("char", "AppID", 1),
|
| | | ("WORD", "ZoneID", 1),
|
| | |
| | | "Robot":(
|
| | | ("DWORD", "ID", 1),
|
| | | ("char", "RobotName", 0),
|
| | | ("BYTE", "RealmLV", 0),
|
| | | ("DWORD", "TempNum", 0),
|
| | | ("DWORD", "TempValue1", 0),
|
| | | ("DWORD", "TempValue2", 0),
|
| | | ("char", "ViewCache", 0),
|
| | | ),
|
| | | }
|
| | |
| | | def GetCostItem(self): return self.attrTuple[3] # 消耗材料 dict
|
| | | def GetAttr(self): return self.attrTuple[4] # 属性 dict |
| | | |
| | | # 群英榜分区表 |
| | | class IPY_QunyingCross(): |
| | | |
| | | def __init__(self): |
| | | self.attrTuple = None |
| | | return |
| | | |
| | | def GetAppID(self): return self.attrTuple[0] # AppID char
|
| | | def GetZoneID(self): return self.attrTuple[1] # 分区ID WORD
|
| | | def GetCrossServerID(self): return self.attrTuple[2] # 跨服服务器ID DWORD
|
| | | def GetServerIDList(self): return self.attrTuple[3] # 互通服务器ID列表 list
|
| | | def GetSplitServerCnt(self): return self.attrTuple[4] # 按X个相邻服分割 BYTE
|
| | | def GetMatchServerCnt(self): return self.attrTuple[5] # 分割区服内X个服随机匹配一组 BYTE |
| | | |
| | | # 跨服公会表 |
| | | class IPY_FamilyCross(): |
| | | |
| | |
| | | |
| | | def GetID(self): return self.attrTuple[0] # 机器人ID,同玩家ID DWORD
|
| | | def GetRobotName(self): return self.attrTuple[1] # char
|
| | | def GetViewCache(self): return self.attrTuple[2] # 机器人缓存 char |
| | | def GetRealmLV(self): return self.attrTuple[2] # 指定官职 BYTE
|
| | | def GetTempNum(self): return self.attrTuple[3] # 功能模版 DWORD
|
| | | def GetTempValue1(self): return self.attrTuple[4] # 功能值1 DWORD
|
| | | def GetTempValue2(self): return self.attrTuple[5] # 功能值2 DWORD
|
| | | def GetViewCache(self): return self.attrTuple[6] # 机器人缓存 char |
| | |
|
| | |
|
| | | def Log(msg, playerID=0, par=0):
|
| | |
| | | self.__LoadFileData("EquipShenEvolve", onlyCheck)
|
| | | self.__LoadFileData("EquipStarUp", onlyCheck)
|
| | | self.__LoadFileData("EquipPlusEvolve", onlyCheck)
|
| | | self.__LoadFileData("QunyingCross", onlyCheck)
|
| | | self.__LoadFileData("FamilyCross", onlyCheck)
|
| | | self.__LoadFileData("Family", onlyCheck)
|
| | | self.__LoadFileData("FamilyEmblem", onlyCheck)
|
| | |
| | | self.CheckLoadData("EquipPlusEvolve") |
| | | return self.ipyEquipPlusEvolveCache[index]
|
| | | |
| | | def GetQunyingCrossCount(self): |
| | | self.CheckLoadData("QunyingCross") |
| | | return self.ipyQunyingCrossLen
|
| | | def GetQunyingCrossByIndex(self, index): |
| | | self.CheckLoadData("QunyingCross") |
| | | return self.ipyQunyingCrossCache[index]
|
| | | |
| | | def GetFamilyCrossCount(self): |
| | | self.CheckLoadData("FamilyCross") |
| | | return self.ipyFamilyCrossLen
|
| | |
| | | import PlayerActManyDayRecharge
|
| | | import PlayerActSingleRecharge
|
| | | import OpenServerActivity
|
| | | import GameLogic_Qunying
|
| | | import ChNetSendPack
|
| | | import PlayerArena
|
| | | import PyGameData
|
| | |
| | | PlayerControl.SendMailByKey("MixServer1", [playerID], addItemList, gold=gold, silver=silver, detail=detailDict)
|
| | |
|
| | | # 同步排行榜
|
| | | PlayerBillboard.UpdatePlayerBillboardOnLeaveServer(curPlayer, isAll=True)
|
| | | #PlayerBillboard.UpdatePlayerBillboardOnLeaveServer(curPlayer, isAll=True)
|
| | | return
|
| | | #---------------------------------------------------------------------
|
| | |
|
| | |
| | | # 领取活动签到奖励 70
|
| | | elif rewardType == ChConfig.Def_RewardType_ActSignAward:
|
| | | PlayerActSign.OnGetActSignAward(curPlayer, dataEx, dataExStr)
|
| | | # 群英榜历史最高名次奖励 7
|
| | | elif rewardType == ChConfig.Def_RewardType_QunyingRankHighest:
|
| | | GameLogic_Qunying.GetQunyingRankHighestAward(curPlayer)
|
| | |
|
| | |
|
| | | # 首充礼包奖励
|
| | |
| | | import FunctionNPCCommon
|
| | | import PlayerActBuyCountGift
|
| | | import OpenServerActivity
|
| | | import GameLogic_Qunying
|
| | | import PlayerActTask
|
| | | import ItemControler
|
| | | import PlayerMingge
|
| | |
| | | # 功能开启需执行的函数{功能ID:执行函数, ...} 函数需返回是否激活成功, 功能开启有需要处理功能逻辑的这里增加函数调用配置即可
|
| | | FuncOpenLogicDict = {
|
| | | ShareDefine.GameFuncID_Arena:lambda curObj:PlayerArena.DoArenaOpen(curObj),
|
| | | ShareDefine.GameFuncID_Qunying:lambda curObj:GameLogic_Qunying.DoQunyingOpen(curObj),
|
| | | ShareDefine.GameFuncID_Shop:lambda curObj:FunctionNPCCommon.DoShopOpen(curObj),
|
| | | ShareDefine.GameFuncID_Horse:lambda curObj:PlayerHorse.DoHorseOpen(curObj),
|
| | | ShareDefine.GameFuncID_Travel:lambda curObj:PlayerTravel.DoTravelOpen(curObj),
|
| | |
| | | import ShareDefine
|
| | | import PlayerControl
|
| | | import ChPyNetSendPack
|
| | | import PlayerViewCache
|
| | | import NetPackCommon
|
| | | import IpyGameDataPY
|
| | | import DBBillboard
|
| | | import PlayerMail
|
| | | import DBDataMgr
|
| | |
|
| | |
| | |
|
| | | def BillboardOnLogin(curPlayer):
|
| | | # 上线默认同步排行榜
|
| | | UpdatePlayerBillboardOnLeaveServer(curPlayer) #排行榜已实时更新,故上线不再同步
|
| | | #UpdatePlayerBillboardOnLeaveServer(curPlayer) #排行榜已实时更新,故上线不再同步
|
| | | return
|
| | |
|
| | | def GetBillboardOperateInfo(curPlayer):
|
| | |
| | | return platform
|
| | |
|
| | | def GetBillboardJob(curPlayer): return curPlayer.GetJob()
|
| | |
|
| | | def UpdatePlayerBillboardOnLeaveServer(curPlayer, isAll=False):
|
| | | ##下线更新玩家排行榜
|
| | | if GameWorld.IsCrossServer():
|
| | | # 跨服服务器不用更新本服榜
|
| | | return
|
| | | |
| | | return
|
| | |
|
| | | def UpdatePlayerBillboardName(curPlayer):
|
| | | ## 更新排行榜中的玩家名字记录
|
| | |
| | | # 跨服榜更新, 待处理
|
| | | return
|
| | |
|
| | | def UpdatePlayerFPTotalBillboard(curPlayer, isForceUpdate=False, isCheckRule=True):
|
| | | ##更新玩家总战斗力
|
| | | return
|
| | |
|
| | | #def __CanPlayerBillboardComm(curPlayer):
|
| | | # ## 玩家可否上榜通用检查
|
| | | # if not GameWorld.IsNormalPlayer(curPlayer):
|
| | | # return False
|
| | | # #if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Billboard):
|
| | | # # GameWorld.DebugLog("排行榜未开启,无法上榜!curLV=%s" % (curPlayer.GetLV()), curPlayer.GetPlayerID())
|
| | | # # return False
|
| | | # |
| | | # return True
|
| | |
|
| | | def UpdatePlayerBillboard(curPlayer, bType, cmpValue, cmpValue2=0, cmpValue3=0, autoSort=False, groupValue1=0, **kwargs):
|
| | | ## 更新玩家排行榜
|
| | |
|
| | |
| | | UpdateBillboard(bType, groupValue1, playerID, playerName, playerOpInfo, playerJob, value1, value2,
|
| | | cmpValue, cmpValue2, cmpValue3, autoSort=autoSort, **kwargs)
|
| | | return
|
| | |
|
| | | def __updPlayerBillViewInfo(billData):
|
| | | playerID = billData.GetID()
|
| | | curCache = PlayerViewCache.FindViewCache(playerID)
|
| | | if not curCache:
|
| | | return
|
| | | billData.SetName1(curCache.GetPlayerName())
|
| | | billData.SetName2(curCache.GetAccID())
|
| | | billData.SetType2(curCache.GetJob())
|
| | | billData.SetValue1(curCache.GetRealmLV())
|
| | | billData.SetValue2(curCache.GetTitleID())
|
| | | billData.SetValue3(curCache.GetFace())
|
| | | billData.SetValue4(curCache.GetFacePic())
|
| | | billData.SetValue5(curCache.GetModelMark())
|
| | | billData.SetValue6(curCache.GetEquipShowSwitch())
|
| | | return
|
| | |
|
| | | def UpdateBillboardLayer(dataID, billboardType, cmpValue, groupValue1=0, autoSort=True):
|
| | | ## 更新榜单所在的层级,一般用于层级模式的榜单,层级模式默认与目标交换名次
|
| | | if GameWorld.IsCrossServer():
|
| | | if billboardType not in ShareDefine.CrossBillboardTypeList:
|
| | | return
|
| | | else:
|
| | | if billboardType not in ShareDefine.BillboardTypeList:
|
| | | return
|
| | | |
| | | if not dataID:
|
| | | return
|
| | | |
| | | groupValue2 = 0
|
| | | billboardMgr = DBDataMgr.GetBillboardMgr()
|
| | | billboardObj = billboardMgr.GetBillboard(billboardType, groupValue1, groupValue2)
|
| | | layerIDList = billboardObj.GetLayerIDList()
|
| | | layerIDCnt = len(layerIDList)
|
| | | if cmpValue <= 0 or cmpValue > layerIDCnt:
|
| | | GameWorld.ErrLog("更新层级榜单名次异常! dataID=%s,billboardType=%s,cmpValue=%s,layerIDCnt=%s" % (dataID, billboardType, cmpValue, layerIDCnt), dataID)
|
| | | return
|
| | | tagIndex = cmpValue - 1
|
| | | tagID = layerIDList[tagIndex]
|
| | | if dataID == tagID:
|
| | | return True
|
| | | tagBillData = billboardObj.FindByID(tagID) # 当是填充的机器人时不存在数据
|
| | | curBillData = billboardObj.FindByID(dataID)
|
| | | |
| | | curTime = int(time.time())
|
| | | |
| | | # 未上榜的替换上榜的
|
| | | if not curBillData:
|
| | | if tagBillData:
|
| | | curBillData = tagBillData
|
| | | curBillData.Clear()
|
| | | tagBillData = None
|
| | | else:
|
| | | curBillData = billboardObj.AddNewBillboardData(dataID)
|
| | | |
| | | # 上榜的直接交换
|
| | | else:
|
| | | curCmpValue = curBillData.GetCmpValue()
|
| | | if curCmpValue <= cmpValue:
|
| | | GameWorld.DebugLog("层级榜单名次值没有提高不更新榜单! curCmpValue=%s <= %s" % (curCmpValue, cmpValue), dataID)
|
| | | return
|
| | | layerIDList[curCmpValue - 1] = tagID
|
| | | |
| | | if tagBillData:
|
| | | tagBillData.SetCmpValue(curCmpValue)
|
| | | tagBillData.SetTime(curTime)
|
| | | |
| | | layerIDList[cmpValue - 1] = dataID
|
| | | billboardObj.SetLayerIDList(layerIDList)
|
| | | curBillData.SetID(dataID)
|
| | | curBillData.SetCmpValue(cmpValue)
|
| | | curBillData.SetTime(curTime)
|
| | | |
| | | __updPlayerBillViewInfo(curBillData)
|
| | | |
| | | GameWorld.DebugLog("更新排行层值: billboardType=%s,groupValue1=%s,dataID=%s,cmpValue=%s,tagID=%s" |
| | | % (billboardType, groupValue1, dataID, cmpValue, tagID), dataID)
|
| | | if autoSort:
|
| | | billboardObj.SortData()
|
| | | return True
|
| | |
|
| | | def SetTempDataByViewCache(playerID, billType, groupValue1=0, groupValue2=0, cmpValue=0):
|
| | | ## 根据玩家缓存更新临时榜单数据,一般用于填充机器人
|
| | | TempBillData = DBBillboard.TempBillData
|
| | | TempBillData.Clear()
|
| | | TempBillData.SetType(billType)
|
| | | TempBillData.SetGroupValue1(groupValue1)
|
| | | TempBillData.SetGroupValue2(groupValue2)
|
| | | if not playerID:
|
| | | return TempBillData
|
| | | |
| | | TempBillData.SetID(playerID)
|
| | | TempBillData.SetCmpValue(cmpValue)
|
| | | __updPlayerBillViewInfo(TempBillData)
|
| | | |
| | | return TempBillData
|
| | |
|
| | | def UpdateBillboardByID(dataID, billboardType, cmpValue, cmpValue2=0, cmpValue3=0, autoSort=False):
|
| | | ## 直接根据榜单ID修改榜单排行相关值,其他值不修改
|
| | |
| | |
|
| | | billboardMgr = DBDataMgr.GetBillboardMgr()
|
| | | billboardObj = billboardMgr.GetBillboard(billboardType, groupValue1, groupValue2)
|
| | | if billboardObj.IsOrderRuleByLayer():
|
| | | # 该模式不处理,请使用 UpdateBillboardLayer
|
| | | return
|
| | | billboardData = billboardObj.FindByID(dataID)
|
| | | isNewData = False
|
| | | if not billboardData:
|
| | |
| | | return
|
| | | return lastBillBoardData
|
| | |
|
| | | def UpdatePlayerCrossBillboard(curPlayer, bType, groupValue1, cmpValue, cmpValue2=0, cmpValue3=0, value1=0, value2=0,
|
| | | groupValue2=0, **kwargs):
|
| | | ## 在本服直接更新玩家跨服排行榜,发送到跨服,之后扩展
|
| | | return
|
| | |
|
| | | #// A1 30 查看榜单 #tagCMViewBillboard
|
| | | #
|
| | | #struct tagCMViewBillboard
|
| | |
| | | billboardObj.SortDelayDo()
|
| | | idOrderDict = billboardObj.GetIDOrderDict()
|
| | | count = billboardObj.GetCount()
|
| | | isLayerMode = billboardObj.IsOrderRuleByLayer() # 层级模式有机器人填充,默认为最大,实际榜单数据中没有机器人数据
|
| | | layerIDList = []
|
| | | if isLayerMode:
|
| | | layerIDList = billboardObj.GetLayerIDList()
|
| | | count = len(layerIDList)
|
| | |
|
| | | maxIndex = count - 1
|
| | | startIndex = max(min(startIndex, maxIndex), 0)
|
| | |
| | | # 查看viewID前后名次
|
| | | if viewID:
|
| | | viewBFCnt = 3 # 查看ViewID返回前后数据条数,一般设置为奇数
|
| | | viewIDIndex = -1
|
| | | if isLayerMode:
|
| | | billboardData = billboardObj.FindByID(viewID)
|
| | | if billboardData:
|
| | | viewIDIndex = billboardData.GetCmpValue() - 1
|
| | | else:
|
| | | viewIDIndex = billboardObj.IndexOfByID(viewID)
|
| | | if viewIDIndex != -1:
|
| | | # 前x后x
|
| | |
| | | clientPack.DataTotal = count
|
| | | clientPack.PageDataList = []
|
| | | for index in viewRange:
|
| | | if index >= count:
|
| | | break
|
| | | billboardData = None
|
| | | if isLayerMode:
|
| | | rank = index + 1
|
| | | dataID = layerIDList[index]
|
| | | billboardData = billboardObj.FindByID(dataID)
|
| | | if not billboardData:
|
| | | cmpValue = rank
|
| | | billboardData = SetTempDataByViewCache(dataID, bbType, groupValue1, groupValue2, cmpValue)
|
| | | else:
|
| | | billboardData = billboardObj.At(index)
|
| | | rank = idOrderDict.get(billboardData.GetID(), 0)
|
| | | if not billboardData:
|
| | | continue
|
| | | viewData = ChPyNetSendPack.tagMCViewBillboardData()
|
| | | viewData.Index = index
|
| | | viewData.Rank = idOrderDict.get(billboardData.GetID(), 0)
|
| | | viewData.Rank = rank
|
| | | viewData.ID = billboardData.GetID()
|
| | | viewData.ID2 = billboardData.GetID2()
|
| | | viewData.Name1 = billboardData.GetName1()
|
| | |
| | | clientPack.ViewID = viewID
|
| | | clientPack.ViewIDDataList = []
|
| | | for index in viewIDRange:
|
| | | billboardData = None
|
| | | if isLayerMode:
|
| | | rank = index + 1
|
| | | dataID = layerIDList[index]
|
| | | billboardData = billboardObj.FindByID(dataID)
|
| | | if not billboardData:
|
| | | cmpValue = rank
|
| | | billboardData = SetTempDataByViewCache(dataID, bbType, groupValue1, groupValue2, cmpValue)
|
| | | else:
|
| | | billboardData = billboardObj.At(index)
|
| | | rank = idOrderDict.get(billboardData.GetID(), 0)
|
| | | if not billboardData:
|
| | | continue
|
| | | viewData = ChPyNetSendPack.tagMCViewBillboardData()
|
| | | viewData.Index = index
|
| | | viewData.Rank = idOrderDict.get(billboardData.GetID(), 0)
|
| | | viewData.Rank = rank
|
| | | viewData.ID = billboardData.GetID()
|
| | | viewData.ID2 = billboardData.GetID2()
|
| | | viewData.Name1 = billboardData.GetName1()
|
| | |
| | | playerControl.RefreshAllState()
|
| | |
|
| | | #玩家下线更新排行榜
|
| | | PlayerBillboard.UpdatePlayerBillboardOnLeaveServer(curPlayer) #排行榜已实时更新,故下线不再同步
|
| | | #PlayerBillboard.UpdatePlayerBillboardOnLeaveServer(curPlayer) #排行榜已实时更新,故下线不再同步
|
| | |
|
| | | #玩家下线通知gameserver记录缓存(放在下线更新排行榜之后,方便Gameserver判断是否需要存入数据库中)
|
| | | PlayerViewCache.OnPlayerLogout(curPlayer)
|
| | |
| | | import PlayerActivity
|
| | | import FBCommon
|
| | | import ChItem
|
| | | import GameLogic_Tianzi
|
| | | import PlayerGoldInvest
|
| | | import PlayerActTask
|
| | | import PlayerActBuyCountGift
|
| | |
| | |
|
| | | def DoLogic_OnDay(tick):
|
| | | GameWorld.Log("MapServer -> OnDay!")
|
| | | #副本OnDay事件响应
|
| | | #FBLogic.OnDay(tick)
|
| | |
|
| | | OpenServerActivity.OnDay()
|
| | | #仙盟
|
| | | FBLogic.OnDay()
|
| | | PlayerFamily.FamilyOnDay()
|
| | | PlayerArena.OnDay()
|
| | | GameLogic_Tianzi.OnDay()
|
| | |
|
| | | PlayerOfflineSupport.OnDay()
|
| | | playerManager = GameWorld.GetPlayerManager()
|
| | |
| | | def DoLogic_OnWeek(tick):
|
| | | GameWorld.Log("MapServer -> OnWeek!")
|
| | |
|
| | | FBLogic.OnWeek()
|
| | | PlayerArena.OnWeek()
|
| | |
|
| | | playerManager = GameWorld.GetPlayerManager()
|
| | |
| | |
|
| | | PlayerOnWeek(curPlayer)
|
| | |
|
| | | #副本OnWeek事件响应
|
| | | FBLogic.OnWeek(tick)
|
| | | return
|
| | |
|
| | | def DoLogic_OnMonth(tick):
|
| | |
| | | import ChItem
|
| | | import PlayerGMOper
|
| | | import OperControlManager
|
| | | import GameLogic_Qunying
|
| | | import ShareDefine
|
| | | import ReadChConfig
|
| | | import IpyGameDataPY
|
| | |
| | | PlayerGoldRush.OnProcess(curPlayer)
|
| | | #游历
|
| | | PlayerTravel.OnProcess(curPlayer)
|
| | | #群英榜
|
| | | GameLogic_Qunying.OnProcess(curPlayer)
|
| | | return
|
| | |
|
| | | def ProcessPlayerMinute(curPlayer, tick):
|
| | |
| | | }
|
| | | return robotDict
|
| | |
|
| | | def LoadRobot():
|
| | | ## 加载机器人缓存,在服务器启动、重读配置时加载
|
| | | def GetRobotFightPowerSortList(tempNum=0):
|
| | | ## 机器人战力倒序排序列表
|
| | | # @return: 倒序排序列表 [[战力, 机器人ID], ...],外部使用可随机修改,不会打乱原始排序
|
| | | robotFPSortList = IpyGameDataPY.GetConfigEx("robotFPSortList%s" % tempNum)
|
| | | if not robotFPSortList:
|
| | | robotFPSortList = []
|
| | | viewCacheMgr = DBDataMgr.GetPlayerViewCacheMgr()
|
| | | ipyDataMgr = IpyGameDataPY.IPY_Data()
|
| | | for index in range(ipyDataMgr.GetRobotCount()):
|
| | | ipyData = ipyDataMgr.GetRobotByIndex(index)
|
| | | if ipyData.GetTempNum() != tempNum:
|
| | | continue
|
| | | robotPlayerID = ipyData.GetID()
|
| | | curCache = viewCacheMgr.GetPlayerViewCache(robotPlayerID)
|
| | | if not curCache:
|
| | |
| | | UpdRobotViewCache(curCache, robotPlayerID, ipyData)
|
| | | robotFPSortList.append([curCache.GetFightPowerTotal(), robotPlayerID])
|
| | | robotFPSortList.sort(reverse=True) # 战力倒序排序
|
| | | IpyGameDataPY.SetConfigEx("robotFPSortList", robotFPSortList)
|
| | | GameWorld.Log("加载机器人战力排序: %s, %s" % (len(robotFPSortList), robotFPSortList))
|
| | | return robotFPSortList
|
| | | IpyGameDataPY.SetConfigEx("robotFPSortList%s" % tempNum, robotFPSortList)
|
| | | GameWorld.Log("加载机器人战力排序: tempNum=%s,%s, %s" % (tempNum, len(robotFPSortList), robotFPSortList))
|
| | |
|
| | | def GetRobotFightPowerSortList():
|
| | | ## 机器人战力倒序排序列表
|
| | | # @return: 倒序排序列表 [[战力, 机器人ID], ...],外部使用可随机修改,不会打乱原始排序
|
| | | sortList = []
|
| | | robotFPSortList = IpyGameDataPY.GetConfigEx("robotFPSortList")
|
| | | if not robotFPSortList:
|
| | | robotFPSortList = LoadRobot()
|
| | | if robotFPSortList:
|
| | | sortList += robotFPSortList
|
| | | return sortList
|
| | | return robotFPSortList
|
| | |
|
| | | def UpdRobotViewCache(curCache, robotID, robotIpyData=None):
|
| | | ## 更新机器人查看缓存
|
| | |
| | | return
|
| | |
|
| | | #curCache.SetAccID(dbPlayer.AccID)
|
| | | |
| | | realmLV = robotIpyData.GetRealmLV()
|
| | | curCache.SetPlayerName(GameWorld.GbkToCode(robotIpyData.GetRobotName()))
|
| | | curCache.SetLV(robotInfo.get("LV", 1))
|
| | | curCache.SetJob(robotInfo.get("Job", 1))
|
| | | curCache.SetRealmLV(robotInfo.get("RealmLV", 0))
|
| | | curCache.SetRealmLV(realmLV if realmLV else robotInfo.get("RealmLV", 0))
|
| | | curCache.SetFace(robotInfo.get("Face", 0))
|
| | | curCache.SetFacePic(robotInfo.get("FacePic", 0))
|
| | | curCache.SetTitleID(robotInfo.get("TitleID", 0))
|
| | |
| | | g_broadCastList = [] # 后台gm广播
|
| | |
|
| | | g_arenaPlayerMatchDict = {} # 本服竞技场玩家匹配记录缓存 {playerID:[tagPlayerID, ...], ...}
|
| | | g_qunyingPlayerMatchDict = {} # 群英榜玩家匹配记录缓存,该功能允许重复的机器人ID,所以记录匹配名次 {playerID:[rank, ...], ...}
|
| | |
|
| | | g_beautyEffTypeDict = {} # 红颜特殊效果缓存 {playerID:{effType:[effValue, effTypeValue], ...}, ...}
|
| | |
|
| | |
| | | Def_BT_OSA_HeroTrain, # 开服武将冲榜 7
|
| | | Def_BT_OSA_BeautyTrain, # 开服红颜冲榜 8
|
| | | Def_BT_OSA_MinggeTrain, # 开服命格冲榜 9
|
| | | ) = range(0, 10) |
| | | Def_BT_Qunying, # 群英榜积分周榜 10
|
| | | ) = range(0, 11)
|
| | |
|
| | | ''' 跨服排行榜类型, 从 150 开始,最大条数在功能配置表 CrossBillboardSet 配置,没配默认100
|
| | | 与本服榜单存储的是不一样的数据库表格,理论上类型可以和本服榜单类型重复,为了做下区分防误导,跨服榜单从 150 开始
|
| | |
| | | 本服榜单表(tagDBBillboard)
|
| | | '''
|
| | | CrossBillboardTypeList = (
|
| | | Def_CBT_ActCTG, # 跨服运营活动 - 充值榜 150
|
| | | Def_CBT_Qunying, # 跨服群英榜积分周榜 - 150
|
| | | ) = range(150, 150 + 1)
|
| | |
|
| | | BillboardTypeAllList = BillboardTypeList + CrossBillboardTypeList
|
| | |
| | | BillboardNameDict = {Def_BT_MainLevel:"主线过关榜", Def_BT_Arena:"演武场积分周榜", Def_BT_Tianzi:"天子考验伤害榜",
|
| | | Def_BT_OSA_MainLevel:"开服关卡榜", Def_BT_OSA_HeroCall:"开服招募榜", Def_BT_Dingjunge:"定军阁过关榜",
|
| | | Def_BT_OSA_HeroTrain:"开服武将冲榜", Def_BT_OSA_BeautyTrain:"开服红颜冲榜", Def_BT_OSA_MinggeTrain:"开服命格冲榜",
|
| | | Def_BT_ActHeroAppear:"武将登场招募榜(分组值1-ActNum)",
|
| | | Def_BT_ActHeroAppear:"武将登场招募榜(分组值1-ActNum)", Def_BT_Qunying:"群英榜积分周榜",
|
| | | Def_CBT_Qunying:"跨服群英榜积分周榜(分组值1-zoneID)",
|
| | | }
|
| | |
|
| | | #仙盟榜单类型
|
| | |
| | | CDBPlayerRefresh_ArenaTicket, # 挑战券 286
|
| | | CDBPlayerRefresh_TehuiPoint, # 特惠印绶 287
|
| | | CDBPlayerRefresh_OSAPoint, # 开服庆典积分 288
|
| | | ) = range(146, 289)
|
| | | CDBPlayerRefresh_QunyingTicket, # 群英榜挑战令 289
|
| | | CDBPlayerRefresh_QunyingPoint, # 群英榜积分 290
|
| | | ) = range(146, 291)
|
| | |
|
| | | TYPE_Price_Gold_Paper_Money = 5 # 金钱类型,(先用礼券,再用金子)
|
| | | TYPE_Price_FamilyExp = 6 # 战盟经验
|
| | |
| | | TYPE_Price_ArenaTicket = 53 # 演武场挑战券
|
| | | TYPE_Price_TehuiPoint = 54 # 特惠印绶
|
| | | TYPE_Price_OSAPoint = 55 # 开服庆典积分
|
| | | TYPE_Price_QunyingTicket = 56 # 群英榜挑战令
|
| | | TYPE_Price_QunyingPoint = 57 # 群英榜积分
|
| | | TYPE_Price_PayCoinDay = 98 # 代币时效,每日过天重置
|
| | | TYPE_Price_PayCoin = 99 # 代币
|
| | |
|
| | | #key可用于遍历所有货币,value仅GM相关会用到
|
| | | MoneyNameDict = {
|
| | | 1:"金币", 15:"公会贡献币", 41:"战锤", 42:"将星玉髓", 43:"将魂", 51:"招募积分", 52:"淘金令", 53:"挑战券", 54:"特惠印绶",
|
| | | 55:"可用开服庆典积分",
|
| | | 55:"可用开服庆典积分", 56:"群英榜挑战令", 57:"群英榜积分",
|
| | | 98:"代币时效", 99:"代币"
|
| | | }
|
| | | #MoneyNameDict = {
|
| | |
| | | TYPE_Price_ArenaTicket:CDBPlayerRefresh_ArenaTicket,
|
| | | TYPE_Price_TehuiPoint:CDBPlayerRefresh_TehuiPoint,
|
| | | TYPE_Price_OSAPoint:CDBPlayerRefresh_OSAPoint,
|
| | | TYPE_Price_QunyingTicket:CDBPlayerRefresh_QunyingTicket,
|
| | | TYPE_Price_QunyingPoint:CDBPlayerRefresh_QunyingPoint,
|
| | | TYPE_Price_PayCoinDay:CDBPlayerRefresh_PayCoinDay,
|
| | | #TYPE_Price_Rune:CDBPlayerRefresh_Rune,
|
| | | #TYPE_Price_RuneSplinters:CDBPlayerRefresh_RuneSplinters,
|
| | |
| | | GameFuncID_OSA_HeroTrain = 59 # 开服武将冲榜
|
| | | GameFuncID_OSA_BeautyTrain = 60 # 开服红颜冲榜
|
| | | GameFuncID_OSA_MinggeTrain = 61 # 开服命格冲榜
|
| | |
|
| | | # 以下为暂时无用的
|
| | | GameFuncID_Pet = -1 # 宠物,灵宠 6
|
| | | GameFuncID_Qunying = 62 # 群英榜
|
| | |
|
| | | #背包类型
|
| | | (
|
| | |
| | | Def_GameRecType_BatPreset, # 战斗方案预设额外存储信息,playerID 309
|
| | | Def_GameRecType_Setting, # 前端自定义存储的设置内容,playerID 310
|
| | | Def_GameRecType_Treasure, # 寻宝记录,treasureType 311
|
| | | ) = range(300, 1 + 311)
|
| | | Def_GameRecType_QunyingRecord, # 群英榜玩家挑战记录,playerID 312
|
| | | ) = range(300, 1 + 312)
|
| | | #通用信息记录新 - 字典key配置,如果有配置,则可额外按对应记录Value值存储字典,方便快速取值,可配置Value编号 1~8,配空默认 Value1
|
| | | Def_GameRecValueKeyDict = {
|
| | | Def_GameRecType_Xiangong:[1],
|
| | | }
|
| | | #仅查看自己的记录
|
| | | Def_ViewGameRecSelfList = [Def_GameRecType_ArenaRecord, Def_GameRecType_BatPreset, Def_GameRecType_Setting]
|
| | | Def_ViewGameRecSelfList = [Def_GameRecType_ArenaRecord, Def_GameRecType_BatPreset, Def_GameRecType_Setting, Def_GameRecType_QunyingRecord]
|
| | |
|
| | | #UserData不使用json的记录类型
|
| | | UserDataNOJsonRecTypeList = []
|
| | |
| | | BatPresetList = (
|
| | | BatPreset_Main, # 主线战斗 1
|
| | | BatPreset_ArenaDef, # 演武场防守 2
|
| | | ) = range(1, 1 + 2)
|
| | | BatPreset_QunyingDef, # 群英榜防守 3
|
| | | ) = range(1, 1 + 3)
|
| | |
|
| | | # 需要缓存的战斗功能预设,一般只要主线+防守功能预设,主动攻击的PVE功能可以不用,如某个副本的主动攻击预设
|
| | | NeedCacheBatPresetList = [BatPreset_Main, BatPreset_ArenaDef]
|
| | | NeedCacheBatPresetList = [BatPreset_Main, BatPreset_ArenaDef, BatPreset_QunyingDef]
|
| | |
|
| | | BatPresetName = {BatPreset_Main:"主线", BatPreset_ArenaDef:"演武场防守"}
|
| | | BatPresetName = {BatPreset_Main:"主线", BatPreset_ArenaDef:"演武场防守", BatPreset_QunyingDef:"群英榜防守"}
|
| | |
|
| | | # 功能预设定义
|
| | | FuncPresetList = (
|