| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
| #-------------------------------------------------------------------------------  | 
| #  | 
| #-------------------------------------------------------------------------------  | 
| #  | 
| ##@package Event.EventSrc.ShopItemManage  | 
| #  | 
| # @todo:×Ô¶¨ÒåÉÌµê  | 
| # @author hxp  | 
| # @date 2014-06-21  | 
| # @version 2.4  | 
| #  | 
| # @change: "2014-08-27 11:30" hxp Ôö¼ÓÕۿ۵깺ÂòÎïÆ·È«·þ¹ã²¥  | 
| # @change: "2014-11-26 15:30" hxp Ôö¼ÓÏÞʱ¹ºÂò״̬ÅÐ¶Ï  | 
| # @change: "2014-11-27 20:30" hxp Ôö¼Ó¹ºÂòÎïÆ·È«·þ¹ã²¥  | 
| # @change: "2014-12-02 11:30" hxp ºÏ·þÕÛ¿Ûµê»î¶¯Ö§³Ö  | 
| # @change: "2014-12-08 17:00" hxp Ôö¼Ó×êʯÏû·ÑÁ÷Ïò  | 
| # @change: "2014-12-12 17:00" hxp ¹ºÂòÕÛ¿ÛµêÎïÆ·¹ã²¥Ð޸ģ¬¿É¸ù¾ÝÉ̵êIDÅäÖò»Í¬µÄ¹ã²¥ÐÅÏ¢  | 
| # @change: "2015-02-04 17:00" hxp ¶¨Ê±ÉñÃØÉ̵ê; ¹ºÂòÎïÆ·¹ã²¥ÐÞ¸Ä  | 
| # @change: "2015-02-10 22:30" hxp Ôö¼Ó×êʯÏûºÄÀàÐÍʼþ»ã±¨  | 
| # @change: "2016-01-26 15:00" hxp PY±íÖ§³ÖÖØ¶Á  | 
| # @change: "2016-07-20 14:30" hxp »õ±ÒÖ§¸¶Á÷ÏòÕûºÏ  | 
| # @change: "2016-09-19 10:30" hxp ÖØÖÃÉ̵êÐÅϢȫ·þÍæ¼ÒÈËÊý»ñÈ¡·½Ê½ÐÞ¸Ä  | 
| # @change: "2016-10-02 10:30" xdh É̵굥¸öÉÌÆ·Ë÷ÒýÖ§³Ö¶à¸öÎïÆ·  | 
| # @change: "2016-11-04 21:00" hxp Ôö¼Ó¶à¸öÎïÆ·°üÉÌÆ·Ãû¼Ç¼£»ÐÞ¸´ÉÌÆ·ÃûÎ޼ǼÎÊÌâ  | 
| # ÏêϸÃèÊö: ×Ô¶¨ÒåÉÌµê  | 
| #---------------------------------------------------------------------  | 
| #"""Version = 2017-05-12 18:00"""  | 
| #---------------------------------------------------------------------  | 
|   | 
| import PyMapTable  | 
| import GameWorld  | 
| import ChPyNetSendPack  | 
| import NetPackCommon  | 
| import ChConfig  | 
| import PlayerControl  | 
| import ItemCommon  | 
| import IPY_GameWorld  | 
| import ItemControler  | 
| import DataRecordPack  | 
| import ShareDefine  | 
| import ReadChConfig  | 
| import PlayerTeHui  | 
| import PlayerActivity  | 
| import EventShell  | 
|   | 
| import math  | 
|   | 
| PerDictKeyMaxCnt = 30  | 
| g_shopDetailInfoDict = {}  | 
|   | 
| # ÉñÃØÉ̵êÅäÖö¨Òå  | 
| (  | 
| Def_TimeShop_RefreshCnt, # Ë¢Ð¸öÊý  | 
| Def_TimeShop_RateList, # Ë÷Òý±ýͼ¸ÅÂÊÁÐ±í  | 
| Def_TimeShop_ExclusionList, # »¥³âË÷ÒýÁÐ±í  | 
| Def_TimeShop_CostFormat, # ÏûºÄ¹«Ê½  | 
| Def_TimeShop_MustItemCnt, # Ë¢Ð´ÎÊý¶ÔÓ¦±Ø³öÎïÆ·ÐÅÏ¢  | 
| Def_TimeShop_Max,  | 
| ) = range(6)  | 
|   | 
|   | 
| ## »ñÈ¡É̵êÎïÆ·¸öÊý  | 
| #  @param shopID:É̵êID  | 
| #  @return  | 
| def GetShopItemCnt(shopID):  | 
|     shopDetailInfo = __GetShopDetailInfo(shopID)  | 
|     return shopDetailInfo[0]  | 
|   | 
| ## »ñÈ¡É̵ê¸öÈËÏÞ¹ºÎïÆ·indexÁÐ±í  | 
| #  @param shopID:É̵êID  | 
| #  @return  | 
| def GetPlayerBuyCntLimitIndexList(shopID):  | 
|     shopDetailInfo = __GetShopDetailInfo(shopID)  | 
|     return shopDetailInfo[1]  | 
|   | 
| ## »ñÈ¡É̵êÈ«·þÏÞ¹ºÎïÆ·indexÁÐ±í  | 
| #  @param shopID:É̵êID  | 
| #  @return  | 
| def GetServerBuyCntLimitIndexList(shopID):  | 
|     shopDetailInfo = __GetShopDetailInfo(shopID)  | 
|     return shopDetailInfo[2]  | 
|   | 
| ## »ñÈ¡É̵êÎïÆ·Ïà¹Ø×Ô¶¨ÒåÃ÷ϸÐÅÏ¢  | 
| #  @param shopID:É̵êID  | 
| #  @return  | 
| def __GetShopDetailInfo(shopID):  | 
|     if shopID not in g_shopDetailInfoDict:  | 
|         GetShopItemList(shopID)  | 
|           | 
|     if shopID not in g_shopDetailInfoDict:  | 
|         return [0, [], []]  | 
|       | 
|     return g_shopDetailInfoDict[shopID]  | 
|   | 
| ## ¸üÐÂÉ̵êÎïÆ·Ïà¹Ø×Ô¶¨ÒåÃ÷ϸÐÅÏ¢  | 
| #  @param shopID:É̵êID  | 
| #  @return  | 
| def __UpdateShopDetailInfo(shopID, shopItemList):  | 
|     global g_shopDetailInfoDict  | 
|       | 
|     if shopID not in g_shopDetailInfoDict:  | 
|         playerBuyCntLimitIndexList = []  | 
|         serverBuyCntLimitIndexList = []  | 
|         for itemInfoDict in shopItemList:  | 
|             itemShopIndex = int(itemInfoDict["ItemShopIndex"])  | 
|             maxBuyCnt = int(itemInfoDict["MaxBuyCnt"])  | 
|             serverMaxBuyCnt = int(itemInfoDict["ServerMaxBuyCnt"])  | 
|             if maxBuyCnt > 0:  | 
|                 playerBuyCntLimitIndexList.append(itemShopIndex)  | 
|             if serverMaxBuyCnt > 0:  | 
|                 serverBuyCntLimitIndexList.append(itemShopIndex)  | 
|           | 
|         shopDetail = [len(shopItemList), playerBuyCntLimitIndexList, serverBuyCntLimitIndexList]  | 
|         GameWorld.DebugLog("¸üÐÂÉ̵êÃ÷ϸͳ¼Æ: shopID=%s,shopDetail=%s" % (shopID, str(shopDetail)))  | 
|         g_shopDetailInfoDict[shopID] = shopDetail  | 
|           | 
|     return g_shopDetailInfoDict[shopID]  | 
|   | 
| ## »ñÈ¡É̵êÎïÆ·ÁÐ±í  | 
| #  @param shopID:É̵êID  | 
| #  @return [{},{},...]  | 
| def GetShopItemList(shopID):  | 
|     if shopID <= 0:  | 
|         return []  | 
|       | 
|     shopItemTable = PyMapTable.GetPyMapTable("ShopItem")  | 
|     itemDataList = shopItemTable.GetRecord("ShopID", str(shopID))  | 
|     if not itemDataList:  | 
|         GameWorld.ErrLog("ÕÒ²»µ½É̵êÎïÆ·ShopItem.txt not itemData shopID=%s" % shopID)  | 
|   | 
|     __UpdateShopDetailInfo(shopID, itemDataList)  | 
|     return itemDataList  | 
|   | 
| ## »ñȡָ¶¨É̵êÎïÆ·ÐÅÏ¢  | 
| #  @param shopID:É̵êID  | 
| #  @param itemShopIndex:ÎïÆ·Ë÷Òý  | 
| #  @return {}  | 
| def GetShopItemInfoDict(shopID, itemShopIndex):  | 
|     itemInfoDict = {}  | 
|     shopItemTable = PyMapTable.GetPyMapTable("ShopItem")  | 
|     itemDataList = shopItemTable.GetRecordByDic({"ShopID":str(shopID), "ItemShopIndex":str(itemShopIndex)})  | 
|     if not itemDataList:  | 
|         GameWorld.ErrLog("ÕÒ²»µ½É̵êÎïÆ·ShopItem.txt,shopID=%s,itemShopIndex=%s" % (shopID, itemShopIndex))  | 
|         return itemInfoDict  | 
|       | 
|     if len(itemDataList) != 1:  | 
|         GameWorld.ErrLog("É̵êÎïÆ·ÖØ¸´ShopItem.txt,shopID=%s,itemShopIndex=%s,Êý¾ÝÌõÊý=%s"   | 
|                          % (shopID, itemShopIndex, len(itemDataList)))  | 
|         return itemInfoDict  | 
|       | 
|     itemInfoDict = itemDataList[0]  | 
|     return itemInfoDict  | 
|   | 
| ## »ñÈ¡¸öÈËÏÞ¹ºÎïÆ·ÒѹºÂò´ÎÊý  | 
| #  @param curPlayer  | 
| #  @param shopID:É̵êID  | 
| #  @param itemShopIndex:ÎïÆ·Ë÷Òý  | 
| #  @return  | 
| def __GetPlayerShopItemBuyCnt(curPlayer, shopID, itemIndex):  | 
|     key = ChConfig.Def_PDict_ShopItemBuyCnt % (shopID, itemIndex)  | 
|     return curPlayer.NomalDictGetProperty(key, 0)  | 
|   | 
| ## ÉèÖøöÈËÏÞ¹ºÎïÆ·ÒѹºÂò´ÎÊý  | 
| #  @param curPlayer  | 
| #  @param shopID:É̵êID  | 
| #  @param itemShopIndex:ÎïÆ·Ë÷Òý  | 
| #  @param cnt:  | 
| #  @return  | 
| def __SetPlayerShopItemBuyCnt(curPlayer, shopID, itemIndex, cnt):  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ShopItemBuyCnt % (shopID, itemIndex), cnt)  | 
|     return  | 
|   | 
|   | 
| ## Çå³ý¸öÈËÏÞ¹ºÎïÆ·¹ºÂò´ÎÊý  | 
| #  @param curPlayer  | 
| #  @param shopID:É̵êID  | 
| #  @return  | 
| def ClearPlayerShopItemBuyCnt(curPlayer, shopID):  | 
|     playerBuyCntLimit = GetPlayerBuyCntLimitIndexList(shopID)  | 
|     # ÕâÀïÖ»×öÇå¿Õ¸öÈËÏÞ¹ºÊý¾Ý£¬²»×ö֪ͨ£¬Ö»ÔÚÍæ¼ÒÇëÇóÉ̵êÎïÆ·Êý¾Ýʱͬ²½  | 
|     for index in playerBuyCntLimit:  | 
|         curBuyCnt = __GetPlayerShopItemBuyCnt(curPlayer, shopID, index)  | 
|         if curBuyCnt != 0:  | 
|             __SetPlayerShopItemBuyCnt(curPlayer, shopID, index, 0)  | 
|           | 
|     return  | 
|   | 
|   | 
| ## Çå³ýÉ̵êÏÞ¹ºÎïÆ·¹ºÂò´ÎÊý£¨°üº¬È«·þÏÞ¹º£©  | 
| #  @param shopID:É̵êID  | 
| #  @return  | 
| def ClearShopItemBuyCnt(shopID):  | 
|     # Í¨ÖªGameServerÇå³ýshopIDÈ«·þÏÞ¹ºÊý¾Ý  | 
|     msgList = [shopID]  | 
|     GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(0, 0, 0, 'ShopItemClearBuyCnt', \  | 
|                 '%s' % (msgList), len(str(msgList)))  | 
|     return  | 
|   | 
| # A2 07 ÇëÇó×Ô¶¨ÒåÉ̵êÎïÆ·ÐÅÏ¢ #tagCMQueryShopItem  | 
| ## ¿Í·þ¶ËÁìÈ¡³äÖµÌØ»Ý½±Àø  | 
| #  @param index:Íæ¼ÒË÷Òý  | 
| #  @param clientPack:·â°ü½á¹¹Ìå  | 
| #  @param tick:ʱ¼ä´Á  | 
| #  @return None  | 
| def QueryShopItem(index, clientPack, tick):  | 
|     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  | 
|     shopID = clientPack.ShopID  | 
|     shopItemList = GetShopItemList(shopID)  | 
|       | 
|     if not shopItemList:  | 
|         return  | 
|       | 
|     Send_ShopItem(curPlayer, shopItemList)  | 
|     Sync_ShopItemBuyCntInfo(curPlayer, shopID)  | 
|     return  | 
|   | 
|   | 
| ## ·¢ËÍÉ̵êÎïÆ·  | 
| #  @param curPlayer:  | 
| #  @param itemList: ÐÅÏ¢ÁÐ±í  | 
| #  @return  | 
| def Send_ShopItem(curPlayer, itemList):  | 
|     shopPack = ChPyNetSendPack.tagMCShopItemInfoList()  | 
|     shopPack.Clear()  | 
|     shopPack.ShopItemList = []  | 
|       | 
|     TimeShopRefreshItem = ReadChConfig.GetEvalChConfig("TimeShopRefreshItem")  | 
|       | 
|     for itemInfoDict in itemList:  | 
|         itemInfo = ChPyNetSendPack.tagMCShopItemInfo()  | 
|         itemInfo.ShopID = int(itemInfoDict["ShopID"])  | 
|         itemInfo.ItemShopIndex = int(itemInfoDict["ItemShopIndex"])  | 
|           | 
|         # Èç¹ûÊǶ¨Ê±Ëæ»úˢеÄÉ̵ֻ꣬ͬ²½Íæ¼Òµ±Ç°¿É¼ûµÄ  | 
|         if itemInfo.ShopID in TimeShopRefreshItem and \  | 
|                 not __GetShopItemState(curPlayer, itemInfo.ShopID, itemInfo.ItemShopIndex):  | 
|             continue  | 
|         itemInfoList = __GetShopItemList(itemInfoDict)  | 
|         itemInfo.ItemList = str(itemInfoList)  | 
|         itemInfo.DataSize = len(itemInfo.ItemList)  | 
|         itemInfo.PriceType = int(itemInfoDict["PriceType"])  | 
|         itemInfo.Price = int(itemInfoDict["Price"])  | 
|         itemInfo.OriginalPrice = int(itemInfoDict["OriginalPrice"])  | 
|         itemInfo.PlayerLVLimit = int(itemInfoDict["PlayerLVLimit"])  | 
|         itemInfo.FamilyLVLimit = int(itemInfoDict["FamilyLVLimit"])  | 
|         itemInfo.MaxBuyCnt = int(itemInfoDict["MaxBuyCnt"])  | 
|         itemInfo.ServerMaxBuyCnt = int(itemInfoDict["ServerMaxBuyCnt"])  | 
|         shopPack.ShopItemList.append(itemInfo)  | 
|   | 
|     shopPack.Count = len(shopPack.ShopItemList)  | 
|     NetPackCommon.SendFakePack(curPlayer, shopPack)  | 
|     return  | 
|   | 
|   | 
| ## ·¢ËÍÉ̵êÏÞ¹º´ÎÊýÐÅÏ¢  | 
| #  @param curPlayer:  | 
| #  @param shopID: É̵êid  | 
| #  @return  | 
| def Sync_ShopItemBuyCntInfo(curPlayer, shopID):  | 
|     serverBuyLimitIndexList = GetServerBuyCntLimitIndexList(shopID)  | 
|     if not serverBuyLimitIndexList:  | 
|         playerBuyCntLimit = GetPlayerBuyCntLimitIndexList(shopID)  | 
|         if playerBuyCntLimit:  | 
|             Send_ShopItemAllBuyCntInfo(curPlayer, shopID)  | 
|         return  | 
|       | 
|     # ÇëÇóGameServerÍÆËÍÈ«·þÏÞ¹º¸öÊýÃ÷ϸºóÔÙͬ²½¸øÍæ¼Ò[shopID, serverBuyLimitIndexList]  | 
|     cmdStr = '%s' % ([ShareDefine.Def_ShopItem_QueryServerBuyCnt, shopID, serverBuyLimitIndexList])  | 
|     GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(curPlayer.GetID(), 0, 0,  | 
|                                     "ShopItem", cmdStr, len(cmdStr))  | 
|     return  | 
|   | 
|   | 
| ## ·¢ËÍÉ̵êËùÓÐÎïÆ·ÏÞ¹º´ÎÊýÐÅÏ¢  | 
| #  @param curPlayer:  | 
| #  @param shopID: É̵êid  | 
| #  @param serverBuyCntDict: È«·þÏÞ¹ºÐÅÏ¢{index:cnt,...}£¬Ò»°ãÓÉGameServerͬ²½¹ýÀ´  | 
| #  @return  | 
| def Send_ShopItemAllBuyCntInfo(curPlayer, shopID, serverBuyCntDict={}):  | 
|       | 
|     sendIndexList = GetPlayerBuyCntLimitIndexList(shopID)  | 
|     serverLimitIndexList = GetServerBuyCntLimitIndexList(shopID)  | 
|       | 
|     for index in serverLimitIndexList:  | 
|           | 
|         if index in sendIndexList:  | 
|             continue  | 
|           | 
|         sendIndexList.append(index)  | 
|       | 
|     if not sendIndexList:  | 
|         return  | 
|       | 
|     Send_ShopItemBuyCntInfo(curPlayer, shopID, sendIndexList, serverBuyCntDict)  | 
|     return  | 
|   | 
|   | 
| ## Í¬²½ÏÞ¹ºÎïÆ·ÒѹºÂò´ÎÊý  | 
| #  @param curPlayer:   | 
| #  @param shopID:   | 
| #  @param sendIndexList:   | 
| #  @param serverBuyCntDict:   | 
| #  @return  | 
| def Send_ShopItemBuyCntInfo(curPlayer, shopID, sendIndexList, serverBuyCntDict):  | 
|     buyCntPack = ChPyNetSendPack.tagMCShopItemBuyCntInfoList()  | 
|     buyCntPack.Clear()  | 
|     buyCntPack.BuyCntList = []  | 
|       | 
|     TimeShopRefreshItem = ReadChConfig.GetEvalChConfig("TimeShopRefreshItem")  | 
|       | 
|     for itemIndex in sendIndexList:  | 
|           | 
|         buyCntInfo = ChPyNetSendPack.tagMCShopItemBuyCntInfo()  | 
|         buyCntInfo.ShopID = shopID  | 
|         buyCntInfo.ItemShopIndex = itemIndex  | 
|   | 
|         # Èç¹ûÊǶ¨Ê±Ëæ»úˢеÄÉ̵ֻ꣬ͬ²½Íæ¼Òµ±Ç°¿É¼ûµÄ  | 
|         if buyCntInfo.ShopID in TimeShopRefreshItem and \  | 
|                 not __GetShopItemState(curPlayer, buyCntInfo.ShopID, buyCntInfo.ItemShopIndex):  | 
|             continue  | 
|           | 
|         buyCntInfo.ItemID = 0 # ²»·¢ËÍItemID£¬·â°ü¾ÍÏȲ»¸ÄÁË  | 
|         buyCntInfo.BuyCnt = __GetPlayerShopItemBuyCnt(curPlayer, shopID, itemIndex)  | 
|         buyCntInfo.ServerBuyCnt = serverBuyCntDict.get(itemIndex, 0)  | 
|         buyCntPack.BuyCntList.append(buyCntInfo)  | 
|           | 
|     buyCntPack.Count = len(buyCntPack.BuyCntList)  | 
|     NetPackCommon.SendFakePack(curPlayer, buyCntPack)  | 
|     return  | 
|   | 
|   | 
| # A2 08 ¹ºÂò×Ô¶¨ÒåÉ̵êÎïÆ· #tagCMBuyShopItem  | 
| ## ¿Í·þ¶ËÁìÈ¡³äÖµÌØ»Ý½±Àø  | 
| #  @param index:Íæ¼ÒË÷Òý  | 
| #  @param clientPack:·â°ü½á¹¹Ìå  | 
| #  @param tick:ʱ¼ä´Á  | 
| #  @return None  | 
| def BuyShopItem(index, clientPack, tick):  | 
|     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  | 
|     shopID = clientPack.ShopID  | 
|     itemShopIndex = clientPack.ItemShopIndex  | 
|     buyCount = clientPack.BuyCount  | 
|     GameWorld.DebugLog("¹ºÂòÉ̵êÎïÆ·ShopItem.txt,shopID=%s,itemShopIndex=%s,buyCount=%s"   | 
|                          % (shopID, itemShopIndex, buyCount), curPlayer.GetPlayerID())  | 
|       | 
|     discountShopIDDict = ReadChConfig.GetEvalChConfig("TeHuiAction_DiscountShopID")  | 
|       | 
|     if shopID in discountShopIDDict:  | 
|         curActionShopIDList = PlayerTeHui.GetCurActionShowIDList()  | 
|         if shopID not in curActionShopIDList:  | 
|             GameWorld.Log("    ²»ÊǻÖеÄÌØ»ÝÕÛ¿ÛµêID£¬ÎÞ·¨¹ºÂò!curActionShopIDList=%s"   | 
|                           % str(curActionShopIDList))  | 
|             return  | 
|       | 
|     itemInfoDict = GetShopItemInfoDict(shopID, itemShopIndex)  | 
|     if not itemInfoDict:  | 
|         return  | 
|       | 
|     priceType = int(itemInfoDict["PriceType"])  | 
|     price = int(itemInfoDict["Price"])  | 
|     playerLVLimit = int(itemInfoDict["PlayerLVLimit"])  | 
|     familyLVLimit = int(itemInfoDict["FamilyLVLimit"])  | 
|     maxBuyCnt = int(itemInfoDict["MaxBuyCnt"])  | 
|     serverMaxBuyCnt = int(itemInfoDict["ServerMaxBuyCnt"])  | 
|     isLimitTime = int(itemInfoDict["IsLimitTime"])  | 
|     # Èç¹ûÊÇÏÞʱ¹ºÂòµÄ£¬ÔòÐèÒªÅжÏÉ̵꿪Æô״̬  | 
|     if isLimitTime:  | 
|         gameWorld = GameWorld.GetGameWorld()  | 
|         shopStateKey = ShareDefine.Def_Notify_WorldKey_ShopState % shopID  | 
|         isShopOpen = gameWorld.GetGameWorldDictByKey(shopStateKey)  | 
|         if not isShopOpen:  | 
|             GameWorld.Log("    ¸ÃÉ̵êûÓпª·Å¹ºÂò!shopID=%s" % shopID)  | 
|             return  | 
|       | 
|     TimeShopRefreshItem = ReadChConfig.GetEvalChConfig("TimeShopRefreshItem")  | 
|       | 
|     # ÉñÃØË¢ÐÂÉ̵꣬¼ì²éÍæ¼ÒÊÇ·ñË¢³ö¸ÃÎïÆ·  | 
|     if shopID in TimeShopRefreshItem and not __GetShopItemState(curPlayer, shopID, itemShopIndex):  | 
|         GameWorld.Log("    ÉñÃØÉÌµê£¬Íæ¼Òδˢ³ö¸ÃÎïÆ·!²»¿É¹ºÂò£¡shopID=%s,itemShopIndex=%s"   | 
|                       % (shopID, itemShopIndex), curPlayer.GetPlayerID())  | 
|         return  | 
|   | 
|       | 
|     totalPrice = buyCount * price  | 
|     if not PlayerControl.HaveMoney(curPlayer, priceType, totalPrice):  | 
|         GameWorld.DebugLog("    »õ±Ò²»×㣬ÎÞ·¨¹ºÂò!priceType=%s,price=%s,totalPrice=%s"   | 
|                            % (priceType, price, totalPrice))  | 
|         return  | 
|       | 
|     if curPlayer.GetLV() < playerLVLimit:  | 
|         GameWorld.DebugLog("    Íæ¼ÒµÈ¼¶²»×㣬ÎÞ·¨¹ºÂò!getPlayerLV=%s,playerLVLimit=%s"   | 
|                            % (curPlayer.GetLV(), playerLVLimit))  | 
|         return  | 
|       | 
|     playerFamilyLV = curPlayer.GetFamilyLV()  | 
|     if playerFamilyLV < familyLVLimit:  | 
|         GameWorld.DebugLog("    Õ½Ã˵ȼ¶²»×㣬ÎÞ·¨¹ºÂò!playerFamilyLV=%s, familyLVLimit=%s"   | 
|                            % (playerFamilyLV, familyLVLimit))  | 
|         return  | 
|       | 
|     playerCanBuyCnt = -1 # Ä¬Èϲ»ÏÞÖÆ¹ºÂò´ÎÊý  | 
|     if maxBuyCnt > 0:  | 
|         playerBuyCnt = __GetPlayerShopItemBuyCnt(curPlayer, shopID, itemShopIndex)  | 
|         playerCanBuyCnt = max(0, maxBuyCnt - playerBuyCnt) # ¸öÈËÏÞ¹º»¹¿É¹ºÂòµÄ¸öÊý  | 
|         if playerCanBuyCnt <= 0 or playerCanBuyCnt < buyCount:  | 
|             GameWorld.DebugLog("    ¸öÈËÏÞ¹º´ÎÊý²»×㣬ÎÞ·¨¹ºÂò!ÒѹºÂò´ÎÊý=%s,Óû¹ºÂò=%s,×î´ó´ÎÊý=%s"   | 
|                                % (playerBuyCnt, buyCount, maxBuyCnt))  | 
|             return  | 
|           | 
|       | 
|     # Èç¹ûÓÐÈ«·þÏÞ¹º£¬Ôòͨ¹ýGameServerÅжϷµ»ØÊÇ·ñ¿É¹ºÂòÔÙ´¦Àí    | 
|     if serverMaxBuyCnt > 0:  | 
|         cmdStr = '%s' % ([ShareDefine.Def_ShopItem_BuyItem, shopID, itemShopIndex, buyCount, serverMaxBuyCnt])  | 
|         GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(curPlayer.GetID(), 0, 0,  | 
|                                         "ShopItem", cmdStr, len(cmdStr))  | 
|         return  | 
|       | 
|     DoBuyShopItem(curPlayer, itemInfoDict, buyCount)  | 
|     return  | 
|   | 
| ## Ö´ÐйºÂòÎïÆ·  | 
| #  @param curPlayer:Íæ¼Ò  | 
| #  @param itemInfoDict:É̵êÐÅÏ¢×Öµä  | 
| #  @param buyCount:¹ºÂò¸öÊý  | 
| #  @param serverBuyCnt:È«·þÏÞ¹ºÒѹºÂò¸öÊý£¬²»Îª-1ʱ´ú±íGameServerÒѳɹ¦´¦ÀíÍê±Ï£¬²¢Í¬²½×îÐÂÈ«·þÏÞ¹º´ÎÊý»ØÀ´  | 
| #  @return None  | 
| #  @remarks ±¾º¯ÊýÖ´ÐÐǰÌáΪËùÓÐÌõ¼þ¶¼ÒÑÅжϹý   | 
| def DoBuyShopItem(curPlayer, itemInfoDict, buyCount, serverBuyCnt=-1):  | 
| #    shopID = int(itemInfoDict["ShopID"])  | 
| #    itemShopIndex = int(itemInfoDict["ItemShopIndex"])  | 
| #    priceType = int(itemInfoDict["PriceType"])  | 
| #    price = int(itemInfoDict["Price"])  | 
| #    maxBuyCnt = int(itemInfoDict["MaxBuyCnt"])  | 
| #    serverMaxBuyCnt = int(itemInfoDict["ServerMaxBuyCnt"])  | 
| #      | 
| #    itemInfoList = __GetShopItemList(itemInfoDict)  | 
| #    if not itemInfoList:  | 
| #        GameWorld.ErrLog("DoBuyCustomShopItem shopID=%s,itemShopIndex=%s is not data!" % (shopID, itemShopIndex), curPlayer.GetPlayerID())  | 
| #        return  | 
| #      | 
| #    itemID = itemInfoList[0][0]  | 
| #    isAppoint = itemInfoList[0][3]  | 
| #    if isAppoint:  | 
| #        itemID = ItemControler.GetAppointItemRealID(itemID)  | 
| #          | 
| #    curItem = GameWorld.GetGameData().GetItemByTypeID(itemID)  | 
| #    if not curItem:  | 
| #        GameWorld.ErrLog("DoBuyCustomShopItem itemID=%s is not data!" % itemID, curPlayer.GetPlayerID())  | 
| #        return  | 
| #    if curItem.GetType() == ChConfig.Def_ItemType_Rune:  | 
| #        packType = ShareDefine.rptRune  | 
| #    else:  | 
| #        packType = IPY_GameWorld.rptItem  | 
| #      | 
| #      | 
| #    emptySpace = ItemCommon.GetItemPackSpace(curPlayer, packType, len(itemInfoList))  | 
| #    if len(itemInfoList) > emptySpace:  | 
| #        GameWorld.DebugLog("    ±³°üûÓпÕ룬ÎÞ·¨¹ºÂò!packType=%s"%packType)  | 
| #        return  | 
| #      | 
| #    itemName = "" # ³¬¹ý1¸öÎïÆ·Ê±È¡ÎïÆ·×éºÏ°üÃû  | 
| #    if len(itemInfoList) > 1:  | 
| #        itemName = itemInfoDict["ItemPackName"]  | 
| #          | 
| #    if not itemName:  | 
| #          | 
| #        itemName = curItem.GetName()  | 
| #          | 
| #    # ¿ÛÇ®  | 
| #    totalPrice = buyCount * price  | 
| #    infoDict = {'shopID':shopID,'itemShopIndex':itemShopIndex,'buyCount':buyCount, ChConfig.Def_Cost_Reason_SonKey:itemName}  | 
| #    if not PlayerControl.PayMoney(curPlayer, priceType, totalPrice, ChConfig.Def_Cost_BuyCustomShopItem, infoDict, buyCount):  | 
| #        return  | 
| #    #»îÔ¾¶È(ÌØÊâÉ̵껨×êʯ¹ºÂò¶«Î÷Ëã»îÔ¾)  | 
| ##    if priceType == IPY_GameWorld.TYPE_Price_Gold_Money and shopID in [1010]:  | 
| ##        PlayerActivity.AddActivityFinishCnt(curPlayer, ShareDefine.ActivityNum_SuperMarketGold)  | 
| #      | 
| #    # ´ú±íGameServerÒѳɹ¦´¦ÀíÍê±Ï£¬²¢Í¬²½×îÐÂÈ«·þÏÞ¹º´ÎÊý»ØÀ´  | 
| #    if serverBuyCnt != -1:  | 
| #        if maxBuyCnt > 0: # È«·þÏÞ¹º£¬Í¬Ê±Ò²ÊǸöÈËÏÞ¹º  | 
| #            playerBuyCnt = __GetPlayerShopItemBuyCnt(curPlayer, shopID, itemShopIndex)  | 
| #            __SetPlayerShopItemBuyCnt(curPlayer, shopID, itemShopIndex, playerBuyCnt + buyCount)  | 
| #          | 
| #        Send_ShopItemBuyCntInfo(curPlayer, shopID, [itemShopIndex], {itemShopIndex:serverBuyCnt})  | 
| #          | 
| #    # Ôö¼Ó¸öÈ˹ºÂò´ÎÊý  | 
| #    elif maxBuyCnt > 0:  | 
| #        playerBuyCnt = __GetPlayerShopItemBuyCnt(curPlayer, shopID, itemShopIndex)  | 
| #        __SetPlayerShopItemBuyCnt(curPlayer, shopID, itemShopIndex, playerBuyCnt + buyCount)  | 
| #          | 
| #        # ·ÇÈ«·þÏÞ¹º£¬ÇÒ¸öÈËÏÞ¹º²ÅÐèҪͬ²½¹ºÂò´ÎÊý  | 
| #        # È«·þÏÞ¹º±ä¸üÓÉGameServerÈ«·þ¹ã²¥Í¬²½  | 
| #        if serverMaxBuyCnt <= 0:  | 
| #            Send_ShopItemBuyCntInfo(curPlayer, shopID, [itemShopIndex], {})  | 
| #      | 
| #    TimeShopRefreshItem = ReadChConfig.GetEvalChConfig("TimeShopRefreshItem") # ÉñÃØÉÌµê  | 
| #      | 
| #    # ÌØ»ÝÕۿ۵깺Âò¹ã²¥  | 
| #    discountShopIDDict = ReadChConfig.GetEvalChConfig("TeHuiAction_DiscountShopID")  | 
| #      | 
| #    eventDataEx = {"shopID":shopID, "itemShopIndex":itemShopIndex}  | 
| #    # ¸øÎïÆ·  | 
| #    for itemID, itemCount, isBind, isAppoint in itemInfoList:  | 
| #        totalCnt = itemCount * buyCount  | 
| #          | 
| #        if isAppoint == 0:  | 
| #            realItemID = itemID  | 
| #            ItemControler.GivePlayerItem(curPlayer, itemID, totalCnt, 0, [IPY_GameWorld.rptItem, IPY_GameWorld.rptAnyWhere], event=["BuyShopItem", True, eventDataEx])  | 
| #        else:  | 
| #            realItemID = ItemControler.GetAppointItemRealID(itemID)  | 
| #            for i in range(buyCount):  | 
| #                ItemControler.GivePlayerAppointItem(curPlayer, itemID, False, event=["BuyShopItem", True, eventDataEx])  | 
| #         | 
| #        if shopID in discountShopIDDict:  | 
| #            notifyMark = discountShopIDDict[shopID]  | 
| #            if notifyMark:  | 
| #                PlayerControl.WorldNotify(0, notifyMark, [curPlayer.GetPlayerName(), realItemID, realItemID])  | 
| #        else:  | 
| #            __BuyItemNotify(curPlayer, shopID, realItemID)  | 
| #              | 
| #    EventShell.EventRespons_OnBuyTeHuiItem(curPlayer, shopID, itemShopIndex)  | 
| #      | 
| #    #¹ºÂòÎïÆ·¹ã²¥(¸ù¾ÝÎïÆ·É̵êË÷Òý¹ã²¥)  | 
| #    __BuyItemIndexNotify(curPlayer, shopID, itemShopIndex)  | 
|     return  | 
|   | 
|   | 
| ## ¹ºÂòÎïÆ·¹ã²¥(¸ù¾ÝÎïÆ·É̵êË÷Òý¹ã²¥)  | 
| #  @param curPlayer:Íæ¼Ò  | 
| #  @return None  | 
| def __BuyItemIndexNotify(curPlayer, shopID, itemShopIndex):  | 
|     playerName = curPlayer.GetPlayerName()  | 
|     BuyItemIndexNotifyDict = eval(ReadChConfig.GetChConfig('BuyItemIndexNotify'))  | 
|     if shopID not in BuyItemIndexNotifyDict:  | 
|         return  | 
|     notifyItemDict = BuyItemIndexNotifyDict[shopID]  | 
|       | 
|     if -1 in notifyItemDict:  | 
|         notifyMark, paramList = notifyItemDict[-1]  | 
|     elif itemShopIndex in notifyItemDict:  | 
|         notifyMark, paramList = notifyItemDict[itemShopIndex]  | 
|     else:  | 
|         return  | 
|       | 
|     PlayerControl.WorldNotify(0, notifyMark, paramList)  | 
|     return  | 
|   | 
| ## »ñÈ¡ÎïÆ·ÐÅÏ¢ÁÐ±í  | 
| def __GetShopItemList(itemInfoDict):  | 
|     itemInfoList = []  | 
|     for i in range(1, 11): #ÔÝÖ§³Ö10¸öÎïÆ·  | 
|         itemID = itemInfoDict.get("ItemID%d" % i)  | 
|         if not itemID or itemID == '-' or itemID == '0':  | 
|             break  | 
|         itemID = int(itemID)  | 
|         itemCount = int(itemInfoDict["ItemCount%d" % i])  | 
|         isBind = int(itemInfoDict["IsBind%d" % i])  | 
|         isAppoint = int(itemInfoDict["IsAppoint%d" % i])  | 
|   | 
|         itemInfoList.append([itemID, itemCount, isBind, isAppoint])  | 
|     return itemInfoList  | 
|   | 
|   | 
| ## ¹ºÂòÎïÆ·¹ã²¥  | 
| #  @param curPlayer:Íæ¼Ò  | 
| #  @return None  | 
| def __BuyItemNotify(curPlayer, shopID, itemID):  | 
|     playerName = curPlayer.GetPlayerName()  | 
|   | 
|     BuyItemNotifyDict = eval(ReadChConfig.GetChConfig('BuyItemNotify'))  | 
|     if shopID not in BuyItemNotifyDict:  | 
|         return  | 
|       | 
|     notifyItemDict = BuyItemNotifyDict[shopID]  | 
|       | 
|     if 0 in notifyItemDict:  | 
|         notifyMark, paramList = notifyItemDict[0]  | 
|     elif itemID in notifyItemDict:  | 
|         notifyMark, paramList = notifyItemDict[itemID]  | 
|     else:  | 
|         return  | 
|       | 
|     PlayerControl.WorldNotify(0, notifyMark, paramList)  | 
|     return  | 
|   | 
|   | 
| ## Íæ¼ÒµÇ¼  | 
| #  @param curPlayer:Íæ¼Ò  | 
| #  @return None  | 
| def DoOnLogin(curPlayer):  | 
|     TimeShopRefreshItem = ReadChConfig.GetEvalChConfig("TimeShopRefreshItem")  | 
|       | 
|     gameWorld = GameWorld.GetGameWorld()  | 
|     for shopID in TimeShopRefreshItem.keys():  | 
|   | 
|         shopStateKey = ShareDefine.Def_Notify_WorldKey_ShopState % shopID  | 
|         shopState = gameWorld.GetGameWorldDictByKey(shopStateKey)  | 
|           | 
|         curWorldRefreshTimeKey = ShareDefine.Def_Notify_WorldKey_TimeShopRefreshTime % shopID  | 
|         curWorldRefreshTime = gameWorld.GetGameWorldDictByKey(curWorldRefreshTimeKey)  | 
|   | 
|         if not shopState or not curWorldRefreshTime:  | 
|             GameWorld.DebugLog("ÉñÃØÉ̵ê(%s)·Ç¿ªÆô״̬!shopState=%s,curWorldRefreshTime=%s"   | 
|                                % (shopID, shopState, curWorldRefreshTime))  | 
|             continue  | 
|           | 
|           | 
|         playerRefreshTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TimeShopLastGlobalRefreshTime % shopID)  | 
|           | 
|         if curWorldRefreshTime == playerRefreshTime:  | 
|             Sync_ShopRefreshCnt(curPlayer, shopID)  | 
|             GameWorld.DebugLog("ÉñÃØÉ̵ê(%s)curWorldRefreshTime=%sÓëÍæ¼ÒÏàͬ£¡" % (shopID, curWorldRefreshTime))  | 
|             continue  | 
|           | 
|         GameWorld.DebugLog("µÇ¼ˢÐÂÉñÃØÉ̵ê(%s)playerRefreshTime=%s,curWorldRefreshTime=%s"   | 
|                            % (shopID, playerRefreshTime, curWorldRefreshTime), curPlayer.GetPlayerID())  | 
|           | 
|         __RefreshShopItemBySys(curPlayer, shopID, TimeShopRefreshItem, curWorldRefreshTime)  | 
|               | 
|     return  | 
|   | 
|   | 
| ## È«·þË¢ÐÂÉñÃØÉ̵êÎïÆ·  | 
| #  @param curPlayer:Íæ¼Ò  | 
| #  @return None  | 
| def OnTimeShopRefresh(key, value, tick):  | 
|     shopID = key[len(ShareDefine.Def_Notify_WorldKey_TimeShopRefreshTime) - 2:]  | 
|     try:  | 
|         shopID = int(shopID)              | 
|     except BaseException:  | 
|         GameWorld.ErrLog("¶¨Ê±Ë¢ÐÂÉ̵êkey´íÎó, key=%s" % key)  | 
|         return  | 
|       | 
|     gameWorld = GameWorld.GetGameWorld()  | 
|     lastRefreshTimeKey = ShareDefine.Def_Notify_WorldKey_TimeShopRefreshTime % shopID  | 
|     lastRefreshTime = gameWorld.GetGameWorldDictByKey(lastRefreshTimeKey)  | 
|     if lastRefreshTime == value:  | 
|         GameWorld.DebugLog("¶¨Ê±É̵êÓëÉÏ´ÎË¢ÐÂʱ¼äÏàͬ£¬²»´¦Àí£¡shopID=%s,lastRefreshTime=%s"   | 
|                            % (shopID, lastRefreshTime))  | 
|         return  | 
|   | 
|     TimeShopRefreshItem = ReadChConfig.GetEvalChConfig("TimeShopRefreshItem")  | 
|       | 
|     if shopID not in TimeShopRefreshItem:  | 
|         GameWorld.ErrLog("·Ç¶¨Ê±ÉñÃØÉ̵꣬²»ÄÜˢУ¡shopID=%s" % shopID)  | 
|         return  | 
|       | 
|     shopStateKey = ShareDefine.Def_Notify_WorldKey_ShopState % shopID  | 
|     shopState = gameWorld.GetGameWorldDictByKey(shopStateKey)  | 
|       | 
|     if not shopState:  | 
|         GameWorld.ErrLog("ÉÌµê¹Ø±Õ״̬£¬²»´¦ÀíÉ̵êÎïÆ·Ë¢Ð£¡key=%s,value=%s" % (key, value))  | 
|         return  | 
|       | 
|     # È«·þˢиÃÉ̵êÎïÆ·  | 
|     GameWorld.DebugLog("È«·þË¢ÐÂÉñÃØÉ̵ê(%s)" % shopID)  | 
|     playerManager = GameWorld.GetPlayerManager()  | 
|     for index in range(0, playerManager.GetPlayerCount()):  | 
|         curPlayer = playerManager.GetPlayerByIndex(index)  | 
|         if curPlayer.GetID() == 0:  | 
|             continue  | 
|           | 
|         __RefreshShopItemBySys(curPlayer, shopID, TimeShopRefreshItem, value)  | 
|           | 
|     return  | 
|   | 
| ## ÏµÍ³Ë¢ÐÂÉñÃØÉ̵êÎïÆ·  | 
| #  @param curPlayer:Íæ¼Ò  | 
| #  @return None  | 
| def __RefreshShopItemBySys(curPlayer, shopID, TimeShopRefreshItem, sysValue):  | 
|       | 
|     isOK = __DoRefreshTimeShopItem(curPlayer, shopID, TimeShopRefreshItem)  | 
|       | 
|     if isOK:  | 
|         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TimeShopRefreshCnt % shopID, 0)  | 
|         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TimeShopLastGlobalRefreshTime % shopID, sysValue)  | 
|         Sync_ShopRefreshCnt(curPlayer, shopID)  | 
|               | 
|     return  | 
|   | 
|   | 
| #// A2 14 Ë¢Ð¶¨Ê±ÉñÃØÉ̵êÎïÆ·#tagCMRefreshShopItem  | 
| #  | 
| #struct    tagCMRefreshShopItem  | 
| #{  | 
| #    tagHead        Head;  | 
| #    DWORD        ShopID;  | 
| #};  | 
| ## Ë¢Ð¶¨Ê±ÉñÃØÉ̵êÎïÆ·  | 
| #  @param index:Íæ¼ÒË÷Òý  | 
| #  @param clientPack:·â°ü½á¹¹Ìå  | 
| #  @param tick:ʱ¼ä´Á  | 
| #  @return None  | 
| def RefreshShopItem(index, clientPack, tick):  | 
|     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  | 
|     shopID = clientPack.ShopID  | 
|       | 
|     TimeShopRefreshItem = ReadChConfig.GetEvalChConfig("TimeShopRefreshItem")  | 
|       | 
|     if shopID not in TimeShopRefreshItem:  | 
|         GameWorld.ErrLog("·Ç¶¨Ê±ÉñÃØÉ̵꣬²»ÄÜˢУ¡shopID=%s" % shopID, curPlayer.GetPlayerID())  | 
|         return  | 
|   | 
|     gameWorld = GameWorld.GetGameWorld()  | 
|     shopStateKey = ShareDefine.Def_Notify_WorldKey_ShopState % shopID  | 
|     shopState = gameWorld.GetGameWorldDictByKey(shopStateKey)  | 
|       | 
|     if not shopState:  | 
|         GameWorld.ErrLog("ÉÌµê¹Ø±Õ״̬£¬²»ÄÜˢУ¡shopID=%s" % (shopID), curPlayer.GetPlayerID())  | 
|         return  | 
|       | 
|     GameWorld.DebugLog("ÊÖ¶¯Ë¢ÐÂÉñÃØÉ̵ê(%s)" % shopID, curPlayer.GetPlayerID())  | 
|     __DoRefreshTimeShopItem(curPlayer, shopID, TimeShopRefreshItem, True)  | 
|     return  | 
|       | 
| ## Ö´ÐÐË¢ÐÂÉñÃØÉ̵êÎïÆ·  | 
| #  @param curPlayer:Íæ¼Ò  | 
| #  @return None  | 
| def __DoRefreshTimeShopItem(curPlayer, shopID, TimeShopRefreshItem, isUseGold=False):  | 
|   | 
|       | 
|     shopItemList = GetShopItemList(shopID)  | 
|     if not shopItemList:  | 
|         return  | 
|       | 
|     refreshInfo = TimeShopRefreshItem[shopID]  | 
|       | 
|     if len(refreshInfo) != Def_TimeShop_Max:  | 
|         return  | 
|       | 
|     itemCnt = len(shopItemList)  | 
|       | 
|     # ÖØÖøöÈËÏÞ¹º  | 
|     ClearPlayerShopItemBuyCnt(curPlayer, shopID)  | 
|       | 
|     # ÖØÖÃÉ̵êÎïÆ·¿ªÆô״̬  | 
|     maxKeyNum = int(math.ceil(itemCnt * 1.0 / PerDictKeyMaxCnt))  | 
|     for kNum in range(maxKeyNum):  | 
|         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ShopItemOpenState % (shopID, kNum), 0)  | 
|           | 
|     needCnt = refreshInfo[Def_TimeShop_RefreshCnt] # Ë¢Ð¸öÊý  | 
|     rateList = refreshInfo[Def_TimeShop_RateList] # Ë÷Òý±ýͼ¸ÅÂÊÁÐ±í  | 
|     exclusionList = refreshInfo[Def_TimeShop_ExclusionList] # »¥³âË÷ÒýÁÐ±í  | 
|     costFormat = refreshInfo[Def_TimeShop_CostFormat] # ÏûºÄ¹«Ê½  | 
|     mustItemCntDict = refreshInfo[Def_TimeShop_MustItemCnt] # Ë¢Ð´ÎÊý¶ÔÓ¦±Ø³öÎïÆ·ÐÅÏ¢  | 
|       | 
|     randIndexList = []  | 
|   | 
|     refreshCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TimeShopRefreshCnt % shopID)  | 
|     if isUseGold:  | 
|         needGold = eval(costFormat)  | 
|         infoDict = {"RefreshCnt":refreshCnt, "ShopID":shopID, ChConfig.Def_Cost_Reason_SonKey:shopID}  | 
|         if not PlayerControl.PayMoney(curPlayer, IPY_GameWorld.TYPE_Price_Gold_Money, needGold,  | 
|                                       ChConfig.Def_Cost_RefreshTimeShop, infoDict):  | 
|             return  | 
|           | 
|         refreshCnt += 1  | 
|         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TimeShopRefreshCnt % shopID, refreshCnt)  | 
|         if refreshCnt in mustItemCntDict:  | 
|             mustIndex = mustItemCntDict[refreshCnt]  | 
|             randIndexList.append(mustIndex)  | 
|             GameWorld.DebugLog("Ìí¼Ó±Ø³öË÷Òý:refreshCnt=%s,mustIndex=%s" % (refreshCnt, mustIndex),  | 
|                                curPlayer.GetPlayerID())  | 
|             __SetShopItemOpenState(curPlayer, shopID, mustIndex)  | 
|               | 
|         Sync_ShopRefreshCnt(curPlayer, shopID)  | 
|           | 
|     maxProcessCnt = needCnt * 100 # ·ÀÖ¹Ëæ²»³öÎïÆ·ËÀÑ»·  | 
|     while maxProcessCnt > 0 and len(randIndexList) < needCnt:  | 
|         maxProcessCnt -= 1  | 
|           | 
|         curIndex = GameWorld.GetResultByRandomList(rateList, 0)  | 
|           | 
|         # ÒѾ´æÔÚµÄ  | 
|         if curIndex in randIndexList:  | 
|             #GameWorld.DebugLog("ÒÑ¾Ëæ»ú³öÀ´¹ýÁË! curIndex=%s,randIndexList=%s"   | 
|             #                   % (curIndex, str(randIndexList)), curPlayer.GetPlayerID())  | 
|             continue  | 
|           | 
|         # »¥³â¼ì²é  | 
|         isInExclusionList = False  | 
|         for exclusionIndexList in exclusionList:  | 
|             if curIndex not in exclusionIndexList:  | 
|                 continue  | 
|               | 
|             for exIndex in exclusionIndexList:  | 
|                 if exIndex in randIndexList:  | 
|                     isInExclusionList = True  | 
|                     break  | 
|                   | 
|             if isInExclusionList:  | 
|                 break  | 
|               | 
|         if isInExclusionList:  | 
|             #GameWorld.DebugLog("ÔÚÒÑ¾Ëæ»ú³öÀ´µÄ»¥³âÁбíÀï curIndex=%s,exclusionIndexList=%s,randIndexList=%s"   | 
|             #                   % (curIndex, str(exclusionIndexList), str(randIndexList)), curPlayer.GetPlayerID())  | 
|             continue  | 
|           | 
|         randIndexList.append(curIndex)  | 
|         __SetShopItemOpenState(curPlayer, shopID, curIndex)  | 
|       | 
|     Send_ShopItem(curPlayer, shopItemList)  | 
|     Sync_ShopItemBuyCntInfo(curPlayer, shopID)  | 
|       | 
|     GameWorld.DebugLog("Ë¢ÐÂÉñÃØÉ̵ê(%s)%s,isUseGold=%s" % (shopID, str(randIndexList), isUseGold),  | 
|                        curPlayer.GetPlayerID())  | 
|     return True  | 
|   | 
|   | 
| ## »ñÈ¡É̵êid¶ÔÓ¦ÎïÆ·Ë÷Òý¿ª·Å״̬  | 
| #  @param curPlayer  | 
| #  @param shopID   | 
| #  @param itemIndex   | 
| #  @return ÊÇ·ñ¿ª·Å¹ºÂò  | 
| def __GetShopItemState(curPlayer, shopID, itemIndex):  | 
|     keyNum = itemIndex / PerDictKeyMaxCnt  | 
|     keyName = ChConfig.Def_PDict_ShopItemOpenState % (shopID, keyNum)  | 
|     shopItemState = curPlayer.NomalDictGetProperty(keyName)  | 
|     curStateIndex = itemIndex % PerDictKeyMaxCnt  | 
|     isOpen = shopItemState & pow(2, curStateIndex)  | 
|     return isOpen  | 
|   | 
|   | 
| ## ÉèÖÃÉ̵êid¶ÔÓ¦ÎïÆ·Ë÷Òý¿ª·Å״̬  | 
| #  @param curPlayer  | 
| #  @param shopID   | 
| #  @param itemIndex   | 
| #  @return  | 
| def __SetShopItemOpenState(curPlayer, shopID, itemIndex):  | 
|     keyNum = itemIndex / PerDictKeyMaxCnt  | 
|     keyName = ChConfig.Def_PDict_ShopItemOpenState % (shopID, keyNum)  | 
|     shopItemState = curPlayer.NomalDictGetProperty(keyName)  | 
|     curStateIndex = itemIndex % PerDictKeyMaxCnt  | 
|     updState = shopItemState | pow(2, curStateIndex)  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, keyName, updState)  | 
|     #GameWorld.DebugLog("¸üÐÂÉ̵êÎïÆ·¿ª·Å״̬shopID=%s,index=%s,key=%s,shopItemState=%s,curIndex=%s,updState=%s" \  | 
|     #                   % (shopID, itemIndex, keyName, shopItemState, curStateIndex, updState), curPlayer.GetPlayerID())  | 
|     return updState  | 
|   | 
| ## Í¬²½ÉñÃØÉ̵êÒÑÊÖ¶¯Ë¢Ð´ÎÊý  | 
| #  @param curPlayer:Íæ¼Ò  | 
| #  @return None  | 
| def Sync_ShopRefreshCnt(curPlayer, shopID):  | 
|     refreshCntPack = ChPyNetSendPack.tagMCShopRefreshCnt()  | 
|     refreshCntPack.Clear()  | 
|     refreshCntPack.ShopID = shopID  | 
|     refreshCntPack.RefreshCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TimeShopRefreshCnt % shopID)  | 
|     NetPackCommon.SendFakePack(curPlayer, refreshCntPack)  | 
|     return  | 
|   |