| #!/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 len=%s" % (cnt, len(savaData)))  | 
|         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 ""  | 
|   | 
|   | 
|   |