129 【战斗】战斗系统-服务端(新增演武场;支持机器人;支持PVP战斗;每场战斗结束后支持查看战斗回放;榜单优化存储玩家形象Value5;主线关卡榜支持;支持查看玩家;)
27个文件已修改
2个文件已删除
2个文件已添加
2862 ■■■■■ 已修改文件
PySysDB/PySysDBPY.h 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py 134 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py 98 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py 1036 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/DBStruct.py 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/StructData/DBFamily.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/StructData/DBGameRec.py 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/StructData/DBPlayerViewCache.py 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Arena.py 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Billboard.py 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/CreateFamily.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Robot.py 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_Arena.py 207 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MainLevel.py 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ChItem.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/Item_AddArenaBattleCount.py 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerArena.py 568 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerBillboard.py 78 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerOnline.py 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerViewCache.py 119 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_Arena.py 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/Collections/DataServerPlayerData.py 229 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/GMToolLogicProcess/ProjSpecialProcess.py 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
PySysDB/PySysDBPY.h
@@ -3292,3 +3292,10 @@
    BYTE        NeedSeconds;    //耗时秒
};
//机器人
struct    Robot
{
    DWORD        _ID;    //机器人ID,同玩家ID
    char        ViewCache;    //机器人缓存
};
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
@@ -513,7 +513,7 @@
Writer = hxp
Releaser = hxp
RegType = 0
RegisterPackCount = 25
RegisterPackCount = 26
PacketCMD_1 = 0xA5
PacketSubCMD_1 = 0x04
@@ -614,6 +614,10 @@
PacketCMD_25=0xA1
PacketSubCMD_25=0x20
PacketCallFunc_25=OnMoneyExchange
PacketCMD_26=0xA0
PacketSubCMD_26=0x08
PacketCallFunc_26=OnViewGameRec
;签到
[PlayerSignDay]
@@ -1282,9 +1286,9 @@
PacketSubCMD_1=0x09
PacketCallFunc_1=OnArenaMatch
PacketCMD_2=0xB2
PacketSubCMD_2=0x10
PacketCallFunc_2=OnArenaBattle
PacketCMD_2=
PacketSubCMD_2=
PacketCallFunc_2=
;节日祝福
[PlayerFeastWish]
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/TurnAttack.py
@@ -21,6 +21,7 @@
import ChConfig
import PlayerTask
import PlayerViewCache
import ChPyNetSendPack
import NetPackCommon
import PlayerControl
@@ -162,26 +163,43 @@
        self.startTime = 0 # 开始时间戳,支持毫秒小数
        self.costTime = 0 # 单场战斗总耗时,支持毫秒小数
        
        # 多小队 - 一般只有PVE用到
        # pve 多小队 - 一般只有PVE用到
        self.lineupIndex = 0 # 当前小队索引
        self.lineupIDList = [] # npc小队列表
        self.strongerLV = 0 # npc成长等级
        self.difficulty = 0 # npc难度
        # pvp 目标
        self.tagPlayerID = 0
        self.tagViewCache = None
        return
    
    def setTurnFight(self, mapID, funcLineID, turnMax, isNeedReport=False, msgDict={}, lineupIDList=[], strongerLV=0, difficulty=0):
    def setTurnFight(self, mapID, funcLineID, turnMax, isNeedReport=False, msgDict={}):
        ## 设置本场回合战斗设定
        self.mapID = mapID
        self.funcLineID = funcLineID
        self.turnMax = turnMax # 最大回合数
        self.isNeedReport = isNeedReport
        self.setPVE()
        self.setPVP()
        self.msgDict = {}
        self.nextTurnFight(msgDict)
        return
    def setPVE(self, lineupIDList=[], strongerLV=0, difficulty=0):
        self.lineupIndex = 0
        self.lineupIDList = lineupIDList
        self.strongerLV = strongerLV
        self.difficulty = difficulty
        self.msgDict = {}
        self.nextTurnFight(msgDict)
        return
    def setPVP(self, tagPlayerID=0, tagViewCache=None):
        self.tagPlayerID = tagPlayerID
        self.tagViewCache = tagViewCache
        return
    #def setPVPTeam(self):
    #    return
    
    def nextTurnFight(self, msgDict={}, resetByNextTeam=False):
        ## 一般用于玩家发起的战斗,在需要保留玩家阵容属性及状态的情况下,重置回合进入下一场战斗
@@ -481,10 +499,30 @@
                          % (chapterID, levelNum, nowChapterID, fixNowValue), curPlayer.GetPlayerID())
    return
def GetPlayerLineupInfoByCache(playerID, lineupID):
    ## 获取玩家阵容信息 - 根据玩家查看缓存
    lineupInfo = {}
def GetCacheLineupFightPower(tagViewCache, lineupID):
    lineupInfo = GetCacheLineupInfo(tagViewCache, lineupID)
    return lineupInfo.get("FightPower", 0)
def GetCacheLineupInfo(tagViewCache, lineupID):
    ## 根据查看缓存获取阵容信息,一般是 GetPlayerLineupInfo 返回的结果
    plusDict = tagViewCache.GetPlusDict()
    lineupDict = plusDict.get("Lineup", {})
    lineupInfo = lineupDict.get("%s" % lineupID, {})
    if not lineupInfo:
        lineupInfo = lineupDict.get("%s" % ShareDefine.Lineup_Main, {})
    return lineupInfo
def GetPlayerLineupFightPower(curPlayer, lineupID):
    ## 获取玩家阵容战力,一般用于直接获取阵容战力记录用
    return GetPlayerLineup(curPlayer, lineupID).fightPower
def GetPlayerLineup(curPlayer, lineupID):
    ## 获取玩家阵容
    olPlayer = PlayerOnline.GetOnlinePlayer(curPlayer)
    lineup = olPlayer.GetLineup(lineupID)
    if not lineup.lineupHeroDict:
        # 为空时默认取主阵容
        lineup = olPlayer.GetLineup(ShareDefine.Lineup_Main)
    return lineup
def GetPlayerLineupInfo(curPlayer, lineupID):
    ## 获取玩家阵容信息,可用于战斗或查看缓存,因为可能取玩家的缓存进行对战,所以统一使用json格式,前端通用
@@ -492,11 +530,10 @@
    # @return: 阵容全部信息json字典,前端通用格式
    
    playerID = curPlayer.GetPlayerID()
    lineup = PlayerOnline.GetOnlinePlayer(curPlayer).GetLineup(lineupID)
    lineup = GetPlayerLineup(curPlayer, lineupID)
    if not lineup.lineupHeroDict:
        return {}
    
    lineupInfo = {"PlayerID":playerID, "FightPower":lineup.fightPower, "ShapeType":lineup.shapeType}
    heroDict = {}
    curPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptHero)
    for posNum in lineup.lineupHeroDict.keys():
@@ -522,8 +559,11 @@
                                 "AttrDict":{str(k):v for k, v in hero.heroBatAttrDict.items() if v > 0},
                                 "SkillIDList":skillIDlist,
                                 }
    lineupInfo.update({"Hero":heroDict})
    
    if not heroDict:
        return {}
    lineupInfo = {"PlayerID":playerID, "FightPower":lineup.fightPower, "ShapeType":lineup.shapeType, "Hero":heroDict}
    return lineupInfo
def GetNPCLineupInfo(lineupID, strongerLV=0, difficulty=0):
@@ -633,7 +673,7 @@
            if skillID:
                skillIDList.append(skillID)
                
    awakeIpyDataList = IpyGameDataPY.GetIpyGameDataList("HeroAwake", heroID)
    awakeIpyDataList = IpyGameDataPY.GetIpyGameDataListNotLog("HeroAwake", heroID)
    if awakeIpyDataList:
        for awakeIpyData in awakeIpyDataList:
            if awakeIpyData.GetAwakeLV() > awakeLV:
@@ -827,8 +867,7 @@
        
    # 玩家
    if tagType == 1:
        # OnTurnFightVSPlayer
        pass
        OnTurnFightVSPlayer(curPlayer, mapID, funcLineID, atkLineupID, defLineupID, tagID)
    
    # NPC
    else:
@@ -852,9 +891,8 @@
        GameWorld.DebugLog("玩家没有该阵容数据! atkLineupID=%s" % atkLineupID, playerID)
        return
    
    turnMax = 15
    turnMax = GetTurnMax(mapID)
    if mapID == ChConfig.Def_FBMapID_MainBoss:
        turnMax = IpyGameDataPY.GetFuncCfg("Mainline", 3)
        # 停止主线小怪战斗、清空
        mainFightMgr = GetMainFightMgr(curPlayer)
        mainTF = mainFightMgr.turnFight
@@ -865,7 +903,8 @@
    turnFight = tfMgr.addTurnFight(mapID, funcLineID, playerID)
    guid = turnFight.guid
    
    turnFight.setTurnFight(mapID, funcLineID, turnMax, True, lineupIDList=npcLineupIDList, strongerLV=strongerLV, difficulty=difficulty)
    turnFight.setTurnFight(mapID, funcLineID, turnMax, True)
    turnFight.setPVE(npcLineupIDList, strongerLV, difficulty)
    turnFight.setFactionLineup(ChConfig.Def_FactionA, {1:lineupMainInfo})
    
    for index, lineupID in enumerate(npcLineupIDList):
@@ -882,9 +921,54 @@
        if not turnFight.isWin:
            break
        
    PlayerOnline.GetOnlinePlayer(curPlayer).SetLastBatBuffer(guid, turnFight.batBuffer)
    SyncTurnFightReport(curPlayer, guid, turnFight.batBuffer)
    tfMgr.delTurnFight(guid)
    return
def OnTurnFightVSPlayer(curPlayer, mapID, funcLineID, atkLineupID, defLineupID, tagPlayerID):
    playerID = curPlayer.GetPlayerID()
    GameWorld.DebugLog("OnTurnFightVSPlayer: mapID=%s,funcLineID=%s,atkLineupID=%s,defLineupID=%s,tagPlayerID=%s"
                       % (mapID, funcLineID, atkLineupID, defLineupID, tagPlayerID), playerID)
    atkLineupInfo = GetPlayerLineupInfo(curPlayer, atkLineupID)
    if not atkLineupInfo:
        GameWorld.DebugLog("玩家没有该阵容数据! atkLineupID=%s" % atkLineupID, playerID)
        return
    tagViewCache = PlayerViewCache.FindViewCache(tagPlayerID)
    if not tagViewCache:
        GameWorld.DebugLog("目标玩家没有缓存数据! tagPlayerID=%s" % tagPlayerID, playerID)
        return {}
    defLineupInfo = GetCacheLineupInfo(tagViewCache, defLineupID)
    if not defLineupInfo:
        GameWorld.DebugLog("目标玩家没有该阵容数据! tagPlayerID=%s,defLineupID=%s" % (tagPlayerID, defLineupID), playerID)
        return
    turnMax = GetTurnMax(mapID)
    tfMgr = GetTurnFightMgr()
    turnFight = tfMgr.addTurnFight(mapID, funcLineID, playerID)
    guid = turnFight.guid
    turnFight.setTurnFight(mapID, funcLineID, turnMax, True)
    turnFight.setPVP(tagPlayerID, tagViewCache)
    turnFight.setFactionLineup(ChConfig.Def_FactionA, {1:atkLineupInfo})
    turnFight.setFactionLineup(ChConfig.Def_FactionB, {1:defLineupInfo})
    turnFight.sortActionQueue()
    turnFight.startFight()
    __processTurnFight(turnFight.guid)
    PlayerOnline.GetOnlinePlayer(curPlayer).SetLastBatBuffer(guid, turnFight.batBuffer)
    SyncTurnFightReport(curPlayer, guid, turnFight.batBuffer)
    tfMgr.delTurnFight(guid)
    return
def GetTurnMax(mapID):
    if mapID == ChConfig.Def_FBMapID_Main:
        return IpyGameDataPY.GetFuncCfg("TurnMax", 1)
    mapTurnMaxDict= IpyGameDataPY.GetFuncEvalCfg("TurnMax", 3, {})
    return mapTurnMaxDict.get(mapID, IpyGameDataPY.GetFuncCfg("TurnMax", 2))
#// B4 13 主线战斗请求 #tagCSMainFightReq
#
@@ -997,13 +1081,14 @@
    mainFightMgr.levelNum = levelNum
    mainFightMgr.waveMax = waveMax
    mainFightMgr.wave = wave
    turnMax = IpyGameDataPY.GetFuncCfg("Mainline", 2)
    mapID, funcLineID = ChConfig.Def_FBMapID_Main, PlayerControl.ComMainLevelValue(chapterID, levelNum, wave)
    turnMax = GetTurnMax(mapID)
    GameWorld.DebugLog("设置起始关卡波: 关卡%s-%s,波=%s/%s,lineupIDList=%s,mapID=%s,funcLineID=%s,lineupID=%s,strongerLV=%s,difficulty=%s" 
                       % (chapterID, levelNum, wave, waveMax, lineupIDList, mapID, funcLineID, lineupID, strongerLV, difficulty), playerID)
    
    turnFight = mainFightMgr.turnFight
    turnFight.setTurnFight(mapID, funcLineID, turnMax, False, lineupIDList=lineupIDList, strongerLV=strongerLV, difficulty=difficulty)
    turnFight.setTurnFight(mapID, funcLineID, turnMax, False)
    turnFight.setPVE(lineupIDList, strongerLV, difficulty)
    turnFight.setFactionLineup(ChConfig.Def_FactionA, {1:lineupMainInfo})
    turnFight.setFactionLineup(ChConfig.Def_FactionB, {1:GetNPCLineupInfo(lineupID, strongerLV, difficulty)})
    turnFight.sortActionQueue()
@@ -1589,10 +1674,19 @@
#    char        GUID[40];    //战报guid
#};
def OnTurnFightReportView(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    guid = clientData.GUID
    
    # 通过查找已存在的战报
    lastBatBufferInfo = PlayerOnline.GetOnlinePlayer(curPlayer).GetLastBatBuffer()
    if lastBatBufferInfo and len(lastBatBufferInfo) == 2 and guid == lastBatBufferInfo[0]:
        guid, reprot = lastBatBufferInfo
        SyncTurnFightReport(curPlayer, guid, reprot)
        return
    
    #SyncTurnFightReport(curPlayer, guid, reprot)
    # 其他战报,一般是入库存储的,待扩展
    # 战报已过期
    PlayerControl.NotifyCode(curPlayer, "FightReportExpired")
    return
def SyncTurnFightReport(curPlayer, guid, reprot):
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -1894,6 +1894,7 @@
Def_FBMapID_Main = 1 # 主线小怪
Def_FBMapID_MainBoss = 2 # 主线Boss
Def_FBMapID_ArenaBattle = 3 # 演武场
#创角新手村地图ID列表
Def_CreatRoleMapIDList = [10000]
@@ -2001,18 +2002,16 @@
Def_FBMapID_CrossBattlefield = 32060
#跨服仙盟夺旗战/逐鹿万界
Def_FBMapID_CrossFamilyFlagwar = 32090
#竞技场战斗
Def_FBMapID_ArenaBattle = 31290
#情缘副本
Def_FBMapID_Love = 31300
#镜像切磋
Def_FBMapID_MirrorBattle = 100
#前端自定义场景地图
ClientCustomSceneList = [Def_FBMapID_PersonalBoss, Def_FBMapID_ArenaBattle, Def_FBMapID_MirrorBattle]
ClientCustomSceneList = []
#镜像PK的地图ID列表
MirrorBattleMapIDList = [Def_FBMapID_MirrorBattle, Def_FBMapID_ArenaBattle, Def_FBMapID_CrossRealmPK, Def_FBMapID_CrossChampionship]
MirrorBattleMapIDList = []
#注册上传跨服服务器数据后直接进入跨服服务器的地图
RegisterEnter_CrossServerMapIDList = [Def_FBMapID_CrossPenglai, Def_FBMapID_CrossDemonLand, Def_FBMapID_CrossDemonKing, 
@@ -2108,6 +2107,7 @@
Def_FB_MapID = {
                'MainLevel':[Def_FBMapID_Main],  # 主线关卡
                'MainLevelBoss':[Def_FBMapID_MainBoss],  # 主线关卡boss
                'Arena':[Def_FBMapID_ArenaBattle],
                }
#特殊副本ID, 由系统分配, 进入时候不验证IsMapCopyFull
@@ -4085,13 +4085,7 @@
Def_PDict_SkillElementLV = "SkillElementLV%s" #专精技能技能等级  参数技能ID
#竞技场
Def_PDict_ArenaOSSeasonState = "ArenaOSSeasonState" # 开服前定制X天赛季状态  0-未比赛过,1-进行中,>1结算时的开服天
Def_PDict_ArenaScore = "ArenaScore" # 当前积分
Def_PDict_ArenaHighestScore = "ArenaHighestScore" # 历史最高积分
Def_PDict_ArenaBattleCountDay = "ArenaBattleCountDay" # 今日已战斗次数
Def_PDict_ArenaMatchRefreshCount = "ArenaMatchRefreshCount" # 匹配刷新列表次数
Def_PDict_ArenaItemAddCount = "ArenaItemAddCount" # 今日已使用物品增加次数
Def_PDict_ArenaBattleTagID = "ArenaBattleTagID" # 当前对战的对手ID
#功能系统特权
Def_PDict_FuncSysPrivilegeActTime = "FuncSysPrivilegeActTime_%s" # 系统功能特权激活时间戳,参数(系统功能ID)
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
@@ -275,20 +275,21 @@
#------------------------------------------------------
#A0 01 查看玩家信息通用记录 #tagViewUniversalGameRec
# A0 08 查看通用记录 #tagCSViewGameRec
class  tagViewUniversalGameRec(Structure):
class  tagCSViewGameRec(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("ViewType", c_ubyte),    #查看记录的类型
                  ("RecType", c_ushort),    #记录类型
                  ("RecID", c_int),    #自定义记录ID
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xA0
        self.SubCmd = 0x01
        self.SubCmd = 0x08
        return
    def ReadData(self, stringData, _pos=0, _len=0):
@@ -298,32 +299,35 @@
    def Clear(self):
        self.Cmd = 0xA0
        self.SubCmd = 0x01
        self.ViewType = 0
        self.SubCmd = 0x08
        self.RecType = 0
        self.RecID = 0
        return
    def GetLength(self):
        return sizeof(tagViewUniversalGameRec)
        return sizeof(tagCSViewGameRec)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''//A0 01 查看玩家信息通用记录 //tagViewUniversalGameRec:
        DumpString = '''// A0 08 查看通用记录 //tagCSViewGameRec:
                                Cmd:%s,
                                SubCmd:%s,
                                ViewType:%d
                                RecType:%d,
                                RecID:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.ViewType
                                self.RecType,
                                self.RecID
                                )
        return DumpString
m_NAtagViewUniversalGameRec=tagViewUniversalGameRec()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagViewUniversalGameRec.Cmd,m_NAtagViewUniversalGameRec.SubCmd))] = m_NAtagViewUniversalGameRec
m_NAtagCSViewGameRec=tagCSViewGameRec()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCSViewGameRec.Cmd,m_NAtagCSViewGameRec.SubCmd))] = m_NAtagCSViewGameRec
#------------------------------------------------------
@@ -14015,70 +14019,14 @@
#------------------------------------------------------
# B2 10 竞技场挑战玩家 #tagCMArenaBattle
# B2 09 演武场匹配玩家 #tagCSArenaMatch
class  tagCMArenaBattle(Structure):
class  tagCSArenaMatch(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("TagPlayerID", c_int),    # 目标玩家ID或机器人ID
                  ("Result", c_ubyte),    # 0-进入自定义场景发送通知后端;1-胜利(后端处理,暂时不需要发送此状态);2-失败(前端被对手击杀需要发送此状态)
                  ]
    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.TagPlayerID = 0
        self.Result = 0
        return
    def GetLength(self):
        return sizeof(tagCMArenaBattle)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// B2 10 竞技场挑战玩家 //tagCMArenaBattle:
                                Cmd:%s,
                                SubCmd:%s,
                                TagPlayerID:%d,
                                Result:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.TagPlayerID,
                                self.Result
                                )
        return DumpString
m_NAtagCMArenaBattle=tagCMArenaBattle()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMArenaBattle.Cmd,m_NAtagCMArenaBattle.SubCmd))] = m_NAtagCMArenaBattle
#------------------------------------------------------
# B2 09 竞技场匹配玩家 #tagCMArenaMatch
class  tagCMArenaMatch(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("IsRefresh", c_ubyte),    # 0-打开界面无匹配数据时时查询,1-强制刷新匹配列表
                  ("IsRefresh", c_ubyte),    # 0-打开界面无匹配数据时查询,1-强制刷新匹配列表
                  ]
    def __init__(self):
@@ -14099,13 +14047,13 @@
        return
    def GetLength(self):
        return sizeof(tagCMArenaMatch)
        return sizeof(tagCSArenaMatch)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// B2 09 竞技场匹配玩家 //tagCMArenaMatch:
        DumpString = '''// B2 09 演武场匹配玩家 //tagCSArenaMatch:
                                Cmd:%s,
                                SubCmd:%s,
                                IsRefresh:%d
@@ -14118,8 +14066,8 @@
        return DumpString
m_NAtagCMArenaMatch=tagCMArenaMatch()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMArenaMatch.Cmd,m_NAtagCMArenaMatch.SubCmd))] = m_NAtagCMArenaMatch
m_NAtagCSArenaMatch=tagCSArenaMatch()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCSArenaMatch.Cmd,m_NAtagCSArenaMatch.SubCmd))] = m_NAtagCSArenaMatch
#------------------------------------------------------
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
@@ -193,6 +193,197 @@
#------------------------------------------------------
# A0 09 通用记录信息 #tagSCGameRecInfo
class  tagSCGameRec(Structure):
    Time = 0    #(DWORD Time)//时间
    Value1 = 0    #(DWORD Value1)//ֵ1
    Value2 = 0    #(DWORD Value2)//ֵ2
    Value3 = 0    #(DWORD Value3)//ֵ3
    Value4 = 0    #(DWORD Value4)//ֵ4
    Value5 = 0    #(DWORD Value5)//ֵ5
    Value6 = 0    #(DWORD Value6)//ֵ6
    Value7 = 0    #(DWORD Value7)//ֵ7
    Value8 = 0    #(DWORD Value8)//ֵ8
    UserDataLen = 0    #(WORD UserDataLen)//扩展数据长度
    UserData = ""    #(String UserData)//扩展数据
    data = None
    def __init__(self):
        self.Clear()
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        self.Time,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.Value1,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.Value2,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.Value3,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.Value4,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.Value5,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.Value6,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.Value7,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.Value8,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.UserDataLen,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.UserData,_pos = CommFunc.ReadString(_lpData, _pos,self.UserDataLen)
        return _pos
    def Clear(self):
        self.Time = 0
        self.Value1 = 0
        self.Value2 = 0
        self.Value3 = 0
        self.Value4 = 0
        self.Value5 = 0
        self.Value6 = 0
        self.Value7 = 0
        self.Value8 = 0
        self.UserDataLen = 0
        self.UserData = ""
        return
    def GetLength(self):
        length = 0
        length += 4
        length += 4
        length += 4
        length += 4
        length += 4
        length += 4
        length += 4
        length += 4
        length += 4
        length += 2
        length += len(self.UserData)
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteDWORD(data, self.Time)
        data = CommFunc.WriteDWORD(data, self.Value1)
        data = CommFunc.WriteDWORD(data, self.Value2)
        data = CommFunc.WriteDWORD(data, self.Value3)
        data = CommFunc.WriteDWORD(data, self.Value4)
        data = CommFunc.WriteDWORD(data, self.Value5)
        data = CommFunc.WriteDWORD(data, self.Value6)
        data = CommFunc.WriteDWORD(data, self.Value7)
        data = CommFunc.WriteDWORD(data, self.Value8)
        data = CommFunc.WriteWORD(data, self.UserDataLen)
        data = CommFunc.WriteString(data, self.UserDataLen, self.UserData)
        return data
    def OutputString(self):
        DumpString = '''
                                Time:%d,
                                Value1:%d,
                                Value2:%d,
                                Value3:%d,
                                Value4:%d,
                                Value5:%d,
                                Value6:%d,
                                Value7:%d,
                                Value8:%d,
                                UserDataLen:%d,
                                UserData:%s
                                '''\
                                %(
                                self.Time,
                                self.Value1,
                                self.Value2,
                                self.Value3,
                                self.Value4,
                                self.Value5,
                                self.Value6,
                                self.Value7,
                                self.Value8,
                                self.UserDataLen,
                                self.UserData
                                )
        return DumpString
class  tagSCGameRecInfo(Structure):
    Head = tagHead()
    RecType = 0    #(WORD RecType)//记录类型
    RecID = 0    #(DWORD RecID)//自定义记录ID
    Count = 0    #(WORD Count)//数量
    RecList = list()    #(vector<tagSCGameRec> RecList)
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xA0
        self.Head.SubCmd = 0x09
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.RecType,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.RecID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.Count,_pos = CommFunc.ReadWORD(_lpData, _pos)
        for i in range(self.Count):
            temRecList = tagSCGameRec()
            _pos = temRecList.ReadData(_lpData, _pos)
            self.RecList.append(temRecList)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xA0
        self.Head.SubCmd = 0x09
        self.RecType = 0
        self.RecID = 0
        self.Count = 0
        self.RecList = list()
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 2
        length += 4
        length += 2
        for i in range(self.Count):
            length += self.RecList[i].GetLength()
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteWORD(data, self.RecType)
        data = CommFunc.WriteDWORD(data, self.RecID)
        data = CommFunc.WriteWORD(data, self.Count)
        for i in range(self.Count):
            data = CommFunc.WriteString(data, self.RecList[i].GetLength(), self.RecList[i].GetBuffer())
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                RecType:%d,
                                RecID:%d,
                                Count:%d,
                                RecList:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.RecType,
                                self.RecID,
                                self.Count,
                                "..."
                                )
        return DumpString
m_NAtagSCGameRecInfo=tagSCGameRecInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagSCGameRecInfo.Head.Cmd,m_NAtagSCGameRecInfo.Head.SubCmd))] = m_NAtagSCGameRecInfo
#------------------------------------------------------
# A0 07 副本地图功能线路人数 #tagGCFBLinePlayerCnt
class  tagGCFBLineInfo(Structure):
@@ -421,190 +612,6 @@
m_NAtagOpenServerDay=tagOpenServerDay()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagOpenServerDay.Cmd,m_NAtagOpenServerDay.SubCmd))] = m_NAtagOpenServerDay
#------------------------------------------------------
# A0 08 玩家记录信息 #tagGCPlayerRecInfo
class  tagGCPlayerRec(Structure):
    Time = 0    #(DWORD Time)//时间
    Value1 = 0    #(DWORD Value1)//ֵ1
    Value2 = 0    #(DWORD Value2)//ֵ2
    Value3 = 0    #(DWORD Value3)//ֵ3
    Value4 = 0    #(DWORD Value4)//ֵ4
    Value5 = 0    #(DWORD Value5)//ֵ5
    Value6 = 0    #(DWORD Value6)//ֵ6
    Value7 = 0    #(DWORD Value7)//ֵ7
    Value8 = 0    #(DWORD Value8)//ֵ8
    UserDataLen = 0    #(WORD UserDataLen)//扩展数据长度
    UserData = ""    #(String UserData)//扩展数据
    data = None
    def __init__(self):
        self.Clear()
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        self.Time,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.Value1,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.Value2,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.Value3,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.Value4,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.Value5,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.Value6,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.Value7,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.Value8,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.UserDataLen,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.UserData,_pos = CommFunc.ReadString(_lpData, _pos,self.UserDataLen)
        return _pos
    def Clear(self):
        self.Time = 0
        self.Value1 = 0
        self.Value2 = 0
        self.Value3 = 0
        self.Value4 = 0
        self.Value5 = 0
        self.Value6 = 0
        self.Value7 = 0
        self.Value8 = 0
        self.UserDataLen = 0
        self.UserData = ""
        return
    def GetLength(self):
        length = 0
        length += 4
        length += 4
        length += 4
        length += 4
        length += 4
        length += 4
        length += 4
        length += 4
        length += 4
        length += 2
        length += len(self.UserData)
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteDWORD(data, self.Time)
        data = CommFunc.WriteDWORD(data, self.Value1)
        data = CommFunc.WriteDWORD(data, self.Value2)
        data = CommFunc.WriteDWORD(data, self.Value3)
        data = CommFunc.WriteDWORD(data, self.Value4)
        data = CommFunc.WriteDWORD(data, self.Value5)
        data = CommFunc.WriteDWORD(data, self.Value6)
        data = CommFunc.WriteDWORD(data, self.Value7)
        data = CommFunc.WriteDWORD(data, self.Value8)
        data = CommFunc.WriteWORD(data, self.UserDataLen)
        data = CommFunc.WriteString(data, self.UserDataLen, self.UserData)
        return data
    def OutputString(self):
        DumpString = '''
                                Time:%d,
                                Value1:%d,
                                Value2:%d,
                                Value3:%d,
                                Value4:%d,
                                Value5:%d,
                                Value6:%d,
                                Value7:%d,
                                Value8:%d,
                                UserDataLen:%d,
                                UserData:%s
                                '''\
                                %(
                                self.Time,
                                self.Value1,
                                self.Value2,
                                self.Value3,
                                self.Value4,
                                self.Value5,
                                self.Value6,
                                self.Value7,
                                self.Value8,
                                self.UserDataLen,
                                self.UserData
                                )
        return DumpString
class  tagGCPlayerRecInfo(Structure):
    Head = tagHead()
    Type = 0    #(BYTE Type)//类型
    Count = 0    #(WORD Count)//数量
    PlayerRecList = list()    #(vector<tagGCPlayerRec> PlayerRecList)
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xA0
        self.Head.SubCmd = 0x08
        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.Count,_pos = CommFunc.ReadWORD(_lpData, _pos)
        for i in range(self.Count):
            temPlayerRecList = tagGCPlayerRec()
            _pos = temPlayerRecList.ReadData(_lpData, _pos)
            self.PlayerRecList.append(temPlayerRecList)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xA0
        self.Head.SubCmd = 0x08
        self.Type = 0
        self.Count = 0
        self.PlayerRecList = list()
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 1
        length += 2
        for i in range(self.Count):
            length += self.PlayerRecList[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.WriteWORD(data, self.Count)
        for i in range(self.Count):
            data = CommFunc.WriteString(data, self.PlayerRecList[i].GetLength(), self.PlayerRecList[i].GetBuffer())
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                Type:%d,
                                Count:%d,
                                PlayerRecList:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.Type,
                                self.Count,
                                "..."
                                )
        return DumpString
m_NAtagGCPlayerRecInfo=tagGCPlayerRecInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCPlayerRecInfo.Head.Cmd,m_NAtagGCPlayerRecInfo.Head.SubCmd))] = m_NAtagGCPlayerRecInfo
#------------------------------------------------------
@@ -923,197 +930,6 @@
m_NAtagServerGmMailInfo=tagServerGmMailInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagServerGmMailInfo.Head.Cmd,m_NAtagServerGmMailInfo.Head.SubCmd))] = m_NAtagServerGmMailInfo
#------------------------------------------------------
#A0 03 玩家信息通用记录 #tagUniversalGameRecInfo
class  tagUniversalGameRec(Structure):
    Time = 0    #(DWORD Time)//时间
    StrValue1Len = 0    #(WORD StrValue1Len)//字符串1长度
    StrValue1 = ""    #(String StrValue1)
    StrValue2Len = 0    #(WORD StrValue2Len)//字符串2长度
    StrValue2 = ""    #(String StrValue2)
    StrValue3Len = 0    #(WORD StrValue3Len)//字符串3长度
    StrValue3 = ""    #(String StrValue3)
    Value1 = 0    #(DWORD Value1)//数值1
    Value2 = 0    #(DWORD Value2)//数值1
    Value3 = 0    #(DWORD Value3)//数值1
    Value4 = 0    #(DWORD Value4)//数值1
    Value5 = 0    #(DWORD Value5)//数值1
    data = None
    def __init__(self):
        self.Clear()
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        self.Time,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.StrValue1Len,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.StrValue1,_pos = CommFunc.ReadString(_lpData, _pos,self.StrValue1Len)
        self.StrValue2Len,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.StrValue2,_pos = CommFunc.ReadString(_lpData, _pos,self.StrValue2Len)
        self.StrValue3Len,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.StrValue3,_pos = CommFunc.ReadString(_lpData, _pos,self.StrValue3Len)
        self.Value1,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.Value2,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.Value3,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.Value4,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.Value5,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        return _pos
    def Clear(self):
        self.Time = 0
        self.StrValue1Len = 0
        self.StrValue1 = ""
        self.StrValue2Len = 0
        self.StrValue2 = ""
        self.StrValue3Len = 0
        self.StrValue3 = ""
        self.Value1 = 0
        self.Value2 = 0
        self.Value3 = 0
        self.Value4 = 0
        self.Value5 = 0
        return
    def GetLength(self):
        length = 0
        length += 4
        length += 2
        length += len(self.StrValue1)
        length += 2
        length += len(self.StrValue2)
        length += 2
        length += len(self.StrValue3)
        length += 4
        length += 4
        length += 4
        length += 4
        length += 4
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteDWORD(data, self.Time)
        data = CommFunc.WriteWORD(data, self.StrValue1Len)
        data = CommFunc.WriteString(data, self.StrValue1Len, self.StrValue1)
        data = CommFunc.WriteWORD(data, self.StrValue2Len)
        data = CommFunc.WriteString(data, self.StrValue2Len, self.StrValue2)
        data = CommFunc.WriteWORD(data, self.StrValue3Len)
        data = CommFunc.WriteString(data, self.StrValue3Len, self.StrValue3)
        data = CommFunc.WriteDWORD(data, self.Value1)
        data = CommFunc.WriteDWORD(data, self.Value2)
        data = CommFunc.WriteDWORD(data, self.Value3)
        data = CommFunc.WriteDWORD(data, self.Value4)
        data = CommFunc.WriteDWORD(data, self.Value5)
        return data
    def OutputString(self):
        DumpString = '''
                                Time:%d,
                                StrValue1Len:%d,
                                StrValue1:%s,
                                StrValue2Len:%d,
                                StrValue2:%s,
                                StrValue3Len:%d,
                                StrValue3:%s,
                                Value1:%d,
                                Value2:%d,
                                Value3:%d,
                                Value4:%d,
                                Value5:%d
                                '''\
                                %(
                                self.Time,
                                self.StrValue1Len,
                                self.StrValue1,
                                self.StrValue2Len,
                                self.StrValue2,
                                self.StrValue3Len,
                                self.StrValue3,
                                self.Value1,
                                self.Value2,
                                self.Value3,
                                self.Value4,
                                self.Value5
                                )
        return DumpString
class  tagUniversalGameRecInfo(Structure):
    Head = tagHead()
    Type = 0    #(BYTE Type)//类型
    Count = 0    #(WORD Count)//数量
    UniversalGameRec = list()    #(vector<tagUniversalGameRec> UniversalGameRec)///size = Count
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xA0
        self.Head.SubCmd = 0x03
        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.Count,_pos = CommFunc.ReadWORD(_lpData, _pos)
        for i in range(self.Count):
            temUniversalGameRec = tagUniversalGameRec()
            _pos = temUniversalGameRec.ReadData(_lpData, _pos)
            self.UniversalGameRec.append(temUniversalGameRec)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xA0
        self.Head.SubCmd = 0x03
        self.Type = 0
        self.Count = 0
        self.UniversalGameRec = list()
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 1
        length += 2
        for i in range(self.Count):
            length += self.UniversalGameRec[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.WriteWORD(data, self.Count)
        for i in range(self.Count):
            data = CommFunc.WriteString(data, self.UniversalGameRec[i].GetLength(), self.UniversalGameRec[i].GetBuffer())
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                Type:%d,
                                Count:%d,
                                UniversalGameRec:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.Type,
                                self.Count,
                                "..."
                                )
        return DumpString
m_NAtagUniversalGameRecInfo=tagUniversalGameRecInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagUniversalGameRecInfo.Head.Cmd,m_NAtagUniversalGameRecInfo.Head.SubCmd))] = m_NAtagUniversalGameRecInfo
#------------------------------------------------------
@@ -3822,74 +3638,6 @@
m_NAtagMCAllEquipAttrActiveInfo=tagMCAllEquipAttrActiveInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCAllEquipAttrActiveInfo.Head.Cmd,m_NAtagMCAllEquipAttrActiveInfo.Head.SubCmd))] = m_NAtagMCAllEquipAttrActiveInfo
#------------------------------------------------------
# A3 C3 竞技场玩家信息 #tagMCArenaPlayerInfo
class  tagMCArenaPlayerInfo(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("IsReset", c_ubyte),    #是否是重置的
                  ("Score", c_int),    #当前积分
                  ("BattleCountToday", c_ubyte),    #今日已挑战次数
                  ("MatchRefreshCount", c_ubyte),    #当前已刷新匹配列表次数,每次挑战后会重置
                  ("ItemAddBattleCountToday", c_ubyte),    #今日已使用物品增加的挑战次数
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xA3
        self.SubCmd = 0xC3
        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 = 0xA3
        self.SubCmd = 0xC3
        self.IsReset = 0
        self.Score = 0
        self.BattleCountToday = 0
        self.MatchRefreshCount = 0
        self.ItemAddBattleCountToday = 0
        return
    def GetLength(self):
        return sizeof(tagMCArenaPlayerInfo)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// A3 C3 竞技场玩家信息 //tagMCArenaPlayerInfo:
                                Cmd:%s,
                                SubCmd:%s,
                                IsReset:%d,
                                Score:%d,
                                BattleCountToday:%d,
                                MatchRefreshCount:%d,
                                ItemAddBattleCountToday:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.IsReset,
                                self.Score,
                                self.BattleCountToday,
                                self.MatchRefreshCount,
                                self.ItemAddBattleCountToday
                                )
        return DumpString
m_NAtagMCArenaPlayerInfo=tagMCArenaPlayerInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCArenaPlayerInfo.Cmd,m_NAtagMCArenaPlayerInfo.SubCmd))] = m_NAtagMCArenaPlayerInfo
#------------------------------------------------------
@@ -17435,6 +17183,7 @@
    RealmLV = 0    #(BYTE RealmLV)
    Face = 0    #(DWORD Face)
    FacePic = 0    #(DWORD FacePic)
    ModelMark = 0    #(DWORD ModelMark)//变形模型mark
    TitleID = 0    #(DWORD TitleID)//佩戴的称号
    ServerID = 0    #(DWORD ServerID)
    FightPower = 0    #(DWORD FightPower)
@@ -17462,6 +17211,7 @@
        self.RealmLV,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.Face,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.FacePic,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.ModelMark,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.TitleID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.ServerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.FightPower,_pos = CommFunc.ReadDWORD(_lpData, _pos)
@@ -17485,6 +17235,7 @@
        self.RealmLV = 0
        self.Face = 0
        self.FacePic = 0
        self.ModelMark = 0
        self.TitleID = 0
        self.ServerID = 0
        self.FightPower = 0
@@ -17511,6 +17262,7 @@
        length += 4
        length += 4
        length += 4
        length += 4
        length += 33
        length += 4
        length += 4
@@ -17528,6 +17280,7 @@
        data = CommFunc.WriteBYTE(data, self.RealmLV)
        data = CommFunc.WriteDWORD(data, self.Face)
        data = CommFunc.WriteDWORD(data, self.FacePic)
        data = CommFunc.WriteDWORD(data, self.ModelMark)
        data = CommFunc.WriteDWORD(data, self.TitleID)
        data = CommFunc.WriteDWORD(data, self.ServerID)
        data = CommFunc.WriteDWORD(data, self.FightPower)
@@ -17549,6 +17302,7 @@
                                RealmLV:%d,
                                Face:%d,
                                FacePic:%d,
                                ModelMark:%d,
                                TitleID:%d,
                                ServerID:%d,
                                FightPower:%d,
@@ -17568,6 +17322,7 @@
                                self.RealmLV,
                                self.Face,
                                self.FacePic,
                                self.ModelMark,
                                self.TitleID,
                                self.ServerID,
                                self.FightPower,
@@ -18992,127 +18747,14 @@
#------------------------------------------------------
# A9 26 竞技场对战玩家最新信息 #tagGCArenaBattlePlayerInfo
# A9 22 演武场匹配玩家列表 #tagSCArenaMatchList
class  tagGCArenaBattlePlayerInfo(Structure):
    Head = tagHead()
class  tagSCArenaMatchInfo(Structure):
    PlayerID = 0    #(DWORD PlayerID)//目标玩家ID
    PlayerName = ""    #(char PlayerName[33])
    Job = 0    #(BYTE Job)
    LV = 0    #(WORD LV)//等级
    RealmLV = 0    #(WORD RealmLV)//境界,机器人读境界表取等级对应境界
    FightPower = 0    #(DWORD FightPower)//战力求余亿部分,机器人读等级表取等级对应战力
    FightPowerEx = 0    #(DWORD FightPowerEx)//战力整除亿部分,机器人读等级表取等级对应战力
    Score = 0    #(DWORD Score)//积分
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xA9
        self.Head.SubCmd = 0x26
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.PlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.PlayerName,_pos = CommFunc.ReadString(_lpData, _pos,33)
        self.Job,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.LV,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.RealmLV,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.FightPower,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.FightPowerEx,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.Score,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xA9
        self.Head.SubCmd = 0x26
        self.PlayerID = 0
        self.PlayerName = ""
        self.Job = 0
        self.LV = 0
        self.RealmLV = 0
        self.FightPower = 0
        self.FightPowerEx = 0
        self.Score = 0
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 4
        length += 33
        length += 1
        length += 2
        length += 2
        length += 4
        length += 4
        length += 4
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteDWORD(data, self.PlayerID)
        data = CommFunc.WriteString(data, 33, self.PlayerName)
        data = CommFunc.WriteBYTE(data, self.Job)
        data = CommFunc.WriteWORD(data, self.LV)
        data = CommFunc.WriteWORD(data, self.RealmLV)
        data = CommFunc.WriteDWORD(data, self.FightPower)
        data = CommFunc.WriteDWORD(data, self.FightPowerEx)
        data = CommFunc.WriteDWORD(data, self.Score)
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                PlayerID:%d,
                                PlayerName:%s,
                                Job:%d,
                                LV:%d,
                                RealmLV:%d,
                                FightPower:%d,
                                FightPowerEx:%d,
                                Score:%d
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.PlayerID,
                                self.PlayerName,
                                self.Job,
                                self.LV,
                                self.RealmLV,
                                self.FightPower,
                                self.FightPowerEx,
                                self.Score
                                )
        return DumpString
m_NAtagGCArenaBattlePlayerInfo=tagGCArenaBattlePlayerInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCArenaBattlePlayerInfo.Head.Cmd,m_NAtagGCArenaBattlePlayerInfo.Head.SubCmd))] = m_NAtagGCArenaBattlePlayerInfo
#------------------------------------------------------
# A9 23 竞技场对战记录列表 #tagGCArenaBattleRecordList
class  tagGCArenaBattleRecord(Structure):
    PlayerID = 0    #(DWORD PlayerID)//目标玩家ID,小于10000为机器人ID
    PlayerName = ""    #(char PlayerName[33])
    Job = 0    #(BYTE Job)
    LV = 0    #(WORD LV)//等级
    RealmLV = 0    #(WORD RealmLV)//境界,机器人读境界表取等级对应境界
    FightPower = 0    #(DWORD FightPower)//战力求余亿部分,机器人读等级表取等级对应战力
    FightPowerEx = 0    #(DWORD FightPowerEx)//战力整除亿部分,机器人读等级表取等级对应战力
    Score = 0    #(DWORD Score)//积分
    AddScoreLen = 0    #(BYTE AddScoreLen)
    AddScore = ""    #(String AddScore)//本次对战增加的积分,有正负
    IsWin = 0    #(BYTE IsWin)//是否获胜
    Time = 0    #(DWORD Time)//时间戳
    FightPower = 0    #(DWORD FightPower)//战力求余亿部分
    FightPowerEx = 0    #(DWORD FightPowerEx)//战力整除亿部分
    Face = 0    #(DWORD Face)//基本脸型
    FacePic = 0    #(DWORD FacePic)//头像框
    data = None
@@ -19125,16 +18767,9 @@
        self.Clear()
        self.PlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.PlayerName,_pos = CommFunc.ReadString(_lpData, _pos,33)
        self.Job,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.LV,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.RealmLV,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.FightPower,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.FightPowerEx,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.Score,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.AddScoreLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.AddScore,_pos = CommFunc.ReadString(_lpData, _pos,self.AddScoreLen)
        self.IsWin,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.Time,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.Face,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.FacePic,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        return _pos
@@ -19142,16 +18777,9 @@
    def Clear(self):
        self.PlayerID = 0
        self.PlayerName = ""
        self.Job = 0
        self.LV = 0
        self.RealmLV = 0
        self.FightPower = 0
        self.FightPowerEx = 0
        self.Score = 0
        self.AddScoreLen = 0
        self.AddScore = ""
        self.IsWin = 0
        self.Time = 0
        self.Face = 0
        self.FacePic = 0
        return
@@ -19160,196 +18788,7 @@
        length = 0
        length += 4
        length += 33
        length += 1
        length += 2
        length += 2
        length += 4
        length += 4
        length += 4
        length += 1
        length += len(self.AddScore)
        length += 1
        length += 4
        length += 4
        length += 4
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteDWORD(data, self.PlayerID)
        data = CommFunc.WriteString(data, 33, self.PlayerName)
        data = CommFunc.WriteBYTE(data, self.Job)
        data = CommFunc.WriteWORD(data, self.LV)
        data = CommFunc.WriteWORD(data, self.RealmLV)
        data = CommFunc.WriteDWORD(data, self.FightPower)
        data = CommFunc.WriteDWORD(data, self.FightPowerEx)
        data = CommFunc.WriteDWORD(data, self.Score)
        data = CommFunc.WriteBYTE(data, self.AddScoreLen)
        data = CommFunc.WriteString(data, self.AddScoreLen, self.AddScore)
        data = CommFunc.WriteBYTE(data, self.IsWin)
        data = CommFunc.WriteDWORD(data, self.Time)
        data = CommFunc.WriteDWORD(data, self.Face)
        data = CommFunc.WriteDWORD(data, self.FacePic)
        return data
    def OutputString(self):
        DumpString = '''
                                PlayerID:%d,
                                PlayerName:%s,
                                Job:%d,
                                LV:%d,
                                RealmLV:%d,
                                FightPower:%d,
                                FightPowerEx:%d,
                                Score:%d,
                                AddScoreLen:%d,
                                AddScore:%s,
                                IsWin:%d,
                                Time:%d,
                                Face:%d,
                                FacePic:%d
                                '''\
                                %(
                                self.PlayerID,
                                self.PlayerName,
                                self.Job,
                                self.LV,
                                self.RealmLV,
                                self.FightPower,
                                self.FightPowerEx,
                                self.Score,
                                self.AddScoreLen,
                                self.AddScore,
                                self.IsWin,
                                self.Time,
                                self.Face,
                                self.FacePic
                                )
        return DumpString
class  tagGCArenaBattleRecordList(Structure):
    Head = tagHead()
    RecordCount = 0    #(BYTE RecordCount)
    BattleRecordList = list()    #(vector<tagGCArenaBattleRecord> BattleRecordList)// 对战列表
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xA9
        self.Head.SubCmd = 0x23
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.RecordCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        for i in range(self.RecordCount):
            temBattleRecordList = tagGCArenaBattleRecord()
            _pos = temBattleRecordList.ReadData(_lpData, _pos)
            self.BattleRecordList.append(temBattleRecordList)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xA9
        self.Head.SubCmd = 0x23
        self.RecordCount = 0
        self.BattleRecordList = list()
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 1
        for i in range(self.RecordCount):
            length += self.BattleRecordList[i].GetLength()
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteBYTE(data, self.RecordCount)
        for i in range(self.RecordCount):
            data = CommFunc.WriteString(data, self.BattleRecordList[i].GetLength(), self.BattleRecordList[i].GetBuffer())
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                RecordCount:%d,
                                BattleRecordList:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.RecordCount,
                                "..."
                                )
        return DumpString
m_NAtagGCArenaBattleRecordList=tagGCArenaBattleRecordList()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCArenaBattleRecordList.Head.Cmd,m_NAtagGCArenaBattleRecordList.Head.SubCmd))] = m_NAtagGCArenaBattleRecordList
#------------------------------------------------------
# A9 22 竞技场匹配玩家列表 #tagGCArenaMatchList
class  tagGCArenaMatchInfo(Structure):
    PlayerID = 0    #(DWORD PlayerID)//目标玩家ID,小于10000为机器人ID
    PlayerName = ""    #(char PlayerName[33])
    Job = 0    #(BYTE Job)
    LV = 0    #(WORD LV)//等级
    RealmLV = 0    #(WORD RealmLV)//境界,机器人读境界表取等级对应境界
    FightPower = 0    #(DWORD FightPower)//战力求余亿部分,机器人读等级表取等级对应战力
    FightPowerEx = 0    #(DWORD FightPowerEx)//战力整除亿部分,机器人读等级表取等级对应战力
    Score = 0    #(DWORD Score)//积分
    Face = 0    #(DWORD Face)//基本脸型
    FacePic = 0    #(DWORD FacePic)//头像框
    data = None
    def __init__(self):
        self.Clear()
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        self.PlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.PlayerName,_pos = CommFunc.ReadString(_lpData, _pos,33)
        self.Job,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.LV,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.RealmLV,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.FightPower,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.FightPowerEx,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.Score,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.Face,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.FacePic,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        return _pos
    def Clear(self):
        self.PlayerID = 0
        self.PlayerName = ""
        self.Job = 0
        self.LV = 0
        self.RealmLV = 0
        self.FightPower = 0
        self.FightPowerEx = 0
        self.Score = 0
        self.Face = 0
        self.FacePic = 0
        return
    def GetLength(self):
        length = 0
        length += 4
        length += 33
        length += 1
        length += 2
        length += 2
        length += 4
        length += 4
        length += 4
        length += 4
@@ -19361,12 +18800,9 @@
        data = ''
        data = CommFunc.WriteDWORD(data, self.PlayerID)
        data = CommFunc.WriteString(data, 33, self.PlayerName)
        data = CommFunc.WriteBYTE(data, self.Job)
        data = CommFunc.WriteWORD(data, self.LV)
        data = CommFunc.WriteWORD(data, self.RealmLV)
        data = CommFunc.WriteDWORD(data, self.FightPower)
        data = CommFunc.WriteDWORD(data, self.FightPowerEx)
        data = CommFunc.WriteDWORD(data, self.Score)
        data = CommFunc.WriteDWORD(data, self.Face)
        data = CommFunc.WriteDWORD(data, self.FacePic)
        return data
@@ -19375,34 +18811,28 @@
        DumpString = '''
                                PlayerID:%d,
                                PlayerName:%s,
                                Job:%d,
                                LV:%d,
                                RealmLV:%d,
                                FightPower:%d,
                                FightPowerEx:%d,
                                Score:%d,
                                Face:%d,
                                FacePic:%d
                                '''\
                                %(
                                self.PlayerID,
                                self.PlayerName,
                                self.Job,
                                self.LV,
                                self.RealmLV,
                                self.FightPower,
                                self.FightPowerEx,
                                self.Score,
                                self.Face,
                                self.FacePic
                                )
        return DumpString
class  tagGCArenaMatchList(Structure):
class  tagSCArenaMatchList(Structure):
    Head = tagHead()
    MatchCount = 0    #(BYTE MatchCount)
    MatchList = list()    #(vector<tagGCArenaMatchInfo> MatchList)// 匹配列表
    MatchList = list()    #(vector<tagSCArenaMatchInfo> MatchList)// 匹配列表,从高分到低分
    data = None
    def __init__(self):
@@ -19416,7 +18846,7 @@
        _pos = self.Head.ReadData(_lpData, _pos)
        self.MatchCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        for i in range(self.MatchCount):
            temMatchList = tagGCArenaMatchInfo()
            temMatchList = tagSCArenaMatchInfo()
            _pos = temMatchList.ReadData(_lpData, _pos)
            self.MatchList.append(temMatchList)
        return _pos
@@ -19461,8 +18891,60 @@
        return DumpString
m_NAtagGCArenaMatchList=tagGCArenaMatchList()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCArenaMatchList.Head.Cmd,m_NAtagGCArenaMatchList.Head.SubCmd))] = m_NAtagGCArenaMatchList
m_NAtagSCArenaMatchList=tagSCArenaMatchList()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagSCArenaMatchList.Head.Cmd,m_NAtagSCArenaMatchList.Head.SubCmd))] = m_NAtagSCArenaMatchList
#------------------------------------------------------
# A9 23 演武场玩家信息 #tagSCArenaPlayerInfo
class  tagSCArenaPlayerInfo(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("Score", c_int),    #当前积分
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xA9
        self.SubCmd = 0x23
        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 = 0x23
        self.Score = 0
        return
    def GetLength(self):
        return sizeof(tagSCArenaPlayerInfo)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// A9 23 演武场玩家信息 //tagSCArenaPlayerInfo:
                                Cmd:%s,
                                SubCmd:%s,
                                Score:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.Score
                                )
        return DumpString
m_NAtagSCArenaPlayerInfo=tagSCArenaPlayerInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagSCArenaPlayerInfo.Cmd,m_NAtagSCArenaPlayerInfo.SubCmd))] = m_NAtagSCArenaPlayerInfo
#------------------------------------------------------
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/DBStruct.py
@@ -1126,6 +1126,7 @@
        ('RealmLV', ctypes.c_ubyte),
        ('Face', ctypes.c_int),
        ('FacePic', ctypes.c_int),
        ('ModelMark', ctypes.c_ulong),
        ('FamilyID', ctypes.c_ulong),
        ('FamilyName', ctypes.c_char * 33),
        ('FamilyEmblemID', ctypes.c_ushort),
@@ -1152,6 +1153,7 @@
        self.RealmLV = 0
        self.Face = 0
        self.FacePic = 0
        self.ModelMark = 0
        self.FamilyID = 0
        self.FamilyName = ''
        self.FamilyEmblemID = 0
@@ -1177,6 +1179,7 @@
        self.RealmLV, pos = CommFunc.ReadBYTE(buf, pos)
        self.Face, pos = CommFunc.ReadDWORD(buf, pos)
        self.FacePic, pos = CommFunc.ReadDWORD(buf, pos)
        self.ModelMark, pos = CommFunc.ReadDWORD(buf, pos)
        self.FamilyID, pos = CommFunc.ReadDWORD(buf, pos)
        self.FamilyName, pos = CommFunc.ReadString(buf, pos, 33)
        self.FamilyEmblemID, pos = CommFunc.ReadWORD(buf, pos)
@@ -1200,6 +1203,7 @@
        buf = CommFunc.WriteBYTE(buf, self.RealmLV)
        buf = CommFunc.WriteDWORD(buf, self.Face)
        buf = CommFunc.WriteDWORD(buf, self.FacePic)
        buf = CommFunc.WriteDWORD(buf, self.ModelMark)
        buf = CommFunc.WriteDWORD(buf, self.FamilyID)
        buf = CommFunc.WriteString(buf, sizeof(ctypes.c_char) * 33, self.FamilyName)
        buf = CommFunc.WriteWORD(buf, self.FamilyEmblemID)
@@ -1223,6 +1227,7 @@
        length += sizeof(ctypes.c_int)
        length += sizeof(ctypes.c_int)
        length += sizeof(ctypes.c_ulong)
        length += sizeof(ctypes.c_ulong)
        length += sizeof(ctypes.c_char) * 33
        length += sizeof(ctypes.c_ushort)
        length += sizeof(ctypes.c_ulong)
@@ -1244,6 +1249,7 @@
            RealmLV = %s,
            Face = %s,
            FacePic = %s,
            ModelMark = %s,
            FamilyID = %s,
            FamilyName = %s,
            FamilyEmblemID = %s,
@@ -1264,6 +1270,7 @@
                self.RealmLV,
                self.Face,
                self.FacePic,
                self.ModelMark,
                self.FamilyID,
                self.FamilyName,
                self.FamilyEmblemID,
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/StructData/DBFamily.py
@@ -490,7 +490,7 @@
                self.__familyList.remove(family)
            family.OnDelete()
        self.__familyIDDict.pop(familyID, None)
        if familyID > ShareDefine.FackFamilyIDMax:
        if familyID >= ShareDefine.RealFamilyIDStart:
            PyMongoMain.GetUserCtrlDB().FreeFamilyID(familyID) # 归还仙盟ID,重复使用
        return family
    
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/StructData/DBGameRec.py
@@ -159,6 +159,7 @@
        recData = self.InitRecDataInstance(dbData)
        return recData
    
    def GetDataList(self): return self.__dataList
    def GetCount(self): return len(self.__dataList)
    def At(self, index):
        recData = None
@@ -339,6 +340,8 @@
            recTypeIDMgr = GameRecIDMgr(recType, recID)
        return recTypeIDMgr
    
    def DelDataByType(self, recType): return self.GetRecTypeMgr(recType).DelAllData()
    # 保存数据 存数据库和realtimebackup
    def GetSaveData(self):
        savaData = ""
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/StructData/DBPlayerViewCache.py
@@ -18,6 +18,7 @@
import DBComm
import DBStruct
import GameWorld
import ShareDefine
import CommFunc
import ChConfig
@@ -44,6 +45,8 @@
    def SetFace(self, face): self.__dbData.Face = face
    def GetFacePic(self): return self.__dbData.FacePic
    def SetFacePic(self, facePic): self.__dbData.FacePic = facePic
    def GetModelMark(self): return self.__dbData.ModelMark
    def SetModelMark(self, modelMark): self.__dbData.ModelMark = modelMark
    def GetFamilyID(self): return self.__dbData.FamilyID
    def SetFamilyID(self, familyID): self.__dbData.FamilyID = familyID
    def GetFamilyName(self): return self.__dbData.FamilyName
@@ -64,6 +67,7 @@
    def GetOffTime(self): return self.__dbData.OffTime
    def SetOffTime(self, offTime): self.__dbData.OffTime = offTime
    def GetPlusDict(self): return self.__plusDict.GetData()
    def SetPlusDict(self, value): self.__plusDict.SetData(value)
    def GetPlusData(self): return self.__plusDict.ToString()
    def GetBuffer(self):
        self.__plusDict.ToString()
@@ -170,6 +174,9 @@
        cnt = 0
        
        for dbData in self.__viewCacheList:
            if dbData.GetPlayerID() < ShareDefine.RealPlayerIDStart:
                # 仅保存真实玩家
                continue
            cnt += 1
            savaData += dbData.GetBuffer()
            
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Arena.py
@@ -28,24 +28,19 @@
#  @return None
#  @remarks 函数详细说明.
def OnExec(curPlayer, msgList):
    if not msgList:
        GameWorld.DebugAnswer(curPlayer, "重置玩家竞技场: Arena 0")
        GameWorld.DebugAnswer(curPlayer, "设置玩家榜积分: Arena 积分")
        GameWorld.DebugAnswer(curPlayer, "设置玩家榜积分: Arena 2 对手ID 积分")
        GameWorld.DebugAnswer(curPlayer, "直接匹配到目标: Arena 1 对手ID 对手ID ...")
        GameWorld.DebugAnswer(curPlayer, "重置赛季直接用 test_OnWeek (需开服7天后)")
        GameWorld.DebugAnswer(curPlayer, "直接匹配到目标: Arena m 对手ID 对手ID ...")
        GameWorld.DebugAnswer(curPlayer, "重置赛季直接用 test_OnWeek")
        return
    
    if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Arena):
        GameWorld.DebugAnswer(curPlayer, "竞技场功能未开启!")
        return
    
    isSendGameServer = False
    value1 = msgList[0]
    if value1 <= 0:
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaOSSeasonState, 0)
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaHighestScore, 0)
        PlayerArena.__DoArenaSeasonReset(curPlayer)
        GameWorld.DebugAnswer(curPlayer, "重置成功!")
        return
@@ -55,18 +50,9 @@
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaScore, value1)
        PlayerArena.Sync_ArenaInfo(curPlayer)
        
        isSendGameServer = True
    elif len(msgList) >= 2 and value1 == 1:
    elif value1 == "m":
        gmMatchIDList = msgList[1:]
        PlayerArena.GMArenaMatch(curPlayer, gmMatchIDList)
        
    elif len(msgList) >= 3 and value1 == 2:
        isSendGameServer = True
    else:
        pass
    return isSendGameServer
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Billboard.py
@@ -26,16 +26,15 @@
        GameWorld.DebugAnswer(curPlayer, errInfo)
    GameWorld.DebugAnswer(curPlayer, "新增榜单假数据: Billboard 类型 分组值1 分组值2 条数 比较值1可选参数(比较值2 常规值1~5)")
    GameWorld.DebugAnswer(curPlayer, "删除榜单假数据: Billboard 类型 分组值1 分组值2")
    GameWorld.DebugAnswer(curPlayer, "榜单类型:0-战力,1-龙魂,2-灵瑶,4-等级,5-坐骑,6-灵宠,7-符印,8-脱机,9-境界,19-助战")
    GameWorld.DebugAnswer(curPlayer, "开服活动榜类型:11-强化,12-坐骑,13-宝石,14-冲级,15-境界,16-战力,18-符印,20-神兵,21-充值,22-灵宠,24-灵根,25-升星,26-洗练")
    GameWorld.DebugAnswer(curPlayer, "运营活动榜类型:17-仙界盛典,23-仙界盛典2,33-boss凭证,36-boss凭证仙盟,38-仙匣,39-古宝,40-骑宠")
    GameWorld.DebugAnswer(curPlayer, "魅力榜单类型:30-总榜,31-周榜,32-日榜")
    GameWorld.DebugAnswer(curPlayer, "运营活动榜类型:150-充值(分组值1配置ID)")
    GameWorld.DebugAnswer(curPlayer, "运营活动榜类型:158-boss凭证,160-凭证仙盟,162-仙匣,163-古宝,164-骑宠")
    GameWorld.DebugAnswer(curPlayer, "古神战场榜类型:151-参与榜,152-召集榜,153-积分榜")
    GameWorld.DebugAnswer(curPlayer, "逐鹿万界榜类型:156-单场榜,157-周榜")
    GameWorld.DebugAnswer(curPlayer, "跨服竞技场榜单:165,分组值1-分区,分组值2-赛季,value2-段位")
    GameWorld.DebugAnswer(curPlayer, "输出排行榜数据: Billboard p 类型 分组值1 分组值2")
    GameWorld.DebugAnswer(curPlayer, "注:如果没有特殊说明,本服榜单分组值均为0,跨服榜单分组值1为分区ID,分组2为0")
    nameTypeList = ShareDefine.BillboardNameDict.keys()
    nameTypeList.sort()
    for billboardType in nameTypeList:
        bName = ShareDefine.BillboardNameDict[billboardType]
        GameWorld.DebugAnswer(curPlayer, "(%s) %s" % (billboardType, bName))
    return
## 执行逻辑
@@ -55,7 +54,7 @@
        return
    
    billboardIndex = value
    if billboardIndex >= ShareDefine.BillboardTypeAllList:
    if billboardIndex not in ShareDefine.BillboardTypeAllList:
        __Help(curPlayer, "榜单类型不存在!")
        return
    
@@ -138,7 +137,7 @@
    return
def __GetBillTypeSign(billboardType, groupValue1, groupValue2):
    billTypeSign = "%s" % billboardType
    billTypeSign = "Type:%s" % billboardType
    if groupValue1:
        billTypeSign = "%s-%s" % (billTypeSign, groupValue1)
    if groupValue2:
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/CreateFamily.py
@@ -233,7 +233,7 @@
            else:
                memFightPower = avgValue + memCnt / 2 - m
                memFightPowerTotal -= memFightPower
            viewCache = PlayerViewCache.FindViewCache(memID, True)
            viewCache = PlayerViewCache.FindViewCache(memID)
            viewCache.SetFightPowerTotal(memFightPower)
            GameWorld.DebugLog("    仙盟成员: memID=%s,memFightPower=%s,fmLV=%s" % (memID, memFightPower, fmLV))
            member.RefreshMemberByID(memID)
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Robot.py
New file
@@ -0,0 +1,46 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package GM.Commands.Robot
#
# @todo:机器人
# @author hxp
# @date 2025-09-12
# @version 1.0
#
# 详细描述: 机器人
#
#-------------------------------------------------------------------------------
#"""Version = 2025-09-12 10:30"""
#-------------------------------------------------------------------------------
import GameWorld
import PlayerViewCache
## GM命令执行入口
#  @param curPlayer 当前玩家
#  @param msgList 参数列表
#  @return None
#  @remarks 函数详细说明.
def OnExec(curPlayer, msgList):
    if not msgList:
        GameWorld.DebugAnswer(curPlayer, "导出机器人: Robot 玩家ID")
        return
    value = msgList[0]
    if len(msgList) == 1:
        tagPlayerID = value if value else curPlayer.GetPlayerID()
        viewCache = PlayerViewCache.FindViewCache(tagPlayerID)
        if not viewCache:
            GameWorld.DebugAnswer(curPlayer, "没有该玩家缓存无法导出! %s" % tagPlayerID)
            return
        robotDict = PlayerViewCache.GetRobotByViewCache(viewCache)
        GameWorld.DebugLog("robotDict:%s" % robotDict)
        GameWorld.DebugAnswer(curPlayer, "已导出!可拷贝到机器人表")
        return
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_Arena.py
New file
@@ -0,0 +1,207 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package GameWorldLogic.FBProcess.GameLogic_Arena
#
# @todo:演武场
# @author hxp
# @date 2025-09-12
# @version 1.0
#
# 详细描述: 演武场
#
#-------------------------------------------------------------------------------
#"""Version = 2025-09-12 10:30"""
#-------------------------------------------------------------------------------
import DBDataMgr
import GameWorld
import TurnAttack
import ShareDefine
import PlayerControl
import IpyGameDataPY
import PlayerBillboard
import ItemControler
import PlayerArena
import PyGameData
import FBCommon
import ChConfig
def __checkCanAtkTagPlayer(curPlayer, tagPlayerID):
    '''检查可否攻击目标
    @return: None - 不可攻击
    @return: >=0 - 在匹配列表里的索引
    @return: -1 - 可反击的
    '''
    playerID = curPlayer.GetPlayerID()
    matchIDList = PyGameData.g_arenaPlayerMatchDict.get(playerID, [])
    #if tagPlayerID in matchIDList:
    #    return matchIDList.index(tagPlayerID)
    gameRecMgr = DBDataMgr.GetGameRecMgr()
    atkRecMgr = gameRecMgr.GetRecTypeIDMgr(ShareDefine.Def_GameRecType_ArenaRecord, playerID)
    for index in range(atkRecMgr.GetCount())[::-1]:
        recData = atkRecMgr.At(index)
        if PlayerArena.GetRecAtkType(recData) != PlayerArena.RecAtkType_Def:
            # 被攻击的才能反击
            continue
        if tagPlayerID != PlayerArena.GetRecTagPlayerID(recData):
            continue
        if GameWorld.CheckTimeIsSameWeek(recData.GetTime()):
            return -1
        break
    GameWorld.DebugLog("演武场不可攻击不在匹配列表里或可复仇的目标! tagPlayerID=%s,matchIDList=%s" % (tagPlayerID, matchIDList), playerID)
    return
def OnTurnFightRequest(curPlayer, mapID, funcLineID, tagType, tagID, valueList):
    ## 回合战斗请求
    if __checkCanAtkTagPlayer(curPlayer, tagID) == None:
        return
    if not PlayerControl.HaveMoney(curPlayer, ShareDefine.TYPE_Price_ArenaTicket, 1):
        return
    return True
def GetFBPlayerLineupID(curPlayer, mapID, funcLineID):
    ## 获取玩家使用的攻防阵容ID
    # @return: 攻击方阵容ID, 防守方阵容ID
    return ShareDefine.Lineup_Arena, ShareDefine.Lineup_ArenaDef
def OnTurnFightOver(curPlayer, turnFight, mapID, funcLineID, overMsg):
    ## 回合战斗结束
    if not curPlayer:
        return
    playerID = curPlayer.GetPlayerID()
    tagPlayerID = turnFight.tagPlayerID
    isWin = turnFight.isWin
    canAtkRet = __checkCanAtkTagPlayer(curPlayer, tagPlayerID)
    GameWorld.DebugLog("结算竞技场! isWin=%s,tagPlayerID=%s,canAtkRet=%s" % (isWin, tagPlayerID, canAtkRet), playerID)
    if canAtkRet == None:
        return
    billboardMgr = DBDataMgr.GetBillboardMgr()
    billBoard = billboardMgr.GetBillboard(ShareDefine.Def_BT_Arena)
    atkAddScore, defDecScore = 0, 0
    if isWin:
        winScoreList = IpyGameDataPY.GetFuncEvalCfg("ArenaMatch", 1)
        scoreCnt = len(winScoreList)
        scoreIndex = scoreCnt - 1 # 默认最低分档
        # 匹配的
        if canAtkRet >= 0:
            if canAtkRet < scoreCnt:
                scoreIndex = canAtkRet
                GameWorld.DebugLog("在匹配中的! scoreIndex=%s" % scoreIndex, playerID)
        # 复仇的
        else:
            # 按排名差
            fromLowerCnt, matchPerRank = IpyGameDataPY.GetFuncEvalCfg("ArenaMatch", 2)
            curPlayerRank = billBoard.IndexOfByID(playerID) + 1
            tagPlayerRank = billBoard.IndexOfByID(tagPlayerID) + 1
            if curPlayerRank >= 1 and tagPlayerRank >= 1:
                fromRank = curPlayerRank - (scoreCnt - fromLowerCnt) * matchPerRank
                for index in range(scoreCnt):
                    toRank = fromRank + matchPerRank - 1
                    if fromRank <= tagPlayerRank <= toRank:
                        scoreIndex = index
                        break
                    fromRank = toRank + 1
            GameWorld.DebugLog("在复仇中的! curPlayerRank=%s,tagPlayerRank=%s,scoreIndex=%s" % (curPlayerRank, tagPlayerRank, scoreIndex), playerID)
        winScoreInfo = winScoreList[scoreIndex] if scoreIndex < scoreCnt else winScoreList[-1]
        atkAddScore, defDecScore = winScoreInfo
        GameWorld.DebugLog("scoreIndex=%s,winScoreInfo=%s" % (scoreIndex, winScoreInfo), playerID)
    if not PlayerControl.PayMoney(curPlayer, ShareDefine.TYPE_Price_ArenaTicket, 1):
        return
    # 无论胜负,只要挑战都给固定奖励
    awardItemList = IpyGameDataPY.GetFuncEvalCfg("ArenaSet", 4)
    ItemControler.GivePlayerItemOrMail(curPlayer, awardItemList, event=["Arena", False, {}], isNotifyAward=False)
    __updArenaBatRecord(curPlayer, turnFight, tagPlayerID, isWin, atkAddScore, defDecScore)
    overMsg.update({"tagPlayerID":tagPlayerID, "atkAddScore":atkAddScore, "defDecScore":defDecScore,
                    FBCommon.Over_itemInfo:FBCommon.GetJsonItemList(awardItemList)})
    PlayerArena.Sync_ArenaInfo(curPlayer)
    # 战斗结束系统强制刷新匹配
    PlayerArena.DoArenaMatchRefresh(curPlayer, True, isSys=True)
    return
def __updArenaBatRecord(curPlayer, turnFight, tagPlayerID, isWin, atkAddScore, defDecScore):
    ## 更新战斗相关日志、榜单等
    playerID = curPlayer.GetPlayerID()
    maxCount = min(50, IpyGameDataPY.GetFuncCfg("ArenaSet", 2))
    score = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaScore)
    updScore = max(0, score + atkAddScore)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaScore, updScore)
    GameWorld.DebugLog("score=%s,atkAddScore=%s,updScore=%s" % (score, atkAddScore, updScore), playerID)
    tagViewCache = turnFight.tagViewCache
    gameRecMgr = DBDataMgr.GetGameRecMgr()
    atkRecMgr = gameRecMgr.GetRecTypeIDMgr(ShareDefine.Def_GameRecType_ArenaRecord, playerID)
    recData = atkRecMgr.AddRecData(maxCount)
    PlayerArena.SetRecUpdScore(recData, updScore)
    PlayerArena.SetRecAtkType(recData, PlayerArena.RecAtkType_Atk)
    PlayerArena.SetRecTagPlayerID(recData, tagPlayerID)
    PlayerArena.SetRecIsWin(recData, isWin)
    PlayerArena.SetRecFace(recData, tagViewCache.GetFace())
    PlayerArena.SetRecFacePic(recData, tagViewCache.GetFacePic())
    PlayerArena.SetRecRealmLV(recData, tagViewCache.GetRealmLV())
    PlayerArena.SetRecLV(recData, tagViewCache.GetLV())
    # 名字、变更积分 +-、战力
    # 战力统一记录防守阵容
    fightPower = TurnAttack.GetCacheLineupFightPower(tagViewCache, ShareDefine.Lineup_ArenaDef)
    recData.SetUserData({"Name":tagViewCache.GetPlayerName(), "AddScore":atkAddScore, "FightPower":fightPower})
    # 攻击方仅在积分变更或者初始积分时更新榜单
    if atkAddScore or updScore == IpyGameDataPY.GetFuncCfg("ArenaSet", 1):
        PlayerBillboard.UpdatePlayerBillboard(curPlayer, ShareDefine.Def_BT_Arena, updScore)
    # 被击方
    if tagPlayerID < ShareDefine.RealPlayerIDStart:
        GameWorld.DebugLog("目标非真实玩家不处理! tagPlayerID=%s" % tagPlayerID, playerID)
        return
    # 以战斗记录作为最新积分的更新记录,支持离线玩家上线后更新最新积分
    # 由于非榜单上的玩家不会被匹配到,所以被匹配到的可以理解为一定有战斗记录,因为要上榜必须战斗过
    defRecMgr = gameRecMgr.GetRecTypeIDMgr(ShareDefine.Def_GameRecType_ArenaRecord, 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
    defScore = PlayerArena.GetRecUpdScore(finalRecData)
    updScore = max(0, defScore - defDecScore)
    GameWorld.DebugLog("defScore=%s,defDecScore=%s,updScore=%s" % (defScore, defDecScore, updScore), playerID)
    recData = defRecMgr.AddRecData(maxCount)
    PlayerArena.SetRecUpdScore(recData, updScore)
    PlayerArena.SetRecAtkType(recData, PlayerArena.RecAtkType_Def)
    PlayerArena.SetRecTagPlayerID(recData, playerID)
    PlayerArena.SetRecIsWin(recData, not isWin)
    PlayerArena.SetRecFace(recData, curPlayer.GetFace())
    PlayerArena.SetRecFacePic(recData, curPlayer.GetFacePic())
    PlayerArena.SetRecRealmLV(recData, curPlayer.GetOfficialRank())
    PlayerArena.SetRecLV(recData, curPlayer.GetLV())
    # 名字、变更积分 +-、战力
    fightPower = TurnAttack.GetPlayerLineupFightPower(curPlayer, ShareDefine.Lineup_ArenaDef)
    recData.SetUserData({"Name":curPlayer.GetPlayerName(), "AddScore":-defDecScore, "FightPower":fightPower})
    if defDecScore: # 防守方仅变更时更新
        PlayerBillboard.UpdateBillboardByID(tagPlayerID, ShareDefine.Def_BT_Arena, updScore)
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/GameLogic_MainLevel.py
@@ -25,6 +25,7 @@
import ItemControler
import IPY_GameWorld
import NetPackCommon
import PlayerArena
import ItemCommon
import PlayerTask
import NPCCommon
@@ -130,6 +131,22 @@
        if dropBootyCnt <= 0:
            continue
        
        itemData = GameWorld.GetGameData().GetItemByTypeID(itemID)
        if not itemData:
            continue
        # 判断挑战券
        if itemData.GetType() == ChConfig.Def_ItemType_AutoUseMoney:
            curEff = itemData.GetEffectByIndex(0)
            effID = curEff.GetEffectID()
            moneyType = curEff.GetEffectValue(1)
            if effID == ChConfig.Def_Effect_ItemGiveMoney and moneyType == ShareDefine.TYPE_Price_ArenaTicket:
                curMoney = PlayerControl.GetMoney(curPlayer, ShareDefine.TYPE_Price_ArenaTicket)
                storeMax = PlayerArena.GetArenaTicketStoreMax(curPlayer)
                if curMoney >= storeMax:
                    GameWorld.DebugLog("挑战券已达存储上限! itemID=%s,curMoney=%s >= %s" % (itemID, curMoney, storeMax), playerID)
                    continue
        dropCntRange = bootyDropCntDict[itemID]
        if not isinstance(dropCntRange, (list, tuple)) or len(dropCntRange) != 2:
            continue
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
@@ -2565,6 +2565,11 @@
                        ("BYTE", "WorkerMax", 0),
                        ("BYTE", "NeedSeconds", 0),
                        ),
                "Robot":(
                        ("DWORD", "ID", 1),
                        ("char", "ViewCache", 0),
                        ),
                }
@@ -6389,6 +6394,16 @@
    def GetWorkerMax(self): return self.attrTuple[5] # 监工上限 BYTE
    def GetNeedSeconds(self): return self.attrTuple[6] # 耗时秒 BYTE
# 机器人
class IPY_Robot():
    def __init__(self):
        self.attrTuple = None
        return
    def GetID(self): return self.attrTuple[0] # 机器人ID,同玩家ID DWORD
    def GetViewCache(self): return self.attrTuple[1] # 机器人缓存 char
def Log(msg, playerID=0, par=0):
    LogUI.Msg("%s\t%s\t%s" % (par, playerID, msg))
@@ -6702,6 +6717,7 @@
        self.__LoadFileData("GoldRushCamp", onlyCheck)
        self.__LoadFileData("GoldRushWorker", onlyCheck)
        self.__LoadFileData("GoldRushItem", onlyCheck)
        self.__LoadFileData("Robot", onlyCheck)
        Log("IPY_DataMgr ReloadOK! onlyCheck=%s" % onlyCheck)
        return
    
@@ -8719,6 +8735,13 @@
        self.CheckLoadData("GoldRushItem")
        return self.ipyGoldRushItemCache[index]
    def GetRobotCount(self):
        self.CheckLoadData("Robot")
        return self.ipyRobotLen
    def GetRobotByIndex(self, index):
        self.CheckLoadData("Robot")
        return self.ipyRobotCache[index]
IPYData = IPY_DataMgr()
def IPY_Data(): return IPYData
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ChItem.py
@@ -704,7 +704,6 @@
                            ChConfig.Def_Effect_TrainRealmLV:"Item_TrainRealmLV", # 境界培养卡
                            ChConfig.Def_Effect_ResetBossKillCnt:"Item_ResetBossKillCnt", # 重置boss击杀疲劳
                            ChConfig.Def_Effect_AddFBCnt:"Item_AddFBCnt", # 增加副本可进入次数
                            ChConfig.Def_Effect_AddArenaBattleCount:"Item_AddArenaBattleCount", # 增加竞技场挑战次数
                            ChConfig.Def_Effect_AddKillBossCnt:"Item_AddKillBossCnt", # 增加BOSS可击杀次数
                            ChConfig.Def_Effect_AddMagicWeaponUpExp:"Item_AddMagicWeaponUpExp", # 增加法宝升星经验
                            ChConfig.Def_Effect_ChatBubbleBox:"Item_ChatBubbleBox", # 激活聊天气泡框
@@ -715,6 +714,7 @@
                            ChConfig.Def_Effect_AddRealmExpRate:"Item_AddRealmExpRate", # 增加聚灵效率
                            ChConfig.Def_Effect_TouchMission:"Item_TouchMission",  # 触发任务接口
                            ChConfig.Def_Effect_HeroSkin:"Item_HeroSkin",  # 武将皮肤
                            #ChConfig.Def_Effect_AddArenaBattleCount:"Item_AddArenaBattleCount", # 增加竞技场挑战次数
                            #ChConfig.Def_Effect_FamilyImpeach:"Item_FamilyImpeach",  # 弹劾符
                            #ChConfig.Def_Effect_ClothesCoatSkin:"Item_ClothesCoatSkin", #激活时装皮肤
                            #ChConfig.Def_Effect_AddOfficialExp:"Item_AddOfficialExp", # 增加爵位经验
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/Item_AddArenaBattleCount.py
File was deleted
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
@@ -4054,3 +4054,50 @@
    #PlayerControl.SetRealmDifficulty(curPlayer, clientData.RealmDifficulty)
    return
#// A0 08 查看通用记录 #tagCSViewGameRec
#
#struct    tagCSViewGameRec
#{
#    tagHead        Head;
#    WORD         RecType;        //记录类型
#    DWORD         RecID;        //自定义记录ID
#};
def OnViewGameRec(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    recType = clientData.RecType
    recID = clientData.RecID
    if recType not in ShareDefine.Def_GameRecTypeList:
        return
    if recType in ShareDefine.Def_ViewGameRecSelfList:
        recID = curPlayer.GetPlayerID()
    recTypeIDMgr = DBDataMgr.GetGameRecMgr().GetRecTypeIDMgr(recType, recID)
    SyncGameRecInfo(curPlayer, recType, recID, recTypeIDMgr.GetDataList())
    return
def SyncGameRecInfo(curPlayer, recType, recID, recDataList):
    recList = []
    for recData in recDataList:
        if not recData:
            continue
        rec = ChPyNetSendPack.tagSCGameRec()
        rec.Time = recData.GetTime()
        rec.Value1 = recData.GetValue1()
        rec.Value2 = recData.GetValue2()
        rec.Value3 = recData.GetValue3()
        rec.Value4 = recData.GetValue4()
        rec.Value5 = recData.GetValue5()
        rec.Value6 = recData.GetValue6()
        rec.Value7 = recData.GetValue7()
        rec.Value8 = recData.GetValue8()
        rec.UserData = recData.GetUserData()
        rec.UserDataLen = len(rec.UserData)
        recList.append(rec)
    clientPack = ChPyNetSendPack.tagSCGameRecInfo()
    clientPack.Clear()
    clientPack.RecType = recType
    clientPack.RecID = recID
    clientPack.RecList = recList
    clientPack.Count = len(clientPack.RecList)
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerArena.py
@@ -4,366 +4,346 @@
#
##@package Player.PlayerArena
#
# @todo:竞技场 - 本服
# @todo:演武场
# @author hxp
# @date 2020-12-07
# @date 2025-09-12
# @version 1.0
#
# 详细描述: 竞技场 - 本服
# 详细描述: 演武场
#
#-------------------------------------------------------------------------------
#"""Version = 2020-12-07 19:30"""
#"""Version = 2025-09-12 10:30"""
#-------------------------------------------------------------------------------
import DBDataMgr
import PlayerMail
import ShareDefine
import GameFuncComm
import PlayerControl
import IpyGameDataPY
import ChPyNetSendPack
import PlayerViewCache
import NetPackCommon
import PyGameData
import GameWorld
import ChConfig
import FBCommon
import IPY_GameWorld
import ItemControler
import PlayerActTask
import PlayerWeekParty
import PlayerFeastTravel
import PlayerActivity
import PlayerSuccess
import PlayerGubao
import random
def DoArenaOpen(curPlayer):
    ## 竞技场功能开启
    __DoArenaSeasonReset(curPlayer)
# 记录攻击类型
RecAtkType_Atk = 1 # 发起攻击
RecAtkType_Def = 2 # 被攻击的
def GetRecUpdScore(recData): return recData.GetValue1() # 更新积分
def SetRecUpdScore(recData, score): return recData.SetValue1(score)
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():
    DoArenaReset()
    return
def OnDay():
    __DoGiveBillboardAward("Day")
    return
def DoArenaReset():
    ''' 赛季重置
    '''
    GameWorld.Log("=============== 重置竞技场 ===============")
    PyGameData.g_arenaPlayerMatchDict = {}
    # 结算上赛季排行奖励
    __DoGiveBillboardAward("Week")
    # 重置排行榜
    DBDataMgr.GetBillboardMgr().RemoveBillboard(ShareDefine.Def_BT_Arena)
    # 重置记录
    #DBDataMgr.GetGameRecMgr().DelDataByType(ShareDefine.Def_GameRecType_ArenaRecord) # 挑战记录不重置
    GameWorld.Log("==========================================")
    return True
def __DoGiveBillboardAward(awardType):
    ## 竞技场结算排行奖励, 每日、赛季通用
    GameWorld.Log("=== 竞技场结算排行奖励! === %s" % awardType)
    billboardMgr = DBDataMgr.GetBillboardMgr()
    billBoard = billboardMgr.GetBillboard(ShareDefine.Def_BT_Arena)
    if not billBoard:
        return
    if awardType == "Day":
        billboradAwardDict = IpyGameDataPY.GetFuncEvalCfg("ArenaBillboradAward", 1, {})
    elif awardType == "Week":
        billboradAwardDict = IpyGameDataPY.GetFuncEvalCfg("ArenaBillboradAward", 2, {})
    else:
        return
    orderList = [int(orderStr) for orderStr in billboradAwardDict.keys()]
    orderList.sort()
    GameWorld.Log("    奖励名次列表: %s" % orderList)
    awardOrder = orderList[0]
    orderPlayerIDDict = {}
    billboardCount, billboardMaxCount = billBoard.GetCount(), billBoard.GetMaxCount()
    GameWorld.Log("    榜单数据数! billboardCount=%s,billboardMaxCount=%s" % (billboardCount, billboardMaxCount))
    for index in xrange(billboardCount):
        billBoardData = billBoard.At(index)
        if not billBoardData:
            continue
        order = index + 1
        if order > awardOrder:
            nextOrderIndex = orderList.index(awardOrder) + 1
            if nextOrderIndex >= len(orderList):
                break
            awardOrder = orderList[nextOrderIndex]
        playerID = billBoardData.GetID()
        if playerID < ShareDefine.RealPlayerIDStart:
            # 非真人不处理
            continue
        orderPlayerIDDict[playerID] = [order, awardOrder]
        paramList = [order]
        awardList = billboradAwardDict[str(awardOrder)]
        PlayerMail.SendMailByKey("ArenaBillboardAward%s" % awardType, playerID, awardList, paramList)
    GameWorld.Log("    奖励玩家名次信息: %s" % orderPlayerIDDict)
    return
def OnLogin(curPlayer):
    if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Arena):
        return
    OSSeasonState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaOSSeasonState)
    if not OSSeasonState:
        __DoArenaSeasonReset(curPlayer)
    else:
    __loginUpdPlayerScore(curPlayer)
        Sync_ArenaInfo(curPlayer)
    return
def __loginUpdPlayerScore(curPlayer):
    playerID = curPlayer.GetPlayerID()
    recMgr = DBDataMgr.GetGameRecMgr()
    recIDMgr = recMgr.GetRecTypeIDMgr(ShareDefine.Def_GameRecType_ArenaRecord, playerID)
    if not recIDMgr.GetCount():
        return
    finalRecData = recIDMgr.At(recIDMgr.GetCount() - 1)
    recTime = finalRecData.GetTime()
    if not GameWorld.CheckTimeIsSameWeek(recTime):
        GameWorld.Log("玩家上线演武场记录积分非本周不更新! recTime=%s" % GameWorld.ChangeTimeNumToStr(recTime), playerID)
        return
    updScore = GetRecUpdScore(finalRecData)
    befScore = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaScore)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaScore, updScore)
    GameWorld.Log("玩家上线更新演武场积分: befScore=%s,updScore=%s,recTime=%s" % (befScore, updScore, GameWorld.ChangeTimeNumToStr(recTime)), playerID)
    return
def OnDayEx(curPlayer):
    if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Arena):
        return
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaItemAddCount, 0)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaBattleCountDay, 0)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaMatchRefreshCount, 0)
    Sync_ArenaInfo(curPlayer)
    openServerDay = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_ServerDay) + 1
    customMaxServerDay = IpyGameDataPY.GetFuncCfg("OperationAction", 1)
    if openServerDay <= customMaxServerDay:
        GameWorld.DebugLog("OnDayEx时竞技场开服定制赛季进行中,不处理! openServerDay=%s <= %s" % (openServerDay, customMaxServerDay))
        return
    OSSeasonState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaOSSeasonState)
    if OSSeasonState > 1:
        GameWorld.DebugLog("OnDayEx时竞技场开服定制赛季已结算过,不处理! OSSeasonState=%s" % (OSSeasonState))
        return
    __DoArenaSeasonReset(curPlayer)
    return
def OnWeekEx(curPlayer):
    if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_Arena):
        return
    openServerDay = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_ServerDay) + 1
    customMaxServerDay = IpyGameDataPY.GetFuncCfg("OperationAction", 1)
    if openServerDay <= customMaxServerDay:
        GameWorld.DebugLog("OnWeekEx时在开服定制天内,不处理竞技场赛季重置! openServerDay=%s <= %s" % (openServerDay, customMaxServerDay))
    __DoArenaSeasonReset(curPlayer)
        return
    
    OSSeasonState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaOSSeasonState)
    if not OSSeasonState or OSSeasonState == 1 or OSSeasonState == openServerDay:
        GameWorld.DebugLog("OnWeekEx时竞技场开服定制赛季进行中或同一天结算,不处理重置! openServerDay=%s,OSSeasonState=%s" % (openServerDay, OSSeasonState))
        return
def DoArenaOpen(curPlayer):
    __DoArenaSeasonReset(curPlayer)
    return
def __DoArenaSeasonReset(curPlayer):
    ## 玩家重置竞技场
    OSSeasonState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaOSSeasonState)
    openServerDay = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_ServerDay) + 1
    customMaxServerDay = IpyGameDataPY.GetFuncCfg("OperationAction", 1)
    if openServerDay <= customMaxServerDay and OSSeasonState != 0:
        GameWorld.DebugLog("开服定制天内不能重置!")
    initScore = IpyGameDataPY.GetFuncCfg("ArenaSet", 1)
    GameWorld.DebugLog("竞技场赛季重置!initScore=%s" % (initScore))
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaScore, initScore)
    Sync_ArenaInfo(curPlayer)
        return
    
    setScoreMin, setScoreMax, refScoreMax = IpyGameDataPY.GetFuncEvalCfg("ArenaSet", 2)
    setScore = setScoreMin
    if openServerDay <= customMaxServerDay and OSSeasonState == 0:
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaOSSeasonState, 1)
        GameWorld.DebugLog("竞技场开服定制赛季! setScore=%s" % setScore)
    else:
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaOSSeasonState, customMaxServerDay + 1)
def GetArenaTicketStoreMax(curPlayer):
    ## 获取挑战券存储上限
    baseCnt = IpyGameDataPY.GetFuncCfg("ArenaSet", 3)
        
        preSeasonscore = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaScore)
        if preSeasonscore <= setScoreMin:
            setScore = setScoreMin
        elif preSeasonscore >= refScoreMax:
            setScore = setScoreMax
        else:
            # 按比例降低积分,都减去最低分的差值算比例
            calcScore = preSeasonscore - setScoreMin
            setScore = setScoreMin + int(calcScore * (setScoreMax - setScoreMin) / float(refScoreMax - setScoreMin))
    # 其他特权提升上限
            
        GameWorld.DebugLog("竞技场赛季重置! preSeasonscore=%s,setScore=%s" % (preSeasonscore, setScore))
    storeMax = baseCnt
    return storeMax
        
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaScore, setScore)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaItemAddCount, 0)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaBattleCountDay, 0)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaMatchRefreshCount, 0)
    Sync_ArenaInfo(curPlayer, True)
    return
def CheckArenaBattleCount(curPlayer):
    ## 验证是否还有对战次数
    todayBattleCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaBattleCountDay)
    itemAddCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaItemAddCount)
    dayFreeCount = IpyGameDataPY.GetFuncCfg("ArenaSet", 3)
    return todayBattleCount < (dayFreeCount + itemAddCount)
#// B2 09 竞技场匹配玩家 #tagCMArenaMatch
#// B2 09 演武场匹配玩家 #tagCSArenaMatch
#
#struct    tagCMArenaMatch
#struct    tagCSArenaMatch
#{
#    tagHead         Head;
#    BYTE        IsRefresh;    // 0-打开界面无匹配数据时时查询,1-强制刷新匹配列表
#    BYTE        IsRefresh;    // 0-打开界面无匹配数据时查询,1-强制刷新匹配列表
#};
def OnArenaMatch(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    isRefresh = clientData.IsRefresh
    playerID = curPlayer.GetPlayerID()
    refreshCountLimit = IpyGameDataPY.GetFuncCfg("ArenaSet", 5)
    if isRefresh and refreshCountLimit:
        refreshCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaMatchRefreshCount)
        if refreshCount >= refreshCountLimit:
            GameWorld.DebugLog("竞技场刷新匹配玩家次数已满!refreshCount=%s >= %s" % (refreshCount, refreshCountLimit), playerID)
            return
    if not GameWorld.SetPlayerTickTime(curPlayer, ChConfig.TYPE_Player_Tick_Arena, tick):
        GameWorld.DebugLog("竞技场匹配操作CD中...", playerID)
        PlayerControl.NotifyCode(curPlayer, "RequestLater")
        return
    playerLV = curPlayer.GetLV()
    playerScore = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaScore)
    msgInfo = str(["MatchRefresh", {"isRefresh":isRefresh, "playerLV":playerLV, "playerScore":playerScore}])
    GameWorld.DebugLog("竞技场发送GameServer匹配: %s" % msgInfo, playerID)
    GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(curPlayer.GetID(), 0, 0, "Arena", msgInfo, len(msgInfo))
    DoArenaMatchRefresh(curPlayer, isRefresh)
    return
def GMArenaMatch(curPlayer, gmMatchIDList):
    playerID = curPlayer.GetPlayerID()
    playerLV = curPlayer.GetLV()
    playerScore = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaScore)
    msgInfo = str(["MatchRefresh", {"isRefresh":1, "playerLV":playerLV, "playerScore":playerScore, "gmMatchIDList":gmMatchIDList}])
    GameWorld.DebugLog("竞技场发送GameServer匹配: %s" % msgInfo, playerID)
    GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(curPlayer.GetID(), 0, 0, "Arena", msgInfo, len(msgInfo))
    ## GM直接匹配
    isRefresh = True
    DoArenaMatchRefresh(curPlayer, isRefresh, gmMatchIDList)
    return
#// B2 10 竞技场挑战玩家 #tagCMArenaBattle
#
#struct    tagCMArenaBattle
#{
#    tagHead         Head;
#    DWORD        TagPlayerID;    // 目标玩家ID或机器人ID
#    BYTE        Result;    // 0-进入自定义场景发送通知后端;1-胜利(后端处理,暂时不需要发送此状态);2-失败(前端被对手击杀需要发送此状态)
#};
def OnArenaBattle(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    playerID = curPlayer.GetPlayerID()
    tagPlayerID = clientData.TagPlayerID
    result = clientData.Result
    GameWorld.DebugLog("竞技场挑战玩家! tagPlayerID=%s,result=%s" % (tagPlayerID, result), playerID)
    if not tagPlayerID:
        return
    if not result:
        GameWorld.DebugLog("更新竞技场对战对手ID! tagPlayerID=%s" % tagPlayerID, playerID)
        # 记录对手ID
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaBattleTagID, tagPlayerID)
        return
    if tagPlayerID >= 10000:
        if result:
            GameWorld.DebugLog("真人由后端镜像PK决定胜负! tagPlayerID=%s" % tagPlayerID, playerID)
            return
    isWin = 1 if result == 1 else 0
#    # 木桩被击杀,后端判断,其他前端同步
#    if isWin:
#        GameWorld.ErrLog("前端不能同步竞技场胜利状态!", playerID)
#        return
    recTagPlayerID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaBattleTagID)
    if tagPlayerID != recTagPlayerID:
        GameWorld.ErrLog("竞技场结算时对手ID不一致! tagPlayerID(%s) != recTagPlayerID(%s)" % (tagPlayerID, recTagPlayerID), playerID)
        __DoArenaBattleOver(curPlayer)
        return
    # 失败结算入口: 前端同步
    SendGameServer_ArenaBattleOver(curPlayer, isWin)
    return
def OnKillBattleNPC(curPlayer, curNPC):
#    ## 击杀对手,前端本,使用木桩NPC作为对手
#
#    if curNPC.GetGameObjType() != IPY_GameWorld.gotNPC or curNPC.GetType() not in [ChConfig.ntPriWoodPilePVE, ChConfig.ntPriWoodPilePVP]:
#        GameWorld.DebugLog("击杀非木桩NPC,不结算!")
#        return
#
#    # 胜利结算入口:后端验证击杀对手
#    tagPlayerID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaBattleTagID)
#    GameWorld.DebugLog("竞技场击杀对手! tagPlayerID=%s" % tagPlayerID, curPlayer.GetPlayerID())
#    isWin = 1
#    SendGameServer_ArenaBattleOver(curPlayer, isWin)
    return
def SendGameServer_ArenaBattleOver(curPlayer, isWin):
    ## 发送GameServer通知战斗结算
def DoArenaMatchRefresh(curPlayer, isRefresh, gmMatchIDList=None, isSys=False):
    ## 玩家刷新匹配对手
    
    playerID = curPlayer.GetPlayerID()
    tagPlayerID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaBattleTagID)
    if not tagPlayerID:
        GameWorld.ErrLog("竞技场结算时没有对手ID!", playerID)
        __DoArenaBattleOver(curPlayer)
        return
    if not CheckArenaBattleCount(curPlayer):
        GameWorld.ErrLog("竞技场已经没有对战次数!", playerID)
        __DoArenaBattleOver(curPlayer)
        return
    tick = GameWorld.GetGameWorld().GetTick()
    if not GameWorld.SetPlayerTickTime(curPlayer, ChConfig.TYPE_Player_Tick_Arena, tick):
        GameWorld.ErrLog("结算竞技场CD中!tagPlayerID=%s" % tagPlayerID, playerID)
        return
    playerLV = curPlayer.GetLV()
    playerScore = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaScore)
    msgInfo = str(["BattleResult", {"tagPlayerID":tagPlayerID, "isWin":isWin, "playerLV":playerLV, "playerScore":playerScore,
                                    "realmLV":curPlayer.GetOfficialRank(), "fightPower":PlayerControl.GetFightPower(curPlayer)}])
    GameWorld.DebugLog("竞技场发送GameServer结算: %s" % msgInfo, playerID)
    GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(curPlayer.GetID(), 0, 0, "Arena", msgInfo, len(msgInfo))
    matchScoreList = IpyGameDataPY.GetFuncEvalCfg("ArenaMatch", 1)
    GameWorld.DebugLog("竞技场玩家刷新匹配列表: isRefresh=%s,playerScore=%s,gmMatchIDList=%s,isSys=%s" % (isRefresh, playerScore, gmMatchIDList, isSys), playerID)
    GameWorld.DebugLog("    matchScoreList=%s" % (matchScoreList), playerID)
    # 匹配对象缓存
    needMatchCount = len(matchScoreList)
    if playerID not in PyGameData.g_arenaPlayerMatchDict:
        PyGameData.g_arenaPlayerMatchDict[playerID] = []
    matchIDList = PyGameData.g_arenaPlayerMatchDict[playerID]
    if len(matchIDList) > needMatchCount:
        matchIDList = matchIDList[:needMatchCount] # 删除多余的个数,一般都是相同的,除非修改匹配数重读配置
    if not isRefresh and len(matchIDList) == needMatchCount:
        # 非刷新的并且已经有记录的直接同步
        GameWorld.DebugLog("    非刷新且有数据,直接同步!", playerID)
        __SyncMatchList(curPlayer, matchIDList)
        return
    if isRefresh and not gmMatchIDList and not isSys:
        costMoney, moneyValue = IpyGameDataPY.GetFuncEvalCfg("ArenaMatch", 4)
        if not costMoney or not moneyValue or not PlayerControl.PayMoney(curPlayer, costMoney, moneyValue, "Arena"):
    return
def __DoArenaBattleOver(curPlayer, retDict={}):
    ## 主动战斗结算奖励
    # @param isOK: True时才结算奖励,防止某些异常情况无法结算通知前端FBOver,导致卡副本
    billboardMgr = DBDataMgr.GetBillboardMgr()
    billBoard = billboardMgr.GetBillboard(ShareDefine.Def_BT_Arena)
    if not billBoard:
        return
    maxOrder = billBoard.GetCount()
    playerOrder = billBoard.IndexOfByID(playerID) + 1  # 玩家在排行榜中的名次,没有名次为-1
    
    GameWorld.DebugLog("结算竞技场对战奖励! retDict=%s" % retDict)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaBattleTagID, 0)
    matchRobotCntDict = IpyGameDataPY.GetFuncEvalCfg("ArenaMatch", 3)
    if playerOrder > 0:
        matchRobotRange = GameWorld.GetOrderValueByDict(matchRobotCntDict, playerOrder)
        matchRobotCnt = random.randint(matchRobotRange[0], matchRobotRange[1])
    else:
        matchRobotCnt = needMatchCount
    matchPlayerCnt = needMatchCount - matchRobotCnt
    GameWorld.DebugLog("    maxOrder=%s,playerOrder=%s,matchRobotCnt=%s,matchPlayerCnt=%s" % (maxOrder, playerOrder, matchRobotCnt, matchPlayerCnt), playerID)
    
    isOK = retDict.get("isOK", False)
    isWin = retDict.get("isWin", 0)
    if not isOK:
        # 一直异常的情况直接同步结束包,防止不结算卡副本
        FBCommon.NotifyFBOver(curPlayer, ChConfig.Def_FBMapID_ArenaBattle, 0, isWin)
    fromLowerCnt, matchPerRank = IpyGameDataPY.GetFuncEvalCfg("ArenaMatch", 2)
    toOrder = playerOrder + fromLowerCnt * matchPerRank # 从低名次往高名次匹配
    GameWorld.DebugLog("    fromLowerCnt=%s,matchPerRank=%s,toOrder=%s" % (fromLowerCnt, matchPerRank, toOrder), playerID)
    matchOrderList = [] # 匹配到的名次
    for _ in range(matchPlayerCnt):
        fromOrder = max(1, toOrder - matchPerRank)
        if toOrder <= fromOrder:
            break
        orderList = range(fromOrder, toOrder)
        random.shuffle(orderList)
        if playerOrder in orderList:
            orderList.remove(playerOrder) # 不包含自己
        if not orderList:
            break
        if fromOrder == 1:
            for order in orderList:
                if order > maxOrder:
                    continue
                matchOrderList.append(order)
                if len(matchOrderList) >= matchPlayerCnt:
                    break
        else:
            order = orderList[0]
            if order <= maxOrder:
                matchOrderList.append(order)
        GameWorld.DebugLog("    匹配玩家: fromOrder=%s,toOrder=%s,matchOrderList=%s" % (fromOrder, toOrder, matchOrderList), playerID)
        toOrder = fromOrder - 1
    # GM指定匹配测试
    if gmMatchIDList != None and curPlayer.GetGMLevel():
        for gmMatchID in gmMatchIDList:
            if gmMatchID == playerID:
                GameWorld.DebugAnswer(curPlayer, "目标ID不能是自己!无法匹配!%s" % gmMatchID)
                continue
            gmMatchOrder = billBoard.IndexOfByID(gmMatchID) + 1
            if gmMatchOrder <= 0:
                GameWorld.DebugAnswer(curPlayer, "目标ID不在榜单上!无法匹配!%s" % gmMatchID)
                continue
            GameWorld.DebugAnswer(curPlayer, "指定匹配ID(%s),order(%s)" % (gmMatchID, gmMatchOrder))
            if gmMatchID not in matchOrderList:
                matchOrderList.insert(0, gmMatchOrder)
        matchOrderList = matchOrderList[:needMatchCount]
    matchOrderList.sort()
    matchIDList = [] # 最终匹配的玩家ID列表
    for matchOrder in matchOrderList:
        if matchOrder > maxOrder or matchOrder <= 0:
            break
        billData = billBoard.At(matchOrder - 1)
        matchIDList.append(billData.GetID())
    needRobotCnt = needMatchCount - len(matchIDList)
    GameWorld.DebugLog("    匹配榜单结果: matchIDList=%s,matchOrderList=%s,needRobotCnt=%s" % (matchIDList, matchOrderList, needRobotCnt), playerID)
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    robotMax = ipyDataMgr.GetRobotCount()
    doCnt = 100
    while doCnt > 0 and needRobotCnt > 0 and robotMax:
        doCnt -= 1
        robotIndex = random.randint(0, robotMax - 1)
        robotIpyData = ipyDataMgr.GetRobotByIndex(robotIndex)
        robotID = robotIpyData.GetID()
        if robotID not in matchIDList:
            matchIDList.append(robotID)
            needRobotCnt -= 1
    GameWorld.DebugLog("    最终匹配结果: matchIDList=%s" % matchIDList, playerID)
    PyGameData.g_arenaPlayerMatchDict[playerID] = matchIDList
    __SyncMatchList(curPlayer, matchIDList)
        return
    
    #GameServer MapServer 同步有一定时间差,本功能存在被动挑战引发积分变动的情况,
    #curScore = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaScore)
    addScore = retDict["addScore"]
    updScore = retDict["updScore"]
    curOrder = retDict["curOrder"]
    updOrder = retDict["updOrder"]
    offlineRecTime = retDict.get("offlineRecTime", 0)
    # 扣次数
    if not offlineRecTime or GameWorld.CheckTimeIsSameServerDayEx(offlineRecTime):
        todayBattleCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaBattleCountDay) + 1
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaBattleCountDay, todayBattleCount)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaMatchRefreshCount, 0)
    # 更新积分
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaScore, updScore)
    highestScore = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaHighestScore)
    if updScore > highestScore:
        highestScore = updScore
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaHighestScore, highestScore)
        GameWorld.DebugLog("    更新竞技场历史最高分! %s" % highestScore)
    # 胜利给额外奖励
    itemList = retDict.get("awardItemList", [])
    ItemControler.GivePlayerItemOrMail(curPlayer, itemList)
    jsonItemList = FBCommon.GetJsonItemList(itemList)
    overDict = {FBCommon.Over_itemInfo:jsonItemList, "addScore":addScore, "updScore":updScore, "curOrder":curOrder, "updOrder":updOrder}
    FBCommon.NotifyFBOver(curPlayer, ChConfig.Def_FBMapID_ArenaBattle, 0, isWin, overDict)
    Sync_ArenaInfo(curPlayer)
    PlayerWeekParty.AddWeekPartyActionCnt(curPlayer, ChConfig.Def_WPAct_Arena, 1)
    PlayerFeastTravel.AddFeastTravelTaskValue(curPlayer, ChConfig.Def_FeastTravel_Arena, 1)
    PlayerActivity.AddDailyActionFinishCnt(curPlayer, ShareDefine.DailyActionID_Arena, 1)
    PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_Arena, 1)
    PlayerGubao.AddGubaoItemEffValue(curPlayer, PlayerGubao.GubaoEffType_Arena, 1)
    PlayerActTask.AddActTaskValue(curPlayer, ChConfig.ActTaskType_Arena)
    return
def __DoUpdateArenaScore(curPlayer, cmdDict={}):
    ''' 玩家直接更新积分,有以下几种情况,都是被挑战的,只更新积分
    1. 被动挑战在线时直接更新积分
    2. 离线/脱机时被挑战,上线后同步最新积分
    '''
    playerScore = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaScore)
    updScore = cmdDict.get("updScore", playerScore)
    if updScore == playerScore:
        return
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaScore, updScore)
    Sync_ArenaInfo(curPlayer)
    return
def GameServer_ArenaResult(curPlayer, msgList, tick):
    if not msgList:
        return
    cmd = msgList[0]
    cmdDict = msgList[1] if len(msgList) > 1 else {}
    retDict = msgList[2] if len(msgList) > 2 else {}
    # 刷新匹配
    if cmd == "MatchRefresh":
        isRefresh = cmdDict.get("isRefresh", False)
        refreshCountLimit = IpyGameDataPY.GetFuncCfg("ArenaSet", 5)
        if isRefresh and refreshCountLimit:
            updRefreshCount = min(250, curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaMatchRefreshCount) + 1)
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ArenaMatchRefreshCount, updRefreshCount)
            GameWorld.DebugLog("更新竞技场刷新匹配次数! updRefreshCount=%s" % updRefreshCount)
            Sync_ArenaInfo(curPlayer)
    # 主动对战结果
    elif cmd == "BattleResult":
        __DoArenaBattleOver(curPlayer, retDict)
    # 被动挑战更新积分
    elif cmd == "UpdScore":
        __DoUpdateArenaScore(curPlayer, cmdDict)
    return
def Sync_ArenaInfo(curPlayer, isReset=False):
    clientPack = ChPyNetSendPack.tagMCArenaPlayerInfo()
    clientPack.IsReset = 1 if isReset else 0
    clientPack.Score = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaScore)
    clientPack.BattleCountToday = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaBattleCountDay)
    clientPack.MatchRefreshCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaMatchRefreshCount)
    clientPack.ItemAddBattleCountToday = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaItemAddCount)
def __SyncMatchList(curPlayer, matchIDList):
    ## 同步匹配列表
    clientPack = ChPyNetSendPack.tagSCArenaMatchList()
    clientPack.MatchList = []
    for matchID in matchIDList:
        viewCache = PlayerViewCache.FindViewCache(matchID)
        matchInfo = ChPyNetSendPack.tagSCArenaMatchInfo()
        matchInfo.PlayerID = matchID
        if viewCache:
            matchInfo.PlayerName = viewCache.GetPlayerName()
            matchInfo.RealmLV = viewCache.GetRealmLV()
            matchInfo.Face = viewCache.GetFace()
            matchInfo.FacePic = viewCache.GetFacePic()
            matchInfo.FightPower = viewCache.GetFightPower()
            matchInfo.FightPowerEx = viewCache.GetFightPowerEx()
        else:
            matchInfo.PlayerName = "p%s" % matchID
        clientPack.MatchList.append(matchInfo)
    clientPack.MatchCount = len(clientPack.MatchList)
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return
def Sync_ArenaInfo(curPlayer):
    clientPack = ChPyNetSendPack.tagSCArenaPlayerInfo()
    clientPack.Score = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ArenaScore)
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerBillboard.py
@@ -61,10 +61,6 @@
        # 跨服服务器不用更新本服榜
        return
    
    UpdatePlayerFPTotalBillboard(curPlayer, True) # 战斗力榜
    UpdateHorseBillboard(curPlayer, True, False) # 坐骑榜
    UpdatePyPetBillboard(curPlayer, True, False) # 灵宠榜
    UpdateRealmBillboard(curPlayer) # 境界榜
    return
def UpdatePlayerFPTotalBillboard(curPlayer, isForceUpdate=False, isCheckRule=True):
@@ -149,39 +145,83 @@
    ##境界榜
    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())
#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
    
    return True
def UpdatePlayerBillboard(curPlayer, bType, cmpValue, cmpValue2=0, cmpValue3=0, value1=0, value2=0, autoSort=False, **kwargs):
def UpdatePlayerBillboard(curPlayer, bType, cmpValue, cmpValue2=0, cmpValue3=0, value1=None, value2=0, autoSort=False, **kwargs):
    ## 更新玩家排行榜
    
    #if not cmpValue and not cmpValue2 and not cmpValue3:
    #    return
    
    if not __CanPlayerBillboardComm(curPlayer):
        return
    playerJob = GetBillboardJob(curPlayer)
    playerID = curPlayer.GetID()
    playerName = curPlayer.GetName()
    playerName = curPlayer.GetPlayerName()
    playerOpInfo = GetBillboardOperateInfo(curPlayer)
    if value1 == None:
        value1 = curPlayer.GetOfficialRank()
    kwargs["value3"] = curPlayer.GetFace()
    kwargs["value4"] = curPlayer.GetFacePic()
    if bType in ShareDefine.BTValue1_OfficialRankList:
        value1 = curPlayer.GetOfficialRank()
    kwargs["value5"] = curPlayer.GetModelMark()
        
    groupValue1 = 0
    UpdateBillboard(bType, groupValue1, playerID, playerName, playerOpInfo, playerJob, value1, value2, 
                    cmpValue, cmpValue2, cmpValue3, autoSort=autoSort, **kwargs)
    return
def UpdateBillboardByID(dataID, billboardType, cmpValue, cmpValue2=0, cmpValue3=0, autoSort=False):
    ## 直接根据榜单ID修改榜单排行相关值,其他值不修改
    if GameWorld.IsCrossServer():
        if billboardType not in ShareDefine.CrossBillboardTypeList:
            return
    else:
        if billboardType not in ShareDefine.BillboardTypeList:
            return
    if not dataID:
        return
    groupValue1, groupValue2 = 0, 0
    billboardMgr = DBDataMgr.GetBillboardMgr()
    billboardObj = billboardMgr.GetBillboard(billboardType, groupValue1, groupValue2)
    billboardData = billboardObj.FindByID(dataID)
    if not billboardData:
        return
    isNewData = False
    cmpValueChange = isNewData or billboardData.GetCmpValue() != cmpValue or billboardData.GetCmpValue2() != cmpValue2 \
        or (cmpValue3 and billboardData.GetCmpValue3() != cmpValue3)
    # 没设置值默认为时间time,先上榜的排前面
    if cmpValue3 == 0:
        # 时间权值仅在比较值变更的情况下才更新, 防止其他附属值更新时导致比较值相同的玩家名次间会变动的问题
        if cmpValueChange:
            calcTime = GameWorld.ChangeTimeStrToNum("2090-01-01 00:00:00")
            cmpValue3 = max(0, calcTime - int(time.time())) # 比较值3如果没指定值则默认存当前更新的time
        else:
            cmpValue3 = billboardData.GetCmpValue3()
    billboardData.SetCmpValue(cmpValue)
    billboardData.SetCmpValue2(cmpValue2)
    billboardData.SetCmpValue3(cmpValue3)
    GameWorld.DebugLog("更新排行榜值: billboardType=%s,groupValue1=%s,groupValue2=%s,dataID=%s,cmpValueChange=%s,cmpValue=%s,cmpValue2=%s,cmpValue3=%s"
                       % (billboardType, groupValue1, groupValue2, dataID, cmpValueChange,
                          cmpValue, cmpValue2, cmpValue3), dataID)
    if not autoSort:
        if isNewData or cmpValueChange:
            billboardObj.SetSortDelay()
    else:
        billboardObj.SortData()
    return True
def UpdateBillboard(billboardType, groupValue1, dataID, name1, name2, type2, value1, value2, cmpValue,
                    cmpValue2=0, cmpValue3=0, groupValue2=0, id2=0, autoSort=True, **kwargs):
    ''' 更新排行榜
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
@@ -4373,6 +4373,8 @@
    value = ComMainLevelValue(chapterID, levelNum, wave)
    SetMainLevelPassValue(curPlayer, value)
    if wave == 0:
        lvID = chapterID * 100 + levelNum
        PlayerBillboard.UpdatePlayerBillboard(curPlayer, ShareDefine.Def_BT_MainLevel, lvID)
        PlayerTask.UpdTaskValue(curPlayer, ChConfig.TaskType_MainLevel)
    return value
def GetMainLevelPassInfo(curPlayer):
@@ -4559,7 +4561,7 @@
        NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FightPower_HighestEx, highestFightPower / ChConfig.Def_PerPointValue)
        
    GameWorld.DebugLog("总战力: %s, 历史最高战力: %s, beforeFightPower=%s" % (value, highestFightPower, beforeFightPower), curPlayer.GetPlayerID())
    PlayerBillboard.UpdatePlayerFPTotalBillboard(curPlayer)
    #PlayerBillboard.UpdatePlayerFPTotalBillboard(curPlayer)
    # 记录开服活动数据
    #OpenServerCampaign.UpdOpenServerCampaignRecordData(curPlayer, ShareDefine.Def_Campaign_Type_FightPower, totalFightPower)
    #if beforeFightPower != totalFightPower:
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
@@ -115,6 +115,7 @@
    
    #仙盟
    PlayerFamily.FamilyOnDay()
    PlayerArena.OnDay()
    
    PlayerOfflineSupport.OnDay()
    playerManager = GameWorld.GetPlayerManager()
@@ -154,6 +155,8 @@
def DoLogic_OnWeek(tick):
    GameWorld.Log("MapServer -> OnWeek!")
    
    PlayerArena.OnWeek()
    playerManager = GameWorld.GetPlayerManager()
    for i in xrange(playerManager.GetPlayerCount()):
        curPlayer = playerManager.GetPlayerByIndex(i)
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerOnline.py
@@ -156,6 +156,8 @@
        
        # 主线战斗
        self.mainFight = TurnAttack.MainFight(playerID)
        self._lastBatBufferInfo = [] # 最后一场战斗临时回放 ["guid", "buffer"]
        return
    
    def OnClear(self):
@@ -247,6 +249,11 @@
        GameWorld.DebugLog("武将物品养成更新索引: %s, 影响阵容:%s" % (itemIndexList, effLineupIDList), self.playerID)
        return effLineupIDList
    
    def GetLastBatBuffer(self): return self._lastBatBufferInfo
    def SetLastBatBuffer(self, guid, batBuffer):
        self._lastBatBufferInfo = [guid, batBuffer]
        return
class OnlineMgr():
    ## 准在线玩家管理
    
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerViewCache.py
@@ -22,9 +22,10 @@
import NetPackCommon
import ChPyNetSendPack
import IpyGameDataPY
import IPY_GameWorld
import ShareDefine
import TurnAttack
import DBDataMgr
import GameObj
import random
import time
@@ -36,12 +37,18 @@
    return
def OnPlayerLogout(curPlayer):
    if curPlayer.GetLV() < 10:
    if curPlayer.GetLV() < IpyGameDataPY.GetFuncCfg("PlayerViewCache", 1):
        return
    
    curCache = UpdPlayerViewCache(curPlayer)
    if curCache and not IsSaveDBViewCache(curCache):
    playerID = curPlayer.GetPlayerID()
    curCache = FindViewCache(playerID)
    if not curCache:
        return
    UpdPlayerViewCache(curPlayer, True)
    if not IsSaveDBViewCache(curCache):
        DBDataMgr.GetPlayerViewCacheMgr().DelPlayerViewCache(curPlayer.GetPlayerID())
        return
        
    return
@@ -53,6 +60,8 @@
    for index in range(viewCacheMgr.GetCount())[::-1]: # 有删除需倒序遍历
        viewCache = viewCacheMgr.At(index)
        playerID = viewCache.GetPlayerID()
        if playerID < ShareDefine.RealPlayerIDStart:
            continue
        curPlayer = playerManager.FindPlayerByID(playerID)
        if curPlayer:
            continue
@@ -68,6 +77,9 @@
        return False
    
    playerID = viewCache.GetPlayerID()
    if playerID < ShareDefine.RealPlayerIDStart:
        #非真实玩家不入库
        return False
    
    #某个功能中不能删除的
    #...
@@ -100,7 +112,7 @@
        
    return False
def FindViewCache(playerID, isAdd=False):
def FindViewCache(playerID):
    '''查找玩家缓存,如果不存在,则会有额外逻辑,如从redis、db直接找,
            本服玩家理论上一定有查看缓存,因为如果不存在会直接从db读,除非该玩家数据被删除
            跨服玩家理论上也一定有缓存,只是通过跨服或从子服查询,延迟获得
@@ -115,7 +127,7 @@
            curCache = updCache
            
    # 真实玩家
    elif playerID > ShareDefine.FackPlayerIDMax:
    elif playerID >= ShareDefine.RealPlayerIDStart:
        curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
        # 本服在线玩家,直接生成新数据
        if curPlayer:
@@ -132,6 +144,10 @@
            pass
            # 跨服玩家,去子服拉取数据,理论上也一定有,但是如果需要拉数据,有一定延迟
            # 逻辑待扩展
    # 机器人
    elif ShareDefine.RobotIDStart <= playerID <= ShareDefine.RobotIDMax:
        curCache = UpdRobotViewCache(playerID)
            
    # 假玩家,默认添加
    elif ShareDefine.FackPlayerIDStart <= playerID <= ShareDefine.FackPlayerIDMax:
@@ -152,7 +168,7 @@
    return curCache
def __CheckUpdViewCache(playerID):
    if playerID <= ShareDefine.FackPlayerIDMax:
    if playerID < ShareDefine.RealPlayerIDStart:
        return
    curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
    if not curPlayer:
@@ -188,6 +204,7 @@
    curCache.SetRealmLV(curPlayer.GetOfficialRank())
    curCache.SetFace(curPlayer.GetFace())
    curCache.SetFacePic(curPlayer.GetFacePic())
    curCache.SetModelMark(curPlayer.GetModelMark())
    curCache.SetFamilyID(curPlayer.GetFamilyID())
    curCache.SetFamilyName(curPlayer.GetFamilyName())
    curCache.SetFamilyEmblemID(PlayerControl.GetFamilyEmblemID(curPlayer))
@@ -197,22 +214,30 @@
    if isOffline:
        curCache.SetOffTime(int(time.time()))
        
    plusDict = curCache.GetPlusDict()
    # 装备
    equipDict = {}
    equipPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptEquip)
    for equipPlace in ChConfig.Def_MainEquipPlaces:
        equipIndex = equipPlace - 1
        if equipIndex < 0 or equipIndex >= equipPack.GetCount():
            continue
        curEquip = equipPack.GetAt(equipIndex)
        if not curEquip or curEquip.IsEmpty():
            continue
        equipDict["%s" % equipIndex] = {"ItemID":curEquip.GetItemTypeID(), "UserData":curEquip.GetUserData()}
        
    #战斗属性
    plusDict.update({
                     "MinAtk":curPlayer.GetMinAtk(),
                     "MaxAtk":curPlayer.GetMaxAtk(),
                     "Def":curPlayer.GetDef(),
                     "MaxHP":GameObj.GetMaxHP(curPlayer),
                     "Hit":curPlayer.GetHit(),
                     "Miss":curPlayer.GetMiss(),
                     "SuperHitRate":curPlayer.GetSuperHitRate(), # 暴击率
                     })
    # 功能数据
    # 阵容
    lineupDict = {}
    for lineupID in ShareDefine.LineupList:
        lineupInfo = TurnAttack.GetPlayerLineupInfo(curPlayer, lineupID)
        if not lineupInfo:
            continue
        lineupDict["%s" % lineupID] = lineupInfo
    
    # 其他
    plusDict= {"Equip":equipDict, "Lineup":lineupDict}
    curCache.SetPlusDict(plusDict)
    
    return curCache
@@ -237,6 +262,7 @@
    curCache.SetRealmLV(dbPlayer.OfficialRank)
    curCache.SetFace(dbPlayer.Face)
    curCache.SetFacePic(dbPlayer.FacePic)
    curCache.SetModelMark(dbPlayer.ModelMark)
    curCache.SetFamilyID(familyID)
    family = DBDataMgr.GetFamilyMgr().FindFamily(familyID)
    curCache.SetFamilyName(family.GetName() if family else "")
@@ -245,6 +271,58 @@
    curCache.SetFightPowerTotal(dbPlayer.FightPowerEx * ChConfig.Def_PerPointValue + dbPlayer.FightPower)
    curCache.SetServerID(GameWorld.GetAccIDServerID(dbPlayer.AccID))
    curCache.SetOffTime(GameWorld.ChangeTimeStrToNum(dbPlayer.LogoffTime) if dbPlayer.LogoffTime else 0)
    return curCache
def GetRobotByViewCache(curCache):
    ## 根据缓存内容获取机器人数据
    if not curCache:
        return
    robotDict = {
                 "PlayerName" : curCache.GetPlayerName(),
                 "LV" : curCache.GetLV(),
                 "Job" : curCache.GetJob(),
                 "RealmLV" : curCache.GetRealmLV(),
                 "Face" : curCache.GetFace(),
                 "FacePic" : curCache.GetFacePic(),
                 "ModelMark" : curCache.GetModelMark(),
                 "FightPower" : curCache.GetFightPowerTotal(),
                 "PlusData" : curCache.GetPlusDict(),
                 }
    return robotDict
def UpdRobotViewCache(robotID):
    ## 更新机器人查看缓存
    robotIpyData = IpyGameDataPY.GetIpyGameData("Robot", robotID)
    if not robotIpyData:
        return
    try:
        robotInfo = eval(robotIpyData.GetViewCache())
    except:
        return
    viewCacheMgr = DBDataMgr.GetPlayerViewCacheMgr()
    curCache = viewCacheMgr.GetPlayerViewCache(robotID)
    if not curCache:
        curCache = viewCacheMgr.AddPlayerViewCache(robotID)
    #curCache.SetAccID(dbPlayer.AccID)
    curCache.SetPlayerName(robotInfo.get("PlayerName", "p%s" % robotID))
    curCache.SetLV(robotInfo.get("LV", 1))
    curCache.SetJob(robotInfo.get("Job", 1))
    curCache.SetRealmLV(robotInfo.get("RealmLV", 0))
    curCache.SetFace(robotInfo.get("Face", 0))
    curCache.SetFacePic(robotInfo.get("FacePic", 0))
    curCache.SetModelMark(robotInfo.get("ModelMark", 0))
    #机器人暂定没有仙盟、称号
    #curCache.SetFamilyID(familyID)
    #family = DBDataMgr.GetFamilyMgr().FindFamily(familyID)
    #curCache.SetFamilyName(family.GetName() if family else "")
    #curCache.SetFamilyEmblemID(family.GetEmblemID() if family else 0)
    #curCache.SetTitleID(PlayerControl.GetTitleID(curPlayer))
    curCache.SetFightPowerTotal(robotInfo.get("FightPower", 1))
    curCache.SetServerID(GameWorld.GetGameWorld().GetServerID()) # 默认本服
    curCache.SetPlusDict(robotInfo.get("PlusData", {}))
    #curCache.SetOffTime(0)
    return curCache
#//A2 12 查看玩家详细信息#tagCMViewPlayerInfo
@@ -285,6 +363,7 @@
    clientPack.RealmLV = curCache.GetRealmLV()
    clientPack.Face = curCache.GetFace()
    clientPack.FacePic = curCache.GetFacePic()
    clientPack.ModelMark = curCache.GetModelMark()
    clientPack.TitleID = curCache.GetTitleID()
    clientPack.ServerID = curCache.GetServerID()
    clientPack.FightPower = curCache.GetFightPower()
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_Arena.py
File was deleted
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
@@ -35,6 +35,8 @@
g_turnFightMgr = None
g_arenaPlayerMatchDict = {} # 本服竞技场玩家匹配记录缓存 {playerID:[tagPlayerID, ...], ...}
g_mapIDTxtInfo = {} # MapID.txt 加载的信息
g_realmDiffPlayerDict = {} # 境界难度玩家信息 {realm:[playerID, ...], ...}
g_realmDiffNPCRefresh = {} # {(lineID, realm):{refreshID:tagNPCRefresh, ...}}
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/Collections/DataServerPlayerData.py
@@ -25884,6 +25884,7 @@
        ('RealmLV', ctypes.c_ubyte),
        ('Face', ctypes.c_int),
        ('FacePic', ctypes.c_int),
        ('ModelMark', ctypes.c_ulong),
        ('FamilyID', ctypes.c_ulong),
        ('FamilyName', ctypes.c_char * 33),
        ('FamilyEmblemID', ctypes.c_ushort),
@@ -25910,6 +25911,7 @@
        self.RealmLV = 0
        self.Face = 0
        self.FacePic = 0
        self.ModelMark = 0
        self.FamilyID = 0
        self.FamilyName = ''
        self.FamilyEmblemID = 0
@@ -25938,6 +25940,7 @@
        self.RealmLV, pos = CommFunc.ReadBYTE(buf, pos)
        self.Face, pos = CommFunc.ReadDWORD(buf, pos)
        self.FacePic, pos = CommFunc.ReadDWORD(buf, pos)
        self.ModelMark, pos = CommFunc.ReadDWORD(buf, pos)
        self.FamilyID, pos = CommFunc.ReadDWORD(buf, pos)
        self.FamilyName, pos = CommFunc.ReadString(buf, pos, 33)
        self.FamilyEmblemID, pos = CommFunc.ReadWORD(buf, pos)
@@ -25961,6 +25964,7 @@
        buf = CommFunc.WriteBYTE(buf, self.RealmLV)
        buf = CommFunc.WriteDWORD(buf, self.Face)
        buf = CommFunc.WriteDWORD(buf, self.FacePic)
        buf = CommFunc.WriteDWORD(buf, self.ModelMark)
        buf = CommFunc.WriteDWORD(buf, self.FamilyID)
        buf = CommFunc.WriteString(buf, sizeof(ctypes.c_char) * 33, self.FamilyName)
        buf = CommFunc.WriteWORD(buf, self.FamilyEmblemID)
@@ -25984,6 +25988,7 @@
        length += sizeof(ctypes.c_int)
        length += sizeof(ctypes.c_int)
        length += sizeof(ctypes.c_ulong)
        length += sizeof(ctypes.c_ulong)
        length += sizeof(ctypes.c_char) * 33
        length += sizeof(ctypes.c_ushort)
        length += sizeof(ctypes.c_ulong)
@@ -26006,6 +26011,7 @@
        rec[u'RealmLV'] = self.RealmLV
        rec[u'Face'] = self.Face
        rec[u'FacePic'] = self.FacePic
        rec[u'ModelMark'] = self.ModelMark
        rec[u'FamilyID'] = self.FamilyID
        rec[u'FamilyName'] = fix_incomingText(self.FamilyName)
        rec[u'FamilyEmblemID'] = self.FamilyEmblemID
@@ -26028,6 +26034,7 @@
        self.RealmLV = rec.get(u'RealmLV', 0)
        self.Face = rec.get(u'Face', 0)
        self.FacePic = rec.get(u'FacePic', 0)
        self.ModelMark = rec.get(u'ModelMark', 0)
        self.FamilyID = rec.get(u'FamilyID', 0)
        self.FamilyName = fix_outgoingText(rec.get(u'FamilyName', u''))
        self.FamilyEmblemID = rec.get(u'FamilyEmblemID', 0)
@@ -26149,6 +26156,7 @@
            RealmLV = %s,
            Face = %s,
            FacePic = %s,
            ModelMark = %s,
            FamilyID = %s,
            FamilyName = %s,
            FamilyEmblemID = %s,
@@ -26169,6 +26177,7 @@
                self.RealmLV,
                self.Face,
                self.FacePic,
                self.ModelMark,
                self.FamilyID,
                self.FamilyName,
                self.FamilyEmblemID,
@@ -26184,7 +26193,7 @@
        return output
    def dumpString(self):
        output = '''%1s\t%1s\t%1s\t%1s\t%1s\t%1s\t%1s\t%1s\t%1s\t%1s\t%1s\t%1s\t%1s\t%1s\t%1s\t%1s\t%1s\t%1s'''%(
        output = '''%1s\t%1s\t%1s\t%1s\t%1s\t%1s\t%1s\t%1s\t%1s\t%1s\t%1s\t%1s\t%1s\t%1s\t%1s\t%1s\t%1s\t%1s\t%1s'''%(
                self.PlayerID,
                self.AccID,
                self.PlayerName,
@@ -26193,6 +26202,7 @@
                self.RealmLV,
                self.Face,
                self.FacePic,
                self.ModelMark,
                self.FamilyID,
                self.FamilyName,
                self.FamilyEmblemID,
@@ -28174,223 +28184,6 @@
        else:
            self.Name = Str[:33]
            
# 通用记录表新 #tagDBGameRec
class tagDBGameRec(Structure):
    _pack_ = 1
    _fields_ = [
        ('RecType', ctypes.c_ushort),
        ('RecID', ctypes.c_ulong),
        ('Time', ctypes.c_double),
        ('Value1', ctypes.c_ulong),
        ('Value2', ctypes.c_ulong),
        ('Value3', ctypes.c_ulong),
        ('Value4', ctypes.c_ulong),
        ('Value5', ctypes.c_ulong),
        ('Value6', ctypes.c_ulong),
        ('Value7', ctypes.c_ulong),
        ('Value8', ctypes.c_ulong),
        ('UserDataLen', ctypes.c_ushort),
        ('UserData', ctypes.c_char_p),
        ('ADOResult', ctypes.c_ulong),
    ]
    def __init__(self):
        Structure.__init__(self)
        self.clear()
    def clear(self):
        self.RecType = 0
        self.RecID = 0
        self.Time = 0.0
        self.Value1 = 0
        self.Value2 = 0
        self.Value3 = 0
        self.Value4 = 0
        self.Value5 = 0
        self.Value6 = 0
        self.Value7 = 0
        self.Value8 = 0
        self.UserDataLen = 0
        self.UserData = ''
    def readData(self, buf, pos = 0, length = 0):
        if not pos <= length:
            msg = error.formatMsg('error', error.ERROR_NO_148, '(pos = %s) > (length = %s)'%(pos, length))
            mylog.error(msg)
            return -1
        if len(buf) < pos + self.getLength():
            msg = error.formatMsg('error', error.ERROR_NO_149, 'len = %s while %s expected!'%(len(buf) - pos, self.getLength()))
            mylog.error(msg)
        self.clear()
        self.RecType, pos = CommFunc.ReadWORD(buf, pos)
        self.RecID, pos = CommFunc.ReadDWORD(buf, pos)
        self.Time, pos = CommFunc.ReadDouble(buf, pos)
        self.Value1, pos = CommFunc.ReadDWORD(buf, pos)
        self.Value2, pos = CommFunc.ReadDWORD(buf, pos)
        self.Value3, pos = CommFunc.ReadDWORD(buf, pos)
        self.Value4, pos = CommFunc.ReadDWORD(buf, pos)
        self.Value5, pos = CommFunc.ReadDWORD(buf, pos)
        self.Value6, pos = CommFunc.ReadDWORD(buf, pos)
        self.Value7, pos = CommFunc.ReadDWORD(buf, pos)
        self.Value8, pos = CommFunc.ReadDWORD(buf, pos)
        self.UserDataLen, pos = CommFunc.ReadWORD(buf, pos)
        tmp, pos = CommFunc.ReadString(buf, pos, self.UserDataLen)
        self.UserData = ctypes.c_char_p(tmp)
        return self.getLength()
    def getBuffer(self):
        buf = ''
        buf = CommFunc.WriteWORD(buf, self.RecType)
        buf = CommFunc.WriteDWORD(buf, self.RecID)
        buf = CommFunc.WriteDouble(buf, self.Time)
        buf = CommFunc.WriteDWORD(buf, self.Value1)
        buf = CommFunc.WriteDWORD(buf, self.Value2)
        buf = CommFunc.WriteDWORD(buf, self.Value3)
        buf = CommFunc.WriteDWORD(buf, self.Value4)
        buf = CommFunc.WriteDWORD(buf, self.Value5)
        buf = CommFunc.WriteDWORD(buf, self.Value6)
        buf = CommFunc.WriteDWORD(buf, self.Value7)
        buf = CommFunc.WriteDWORD(buf, self.Value8)
        buf = CommFunc.WriteWORD(buf, self.UserDataLen)
        buf = CommFunc.WriteString(buf, self.UserDataLen, self.UserData)
        return buf
    def getLength(self):
        length = 0
        length += sizeof(ctypes.c_ushort)
        length += sizeof(ctypes.c_ulong)
        length += sizeof(ctypes.c_double)
        length += sizeof(ctypes.c_ulong)
        length += sizeof(ctypes.c_ulong)
        length += sizeof(ctypes.c_ulong)
        length += sizeof(ctypes.c_ulong)
        length += sizeof(ctypes.c_ulong)
        length += sizeof(ctypes.c_ulong)
        length += sizeof(ctypes.c_ulong)
        length += sizeof(ctypes.c_ulong)
        length += sizeof(ctypes.c_ushort)
        length += self.UserDataLen
        return length
    def getRecord(self):
        '''组织存储记录'''
        rec = {}
        rec[u'RecType'] = self.RecType
        rec[u'RecID'] = self.RecID
        rec[u'Time'] = self.Time
        rec[u'Value1'] = self.Value1
        rec[u'Value2'] = self.Value2
        rec[u'Value3'] = self.Value3
        rec[u'Value4'] = self.Value4
        rec[u'Value5'] = self.Value5
        rec[u'Value6'] = self.Value6
        rec[u'Value7'] = self.Value7
        rec[u'Value8'] = self.Value8
        rec[u'UserDataLen'] = self.UserDataLen
        rec[u'UserData'] = fix_incomingText(self.UserData)
        return rec
    def readRecord(self, rec):
        '''由于MongoDB读出来是unicode,所有字符串需要进行转换'''
        self.RecType = rec.get(u'RecType', 0)
        self.RecID = rec.get(u'RecID', 0)
        self.Time = rec.get(u'Time', 0)
        self.Value1 = rec.get(u'Value1', 0)
        self.Value2 = rec.get(u'Value2', 0)
        self.Value3 = rec.get(u'Value3', 0)
        self.Value4 = rec.get(u'Value4', 0)
        self.Value5 = rec.get(u'Value5', 0)
        self.Value6 = rec.get(u'Value6', 0)
        self.Value7 = rec.get(u'Value7', 0)
        self.Value8 = rec.get(u'Value8', 0)
        self.UserDataLen = rec.get(u'UserDataLen', 0)
        self.UserData = fix_outgoingText(rec.get(u'UserData', u''))
#Can not implement adoLoadStr method:No key defined!
#Can not implement adoInsertStr method:No key defined!
#Can not implement adoUpdateStr method:No key defined!
#Can not implement adoUpdateStr method:No key defined!
#Can not implement adoCheckUpdateStr method:No key defined!
#Can not implement adoCheckUpdateExStr method:No key defined!
    def getAdoRecords(self, resultCollection):
        '''查询结果打包成二进制流'''
        result = ''
        result = CommFunc.WriteDWORD(result, resultCollection.count())
        for rec in resultCollection:
            self.readRecord(rec)
            result += self.getBuffer()
        return result
#Can not implement adoQueryIndexStr method:No key defined!
    def adoQueryCustom(self, collection, queryDict):
        '''自定义查询'''
        resultCollection = collection.find(queryDict)
        return self.getAdoRecords(resultCollection)
    def adoQueryAll(self, collection):
        '''查询所有'''
        resultCollection = collection.find()
        return self.getAdoRecords(resultCollection)
#Can not implement adoDeleteByIndexStr method:No key defined!
    def outputString(self):
        output = '''// 通用记录表新 #tagDBGameRec:
            RecType = %s,
            RecID = %s,
            Time = %s,
            Value1 = %s,
            Value2 = %s,
            Value3 = %s,
            Value4 = %s,
            Value5 = %s,
            Value6 = %s,
            Value7 = %s,
            Value8 = %s,
            UserDataLen = %s,
            UserData = %s,
            ADOResult = %s,
            '''%(
                self.RecType,
                self.RecID,
                self.Time,
                self.Value1,
                self.Value2,
                self.Value3,
                self.Value4,
                self.Value5,
                self.Value6,
                self.Value7,
                self.Value8,
                self.UserDataLen,
                self.UserData,
                self.ADOResult,
            )
        return output
    def dumpString(self):
        output = '''%1s\t%1s\t%1s\t%1s\t%1s\t%1s\t%1s\t%1s\t%1s\t%1s\t%1s\t%1s\t%1s'''%(
                self.RecType,
                self.RecID,
                self.Time,
                self.Value1,
                self.Value2,
                self.Value3,
                self.Value4,
                self.Value5,
                self.Value6,
                self.Value7,
                self.Value8,
                self.UserDataLen,
                self.UserData,
            )
        return output
# 功能队伍表 #tagDBFuncTeam
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/GMToolLogicProcess/ProjSpecialProcess.py
@@ -325,6 +325,8 @@
            elif isinstance(ret, tuple):
                execType = ret[0]
                execInfo = ret[1]
        else:
            execType = GMCommon.Def_GMCmdNone
                
        GetGMOrderMgr().PopCmd(self.orderId)
        GMCommandResult(self.orderId, self.funcName, execType, execInfo)
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
@@ -62,8 +62,15 @@
#支持超20亿数值的数值点单位数值, 1亿
Def_PerPointValue = 100000000
#真实玩家ID、仙盟ID是从100000开始
#假玩家ID
#真实玩家ID、仙盟ID是从 1000000 开始
RealPlayerIDStart = 1000000
RealFamilyIDStart = 1000000
#机器人ID - 供功能用,线上版本支持的机器人
RobotIDStart = 10001
RobotIDMax = 19999
#假玩家ID - 供内部功能测试用,一般线上版本没有,仅内部功能开发、测试用
FackPlayerIDStart = 1
FackPlayerIDMax = 9999
@@ -466,7 +473,8 @@
#此地方改动需要通知修改ChConfig.Def_BT_Cnt, ChConfig.Def_BT_SaveType
BillboardTypeList = (
Def_BT_MainLevel,    # 主线关卡过关榜 0
) = range(0, 1)
Def_BT_Arena,    # 演武场积分周榜 1
) = range(0, 2)
''' 跨服排行榜类型, 从 150 开始,最大条数在功能配置表 CrossBillboardSet 配置,没配默认100
与本服榜单存储的是不一样的数据库表格,理论上类型可以和本服榜单类型重复,为了做下区分防误导,跨服榜单从 150 开始
@@ -479,11 +487,10 @@
BillboardTypeAllList = BillboardTypeList + CrossBillboardTypeList
BillboardNameDict = {Def_BT_MainLevel:"主线过关榜", Def_BT_Arena:"演武场积分周榜"}
#仙盟榜单类型
FamilyBillboardList = []
#排行榜Value1存储境界信息的榜单列表
BTValue1_OfficialRankList = [Def_BT_MainLevel]
##---比率---
#百分率
@@ -727,7 +734,8 @@
CDBPlayerRefresh_DOTPer, # 持续增伤 283
CDBPlayerRefresh_DOTPerDef, # 持续减伤 284
CDBPlayerRefresh_GoldRushEnergy, # 淘金令 285
) = range(146, 286)
CDBPlayerRefresh_ArenaTicket, # 挑战券 286
) = range(146, 287)
TYPE_Price_Gold_Paper_Money = 5    # 金钱类型,(先用礼券,再用金子)
TYPE_Price_Family_Contribution = 6 # 战盟贡献度(活跃度转换得来)
@@ -768,12 +776,13 @@
TYPE_Price_HuanjinggeScore = 50    # 幻境阁积分
TYPE_Price_HeroScore = 51    # 招募积分
TYPE_Price_GoldRushEnergy = 52    # 淘金令体力
TYPE_Price_ArenaTicket = 53    # 演武场挑战券
TYPE_Price_PayCoinDay = 98    # 代币时效,每日过天重置
TYPE_Price_PayCoin = 99    # 代币
#key可用于遍历所有货币,value仅GM相关会用到
MoneyNameDict = {
                 1:"金币", 41:"战锤", 42:"将星玉髓", 51:"招募积分", 52:"淘金令",
                 1:"金币", 41:"战锤", 42:"将星玉髓", 51:"招募积分", 52:"淘金令", 53:"挑战券",
                 98:"代币时效", 99:"代币"
                 }
#MoneyNameDict = {
@@ -787,11 +796,6 @@
#需要记录累计消耗的货币类型
UseTotalPriceTypeList = [TYPE_Price_TiandaoFruit]
#以下是旧的金钱类型
TYPE_Price_Magic_Integral = 101      # 魔方寻宝积分
TYPE_Price_GongXun = 105    # 功勋点
TYPE_Price_ArrestPoint = 110    # 悬赏积分
# 自定义积分及通知字典 {货币类型:通知客户端刷新类型, ...} , 如果不通知的话刷新类型则配置 None
TYPE_Price_CurrencyDict = {
@@ -825,6 +829,7 @@
                           TYPE_Price_HuanjinggeScore:CDBPlayerRefresh_HuanjinggeScore,
                           TYPE_Price_HeroScore:CDBPlayerRefresh_HeroScore,
                           TYPE_Price_GoldRushEnergy:CDBPlayerRefresh_GoldRushEnergy,
                           TYPE_Price_ArenaTicket:CDBPlayerRefresh_ArenaTicket,
                           TYPE_Price_PayCoinDay:CDBPlayerRefresh_PayCoinDay,
                           }
@@ -927,11 +932,14 @@
                       Def_GameRecType_FamilyGCZCityWall, # 仙盟攻城战城池信息, zoneID 305
                       Def_GameRecType_TalkCache, # 聊天缓存,频道 306
                       Def_GameRecType_PlayerOfflineUnprocessed, # 离线玩家待处理事件,playerID 307
                       ) = range(300, 1 + 307)
                       Def_GameRecType_ArenaRecord, # 演武场玩家挑战记录,playerID 308
                       ) = range(300, 1 + 308)
#通用信息记录新 - 字典key配置,如果有配置,则可额外按对应记录Value值存储字典,方便快速取值,可配置Value编号 1~8,配空默认 Value1
Def_GameRecValueKeyDict = {
                           Def_GameRecType_Xiangong:[1],
                           }
#仅查看自己的记录
Def_ViewGameRecSelfList = [Def_GameRecType_ArenaRecord]
#通用信息记录类型
Def_UniversalGameRecTypeList = (
@@ -1326,9 +1334,9 @@
# 阵容定义
LineupList = (
Lineup_Main, # 主阵容
Lineup_Arena, # 竞技场进攻阵容
Lineup_ArenaDef, # 竞技场防守阵容
Lineup_Main, # 主阵容 1
Lineup_Arena, # 竞技场进攻阵容 2
Lineup_ArenaDef, # 竞技场防守阵容 3
) = range(1, 1 + 3)
# 宠物物品数据状态