hxp
2025-05-23 fdebf36f0d9201c6a6949a08cdfeebb718c25ce2
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
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package DB.StructData.DBGameRec
#
# @todo:ͨÓüǼ±íÐÂ
# @author hxp
# @date 2025-05-23
# @version 1.0
#
# ÏêϸÃèÊö: Í¨ÓüǼ±íУ¬Ô­Í¨ÓüǼ×Ö·û³¤¶È¼Ç¼ÓÐÏÞ£¬ÇÒÕë¶Ôij¸ö¼Ç¼ÀàÐÍϵÄ×ÓÀàÐͲéÕÒÿ´ÎÐèÒª±éÀú£¬Ð§Âʲ»¸ß
#
#-------------------------------------------------------------------------------
#"""Version = 2025-05-23 20:00"""
#-------------------------------------------------------------------------------
 
import DBStruct
import GameWorld
import ShareDefine
import CommFunc
import DBComm
 
import time
 
class GameRecData():
    
    def __init__(self, dbData=None, dataToJson=False):
        if not dbData:
            dbData = DBStruct.tagDBGameRec()
        self.__dbData = dbData
        self.__dataDict = DBComm.UserDataDict(self.__dbData, "UserData", "UserDataLen", dataToJson)
        return
    def GetRecType(self): return self.__dbData.RecType
    def SetRecType(self, recType): self.__dbData.RecType = recType
    def GetRecID(self): return self.__dbData.RecID
    def SetRecID(self, recID): self.__dbData.RecID = recID
    def GetTime(self): return self.__dbData.Time
    def SetTime(self, sTime): self.__dbData.Time = sTime
    def GetValue1(self): return self.__dbData.Value1
    def SetValue1(self, value1): self.__dbData.Value1 = value1
    def GetValue2(self): return self.__dbData.Value2
    def SetValue2(self, value2): self.__dbData.Value2 = value2
    def GetValue3(self): return self.__dbData.Value3
    def SetValue3(self, value3): self.__dbData.Value3 = value3
    def GetValue4(self): return self.__dbData.Value4
    def SetValue4(self, value4): self.__dbData.Value4 = value4
    def GetValue5(self): return self.__dbData.Value5
    def SetValue5(self, value5): self.__dbData.Value5 = value5
    def GetValue6(self): return self.__dbData.Value6
    def SetValue6(self, value6): self.__dbData.Value6 = value6
    def GetValue7(self): return self.__dbData.Value7
    def SetValue7(self, value7): self.__dbData.Value7 = value7
    def GetValue8(self): return self.__dbData.Value8
    def SetValue8(self, value8): self.__dbData.Value8 = value8
    def GetUserDict(self): return self.__dataDict.GetData()
    def GetUserData(self): return self.__dataDict.ToString()
    def SetUserData(self, value): self.__dataDict.SetData(value)
    def GetBuffer(self):
        self.__dataDict.ToString()
        return self.__dbData.getBuffer()
    
    def IsMatchValue(self, valueList):
        # ¼ì²é¼Ç¼ֵÁбíÊÇ·ñÅäÖøüǼ
        # @param valueList: [value1, value2, ...] valueΪNoneʱ²»ÅжϸÃÖµ
        if not valueList:
            return False
        for i, value in enumerate(valueList, 1):
            if value == None:
                continue
            if not hasattr(self, "GetValue%s" % i):
                return False
            curValue = getattr(self, "GetValue%s" % i)()
            if curValue != value:
                return False
        return True
    
    def GetValueIndexKey(self):
        ## »ñÈ¡Value¿ìËÙ²éÕÒË÷Òýkey£¬Ä¬ÈÏʹÓÃvalue1
        recType = self.GetRecType()
        if recType not in ShareDefine.Def_GameRecValueKeyDict:
            return ""
        valueNumList = ShareDefine.Def_GameRecValueKeyDict[recType]
        if not valueNumList:
            valueNumList = [1]
        keyStr = ""
        for num in valueNumList:
            if not hasattr(self, "GetValue%s" % num):
                return ""
            if keyStr:
                keyStr += "_"
            keyStr += str(getattr(self, "GetValue%s" % num)())
        return keyStr
    
class GameRecIDMgr():
    ## ÀàÐÍÊý¾ÝID¹ÜÀí
    
    def __init__(self, recType, recID):
        self.__recType = recType
        self.__recID = recID
        self.__dataList = [] # Êý¾ÝÁбí [GameRecData, ...]
        self.__valueIndexDict = {} # valueË÷ÒýÖµ¶ÔÓ¦Êý¾ÝÁбí {indexKey:[GameRecData, ...], ...}
        return
    
    def InitRecDataInstance(self, dbData):
        '''³õʼ»¯¹¦ÄÜÊý¾ÝʵÀý£¬´´½¨»ò¼ÓÔØÊý¾ÝʱͨÓ㬹¦ÄÜÒ»°ã²»µ÷ÓÃ
        @param dbData: ÊµÀý¶ÔÓ¦°ó¶¨µÄdbData
        @return: ³É¹¦·µ»ØÊµÀý¶ÔÏó£¬Ê§°Ü·µ»ØNone
        '''
        dataToJson = False
        # Èç¹ûÐèÒª dataToJson£¬¿É¸ù¾Ý RecType ÔÚÕâÀï´¦Àí
        if dbData.RecType in []:
            dataToJson = True
        recData = GameRecData(dbData, dataToJson)
        self.__dataList.append(recData)
        
        keyStr = recData.GetValueIndexKey()
        if keyStr:
            if keyStr not in self.__valueIndexDict:
                self.__valueIndexDict[keyStr] = []
            recIndexDataList = self.__valueIndexDict[keyStr]
            recIndexDataList.append(recData)
            
        return recData
    
    def GetRecType(self): return self.__recType
    def GetRecID(self): return self.__recID
    
    def SortByTime(self):
        self.__dataList.sort(key=lambda r: (r.GetTime()), reverse=False)
        return
    
    def AddRecData(self, maxCount=None):
        '''Ìí¼Ó¼Ç¼
        @param maxCount: ¿É´«ÈëÓÉÅäÖþö¶¨µÄ×î´óÌõÊý£¬Èç¹ûΪNoneÔò½øÒ»²½È¡³ÌÐòĬÈÏÉ趨µÄ×î´óÌõÊý£¬¶¼Ã»ÅäÖõϰĬÈϲ»ÏÞÌõÊý
        '''
        
        fullClear = True
        recData = None
        if maxCount == None:
            maxCount = 0
        if maxCount and self.GetCount() >= maxCount:
            if not fullClear:
                #³¬¹ý¼Ç¼¼Ç¼²»ÁËÁË
                return recData
            #self.SortByTime()  # °´Ê±¼äÉýÐò
            self.DelCount(self.GetCount() - maxCount + 1)
            
        dbData = DBStruct.tagDBGameRec()
        dbData.RecType = self.__recType
        dbData.RecID = self.__recID
        dbData.Time = int(time.time())
        #if valueSetList:
        #    for num, v in enumerate(valueSetList, 1):
        #        if not hasattr(dbData, "Value%s" % num):
        #            continue
        #        setattr(dbData, "Value%s" % num, v
        
        recData = self.InitRecDataInstance(dbData)
        return recData
    
    def GetCount(self): return len(self.__dataList)
    def At(self, index):
        recData = None
        if 0 <= index < len(self.__dataList):
            recData = self.__dataList[index]
        elif False:
            recData = GameRecData()
        return recData
    
    def GetOneRecData(self, isAddNew=False):
        ## »ñÈ¡µÚÒ»Ìõ¼Ç¼£¬ÊÊÓÃÓÚ½öÐèÒ»ÌõµÄ¼Ç¼ÀàÐÍ
        # @param isAddNew: Ã»ÓмǼʱÊÇ·ñÌí¼ÓÒ»ÌõмǼ£¬Ò»°ã»ñÈ¡ºóÐèÒª¸üÐÂÊý¾ÝµÄ¿ÉÒÔÉèÖÃΪTrue£¬½öÅжÏÓõĽ¨ÒéÉèÖÃΪFalse£¬¼õÉÙ²úÉú¶àÓà¿ÕÊý¾Ý
        recData = None
        if self.__dataList:
            recData = self.__dataList[0]
        elif isAddNew:
            recData = self.AddRecData()
        return recData
    
    def GetRecDataByValues(self, valueList, findone=False):
        '''»ñȡƥÅävalueÖµµÄ¼Ç¼
        @param valueList: [value1, value2, ...] valueΪNoneʱ²»ÅжϸÃÖµ
        @param findone: ÊÇ·ñֻƥÅäÒ»ÌõÂú×ãµÄ¼Ç¼
        @return: recData or [recData, ...] or None
        '''
        
        # ÓÐÅäÖÃvalueË÷ÒýkeyµÄ£¬Ö±½Ó¿ìËÙ»ñÈ¡
        if self.__recType in ShareDefine.Def_GameRecValueKeyDict:
            keyStr = ""
            for v in valueList:
                if keyStr:
                    keyStr += "_"
                keyStr += str(v)
            if keyStr not in self.__valueIndexDict:
                return
            recIndexDataList = self.__valueIndexDict[keyStr]
            if not recIndexDataList:
                return
            return recIndexDataList[0] if findone else recIndexDataList
        
        # Ã»ÓеÄÔò±éÀúÆ¥Åä
        matchRecDataList = []
        for recData in self.__dataList:
            if not recData.IsMatchValue(valueList):
                continue
            if findone:
                return recData
            matchRecDataList.append(recData)
        return matchRecDataList
    
    def DelAllData(self):
        ## É¾³ý¸Ã¼Ç¼IDµÄËùÓÐÊý¾Ý
        dataCount = self.GetCount()
        if not dataCount:
            return 0
        #GameWorld.DebugLog("ɾ³ýͨÓüǼij¸öÀàÐÍIDËùÓмǼ: recType=%s,recID=%s,dataCount=%s" % (self.__recType, self.__recID, dataCount))
        self.__dataList = []
        self.__valueIndexDict = {}
        return dataCount
    
    def DelDataByValue(self, valueList):
        ## É¾³ý¸Ã¼Ç¼IDËùÓÐÆ¥ÅäValueÖµÁбíµÄÊý¾Ý¼Ç¼
        # @param valueList: [value1, value2, ...] valueΪNoneʱ²»ÅжϸÃÖµ
        if not valueList:
            return 0
        
        delCount = 0
        for recData in self.__dataList[::-1]: # µ¹Ðò´¦Àíɾ³ý
            if recData.IsMatchValue(valueList):
                self.DelRecData(recData)
                delCount += 1
                
        #if delCount:
        #    GameWorld.DebugLog("ɾ³ýͨÓüǼij¸öÀàÐÍIDËùÓÐÆ¥ÅäValueÖµµÄ¼Ç¼: recType=%s,recID=%s,valueList=%s,delCount=%s" 
        #                       % (self.__recType, self.__recID, valueList, delCount))
        return delCount
    
    def DelRecData(self, recData):
        ## É¾³ýÖ¸¶¨¼Ç¼
        if not recData:
            return 0
        
        if recData in self.__dataList:
            self.__dataList.remove(recData)
            
        keyStr = recData.GetValueIndexKey()
        if keyStr in self.__valueIndexDict:
            recIndexDataList = self.__valueIndexDict[keyStr]
            if recData in recIndexDataList:
                recIndexDataList.remove(recData)
                
        return 1
    
    def DelCount(self, delCount, reverse=False):
        ## É¾³ýÌõÊý
        # @param reverse: False-´ÓË÷Òý0¿ªÊ¼É¾³ý£¬True-´Ó×îºóÒ»¸öË÷ÒýÍùǰɾ
        delDataList = self.__dataList[:delCount] if not reverse else self.__dataList[-delCount-1:]
        for recData in delDataList:
            self.DelRecData(recData)
        #GameWorld.DebugLog("ɾ³ýͨÓüǼÌõÊý: recType=%s,recID=%s,delCount=%s,remainCount=%s" 
        #                   % (self.__recType, self.__recID, delCount, len(self.__dataList)))
        return
    
class GameRecTypeMgr():
    ## ÀàÐ͹ÜÀí
    
    def __init__(self, recType):
        self.__recType = recType
        self.__recIDDict = {} # recID¶ÔÓ¦Êý¾ÝÁбí {recID:GameRecIDMgr, ...}
        return
    
    def GetRecType(self): return self.__recType
    
    def GetRecIDMgr(self, recID):
        recIDMgr = None
        if recID in self.__recIDDict:
            recIDMgr = self.__recIDDict[recID]
        else:
            recIDMgr = GameRecIDMgr(self.__recType, recID)
            self.__recIDDict[recID] = recIDMgr
        return recIDMgr
    
    def GetRecIDList(self): return self.__recIDDict.keys()
    
    def GetRecDataByValues(self, valueList, findone=False):
        ## »ñÈ¡¸ÃÀàÐÍËùÓмǼƥÅävalueÖµµÄ¼Ç¼
        matchRecDataList = []
        for recID in self.__recIDDict.keys():
            recIDMgr = self.GetRecIDMgr(recID)
            ret = recIDMgr.GetRecDataByValues(valueList, findone)
            if not ret:
                continue
            if findone:
                return ret
            
            if isinstance(ret, list):
                matchRecDataList += ret
                
        return matchRecDataList
    
    def DelAllData(self):
        ## É¾³ý¸ÃÀàÐÍËùÓмǼ
        delCount = 0
        for recID in self.__recIDDict.keys():
            delCount += self.DelDataByRecID(recID)
        return delCount
    def DelDataByRecID(self, recID):
        ## É¾³ý¸ÃÀàÐÍij¸ö¼Ç¼IDµÄËùÓмǼ
        return self.GetRecIDMgr(recID).DelAllData()
    def DelDataByValue(self, valueList):
        ## É¾³ý¸ÃÀàÐÍËùÓÐÆ¥ÅäValueÖµÁбíµÄ¼Ç¼
        delCount = 0
        for recID in self.__recIDDict.keys():
            recIDMgr = self.GetRecIDMgr(recID)
            delCount += recIDMgr.DelDataByValue(valueList)
        return delCount
    
class GameRecMgr():
    ## Í¨ÓüǼ¹ÜÀí
    
    def __init__(self):
        self.__recTypeDict = {} # {recType:GameRecTypeMgr, ...}
        return
    
    def GetRecTypeMgr(self, recType):
        recTypeMgr = None
        if recType in self.__recTypeDict:
            recTypeMgr = self.__recTypeDict[recType]
        else:
            recTypeMgr = GameRecTypeMgr(recType)
            self.__recTypeDict[recType] = recTypeMgr
        return recTypeMgr
    
    def GetRecTypeIDMgr(self, recType, recID):
        recTypeMgr = self.GetRecTypeMgr(recType)
        recTypeIDMgr = recTypeMgr.GetRecIDMgr(recID)
        if not recTypeIDMgr and False:
            recTypeIDMgr = GameRecIDMgr(recType, recID)
        return recTypeIDMgr
    
    # ±£´æÊý¾Ý ´æÊý¾Ý¿âºÍrealtimebackup
    def GetSaveData(self):
        savaData = ""
        cntData = ""
        cnt = 0
        
        for recType in self.__recTypeDict.keys():
            recTypeMgr = self.GetRecTypeMgr(recType)
            for recID in recTypeMgr.GetRecIDList():
                recTypeIDMgr = recTypeMgr.GetRecIDMgr(recID)
                for index in range(recTypeIDMgr.GetCount()):
                    recData = recTypeIDMgr.At(index)
                    savaData += recData.GetBuffer()
                    cnt += 1
                    
        GameWorld.Log("Save DBGameRec count :%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("Load DBGameRec count :%s" % cnt)
        
        for _ in xrange(cnt):
            dbData = DBStruct.tagDBGameRec()
            dbData.readData(datas, pos, dataslen)
            recType = dbData.RecType
            recID = dbData.RecID
            recTypeIDMgr = self.GetRecTypeIDMgr(recType, recID)
            recTypeIDMgr.InitRecDataInstance(dbData)
            
        for recType in self.__recTypeDict.keys():
            recTypeMgr = self.GetRecTypeMgr(recType)
            for recID in recTypeMgr.GetRecIDList():
                recTypeIDMgr = recTypeMgr.GetRecIDMgr(recID)
                recTypeIDMgr.SortByTime()
                
        return pos