| | |
| | | import PyGameDataStruct
|
| | | import PlayerCompensation
|
| | | import ChPyNetSendPack
|
| | | import PlayerDBGSEvent
|
| | | import IpyGameDataPY
|
| | | import NetPackCommon
|
| | | import PlayerBourse
|
| | | import PlayerFamily
|
| | | import ShareDefine
|
| | | import PyGameData
|
| | | import ChConfig
|
| | |
|
| | | import random
|
| | | import datetime
|
| | | import operator
|
| | | import time
|
| | | import math
|
| | |
| | | AuctionRecordResult_BidOK, # 竞价成功
|
| | | AuctionRecordResult_BidFail, # 竞价失败
|
| | | AuctionRecordResult_MoveToWorld, # 仙盟拍品转移到全服拍品
|
| | | ) = range(6)
|
| | | AuctionRecordResult_Unsell, # 下架
|
| | | ) = range(7)
|
| | |
|
| | | # 当前拍品归类 0-全服拍品 1-仙盟私有拍品
|
| | | AuctionType_World = 0
|
| | |
| | |
|
| | | def __InitAuctionAttentionAttrEx(attentionData):
|
| | | ## 初始化拍卖关注实例附加属性
|
| | | setattr(attentionData, "AttentionItemIDList", [] if not attentionData.AttentionInfo else json.loads(attentionData.AttentionInfo))
|
| | | setattr(attentionData, "AttentionItemIDList", [])
|
| | | if attentionData.AttentionInfo.startswith("[") and attentionData.AttentionInfo.endswith("]"):
|
| | | attentionData.AttentionItemIDList = json.loads(attentionData.AttentionInfo)
|
| | | return
|
| | |
|
| | | ##-------------------------------------------------------------------------------------------------
|
| | | def OnGameServerInitOK():
|
| | | ## 服务器启动成功
|
| | | |
| | | allAuctionItemByEndTimeList = PyDataManager.GetAuctionItemManager().allAuctionItemByEndTimeList
|
| | | # 由于服务器未启动成功时取不到正确的开服天,所以启动成功后刷新一下拍品系统回购时间
|
| | | for auctionItem in allAuctionItemByEndTimeList:
|
| | | __SetAuctionItemSysBuyTime(auctionItem)
|
| | | |
| | | __SortAuctionitem()
|
| | | return
|
| | |
|
| | | def OnLoadAuctionItemDataEx(dbData):
|
| | | ## 加载拍卖物品表时附加处理
|
| | |
| | |
|
| | | if dbData.AuctionType == AuctionType_World:
|
| | | pyAuctionItemMgr.worldAuctionItemList.append(dbData)
|
| | | __OnCalcWorldAuctionItemCount(dbData, 1)
|
| | |
|
| | | if familyID:
|
| | | familyItemList = pyAuctionItemMgr.familyAuctionItemDict.get(familyID, [])
|
| | |
| | | setattr(auctionItem, "BiddingQueryID", 0) # 当前正在竞价的玩家ID
|
| | | setattr(auctionItem, "BiddingQueryTick", 0) # 当前正在竞价的tick
|
| | | setattr(auctionItem, "EndTime", 0) # 结束竞价time值
|
| | | setattr(auctionItem, "SysBuyTime", 0) # 系统一口价时间
|
| | |
|
| | | __SetAuctionItemSysBuyTime(auctionItem)
|
| | | __SetAuctionItemEndTime(auctionItem, ipyData)
|
| | | return True
|
| | |
|
| | | def __SetAuctionItemSysBuyTime(auctionItem):
|
| | | ## 更新系统一口价该拍品时间
|
| | | if not GameWorld.GetGameWorld().GetDictByKey(ChConfig.Def_WorldKey_GameWorldInitOK):
|
| | | #GameWorld.DebugLog("服务器未启动好,取不到正确的开服天,不处理拍品系统回购时间!")
|
| | | return
|
| | | #itemGUID = auctionItem.ItemGUID
|
| | | itemID = auctionItem.ItemID
|
| | | itemType = auctionItem.ItemType
|
| | | playerID = auctionItem.PlayerID
|
| | | familyID = auctionItem.FamilyID
|
| | | if not playerID and not familyID:
|
| | | #GameWorld.DebugLog("该拍品为系统上架的拍品,不设置系统一口价时间! GUID=%s,itemID=%s" % (itemGUID, itemID))
|
| | | return
|
| | | |
| | | if familyID:
|
| | | #GameWorld.DebugLog("该拍品为仙盟拍品,不设置系统一口价时间! GUID=%s,itemID=%s,familyID=%s" % (itemGUID, itemID, familyID))
|
| | | return
|
| | | |
| | | # 注意: 因为GameServer没传是否套装,所以暂时按策划的ID规则来处理,最后一位代表是否套装
|
| | | if itemID % 10 == 1:
|
| | | #GameWorld.DebugLog("该拍品为套装拍品,不设置系统一口价时间! itemID=%s" % (itemID))
|
| | | return
|
| | | |
| | | if auctionItem.BidderID:
|
| | | #GameWorld.DebugLog("该拍品已经有人竞价,不设置系统一口价时间! itemID=%s,bidderID=%s" % (itemID, auctionItem.BidderID))
|
| | | return
|
| | | |
| | | classLV = auctionItem.ItemClassLV
|
| | | classSysBuyRateDict = IpyGameDataPY.GetFuncEvalCfg("AuctionItemSystem", 5)
|
| | | if classLV in classSysBuyRateDict:
|
| | | sysBuyRate = classSysBuyRateDict[classLV]
|
| | | if not GameWorld.CanHappen(sysBuyRate, 100):
|
| | | #GameWorld.DebugLog("该拍品阶概率不回收,不设置系统一口价时间! itemID=%s,classLV=%s,sysBuyRate=%s" % (itemID, classLV, sysBuyRate))
|
| | | return
|
| | | |
| | | canSysBuyItemTypeList = IpyGameDataPY.GetFuncEvalCfg("AuctionItemSystem", 2)
|
| | | if itemType not in canSysBuyItemTypeList:
|
| | | #GameWorld.DebugLog("该拍品类型不可被系统一口价,不设置系统一口价时间! itemID=%s,itemType=%s" % (itemID, itemType))
|
| | | return
|
| | | |
| | | sysBuyTimeRange = {}
|
| | | openServerDay = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_ServerDay) + 1
|
| | | oscDaySysBuyTimeRangeDict = IpyGameDataPY.GetFuncEvalCfg("AuctionItemSystem", 1, {})
|
| | | openServerDayList = oscDaySysBuyTimeRangeDict.keys()
|
| | | openServerDayList.sort()
|
| | | for oscDay in openServerDayList:
|
| | | if openServerDay <= oscDay:
|
| | | sysBuyTimeRange = oscDaySysBuyTimeRangeDict[oscDay]
|
| | | break
|
| | | if len(sysBuyTimeRange) != 2:
|
| | | #GameWorld.DebugLog("该开服天没有配置系统中间商回购支持! openServerDay=%s, %s" % (openServerDay, oscDaySysBuyTimeRangeDict))
|
| | | return
|
| | | randMinutes = random.randint(sysBuyTimeRange[0], sysBuyTimeRange[1])
|
| | | addTimeStr = auctionItem.AddTime
|
| | | addTime = GameWorld.ChangeTimeStrToNum(addTimeStr)
|
| | | auctionItem.SysBuyTime = addTime + randMinutes * 60
|
| | | pyAuctionItemMgr = PyDataManager.GetAuctionItemManager()
|
| | | pyAuctionItemMgr.sysBuyoutItemByTimeList.append(auctionItem)
|
| | | #GameWorld.DebugLog("更新拍品系统一口价时间: GUID=%s,itemID=%s,addTime=%s(%s),openServerDay=%s,randMinutes=%s(%s),sysBuyTime=%s" |
| | | # % (itemGUID, itemID, addTime, addTimeStr, openServerDay, randMinutes, sysBuyTimeRange, auctionItem.SysBuyTime))
|
| | | return
|
| | |
|
| | | def __SetAuctionItemEndTime(auctionItem, ipyData):
|
| | | ## 更新拍品结束竞价time值
|
| | |
| | | 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"
|
| | | openServerDay = PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_ServerDay) + 1
|
| | | AuctionSystemItem = IpyGameDataPY.GetConfigEx(key)
|
| | | reloadSign = openServerDay
|
| | | if AuctionSystemItem and AuctionSystemItem[0] == reloadSign:
|
| | | GameWorld.DebugLog("已经加载过本日系统拍品处理信息!openServerDay=%s" % openServerDay)
|
| | | return AuctionSystemItem[1]
|
| | | |
| | | # 因为后面的时间判断都是精确到分的,而处理此逻辑的时候可能不是0秒,所以这里的datetime取当前时间精确到分的
|
| | | serverTime = GameWorld.GetServerTime()
|
| | | curDateStr = "%d-%d-%d" % (serverTime.year, serverTime.month, serverTime.day)
|
| | | curDateTimeStr = "%d-%d-%d %02d:%02d:00" % (serverTime.year, serverTime.month, serverTime.day, serverTime.hour, serverTime.minute)
|
| | | curDateTime = datetime.datetime.strptime(curDateTimeStr, ChConfig.TYPE_Time_Format)
|
| | | |
| | | GameWorld.Log("===== 加载本日系统拍品信息: %s,openServerDay=%s =====" % (curDateTime, openServerDay))
|
| | | addSystemAuctionItemInfo = []
|
| | | ipyDataMgr = IpyGameDataPY.IPY_Data()
|
| | | for index in xrange(ipyDataMgr.GetAuctionSystemItemCount()):
|
| | | ipyData = ipyDataMgr.GetAuctionSystemItemByIndex(index)
|
| | | cfgID = ipyData.GetCfgID()
|
| | | startDateStr = ipyData.GetStartDate()
|
| | | endDateStr = ipyData.GetEndDate()
|
| | | startTimeStr = ipyData.GetStartTime()
|
| | | 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,replenishAuctionCount=%s" |
| | | % (cfgID, startDateStr, endDateStr, startTimeStr, endTimeStr, auctionCount, randMinuteRange, replenishAuctionCount))
|
| | | |
| | | if not startDateStr:
|
| | | startDateStr = curDateStr
|
| | | elif startDateStr.isdigit():
|
| | | startServerDay = int(startDateStr)
|
| | | openServerDateTime = curDateTime + datetime.timedelta(days=(startServerDay-openServerDay))
|
| | | startDateStr = "%d-%d-%d" % (openServerDateTime.year, openServerDateTime.month, openServerDateTime.day)
|
| | | |
| | | if not endDateStr:
|
| | | endDateStr = curDateStr
|
| | | elif endDateStr.isdigit():
|
| | | endServerDay = int(endDateStr)
|
| | | endServerDateTime = curDateTime + datetime.timedelta(days=(endServerDay-openServerDay))
|
| | | endDateStr = "%d-%d-%d" % (endServerDateTime.year, endServerDateTime.month, endServerDateTime.day)
|
| | | |
| | | startDate = datetime.datetime.strptime("%s 00:00:00" % (startDateStr), ChConfig.TYPE_Time_Format)
|
| | | endDate = datetime.datetime.strptime("%s 23:59:00" % (endDateStr), ChConfig.TYPE_Time_Format)
|
| | | if serverTime < startDate or serverTime > endDate:
|
| | | GameWorld.DebugLog(" 不在上架日期内,不处理!")
|
| | | continue
|
| | | |
| | | if not startTimeStr:
|
| | | startTimeStr = "00:00"
|
| | | if not endTimeStr:
|
| | | endTimeStr = "23:59"
|
| | | startDatetime = datetime.datetime.strptime("%s %s:00" % (curDateStr, startTimeStr), ChConfig.TYPE_Time_Format)
|
| | | endDatetime = datetime.datetime.strptime("%s %s:00" % (curDateStr, endTimeStr), ChConfig.TYPE_Time_Format)
|
| | | if serverTime >= endDatetime:
|
| | | GameWorld.DebugLog(" 已超过今日的上架时间段,不处理!")
|
| | | continue
|
| | | if serverTime > startDatetime:
|
| | | startDatetime = curDateTime
|
| | | |
| | | addAuctionItemDatetimeList = []
|
| | | nextAddAuctionItemDatetime = startDatetime
|
| | | for _ in xrange(auctionCount):
|
| | | if len(randMinuteRange) == 2:
|
| | | nextAddMinutes = random.randint(randMinuteRange[0], randMinuteRange[1])
|
| | | elif len(randMinuteRange) == 1:
|
| | | nextAddMinutes = randMinuteRange[0]
|
| | | else:
|
| | | continue
|
| | | nextAddAuctionItemDatetime += datetime.timedelta(minutes=nextAddMinutes)
|
| | | if nextAddAuctionItemDatetime > endDatetime:
|
| | | break
|
| | | GameWorld.DebugLog(" 添加上架系统拍品时间: nextAddMinutes=%s %s" % (nextAddMinutes, nextAddAuctionItemDatetime))
|
| | | addAuctionItemDatetimeList.append(nextAddAuctionItemDatetime)
|
| | | |
| | | # 动态补充拍品模式
|
| | | if replenishAuctionCount:
|
| | | GameWorld.DebugLog(" 添加动态补充系统拍品计划: %s" % replenishAuctionCount)
|
| | | # 指定上架拍品模式
|
| | | elif addAuctionItemDatetimeList:
|
| | | GameWorld.DebugLog(" 添加上架系统拍品时间计划: %s" % addAuctionItemDatetimeList)
|
| | | else:
|
| | | continue
|
| | | addSystemAuctionItemInfo.append([cfgID, ipyData, startDatetime, endDatetime, addAuctionItemDatetimeList])
|
| | | |
| | | AuctionSystemItem = IpyGameDataPY.SetConfigEx(key, [reloadSign, addSystemAuctionItemInfo])
|
| | | GameWorld.Log("本日系统拍品信息加载完毕!reloadSign=%s" % (reloadSign))
|
| | | GameWorld.Log("本日系统拍品上架时间信息: %s" % addSystemAuctionItemInfo)
|
| | | GameWorld.Log("=============================================================")
|
| | | return AuctionSystemItem[1]
|
| | |
|
| | | def OnAuctionItemMinuteProcess(tick):
|
| | | ## 拍卖行拍品定时处理,每整分钟触发一次
|
| | | |
| | | # 这里时间需精确到分钟,不然后面的比较会匹配不到
|
| | | curDateTime = GameWorld.GetServerTime()
|
| | | curDateTime = datetime.datetime.strptime("%d-%d-%d %d:%d:00" % (curDateTime.year, curDateTime.month, curDateTime.day,
|
| | | curDateTime.hour, curDateTime.minute), ChConfig.TYPE_Time_Format)
|
| | | |
| | | randMailKey = ""
|
| | | sysAuctionItemListDict = IpyGameDataPY.GetConfigEx("SysWaitAuctionItemListDict") # 系统等待上架的拍品列表字典 {cfgID:[待上架拍品列表], ...}
|
| | | if not sysAuctionItemListDict:
|
| | | sysAuctionItemListDict = {}
|
| | | |
| | | 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
|
| | | |
| | | 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:
|
| | | playerIDList = []
|
| | | addItemList = []
|
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for i in xrange(playerManager.GetActivePlayerCount()):
|
| | | player = playerManager.GetActivePlayerAt(i)
|
| | | if player == None:
|
| | | continue
|
| | | if PlayerControl.GetIsTJG(player):
|
| | | continue
|
| | | playerIDList.append(player.GetPlayerID())
|
| | | PlayerCompensation.SendMailByKey(randMailKey, playerIDList, addItemList)
|
| | | |
| | | return
|
| | |
|
| | | def __DoSysWaitAddAuctionItem(tick):
|
| | | SysWaitAuctionItemListDict = IpyGameDataPY.GetConfigEx("SysWaitAuctionItemListDict") # 系统等待上架的拍品列表
|
| | | if not SysWaitAuctionItemListDict:
|
| | | return
|
| | | |
| | | 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):
|
| | | ## 拍卖行拍品定时处理,每秒触发一次
|
| | | |
| | | __DoSysBuyoutItemByTime(curTime)
|
| | | |
| | | __DoSysWaitAddAuctionItem(tick)
|
| | | |
| | | allAuctionItemByEndTimeList = PyDataManager.GetAuctionItemManager().allAuctionItemByEndTimeList
|
| | | if not allAuctionItemByEndTimeList:
|
| | | return
|
| | |
| | | __MoveFamilyAuctionItemToWorld(moveToWorldItemList)
|
| | | return
|
| | |
|
| | | def __DoSysBuyoutItemByTime(curTime):
|
| | | ## 系统一口价拍品
|
| | | |
| | | sysBuyoutItemByTimeList = PyDataManager.GetAuctionItemManager().sysBuyoutItemByTimeList
|
| | | if not sysBuyoutItemByTimeList:
|
| | | return
|
| | | |
| | | sysAuctionItemList = []
|
| | | color = 4 # 固定橙色
|
| | | isSuit = 0 # 固定非套装 |
| | | star = 0 # 固定0星
|
| | | |
| | | endItemList = [] # 结束竞价的拍品列表
|
| | | doCount = len(sysBuyoutItemByTimeList)
|
| | | while doCount > 0 and sysBuyoutItemByTimeList:
|
| | | doCount -= 1
|
| | | auctionItem = sysBuyoutItemByTimeList[0]
|
| | | if curTime <= auctionItem.SysBuyTime:
|
| | | break
|
| | | sysBuyoutItemByTimeList.pop(0)
|
| | | |
| | | if auctionItem.BidderPrice or auctionItem.BidderID:
|
| | | continue
|
| | | |
| | | classLV = auctionItem.ItemClassLV
|
| | | if not classLV:
|
| | | continue |
| | | |
| | | itemID = auctionItem.ItemID
|
| | | ipyData = IpyGameDataPY.GetIpyGameData("AuctionItem", itemID)
|
| | | if not ipyData:
|
| | | continue
|
| | | buyoutPrice = ipyData.GetBuyoutPrice()
|
| | | if not buyoutPrice:
|
| | | continue
|
| | | |
| | | buyoutPrice *= auctionItem.Count
|
| | | auctionItem.BidderPrice = buyoutPrice # 没人竞价的系统直接一口价回收
|
| | | endItemList.append(auctionItem)
|
| | | |
| | | # 生成系统补上架的装备信息
|
| | | randPlaceList = IpyGameDataPY.GetFuncEvalCfg("AuctionItemSystem", 4)
|
| | | if not randPlaceList:
|
| | | curPlace = itemID % 1000 / 10 # 倒数2、3位代表部位
|
| | | placeList = [curPlace]
|
| | | else:
|
| | | placeList = randPlaceList
|
| | | |
| | | totalPlayerCount = 0
|
| | | jobWeightList = []
|
| | | openJobList = IpyGameDataPY.GetFuncEvalCfg("OpenJob", 1)
|
| | | for job in openJobList:
|
| | | jobPlayerCount = len(PyGameData.g_onedayJobPlayerLoginoffTimeDict.get(job, {}))
|
| | | jobPlayerCount = max(1, jobPlayerCount) # 人数默认至少1个
|
| | | totalPlayerCount += jobPlayerCount
|
| | | jobWeightList.append([jobPlayerCount, job])
|
| | | GameWorld.DebugLog("职业人数: job=%s,count=%s" % (job, jobPlayerCount))
|
| | | |
| | | maxJobPer = IpyGameDataPY.GetFuncCfg("AuctionItemSystem", 3) # 单职业最大百分比
|
| | | if maxJobPer and maxJobPer < 100 and totalPlayerCount:
|
| | | minJobPer = 100 - maxJobPer # 单职业至少百分比
|
| | | for jobWeightInfo in jobWeightList:
|
| | | jobPlayerCount = jobWeightInfo[0]
|
| | | jobPer = int(jobPlayerCount * 100.0 / totalPlayerCount)
|
| | | jobPer = min(max(minJobPer, jobPer), maxJobPer)
|
| | | jobWeightInfo[0] = jobPer
|
| | | GameWorld.DebugLog("随机上架职业装备比重: jobWeightList=%s" % jobWeightList)
|
| | | job = GameWorld.GetResultByWeightList(jobWeightList)
|
| | | itemJobList = [job] if job != None else openJobList
|
| | | sysAuctionItemList.append([classLV, color, placeList, isSuit, star, itemJobList])
|
| | | |
| | | if not endItemList:
|
| | | return
|
| | | |
| | | __EndAuctionItem(endItemList, "SysBuyout")
|
| | | |
| | | # 系统回收拍品后立即按规则补上架拍品
|
| | | if sysAuctionItemList:
|
| | | DoAddSystemAuctionItem(sysAuctionItemList)
|
| | | |
| | | return
|
| | |
|
| | |
|
| | | def __MoveFamilyAuctionItemToWorld(auctionItemList):
|
| | | ## 仙盟拍品转移到全服
|
| | | if not auctionItemList:
|
| | |
| | |
|
| | | auctionItemMgr.allAuctionItemByEndTimeList.append(auctionItem)
|
| | | auctionItemMgr.worldAuctionItemList.append(auctionItem)
|
| | | __OnCalcWorldAuctionItemCount(auctionItem, 1)
|
| | | notifyWorldAddItemList.append([itemGUID, itemID, playerID])
|
| | |
|
| | | AddAuctionRecord(auctionItem, AuctionRecordResult_MoveToWorld)
|
| | |
| | | if isSortWorldItem:
|
| | | auctionItemMgr.worldAuctionItemList.sort(key=operator.attrgetter("Sortpriority", "AddTime"))
|
| | | auctionItemMgr.worldAuctionItemQueryDict = {} # 重置全服拍品条件查询,下次有玩家查询时再重新刷新
|
| | | auctionItemMgr.sysBuyoutItemByTimeList.sort(key=operator.attrgetter("SysBuyTime"))
|
| | | return
|
| | |
|
| | | def __EndAuctionItem(endItemList, endEvent):
|
| | |
| | | bidderPrice = auctionItem.BidderPrice # 当前竞价,有人竞价的话代表竞拍成功
|
| | | endType = ""
|
| | | # 有人竞价,成交
|
| | | if bidderID and bidderPrice:
|
| | | if bidderPrice:
|
| | | endType = "OK"
|
| | |
|
| | | # 竞拍成功邮件,发放物品
|
| | | paramList = [bidderPrice]
|
| | | detail = {"ItemGUID":itemGUID}
|
| | | addItemList = [{"ItemID":itemID, "Count":itemCount, "IsAuctionItem":False, "UserData":auctionItem.UserData}]
|
| | | PlayerCompensation.SendMailByKey("PaimaiMail3", [bidderID], addItemList, paramList, detail=detail)
|
| | | AddAuctionRecord(auctionItem, AuctionRecordResult_BidOK)
|
| | | if bidderID:
|
| | | paramList = [bidderPrice]
|
| | | detail = {"ItemGUID":itemGUID}
|
| | | addItemList = [{"ItemID":itemID, "Count":itemCount, "IsAuctionItem":False, "UserData":auctionItem.UserData}]
|
| | | PlayerCompensation.SendMailByKey("PaimaiMail3", [bidderID], addItemList, paramList, detail=detail)
|
| | | AddAuctionRecord(auctionItem, AuctionRecordResult_BidOK)
|
| | |
|
| | | # 拍卖成功收益,都以玩家收益向上取整
|
| | | if familyID and auctionItem.FamilyPlayerIDInfo:
|
| | |
| | |
|
| | | # 仙盟拍品收益邮件
|
| | | detail = {"ItemGUID":itemGUID, "ItemID":itemID, "Count":itemCount, "BidderPrice":bidderPrice, "FamilyPlayerIDList":familyPlayerIDList}
|
| | | paramList = [itemID, itemID, auctionItem.BidderName, bidderPrice, taxRate, giveGoldAverage, personMaxRate]
|
| | | PlayerCompensation.SendMailByKey("PaimaiMail6", familyPlayerIDList, [], paramList, gold=giveGoldAverage, |
| | | paramList = [itemID, itemID, bidderPrice, taxRate, giveGoldAverage, personMaxRate]
|
| | | PlayerCompensation.SendMailByKey("PaimaiMail8", familyPlayerIDList, [], paramList, goldPaper=giveGoldAverage, |
| | | detail=detail, moneySource=ChConfig.Def_GiveMoney_AuctionGain)
|
| | | else:
|
| | | GameWorld.ErrLog("仙盟拍品没有人获得收益!familyID=%s,itemID=%s,itemGUID=%s" % (familyID, itemID, itemGUID))
|
| | |
| | |
|
| | | # 个人拍卖收益邮件
|
| | | detail = {"ItemGUID":itemGUID, "ItemID":itemID, "Count":itemCount, "BidderPrice":bidderPrice}
|
| | | paramList = [itemID, itemID, auctionItem.BidderName, bidderPrice, taxRate, givePlayerGold]
|
| | | PlayerCompensation.SendMailByKey("PaimaiMail5", [playerID], [], paramList, gold=givePlayerGold, |
| | | paramList = [itemID, itemID, bidderPrice, taxRate, givePlayerGold]
|
| | | PlayerCompensation.SendMailByKey("PaimaiMail7", [playerID], [], paramList, goldPaper=givePlayerGold, |
| | | detail=detail, moneySource=ChConfig.Def_GiveMoney_AuctionGain)
|
| | | |
| | | else:
|
| | | GameWorld.Log("系统拍品成交: itemGUID=%s,itemID=%s" % (itemGUID, itemID))
|
| | |
|
| | | AddAuctionRecord(auctionItem, AuctionRecordResult_SellOK)
|
| | |
|
| | | ipyData = IpyGameDataPY.GetIpyGameData("AuctionItem", itemID)
|
| | | if ipyData and ipyData.GetNeedWorldNotify():
|
| | | PlayerControl.WorldNotify(0, "Paimai6", [auctionItem.BidderName, bidderID, auctionItem.AuctionType, bidderPrice, itemID])
|
| | | #策划需求屏蔽掉成交广播
|
| | | #ipyData = IpyGameDataPY.GetIpyGameData("AuctionItem", itemID)
|
| | | #if ipyData and ipyData.GetNeedWorldNotify():
|
| | | # PlayerControl.WorldNotify(0, "Paimai6", [auctionItem.BidderName, bidderID, auctionItem.AuctionType, bidderPrice, itemID])
|
| | | else:
|
| | | # 仙盟拍品回收
|
| | | if familyID:
|
| | | endType = "Recycle"
|
| | | AddAuctionRecord(auctionItem, AuctionRecordResult_Recycle)
|
| | | # 个人拍品流拍,物品返还
|
| | | else:
|
| | | elif playerID:
|
| | | endType = "Return"
|
| | |
|
| | | # 流拍返还物品邮件
|
| | | # 返还物品邮件
|
| | | paramList = []
|
| | | detail = {"ItemGUID":itemGUID}
|
| | | addItemList = [{"ItemID":itemID, "Count":itemCount, "IsAuctionItem":False, "UserData":auctionItem.UserData}]
|
| | | PlayerCompensation.SendMailByKey("PaimaiMail4", [playerID], addItemList, paramList, detail=detail)
|
| | | |
| | | AddAuctionRecord(auctionItem, AuctionRecordResult_SellFail)
|
| | | addItemList = [{"ItemID":itemID, "Count":itemCount, "IsAuctionItem":True, "UserData":auctionItem.UserData}]
|
| | | # 下架
|
| | | if endEvent == "Unsell":
|
| | | PlayerCompensation.SendMailByKey("PaimaiMail9", [playerID], addItemList, paramList, detail=detail)
|
| | | AddAuctionRecord(auctionItem, AuctionRecordResult_Unsell)
|
| | | else:
|
| | | PlayerCompensation.SendMailByKey("PaimaiMail4", [playerID], addItemList, paramList, detail=detail)
|
| | | AddAuctionRecord(auctionItem, AuctionRecordResult_SellFail)
|
| | | else:
|
| | | endType = "SystemDelete"
|
| | | GameWorld.Log("系统拍品流拍: itemGUID=%s,itemID=%s" % (itemGUID, itemID))
|
| | |
|
| | | drDict = {"AuctionItemInfo":__GetAuctionItemDRDict(auctionItem), "EndType":endType, "EndEvent":endEvent}
|
| | | DR_AuctionHouse(None, "EndAuctionItem", drDict)
|
| | |
| | |
|
| | | if auctionItem in auctionItemMgr.worldAuctionItemList:
|
| | | auctionItemMgr.worldAuctionItemList.remove(auctionItem)
|
| | | __OnCalcWorldAuctionItemCount(auctionItem, -1)
|
| | |
|
| | | for queryItemList in auctionItemMgr.worldAuctionItemQueryDict.values():
|
| | | if auctionItem in queryItemList:
|
| | |
| | | if auctionItem in familyItemList:
|
| | | familyItemList.remove(auctionItem)
|
| | |
|
| | | if auctionItem in auctionItemMgr.sysBuyoutItemByTimeList:
|
| | | auctionItemMgr.sysBuyoutItemByTimeList.remove(auctionItem)
|
| | | |
| | | for nowBiddingItemList in auctionItemMgr.nowBiddingAuctionItemDict.values():
|
| | | if auctionItem in nowBiddingItemList:
|
| | | nowBiddingItemList.remove(auctionItem)
|
| | |
| | |
|
| | | return
|
| | |
|
| | | # 下架拍品
|
| | | elif queryType == "UnsellAuctionItem":
|
| | | itemGUID = queryData[0]
|
| | | __DoUnsellAuctionItem(curPlayer, itemGUID)
|
| | | return
|
| | | |
| | | elif queryType == "ClearAuctionItem":
|
| | | __DoGMClearAuctionItem(curPlayer)
|
| | | return
|
| | |
| | | notifyAddItemList = [] # 新增拍品通知 [[itemGUID, itemID, playerID], ...]
|
| | | notifyFamilyAddItemDict = {} # 新增仙盟拍品通知 {familyID:[auctionItem, ...], ...}
|
| | | for playerID, familyID, familyPlayerIDList, itemData in addAuctionItemList:
|
| | | if not playerID and not familyID:
|
| | | continue
|
| | | #系统拍品玩家ID、仙盟ID都为0,可上架,这里不再限制
|
| | | #if not playerID and not familyID:
|
| | | # continue
|
| | |
|
| | | auctionItem = __DoAddAuctionItem(curPlayer, playerID, familyID, familyPlayerIDList, itemData)
|
| | | if not auctionItem:
|
| | |
| | | auctionItem.UserDataLen = len(auctionItem.UserData)
|
| | | auctionItem.FamilyPlayerIDInfo = str(familyPlayerIDList)
|
| | | auctionItem.FamilyPlayerIDLen = len(auctionItem.FamilyPlayerIDInfo)
|
| | | |
| | | auctionItem.AuctionType = AuctionType_Family if familyID else AuctionType_World
|
| | | GameWorld.Log("上架拍品: playerID=%s,familyID=%s,itemID=%s,auctionType=%s" % (playerID, familyID, itemID, auctionItem.AuctionType))
|
| | | |
| | | if not __InitAuctionItemAttrEx(auctionItem):
|
| | | return
|
| | |
|
| | |
| | | auctionItemMgr.allAuctionItemByEndTimeList.append(auctionItem)
|
| | |
|
| | | if familyID:
|
| | | auctionItem.AuctionType = AuctionType_Family
|
| | | familyItemList = auctionItemMgr.familyAuctionItemDict.get(familyID, [])
|
| | | familyItemList.append(auctionItem)
|
| | | auctionItemMgr.familyAuctionItemDict[familyID] = familyItemList
|
| | | else:
|
| | | auctionItem.AuctionType = AuctionType_World
|
| | | auctionItemMgr.worldAuctionItemList.append(auctionItem)
|
| | | __OnCalcWorldAuctionItemCount(auctionItem, 1)
|
| | |
|
| | | # 添加进我的拍卖
|
| | | if playerID:
|
| | |
| | | if infoPack:
|
| | | infoPack.AddCount = len(infoPack.AddAuctionItemList)
|
| | | NetPackCommon.SendFakePack(player, infoPack)
|
| | | return
|
| | |
|
| | | def __DoUnsellAuctionItem(curPlayer, itemGUID):
|
| | | ## 下架拍品
|
| | | auctionItem = GetAuctionItem(itemGUID)
|
| | | if not auctionItem:
|
| | | # 拍品不存在
|
| | | PlayerControl.NotifyCode(curPlayer, "Paimai3")
|
| | | return
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | itemID = auctionItem.ItemID
|
| | | if auctionItem.FamilyID:
|
| | | GameWorld.ErrLog("仙盟拍品无法下架!itemGUID=%s,itemID=%s,itemFamilyID=%s" |
| | | % (itemGUID, itemID, auctionItem.FamilyID), playerID)
|
| | | return
|
| | | if auctionItem.PlayerID != playerID:
|
| | | GameWorld.ErrLog("不是玩家自己的拍品无法下架!itemGUID=%s,itemID=%s,itemPlayerID=%s" |
| | | % (itemGUID, itemID, auctionItem.PlayerID), playerID)
|
| | | return
|
| | | if auctionItem.BidderPrice:
|
| | | # 竞价中的拍品不能下架
|
| | | PlayerControl.NotifyCode(curPlayer, "Paimai9")
|
| | | return
|
| | | |
| | | __EndAuctionItem([auctionItem], "Unsell")
|
| | | return
|
| | |
|
| | | def __DoPlayerBidAuctionItem(curPlayer, itemGUID, biddingPrice, tick, isOnlyCheck):
|
| | |
| | | if isBuyout:
|
| | | # 竞拍失败,仅通知
|
| | | paramList = [itemID, itemID, lastBidderPrice]
|
| | | PlayerCompensation.SendMailByKey("PaimaiMail2", [lastBidderID], [], paramList, gold=lastBidderPrice, |
| | | PlayerCompensation.SendMailByKey("PaimaiMail2", [lastBidderID], [], paramList, goldPaper=lastBidderPrice, |
| | | detail=detail, moneySource=ChConfig.Def_GiveMoney_AuctionBidReturn)
|
| | | else:
|
| | | # 竞拍失败,可继续竞价邮件
|
| | | paramList = [itemID, itemID, lastBidderPrice, itemGUID]
|
| | | PlayerCompensation.SendMailByKey("PaimaiMail1", [lastBidderID], [], paramList, gold=lastBidderPrice, |
| | | PlayerCompensation.SendMailByKey("PaimaiMail1", [lastBidderID], [], paramList, goldPaper=lastBidderPrice, |
| | | detail=detail, moneySource=ChConfig.Def_GiveMoney_AuctionBidReturn)
|
| | | AddAuctionRecord(auctionItem, AuctionRecordResult_BidFail)
|
| | |
|
| | |
| | | GameWorld.DebugLog("玩家竞价拍品: itemGUID=%s,itemID=%s,isBuyout=%s,lastBidderID=%s,lastBidderPrice=%s,bidderIDInfo=%s"
|
| | | % (itemGUID, itemID, isBuyout, lastBidderID, lastBidderPrice, auctionItem.BidderIDInfo), playerID)
|
| | |
|
| | | if auctionItem in auctionItemMgr.sysBuyoutItemByTimeList:
|
| | | auctionItemMgr.sysBuyoutItemByTimeList.remove(auctionItem)
|
| | | #GameWorld.DebugLog("拍品有人竞价了,移除系统一口价拍品列表!")
|
| | | |
| | | if isBuyout:
|
| | | __EndAuctionItem([auctionItem], "Buyout")
|
| | | else:
|
| | |
| | | for i, auctionItem in enumerate(allAuctionItemByEndTimeList):
|
| | | GameWorld.DebugLog(" i=%s, %s" % (i, __GetAuctionItemDRDict(auctionItem)))
|
| | |
|
| | | GameWorld.DebugLog("AllDict总拍品数: =%s" % len(auctionItemMgr.allAuctionItemDict))
|
| | | GameWorld.DebugLog("AllDict总拍品数: %s" % len(auctionItemMgr.allAuctionItemDict))
|
| | |
|
| | | GameWorld.DebugLog("全服拍品个数: =%s" % len(auctionItemMgr.worldAuctionItemList))
|
| | | GameWorld.DebugLog("全服拍品个数: %s" % len(auctionItemMgr.worldAuctionItemList))
|
| | | |
| | | GameWorld.DebugLog("系统一口价拍品个数: %s" % len(auctionItemMgr.sysBuyoutItemByTimeList))
|
| | | |
| | | for familyID, familyItemList in auctionItemMgr.familyAuctionItemDict.items():
|
| | | GameWorld.DebugLog("仙盟拍品个数: familyID=%s, %s" % (familyID, len(familyItemList)))
|
| | |
|
| | |
| | | GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_AddFamilyAuctionItem, [mapID, familyAuctionItemDict])
|
| | | return
|
| | |
|
| | | def DoAddSystemAuctionItem(sysAuctionItemList):
|
| | | ''' 上架系统拍品
|
| | | @param sysAuctionItemList: [物品ID, [阶,颜色,[部位, ...],是否套装,星级,[可选参数职业, ...]], ...]
|
| | | '''
|
| | | mapID = ChConfig.Def_FBMapID_MainCity
|
| | | GameWorld.Log("发送地图上架系统拍品: mapID=%s, %s" % (mapID, sysAuctionItemList))
|
| | | GameWorld.SendMapServerMsgEx(ShareDefine.Def_Notify_WorldKey_AddSystemAuctionItem, [mapID, sysAuctionItemList])
|
| | | return
|
| | |
|