From bd2e571ccdb5b0c7d9c1cadab3ba0996c26c9d38 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期五, 27 九月 2019 18:49:30 +0800
Subject: [PATCH] 8280 【主干】拍卖行系统上架优化(服务器可动态根据配置动态补充拍品)
---
ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py | 32 +++++-
ServerPython/CoreServerGroup/GameServer/Script/PyDataManager.py | 4
PySysDB/PySysDBG.h | 16 ++-
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/AuctionHouse.py | 203 ++++++++++++++++++++++++++++++---------
4 files changed, 194 insertions(+), 61 deletions(-)
diff --git a/PySysDB/PySysDBG.h b/PySysDB/PySysDBG.h
index 9542deb..4a29f46 100644
--- a/PySysDB/PySysDBG.h
+++ b/PySysDB/PySysDBG.h
@@ -63,12 +63,18 @@
char EndDate; //结束日期
char StartTime; //开启时间
char EndTime; //结束时间
- BYTE AuctionCount; //上架次数
- list RandMinuteRange; //上架随机间隔分钟下限|上限
- list ItemCountWeightList; //上架随机件数权重列表, [[权重, 件数], ...]
+ list WorldLVRange; //世界等级范围限制
list AddRandSecondRange; //每件拍品随机间隔上架秒数 上限|下限
- list AuctionItemWeightList; //上架物品随机权重, [[权重, 物品ID],[权重, [阶,颜色,部位集合,是否套装,星级]] ...]
- list RandMailKeyList; //上架随机邮件列表,有配置时上架的时候在线玩家会收到一封上架邮件提醒
+ WORD ReplenishCDMinutes; //动态补充拍品间隔分钟
+ BYTE ReplenishAuctionCount; //动态补充拍品保底数
+ DWORD ReplenishItemID; //动态补充物品ID
+ list ReplenishEquipInfo; //动态补充装备信息 [阶,颜色,是否套装]
+ list ReplenishEquipPlaces; //动态补充上架装备位列表
+ BYTE AuctionCount; //指定上架次数
+ list RandMinuteRange; //指定上架随机间隔分钟下限|上限
+ list ItemCountWeightList; //指定上架随机件数权重列表, [[权重, 件数], ...]
+ list AuctionItemWeightList; //指定上架物品随机权重, [[权重, 物品ID],[权重, [阶,颜色,部位集合,是否套装,星级]] ...]
+ list RandMailKeyList; //指定上架随机邮件列表,有配置时上架的时候在线玩家会收到一封上架邮件提醒
};
//日常活动表
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/AuctionHouse.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/AuctionHouse.py
index fd99fd1..c1a2563 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/AuctionHouse.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/AuctionHouse.py
@@ -248,6 +248,7 @@
if dbData.AuctionType == AuctionType_World:
pyAuctionItemMgr.worldAuctionItemList.append(dbData)
+ __OnCalcWorldAuctionItemCount(dbData, 1)
if familyID:
familyItemList = pyAuctionItemMgr.familyAuctionItemDict.get(familyID, [])
@@ -407,6 +408,37 @@
return True
return False
+def __OnCalcWorldAuctionItemCount(auctionItem, changeCount):
+ ## 世界拍品数量变更统计处理
+
+ if auctionItem.AuctionType != AuctionType_World:
+ return
+
+ auctionItemMgr = PyDataManager.GetAuctionItemManager()
+ itemID = auctionItem.ItemID
+ #GameWorld.DebugLog("世界拍品数量变更统计: itemID=%s,changeCount=%s" % (itemID, changeCount))
+
+ itemIDStr = str(itemID)
+ classLV = auctionItem.ItemClassLV
+ jobLimit = auctionItem.ItemJobLimit
+ # 统计有职业限制的境界装备
+ if jobLimit and classLV and len(itemIDStr) == 7:
+ color = int(itemIDStr[3:4])
+ isSuit = int(itemIDStr[-1])
+ jobEquipKey = (jobLimit, classLV, color, isSuit) # 职业,阶,颜色,是否套装
+ befCount = auctionItemMgr.worldAuctionJobEquipCountDict.get(jobEquipKey, 0)
+ updCount = max(befCount + changeCount, 0)
+ auctionItemMgr.worldAuctionJobEquipCountDict[jobEquipKey] = updCount
+ #GameWorld.DebugLog(" 职业境界装备数量变更: jobLimit=%s,classLV=%s,color=%s,isSuit=%s,befCount=%s,updCount=%s"
+ # % (jobLimit, classLV, color, isSuit, befCount, updCount))
+ # 其他的直接用itemID统计
+ else:
+ befCount = auctionItemMgr.worldAuctionItemCountDict.get(itemID, 0)
+ updCount = max(befCount + changeCount, 0)
+ auctionItemMgr.worldAuctionItemCountDict[itemID] = updCount
+ #GameWorld.DebugLog(" 物品ID数量变更: itemID=%s,befCount=%s,updCount=%s" % (itemID, befCount, updCount))
+
+ return
def __GetAuctionSystemItemInfo():
key = "AuctionSystemItem"
@@ -435,9 +467,10 @@
endTimeStr = ipyData.GetEndTime()
auctionCount = ipyData.GetAuctionCount()
randMinuteRange = ipyData.GetRandMinuteRange()
+ replenishAuctionCount = ipyData.GetReplenishAuctionCount()
- GameWorld.DebugLog("cfgID=%s,startDateStr=%s,endDateStr=%s,startTimeStr=%s,endTimeStr=%s,auctionCount=%s,randMinuteRange=%s"
- % (cfgID, startDateStr, endDateStr, startTimeStr, endTimeStr, auctionCount, randMinuteRange))
+ GameWorld.DebugLog("cfgID=%s,startDateStr=%s,endDateStr=%s,startTimeStr=%s,endTimeStr=%s,auctionCount=%s,randMinuteRange=%s,replenishAuctionCount=%s"
+ % (cfgID, startDateStr, endDateStr, startTimeStr, endTimeStr, auctionCount, randMinuteRange, replenishAuctionCount))
if not startDateStr:
startDateStr = curDateStr
@@ -486,10 +519,15 @@
GameWorld.DebugLog(" 添加上架系统拍品时间: nextAddMinutes=%s %s" % (nextAddMinutes, nextAddAuctionItemDatetime))
addAuctionItemDatetimeList.append(nextAddAuctionItemDatetime)
- if not addAuctionItemDatetimeList:
+ # 动态补充拍品模式
+ if replenishAuctionCount:
+ GameWorld.DebugLog(" 添加动态补充系统拍品计划: %s" % replenishAuctionCount)
+ # 指定上架拍品模式
+ elif addAuctionItemDatetimeList:
+ GameWorld.DebugLog(" 添加上架系统拍品时间计划: %s" % addAuctionItemDatetimeList)
+ else:
continue
- GameWorld.DebugLog(" 添加上架系统拍品时间: %s" % addAuctionItemDatetimeList)
- addSystemAuctionItemInfo.append([cfgID, ipyData, addAuctionItemDatetimeList])
+ addSystemAuctionItemInfo.append([cfgID, ipyData, startDatetime, endDatetime, addAuctionItemDatetimeList])
AuctionSystemItem = IpyGameDataPY.SetConfigEx(key, [reloadSign, addSystemAuctionItemInfo])
GameWorld.Log("本日系统拍品信息加载完毕!reloadSign=%s" % (reloadSign))
@@ -506,39 +544,98 @@
curDateTime.hour, curDateTime.minute), ChConfig.TYPE_Time_Format)
randMailKey = ""
- addItemTick = tick
- sysAuctionItemList = IpyGameDataPY.GetConfigEx("SysWaitAuctionItemList") # 系统等待上架的拍品列表
- if not sysAuctionItemList:
- sysAuctionItemList = []
- addSystemAuctionItemInfo = __GetAuctionSystemItemInfo()
- for cfgID, ipyData, addAuctionItemDatetimeList in addSystemAuctionItemInfo:
- if curDateTime not in addAuctionItemDatetimeList:
- continue
- #cfgID = ipyData.GetCfgID()
- addCountWeightList = ipyData.GetItemCountWeightList()
- auctionItemWeightList = ipyData.GetAuctionItemWeightList()
- randSecondRange = ipyData.GetAddRandSecondRange()
+ sysAuctionItemListDict = IpyGameDataPY.GetConfigEx("SysWaitAuctionItemListDict") # 系统等待上架的拍品列表字典 {cfgID:[待上架拍品列表], ...}
+ if not sysAuctionItemListDict:
+ sysAuctionItemListDict = {}
- addCount = GameWorld.GetResultByWeightList(addCountWeightList)
- GameWorld.Log("增加等待上架的系统拍品信息: cfgID=%s,addCount=%s,addItemTick=%s" % (cfgID, addCount, addItemTick))
- for _ in xrange(addCount):
- itemInfo = GameWorld.GetResultByWeightList(auctionItemWeightList)
- if itemInfo != None:
- randSeconds = 0
- if len(randSecondRange) == 2:
- randSeconds = random.randint(randSecondRange[0], randSecondRange[1])
- elif len(randSecondRange) == 1:
- randSeconds = randSecondRange[0]
- addItemTick = addItemTick + randSeconds * 1000
- sysAuctionItemList.append([addItemTick, itemInfo])
- GameWorld.Log(" 增加等待上架的系统拍品: randSeconds=%s,addItemTick=%s,itemInfo=%s" % (randSeconds, addItemTick, itemInfo))
-
- randMailKeyList = ipyData.GetRandMailKeyList()
- if randMailKeyList:
- randMailKey = random.choice(randMailKeyList)
+ curTime = int(time.time())
+ addItemTime = curTime
+ openJobList = IpyGameDataPY.GetFuncEvalCfg("OpenJob", 1)
+ auctionItemMgr = PyDataManager.GetAuctionItemManager()
+ curWorldLV = PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_WorldAverageLv)
+ addSystemAuctionItemInfo = __GetAuctionSystemItemInfo()
+ for cfgID, ipyData, startDatetime, endDatetime, addAuctionItemDatetimeList in addSystemAuctionItemInfo:
+ #cfgID = ipyData.GetCfgID()
+ if cfgID in sysAuctionItemListDict:
+ #GameWorld.DebugLog(" 队列中还有未处理的拍品时不处理,防止重复添加!cfgID=%s" % (cfgID))
+ continue
+ worldLVRange = ipyData.GetWorldLVRange()
+ if worldLVRange and len(worldLVRange) == 2:
+ worldLVMin, worldLVMax = worldLVRange
+ if curWorldLV < worldLVMin or curWorldLV > worldLVMax:
+ #GameWorld.DebugLog(" 不满足当前世界等级范围条件,不处理该系统上架拍品计划!cfgID=%s,curWorldLV=%s" % (cfgID, curWorldLV))
+ continue
- IpyGameDataPY.SetConfigEx("SysWaitAuctionItemList", sysAuctionItemList)
- #GameWorld.DebugLog("等待系统上架的拍品列表: %s" % sysAuctionItemList)
+ if curDateTime < startDatetime or curDateTime > endDatetime:
+ #GameWorld.DebugLog(" 不在规定的时间内,不处理该系统上架拍品计划!cfgID=%s" % (cfgID))
+ continue
+
+ randSecondRange = ipyData.GetAddRandSecondRange()
+ if len(randSecondRange) != 2:
+ #GameWorld.DebugLog(" 随机上架秒数格式错误,不处理该系统上架拍品计划!cfgID=%s" % (cfgID))
+ continue
+
+ addItemInfoList = []
+ replenishAuctionCount = ipyData.GetReplenishAuctionCount()
+ # 动态模式
+ if replenishAuctionCount:
+ replenishCDSeconds = ipyData.GetReplenishCDMinutes() * 60
+ lastReplenishTime = auctionItemMgr.worldAuctionReplenishTimeDict.get(cfgID, 0)
+ if curTime - lastReplenishTime < replenishCDSeconds:
+ continue
+ auctionItemMgr.worldAuctionReplenishTimeDict[cfgID] = curTime
+
+ replenishItemID = ipyData.GetReplenishItemID()
+ if replenishItemID:
+ curItemIDCount = auctionItemMgr.worldAuctionItemCountDict.get(replenishItemID, 0)
+ if curItemIDCount >= replenishAuctionCount:
+ continue
+ addItemIDCount = replenishAuctionCount - curItemIDCount
+ GameWorld.DebugLog(" 动态补充拍品队列: cfgID=%s,replenishItemID=%s,addItemIDCount=%s" % (cfgID, replenishItemID, addItemIDCount))
+ for _ in xrange(addItemIDCount):
+ addItemInfoList.append(replenishItemID)
+ else:
+ replenishEquipPlaces = ipyData.GetReplenishEquipPlaces()
+ rpClassLV, rpColor, rpIsSuit = ipyData.GetReplenishEquipInfo()
+ rpStar = 0
+ for job in openJobList:
+ jobEquipKey = (job, rpClassLV, rpColor, rpIsSuit)
+ curJobEquipCount = auctionItemMgr.worldAuctionJobEquipCountDict.get(jobEquipKey, 0)
+ if curJobEquipCount >= replenishAuctionCount:
+ continue
+ addEquipCount = replenishAuctionCount - curJobEquipCount
+ GameWorld.DebugLog(" 动态补充拍品队列: cfgID=%s,addEquipCount=%s,job=%s" % (cfgID, addEquipCount, job))
+ for _ in xrange(addEquipCount):
+ addItemInfoList.append([rpClassLV, rpColor, replenishEquipPlaces, rpIsSuit, rpStar, [job]])
+
+ random.shuffle(addItemInfoList) # 动态模式待添加拍品打乱下顺序,防止批量添加同一职业物品
+
+ # 指定模式
+ elif curDateTime in addAuctionItemDatetimeList:
+
+ addCountWeightList = ipyData.GetItemCountWeightList()
+ auctionItemWeightList = ipyData.GetAuctionItemWeightList()
+
+ addCount = GameWorld.GetResultByWeightList(addCountWeightList)
+ GameWorld.DebugLog(" 指定补充拍品队列: cfgID=%s,addCount=%s" % (cfgID, addCount))
+ for _ in xrange(addCount):
+ itemInfo = GameWorld.GetResultByWeightList(auctionItemWeightList)
+ if itemInfo != None:
+ addItemInfoList.append(itemInfo)
+
+ randMailKeyList = ipyData.GetRandMailKeyList()
+ if randMailKeyList:
+ randMailKey = random.choice(randMailKeyList)
+
+ sysWaitAuctionItemList = []
+ for itemInfo in addItemInfoList:
+ randSeconds = random.randint(randSecondRange[0], randSecondRange[1])
+ addItemTime = addItemTime + randSeconds
+ sysWaitAuctionItemList.append([addItemTime, itemInfo])
+ sysAuctionItemListDict[cfgID] = sysWaitAuctionItemList
+
+ IpyGameDataPY.SetConfigEx("SysWaitAuctionItemListDict", sysAuctionItemListDict)
+ #GameWorld.DebugLog("等待系统上架的拍品列表: %s" % sysAuctionItemListDict)
# 随机邮件通知
if randMailKey:
@@ -557,21 +654,26 @@
return
def __DoSysWaitAddAuctionItem(tick):
- sysAuctionItemList = IpyGameDataPY.GetConfigEx("SysWaitAuctionItemList") # 系统等待上架的拍品列表
- if not sysAuctionItemList:
+ SysWaitAuctionItemListDict = IpyGameDataPY.GetConfigEx("SysWaitAuctionItemListDict") # 系统等待上架的拍品列表
+ if not SysWaitAuctionItemListDict:
return
- doCount = len(sysAuctionItemList)
- while doCount > 0 and sysAuctionItemList:
- doCount -= 1
- addItemTick, itemInfo = sysAuctionItemList[0]
- if tick < addItemTick:
- #GameWorld.DebugLog("未到系统等待上架的拍品tick,不处理! tick=%s,sysAuctionItemList=%s" % (tick, sysAuctionItemList))
- break
- sysAuctionItemList.pop(0)
- GameWorld.DebugLog("系统等待上架的拍品tick已到,可上架! tick=%s >= addItemTick=%s,itemInfo=%s,sysAuctionItemList=%s" % (tick, addItemTick, itemInfo, sysAuctionItemList))
- DoAddSystemAuctionItem([itemInfo])
-
+ curTime = int(time.time())
+ for cfgID, sysAuctionItemList in SysWaitAuctionItemListDict.items():
+ doCount = len(sysAuctionItemList)
+ while doCount > 0 and sysAuctionItemList:
+ doCount -= 1
+ addItemTime, itemInfo = sysAuctionItemList[0]
+ if curTime < addItemTime:
+ #GameWorld.DebugLog("未到系统等待上架的拍品时间,不处理! curTime=%s,sysAuctionItemList=%s" % (curTime, sysAuctionItemList))
+ break
+ sysAuctionItemList.pop(0)
+ GameWorld.DebugLog("系统等待上架的拍品时间已到,可上架! curTime=%s >= addItemTime=%s,itemInfo=%s,sysAuctionItemList=%s" % (curTime, addItemTime, itemInfo, sysAuctionItemList))
+ DoAddSystemAuctionItem([itemInfo])
+
+ if not sysAuctionItemList:
+ SysWaitAuctionItemListDict.pop(cfgID)
+
return
def OnAuctionItemTimeProcess(curTime, tick):
@@ -716,6 +818,7 @@
auctionItemMgr.allAuctionItemByEndTimeList.append(auctionItem)
auctionItemMgr.worldAuctionItemList.append(auctionItem)
+ __OnCalcWorldAuctionItemCount(auctionItem, 1)
notifyWorldAddItemList.append([itemGUID, itemID, playerID])
AddAuctionRecord(auctionItem, AuctionRecordResult_MoveToWorld)
@@ -876,6 +979,7 @@
if auctionItem in auctionItemMgr.worldAuctionItemList:
auctionItemMgr.worldAuctionItemList.remove(auctionItem)
+ __OnCalcWorldAuctionItemCount(auctionItem, -1)
for queryItemList in auctionItemMgr.worldAuctionItemQueryDict.values():
if auctionItem in queryItemList:
@@ -1085,6 +1189,7 @@
auctionItemMgr.familyAuctionItemDict[familyID] = familyItemList
else:
auctionItemMgr.worldAuctionItemList.append(auctionItem)
+ __OnCalcWorldAuctionItemCount(auctionItem, 1)
# 添加进我的拍卖
if playerID:
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py b/ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py
index 1d35e5c..b5d1a56 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/IpyGameDataPY.py
@@ -79,10 +79,16 @@
("char", "EndDate", 0),
("char", "StartTime", 0),
("char", "EndTime", 0),
+ ("list", "WorldLVRange", 0),
+ ("list", "AddRandSecondRange", 0),
+ ("WORD", "ReplenishCDMinutes", 0),
+ ("BYTE", "ReplenishAuctionCount", 0),
+ ("DWORD", "ReplenishItemID", 0),
+ ("list", "ReplenishEquipInfo", 0),
+ ("list", "ReplenishEquipPlaces", 0),
("BYTE", "AuctionCount", 0),
("list", "RandMinuteRange", 0),
("list", "ItemCountWeightList", 0),
- ("list", "AddRandSecondRange", 0),
("list", "AuctionItemWeightList", 0),
("list", "RandMailKeyList", 0),
),
@@ -651,10 +657,16 @@
self.EndDate = ""
self.StartTime = ""
self.EndTime = ""
+ self.WorldLVRange = []
+ self.AddRandSecondRange = []
+ self.ReplenishCDMinutes = 0
+ self.ReplenishAuctionCount = 0
+ self.ReplenishItemID = 0
+ self.ReplenishEquipInfo = []
+ self.ReplenishEquipPlaces = []
self.AuctionCount = 0
self.RandMinuteRange = []
self.ItemCountWeightList = []
- self.AddRandSecondRange = []
self.AuctionItemWeightList = []
self.RandMailKeyList = []
return
@@ -664,12 +676,18 @@
def GetEndDate(self): return self.EndDate # 结束日期
def GetStartTime(self): return self.StartTime # 开启时间
def GetEndTime(self): return self.EndTime # 结束时间
- def GetAuctionCount(self): return self.AuctionCount # 上架次数
- def GetRandMinuteRange(self): return self.RandMinuteRange # 上架随机间隔分钟下限|上限
- def GetItemCountWeightList(self): return self.ItemCountWeightList # 上架随机件数权重列表, [[权重, 件数], ...]
+ def GetWorldLVRange(self): return self.WorldLVRange # 世界等级范围限制
def GetAddRandSecondRange(self): return self.AddRandSecondRange # 每件拍品随机间隔上架秒数 上限|下限
- def GetAuctionItemWeightList(self): return self.AuctionItemWeightList # 上架物品随机权重, [[权重, 物品ID],[权重, [阶,颜色,部位集合,是否套装,星级]] ...]
- def GetRandMailKeyList(self): return self.RandMailKeyList # 上架随机邮件列表,有配置时上架的时候在线玩家会收到一封上架邮件提醒
+ def GetReplenishCDMinutes(self): return self.ReplenishCDMinutes # 动态补充拍品间隔分钟
+ def GetReplenishAuctionCount(self): return self.ReplenishAuctionCount # 动态补充拍品保底数
+ def GetReplenishItemID(self): return self.ReplenishItemID # 动态补充物品ID
+ def GetReplenishEquipInfo(self): return self.ReplenishEquipInfo # 动态补充装备信息 [阶,颜色,是否套装]
+ def GetReplenishEquipPlaces(self): return self.ReplenishEquipPlaces # 动态补充上架装备位列表
+ def GetAuctionCount(self): return self.AuctionCount # 指定上架次数
+ def GetRandMinuteRange(self): return self.RandMinuteRange # 指定上架随机间隔分钟下限|上限
+ def GetItemCountWeightList(self): return self.ItemCountWeightList # 指定上架随机件数权重列表, [[权重, 件数], ...]
+ def GetAuctionItemWeightList(self): return self.AuctionItemWeightList # 指定上架物品随机权重, [[权重, 物品ID],[权重, [阶,颜色,部位集合,是否套装,星级]] ...]
+ def GetRandMailKeyList(self): return self.RandMailKeyList # 指定上架随机邮件列表,有配置时上架的时候在线玩家会收到一封上架邮件提醒
# 日常活动表
class IPY_DailyAction():
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/PyDataManager.py b/ServerPython/CoreServerGroup/GameServer/Script/PyDataManager.py
index 1d073dc..fe34525 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/PyDataManager.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/PyDataManager.py
@@ -171,6 +171,10 @@
self.hisBiddingAuctionItemDict = {} # 玩家曾经参与过竞价的拍品,含所有拍品 {playerID:[tagDBAuctionItem, ...], ...}
self.myAuctionItemDict = {} # 玩家拍卖中的物品 ,不包含仙盟拍品,由前端界面自行整合数据 {playerID:[tagDBAuctionItem, ...], ...}
self.myAttentionItemDict = {} # 玩家关注中的物品 ,不包含仙盟拍品,由前端界面自行整合数据,只保存在线的玩家,离线清除,上线不同步,由前端查询 {playerID:[tagDBAuctionItem, ...], ...}
+
+ self.worldAuctionItemCountDict = {} # 全服拍品物品ID对应件数统计 {itemID:件数, ...}
+ self.worldAuctionJobEquipCountDict = {} # 全服拍品职业装备对应件数统计 {(职业,阶,颜色,是否套装):件数, ...}
+ self.worldAuctionReplenishTimeDict = {} # 全服拍品动态上架历史处理时间 {cfgID:time, ...}
return
# 保存数据 存数据库和realtimebackup
--
Gitblit v1.8.0