From fea76cc7386e6c35cfe0f4910f066d04d24061f0 Mon Sep 17 00:00:00 2001
From: xdh <xiefantasy@qq.com>
Date: 星期六, 13 十月 2018 14:26:42 +0800
Subject: [PATCH] 4075 【后端】限时抢购开发

---
 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerStore.py                                                    |  108 ++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFlashSale.py                           |  258 ++++++++++
 ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldActionControl.py                                 |    6 
 ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py                                                         |   82 +++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventSrc/FunctionNPCCommon.py                 |   58 ++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_GetStoreServerBuyCnt.py |   57 ++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py                                      |    5 
 ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py                                                    |    9 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py                                  |  366 ++++++++++++++
 ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py                                                       |    4 
 ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py                                                       |  366 ++++++++++++++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py                               |    3 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini                                              |   14 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py                                    |   52 ++
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py                                  |    7 
 PySysDB/PySysDBPY.h                                                                                                     |   20 
 ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py                                                           |    5 
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py                        |    4 
 PySysDB/PySysDBG.h                                                                                                      |   31 +
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py                                         |   11 
 20 files changed, 1,446 insertions(+), 20 deletions(-)

diff --git a/PySysDB/PySysDBG.h b/PySysDB/PySysDBG.h
index ab00777..34a0d5b 100644
--- a/PySysDB/PySysDBG.h
+++ b/PySysDB/PySysDBG.h
@@ -323,3 +323,34 @@
 	WORD		Multiple;	//倍数
 	WORD		LVLimit;	//限制等级
 };
+
+//限时抢购表
+
+struct tagActFlashSale
+{
+	DWORD		_CfgID;	//配置ID
+	char		ActMark;	//活动组标记
+	list		ServerIDList;	//服务器ID列表
+	char		StartDate;	//开启日期
+	char		EndDate;	//结束日期
+	list		StartTimeList;	//开启时间列表, 支持多个时段
+	list		EndTimeList;	//结束时间列表, 支持多个时段
+	WORD		AdvanceMinutes;	//前端提前X分钟展示活动
+	dict		NotifyInfoStart;	//全服提示信息 - 相对开始时间
+	dict		NotifyInfoEnd;	//全服提示信息 - 相对结束时间
+	list		NotifyInfoLoop;	//全服提示信息 - 循环广播[间隔分钟, 广播key]
+	WORD		LVLimit;	//限制等级
+	BYTE		IsDayReset;	//是否每天重置
+	list		ShopTypeList;	//商店类型列表
+};
+
+
+//商城表
+
+struct tagStore
+{
+	DWORD		_ID;	//ID
+	DWORD		ShopType;	//商店类型
+	BYTE		RefreshType;	//刷新类型 0-不重置,1-onWeek0点,2-onWeek5点,3-OnDay0点,4-OnDay5点
+	DWORD		ServerLimitCnt;	//全服限制数量
+};
\ No newline at end of file
diff --git a/PySysDB/PySysDBPY.h b/PySysDB/PySysDBPY.h
index ad4e352..ac81320 100644
--- a/PySysDB/PySysDBPY.h
+++ b/PySysDB/PySysDBPY.h
@@ -754,7 +754,8 @@
 	BYTE		RefreshType;	//刷新类型 0-不重置,1-onWeek0点,2-onWeek5点,3-OnDay0点,4-OnDay5点
 	list		LimitVIPLV;	//VIP限制
 	DWORD		LimitLV;	//等级限制
-	list		LimitCnt;	//限制数量
+	list		LimitCnt;	//个人限制数量
+	DWORD		ServerLimitCnt;	//全服限制数量
 	BYTE		MoneyType;	//金钱类型
 	DWORD		MoneyNum;	//金钱数量
 	DWORD		MoneyOriginal;	//原价
@@ -1279,4 +1280,21 @@
 	DWORD		_SkillID;	//技能ID
 	BYTE		TalentType;	//天赋类型
 	BYTE		Series;	//天赋系别
+};
+
+//限时抢购表
+
+struct tagActFlashSale
+{
+	DWORD		_CfgID;	//配置ID
+	char		StartDate;	//开启日期
+	char		EndDate;	//结束日期
+	list		StartTimeList;	//开启时间列表, 支持多个时段
+	list		EndTimeList;	//结束时间列表, 支持多个时段
+	WORD		AdvanceMinutes;	//前端提前X分钟展示活动
+	WORD		LVLimit;	//限制等级
+	BYTE		IsDayReset;	//是否每天重置
+	list		ShopTypeList;	//商店类型列表
+	char		MailKey;		//活动更新时发送邮件key
+	list		MailItemPrize;		//活动更新时发送邮件奖励物品
 };
\ No newline at end of file
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
index 0fbe5fd..51d6d86 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
@@ -20177,6 +20177,372 @@
 
 
 #------------------------------------------------------
+# AA 18 限时抢购活动玩家预约信息 #tagMCFlashSaleAppointmentInfo
+
+class  tagMCFlashSaleAppointmentInfo(Structure):
+    Head = tagHead()
+    GoodsCount = 0    #(WORD GoodsCount)// 商品数
+    GoodsList = list()    #(vector<DWORD> GoodsList)// 预约的商品
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        self.Head.Cmd = 0xAA
+        self.Head.SubCmd = 0x18
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        _pos = self.Head.ReadData(_lpData, _pos)
+        self.GoodsCount,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        for i in range(self.GoodsCount):
+            value,_pos=CommFunc.ReadDWORD(_lpData,_pos)
+            self.GoodsList.append(value)
+        return _pos
+
+    def Clear(self):
+        self.Head = tagHead()
+        self.Head.Clear()
+        self.Head.Cmd = 0xAA
+        self.Head.SubCmd = 0x18
+        self.GoodsCount = 0
+        self.GoodsList = list()
+        return
+
+    def GetLength(self):
+        length = 0
+        length += self.Head.GetLength()
+        length += 2
+        length += 4 * self.GoodsCount
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+        data = CommFunc.WriteWORD(data, self.GoodsCount)
+        for i in range(self.GoodsCount):
+            data = CommFunc.WriteDWORD(data, self.GoodsList[i])
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Head:%s,
+                                GoodsCount:%d,
+                                GoodsList:%s
+                                '''\
+                                %(
+                                self.Head.OutputString(),
+                                self.GoodsCount,
+                                "..."
+                                )
+        return DumpString
+
+
+m_NAtagMCFlashSaleAppointmentInfo=tagMCFlashSaleAppointmentInfo()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCFlashSaleAppointmentInfo.Head.Cmd,m_NAtagMCFlashSaleAppointmentInfo.Head.SubCmd))] = m_NAtagMCFlashSaleAppointmentInfo
+
+
+#------------------------------------------------------
+# AA 17 限时抢购活动信息 #tagMCFlashSaleInfo
+
+class  tagMCFlashSaleGiftbag(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("GiftID", c_int),    #商城表的物品ID
+                  ("BuyCountLimit", c_ubyte),    #限购数
+                  ("ServerBuyCountLimit", c_ushort),    #全服限购数
+                  ("MoneyType", c_ubyte),    #消耗货币类型
+                  ("MoneyNumber", c_int),    #消耗货币数量
+                  ("MoneyOriginal", c_int),    #原价
+                  ("ItemID", c_int),    
+                  ("ItemCount", c_ushort),    
+                  ("IsBind", c_ubyte),    
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        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.GiftID = 0
+        self.BuyCountLimit = 0
+        self.ServerBuyCountLimit = 0
+        self.MoneyType = 0
+        self.MoneyNumber = 0
+        self.MoneyOriginal = 0
+        self.ItemID = 0
+        self.ItemCount = 0
+        self.IsBind = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagMCFlashSaleGiftbag)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// AA 17 限时抢购活动信息 //tagMCFlashSaleInfo:
+                                GiftID:%d,
+                                BuyCountLimit:%d,
+                                ServerBuyCountLimit:%d,
+                                MoneyType:%d,
+                                MoneyNumber:%d,
+                                MoneyOriginal:%d,
+                                ItemID:%d,
+                                ItemCount:%d,
+                                IsBind:%d
+                                '''\
+                                %(
+                                self.GiftID,
+                                self.BuyCountLimit,
+                                self.ServerBuyCountLimit,
+                                self.MoneyType,
+                                self.MoneyNumber,
+                                self.MoneyOriginal,
+                                self.ItemID,
+                                self.ItemCount,
+                                self.IsBind
+                                )
+        return DumpString
+
+
+class  tagMCFlashSaleShop(Structure):
+    DayIndex = 0    #(BYTE DayIndex)// 活动第几天
+    TimeIndex = 0    #(BYTE TimeIndex)// 第几个时间段
+    GiftbagCount = 0    #(BYTE GiftbagCount)// 商店礼包数
+    GiftbagInfo = list()    #(vector<tagMCFlashSaleGiftbag> GiftbagInfo)// 礼包信息
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        self.DayIndex,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.TimeIndex,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.GiftbagCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.GiftbagCount):
+            temGiftbagInfo = tagMCFlashSaleGiftbag()
+            _pos = temGiftbagInfo.ReadData(_lpData, _pos)
+            self.GiftbagInfo.append(temGiftbagInfo)
+        return _pos
+
+    def Clear(self):
+        self.DayIndex = 0
+        self.TimeIndex = 0
+        self.GiftbagCount = 0
+        self.GiftbagInfo = list()
+        return
+
+    def GetLength(self):
+        length = 0
+        length += 1
+        length += 1
+        length += 1
+        for i in range(self.GiftbagCount):
+            length += self.GiftbagInfo[i].GetLength()
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteBYTE(data, self.DayIndex)
+        data = CommFunc.WriteBYTE(data, self.TimeIndex)
+        data = CommFunc.WriteBYTE(data, self.GiftbagCount)
+        for i in range(self.GiftbagCount):
+            data = CommFunc.WriteString(data, self.GiftbagInfo[i].GetLength(), self.GiftbagInfo[i].GetBuffer())
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                DayIndex:%d,
+                                TimeIndex:%d,
+                                GiftbagCount:%d,
+                                GiftbagInfo:%s
+                                '''\
+                                %(
+                                self.DayIndex,
+                                self.TimeIndex,
+                                self.GiftbagCount,
+                                "..."
+                                )
+        return DumpString
+
+
+class  tagMCFlashSaleTime(Structure):
+    StartTime = ""    #(char StartTime[5])// 开始时间 H:M
+    EndtTime = ""    #(char EndtTime[5])// 结束时间 H:M
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        self.StartTime,_pos = CommFunc.ReadString(_lpData, _pos,5)
+        self.EndtTime,_pos = CommFunc.ReadString(_lpData, _pos,5)
+        return _pos
+
+    def Clear(self):
+        self.StartTime = ""
+        self.EndtTime = ""
+        return
+
+    def GetLength(self):
+        length = 0
+        length += 5
+        length += 5
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteString(data, 5, self.StartTime)
+        data = CommFunc.WriteString(data, 5, self.EndtTime)
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                StartTime:%s,
+                                EndtTime:%s
+                                '''\
+                                %(
+                                self.StartTime,
+                                self.EndtTime
+                                )
+        return DumpString
+
+
+class  tagMCFlashSaleInfo(Structure):
+    Head = tagHead()
+    StartDate = ""    #(char StartDate[10])// 开始日期 y-m-d
+    EndtDate = ""    #(char EndtDate[10])// 结束日期 y-m-d
+    AdvanceMinutes = 0    #(WORD AdvanceMinutes)// 提前显示分钟
+    ActivityTimeCount = 0    #(BYTE ActivityTimeCount)
+    ActivityTime = list()    #(vector<tagMCFlashSaleTime> ActivityTime)//活动时间
+    IsDayReset = 0    #(BYTE IsDayReset)//是否每天重置
+    LimitLV = 0    #(WORD LimitLV)// 限制等级
+    ShopCount = 0    #(BYTE ShopCount)// 商店数
+    ShopInfo = list()    #(vector<tagMCFlashSaleShop> ShopInfo)// 商店信息, 当有多个商店且有多个活动时间段时则每个时间段对应一个商店;
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        self.Head.Cmd = 0xAA
+        self.Head.SubCmd = 0x17
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        _pos = self.Head.ReadData(_lpData, _pos)
+        self.StartDate,_pos = CommFunc.ReadString(_lpData, _pos,10)
+        self.EndtDate,_pos = CommFunc.ReadString(_lpData, _pos,10)
+        self.AdvanceMinutes,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.ActivityTimeCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.ActivityTimeCount):
+            temActivityTime = tagMCFlashSaleTime()
+            _pos = temActivityTime.ReadData(_lpData, _pos)
+            self.ActivityTime.append(temActivityTime)
+        self.IsDayReset,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.LimitLV,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.ShopCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.ShopCount):
+            temShopInfo = tagMCFlashSaleShop()
+            _pos = temShopInfo.ReadData(_lpData, _pos)
+            self.ShopInfo.append(temShopInfo)
+        return _pos
+
+    def Clear(self):
+        self.Head = tagHead()
+        self.Head.Clear()
+        self.Head.Cmd = 0xAA
+        self.Head.SubCmd = 0x17
+        self.StartDate = ""
+        self.EndtDate = ""
+        self.AdvanceMinutes = 0
+        self.ActivityTimeCount = 0
+        self.ActivityTime = list()
+        self.IsDayReset = 0
+        self.LimitLV = 0
+        self.ShopCount = 0
+        self.ShopInfo = list()
+        return
+
+    def GetLength(self):
+        length = 0
+        length += self.Head.GetLength()
+        length += 10
+        length += 10
+        length += 2
+        length += 1
+        for i in range(self.ActivityTimeCount):
+            length += self.ActivityTime[i].GetLength()
+        length += 1
+        length += 2
+        length += 1
+        for i in range(self.ShopCount):
+            length += self.ShopInfo[i].GetLength()
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+        data = CommFunc.WriteString(data, 10, self.StartDate)
+        data = CommFunc.WriteString(data, 10, self.EndtDate)
+        data = CommFunc.WriteWORD(data, self.AdvanceMinutes)
+        data = CommFunc.WriteBYTE(data, self.ActivityTimeCount)
+        for i in range(self.ActivityTimeCount):
+            data = CommFunc.WriteString(data, self.ActivityTime[i].GetLength(), self.ActivityTime[i].GetBuffer())
+        data = CommFunc.WriteBYTE(data, self.IsDayReset)
+        data = CommFunc.WriteWORD(data, self.LimitLV)
+        data = CommFunc.WriteBYTE(data, self.ShopCount)
+        for i in range(self.ShopCount):
+            data = CommFunc.WriteString(data, self.ShopInfo[i].GetLength(), self.ShopInfo[i].GetBuffer())
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Head:%s,
+                                StartDate:%s,
+                                EndtDate:%s,
+                                AdvanceMinutes:%d,
+                                ActivityTimeCount:%d,
+                                ActivityTime:%s,
+                                IsDayReset:%d,
+                                LimitLV:%d,
+                                ShopCount:%d,
+                                ShopInfo:%s
+                                '''\
+                                %(
+                                self.Head.OutputString(),
+                                self.StartDate,
+                                self.EndtDate,
+                                self.AdvanceMinutes,
+                                self.ActivityTimeCount,
+                                "...",
+                                self.IsDayReset,
+                                self.LimitLV,
+                                self.ShopCount,
+                                "..."
+                                )
+        return DumpString
+
+
+m_NAtagMCFlashSaleInfo=tagMCFlashSaleInfo()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCFlashSaleInfo.Head.Cmd,m_NAtagMCFlashSaleInfo.Head.SubCmd))] = m_NAtagMCFlashSaleInfo
+
+
+#------------------------------------------------------
 # AA 05 充值排行特惠信息 #tagMCRechargeRankTeHuiInfo
 
 class  tagMCRechargeRankTeHuiInfo(Structure):
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldActionControl.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldActionControl.py
index 7ee030f..c185620 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldActionControl.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/GameWorldActionControl.py
@@ -43,6 +43,7 @@
 import GameWorldProcess
 import ChPyNetSendPack
 import NetPackCommon
+import PlayerStore
 
 from types import IntType
 import time
@@ -467,6 +468,11 @@
         elif actName == ShareDefine.OperationActionName_RealmPoint:
             if isReload and ipyData:
                 Sync_OperationAction_RealmPoint(ipyData)
+        elif actName == ShareDefine.OperationActionName_FlashSale:
+            if ipyData and preState != state:
+                dayIndex = sendMapServerMsgDict.get(ShareDefine.ActKey_DayIndex, 0)
+                PlayerStore.ResetFlashSaleBuyCnt(ipyData, dayIndex, state)
+                
         #通知Mapserver,设置字典
         #GameWorld.SendMapServerMsgEx(dictName, state) # 运营活动不单独通知活动状态,需与活动信息整合后一起通知
         
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py b/ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py
index ce59ba0..e945a24 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py
@@ -281,6 +281,30 @@
                         ("WORD", "Multiple", 0),
                         ("WORD", "LVLimit", 0),
                         ),
+
+                "ActFlashSale":(
+                        ("DWORD", "CfgID", 1),
+                        ("char", "ActMark", 0),
+                        ("list", "ServerIDList", 0),
+                        ("char", "StartDate", 0),
+                        ("char", "EndDate", 0),
+                        ("list", "StartTimeList", 0),
+                        ("list", "EndTimeList", 0),
+                        ("WORD", "AdvanceMinutes", 0),
+                        ("dict", "NotifyInfoStart", 0),
+                        ("dict", "NotifyInfoEnd", 0),
+                        ("list", "NotifyInfoLoop", 0),
+                        ("WORD", "LVLimit", 0),
+                        ("BYTE", "IsDayReset", 0),
+                        ("list", "ShopTypeList", 0),
+                        ),
+
+                "Store":(
+                        ("DWORD", "ID", 1),
+                        ("DWORD", "ShopType", 0),
+                        ("BYTE", "RefreshType", 0),
+                        ("DWORD", "ServerLimitCnt", 0),
+                        ),
                 }
 
 
@@ -808,6 +832,56 @@
     def GetNotifyInfoEnd(self): return self.NotifyInfoEnd # 全服提示信息 - 相对结束时间
     def GetMultiple(self): return self.Multiple # 倍数
     def GetLVLimit(self): return self.LVLimit # 限制等级
+
+# 限时抢购表
+class IPY_ActFlashSale():
+    
+    def __init__(self):
+        self.CfgID = 0
+        self.ActMark = ""
+        self.ServerIDList = []
+        self.StartDate = ""
+        self.EndDate = ""
+        self.StartTimeList = []
+        self.EndTimeList = []
+        self.AdvanceMinutes = 0
+        self.NotifyInfoStart = {}
+        self.NotifyInfoEnd = {}
+        self.NotifyInfoLoop = []
+        self.LVLimit = 0
+        self.IsDayReset = 0
+        self.ShopTypeList = []
+        return
+        
+    def GetCfgID(self): return self.CfgID # 配置ID
+    def GetActMark(self): return self.ActMark # 活动组标记
+    def GetServerIDList(self): return self.ServerIDList # 服务器ID列表
+    def GetStartDate(self): return self.StartDate # 开启日期
+    def GetEndDate(self): return self.EndDate # 结束日期
+    def GetStartTimeList(self): return self.StartTimeList # 开启时间列表, 支持多个时段
+    def GetEndTimeList(self): return self.EndTimeList # 结束时间列表, 支持多个时段
+    def GetAdvanceMinutes(self): return self.AdvanceMinutes # 前端提前X分钟展示活动
+    def GetNotifyInfoStart(self): return self.NotifyInfoStart # 全服提示信息 - 相对开始时间
+    def GetNotifyInfoEnd(self): return self.NotifyInfoEnd # 全服提示信息 - 相对结束时间
+    def GetNotifyInfoLoop(self): return self.NotifyInfoLoop # 全服提示信息 - 循环广播[间隔分钟, 广播key]
+    def GetLVLimit(self): return self.LVLimit # 限制等级
+    def GetIsDayReset(self): return self.IsDayReset # 是否每天重置
+    def GetShopTypeList(self): return self.ShopTypeList # 商店类型列表
+
+# 商城表
+class IPY_Store():
+    
+    def __init__(self):
+        self.ID = 0
+        self.ShopType = 0
+        self.RefreshType = 0
+        self.ServerLimitCnt = 0
+        return
+        
+    def GetID(self): return self.ID # ID
+    def GetShopType(self): return self.ShopType # 商店类型
+    def GetRefreshType(self): return self.RefreshType # 刷新类型 0-不重置,1-onWeek0点,2-onWeek5点,3-OnDay0点,4-OnDay5点
+    def GetServerLimitCnt(self): return self.ServerLimitCnt # 全服限制数量
 
 
 def Log(msg, playerID=0, par=0):
@@ -883,6 +957,10 @@
         self.ipyUniquenessArriveLen = len(self.ipyUniquenessArriveCache)
         self.ipyActRealmPointCache = self.__LoadFileData("ActRealmPoint", IPY_ActRealmPoint)
         self.ipyActRealmPointLen = len(self.ipyActRealmPointCache)
+        self.ipyActFlashSaleCache = self.__LoadFileData("ActFlashSale", IPY_ActFlashSale)
+        self.ipyActFlashSaleLen = len(self.ipyActFlashSaleCache)
+        self.ipyStoreCache = self.__LoadFileData("Store", IPY_Store)
+        self.ipyStoreLen = len(self.ipyStoreCache)
         Log("IPY_FuncConfig count=%s" % len(self.ipyFuncConfigDict))
         Log("IPY_DataMgr InitOK!")
         return
@@ -1099,6 +1177,10 @@
     def GetUniquenessArriveByIndex(self, index): return self.ipyUniquenessArriveCache[index]
     def GetActRealmPointCount(self): return self.ipyActRealmPointLen
     def GetActRealmPointByIndex(self, index): return self.ipyActRealmPointCache[index]
+    def GetActFlashSaleCount(self): return self.ipyActFlashSaleLen
+    def GetActFlashSaleByIndex(self, index): return self.ipyActFlashSaleCache[index]
+    def GetStoreCount(self): return self.ipyStoreLen
+    def GetStoreByIndex(self, index): return self.ipyStoreCache[index]
 
 IPYData = IPY_DataMgr()
 def IPY_Data(): return IPYData
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py
index 4452fb6..a92f212 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/ChPlayer.py
@@ -63,6 +63,7 @@
 import IpyGameDataPY
 import PlayerTalk
 import PlayerGeTui
+import PlayerStore
 import GameWorldActionControl
 import GMT_CTG
 import PyGameData
@@ -143,7 +144,8 @@
         PlayerXMZZ.OnXMZZOnLogin(curPlayer)
         #等级奖励
         PlayerLVAward.OnPlayerLogin(curPlayer)
-    
+        #商店购买次数
+        PlayerStore.OnPlayerLogin(curPlayer)
         #通知世界boss信息
         GameWorldBoss.OnPlayerLogin(curPlayer)
         #家族副本boss状态通知
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py
index 67c60a0..e79356d 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerQuery.py
@@ -72,6 +72,7 @@
 import PyDataManager
 import PyGameData
 import PlayerTalk
+import PlayerStore
 
 import time
 import datetime
@@ -774,6 +775,14 @@
 
     
 #---有可能return-----------------------------------------------------------------
+    #商城全服购买限制
+    if callName == "GetStoreServerBuyCnt":
+        curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(srcPlayerID)
+        if not curPlayer:
+            return
+        ret = PlayerStore.DoStoreServerBuyQueryResult(curPlayer, eval(resultName))
+        resultName = '%s' % ret
+        
     #玩家等级奖励
     if callName == "GetPlayerLVAward":
         curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(srcPlayerID)
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerStore.py b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerStore.py
new file mode 100644
index 0000000..c425e21
--- /dev/null
+++ b/ServerPython/CoreServerGroup/GameServer/Script/Player/PlayerStore.py
@@ -0,0 +1,108 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+#-------------------------------------------------------------------------------
+#
+##@package PlayerStore
+#
+# @todo:商城
+# @author xdh
+# @date 2018-10-09
+# @version 1.0
+#
+#
+# 详细描述: 商城全服限购处理
+#
+#---------------------------------------------------------------------
+"""Version = 2018-10-09 17:00"""
+
+import GameWorld
+import PlayerUniversalGameRec
+import ShareDefine
+import PlayerControl
+import IpyGameDataPY
+
+RecType = ShareDefine.Def_UniversalGameRecType_StoreServerCntRecord
+
+## 玩家登录
+#  @param None
+#  @return None
+def OnPlayerLogin(curPlayer):
+    PlayerUniversalGameRec.SendUniversalGameRecInfo(curPlayer, RecType)
+    return
+
+
+## 商城全服限购查询结果
+#  @param curPlayer 玩家实例
+#  @param msgList 信息列表
+#  @return awardID
+def DoStoreServerBuyQueryResult(curPlayer, msgList):
+    goodsID = msgList[0]
+    serverLimitCnt = msgList[1]
+    buyCount = msgList[2]
+    
+    curGotCnt = 0
+    
+    universalRecMgr = GameWorld.GetUniversalRecMgr()
+    recTypeListData = universalRecMgr.GetTypeList(RecType)
+    findRecData = None 
+    for index in range(recTypeListData.Count()):
+        recData = recTypeListData.At(index)
+        curGoodsID = recData.GetValue1()
+        if goodsID == curGoodsID:
+            findRecData = recData
+            curGotCnt = recData.GetValue2()
+            break
+    
+    if curGotCnt + buyCount > serverLimitCnt:
+        GameWorld.Log('    购买商品 全服购买次数不够 goodsID=%s,curGotCnt=%s,buyCount=%s,serverLimitCnt=%s'%(goodsID, curGotCnt, buyCount, serverLimitCnt))
+        return
+    if not findRecData:
+        findRecData = recTypeListData.AddRec()
+        findRecData.SetValue1(goodsID)
+    findRecData.SetValue2(curGotCnt+buyCount)
+    #通知
+    playerManager = GameWorld.GetPlayerManager()
+    for i in xrange(playerManager.GetActivePlayerCount()):
+        curPlayer = playerManager.GetActivePlayerAt(i)
+        if curPlayer == None or not curPlayer.GetInitOK():
+            continue
+        if PlayerControl.GetIsTJG(curPlayer):
+            continue
+        PlayerUniversalGameRec.SendUniversalGameRecSingle(curPlayer, findRecData)
+    
+    return msgList
+
+def DoResetStoreServerBuyCnt(shopTypeList):
+    '''根据商店类型重置全服购买次数'''
+    universalRecMgr = GameWorld.GetUniversalRecMgr()
+    recTypeListData = universalRecMgr.GetTypeList(RecType)
+    
+    delCnt = 0
+    for index in xrange(recTypeListData.Count()):
+        dataIndex = index - delCnt
+        recData = recTypeListData.At(dataIndex)
+        curGoodsID = recData.GetValue1()
+        ipyData = IpyGameDataPY.GetIpyGameData("Store", curGoodsID)
+        if not ipyData:
+            continue
+        if ipyData.GetShopType() not in shopTypeList:
+            continue
+        recTypeListData.Delete(dataIndex)
+        delCnt +=1
+    GameWorld.DebugLog('    根据商店类型重置全服购买次数 shopTypeList=%s'%shopTypeList)
+    if delCnt:
+        PlayerUniversalGameRec.SendUniversalGameRecInfo(None, RecType)
+    return
+
+
+def ResetFlashSaleBuyCnt(ipyData, dayIndex, state):
+    #重置限时抢购商店全服购买次数
+    if state == 0:
+        return
+    shopTypeList = ipyData.GetShopTypeList()
+    dayShopList = shopTypeList[dayIndex] if dayIndex < len(shopTypeList) else shopTypeList[-1]
+    shopType = dayShopList[state-1] if state-1 < len(dayShopList) else dayShopList[-1]
+    DoResetStoreServerBuyCnt([shopType])
+    return
\ No newline at end of file
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py b/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
index dc883cc..367e6e4 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
@@ -232,10 +232,11 @@
 OperationActionName_FlashGiftbag = "ActFlashGiftbag" # 限时礼包活动
 OperationActionName_FairyCeremony = "ActFairyCeremony" # 仙界盛典活动
 OperationActionName_RealmPoint = "ActRealmPoint" # 多倍修行点活动
+OperationActionName_FlashSale = "ActFlashSale" # 限时抢购活动
 OperationActionNameList = [OperationActionName_ExpRate, OperationActionName_CostRebate, 
                            OperationActionName_BossReborn,OperationActionName_SpringSale, 
                            OperationActionName_FlashGiftbag, OperationActionName_FairyCeremony,
-                           OperationActionName_RealmPoint]
+                           OperationActionName_RealmPoint, OperationActionName_FlashSale]
 #需要记录开启活动时的世界等级的运营活动
 NeedWorldLVOperationActNameList = [OperationActionName_FairyCeremony]
 
@@ -923,7 +924,7 @@
                                 Def_UniversalGameRecType_DujieHelpCntRecord, # 渡劫副本护法次数5
                                 Def_UniversalGameRecType_TodayPlayerLVInfo, #今日活跃玩家等级信息6
                                 Def_UniversalGameRecType_YesterdayPlayerLVInfo,#昨日活跃玩家等级信息7
-                                Def_UniversalGameRecType_8,
+                                Def_UniversalGameRecType_StoreServerCntRecord,  #商店全服购买记录 8,
                                 Def_UniversalGameRecType_9,
                                 Def_UniversalGameRecType_10,
                                 Def_UniversalGameRecType_11,
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
index dcaa38f..960124e 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
@@ -1327,4 +1327,16 @@
 
 PacketCMD_1=0xA5
 PacketSubCMD_1=0x17
-PacketCallFunc_1=OnStartBindJadeWheel
\ No newline at end of file
+PacketCallFunc_1=OnStartBindJadeWheel
+
+;限时抢购
+[PlayerFlashSale]
+ScriptName = Player\PlayerFlashSale.py
+Writer = xdh
+Releaser = xdh
+RegType = 0
+RegisterPackCount = 1
+
+PacketCMD_1=0xAA
+PacketSubCMD_1=0x05
+PacketCallFunc_1=OnFlashSaleAppointment
\ No newline at end of file
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
index f9a704b..8a604b4 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -2142,6 +2142,7 @@
                          1000 * 3,                         # 仓库整理间隔
                          1000 * 15,                        # 渡劫鼓舞间隔
                          1000 * 1,                        # vip体验时效
+                         1000 * 1,                        # 限时抢购
                          ]
 TYPE_Player_Tick_Count = len(TYPE_Player_Tick_Time) 
 
@@ -2217,6 +2218,7 @@
 TYPE_Player_Tick_WareHouseSort,    # 仓库整理间隔
 TYPE_Player_Tick_DuJieInspire,    # 渡劫鼓舞间隔
 TYPE_Player_Tick_VIPExperience,        #vip体验时效
+TYPE_Player_Tick_FlashSale,        #限时抢购
 ) = range(0, TYPE_Player_Tick_Count)
 
 #---------------------------------------------------------------------
@@ -3039,6 +3041,7 @@
 Def_PlayerKey_ComboAddHurtPer = "ComboAddHurtPer"    #当前连击的伤害加成万分率
 Def_PlayerKey_ComboBuffProcessState = "ComboBuffProcessState"    #持续性buff连击处理状态
 Def_PlayerKey_LvAwardQueryState = 'LvAwardQueryState'  # 等级奖励领奖查询状态
+Def_PlayerKey_StoreQueryState = 'StoreQueryState'  # 商店全服购买次数查询状态
 #===============================================================================
 # # 持续性buff伤害处理连击技能ID列表
 # # 因为释放一次技能后一段时间内是持续性的, 故连接判断效果仅处理一次, 持续时间内均受此效果影响, 不重复处理连击
@@ -3193,7 +3196,7 @@
 Def_PDictType_Default,  # 默认
 Def_PDictType_OnlinePrize,  # 在线奖励(暂停使用),领取后重新计时型
 Def_PDictType_FBWipeOut,  # fb扫荡
-Def_PDictType_3,
+Def_PDictType_FlashSale, #限时抢购
 Def_PDictType_TJGNotify,  # 脱机挂结果通知
 Def_PDictType_LVAward,  # 等级奖励领取信息记录5
 Def_PDictType_GoldGift,  # 充值豪礼
@@ -3608,6 +3611,12 @@
 #绑玉转盘
 Def_PDict_BindJadeWheelCurCnt = "BindJadeWheelCurCnt"  # 今日已转次数
 Def_PDict_BindJadeWheelHistoryCnt = "BindJadeWheelHistoryCnt"  # 历史已转次数
+
+#限时抢购活动
+Def_PDict_FlashSaleID = "FlashSaleID"  # 玩家身上的限时抢购活动ID,唯一标识,取活动开始日期time
+Def_PDict_FlashSaleState = "FlashSaleState"  # 玩家身上的限时抢购活动state
+Def_PDict_FlashSaleMailState = "FlashSaleMailState"  # 玩家身上的活动更新提醒邮件状态
+Def_PDict_FlashSaleYY = "FlashSaleYY_%s"  # 玩家预约限时抢购商品
 #-------------------------------------------------------------------------------
 #类型 Def_PDictType_OnlinePrize
 Def_PDict1_OnlinePrizeCnt = "OnlinePrizeCnt"  # 新手在线已领取奖励次数
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
index 0fbe5fd..51d6d86 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
@@ -20177,6 +20177,372 @@
 
 
 #------------------------------------------------------
+# AA 18 限时抢购活动玩家预约信息 #tagMCFlashSaleAppointmentInfo
+
+class  tagMCFlashSaleAppointmentInfo(Structure):
+    Head = tagHead()
+    GoodsCount = 0    #(WORD GoodsCount)// 商品数
+    GoodsList = list()    #(vector<DWORD> GoodsList)// 预约的商品
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        self.Head.Cmd = 0xAA
+        self.Head.SubCmd = 0x18
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        _pos = self.Head.ReadData(_lpData, _pos)
+        self.GoodsCount,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        for i in range(self.GoodsCount):
+            value,_pos=CommFunc.ReadDWORD(_lpData,_pos)
+            self.GoodsList.append(value)
+        return _pos
+
+    def Clear(self):
+        self.Head = tagHead()
+        self.Head.Clear()
+        self.Head.Cmd = 0xAA
+        self.Head.SubCmd = 0x18
+        self.GoodsCount = 0
+        self.GoodsList = list()
+        return
+
+    def GetLength(self):
+        length = 0
+        length += self.Head.GetLength()
+        length += 2
+        length += 4 * self.GoodsCount
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+        data = CommFunc.WriteWORD(data, self.GoodsCount)
+        for i in range(self.GoodsCount):
+            data = CommFunc.WriteDWORD(data, self.GoodsList[i])
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Head:%s,
+                                GoodsCount:%d,
+                                GoodsList:%s
+                                '''\
+                                %(
+                                self.Head.OutputString(),
+                                self.GoodsCount,
+                                "..."
+                                )
+        return DumpString
+
+
+m_NAtagMCFlashSaleAppointmentInfo=tagMCFlashSaleAppointmentInfo()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCFlashSaleAppointmentInfo.Head.Cmd,m_NAtagMCFlashSaleAppointmentInfo.Head.SubCmd))] = m_NAtagMCFlashSaleAppointmentInfo
+
+
+#------------------------------------------------------
+# AA 17 限时抢购活动信息 #tagMCFlashSaleInfo
+
+class  tagMCFlashSaleGiftbag(Structure):
+    _pack_ = 1
+    _fields_ = [
+                  ("GiftID", c_int),    #商城表的物品ID
+                  ("BuyCountLimit", c_ubyte),    #限购数
+                  ("ServerBuyCountLimit", c_ushort),    #全服限购数
+                  ("MoneyType", c_ubyte),    #消耗货币类型
+                  ("MoneyNumber", c_int),    #消耗货币数量
+                  ("MoneyOriginal", c_int),    #原价
+                  ("ItemID", c_int),    
+                  ("ItemCount", c_ushort),    
+                  ("IsBind", c_ubyte),    
+                  ]
+
+    def __init__(self):
+        self.Clear()
+        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.GiftID = 0
+        self.BuyCountLimit = 0
+        self.ServerBuyCountLimit = 0
+        self.MoneyType = 0
+        self.MoneyNumber = 0
+        self.MoneyOriginal = 0
+        self.ItemID = 0
+        self.ItemCount = 0
+        self.IsBind = 0
+        return
+
+    def GetLength(self):
+        return sizeof(tagMCFlashSaleGiftbag)
+
+    def GetBuffer(self):
+        return string_at(addressof(self), self.GetLength())
+
+    def OutputString(self):
+        DumpString = '''// AA 17 限时抢购活动信息 //tagMCFlashSaleInfo:
+                                GiftID:%d,
+                                BuyCountLimit:%d,
+                                ServerBuyCountLimit:%d,
+                                MoneyType:%d,
+                                MoneyNumber:%d,
+                                MoneyOriginal:%d,
+                                ItemID:%d,
+                                ItemCount:%d,
+                                IsBind:%d
+                                '''\
+                                %(
+                                self.GiftID,
+                                self.BuyCountLimit,
+                                self.ServerBuyCountLimit,
+                                self.MoneyType,
+                                self.MoneyNumber,
+                                self.MoneyOriginal,
+                                self.ItemID,
+                                self.ItemCount,
+                                self.IsBind
+                                )
+        return DumpString
+
+
+class  tagMCFlashSaleShop(Structure):
+    DayIndex = 0    #(BYTE DayIndex)// 活动第几天
+    TimeIndex = 0    #(BYTE TimeIndex)// 第几个时间段
+    GiftbagCount = 0    #(BYTE GiftbagCount)// 商店礼包数
+    GiftbagInfo = list()    #(vector<tagMCFlashSaleGiftbag> GiftbagInfo)// 礼包信息
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        self.DayIndex,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.TimeIndex,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.GiftbagCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.GiftbagCount):
+            temGiftbagInfo = tagMCFlashSaleGiftbag()
+            _pos = temGiftbagInfo.ReadData(_lpData, _pos)
+            self.GiftbagInfo.append(temGiftbagInfo)
+        return _pos
+
+    def Clear(self):
+        self.DayIndex = 0
+        self.TimeIndex = 0
+        self.GiftbagCount = 0
+        self.GiftbagInfo = list()
+        return
+
+    def GetLength(self):
+        length = 0
+        length += 1
+        length += 1
+        length += 1
+        for i in range(self.GiftbagCount):
+            length += self.GiftbagInfo[i].GetLength()
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteBYTE(data, self.DayIndex)
+        data = CommFunc.WriteBYTE(data, self.TimeIndex)
+        data = CommFunc.WriteBYTE(data, self.GiftbagCount)
+        for i in range(self.GiftbagCount):
+            data = CommFunc.WriteString(data, self.GiftbagInfo[i].GetLength(), self.GiftbagInfo[i].GetBuffer())
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                DayIndex:%d,
+                                TimeIndex:%d,
+                                GiftbagCount:%d,
+                                GiftbagInfo:%s
+                                '''\
+                                %(
+                                self.DayIndex,
+                                self.TimeIndex,
+                                self.GiftbagCount,
+                                "..."
+                                )
+        return DumpString
+
+
+class  tagMCFlashSaleTime(Structure):
+    StartTime = ""    #(char StartTime[5])// 开始时间 H:M
+    EndtTime = ""    #(char EndtTime[5])// 结束时间 H:M
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        self.StartTime,_pos = CommFunc.ReadString(_lpData, _pos,5)
+        self.EndtTime,_pos = CommFunc.ReadString(_lpData, _pos,5)
+        return _pos
+
+    def Clear(self):
+        self.StartTime = ""
+        self.EndtTime = ""
+        return
+
+    def GetLength(self):
+        length = 0
+        length += 5
+        length += 5
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteString(data, 5, self.StartTime)
+        data = CommFunc.WriteString(data, 5, self.EndtTime)
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                StartTime:%s,
+                                EndtTime:%s
+                                '''\
+                                %(
+                                self.StartTime,
+                                self.EndtTime
+                                )
+        return DumpString
+
+
+class  tagMCFlashSaleInfo(Structure):
+    Head = tagHead()
+    StartDate = ""    #(char StartDate[10])// 开始日期 y-m-d
+    EndtDate = ""    #(char EndtDate[10])// 结束日期 y-m-d
+    AdvanceMinutes = 0    #(WORD AdvanceMinutes)// 提前显示分钟
+    ActivityTimeCount = 0    #(BYTE ActivityTimeCount)
+    ActivityTime = list()    #(vector<tagMCFlashSaleTime> ActivityTime)//活动时间
+    IsDayReset = 0    #(BYTE IsDayReset)//是否每天重置
+    LimitLV = 0    #(WORD LimitLV)// 限制等级
+    ShopCount = 0    #(BYTE ShopCount)// 商店数
+    ShopInfo = list()    #(vector<tagMCFlashSaleShop> ShopInfo)// 商店信息, 当有多个商店且有多个活动时间段时则每个时间段对应一个商店;
+    data = None
+
+    def __init__(self):
+        self.Clear()
+        self.Head.Cmd = 0xAA
+        self.Head.SubCmd = 0x17
+        return
+
+    def ReadData(self, _lpData, _pos=0, _Len=0):
+        self.Clear()
+        _pos = self.Head.ReadData(_lpData, _pos)
+        self.StartDate,_pos = CommFunc.ReadString(_lpData, _pos,10)
+        self.EndtDate,_pos = CommFunc.ReadString(_lpData, _pos,10)
+        self.AdvanceMinutes,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.ActivityTimeCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.ActivityTimeCount):
+            temActivityTime = tagMCFlashSaleTime()
+            _pos = temActivityTime.ReadData(_lpData, _pos)
+            self.ActivityTime.append(temActivityTime)
+        self.IsDayReset,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        self.LimitLV,_pos = CommFunc.ReadWORD(_lpData, _pos)
+        self.ShopCount,_pos = CommFunc.ReadBYTE(_lpData, _pos)
+        for i in range(self.ShopCount):
+            temShopInfo = tagMCFlashSaleShop()
+            _pos = temShopInfo.ReadData(_lpData, _pos)
+            self.ShopInfo.append(temShopInfo)
+        return _pos
+
+    def Clear(self):
+        self.Head = tagHead()
+        self.Head.Clear()
+        self.Head.Cmd = 0xAA
+        self.Head.SubCmd = 0x17
+        self.StartDate = ""
+        self.EndtDate = ""
+        self.AdvanceMinutes = 0
+        self.ActivityTimeCount = 0
+        self.ActivityTime = list()
+        self.IsDayReset = 0
+        self.LimitLV = 0
+        self.ShopCount = 0
+        self.ShopInfo = list()
+        return
+
+    def GetLength(self):
+        length = 0
+        length += self.Head.GetLength()
+        length += 10
+        length += 10
+        length += 2
+        length += 1
+        for i in range(self.ActivityTimeCount):
+            length += self.ActivityTime[i].GetLength()
+        length += 1
+        length += 2
+        length += 1
+        for i in range(self.ShopCount):
+            length += self.ShopInfo[i].GetLength()
+
+        return length
+
+    def GetBuffer(self):
+        data = ''
+        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
+        data = CommFunc.WriteString(data, 10, self.StartDate)
+        data = CommFunc.WriteString(data, 10, self.EndtDate)
+        data = CommFunc.WriteWORD(data, self.AdvanceMinutes)
+        data = CommFunc.WriteBYTE(data, self.ActivityTimeCount)
+        for i in range(self.ActivityTimeCount):
+            data = CommFunc.WriteString(data, self.ActivityTime[i].GetLength(), self.ActivityTime[i].GetBuffer())
+        data = CommFunc.WriteBYTE(data, self.IsDayReset)
+        data = CommFunc.WriteWORD(data, self.LimitLV)
+        data = CommFunc.WriteBYTE(data, self.ShopCount)
+        for i in range(self.ShopCount):
+            data = CommFunc.WriteString(data, self.ShopInfo[i].GetLength(), self.ShopInfo[i].GetBuffer())
+        return data
+
+    def OutputString(self):
+        DumpString = '''
+                                Head:%s,
+                                StartDate:%s,
+                                EndtDate:%s,
+                                AdvanceMinutes:%d,
+                                ActivityTimeCount:%d,
+                                ActivityTime:%s,
+                                IsDayReset:%d,
+                                LimitLV:%d,
+                                ShopCount:%d,
+                                ShopInfo:%s
+                                '''\
+                                %(
+                                self.Head.OutputString(),
+                                self.StartDate,
+                                self.EndtDate,
+                                self.AdvanceMinutes,
+                                self.ActivityTimeCount,
+                                "...",
+                                self.IsDayReset,
+                                self.LimitLV,
+                                self.ShopCount,
+                                "..."
+                                )
+        return DumpString
+
+
+m_NAtagMCFlashSaleInfo=tagMCFlashSaleInfo()
+ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCFlashSaleInfo.Head.Cmd,m_NAtagMCFlashSaleInfo.Head.SubCmd))] = m_NAtagMCFlashSaleInfo
+
+
+#------------------------------------------------------
 # AA 05 充值排行特惠信息 #tagMCRechargeRankTeHuiInfo
 
 class  tagMCRechargeRankTeHuiInfo(Structure):
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventSrc/FunctionNPCCommon.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventSrc/FunctionNPCCommon.py
index b3684b9..6774b4b 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventSrc/FunctionNPCCommon.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Event/EventSrc/FunctionNPCCommon.py
@@ -57,7 +57,7 @@
 import PlayerControl
 import ItemCommon
 import ShareDefine
-import DataRecordPack
+import PlayerFlashSale
 #import EventSrc
 import ChItem
 import IpyGameDataPY
@@ -340,8 +340,8 @@
     if not ipyData:
         return
     shopType = ipyData.GetShopType()
-    
-    if ipyData.GetOperationActionShop():
+    operationActionShopType = ipyData.GetOperationActionShop()
+    if operationActionShopType == 1:
         actInfo = PyGameData.g_operationActionDict.get(ShareDefine.OperationActionName_SpringSale, {})
         state = actInfo.get(ShareDefine.ActKey_State, 0)
         if not state:
@@ -353,6 +353,20 @@
         actShopType = shopTypeList[-1] if state > len(shopTypeList) else shopTypeList[state - 1]
         if shopType != actShopType:
             GameWorld.DebugLog("限时特惠非活动中的商店类型!state=%s,shopType=%s,actShopType=%s,shopTypeList=%s" 
+                               % (state, shopType, actShopType, shopTypeList), curPlayer.GetPlayerID())
+            return
+    elif operationActionShopType == 2:
+        actInfo = PyGameData.g_operationActionDict.get(ShareDefine.OperationActionName_FlashSale, {})
+        state = actInfo.get(ShareDefine.ActKey_State, 0)
+        if not state:
+            GameWorld.DebugLog("限时抢购非活动中!state=%s" % (state), curPlayer.GetPlayerID())
+            return
+        shopTypeList = PlayerFlashSale.GetShopTypeList(actInfo.get(ShareDefine.ActKey_CfgID, 0), actInfo.get(ShareDefine.ActKey_DayIndex, 0), state)
+        if not shopTypeList:
+            return
+        actShopType = shopTypeList[0]
+        if shopType != actShopType:
+            GameWorld.DebugLog("限时抢购非活动中的商店类型!state=%s,shopType=%s,actShopType=%s,shopTypeList=%s" 
                                % (state, shopType, actShopType, shopTypeList), curPlayer.GetPlayerID())
             return
         
@@ -381,7 +395,7 @@
         if limitBuyCnt == -1:
             GameWorld.DebugLog("    vip%s才能购买"%viplv)
             return
-        
+    
     curDayBuyCnt = 0
     dayBuyCntKey = ChConfig.Def_PDict_ShopItemDayBuyCnt % itemIndex
     if limitBuyCnt > 0:
@@ -394,7 +408,10 @@
             GameWorld.DebugLog("BuyShopItem 修正购买次数!shopType=%s,itemIndex=%s,clientBuyCount=%s,canBuyCnt=%s" 
                                % (shopType, itemIndex, clientBuyCount, canBuyCnt))
             clientBuyCount = canBuyCnt
-            
+    serverLimitCnt = ipyData.GetServerLimitCnt()
+    if serverLimitCnt > 0:
+        clientBuyCount = min(serverLimitCnt, clientBuyCount)
+        
     itemID, itemCount, isBind = ipyData.GetItemID(), ipyData.GetItemCnt(), ipyData.GetIsBind()
     itemListEx = ipyData.GetItemListEx()
     priceType, itemPrice = ipyData.GetMoneyType(), ipyData.GetMoneyNum()
@@ -447,18 +464,43 @@
         GameWorld.Log("Store shop item buy limit! shopType=%s,itemIndex=%s,limitValue=%s" 
                       % (shopType, itemIndex, ipyData.GetLimitValue()), curPlayer.GetPlayerID())
         return
+    if not PlayerControl.HaveMoney(curPlayer, priceType, itemPrice):
+        curPlayer.ShopResult(itemIndex, IPY_GameWorld.tsrNoMoney)
+        return
     
+    if serverLimitCnt > 0: #全服限购判断放到最后面,GameServer直接加次数
+        if curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_StoreQueryState) == 1:
+            #已经在查询中, 不重复查询
+            GameWorld.DebugLog("全服购买次数已经在查询中, 不重复查询 itemIndex=%s" % itemIndex)
+            return
+        cmdStr = '%s' % ([itemIndex, serverLimitCnt, clientBuyCount, totalItemList, mainItemID, limitBuyCnt])
+        GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(curPlayer.GetID(), 0, 0,
+                                        "GetStoreServerBuyCnt", cmdStr, len(cmdStr))
+        #设置状态查询中
+        curPlayer.SetDict(ChConfig.Def_PlayerKey_StoreQueryState, 1)
+        return
     #-------------------------开始购买物品-----------------------------
+    DoBuyStoreItem(curPlayer, itemIndex, clientBuyCount, totalItemList, mainItemID, limitBuyCnt, ipyData)
+    
+    return
+
+def DoBuyStoreItem(curPlayer, itemIndex, clientBuyCount, totalItemList, mainItemID, limitBuyCnt, ipyData=None):
+    if not ipyData:
+        ipyData = IpyGameDataPY.GetIpyGameData("Store", itemIndex)
+    priceType, itemPrice = ipyData.GetMoneyType(), ipyData.GetMoneyNum()
+    shopType = ipyData.GetShopType()
+    
     beforeMoney = PlayerControl.GetMoney(curPlayer, priceType)
     infoDict = {"TotalItemList":totalItemList, "ClientBuyCount":clientBuyCount, "ShopType":shopType,
                 "ShopItemIndex":itemIndex, ChConfig.Def_Cost_Reason_SonKey:mainItemID}
-    if not PlayerControl.PayMoney(curPlayer, priceType, itemPrice, ChConfig.Def_Cost_BuyStoreItem, infoDict, clientBuyCount):
-        curPlayer.ShopResult(itemIndex, IPY_GameWorld.tsrNoMoney)
-        return
+    PlayerControl.PayMoney(curPlayer, priceType, itemPrice, ChConfig.Def_Cost_BuyStoreItem, infoDict, clientBuyCount)
+        
     afterMoney = PlayerControl.GetMoney(curPlayer, priceType)
     
     # 今日购买次数+1
     if limitBuyCnt > 0:
+        dayBuyCntKey = ChConfig.Def_PDict_ShopItemDayBuyCnt % itemIndex
+        curDayBuyCnt = curPlayer.NomalDictGetProperty(dayBuyCntKey)
         PlayerControl.NomalDictSetProperty(curPlayer, dayBuyCntKey, curDayBuyCnt + clientBuyCount)
         SyncShopItemTodayBuyCount(curPlayer, [itemIndex])
         
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
index 6c738f8..a6ee6f5 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
@@ -628,6 +628,7 @@
                         ("list", "LimitVIPLV", 0),
                         ("DWORD", "LimitLV", 0),
                         ("list", "LimitCnt", 0),
+                        ("DWORD", "ServerLimitCnt", 0),
                         ("BYTE", "MoneyType", 0),
                         ("DWORD", "MoneyNum", 0),
                         ("DWORD", "MoneyOriginal", 0),
@@ -1014,6 +1015,20 @@
                         ("DWORD", "SkillID", 1),
                         ("BYTE", "TalentType", 0),
                         ("BYTE", "Series", 0),
+                        ),
+
+                "ActFlashSale":(
+                        ("DWORD", "CfgID", 1),
+                        ("char", "StartDate", 0),
+                        ("char", "EndDate", 0),
+                        ("list", "StartTimeList", 0),
+                        ("list", "EndTimeList", 0),
+                        ("WORD", "AdvanceMinutes", 0),
+                        ("WORD", "LVLimit", 0),
+                        ("BYTE", "IsDayReset", 0),
+                        ("list", "ShopTypeList", 0),
+                        ("char", "MailKey", 0),
+                        ("list", "MailItemPrize", 0),
                         ),
                 }
 
@@ -2247,6 +2262,7 @@
         self.LimitVIPLV = []
         self.LimitLV = 0
         self.LimitCnt = []
+        self.ServerLimitCnt = 0
         self.MoneyType = 0
         self.MoneyNum = 0
         self.MoneyOriginal = 0
@@ -2266,7 +2282,8 @@
     def GetRefreshType(self): return self.RefreshType # 刷新类型 0-不重置,1-onWeek0点,2-onWeek5点,3-OnDay0点,4-OnDay5点
     def GetLimitVIPLV(self): return self.LimitVIPLV # VIP限制
     def GetLimitLV(self): return self.LimitLV # 等级限制
-    def GetLimitCnt(self): return self.LimitCnt # 限制数量
+    def GetLimitCnt(self): return self.LimitCnt # 个人限制数量
+    def GetServerLimitCnt(self): return self.ServerLimitCnt # 全服限制数量
     def GetMoneyType(self): return self.MoneyType # 金钱类型
     def GetMoneyNum(self): return self.MoneyNum # 金钱数量
     def GetMoneyOriginal(self): return self.MoneyOriginal # 原价
@@ -3079,6 +3096,35 @@
     def GetSkillID(self): return self.SkillID # 技能ID
     def GetTalentType(self): return self.TalentType # 天赋类型
     def GetSeries(self): return self.Series # 天赋系别
+
+# 限时抢购表
+class IPY_ActFlashSale():
+    
+    def __init__(self):
+        self.CfgID = 0
+        self.StartDate = ""
+        self.EndDate = ""
+        self.StartTimeList = []
+        self.EndTimeList = []
+        self.AdvanceMinutes = 0
+        self.LVLimit = 0
+        self.IsDayReset = 0
+        self.ShopTypeList = []
+        self.MailKey = ""
+        self.MailItemPrize = []
+        return
+        
+    def GetCfgID(self): return self.CfgID # 配置ID
+    def GetStartDate(self): return self.StartDate # 开启日期
+    def GetEndDate(self): return self.EndDate # 结束日期
+    def GetStartTimeList(self): return self.StartTimeList # 开启时间列表, 支持多个时段
+    def GetEndTimeList(self): return self.EndTimeList # 结束时间列表, 支持多个时段
+    def GetAdvanceMinutes(self): return self.AdvanceMinutes # 前端提前X分钟展示活动
+    def GetLVLimit(self): return self.LVLimit # 限制等级
+    def GetIsDayReset(self): return self.IsDayReset # 是否每天重置
+    def GetShopTypeList(self): return self.ShopTypeList # 商店类型列表
+    def GetMailKey(self): return self.MailKey # 活动更新时发送邮件key
+    def GetMailItemPrize(self): return self.MailItemPrize # 活动更新时发送邮件奖励物品
 
 
 def Log(msg, playerID=0, par=0):
@@ -3292,6 +3338,8 @@
         self.ipyMapEventPointLen = len(self.ipyMapEventPointCache)
         self.ipyTalentSkillCache = self.__LoadFileData("TalentSkill", IPY_TalentSkill)
         self.ipyTalentSkillLen = len(self.ipyTalentSkillCache)
+        self.ipyActFlashSaleCache = self.__LoadFileData("ActFlashSale", IPY_ActFlashSale)
+        self.ipyActFlashSaleLen = len(self.ipyActFlashSaleCache)
         Log("IPY_FuncConfig count=%s" % len(self.ipyFuncConfigDict))
         Log("IPY_DataMgr InitOK!")
         return
@@ -3646,6 +3694,8 @@
     def GetMapEventPointByIndex(self, index): return self.ipyMapEventPointCache[index]
     def GetTalentSkillCount(self): return self.ipyTalentSkillLen
     def GetTalentSkillByIndex(self, index): return self.ipyTalentSkillCache[index]
+    def GetActFlashSaleCount(self): return self.ipyActFlashSaleLen
+    def GetActFlashSaleByIndex(self, index): return self.ipyActFlashSaleCache[index]
 
 IPYData = IPY_DataMgr()
 def IPY_Data(): return IPYData
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 fb1a30c..29bb164 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
@@ -102,7 +102,7 @@
 import PlayerTJG
 import GameLogic_XMZZ
 import GameLogic_SealDemon
-import GameLogic_Dogz
+import PlayerFlashSale
 import PlayerFlashGiftbag
 import PlayerCostRebate
 import PlayerSpringSale
@@ -491,7 +491,8 @@
     PlayerSpringSale.OnPlayerLogin(curPlayer)
     #限时礼包
     PlayerFlashGiftbag.OnPlayerLogin(curPlayer)
-    
+    #限时抢购
+    PlayerFlashSale.OnPlayerLogin(curPlayer)
 #    # 消费VIP
 #    PlayerCostVIP.CostVIPOnLogin(curPlayer, tick)
 #    
@@ -544,7 +545,7 @@
     # 骑宠
     FamilyRobBoss.OnPlayerLogin(curPlayer)
     # 绑玉转盘
-    PlayerBindJadeWheel.OnDay(curPlayer)
+    PlayerBindJadeWheel.OnLogin(curPlayer)
     
     # 上线查询一次充值订单
     curPlayer.SendDBQueryRecharge()
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 e7e2154..00ab102 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
@@ -91,6 +91,7 @@
 import PlayerFlashGiftbag
 import PlayerFairyCeremony
 import PlayerRefineStove
+import PlayerFlashSale
 import PlayerVip
 import PlayerDiceEx
 import IpyGameDataPY
@@ -1280,6 +1281,9 @@
             
             elif actionName == ShareDefine.OperationActionName_FairyCeremony:
                 PlayerFairyCeremony.RefreshOperationAction_FairyCeremony()
+            
+            elif actionName == ShareDefine.OperationActionName_FlashSale:
+                PlayerFlashSale.RefreshflashSaleActionInfo()
             return
         
         if msgValue.isdigit():
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFlashSale.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFlashSale.py
new file mode 100644
index 0000000..7e3cb9a
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerFlashSale.py
@@ -0,0 +1,258 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package Player.PlayerFlashSale
+#
+# @todo:限时抢购活动
+# @author xdh
+# @date 2018-7-17
+# @version 1.0
+#
+# 详细描述: 限时抢购活动
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2018-7-17 12:00"""
+#-------------------------------------------------------------------------------
+
+import PyGameData
+import ShareDefine
+import PlayerControl
+import IpyGameDataPY
+import FunctionNPCCommon
+import ChPyNetSendPack
+import NetPackCommon
+import GameWorld
+import ChConfig
+
+import datetime
+
+
+def GetShopTypeList(cfgID, dayIndex, state):
+    if cfgID == 0 or state == 0:
+        return []
+    ipyData = IpyGameDataPY.GetIpyGameData("ActFlashSale", cfgID)
+    if not ipyData:
+        return []
+    shopTypeList = ipyData.GetShopTypeList()
+    todayShopTypeList = shopTypeList[-1] if dayIndex >= len(shopTypeList) else shopTypeList[dayIndex]
+    return [todayShopTypeList[state - 1] if state - 1 < len(todayShopTypeList) else todayShopTypeList[-1]]
+
+
+def OnPlayerLogin(curPlayer):
+    __CheckPlayerflashSaleAction(curPlayer)
+    return
+
+
+def RefreshflashSaleActionInfo():
+    ## 收到GameServer同步的活动信息,刷新活动信息
+    playerManager = GameWorld.GetPlayerManager()
+    for index in xrange(playerManager.GetPlayerCount()):
+        curPlayer = playerManager.GetPlayerByIndex(index)
+        if curPlayer.GetID() == 0:
+            continue
+        __CheckPlayerflashSaleAction(curPlayer)
+    return
+
+
+def __CheckPlayerflashSaleAction(curPlayer):
+    ## 检查玩家限时抢购活动数据信息
+    
+    playerID = curPlayer.GetPlayerID()
+    
+    actInfo = PyGameData.g_operationActionDict.get(ShareDefine.OperationActionName_FlashSale, {})
+    actID = actInfo.get(ShareDefine.ActKey_ID, 0)
+    state = actInfo.get(ShareDefine.ActKey_State, 0)
+    cfgID = actInfo.get(ShareDefine.ActKey_CfgID, 0)
+    dayIndex = actInfo.get(ShareDefine.ActKey_DayIndex, 0)
+    playerActID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FlashSaleID, 0, ChConfig.Def_PDictType_FlashSale)  # 玩家身上的活动ID
+    playerActState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FlashSaleState, 0, ChConfig.Def_PDictType_FlashSale)  # 玩家身上的活动State
+    playerMailState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FlashSaleMailState, 0, ChConfig.Def_PDictType_FlashSale)  # 玩家身上的活动提醒邮件状态
+    isReset = False
+    if actID != playerActID or (state != playerActState):
+        isReset = True
+        if cfgID:
+            flashSaleIpyData = IpyGameDataPY.GetIpyGameData("ActFlashSale", cfgID)
+            startDate = flashSaleIpyData.GetStartDate()
+            startTimeNum = GameWorld.ChangeTimeStrToNum(startDate, timeFormat=ChConfig.TYPE_Time_Format_Day)
+        else:
+            startTimeNum = 0
+        if playerMailState != startTimeNum:
+            GameWorld.DebugLog('    限时抢购活动重置!')
+            curPlayer.ClearNomalDict(ChConfig.Def_PDictType_FlashSale)
+        
+        shopTypeList = GetShopTypeList(cfgID, dayIndex, state)
+        if shopTypeList:
+            FunctionNPCCommon.ResetShopItemBuyCountByShopType(curPlayer, shopTypeList)
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FlashSaleID, actID, ChConfig.Def_PDictType_FlashSale)
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FlashSaleState, state, ChConfig.Def_PDictType_FlashSale)
+        #Sync_flashSaleActionInfo(curPlayer)
+        GameWorld.DebugLog("限时抢购单场重置! actID=%s,playerActID=%s,dayIndex=%s,state=%s,playerActState=%s,shopTypeList=%s,playerMailState=%s" % (actID, playerActID, dayIndex, state, playerActState, shopTypeList,playerMailState), playerID)
+    else:
+        GameWorld.DebugLog("限时抢购活动ID不变,不处理!", playerID)
+        
+    if cfgID:
+        Sync_flashSaleActionInfo(curPlayer)
+        Sync_FlashSaleAppointmentInfo(curPlayer)
+    return isReset
+
+
+def ProcessFlashSaleMail(curPlayer, tick):
+    if not GameWorld.SetPlayerTickTime(curPlayer, ChConfig.TYPE_Player_Tick_FlashSale, tick):
+        return
+    playerMailState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FlashSaleMailState, 0, ChConfig.Def_PDictType_FlashSale)  # 玩家身上的活动提醒邮件状态
+    if playerMailState:
+        return
+    actInfo = PyGameData.g_operationActionDict.get(ShareDefine.OperationActionName_FlashSale, {})
+    if not actInfo:
+        return
+    cfgID = actInfo.get(ShareDefine.ActKey_CfgID, 0)
+    if not cfgID:
+        return
+    flashSaleIpyData = IpyGameDataPY.GetIpyGameData("ActFlashSale", cfgID)
+    if not flashSaleIpyData:
+        return
+    mailKey = flashSaleIpyData.GetMailKey()
+    LVLimit = flashSaleIpyData.GetLVLimit()
+    if not mailKey or curPlayer.GetLV() < LVLimit:
+        return
+    startDate = flashSaleIpyData.GetStartDate()
+    endDate = flashSaleIpyData.GetEndDate()
+    startTimeList = flashSaleIpyData.GetStartTimeList()
+    endTimeList = flashSaleIpyData.GetEndTimeList()
+    if not startTimeList or not endTimeList:
+        return
+    advanceMinutes = flashSaleIpyData.GetAdvanceMinutes()
+    startTime = datetime.datetime.strptime("%s %s:00" % (startDate, startTimeList[0]), ChConfig.TYPE_Time_Format) + datetime.timedelta(minutes=-advanceMinutes)
+    endTime = datetime.datetime.strptime("%s %s:00" % (endDate, endTimeList[-1]), ChConfig.TYPE_Time_Format)
+    curDateTime = GameWorld.GetCurrentTime()
+    if startTime <= curDateTime <= endTime:
+        PlayerControl.SendMailByKey(mailKey, [curPlayer.GetID()], flashSaleIpyData.GetMailItemPrize())
+        startTimeNum = GameWorld.ChangeTimeStrToNum(startDate, timeFormat=ChConfig.TYPE_Time_Format_Day)
+        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FlashSaleMailState, startTimeNum, ChConfig.Def_PDictType_FlashSale)
+        GameWorld.DebugLog("    发送新限时抢购邮件提醒!", curPlayer.GetID())
+#    else:
+#        GameWorld.DebugLog("    发送新限时抢购邮件提醒  时间没到!startTime=%s,endTime=%s,curDateTime=%s"%(startTime,endTime,curDateTime), curPlayer.GetID())
+    return
+
+
+def Sync_flashSaleActionInfo(curPlayer):
+    ## 通知限时抢购活动信息
+    actInfo = PyGameData.g_operationActionDict.get(ShareDefine.OperationActionName_FlashSale, {})
+    if not actInfo:
+        return
+    
+    #需要提前通知,所以去掉此限制
+    #if not actInfo.get(ShareDefine.ActKey_State):
+    #    return
+    
+    cfgID = actInfo.get(ShareDefine.ActKey_CfgID, 0)
+    if not cfgID:
+        return
+
+    flashSaleIpyData = IpyGameDataPY.GetIpyGameData("ActFlashSale", cfgID)
+    if not flashSaleIpyData:
+        return
+    shopTypeList = flashSaleIpyData.GetShopTypeList()
+    startTimeList = flashSaleIpyData.GetStartTimeList()
+    endTimeList = flashSaleIpyData.GetEndTimeList()
+    if len(startTimeList) != len(endTimeList):
+        GameWorld.ErrLog("限时抢购开关时间时分配置错误!cfgID=%s" % cfgID)
+        return
+    
+    openServerDay = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_ServerDay) + 1
+    packInfo = ChPyNetSendPack.tagMCFlashSaleInfo()
+    packInfo.StartDate = GameWorld.GetOperationActionDateStr(flashSaleIpyData.GetStartDate(), openServerDay)
+    packInfo.EndtDate = GameWorld.GetOperationActionDateStr(flashSaleIpyData.GetEndDate(), openServerDay)
+    packInfo.AdvanceMinutes = flashSaleIpyData.GetAdvanceMinutes()
+    packInfo.ActivityTime = []
+    for i, startTime in enumerate(startTimeList):
+        timeInfo = ChPyNetSendPack.tagMCFlashSaleTime()
+        timeInfo.StartTime = startTime
+        timeInfo.EndtTime = endTimeList[i]
+        packInfo.ActivityTime.append(timeInfo)
+    packInfo.ActivityTimeCount = len(packInfo.ActivityTime)
+    packInfo.IsDayReset = flashSaleIpyData.GetIsDayReset()
+    packInfo.LimitLV = flashSaleIpyData.GetLVLimit()
+    packInfo.ShopInfo = []
+    for dayIndex, shopList in enumerate(shopTypeList):
+        for timeIndex, shopType in enumerate(shopList): 
+            shopItemIpyDataList = IpyGameDataPY.GetIpyGameDataByCondition("Store", {"ShopType":shopType}, True, True)
+            if not shopItemIpyDataList:
+                continue
+            
+            shop = ChPyNetSendPack.tagMCFlashSaleShop()
+            shop.DayIndex = dayIndex
+            shop.TimeIndex = timeIndex
+            shop.GiftbagInfo = []
+            
+            for itemIpyData in shopItemIpyDataList:
+                giftBag = ChPyNetSendPack.tagMCFlashSaleGiftbag()
+                giftBag.GiftID = itemIpyData.GetID()
+                giftBag.BuyCountLimit = 0 if not itemIpyData.GetLimitCnt() else itemIpyData.GetLimitCnt()[0]
+                giftBag.ServerBuyCountLimit = itemIpyData.GetServerLimitCnt()
+                giftBag.MoneyType = itemIpyData.GetMoneyType()
+                giftBag.MoneyNumber = itemIpyData.GetMoneyNum()
+                giftBag.MoneyOriginal = itemIpyData.GetMoneyOriginal()
+                giftBag.ItemID = itemIpyData.GetItemID()
+                giftBag.ItemCount = itemIpyData.GetItemCnt()
+                giftBag.IsBind = itemIpyData.GetIsBind()
+                shop.GiftbagInfo.append(giftBag)
+                
+            shop.GiftbagCount = len(shop.GiftbagInfo)
+            packInfo.ShopInfo.append(shop)
+        
+    packInfo.ShopCount = len(packInfo.ShopInfo)
+    NetPackCommon.SendFakePack(curPlayer, packInfo)
+    return
+
+
+#// AA 05 限时抢购预约 #tagCMFlashSaleAppointment
+#
+#struct     tagCMFlashSaleAppointment
+#{
+#    tagHead        Head;
+#    DWORD        GoodsID;         // 抢购商品标识
+#    BYTE        State;         // 1-预约 0-取消
+#};
+def OnFlashSaleAppointment(index, packData, tick):
+    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+    goodsID = packData.GoodsID
+    
+    actInfo = PyGameData.g_operationActionDict.get(ShareDefine.OperationActionName_FlashSale, {})
+    if not actInfo:
+        return
+    cfgID = actInfo.get(ShareDefine.ActKey_CfgID, 0)
+    if not cfgID:
+        return
+    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_FlashSaleYY % goodsID, packData.State, ChConfig.Def_PDictType_FlashSale)
+    return
+
+
+def Sync_FlashSaleAppointmentInfo(curPlayer):
+    ##通知限时抢购预约情况
+    actInfo = PyGameData.g_operationActionDict.get(ShareDefine.OperationActionName_FlashSale, {})
+    if not actInfo:
+        return
+    cfgID = actInfo.get(ShareDefine.ActKey_CfgID, 0)
+    if not cfgID:
+        return
+    flashSaleIpyData = IpyGameDataPY.GetIpyGameData("ActFlashSale", cfgID)
+    if not flashSaleIpyData:
+        return
+    packInfo = ChPyNetSendPack.tagMCFlashSaleAppointmentInfo()
+    packInfo.GoodsList = []
+    shopTypeList = flashSaleIpyData.GetShopTypeList()
+    for dayIndex, shopList in enumerate(shopTypeList):
+        for timeIndex, shopType in enumerate(shopList):
+            shopItemIpyDataList = IpyGameDataPY.GetIpyGameDataByCondition("Store", {"ShopType":shopType}, True, True)
+            if not shopItemIpyDataList:
+                continue
+            for i in xrange(len(shopItemIpyDataList)):
+                goodsMark = dayIndex * 10000 + timeIndex * 100 + i  #商品标识
+                isAppointment = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_FlashSaleYY % goodsMark, 0, ChConfig.Def_PDictType_FlashSale)
+                if isAppointment:
+                    packInfo.GoodsList.append(goodsMark)
+    packInfo.GoodsCount = len(packInfo.GoodsList)
+    NetPackCommon.SendFakePack(curPlayer, packInfo)
+    return
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py
index 9912a3e..5d48d00 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerState.py
@@ -55,6 +55,7 @@
 import PassiveBuffEffMng
 import PlayerFamilyRedPacket
 import PlayerGoldGift
+import PlayerFlashSale
 import PlayerWing
 import ChEquip
 
@@ -1227,6 +1228,8 @@
     PlayerSuccess.FinishDelayAddSuccessProgress(curPlayer, tick, False)
     #开服红包处理
     PlayerFamilyRedPacket.ProcessOSRedPacket(curPlayer, tick)
+    #限时抢购
+    PlayerFlashSale.ProcessFlashSaleMail(curPlayer, tick)
     return
 
 
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_GetStoreServerBuyCnt.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_GetStoreServerBuyCnt.py
new file mode 100644
index 0000000..951cd1a
--- /dev/null
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_GetStoreServerBuyCnt.py
@@ -0,0 +1,57 @@
+#!/usr/bin/python
+# -*- coding: GBK -*-
+#-------------------------------------------------------------------------------
+#
+##@package Player.RemoteQuery.GY_Query_GetStoreServerBuyCnt
+#
+# @todo:商城全服限购处理
+# @author xdh
+# @date 2018-03-07
+# @version 1.0
+#
+# 详细描述: 商城全服限购处理
+#
+#-------------------------------------------------------------------------------
+#"""Version = 2018-03-07 17:30"""
+#-------------------------------------------------------------------------------
+
+import GameWorld
+import FunctionNPCCommon
+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):
+    GameWorld.DebugLog("GY_Query_GetStoreServerBuyCnt funResult=%s" % funResult)
+    curPlayer.SetDict(ChConfig.Def_PlayerKey_StoreQueryState, 0)
+    result = eval(funResult)
+    if len(result) != 6:
+        return
+    itemIndex, serverLimitCnt, clientBuyCount, totalItemList, mainItemID, limitBuyCnt = result
+    FunctionNPCCommon.DoBuyStoreItem(curPlayer, itemIndex, clientBuyCount, totalItemList, mainItemID, limitBuyCnt)
+    
+    return
+
+
diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
index dc883cc..367e6e4 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
@@ -232,10 +232,11 @@
 OperationActionName_FlashGiftbag = "ActFlashGiftbag" # 限时礼包活动
 OperationActionName_FairyCeremony = "ActFairyCeremony" # 仙界盛典活动
 OperationActionName_RealmPoint = "ActRealmPoint" # 多倍修行点活动
+OperationActionName_FlashSale = "ActFlashSale" # 限时抢购活动
 OperationActionNameList = [OperationActionName_ExpRate, OperationActionName_CostRebate, 
                            OperationActionName_BossReborn,OperationActionName_SpringSale, 
                            OperationActionName_FlashGiftbag, OperationActionName_FairyCeremony,
-                           OperationActionName_RealmPoint]
+                           OperationActionName_RealmPoint, OperationActionName_FlashSale]
 #需要记录开启活动时的世界等级的运营活动
 NeedWorldLVOperationActNameList = [OperationActionName_FairyCeremony]
 
@@ -923,7 +924,7 @@
                                 Def_UniversalGameRecType_DujieHelpCntRecord, # 渡劫副本护法次数5
                                 Def_UniversalGameRecType_TodayPlayerLVInfo, #今日活跃玩家等级信息6
                                 Def_UniversalGameRecType_YesterdayPlayerLVInfo,#昨日活跃玩家等级信息7
-                                Def_UniversalGameRecType_8,
+                                Def_UniversalGameRecType_StoreServerCntRecord,  #商店全服购买记录 8,
                                 Def_UniversalGameRecType_9,
                                 Def_UniversalGameRecType_10,
                                 Def_UniversalGameRecType_11,

--
Gitblit v1.8.0