From 46fbb9a99444693cdbcd0df7f6de0d0511235d56 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期一, 13 十二月 2021 14:46:53 +0800
Subject: [PATCH] 9265 【BT5】【后端】53、新增幸运云购

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py                               |  154 +++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py                           |  486 +++++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py                                |    3 
 ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py                                                    |  154 +++
 ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/CrossServerTime.py                                    |   52 +
 ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py                                                |  486 +++++++++
 ServerPython/CoreServerGroup/GameServer/Script/ReadChConfig.py                                                   |    2 
 ServerPython/CoreServerGroup/GameServer/Script/GameWorld.py                                                      |   11 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py                           |    7 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerLuckyCloudBuy.py                |  199 ++++
 ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py                                                    |   10 
 ServerPython/CoreServerGroup/GameServer/PyNetPack.ini                                                            |   15 
 ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossLuckyCloudBuy.py                              |  977 ++++++++++++++++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_LuckyCloudBuy.py |   51 +
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py                               |   10 
 ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/LuckyCloudBuy.py                                      |   80 +
 ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py                                                |    6 
 ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py                                   |   38 
 ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py                                |   13 
 ServerPython/CoreServerGroup/GameServer/Script/PyGameData.py                                                     |    6 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini                                       |   12 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py                                 |   11 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/LuckyCloudBuy.py                 |   55 +
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py                 |   11 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py                                  |    8 
 25 files changed, 2,789 insertions(+), 68 deletions(-)

diff --git a/ServerPython/CoreServerGroup/GameServer/PyNetPack.ini b/ServerPython/CoreServerGroup/GameServer/PyNetPack.ini
index b653ce7..875d8e5 100644
--- a/ServerPython/CoreServerGroup/GameServer/PyNetPack.ini
+++ b/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
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
index 81983c8..9498bb2 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
+++ b/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
\ No newline at end of file
+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
\ No newline at end of file
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
index 3a9ad76..f04a366 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
+++ b/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):
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/CrossServerTime.py b/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/CrossServerTime.py
new file mode 100644
index 0000000..a7ccce7
--- /dev/null
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/CrossServerTime.py
@@ -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]
+
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/LuckyCloudBuy.py b/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/LuckyCloudBuy.py
new file mode 100644
index 0000000..008e441
--- /dev/null
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GM/Commands/LuckyCloudBuy.py
@@ -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]
+
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorld.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorld.py
index 0bcfc8e..256d3c3 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorld.py
+++ b/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: 区服名
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossLuckyCloudBuy.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossLuckyCloudBuy.py
new file mode 100644
index 0000000..ebab7a0
--- /dev/null
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossLuckyCloudBuy.py
@@ -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
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py
index 4352872..5114bb5 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossRealmMsg.py
+++ b/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("没有该信息类型逻辑处理!")
             
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py
index 54357ae..dad5cba 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldProcess.py
+++ b/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++关服!")
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py
index ce5dfbb..17c406e 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py
+++ b/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)
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/PyGameData.py b/ServerPython/CoreServerGroup/GameServer/Script/PyGameData.py
index d06282f..debbfe6 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/PyGameData.py
+++ b/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都存在,仅作为删除邮件时用到
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ReadChConfig.py b/ServerPython/CoreServerGroup/GameServer/Script/ReadChConfig.py
index 40bc7a3..8311de4 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ReadChConfig.py
+++ b/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
 
 
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py b/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
index 7cfb252..5b25f85 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
+++ b/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"           # 子服启动成功
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
index 0816ae1..b64d1b7 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
+++ b/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
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
index d92cdd9..61f6aa2 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
+++ b/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"
 
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
index 81983c8..9498bb2 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
+++ b/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
\ No newline at end of file
+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
\ No newline at end of file
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
index 3a9ad76..f04a366 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
+++ b/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):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/LuckyCloudBuy.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/LuckyCloudBuy.py
new file mode 100644
index 0000000..660dd5d
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/LuckyCloudBuy.py
@@ -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
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py
index 78c0d00..ed1bd2b 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py
+++ b/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年起
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
index 47807a9..61c7c46 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
+++ b/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)
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
index 385bd7b..2e585d3 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
+++ b/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:
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerLuckyCloudBuy.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerLuckyCloudBuy.py
new file mode 100644
index 0000000..287276b
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerLuckyCloudBuy.py
@@ -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
+
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_LuckyCloudBuy.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_LuckyCloudBuy.py
new file mode 100644
index 0000000..c066eca
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_LuckyCloudBuy.py
@@ -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
+    
+    
+    
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
index 3633870..cb0f2eb 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
+++ b/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, ...}
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
index 7cfb252..5b25f85 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
+++ b/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"           # 子服启动成功

--
Gitblit v1.8.0