| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
| #-------------------------------------------------------------------------------  | 
| #  | 
| #-------------------------------------------------------------------------------  | 
| #  | 
| ##@package GameWorldShopItem  | 
| #  | 
| # @todo:×Ô¶¨ÒåÉÌµê  | 
| # @author hxp  | 
| # @date 2014-06-21  | 
| # @version 1.3  | 
| #  | 
| # @change: "2015-02-04 14:30" hxp ÉñÃØÉÌµê  | 
| # @change: "2015-02-09 18:00" ljd Ð޸ĵǽδÍê³ÉʱÊÕ²»µ½µ¹¼ÆÊ±Ë¢Ð°üÎÊÌâ  | 
| # @change: "2015-04-28 17:00" hxp ¶¨Ê±Ë¢ÐÂÉ̵꿪Æôʱ֪ͨÀ뿪ʱ¼ä  | 
| #  | 
| # ÏêϸÃèÊö: ×Ô¶¨ÒåÉÌµê  | 
| #  | 
| #---------------------------------------------------------------------  | 
| """Version = 2015-04-28 17:00"""  | 
|   | 
| import GameWorld  | 
| import ChPyNetSendPack  | 
| import NetPackCommon  | 
| import ReadChConfig  | 
| import ShareDefine  | 
| import ChConfig  | 
|   | 
| import time  | 
|   | 
| ## ³äÖµÉ̵êÈ«·þÏÞ¹ºÊý¾Ý  | 
| #  @param shopID É̵êid  | 
| #  @return  | 
| def DoShopItemClearBuyCnt(shopID):  | 
|       | 
|     recTypeListData = __GetShopItemRecData()  | 
|       | 
|     # ±éÀúÇå¿ÕÈ«·þÏÞ¹º´ÎÊý  | 
|     for index in range(recTypeListData.Count()):  | 
|         recData = recTypeListData.At(index)  | 
|         curShopID = recData.GetValue1()  | 
|         if curShopID == shopID:  | 
|             recData.SetValue3(0)  | 
|       | 
|     resultName = "%s" % [ShareDefine.Def_ShopItem_ClearBuyCnt, shopID]  | 
|       | 
|     # Í¨ÖªÈ«·þÍæ¼Ò  | 
|     playerManager = GameWorld.GetPlayerManager()  | 
|     for i in range(0, playerManager.GetPlayerCount()):  | 
|         curPlayer = playerManager.GetPlayerByIndex(i)  | 
|         if curPlayer == None or not curPlayer.GetInitOK():  | 
|             continue  | 
|           | 
|         curPlayer.MapServer_QueryPlayerResult(0, 0, "ShopItem", resultName, len(resultName))  | 
|           | 
|     return  | 
|   | 
|   | 
| ## ×Ô¶¨ÒåÉ̵êÎïÆ·²éѯ½á¹û  | 
| #  @param curPlayer Íæ¼ÒʵÀý  | 
| #  @param msgList ÐÅÏ¢ÁÐ±í  | 
| #  @return [queryType, À©Õ¹Êý¾Ý]  | 
| def DoShopItemQueryResult(curPlayer, msgList):  | 
|     queryType = msgList[0]  | 
|     result = []  | 
|       | 
|     # Í¬²½¹ºÂò´ÎÊý[queryType, shopID, serverBuyLimitIndexList]  | 
|     if queryType == ShareDefine.Def_ShopItem_QueryServerBuyCnt:  | 
|         shopID = msgList[1]  | 
|         limitIndexList = msgList[2]  | 
|         buyCntDict = __GetShopItemServerBuyCntDict(shopID, limitIndexList)  | 
|         result = [queryType, shopID, buyCntDict]  | 
|       | 
|     # ¹ºÂòÎïÆ·[queryType, shopID, itemShopIndex, buyCount, serverMaxBuyCnt]  | 
|     elif queryType == ShareDefine.Def_ShopItem_BuyItem:  | 
|         shopID = msgList[1]  | 
|         itemShopIndex = msgList[2]  | 
|         buyCount = msgList[3]  | 
|         serverMaxBuyCnt = msgList[4]  | 
|         buyCntDict = __GetShopItemServerBuyCntDict(shopID, [itemShopIndex])  | 
|         serverBuyCnt = buyCntDict.get(itemShopIndex, 0)  | 
|         # ÒѹºÂòµÄ + Òª¹ºÂòµÄ ²»³¬¹ý£¬ÔòÔÊÐí¹ºÂò  | 
|         canBuy = 0 if (serverBuyCnt + buyCount) > serverMaxBuyCnt else 1  | 
|         GameWorld.DebugLog("¹ºÂòÈ«·þÏÞ¹ºÎïÆ·£ºÈ«·þÒѹºÂò=%s,Óû¹ºÂò=%s,×î´ó¹ºÂò=%s,canBuy=%s"   | 
|                            % (serverBuyCnt, buyCount, serverMaxBuyCnt, canBuy))  | 
|         if canBuy:  | 
|             serverBuyCnt = __AddShopItemServerBuyCnt(shopID, itemShopIndex, buyCount)  | 
|               | 
|             # Í¨ÖªÈ«·þÔÚÏßÍæ¼Ò¸ÃÎïÆ·ÏÞ¹º´ÎÊý±ä¸ü  | 
|             syncInfo = "%s" % [ShareDefine.Def_ShopItem_SyncServerBuyCnt, shopID,  | 
|                                  itemShopIndex, serverBuyCnt]  | 
|             playerManager = GameWorld.GetPlayerManager()  | 
|             for i in range(0, playerManager.GetPlayerCount()):  | 
|                 player = playerManager.GetPlayerByIndex(i)  | 
|                 # ×Ô¼ºÓÉMapServer¹ºÂòºóͬ²½  | 
|                 # ÒòΪÓпÉÄܸÄÎïÆ·Ò²ÓиöÈËÏÞ¹º£¬ÐèMapServer´¦ÀíÍêºóÔÙͬ²½  | 
|                 if player == None or not player.GetInitOK():  | 
|                     continue  | 
|                   | 
|                 if player.GetPlayerID() == curPlayer.GetPlayerID():  | 
|                     #GameWorld.DebugLog("        ×Ô¼ºÏȲ»Í¬²½")  | 
|                     continue  | 
|                   | 
|                 player.MapServer_QueryPlayerResult(0, 0, "ShopItem", syncInfo, len(syncInfo))  | 
|           | 
|         result = [queryType, shopID, itemShopIndex, buyCount, canBuy, serverBuyCnt]  | 
|       | 
|       | 
|     return result  | 
|   | 
|   | 
| ## Ôö¼ÓÏÞ¹ºÎïÆ·¹ºÂò´ÎÊý  | 
| #  @param shopID É̵êid  | 
| #  @param itemShopIndex ÎïÆ·Ë÷Òý  | 
| #  @param addBuyCount Ôö¼Ó´ÎÊý  | 
| #  @return ¸üкóµÄÒѹºÂò´ÎÊý  | 
| def __AddShopItemServerBuyCnt(shopID, itemShopIndex, addBuyCount):  | 
|     recTypeListData = __GetShopItemRecData()  | 
|       | 
|     shopItemRec = None  | 
|     for index in range(recTypeListData.Count()):  | 
|         recData = recTypeListData.At(index)  | 
|         curShopID = recData.GetValue1()  | 
|         curItemShopIndex = recData.GetValue2()  | 
|         if curShopID == shopID and curItemShopIndex == itemShopIndex:  | 
|             shopItemRec = recData  | 
|           | 
|     if shopItemRec == None:  | 
|         #»¹Î´¼Ç¼£¬ÔòÌí¼ÓÒ»¸ö¼Ç¼¶ÔÏó  | 
|         shopItemRec = recTypeListData.AddRec()   | 
|         shopItemRec.SetValue1(shopID)  | 
|         shopItemRec.SetValue2(itemShopIndex)  | 
|         shopItemRec.SetValue3(0)  | 
|           | 
|     buyCnt = shopItemRec.GetValue3()  | 
|     buyCnt += addBuyCount  | 
|     shopItemRec.SetValue3(buyCnt)  | 
|     return buyCnt  | 
|   | 
|   | 
| ## »ñÈ¡É̵êÈ«·þÏÞ¹ºÎïÆ·¶ÔÓ¦ÒѹºÂò¸öÊý  | 
| #  @param shopID  | 
| #  @param indexList  | 
| #  @return {index:buyCnt, ...}  | 
| def __GetShopItemServerBuyCntDict(shopID, indexList):  | 
|     findCnt = 0  | 
|     buyCntDict = {}  | 
|     recTypeListData = __GetShopItemRecData()  | 
|       | 
|     for index in range(recTypeListData.Count()):  | 
|         recData = recTypeListData.At(index)  | 
|         curShopID = recData.GetValue1()  | 
|         itemShopIndex = recData.GetValue2()  | 
|         buyCnt = recData.GetValue3()  | 
|         if curShopID == shopID and itemShopIndex in indexList:  | 
|             buyCntDict[itemShopIndex] = buyCnt  | 
|             findCnt += 1  | 
|             if findCnt >= len(indexList):  | 
|                 break  | 
|           | 
|     return buyCntDict  | 
|   | 
|   | 
| ## »ñÈ¡É̵êRecÊý¾Ý  | 
| #  @param None  | 
| #  @return recTypeListData  | 
| def __GetShopItemRecData():  | 
|     recType = ShareDefine.Def_UniversalGameRecType_ShopItem  | 
|     universalRecMgr = GameWorld.GetUniversalRecMgr()  | 
|     recTypeListData = universalRecMgr.GetTypeList(recType)  | 
|     return recTypeListData  | 
|   | 
| ## µØÍ¼Æô¶¯Í¨Öª  | 
| #  @param None  | 
| #  @return  | 
| def OnMapServerInitOK():  | 
|   | 
|     TimeShopRefreshDict = ReadChConfig.GetEvalChConfig("TimeShopRefresh")  | 
|       | 
|     gameWorld = GameWorld.GetGameWorld()  | 
|       | 
|     for shopID in TimeShopRefreshDict.keys():  | 
|           | 
|         isOpen = gameWorld.GetDictByKey(ShareDefine.Def_Notify_WorldKey_ShopState % shopID)  | 
|       | 
|         if not isOpen:  | 
|             continue  | 
|           | 
|         lastRefreshTime = gameWorld.GetDictByKey(ShareDefine.Def_Notify_WorldKey_TimeShopRefreshTime % shopID)  | 
|           | 
|         GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_ShopState % shopID, isOpen)  | 
|         GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_TimeShopRefreshTime % shopID, lastRefreshTime)  | 
|           | 
|     return  | 
|   | 
| ## Íæ¼ÒµÇ¼  | 
| #  @param curPlayer  | 
| #  @return  | 
| def OnPlayerLogin(curPlayer):  | 
|     Sync_TimeShopRefreshTime(curPlayer)  | 
|     return  | 
|   | 
| ## É̵ê״̬±ä¸ü´¦Àí  | 
| #  @param curPlayer  | 
| #  @param isOpen  | 
| #  @return  | 
| def OnShopStateChange(dictName, isOpen):  | 
|     shopID = dictName[len(ShareDefine.Def_Notify_WorldKey_ShopState) - 2:]  | 
|     try:  | 
|         shopID = int(shopID)              | 
|     except BaseException:  | 
|         GameWorld.ErrLog("É̵êIDÅäÖÃkey´íÎó, key=%s" % dictName)  | 
|         return  | 
|       | 
|     TimeShopRefreshDict = ReadChConfig.GetEvalChConfig("TimeShopRefresh")  | 
|       | 
|     if shopID in TimeShopRefreshDict:  | 
|         __DoTimeShopStateChange(shopID, isOpen)  | 
|       | 
|     return  | 
|   | 
| ## Ö´ÐÐÉ̵ê״̬±ä¸ü´¦Àí  | 
| #  @param shopID  | 
| #  @param isOpen  | 
| #  @return  | 
| def __DoTimeShopStateChange(shopID, isOpen):  | 
|       | 
|     if not isOpen:  | 
|         return  | 
|       | 
|     curTime = int(time.time())  | 
|       | 
|     gameWorld = GameWorld.GetGameWorld()  | 
|     gameWorld.SetDict(ShareDefine.Def_Notify_WorldKey_TimeShopRefreshTime % shopID, curTime)  | 
|     GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_TimeShopRefreshTime % shopID, curTime)  | 
|     Sync_TimeShopRefreshTime()  | 
|     return  | 
|   | 
|   | 
| ## ¶¨Ê±É̵êÎïÆ·Ë¢Ð  | 
| #  @param tick  | 
| #  @return  | 
| def Dispose_ShopItemRefresh(tick):  | 
|       | 
|     if not GameWorld.SetWorldDictKey(ChConfig.TYPE_TimeShopProcessTick, tick):  | 
|         return  | 
|       | 
|     TimeShopRefreshDict = ReadChConfig.GetEvalChConfig("TimeShopRefresh")  | 
|           | 
|     isNeedSyncTime = False  | 
|     curTime = int(time.time())  | 
|     gameWorld = GameWorld.GetGameWorld()  | 
|       | 
|     for shopID, refreshInterval in TimeShopRefreshDict.items():  | 
|           | 
|         isOpen = gameWorld.GetDictByKey(ShareDefine.Def_Notify_WorldKey_ShopState % shopID)  | 
|       | 
|         if not isOpen:  | 
|             continue  | 
|           | 
|         lastRefreshTime = gameWorld.GetDictByKey(ShareDefine.Def_Notify_WorldKey_TimeShopRefreshTime % shopID)  | 
|           | 
|         if not lastRefreshTime:  | 
|             continue  | 
|           | 
|         pastTime = max(0, curTime - lastRefreshTime)  | 
|           | 
|         if pastTime >= refreshInterval:  | 
|             gameWorld.SetDict(ShareDefine.Def_Notify_WorldKey_TimeShopRefreshTime % shopID, curTime)  | 
|             GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_TimeShopRefreshTime % shopID, curTime)  | 
|             isNeedSyncTime = True  | 
|       | 
|     if isNeedSyncTime:  | 
|         Sync_TimeShopRefreshTime()  | 
|           | 
|     return  | 
|   | 
|   | 
| ## Í¬²½¶¨Ê±É̵êˢе¹¼ÆÊ±  | 
| #  @param curPlayer  | 
| #  @return  | 
| def Sync_TimeShopRefreshTime(curPlayer=None):  | 
|       | 
|     refreshTimeListPack = ChPyNetSendPack.tagGCShopRefreshTimeList()  | 
|       | 
|     refreshTimeListPack.Clear()  | 
|     refreshTimeListPack.ShopTimeInfoList = []  | 
|   | 
|     TimeShopRefreshDict = ReadChConfig.GetEvalChConfig("TimeShopRefresh")  | 
|     gameWorld = GameWorld.GetGameWorld()  | 
|     curTime = int(time.time())  | 
|       | 
|     for shopID, refreshInterval in TimeShopRefreshDict.items():  | 
|           | 
|         isOpen = gameWorld.GetDictByKey(ShareDefine.Def_Notify_WorldKey_ShopState % shopID)  | 
|       | 
|         if not isOpen:  | 
|             continue  | 
|           | 
|         lastRefreshTime = gameWorld.GetDictByKey(ShareDefine.Def_Notify_WorldKey_TimeShopRefreshTime % shopID)  | 
|           | 
|         if not lastRefreshTime:  | 
|             continue  | 
|           | 
|         passTime = max(0, curTime - lastRefreshTime)  | 
|           | 
|         refreshShopTime = ChPyNetSendPack.tagGCShopRefreshTime()  | 
|         refreshShopTime.Clear()  | 
|         refreshShopTime.ShopID = shopID  | 
|         refreshShopTime.RemainSecond = max(0, refreshInterval - passTime)  | 
|           | 
|         refreshTimeListPack.ShopTimeInfoList.append(refreshShopTime)  | 
|       | 
|     refreshTimeListPack.ShopCnt = len(refreshTimeListPack.ShopTimeInfoList)  | 
|       | 
|     if refreshTimeListPack.ShopCnt <= 0:  | 
|         return  | 
|       | 
|     # Í¨Öª¿Í»§¶Ëͬ²½Ê±¼ä          | 
|     if not curPlayer:  | 
|         # È«·þ¹ã²¥ÔÚÏßÍæ¼Ò  | 
|         playerManager = GameWorld.GetPlayerManager()  | 
|         for i in range(0, playerManager.GetPlayerCount()):  | 
|             curPlayer = playerManager.GetPlayerByIndex(i)  | 
|             if curPlayer == None or curPlayer.GetPlayerID() <= 0:  | 
|                 continue  | 
|               | 
|             NetPackCommon.SendFakePack(curPlayer, refreshTimeListPack)  | 
|     else:  | 
|         NetPackCommon.SendFakePack(curPlayer, refreshTimeListPack)  | 
|     return  | 
|   |