#!/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  
 | 
  
 |