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
384
385
386
387
388
389
390
391
392
393
394
395
396
397
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package DB.StructData.DBFuncTeam
#
# @todo:¹¦ÄܶÓÎé±í
# @author hxp
# @date 2025-05-28
# @version 1.0
#
# ÏêϸÃèÊö: ¹¦ÄܶÓÎé±í
#
#-------------------------------------------------------------------------------
#"""Version = 2025-05-28 10:00"""
#-------------------------------------------------------------------------------
 
import DBStruct
import GameWorld
import IpyGameDataPY
import PlayerViewCache
import DBDataMgr
import CommFunc
import ChConfig
 
import time
 
class FuncTeamMem():
    ## ¹¦ÄܶÓÎé³ÉÔ±
    
    def __init__(self, dbData=None):
        self.__dbData = DBStruct.tagDBFuncTeamMem() if not dbData else dbData
        return
    
    def GetTeamID(self): return self.__dbData.TeamID
    def SetTeamID(self, teamID): self.__dbData.TeamID = teamID
    def GetPlayerID(self): return self.__dbData.PlayerID
    def SetPlayerID(self, playerID): self.__dbData.PlayerID = playerID
    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 GetBuffer(self): return self.__dbData.getBuffer()
    
    def GetFightPower(self):
        viewCache = PlayerViewCache.FindViewCache(self.GetPlayerID())
        return viewCache.GetFightPowerTotal() if viewCache else 0
    
class FuncTeam():
    ## ¹¦ÄܶÓÎé
    
    def __init__(self, dbData=None):
        self.__dbData = DBStruct.tagDBFuncTeam() if not dbData else dbData
        self.__memberList = []
        try:
            self.__applyIDList = eval(self.__dbData.ApplyIDList)
        except:
            self.__applyIDList = []  
        return
    
    def GetTeamID(self): return self.__dbData.TeamID
    def SetTeamID(self, teamID): self.__dbData.TeamID = teamID
    def GetTeamName(self): return self.__dbData.TeamName
    def SetTeamName(self, teamName): self.__dbData.SetTeamName(teamName)
    def GetZoneID(self): return self.__dbData.ZoneID
    def SetZoneID(self, zoneID): self.__dbData.ZoneID = zoneID
    def GetFuncMapID(self): return self.__dbData.FuncMapID
    def SetFuncMapID(self, funcMapID): self.__dbData.FuncMapID = funcMapID
    def GetFuncMapEx(self): return self.__dbData.FuncMapEx
    def SetFuncMapEx(self, funcMapEx): self.__dbData.FuncMapEx = funcMapEx
    def GetCreateTime(self): return self.__dbData.CreateTime
    def SetCreateTime(self, createTime): self.__dbData.CreateTime = createTime
    def GetCaptainID(self): return self.__dbData.CaptainID
    def SetCaptainID(self, captainID): self.__dbData.CaptainID = captainID
    def GetMinLV(self): return self.__dbData.MinLV
    def SetMinLV(self, minLV): self.__dbData.MinLV = minLV
    def GetMinFightPower(self): return self.__dbData.MinFightPower
    def GetMinFightPowerEx(self): return self.__dbData.MinFightPowerEx
    def SetMinFightPowerTotal(self, minFightPower):
        self.__dbData.MinFightPower = minFightPower % ChConfig.Def_PerPointValue
        self.__dbData.MinFightPowerEx = minFightPower / ChConfig.Def_PerPointValue
        return
    def GetServerOnly(self): return self.__dbData.ServerOnly
    def SetServerOnly(self, serverOnly): self.__dbData.ServerOnly = serverOnly
    def GetNeedCheck(self): return self.__dbData.NeedCheck
    def SetNeedCheck(self, needCheck): self.__dbData.NeedCheck = needCheck
    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 GetBuffer(self):
        self.__dbData.ApplyIDList = str(self.__applyIDList).replace(" ", "")
        self.__dbData.ApplyIDLen = len(self.__dbData.ApplyIDList)
        return self.__dbData.getBuffer()
    
    def InitTeamMemInstance(self, dbData):
        '''³õʼ»¯¹¦ÄÜÊý¾ÝʵÀý£¬´´½¨»ò¼ÓÔØÊý¾ÝʱͨÓ㬹¦ÄÜÒ»°ã²»µ÷ÓÃ
        @param dbData: ÊµÀý¶ÔÓ¦°ó¶¨µÄdbData
        @return: ³É¹¦·µ»ØÊµÀý¶ÔÏó£¬Ê§°Ü·µ»ØNone
        '''
        
        teamMem = FuncTeamMem(dbData)
        self.__memberList.append(teamMem)
        
        DBDataMgr.GetFuncTeamMgr().UpdPlayerTeamID(teamMem.GetPlayerID(), self.GetFuncMapID(), self.GetTeamID())
        return teamMem
    
    def AddTeamMember(self, playerID):
        teamMem = None
        self.DelApplyID(playerID) # ¼ÓÈëµÄͬʱ´ÓÉêÇëÁбíÖÐÒÆ³ý
        mem = self.GetMemberByID(playerID)
        if mem:
            teamMem = mem
            return teamMem
        
        dbData = DBStruct.tagDBFuncTeamMem()
        dbData.TeamID = self.GetTeamID()
        dbData.PlayerID = playerID
        
        teamMem = self.InitTeamMemInstance(dbData)
        return teamMem
    
    def GetMemberCount(self): return len(self.__memberList)
    def GetMemberAt(self, index):
        mem = None
        if 0 <= index < len(self.__memberList):
            mem = self.__memberList[index]
        elif False:
            mem = FuncTeamMem()
        return mem
    def GetMemberIDList(self): return [mem.GetPlayerID() for mem in self.__memberList]
    def GetMemberByID(self, playerID):
        for mem in self.__memberList:
            if mem.GetPlayerID() == playerID:
                return mem
        return
    
    def GetMemFightPowerTotal(self):
        ## ¶ÓÔ±×ÜÕ½Á¦
        totalFightPower = 0
        for mem in self.__memberList:
            totalFightPower += mem.GetFightPower()
        return totalFightPower
    
    def DelTeamMember(self, playerID):
        for mem in self.__memberList[::-1]:
            if mem.GetPlayerID() == playerID:
                self.__memberList.remove(mem)
                
                DBDataMgr.GetFuncTeamMgr().UpdPlayerTeamID(playerID, self.GetFuncMapID(), 0)
                break
        return
    
    def GetApplyIDList(self): return self.__applyIDList
    
    def AddApplyID(self, playerID):
        if playerID not in self.__applyIDList:
            self.__applyIDList.append(playerID)
        return
    
    def DelApplyID(self, playerID):
        if playerID in self.__applyIDList:
            self.__applyIDList.remove(playerID)
        return
    
    def DelApplyIDAll(self):
        self.__applyIDList = []
        return
    
class FuncTeamMgr():
    ## ¹¦ÄܶÓÎé¹ÜÀí
    
    def __init__(self):
        self.__funcTeamDict = {} # {teamID:FuncTeam, ...}
        self.__funcTeamListDict = {} # {funcMapID:{zoneID:[FuncTeam, ...], ...}, ...}
        self.__playerFuncTeamIDDict = {} # {playerID:{funcMapID:teamID, ...}, ...} # 
        self.__loopTeamID = 0 # µÝÔö£¬Ö±µ½³¬¹ýÉÏÏÞºó£¬ÔÙ´ÓÍ·¿ªÊ¼
        return
    
    def __GetNewTeamID(self):
        ## »ñȡжÓÎéID
        idMin, idMax = 100, 9999 # ·Ç¿ç·þ¶ÓÎéID·¶Î§£¬´æ´¢±¾·þ£¬ºÏ·þÇå¿Õ
        if GameWorld.IsCrossServer():
            idMin, idMax = 10000, 99999 # ¿ç·þ¶ÓÎéID·¶Î§£¬´æ´¢¿ç·þ£¬ºÏ·þ²»Ó°Ïì
            
        teamMax = idMax - idMin + 1
        if len(self.__funcTeamDict) >= teamMax:
            GameWorld.ErrLog("¹¦ÄܶÓÎéIDÒÑÂú!")
            return
        
        if not self.__loopTeamID and self.__funcTeamDict:
            self.__loopTeamID = max(self.__funcTeamDict)
            
        newTeamID = 0
        doCount = 0
        while doCount < teamMax:
            doCount += 1
            if not self.__loopTeamID or self.__loopTeamID >= idMax or self.__loopTeamID < idMin:
                self.__loopTeamID = idMin
            else:
                self.__loopTeamID += 1
            if self.__loopTeamID not in self.__funcTeamDict:
                newTeamID = self.__loopTeamID
                break
        return newTeamID
    
    def __InitTeamInstance(self, dbData):
        '''³õʼ»¯¹¦ÄÜÊý¾ÝʵÀý£¬´´½¨»ò¼ÓÔØÊý¾ÝʱͨÓ㬹¦ÄÜÒ»°ã²»µ÷ÓÃ
        @param dbData: ÊµÀý¶ÔÓ¦°ó¶¨µÄdbData
        @return: ³É¹¦·µ»ØÊµÀý¶ÔÏó£¬Ê§°Ü·µ»ØNone
        '''
        team = FuncTeam(dbData)
        teamID = team.GetTeamID()
        zoneID = team.GetZoneID()
        funcMapID = team.GetFuncMapID()
        funcTeamList = self.__getFuncTeamList(funcMapID, zoneID)
        if team not in funcTeamList:
            funcTeamList.append(team)
            
        self.__funcTeamDict[teamID] = team
        return team
    
    def __getFuncTeamList(self, funcMapID, zoneID):
        if funcMapID not in self.__funcTeamListDict:
            self.__funcTeamListDict[funcMapID] = {}
        funcZoneTeamDict = self.__funcTeamListDict[funcMapID]
        if zoneID not in funcZoneTeamDict:
            funcZoneTeamDict[zoneID] = []
        funcTeamList = funcZoneTeamDict[zoneID]
        return funcTeamList
    
    def CreateFuncTeam(self, playerID, funcMapID, funcMapEx, teamName="", zoneID=0):
        funcTeam = None
        teamID = self.__GetNewTeamID()
        if not teamID:
            return funcTeam
        
        dbData = DBStruct.tagDBFuncTeam()
        dbData.TeamID = teamID
        dbData.TeamName = teamName
        dbData.ZoneID = zoneID
        dbData.FuncMapID = funcMapID
        dbData.FuncMapEx = funcMapEx
        dbData.CreateTime = int(time.time())
        dbData.CaptainID = playerID
        
        funcTeam = self.__InitTeamInstance(dbData)
        funcTeam.AddTeamMember(playerID)
        return funcTeam
    
    def SortTeam(self, funcMapID, zoneID, sortReason=""):
        ipyData = IpyGameDataPY.GetIpyGameData("FuncTeamSet", funcMapID)
        if not ipyData:
            return
        sortType = ipyData.GetSortType()
        sortReverse = ipyData.GetSortReverse()
        
        teamList = self.__getFuncTeamList(funcMapID, zoneID)
        if not teamList:
            return
        
        # °´´´½¨Ê±¼ä
        if sortType == 0:
            if not sortReason or sortReason == "create":
                teamList.sort(key=lambda t: (t.GetCreateTime()), reverse=sortReverse)
                #GameWorld.DebugLog("°´Ê±¼äÅÅÐò: zoneID=%s,funcMapID=%s,sortReason=%s" % (zoneID, funcMapID, sortReason))
        # °´¶ÓÔ±×ÜÕ½Á¦
        elif sortType == 1:
            if not sortReason or sortReason == "member":
                teamList.sort(key=lambda t: (t.GetMemFightPowerTotal()), reverse=sortReverse)
                #GameWorld.DebugLog("°´Õ½Á¦ÅÅÐò: zoneID=%s,funcMapID=%s,sortReason=%s" % (zoneID, funcMapID, sortReason))
        return
    
    def GetFuncTeam(self, teamID):
        funcTeam = None
        if teamID in self.__funcTeamDict:
            funcTeam = self.__funcTeamDict[teamID]
        if not funcTeam and False:
            # ²»»áÖ´ÐУ¬½öΪÁË.Ìáʾ´úÂëÓÃ
            funcTeam = FuncTeam()
        return funcTeam
    
    def DelTeam(self, teamID):
        ## É¾³ý¶ÓÎé
        funcTeam = self.GetFuncTeam(teamID)
        if not funcTeam:
            return
        
        zoneID = funcTeam.GetZoneID()
        funcMapID = funcTeam.GetFuncMapID()
        for index in range(funcTeam.GetMemberCount()):
            mem = funcTeam.GetMemberAt(index)
            self.UpdPlayerTeamID(mem.GetPlayerID(), funcMapID, 0)
            
        # ÒƳýʵÀý
        teamList = self.__getFuncTeamList(funcMapID, zoneID)
        if funcTeam in teamList:
            teamList.remove(funcTeam)
                        
        self.__funcTeamDict.pop(teamID, None)
        return
    
    def UpdPlayerTeamID(self, playerID, funcMapID, teamID):
        if playerID not in self.__playerFuncTeamIDDict:
            self.__playerFuncTeamIDDict[playerID] = {}
        teamIDDict = self.__playerFuncTeamIDDict[playerID]
        if not teamID:
            teamIDDict.pop(funcMapID, 0)
            if not teamIDDict:
                self.__playerFuncTeamIDDict.pop(playerID, None)
        else:
            teamIDDict[funcMapID] = teamID
        return
    
    def GetPlayerTeamID(self, playerID, funcMapID):
        if playerID not in self.__playerFuncTeamIDDict:
            return 0
        teamIDDict = self.__playerFuncTeamIDDict[playerID]
        return teamIDDict.get(funcMapID, 0)
    #def GetPlayerTeamIDDict(self, playerID): return self.playerFuncTeamIDDict.get(playerID, {})
    
    def IsTeamPlayer(self, playerID):
        if playerID in self.__playerFuncTeamIDDict:
            return True
        for zoneTeamInfo in self.__funcTeamListDict.values():
            for funcTeamList in zoneTeamInfo.values():
                for funcTeam in funcTeamList:
                    if playerID in funcTeam.GetApplyIDList():
                        return True
        return False
    
    # ±£´æÊý¾Ý ´æÊý¾Ý¿âºÍrealtimebackup
    def GetSaveData(self):
        
        teamCnt, teamSavaData = 0, ""
        memCnt, memSavaData = 0, ""
        for zoneTeamInfo in self.__funcTeamListDict.values():
            for funcTeamList in zoneTeamInfo.values():
                for funcTeam in funcTeamList:
                    teamSavaData += funcTeam.GetBuffer()
                    teamCnt += 1
                    for index in range(funcTeam.GetMemberCount()):
                        mem = funcTeam.GetMemberAt(index)
                        memSavaData += mem.GetBuffer()
                        memCnt += 1
                    
        saveData = ""
        
        saveData += CommFunc.WriteDWORD("", teamCnt) + teamSavaData
        GameWorld.Log("Save DBFuncTeam count :%s len=%s" % (teamCnt, len(teamSavaData)))
        
        saveData += CommFunc.WriteDWORD("", memCnt) + memSavaData
        GameWorld.Log("Save DBFuncTeamMem count :%s len=%s" % (memCnt, len(memSavaData)))
        
        return saveData
    
    # ´ÓÊý¾Ý¿âÔØÈëÊý¾Ý
    def LoadPyGameData(self, datas, pos, dataslen):
        
        # ¶ÓÎé
        cnt, pos = CommFunc.ReadDWORD(datas, pos)
        GameWorld.Log("Load DBFuncTeam count :%s" % cnt)
        for _ in xrange(cnt):
            dbData = DBStruct.tagDBFuncTeam()
            pos += dbData.readData(datas, pos, dataslen)
            self.__InitTeamInstance(dbData)
            
        # ³ÉÔ±
        cnt, pos = CommFunc.ReadDWORD(datas, pos)
        GameWorld.Log("Load DBFuncTeamMem count :%s" % cnt)
        for _ in xrange(cnt):
            dbData = DBStruct.tagDBFuncTeamMem()
            pos += dbData.readData(datas, pos, dataslen)
            
            team = self.GetFuncTeam(dbData.TeamID)
            if not team:
                continue
            team.InitTeamMemInstance(dbData)
            
        # ÅÅÐò
        for funcMapID, zoneTeamInfo in self.__funcTeamListDict.items():
            for zoneID in zoneTeamInfo.keys():
                self.SortTeam(funcMapID, zoneID)
        return pos