hxp
2021-10-21 46fbb9a99444693cdbcd0df7f6de0d0511235d56
9265 【BT5】【后端】53、新增幸运云购

# Conflicts:
# ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py
# ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
# ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
# ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
# ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
19个文件已修改
6个文件已添加
2857 ■■■■■ 已修改文件
ServerPython/CoreServerGroup/GameServer/PyNetPack.ini 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py 154 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py 486 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/CrossServerTime.py 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/LuckyCloudBuy.py 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/GameWorld.py 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossLuckyCloudBuy.py 977 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/PyGameData.py 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/ReadChConfig.py 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py 154 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py 486 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/LuckyCloudBuy.py 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerLuckyCloudBuy.py 199 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_LuckyCloudBuy.py 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/PyNetPack.ini
@@ -401,6 +401,21 @@
PacketSubCMD_1=0x04
PacketCallFunc_1=OnViewCrossBillboard
[CrossLuckyCloudBuy]
ScriptName = GameWorldLogic\CrossLuckyCloudBuy.py
Writer = hxp
Releaser = hxp
RegType = 0
RegisterPackCount = 2
PacketCMD_1=0xC0
PacketSubCMD_1=0x05
PacketCallFunc_1=OnQueryLuckyCloudBuyNumRec
PacketCMD_2=0xC0
PacketSubCMD_2=0x06
PacketCallFunc_2=OnQueryLuckyCloudBuyLotteryRec
[PlayerXMZZ]
ScriptName = Player\PlayerXMZZ.py
Writer = xdh
ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
@@ -4035,6 +4035,106 @@
#------------------------------------------------------
# C0 06 查询幸运云购开奖记录 #tagCGQueryLuckyCloudBuyLotteryRec
class  tagCGQueryLuckyCloudBuyLotteryRec(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("ZoneID", c_ubyte),    #查询分区ID,分区同跨服PK分区
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xC0
        self.SubCmd = 0x06
        return
    def ReadData(self, stringData, _pos=0, _len=0):
        self.Clear()
        memmove(addressof(self), stringData[_pos:], self.GetLength())
        return _pos + self.GetLength()
    def Clear(self):
        self.Cmd = 0xC0
        self.SubCmd = 0x06
        self.ZoneID = 0
        return
    def GetLength(self):
        return sizeof(tagCGQueryLuckyCloudBuyLotteryRec)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// C0 06 查询幸运云购开奖记录 //tagCGQueryLuckyCloudBuyLotteryRec:
                                Cmd:%s,
                                SubCmd:%s,
                                ZoneID:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.ZoneID
                                )
        return DumpString
m_NAtagCGQueryLuckyCloudBuyLotteryRec=tagCGQueryLuckyCloudBuyLotteryRec()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCGQueryLuckyCloudBuyLotteryRec.Cmd,m_NAtagCGQueryLuckyCloudBuyLotteryRec.SubCmd))] = m_NAtagCGQueryLuckyCloudBuyLotteryRec
#------------------------------------------------------
# C0 05 查询幸运云购购买号码记录 #tagCGQueryLuckyCloudBuyNumRec
class  tagCGQueryLuckyCloudBuyNumRec(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xC0
        self.SubCmd = 0x05
        return
    def ReadData(self, stringData, _pos=0, _len=0):
        self.Clear()
        memmove(addressof(self), stringData[_pos:], self.GetLength())
        return _pos + self.GetLength()
    def Clear(self):
        self.Cmd = 0xC0
        self.SubCmd = 0x05
        return
    def GetLength(self):
        return sizeof(tagCGQueryLuckyCloudBuyNumRec)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// C0 05 查询幸运云购购买号码记录 //tagCGQueryLuckyCloudBuyNumRec:
                                Cmd:%s,
                                SubCmd:%s
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd
                                )
        return DumpString
m_NAtagCGQueryLuckyCloudBuyNumRec=tagCGQueryLuckyCloudBuyNumRec()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCGQueryLuckyCloudBuyNumRec.Cmd,m_NAtagCGQueryLuckyCloudBuyNumRec.SubCmd))] = m_NAtagCGQueryLuckyCloudBuyNumRec
#------------------------------------------------------
# C0 04 查看跨服排行榜 #tagCGViewCrossBillboard
class  tagCGViewCrossBillboard(Structure):
@@ -19213,4 +19313,56 @@
m_NAtagCMExitCrossRealm=tagCMExitCrossRealm()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMExitCrossRealm.Cmd,m_NAtagCMExitCrossRealm.SubCmd))] = m_NAtagCMExitCrossRealm
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMExitCrossRealm.Cmd,m_NAtagCMExitCrossRealm.SubCmd))] = m_NAtagCMExitCrossRealm
#------------------------------------------------------
# C1 10 幸运云购购买 #tagCMLuckyCloudBuy
class  tagCMLuckyCloudBuy(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("BuyCount", c_ushort),    # 购买份数
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xC1
        self.SubCmd = 0x10
        return
    def ReadData(self, stringData, _pos=0, _len=0):
        self.Clear()
        memmove(addressof(self), stringData[_pos:], self.GetLength())
        return _pos + self.GetLength()
    def Clear(self):
        self.Cmd = 0xC1
        self.SubCmd = 0x10
        self.BuyCount = 0
        return
    def GetLength(self):
        return sizeof(tagCMLuckyCloudBuy)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// C1 10 幸运云购购买 //tagCMLuckyCloudBuy:
                                Cmd:%s,
                                SubCmd:%s,
                                BuyCount:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.BuyCount
                                )
        return DumpString
m_NAtagCMLuckyCloudBuy=tagCMLuckyCloudBuy()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMLuckyCloudBuy.Cmd,m_NAtagCMLuckyCloudBuy.SubCmd))] = m_NAtagCMLuckyCloudBuy
ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
@@ -561,33 +561,41 @@
#A0 04 同步客户端时间 #tagServerDateTime
class  tagServerDateTime(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("Year", c_ushort),
                  ("Month", c_ubyte),
                  ("Day", c_ubyte),
                  ("Hour", c_ubyte),
                  ("Minute", c_ubyte),
                  ("Second", c_ubyte),
                  ("MicSecond", c_int),
                  ]
    Head = tagHead()
    Year = 0    #(WORD Year)
    Month = 0    #(BYTE Month)
    Day = 0    #(BYTE Day)
    Hour = 0    #(BYTE Hour)
    Minute = 0    #(BYTE Minute)
    Second = 0    #(BYTE Second)
    MicSecond = 0    #(DWORD MicSecond)
    CrossServerTime = ""    #(char CrossServerTime[19])
    data = None
    def __init__(self):
        self.Clear()
        self.Cmd = 0xA0
        self.SubCmd = 0x04
        self.Head.Cmd = 0xA0
        self.Head.SubCmd = 0x04
        return
    def ReadData(self, stringData, _pos=0, _len=0):
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        memmove(addressof(self), stringData[_pos:], self.GetLength())
        return _pos + self.GetLength()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.Year,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.Month,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.Day,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.Hour,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.Minute,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.Second,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.MicSecond,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.CrossServerTime,_pos = CommFunc.ReadString(_lpData, _pos,19)
        return _pos
    def Clear(self):
        self.Cmd = 0xA0
        self.SubCmd = 0x04
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xA0
        self.Head.SubCmd = 0x04
        self.Year = 0
        self.Month = 0
        self.Day = 0
@@ -595,42 +603,64 @@
        self.Minute = 0
        self.Second = 0
        self.MicSecond = 0
        self.CrossServerTime = ""
        return
    def GetLength(self):
        return sizeof(tagServerDateTime)
        length = 0
        length += self.Head.GetLength()
        length += 2
        length += 1
        length += 1
        length += 1
        length += 1
        length += 1
        length += 4
        length += 19
        return length
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteWORD(data, self.Year)
        data = CommFunc.WriteBYTE(data, self.Month)
        data = CommFunc.WriteBYTE(data, self.Day)
        data = CommFunc.WriteBYTE(data, self.Hour)
        data = CommFunc.WriteBYTE(data, self.Minute)
        data = CommFunc.WriteBYTE(data, self.Second)
        data = CommFunc.WriteDWORD(data, self.MicSecond)
        data = CommFunc.WriteString(data, 19, self.CrossServerTime)
        return data
    def OutputString(self):
        DumpString = '''//A0 04 同步客户端时间 //tagServerDateTime:
                                Cmd:%s,
                                SubCmd:%s,
        DumpString = '''
                                Head:%s,
                                Year:%d,
                                Month:%d,
                                Day:%d,
                                Hour:%d,
                                Minute:%d,
                                Second:%d,
                                MicSecond:%d
                                MicSecond:%d,
                                CrossServerTime:%s
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.Head.OutputString(),
                                self.Year,
                                self.Month,
                                self.Day,
                                self.Hour,
                                self.Minute,
                                self.Second,
                                self.MicSecond
                                self.MicSecond,
                                self.CrossServerTime
                                )
        return DumpString
m_NAtagServerDateTime=tagServerDateTime()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagServerDateTime.Cmd,m_NAtagServerDateTime.SubCmd))] = m_NAtagServerDateTime
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagServerDateTime.Head.Cmd,m_NAtagServerDateTime.Head.SubCmd))] = m_NAtagServerDateTime
#------------------------------------------------------
@@ -13266,6 +13296,352 @@
m_NAtagGCCrossRealmPKStartMatch=tagGCCrossRealmPKStartMatch()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCCrossRealmPKStartMatch.Cmd,m_NAtagGCCrossRealmPKStartMatch.SubCmd))] = m_NAtagGCCrossRealmPKStartMatch
#------------------------------------------------------
# C0 14 幸运云购开奖记录 #tagGCLuckyCloudBuyLotteryRecInfo
class  tagGCLuckyCloudBuyLotteryRec(Structure):
    SuperItemID = 0    #(DWORD SuperItemID)// 大奖物品ID
    SuperItemCount = 0    #(BYTE SuperItemCount)// 大奖物品个数
    NameLen = 0    #(BYTE NameLen)
    PlayerName = ""    #(String PlayerName)// 中奖玩家名
    LotteryNum = 0    #(WORD LotteryNum)// 开奖号码
    LotteryTime = 0    #(DWORD LotteryTime)// 开奖时间戳,秒
    data = None
    def __init__(self):
        self.Clear()
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        self.SuperItemID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.SuperItemCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.NameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.PlayerName,_pos = CommFunc.ReadString(_lpData, _pos,self.NameLen)
        self.LotteryNum,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.LotteryTime,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        return _pos
    def Clear(self):
        self.SuperItemID = 0
        self.SuperItemCount = 0
        self.NameLen = 0
        self.PlayerName = ""
        self.LotteryNum = 0
        self.LotteryTime = 0
        return
    def GetLength(self):
        length = 0
        length += 4
        length += 1
        length += 1
        length += len(self.PlayerName)
        length += 2
        length += 4
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteDWORD(data, self.SuperItemID)
        data = CommFunc.WriteBYTE(data, self.SuperItemCount)
        data = CommFunc.WriteBYTE(data, self.NameLen)
        data = CommFunc.WriteString(data, self.NameLen, self.PlayerName)
        data = CommFunc.WriteWORD(data, self.LotteryNum)
        data = CommFunc.WriteDWORD(data, self.LotteryTime)
        return data
    def OutputString(self):
        DumpString = '''
                                SuperItemID:%d,
                                SuperItemCount:%d,
                                NameLen:%d,
                                PlayerName:%s,
                                LotteryNum:%d,
                                LotteryTime:%d
                                '''\
                                %(
                                self.SuperItemID,
                                self.SuperItemCount,
                                self.NameLen,
                                self.PlayerName,
                                self.LotteryNum,
                                self.LotteryTime
                                )
        return DumpString
class  tagGCLuckyCloudBuyLotteryRecInfo(Structure):
    Head = tagHead()
    ZoneID = 0    #(BYTE ZoneID)// 分区
    Count = 0    #(WORD Count)
    LotteryRecList = list()    #(vector<tagGCLuckyCloudBuyLotteryRec> LotteryRecList)
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xC0
        self.Head.SubCmd = 0x14
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.ZoneID,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.Count,_pos = CommFunc.ReadWORD(_lpData, _pos)
        for i in range(self.Count):
            temLotteryRecList = tagGCLuckyCloudBuyLotteryRec()
            _pos = temLotteryRecList.ReadData(_lpData, _pos)
            self.LotteryRecList.append(temLotteryRecList)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xC0
        self.Head.SubCmd = 0x14
        self.ZoneID = 0
        self.Count = 0
        self.LotteryRecList = list()
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 1
        length += 2
        for i in range(self.Count):
            length += self.LotteryRecList[i].GetLength()
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteBYTE(data, self.ZoneID)
        data = CommFunc.WriteWORD(data, self.Count)
        for i in range(self.Count):
            data = CommFunc.WriteString(data, self.LotteryRecList[i].GetLength(), self.LotteryRecList[i].GetBuffer())
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                ZoneID:%d,
                                Count:%d,
                                LotteryRecList:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.ZoneID,
                                self.Count,
                                "..."
                                )
        return DumpString
m_NAtagGCLuckyCloudBuyLotteryRecInfo=tagGCLuckyCloudBuyLotteryRecInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCLuckyCloudBuyLotteryRecInfo.Head.Cmd,m_NAtagGCLuckyCloudBuyLotteryRecInfo.Head.SubCmd))] = m_NAtagGCLuckyCloudBuyLotteryRecInfo
#------------------------------------------------------
# C0 13 幸运云购购买号码记录 #tagGCLuckyCloudBuyNumRecInfo
class  tagGCLuckyCloudBuyNumRec(Structure):
    NameLen = 0    #(BYTE NameLen)
    PlayerName = ""    #(String PlayerName)
    BuyNum = 0    #(WORD BuyNum)
    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.PlayerName,_pos = CommFunc.ReadString(_lpData, _pos,self.NameLen)
        self.BuyNum,_pos = CommFunc.ReadWORD(_lpData, _pos)
        return _pos
    def Clear(self):
        self.NameLen = 0
        self.PlayerName = ""
        self.BuyNum = 0
        return
    def GetLength(self):
        length = 0
        length += 1
        length += len(self.PlayerName)
        length += 2
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteBYTE(data, self.NameLen)
        data = CommFunc.WriteString(data, self.NameLen, self.PlayerName)
        data = CommFunc.WriteWORD(data, self.BuyNum)
        return data
    def OutputString(self):
        DumpString = '''
                                NameLen:%d,
                                PlayerName:%s,
                                BuyNum:%d
                                '''\
                                %(
                                self.NameLen,
                                self.PlayerName,
                                self.BuyNum
                                )
        return DumpString
class  tagGCLuckyCloudBuyNumRecInfo(Structure):
    Head = tagHead()
    Count = 0    #(WORD Count)
    BuyNumRecList = list()    #(vector<tagGCLuckyCloudBuyNumRec> BuyNumRecList)
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xC0
        self.Head.SubCmd = 0x13
        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):
            temBuyNumRecList = tagGCLuckyCloudBuyNumRec()
            _pos = temBuyNumRecList.ReadData(_lpData, _pos)
            self.BuyNumRecList.append(temBuyNumRecList)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xC0
        self.Head.SubCmd = 0x13
        self.Count = 0
        self.BuyNumRecList = list()
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 2
        for i in range(self.Count):
            length += self.BuyNumRecList[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.BuyNumRecList[i].GetLength(), self.BuyNumRecList[i].GetBuffer())
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                Count:%d,
                                BuyNumRecList:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.Count,
                                "..."
                                )
        return DumpString
m_NAtagGCLuckyCloudBuyNumRecInfo=tagGCLuckyCloudBuyNumRecInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCLuckyCloudBuyNumRecInfo.Head.Cmd,m_NAtagGCLuckyCloudBuyNumRecInfo.Head.SubCmd))] = m_NAtagGCLuckyCloudBuyNumRecInfo
#------------------------------------------------------
# C0 12 幸运云购轮次信息 #tagGCLuckyCloudBuyRoundInfo
class  tagGCLuckyCloudBuyRoundInfo(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("RoundID", c_int),    # 轮次唯一ID标识,当收到的轮次ID变更时,前端需清空购买号码记录缓存
                  ("RoundNum", c_ubyte),    # 今日第几轮
                  ("SuperItemID", c_int),    # 大奖物品ID
                  ("SuperItemCount", c_ubyte),    # 大奖物品个数
                  ("SuperItemMoneyType", c_ubyte),    # 大奖价值货币类型
                  ("SuperItemMoneyValue", c_int),    # 大奖价值
                  ("RemainCount", c_ushort),    # 开奖剩余份数
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xC0
        self.SubCmd = 0x12
        return
    def ReadData(self, stringData, _pos=0, _len=0):
        self.Clear()
        memmove(addressof(self), stringData[_pos:], self.GetLength())
        return _pos + self.GetLength()
    def Clear(self):
        self.Cmd = 0xC0
        self.SubCmd = 0x12
        self.RoundID = 0
        self.RoundNum = 0
        self.SuperItemID = 0
        self.SuperItemCount = 0
        self.SuperItemMoneyType = 0
        self.SuperItemMoneyValue = 0
        self.RemainCount = 0
        return
    def GetLength(self):
        return sizeof(tagGCLuckyCloudBuyRoundInfo)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// C0 12 幸运云购轮次信息 //tagGCLuckyCloudBuyRoundInfo:
                                Cmd:%s,
                                SubCmd:%s,
                                RoundID:%d,
                                RoundNum:%d,
                                SuperItemID:%d,
                                SuperItemCount:%d,
                                SuperItemMoneyType:%d,
                                SuperItemMoneyValue:%d,
                                RemainCount:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.RoundID,
                                self.RoundNum,
                                self.SuperItemID,
                                self.SuperItemCount,
                                self.SuperItemMoneyType,
                                self.SuperItemMoneyValue,
                                self.RemainCount
                                )
        return DumpString
m_NAtagGCLuckyCloudBuyRoundInfo=tagGCLuckyCloudBuyRoundInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCLuckyCloudBuyRoundInfo.Cmd,m_NAtagGCLuckyCloudBuyRoundInfo.SubCmd))] = m_NAtagGCLuckyCloudBuyRoundInfo
#------------------------------------------------------
@@ -40762,6 +41138,58 @@
#------------------------------------------------------
# C1 08 幸运云购玩家信息 #tagMCLuckyCloudBuyPlayerInfo
class  tagMCLuckyCloudBuyPlayerInfo(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("BuyCount", c_ushort),    # 本轮已购买份数
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xC1
        self.SubCmd = 0x08
        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 = 0xC1
        self.SubCmd = 0x08
        self.BuyCount = 0
        return
    def GetLength(self):
        return sizeof(tagMCLuckyCloudBuyPlayerInfo)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// C1 08 幸运云购玩家信息 //tagMCLuckyCloudBuyPlayerInfo:
                                Cmd:%s,
                                SubCmd:%s,
                                BuyCount:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.BuyCount
                                )
        return DumpString
m_NAtagMCLuckyCloudBuyPlayerInfo=tagMCLuckyCloudBuyPlayerInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCLuckyCloudBuyPlayerInfo.Cmd,m_NAtagMCLuckyCloudBuyPlayerInfo.SubCmd))] = m_NAtagMCLuckyCloudBuyPlayerInfo
#------------------------------------------------------
# C1 04 准备进入跨服服务器 #tagMCPrepareEnterCrossServer
class  tagMCPrepareEnterCrossServer(Structure):
ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/CrossServerTime.py
New file
@@ -0,0 +1,52 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package GM.Commands.CrossServerTime
#
# @todo:跨服服务器时间同步
# @author hxp
# @date 2021-10-21
# @version 1.0
#
# 详细描述: 跨服服务器时间同步
#
#-------------------------------------------------------------------------------
#"""Version = 2021-10-21 17:00"""
#-------------------------------------------------------------------------------
import GameWorld
import CrossRealmMsg
import ShareDefine
#---------------------------------------------------------------------
#全局变量
#---------------------------------------------------------------------
#---------------------------------------------------------------------
#逻辑实现
## 执行逻辑
#  @param curPlayer 当前玩家
#  @param gmList [cmdIndex gmAccID msg]
#  @return None
#  @remarks 函数详细说明.
def OnExec(curPlayer, gmList):
    ## 本服处理
    return
def OnMergeServerExec(gmList, tick):
    ## 跨服处理
    serverGroupID = gmList[0]
    playerID = gmList[1]
    dataMsg = {"PlayerID":playerID}
    serverGroupIDList = [serverGroupID]
    CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_CrossServerTime, dataMsg, serverGroupIDList)
    return
def OnGetMergeParam(curPlayer):
    playerID = curPlayer.GetPlayerID()
    serverGroupID = GameWorld.GetServerGroupID()
    return [serverGroupID, playerID]
ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/LuckyCloudBuy.py
New file
@@ -0,0 +1,80 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package GM.Commands.LuckyCloudBuy
#
# @todo:幸运云购
# @author hxp
# @date 2021-10-21
# @version 1.0
#
# 详细描述: 幸运云购
#
#-------------------------------------------------------------------------------
#"""Version = 2021-10-21 17:00"""
#-------------------------------------------------------------------------------
import GameWorld
import CrossLuckyCloudBuy
import IpyGameDataPY
import PyGameData
#---------------------------------------------------------------------
#全局变量
#---------------------------------------------------------------------
#---------------------------------------------------------------------
#逻辑实现
## 执行逻辑
#  @param curPlayer 当前玩家
#  @param gmList [cmdIndex gmAccID msg]
#  @return None
#  @remarks 函数详细说明.
def OnExec(curPlayer, gmList):
    ## 本服处理
    value1 = gmList[0]
    # 重置
    if value1 == 0 and len(gmList) == 1:
        PyGameData.g_luckyCloudBuyNumDict = {}
        PyGameData.g_luckyCloudBuyLotteryDict = {}
        PyGameData.g_unNotifyCloudBuyNumDict = {}
    # 添加云购记录
    elif value1 == 1:
        pass
    return
def OnMergeServerExec(gmList, tick):
    ## 跨服处理
    value1 = gmList[0]
    # 重置
    if value1 == 0:
        GameWorld.DebugLog("GM重置幸运云购!")
        PyGameData.g_luckyCloudBuyNumDict = {}
        PyGameData.g_luckyCloudBuyLotteryDict = {}
        crossZoneName = GameWorld.GetCrossZoneName()
        crossZoneList = IpyGameDataPY.GetIpyGameDataByCondition("CrossZonePK", {"CrossZoneName":crossZoneName}, True)
        if not crossZoneList:
            return
        for zoneIpyData in crossZoneList:
            zoneID = zoneIpyData.GetZoneID()
            CrossLuckyCloudBuy.DoStartNewRoundLuckyCloudBuy(zoneID, 1)
    # 添加云购记录
    elif value1 == 1:
        buyCount = gmList[1]
        serverGroupID = gmList[-1]
        CrossLuckyCloudBuy.DoGMLuckyCloudBuy(serverGroupID, buyCount)
    return
def OnGetMergeParam(curPlayer):
    serverGroupID = GameWorld.GetServerGroupID()
    return [serverGroupID]
ServerPython/CoreServerGroup/GameServer/Script/GameWorld.py
@@ -918,6 +918,17 @@
        return ReadChConfig.GetPyMongoConfig("Merge", "CrossZoneName")
    return PyGameData.g_crossZoneName
def GetCrossServerTimeStr():
    ## 跨服服务器时间
    if IsCrossServer():
        return GetCurrentDataTimeStr()
    lastCrossServerTime, lastServerTime, _ = PyGameData.g_crossServerTimeInfo
    if not lastCrossServerTime:
        return GetCurrentDataTimeStr()
    curTime = int(time.time())
    crossServerTime = lastCrossServerTime + (curTime - lastServerTime)
    return ChangeTimeNumToStr(crossServerTime)
## 获取玩家的区服名,仅在跨服有效
#  @param curPlayer 玩家实例
#  @return: 区服名
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossLuckyCloudBuy.py
New file
@@ -0,0 +1,977 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package CrossLuckyCloudBuy
#
# @todo:幸运云购
# @author hxp
# @date 2021-10-21
# @version 1.0
#
# 详细描述: 幸运云购
#
#-------------------------------------------------------------------------------
#"""Version = 2021-10-21 17:00"""
#-------------------------------------------------------------------------------
import GameWorld
import ShareDefine
import CrossRealmMsg
import PlayerControl
import DataRecordPack
import PlayerCompensation
import ChPyNetSendPack
import IpyGameDataPY
import NetPackCommon
import CrossRealmPK
import PyGameData
import ChConfig
import operator
import random
import math
import time
Def_RecType_LuckyCloudBuyNum = ShareDefine.Def_UniversalGameRecType_LuckyCloudBuyNum
'''
幸运云购购买号码记录
ShareDefine.Def_UniversalGameRecType_LuckyCloudBuyNum
time:idTime             绑定的轮次标识ID,对应开奖记录的time值
value1:zoneID        分区ID
value2:roundNum        今日第几轮
value3:playerID        玩家ID
value4:buyNum          购买号码
value5:buyTime         购买时间
StrValue1:playerName    玩家名
StrValue3:accID        玩家账号
'''
Def_RecType_LuckyCloudBuyLottery = ShareDefine.Def_UniversalGameRecType_LuckyCloudBuyLottery
'''
幸运云购开奖记录
ShareDefine.Def_UniversalGameRecType_LuckyCloudBuyLottery
time:idTime                创建时间(也作为本轮唯一标识ID,用生成时间time值作为唯一ID)
value1:zoneID            分区ID
value2:roundNum          今日第几轮
value3:luckyPlayerID     中奖玩家ID
value4:lotteryNum         开奖号码
value5:lotteryTime       开奖时间
StrValue1:luckyPlayerName    中奖玩家名
StrValue3:lotteryInfo        分区信息|大奖信息|中奖玩家账号
'''
class LuckyCloudBuyNum():
    ''' 幸运云购购买号码记录
    '''
    def __init__(self):
        self.idTime = 0
        self.zoneID = 0
        self.roundNum = 0
        self.playerID = 0
        self.buyNum = 0
        self.buyTime = 0
        self.playerName = ""
        self.accID = ""
        return
    def GetString(self):
        return {"idTime":self.idTime, "zoneID":self.zoneID, "roundNum":self.roundNum, "playerID":self.playerID,
                "buyNum":self.buyNum, "buyTime":self.buyTime, "playerName":self.playerName, "accID":self.accID}
    def SetAttrByDict(self, attrDict):
        for k, v in attrDict.items():
            setattr(self, k, v)
        return
class LuckyCloudBuyLottery():
    ''' 幸运云购开奖记录
    '''
    def __init__(self):
        self.idTime = 0
        self.zoneID = 0
        self.roundNum = 0
        self.luckyPlayerID = 0
        self.lotteryNum = 0
        self.lotteryTime = 0
        self.luckyPlayerName = ""
        self.serverGroupIDList = [] # 分区信息
        self.superItemInfo = [] # 大奖信息
        self.luckyPlayerAccID = "" # 中奖玩家账号
        return
    def GetString(self):
        return {"idTime":self.idTime, "zoneID":self.zoneID, "roundNum":self.roundNum, "luckyPlayerID":self.luckyPlayerID,
                "lotteryNum":self.lotteryNum, "lotteryTime":self.lotteryTime, "luckyPlayerName":self.luckyPlayerName,
                "serverGroupIDList":self.serverGroupIDList, "superItemInfo":self.superItemInfo, "luckyPlayerAccID":self.luckyPlayerAccID}
    def SetAttrByDict(self, attrDict):
        for k, v in attrDict.items():
            setattr(self, k, v)
        return
def OnServerStart():
    if not GameWorld.IsCrossServer():
        return
    PyGameData.g_luckyCloudBuyNumDict = {}
    PyGameData.g_luckyCloudBuyLotteryDict = {}
    universalRecMgr = GameWorld.GetUniversalRecMgr()
    recDataList = universalRecMgr.GetTypeList(Def_RecType_LuckyCloudBuyNum)
    GameWorld.Log("加载幸运云购购买记录! %s" % recDataList.Count())
    for index in xrange(recDataList.Count()):
        recData = recDataList.At(index)
        zoneID = recData.GetValue1()
        buyRec = LuckyCloudBuyNum()
        buyRec.idTime = int(recData.GetTime())
        buyRec.zoneID = zoneID
        buyRec.roundNum = recData.GetValue2()
        buyRec.playerID = recData.GetValue3()
        buyRec.buyNum = recData.GetValue4()
        buyRec.buyTime = recData.GetValue5()
        buyRec.playerName = recData.GetStrValue1()
        buyRec.accID = recData.GetStrValue3()
        if zoneID not in PyGameData.g_luckyCloudBuyNumDict:
            PyGameData.g_luckyCloudBuyNumDict[zoneID] = []
        buyRecList = PyGameData.g_luckyCloudBuyNumDict[zoneID]
        buyRecList.append(buyRec)
    for zoneID, buyRecList in PyGameData.g_luckyCloudBuyNumDict.items():
        buyRecList.sort(key=operator.attrgetter("idTime"))
        GameWorld.Log("    幸运云购分区购买记录! zoneID=%s, count=%s" % (zoneID, len(buyRecList)))
    recDataList = universalRecMgr.GetTypeList(Def_RecType_LuckyCloudBuyLottery)
    GameWorld.Log("加载幸运云购开奖记录! %s" % recDataList.Count())
    for index in xrange(recDataList.Count()):
        recData = recDataList.At(index)
        zoneID = recData.GetValue1()
        lotteryRec = LuckyCloudBuyLottery()
        lotteryRec.idTime = int(recData.GetTime())
        lotteryRec.zoneID = zoneID
        lotteryRec.roundNum = recData.GetValue2()
        lotteryRec.luckyPlayerID = recData.GetValue3()
        lotteryRec.lotteryNum = recData.GetValue4()
        lotteryRec.lotteryTime = recData.GetValue5()
        lotteryRec.luckyPlayerName = recData.GetStrValue1()
        strValue3 = recData.GetStrValue3()
        lotteryRec.serverGroupIDList, lotteryRec.superItemInfo, lotteryRec.luckyPlayerAccID = [], [], ""
        if strValue3:
            groupIDStr, superItemStr, accID = strValue3.split("|")
            lotteryRec.serverGroupIDList = eval(groupIDStr) if (groupIDStr.startswith("[") and groupIDStr.endswith("]")) else []
            lotteryRec.superItemInfo = eval(superItemStr) if (superItemStr.startswith("[") and superItemStr.endswith("]")) else []
            lotteryRec.luckyPlayerAccID = accID
        if zoneID not in PyGameData.g_luckyCloudBuyLotteryDict:
            PyGameData.g_luckyCloudBuyLotteryDict[zoneID] = []
        lotteryRecList = PyGameData.g_luckyCloudBuyLotteryDict[zoneID]
        lotteryRecList.append(lotteryRec)
    for zoneID, lotteryRecList in PyGameData.g_luckyCloudBuyLotteryDict.items():
        lotteryRecList.sort(key=operator.attrgetter("idTime"))
        GameWorld.Log("    幸运云购分区开奖记录! zoneID=%s, count=%s" % (zoneID, len(lotteryRecList)))
    CheckLuckyCloudBuyZoneInfoChange()
    return
def OnServerClose():
    if not GameWorld.IsCrossServer():
        return
    universalRecMgr = GameWorld.GetUniversalRecMgr()
    GameWorld.Log("保存幸运云购购买记录!")
    universalRecMgr.Delete(Def_RecType_LuckyCloudBuyNum)
    recDataList = universalRecMgr.GetTypeList(Def_RecType_LuckyCloudBuyNum)
    for zoneID, buyRecList in PyGameData.g_luckyCloudBuyNumDict.items():
        GameWorld.Log("    保存幸运云购购买记录! zoneID=%s, count=%s" % (zoneID, len(buyRecList)))
        for buyRec in buyRecList:
            recData = recDataList.AddRec()
            recData.SetTime(buyRec.idTime)
            recData.SetValue1(buyRec.zoneID)
            recData.SetValue2(buyRec.roundNum)
            recData.SetValue3(buyRec.playerID)
            recData.SetValue4(buyRec.buyNum)
            recData.SetValue5(buyRec.buyTime)
            recData.SetStrValue1(buyRec.playerName)
            recData.SetStrValue3(buyRec.accID)
    GameWorld.Log("保存幸运云购开奖记录!")
    universalRecMgr.Delete(Def_RecType_LuckyCloudBuyLottery)
    recDataList = universalRecMgr.GetTypeList(Def_RecType_LuckyCloudBuyLottery)
    for zoneID, lotteryRecList in PyGameData.g_luckyCloudBuyLotteryDict.items():
        GameWorld.Log("    保存幸运云购开奖记录! zoneID=%s, count=%s" % (zoneID, len(lotteryRecList)))
        for lotteryRec in lotteryRecList:
            recData = recDataList.AddRec()
            recData.SetTime(lotteryRec.idTime)
            recData.SetValue1(lotteryRec.zoneID)
            recData.SetValue2(lotteryRec.roundNum)
            recData.SetValue3(lotteryRec.luckyPlayerID)
            recData.SetValue4(lotteryRec.lotteryNum)
            recData.SetValue5(lotteryRec.lotteryTime)
            recData.SetStrValue1(lotteryRec.luckyPlayerName)
            recData.SetStrValue3("%s|%s|%s" % (str(lotteryRec.serverGroupIDList).replace(" ", ""),
                                               str(lotteryRec.superItemInfo).replace(" ", ""),
                                               lotteryRec.luckyPlayerAccID))
    return
def OnPlayerLogin(curPlayer):
    if GameWorld.IsCrossServer():
        return
    Sync_LuckyCloudBuyRoundInfo(curPlayer)
    __LoginNotifyMapCloudBuyNumInfo(curPlayer)
    return
def DoOnDay():
    # 清除过期的开奖记录,购买记录仅保留本期
    crossServerTime = GameWorld.ChangeTimeStrToNum(GameWorld.GetCrossServerTimeStr())
    MaxTime = 3 * 24 * 3600 # 最大保留近3天记录
    for zoneID, lotteryRecList in PyGameData.g_luckyCloudBuyLotteryDict.items():
        doCount = len(lotteryRecList)
        GameWorld.DebugLog("检查幸运云购分区开奖记录是否超时! zoneID=%s,count=%s" % (zoneID, doCount))
        while lotteryRecList and doCount > 0:
            doCount -= 1
            lotteryRec = lotteryRecList[0]
            passTime = crossServerTime - lotteryRec.lotteryTime
            if not lotteryRec.lotteryNum or not lotteryRec.lotteryTime or passTime < MaxTime:
                GameWorld.DebugLog("    未开奖或在保留时间内! lotteryNum=%s,crossServerTime=%s(%s),lotteryTime=%s(%s),passTime=%s < %s"
                                   % (lotteryRec.lotteryNum, crossServerTime, GameWorld.ChangeTimeNumToStr(crossServerTime),
                                      lotteryRec.lotteryTime, GameWorld.ChangeTimeNumToStr(lotteryRec.lotteryTime), passTime, MaxTime))
                break
            lotteryRec = lotteryRecList.pop(0)
            GameWorld.DebugLog("    云购开奖记录超时,删除! lotteryNum=%s,crossServerTime=%s(%s),lotteryTime=%s(%s),passTime=%s >= %s"
                                   % (lotteryRec.lotteryNum, crossServerTime, GameWorld.ChangeTimeNumToStr(crossServerTime),
                                      lotteryRec.lotteryTime, GameWorld.ChangeTimeNumToStr(lotteryRec.lotteryTime), passTime, MaxTime))
    if not GameWorld.IsCrossServer():
        return
    maxBuyCount = IpyGameDataPY.GetFuncCfg("LuckyCloudBuySet", 2)
    doLotteryBuyCountPer = IpyGameDataPY.GetFuncCfg("LuckyCloudBuySet", 3)
    doLotteryBuyCount = int(math.ceil(maxBuyCount * doLotteryBuyCountPer / 100.0))
    for zoneID, lotteryRecList in PyGameData.g_luckyCloudBuyLotteryDict.items():
        if not lotteryRecList:
            continue
        lastLotteryRec = lotteryRecList[-1] # 取最后一个为最新一期
        if lastLotteryRec.lotteryNum:
            GameWorld.Log("OnDay已开奖进入新一天第一轮! zoneID=%s" % zoneID)
            DoStartNewRoundLuckyCloudBuy(zoneID, 1)
            continue
        buyRecList = PyGameData.g_luckyCloudBuyNumDict.get(zoneID, [])
        buyCount = len(buyRecList)
        if len(buyRecList) >= doLotteryBuyCount:
            GameWorld.Log("OnDay未开奖但购买份数超过开奖保底份数! zoneID=%s,buyCount=%s >= %s" % (zoneID, buyCount, doLotteryBuyCount))
            DoLuckyCloudBuyLottery(lastLotteryRec, True, "OnDay")
            continue
        GameWorld.Log("已购买份数不足开奖保底份数,重置为新一天的第一轮! zoneID=%s,buyCount=%s < %s" % (zoneID, buyCount, doLotteryBuyCount))
        lastLotteryRec.roundNum = 1
        dataDict = {"Type":"ResetRound"}
        dataDict.update(lastLotteryRec.GetString())
        DataRecordPack.SendEventPack("LuckyCloudBuyLottery", dataDict)
        # 广播子服轮次信息变更
        crossZoneName = GameWorld.GetCrossZoneName()
        zoneIpyData = IpyGameDataPY.GetIpyGameData("CrossZonePK", crossZoneName, zoneID)
        if zoneIpyData:
            serverGroupIDList = zoneIpyData.GetServerGroupIDList()
            zoneLotteryInfo = {zoneID:[lastLotteryRec.GetString()]}
            dataMsg = {"syncType":"Update", "zoneLotteryInfo":zoneLotteryInfo}
            CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_LuckyCloudBuyLottery, dataMsg, serverGroupIDList)
    return
def CheckLuckyCloudBuyZoneInfoChange():
    ## 检查云购分区配置变更
    if not GameWorld.IsCrossServer():
        return
    crossZoneName = GameWorld.GetCrossZoneName()
    crossZoneList = IpyGameDataPY.GetIpyGameDataByCondition("CrossZonePK", {"CrossZoneName":crossZoneName}, True)
    if not crossZoneList:
        return
    checkZoneInfo = {} # 分区调整可能变多、变少、或只调整范围,所以检查的分区要取配置及活动分区数据的所有分区汇总
    for zoneIpyData in crossZoneList:
        zoneID = zoneIpyData.GetZoneID()
        checkZoneInfo[zoneID] = zoneIpyData.GetServerGroupIDList()
    for zoneID in PyGameData.g_luckyCloudBuyLotteryDict.keys():
        if zoneID not in checkZoneInfo:
            checkZoneInfo[zoneID] = None
    haveChange = False
    for zoneID, serverGroupIDList in checkZoneInfo.items():
        lotteryRecList = PyGameData.g_luckyCloudBuyLotteryDict.get(zoneID, [])
        if lotteryRecList:
            lastLotteryRec = lotteryRecList[-1] # 取最后一个为最新一期
            if lastLotteryRec.lotteryNum:
                GameWorld.DebugLog("已开奖,不处理! zoneID=%s" % zoneID)
                continue
            if lastLotteryRec.serverGroupIDList != serverGroupIDList:
                GameWorld.Log("分区信息变更,强制开奖! zoneID=%s,recGroupIDList=%s,serverGroupIDList=%s"
                              % (zoneID, lastLotteryRec.serverGroupIDList, serverGroupIDList))
                DoLuckyCloudBuyLottery(lastLotteryRec, True, "ServerGroupIDChange")
                haveChange = True
            else:
                GameWorld.DebugLog("分区信息不变,不处理! zoneID=%s" % zoneID)
        else:
            GameWorld.Log("配置了新分区,开启新云购! zoneID=%s,serverGroupIDList=%s" % (zoneID, serverGroupIDList))
            DoStartNewRoundLuckyCloudBuy(zoneID, 1)
            haveChange = True
        if serverGroupIDList == None:
            GameWorld.Log("分区被删除! zoneID=%s" % zoneID)
            PyGameData.g_luckyCloudBuyLotteryDict.pop(zoneID, None)
            PyGameData.g_luckyCloudBuyNumDict.pop(zoneID, None)
    if haveChange:
        Sync_LuckyCloudBuyDataToClientServer(GameWorld.GetGameWorld().GetTick())
    return
def DoLuckyCloudBuyLottery(lotteryRec, resetRound=False, sign=""):
    idTime = lotteryRec.idTime
    zoneID = lotteryRec.zoneID
    roundNum = lotteryRec.roundNum
    lotteryDateStr = GameWorld.ChangeTimeNumToStr(idTime, ChConfig.TYPE_Time_YmdFormat)
    GameWorld.Log("幸运云购开奖: idTime=%s(%s),zoneID=%s,roundNum=%s,resetRound=%s,sign=%s"
                  % (idTime, lotteryDateStr, zoneID, roundNum, resetRound, sign))
    todayLuckyPlayerCountInfo = {} # 当日中奖玩家中奖次数信息 {playerID:count, ...}
    lotteryRecList = PyGameData.g_luckyCloudBuyLotteryDict.get(zoneID, [])
    for lotRec in lotteryRecList[-roundNum:]:
        if lotRec.luckyPlayerID:
            todayLuckyPlayerCountInfo[lotRec.luckyPlayerID] = todayLuckyPlayerCountInfo.get(lotRec.luckyPlayerID, 0) + 1
    GameWorld.Log("    当日已中奖玩家次数信息: %s" % todayLuckyPlayerCountInfo)
    # 开奖
    playerNumListDict = {}
    baseWeight = 100
    randList = []
    maxRate = 0
    luckyCountLimit, luckyWeightReducePer = IpyGameDataPY.GetFuncEvalCfg("LuckyCloudBuySet", 4)
    buyRecList = PyGameData.g_luckyCloudBuyNumDict.get(zoneID, [])
    for buyRec in buyRecList:
        if buyRec.idTime != idTime:
            GameWorld.ErrLog("    非本轮购买的号码! idTime=%s, buyRecInfo=%s" % (idTime, buyRec.GetString()))
            continue
        playerID = buyRec.playerID
        luckyCount = todayLuckyPlayerCountInfo.get(playerID, 0)
        if luckyCount >= luckyCountLimit:
            weight = max(1, int(baseWeight * (100 - luckyWeightReducePer) / 100.0))
            #GameWorld.Log("    玩家当日中奖次数超过指定次数,中奖权重降低! playerID=%s, luckyCount(%s) >= %s, weight=%s"
            #              % (playerID, luckyCount, luckyCountLimit, weight))
        else:
            weight = baseWeight
        maxRate += weight
        randList.append([maxRate, buyRec])
        # 统计玩家所有号码
        if playerID not in playerNumListDict:
            playerNumListDict[playerID] = []
        playerNumList = playerNumListDict[playerID]
        playerNumList.append(buyRec.buyNum)
    GameWorld.Log("    本轮开奖饼图列表信息: buyCount=%s,randListLen=%s,maxRate=%s" % (len(buyRecList), len(randList), maxRate))
    luckyBuyRec = GameWorld.GetResultByRandomList(randList)
    if luckyBuyRec:
        GameWorld.Log("    幸运中奖号码记录: lotteryNum=%s, %s" % (luckyBuyRec.buyNum, luckyBuyRec.GetString()))
        lotteryRec.luckyPlayerID = luckyBuyRec.playerID
        lotteryRec.luckyPlayerName = luckyBuyRec.playerName
        lotteryRec.luckyPlayerAccID = luckyBuyRec.accID
        lotteryRec.lotteryNum = luckyBuyRec.buyNum
        lotteryRec.lotteryTime = int(time.time())
        dataDict = {"Type":"Lottery"}
        dataDict.update(lotteryRec.GetString())
        DataRecordPack.SendEventPack("LuckyCloudBuyLottery", dataDict)
        # 广播子服开奖信息
        crossZoneName = GameWorld.GetCrossZoneName()
        zoneIpyData = IpyGameDataPY.GetIpyGameData("CrossZonePK", crossZoneName, zoneID)
        if zoneIpyData:
            serverGroupIDList = zoneIpyData.GetServerGroupIDList()
            zoneLotteryInfo = {zoneID:[lotteryRec.GetString()]}
            dataMsg = {"syncType":"Update", "zoneLotteryInfo":zoneLotteryInfo}
            CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_LuckyCloudBuyLottery, dataMsg, serverGroupIDList)
        # 发邮件
        for playerID, buyNumList in playerNumListDict.items():
            if playerID == lotteryRec.luckyPlayerID:
                addItemList = [lotteryRec.superItemInfo[:3]] if len(lotteryRec.superItemInfo) >= 3 else []
                PlayerCompensation.SendMailByKey("LuckyCloudBuyWin", [playerID], addItemList, [lotteryRec.lotteryNum], crossMail=True)
            else:
                buyNums = GetMailBuyNums(buyNumList)
                PlayerCompensation.SendMailByKey("LuckyCloudBuyFail", [playerID], [], [lotteryRec.lotteryNum, buyNums], crossMail=True)
    else:
        GameWorld.ErrLog("    云购开奖异常! zoneID=%s" % zoneID)
    if roundNum >= IpyGameDataPY.GetFuncCfg("LuckyCloudBuySet", 1):
        GameWorld.Log("    当日已达每日云购轮数上限,不开下一轮! roundNum=%s" % roundNum)
        return
    nextRoundNum = 1 if resetRound else (roundNum + 1)
    GameWorld.Log("幸运云购开启下一轮! zoneID=%s,roundNum=%s,resetRound=%s,nextRoundNum=%s"
                  % (zoneID, roundNum, resetRound, nextRoundNum))
    # 开始下一轮
    DoStartNewRoundLuckyCloudBuy(zoneID, nextRoundNum)
    return
def GetMailBuyNums(buyNumList):
    buyNumList.sort()
    buyNums = "" # 形如 1-3、5-7、10、20、100、200-205
    startNum, lastNum = None, None
    sign = "、".decode(ShareDefine.Def_Game_Character_Encoding).encode(GameWorld.GetCharacterEncoding())
    for i, num in enumerate(buyNumList):
        if num - 1 == lastNum:
            lastNum = num
            if not buyNums.endswith("-"):
                buyNums += "-"
            if i == len(buyNumList) - 1:
                buyNums += str(num)
            continue
        if startNum != lastNum:
            buyNums += str(lastNum)
        if buyNums:
            buyNums += sign
        buyNums += str(num)
        startNum = num
        lastNum = num
    return buyNums
def DoStartNewRoundLuckyCloudBuy(zoneID, roundNum):
    # 开启新一轮云购
    crossZoneName = GameWorld.GetCrossZoneName()
    zoneIpyData = IpyGameDataPY.GetIpyGameData("CrossZonePK", crossZoneName, zoneID)
    if not zoneIpyData:
        return
    serverGroupIDList = zoneIpyData.GetServerGroupIDList()
    superItemInfo = GameWorld.GetResultByRandomList(IpyGameDataPY.GetFuncEvalCfg("LuckyCloudBuyAward", 3), [])
    if not superItemInfo or len(superItemInfo) < 3:
        GameWorld.ErrLog("幸运云购生成大奖失败! zoneID=%s,roundNum=%s,superItemInfo=%s" % (zoneID, roundNum, superItemInfo))
        return
    lotteryRec = LuckyCloudBuyLottery()
    lotteryRec.idTime = int(time.time())
    lotteryRec.zoneID = zoneID
    lotteryRec.roundNum = roundNum
    lotteryRec.serverGroupIDList = serverGroupIDList
    lotteryRec.superItemInfo = superItemInfo
    if zoneID not in PyGameData.g_luckyCloudBuyLotteryDict:
        PyGameData.g_luckyCloudBuyLotteryDict[zoneID] = []
    lotteryRecList = PyGameData.g_luckyCloudBuyLotteryDict[zoneID]
    lotteryRecList.append(lotteryRec)
    PyGameData.g_luckyCloudBuyNumDict[zoneID] = [] # 新一轮情况购买记录
    dataDict = {"Type":"NewRound"}
    dataDict.update(lotteryRec.GetString())
    DataRecordPack.SendEventPack("LuckyCloudBuyLottery", dataDict)
    # 广播子服开奖信息
    zoneLotteryInfo = {zoneID:[lotteryRec.GetString()]}
    dataMsg = {"syncType":"New", "zoneLotteryInfo":zoneLotteryInfo}
    CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_LuckyCloudBuyLottery, dataMsg, serverGroupIDList)
    return
def Sync_LuckyCloudBuyDataToClientServer(tick, serverGroupID=0):
    GameWorld.Log("同步给子服对应的幸运云购信息: syncServerGroupID=%s" % (serverGroupID))
    if serverGroupID:
        ipyData = CrossRealmPK.GetCrossPKServerGroupZone(serverGroupID)
        if not ipyData:
            return
        crossZoneList = [ipyData]
    else:
        crossZoneName = GameWorld.GetCrossZoneName()
        crossZoneList = IpyGameDataPY.GetIpyGameDataByCondition("CrossZonePK", {"CrossZoneName":crossZoneName}, True)
    if not crossZoneList:
        return
    #注: 开奖记录同步所有分区的开奖内容;购买记录仅同步自己分区的记录即可
    # 开奖记录
    zoneLotteryInfo = {}
    for zoneID, lotteryRecList in PyGameData.g_luckyCloudBuyLotteryDict.items():
        zoneLotteryList = []
        for lotteryRec in lotteryRecList:
            zoneLotteryList.append(lotteryRec.GetString())
        zoneLotteryInfo[zoneID] = zoneLotteryList
    for zoneIpyData in crossZoneList:
        zoneID = zoneIpyData.GetZoneID()
        serverGroupIDList = [serverGroupID] if serverGroupID else zoneIpyData.GetServerGroupIDList()
        dataMsg = {"syncType":"All", "zoneLotteryInfo":zoneLotteryInfo}
        CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_LuckyCloudBuyLottery, dataMsg, serverGroupIDList)
        # 购买记录
        zoneBuyNumList = []
        buyRecList = PyGameData.g_luckyCloudBuyNumDict.get(zoneID, [])
        for buyRec in buyRecList:
            zoneBuyNumList.append(buyRec.GetString())
        dataMsg = {"syncType":"All", "zoneID":zoneID, "zoneBuyNumList":zoneBuyNumList}
        CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_LuckyCloudBuyNum, dataMsg, serverGroupIDList)
    return
def CrossServerMsg_LuckyCloudBuyLottery(msgData):
    ## 子服收到开奖记录通知
    syncType = msgData["syncType"] # All New Update
    zoneLotteryInfo = msgData["zoneLotteryInfo"]
    serverGroupID = GameWorld.GetServerGroupID()
    zoneIpyData = CrossRealmPK.GetCrossPKServerGroupZone(serverGroupID)
    if not zoneIpyData:
        return
    serverZoneID = zoneIpyData.GetZoneID()
    syncMapLotteryRec = None # 有需要同步地图的,即有本分区的数据同步
    if syncType == "All":
        PyGameData.g_luckyCloudBuyLotteryDict = {}
    for zoneID, zoneLotteryList in zoneLotteryInfo.items():
        if zoneID not in PyGameData.g_luckyCloudBuyLotteryDict:
            PyGameData.g_luckyCloudBuyLotteryDict[zoneID] = []
        lotteryRecList = PyGameData.g_luckyCloudBuyLotteryDict[zoneID]
        GameWorld.Log("收到分区云购开奖记录同步信息: syncType=%s,zoneID=%s,count=%s" % (syncType, zoneID, zoneLotteryList))
        for attrDict in zoneLotteryList:
            if syncType in ["All", "New"]:
                lotteryRec = LuckyCloudBuyLottery()
                lotteryRec.SetAttrByDict(attrDict)
                lotteryRecList.append(lotteryRec)
                if zoneID == serverZoneID:
                    syncMapLotteryRec = lotteryRec
                # 本分区新轮次
                if syncType == "New" and zoneID == serverZoneID:
                    GameWorld.Log("    新增云购开奖记录信息: idTime=%s" % lotteryRec.idTime)
                    PyGameData.g_luckyCloudBuyNumDict[zoneID] = []
                    if len(lotteryRec.superItemInfo) >= 2:
                        superItemID, superItemCount = lotteryRec.superItemInfo[0], lotteryRec.superItemInfo[1]
                        PlayerControl.WorldNotify(0, "LuckyCloudBuyOpen", [superItemID, superItemCount])
            elif syncType == "Update":
                for lotteryRec in lotteryRecList[::-1]: # 一般是最后一个必命中
                    if lotteryRec.idTime == attrDict["idTime"] and lotteryRec.zoneID == attrDict["zoneID"]:
                        lotteryRec.SetAttrByDict(attrDict)
                        GameWorld.Log("    更新云购开奖记录信息: idTime=%s" % lotteryRec.idTime)
                        if zoneID != serverZoneID:
                            break
                        syncMapLotteryRec = lotteryRec
                        # 本分区开奖记录同步
                        if lotteryRec.lotteryNum:
                            if len(lotteryRec.superItemInfo) >= 2:
                                superItemID, superItemCount = lotteryRec.superItemInfo[0], lotteryRec.superItemInfo[1]
                                PlayerControl.WorldNotify(0, "LuckyCloudBuyClose", [lotteryRec.lotteryNum, lotteryRec.luckyPlayerName, superItemID, superItemCount])
                        break
    # 通知地图
    if syncMapLotteryRec:
        Sync_LuckyCloudBuyRoundInfo(None)
        GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_LuckyCloudBuyInfo, syncMapLotteryRec.GetString())
    return
def OnMapServerInitOK():
    # 通知地图服务器状态
    if GameWorld.IsCrossServer():
        return
    serverGroupID = GameWorld.GetServerGroupID()
    zoneIpyData = CrossRealmPK.GetCrossPKServerGroupZone(serverGroupID)
    if not zoneIpyData:
        return
    zoneID = zoneIpyData.GetZoneID()
    lotteryRecList = PyGameData.g_luckyCloudBuyLotteryDict.get(zoneID, [])
    lastLotteryRec = None if not lotteryRecList else lotteryRecList[-1]
    sendMsg = {} if not lastLotteryRec else lastLotteryRec.GetString()
    GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_LuckyCloudBuyInfo, sendMsg)
    return
def ClientServerMsg_LuckyCloudBuy(serverGroupID, msgData):
    ## 收到子服请求幸运云购购买
    zoneIpyData = CrossRealmPK.GetCrossPKServerGroupZone(serverGroupID)
    if not zoneIpyData:
        return
    zoneID = zoneIpyData.GetZoneID()
    accID = msgData["accID"]
    playerID = msgData["playerID"]
    playerName = msgData["playerName"]
    buyCount = msgData["buyCount"]
    roundID = msgData["roundID"]
    lotteryRecList = PyGameData.g_luckyCloudBuyLotteryDict.get(zoneID, [])
    if not lotteryRecList:
        return
    lotteryRec = lotteryRecList[-1]
    if roundID != lotteryRec.idTime or zoneID != lotteryRec.zoneID:
        GameWorld.ErrLog("幸运云购购买异常!奖池轮次信息不一致! roundID=%s,zoneID=%s, lotteryRec idTime=%s,zoneID=%s"
                          % (roundID, zoneID, lotteryRec.idTime, lotteryRec.zoneID))
        PlayerControl.CrossNotifyCode(serverGroupID, playerID, "LuckyCloudBuyError")
        return
    if lotteryRec.lotteryNum:
        GameWorld.ErrLog("幸运云购购买异常!已开奖,无法再购买! roundID=%s,zoneID=%s, lotteryNum=%s"
                          % (roundID, zoneID, lotteryRec.lotteryNum))
        PlayerControl.CrossNotifyCode(serverGroupID, playerID, "LuckyCloudBuyError")
        return
    buyRecList = PyGameData.g_luckyCloudBuyNumDict.get(zoneID, [])
    maxBuyCount = IpyGameDataPY.GetFuncCfg("LuckyCloudBuySet", 2)
    remainCount = max(0, maxBuyCount - len(buyRecList))
    if remainCount < buyCount:
        GameWorld.ErrLog("幸运云购购买异常!剩余可购买的份数不足! remainCount=%s < buyCount=%s" % (remainCount, buyCount))
        PlayerControl.CrossNotifyCode(serverGroupID, playerID, "LuckyCloudBuyError")
        return
    preBuyRec = None if not buyRecList else buyRecList[-1]
    startNum = 1 if not preBuyRec else (preBuyRec.buyNum + 1)
    buyNumList = range(startNum, startNum + buyCount)
    zoneBuyNumList = []
    for buyNum in buyNumList:
        buyRec = LuckyCloudBuyNum()
        buyRec.idTime = roundID
        buyRec.zoneID = zoneID
        buyRec.roundNum = lotteryRec.roundNum
        buyRec.playerID = playerID
        buyRec.buyNum = buyNum
        buyRec.buyTime = int(time.time())
        buyRec.playerName = playerName
        buyRec.accID = accID
        if zoneID not in PyGameData.g_luckyCloudBuyNumDict:
            PyGameData.g_luckyCloudBuyNumDict[zoneID] = []
        buyRecList = PyGameData.g_luckyCloudBuyNumDict[zoneID]
        buyRecList.append(buyRec)
        zoneBuyNumList.append(buyRec.GetString())
    dataDict = {"PlayerID":playerID, "AccID":accID, "zoneID":zoneID, "roundID":roundID, "roundNum":lotteryRec.roundNum,
                "buyNumList":buyNumList, "buyCount":buyCount, "remainCount":(remainCount - buyCount)}
    DataRecordPack.SendEventPack("LuckyCloudBuyNum", dataDict)
    # 通知子服
    dataMsg = {"syncType":"New", "zoneID":zoneID, "zoneBuyNumList":zoneBuyNumList, "buyPlayer":[serverGroupID, playerID, roundID, buyCount]}
    serverGroupIDList = zoneIpyData.GetServerGroupIDList()
    CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_LuckyCloudBuyNum, dataMsg, serverGroupIDList)
    # 结算开奖
    if remainCount == buyCount:
        DoLuckyCloudBuyLottery(lotteryRec, False, "SoldOut")
    return
def DoGMLuckyCloudBuy(serverGroupID, buyCount):
    GameWorld.Log("GM添加云购记录! serverGroupID=%s,buyCount=%s" % (serverGroupID, buyCount))
    zoneIpyData = CrossRealmPK.GetCrossPKServerGroupZone(serverGroupID)
    if not zoneIpyData:
        return
    zoneID = zoneIpyData.GetZoneID()
    lotteryRecList = PyGameData.g_luckyCloudBuyLotteryDict.get(zoneID, [])
    if not lotteryRecList:
        return
    lotteryRec = lotteryRecList[-1]
    buyRecList = PyGameData.g_luckyCloudBuyNumDict.get(zoneID, [])
    maxBuyCount = IpyGameDataPY.GetFuncCfg("LuckyCloudBuySet", 2)
    remainCount = max(0, maxBuyCount - len(buyRecList))
    buyCount = min(buyCount, remainCount)
    if buyCount <= 0:
        GameWorld.ErrLog("GM幸运云购购买异常!剩余可购买的份数不足!buyCount=%s" % buyCount)
        return
    preBuyRec = None if not buyRecList else buyRecList[-1]
    startNum = 1 if not preBuyRec else (preBuyRec.buyNum + 1)
    buyNumList = range(startNum, startNum + buyCount)
    buyPlayerID = random.choice([1001, 1002, 1003]) # 随机选一个GM测试playerID
    zoneBuyNumList = []
    for buyNum in buyNumList:
        buyRec = LuckyCloudBuyNum()
        buyRec.idTime = lotteryRec.idTime
        buyRec.zoneID = zoneID
        buyRec.roundNum = lotteryRec.roundNum
        buyRec.playerID = buyPlayerID
        buyRec.buyNum = buyNum
        buyRec.buyTime = int(time.time())
        buyRec.playerName = "[s%s]playerName_%s" % (serverGroupID, buyPlayerID)
        buyRec.accID = "accID_%s@test@s%s" % (buyPlayerID, serverGroupID)
        if zoneID not in PyGameData.g_luckyCloudBuyNumDict:
            PyGameData.g_luckyCloudBuyNumDict[zoneID] = []
        buyRecList = PyGameData.g_luckyCloudBuyNumDict[zoneID]
        buyRecList.append(buyRec)
        zoneBuyNumList.append(buyRec.GetString())
    # 通知子服
    dataMsg = {"syncType":"New", "zoneID":zoneID, "zoneBuyNumList":zoneBuyNumList}
    serverGroupIDList = zoneIpyData.GetServerGroupIDList()
    CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_LuckyCloudBuyNum, dataMsg, serverGroupIDList)
    # 结算开奖
    if remainCount == buyCount:
        DoLuckyCloudBuyLottery(lotteryRec, False, "SoldOut")
    return
def CrossServerMsg_LuckyCloudBuyNum(msgData):
    ## 子服收到购买记录通知
    syncType = msgData["syncType"] # All New
    zoneID = msgData["zoneID"]
    zoneBuyNumList = msgData["zoneBuyNumList"]
    if syncType == "All":
        PyGameData.g_luckyCloudBuyNumDict = {}
    if zoneID not in PyGameData.g_luckyCloudBuyNumDict:
        PyGameData.g_luckyCloudBuyNumDict[zoneID] = []
    buyRecList = PyGameData.g_luckyCloudBuyNumDict[zoneID]
    syncRecList = []
    for attrDict in zoneBuyNumList:
        buyRec = LuckyCloudBuyNum()
        buyRec.SetAttrByDict(attrDict)
        buyRecList.append(buyRec)
        if syncType == "New":
            syncRecList.append(buyRec)
    if syncType == "New":
        Sync_LuckyCloudBuyRoundInfo(None)
    if syncRecList:
        Sync_LuckyCloudBuyNumRecInfo(None, syncRecList)
    buyPlayer = msgData.get("buyPlayer")
    if not buyPlayer:
        return
    serverGroupID, playerID, roundID, buyCount = buyPlayer
    curServerGroupID = GameWorld.GetServerGroupID()
    if curServerGroupID != serverGroupID:
        #GameWorld.DebugLog("非本服玩家购买云购,不通知地图玩家处理!curServerGroupID=%s,buyPlayerServerGroupID=%s"
        #                   % (curServerGroupID, serverGroupID), playerID)
        return
    player = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
    if not player:
        GameWorld.Log("玩家不在线先缓存,玩家上线后再同步云购! roundID=%s,buyCount=%s" % (roundID, buyCount), playerID)
        PyGameData.g_unNotifyCloudBuyNumDict[playerID] = [roundID, buyCount]
        return
    mapID = player.GetRealMapID()
    sysMsg = str(["LuckyCloudBuyNum", roundID, buyCount])
    player.MapServer_QueryPlayerResult(0, 0, "LuckyCloudBuy", sysMsg, len(sysMsg))
    GameWorld.Log("通知地图跨服云购购买结算: roundID=%s,buyCount=%s,mapID=%s" % (roundID, buyCount, mapID), playerID)
    return
def __LoginNotifyMapCloudBuyNumInfo(curPlayer):
    playerID = curPlayer.GetPlayerID()
    if playerID not in PyGameData.g_unNotifyCloudBuyNumDict:
        return
    roundID, buyCount = PyGameData.g_unNotifyCloudBuyNumDict.pop(playerID)
    mapID = curPlayer.GetRealMapID()
    sysMsg = str(["LuckyCloudBuyNum", roundID, buyCount])
    curPlayer.MapServer_QueryPlayerResult(0, 0, "LuckyCloudBuy", sysMsg, len(sysMsg))
    GameWorld.Log("上线补通知地图跨服云购购买结算: roundID=%s,buyCount=%s,mapID=%s" % (roundID, buyCount, mapID), playerID)
    return
#// C0 05 查询幸运云购购买号码记录 #tagCGQueryLuckyCloudBuyNumRec
#
#struct    tagCGQueryLuckyCloudBuyNumRec
#{
#    tagHead        Head;
#};
def OnQueryLuckyCloudBuyNumRec(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    if GameWorld.IsCrossServer():
        return
    Sync_LuckyCloudBuyNumRecInfo(curPlayer)
    return
#// C0 06 查询幸运云购开奖记录 #tagCGQueryLuckyCloudBuyLotteryRec
#
#struct    tagCGQueryLuckyCloudBuyLotteryRec
#{
#    tagHead        Head;
#    BYTE        ZoneID;    //查询分区ID,分区同跨服PK分区
#};
def OnQueryLuckyCloudBuyLotteryRec(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    if GameWorld.IsCrossServer():
        return
    zoneID = clientData.ZoneID
    Sync_LuckyCloudBuyLotteryRecInfo(curPlayer, zoneID)
    return
def Sync_LuckyCloudBuyRoundInfo(curPlayer):
    serverGroupID = GameWorld.GetServerGroupID()
    zoneIpyData = CrossRealmPK.GetCrossPKServerGroupZone(serverGroupID)
    if not zoneIpyData:
        return
    zoneID = zoneIpyData.GetZoneID()
    lotteryRecList = PyGameData.g_luckyCloudBuyLotteryDict.get(zoneID, [])
    lotteryRec = None if not lotteryRecList else lotteryRecList[-1] # 取最新一期的
    if not lotteryRec:
        return
    buyRecList = PyGameData.g_luckyCloudBuyNumDict.get(zoneID, [])
    maxBuyCount = IpyGameDataPY.GetFuncCfg("LuckyCloudBuySet", 2)
    superItemInfo = lotteryRec.superItemInfo + [0, 0, 0, 0, 0]
    superItemID, superItemCount, _, moneyType, moneyValue = superItemInfo[:5]
    clientPack = ChPyNetSendPack.tagGCLuckyCloudBuyRoundInfo()
    clientPack.RoundID = lotteryRec.idTime
    clientPack.RoundNum = lotteryRec.roundNum
    clientPack.SuperItemID = superItemID
    clientPack.SuperItemCount = superItemCount
    clientPack.SuperItemMoneyType = moneyType
    clientPack.SuperItemMoneyValue = moneyValue
    clientPack.RemainCount = max(0, maxBuyCount - len(buyRecList))
    if not curPlayer:
        playerManager = GameWorld.GetPlayerManager()
        for i in xrange(playerManager.GetActivePlayerCount()):
            curPlayer = playerManager.GetActivePlayerAt(i)
            if curPlayer == None:
                continue
            if PlayerControl.GetIsTJG(curPlayer):
                continue
            NetPackCommon.SendFakePack(curPlayer, clientPack)
    else:
        if PlayerControl.GetIsTJG(curPlayer):
            return
        NetPackCommon.SendFakePack(curPlayer, clientPack)
    return
def Sync_LuckyCloudBuyNumRecInfo(curPlayer, syncRecList=None):
    if syncRecList == None:
        serverGroupID = GameWorld.GetServerGroupID()
        zoneIpyData = CrossRealmPK.GetCrossPKServerGroupZone(serverGroupID)
        if not zoneIpyData:
            return
        zoneID = zoneIpyData.GetZoneID()
        lotteryRecList = PyGameData.g_luckyCloudBuyLotteryDict.get(zoneID, [])
        lotteryRec = None if not lotteryRecList else lotteryRecList[-1] # 取最新一期的
        if not lotteryRec:
            return
        buyRecList = PyGameData.g_luckyCloudBuyNumDict.get(zoneID, [])
        syncRecList = buyRecList[-50:]
    clientPack = ChPyNetSendPack.tagGCLuckyCloudBuyNumRecInfo()
    clientPack.BuyNumRecList = []
    for buyRec in syncRecList:
        buyNumInfo = ChPyNetSendPack.tagGCLuckyCloudBuyNumRec()
        buyNumInfo.PlayerName = buyRec.playerName
        buyNumInfo.NameLen = len(buyNumInfo.PlayerName)
        buyNumInfo.BuyNum = buyRec.buyNum
        clientPack.BuyNumRecList.append(buyNumInfo)
    clientPack.Count = len(clientPack.BuyNumRecList)
    if not curPlayer:
        playerManager = GameWorld.GetPlayerManager()
        for i in xrange(playerManager.GetActivePlayerCount()):
            curPlayer = playerManager.GetActivePlayerAt(i)
            if curPlayer == None:
                continue
            if PlayerControl.GetIsTJG(curPlayer):
                continue
            NetPackCommon.SendFakePack(curPlayer, clientPack)
    else:
        if PlayerControl.GetIsTJG(curPlayer):
            return
        NetPackCommon.SendFakePack(curPlayer, clientPack)
    return
def Sync_LuckyCloudBuyLotteryRecInfo(curPlayer, zoneID, syncRec=None):
    if syncRec == None:
        lotteryRecList = PyGameData.g_luckyCloudBuyLotteryDict.get(zoneID, [])
    else:
        lotteryRecList = [syncRec]
    clientPack = ChPyNetSendPack.tagGCLuckyCloudBuyLotteryRecInfo()
    clientPack.ZoneID = zoneID
    clientPack.LotteryRecList = []
    for lotteryRec in lotteryRecList:
        if not lotteryRec.lotteryNum:
            # 未开奖的暂不同步
            continue
        lotteryInfo = ChPyNetSendPack.tagGCLuckyCloudBuyLotteryRec()
        lotteryInfo.SuperItemID = lotteryRec.superItemInfo[0] if len(lotteryRec.superItemInfo) > 0 else 0
        lotteryInfo.SuperItemCount = lotteryRec.superItemInfo[1] if len(lotteryRec.superItemInfo) > 1 else 0
        lotteryInfo.PlayerName = lotteryRec.luckyPlayerName
        lotteryInfo.NameLen = len(lotteryInfo.PlayerName)
        lotteryInfo.LotteryNum = lotteryRec.lotteryNum
        lotteryInfo.LotteryTime = lotteryRec.lotteryTime
        clientPack.LotteryRecList.append(lotteryInfo)
    clientPack.Count = len(clientPack.LotteryRecList)
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py
@@ -18,6 +18,7 @@
import GameWorld
import ShareDefine
import PlayerControl
import CrossLuckyCloudBuy
import IPY_GameServer
import CrossRealmPlayer
import PlayerCompensation
@@ -27,6 +28,7 @@
import CrossRealmPK
import PlayerQuery
import PlayerTalk
import PyGameData
import CrossBoss
import ChConfig
import PlayerFB
@@ -34,6 +36,7 @@
import traceback
import cPickle
import time
def SendMsgToCrossServer(msgType, dataMsg):
    ## 发送信息到跨服服务器上
@@ -80,6 +83,9 @@
            
        elif msgType == ShareDefine.ClientServerMsg_PKBillboard:
            CrossRealmPK.ClientServerMsg_PKBillboard(serverGroupID, msgData)
        elif msgType == ShareDefine.ClientServerMsg_LuckyCloudBuy:
            CrossLuckyCloudBuy.ClientServerMsg_LuckyCloudBuy(serverGroupID, msgData)
            
        elif msgType == ShareDefine.ClientServerMsg_QueryBillboard:
            CrossBillboard.ClientServerMsg_QueryBillboard(serverGroupID, msgData)
@@ -144,6 +150,7 @@
    CrossRealmPlayer.Sync_CrossCommInitDataToClientServer(serverGroupID)
    CrossRealmPK.Sync_CrossPKInitDataToClientServer(tick, serverGroupID)
    CrossBoss.Sync_CrossBossInitDataToClientServer(serverGroupID)
    CrossLuckyCloudBuy.Sync_LuckyCloudBuyDataToClientServer(tick, serverGroupID)
    CrossActionControl.Sync_CrossActInfoToClientServer(serverGroupID)
    PlayerCompensation.Sync_CrossMailPlayerIDToClientServer(serverGroupID)
    return
@@ -198,7 +205,7 @@
    if not dataMsg:
        return
    
    srcMsg = {"MsgType":msgType, "Data":dataMsg}
    srcMsg = {"MsgType":msgType, "Data":dataMsg, "CrossServerTime":GameWorld.GetCurrentDataTimeStr()}
    sendMsg = cPickle.dumps(srcMsg, 2)
    if not GameWorld.GetGameWorld().GetDictByKey(ChConfig.Def_WorldKey_GameWorldInitOK):
        GameWorld.ErrLog("跨服服务器未启动好,不允许向子服发送数据! serverGroupIDList=%s, srcMsg=%s" % (serverGroupIDList, srcMsg))
@@ -227,8 +234,22 @@
        msgDict = cPickle.loads(dataMsg)
        msgType = msgDict.get("MsgType", -1)    
        msgData = msgDict.get("Data", "")
        crossServerTimeStr = msgDict.get("CrossServerTime", "")
        GameWorld.Log("OnClientServerReceiveMsg: %s" % msgDict)
        if crossServerTimeStr:
            curServerTime = int(time.time())
            crossServerTime = GameWorld.ChangeTimeStrToNum(crossServerTimeStr)
            curServerCrossServerTime = GameWorld.ChangeTimeStrToNum(GameWorld.GetCrossServerTimeStr())
            diffSeconds = curServerCrossServerTime - crossServerTime# 本服计算误差
            _, _, syncMapTime = PyGameData.g_crossServerTimeInfo
            PyGameData.g_crossServerTimeInfo = [crossServerTime, curServerTime, syncMapTime]
            if curServerTime - syncMapTime >= 600 or abs(diffSeconds) >= 30 or msgType == ShareDefine.CrossServerMsg_CrossServerTime: # 一定时间同步地图一次 或计算 误差超过30秒 或强制同步时间的
                GameWorld.DebugLog("同步地图跨服服务器时间时,本服与跨服服务器时间计算误差! diffSeconds=%s" % (diffSeconds))
                syncMapTime = curServerTime
                PyGameData.g_crossServerTimeInfo = [crossServerTime, curServerTime, syncMapTime]
                GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_CrossServerTime, PyGameData.g_crossServerTimeInfo)
        if msgType == ShareDefine.CrossServerMsg_ExitCrossServer:
            CrossRealmPlayer.CrossServerMsg_ExitCrossServer(msgData)
            
@@ -261,6 +282,12 @@
            
        elif msgType == ShareDefine.CrossServerMsg_PKSyncBillboard:
            CrossRealmPK.CrossServerMsg_PKSyncBillboard(msgData)
        elif msgType == ShareDefine.CrossServerMsg_LuckyCloudBuyLottery:
            CrossLuckyCloudBuy.CrossServerMsg_LuckyCloudBuyLottery(msgData)
        elif msgType == ShareDefine.CrossServerMsg_LuckyCloudBuyNum:
            CrossLuckyCloudBuy.CrossServerMsg_LuckyCloudBuyNum(msgData)
            
        elif msgType == ShareDefine.CrossServerMsg_SyncBillboard:
            CrossBillboard.CrossServerMsg_SyncBillboard(msgData, tick)
@@ -309,6 +336,13 @@
        elif msgType == ShareDefine.CrossServerMsg_CrossServerState:
            CrossRealmPlayer.CrossServerMsg_CrossServerState(msgData)
            
        elif msgType == ShareDefine.CrossServerMsg_CrossServerTime:
            playerID = msgData.get("PlayerID")
            if playerID:
                tagPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
                if tagPlayer:
                    GameWorld.DebugAnswer(tagPlayer, "跨服服务器时间: %s" % GameWorld.GetCrossServerTimeStr())
        else:
            GameWorld.ErrLog("没有该信息类型逻辑处理!")
            
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py
@@ -98,6 +98,7 @@
import PlayerFamilyParty
import GameWorldFamilyWar
import GameWorldArena
import CrossLuckyCloudBuy
import AuctionHouse
import PlayerXMZZ
import PlayerLove
@@ -175,6 +176,8 @@
    GameWorldFamilyWar.DoOnDay()
    # 情缘
    PlayerLove.DoOnDay()
    # 云购
    CrossLuckyCloudBuy.DoOnDay()
    return
def OnDayEx(tick):
@@ -374,6 +377,10 @@
        PlayerFamily.UpdFamilyTotalFightPower()
        PlayerFamilyRedPacket.CheckDelRedpacketData()
        
    return
def OnReloadConfig():
    CrossLuckyCloudBuy.CheckLuckyCloudBuyZoneInfoChange()
    return
#---------------------------------------------------------------------
@@ -1252,6 +1259,8 @@
    CrossRealmPK.OnGameServerInitOK()
    #红包
    PlayerFamilyRedPacket.OnServerStart()
    #云购
    CrossLuckyCloudBuy.OnServerStart()
    #世界boss被杀次数重置
    #GameWorldBoss.CheckResetBossKilledCntOnServerInit()
    
@@ -1433,6 +1442,7 @@
    GameWorldFamilyWar.OnMapServerInitOK()
    
    # 跨服服务器状态
    GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_CrossServerTime, PyGameData.g_crossServerTimeInfo)
    isCrossServerOpen = GameWorld.GetGameWorld().GetDictByKey(ShareDefine.Def_Notify_WorldKey_CrossServerOpen)
    GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_CrossServerOpen, isCrossServerOpen)
    GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_CrossZoneName, PyGameData.g_crossZoneName)
@@ -1441,6 +1451,8 @@
    CrossRealmPK.OnMapServerInitOK()
    # 本服竞技场
    GameWorldArena.SendMapServerArenaInfo()
    # 幸运云购
    CrossLuckyCloudBuy.OnMapServerInitOK()
    
    SendAllMapGlobalDropInfo() # 全局掉落控制
    
@@ -1951,6 +1963,7 @@
    PlayerFBHelpBattle.OnServerClose()
    CrossActionControl.OnServerClose()
    PlayerFamilyRedPacket.OnServerClose()
    CrossLuckyCloudBuy.OnServerClose()
    GameWorldArena.OnServerClose()
    PlayerLove.OnServerClose()
    GameWorld.Log("通知C++关服!")
ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py
@@ -62,6 +62,7 @@
import GMShell
import IPY_PlayerDefine
import GameWorldArena
import CrossLuckyCloudBuy
import CrossRealmPK
import AuctionHouse
import PlayerAssist
@@ -186,6 +187,8 @@
        GameWorldArena.OnPlayerLogin(curPlayer)
        #跨服PK
        CrossRealmPK.OnPlayerLogin(curPlayer)
        #幸运云购
        CrossLuckyCloudBuy.OnPlayerLogin(curPlayer)
        #诛仙BOSS
        PlayerZhuXianBoss.OnPlayerLogin(curPlayer)
        #骑宠boss状态通知
@@ -1216,7 +1219,8 @@
    serverDateTime.Hour = serverTime.hour
    serverDateTime.Minute = serverTime.minute
    serverDateTime.Second = serverTime.second
    serverDateTime.MicSecond = serverTime.microsecond
    serverDateTime.MicSecond = serverTime.microsecond
    serverDateTime.CrossServerTime = GameWorld.GetCrossServerTimeStr()
    
    # 通知客户端同步时间
    NetPackCommon.SendFakePack(curPlayer, serverDateTime)
ServerPython/CoreServerGroup/GameServer/Script/PyGameData.py
@@ -102,6 +102,12 @@
g_crossZoneName = "" # 跨服分区名
g_crossServerTimeInfo = [0, 0, 0] # 跨服时间信息 [crossServerTime, curServerTime, syncMapTime]
g_luckyCloudBuyNumDict = {} # 幸运云购购买记录 {zoneID:[LuckyCloudBuyNum, ...], ...}
g_luckyCloudBuyLotteryDict = {} # 幸运云购开奖记录 {zoneID:[LuckyCloudBuyLottery, ...], ...}
g_unNotifyCloudBuyNumDict = {} # 未通知的跨服云购购买信息 {playerID:msgData, ...}
g_crossActInfoDict = None # 跨服运营活动信息 {actName:{actInfoDict}, ...}
g_playerDelMailGUIDDict = {} # 玩家邮件GUID信息 {playerID:[GUID, ...], ...} 仅触发删除才有数据,且并不一定所有GUID都存在,仅作为删除邮件时用到
ServerPython/CoreServerGroup/GameServer/Script/ReadChConfig.py
@@ -295,6 +295,8 @@
    ClearAllConfig()
    GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_ReloadConfig, 1)
    IpyGameDataPY.IPYData.IpyDataClear()
    import GameWorldProcess
    GameWorldProcess.OnReloadConfig()
    return
ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
@@ -177,10 +177,13 @@
Def_Notify_WorldKey_CrossServerConnState = "CrossServerConnState"  # 跨服服务器链接状态
Def_Notify_WorldKey_CrossServerOpen = "CrossServerOpen"  # 跨服服务器是否开启中
Def_Notify_WorldKey_CrossZoneName = "CrossZoneName"  # 跨服分区名
Def_Notify_WorldKey_CrossServerTime = "CrossServerTime"  # 跨服时间
Def_Notify_WorldKey_CrossPKZoneID = "CrossPKZoneID"  # 本服跨服PK所属赛区
Def_Notify_WorldKey_CrossPKSeasonID = "CrossPKSeasonID"  # 本服跨服PK当前赛季
Def_Notify_WorldKey_CrossPKSeasonState = "CrossPKSeasonState"  # 本服跨服PK赛季状态 0-关闭,1-开启中
Def_Notify_WorldKey_LuckyCloudBuyInfo = "LuckyCloudBuyInfo"  # 本服幸运云购最新一期信息
Def_Notify_WorldKey_GameWorldBossRebornCross = 'BossRebornCross_%s_%s'   # 跨服世界boss重生, 参数为(zoneID, bossID)
Def_Notify_WorldKey_GameWorldBossReborn = 'BossReborn_%s'   # 世界boss重生, 参数为(bossID)
@@ -1170,8 +1173,8 @@
                                Def_UniversalGameRecType_ActWorldLVLimitInfo, # 运营活动世界等级限制开启信息 18
                                Def_UniversalGameRecType_19,
                                Def_UniversalGameRecType_20,
                                Def_UniversalGameRecType_21,
                                Def_UniversalGameRecType_22,
                                Def_UniversalGameRecType_LuckyCloudBuyNum, # 幸运云购购买号码记录 21
                                Def_UniversalGameRecType_LuckyCloudBuyLottery, # 幸运云购开奖记录 22
                                Def_UniversalGameRecType_23,
                                Def_UniversalGameRecType_UpdatePlayerName,  # 玩家改名正在改名中的信息24
                                Def_UniversalGameRecType_BossDropGoodItemInfo,  # boss掉落好物品信息记录25
@@ -1368,6 +1371,9 @@
CrossServerMsg_CrossActInfo = "CrossActInfo"            # 跨服运营活动信息
CrossServerMsg_MailPlayerIDList = "MailPlayerIDList"    # 跨服邮件玩家ID通知,玩家目标服务器可能无法知道,被动推送
CrossServerMsg_MailContent = "MailContent"              # 跨服邮件内容通知
CrossServerMsg_LuckyCloudBuyNum = "LuckyCloudBuyNum"    # 幸运云购购买记录通知
CrossServerMsg_LuckyCloudBuyLottery = "LuckyCloudBuyLottery"    # 幸运云购开奖记录通知
CrossServerMsg_CrossServerTime = "CrossServerTime"      # 跨服时间同步
# 子服发送跨服信息定义
ClientServerMsg_ServerInitOK = "ServerInitOK"           # 子服启动成功
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
@@ -638,6 +638,18 @@
PacketSubCMD_1=0x04
PacketCallFunc_1=OnExitCrossRealm
;幸运云购
[PlayerLuckyCloudBuy]
ScriptName = Player\PlayerLuckyCloudBuy.py
Writer = hxp
Releaser = hxp
RegType = 0
RegisterPackCount = 1
PacketCMD_1=0xC1
PacketSubCMD_1=0x10
PacketCallFunc_1=OnLuckyCloudBuy
;改名功能
[UpdatePlayerName]
ScriptName = Player\UpdatePlayerName.py
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -2255,6 +2255,8 @@
                         1000 * 5,                        # 请求协助间隔
                         1000 * 10,                        # 竞技场间隔
                         1000 * 5,                        # 情缘
                         1000 * 10,                        # 跨服战场
                         1000 * 10,                        # 幸运云购
                         ]
TYPE_Player_Tick_Count = len(TYPE_Player_Tick_Time) 
@@ -2331,6 +2333,8 @@
TYPE_Player_Tick_RequestAssist,        #请求协助间隔
TYPE_Player_Tick_Arena,        #竞技场间隔
TYPE_Player_Tick_Love,        #情缘
TYPE_Player_Tick_Battlefield,        #跨服战场
TYPE_Player_Tick_LuckyCloudBuy,        #幸运云购
) = range(0, TYPE_Player_Tick_Count)
#---------------------------------------------------------------------
@@ -4054,6 +4058,10 @@
Def_PDict_CrossPK_SeasonOrder = "CrossPK_SeasonOrder_%s" # 历史赛季名次,参数,赛季ID
Def_PDict_CrossPK_SeasonAwardLV = "CrossPK_SeasonAwardLV_%s" # 历史赛季奖励等级(一般是段位等级,排行奖励的在最高段位等级基础上增加),参数,赛季ID
# 跨服幸运云购
Def_PDict_LuckyCloudBuy_RoundID = "LuckyCloudBuy_RoundID" # 本轮标识ID
Def_PDict_LuckyCloudBuy_BuyCount = "LuckyCloudBuy_BuyCount" # 本轮已购买份数
#自动战斗设置记录
Def_PDict_AutoFightSetting = "AFSetting_%s_%s"
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
@@ -4035,6 +4035,106 @@
#------------------------------------------------------
# C0 06 查询幸运云购开奖记录 #tagCGQueryLuckyCloudBuyLotteryRec
class  tagCGQueryLuckyCloudBuyLotteryRec(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("ZoneID", c_ubyte),    #查询分区ID,分区同跨服PK分区
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xC0
        self.SubCmd = 0x06
        return
    def ReadData(self, stringData, _pos=0, _len=0):
        self.Clear()
        memmove(addressof(self), stringData[_pos:], self.GetLength())
        return _pos + self.GetLength()
    def Clear(self):
        self.Cmd = 0xC0
        self.SubCmd = 0x06
        self.ZoneID = 0
        return
    def GetLength(self):
        return sizeof(tagCGQueryLuckyCloudBuyLotteryRec)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// C0 06 查询幸运云购开奖记录 //tagCGQueryLuckyCloudBuyLotteryRec:
                                Cmd:%s,
                                SubCmd:%s,
                                ZoneID:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.ZoneID
                                )
        return DumpString
m_NAtagCGQueryLuckyCloudBuyLotteryRec=tagCGQueryLuckyCloudBuyLotteryRec()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCGQueryLuckyCloudBuyLotteryRec.Cmd,m_NAtagCGQueryLuckyCloudBuyLotteryRec.SubCmd))] = m_NAtagCGQueryLuckyCloudBuyLotteryRec
#------------------------------------------------------
# C0 05 查询幸运云购购买号码记录 #tagCGQueryLuckyCloudBuyNumRec
class  tagCGQueryLuckyCloudBuyNumRec(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xC0
        self.SubCmd = 0x05
        return
    def ReadData(self, stringData, _pos=0, _len=0):
        self.Clear()
        memmove(addressof(self), stringData[_pos:], self.GetLength())
        return _pos + self.GetLength()
    def Clear(self):
        self.Cmd = 0xC0
        self.SubCmd = 0x05
        return
    def GetLength(self):
        return sizeof(tagCGQueryLuckyCloudBuyNumRec)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// C0 05 查询幸运云购购买号码记录 //tagCGQueryLuckyCloudBuyNumRec:
                                Cmd:%s,
                                SubCmd:%s
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd
                                )
        return DumpString
m_NAtagCGQueryLuckyCloudBuyNumRec=tagCGQueryLuckyCloudBuyNumRec()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCGQueryLuckyCloudBuyNumRec.Cmd,m_NAtagCGQueryLuckyCloudBuyNumRec.SubCmd))] = m_NAtagCGQueryLuckyCloudBuyNumRec
#------------------------------------------------------
# C0 04 查看跨服排行榜 #tagCGViewCrossBillboard
class  tagCGViewCrossBillboard(Structure):
@@ -19213,4 +19313,56 @@
m_NAtagCMExitCrossRealm=tagCMExitCrossRealm()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMExitCrossRealm.Cmd,m_NAtagCMExitCrossRealm.SubCmd))] = m_NAtagCMExitCrossRealm
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMExitCrossRealm.Cmd,m_NAtagCMExitCrossRealm.SubCmd))] = m_NAtagCMExitCrossRealm
#------------------------------------------------------
# C1 10 幸运云购购买 #tagCMLuckyCloudBuy
class  tagCMLuckyCloudBuy(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("BuyCount", c_ushort),    # 购买份数
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xC1
        self.SubCmd = 0x10
        return
    def ReadData(self, stringData, _pos=0, _len=0):
        self.Clear()
        memmove(addressof(self), stringData[_pos:], self.GetLength())
        return _pos + self.GetLength()
    def Clear(self):
        self.Cmd = 0xC1
        self.SubCmd = 0x10
        self.BuyCount = 0
        return
    def GetLength(self):
        return sizeof(tagCMLuckyCloudBuy)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// C1 10 幸运云购购买 //tagCMLuckyCloudBuy:
                                Cmd:%s,
                                SubCmd:%s,
                                BuyCount:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.BuyCount
                                )
        return DumpString
m_NAtagCMLuckyCloudBuy=tagCMLuckyCloudBuy()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMLuckyCloudBuy.Cmd,m_NAtagCMLuckyCloudBuy.SubCmd))] = m_NAtagCMLuckyCloudBuy
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
@@ -561,33 +561,41 @@
#A0 04 同步客户端时间 #tagServerDateTime
class  tagServerDateTime(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("Year", c_ushort),
                  ("Month", c_ubyte),
                  ("Day", c_ubyte),
                  ("Hour", c_ubyte),
                  ("Minute", c_ubyte),
                  ("Second", c_ubyte),
                  ("MicSecond", c_int),
                  ]
    Head = tagHead()
    Year = 0    #(WORD Year)
    Month = 0    #(BYTE Month)
    Day = 0    #(BYTE Day)
    Hour = 0    #(BYTE Hour)
    Minute = 0    #(BYTE Minute)
    Second = 0    #(BYTE Second)
    MicSecond = 0    #(DWORD MicSecond)
    CrossServerTime = ""    #(char CrossServerTime[19])
    data = None
    def __init__(self):
        self.Clear()
        self.Cmd = 0xA0
        self.SubCmd = 0x04
        self.Head.Cmd = 0xA0
        self.Head.SubCmd = 0x04
        return
    def ReadData(self, stringData, _pos=0, _len=0):
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        memmove(addressof(self), stringData[_pos:], self.GetLength())
        return _pos + self.GetLength()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.Year,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.Month,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.Day,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.Hour,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.Minute,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.Second,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.MicSecond,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.CrossServerTime,_pos = CommFunc.ReadString(_lpData, _pos,19)
        return _pos
    def Clear(self):
        self.Cmd = 0xA0
        self.SubCmd = 0x04
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xA0
        self.Head.SubCmd = 0x04
        self.Year = 0
        self.Month = 0
        self.Day = 0
@@ -595,42 +603,64 @@
        self.Minute = 0
        self.Second = 0
        self.MicSecond = 0
        self.CrossServerTime = ""
        return
    def GetLength(self):
        return sizeof(tagServerDateTime)
        length = 0
        length += self.Head.GetLength()
        length += 2
        length += 1
        length += 1
        length += 1
        length += 1
        length += 1
        length += 4
        length += 19
        return length
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteWORD(data, self.Year)
        data = CommFunc.WriteBYTE(data, self.Month)
        data = CommFunc.WriteBYTE(data, self.Day)
        data = CommFunc.WriteBYTE(data, self.Hour)
        data = CommFunc.WriteBYTE(data, self.Minute)
        data = CommFunc.WriteBYTE(data, self.Second)
        data = CommFunc.WriteDWORD(data, self.MicSecond)
        data = CommFunc.WriteString(data, 19, self.CrossServerTime)
        return data
    def OutputString(self):
        DumpString = '''//A0 04 同步客户端时间 //tagServerDateTime:
                                Cmd:%s,
                                SubCmd:%s,
        DumpString = '''
                                Head:%s,
                                Year:%d,
                                Month:%d,
                                Day:%d,
                                Hour:%d,
                                Minute:%d,
                                Second:%d,
                                MicSecond:%d
                                MicSecond:%d,
                                CrossServerTime:%s
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.Head.OutputString(),
                                self.Year,
                                self.Month,
                                self.Day,
                                self.Hour,
                                self.Minute,
                                self.Second,
                                self.MicSecond
                                self.MicSecond,
                                self.CrossServerTime
                                )
        return DumpString
m_NAtagServerDateTime=tagServerDateTime()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagServerDateTime.Cmd,m_NAtagServerDateTime.SubCmd))] = m_NAtagServerDateTime
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagServerDateTime.Head.Cmd,m_NAtagServerDateTime.Head.SubCmd))] = m_NAtagServerDateTime
#------------------------------------------------------
@@ -13266,6 +13296,352 @@
m_NAtagGCCrossRealmPKStartMatch=tagGCCrossRealmPKStartMatch()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCCrossRealmPKStartMatch.Cmd,m_NAtagGCCrossRealmPKStartMatch.SubCmd))] = m_NAtagGCCrossRealmPKStartMatch
#------------------------------------------------------
# C0 14 幸运云购开奖记录 #tagGCLuckyCloudBuyLotteryRecInfo
class  tagGCLuckyCloudBuyLotteryRec(Structure):
    SuperItemID = 0    #(DWORD SuperItemID)// 大奖物品ID
    SuperItemCount = 0    #(BYTE SuperItemCount)// 大奖物品个数
    NameLen = 0    #(BYTE NameLen)
    PlayerName = ""    #(String PlayerName)// 中奖玩家名
    LotteryNum = 0    #(WORD LotteryNum)// 开奖号码
    LotteryTime = 0    #(DWORD LotteryTime)// 开奖时间戳,秒
    data = None
    def __init__(self):
        self.Clear()
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        self.SuperItemID,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        self.SuperItemCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.NameLen,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.PlayerName,_pos = CommFunc.ReadString(_lpData, _pos,self.NameLen)
        self.LotteryNum,_pos = CommFunc.ReadWORD(_lpData, _pos)
        self.LotteryTime,_pos = CommFunc.ReadDWORD(_lpData, _pos)
        return _pos
    def Clear(self):
        self.SuperItemID = 0
        self.SuperItemCount = 0
        self.NameLen = 0
        self.PlayerName = ""
        self.LotteryNum = 0
        self.LotteryTime = 0
        return
    def GetLength(self):
        length = 0
        length += 4
        length += 1
        length += 1
        length += len(self.PlayerName)
        length += 2
        length += 4
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteDWORD(data, self.SuperItemID)
        data = CommFunc.WriteBYTE(data, self.SuperItemCount)
        data = CommFunc.WriteBYTE(data, self.NameLen)
        data = CommFunc.WriteString(data, self.NameLen, self.PlayerName)
        data = CommFunc.WriteWORD(data, self.LotteryNum)
        data = CommFunc.WriteDWORD(data, self.LotteryTime)
        return data
    def OutputString(self):
        DumpString = '''
                                SuperItemID:%d,
                                SuperItemCount:%d,
                                NameLen:%d,
                                PlayerName:%s,
                                LotteryNum:%d,
                                LotteryTime:%d
                                '''\
                                %(
                                self.SuperItemID,
                                self.SuperItemCount,
                                self.NameLen,
                                self.PlayerName,
                                self.LotteryNum,
                                self.LotteryTime
                                )
        return DumpString
class  tagGCLuckyCloudBuyLotteryRecInfo(Structure):
    Head = tagHead()
    ZoneID = 0    #(BYTE ZoneID)// 分区
    Count = 0    #(WORD Count)
    LotteryRecList = list()    #(vector<tagGCLuckyCloudBuyLotteryRec> LotteryRecList)
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xC0
        self.Head.SubCmd = 0x14
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.ZoneID,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        self.Count,_pos = CommFunc.ReadWORD(_lpData, _pos)
        for i in range(self.Count):
            temLotteryRecList = tagGCLuckyCloudBuyLotteryRec()
            _pos = temLotteryRecList.ReadData(_lpData, _pos)
            self.LotteryRecList.append(temLotteryRecList)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xC0
        self.Head.SubCmd = 0x14
        self.ZoneID = 0
        self.Count = 0
        self.LotteryRecList = list()
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 1
        length += 2
        for i in range(self.Count):
            length += self.LotteryRecList[i].GetLength()
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteBYTE(data, self.ZoneID)
        data = CommFunc.WriteWORD(data, self.Count)
        for i in range(self.Count):
            data = CommFunc.WriteString(data, self.LotteryRecList[i].GetLength(), self.LotteryRecList[i].GetBuffer())
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                ZoneID:%d,
                                Count:%d,
                                LotteryRecList:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.ZoneID,
                                self.Count,
                                "..."
                                )
        return DumpString
m_NAtagGCLuckyCloudBuyLotteryRecInfo=tagGCLuckyCloudBuyLotteryRecInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCLuckyCloudBuyLotteryRecInfo.Head.Cmd,m_NAtagGCLuckyCloudBuyLotteryRecInfo.Head.SubCmd))] = m_NAtagGCLuckyCloudBuyLotteryRecInfo
#------------------------------------------------------
# C0 13 幸运云购购买号码记录 #tagGCLuckyCloudBuyNumRecInfo
class  tagGCLuckyCloudBuyNumRec(Structure):
    NameLen = 0    #(BYTE NameLen)
    PlayerName = ""    #(String PlayerName)
    BuyNum = 0    #(WORD BuyNum)
    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.PlayerName,_pos = CommFunc.ReadString(_lpData, _pos,self.NameLen)
        self.BuyNum,_pos = CommFunc.ReadWORD(_lpData, _pos)
        return _pos
    def Clear(self):
        self.NameLen = 0
        self.PlayerName = ""
        self.BuyNum = 0
        return
    def GetLength(self):
        length = 0
        length += 1
        length += len(self.PlayerName)
        length += 2
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteBYTE(data, self.NameLen)
        data = CommFunc.WriteString(data, self.NameLen, self.PlayerName)
        data = CommFunc.WriteWORD(data, self.BuyNum)
        return data
    def OutputString(self):
        DumpString = '''
                                NameLen:%d,
                                PlayerName:%s,
                                BuyNum:%d
                                '''\
                                %(
                                self.NameLen,
                                self.PlayerName,
                                self.BuyNum
                                )
        return DumpString
class  tagGCLuckyCloudBuyNumRecInfo(Structure):
    Head = tagHead()
    Count = 0    #(WORD Count)
    BuyNumRecList = list()    #(vector<tagGCLuckyCloudBuyNumRec> BuyNumRecList)
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xC0
        self.Head.SubCmd = 0x13
        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):
            temBuyNumRecList = tagGCLuckyCloudBuyNumRec()
            _pos = temBuyNumRecList.ReadData(_lpData, _pos)
            self.BuyNumRecList.append(temBuyNumRecList)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xC0
        self.Head.SubCmd = 0x13
        self.Count = 0
        self.BuyNumRecList = list()
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 2
        for i in range(self.Count):
            length += self.BuyNumRecList[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.BuyNumRecList[i].GetLength(), self.BuyNumRecList[i].GetBuffer())
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                Count:%d,
                                BuyNumRecList:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.Count,
                                "..."
                                )
        return DumpString
m_NAtagGCLuckyCloudBuyNumRecInfo=tagGCLuckyCloudBuyNumRecInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCLuckyCloudBuyNumRecInfo.Head.Cmd,m_NAtagGCLuckyCloudBuyNumRecInfo.Head.SubCmd))] = m_NAtagGCLuckyCloudBuyNumRecInfo
#------------------------------------------------------
# C0 12 幸运云购轮次信息 #tagGCLuckyCloudBuyRoundInfo
class  tagGCLuckyCloudBuyRoundInfo(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("RoundID", c_int),    # 轮次唯一ID标识,当收到的轮次ID变更时,前端需清空购买号码记录缓存
                  ("RoundNum", c_ubyte),    # 今日第几轮
                  ("SuperItemID", c_int),    # 大奖物品ID
                  ("SuperItemCount", c_ubyte),    # 大奖物品个数
                  ("SuperItemMoneyType", c_ubyte),    # 大奖价值货币类型
                  ("SuperItemMoneyValue", c_int),    # 大奖价值
                  ("RemainCount", c_ushort),    # 开奖剩余份数
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xC0
        self.SubCmd = 0x12
        return
    def ReadData(self, stringData, _pos=0, _len=0):
        self.Clear()
        memmove(addressof(self), stringData[_pos:], self.GetLength())
        return _pos + self.GetLength()
    def Clear(self):
        self.Cmd = 0xC0
        self.SubCmd = 0x12
        self.RoundID = 0
        self.RoundNum = 0
        self.SuperItemID = 0
        self.SuperItemCount = 0
        self.SuperItemMoneyType = 0
        self.SuperItemMoneyValue = 0
        self.RemainCount = 0
        return
    def GetLength(self):
        return sizeof(tagGCLuckyCloudBuyRoundInfo)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// C0 12 幸运云购轮次信息 //tagGCLuckyCloudBuyRoundInfo:
                                Cmd:%s,
                                SubCmd:%s,
                                RoundID:%d,
                                RoundNum:%d,
                                SuperItemID:%d,
                                SuperItemCount:%d,
                                SuperItemMoneyType:%d,
                                SuperItemMoneyValue:%d,
                                RemainCount:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.RoundID,
                                self.RoundNum,
                                self.SuperItemID,
                                self.SuperItemCount,
                                self.SuperItemMoneyType,
                                self.SuperItemMoneyValue,
                                self.RemainCount
                                )
        return DumpString
m_NAtagGCLuckyCloudBuyRoundInfo=tagGCLuckyCloudBuyRoundInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagGCLuckyCloudBuyRoundInfo.Cmd,m_NAtagGCLuckyCloudBuyRoundInfo.SubCmd))] = m_NAtagGCLuckyCloudBuyRoundInfo
#------------------------------------------------------
@@ -40762,6 +41138,58 @@
#------------------------------------------------------
# C1 08 幸运云购玩家信息 #tagMCLuckyCloudBuyPlayerInfo
class  tagMCLuckyCloudBuyPlayerInfo(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("BuyCount", c_ushort),    # 本轮已购买份数
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xC1
        self.SubCmd = 0x08
        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 = 0xC1
        self.SubCmd = 0x08
        self.BuyCount = 0
        return
    def GetLength(self):
        return sizeof(tagMCLuckyCloudBuyPlayerInfo)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// C1 08 幸运云购玩家信息 //tagMCLuckyCloudBuyPlayerInfo:
                                Cmd:%s,
                                SubCmd:%s,
                                BuyCount:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.BuyCount
                                )
        return DumpString
m_NAtagMCLuckyCloudBuyPlayerInfo=tagMCLuckyCloudBuyPlayerInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCLuckyCloudBuyPlayerInfo.Cmd,m_NAtagMCLuckyCloudBuyPlayerInfo.SubCmd))] = m_NAtagMCLuckyCloudBuyPlayerInfo
#------------------------------------------------------
# C1 04 准备进入跨服服务器 #tagMCPrepareEnterCrossServer
class  tagMCPrepareEnterCrossServer(Structure):
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/LuckyCloudBuy.py
New file
@@ -0,0 +1,55 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package GM.Commands.LuckyCloudBuy
#
# @todo:幸运云购
# @author hxp
# @date 2021-10-21
# @version 1.0
#
# 详细描述: 幸运云购
#
#-------------------------------------------------------------------------------
#"""Version = 2021-10-21 17:00"""
#-------------------------------------------------------------------------------
import GameWorld
import PlayerControl
import PlayerLuckyCloudBuy
import ChConfig
## GM命令执行入口
#  @param curPlayer 当前玩家
#  @param msgList 参数列表 [addSkillID]
#  @return None
#  @remarks 函数详细说明.
def OnExec(curPlayer, msgList):
    if not msgList:
        GameWorld.DebugAnswer(curPlayer, "重置所有数据: FairyCard 0")
        GameWorld.DebugAnswer(curPlayer, "重置本人数据: FairyCard 0 1")
        GameWorld.DebugAnswer(curPlayer, "添加云购记录: FairyCard 1 份数")
        return
    isSendGameServer = False
    value1 = msgList[0]
    if value1 == 0:
        # 重置所有
        if len(msgList) == 1:
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LuckyCloudBuy_RoundID, 0)
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LuckyCloudBuy_BuyCount, 0)
            isSendGameServer = True
        # 重置本人数据
        elif len(msgList) == 2 and msgList[1] == 1:
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LuckyCloudBuy_RoundID, 0)
            PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LuckyCloudBuy_BuyCount, 0)
    elif value1 == 1:
        isSendGameServer = True
        return isSendGameServer
    PlayerLuckyCloudBuy.Sync_LuckyCloudBuyPlayerInfo(curPlayer)
    return isSendGameServer
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py
@@ -1677,6 +1677,17 @@
        return ReadChConfig.GetPyMongoConfig("Merge", "CrossZoneName")
    return PyGameData.g_crossZoneName
def GetCrossServerTimeStr():
    ## 跨服服务器时间
    if IsCrossServer():
        return GetCurrentDataTimeStr()
    lastCrossServerTime, lastServerTime, _ = PyGameData.g_crossServerTimeInfo
    if not lastCrossServerTime:
        return GetCurrentDataTimeStr()
    curTime = int(time.time())
    crossServerTime = lastCrossServerTime + (curTime - lastServerTime)
    return ChangeTimeNumToStr(crossServerTime)
## 时间格式转换成数值时间,可参考datetime.datetime.fromtimestamp(102645645)
#  @param timeNum
#  @return 时间数值 1970年起
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
@@ -117,6 +117,7 @@
import PlayerNewFairyCeremony
import GY_Query_BossFirstKill
import PlayerFeastRedPacket
import PlayerLuckyCloudBuy
import PlayerLuckyTreasure
import Item_ResetAttrPoint
import CrossActCTGBillboard
@@ -709,6 +710,9 @@
    
    # 跨服PK
    PlayerCrossRealmPK.DoPlayerLogin(curPlayer)
    # 幸运云购
    PlayerLuckyCloudBuy.OnPlayerLogin(curPlayer)
    
    # 竞技场
    PlayerArena.OnLogin(curPlayer)
@@ -5831,7 +5835,8 @@
    serverDateTime.Hour = serverTime.hour
    serverDateTime.Minute = serverTime.minute
    serverDateTime.Second = serverTime.second
    serverDateTime.MicSecond = serverTime.microsecond
    serverDateTime.MicSecond = serverTime.microsecond
    serverDateTime.CrossServerTime = GameWorld.GetCrossServerTimeStr()
    
    # 通知客户端同步时间
    NetPackCommon.SendFakePack(curPlayer, serverDateTime)
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
@@ -99,6 +99,7 @@
import PlayerNewFairyCeremony
import PlayerActHorsePetFeast
import PlayerFeastRedPacket
import PlayerLuckyCloudBuy
import PlayerLuckyTreasure
import PlayerAuctionHouse
import PlayerRefineStove
@@ -1479,6 +1480,16 @@
            PyGameData.g_crossZoneName = msgValue
            return
        
        if key == ShareDefine.Def_Notify_WorldKey_CrossServerTime:
            PyGameData.g_crossServerTimeInfo = eval(msgValue)
            return
        # 幸运云购
        if key == ShareDefine.Def_Notify_WorldKey_LuckyCloudBuyInfo:
            PyGameData.g_luckyCloudBuyInfo = eval(msgValue)
            PlayerLuckyCloudBuy.OnLuckyCloudBuyChange()
            return
        if msgValue.isdigit():
            value = int(msgValue)
        else:
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerLuckyCloudBuy.py
New file
@@ -0,0 +1,199 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package Player.PlayerLuckyCloudBuy
#
# @todo:幸运云购
# @author hxp
# @date 2021-10-21
# @version 1.0
#
# 详细描述: 幸运云购
#
#-------------------------------------------------------------------------------
#"""Version = 2021-10-21 17:00"""
#-------------------------------------------------------------------------------
import ChConfig
import PyGameData
import ShareDefine
import PlayerControl
import IpyGameDataPY
import CrossRealmPlayer
import ChPyNetSendPack
import IPY_GameWorld
import NetPackCommon
import ItemControler
import ItemCommon
import GameWorld
def OnPlayerLogin(curPlayer):
    if GameWorld.IsCrossServer():
        return
    if not CrossRealmPlayer.IsCrossServerOpen():
        return
    __CheckLuckyCloudBuyID(curPlayer)
    Sync_LuckyCloudBuyPlayerInfo(curPlayer)
    return
def OnLuckyCloudBuyChange():
    if GameWorld.IsCrossServer():
        return
    if not CrossRealmPlayer.IsCrossServerOpen():
        return
    playerManager = GameWorld.GetPlayerManager()
    for index in xrange(playerManager.GetPlayerCount()):
        curPlayer = playerManager.GetPlayerByIndex(index)
        if curPlayer.GetID() == 0:
            continue
        __CheckLuckyCloudBuyID(curPlayer)
        Sync_LuckyCloudBuyPlayerInfo(curPlayer) # 该功能收到就同步,不论有没有重置,因为可能由跨服关闭变为开启时的数据同步
    return
def __CheckLuckyCloudBuyID(curPlayer):
    roundID = PyGameData.g_luckyCloudBuyInfo.get("idTime", 0)
    playerRoundID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_LuckyCloudBuy_RoundID) # 玩家身上的活动ID
    if playerRoundID == roundID:
        GameWorld.DebugLog("幸运云购奖励期ID相同,不重置! playerRoundID=%s,roundID=%s" % (playerRoundID, roundID), curPlayer.GetPlayerID())
        return
    GameWorld.DebugLog("幸运云购奖励期ID变更,重置! playerRoundID=%s,roundID=%s" % (playerRoundID, roundID), curPlayer.GetPlayerID())
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LuckyCloudBuy_RoundID, roundID)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LuckyCloudBuy_BuyCount, 0)
    return True
#// C1 10 幸运云购购买 #tagCMLuckyCloudBuy
#
#struct    tagCMLuckyCloudBuy
#{
#    tagHead        Head;
#    BYTE        BuyCount;    // 购买次数
#};
def OnLuckyCloudBuy(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    accID = curPlayer.GetAccID()
    playerID = curPlayer.GetPlayerID()
    buyCount = clientData.BuyCount
    if GameWorld.IsCrossServer():
        return
    if not CrossRealmPlayer.IsCrossServerOpen():
        PlayerControl.NotifyCode(curPlayer, "CrossMatching18")
        return
    unLimitHour, unLimitMinute = IpyGameDataPY.GetFuncEvalCfg("LuckyCloudBuyCost", 3)
    crossServerDateTime = GameWorld.ChangeStrToDatetime(GameWorld.GetCrossServerTimeStr())
    unLimitDateTime = GameWorld.ChangeStrToDatetime("%d-%d-%d %d:%d:00" \
                                % (crossServerDateTime.year, crossServerDateTime.month, crossServerDateTime.day, unLimitHour, unLimitMinute))
    if crossServerDateTime >= unLimitDateTime:
        GameWorld.DebugLog("当前跨服服务器时间不限制幸运云购购买次数了! crossServerDateTime=%s,unLimitHour=%s,unLimitMinute=%s"
                           % (crossServerDateTime, unLimitHour, unLimitMinute))
    else:
        hadBuyCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_LuckyCloudBuy_BuyCount)
        curGMLV = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_BTGMLV)
        gmLVLimitBuyCountList = IpyGameDataPY.GetFuncEvalCfg("LuckyCloudBuyCost", 2)
        maxBuyCount = gmLVLimitBuyCountList[curGMLV] if len(gmLVLimitBuyCountList) > curGMLV else gmLVLimitBuyCountList[-1]
        if hadBuyCount + buyCount > maxBuyCount:
            GameWorld.DebugLog("幸运云购购买次数限制! hadBuyCount=%s,buyCount=%s,curGMLV=%s,maxBuyCount=%s,crossServerDateTime=%s"
                               % (hadBuyCount, buyCount, curGMLV, maxBuyCount, crossServerDateTime))
            return
    buyCountCostMoneyDict = IpyGameDataPY.GetFuncEvalCfg("LuckyCloudBuyCost", 1, {})
    if str(buyCount) not in buyCountCostMoneyDict:
        return
    costMoneyType, costMoneyValue = buyCountCostMoneyDict[str(buyCount)]
    if not PlayerControl.HaveMoney(curPlayer, costMoneyType, costMoneyValue):
        return
    needSpace = min(buyCount, 10)
    emptySpace = ItemCommon.GetItemPackSpace(curPlayer, IPY_GameWorld.rptItem, needSpace)
    if needSpace > emptySpace:
        PlayerControl.NotifyCode(curPlayer, "GeRen_lhs_202580")
        return
    if not GameWorld.SetPlayerTickTime(curPlayer, ChConfig.TYPE_Player_Tick_LuckyCloudBuy, tick):
        PlayerControl.NotifyCode(curPlayer, "RequestLater")
        return
    GameWorld.Log("幸运云购购买: buyCount=%s" % (buyCount), playerID)
    dataMsg = {"accID":accID,
               "playerID":playerID,
               "playerName":CrossRealmPlayer.GetCrossPlayerName(curPlayer),
               "buyCount":buyCount,
               "roundID":curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_LuckyCloudBuy_RoundID),
               }
    GameWorld.SendMsgToCrossServer(ShareDefine.ClientServerMsg_LuckyCloudBuy, dataMsg)
    return
def GameServer_LuckyCloudBuy(curPlayer, msgData):
    msgType = msgData[0]
    if msgType == "LuckyCloudBuyNum":
        CrossServerMsg_LuckyCloudBuyNum(curPlayer, msgData)
    return
def CrossServerMsg_LuckyCloudBuyNum(curPlayer, msgData):
    playerID = curPlayer.GetPlayerID()
    _, roundID, buyCount = msgData
    # 消耗钱及奖励必须执行,增加次数需同一个轮次ID
    playerRoundID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_LuckyCloudBuy_RoundID)
    hadBuyCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_LuckyCloudBuy_BuyCount)
    GameWorld.Log("地图玩家收到幸运云购购买结算信息! playerRoundID=%s,hadBuyCount=%s, roundID=%s,buyCount=%s"
                  % (playerRoundID, hadBuyCount, roundID, buyCount), playerID)
    buyCountCostMoneyDict = IpyGameDataPY.GetFuncEvalCfg("LuckyCloudBuyCost", 1, {})
    if str(buyCount) not in buyCountCostMoneyDict:
        return
    costMoneyType, costMoneyValue = buyCountCostMoneyDict[str(buyCount)]
    if not PlayerControl.PayMoney(curPlayer, costMoneyType, costMoneyValue, "LuckyCloudBuy"):
        return
    if roundID == playerRoundID:
        updBuyCount = hadBuyCount + buyCount
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_LuckyCloudBuy_BuyCount, updBuyCount)
        GameWorld.Log("    更新幸运云购购买次数: updBuyCount=%s" % (updBuyCount), playerID)
    baseAwardList = IpyGameDataPY.GetFuncEvalCfg("LuckyCloudBuyAward", 1) # 固定奖励列表
    randAwardList = IpyGameDataPY.GetFuncEvalCfg("LuckyCloudBuyAward", 2) # 随机饼图奖励列表
    awardItemDict = {}
    for _ in range(buyCount):
        itemList = []
        itemList += baseAwardList
        randItemInfo = GameWorld.GetResultByRandomList(randAwardList)
        if randItemInfo:
            itemList.append(randItemInfo)
        for itemID, itemCount, isAuctionItem in itemList:
            if itemID not in awardItemDict:
                awardItemDict[itemID] = [itemID, itemCount, isAuctionItem]
            else:
                awardItemDict[itemID] = [itemID, itemCount + awardItemDict[itemID][1], isAuctionItem]
    awardItemList = awardItemDict.values()
    GameWorld.Log("    结算幸运云购购买奖励: awardItemList=%s" % str(awardItemList), playerID)
    ItemControler.GivePlayerItemOrMail(curPlayer, awardItemList, event=["LuckyCloudBuy", False, {}])
    Sync_LuckyCloudBuyPlayerInfo(curPlayer)
    return
def Sync_LuckyCloudBuyPlayerInfo(curPlayer):
    clientPack = ChPyNetSendPack.tagMCLuckyCloudBuyPlayerInfo()
    clientPack.BuyCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_LuckyCloudBuy_BuyCount)
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_LuckyCloudBuy.py
New file
@@ -0,0 +1,51 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package Player.RemoteQuery.GY_Query_LuckyCloudBuy
#
# @todo:幸运云购
# @author hxp
# @date 2021-10-21
# @version 1.0
#
# 详细描述: 幸运云购
#
#-------------------------------------------------------------------------------
#"""Version = 2021-10-21 17:00"""
#-------------------------------------------------------------------------------
import GameWorld
import PlayerLuckyCloudBuy
import ChConfig
#------------------------------------------------------------------------------
## 跨服赛报名调用接口
#  @param query_Type 请求类型
#  @param query_ID 请求的玩家ID
#  @param packCMDList 发包命令
#  @param tick 当前时间
#  @return "True" or "False" or ""
#  @remarks 函数详细说明.
def DoLogic(query_Type, query_ID, packCMDList, tick):
    return
#------------------------------------------------------------------------------
## 执行结果
#  @param curPlayer 发出请求的玩家
#  @param callFunName 功能名称
#  @param funResult 查询的结果
#  @param tick 当前时间
#  @return None
#  @remarks 函数详细说明.
def DoResult(curPlayer, callFunName, funResult, tick):
    curPlayer.SetTickByType(ChConfig.TYPE_Player_Tick_LuckyCloudBuy, 0)
    msgData = eval(funResult)
    playerID = curPlayer.GetPlayerID()
    GameWorld.Log("GY_Query_LuckyCloudBuy msgData=%s" % (msgData), playerID)
    PlayerLuckyCloudBuy.GameServer_LuckyCloudBuy(curPlayer, msgData)
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
@@ -90,6 +90,9 @@
g_gathersoulfbAwardDict = {} #聚魂副本奖励记录{playerID:[[itemID,itemCnt]]}
g_luckyCloudBuyInfo = {} # 幸运云购最新一期信息
g_crossServerTimeInfo = [0, 0, 0] # 跨服时间信息 [crossServerTime, curServerTime, syncMapTime]
g_crossZoneName = "" # 跨服分区名
g_crossRegPlayerAttrDict = {} #跨服注册时登记的会影响战力的属性值 {playerID:[value, ...], ...}
g_crossSyncTickDict = {} #需要同步跨服数据的玩家同步tick字典 {playerID:tick, ...}
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
@@ -177,10 +177,13 @@
Def_Notify_WorldKey_CrossServerConnState = "CrossServerConnState"  # 跨服服务器链接状态
Def_Notify_WorldKey_CrossServerOpen = "CrossServerOpen"  # 跨服服务器是否开启中
Def_Notify_WorldKey_CrossZoneName = "CrossZoneName"  # 跨服分区名
Def_Notify_WorldKey_CrossServerTime = "CrossServerTime"  # 跨服时间
Def_Notify_WorldKey_CrossPKZoneID = "CrossPKZoneID"  # 本服跨服PK所属赛区
Def_Notify_WorldKey_CrossPKSeasonID = "CrossPKSeasonID"  # 本服跨服PK当前赛季
Def_Notify_WorldKey_CrossPKSeasonState = "CrossPKSeasonState"  # 本服跨服PK赛季状态 0-关闭,1-开启中
Def_Notify_WorldKey_LuckyCloudBuyInfo = "LuckyCloudBuyInfo"  # 本服幸运云购最新一期信息
Def_Notify_WorldKey_GameWorldBossRebornCross = 'BossRebornCross_%s_%s'   # 跨服世界boss重生, 参数为(zoneID, bossID)
Def_Notify_WorldKey_GameWorldBossReborn = 'BossReborn_%s'   # 世界boss重生, 参数为(bossID)
@@ -1170,8 +1173,8 @@
                                Def_UniversalGameRecType_ActWorldLVLimitInfo, # 运营活动世界等级限制开启信息 18
                                Def_UniversalGameRecType_19,
                                Def_UniversalGameRecType_20,
                                Def_UniversalGameRecType_21,
                                Def_UniversalGameRecType_22,
                                Def_UniversalGameRecType_LuckyCloudBuyNum, # 幸运云购购买号码记录 21
                                Def_UniversalGameRecType_LuckyCloudBuyLottery, # 幸运云购开奖记录 22
                                Def_UniversalGameRecType_23,
                                Def_UniversalGameRecType_UpdatePlayerName,  # 玩家改名正在改名中的信息24
                                Def_UniversalGameRecType_BossDropGoodItemInfo,  # boss掉落好物品信息记录25
@@ -1368,6 +1371,9 @@
CrossServerMsg_CrossActInfo = "CrossActInfo"            # 跨服运营活动信息
CrossServerMsg_MailPlayerIDList = "MailPlayerIDList"    # 跨服邮件玩家ID通知,玩家目标服务器可能无法知道,被动推送
CrossServerMsg_MailContent = "MailContent"              # 跨服邮件内容通知
CrossServerMsg_LuckyCloudBuyNum = "LuckyCloudBuyNum"    # 幸运云购购买记录通知
CrossServerMsg_LuckyCloudBuyLottery = "LuckyCloudBuyLottery"    # 幸运云购开奖记录通知
CrossServerMsg_CrossServerTime = "CrossServerTime"      # 跨服时间同步
# 子服发送跨服信息定义
ClientServerMsg_ServerInitOK = "ServerInitOK"           # 子服启动成功