1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
#!/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 ""