#!/usr/bin/python  
 | 
# -*- coding: GBK -*-  
 | 
#-------------------------------------------------------------------------------  
 | 
#  
 | 
##@package PlayerFamilyStore  
 | 
#  
 | 
# @todo:Õ½ÃË²Ö¿â  
 | 
# @author hxp  
 | 
# @date 2017-09-09  
 | 
# @version 1.0  
 | 
#  
 | 
# ÏêϸÃèÊö: Õ½ÃË²Ö¿â  
 | 
#  
 | 
#-------------------------------------------------------------------------------  
 | 
#"""Version = 2017-09-09 18:30"""  
 | 
#-------------------------------------------------------------------------------  
 | 
  
 | 
import GameWorld  
 | 
import CommFunc  
 | 
import PyGameDataStruct  
 | 
import IpyGameDataPY  
 | 
import PyDataManager  
 | 
import DataRecordPack  
 | 
import PlayerFamilyAction  
 | 
import ShareDefine  
 | 
import PlayerFamily  
 | 
import ChPyNetSendPack  
 | 
import NetPackCommon  
 | 
import ChConfig  
 | 
  
 | 
import json  
 | 
  
 | 
Def_Store_Donate = 1 # ²Ö¿â²Ù×÷ - ¾èÏ×  
 | 
Def_Store_Exchange = 2 # ²Ö¿â²Ù×÷ - ¶Ò»»  
 | 
Def_Store_Del = 3 # ²Ö¿â²Ù×÷ - Ïú»Ù  
 | 
  
 | 
# Õ½Ã˲ֿâÎïÆ·¹ÜÀí  
 | 
class FamilyStoreItemManager(object):  
 | 
      
 | 
    def __init__(self):  
 | 
        self.FamilyStoreItems = {}     # {familyID:{index:storeItem, ...}, ...} PyGameDataStruct.tagDBPyFamilyStoreItem  
 | 
        return  
 | 
      
 | 
    def GetFamilyStoreItems(self, familyID):  
 | 
        return self.FamilyStoreItems.get(familyID, {})  
 | 
      
 | 
    def GetFamilyStoreItem(self, familyID, itemIndex):  
 | 
        return self.FamilyStoreItems.get(familyID, {}).get(itemIndex)  
 | 
      
 | 
    def CheckFamilyStoreHasSpace(self, familyID):  
 | 
        # ÊÇ·ñ»¹ÓÐ¿Õ¼ä  
 | 
        storeItemsDict = self.FamilyStoreItems.get(familyID, {})  
 | 
        familyStoreMaxSpace = IpyGameDataPY.GetFuncCfg("FamilyStoreSpace") # Õ½Ã˲ֿâ×î´ó´æ´¢¿Õ¼ä  
 | 
        return len(storeItemsDict) < familyStoreMaxSpace  
 | 
      
 | 
    def AddFamilyStoreItem(self, curPlayer, familyID, itemInfo, tick):  
 | 
        emptyIndex = None  
 | 
          
 | 
        familyStoreMaxSpace = IpyGameDataPY.GetFuncCfg("FamilyStoreSpace") # Õ½Ã˲ֿâ×î´ó´æ´¢¿Õ¼ä  
 | 
        storeItemDict = self.FamilyStoreItems.get(familyID, {})  
 | 
        for i in xrange(familyStoreMaxSpace):  
 | 
            if i not in storeItemDict:  
 | 
                emptyIndex = i  
 | 
                break  
 | 
              
 | 
        if emptyIndex == None:  
 | 
            GameWorld.DebugLog("Õ½Ã˲ֿâ¿Õ¼äÒÑÂú£¡familyID=%s" % familyID)  
 | 
            return  
 | 
        # Á÷Ïò  
 | 
        DataRecordPack.DR_FamilyStore(curPlayer, familyID, emptyIndex, "Donate", itemInfo)  
 | 
          
 | 
        itemID = itemInfo.pop("ItemID")  
 | 
        userData = json.dumps(itemInfo, ensure_ascii=False)  
 | 
          
 | 
        storeItem = PyGameDataStruct.tagDBPyFamilyStoreItem()  
 | 
        storeItem.clear()  
 | 
        storeItem.FamilyID = familyID  
 | 
        storeItem.ItemIndex = emptyIndex # »ñȡһ¸ö¿Õ¸ñ×ÓλÖà  
 | 
        storeItem.ItemID = itemID  
 | 
        storeItem.UserData = userData  
 | 
        storeItem.UserDataLen = len(storeItem.UserData)  
 | 
          
 | 
        storeItemDict[emptyIndex] = storeItem  
 | 
        self.FamilyStoreItems[familyID] = storeItemDict  
 | 
        GameWorld.DebugLog("AddFamilyStoreItem familyID=%s,itemIndex=%s,itemID=%s,userData=%s"   
 | 
                           % (familyID, emptyIndex, itemID, userData), curPlayer.GetPlayerID())  
 | 
          
 | 
        # ¾èÔùʼþ  
 | 
        PlayerFamilyAction.AddFamilyActionNote(curPlayer.GetName(), familyID, ShareDefine.Def_ActionType_FamilyStore,   
 | 
                                               [Def_Store_Donate, curPlayer.GetPlayerID(), itemID], tick, True, userData)  
 | 
          
 | 
        # Í¬²½¿Í»§¶Ë  
 | 
        self.SyncFamilyStoreItem(None, familyID, emptyIndex)  
 | 
        return True  
 | 
      
 | 
    def DelFamilyStoreItem(self, curPlayer, familyID, delIndexList, opType, tick):  
 | 
        if familyID not in self.FamilyStoreItems:  
 | 
            GameWorld.DebugLog("Õ½Ã˲ֿâûÓÐÎïÆ·: familyID=%s" % familyID)  
 | 
            return  
 | 
        GameWorld.DebugLog("DelFamilyStoreItem familyID=%s,delIndexList=%s" % (familyID, delIndexList), curPlayer.GetPlayerID())  
 | 
        storeItemDict = self.FamilyStoreItems[familyID]  
 | 
        for delIndex in delIndexList:  
 | 
            if delIndex not in storeItemDict:  
 | 
                GameWorld.ErrLog("Õ½Ã˲ֿâûÓиÃÎïÆ·: familyID=%s,delIndex=%s" % (familyID, delIndex))  
 | 
                continue  
 | 
            storeItem = storeItemDict.pop(delIndex)  
 | 
            itemID = storeItem.ItemID  
 | 
            userData = storeItem.UserData  
 | 
              
 | 
            itemDict = eval(userData)  
 | 
            itemDict.update({"ItemID":itemID})  
 | 
              
 | 
            # Á÷Ïò  
 | 
            eventName = "Exchange" if opType == Def_Store_Exchange else "Delete"  
 | 
            DataRecordPack.DR_FamilyStore(curPlayer, familyID, delIndex, eventName, itemDict)  
 | 
              
 | 
            # Ê¼þ  
 | 
            PlayerFamilyAction.AddFamilyActionNote(curPlayer.GetName(), familyID, ShareDefine.Def_ActionType_FamilyStore,   
 | 
                                                   [opType, curPlayer.GetPlayerID(), itemID], tick, True, userData)  
 | 
          
 | 
        # Í¬²½¿Í»§¶Ë  
 | 
        self.SyncFamilyStoreItemClear(familyID, 0, delIndexList)  
 | 
        return itemDict  
 | 
      
 | 
    def DelFamilyStoreItemAll(self, familyID):  
 | 
        # Çå³ý±¦¿âËùÓÐÎïÆ·  
 | 
        if familyID not in self.FamilyStoreItems:  
 | 
            #GameWorld.DebugLog("Õ½Ã˲ֿâûÓÐÎïÆ·: familyID=%s" % familyID)  
 | 
            return 0  
 | 
        delItemCount = len(self.FamilyStoreItems.pop(familyID))  
 | 
        GameWorld.DebugLog("DelFamilyStoreItemAll familyID=%s,delItemCount=%s" % (familyID, delItemCount))  
 | 
        # Í¬²½¿Í»§¶Ë  
 | 
        self.SyncFamilyStoreItemClear(familyID, 1)  
 | 
        return delItemCount  
 | 
      
 | 
    def SyncFamilyStoreItem(self, curPlayer, familyID, index=-1):  
 | 
        '''  
 | 
        @param index: -1-ͬ²½ËùÓÐÎïÆ·£» >=0-ͬ²½Ö¸¶¨¸ñ×ÓÎïÆ·ÐÅÏ¢  
 | 
        '''  
 | 
        storeItemDict = self.FamilyStoreItems.get(familyID, {})  
 | 
        if index in storeItemDict:  
 | 
            syncIndexList = [index]              
 | 
        elif index == -1:  
 | 
            syncIndexList = storeItemDict.keys()  
 | 
        else:  
 | 
            return  
 | 
              
 | 
        itemInfo = ChPyNetSendPack.tagGCFamilyStoreItemInfo()  
 | 
        itemInfo.Clear()  
 | 
        itemInfo.StoreItemList = []  
 | 
        for index in syncIndexList:  
 | 
            storeItem = storeItemDict[index]  
 | 
            item = ChPyNetSendPack.tagGCFamilyStoreItem()  
 | 
            item.Clear()  
 | 
            item.Index = index  
 | 
            item.ItemID = storeItem.ItemID  
 | 
            item.ItemData = storeItem.UserData  
 | 
            item.ItemDataLen = len(item.ItemData)  
 | 
            itemInfo.StoreItemList.append(item)  
 | 
        itemInfo.Count = len(itemInfo.StoreItemList)  
 | 
        if curPlayer:  
 | 
            NetPackCommon.SendFakePack(curPlayer, itemInfo)  
 | 
        else:  
 | 
            PlayerFamily.SendFamilyFakePack(familyID, itemInfo)  
 | 
        return  
 | 
      
 | 
    def SyncFamilyStoreItemClear(self, familyID, clearType, indexList=[]):  
 | 
        '''  
 | 
        @param clearType: 0-µ¥¸ñ×ÓÇå³ý; 1-ËùÓÐÎïÆ·Çå³ý  
 | 
        @param index: Çå³ýµÄ¸ñ×ÓË÷Òý, ½öµ¥¸ñ×ÓÇå³ýʱÓÐЧ,´Ó0¿ªÊ¼´ú±íµÚÒ»¸ñ  
 | 
        '''  
 | 
        itemClear = ChPyNetSendPack.tagGCFamilyStoreItemClear()  
 | 
        itemClear.Clear()  
 | 
        itemClear.ClearType = clearType  
 | 
        itemClear.IndexList = indexList  
 | 
        itemClear.IndexCount = len(itemClear.IndexList)  
 | 
        PlayerFamily.SendFamilyFakePack(familyID, itemClear)  
 | 
        return  
 | 
      
 | 
    # ±£´æºÃÓÑÊý¾Ý ´æÊý¾Ý¿âºÍrealtimebackup  
 | 
    def GetSaveData(self):  
 | 
        savaData = ""  
 | 
        cntData = ""  
 | 
        cnt = 0  
 | 
        for storeItemDict in self.FamilyStoreItems.values():  
 | 
            for storeItem in storeItemDict.values():  
 | 
                cnt += 1  
 | 
                savaData += storeItem.getBuffer()  
 | 
                  
 | 
        GameWorld.Log("SaveFamilyStoreItem cnt :%s"%cnt)  
 | 
        return CommFunc.WriteDWORD(cntData, cnt) + savaData  
 | 
      
 | 
    # ´ÓÊý¾Ý¿âÔØÈëºÃÓÑÊý¾Ý  
 | 
    def LoadPyGameData(self, datas, pos, dataslen):  
 | 
        cnt, pos = CommFunc.ReadDWORD(datas, pos)  
 | 
        GameWorld.Log("LoadFamilyStoreItem cnt :%s"%cnt)  
 | 
          
 | 
        self.FamilyStoreItems = {}  
 | 
          
 | 
        for _ in xrange(cnt):  
 | 
            storeItem = PyGameDataStruct.tagDBPyFamilyStoreItem()  
 | 
            storeItem.clear()  
 | 
            pos += storeItem.readData(datas, pos, dataslen)  
 | 
              
 | 
            familyID = storeItem.FamilyID  
 | 
            itemIndex = storeItem.ItemIndex  
 | 
            storeItemDict = self.FamilyStoreItems.get(familyID, {})  
 | 
            storeItemDict[itemIndex] = storeItem  
 | 
            self.FamilyStoreItems[familyID] = storeItemDict  
 | 
              
 | 
        return pos  
 | 
      
 | 
def OnPlayerLogin(curPlayer):  
 | 
    familyID = curPlayer.GetFamilyID()  
 | 
    if not familyID:  
 | 
        return  
 | 
    PyDataManager.GetFamilyStoreItemManager().SyncFamilyStoreItem(curPlayer, familyID)  
 | 
    return  
 | 
  
 | 
#// A4 09 ¼Ò×å²Ö¿âɾ³ýÎïÆ· #tagCGFamilyStoreDel  
 | 
#  
 | 
#struct     tagCGFamilyStoreDel  
 | 
#{  
 | 
#    tagHead        Head;  
 | 
#    BYTE        IndexCount;  
 | 
#    BYTE        StoreItemIndex[IndexCount];    // ²Ö¿âÎïÆ·Ë÷Òý£¬1´ú±íË÷Òý0µÄÎïÆ·£¬Óë¶Ò»»Ò»Ö  
 | 
#};  
 | 
def OnFamilyStoreDel(index, clientData, tick):  
 | 
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  
 | 
    delIndexList = clientData.StoreItemIndex  
 | 
      
 | 
    curPlayerID = curPlayer.GetPlayerID()  
 | 
    curFamily = curPlayer.GetFamily()  
 | 
    if curFamily == None:  
 | 
        GameWorld.DebugLog("ɾ³ý¼Ò×å²Ö¿âÎïÆ· -> Íæ¼ÒÎÞ¼Ò×å", curPlayerID)  
 | 
        return  
 | 
      
 | 
    curMember = curFamily.FindMember(curPlayerID)  
 | 
    if curMember == None:  
 | 
        GameWorld.DebugLog("ɾ³ý¼Ò×å²Ö¿âÎïÆ· -> ÕÒ²»µ½³ÉÔ±", curPlayerID)  
 | 
        return  
 | 
      
 | 
    if not PlayerFamily.GetFamilyMemberHasPow(curMember, ChConfig.Def_PurviewDictKey_CanClearPack):  
 | 
        GameWorld.DebugLog("ɾ³ý¼Ò×å²Ö¿âÎïÆ· -> ÄãûÓÐȨÏÞ", curPlayerID)  
 | 
        return  
 | 
      
 | 
    familyItemMgr = PyDataManager.GetFamilyStoreItemManager()  
 | 
    familyItemMgr.DelFamilyStoreItem(curPlayer, curPlayer.GetFamilyID(), delIndexList, Def_Store_Del, tick)  
 | 
    return  
 | 
  
 | 
  
 | 
def DoMapServerFamilyStore(curPlayer, msgList, tick):  
 | 
    opType = msgList[0]  
 | 
    familyItemMgr = PyDataManager.GetFamilyStoreItemManager()  
 | 
    familyID = curPlayer.GetFamilyID()  
 | 
      
 | 
    # ¾èÔùÇëÇó  
 | 
    if opType == "DonateReq":  
 | 
        hasSpace = familyItemMgr.CheckFamilyStoreHasSpace(familyID)  
 | 
        return msgList + [hasSpace]  
 | 
      
 | 
    # ¾èÔùÎïÆ·ÐÅÏ¢Ìá½»  
 | 
    elif opType == "DonateItem":  
 | 
        isOK = familyItemMgr.AddFamilyStoreItem(curPlayer, familyID, msgList[1], tick)  
 | 
        return ["DonateItem", isOK]  
 | 
      
 | 
    # ¶Ò»»ÎïÆ·  
 | 
    elif opType == "Exchange":  
 | 
        itemIndex = msgList[1]  
 | 
        itemID = msgList[2]  
 | 
        storeItem = familyItemMgr.GetFamilyStoreItem(familyID, itemIndex)  
 | 
        if not storeItem or storeItem.ItemID != itemID:  
 | 
            GameWorld.DebugLog("Õ½Ã˲ֿâÄ¿±êλÖÃûÓÐÎïÆ·»òÎïÆ·ID´íÎó£¡itemIndex=%s,itemID=%s" % (itemIndex, itemID))  
 | 
            return msgList + [{}]  
 | 
          
 | 
        itemDict = familyItemMgr.DelFamilyStoreItem(curPlayer, familyID, [itemIndex], Def_Store_Exchange, tick)  
 | 
        if not itemDict:  
 | 
            GameWorld.DebugLog("Õ½Ã˲ֿâÄ¿±êÎïÆ·É¾³ýʧ°Ü£¡itemIndex=%s,itemID=%s" % (itemIndex, itemID))  
 | 
            return msgList + [{}]  
 | 
          
 | 
        return msgList + [itemDict]  
 | 
      
 | 
    return ""  
 | 
  
 | 
  
 | 
  
 |