hxp
2025-05-23 fdebf36f0d9201c6a6949a08cdfeebb718c25ce2
16 卡牌服务端(聊天、广播、通用记录、查看玩家;)
30个文件已修改
2个文件已删除
2个文件已添加
4342 ■■■■■ 已修改文件
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini 31 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script.ini 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BaseAttack.py 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/MirrorAttack.py 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py 416 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py 848 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/DBDataMgr.py 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/DBStruct.py 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/StructData/DBFamily.py 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/StructData/DBGameRec.py 383 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/StructData/DBPlayerViewCache.py 176 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/CreateFamily.py 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/PlayerMirror.py 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/FBHelpBattle.py 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/ItemCommon.py 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NetPackCommon.py 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFamily.py 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerGeTui.py 310 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTJG.py 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTalk.py 716 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerViewCache.py 298 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerViewCacheTube.py 493 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_PlayerMirror.py 43 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/Collections/CollectionDefine.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/Collections/DataServerPlayerData.py 218 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/LogicProcess/UserCtrlDB.py 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
@@ -960,7 +960,7 @@
;玩家查看数据缓存
[PlayerViewCache]
ScriptName = Player\PlayerViewCacheTube.py
ScriptName = Player\PlayerViewCache.py
Writer = xmnathan
Releaser = xmnathan
RegType = 0
@@ -1121,20 +1121,11 @@
Writer = hxp
Releaser = hxp
RegType = 0
RegisterPackCount = 3
RegisterPackCount = 1
PacketCMD_1=0xA2
PacketSubCMD_1=0x16
PacketCallFunc_1=OnPyTalk
PacketCMD_2=0xA2
PacketSubCMD_2=0x17
PacketCallFunc_2=OnUsePYSpeaker
PacketCMD_3=0xA2
PacketSubCMD_3=0x26
PacketCallFunc_3=OnVoiceChat
PacketCMD_1=0xB3
PacketSubCMD_1=0x20
PacketCallFunc_1=OnTalk
;属性果实
[PlayerAttrFruit]
@@ -1588,18 +1579,6 @@
PacketCMD_5=0xA5
PacketSubCMD_5=0xC4
PacketCallFunc_5=OnDogzEquipPlus
;个推
[PlayerGeTui]
ScriptName = Player\PlayerGeTui.py
Writer = Alee
Releaser = Alee
RegType = 0
RegisterPackCount = 1
PacketCMD_1=0xB2
PacketSubCMD_1=0x5
PacketCallFunc_1=GeTuiSetting
;充值
[PlayerCoin]
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script.ini
@@ -524,46 +524,6 @@
PacketSubCMD_1=0x3
PacketCallFunc_1=PetStateChange
;聊天
[Talk]
ScriptName = Player\PlayerTalk.py
Writer = Mark
Releaser = Mark
RegType = 0
RegisterPackCount = 7
PacketCMD_1=0x2
PacketSubCMD_1=0x7
PacketCallFunc_1=TalkArea
PacketCMD_2=0x2
PacketSubCMD_2=0x3
PacketCallFunc_2=TalkFamily
PacketCMD_3=0x2
PacketSubCMD_3=0x5
PacketCallFunc_3=TalkTeam
PacketCMD_4=0x2
PacketSubCMD_4=0x1
PacketCallFunc_4=TalkWorld
PacketCMD_5=0x2
PacketSubCMD_5=0x6
PacketCallFunc_5=TalkPrivateName
PacketCMD_6=0x2
PacketSubCMD_6=0x9
PacketCallFunc_6=TalkPrivate
PacketCMD_7=0x2
PacketSubCMD_7=0x8
PacketCallFunc_7=TalkCountry
;战斗
[Battle]
ScriptName = Player\PlayerBattle.py
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/BaseAttack.py
@@ -40,7 +40,6 @@
import ChNetSendPack
import NetPackCommon
import PassiveBuffEffMng
import PlayerGeTui
import IpyGameDataPY
#---------------------------------------------------------------------
g_skillHurtList = IPY_GameWorld.IPY_HurtList()
@@ -363,7 +362,6 @@
    if GameObj.GetHP(defender) <= 0:
        defender.SetDict(ChConfig.Def_NPCDead_KillerType, attacker.GetGameObjType())
        defender.SetDict(ChConfig.Def_NPCDead_KillerID, attacker.GetID())
        #PlayerGeTui.TJGDead(defender, attacker.GetName())
        if defender.GetGameObjType() == IPY_GameWorld.gotNPC:
            skillID = 0 if not useSkill else useSkill.GetSkillID()
            # 记录死亡原因
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Attack/MirrorAttack.py
@@ -27,7 +27,6 @@
import IPY_GameWorld
import PlayerControl
import OperControlManager
import PlayerViewCacheTube
import PassiveBuffEffMng
import GameWorldProcess
import ChNetSendPack
@@ -38,7 +37,6 @@
import SkillShell
import CommFunc
import FBCommon
import PlayerFB
import GameMap
import FBLogic
import GameObj
@@ -449,7 +447,7 @@
#};
def OnSycnPlayerPackData(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    PlayerViewCacheTube.UpdateGameServerPlayerCache(curPlayer, tick, forcePackData=True)
    #PlayerViewCacheTube.UpdateGameServerPlayerCache(curPlayer, tick, forcePackData=True)
    return
#// B4 11 镜像战斗 #tagCMMirrorFight
@@ -562,8 +560,8 @@
        return True
    
    # 玩家自身需要用镜像的情况
    if isSysbg and playerID and playerID in mirrorIDList:
        PlayerViewCacheTube.NormalSyncPackData(curPlayer)
    #if isSysbg and playerID and playerID in mirrorIDList:
    #    PlayerViewCacheTube.NormalSyncPackData(curPlayer)
        
    sendMsg = str(sendMsg)
    GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, "ReuestPlayerPackData", sendMsg, len(sendMsg))
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -2170,34 +2170,9 @@
Def_NPCErrorMaxDist = 99999
#玩家聊天-------------------------------------------
#聊天通用间隔时间
Def_PlayerTalkTick = 1000
#玩家聊天频道最大个数
Def_PlayerTalkChannelMaxCount = 10
#玩家聊天,单句最大字节数
Def_PlayerTalkMaxCount = 8000           #原来为100
#轻频频道
#轻频频道相同内容允许时间(10秒2次)
Def_PlayerTalkQingTime = 5000
#区域频道
#区域聊天频道时间间隔(1秒)
Def_PlayerTalkAreaTime = 1000           #原来为180000 目前测试
#区域聊天频道等级限制
Def_PlayerTalkAreaLV = 1
#国家频道
#国家聊天频道时间间隔(10秒)
Def_PlayerTalkCountryTime = 10000        #文档中为18000
#国家聊天频道等级限制
Def_PlayerTalkCountryLV = 41
#国家频道聊天花费
Def_PlayerTalkCoutryMoney = 10
#世界频道
#世界频道聊天花费(银子或银票)
Def_PlayerTalkWorldMoney = 1000
#世界聊天时间间隔(1秒)
Def_PlayerTalkWorldTime = 1000
#不可以轻频聊天的地图
CanNotQingTalkMapIDList = []
Def_PlayerTalkTick = 1000 #聊天通用间隔时间
Def_PlayerTalkMaxCount = 8000   #玩家聊天,单句最大字节数
Def_ChannelTalkTick = "ChannelTalkTick_%s" # 聊天频道玩家最近一次聊天tick
###################################################
#类型定义, 以下内容不要修改
@@ -2713,19 +2688,6 @@
) = range(0, Def_QueryType_Count)
#------------------------------------------------------------------------------ 
#家族某行为类型保存的条数
ActionTypeSaveCnt = {
              ShareDefine.Def_ActionType_FamilyPray:10 ,    #家族祈福
              ShareDefine.Def_ActionType_FamilyArrest:7,     #家族悬赏
              ShareDefine.Def_ActionType_FamilyMember:1,       #记录家族成员信息
              ShareDefine.Def_ActionType_LeaderImpeachTime:1,  # 族长下线了多久
              ShareDefine.Def_ActionType_FamilyBossFB:1,  # 记录家族boss副本信息
              ShareDefine.Def_ActionType_FamilyStore:30,       #仓库操作记录
              ShareDefine.Def_ActionType_OfficerModelEquip:10,  # 记录家族有职位的成员模型装备信息(盟主+副盟主*2+战斗队长*5)
              ShareDefine.Def_ActionType_FamilyEvent:50,  # 记录家族事件
              }
#---------------------------------------------------------------------
#数值上限 2^31 - 1
Def_UpperLimit_DWordEx = ShareDefine.Def_UpperLimit_DWordEx
#数值上限(20亿)
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
@@ -3145,101 +3145,6 @@
#------------------------------------------------------
#B3 07 语音聊天 #tagCGVoiceChat
class  tagCGVoiceChat(Structure):
    Head = tagHead()
    ChannelType = 0    #(BYTE ChannelType)// 1 世界 2 仙盟 3 私聊(好友) 4 队伍 -------查看封包tagCMVoiceChat 5 区域
    TargetNameLen = 0    #(BYTE TargetNameLen)
    TargetName = ""    #(String TargetName)//size = TargetNameLen
    TargetID = 0    #(DWORD TargetID)// 默认发玩家ID,没有ID才发名称
    Len = 0    #(WORD Len)
    Content = list()    #(vector<BYTE> Content)//size = Len
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xB3
        self.Head.SubCmd = 0x07
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.ChannelType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.TargetNameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.TargetName,_pos = CommFunc.ReadString(_lpData, _pos,self.TargetNameLen)
        self.TargetID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.Len,_pos = CommFunc.ReadWORD(_lpData, _pos)
        for i in range(self.Len):
            value,_pos=CommFunc.ReadBYTE(_lpData,_pos)
            self.Content.append(value)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xB3
        self.Head.SubCmd = 0x07
        self.ChannelType = 0
        self.TargetNameLen = 0
        self.TargetName = ""
        self.TargetID = 0
        self.Len = 0
        self.Content = list()
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 1
        length += 1
        length += len(self.TargetName)
        length += 4
        length += 2
        length += 1 * self.Len
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteBYTE(data, self.ChannelType)
        data = CommFunc.WriteBYTE(data, self.TargetNameLen)
        data = CommFunc.WriteString(data, self.TargetNameLen, self.TargetName)
        data = CommFunc.WriteDWORD(data, self.TargetID)
        data = CommFunc.WriteWORD(data, self.Len)
        for i in range(self.Len):
            data = CommFunc.WriteBYTE(data, self.Content[i])
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                ChannelType:%d,
                                TargetNameLen:%d,
                                TargetName:%s,
                                TargetID:%d,
                                Len:%d,
                                Content:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.ChannelType,
                                self.TargetNameLen,
                                self.TargetName,
                                self.TargetID,
                                self.Len,
                                "..."
                                )
        return DumpString
m_NAtagCGVoiceChat=tagCGVoiceChat()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCGVoiceChat.Head.Cmd,m_NAtagCGVoiceChat.Head.SubCmd))] = m_NAtagCGVoiceChat
#------------------------------------------------------
#B3 03 是否允许加入好友的回应#tagCGJoinFriendAnswer
class  tagCGJoinFriendAnswer(Structure):
@@ -6241,7 +6146,7 @@
                  ("GroupValue2", c_int),    #分组值2,与分组值1组合归为同组榜单数据
                  ("StartIndex", c_ushort),    #查看的起始名次索引, 默认0
                  ("ViewCnt", c_ubyte),    #查看条数,默认20,单次最大不超过100
                  ("ViewID", c_int),    #附带查看指定ID所在名次前后数据,如玩家ID、家族ID等,仅首页查询时有效,即StartIndex为0时
                  ("ViewID", c_int),    #附带查看指定ID所在名次前后数据,如玩家ID、家族ID等
                  ]
    def __init__(self):
@@ -7124,162 +7029,6 @@
#------------------------------------------------------
# A2 17 喇叭聊天 #tagCMPYSpeaker
class  tagCMPYSpeaker(Structure):
    Head = tagHead()
    SpeakerType = 0    #(BYTE SpeakerType)//1-本服;2-跨服
    IsUseGold = 0    #(BYTE IsUseGold)//是否使用钻石
    ItemIndex = 0    #(BYTE ItemIndex)//使用物品说话时, 物品Index
    TextLen = 0    #(WORD TextLen)//字符长度
    Text = ""    #(String Text)//size = TextLen
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xA2
        self.Head.SubCmd = 0x17
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.SpeakerType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.IsUseGold,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.ItemIndex,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.TextLen,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.Text,_pos = CommFunc.ReadString(_lpData, _pos,self.TextLen)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xA2
        self.Head.SubCmd = 0x17
        self.SpeakerType = 0
        self.IsUseGold = 0
        self.ItemIndex = 0
        self.TextLen = 0
        self.Text = ""
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 1
        length += 1
        length += 1
        length += 2
        length += len(self.Text)
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteBYTE(data, self.SpeakerType)
        data = CommFunc.WriteBYTE(data, self.IsUseGold)
        data = CommFunc.WriteBYTE(data, self.ItemIndex)
        data = CommFunc.WriteWORD(data, self.TextLen)
        data = CommFunc.WriteString(data, self.TextLen, self.Text)
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                SpeakerType:%d,
                                IsUseGold:%d,
                                ItemIndex:%d,
                                TextLen:%d,
                                Text:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.SpeakerType,
                                self.IsUseGold,
                                self.ItemIndex,
                                self.TextLen,
                                self.Text
                                )
        return DumpString
m_NAtagCMPYSpeaker=tagCMPYSpeaker()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMPYSpeaker.Head.Cmd,m_NAtagCMPYSpeaker.Head.SubCmd))] = m_NAtagCMPYSpeaker
#------------------------------------------------------
# A2 16 自定义玩家聊天 #tagCMPyTalk
class  tagCMPyTalk(Structure):
    Head = tagHead()
    TalkType = 0    #(BYTE TalkType)// 自定义聊天类型
    Len = 0    #(WORD Len)
    Content = ""    #(String Content)//size = Len
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xA2
        self.Head.SubCmd = 0x16
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.TalkType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.Len,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.Content,_pos = CommFunc.ReadString(_lpData, _pos,self.Len)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xA2
        self.Head.SubCmd = 0x16
        self.TalkType = 0
        self.Len = 0
        self.Content = ""
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 1
        length += 2
        length += len(self.Content)
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteBYTE(data, self.TalkType)
        data = CommFunc.WriteWORD(data, self.Len)
        data = CommFunc.WriteString(data, self.Len, self.Content)
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                TalkType:%d,
                                Len:%d,
                                Content:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.TalkType,
                                self.Len,
                                self.Content
                                )
        return DumpString
m_NAtagCMPyTalk=tagCMPyTalk()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMPyTalk.Head.Cmd,m_NAtagCMPyTalk.Head.SubCmd))] = m_NAtagCMPyTalk
#------------------------------------------------------
#A2 11 查询世界Boss伤血列表 #tagCMQueryBossHurtList
class  tagCMQueryBossHurtList(Structure):
@@ -8123,101 +7872,6 @@
m_NAtagCMClientTaskCount=tagCMClientTaskCount()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMClientTaskCount.Cmd,m_NAtagCMClientTaskCount.SubCmd))] = m_NAtagCMClientTaskCount
#------------------------------------------------------
#A2 26 语音聊天 #tagCMVoiceChat
class  tagCMVoiceChat(Structure):
    Head = tagHead()
    ChannelType = 0    #(BYTE ChannelType)//  5 区域 --- 查看封包tagCGVoiceChat 1 世界 2 仙盟 3 私聊(好友) 4 队伍
    TargetNameLen = 0    #(BYTE TargetNameLen)
    TargetName = ""    #(String TargetName)//size = TargetNameLen
    TargetID = 0    #(DWORD TargetID)// 私聊默认发玩家ID,没有ID才发名称
    Len = 0    #(WORD Len)
    Content = list()    #(vector<BYTE> Content)//size = Len
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xA2
        self.Head.SubCmd = 0x26
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.ChannelType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.TargetNameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.TargetName,_pos = CommFunc.ReadString(_lpData, _pos,self.TargetNameLen)
        self.TargetID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.Len,_pos = CommFunc.ReadWORD(_lpData, _pos)
        for i in range(self.Len):
            value,_pos=CommFunc.ReadBYTE(_lpData,_pos)
            self.Content.append(value)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xA2
        self.Head.SubCmd = 0x26
        self.ChannelType = 0
        self.TargetNameLen = 0
        self.TargetName = ""
        self.TargetID = 0
        self.Len = 0
        self.Content = list()
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 1
        length += 1
        length += len(self.TargetName)
        length += 4
        length += 2
        length += 1 * self.Len
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteBYTE(data, self.ChannelType)
        data = CommFunc.WriteBYTE(data, self.TargetNameLen)
        data = CommFunc.WriteString(data, self.TargetNameLen, self.TargetName)
        data = CommFunc.WriteDWORD(data, self.TargetID)
        data = CommFunc.WriteWORD(data, self.Len)
        for i in range(self.Len):
            data = CommFunc.WriteBYTE(data, self.Content[i])
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                ChannelType:%d,
                                TargetNameLen:%d,
                                TargetName:%s,
                                TargetID:%d,
                                Len:%d,
                                Content:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.ChannelType,
                                self.TargetNameLen,
                                self.TargetName,
                                self.TargetID,
                                self.Len,
                                "..."
                                )
        return DumpString
m_NAtagCMVoiceChat=tagCMVoiceChat()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMVoiceChat.Head.Cmd,m_NAtagCMVoiceChat.Head.SubCmd))] = m_NAtagCMVoiceChat
#------------------------------------------------------
@@ -21924,6 +21578,74 @@
#------------------------------------------------------
# B3 20 聊天 #tagCMTalk
class  tagCMPyTalk(Structure):
    Head = tagHead()
    ChannelType = 0    #(BYTE ChannelType)// 频道
    Len = 0    #(WORD Len)
    Content = ""    #(String Content)//size = Len
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xB3
        self.Head.SubCmd = 0x20
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.ChannelType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.Len,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.Content,_pos = CommFunc.ReadString(_lpData, _pos,self.Len)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xB3
        self.Head.SubCmd = 0x20
        self.ChannelType = 0
        self.Len = 0
        self.Content = ""
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 1
        length += 2
        length += len(self.Content)
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteBYTE(data, self.ChannelType)
        data = CommFunc.WriteWORD(data, self.Len)
        data = CommFunc.WriteString(data, self.Len, self.Content)
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                ChannelType:%d,
                                Len:%d,
                                Content:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.ChannelType,
                                self.Len,
                                self.Content
                                )
        return DumpString
#------------------------------------------------------
# B4 11 镜像战斗 #tagCMMirrorFight
class  tagCMMirrorFight(Structure):
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
@@ -11547,292 +11547,6 @@
#------------------------------------------------------
#B3 10 语音聊天 #tagGCVoiceChat
class  tagGCVoiceChat(Structure):
    Head = tagHead()
    ChannelType = 0    #(BYTE ChannelType)// 1 世界 2 仙盟 3 私聊(好友) 4 队伍 5 区域
    SrcNameLen = 0    #(BYTE SrcNameLen)
    SrcName = ""    #(String SrcName)//size = SrcNameLen
    PlayerID = 0    #(DWORD PlayerID)
    ToNameLen = 0    #(BYTE ToNameLen)
    ToName = ""    #(String ToName)//size = ToNameLen
    ToPlayerID = 0    #(DWORD ToPlayerID)
    Len = 0    #(WORD Len)
    Content = list()    #(vector<BYTE> Content)//size = Len
    ExtraValue = 0    #(DWORD ExtraValue)//附加值
    Extras = ""    #(char Extras[256])//附加值列表
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xB3
        self.Head.SubCmd = 0x10
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.ChannelType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.SrcNameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.SrcName,_pos = CommFunc.ReadString(_lpData, _pos,self.SrcNameLen)
        self.PlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.ToNameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.ToName,_pos = CommFunc.ReadString(_lpData, _pos,self.ToNameLen)
        self.ToPlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.Len,_pos = CommFunc.ReadWORD(_lpData, _pos)
        for i in range(self.Len):
            value,_pos=CommFunc.ReadBYTE(_lpData,_pos)
            self.Content.append(value)
        self.ExtraValue,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.Extras,_pos = CommFunc.ReadString(_lpData, _pos,256)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xB3
        self.Head.SubCmd = 0x10
        self.ChannelType = 0
        self.SrcNameLen = 0
        self.SrcName = ""
        self.PlayerID = 0
        self.ToNameLen = 0
        self.ToName = ""
        self.ToPlayerID = 0
        self.Len = 0
        self.Content = list()
        self.ExtraValue = 0
        self.Extras = ""
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 1
        length += 1
        length += len(self.SrcName)
        length += 4
        length += 1
        length += len(self.ToName)
        length += 4
        length += 2
        length += 1 * self.Len
        length += 4
        length += 256
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteBYTE(data, self.ChannelType)
        data = CommFunc.WriteBYTE(data, self.SrcNameLen)
        data = CommFunc.WriteString(data, self.SrcNameLen, self.SrcName)
        data = CommFunc.WriteDWORD(data, self.PlayerID)
        data = CommFunc.WriteBYTE(data, self.ToNameLen)
        data = CommFunc.WriteString(data, self.ToNameLen, self.ToName)
        data = CommFunc.WriteDWORD(data, self.ToPlayerID)
        data = CommFunc.WriteWORD(data, self.Len)
        for i in range(self.Len):
            data = CommFunc.WriteBYTE(data, self.Content[i])
        data = CommFunc.WriteDWORD(data, self.ExtraValue)
        data = CommFunc.WriteString(data, 256, self.Extras)
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                ChannelType:%d,
                                SrcNameLen:%d,
                                SrcName:%s,
                                PlayerID:%d,
                                ToNameLen:%d,
                                ToName:%s,
                                ToPlayerID:%d,
                                Len:%d,
                                Content:%s,
                                ExtraValue:%d,
                                Extras:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.ChannelType,
                                self.SrcNameLen,
                                self.SrcName,
                                self.PlayerID,
                                self.ToNameLen,
                                self.ToName,
                                self.ToPlayerID,
                                self.Len,
                                "...",
                                self.ExtraValue,
                                self.Extras
                                )
        return DumpString
m_NAtagGCVoiceChat=tagGCVoiceChat()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCVoiceChat.Head.Cmd,m_NAtagGCVoiceChat.Head.SubCmd))] = m_NAtagGCVoiceChat
#------------------------------------------------------
# B3 11 聊天缓存通知 #tagGCTalkCache
class  tagGCTalkCacheInfo(Structure):
    ChannelType = 0    #(BYTE ChannelType)// 1 世界 2 仙盟
    NameLen = 0    #(BYTE NameLen)
    Name = ""    #(String Name)//size = SrcNameLen
    PlayerID = 0    #(DWORD PlayerID)
    Time = 0    #(DWORD Time)
    Len = 0    #(WORD Len)
    Content = ""    #(String Content)//size = Len
    Extras = ""    #(char Extras[256])//附加值列表
    data = None
    def __init__(self):
        self.Clear()
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        self.ChannelType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.NameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.Name,_pos = CommFunc.ReadString(_lpData, _pos,self.NameLen)
        self.PlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.Time,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.Len,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.Content,_pos = CommFunc.ReadString(_lpData, _pos,self.Len)
        self.Extras,_pos = CommFunc.ReadString(_lpData, _pos,256)
        return _pos
    def Clear(self):
        self.ChannelType = 0
        self.NameLen = 0
        self.Name = ""
        self.PlayerID = 0
        self.Time = 0
        self.Len = 0
        self.Content = ""
        self.Extras = ""
        return
    def GetLength(self):
        length = 0
        length += 1
        length += 1
        length += len(self.Name)
        length += 4
        length += 4
        length += 2
        length += len(self.Content)
        length += 256
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteBYTE(data, self.ChannelType)
        data = CommFunc.WriteBYTE(data, self.NameLen)
        data = CommFunc.WriteString(data, self.NameLen, self.Name)
        data = CommFunc.WriteDWORD(data, self.PlayerID)
        data = CommFunc.WriteDWORD(data, self.Time)
        data = CommFunc.WriteWORD(data, self.Len)
        data = CommFunc.WriteString(data, self.Len, self.Content)
        data = CommFunc.WriteString(data, 256, self.Extras)
        return data
    def OutputString(self):
        DumpString = '''
                                ChannelType:%d,
                                NameLen:%d,
                                Name:%s,
                                PlayerID:%d,
                                Time:%d,
                                Len:%d,
                                Content:%s,
                                Extras:%s
                                '''\
                                %(
                                self.ChannelType,
                                self.NameLen,
                                self.Name,
                                self.PlayerID,
                                self.Time,
                                self.Len,
                                self.Content,
                                self.Extras
                                )
        return DumpString
class  tagGCTalkCache(Structure):
    Head = tagHead()
    Count = 0    #(WORD Count)
    InfoList = list()    #(vector<tagGCTalkCacheInfo> InfoList)//size = Count
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xB3
        self.Head.SubCmd = 0x11
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.Count,_pos = CommFunc.ReadWORD(_lpData, _pos)
        for i in range(self.Count):
            temInfoList = tagGCTalkCacheInfo()
            _pos = temInfoList.ReadData(_lpData, _pos)
            self.InfoList.append(temInfoList)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xB3
        self.Head.SubCmd = 0x11
        self.Count = 0
        self.InfoList = list()
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 2
        for i in range(self.Count):
            length += self.InfoList[i].GetLength()
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteWORD(data, self.Count)
        for i in range(self.Count):
            data = CommFunc.WriteString(data, self.InfoList[i].GetLength(), self.InfoList[i].GetBuffer())
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                Count:%d,
                                InfoList:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.Count,
                                "..."
                                )
        return DumpString
m_NAtagGCTalkCache=tagGCTalkCache()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCTalkCache.Head.Cmd,m_NAtagGCTalkCache.Head.SubCmd))] = m_NAtagGCTalkCache
#------------------------------------------------------
# B5 04 拍卖行新上架拍品 #tagGCAddAuctionItemInfo
class  tagGCAddAuctionItem(Structure):
@@ -36251,112 +35965,6 @@
#------------------------------------------------------
# A7 07 通知玩家自定义聊天 #tagMCPyTalk
class  tagMCPyTalk(Structure):
    Head = tagHead()
    TalkType = 0    #(BYTE TalkType)// 自定义聊天类型
    NameLen = 0    #(BYTE NameLen)
    Name = ""    #(String Name)//size = NameLen
    PlayerID = 0    #(DWORD PlayerID)
    Len = 0    #(WORD Len)
    Content = ""    #(String Content)//size = Len
    ExtraValue = 0    #(DWORD ExtraValue)//附加值
    Extras = ""    #(char Extras[256])//附加值列表
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xA7
        self.Head.SubCmd = 0x07
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.TalkType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.NameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.Name,_pos = CommFunc.ReadString(_lpData, _pos,self.NameLen)
        self.PlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.Len,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.Content,_pos = CommFunc.ReadString(_lpData, _pos,self.Len)
        self.ExtraValue,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.Extras,_pos = CommFunc.ReadString(_lpData, _pos,256)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xA7
        self.Head.SubCmd = 0x07
        self.TalkType = 0
        self.NameLen = 0
        self.Name = ""
        self.PlayerID = 0
        self.Len = 0
        self.Content = ""
        self.ExtraValue = 0
        self.Extras = ""
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 1
        length += 1
        length += len(self.Name)
        length += 4
        length += 2
        length += len(self.Content)
        length += 4
        length += 256
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteBYTE(data, self.TalkType)
        data = CommFunc.WriteBYTE(data, self.NameLen)
        data = CommFunc.WriteString(data, self.NameLen, self.Name)
        data = CommFunc.WriteDWORD(data, self.PlayerID)
        data = CommFunc.WriteWORD(data, self.Len)
        data = CommFunc.WriteString(data, self.Len, self.Content)
        data = CommFunc.WriteDWORD(data, self.ExtraValue)
        data = CommFunc.WriteString(data, 256, self.Extras)
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                TalkType:%d,
                                NameLen:%d,
                                Name:%s,
                                PlayerID:%d,
                                Len:%d,
                                Content:%s,
                                ExtraValue:%d,
                                Extras:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.TalkType,
                                self.NameLen,
                                self.Name,
                                self.PlayerID,
                                self.Len,
                                self.Content,
                                self.ExtraValue,
                                self.Extras
                                )
        return DumpString
m_NAtagMCPyTalk=tagMCPyTalk()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCPyTalk.Head.Cmd,m_NAtagMCPyTalk.Head.SubCmd))] = m_NAtagMCPyTalk
#------------------------------------------------------
# A7 08 通知跑环奖励记录 #tagMCRunTaskAwardInfo
class  tagMCRunTaskAwardRecord(Structure):
@@ -36473,11 +36081,20 @@
class  tagSCQueryPlayerCacheResult(Structure):
    Head = tagHead()
    PlayerID = 0    #(DWORD PlayerID)//玩家ID
    PropDataSize = 0    #(DWORD PropDataSize)
    PropData = ""    #(String PropData)//属性记录
    ItemDataSize = 0    #(DWORD ItemDataSize)
    ItemData = ""    #(String ItemData)//物品记录
    PlayerID = 0    #(DWORD PlayerID)
    PlayerName = ""    #(char PlayerName[33])
    LV = 0    #(WORD LV)
    Job = 0    #(BYTE Job)
    RealmLV = 0    #(BYTE RealmLV)
    Face = 0    #(DWORD Face)
    FacePic = 0    #(DWORD FacePic)
    TitleID = 0    #(DWORD TitleID)//佩戴的称号
    ServerID = 0    #(DWORD ServerID)
    FightPower = 0    #(DWORD FightPower)
    FightPowerEx = 0    #(DWORD FightPowerEx)
    FamilyID = 0    #(DWORD FamilyID)
    FamilyName = ""    #(char FamilyName[33])
    FamilyEmblemID = 0    #(DWORD FamilyEmblemID)//仙盟徽章ID
    PlusDataSize = 0    #(DWORD PlusDataSize)
    PlusData = ""    #(String PlusData)//扩展记录    
    data = None
@@ -36492,10 +36109,19 @@
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.PlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.PropDataSize,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.PropData,_pos = CommFunc.ReadString(_lpData, _pos,self.PropDataSize)
        self.ItemDataSize,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.ItemData,_pos = CommFunc.ReadString(_lpData, _pos,self.ItemDataSize)
        self.PlayerName,_pos = CommFunc.ReadString(_lpData, _pos,33)
        self.LV,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.Job,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.RealmLV,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.Face,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.FacePic,_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)
        self.FightPowerEx,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.FamilyID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.FamilyName,_pos = CommFunc.ReadString(_lpData, _pos,33)
        self.FamilyEmblemID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.PlusDataSize,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.PlusData,_pos = CommFunc.ReadString(_lpData, _pos,self.PlusDataSize)
        return _pos
@@ -36506,10 +36132,19 @@
        self.Head.Cmd = 0xA7
        self.Head.SubCmd = 0x05
        self.PlayerID = 0
        self.PropDataSize = 0
        self.PropData = ""
        self.ItemDataSize = 0
        self.ItemData = ""
        self.PlayerName = ""
        self.LV = 0
        self.Job = 0
        self.RealmLV = 0
        self.Face = 0
        self.FacePic = 0
        self.TitleID = 0
        self.ServerID = 0
        self.FightPower = 0
        self.FightPowerEx = 0
        self.FamilyID = 0
        self.FamilyName = ""
        self.FamilyEmblemID = 0
        self.PlusDataSize = 0
        self.PlusData = ""
        return
@@ -36518,10 +36153,19 @@
        length = 0
        length += self.Head.GetLength()
        length += 4
        length += 33
        length += 2
        length += 1
        length += 1
        length += 4
        length += len(self.PropData)
        length += 4
        length += len(self.ItemData)
        length += 4
        length += 4
        length += 4
        length += 4
        length += 4
        length += 33
        length += 4
        length += 4
        length += len(self.PlusData)
@@ -36531,10 +36175,19 @@
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteDWORD(data, self.PlayerID)
        data = CommFunc.WriteDWORD(data, self.PropDataSize)
        data = CommFunc.WriteString(data, self.PropDataSize, self.PropData)
        data = CommFunc.WriteDWORD(data, self.ItemDataSize)
        data = CommFunc.WriteString(data, self.ItemDataSize, self.ItemData)
        data = CommFunc.WriteString(data, 33, self.PlayerName)
        data = CommFunc.WriteWORD(data, self.LV)
        data = CommFunc.WriteBYTE(data, self.Job)
        data = CommFunc.WriteBYTE(data, self.RealmLV)
        data = CommFunc.WriteDWORD(data, self.Face)
        data = CommFunc.WriteDWORD(data, self.FacePic)
        data = CommFunc.WriteDWORD(data, self.TitleID)
        data = CommFunc.WriteDWORD(data, self.ServerID)
        data = CommFunc.WriteDWORD(data, self.FightPower)
        data = CommFunc.WriteDWORD(data, self.FightPowerEx)
        data = CommFunc.WriteDWORD(data, self.FamilyID)
        data = CommFunc.WriteString(data, 33, self.FamilyName)
        data = CommFunc.WriteDWORD(data, self.FamilyEmblemID)
        data = CommFunc.WriteDWORD(data, self.PlusDataSize)
        data = CommFunc.WriteString(data, self.PlusDataSize, self.PlusData)
        return data
@@ -36543,20 +36196,38 @@
        DumpString = '''
                                Head:%s,
                                PlayerID:%d,
                                PropDataSize:%d,
                                PropData:%s,
                                ItemDataSize:%d,
                                ItemData:%s,
                                PlayerName:%s,
                                LV:%d,
                                Job:%d,
                                RealmLV:%d,
                                Face:%d,
                                FacePic:%d,
                                TitleID:%d,
                                ServerID:%d,
                                FightPower:%d,
                                FightPowerEx:%d,
                                FamilyID:%d,
                                FamilyName:%s,
                                FamilyEmblemID:%d,
                                PlusDataSize:%d,
                                PlusData:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.PlayerID,
                                self.PropDataSize,
                                self.PropData,
                                self.ItemDataSize,
                                self.ItemData,
                                self.PlayerName,
                                self.LV,
                                self.Job,
                                self.RealmLV,
                                self.Face,
                                self.FacePic,
                                self.TitleID,
                                self.ServerID,
                                self.FightPower,
                                self.FightPowerEx,
                                self.FamilyID,
                                self.FamilyName,
                                self.FamilyEmblemID,
                                self.PlusDataSize,
                                self.PlusData
                                )
@@ -58778,6 +58449,345 @@
#------------------------------------------------------
# B3 10 聊天信息 #tagMCTalk
class  tagMCTalk(Structure):
    Head = tagHead()
    ChannelType = 0    #(BYTE ChannelType)// 0-世界;1-跨服;3- 仙盟
    NameLen = 0    #(BYTE NameLen)
    Name = ""    #(String Name)//size = NameLen
    PlayerID = 0    #(DWORD PlayerID)
    Len = 0    #(WORD Len)
    Content = ""    #(String Content)//size = Len
    BubbleBox = 0    #(DWORD BubbleBox)//聊天气泡框
    LV = 0    #(WORD LV)//等级
    Job = 0    #(BYTE Job)//ְҵ
    RealmLV = 0    #(BYTE RealmLV)//境界
    Face = 0    #(DWORD Face)//基本脸型
    FacePic = 0    #(DWORD FacePic)//头像框
    ServerID = 0    #(DWORD ServerID)//所属区服ID
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xB3
        self.Head.SubCmd = 0x10
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.ChannelType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.NameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.Name,_pos = CommFunc.ReadString(_lpData, _pos,self.NameLen)
        self.PlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.Len,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.Content,_pos = CommFunc.ReadString(_lpData, _pos,self.Len)
        self.BubbleBox,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.LV,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.Job,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.RealmLV,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.Face,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.FacePic,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.ServerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xB3
        self.Head.SubCmd = 0x10
        self.ChannelType = 0
        self.NameLen = 0
        self.Name = ""
        self.PlayerID = 0
        self.Len = 0
        self.Content = ""
        self.BubbleBox = 0
        self.LV = 0
        self.Job = 0
        self.RealmLV = 0
        self.Face = 0
        self.FacePic = 0
        self.ServerID = 0
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 1
        length += 1
        length += len(self.Name)
        length += 4
        length += 2
        length += len(self.Content)
        length += 4
        length += 2
        length += 1
        length += 1
        length += 4
        length += 4
        length += 4
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteBYTE(data, self.ChannelType)
        data = CommFunc.WriteBYTE(data, self.NameLen)
        data = CommFunc.WriteString(data, self.NameLen, self.Name)
        data = CommFunc.WriteDWORD(data, self.PlayerID)
        data = CommFunc.WriteWORD(data, self.Len)
        data = CommFunc.WriteString(data, self.Len, self.Content)
        data = CommFunc.WriteDWORD(data, self.BubbleBox)
        data = CommFunc.WriteWORD(data, self.LV)
        data = CommFunc.WriteBYTE(data, self.Job)
        data = CommFunc.WriteBYTE(data, self.RealmLV)
        data = CommFunc.WriteDWORD(data, self.Face)
        data = CommFunc.WriteDWORD(data, self.FacePic)
        data = CommFunc.WriteDWORD(data, self.ServerID)
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                ChannelType:%d,
                                NameLen:%d,
                                Name:%s,
                                PlayerID:%d,
                                Len:%d,
                                Content:%s,
                                BubbleBox:%d,
                                LV:%d,
                                Job:%d,
                                RealmLV:%d,
                                Face:%d,
                                FacePic:%d,
                                ServerID:%d
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.ChannelType,
                                self.NameLen,
                                self.Name,
                                self.PlayerID,
                                self.Len,
                                self.Content,
                                self.BubbleBox,
                                self.LV,
                                self.Job,
                                self.RealmLV,
                                self.Face,
                                self.FacePic,
                                self.ServerID
                                )
        return DumpString
m_NAtagMCTalk=tagMCTalk()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCTalk.Head.Cmd,m_NAtagMCTalk.Head.SubCmd))] = m_NAtagMCTalk
#------------------------------------------------------
# B3 11 聊天缓存通知 #tagMCTalkCacheList
class  tagMCTalkCacheInfo(Structure):
    NameLen = 0    #(BYTE NameLen)
    Name = ""    #(String Name)//size = NameLen
    PlayerID = 0    #(DWORD PlayerID)
    Len = 0    #(WORD Len)
    Content = ""    #(String Content)//size = Len
    BubbleBox = 0    #(DWORD BubbleBox)//聊天气泡框
    LV = 0    #(WORD LV)//等级
    Job = 0    #(BYTE Job)//ְҵ
    RealmLV = 0    #(BYTE RealmLV)//境界
    Face = 0    #(DWORD Face)//基本脸型
    FacePic = 0    #(DWORD FacePic)//头像框
    ServerID = 0    #(DWORD ServerID)//所属区服ID
    TalkTime = 0    #(DWORD TalkTime)//该聊天发送时间戳
    data = None
    def __init__(self):
        self.Clear()
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        self.NameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.Name,_pos = CommFunc.ReadString(_lpData, _pos,self.NameLen)
        self.PlayerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.Len,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.Content,_pos = CommFunc.ReadString(_lpData, _pos,self.Len)
        self.BubbleBox,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.LV,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.Job,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.RealmLV,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.Face,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.FacePic,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.ServerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.TalkTime,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        return _pos
    def Clear(self):
        self.NameLen = 0
        self.Name = ""
        self.PlayerID = 0
        self.Len = 0
        self.Content = ""
        self.BubbleBox = 0
        self.LV = 0
        self.Job = 0
        self.RealmLV = 0
        self.Face = 0
        self.FacePic = 0
        self.ServerID = 0
        self.TalkTime = 0
        return
    def GetLength(self):
        length = 0
        length += 1
        length += len(self.Name)
        length += 4
        length += 2
        length += len(self.Content)
        length += 4
        length += 2
        length += 1
        length += 1
        length += 4
        length += 4
        length += 4
        length += 4
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteBYTE(data, self.NameLen)
        data = CommFunc.WriteString(data, self.NameLen, self.Name)
        data = CommFunc.WriteDWORD(data, self.PlayerID)
        data = CommFunc.WriteWORD(data, self.Len)
        data = CommFunc.WriteString(data, self.Len, self.Content)
        data = CommFunc.WriteDWORD(data, self.BubbleBox)
        data = CommFunc.WriteWORD(data, self.LV)
        data = CommFunc.WriteBYTE(data, self.Job)
        data = CommFunc.WriteBYTE(data, self.RealmLV)
        data = CommFunc.WriteDWORD(data, self.Face)
        data = CommFunc.WriteDWORD(data, self.FacePic)
        data = CommFunc.WriteDWORD(data, self.ServerID)
        data = CommFunc.WriteDWORD(data, self.TalkTime)
        return data
    def OutputString(self):
        DumpString = '''
                                NameLen:%d,
                                Name:%s,
                                PlayerID:%d,
                                Len:%d,
                                Content:%s,
                                BubbleBox:%d,
                                LV:%d,
                                Job:%d,
                                RealmLV:%d,
                                Face:%d,
                                FacePic:%d,
                                ServerID:%d,
                                TalkTime:%d
                                '''\
                                %(
                                self.NameLen,
                                self.Name,
                                self.PlayerID,
                                self.Len,
                                self.Content,
                                self.BubbleBox,
                                self.LV,
                                self.Job,
                                self.RealmLV,
                                self.Face,
                                self.FacePic,
                                self.ServerID,
                                self.TalkTime
                                )
        return DumpString
class  tagMCTalkCacheList(Structure):
    Head = tagHead()
    ChannelType = 0    #(BYTE ChannelType)// 0-世界;1-跨服;3- 仙盟
    Count = 0    #(BYTE Count)
    InfoList = list()    #(vector<tagMCTalkCacheInfo> InfoList)//size = Count
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xB3
        self.Head.SubCmd = 0x11
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.ChannelType,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.Count,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        for i in range(self.Count):
            temInfoList = tagMCTalkCacheInfo()
            _pos = temInfoList.ReadData(_lpData, _pos)
            self.InfoList.append(temInfoList)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xB3
        self.Head.SubCmd = 0x11
        self.ChannelType = 0
        self.Count = 0
        self.InfoList = list()
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 1
        length += 1
        for i in range(self.Count):
            length += self.InfoList[i].GetLength()
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteBYTE(data, self.ChannelType)
        data = CommFunc.WriteBYTE(data, self.Count)
        for i in range(self.Count):
            data = CommFunc.WriteString(data, self.InfoList[i].GetLength(), self.InfoList[i].GetBuffer())
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                ChannelType:%d,
                                Count:%d,
                                InfoList:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.ChannelType,
                                self.Count,
                                "..."
                                )
        return DumpString
m_NAtagMCTalkCacheList=tagMCTalkCacheList()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCTalkCacheList.Head.Cmd,m_NAtagMCTalkCacheList.Head.SubCmd))] = m_NAtagMCTalkCacheList
#------------------------------------------------------
# B4 11 新增恶意攻击玩家 #tagMCAddMaliciousAtkPlayer
class  tagMCAddMaliciousAtkPlayer(Structure):
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/DBDataMgr.py
@@ -24,6 +24,7 @@
import DBPlayerViewCache
import DBEventTrig
import DBBillboard
import DBGameRec
import DBFamily
import DBMail
@@ -218,6 +219,7 @@
        self.BillboardMgr = DBBillboard.BillboardMgr()
        self.MailMgr = DBMail.MailMgr()
        self.FamilyMgr = DBFamily.FamilyMgr()
        self.GameRecMgr = DBGameRec.GameRecMgr()
        return
    
    def GetSaveData(self):
@@ -227,6 +229,7 @@
        buff += self.BillboardMgr.GetSaveData()
        buff += self.MailMgr.GetSaveData()
        buff += self.FamilyMgr.GetSaveData()
        buff += self.GameRecMgr.GetSaveData()
        return buff
    
    def LoadGameData(self, gameBuffer, pos):
@@ -236,6 +239,7 @@
        pos = self.BillboardMgr.LoadPyGameData(gameBuffer, pos, dataslen)
        pos = self.MailMgr.LoadPyGameData(gameBuffer, pos, dataslen)
        pos = self.FamilyMgr.LoadPyGameData(gameBuffer, pos, dataslen)
        pos = self.GameRecMgr.LoadPyGameData(gameBuffer, pos, dataslen)
        return pos
    
def GetDBDataMgr():
@@ -275,3 +279,8 @@
    dbDataMgr = GetDBDataMgr()
    return dbDataMgr.BillboardMgr
def GetGameRecMgr():
    ## 通用记录数据管理器
    dbDataMgr = GetDBDataMgr()
    return dbDataMgr.GameRecMgr
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/DBStruct.py
@@ -1899,10 +1899,141 @@
            self.Name2 = Str[:65]
            
# 通用记录表新 #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:
            return -1
        if len(buf) < pos + self.getLength():
            return -1
        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 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
#服务器世界数据表版本号
GAMEWORLD_DATA_VERSION_NO = ctypes.c_ulong (\
    sizeof(tagDBEventTrig) + sizeof(tagDBFamily) + sizeof(tagDBFamilyMem) + sizeof(tagDBFamilyAction) + 
    sizeof(tagDBPlayerViewCache) + sizeof(tagDBMailPersonal) + sizeof(tagDBMailServer) + sizeof(tagDBMailItem) + 
    sizeof(tagDBMailPlayerRec) + sizeof(tagDBBillboard)
    sizeof(tagDBMailPlayerRec) + sizeof(tagDBBillboard) + sizeof(tagDBGameRec)
    ).value
    
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/StructData/DBFamily.py
@@ -20,6 +20,7 @@
import GameWorld
import ShareDefine
import PlayerControl
import PlayerViewCache
import PyMongoMain
import DBDataMgr
import ChConfig
@@ -82,12 +83,15 @@
        self.__actionDataList.append(actionData)
        return actionData
    
    def AddAction(self, fullClear=True):
    def AddAction(self, maxCount=None):
        ## 添加仙盟Action数据
        # @param fullClear: 数据条数超过最大数时是否清除最早一条,并创建一条新记录
        # @param maxCount: 可传入由配置决定的最大条数,如果为None则进一步取程序默认设定的最大条数,都没配置的话默认不限条数
        
        fullClear = True
        if maxCount == None:
            maxCount = ShareDefine.ActionTypeSaveCnt.get(self.actionType, 0)
        actionData = None
        if self.Count() >= ChConfig.ActionTypeSaveCnt.get(self.actionType, 0):
        if maxCount and self.Count() >= maxCount:
            if not fullClear:
                #超过记录记录不了了
                return actionData
@@ -207,7 +211,7 @@
        ## 根据玩家ID更新成员数据,一般用于离线功能,如添加离线成员,直接使用查看缓存更新
        if playerID != self.GetPlayerID():
            return
        viewCache = DBDataMgr.GetPlayerViewCacheMgr().FindViewCache(playerID)
        viewCache = PlayerViewCache.FindViewCache(playerID)
        if not viewCache:
            return
        self.SetPlayerName(viewCache.GetPlayerName())
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/StructData/DBGameRec.py
New file
@@ -0,0 +1,383 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package DB.StructData.DBGameRec
#
# @todo:通用记录表新
# @author hxp
# @date 2025-05-23
# @version 1.0
#
# 详细描述: 通用记录表新,原通用记录字符长度记录有限,且针对某个记录类型下的子类型查找每次需要遍历,效率不高
#
#-------------------------------------------------------------------------------
#"""Version = 2025-05-23 20:00"""
#-------------------------------------------------------------------------------
import DBStruct
import GameWorld
import ShareDefine
import CommFunc
import DBComm
import time
class GameRecData():
    def __init__(self, dbData=None, dataToJson=False):
        if not dbData:
            dbData = DBStruct.tagDBGameRec()
        self.__dbData = dbData
        self.__dataDict = DBComm.UserDataDict(self.__dbData, "UserData", "UserDataLen", dataToJson)
        return
    def GetRecType(self): return self.__dbData.RecType
    def SetRecType(self, recType): self.__dbData.RecType = recType
    def GetRecID(self): return self.__dbData.RecID
    def SetRecID(self, recID): self.__dbData.RecID = recID
    def GetTime(self): return self.__dbData.Time
    def SetTime(self, sTime): self.__dbData.Time = sTime
    def GetValue1(self): return self.__dbData.Value1
    def SetValue1(self, value1): self.__dbData.Value1 = value1
    def GetValue2(self): return self.__dbData.Value2
    def SetValue2(self, value2): self.__dbData.Value2 = value2
    def GetValue3(self): return self.__dbData.Value3
    def SetValue3(self, value3): self.__dbData.Value3 = value3
    def GetValue4(self): return self.__dbData.Value4
    def SetValue4(self, value4): self.__dbData.Value4 = value4
    def GetValue5(self): return self.__dbData.Value5
    def SetValue5(self, value5): self.__dbData.Value5 = value5
    def GetValue6(self): return self.__dbData.Value6
    def SetValue6(self, value6): self.__dbData.Value6 = value6
    def GetValue7(self): return self.__dbData.Value7
    def SetValue7(self, value7): self.__dbData.Value7 = value7
    def GetValue8(self): return self.__dbData.Value8
    def SetValue8(self, value8): self.__dbData.Value8 = value8
    def GetUserDict(self): return self.__dataDict.GetData()
    def GetUserData(self): return self.__dataDict.ToString()
    def SetUserData(self, value): self.__dataDict.SetData(value)
    def GetBuffer(self):
        self.__dataDict.ToString()
        return self.__dbData.getBuffer()
    def IsMatchValue(self, valueList):
        # 检查记录值列表是否配置该记录
        # @param valueList: [value1, value2, ...] value为None时不判断该值
        if not valueList:
            return False
        for i, value in enumerate(valueList, 1):
            if value == None:
                continue
            if not hasattr(self, "GetValue%s" % i):
                return False
            curValue = getattr(self, "GetValue%s" % i)()
            if curValue != value:
                return False
        return True
    def GetValueIndexKey(self):
        ## 获取Value快速查找索引key,默认使用value1
        recType = self.GetRecType()
        if recType not in ShareDefine.Def_GameRecValueKeyDict:
            return ""
        valueNumList = ShareDefine.Def_GameRecValueKeyDict[recType]
        if not valueNumList:
            valueNumList = [1]
        keyStr = ""
        for num in valueNumList:
            if not hasattr(self, "GetValue%s" % num):
                return ""
            if keyStr:
                keyStr += "_"
            keyStr += str(getattr(self, "GetValue%s" % num)())
        return keyStr
class GameRecIDMgr():
    ## 类型数据ID管理
    def __init__(self, recType, recID):
        self.__recType = recType
        self.__recID = recID
        self.__dataList = [] # 数据列表 [GameRecData, ...]
        self.__valueIndexDict = {} # value索引值对应数据列表 {indexKey:[GameRecData, ...], ...}
        return
    def InitRecDataInstance(self, dbData):
        '''初始化功能数据实例,创建或加载数据时通用,功能一般不调用
        @param dbData: 实例对应绑定的dbData
        @return: 成功返回实例对象,失败返回None
        '''
        dataToJson = False
        # 如果需要 dataToJson,可根据 RecType 在这里处理
        if dbData.RecType in []:
            dataToJson = True
        recData = GameRecData(dbData, dataToJson)
        self.__dataList.append(recData)
        keyStr = recData.GetValueIndexKey()
        if keyStr:
            if keyStr not in self.__valueIndexDict:
                self.__valueIndexDict[keyStr] = []
            recIndexDataList = self.__valueIndexDict[keyStr]
            recIndexDataList.append(recData)
        return recData
    def GetRecType(self): return self.__recType
    def GetRecID(self): return self.__recID
    def SortByTime(self):
        self.__dataList.sort(key=lambda r: (r.GetTime()), reverse=False)
        return
    def AddRecData(self, maxCount=None):
        '''添加记录
        @param maxCount: 可传入由配置决定的最大条数,如果为None则进一步取程序默认设定的最大条数,都没配置的话默认不限条数
        '''
        fullClear = True
        recData = None
        if maxCount == None:
            maxCount = 0
        if maxCount and self.GetCount() >= maxCount:
            if not fullClear:
                #超过记录记录不了了
                return recData
            #self.SortByTime()  # 按时间升序
            self.DelCount(self.GetCount() - maxCount + 1)
        dbData = DBStruct.tagDBGameRec()
        dbData.RecType = self.__recType
        dbData.RecID = self.__recID
        dbData.Time = int(time.time())
        #if valueSetList:
        #    for num, v in enumerate(valueSetList, 1):
        #        if not hasattr(dbData, "Value%s" % num):
        #            continue
        #        setattr(dbData, "Value%s" % num, v
        recData = self.InitRecDataInstance(dbData)
        return recData
    def GetCount(self): return len(self.__dataList)
    def At(self, index):
        recData = None
        if 0 <= index < len(self.__dataList):
            recData = self.__dataList[index]
        elif False:
            recData = GameRecData()
        return recData
    def GetOneRecData(self, isAddNew=False):
        ## 获取第一条记录,适用于仅需一条的记录类型
        # @param isAddNew: 没有记录时是否添加一条新记录,一般获取后需要更新数据的可以设置为True,仅判断用的建议设置为False,减少产生多余空数据
        recData = None
        if self.__dataList:
            recData = self.__dataList[0]
        elif isAddNew:
            recData = self.AddRecData()
        return recData
    def GetRecDataByValues(self, valueList, findone=False):
        '''获取匹配value值的记录
        @param valueList: [value1, value2, ...] value为None时不判断该值
        @param findone: 是否只匹配一条满足的记录
        @return: recData or [recData, ...] or None
        '''
        # 有配置value索引key的,直接快速获取
        if self.__recType in ShareDefine.Def_GameRecValueKeyDict:
            keyStr = ""
            for v in valueList:
                if keyStr:
                    keyStr += "_"
                keyStr += str(v)
            if keyStr not in self.__valueIndexDict:
                return
            recIndexDataList = self.__valueIndexDict[keyStr]
            if not recIndexDataList:
                return
            return recIndexDataList[0] if findone else recIndexDataList
        # 没有的则遍历匹配
        matchRecDataList = []
        for recData in self.__dataList:
            if not recData.IsMatchValue(valueList):
                continue
            if findone:
                return recData
            matchRecDataList.append(recData)
        return matchRecDataList
    def DelAllData(self):
        ## 删除该记录ID的所有数据
        dataCount = self.GetCount()
        if not dataCount:
            return 0
        #GameWorld.DebugLog("删除通用记录某个类型ID所有记录: recType=%s,recID=%s,dataCount=%s" % (self.__recType, self.__recID, dataCount))
        self.__dataList = []
        self.__valueIndexDict = {}
        return dataCount
    def DelDataByValue(self, valueList):
        ## 删除该记录ID所有匹配Value值列表的数据记录
        # @param valueList: [value1, value2, ...] value为None时不判断该值
        if not valueList:
            return 0
        delCount = 0
        for recData in self.__dataList[::-1]: # 倒序处理删除
            if recData.IsMatchValue(valueList):
                self.DelRecData(recData)
                delCount += 1
        #if delCount:
        #    GameWorld.DebugLog("删除通用记录某个类型ID所有匹配Value值的记录: recType=%s,recID=%s,valueList=%s,delCount=%s"
        #                       % (self.__recType, self.__recID, valueList, delCount))
        return delCount
    def DelRecData(self, recData):
        ## 删除指定记录
        if not recData:
            return 0
        if recData in self.__dataList:
            self.__dataList.remove(recData)
        keyStr = recData.GetValueIndexKey()
        if keyStr in self.__valueIndexDict:
            recIndexDataList = self.__valueIndexDict[keyStr]
            if recData in recIndexDataList:
                recIndexDataList.remove(recData)
        return 1
    def DelCount(self, delCount, reverse=False):
        ## 删除条数
        # @param reverse: False-从索引0开始删除,True-从最后一个索引往前删
        delDataList = self.__dataList[:delCount] if not reverse else self.__dataList[-delCount-1:]
        for recData in delDataList:
            self.DelRecData(recData)
        #GameWorld.DebugLog("删除通用记录条数: recType=%s,recID=%s,delCount=%s,remainCount=%s"
        #                   % (self.__recType, self.__recID, delCount, len(self.__dataList)))
        return
class GameRecTypeMgr():
    ## 类型管理
    def __init__(self, recType):
        self.__recType = recType
        self.__recIDDict = {} # recID对应数据列表 {recID:GameRecIDMgr, ...}
        return
    def GetRecType(self): return self.__recType
    def GetRecIDMgr(self, recID):
        recIDMgr = None
        if recID in self.__recIDDict:
            recIDMgr = self.__recIDDict[recID]
        else:
            recIDMgr = GameRecIDMgr(self.__recType, recID)
            self.__recIDDict[recID] = recIDMgr
        return recIDMgr
    def GetRecIDList(self): return self.__recIDDict.keys()
    def GetRecDataByValues(self, valueList, findone=False):
        ## 获取该类型所有记录匹配value值的记录
        matchRecDataList = []
        for recID in self.__recIDDict.keys():
            recIDMgr = self.GetRecIDMgr(recID)
            ret = recIDMgr.GetRecDataByValues(valueList, findone)
            if not ret:
                continue
            if findone:
                return ret
            if isinstance(ret, list):
                matchRecDataList += ret
        return matchRecDataList
    def DelAllData(self):
        ## 删除该类型所有记录
        delCount = 0
        for recID in self.__recIDDict.keys():
            delCount += self.DelDataByRecID(recID)
        return delCount
    def DelDataByRecID(self, recID):
        ## 删除该类型某个记录ID的所有记录
        return self.GetRecIDMgr(recID).DelAllData()
    def DelDataByValue(self, valueList):
        ## 删除该类型所有匹配Value值列表的记录
        delCount = 0
        for recID in self.__recIDDict.keys():
            recIDMgr = self.GetRecIDMgr(recID)
            delCount += recIDMgr.DelDataByValue(valueList)
        return delCount
class GameRecMgr():
    ## 通用记录管理
    def __init__(self):
        self.__recTypeDict = {} # {recType:GameRecTypeMgr, ...}
        return
    def GetRecTypeMgr(self, recType):
        recTypeMgr = None
        if recType in self.__recTypeDict:
            recTypeMgr = self.__recTypeDict[recType]
        else:
            recTypeMgr = GameRecTypeMgr(recType)
            self.__recTypeDict[recType] = recTypeMgr
        return recTypeMgr
    def GetRecTypeIDMgr(self, recType, recID):
        recTypeMgr = self.GetRecTypeMgr(recType)
        recTypeIDMgr = recTypeMgr.GetRecIDMgr(recID)
        if not recTypeIDMgr and False:
            recTypeIDMgr = GameRecIDMgr(recType, recID)
        return recTypeIDMgr
    # 保存数据 存数据库和realtimebackup
    def GetSaveData(self):
        savaData = ""
        cntData = ""
        cnt = 0
        for recType in self.__recTypeDict.keys():
            recTypeMgr = self.GetRecTypeMgr(recType)
            for recID in recTypeMgr.GetRecIDList():
                recTypeIDMgr = recTypeMgr.GetRecIDMgr(recID)
                for index in range(recTypeIDMgr.GetCount()):
                    recData = recTypeIDMgr.At(index)
                    savaData += recData.GetBuffer()
                    cnt += 1
        GameWorld.Log("Save DBGameRec count :%s len=%s" % (cnt, len(savaData)))
        return CommFunc.WriteDWORD(cntData, cnt) + savaData
    # 从数据库载入数据
    def LoadPyGameData(self, datas, pos, dataslen):
        cnt, pos = CommFunc.ReadDWORD(datas, pos)
        GameWorld.Log("Load DBGameRec count :%s" % cnt)
        for _ in xrange(cnt):
            dbData = DBStruct.tagDBGameRec()
            dbData.readData(datas, pos, dataslen)
            recType = dbData.RecType
            recID = dbData.RecID
            recTypeIDMgr = self.GetRecTypeIDMgr(recType, recID)
            recTypeIDMgr.InitRecDataInstance(dbData)
        for recType in self.__recTypeDict.keys():
            recTypeMgr = self.GetRecTypeMgr(recType)
            for recID in recTypeMgr.GetRecIDList():
                recTypeIDMgr = recTypeMgr.GetRecIDMgr(recID)
                recTypeIDMgr.SortByTime()
        return pos
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/StructData/DBPlayerViewCache.py
@@ -18,17 +18,8 @@
import DBComm
import DBStruct
import GameWorld
import ShareDefine
import PlayerControl
import DBDataMgr
import CommFunc
import ChConfig
import GameObj
import random
import time
Key_UpdViewCacheTick = "UpdViewCacheTick"
class PlayerViewCache():
    
@@ -84,97 +75,36 @@
    
    def __init__(self):
        self.__viewCacheList = [] # [PlayerViewCache, ...]
        self.__idIndexDict = {} # {playerID:index, ...}
        self.__viewCacheDict = {} # {playerID:PlayerViewCache, ...}
        self.__needSort = False
        self.__serverIDRangePlayerIDDict = {} # {serverIDRangeTuple:[playerID, ...], ....}
        return
    
    def InitViewCacheInstance(self, dbData):
    def __InitViewCacheInstance(self, dbData):
        '''初始化功能数据实例,创建或加载数据时通用,功能一般不调用
        @param dbData: 实例对应绑定的dbData
        @return: 成功返回实例对象,失败返回None
        '''
        playerID = dbData.PlayerID
        self.__refreshIDIndex()
        if playerID in self.__idIndexDict:
        if playerID in self.__viewCacheDict:
            return
        viewCache = PlayerViewCache(dbData)
        self.__viewCacheList.append(viewCache)
        self.__idIndexDict[playerID] = len(self.__viewCacheList) - 1
        self.__viewCacheDict[playerID] = viewCache
        self.__needSort = True
        return viewCache
    
    def CheckUpdViewCache(self, playerID):
        if playerID <= ShareDefine.FackPlayerIDMax:
            return
        curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
        if not curPlayer:
            return
        lastUpdTick = curPlayer.GetDictByKey(Key_UpdViewCacheTick)
        tick = GameWorld.GetGameWorld().GetTick()
        if lastUpdTick and tick - lastUpdTick < 60000:
            GameWorld.DebugLog("1分钟内只更新一次玩家缓存", playerID)
            return
        curPlayer.SetDict(Key_UpdViewCacheTick, tick)
        return UpdPlayerViewCache(curPlayer)
    def FindViewCache(self, playerID, isAdd=False):
        '''查找玩家缓存,如果不存在,则会有额外逻辑,如从redis、db直接找,
                        跨服玩家从跨服取,可能延迟获得
        '''
        curCache = self.GetPlayerViewCache(playerID)
        if curCache:
            updCache = self.CheckUpdViewCache(playerID)
            if updCache:
                curCache = updCache
        # 真实玩家
        elif playerID > ShareDefine.FackPlayerIDMax:
            curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
            # 本服在线玩家,直接生成新数据
            if curPlayer:
                dbData = DBStruct.tagDBPlayerViewCache()
                dbData.PlayerID = playerID
                self.InitViewCacheInstance(dbData)
                UpdPlayerViewCache(curPlayer)
            # 离线玩家
            else:
                pass
                # 本服玩家,从redis或db读取重新加载读取,换句话说,本服玩家只要获取一定有查看缓存数据
                # 跨服玩家,去子服拉取数据,理论上也一定有,但是如果需要拉数据,有一定延迟
                # 逻辑待扩展
        # 假玩家,默认添加
        elif ShareDefine.FackPlayerIDStart <= playerID <= ShareDefine.FackPlayerIDMax:
            serverID = playerID % 100 + 1 # 1 ~ 100 服
            accID = "fake%s@test@s%s" % (playerID, serverID)
            fightPower = random.randint(1000000, 100000000) # 先随机,外层有需要的话再自己设置
            dbData = DBStruct.tagDBPlayerViewCache()
            dbData.PlayerID = playerID
            dbData.PlayerName = "%s%s" % (GameWorld.GbkToCode("神秘道友"), playerID)
            dbData.AccID = accID
            dbData.LV = random.randint(100, 200)
            dbData.Job = random.randint(1, 2)
            dbData.RealmLV = random.randint(5, 15)
            dbData.FightPower = fightPower % ChConfig.Def_PerPointValue
            dbData.FightPowerEx = fightPower / ChConfig.Def_PerPointValue
            dbData.ServerID = serverID
            dbData.OffTime = int(time.time()) - random.randint(1, 3600 * 24 * 10) # 随机离线 0~10天
            curCache = self.InitViewCacheInstance(dbData)
        return curCache
    def AddPlayerViewCache(self, playerID):
        dbData = DBStruct.tagDBPlayerViewCache()
        dbData.PlayerID = playerID
        return self.__InitViewCacheInstance(dbData)
    
    def GetPlayerViewCache(self, playerID):
        ## 获取玩家查看缓存,仅内存中数据,无额外逻辑
        self.__refreshIDIndex()
        viewCache = None
        if playerID in self.__idIndexDict:
            index = self.__idIndexDict[playerID]
            if index < len(self.__viewCacheList):
                viewCache = self.__viewCacheList[index]
        if playerID in self.__viewCacheDict:
            viewCache = self.__viewCacheDict[playerID]
        if not viewCache and False:
            viewCache = PlayerViewCache()
            
@@ -200,32 +130,19 @@
            self.__serverIDRangePlayerIDDict[key] = playerIDList
        return self.__serverIDRangePlayerIDDict[key]
    
    def IsPlayerIn(self, playerID):
        self.__refreshIDIndex()
        return playerID in self.__idIndexDict
    def __refreshIDIndex(self):
        if not self.__idIndexDict:
            self.__idIndexDict = {}
            for index, viewCache in enumerate(self.__viewCacheList):
                self.__idIndexDict[viewCache.GetPlayerID()] = index
        return self.__idIndexDict
    def DelPlayerViewCache(self, playerID):
        self.__refreshIDIndex()
        index = self.__idIndexDict.pop(playerID, -1)
        if index >= 0 and index < len(self.__viewCacheList):
            self.__viewCacheList.pop(index)
        viewCache = self.__viewCacheDict.pop(playerID, None)
        if viewCache in self.__viewCacheList:
            self.__viewCacheList.remove(viewCache)
        for playerIDList in self.__serverIDRangePlayerIDDict.values():
            if playerID in playerIDList:
                playerIDList.remove(playerID)
        self.__idIndexDict = {}
        self.__serverIDRangePlayerIDDict = {}
        return
    
    def DelAllCache(self):
        self.__viewCacheList = []
        self.__idIndexDict = {}
        self.__viewCacheDict = {}
        self.__needSort = False
        self.__serverIDRangePlayerIDDict = {}
        return
@@ -243,9 +160,7 @@
            return
        self.__needSort = False
        self.__viewCacheList.sort(key=lambda v: (v.GetFightPowerTotal(), v.GetLV()), reverse=True)
        self.__idIndexDict = {}
        self.__serverIDRangePlayerIDDict = {}
        self.__refreshIDIndex()
        return
    
    # 保存数据 存数据库和realtimebackup
@@ -269,66 +184,7 @@
        for _ in xrange(cnt):
            dbData = DBStruct.tagDBPlayerViewCache()
            pos += dbData.readData(datas, pos, dataslen)
            self.InitViewCacheInstance(dbData)
            self.__InitViewCacheInstance(dbData)
            
        self.Sort()
        return pos
def OnPlayerLogout(curPlayer):
    if curPlayer.GetLV() >= 10:
        UpdPlayerViewCache(curPlayer)
    return
def UpdPlayerViewCache(curPlayer, isOffline=False):
    '''更新玩家查看缓存数据,更新时机由外层自己判断,这里只做更新逻辑
    1. 下线时强制更新一次,上线暂不更新,上线时由各功能如果有需要用到触发更新
    2. 有需要用到缓存数据时,如果玩家在线,1分钟内多次获取时最多更新一次,没有获取缓存数据则不更新
    '''
    if not curPlayer:
        return
    playerID = curPlayer.GetPlayerID()
    curCache = DBDataMgr.GetPlayerViewCacheMgr().GetPlayerViewCache(playerID)
    if not curCache:
        return
    tick = GameWorld.GetGameWorld().GetTick()
    curPlayer.SetDict(Key_UpdViewCacheTick, tick)
    GameWorld.DebugLog("更新玩家查看缓存数据! isOffline=%s" % isOffline, playerID)
    curCache.SetAccID(curPlayer.GetAccID())
    curCache.SetPlayerName(curPlayer.GetPlayerName())
    curCache.SetLV(curPlayer.GetLV())
    curCache.SetJob(curPlayer.GetJob())
    curCache.SetRealmLV(curPlayer.GetOfficialRank())
    curCache.SetFace(curPlayer.GetFace())
    curCache.SetFacePic(curPlayer.GetFacePic())
    curCache.SetFamilyID(curPlayer.GetFamilyID())
    curCache.SetFamilyName(curPlayer.GetFamilyName())
    curCache.SetFamilyEmblemID(PlayerControl.GetFamilyEmblemID(curPlayer))
    curCache.SetTitleID(PlayerControl.GetTitleID(curPlayer))
    curCache.SetFightPowerTotal(PlayerControl.GetFightPower(curPlayer))
    curCache.SetServerID(GameWorld.GetPlayerServerID(curPlayer))
    if isOffline:
        curCache.SetOffTime(int(time.time()))
    plusDict = curCache.GetPlusDict()
    #战斗属性
    plusDict.update({
                     "MinAtk":curPlayer.GetMinAtk(),
                     "MaxAtk":curPlayer.GetMaxAtk(),
                     "Def":curPlayer.GetDef(),
                     "MaxHP":GameObj.GetMaxHP(curPlayer),
                     "Hit":curPlayer.GetHit(),
                     "Miss":curPlayer.GetMiss(),
                     "SuperHitRate":curPlayer.GetSuperHitRate(), # 暴击率
                     })
    # 功能数据
    # 其他
    return curCache
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/CreateFamily.py
@@ -17,6 +17,7 @@
import GameWorld
import ShareDefine
import PlayerViewCache
import IPY_PlayerDefine
import PlayerFamily
import DBDataMgr
@@ -232,7 +233,7 @@
            else:
                memFightPower = avgValue + memCnt / 2 - m
                memFightPowerTotal -= memFightPower
            viewCache = DBDataMgr.GetPlayerViewCacheMgr().FindViewCache(memID, True)
            viewCache = PlayerViewCache.FindViewCache(memID, True)
            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/PlayerMirror.py
@@ -17,7 +17,6 @@
import GameWorld
import MirrorAttack
import PlayerViewCacheTube
import ChConfig
## GM命令执行入口
@@ -97,8 +96,8 @@
                return
            
    elif value1 == 5:
        tick = GameWorld.GetGameWorld().GetTick()
        PlayerViewCacheTube.UpdateGameServerPlayerCache(curPlayer, tick, forcePackData=True)
        #tick = GameWorld.GetGameWorld().GetTick()
        #PlayerViewCacheTube.UpdateGameServerPlayerCache(curPlayer, tick, forcePackData=True)
        GameWorld.DebugAnswer(curPlayer, "已更新最新镜像缓存!")
    elif value1 in ["a", "d", "p"]:
        return True
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py
@@ -1406,6 +1406,9 @@
        return mainServerID
    return 0
def GetDBPlayerAccIDByID(playerID):
    ## 获取玩家表账号ID - 根据玩家ID, 可用于判断是否本服玩家
    return PyGameData.g_dbPlayerIDMap.get(playerID, "")
#===============================================================================
# ƽ̨ID = appid
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/FBHelpBattle.py
@@ -20,7 +20,6 @@
import PlayerControl
import ChPyNetSendPack
import NetPackCommon
import PlayerViewCacheTube
import PlayerActGarbageSorting
import FBCommon
import IpyGameDataPY
@@ -111,8 +110,8 @@
        PlayerActGarbageSorting.AddActGarbageTaskProgress(curPlayer, ChConfig.Def_GarbageTask_HelpBattle)
        
        # 没有数据缓存的话,马上同步一次
        if not haveViewCache:
            PlayerViewCacheTube.UpdateGameServerPlayerCache(curPlayer, tick, False)
        #if not haveViewCache:
        #    PlayerViewCacheTube.UpdateGameServerPlayerCache(curPlayer, tick, False)
            
    SyncCheckInState(curPlayer, 1, False)
    
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/ItemCommon.py
@@ -31,7 +31,6 @@
import ChItem
import IpyGameDataPY
import Operate_EquipStone
import PlayerViewCacheTube
import Operate_EquipWash
import FormulaControl
import ChPyNetSendPack
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NetPackCommon.py
@@ -228,6 +228,19 @@
    #curPlayer.SendFakePack(innerPackData, len(innerPackData))
    curPlayer.SendFakePack(clientPack.GetBuffer(), clientPack.GetLength())
    
def SendFackPackOnline(clientPack, parseFunc=None, *args):
    ## 发送给全服在线玩家
    # @param parseFunc: 中间处理逻辑,可以做一些修改包数据的逻辑或者过滤某些玩家不发送,返回值为True时发送
    # @param args: parseFunc方法参数(curPlayer, ...)
    playerManager = GameWorld.GetPlayerManager()
    for i in xrange(playerManager.OnlineCount()):
        curPlayer = playerManager.OnlineAt(i)
        if not GameWorld.IsNormalPlayer(curPlayer):
            continue
        if parseFunc and not parseFunc(curPlayer, *args):
            continue
        SendFakePack(curPlayer, clientPack)
    return
#-------------------------------------------------------------------------------
#---Py封包注册信息
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
@@ -145,7 +145,6 @@
import PlayerArena
import PyGameData
import PlayerCoin
import PlayerGeTui
import PlayerCharm
import PlayerDogz
import PlayerCoat
@@ -178,6 +177,7 @@
import IPY_ServerDefine
import CommFunc
from PyMongoDB import RecvPackToMapDB
import PlayerTalk
import datetime
import time
@@ -208,10 +208,6 @@
    #初始化玩家的时钟个数
    if curPlayer.GetTickTypeCount() == 0:
        curPlayer.SetTickTypeCount(ChConfig.TYPE_Player_Tick_Count)
    #初始化玩家聊天频道
    if curPlayer.GetMaxChannelCount() == 0:
        curPlayer.SetMaxChannelCount(ChConfig.Def_PlayerTalkChannelMaxCount)
        
#===============================================================================
#    #初始化玩家鉴定管理器物品最大个数
@@ -643,9 +639,6 @@
    #大师
    PlayerGreatMaster.MasterOnLogin(curPlayer)
    
    # 推送提醒
    PlayerGeTui.LoginNotifySetting(curPlayer)
    #֪ͨVIP
    PlayerVip.DoOnLogin(curPlayer, tick)
    
@@ -998,6 +991,7 @@
        PlayerMineArea.OnPlayerLogin(curPlayer)
        PlayerGuaji.OnPlayerLogin(curPlayer)
        PlayerActFamilyGCZ.OnPlayerLogin(curPlayer)
        PlayerTalk.OnPlayerLogin(curPlayer)
        
        # 上线查询一次充值订单
        curPlayer.SendDBQueryRecharge()
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
@@ -37,6 +37,7 @@
import OperControlManager
import PlayerFamily
import ShareDefine
import PlayerViewCache
import PlayerBillboard
import GameServerRefresh
import IPY_GameWorld
@@ -56,7 +57,6 @@
import PlayerWorldAverageLv
import PlayerActivity
import FBCommon
import PlayerViewCacheTube
import PassiveBuffEffMng
import PlayerGameEvent
import EventReport
@@ -87,9 +87,7 @@
import PlayerActGarbageSorting
import GY_Query_CrossRealmReg
import PlayerTongTianLing
import PlayerCrossRealmPK
import FunctionNPCCommon
import DBPlayerViewCache
import PlayerGoldInvest
import IPY_PlayerDefine
import CrossRealmPlayer
@@ -251,7 +249,13 @@
#  @param mergeMapInfo 该提示所属的跨服活动地图信息, 主要用于不同子服对应所跨的活动地图ID
#  @return 无返回值
def WorldNotify(country, msgMark, msgParamList=[], lineID=0, mergeMinOSD=-1, mergeMaxOSD=-1, mergeMapInfo=[]):
    GameWorld.GetPlayerManager().BroadcastCountry_NotifyCode(country, 0, msgMark, __GetNotifyCodeList(msgParamList), lineID)
    #GameWorld.GetPlayerManager().BroadcastCountry_NotifyCode(country, 0, msgMark, __GetNotifyCodeList(msgParamList), lineID)
    playerManager = GameWorld.GetPlayerManager()
    for i in xrange(playerManager.OnlineCount()):
        curPlayer = playerManager.OnlineAt(i)
        if not GameWorld.IsNormalPlayer(curPlayer):
            continue
        NotifyCode(curPlayer, msgMark, msgParamList)
    return
def GetCrossWorldNotifyInfo(country, msgMark, msgParamList=[]):
@@ -277,7 +281,8 @@
#  @return 无返回值
#  @remarks 
def FamilyNotify(familyID, msgMark, msgParamList=[]):
    GameWorld.GetPlayerManager().BroadcastCountry_NotifyCode(0, familyID, msgMark, __GetNotifyCodeList(msgParamList))
    #GameWorld.GetPlayerManager().BroadcastCountry_NotifyCode(0, familyID, msgMark, __GetNotifyCodeList(msgParamList))
    PlayerFamily.NotifyAllFamilyMemberMsg(familyID, msgMark, msgParamList)
    return
#---------------------------------------------------------------------
@@ -1488,8 +1493,7 @@
    PlayerBillboard.UpdatePlayerBillboardOnLeaveServer(curPlayer) #排行榜已实时更新,故下线不再同步
    
    #玩家下线通知gameserver记录缓存(放在下线更新排行榜之后,方便Gameserver判断是否需要存入数据库中)
    PlayerViewCacheTube.OnPlayerLogOut(curPlayer, tick)
    DBPlayerViewCache.OnPlayerLogout(curPlayer)
    PlayerViewCache.OnPlayerLogout(curPlayer)
    PlayerFamily.OnPlayerLogout(curPlayer)
    
    #玩家下线/玩家切换地图公用逻辑
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
@@ -129,6 +129,7 @@
import PlayerFuncTeam
import PlayerMineArea
import PlayerBillboard
import PlayerViewCache
import PlayerMail
import datetime
@@ -168,6 +169,7 @@
    DoLogic_OnDayEx(tick)
    
    PlayerBillboard.OnDay()
    PlayerViewCache.OnDay()
    return
def DoLogic_OnDayEx(tick):
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFamily.py
@@ -20,6 +20,7 @@
import ShareDefine
import PlayerControl
import NetPackCommon
import PlayerViewCache
import ChPyNetSendPack
import PlayerFamilyTech
import PlayerFamilyEmblem
@@ -755,7 +756,7 @@
        reqInfo.ReqTime = reqTime
        if curPlayer:
            reqInfo.IsOnLine = True
        viewCache = DBDataMgr.GetPlayerViewCacheMgr().FindViewCache(playerID)
        viewCache = PlayerViewCache.FindViewCache(playerID)
        if viewCache:
            reqInfo.Name = viewCache.GetPlayerName()
            reqInfo.NameLen = len(reqInfo.Name)
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerGeTui.py
File was deleted
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py
@@ -34,7 +34,6 @@
import PlayerAutoCheckOnline
import PlayerGameWallow
import ReadChConfig
import PlayerViewCacheTube
import PlayerDienstgrad
import PlayerVip
import IpyGameDataPY
@@ -1274,9 +1273,6 @@
    
    #副本相关时间处理
    PlayerFB.DoPlayerFBTimeProcess(curPlayer, tick)
    #玩家数据缓存定时同步
    PlayerViewCacheTube.ProcessCache(curPlayer, tick)
    
    #脱机计算
    #PlayerTJG.ProcessPlayerTJG(curPlayer, tick)
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTJG.py
@@ -48,7 +48,6 @@
import math
import PassiveBuffEffMng
import PlayerPet
import PlayerGeTui
import ChEquip
import QuestCommon
import random
@@ -284,8 +283,6 @@
    ChangeGuard(curPlayer, tick)
    times, finalAddExp = CalcPlayerTJG(curPlayer, tick)
    
    #PlayerGeTui.TJGEfficiency(curPlayer, times, finalAddExp)
    #PlayerGeTui.TJGTimeLess(curPlayer)
    return
def GetTJGTime(curPlayer): return curPlayer.GetHappyPoint()
@@ -619,7 +616,6 @@
def CheckPackFull(curPlayer):
    if not ItemCommon.CheckPackHasSpace(curPlayer, IPY_GameWorld.rptItem):
        curPlayer.SetDict(ChConfig.Def_PlayerKey_TJGPackFullAfterEat, 1)
        #PlayerGeTui.FullPack(curPlayer)
# 可执行吞噬操作
def CanEatItemsOper(curPlayer):
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTalk.py
@@ -1,268 +1,110 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package
##@package Player.PlayerTalk
#
# @todo: 玩家聊天逻辑 支持语音
#
# @author: Alee
# @date 2018-4-24 下午07:36:28
# @todo:聊天
# @author hxp
# @date 2025-05-23
# @version 1.0
#
# @note:
# 详细描述: 聊天
#
#---------------------------------------------------------------------
import IPY_GameWorld
import GameWorld
import PlayerControl
#-------------------------------------------------------------------------------
#"""Version = 2025-05-23 20:00"""
#-------------------------------------------------------------------------------
import ChConfig
import FBLogic
#import ReadChConfig
import GameWorld
import ShareDefine
import IPY_GameWorld
import ChPyNetSendPack
import CrossRealmPlayer
import PlayerViewCache
import NetPackCommon
import EventReport
import PlayerSuccess
import IpyGameDataPY
import ItemCommon
import ChItem
import PlayerTJG
import EventShell
import PyGameData
import PlayerLove
import PlayerControl
import PlayerFamily
import DBDataMgr
import math
#---------------------------------------------------------------------
#需要记录聊天缓存的频道对应限制最大条数
ChannelCacheMax = {IPY_GameWorld.tcFamily:30,
                   IPY_GameWorld.tcWorld:100,
                   }
def OnPlayerLogin(curPlayer):
    NotifyTalkCache(curPlayer)
    return
## 区域频道(封包参数)
#  @param index 玩家索引
#  @param tick 当前时间
#  @return None
#  @remarks 函数详细说明.
#  整个地图的人都可以听到
def TalkArea(index, tick):
#// B3 20 聊天 #tagCMTalk
#
#struct    tagCMPyTalk
#{
#    tagHead        Head;
#    BYTE        ChannelType;    // 频道
#    WORD        Len;
#    char        Content[Len];        //size = Len
#};
def OnTalk(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    playerID = curPlayer.GetPlayerID()
    familyID = curPlayer.GetFamilyID()
    channelType = clientData.ChannelType
    content = clientData.Content
    
    #获得区域频封包
    sendPack = IPY_GameWorld.IPY_CTalkArea()
    #玩家聊天内容
    content = sendPack.GetContent()
    #通用判断
    if not __CheckTalk(curPlayer, content, sendPack.GetLen(), tick, talkType=IPY_GameWorld.tcArea):
        return
    #通用设置
    SetTalkTime(curPlayer, content, IPY_GameWorld.tcArea, tick)
    #如果在普通地图, 就广播, 如果在副本就单个通知
    if GameWorld.GetMap().GetMapFBType() == IPY_GameWorld.fbtNull and not GameWorld.IsCrossServer():
        #广播
        extras = GetTalkExtraValue(curPlayer)
        curPlayer.ChatArea(content, 0, extras)
    else:
        __DoLogic_FB_TalkArea(curPlayer, content)
    return True
## 副本中说话
#  @param curPlayer 当前玩家
#  @param content 讲话的内容
#  @return None
#  @remarks 函数详细说明.
def __DoLogic_FB_TalkArea(curPlayer, content):
    playerManager = GameWorld.GetMapCopyPlayerManager()
    for index in range(0 , playerManager.GetPlayerCount()):
        #广播玩家
        tempPlayer = playerManager.GetPlayerByIndex(index)
        if not tempPlayer.GetPlayerID():
            continue
    #GameWorld.DebugLog("OnTalk channelType=%s, %s" % (channelType, GameWorld.CodeToGbk(content)))
    if channelType == IPY_GameWorld.tcFamily:
        if not familyID:
            PlayerControl.NotifyCode(curPlayer, "jiazu_lhs_0")
            return
        
        #单个广播说话
        extras = GetTalkExtraValue(curPlayer)
        tempPlayer.Sync_ChatArea(curPlayer.GetPlayerID(), content, 0, extras)
    elif channelType == IPY_GameWorld.tcCountry:
        if GameWorld.IsCrossServer():
            return
        if not CrossRealmPlayer.IsCrossServerOpen():
            PlayerControl.NotifyCode(curPlayer, "CrossMatching18")
            return
        
    if not __CheckTalk(curPlayer, channelType, content, tick):
        return
    curPlayer.SetLastChatTick(tick)
    curPlayer.SetDict(ChConfig.Def_ChannelTalkTick % channelType, tick)
    if channelType == IPY_GameWorld.tcCountry:
        #发送到跨服,待扩展
        return
    bubbleBox = PlayerControl.GetChatBubbleBox(curPlayer) # 气泡框
    clientPack = ChPyNetSendPack.tagMCTalk()
    clientPack.ChannelType = channelType
    clientPack.PlayerID = playerID
    clientPack.Name = curPlayer.GetPlayerName()
    clientPack.NameLen = len(clientPack.Name)
    clientPack.Content = content
    clientPack.Len = len(clientPack.Content)
    clientPack.BubbleBox = bubbleBox
    clientPack.LV = curPlayer.GetLV()
    clientPack.Job = curPlayer.GetJob()
    clientPack.RealmLV = curPlayer.GetOfficialRank()
    clientPack.Face = curPlayer.GetFace()
    clientPack.FacePic = curPlayer.GetFacePic()
    clientPack.ServerID = GameWorld.GetPlayerServerID(curPlayer)
    if channelType == IPY_GameWorld.tcWorld:
        NetPackCommon.SendFackPackOnline(clientPack)
    elif channelType == IPY_GameWorld.tcFamily:
        PlayerFamily.Broadcast_FamilyPack(familyID, clientPack)
    DoTalkCache(channelType, playerID, content, bubbleBox, familyID)
    return
## 世界频道(封包参数)
#  @param index 玩家索引
#  @param tick 当前时间
#  @return None
#  @remarks 函数详细说明.
def TalkWorld(index, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    sendPack = IPY_GameWorld.IPY_CTalkGong()
    #玩家聊天内容
    content = sendPack.GetContent()
    #通用检测
    if not __CheckTalk(curPlayer, content, sendPack.GetLen(), tick, checkSameMsg = False, talkType=IPY_GameWorld.tcWorld):
        return
    #通用设置
    SetTalkTime(curPlayer, content, IPY_GameWorld.tcWorld, tick)
    #发送聊天内容
    extras = GetTalkExtraValue(curPlayer)
    curPlayer.ChatGong(content, 0, extras)
    #世界频道发言成就
    #PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_TalkWorld, 1)
    PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_FeastRedPack_TalkWorld, 1)
    EventShell.EventRespons_Talk(curPlayer, 'talkworld')
    return
## 国家频道(封包参数)
#  @param index 玩家索引
#  @param tick 当前时间
#  @return None
#  @remarks 函数详细说明.
def TalkCountry(index, tick):
    ## 跨服世界频道
    if GameWorld.IsCrossServer():
        return
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    if not CrossRealmPlayer.IsCrossServerOpen():
        PlayerControl.NotifyCode(curPlayer, "CrossMatching18")
        return
    sendPack = IPY_GameWorld.IPY_CTalkCountry()
    #玩家聊天内容
    content = sendPack.GetContent()
    #通用检测
    if not __CheckTalk(curPlayer, content, sendPack.GetLen(), tick, checkSameMsg = False, talkType=IPY_GameWorld.tcCountry):
        return
    #通用设置
    SetTalkTime(curPlayer, content, IPY_GameWorld.tcCountry, tick)
    #发送聊天内容
    extras = GetTalkExtraValue(curPlayer)
    curPlayer.ChatCountry(content, 0, extras)
    return
## 联盟家族频道(封包参数)
#  @param index 玩家索引
#  @param tick 当前时间
#  @return None
#  @remarks 函数详细说明.
def TalkFamily(index, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    if curPlayer.GetFamilyID() == 0:
        PlayerControl.NotifyCode(curPlayer, "jiazu_lhs_0 ")
        return
    sendPack = IPY_GameWorld.IPY_CTalkBang()
    #玩家聊天内容
    content = sendPack.GetContent()
    if not __CheckTalk(curPlayer, content, sendPack.GetLen(), tick, talkType=IPY_GameWorld.tcFamily):
        return
    #通用设置
    SetTalkTime(curPlayer, content, IPY_GameWorld.tcFamily, tick)
    extras = GetTalkExtraValue(curPlayer)
    curPlayer.ChatFamily(content, 0, extras)
    #仙盟频道发言成就
    PlayerSuccess.DoAddSuccessProgress(curPlayer, ShareDefine.SuccType_TalkFamily, 1)
    EventShell.EventRespons_Talk(curPlayer, 'talkfamily')
    return
## 队伍频道(封包参数)
#  @param index 玩家索引
#  @param tick 当前时间
#  @return None
#  @remarks 函数详细说明.
def TalkTeam(index, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    if curPlayer.GetTeam() == None:
        PlayerControl.NotifyCode(curPlayer, "GeRen_lhs_161795 ")
        return
    sendPack = IPY_GameWorld.IPY_CTalkDui()
    #玩家聊天内容
    content = sendPack.GetContent()
    if not __CheckTalk(curPlayer, content, sendPack.GetLen(), tick, talkType=IPY_GameWorld.tcTeam):
        return
    #通用设置
    SetTalkTime(curPlayer, content, IPY_GameWorld.tcTeam, tick)
    #说话
    extras = GetTalkExtraValue(curPlayer)
    curPlayer.ChatTeam(content, 0, extras)
    return
## 私聊频道(封包参数)
#  @param index 玩家索引
#  @param tick 当前时间
#  @return None
#  @remarks 函数详细说明.
def TalkPrivate(index, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    sendPack = IPY_GameWorld.IPY_CTalkMiFix()
    #玩家聊天内容
    content = sendPack.GetContent()
    if not __CheckTalk(curPlayer, content, sendPack.GetLen(), tick, talkType=IPY_GameWorld.tcPrivate):
        return
    #通用设置
    SetTalkTime(curPlayer, content, IPY_GameWorld.tcPrivate, tick)
    #说话
    extras = GetTalkExtraValue(curPlayer)
    curPlayer.ChatMiByID(sendPack.GetTalkType(), sendPack.GetPlayerID(), content, 0, extras)
    return
def TalkPrivateByID(curPlayer, tagPlayerID, content):
    #私聊 0为默认 1为1对1聊天
    talkType = 1
    extras = GetTalkExtraValue(curPlayer)
    curPlayer.ChatMiByID(talkType, tagPlayerID, content, 0, extras)
    return
## 私聊频道(封包参数)
#  @param index 玩家索引
#  @param tick 当前时间
#  @return None
#  @remarks 函数详细说明.
def TalkPrivateName(index, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    sendPack = IPY_GameWorld.IPY_CTalkMi()
    #玩家聊天内容
    content = sendPack.GetContent()
    if not __CheckTalk(curPlayer, content, sendPack.GetLen(), tick, talkType=IPY_GameWorld.tcPrivate):
        return
    #通用设置
    SetTalkTime(curPlayer, content, IPY_GameWorld.tcPrivate, tick)
    #说话
    extras = GetTalkExtraValue(curPlayer)
    curPlayer.ChatMiByName(sendPack.GetTalkType(), sendPack.GetTargetName(), content, 0, extras)
    return
#-3秒重复,;聊天信息太长
## 聊天通用检查
#  @param curPlayer 当前玩家
#  @param content 聊天内容
#  @param length 聊天长度
#  @param tick 当前时间
#  @param checkGMForbidenTalk 检查是否禁言
#  @param checkSameMsg 是否检查相同信息
#  @return True or False
#  @remarks 函数详细说明.
def __CheckTalk(curPlayer, content, length, tick, checkGMForbidenTalk = True, checkSameMsg = True, talkType=None):
def __CheckTalk(curPlayer, channelType, content, tick, checkGMForbidenTalk=True):
    ## 聊天通用检查
    if checkGMForbidenTalk and GetGMToolForbidTalk(curPlayer):
        #GeRen_chenxin_921745 对不起,您已被GM禁言,发送信息失败
        #PlayerControl.NotifyCode(curPlayer, "GeRen_chenxin_921745")
@@ -274,18 +116,18 @@
        return False
    
    #频道各自间隔时间
    if talkType != None:
    if channelType != None:
        talkCDDict = IpyGameDataPY.GetFuncEvalCfg("TalkCD", 1, {})
        if str(talkType) in talkCDDict:
            cdTicks = talkCDDict[str(talkType)] * 1000
            lastTalkTick = curPlayer.GetTalkTick(talkType)
        if str(channelType) in talkCDDict:
            cdTicks = talkCDDict[str(channelType)] * 1000
            lastTalkTick = curPlayer.GetDictByKey(ChConfig.Def_ChannelTalkTick % channelType)
            remainTick = cdTicks - (tick - lastTalkTick)
            if remainTick > 0:
                PlayerControl.NotifyCode(curPlayer, "CanootTalk01", [int(math.ceil(remainTick/1000.0))])
                PlayerControl.NotifyCode(curPlayer, "CanootTalk01", [int(math.ceil(remainTick / 1000.0))])
                return False
            
    #聊天信息太长
    if length > ChConfig.Def_PlayerTalkMaxCount :
    if len(content) > ChConfig.Def_PlayerTalkMaxCount:
        PlayerControl.NotifyCode(curPlayer, "CanootTalk13")
        return False
    
@@ -296,315 +138,97 @@
    
    return True
## 获得玩家是否被禁言
#  @param curPlayer 当前玩家
#  @return 是否禁言
def GetGMToolForbidTalk(curPlayer):
    ## 获得玩家是否被禁言
    #accIDForbid = (curPlayer.GetAccState() & pow(2, ChConfig.Def_PysForbidTalk)) > 0
    return curPlayer.GetGMForbidenTalk()# or accIDForbid
## 聊天时间通用设置
#  @param curPlayer 当前玩家
#  @param content 聊天内容
#  @param type 类型
#  @param tick 当前时间
#  @return None
#  @remarks 函数详细说明.
def SetTalkTime(curPlayer, content, type, tick):
    #设置当前时间为玩家开始聊天时间
    curPlayer.SetLastChatTick(tick)
    #设置当前聊天内容为玩家本次聊天内容
    #curPlayer.SetLastChatContent(content)
    #设置当前频道时间
    curPlayer.SetTalkTick(type, tick)
    return
## 信件2B封包
#  @param index 玩家索引
#  @param tick 当前时间
#  @return None
#  @remarks 函数详细说明.
def GBLetter(index, tick):
    #===========================================================================
    # curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    # sendPack = IPY_GameWorld.IPY_CGBLetter()
    #
    # if tick - curPlayer.GetTickByType(ChConfig.TYPE_Player_Tick_GBLetter) <= ChConfig.TYPE_Player_Tick_Time[ChConfig.TYPE_Player_Tick_GBLetter]:
    #    #发信1秒间隔
    #    return
    #
    # curPlayer.SetTickByType(ChConfig.TYPE_Player_Tick_GBLetter, tick)
    #
    # #信件标题和内容
    # titleStr = sendPack.GetTitle()
    # contentStr = sendPack.GetContent()
    #
    # #发给GM
    # curPlayer.Interface_SendGMLetter(titleStr, contentStr)
    #===========================================================================
    return
## 记录玩家聊天内容
#  @param messageStr 聊天类型
#  @param curPlayer 聊天的玩家
#  @param tagPlayer None
#  @param content 聊天内容
#  @param addinfo 额外信息
#  @return None
#  @remarks 函数详细说明.
def __LogInDBPlayerTalk(messageStr , curPlayer , tagPlayer , content, addinfo=""):
    # 由客户端向后台发送
    return
    #===========================================================================
    # tagName = "" if not tagPlayer else tagPlayer.GetName()
    # #EventReport.WriteEvent_chat_log(curPlayer, content, messageStr, tagName, addinfo)
    # gameWorld = GameWorld.GetGameWorld()
    # #开关未开启
    # if not gameWorld.GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_PurTalk):
    #    return
    #
    # #将聊天内容存入数据库
    # gameWorld.DataServer_TalkTrace('%s'%(messageStr), curPlayer, tagPlayer, content)
    # return
    #===========================================================================
## 获取聊天内容附加值
#  @param objTalk: 聊天对象
#  @return: 聊天内容附加值
def GetTalkExtraValue(objTalk):
    vipLv = objTalk.GetVIPLv()  # 玩家vip等级
    GMLevel = objTalk.GetGMLevel()
    job = objTalk.GetJob()
    playerID = objTalk.GetID()
    extraValueStr = ""
    # vip等级
    extraValueStr += GetTalkExtraValueStar(ShareDefine.Def_TalkExtraValue_Bit_VipLv)%vipLv
    # GM
    extraValueStr += GetTalkExtraValueStar(ShareDefine.Def_TalkExtraValue_Bit_GM)% (GMLevel > 0)
    # job
    extraValueStr += GetTalkExtraValueStar(ShareDefine.Def_TalkExtraValue_Bit_JOB)% job
    # 气泡框
    extraValueStr += GetTalkExtraValueStar(ShareDefine.Def_TalkExtraValue_Bit_BubbleBox) % PlayerControl.GetChatBubbleBox(objTalk)
    # 服务器组ID
    extraValueStr += GetTalkExtraValueStar(ShareDefine.Def_TalkExtraValue_Bit_ServerGroupID) % PlayerControl.GetPlayerServerGroupID(objTalk)
    # 等级
    extraValueStr += GetTalkExtraValueStar(ShareDefine.Def_TalkExtraValue_Bit_LV) % objTalk.GetLV()
    # 伴侣信息
    coupleName = PlayerControl.GetCoupleName(objTalk)
    coupleJob = PlayerControl.GetCoupleJob(objTalk)
    bridePriceMaxID = PlayerControl.GetBridePriceMaxID(objTalk)
    face = objTalk.GetFace()
    facePic = objTalk.GetFacePic()
    extraValueStr = "%s|%s|%s|%s|%s|%s" % (extraValueStr, coupleName, coupleJob, bridePriceMaxID, face, facePic)
    return extraValueStr
## 附加信息的长度匹配
#  @param extraValueInfo: 附加信息的长度
#  @return:
def GetTalkExtraValueStar(extraValueType):
    extraValueInfo = ShareDefine.Def_TalkExtraValue_LenDict.get(extraValueType)
    extraValueLen = extraValueInfo[1] - extraValueInfo[0]
    return "%0" + str(extraValueLen) + "d"
#// A2 17 喇叭聊天 #tagCMPYSpeaker
#
#struct    tagCMPYSpeaker
#{
#    tagHead        Head;
#    BYTE        SpeakerType;        //1-本服;2-跨服
#    BYTE        IsUseGold;        //是否使用钻石
#    BYTE        ItemIndex;        //使用物品说话时, 物品Index
#    BYTE        TextLen;        //字符长度
#    char        Text[TextLen];        //size = TextLen
#};
def OnUsePYSpeaker(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    playerID = curPlayer.GetPlayerID()
    SpeakerType = clientData.SpeakerType
    IsUseGold = clientData.IsUseGold
    ItemIndex = clientData.ItemIndex
    TextLen = clientData.TextLen
    Text = clientData.Text
    #GameWorld.Log("玩家喇叭聊天: SpeakerType=%s,IsUseGold=%s,ItemIndex=%s"
    #              % (SpeakerType, IsUseGold, ItemIndex), playerID)
    if not __CheckTalk(curPlayer, Text, TextLen, tick):
def DoTalkCache(channelType, playerID, content, bubbleBox, familyID=0):
    # 聊天缓存
    if channelType not in ChannelCacheMax:
        return
    cacheMaxDict = IpyGameDataPY.GetFuncEvalCfg("TalkCache", 1, {})
    maxCount = min(ChannelCacheMax[channelType], cacheMaxDict.get(channelType, 0))
    
    if IsUseGold:
        bugleItemID = IpyGameDataPY.GetFuncCfg('BugleItem', SpeakerType)
        if not bugleItemID:
            GameWorld.ErrLog("功能配置表没有配置对应喇叭类型物品消耗!SpeakerType=%s,请检查BugleItem!" % SpeakerType)
            return
        costMoney = ItemCommon.GetAutoBuyItemNeedGold({bugleItemID:1})
        if not costMoney:
            return
        moneyType = IPY_GameWorld.TYPE_Price_Gold_Money
        infoDict = {"SpeakerType":SpeakerType, ChConfig.Def_Cost_Reason_SonKey:bugleItemID}
        if not PlayerControl.PayMoney(curPlayer, moneyType, costMoney, ChConfig.Def_Cost_UseSpeaker, infoDict, 1):
            return
    # 检查使用喇叭道具
    elif not ChItem.DoSpeaker_UseItem(curPlayer, ItemIndex, SpeakerType):
        GameWorld.Log("    喇叭道具不可用!", playerID)
        return
    #通知世界服务器,使用小喇叭
    extraValue = 0
    extras = GetTalkExtraValue(curPlayer)
    msgList = str([SpeakerType, Text, extraValue, extras])
    GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(playerID, 0, 0, 'PYSpeaker', msgList, len(msgList))
    return
#// A2 16 自定义玩家聊天 #tagCMPyTalk
#
#struct    tagCMPyTalk
#{
#    tagHead        Head;
#    BYTE        TalkType;        // 自定义聊天类型
#    WORD        Len;
#    char        Content[Len];        //size = Len
#};
## 自定义玩家聊天
#  @param index
#  @param clientData
#  @param tick
#  @return
def OnPyTalk(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    #GameWorld.DebugLog("OnPyTalk, Name:%s" % curPlayer.GetPlayerName())
    talkType = clientData.TalkType
    contentLen = clientData.Len
    content = clientData.Content
    if talkType not in ShareDefine.TalkTypeList:
        GameWorld.ErrLog("OnPyTalk talkType(%s) is not define!" % talkType, curPlayer.GetPlayerID())
        return
    #通用判断
    if not __CheckTalk(curPlayer, content, contentLen, tick):
        return
    #说话
    extraValue = 0
    extras = GetTalkExtraValue(curPlayer)
    isChatOK = False
    if talkType == ShareDefine.Def_TalkType_FBFaction:
        isChatOK = __ChatFBFaction(curPlayer, talkType, content, extraValue, extras)
    # 仙盟聊天存FamilyAction
    if channelType == IPY_GameWorld.tcFamily:
        familyActonMgr = DBDataMgr.GetFamilyActionMgr().GetFamilyAction(familyID, ShareDefine.Def_ActionType_TalkCache)
        actionData = familyActonMgr.AddAction(maxCount)
        actionData.SetValue1(playerID)
        actionData.SetValue2(bubbleBox)
        actionData.GetUserDict().update({"content":content})
        
    if not isChatOK:
        return
    #设置当前时间为玩家开始聊天时间
    curPlayer.SetLastChatTick(tick)
    #设置当前聊天内容为玩家本次聊天内容
    curPlayer.SetLastChatContent(content)
    return True
    else:
        recTypeIDMgr = DBDataMgr.GetGameRecMgr().GetRecTypeIDMgr(ShareDefine.Def_GameRecType_TalkCache, channelType)
        recData = recTypeIDMgr.AddRecData(maxCount)
        recData.SetValue1(playerID)
        recData.SetValue2(bubbleBox)
        recData.GetUserDict().update({"content":content})
    return
## py自定义聊天推送包
def __GetPyTalkPack(curPlayer, talkType, content, extraValue, extras):
    pyTalk = ChPyNetSendPack.tagMCPyTalk()
    pyTalk.Clear()
    pyTalk.TalkType = talkType
    pyTalk.Name = curPlayer.GetPlayerName()
    pyTalk.NameLen = len(pyTalk.Name)
    pyTalk.PlayerID = curPlayer.GetPlayerID()
    pyTalk.Len = len(content)
    pyTalk.Content = content
    pyTalk.ExtraValue = extraValue
    pyTalk.Extras = extras
    return pyTalk
## 副本阵营聊天
def __ChatFBFaction(curPlayer, talkType, content, extraValue, extras):
    curFaction = curPlayer.GetFaction()
    if not curFaction:
        return False
def NotifyTalkCache(curPlayer):
    ##上线通知聊天缓存
    
    pyTalkPack = __GetPyTalkPack(curPlayer, talkType, content, extraValue, extras)
    playerManager = GameWorld.GetMapCopyPlayerManager()
    for index in range(playerManager.GetPlayerCount()):
        player = playerManager.GetPlayerByIndex(index)
        if not player:
    for channelType in ChannelCacheMax.keys():
        cacheList = []
        if channelType == IPY_GameWorld.tcFamily:
            familyID = curPlayer.GetFamilyID()
            if not familyID:
                continue
            familyActonMgr = DBDataMgr.GetFamilyActionMgr().GetFamilyAction(familyID, ShareDefine.Def_ActionType_TalkCache)
            for index in range(familyActonMgr.Count()):
                actionData = familyActonMgr.At(index)
                talkTime = actionData.GetTime()
                playerID = actionData.GetValue1()
                bubbleBox = actionData.GetValue2()
                content = actionData.GetUserDict().get("content", "")
                if not content:
                    content
                cacheList.append([talkTime, playerID, bubbleBox, content])
        else:
            recTypeIDMgr = DBDataMgr.GetGameRecMgr().GetRecTypeIDMgr(ShareDefine.Def_GameRecType_TalkCache, channelType)
            for index in range(recTypeIDMgr.GetCount()):
                recData = recTypeIDMgr.At(index)
                talkTime = recData.GetTime()
                playerID = recData.GetValue1()
                bubbleBox = recData.GetValue2()
                content = recData.GetUserDict().get("content", "")
                if not content:
                    content
                cacheList.append([talkTime, playerID, bubbleBox, content])
        if not cacheList:
            continue
        
        if player.GetFaction() != curFaction:
        packCacheList = []
        for talkTime, playerID, bubbleBox, content in cacheList:
            viewCache = PlayerViewCache.FindViewCache(playerID)
            if not viewCache:
                continue
            talkCache = ChPyNetSendPack.tagMCTalkCacheInfo()
            talkCache.PlayerID = playerID
            talkCache.Name = viewCache.GetPlayerName()
            talkCache.NameLen = len(talkCache.Name)
            talkCache.Content = content
            talkCache.Len = len(talkCache.Content)
            talkCache.BubbleBox = bubbleBox
            talkCache.LV = viewCache.GetLV()
            talkCache.Job = viewCache.GetJob()
            talkCache.RealmLV = viewCache.GetRealmLV()
            talkCache.Face = viewCache.GetFace()
            talkCache.FacePic = viewCache.GetFacePic()
            talkCache.ServerID = viewCache.GetServerID()
            talkCache.TalkTime = talkTime
            packCacheList.append(talkCache)
        if not packCacheList:
            continue
        
        if PlayerTJG.GetIsTJG(player):
            continue
        clientPack = ChPyNetSendPack.tagMCTalkCacheList()
        clientPack.ChannelType = channelType
        clientPack.InfoList = packCacheList
        clientPack.Count = len(clientPack.InfoList)
        NetPackCommon.SendFakePack(curPlayer, clientPack)
        
        NetPackCommon.SendFakePack(player, pyTalkPack)
    return True
#===============================================================================
# //A2 26 语音聊天 #tagCMVoiceChat
#
# struct    tagCMVoiceChat
# {
#    tagHead        Head;
#    BYTE        ChannelType;     //  5 区域 --- 查看封包tagCGVoiceChat 1 世界 2 仙盟 3 私聊(好友) 4 队伍
#    BYTE        TargetNameLen;
#    char        TargetName[TargetNameLen];        //size = TargetNameLen
#    DWORD        TargetID;        // 默认发玩家ID,没有ID才发名称
#    WORD        Len;
#    BYTE        Content[Len];        //size = Len
# };
#===============================================================================
def OnVoiceChat(index, clientPack, tick):
#    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
#    if GetGMToolForbidTalk(curPlayer):
#        return
#    if clientPack.ChannelType != ShareDefine.Def_ChannelChat_Area:
#        return
#    sendPack = ChPyNetSendPack.tagGCVoiceChat()
#    sendPack.Clear()
#    sendPack.ChannelType = clientPack.ChannelType
#    sendPack.SrcName = curPlayer.GetName()
#    sendPack.SrcNameLen = len(curPlayer.GetName())
#    sendPack.PlayerID = curPlayer.GetID()
#    sendPack.Len = clientPack.Len
#    sendPack.Content = clientPack.Content
#    sendPack.Extras = GetTalkExtraValue(curPlayer)
#    sendPack.ExtraValue = len(sendPack.Extras)
#
#    # 区域频道
#
#    #如果在普通地图, 就广播, 如果在副本就单个通知
#    if GameWorld.GetMap().GetMapFBType() == IPY_GameWorld.fbtNull:
#        curPlayer.BroadCastAll(sendPack.GetBuffer(), len(sendPack.GetBuffer()))
#    else:
#        playerManager = GameWorld.GetMapCopyPlayerManager()
#
#        for index in range(0 , playerManager.GetPlayerCount()):
#            #广播玩家
#            tempPlayer = playerManager.GetPlayerByIndex(index)
#            if not tempPlayer.GetPlayerID():
#                continue
#
#            if PlayerTJG.GetIsTJG(tempPlayer):
#                continue
#
#            NetPackCommon.SendFakePack(tempPlayer, sendPack)
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerViewCache.py
New file
@@ -0,0 +1,298 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package Player.PlayerViewCache
#
# @todo:玩家缓存
# @author hxp
# @date 2025-5-22
# @version 1.0
#
# 详细描述: 玩家缓存
#
#-------------------------------------------------------------------------------
#"""Version = 2025-5-22 下午6:37:10"""
#-------------------------------------------------------------------------------
import ChConfig
import GameWorld
import PyMongoMain
import PlayerControl
import NetPackCommon
import ChPyNetSendPack
import IpyGameDataPY
import ShareDefine
import DBDataMgr
import GameObj
import random
import time
Key_UpdViewCacheTick = "UpdViewCacheTick"
def OnDay():
    DelOutofTimeViewCacheData()
    return
def OnPlayerLogout(curPlayer):
    if curPlayer.GetLV() < 10:
        return
    curCache = UpdPlayerViewCache(curPlayer)
    if curCache and not IsSaveDBViewCache(curCache):
        DBDataMgr.GetPlayerViewCacheMgr().DelPlayerViewCache(curPlayer.GetPlayerID())
    return
def DelOutofTimeViewCacheData():
    ## 删除过期的查看缓存数据
    playerManager = GameWorld.GetPlayerManager()
    viewCacheMgr = DBDataMgr.GetPlayerViewCacheMgr()
    for index in range(viewCacheMgr.GetCount())[::-1]: # 有删除需倒序遍历
        viewCache = viewCacheMgr.At(index)
        playerID = viewCache.GetPlayerID()
        curPlayer = playerManager.FindPlayerByID(playerID)
        if curPlayer:
            continue
        if IsSaveDBViewCache(viewCache):
            continue
        viewCacheMgr.DelPlayerViewCache(playerID)
    return
def IsSaveDBViewCache(viewCache):
    ## 缓存数据是否入库
    if not viewCache:
        return False
    playerID = viewCache.GetPlayerID()
    #某个功能中不能删除的
    #...
    #排行版上的默认保留
    billboardMgr = DBDataMgr.GetBillboardMgr()
    for bType in ShareDefine.BillboardTypeAllList:
        if bType in ShareDefine.FamilyBillboardList:
            continue
        groupList = billboardMgr.GetBillboardGroupList(bType)
        for billboardType, groupValue1, groupValue2 in groupList:
            billboardObj = billboardMgr.GetBillboard(billboardType, groupValue1, groupValue2)
            if billboardObj.FindByID(playerID):
                return True
    # 以上是相关功能需要用到的数据,必定不能删除的
    # 以下是保留近期活跃玩家,等级限制
    playerLV = viewCache.GetLV()
    if playerLV >= IpyGameDataPY.GetFuncCfg("PlayerViewCache", 1):
        maxDays = IpyGameDataPY.GetFuncCfg("PlayerViewCache", 2)
        if not maxDays:
            maxDays = 7 # 默认7天
        MaxTime = maxDays * 3600 * 24
        curTime = int(time.time())
        passTime = curTime - viewCache.GetOffTime()
        if passTime < MaxTime:
            return True
    return False
def FindViewCache(playerID, isAdd=False):
    '''查找玩家缓存,如果不存在,则会有额外逻辑,如从redis、db直接找,
            本服玩家理论上一定有查看缓存,因为如果不存在会直接从db读,除非该玩家数据被删除
            跨服玩家理论上也一定有缓存,只是通过跨服或从子服查询,延迟获得
            【注】外层调用依然要判断是否有数据
    '''
    viewCacheMgr = DBDataMgr.GetPlayerViewCacheMgr()
    curCache = viewCacheMgr.GetPlayerViewCache(playerID)
    if curCache:
        updCache = __CheckUpdViewCache(playerID)
        if updCache:
            curCache = updCache
    # 真实玩家
    elif playerID > ShareDefine.FackPlayerIDMax:
        curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
        # 本服在线玩家,直接生成新数据
        if curPlayer:
            curCache = viewCacheMgr.AddPlayerViewCache(playerID)
            UpdPlayerViewCache(curPlayer)
        # 本服离线玩家
        elif GameWorld.GetDBPlayerAccIDByID(playerID):
            # 本服玩家,从redis或db读取重新加载读取,换句话说,本服玩家只要获取一定有查看缓存数据
            curCache = UpdPlayerViewCacheByDB(playerID)
        # 跨服玩家
        else:
            pass
            # 跨服玩家,去子服拉取数据,理论上也一定有,但是如果需要拉数据,有一定延迟
            # 逻辑待扩展
    # 假玩家,默认添加
    elif ShareDefine.FackPlayerIDStart <= playerID <= ShareDefine.FackPlayerIDMax:
        serverID = playerID % 100 + 1 # 1 ~ 100 服
        accID = "fake%s@test@s%s" % (playerID, serverID)
        fightPower = random.randint(1000000, 100000000) # 先随机,外层有需要的话再自己设置
        curCache = viewCacheMgr.AddPlayerViewCache(playerID)
        curCache.SetPlayerName("%s%s" % (GameWorld.GbkToCode("神秘道友"), playerID))
        curCache.SetAccID(accID)
        curCache.SetLV(random.randint(100, 200))
        curCache.SetJob(random.randint(1, 2))
        curCache.SetRealmLV(random.randint(5, 15))
        curCache.SetFightPowerTotal(fightPower)
        curCache.SetServerID(serverID)
        curCache.SetOffTime(int(time.time()) - random.randint(1, 3600 * 24 * 10)) # 随机离线 0~10天
    return curCache
def __CheckUpdViewCache(playerID):
    if playerID <= ShareDefine.FackPlayerIDMax:
        return
    curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
    if not curPlayer:
        return
    lastUpdTick = curPlayer.GetDictByKey(Key_UpdViewCacheTick)
    tick = GameWorld.GetGameWorld().GetTick()
    if lastUpdTick and tick - lastUpdTick < 60000:
        GameWorld.DebugLog("1分钟内只更新一次玩家缓存", playerID)
        return
    curPlayer.SetDict(Key_UpdViewCacheTick, tick)
    return UpdPlayerViewCache(curPlayer)
def UpdPlayerViewCache(curPlayer, isOffline=False):
    '''更新玩家查看缓存数据,更新时机由外层自己判断,这里只做更新逻辑
    1. 下线时强制更新一次,上线暂不更新,上线时由各功能如果有需要用到触发更新
    2. 有需要用到缓存数据时,如果玩家在线,1分钟内多次获取时最多更新一次,没有获取缓存数据则不更新
    '''
    if not curPlayer:
        return
    playerID = curPlayer.GetPlayerID()
    curCache = DBDataMgr.GetPlayerViewCacheMgr().GetPlayerViewCache(playerID)
    if not curCache:
        return
    tick = GameWorld.GetGameWorld().GetTick()
    curPlayer.SetDict(Key_UpdViewCacheTick, tick)
    GameWorld.DebugLog("更新玩家查看缓存数据! isOffline=%s" % isOffline, playerID)
    curCache.SetAccID(curPlayer.GetAccID())
    curCache.SetPlayerName(curPlayer.GetPlayerName())
    curCache.SetLV(curPlayer.GetLV())
    curCache.SetJob(curPlayer.GetJob())
    curCache.SetRealmLV(curPlayer.GetOfficialRank())
    curCache.SetFace(curPlayer.GetFace())
    curCache.SetFacePic(curPlayer.GetFacePic())
    curCache.SetFamilyID(curPlayer.GetFamilyID())
    curCache.SetFamilyName(curPlayer.GetFamilyName())
    curCache.SetFamilyEmblemID(PlayerControl.GetFamilyEmblemID(curPlayer))
    curCache.SetTitleID(PlayerControl.GetTitleID(curPlayer))
    curCache.SetFightPowerTotal(PlayerControl.GetFightPower(curPlayer))
    curCache.SetServerID(GameWorld.GetPlayerServerID(curPlayer))
    if isOffline:
        curCache.SetOffTime(int(time.time()))
    plusDict = curCache.GetPlusDict()
    #战斗属性
    plusDict.update({
                     "MinAtk":curPlayer.GetMinAtk(),
                     "MaxAtk":curPlayer.GetMaxAtk(),
                     "Def":curPlayer.GetDef(),
                     "MaxHP":GameObj.GetMaxHP(curPlayer),
                     "Hit":curPlayer.GetHit(),
                     "Miss":curPlayer.GetMiss(),
                     "SuperHitRate":curPlayer.GetSuperHitRate(), # 暴击率
                     })
    # 功能数据
    # 其他
    return curCache
def UpdPlayerViewCacheByDB(playerID):
    '''更新玩家查看缓存数据,直接从db数据更新,仅更新dbPlayer表有的属性,
    '''
    GameWorld.DebugLog("UpdPlayerViewCacheByDB", playerID)
    curCache = None
    dbPlayer = PyMongoMain.GetUserCtrlDB().findDBPlayer(playerID)
    if not dbPlayer:
        GameWorld.DebugLog("1111111111111111", playerID)
        return curCache
    viewCacheMgr = DBDataMgr.GetPlayerViewCacheMgr()
    curCache = viewCacheMgr.GetPlayerViewCache(playerID)
    if not curCache:
        curCache = viewCacheMgr.AddPlayerViewCache(playerID)
    familyID = dbPlayer.FamilyID
    GameWorld.DebugLog("db查找直接更新玩家查看缓存数据!", playerID)
    curCache.SetAccID(dbPlayer.AccID)
    curCache.SetPlayerName(dbPlayer.PlayerName)
    curCache.SetLV(dbPlayer.LV)
    curCache.SetJob(dbPlayer.Job)
    curCache.SetRealmLV(dbPlayer.OfficialRank)
    curCache.SetFace(dbPlayer.Face)
    curCache.SetFacePic(dbPlayer.FacePic)
    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(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
#//A2 12 查看玩家详细信息#tagCMViewPlayerInfo
#struct tagCMViewPlayerInfo
#{
#    tagHead        Head;
#    DWORD        PlayerID;
#    BYTE        EquipClassLV;    //大于0为查看指定境界阶装备信息,  0为查看默认信息
#};
def OnCMViewPlayerInfo(index, clientPack, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    findPlayerID = clientPack.PlayerID
    #equipClassLV = clientPack.EquipClassLV
    clientPack = GetPack_ViewCache(findPlayerID)
    if clientPack:
        NetPackCommon.SendFakePack(curPlayer, clientPack)
        return
    if GameWorld.GetDBPlayerAccIDByID(findPlayerID):
        PlayerControl.NotifyCode(curPlayer, "ViewPlayer_OffLine")
        return
    # 跨服玩家发送跨服查询,待扩展...
    return
def GetPack_ViewCache(playerID):
    ## 获取同步封包 - 玩家查看缓存
    curCache = FindViewCache(playerID)
    if not curCache:
        return
    clientPack = ChPyNetSendPack.tagSCQueryPlayerCacheResult()
    clientPack.PlayerID = curCache.GetPlayerID()
    clientPack.PlayerName = curCache.GetPlayerName()
    clientPack.LV = curCache.GetLV()
    clientPack.Job = curCache.GetJob()
    clientPack.RealmLV = curCache.GetRealmLV()
    clientPack.Face = curCache.GetFace()
    clientPack.FacePic = curCache.GetFacePic()
    clientPack.TitleID = curCache.GetTitleID()
    clientPack.ServerID = curCache.GetServerID()
    clientPack.FightPower = curCache.GetFightPower()
    clientPack.FightPowerEx = curCache.GetFightPowerEx()
    clientPack.FamilyID = curCache.GetFamilyID()
    clientPack.FamilyName = curCache.GetFamilyName()
    clientPack.FamilyEmblemID = curCache.GetFamilyEmblemID()
    clientPack.PlusData = curCache.GetPlusData()
    clientPack.PlusDataSize = len(clientPack.PlusData)
    return clientPack
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerViewCacheTube.py
File was deleted
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_PlayerMirror.py
@@ -17,7 +17,6 @@
import GameWorld
import MirrorAttack
import PlayerViewCacheTube
import PyGameData
#---------------------------------------------------------------------
@@ -62,36 +61,36 @@
        return
    msgType = funResult[0]
    msgData = funResult[1]
    if msgType == "PackDataSyncState":
        PlayerViewCacheTube.UpdPackDataSyncState(curPlayer, msgData)
        if msgData.get("PackDataCross"): # 如果跨服需要的,立即同步一次
            PlayerViewCacheTube.UpdateGameServerPlayerCache(curPlayer, tick)
    elif msgType == "PullPlayerPackData":
        msgInfo = msgData
        __DoPullPlayerPackData(curPlayer, msgInfo, tick)
    elif msgType == "PullPlayerViewCache":
        msgInfo = msgData
        __DoPullPlayerViewCache(curPlayer, msgInfo, tick)
#
#    if msgType == "PackDataSyncState":
#        PlayerViewCacheTube.UpdPackDataSyncState(curPlayer, msgData)
#        if msgData.get("PackDataCross"): # 如果跨服需要的,立即同步一次
#            PlayerViewCacheTube.UpdateGameServerPlayerCache(curPlayer, tick)
#    elif msgType == "PullPlayerPackData":
#        msgInfo = msgData
#        __DoPullPlayerPackData(curPlayer, msgInfo, tick)
#
#    elif msgType == "PullPlayerViewCache":
#        msgInfo = msgData
#        __DoPullPlayerViewCache(curPlayer, msgInfo, tick)
#
    return
def __DoPullPlayerPackData(curPlayer, msgInfo, tick):
    pullFrom = msgInfo.get("pullFrom")
    # 0 或 非本服代表跨服需要
    if pullFrom == 0 or (pullFrom > 0 and pullFrom != GameWorld.GetServerGroupID()):
        PlayerViewCacheTube.SetPackDataCrossSyncState(curPlayer)
    else:
        PlayerViewCacheTube.SetPackDataSyncState(curPlayer)
    PlayerViewCacheTube.UpdateGameServerPlayerCache(curPlayer, tick, forcePackData=True, packMsg=msgInfo)
#    if pullFrom == 0 or (pullFrom > 0 and pullFrom != GameWorld.GetServerGroupID()):
#        PlayerViewCacheTube.SetPackDataCrossSyncState(curPlayer)
#    else:
#        PlayerViewCacheTube.SetPackDataSyncState(curPlayer)
#    PlayerViewCacheTube.UpdateGameServerPlayerCache(curPlayer, tick, forcePackData=True, packMsg=msgInfo)
    return
def __DoPullPlayerViewCache(curPlayer, msgInfo, tick):
    viewFrom = msgInfo.get("viewFrom")
    # 0 或 非本服代表跨服需要
    if viewFrom == 0 or (viewFrom > 0 and viewFrom != GameWorld.GetServerGroupID()):
        PlayerViewCacheTube.SetViewCacheCrossSyncState(curPlayer)
    PlayerViewCacheTube.UpdateGameServerPlayerCache(curPlayer, tick, packMsg=msgInfo, isOnlyViewCache=True)
#    if viewFrom == 0 or (viewFrom > 0 and viewFrom != GameWorld.GetServerGroupID()):
#        PlayerViewCacheTube.SetViewCacheCrossSyncState(curPlayer)
#    PlayerViewCacheTube.UpdateGameServerPlayerCache(curPlayer, tick, packMsg=msgInfo, isOnlyViewCache=True)
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
@@ -26,6 +26,8 @@
g_pyGameDataManager = None
g_dbPlayerIDMap = {} # 本服DBPlayer玩家表ID映射关系 {playerID:accID, ...}
g_mapIDTxtInfo = {} # MapID.txt 加载的信息
g_realmDiffPlayerDict = {} # 境界难度玩家信息 {realm:[playerID, ...], ...}
g_realmDiffNPCRefresh = {} # {(lineID, realm):{refreshID:tagNPCRefresh, ...}}
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/Collections/CollectionDefine.py
@@ -5,6 +5,7 @@
#-------------------------------------------------------------------------------
#
#卡牌服务器表
UCN_DBGameRec="tagDBGameRec"
UCN_DBFamilyAction="tagDBFamilyAction"
UCN_DBFamilyMem="tagDBFamilyMem"
UCN_DBFamily="tagDBFamily"
@@ -18,7 +19,6 @@
#MMO旧表
UCN_DBPlayerPackData="tagDBPlayerPackData"
UCN_DBGameRec="tagDBGameRec"
UCN_DBPyFuncTeam="tagDBPyFuncTeam"
UCN_DBPyFuncTeamMem="tagDBPyFuncTeamMem"
UCN_DBPlayerRecData="tagDBPlayerRecData"
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/Collections/DataServerPlayerData.py
@@ -28697,3 +28697,221 @@
            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
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/LogicProcess/UserCtrlDB.py
@@ -400,10 +400,27 @@
            PyGameData.g_UserCtrlDBFirstInit = True
            self.__PlayerBackupSave()
            CheckGameVersion()
            #后续也要增加公共数据保存如家族等,考虑保存失败可以直接关闭地图
            self.loadDBPlayerIDMap()
        return
    def loadDBPlayerIDMap(self):
        ## 加载本服玩家映射关系
        col = self.db[UCN_DBPlayer]
        resultSet = col.find({}, {"PlayerID":1, "AccID":1, "_id":0})
        if resultSet and resultSet.count():
            for resultDict in resultSet:
                PyGameData.g_dbPlayerIDMap[resultDict["PlayerID"]] = resultDict["AccID"]
        GameWorld.Log("启动服务器加载DBPlayer玩家账号ID对应关系! %s, %s" % (len(PyGameData.g_dbPlayerIDMap), PyGameData.g_dbPlayerIDMap))
        return
    def findDBPlayer(self, playerID):
        col = self.db[UCN_DBPlayer]
        dbPlayer = DataServerPlayerData.tagDBPlayer()
        dbPlayer.IsDeleted = 0
        if not dbPlayer.adoLoadCEx(col, {"PlayerID":playerID}):
            return
        return dbPlayer
    
    def requestLogicProcess(self, pack):
        db = self.db
@@ -1662,7 +1679,7 @@
            mylog.debug('RevoverBillProcess success...%s'%orderID)
        except:
            mylog.error("RevoverBillProcess error %s"%orderID)
            mylog.error("RevoverBillProcess error %s"%traceback.format_exc())
    
    def SavePlayerMapServerData(self, db, saveData):
        playerRec = DataServerPlayerData.tagDBPlayer()
@@ -2413,6 +2430,9 @@
            return 0, disDataBaseError, createPlayer.AccID, '' 
        mylog.debug('insert role ok!accid = %s, PlayerName = %s'%(createPlayer.AccID, createPlayer.PlayerName))
        PyGameData.g_dbPlayerIDMap[newPlayerID] = createPlayer.AccID
        mylog.debug('PyGameData.g_dbPlayerIDMap = %s, %s'%(len(PyGameData.g_dbPlayerIDMap), PyGameData.g_dbPlayerIDMap))
        #构造其他角色初始数据
        itemData = ''
        itemData = CommFunc.WriteDWORD(itemData, 0)
@@ -3409,6 +3429,11 @@
        data += DBFamilyAction.adoQueryAll(collection)
        mylog.info("tagDBFamilyAction ok")
        
        collection = db[UCN_DBGameRec]
        DBGameRec = DataServerPlayerData.tagDBGameRec()
        data += DBGameRec.adoQueryAll(collection)
        mylog.info("tagDBGameRec ok")
        mylog.info('readGameWorldData len:%s' % len(data))
        return data
    
@@ -3430,6 +3455,7 @@
            gameDataReadPos = self.savegameServerWorldData(saveData, gameDataReadPos, UCN_DBFamily, DataServerPlayerData.tagDBFamily, db)
            gameDataReadPos = self.savegameServerWorldData(saveData, gameDataReadPos, UCN_DBFamilyMem, DataServerPlayerData.tagDBFamilyMem, db)
            gameDataReadPos = self.savegameServerWorldData(saveData, gameDataReadPos, UCN_DBFamilyAction, DataServerPlayerData.tagDBFamilyAction, db)
            gameDataReadPos = self.savegameServerWorldData(saveData, gameDataReadPos, UCN_DBGameRec, DataServerPlayerData.tagDBGameRec, db)
            
            mylog.info('saveGameWorldData ok!')
            
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
@@ -946,6 +946,9 @@
BillboardTypeAllList = BillboardTypeList + CrossBillboardTypeList
#仙盟榜单类型
FamilyBillboardList = [Def_BT_BossTrialSubmitFamily, Def_BT_BossTrialSubmitFamilyBak, Def_CBT_FamilyGCZScore, Def_CBT_FamilyGCZRoundHurt]
#职业对应战力排行榜类型
JobFightPowerBillboardDict = {
                              PlayerJob_Warrior:Def_BT_FightPower_Warrior,
@@ -958,9 +961,6 @@
                             Def_BT_LV, Def_BT_FightPower_Horse, Def_BT_FightPower_Pet, Def_BT_TrialTower, Def_BT_OffLineEfficient,
                             Def_BT_SkyTower, Def_BT_CharmTotal, Def_BT_CharmWeek, Def_BT_CharmDay
                             ]
#仙盟榜单类型
FamilyBillboardList = [Def_BT_BossTrialSubmitFamily, Def_BT_BossTrialSubmitFamilyBak]
##---比率---
#百分率
@@ -1381,35 +1381,6 @@
    5006:6,
    }
#聊天信息附加值
(
Def_TalkExtraValue_Bit_VipLv,  # vip等级
Def_TalkExtraValue_Bit_GM,            #GM
Def_TalkExtraValue_Bit_JOB, #job
Def_TalkExtraValue_Bit_BubbleBox, #气泡框
Def_TalkExtraValue_Bit_ServerGroupID, #服务器组ID
Def_TalkExtraValue_Bit_LV, #等级
) = range(0, 6)
#聊天信息附加值中某信息数据所占位置
#{聊天信息附加值类型:[起始位置(从左往右), 结束位置(不包含)]}
Def_TalkExtraValue_LenDict = {
     Def_TalkExtraValue_Bit_VipLv:[0, 2],  # vip等级
     Def_TalkExtraValue_Bit_GM:[2, 3],  # GM
     Def_TalkExtraValue_Bit_JOB:[3, 4],  # job
     Def_TalkExtraValue_Bit_BubbleBox:[4, 6],  # 气泡框
     Def_TalkExtraValue_Bit_ServerGroupID:[6, 13],  # 服务器组ID
     Def_TalkExtraValue_Bit_LV:[13, 17],  # 等级
     }
# 聊天频道 暂用语音
(Def_ChannelChat_World,     # 世界
Def_ChannelChat_Family,     # 仙盟
Def_ChannelChat_Private,    # 私聊含好友
Def_ChannelChat_Team,       # 队伍
Def_ChannelChat_Area,    # 区域(当前地图或副本线)
) = range(1, 6)
#背包类型
(
rptTempSwap,        # 临时交换背包 28
@@ -1469,7 +1440,8 @@
                       Def_GameRecType_FamilyGCZJoinFamily, # 仙盟攻城战参与仙盟信息, zoneID 303
                       Def_GameRecType_FamilyGCZJoinMember, # 仙盟攻城战参与成员信息, zoneID 304
                       Def_GameRecType_FamilyGCZCityWall, # 仙盟攻城战城池信息, zoneID 305
                       ) = range(300, 1 + 305)
                       Def_GameRecType_TalkCache, # 聊天缓存,频道 306
                       ) = range(300, 1 + 306)
#通用信息记录新 - 字典key配置,如果有配置,则可额外按对应记录Value值存储字典,方便快速取值,可配置Value编号 1~8,配空默认 Value1
Def_GameRecValueKeyDict = {
                           Def_GameRecType_Xiangong:[1],
@@ -1580,7 +1552,20 @@
                      Def_ActionType_FamilyCTGAssist,    #仙盟充值协助活动 14
                      Def_ActionType_FamilyEmblem,    #仙盟时效徽章信息 15
                      Def_ActionType_Zhenbaoge,    #珍宝阁 16
                      ) = range(0, 17)
                      Def_ActionType_TalkCache,    #聊天缓存 17,最大条数配置决定
                      ) = range(0, 18)
#家族某行为类型保存的条数
ActionTypeSaveCnt = {
                     Def_ActionType_FamilyPray:10 ,    #家族祈福
                     Def_ActionType_FamilyArrest:7,     #家族悬赏
                     Def_ActionType_FamilyMember:1,       #记录家族成员信息
                     Def_ActionType_LeaderImpeachTime:1,  # 族长下线了多久
                     Def_ActionType_FamilyBossFB:1,  # 记录家族boss副本信息
                     Def_ActionType_FamilyStore:30,       #仓库操作记录
                     Def_ActionType_OfficerModelEquip:10,  # 记录家族有职位的成员模型装备信息(盟主+副盟主*2+战斗队长*5)
                     Def_ActionType_FamilyEvent:50,  # 记录家族事件
                     }
# 家族行为事件类型定义; Def_ActionType_FamilyEvent; 存与事件记录Value1
# 通用:time-时间;name-玩家;value1-事件类型