66 【公会】基础主体-服务端(跨服公会所有基本功能支持、跨服砍价支持;修改查看目标公会、查看目标玩家方式;)
21个文件已修改
921 ■■■■ 已修改文件
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py 180 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/CommFunc.py 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/StructData/DBFamily.py 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/StructData/DBPlayerViewCache.py 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/CreateFamily.py 78 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Family.py 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py 45 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/CrossMgr.py 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/CrossMsg.py 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldEvent.py 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NetPackCommon.py 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/CrossPlayer.py 72 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFamily.py 151 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFamilyEmblem.py 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerViewCache.py 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
@@ -166,9 +166,9 @@
PacketSubCMD_6=0x12
PacketCallFunc_6=OnFamilyMoneyDonate
PacketCMD_7=
PacketSubCMD_7=
PacketCallFunc_7=
PacketCMD_7=A6
PacketSubCMD_7=19
PacketCallFunc_7=OnViewTagFamily
PacketCMD_8=0xA6
PacketSubCMD_8=0x20
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
@@ -2165,7 +2165,7 @@
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("PlayerID", c_int),    
                  ("EquipClassLV", c_ubyte),    #大于0为查看指定境界阶装备信息,  0为查看默认信息
                  ("ServerID", c_int),    #玩家服务器ID,发0默认本服玩家
                  ]
    def __init__(self):
@@ -2183,7 +2183,7 @@
        self.Cmd = 0xA2
        self.SubCmd = 0x12
        self.PlayerID = 0
        self.EquipClassLV = 0
        self.ServerID = 0
        return
    def GetLength(self):
@@ -2197,13 +2197,13 @@
                                Cmd:%s,
                                SubCmd:%s,
                                PlayerID:%d,
                                EquipClassLV:%d
                                ServerID:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.PlayerID,
                                self.EquipClassLV
                                self.ServerID
                                )
        return DumpString
@@ -7565,6 +7565,62 @@
#------------------------------------------------------
# A6 19 查看目标公会 #tagCSViewTagFamily
class  tagCSViewTagFamily(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("FamilyID", c_int),
                  ("ServerID", c_int),    #公会服务器ID,发0默认本服公会
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xA6
        self.SubCmd = 0x19
        return
    def ReadData(self, stringData, _pos=0, _len=0):
        self.Clear()
        memmove(addressof(self), stringData[_pos:], self.GetLength())
        return _pos + self.GetLength()
    def Clear(self):
        self.Cmd = 0xA6
        self.SubCmd = 0x19
        self.FamilyID = 0
        self.ServerID = 0
        return
    def GetLength(self):
        return sizeof(tagCSViewTagFamily)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// A6 19 查看目标公会 //tagCSViewTagFamily:
                                Cmd:%s,
                                SubCmd:%s,
                                FamilyID:%d,
                                ServerID:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.FamilyID,
                                self.ServerID
                                )
        return DumpString
m_NAtagCSViewTagFamily=tagCSViewTagFamily()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCSViewTagFamily.Cmd,m_NAtagCSViewTagFamily.SubCmd))] = m_NAtagCSViewTagFamily
#------------------------------------------------------
# A6 16 珍宝阁操作 #tagCMZhenbaogeOP
class  tagCMZhenbaogeOP(Structure):
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
@@ -11133,6 +11133,7 @@
    FamilyCount = 0    #(BYTE FamilyCount)
    FamilyList = list()    #(vector<tagMCFamilyView> FamilyList)//本页家族信息列表
    Rank = 0    #(DWORD Rank)//玩家公会所在名次,0-没有公会或没有在榜上;>0-对应排名
    DataServerID = 0    #(DWORD DataServerID)//数据所在服务器ID
    data = None
    def __init__(self):
@@ -11155,6 +11156,7 @@
            _pos = temFamilyList.ReadData(_lpData, _pos)
            self.FamilyList.append(temFamilyList)
        self.Rank,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.DataServerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        return _pos
    def Clear(self):
@@ -11170,6 +11172,7 @@
        self.FamilyCount = 0
        self.FamilyList = list()
        self.Rank = 0
        self.DataServerID = 0
        return
    def GetLength(self):
@@ -11183,6 +11186,7 @@
        length += 1
        for i in range(self.FamilyCount):
            length += self.FamilyList[i].GetLength()
        length += 4
        length += 4
        return length
@@ -11199,6 +11203,7 @@
        for i in range(self.FamilyCount):
            data = CommFunc.WriteString(data, self.FamilyList[i].GetLength(), self.FamilyList[i].GetBuffer())
        data = CommFunc.WriteDWORD(data, self.Rank)
        data = CommFunc.WriteDWORD(data, self.DataServerID)
        return data
    def OutputString(self):
@@ -11211,7 +11216,8 @@
                                TotalPage:%d,
                                FamilyCount:%d,
                                FamilyList:%s,
                                Rank:%d
                                Rank:%d,
                                DataServerID:%d
                                '''\
                                %(
                                self.Head.OutputString(),
@@ -11222,7 +11228,8 @@
                                self.TotalPage,
                                self.FamilyCount,
                                "...",
                                self.Rank
                                self.Rank,
                                self.DataServerID
                                )
        return DumpString
@@ -11693,6 +11700,175 @@
#------------------------------------------------------
# A5 19 查看目标公会信息 #tagSCTagFamilyInfo
class  tagSCTagFamilyInfo(Structure):
    Head = tagHead()
    FamilyID = 0    #(DWORD FamilyID)//家族ID
    FamilyNameLen = 0    #(BYTE FamilyNameLen)
    FamilyName = ""    #(String FamilyName)//size = FamilyNameLen
    LeaderID = 0    #(DWORD LeaderID)//族长ID
    LeaderNameLen = 0    #(BYTE LeaderNameLen)
    LeaderName = ""    #(String LeaderName)//size = LeaderNameLen
    LeaderServerID = 0    #(DWORD LeaderServerID)//会长区服ID
    FamilyLV = 0    #(BYTE FamilyLV)//家族等级
    ServerID = 0    #(DWORD ServerID)//区服ID
    EmblemID = 0    #(DWORD EmblemID)//徽章ID
    EmblemWord = ""    #(char EmblemWord[3])//徽章文字
    FightPower = 0    #(DWORD FightPower)//总战力,求余亿部分
    FightPowerEx = 0    #(DWORD FightPowerEx)//总战力,整除亿部分
    BroadcastLen = 0    #(WORD BroadcastLen)//公告
    Broadcast = ""    #(String Broadcast)//size = BroadcastLen
    MemberCount = 0    #(BYTE MemberCount)//成员人数
    DataServerID = 0    #(DWORD DataServerID)//数据所在服务器ID
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xA5
        self.Head.SubCmd = 0x19
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.FamilyID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.FamilyNameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.FamilyName,_pos = CommFunc.ReadString(_lpData, _pos,self.FamilyNameLen)
        self.LeaderID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.LeaderNameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.LeaderName,_pos = CommFunc.ReadString(_lpData, _pos,self.LeaderNameLen)
        self.LeaderServerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.FamilyLV,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.ServerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.EmblemID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.EmblemWord,_pos = CommFunc.ReadString(_lpData, _pos,3)
        self.FightPower,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.FightPowerEx,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.BroadcastLen,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.Broadcast,_pos = CommFunc.ReadString(_lpData, _pos,self.BroadcastLen)
        self.MemberCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.DataServerID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xA5
        self.Head.SubCmd = 0x19
        self.FamilyID = 0
        self.FamilyNameLen = 0
        self.FamilyName = ""
        self.LeaderID = 0
        self.LeaderNameLen = 0
        self.LeaderName = ""
        self.LeaderServerID = 0
        self.FamilyLV = 0
        self.ServerID = 0
        self.EmblemID = 0
        self.EmblemWord = ""
        self.FightPower = 0
        self.FightPowerEx = 0
        self.BroadcastLen = 0
        self.Broadcast = ""
        self.MemberCount = 0
        self.DataServerID = 0
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 4
        length += 1
        length += len(self.FamilyName)
        length += 4
        length += 1
        length += len(self.LeaderName)
        length += 4
        length += 1
        length += 4
        length += 4
        length += 3
        length += 4
        length += 4
        length += 2
        length += len(self.Broadcast)
        length += 1
        length += 4
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteDWORD(data, self.FamilyID)
        data = CommFunc.WriteBYTE(data, self.FamilyNameLen)
        data = CommFunc.WriteString(data, self.FamilyNameLen, self.FamilyName)
        data = CommFunc.WriteDWORD(data, self.LeaderID)
        data = CommFunc.WriteBYTE(data, self.LeaderNameLen)
        data = CommFunc.WriteString(data, self.LeaderNameLen, self.LeaderName)
        data = CommFunc.WriteDWORD(data, self.LeaderServerID)
        data = CommFunc.WriteBYTE(data, self.FamilyLV)
        data = CommFunc.WriteDWORD(data, self.ServerID)
        data = CommFunc.WriteDWORD(data, self.EmblemID)
        data = CommFunc.WriteString(data, 3, self.EmblemWord)
        data = CommFunc.WriteDWORD(data, self.FightPower)
        data = CommFunc.WriteDWORD(data, self.FightPowerEx)
        data = CommFunc.WriteWORD(data, self.BroadcastLen)
        data = CommFunc.WriteString(data, self.BroadcastLen, self.Broadcast)
        data = CommFunc.WriteBYTE(data, self.MemberCount)
        data = CommFunc.WriteDWORD(data, self.DataServerID)
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                FamilyID:%d,
                                FamilyNameLen:%d,
                                FamilyName:%s,
                                LeaderID:%d,
                                LeaderNameLen:%d,
                                LeaderName:%s,
                                LeaderServerID:%d,
                                FamilyLV:%d,
                                ServerID:%d,
                                EmblemID:%d,
                                EmblemWord:%s,
                                FightPower:%d,
                                FightPowerEx:%d,
                                BroadcastLen:%d,
                                Broadcast:%s,
                                MemberCount:%d,
                                DataServerID:%d
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.FamilyID,
                                self.FamilyNameLen,
                                self.FamilyName,
                                self.LeaderID,
                                self.LeaderNameLen,
                                self.LeaderName,
                                self.LeaderServerID,
                                self.FamilyLV,
                                self.ServerID,
                                self.EmblemID,
                                self.EmblemWord,
                                self.FightPower,
                                self.FightPowerEx,
                                self.BroadcastLen,
                                self.Broadcast,
                                self.MemberCount,
                                self.DataServerID
                                )
        return DumpString
m_NAtagSCTagFamilyInfo=tagSCTagFamilyInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagSCTagFamilyInfo.Head.Cmd,m_NAtagSCTagFamilyInfo.Head.SubCmd))] = m_NAtagSCTagFamilyInfo
#------------------------------------------------------
# A6 05 VIP礼包购买记录 #tagMCVIPAwardMsg
class  tagMCVIPAwardMsg(Structure):
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/CommFunc.py
@@ -69,7 +69,14 @@
    if space:
        hex_str = ' '.join(hex_str[i:i+2] for i in range(0, len(hex_str), 2))
    return hex_str
def GetPackHead(clientPack):
    if hasattr(clientPack, "Head"):
        headStr = "%02x%02x" % (clientPack.Head.Cmd, clientPack.Head.SubCmd)
    else:
        headStr = "%02x%02x" % (clientPack.Cmd, clientPack.SubCmd)
    return headStr.upper()
#获取异常信息#(try:...except:..GetExceptionInfo())
## 
#  @param 参数
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/StructData/DBFamily.py
@@ -263,6 +263,8 @@
        self.SetFacePic(viewCache.GetFacePic())
        self.SetTitleID(viewCache.GetTitleID())
        self.SetServerID(viewCache.GetServerID())
        if not self.GetOffTime(): # 有离线时间数据了,以成员自己的为准
            self.SetOffTime(viewCache.GetOffTime())
        fpChange = False
        fightPowerTotal = viewCache.GetFightPowerTotal()
        if self.GetFightPowerTotal() != fightPowerTotal:
@@ -343,6 +345,9 @@
            return
        self.__memberDict[playerID] = member
        self.__memberList.append(member)
        viewCache = PlayerViewCache.FindViewCache(playerID)
        member.SetOffTime(viewCache.GetOffTime() if viewCache else int(time.time()))
        self.__familyMgr.OnAddMember(self, playerID)
        return member
    
    def GetMemberIDList(self): return self.__memberDict.keys()
@@ -360,7 +365,6 @@
            if not member and False:
                member = FamilyMem()
        self.RefrshFightPowerTotal()
        self.__familyMgr.OnAddMember(self, playerID)
        return member
    
    def DeleteMember(self, playerID):
@@ -520,6 +524,8 @@
                if fixName not in self.__familyNameDict:
                    familyName = fixName
                    break
            family.SetName(familyName)
            family.SetExtra1(0) # 重置改名CD
        self.__familyNameDict[familyName] = family
        
        if family not in self.__familyList:
@@ -834,10 +840,18 @@
        self.__crossZoneCfgDict = updCrossZoneCfgDict
        self.__zoneFamilyMgrDict = {}
        self.__familyIDZoneIDDict = {}
        # 重新初始化本服管理的分区
        zoneDict = self.__crossZoneCfgDict[crossServerID]
        GameWorld.Log("本跨服重置公会互通分区! crossServerID=%s,zoneDict=%s" % (crossServerID, zoneDict))
        for zoneID in zoneDict.keys():
            self.GetZoneFamilyMgr(zoneID)
        GameWorld.Log("GetZoneIDListThisServer=%s" % self.GetZoneIDListThisServer())
        # 重新将本服公会数据分配到所属分区
        for family in self.__familyIDDict.values():
            familyID = family.GetID()
            zoneID = familyZoneDict.get(familyID, 0) # 理论上不可能再为0
            zoneID = familyZoneDict.get(familyID, 0) # 理论上不可能再为0,因为有0时 noZoneServerIDList 验证不会通过
            zoneMgr = self.GetZoneFamilyMgr(zoneID)
            zoneMgr.AddFamilyToZone(family)
            
@@ -877,7 +891,7 @@
                    break
        return zoneID
    
    def GetZoneIDListThisServer(self): return self.__zoneFamilyMgrDict.keys() # 在本服数据中已存在的分区
    def GetZoneIDListThisServer(self): return self.__zoneFamilyMgrDict.keys() # 本服管理的分区
    
    def GetFamilyZoneID(self, familyID): return self.__familyIDZoneIDDict.get(familyID, -1) # -1-未找到所属分区;>=0-所属分区
    
@@ -1035,7 +1049,7 @@
            self.__setFamilyToDefaultZone() # 游戏服本服的数据无论有没有跨服了都同意设置到默认分区
        return pos
    
def LoadZoneCfg(self):
def LoadZoneCfg():
    crossZoneCfgDict = {}
    appID = GameWorld.GetAppID()
    ipyDataMgr = IpyGameDataPY.IPY_Data()
@@ -1049,6 +1063,7 @@
            crossZoneCfgDict[crossServerID] = {}
        zoneDict = crossZoneCfgDict[crossServerID]
        zoneDict[zoneID] = [] + ipyData.GetServerIDList()
    GameWorld.Log("跨服公会分区配置加载: appID=%s,%s" % (appID, crossZoneCfgDict))
    return crossZoneCfgDict
def CheckCrossZoneCfg(curCrossZoneCfgDict, updCrossZoneCfgDict):
@@ -1058,7 +1073,7 @@
        GameWorld.Log("跨服公会互通分区配置不变不处理")
        return
    
    # 验证配置,是否有交叉、拆分,并邮件通知运维,待扩展,先开发功能
    # 验证配置,是否有交叉、拆分,并邮件通知运维,待扩展,功能完整性优先
    #GameWorld.SendGameErrorEx("FamilyCrossZoneCfgError", "noZoneServerIDList=%s" % noZoneServerIDList)
    
    return True
@@ -1073,11 +1088,13 @@
        if not crossZoneCfgDict or not DBDataMgr.GetFamilyMgr().UpdCrossZoneCfgDict(crossZoneCfgDict):
            return
        Sync_CenterToCross_FamilyCrossCfg()
        Sync_CrossToServer_FamilyInfo()
    return
def Sync_CenterToCross_FamilyInfo(serverType, serverID):
    ## 跨服中心同步给跨服服务器
    # 【注】只同步给跨服服务器,各跨服验证通过后,游戏服才会通过所属跨服取得最终的分区信息
    if serverType == ShareDefine.serverType_Cross:
        Sync_CenterToCross_FamilyCrossCfg(serverID)
    return
@@ -1115,6 +1132,7 @@
    ## 跨服服务器同步互通公会信息给游戏服
    # @param toServerID: 有指定游戏服连上时只发给该服,没有的话一般是分区配置变更时由跨服主动同步所有相关游戏服
    
    GameWorld.DebugLog("Sync_CrossToServer_FamilyInfo toServerID=%s,syncZoneID=%s,syncFamilyIDList=%s" % (toServerID, syncZoneID, syncFamilyIDList))
    familyMgr = DBDataMgr.GetFamilyMgr()
    crossZoneCfgDict = familyMgr.GetCrossZoneCfgDict() # 配置的互通
    if not crossZoneCfgDict:
@@ -1123,6 +1141,7 @@
    if crossServerID not in crossZoneCfgDict:
        return
    zoneCfgDict = crossZoneCfgDict[crossServerID]
    GameWorld.DebugLog("    crossServerID=%s,zoneCfgDict=%s" % (crossServerID, zoneCfgDict))
    
    for zoneID in familyMgr.GetZoneIDListThisServer():
        if syncZoneID and syncZoneID != zoneID:
@@ -1134,6 +1153,7 @@
        if toServerID:
            if not GameWorld.CheckServerIDInList(toServerID, cfgServerIDList):
                # 非指定目标服务器所属分区不同步
                #GameWorld.DebugLog("    非指定目标服务器所属分区不同步 toServerID=%s" % (toServerID))
                continue
            toServerIDList = [toServerID]
        else:
@@ -1260,6 +1280,7 @@
    syncData = familyMgr.GetSaveData(cntDict)
    familyIDList = familyMgr.GetFamilyIDList()
    
    GameWorld.Log("dataslen=%s" % len(syncData))
    CrossMsg.SendToCrossServer(ShareDefine.S2C_FamilyData, {"syncData":syncData, "familyIDList":familyIDList, "cntDict":cntDict}, [crossServerID])
    return
@@ -1270,11 +1291,9 @@
    GameWorld.Log("收到游戏服同步的互通公会数据! fromServerID=%s,cntDict=%s,familyIDList=%s" % (fromServerID, cntDict, familyIDList))
    
    unpackRet = __unpackFamilyData(syncData, familyIDList, cntDict)
    if not unpackRet:
        errorMsg = "unknown"
    else:
        errorMsg = unpackRet[0]
    if errorMsg:
    isOK = unpackRet[0]
    if not isOK:
        errorMsg = unpackRet[1]
        GameWorld.SendGameErrorEx("S2C_FamilyDataError", "互通公会数据同步失败! fromServerID=%s,errorMsg=%s" % (fromServerID, errorMsg))
        CrossMsg.SendToClientServer(ShareDefine.C2S_FamilyDataRet, {"isOK":False}, [fromServerID])
        return
@@ -1287,7 +1306,6 @@
    
    syncFamilyIDList = []
    for dbData in familyDataList:
        dbData = DBStruct.tagDBFamily()
        familyID = dbData.ID
        familyMgr.DelFamily(familyID, False) # 每次都强制先删除,支持重复同步
        zoneMgr.AddFamilyToZone(familyMgr.InitFamilyInstance(dbData))
@@ -1327,6 +1345,7 @@
    
    errorMsg = ""
    datas, pos, dataslen = syncData, 0, len(syncData)
    GameWorld.Log("__unpackFamilyData: dataslen=%s" % dataslen)
    
    zoneIDDict = {}
    familyMgr = DBDataMgr.GetFamilyMgr()
@@ -1342,25 +1361,25 @@
        familyID = dbData.ID
        if familyID not in familyIDList:
            errorMsg = "同步的数据公会ID不匹配! familyID=%s not in %s" % (familyID, familyIDList)
            return errorMsg
            return False, errorMsg
        
        familyServerID = dbData.ServerID
        zoneID = familyMgr.GetZoneIDInThisServer(familyServerID)
        if zoneID <= 0:
            errorMsg = "同步的公会数据不属于本跨服! familyID=%s,familyServerID=%s,zoneID=%s" % (familyID, familyServerID, zoneID)
            return errorMsg
            return False, errorMsg
        zoneIDDict[zoneID] = familyServerID
        
    if len(zoneIDDict) != 1:
        errorMsg = "同步的公会数据分区异常可能存在多个分区! zoneIDDict=%s" % zoneIDDict
        return errorMsg
        return False, errorMsg
    zoneID = zoneIDDict.keys()[0]
    
    uppackFamilyCnt = len(familyDataList)
    familyDataCnt = cntDict.get("familyDataCnt", 0)
    if uppackFamilyCnt != familyDataCnt:
        errorMsg = "同步的公会个数不匹配! uppackFamilyCnt=%s != %s" % (uppackFamilyCnt, familyDataCnt)
        return errorMsg
        return False, errorMsg
    
    # 成员
    memberDataList = []
@@ -1375,7 +1394,7 @@
    membreDataCnt = cntDict.get("membreDataCnt", 0)
    if uppackMemberCnt != membreDataCnt:
        errorMsg = "同步的成员个数不匹配! uppackMemberCnt=%s != %s" % (uppackMemberCnt, membreDataCnt)
        return errorMsg
        return False, errorMsg
    
    # 行为
    actionDataList = []
@@ -1390,9 +1409,9 @@
    actionDataCnt = cntDict.get("actionDataCnt", 0)
    if uppackMemberCnt != membreDataCnt:
        errorMsg = "同步的行为个数不匹配! uppackActionCnt=%s != %s" % (uppackActionCnt, actionDataCnt)
        return errorMsg
        return False, errorMsg
    
    return errorMsg, zoneID, familyDataList, memberDataList, actionDataList
    return True, zoneID, familyDataList, memberDataList, actionDataList
def C2S_FamilyDataRet(dataMsg, fromServerID):
    isOK = dataMsg["isOK"]
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/DB/StructData/DBPlayerViewCache.py
@@ -21,6 +21,7 @@
import ShareDefine
import CommFunc
import ChConfig
import time
class PlayerViewCache():
    
@@ -97,6 +98,8 @@
        if playerID in self.__viewCacheDict:
            return
        viewCache = PlayerViewCache(dbData)
        if not viewCache.GetOffTime(): # 无值时默认离线时间为当前,适用于机器人、假人、重启加载数据时修正异常在线状态
            viewCache.SetOffTime(int(time.time()))
        self.__viewCacheList.append(viewCache)
        self.__viewCacheDict[playerID] = viewCache
        self.__needSort = True
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/CreateFamily.py
@@ -27,20 +27,27 @@
def GetGMServerIDList(curPlayer):
    ## 获取命令额外发送到其他服务器,如跨服
    crossServerID = DBDataMgr.GetFamilyMgr().GetCurCrossServerID()
    #GameWorld.DebugAnswer(curPlayer, "GetGMServerIDList: %s" % crossServerID)
    GameWorld.DebugAnswer(curPlayer, "本服公会互通跨服ID:%s" % crossServerID)
    if crossServerID:
        return [crossServerID]
    return []
def OnExecCross(crossPlayer, gmList):
    ## 跨服执行命令
    GameWorld.DebugLog("OnExecCross %s" % gmList, crossPlayer.GetPlayerID())
    playerID = crossPlayer.GetPlayerID()
    familyMgr = DBDataMgr.GetFamilyMgr()
    familyID = familyMgr.GetPlayerFamilyID(playerID)
    zoneID = familyMgr.GetFamilyZoneID(familyID)
    GameWorld.DebugAnswer(crossPlayer, "跨服公会ID:%s,zoneID=%s" % (familyID, zoneID))
    OnExec(crossPlayer, gmList)
    return
def OnExec(curPlayer, gmList):
    ## 游戏服执行命令
    
    if not gmList:
        if GameWorld.IsCrossServer():
            return
        GameWorld.DebugAnswer(curPlayer, "创建假人公会: CreatFamily 个数 [总战力 ServerID 等级 成员数  是否审核 官职限制]")
        GameWorld.DebugAnswer(curPlayer, "删除假人公会: CreatFamily 0")
        GameWorld.DebugAnswer(curPlayer, "输出公会列表: CreatFamily pl [条数 从第x名]")
@@ -51,46 +58,45 @@
    
    crossPlayer = CrossPlayer.GetCrossPlayerMgr().FindCrossPlayer(curPlayer.GetPlayerID())
    if not crossPlayer:
        #GameWorld.DebugAnswer(curPlayer, "找不到crossPlayer")
        return
    
    value1 = gmList[0]
    if value1 == "pl":
        __printFamilyList(curPlayer, gmList)
        __printFamilyList(crossPlayer, gmList)
        return
    
    if value1 == "pf":
        __printFamilyInfo(curPlayer, gmList)
        __printFamilyInfo(crossPlayer, gmList)
        return
    
    if value1 == "sq":
        __addFackRequestJoin(curPlayer, gmList)
        __addFackRequestJoin(crossPlayer, gmList)
        return
    
    if value1 == "m":
        __addFackMember(curPlayer, gmList, crossPlayer)
        __addFackMember(crossPlayer, gmList)
        return
    
    creatCount = value1
    if creatCount <= 0:
        __delFackFamily(curPlayer)
        __delFackFamily(crossPlayer)
        return
    __createFackFamily(curPlayer, gmList)
    __createFackFamily(crossPlayer, gmList)
    return
def __addFackMember(curPlayer, gmList, crossPlayer):
def __addFackMember(crossPlayer, gmList):
    memCnt = gmList[1] if len(gmList) > 1 else 1
    familyID = gmList[2] if len(gmList) > 2 else curPlayer.GetFamilyID()
    familyID = gmList[2] if len(gmList) > 2 else crossPlayer.GetFamilyID()
    
    familyMgr = DBDataMgr.GetFamilyMgr()
    curFamily = familyMgr.FindFamily(familyID)
    if not curFamily:
        GameWorld.DebugAnswer(curPlayer, "没有该公会: %s" % familyID)
        GameWorld.DebugAnswer(crossPlayer, "没有该公会: %s" % familyID)
        return
    
    MemberMax = PlayerFamily.GetFamilySetting(curFamily.GetLV(), "MemberMax")
    if curFamily.GetCount() >= MemberMax:
        GameWorld.DebugAnswer(curPlayer, "成员已满: %s" % MemberMax)
        GameWorld.DebugAnswer(crossPlayer, "成员已满: %s" % MemberMax)
        return
    memCnt = min(memCnt, MemberMax - curFamily.GetCount())
    
@@ -120,17 +126,17 @@
        
    curZoneMgr.Sort()
    PlayerFamily.Sync_FamilyInfo(crossPlayer)
    GameWorld.DebugAnswer(curPlayer, "增加成员数:%s, 总成员:%s" % (addCnt, curFamily.GetCount()))
    GameWorld.DebugAnswer(crossPlayer, "增加成员数:%s, 总成员:%s" % (addCnt, curFamily.GetCount()))
    return
def __addFackRequestJoin(curPlayer, gmList):
def __addFackRequestJoin(crossPlayer, gmList):
    reqCnt = gmList[1] if len(gmList) > 1 else 1
    familyID = gmList[2] if len(gmList) > 2 else curPlayer.GetFamilyID()
    familyID = gmList[2] if len(gmList) > 2 else crossPlayer.GetFamilyID()
    
    familyMgr = DBDataMgr.GetFamilyMgr()
    family = familyMgr.FindFamily(familyID)
    if not family:
        GameWorld.DebugAnswer(curPlayer, "没有该公会: %s" % familyID)
        GameWorld.DebugAnswer(crossPlayer, "没有该公会: %s" % familyID)
        return
    
    reqCnt = min(reqCnt, 100)
@@ -149,10 +155,10 @@
            break
    # 广播给有招人权限的
    PlayerFamily.SendFamilyReqJoinInfo(familyID)
    GameWorld.DebugAnswer(curPlayer, "增加申请数:%s, 总申请:%s" % (addCnt, len(family.GetReqJoinPlayerInfo())))
    GameWorld.DebugAnswer(crossPlayer, "增加申请数:%s, 总申请:%s" % (addCnt, len(family.GetReqJoinPlayerInfo())))
    return
def __printFamilyList(curPlayer, gmList):
def __printFamilyList(crossPlayer, gmList):
    printCnt = gmList[1] if len(gmList) > 1 else 20
    fromIndex = gmList[2] if len(gmList) > 2 else 0
    
@@ -163,7 +169,7 @@
        zoneMgr = familyMgr.GetZoneFamilyMgr(zoneID)
        zoneMgr.Sort()
        familyCnt = zoneMgr.GetCount()
        GameWorld.DebugAnswer(curPlayer, "----- 【分区%s】公会总数: %s -----" % (zoneID, familyCnt))
        GameWorld.DebugAnswer(crossPlayer, "----- 【分区%s】公会总数: %s -----" % (zoneID, familyCnt))
        for index in range(fromIndex, fromIndex + printCnt):
            if index >= familyCnt:
                break
@@ -173,38 +179,38 @@
            text = "%s,ID:%s,LV:%s,战:%s,成:%s,审:%s,官:%s" % (rank, family.GetID(), family.GetLV(), family.GetFightPowerTotal(), family.GetCount(), family.GetJoinReview(), family.GetJoinLVMin())
            printAnswerCnt += 1
            if printAnswerCnt <= 100:
                GameWorld.DebugAnswer(curPlayer, text)
                GameWorld.DebugAnswer(crossPlayer, text)
            else:
                GameWorld.DebugLog(text)
            
    return
def __printFamilyInfo(curPlayer, gmList):
    familyID = gmList[1] if len(gmList) > 1 else curPlayer.GetFamilyID()
def __printFamilyInfo(crossPlayer, gmList):
    familyID = gmList[1] if len(gmList) > 1 else crossPlayer.GetFamilyID()
    
    familyMgr = DBDataMgr.GetFamilyMgr()
    family = familyMgr.FindFamily(familyID)
    if not family:
        GameWorld.DebugAnswer(curPlayer, "公会不存在: %s" % familyID)
        GameWorld.DebugAnswer(crossPlayer, "公会不存在: %s" % familyID)
        return
    
    zoneID = familyMgr.GetFamilyZoneID(familyID)
    GameWorld.DebugAnswer(curPlayer, "----- 【%s】 -----" % (GameWorld.CodeToGbk(family.GetName())))
    GameWorld.DebugAnswer(curPlayer, "公会ID:%s, ServerID:%s, 分区:%s" % (familyID, family.GetServerID(), zoneID))
    GameWorld.DebugAnswer(curPlayer, "LV:%s, Exp:%s" % (family.GetLV(), family.GetExp()))
    GameWorld.DebugAnswer(curPlayer, "审核:%s, 官职条件:%s, 申请数:%s" % (family.GetJoinReview(), family.GetJoinLVMin(), len(family.GetReqJoinPlayerInfo())))
    GameWorld.DebugAnswer(curPlayer, "战旗:%s, 旗号【%s】" % (family.GetEmblemID(), GameWorld.CodeToGbk(family.GetEmblemWord())))
    GameWorld.DebugAnswer(curPlayer, "总战力:%s, 人数:%s" % (family.GetFightPowerTotal(), family.GetCount()))
    GameWorld.DebugAnswer(curPlayer, "盟主ID:%s" % (family.GetLeaderID()))
    GameWorld.DebugAnswer(crossPlayer, "----- 【%s】 -----" % (GameWorld.CodeToGbk(family.GetName())))
    GameWorld.DebugAnswer(crossPlayer, "公会ID:%s, ServerID:%s, 分区:%s" % (familyID, family.GetServerID(), zoneID))
    GameWorld.DebugAnswer(crossPlayer, "LV:%s, Exp:%s" % (family.GetLV(), family.GetExp()))
    GameWorld.DebugAnswer(crossPlayer, "审核:%s, 官职条件:%s, 申请数:%s" % (family.GetJoinReview(), family.GetJoinLVMin(), len(family.GetReqJoinPlayerInfo())))
    GameWorld.DebugAnswer(crossPlayer, "战旗:%s, 旗号【%s】" % (family.GetEmblemID(), GameWorld.CodeToGbk(family.GetEmblemWord())))
    GameWorld.DebugAnswer(crossPlayer, "总战力:%s, 人数:%s" % (family.GetFightPowerTotal(), family.GetCount()))
    GameWorld.DebugAnswer(crossPlayer, "盟主ID:%s" % (family.GetLeaderID()))
    for index in range(family.GetCount()):
        member = family.GetAt(index)
        playerID = member.GetPlayerID()
        fightPower = member.GetFightPowerTotal()
        GameWorld.DebugAnswer(curPlayer, "%s,ID:%s,职位:%s,战力:%s" % (index, playerID, member.GetFmLV(), fightPower))
        GameWorld.DebugAnswer(crossPlayer, "%s,ID:%s,职位:%s,战力:%s" % (index, playerID, member.GetFmLV(), fightPower))
        
    return
def __delFackFamily(curPlayer):
def __delFackFamily(crossPlayer):
    
    delCnt = 0
    familyMgr = DBDataMgr.GetFamilyMgr()
@@ -215,10 +221,10 @@
        familyMgr.DelFamily(familyID)
        
    remainCnt = len(familyMgr.GetFamilyIDList())
    GameWorld.DebugAnswer(curPlayer, "删除假公会数: %s,剩余:%s" % (delCnt, remainCnt))
    GameWorld.DebugAnswer(crossPlayer, "删除假公会数: %s,剩余:%s" % (delCnt, remainCnt))
    return
def __createFackFamily(curPlayer, gmList):
def __createFackFamily(crossPlayer, gmList):
    ## 个数 [总战力 ServerID 等级 成员数]
    
    creatCount = gmList[0] if len(gmList) > 0 else 1 # 默认1个
@@ -307,5 +313,5 @@
        createOKCnt += 1
        familyFightPower += 10000
        
    GameWorld.DebugAnswer(curPlayer, "成功创建假公会: %s,总:%s" % (creatCount, len(familyMgr.GetFamilyIDList())))
    GameWorld.DebugAnswer(crossPlayer, "成功创建假公会: %s,总:%s" % (creatCount, len(familyMgr.GetFamilyIDList())))
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/Family.py
@@ -23,25 +23,33 @@
import PlayerFamily
import CrossPlayer
import DBDataMgr
import DBFamily
import time
def GetGMServerIDList(curPlayer):
    ## 获取命令额外发送到其他服务器,如跨服
    crossServerID = DBDataMgr.GetFamilyMgr().GetCurCrossServerID()
    GameWorld.DebugAnswer(curPlayer, "GetGMServerIDList: %s" % crossServerID)
    GameWorld.DebugAnswer(curPlayer, "本服公会互通跨服ID:%s" % crossServerID)
    if crossServerID:
        return [crossServerID]
    return []
def OnExecCross(crossPlayer, msgList):
def OnExecCross(crossPlayer, gmList):
    ## 跨服执行命令
    GameWorld.DebugLog("OnExecCross %s" % msgList, crossPlayer.GetPlayerID())
    playerID = crossPlayer.GetPlayerID()
    familyMgr = DBDataMgr.GetFamilyMgr()
    familyID = familyMgr.GetPlayerFamilyID(playerID)
    zoneID = familyMgr.GetFamilyZoneID(familyID)
    GameWorld.DebugAnswer(crossPlayer, "跨服公会ID:%s,zoneID=%s" % (familyID, zoneID))
    OnExec(crossPlayer, gmList)
    return
def OnExec(curPlayer, msgList):
    ## 游戏服执行命令
    
    if not msgList:
        if GameWorld.IsCrossServer():
            return
        GameWorld.DebugAnswer(curPlayer, "设置等级: Family lv 等级 经验")
        GameWorld.DebugAnswer(curPlayer, "设置徽章: Family e 徽章ID [剩余时间秒]")
        GameWorld.DebugAnswer(curPlayer, "设置贡献: Family c 今日贡献 累计贡献 [成员ID]")
@@ -56,9 +64,11 @@
    if not crossPlayer:
        return
    
    isMainServer = GameWorld.IsMainServer()
    value = msgList[0]
    if value == "l":
        if not isMainServer:
            return
        leaveCnt = msgList[1] if len(msgList) > 1 else 0
        kickedCnt = msgList[2] if len(msgList) > 2 else 0
        lastVoluntarily = msgList[3] if len(msgList) > 3 else 0
@@ -68,63 +78,67 @@
        GameWorld.DebugAnswer(curPlayer, "设置离开: Info=%s,%s" % (leaveInfo, GameWorld.ChangeTimeNumToStr(leaveTime)))
        return
    
    familyID = curPlayer.GetFamilyID()
    if isMainServer and DBFamily.IsFamilyCross():
        GameWorld.DebugAnswer(curPlayer, "公会已跨服由跨服执行命令")
        return
    familyID = crossPlayer.GetFamilyID()
    familyMgr = DBDataMgr.GetFamilyMgr()
    curFamily = familyMgr.FindFamily(familyID) if familyID else None
    if not curFamily:
        GameWorld.DebugAnswer(curPlayer, "玩家未加入仙盟!")
        GameWorld.DebugAnswer(crossPlayer, "玩家未加入仙盟!")
        return
    
    if value == "lv":
        lv = msgList[1] if len(msgList) > 1 else 1
        exp = msgList[2] if len(msgList) > 2 else 0
        if not IpyGameDataPY.GetIpyGameData("Family", lv):
            GameWorld.DebugAnswer(curPlayer, "仙盟等级不存在: %s" % (lv))
            GameWorld.DebugAnswer(crossPlayer, "仙盟等级不存在: %s" % (lv))
            return
        curFamily.SetLV(lv)
        curFamily.SetExp(exp)
        GameWorld.DebugAnswer(curPlayer, "设置仙盟等级:%s, exp=%s" % (lv, exp))
        GameWorld.DebugAnswer(crossPlayer, "设置仙盟等级:%s, exp=%s" % (lv, exp))
        
    elif value == "e":
        emblemID = msgList[1] if len(msgList) > 1 else 0
        setExpireTimes = msgList[2] if len(msgList) > 2 else None
        emblemActionObj = PlayerFamilyEmblem.AddFamilyEmblem(curFamily.GetID(), emblemID, setExpireTimes)
        if not emblemActionObj:
            GameWorld.DebugAnswer(curPlayer, "该徽章ID无法添加")
            GameWorld.DebugAnswer(crossPlayer, "该徽章ID无法添加")
            return
        endTime = PlayerFamilyEmblem.GetActionEmblemEndTime(emblemActionObj)
        GameWorld.DebugAnswer(curPlayer, "添加徽章(%s)到期:%s" % (emblemID, GameWorld.ChangeTimeNumToStr(endTime)))
        GameWorld.DebugAnswer(crossPlayer, "添加徽章(%s)到期:%s" % (emblemID, GameWorld.ChangeTimeNumToStr(endTime)))
        return
    
    elif value == "m":
        CreateFamily.OnExec(curPlayer, msgList)
        CreateFamily.OnExec(crossPlayer, msgList)
        return
    
    elif value == "n":
        PlayerFamily.SetRenameTime(curFamily, 0)
        GameWorld.DebugAnswer(curPlayer, "重置改名CD")
        GameWorld.DebugAnswer(crossPlayer, "重置改名CD")
        
    elif value == "c":
        contribDay = msgList[1] if len(msgList) > 1 else 0
        contribTotal = msgList[2] if len(msgList) > 2 else 0
        memID = msgList[3] if len(msgList) > 3 else curPlayer.GetPlayerID()
        memID = msgList[3] if len(msgList) > 3 else crossPlayer.GetPlayerID()
        member = curFamily.FindMember(memID)
        if not member:
            GameWorld.DebugAnswer(curPlayer, "不存在该成员ID:%s" % memID)
            GameWorld.DebugAnswer(crossPlayer, "不存在该成员ID:%s" % memID)
            return
        member.SetContribDay(contribDay)
        member.SetContribTotal(contribTotal)
        GameWorld.DebugAnswer(curPlayer, "设置贡献:%s/%s, ID:%s" % (contribDay, contribTotal, memID))
        GameWorld.DebugAnswer(crossPlayer, "设置贡献:%s/%s, ID:%s" % (contribDay, contribTotal, memID))
        
    elif value == "ml":
        memID = msgList[1] if len(msgList) > 1 else 0
        logoutMinutes = msgList[2] if len(msgList) > 2 else 0
        member = curFamily.FindMember(memID)
        if not member:
            GameWorld.DebugAnswer(curPlayer, "不存在该成员ID:%s" % memID)
            GameWorld.DebugAnswer(crossPlayer, "不存在该成员ID:%s" % memID)
            return
        member.SetOffTime(int(time.time()) - logoutMinutes * 60)
        GameWorld.DebugAnswer(curPlayer, "成员ID:%s,离线时间:%s" % (memID, GameWorld.ChangeTimeNumToStr(member.GetOffTime())))
        GameWorld.DebugAnswer(crossPlayer, "成员ID:%s,离线时间:%s" % (memID, GameWorld.ChangeTimeNumToStr(member.GetOffTime())))
        
    PlayerFamily.Sync_FamilyInfo(crossPlayer)
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py
@@ -1371,6 +1371,22 @@
    ## 是否跨服中心服务器
    return GetServerType() == ShareDefine.serverType_CrossCenter
def CheckCrossCenterUniquenessErr():
    ## 检查跨服中心唯一性
    # @return: 是否异常
    if not IsCrossCenter():
        return
    serverCnt = 0
    serverDict = ReadChConfig.GetServerConfigDict()
    for serverInfo in serverDict.values():
        serverType = serverInfo[ShareDefine.serverCfgIndex_ServerType]
        if serverType == ShareDefine.serverType_CrossCenter:
            serverCnt += 1
            if serverCnt > 1:
                SendGameErrorEx("CrossCenterUniquenessErr", "跨服中心只允许配置一台", isRaiseErr=True)
                return
    return
def IsMainServer():
    ## 是否游戏服
    return GetServerType() == ShareDefine.serverType_Main
@@ -1407,7 +1423,7 @@
    #    MainServerDict = {} # 所属主服ID {子服ID:主服ID, ...}
    #    groupName = GetServerGroupName()
    #    serverDict = ReadChConfig.GetServerConfigDict()
    #    for serverInfo in serverDict:
    #    for serverInfo in serverDict.values():
    #        groupName = serverInfo[ShareDefine.serverCfgIndex_GroupName]
    #        serverMapID = serverInfo[ShareDefine.serverCfgIndex_MapID]
    #        serverType = serverInfo[ShareDefine.serverCfgIndex_ServerType]
@@ -2445,15 +2461,32 @@
def DebugAnswer(curPlayer, text):
    '''转码后再发DebugAnswer'''
    '''转码后再发DebugAnswer
    @param curPlayer: 跨服服务器时支持直接传入 crossPlayer
    '''
    #===========================================================================
    # if not GetGameWorld().GetDebugLevel():
    #    return
    #===========================================================================
    DebugLog(text, curPlayer.GetPlayerID())
    playerID = curPlayer.GetPlayerID()
    if IsCrossServer():
        crossPlayer = curPlayer
        mainServerID = crossPlayer.GetMainServerID()
        if not mainServerID:
            return
        import CrossMsg
        CrossMsg.SendToClientServer(ShareDefine.C2S_GMDebugAnswer, {"text":text}, [mainServerID], playerID)
        return
    DebugLog(text, playerID)
    text = text.decode(ShareDefine.Def_Game_Character_Encoding).encode(GetCharacterEncoding())
    curPlayer.DebugAnswer(text)
    return
def C2S_GMDebugAnswer(dataMsg, playerID):
    text = dataMsg["text"]
    curPlayer = GetPlayerManager().FindPlayerByID(playerID)
    if curPlayer:
        DebugAnswer(curPlayer, text)
    return
def RaiseException(errorMsg, playerID=0):
@@ -2465,10 +2498,10 @@
        SendGameError("MapServerRaiseException", errorMsg)
    return
def SendGameErrorEx(errType, msgInfo="", playerID=0):
def SendGameErrorEx(errType, msgInfo="", playerID=0, isRaiseErr=False):
    ErrLog("SendGameErrorEx: %s -> %s" % (errType, msgInfo), playerID)
    SendGameError(errType, msgInfo)
    if GetGameWorld().GetDebugLevel():
    if isRaiseErr or GetGameWorld().GetDebugLevel():
        raise Exception("%s -> %s" % (errType, msgInfo))
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/CrossMgr.py
@@ -76,6 +76,16 @@
    def SetConnState(self, connState): self._connState = connState
    def GetHeartCurTime(self): return self._heartCurTime # 上次收到该服心跳时的本服时间戳
    def SetHeartCurTime(self, curTime): self._heartCurTime = curTime
    def IsServerOpen(self):
        ## 是否正常开放中
        # 验证连接状态
        if self._connState != ShareDefine.ssConn_Normal:
            return False
        # 验证维护状态
        return True
    
class SSServerMgr():
    ## 其他服务器管理器,所有服务器通用
@@ -103,14 +113,16 @@
    def DoHeartbeat(self, curTime):
        ## 心跳广播给其他服
        
        if not GameWorld.IsCrossServer():
            # 目前仅跨服服务器需要处理心跳广播 ,其他暂时不用
            return
        # 时间回调时也立刻同步心跳
        if self._heartTime and curTime >= self._heartTime and curTime - self._heartTime < HeartBreat:
            #GameWorld.DebugLog("不广播心跳! self._heartTime=%s,curTime=%s,diff=%s" % (self._heartTime, curTime, curTime - self._heartTime))
            return
        self._heartTime = curTime
        if not GameWorld.IsCrossServer():
            # 目前仅跨服服务器需要处理心跳,其他暂时不用
            return
        #GameWorld.DebugLog("广播心跳! self._heartTime=%s,%s" % (self._heartTime, GameWorld.ChangeTimeNumToStr(self._heartTime)))
        
        pack = ChServerToServerPyPack.tagSSHeart()
        pack.ServerID = GameWorld.GetGameWorld().GetServerID()
@@ -127,32 +139,42 @@
        curTime = int(time.time())
        
        ssServer = self.GetSSServer(serverID)
        ssServer.SetServerType(serverType)
        ssServer.SetHeartCurTime(curTime)
        
        befConnState = ssServer.GetConnState()
        
        ssServer.SetServerType(serverType)
        ssServer.SetConnState(ShareDefine.ssConn_Normal)
        ssServer.SetHeartCurTime(curTime)
        # 目标是跨服中心,更新跨服时间
        if serverType == ShareDefine.serverType_CrossCenter:
            if not self._crossCenterID:
                self._crossCenterID = serverID
            updCrossTime = serverTime
            curCrossTime = self.GetCrossTime()
            self.SetCrossTime(updCrossTime, curTime)
            diffSeconds = updCrossTime - curCrossTime # 误差秒
            #GameWorld.DebugLog("curCrossTime=%s" % GameWorld.ChangeTimeNumToStr(curCrossTime))
            #GameWorld.DebugLog("updCrossTime=%s" % GameWorld.ChangeTimeNumToStr(updCrossTime))
            #GameWorld.DebugLog("与跨服时间误差=%s" % diffSeconds)
            if abs(diffSeconds) >= 30:
                GameWorld.Log("本服的跨服时间与跨服实际时间误差过大同步前端! diffSeconds=%s" % diffSeconds)
                GameWorld.Log("curCrossTime=%s" % GameWorld.ChangeTimeNumToStr(curCrossTime))
                GameWorld.Log("updCrossTime=%s" % GameWorld.ChangeTimeNumToStr(updCrossTime))
                ChPlayer.Sync_PyServerDataTimeToClient()
        if befConnState == ShareDefine.ssConn_Normal:
            #GameWorld.Log("收到目标跨服服务器心跳,正常连接中: crossServerID=%s,crossServerTime=%s" % (serverID, GameWorld.ChangeTimeNumToStr(serverTime)))
            return
        
        ssServer.SetConnState(ShareDefine.ssConn_Normal)
        isReconn = True if befConnState == ShareDefine.ssConn_Disconnected else False
        
        # 跨服服务器
        if serverType == ShareDefine.serverType_CrossCenter:
            GameWorld.Log("连上跨服中心服务器: crossServerID=%s,isReconn=%s,crossServerTime=%s" % (serverID, isReconn, GameWorld.ChangeTimeNumToStr(serverTime)))
            if not self._crossCenterID:
                self._crossCenterID = serverID
            if serverID not in self._crossServerIDList:
                self._crossServerIDList.append(serverID)
            lastCrossTime = self.GetCrossTime()
            self.SetCrossTime(serverTime, curTime)
            # 时间回调或误差过大立即同步给前端
            if serverTime < lastCrossTime or (serverTime - lastCrossTime) >= 30:
                ChPlayer.Sync_PyServerDataTimeToClient()
        elif serverType == ShareDefine.serverType_Cross:
            GameWorld.Log("连上跨服服务器: crossServerID=%s,isReconn=%s" % (serverID, isReconn))
        if serverType in [ShareDefine.serverType_CrossCenter, ShareDefine.serverType_Cross]:
            if serverType == ShareDefine.serverType_CrossCenter:
                GameWorld.Log("连上跨服中心服务器: crossServerID=%s,isReconn=%s,crossServerTime=%s" % (serverID, isReconn, GameWorld.ChangeTimeNumToStr(serverTime)))
            elif serverType == ShareDefine.serverType_Cross:
                GameWorld.Log("连上常规跨服服务器: crossServerID=%s,isReconn=%s" % (serverID, isReconn))
            if serverID not in self._crossServerIDList:
                self._crossServerIDList.append(serverID)
                
@@ -167,6 +189,7 @@
        ## 获取跨服服务器时间 - 以跨服中心服务器为准,如果没有默认取本服时间
        curTime = int(time.time())
        if not self._crossTime:
            #GameWorld.DebugLog("没有跨服时间,直接返回本服时间")
            return curTime
        self._crossTime += max(0, curTime - self._crossTimeCurTime)
        self._crossTimeCurTime = curTime
@@ -178,7 +201,8 @@
        self._crossTimeCurTime = curTime if curTime else int(time.time())
        return serverTime
    
    def GetCrossServerIDList(self): return self._crossServerIDList
    def GetCrossCenterID(self): return self._crossCenterID # 跨服中心服务器ID
    def GetCrossServerIDList(self): return self._crossServerIDList # 所有运行中的跨服服务器ID,包含跨服中心
    
    def CheckSSServerDisconnected(self, curTime):
        ## 检查其他服是否断开连接
@@ -203,6 +227,7 @@
                # 本服时间回调了暂不处理
                continue
            if curTime - lastHeartTime <= DisconnectedTime:
                #GameWorld.Log("检查断开时为正常连接中: serverID=%s,serverType=%s,pass=%s" % (ssServer.GetServerID(), ssServer.GetServerType(), curTime - lastHeartTime))
                continue
            ssServer.SetConnState(ShareDefine.ssConn_Disconnected)
            
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/CrossMsg.py
@@ -22,6 +22,7 @@
import NetPackCommon
import ChServerToServerPyPack
from GM import GMShell
import PlayerViewCache
import PlayerFamily
import CrossPlayer
import TurnAttack
@@ -39,6 +40,8 @@
    #if not dataMsg:
    #    return
    logData = "" if msgType in ShareDefine.NoLogDataSSMsgTypes else dataMsg
    if msgType == ShareDefine.S2C_FamilyPyPack:
        logData = "%s%s" % (dataMsg["funcName"], logData)
    GameWorld.Log("SendToCrossServer => %s, %s, %s" % (msgType, serverIDList, logData), playerID)
    SendToServer(msgType, dataMsg, serverIDList, ShareDefine.dirType_Cross, playerID, isLog=False)
    return
@@ -53,6 +56,8 @@
    #if not dataMsg:
    #    return
    logData = "" if msgType in ShareDefine.NoLogDataSSMsgTypes else dataMsg
    if msgType == ShareDefine.C2S_SendFakePack:
        logData = "%s%s" % (dataMsg["packHead"], logData)
    GameWorld.Log("SendToClientServer => %s, %s, %s" % (msgType, serverIDList, logData), playerID)
    SendToServer(msgType, dataMsg, serverIDList, ShareDefine.dirType_Main, playerID, isLog=False) # 默认发给主服即可
    return
@@ -144,6 +149,10 @@
        dataMsg = cPickle.loads(recvMsg)
        
        logData = "" if msgType in ShareDefine.NoLogDataSSMsgTypes else str(dataMsg)
        if msgType == ShareDefine.C2S_SendFakePack:
            logData = "%s%s" % (dataMsg["packHead"], logData)
        elif msgType == ShareDefine.S2C_FamilyPyPack:
            logData = "%s%s" % (dataMsg["funcName"], logData)
        GameWorld.Log("OnSSRecvMsg => %s, fromServerID=%s, %s,time=%s" % (msgType, fromServerID, logData, time.time()), playerID)
        
        # 所有类型服务器均可能收到的信息
@@ -151,6 +160,10 @@
            TurnAttack.S2B_BattleRequest(dataMsg, fromServerID, msgType)      
        elif msgType == ShareDefine.B2S_BattleResult: # 战斗结果
            TurnAttack.B2S_BattleResult(dataMsg, fromServerID, msgType)
        elif msgType == ShareDefine.S2S_ViewTagFamily: # 查看目标公会
            PlayerFamily.S2S_ViewTagFamily(dataMsg, fromServerID, playerID)
        elif msgType == ShareDefine.S2S_ViewTagPlayer: # 查看目标玩家
            PlayerViewCache.S2S_ViewTagPlayer(dataMsg, fromServerID, playerID)
            
        else:
            curServerType = GameWorld.GetServerType()
@@ -184,7 +197,7 @@
                elif msgType == ShareDefine.C2S_FamilyPyPackRet:
                    PlayerFamily.C2S_FamilyPyPackRet(dataMsg, playerID)
                elif msgType == ShareDefine.C2S_NotifyCode:
                    CrossPlayer.C2S_NotifyCode(dataMsg, playerID)
                    CrossPlayer.C2S_NotifyCode(dataMsg)
                elif msgType == ShareDefine.C2S_SendFakePack:
                    CrossPlayer.C2S_SendFakePack(dataMsg)
                elif msgType == ShareDefine.C2S_CostPlayerResources:
@@ -195,6 +208,8 @@
                    CrossPlayer.C2S_SetPlayerNomalDict(dataMsg, playerID)
                elif msgType == ShareDefine.C2S_SendPlayerMail:
                    PlayerMail.C2S_SendPlayerMail(dataMsg, playerID)
                elif msgType == ShareDefine.C2S_GMDebugAnswer:
                    GameWorld.C2S_GMDebugAnswer(dataMsg, playerID)
                    
    except:
        GameWorld.RaiseException("服务器接收信息处理报错 \r\n%s" % str(traceback.format_exc()))
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/GameWorldEvent.py
@@ -92,6 +92,9 @@
    PlayerViewCache.LoadRobot()
    PyGameData.g_initGameTime = int(time.time()) # 放到加载数据之后
    
    # 检查跨服中心唯一性
    GameWorld.CheckCrossCenterUniquenessErr()
    if DBDataMgr.GetEventTrigMgr().GetValue(ShareDefine.Def_FamilyTransDataTime):
        DBDataMgr.GetEventTrigMgr().SetValue(ShareDefine.Def_FamilyTransDataTime, 0)
        GameWorld.Log("启动服务器时重置跨服公会传输数据状态!")
@@ -464,15 +467,18 @@
        serverEventValue = centerEventValue
        DBDataMgr.GetEventTrigMgr().SetValue(ShareDefine.Def_CrossCenterEvent, centerEventValue)
        
    if centerServerID:
        GameWorld.Log("处理跨服中心事件值! serverEventValue=%s,centerEventValue=%s,centerServerID=%s" % (serverEventValue, centerEventValue, centerServerID))
    if serverEventValue == centerEventValue:
        GameWorld.DebugLog("跨服中心事件值不变! serverEventValue=%s,centerEventValue=%s,centerServerID=%s" % (serverEventValue, centerEventValue, centerServerID))
        if centerServerID:
            GameWorld.Log("本服与跨服中心事件值相同不处理! serverEventValue=%s,centerEventValue=%s,centerServerID=%s" % (serverEventValue, centerEventValue, centerServerID))
        return
    
    serverEventTime = GameWorld.ChangeStrToDatetime("%s:%02d:%02d" % serverEventValue, ChConfig.TYPE_Time_Format_YmdHMS)
    centerEventTime = GameWorld.ChangeStrToDatetime("%s:%02d:%02d" % centerEventValue, ChConfig.TYPE_Time_Format_YmdHMS)
    if centerServerID:
        GameWorld.Log("本服与跨服中心事件值变化! serverEventValue=%s,centerEventValue=%s,centerServerID=%s" % (serverEventValue, centerEventValue, centerServerID))
    else:
        GameWorld.Log("跨服中心服务器事件值变化! serverEventValue=%s,centerEventValue=%s" % (serverEventValue, centerEventValue))
    serverEventTime = GameWorld.ChangeStrToDatetime("%s" % serverEventValue, ChConfig.TYPE_Time_Format_YmdH)
    centerEventTime = GameWorld.ChangeStrToDatetime("%s" % centerEventValue, ChConfig.TYPE_Time_Format_YmdH)
    
    serverHour = serverEventTime.hour
    serverDay = serverEventTime.day
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/NetPackCommon.py
@@ -377,7 +377,8 @@
def RecCrossServerNetPack(netPackBuffer):
    
    try:
        GameWorld.GetGameWorld().SetCurGameWorldIndex(0) # 需要设置,不然获取不到 GetMap 等虚拟分线相关接口
        #没有PY封包头
        if len(netPackBuffer) <= 1:
            return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
@@ -870,29 +870,34 @@
    return
def S2C_OnlineState(dataMsg, fromServerID, playerID):
    ## 收到游戏服玩家在线状态同步
    '''收到游戏服玩家在线状态同步
    跨服收到在线状态同步时都视为在跨服上线,需要处理跨服在线/上线的逻辑
    不然在跨服维护游戏服不维护的情况下,等跨服重开后,游戏服重新同步在线玩家,此时如果跨服不处理登录逻辑,会少同步封包
    如公会,跨服维护之后登录的玩家会取不到公会数据,等跨服重开后,需视为登录重新同步
    与跨服重连一样的道理,都是重新同步所有信息
    '''
    isOnline = dataMsg["isOnline"]
    isLoginout = dataMsg["isLoginout"]
    #isLoginout = dataMsg["isLoginout"] # 如果个别跨服功能有需要对真实上下线做特殊处理的可使用该参数判断
    baseInfo = dataMsg["baseInfo"]
    
    crossPlayer = UpdCrossPlayerFromMainServer(fromServerID, playerID, baseInfo, isOnline)
    
    # 其他跨服功能处理,暂时仅上下线时处理
    curServerID = GameWorld.GetGameWorld().GetServerID()
    if isLoginout:
        # 公会
        if "crossFamilyServerID" in dataMsg:
            crossFamilyServerID = dataMsg["crossFamilyServerID"]
            if curServerID == crossFamilyServerID:
                if isOnline:
                    PlayerFamily.OnCrossPlayerLogin(crossPlayer)
                else:
                    PlayerFamily.OnCrossPlayerLogout(crossPlayer)
        # 最后处理缓存,先放在更新中处理删除,有问题再放后面
        #if not isOnline:
        #    PlayerViewCache.OnCrossPlayerLogout(crossPlayer)
        #    CrossPlayer.GetCrossPlayerMgr().DeletePlayer(playerID)
    #if isLoginout:
    # 公会
    if "crossFamilyServerID" in dataMsg:
        crossFamilyServerID = dataMsg["crossFamilyServerID"]
        if curServerID == crossFamilyServerID:
            if isOnline:
                PlayerFamily.OnCrossPlayerLogin(crossPlayer)
            else:
                PlayerFamily.OnCrossPlayerLogout(crossPlayer)
    # 最后处理缓存,先放在更新中处理删除,有问题再放后面
    #if not isOnline:
    #    PlayerViewCache.OnCrossPlayerLogout(crossPlayer)
    #    CrossPlayer.GetCrossPlayerMgr().DeletePlayer(playerID)
            
    # 最后同步处理跨服登录成功
    #if isLoginout and isOnline:
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/CrossPlayer.py
@@ -26,6 +26,7 @@
import IPY_GameObj
import CrossMsg
import ChConfig
import CommFunc
class CrossPlayerObj():
    ## 跨服在线玩家实例,不入库,由游戏服玩家登录同步,当做以前GameServer的Player处理,跨服及游戏服本服通用,方便统一逻辑
@@ -54,7 +55,7 @@
        self.SetServerID(curCache.GetServerID())
        self.SetMainServerID(fromServerID)
        self.SetRealmLV(curCache.GetRealmLV())
        # familyID 由公会模块管理
        self.SetFamilyID(curCache.GetFamilyID())
        return
    
    def GetPlayer(self): return self.__curPlayer
@@ -177,9 +178,9 @@
    if not crossServerPlayerDict:
        return
    
    packBuff, packLen = clientPack.GetBuffer(), clientPack.GetLength()
    packBuff, packLen, packHead = clientPack.GetBuffer(), clientPack.GetLength(), CommFunc.GetPackHead(clientPack)
    for mainServerID, playerIDList in crossServerPlayerDict.items():
        dataMsg = {"playerIDList":playerIDList, "packBuff":packBuff, "packLen":packLen}
        dataMsg = {"playerIDList":playerIDList, "packBuff":packBuff, "packLen":packLen, "packHead":packHead}
        playerID = playerIDList[0]
        CrossMsg.SendToClientServer(ShareDefine.C2S_SendFakePack, dataMsg, [mainServerID], playerID)
        
@@ -202,8 +203,17 @@
    
    playerID = crossPlayer.GetPlayerID()
    packBuff, packLen = clientPack.GetBuffer(), clientPack.GetLength()
    dataMsg = {"playerIDList":[playerID], "packBuff":packBuff, "packLen":packLen}
    dataMsg = {"playerIDList":[playerID], "packBuff":packBuff, "packLen":packLen, "packHead":CommFunc.GetPackHead(clientPack)}
    CrossMsg.SendToClientServer(ShareDefine.C2S_SendFakePack, dataMsg, [mainServerID], playerID)
    return
def SendFakePackByID(playerID, clientPack, fromServerID=0):
    if not clientPack:
        return
    packBuff, packLen = clientPack.GetBuffer(), clientPack.GetLength()
    dataMsg = {"playerIDList":[playerID], "packBuff":packBuff, "packLen":packLen, "packHead":CommFunc.GetPackHead(clientPack)}
    CrossMsg.SendToClientServer(ShareDefine.C2S_SendFakePack, dataMsg, [fromServerID], playerID)
    CrossMsg.SendToServer(ShareDefine.C2S_SendFakePack, dataMsg, [fromServerID], ShareDefine.dirType_All, playerID)
    return
def C2S_SendFakePack(dataMsg):
@@ -232,16 +242,58 @@
        #本游戏服又没有玩家的不处理
        return
    playerID = crossPlayer.GetPlayerID()
    dataMsg = {"msgMark":msgMark, "msgParamList":msgParamList}
    dataMsg = {"playerIDList":[playerID], "msgMark":msgMark, "msgParamList":msgParamList}
    CrossMsg.SendToClientServer(ShareDefine.C2S_NotifyCode, dataMsg, [mainServerID], playerID)
    return
def C2S_NotifyCode(dataMsg, playerID):
def FamilyNotify(familyID, msgMark, msgParamList=[], excludeIDList=[]):
    family = DBDataMgr.GetFamilyMgr().FindFamily(familyID)
    if not family:
        return
    curServerID = GameWorld.GetGameWorld().GetServerID()
    crossServerPlayerDict = {}
    crossPlayerMgr = GetCrossPlayerMgr()
    for index in range(family.GetCount()):
        member = family.GetAt(index)
        playerID = member.GetPlayerID()
        if excludeIDList and playerID in excludeIDList:
            continue
        crossPlayer = crossPlayerMgr.FindCrossPlayer(playerID)
        if not crossPlayer:
            # 不在线
            continue
        curPlayer = crossPlayer.GetPlayer()
        if curPlayer: # 有玩家,一般只有游戏服有,可视为游戏服在线,直接发送
            PlayerControl.NotifyCode(curPlayer, msgMark, msgParamList)
            continue
        mainServerID = crossPlayer.GetMainServerID()
        if mainServerID == curServerID:
            #本游戏服又没有玩家的不处理
            continue
        if mainServerID not in crossServerPlayerDict:
            crossServerPlayerDict[mainServerID] = []
        playerIDList = crossServerPlayerDict[mainServerID]
        if playerID not in playerIDList:
            playerIDList.append(playerID)
    for mainServerID, playerIDList in crossServerPlayerDict.items():
        dataMsg = {"playerIDList":playerIDList, "msgMark":msgMark, "msgParamList":msgParamList}
        CrossMsg.SendToClientServer(ShareDefine.C2S_NotifyCode, dataMsg, [mainServerID])
    return
def C2S_NotifyCode(dataMsg):
    msgMark = dataMsg["msgMark"]
    msgParamList = dataMsg["msgParamList"]
    curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
    if curPlayer:
    playerIDList = dataMsg["playerIDList"]
    playerManager = GameWorld.GetPlayerManager()
    for playerID in playerIDList:
        curPlayer = playerManager.FindPlayerByID(playerID)
        if curPlayer == None:
            continue
        PlayerControl.NotifyCode(curPlayer, msgMark, msgParamList)
    return
def OnPlayerLogin(curPlayer):
@@ -414,8 +466,8 @@
    if resetType != "":
        centerEventValue = eventData.get("centerEventValue", 0)
        playerEventValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_OnCrossEvent)
        centerEventTime = GameWorld.ChangeStrToDatetime("%s:%02d:%02d" % centerEventValue, ChConfig.TYPE_Time_Format_YmdHMS)
        playerEventTime = GameWorld.ChangeStrToDatetime("%s:%02d:%02d" % playerEventValue, ChConfig.TYPE_Time_Format_YmdHMS)
        centerEventTime = GameWorld.ChangeStrToDatetime("%s" % centerEventValue, ChConfig.TYPE_Time_Format_YmdH)
        playerEventTime = GameWorld.ChangeStrToDatetime("%s" % playerEventValue, ChConfig.TYPE_Time_Format_YmdH)
        
        center_Day = centerEventTime.day
        center_Month = centerEventTime.month
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
@@ -4321,7 +4321,8 @@
    #if value < beforeFightPower:
    #    DataRecordPack.DR_FightPowerChangeInfo(curPlayer, beforeFightPower)
    GameWorld.DebugLog("总战力: %s, beforeFightPower=%s" % (value, beforeFightPower), curPlayer.GetPlayerID())
    ChPlayer.OnPlayerBaseInfoChange(curPlayer, IPY_PlayerDefine.CDBPlayerRefresh_FightPower) # 战力
    if beforeFightPower != value:
        ChPlayer.OnPlayerBaseInfoChange(curPlayer, IPY_PlayerDefine.CDBPlayerRefresh_FightPower) # 战力
    return
## 设置模块战斗力,支持超过20E = 模块公式战力 + 技能附加战力 + 其他附加战力
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
@@ -244,8 +244,8 @@
    if playerEventValue == centerEventValue:
        return
    
    centerEventTime = GameWorld.ChangeStrToDatetime("%s:%02d:%02d" % centerEventValue, ChConfig.TYPE_Time_Format_YmdHMS)
    playerEventTime = GameWorld.ChangeStrToDatetime("%s:%02d:%02d" % playerEventValue, ChConfig.TYPE_Time_Format_YmdHMS)
    centerEventTime = GameWorld.ChangeStrToDatetime("%s" % centerEventValue, ChConfig.TYPE_Time_Format_YmdH)
    playerEventTime = GameWorld.ChangeStrToDatetime("%s" % playerEventValue, ChConfig.TYPE_Time_Format_YmdH)
    
    center_Day = centerEventTime.day
    center_Month = centerEventTime.month
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFamily.py
@@ -35,6 +35,7 @@
import DBDataMgr
import DBFamily
import CrossMsg
import CrossMgr
import random
import time
@@ -77,7 +78,7 @@
def FamilyOnHour():
    if not GameWorld.IsMainServer() or DBFamily.IsFamilyCross():
        # 非游戏服或本服已跨服互通了不处理
        GameWorld.DebugLog("非游戏服或本服已跨服互通了不处理 FamilyOnHour")
        return
    __doFamilyOnHour()
    return
@@ -101,7 +102,7 @@
    ## 本服时间自己触发的onday逻辑
    
    if not GameWorld.IsMainServer() or DBFamily.IsFamilyCross():
        # 非游戏服或本服已跨服互通了不处理
        GameWorld.DebugLog("非游戏服或本服已跨服互通了不处理 FamilyOnDay")
        return
    
    __doFamilyOnDay()
@@ -125,7 +126,7 @@
                member.SetContribDay(0)
                member.SetDonateCntDay(0)
                
            Broadcast_FamilyInfo(familyID)
            Broadcast_FamilyInfo(familyID) # onday
    return
def PlayerCrossCenterOnDay(curPlayer):
@@ -153,7 +154,7 @@
def OnPlayerLogin(curPlayer, tick):
    Do_MapServer_PlayerLogin(curPlayer)
    if DBFamily.IsFamilyCross():
        #公会已跨服不处理,由所属跨服服务器处理成员登录逻辑
        GameWorld.DebugLog("公会已跨服不处理,由所属跨服服务器处理成员登录逻辑 OnPlayerLogin", curPlayer.GetPlayerID())
        return
    crossPlayer = CrossPlayer.GetCrossPlayerMgr().FindCrossPlayer(curPlayer.GetPlayerID())
    OnCrossPlayerLogin(crossPlayer)
@@ -168,7 +169,7 @@
def OnPlayerLogout(curPlayer):
    if DBFamily.IsFamilyCross():
        #公会已跨服不处理,由所属跨服服务器处理成员登录逻辑
        GameWorld.DebugLog("公会已跨服不处理,由所属跨服服务器处理成员离线逻辑 OnPlayerLogout", curPlayer.GetPlayerID())
        return
    crossPlayer = CrossPlayer.GetCrossPlayerMgr().FindCrossPlayer(curPlayer.GetPlayerID())
    OnCrossPlayerLogout(crossPlayer)
@@ -190,7 +191,7 @@
    curMember.SetOffTime(int(time.time()))
    
    # 通知成员下线
    Broadcast_FamilyInfo(familyID, changeMemIDList=[playerID])
    Broadcast_FamilyInfo(familyID, changeMemIDList=[playerID]) # 成员下线
    return
def SendToFamilyMapPlayer(crossPlayer, doType, doData):
@@ -225,6 +226,8 @@
            familyID = 0
                    
    crossPlayer.SetFamilyID(familyID)
    # 同步更新查看缓存
    PlayerViewCache.UpdPlayerViewFamilyInfo(playerID, familyID, FamilyName, EmblemID, EmblemWord)
    
    doData = {"FamilyID":familyID}
    if familyID:
@@ -242,7 +245,7 @@
    refreshFamilyID = familyMgr.GetPlayerFamilyID(playerID)
    GameWorld.DebugLog("PlayerLoginRefreshFamily playerID=%s,refreshFamilyID=%s" % (playerID, refreshFamilyID))
    crossPlayer.SetFamilyID(refreshFamilyID)
    MapServer_FamilyRefresh(crossPlayer, refreshFamilyID)
    MapServer_FamilyRefresh(crossPlayer, refreshFamilyID) # 登录
    familyID = refreshFamilyID
    if not familyID:
        return
@@ -258,7 +261,7 @@
    
    Sync_FamilyInfo(crossPlayer) # 给自己同步完整的
    # 广播成员在线
    Broadcast_FamilyInfo(familyID, changeMemIDList=[playerID], excludeIDList=[playerID])
    Broadcast_FamilyInfo(familyID, changeMemIDList=[playerID], excludeIDList=[playerID]) # 成员登录
    
    #通知招人
    if GetFamilyMemberHasPow(curMember, FamilyPowerID_Call):
@@ -312,13 +315,18 @@
            __doFamilyPyPackRet(curPlayer, clientData, funcName, isOK)
        return
    
    ssServer = CrossMgr.GetSSServerMgr().GetSSServer(crossServerID)
    if not ssServer or not ssServer.IsServerOpen():
        PlayerControl.NotifyCode(curPlayer, "ServerNoOpen")
        return
    # 转发请求CD验证
    if reqCD:
        reqTick = curPlayer.GetDictByKey("FamilyPyPackForwardingTick")
        reqTick = curPlayer.GetDictByKey(funcName) # 根据函数名单独处理CD,防止相互影响
        if reqTick and (tick - reqTick) < reqCD * 1000:
            PlayerControl.NotifyCode(curPlayer, "RequestLater")
            return
        curPlayer.SetDict("FamilyPyPackForwardingTick", tick)
        curPlayer.SetDict(funcName, tick)
        
    # 剩下的就是大于0
    dataMsg = {"funcName":funcName}
@@ -352,10 +360,11 @@
    curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
    if not curPlayer:
        return
    curPlayer.SetDict("FamilyPyPackForwardingTick", 0)
    funcName = dataMsg["funcName"]
    packBuff = dataMsg.get("packBuff")
    curPlayer.SetDict(funcName, 0) # 重置CD
    clientData = None
    if packBuff:
        clientData = NetPackCommon.ReadRecPyPackData(packBuff)
@@ -470,11 +479,13 @@
        GameWorld.ErrLog("创建家族失败", playerID)
        return
    newFamilyID = curFamily.GetID()
    zoneMgr = familyMgr.GetZoneFamilyMgrByFamilyID(newFamilyID)
    zoneID = zoneMgr.GetZoneID() if zoneMgr else -1
    curFamily.SetLV(1)
    emblemIDList = PlayerFamilyEmblem.GetDefaultFamilyEmblemIDList()
    if not emblemID or emblemID not in emblemIDList:
        emblemID = random.choice(emblemIDList) # 从默认徽章中随机选择一个
    GameWorld.Log("创建公会: familyID=%s,playerID=%s,emblemID=%s,serverID=%s" % (newFamilyID, playerID, emblemID, serverID))
    GameWorld.Log("创建公会: familyID=%s,playerID=%s,emblemID=%s,serverID=%s,zoneID=%s" % (newFamilyID, playerID, emblemID, serverID, zoneID))
    curFamily.SetEmblemID(emblemID)
    curFamily.SetEmblemWord(emblemWord)
    
@@ -486,9 +497,9 @@
        
    #-设置家族成员属性
    DoPlayerJionFamily(curFamily, playerID, crossPlayer, IPY_PlayerDefine.fmlLeader)
    zoneMgr = familyMgr.GetZoneFamilyMgrByFamilyID(newFamilyID)
    zoneMgr and zoneMgr.Sort()
    if zoneMgr:
        zoneMgr.Sort()
    #XW_JZ_EstablishSud <n color="255,255,0">恭喜您,家族建立成功!</n>    25  -   -
    #CrossPlayer.NotifyCode(crossPlayer, "XW_JZ_EstablishSud")
    #PlayerControl.WorldNotify(0, "jiazu_liubo_671654", [curPlayer.GetName(), fullFamilyName, newFamilyID])
@@ -559,26 +570,25 @@
    member = curFamily.AddMember(playerID)
    member.SetFmLV(jionFamilySetLv)
    member.RefreshMemberByID(playerID)
    curFamily.SetFightPowerTotal(curFamily.GetFightPowerTotal() + member.GetFightPowerTotal())
    
    if jionFamilySetLv == IPY_PlayerDefine.fmlLeader:
        curFamily.SetLeaderID(playerID)
        
    if broadcastFamilyChange:
        # 广播其他在线成员
        Broadcast_FamilyInfo(familyID, changeMemIDList=[playerID], excludeIDList=[playerID])
        Broadcast_FamilyInfo(familyID, changeMemIDList=[playerID], excludeIDList=[playerID]) # 成员加入
        
    familyMgr.DelPlayerReqJoinFamilyIDAll(playerID)
    #设置玩家身上保存的家族信息
    if crossPlayer:
        MapServer_FamilyRefresh(crossPlayer, familyID)
        MapServer_FamilyRefresh(crossPlayer, familyID) # 加入
        Sync_FamilyInfo(crossPlayer) # 给自己同步完整的
        Sync_RequestAddFamilyInfo(crossPlayer)
        PlayerFamilyTaofa.OnCrossPlayerEnterFamily(crossPlayer)
        
    #if jionFamilySetLv != IPY_PlayerDefine.fmlLeader:
    if jionFamilySetLv != IPY_PlayerDefine.fmlLeader:
        #通知所有家族成员, 这个人加入了家族
        #NotifyAllFamilyMemberMsg(familyID, "XW_JZ_EnterFamily", [member.GetPlayerName()], excludeIDList=[playerID])
        CrossPlayer.FamilyNotify(familyID, "XW_JZ_EnterFamily", [member.GetPlayerName()], excludeIDList=[playerID])
        #if jionPlayer:
        #    PlayerControl.NotifyCode(jionPlayer, 'XW_JZ_EnterFamilyInfo', [family.GetName()])
            
@@ -1086,7 +1096,7 @@
    #    return
    SendFamilyReqJoinInfo(familyID)
    if joinOKPlayerIDList:
        Broadcast_FamilyInfo(familyID, changeMemIDList=joinOKPlayerIDList, excludeIDList=joinOKPlayerIDList)
        Broadcast_FamilyInfo(familyID, changeMemIDList=joinOKPlayerIDList, excludeIDList=joinOKPlayerIDList) # 审核
    return
#// A6 22 修改收人方式 #tagCMChangeFamilyJoin
@@ -1124,7 +1134,7 @@
    GameWorld.DebugLog("修改招人设置: familyID=%s,joinReview=%s,joinLVMin=%s" % (familyID, joinReview, joinLVMin), playerID)
    family.SetJoinReview(joinReview)
    family.SetJoinLVMin(joinLVMin)
    Broadcast_FamilyInfo(familyID, isSyncMem=False)
    Broadcast_FamilyInfo(familyID, isSyncMem=False) # 修改招人
    return
#// A6 23 修改家族公告 #tagCMChangeFamilyBroadcast
@@ -1158,7 +1168,7 @@
        return
    family.SetBroadcast(broadcast)
    GameWorld.DebugLog('更改公会公告: Family=%s,公告=%s' % (GameWorld.CodeToGbk(family.GetName()), GameWorld.CodeToGbk(broadcast)), playerID)
    Broadcast_FamilyInfo(familyID, isSyncMem=False)
    Broadcast_FamilyInfo(familyID, isSyncMem=False) # 修改公告
    return
#// A6 24 修改家族徽章 #tagCMChangeFamilyEmblem
@@ -1265,7 +1275,7 @@
        
    if isGMOP:
        family.SetBroadcast("")
    Broadcast_FamilyInfo(familyID, changeMemIDList=changeMemIDList)
    Broadcast_FamilyInfo(familyID, changeMemIDList=changeMemIDList) # 修改职位
    return True
def ChangeFamilyLeader(family, newLeaderMem):
@@ -1298,7 +1308,7 @@
    
    tagCrossPlayer = CrossPlayer.GetCrossPlayerMgr().FindCrossPlayer(tagID)
    if tagCrossPlayer:
        MapServer_FamilyRefresh(tagCrossPlayer, familyID)
        MapServer_FamilyRefresh(tagCrossPlayer, familyID) # 修改职位
        if GetFamilyMemberHasPow(tagMember, FamilyPowerID_Call):
            CrossPlayer.SendFakePack(tagCrossPlayer, GetPack_FamilyReqJoinInfo(familyID))
        
@@ -1308,8 +1318,7 @@
                        [ShareDefine.Def_FamilyActionEvent_MemberChange, ShareDefine.Def_FamilyMemberChange_FMLV, changeFamilyLV, befFamilyLV], tick)
    
    #xx被任命为xx
    #NotifyAllFamilyMemberMsg(familyID, "XW_JZ_AppointFamily", [memName, changeFamilyLV])
    #GetFamilyMgr().SetSyncCrossFamilyUpd(familyMember.GetFamilyID(), familyMember.GetPlayerID(), syncNow=True) # 成员职位变更
    CrossPlayer.FamilyNotify(familyID, "XW_JZ_AppointFamily", [memName, changeFamilyLV])
    return
def __AutoChangeLeader(curFamily):
@@ -1376,7 +1385,7 @@
    GameWorld.Log("公会自动传位: familyID=%s,leaderID=%s,offTime=%s,passHours=%s,newLeaderID=%s" 
                  % (familyID, leaderID, GameWorld.ChangeTimeNumToStr(offTime), passHours, newLeaderID))
    ChangeFamilyLeader(curFamily, toMember)
    Broadcast_FamilyInfo(familyID, changeMemIDList=[leaderID, newLeaderID])
    Broadcast_FamilyInfo(familyID, changeMemIDList=[leaderID, newLeaderID]) # 自动传位
    
    # 邮件通知
    toServerID = toMember.GetServerID()
@@ -1437,12 +1446,11 @@
    AddFamilyActionNote(crossPlayer.GetPlayerName(), familyID, ShareDefine.Def_ActionType_FamilyEvent, 
                        [ShareDefine.Def_FamilyActionEvent_MemberChange, ShareDefine.Def_FamilyMemberChange_Leave], tick)
    
    #XW_JZ_LeaveFamily   <n color="0,190,255">{%S1%}</n><n color="255,255,0">退出了家族!</n>  25  -   -
    #NotifyAllFamilyMemberMsg(familyID, "XW_JZ_LeaveFamily", [curPlayer.GetName()])
    __DoPlayerLeaveFamilyByID(family, playerID, crossPlayer)
    MapServer_FamilyRefresh(crossPlayer, 0, 1)
    MapServer_FamilyRefresh(crossPlayer, 0, 1) # 主动退出
    CrossPlayer.SendFakePackByFamily(familyID, GetPack_FamilyDel(playerID, crossPlayer.GetPlayerName(), 1))
    CrossPlayer.FamilyNotify(familyID, "XW_JZ_LeaveFamily", [crossPlayer.GetPlayerName()])
    Broadcast_FamilyInfo(familyID, isSyncMem=False) # 退出
    
    if family.GetCount() == 0:
        #玩家离开后, 家族没有人了 , 删除这个家族
@@ -1508,15 +1516,17 @@
                        [ShareDefine.Def_FamilyActionEvent_MemberChange, ShareDefine.Def_FamilyMemberChange_KickOut], tick)
    
    #XW_JZ_LeaveFamily   <n color="0,190,255">{%S1%}</n><n color="255,255,0">退出了家族!</n>  25  -   -
    #NotifyAllFamilyMemberMsg(familyID, "XW_JZ_LeaveFamily", [tagPlayerName])
    CrossPlayer.FamilyNotify(familyID, "XW_JZ_LeaveFamily", [tagPlayerName])
    
    #删除玩家
    crossPlayer = CrossPlayer.GetCrossPlayerMgr().FindCrossPlayer(tagMemberID)
    __DoPlayerLeaveFamilyByID(family, tagPlayerID, crossPlayer)
    if crossPlayer:
        MapServer_FamilyRefresh(crossPlayer, 0)
    tagCrossPlayer = CrossPlayer.GetCrossPlayerMgr().FindCrossPlayer(tagMemberID)
    __DoPlayerLeaveFamilyByID(family, tagPlayerID, tagCrossPlayer)
    if tagCrossPlayer:
        MapServer_FamilyRefresh(tagCrossPlayer, 0) # 被踢
        CrossPlayer.NotifyCode(tagCrossPlayer, "XW_JZ_LeaveFamilyKick", [curMember.GetPlayerName()])
        
    CrossPlayer.SendFakePackByFamily(familyID, GetPack_FamilyDel(tagMemberID, tagPlayerName, 0))
    Broadcast_FamilyInfo(familyID, isSyncMem=False) # 踢人
    return
def __DoPlayerLeaveFamilyByID(curFamily, leavePlayerID, crossPlayer=None):
@@ -1593,11 +1603,66 @@
        memCrossPlayer = crossPlayerMgr.FindCrossPlayer(memID)
        if not memCrossPlayer:
            continue
        MapServer_FamilyRefresh(memCrossPlayer, familyID)
        MapServer_FamilyRefresh(memCrossPlayer, familyID) # 改名
        #player.Notify_FamilyNameRefresh() #//04 36    周围玩家家族名刷新#tagPlayerFamilyNameRefresh
        
    Broadcast_FamilyInfo(familyID, isSyncMem=False)
    Broadcast_FamilyInfo(familyID, isSyncMem=False) # 改名
    return True
#// A6 19 查看目标公会 #tagCSViewTagFamily
#
#struct tagCSViewTagFamily
#{
#    tagHead        Head;
#    DWORD        FamilyID;
#    DWORD        DataServerID;    //数据所在服务器ID
#};
def OnViewTagFamily(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    playerID = curPlayer.GetPlayerID()
    tagFamilyID = clientData.FamilyID
    dataServerID = clientData.DataServerID
    # 本服或主服是本服
    if not dataServerID or dataServerID == GameWorld.GetGameWorld().GetServerID():
        NetPackCommon.SendFakePack(curPlayer, GetTagFamilyInfoPack(tagFamilyID))
        return
    CrossMsg.SendToServer(ShareDefine.S2S_ViewTagFamily, {"tagFamilyID":tagFamilyID}, [dataServerID], ShareDefine.dirType_All, playerID)
    return
def S2S_ViewTagFamily(dataMsg, fromServerID, playerID):
    tagFamilyID = dataMsg["tagFamilyID"]
    CrossPlayer.SendFakePackByID(playerID, GetTagFamilyInfoPack(tagFamilyID), fromServerID)
    return
def GetTagFamilyInfoPack(tagFamilyID):
    familyMgr = DBDataMgr.GetFamilyMgr()
    family = familyMgr.FindFamily(tagFamilyID)
    if not family:
        GameWorld.ErrLog("本服数据找不到目标公会! tagFamilyID=%s" % tagFamilyID)
        return
    clientPack = ChPyNetSendPack.tagSCTagFamilyInfo()
    clientPack.FamilyID = family.GetID()
    clientPack.FamilyName = family.GetName()
    clientPack.FamilyNameLen = len(clientPack.FamilyName)
    clientPack.LeaderID = family.GetLeaderID()
    leaderMember = family.FindMember(clientPack.LeaderID)
    if leaderMember:
        clientPack.LeaderName = leaderMember.GetPlayerName()
        clientPack.LeaderNameLen = len(clientPack.LeaderName)
        clientPack.LeaderServerID = leaderMember.GetServerID()
    clientPack.FamilyLV = family.GetLV()
    clientPack.ServerID = family.GetServerID()
    clientPack.EmblemID = family.GetEmblemID()
    clientPack.EmblemWord = family.GetEmblemWord()
    clientPack.FightPower = family.GetFightPower()
    clientPack.FightPowerEx = family.GetFightPowerEx()
    clientPack.Broadcast = family.GetBroadcast()
    clientPack.BroadcastLen = len(clientPack.Broadcast)
    clientPack.MemberCount = family.GetCount()
    clientPack.DataServerID = GameWorld.GetGameWorld().GetServerID()
    return clientPack
#// A6 20 搜索家族列表 #tagCMViewFamilyPage
#
@@ -1687,6 +1752,7 @@
        clientPack.FamilyCount = len(clientPack.FamilyList)
        if clientPack.FamilyCount >= showCount:
            break
    clientPack.DataServerID = GameWorld.GetGameWorld().GetServerID()
    CrossPlayer.SendFakePack(crossPlayer, clientPack)
    return
@@ -1815,7 +1881,7 @@
    curFamily.SetLV(updLV)
    curFamily.SetExp(updExp)
    
    Broadcast_FamilyInfo(familyID, isSyncMem=False)
    Broadcast_FamilyInfo(familyID, isSyncMem=False) # 公会经验
    return True
def AddFamilyContrib(curPlayer, addContribValue):
@@ -1847,7 +1913,7 @@
    curMember.SetContribTotal(contribTotal)
    GameWorld.DebugLog("增加成员贡献: familyID=%s,addContribValue=%s,contribDay=%s,contribTotal=%s" % (familyID, addContribValue, contribDay, contribTotal), playerID)
    
    Broadcast_FamilyInfo(familyID, isSyncMem=False)
    Broadcast_FamilyInfo(familyID, isSyncMem=False) # 成员贡献
    return
## ------------------------------------------------------------------------------------------------
@@ -1970,6 +2036,7 @@
    return
def Do_MapServer_PlayerLogin(curPlayer):
    DBFamily.Sync_FamilyCrossInfo(curPlayer)
    SyncDonateCntInfo(curPlayer)
    PlayerFamilyZhenbaoge.OnPlayerLogin(curPlayer)
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFamilyEmblem.py
@@ -71,7 +71,7 @@
                    updEmblemID = random.choice(defaultEmblemIDList) if defaultEmblemIDList else 0
                    GameWorld.Log("仙盟佩戴徽章过期恢复随机默认徽章! familyID=%s,emblemID=%s,endTime=%s,updEmblemID=%s" % (familyID, emblemID, endTime, updEmblemID))
                    family.SetEmblemID(updEmblemID)
                    PlayerFamily.Broadcast_FamilyInfo(familyID, isSyncMem=False)
                    PlayerFamily.Broadcast_FamilyInfo(familyID, isSyncMem=False) # 徽章过期
    return
def GetFamilyEmblemActionData(familyID, emblemID):
@@ -182,5 +182,5 @@
    curFamily.SetEmblemID(emblemID)
    if emblemWord:
        curFamily.SetEmblemWord(emblemWord)
    PlayerFamily.Broadcast_FamilyInfo(familyID, isSyncMem=False)
    PlayerFamily.Broadcast_FamilyInfo(familyID, isSyncMem=False) # 徽章修改
    return True
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerViewCache.py
@@ -32,6 +32,7 @@
import ShareDefine
import TurnAttack
import DBDataMgr
import CrossMsg
import random
import time
@@ -267,9 +268,8 @@
    #curCache.SetFamilyEmblemWord(familyBase.GetEmblemWord())
    curCache.SetFightPowerTotal(PlayerControl.GetFightPower(curPlayer))
    curCache.SetServerID(GameWorld.GetPlayerServerID(curPlayer))
    if isOffline:
        curCache.SetOffTime(int(time.time()))
    curCache.SetOffTime(int(time.time()) if isOffline else 0)
    # 装备
    equipDict = {}
    equipPack = curPlayer.GetItemManager().GetPack(IPY_GameWorld.rptEquip)
@@ -369,7 +369,7 @@
    return curCache
def UpdPlayerViewFamilyInfo(playerID, familyID, familyName, emblemID, emblemWord):
    ## 玩家公会刷新时更新,兼容本服或跨服回传回来更新
    ## 玩家公会刷新时更新,兼容本服或跨服回传回来更新,跨服自己也更新,本服也更新
    curCache = DBDataMgr.GetPlayerViewCacheMgr().GetPlayerViewCache(playerID)
    if not curCache:
        return
@@ -393,6 +393,7 @@
                    "Face":curPlayer.GetFace(),
                    "FacePic":curPlayer.GetFacePic(),
                    "TitleID":PlayerControl.GetTitleID(curPlayer),
                    "FamilyID":curPlayer.GetFamilyID(),
                    "ServerID":GameWorld.GetPlayerServerID(curPlayer),
                    "FightPower":PlayerControl.GetFightPower(curPlayer),
                    }
@@ -407,6 +408,7 @@
                        "Face":viewCache.GetFace(),
                        "FacePic":viewCache.GetFacePic(),
                        "TitleID":viewCache.GetTitleID(),
                        "FamilyID":viewCache.GetFamilyID(),
                        "ServerID":viewCache.GetServerID(),
                        "FightPower":viewCache.GetFightPowerTotal(),
                        }
@@ -425,10 +427,10 @@
    curCache.SetFace(baseInfo.get("Face", curCache.GetFace()))
    curCache.SetFacePic(baseInfo.get("FacePic", curCache.GetFacePic()))
    curCache.SetTitleID(baseInfo.get("TitleID", curCache.GetTitleID()))
    curCache.SetFamilyID(baseInfo.get("FamilyID", curCache.GetFamilyID()))
    curCache.SetServerID(baseInfo.get("ServerID", curCache.GetServerID()))
    curCache.SetFightPowerTotal(baseInfo.get("FightPower", curCache.GetFightPowerTotal()))
    if isOffline:
        curCache.SetOffTime(int(time.time()))
    curCache.SetOffTime(int(time.time()) if isOffline else 0)
    return curCache
def GetRobotByViewCache(curCache):
@@ -520,30 +522,34 @@
#{
#    tagHead        Head;
#    DWORD        PlayerID;
#    BYTE        EquipClassLV;    //大于0为查看指定境界阶装备信息,  0为查看默认信息
#    DWORD        ServerID;        //玩家服务器ID,发0默认本服玩家
#};
def OnCMViewPlayerInfo(index, clientPack, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    playerID = curPlayer.GetPlayerID()
    
    findPlayerID = clientPack.PlayerID
    #equipClassLV = clientPack.EquipClassLV
    tagPlayerID = clientPack.PlayerID
    tagServerID = clientPack.ServerID
    
    clientPack = GetPack_ViewCache(findPlayerID)
    if clientPack:
        NetPackCommon.SendFakePack(curPlayer, clientPack)
        return
    if GameWorld.GetDBPlayerAccIDByID(findPlayerID):
        PlayerControl.NotifyCode(curPlayer, "ViewPlayer_OffLine")
    # 本服或主服是本服
    if not tagServerID or tagServerID == GameWorld.GetGameWorld().GetServerID():
        NetPackCommon.SendFakePack(curPlayer, GetPack_ViewCache(tagPlayerID))
        return
    
    # 跨服玩家发送跨服查询,待扩展...
    # 直接去目标服务器查询
    CrossMsg.SendToServer(ShareDefine.S2S_ViewTagPlayer, {"tagPlayerID":tagPlayerID}, [tagServerID], ShareDefine.dirType_All, playerID)
    return
def S2S_ViewTagPlayer(dataMsg, fromServerID, playerID):
    tagPlayerID = dataMsg["tagPlayerID"]
    CrossPlayer.SendFakePackByID(playerID, GetPack_ViewCache(tagPlayerID), fromServerID)
    return
def GetPack_ViewCache(playerID):
    ## 获取同步封包 - 玩家查看缓存
    curCache = FindViewCache(playerID)
    if not curCache:
        GameWorld.ErrLog("查看玩家找不到目标! playerID=%s" % playerID)
        return
    clientPack = ChPyNetSendPack.tagSCQueryPlayerCacheResult()
    clientPack.PlayerID = curCache.GetPlayerID()
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
@@ -1045,6 +1045,7 @@
C2S_FamilyDataRet = "C2S_FamilyDataRet"                 # 公会首次跨服互通时同步数据结果回复
C2S_FamilyMapPlayer = "C2S_FamilyMapPlayer"             # 给公会玩家处理地图服务器逻辑
C2S_FamilyPyPackRet = "C2S_FamilyPyPackRet"             # 公会功能玩家请求包处理结束回包,一般用于重置请求cd等
C2S_GMDebugAnswer = "C2S_GMDebugAnswer"                 # 发给玩家的DebugAnswer
C2S_NotifyCode = "C2S_NotifyCode"                       # 给玩家发送信息提示
C2S_CostPlayerResources = "C2S_CostPlayerResources"     # 扣除玩家资源,货币、物品等
C2S_GivePlayerResources = "C2S_GivePlayerResources"     # 奖励玩家资源,货币、物品等
@@ -1058,12 +1059,16 @@
S2C_FamilyPyPack = "S2C_FamilyPyPack"                   # 公会功能玩家请求包
S2C_GMCMD = "S2C_GMCMD"                                 # GM命令
# 其他
# 游戏服  -> 任意服务器
S2S_ViewTagFamily = "S2S_ViewTagFamily"                 # 查看目标公会
S2S_ViewTagPlayer = "S2S_ViewTagPlayer"                 # 查看目标玩家
# 任意服务器 -> 战斗服务器
S2B_BattleRequest = "S2B_BattleRequest"                 # 战斗请求
B2S_BattleResult = "B2S_BattleResult"                   # 战斗结果
# Debug日志不输出通讯数据明细的类型,debug模式下看,一些纯数据类的可不输出通讯数据明细
NoLogDataSSMsgTypes = [S2B_BattleRequest, B2S_BattleResult, S2C_FamilyData, C2S_SendFakePack]
NoLogDataSSMsgTypes = [S2B_BattleRequest, B2S_BattleResult, S2C_FamilyData, C2S_SendFakePack, S2C_FamilyPyPack]
# 跨服服务器发送子服信息定义
CrossServerMsg_CrossServerState = "CrossServerState"    # 跨服服务器状态变更