#!/usr/bin/python
|
# -*- coding: GBK -*-
|
#-------------------------------------------------------------------------------
|
#
|
##@package DB.StructData.DBBillboard
|
#
|
# @todo:DBÅÅÐаñ
|
# @author hxp
|
# @date 2025-05-16
|
# @version 1.0
|
#
|
# ÏêϸÃèÊö: DBÅÅÐаñ
|
#
|
#-------------------------------------------------------------------------------
|
#"""Version = 2025-05-16 12:00"""
|
#-------------------------------------------------------------------------------
|
|
import DBStruct
|
import GameWorld
|
import ShareDefine
|
import DataRecordPack
|
import IpyGameDataPY
|
import DBDataMgr
|
import CommFunc
|
|
import json
|
|
class BillboardData():
|
## °ñµ¥Êý¾Ý
|
|
def __init__(self, dbData=None):
|
self.__dbData = DBStruct.tagDBBillboard() if not dbData else dbData
|
return
|
|
def GetType(self): return self.__dbData.BillboardType
|
def SetType(self, bType): self.__dbData.BillboardType = bType
|
def GetGroupValue1(self): return self.__dbData.GroupValue1
|
def SetGroupValue1(self, groupValue1): self.__dbData.GroupValue1 = groupValue1
|
def GetGroupValue2(self): return self.__dbData.GroupValue2
|
def SetGroupValue2(self, groupValue2): self.__dbData.GroupValue2 = groupValue2
|
def GetID(self): return self.__dbData.ID
|
def SetID(self, dataID): self.__dbData.ID = dataID
|
def GetID2(self): return self.__dbData.ID2
|
def SetID2(self, id2): self.__dbData.ID2 = id2
|
def GetName1(self): return self.__dbData.Name1
|
def SetName1(self, name): self.__dbData.Name1 = name
|
def GetName2(self): return self.__dbData.Name2
|
def SetName2(self, name2): self.__dbData.Name2 = name2
|
def GetType2(self): return self.__dbData.Type2
|
def SetType2(self, type2): self.__dbData.Type2 = type2
|
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 GetCmpValue(self): return self.__dbData.CmpValue
|
def SetCmpValue(self, cmpValue): self.__dbData.CmpValue = cmpValue
|
def GetCmpValue2(self): return self.__dbData.CmpValue2
|
def SetCmpValue2(self, cmpValue2): self.__dbData.CmpValue2 = cmpValue2
|
def GetCmpValue3(self): return self.__dbData.CmpValue3
|
def SetCmpValue3(self, cmpValue3): self.__dbData.CmpValue3 = cmpValue3
|
def GetUserData(self): return self.__dbData.UserData
|
def SetUserData(self, userData):
|
if not isinstance(userData, str):
|
if isinstance(userData, dict) or isinstance(userData, list):
|
userData = json.dumps(userData, ensure_ascii=False)
|
else:
|
userData = ""
|
userData = userData.replace(" ", "")
|
self.__dbData.UserData = userData
|
self.__dbData.DataLen = len(self.__dbData.UserData)
|
return
|
def GetBuffer(self): return self.__dbData.getBuffer()
|
def Clear(self): return self.__dbData.clear()
|
def Copy(self, setType=None):
|
copyData = BillboardData()
|
copyData.SetType(setType if setType != None else self.GetType())
|
copyData.SetGroupValue1(self.GetGroupValue1())
|
copyData.SetGroupValue2(self.GetGroupValue2())
|
copyData.SetID(self.GetID())
|
copyData.SetID2(self.GetID2())
|
copyData.SetName1(self.GetName1())
|
copyData.SetName2(self.GetName2())
|
copyData.SetType2(self.GetType2())
|
copyData.SetValue1(self.GetValue1())
|
copyData.SetValue2(self.GetValue2())
|
copyData.SetValue3(self.GetValue3())
|
copyData.SetValue4(self.GetValue4())
|
copyData.SetValue5(self.GetValue5())
|
copyData.SetValue6(self.GetValue6())
|
copyData.SetValue7(self.GetValue7())
|
copyData.SetValue8(self.GetValue8())
|
copyData.SetUserData(self.GetUserData())
|
copyData.SetCmpValue(self.GetCmpValue())
|
copyData.SetCmpValue2(self.GetCmpValue2())
|
copyData.SetCmpValue3(self.GetCmpValue3())
|
return copyData
|
|
class Billboard():
|
## ij¸öÅÅÐаñÀà
|
|
def __init__(self, billboardType=0, groupValue1=0, groupValue2=0):
|
self.__billboardType = billboardType
|
self.__groupValue1 = groupValue1
|
self.__groupValue2 = groupValue2
|
self.__billboardList = [] # [BillboardData, ...]
|
self.__idIndexDict = {} # {id:index, ...}
|
self.__idOrderDict = {} # {id:Ãû´Î, ...}
|
self.__orderRuleList = None # Ö¸¶¨ÅÅÃûËùÐèÖµ¹æÔòÁбí [[order, needCmpValue], ...]
|
self.__sortDelay = False # ÊÇ·ñÐèÒªÑÓ³ÙÅÅÐò
|
return
|
|
def GetType(self): return self.__billboardType
|
def GetGroupValue1(self): return self.__groupValue1
|
def GetGroupValue2(self): return self.__groupValue2
|
|
def ClearData(self):
|
if not self.__billboardList:
|
return
|
GameWorld.Log("Billboard ClearData billboardType=%s,groupValue1=%s,groupValue2=%s,dataCount=%s"
|
% (self.__billboardType, self.__groupValue1, self.__groupValue2, len(self.__billboardList)))
|
if GameWorld.IsCrossServer():
|
self.SaveDRData("Clear")
|
self.__billboardList = [] # [BillboardData, ...]
|
self.__idOrderDict = {} # {id:Ãû´Î, ...}
|
self.__idIndexDict = {}
|
return
|
|
def SortData(self):
|
GameWorld.DebugLog("°ñµ¥ÅÅÐò: billboardType=%s,groupValue1=%s,groupValue2=%s,dataCount=%s"
|
% (self.__billboardType, self.__groupValue1, self.__groupValue2, len(self.__billboardList)))
|
self.__billboardList.sort(key=lambda b: (b.GetCmpValue(), b.GetCmpValue2(), b.GetCmpValue3()), reverse=True)
|
self.__idOrderDict = {} # ÅÅÐòºóÖØÖã¬Ï´βéѯʱ¸üв¢»º´æ
|
self.__idIndexDict = {}
|
self.__sortDelay = False
|
return
|
|
def SetSortDelay(self):
|
## ÉèÖÃÑÓ³ÙÅÅÐò
|
GameWorld.DebugLog("°ñµ¥ÉèÖÃÑÓ³ÙÅÅÐò: billboardType=%s,groupValue1=%s,groupValue2=%s,dataCount=%s"
|
% (self.__billboardType, self.__groupValue1, self.__groupValue2, len(self.__billboardList)))
|
self.__sortDelay = True
|
return
|
|
def SortDelayDo(self):
|
## ÑÓ³ÙÅÅÐòÖ´ÐÐÅÅÐò
|
if not self.__sortDelay:
|
return
|
self.SortData()
|
return
|
|
def AddNewBillboardData(self):
|
newData = None
|
if self.IsFull():
|
return newData
|
newData = BillboardData()
|
newData.SetType(self.__billboardType)
|
newData.SetGroupValue1(self.__groupValue1)
|
newData.SetGroupValue2(self.__groupValue2)
|
self.AddBillboardData(newData)
|
return newData
|
|
def AddBillboardData(self, billboardData):
|
## Ìí¼Ó°ñµ¥Êý¾Ýµ½¸Ã°ñ
|
# @param billboardData: BillboardData
|
# @return: ÊÇ·ñ³É¹¦
|
if self.IsFull():
|
return False
|
self.__billboardList.append(billboardData)
|
self.__idIndexDict[billboardData.GetID()] = len(self.__billboardList) - 1
|
self.__sortDelay = True
|
# __idOrderDict ²»´¦Àí£¬µÈÏ´ÎÅÅÐòºó×Ô¶¯´¦Àí£¬ËùÒÔÐÂÌí¼ÓµÄÊý¾Ý¿ÉÄÜÕÒ²»µ½¶ÔÓ¦Ãû´Î£¬µ«ÊÇÄÜÕÒµ½¶ÔÓ¦Ë÷Òý¼°Êý¾Ý
|
return True
|
|
def FindByID(self, findID):
|
''' ¸ù¾ÝID²éѯ°ñµ¥Êý¾Ý
|
@param findID: ²éÕÒµÄID
|
@return: None or BillboardData
|
'''
|
billData = None
|
self.GetIDOrderDict()
|
if findID not in self.__idIndexDict:
|
return billData
|
idIndex = self.__idIndexDict[findID]
|
if idIndex >= len(self.__billboardList):
|
return billData
|
billData = self.__billboardList[idIndex]
|
if not billData and False:
|
billData = BillboardData() # ²»»áÖ´Ðе½£¬Ö»ÎªÁË.³ö´úÂëÌáʾ
|
return billData
|
|
def IndexOfByID(self, findID):
|
''' ¸ù¾ÝID²éѯËùÔÚ°ñµ¥Ë÷Òý
|
@param findID: ²éÕÒµÄID
|
@return: -1 or >=0
|
'''
|
self.GetIDOrderDict()
|
if findID not in self.__idIndexDict:
|
return -1
|
idIndex = self.__idIndexDict[findID]
|
return idIndex
|
|
def SaveDRData(self, eventName="", addDataDict={}):
|
## ¼Ç¼Á÷ÏòÊý¾Ý
|
|
self.SortDelayDo()
|
dataCount = len(self.__billboardList)
|
if not dataCount:
|
return
|
|
idOrderDict = self.GetIDOrderDict()
|
serverTime = GameWorld.GetServerTime()
|
timeStr = "%02d%02d%02d%s" % (serverTime.hour, serverTime.minute, serverTime.second, str(serverTime.microsecond)[:3])
|
eventTypeStr = "Billboard_%s_%s_%s_%s_%s" % (self.__billboardType, self.__groupValue1, self.__groupValue2, eventName, timeStr)
|
|
dataDict = {"BillboardType":self.__billboardType, "DataCount":dataCount, "addDataDict":addDataDict,
|
"GroupValue1":self.__groupValue1, "GroupValue2":self.__groupValue2}
|
DataRecordPack.SendEventPack(eventTypeStr, dataDict)
|
|
for index, bData in enumerate(self.__billboardList):
|
rank = idOrderDict.get(bData.GetID(), index + 1)
|
dataDict = {"Type2":bData.GetType2(), "Rank":rank, "Index":index,
|
"ID":bData.GetID(), "ID2":bData.GetID2(),
|
"Name1":bData.GetName1(), "Name2":bData.GetName2(),
|
"Value1":bData.GetValue1(), "Value2":bData.GetValue2(),
|
"Value3":bData.GetValue3(), "Value4":bData.GetValue4(),
|
"Value5":bData.GetValue5(), "Value6":bData.GetValue6(),
|
"Value7":bData.GetValue7(), "Value8":bData.GetValue8(),
|
"CmpValue":bData.GetCmpValue(), "CmpValue2":bData.GetCmpValue2(),
|
"CmpValue3":bData.GetCmpValue3(), "UserData":bData.GetUserData()}
|
DataRecordPack.SendEventPack(eventTypeStr, dataDict)
|
|
return
|
|
def GetBillboardDataList(self): return self.__billboardList
|
def GetIDOrderDict(self):
|
## »ñÈ¡ID¶ÔÓ¦Ãû´Î×Öµä
|
# @return: {ID:Ãû´Î, ...} Ãû´Î´Ó1¿ªÊ¼
|
if not self.__idOrderDict or not self.__idIndexDict:
|
self.__idOrderDict = {}
|
self.__idIndexDict = {}
|
if self.__orderRuleList:
|
billboardDataCount = self.GetCount()
|
rankPre = 0
|
billboardIndex = 0
|
for rank, needCmpValue in self.__orderRuleList:
|
orderCountTotal = rank - rankPre # ½±ÀøÃû´ÎÊýÁ¿
|
rankPre = rank
|
for index in xrange(billboardIndex, billboardDataCount):
|
if orderCountTotal <= 0:
|
break
|
billboardData = self.At(index)
|
if billboardData.GetCmpValue() < needCmpValue:
|
break
|
orderReal = rank - orderCountTotal + 1
|
self.__idOrderDict[billboardData.GetID()] = orderReal
|
orderCountTotal -= 1
|
billboardIndex += 1
|
for order, billboardData in enumerate(self.__billboardList, 1):
|
self.__idIndexDict[billboardData.GetID()] = order - 1
|
else:
|
for order, billboardData in enumerate(self.__billboardList, 1):
|
self.__idOrderDict[billboardData.GetID()] = order
|
self.__idIndexDict[billboardData.GetID()] = order - 1
|
return self.__idOrderDict
|
|
def SetOrderRuleList(self, orderRuleList):
|
## ÅÅÃûËùÐèÖµ¹æÔòÁбí
|
# @param orderRuleList: ÅÅÃûËùÐèÖµ¹æÔòÁбí [[order, needCmpValue], ...]
|
self.__orderRuleList = orderRuleList
|
self.__idOrderDict = {} # ÉèÖúóÐèÖØÖ㬿ÉÄÜÅäÖùæÔò±ä»¯Á˵¼ÖÂʵ¼ÊÅÅÃû¿ÉÄܱ仯
|
self.__idIndexDict = {}
|
GameWorld.Log("ÉèÖÃÅÅÃûËùÐèÖµ¹æÔòÁбí: billboardType=%s,groupValue1=%s,groupValue2=%s, %s"
|
% (self.__billboardType, self.__groupValue1, self.__groupValue2, orderRuleList))
|
return
|
|
def GetCount(self): return len(self.__billboardList)
|
def GetMaxCount(self):
|
maxCountDict = IpyGameDataPY.GetFuncEvalCfg("BillboardSet", 2, {})
|
return maxCountDict.get(self.__billboardType, 100)
|
|
def At(self, index):
|
billData = self.__billboardList[index]
|
if not billData and False:
|
billData = BillboardData() # ²»»áÖ´Ðе½£¬Ö»ÎªÁË.³ö´úÂëÌáʾ
|
return billData
|
|
def IsFull(self): return len(self.__billboardList) >= self.GetMaxCount()
|
|
def DeleteByIndex(self, index):
|
if index >= len(self.__billboardList):
|
return
|
self.__billboardList.pop(index)
|
self.__idOrderDict = {}
|
self.__idIndexDict = {}
|
return
|
|
def DeleteByID(self, dataID):
|
index = self.IndexOfByID(dataID)
|
if index >= 0:
|
self.DeleteByIndex(index)
|
return
|
|
class BillboardMgr():
|
## ÅÅÐаñ¹ÜÀí
|
|
def __init__(self):
|
self.__billboardDict = {} # ÅÅÐаñ×Öµä {(billboardType, groupValue1, groupValue2):Billboard, ...}
|
return
|
|
def GetBillboardGroupList(self, bType):
|
## ¸ù¾Ý°ñµ¥ÀàÐÍ»ñÈ¡¸ÃÀàÐÍËùÓзÖ×é°ñµ¥ÐÅÏ¢
|
## @return: [(billboardType, groupValue1, groupValue2), ...]
|
groupList = []
|
for billboardType, groupValue1, groupValue2 in self.__billboardDict.keys():
|
if bType == billboardType:
|
groupList.append((billboardType, groupValue1, groupValue2))
|
return groupList
|
|
def GetBillboard(self, billboardType, groupValue1=0, groupValue2=0):
|
''' »ñÈ¡ÅÅÐаñ
|
@param billboardType: ÅÅÐаñÀàÐÍ
|
@param groupValue1: ·Ö×éÖµ1
|
@param groupValue2: ·Ö×éÖµ2£¬Óë·Ö×éÖµ1×éºÏ¹éΪͬ×é°ñµ¥Êý¾Ý
|
@return: Billboard
|
'''
|
key = (billboardType, groupValue1, groupValue2)
|
if key in self.__billboardDict:
|
billboardObj = self.__billboardDict[key]
|
else:
|
billboardObj = Billboard(billboardType, groupValue1, groupValue2)
|
self.__billboardDict[key] = billboardObj
|
return billboardObj
|
|
def RemoveBillboard(self, billboardType):
|
## ÒÆ³ýij¸öÀàÐ͵İñµ¥ËùÓÐÊý¾Ý
|
for key in self.__billboardDict.keys():
|
if key[0] == billboardType:
|
self.__billboardDict.pop(key)
|
return
|
|
def ClearBillboard(self, billboardType, groupValue1=None, groupValue2=None):
|
'''Çå³ýij¸öÀàÐ͵İñµ¥ËùÓÐÊý¾Ý£¬¿ÉÖ¸¶¨¹ýÂËgroupValue£¬ÓÐÁ÷Ïò¼Ç¼
|
@param groupValue1: ²»ÎªNoneʱÑéÖ¤ groupValue1 ÊÇ·ñÏàͬ
|
@param groupValue2: ²»ÎªNoneʱÑéÖ¤ groupValue2 ÊÇ·ñÏàͬ
|
Èç¹ûgroupValue1 groupValue2 ¶¼´«ÈëNone£¬Ï൱ÓÚÇå¿Õ billboardType ÀàÐ͵ÄËùÓаñµ¥Êý¾Ý
|
'''
|
clearList = []
|
for bType, gValue1, gValue2 in self.__billboardDict.keys():
|
if bType != billboardType:
|
continue
|
if groupValue1 != None and groupValue1 != gValue1:
|
continue
|
if groupValue2 != None and groupValue2 != gValue2:
|
continue
|
key = (bType, gValue1, gValue2)
|
clearList.append(key)
|
|
for bType, gValue1, gValue2 in clearList:
|
self.GetBillboard(bType, gValue1, gValue2).ClearData()
|
return
|
|
def CopyBillboard(self, fromBillboardType, toBillboardType, groupValue1=None, groupValue2=None):
|
'''½«Ä³¸öÀàÐ͵İñµ¥ÍêÈ«¿½±´µ½ÆäËû°ñµ¥ - Ò»°ãÓÃÓÚ±¸·Ý¡¢×ªÒÆÊý¾Ý
|
@param fromBillboardType: Ô´°ñµ¥ÀàÐÍ
|
@param toBillboardType: Ä¿±ê°ñµ¥ÀàÐÍ
|
@param groupValue1: ĬÈÏΪNone-¿½±´¸ÃÀàÐÍËùÓаñµ¥£¬´óÓÚµÈÓÚ0ʱ-½ö¿½±´¸ÃÀàÐÍϵÄÖ¸¶¨°ñµ¥
|
@param groupValue2: ĬÈÏΪNone-¿½±´¸ÃÀàÐÍËùÓаñµ¥£¬´óÓÚµÈÓÚ0ʱ-½ö¿½±´¸ÃÀàÐÍϵÄÖ¸¶¨°ñµ¥
|
'''
|
|
if groupValue1 == None:
|
self.RemoveBillboard(toBillboardType) # ĬÈÏÇå¿ÕÄ¿±ê°ñµ¥
|
groupList = self.GetBillboardGroupList(fromBillboardType)
|
else:
|
groupValue2 = groupValue2 if groupValue2 != None else 0
|
groupList = [fromBillboardType, groupValue1, groupValue2]
|
|
for billboardType, groupValue1, groupValue2 in groupList:
|
frbillboardObj = self.GetBillboard(billboardType, groupValue1, groupValue2)
|
toBillboardObj = self.GetBillboard(toBillboardType, groupValue1, groupValue2)
|
GameWorld.Log("CopyBillboard: billboardType=%s,toBillboardType=%s,groupValue1=%s,groupValue2=%s"
|
% (billboardType, toBillboardType, groupValue1, groupValue2))
|
toBillboardObj.ClearData()
|
for index in range(frbillboardObj.GetCount()):
|
frbillboardData = frbillboardObj.At(index)
|
toBillboardObj.AddBillboardData(frbillboardData.Copy(toBillboardType))
|
|
return
|
|
# ±£´æÊý¾Ý ´æÊý¾Ý¿âºÍrealtimebackup
|
def GetSaveData(self):
|
savaData = ""
|
cntData = ""
|
cnt = 0
|
for billboardType, groupValue1, groupValue2 in self.__billboardDict.keys():
|
billboardObj = self.GetBillboard(billboardType, groupValue1, groupValue2)
|
for i in xrange(billboardObj.GetCount()):
|
billboardData = billboardObj.At(i)
|
cnt += 1
|
savaData += billboardData.GetBuffer()
|
|
GameWorld.Log("Save DBBillboard count :%s len=%s" % (cnt, len(savaData)))
|
return CommFunc.WriteDWORD(cntData, cnt) + savaData
|
|
# ´ÓÊý¾Ý¿âÔØÈëÊý¾Ý
|
def LoadPyGameData(self, datas, pos, dataslen):
|
if pos >= dataslen:
|
return
|
|
cnt, pos = CommFunc.ReadDWORD(datas, pos)
|
GameWorld.Log("Load DBBillboard count :%s" % cnt)
|
|
for _ in xrange(cnt):
|
dbData = DBStruct.tagDBBillboard()
|
dbData.clear()
|
pos += dbData.readData(datas, pos, dataslen)
|
|
billboardType, groupValue1, groupValue2 = dbData.BillboardType, dbData.GroupValue1, dbData.GroupValue2
|
|
billboardObj = self.GetBillboard(billboardType, groupValue1, groupValue2)
|
billboardObj.AddBillboardData(BillboardData(dbData))
|
|
# ÅÅÐò
|
for billboardType, groupValue1, groupValue2 in self.__billboardDict.keys():
|
billboardObj = self.GetBillboard(billboardType, groupValue1, groupValue2)
|
billboardObj.SortData()
|
|
return pos
|
|
def OnMinute():
|
|
## ÿ·ÖÖÓÑÓ³ÙÅÅÐò
|
billboardMgr = DBDataMgr.GetBillboardMgr()
|
for billboardType in ShareDefine.BillboardTypeAllList:
|
groupList = billboardMgr.GetBillboardGroupList(billboardType)
|
for billboardType, groupValue1, groupValue2 in groupList:
|
billboardObj = billboardMgr.GetBillboard(billboardType, groupValue1, groupValue2)
|
billboardObj.SortDelayDo()
|
|
return
|
|
|