From 71ea04a0d2f445b3b3947175bacc6829a5996af9 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期一, 25 三月 2019 21:26:48 +0800
Subject: [PATCH] 6385 【后端】【2.0】五行灵根开发(修复洗点报错 )
---
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/AuctionHouse.py | 1366 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 1,320 insertions(+), 46 deletions(-)
diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/AuctionHouse.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/AuctionHouse.py
index bcc347c..f4972cb 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/AuctionHouse.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/AuctionHouse.py
@@ -6,66 +6,1340 @@
#
# @todo:拍卖行
# @author hxp
-# @date 2019-02-19
+# @date 2019-03-04
# @version 1.0
#
# 详细描述: 拍卖行
#
#-------------------------------------------------------------------------------
-#"""Version = 2019-02-19 12:00"""
+#"""Version = 2019-03-04 17:00"""
#-------------------------------------------------------------------------------
-import CommFunc
import GameWorld
+import PyDataManager
+import PlayerControl
+import DataRecordPack
+import PyGameDataStruct
+import PlayerCompensation
+import ChPyNetSendPack
+import IpyGameDataPY
+import NetPackCommon
+import PlayerBourse
+import PlayerFamily
+import ChConfig
+import operator
+import time
+import math
+import json
-#拍卖记录管理,注意该类只处理数据逻辑,功能相关逻辑不要写在该类,不然重读脚本不会生效
-class AuctionRecordManager(object):
-
- def __init__(self):
+# 拍卖记录类型定义
+AuctionRecordTypeList = (
+AuctionRecordType_MyAuction, # 我的拍品
+AuctionRecordType_FamilyAuction, # 仙盟拍品
+AuctionRecordType_MyBid, # 我的竞拍
+) = range(3)
+
+# 拍卖记录结果定义
+AuctionRecordResultList = (
+AuctionRecordResult_SellFail, # 流拍
+AuctionRecordResult_SellOK, # 拍卖成交
+AuctionRecordResult_Recycle, # 系统回收
+AuctionRecordResult_BidOK, # 竞价成功
+AuctionRecordResult_BidFail, # 竞价失败
+AuctionRecordResult_MoveToWorld, # 仙盟拍品转移到全服拍品
+) = range(6)
+
+# 当前拍品归类 0-全服拍品 1-仙盟私有拍品
+AuctionType_World = 0
+AuctionType_Family = 1
+
+#拍卖行状态开关
+def GetAuctionHouseState(): return PlayerBourse.GetOpenState()
+
+def OnPlayerLogin(curPlayer):
+ Sync_PlayerAuctionItemInfo(curPlayer)
+ Sync_FamilyAuctionItemInfo(curPlayer, curPlayer.GetFamilyID())
+ Sync_PlayerBiddingItemInfo(curPlayer)
+ Sync_PlayerAttentionAuctionItemID(curPlayer, False)
+ return
+
+def OnPlayerLeaveServer(curPlayer):
+ playerID = curPlayer.GetPlayerID()
+ auctionItemMgr = PyDataManager.GetAuctionItemManager()
+ auctionItemMgr.myAttentionItemDict.pop(playerID, None)
+ return
+
+##--------------------------------------- 拍卖记录 -------------------------------------------------
+def GetMyAuctionItemRecord(playerID):
+ ## 获取我的拍品记录
+ return PyDataManager.GetAuctionRecordManager().myAuctionItemRecordDict.get(playerID, [])
+
+def GetMyBiddingItemRecord(playerID):
+ ## 获取我的竞拍记录
+ return PyDataManager.GetAuctionRecordManager().myBidItemRecordDict.get(playerID, [])
+
+def GetFamilyAuctionItemRecord(familyID):
+ ## 获取仙盟拍品记录
+ return PyDataManager.GetAuctionRecordManager().familyAuctionItemRecordDict.get(familyID, [])
+
+def AddAuctionRecord(auctionItem, recordResult):
+ ''' 添加拍卖行记录
+ @param auctionItem: 相关的拍品实例
+ @param recordResult: 记录结果 0-流拍 1-拍卖成交 2-回收 3-竞价成功 4-竞价失败
+ '''
+ if not auctionItem:
return
- ## ===========================================================================================
+ playerID, familyID, bidderID = auctionItem.PlayerID, auctionItem.FamilyID, auctionItem.BidderID
+ recordPlayerID, recordFamilyID = 0, 0
- # 保存数据 存数据库和realtimebackup
- def GetSaveData(self):
- savaData = ""
- cntData = ""
- cnt = 0
-
- GameWorld.Log("Save AuctionRecord count :%s" % cnt)
- return CommFunc.WriteDWORD(cntData, cnt) + savaData
-
- # 从数据库载入数据
- def LoadPyGameData(self, datas, pos, dataslen):
- cnt, pos = CommFunc.ReadDWORD(datas, pos)
- GameWorld.Log("Load AuctionRecord count :%s" % cnt)
-
- return pos
-
-
-#拍卖物品管理,注意该类只处理数据逻辑,功能相关逻辑不要写在该类,不然重读脚本不会生效
-class AuctionItemManager(object):
-
- def __init__(self):
+ if recordResult in [AuctionRecordResult_BidOK, AuctionRecordResult_BidFail]:
+ recordType = AuctionRecordType_MyBid
+ recordPlayerID = bidderID
+ else:
+ if familyID:
+ recordType = AuctionRecordType_FamilyAuction
+ recordFamilyID = familyID
+ else:
+ recordType = AuctionRecordType_MyAuction
+ recordPlayerID = playerID
+
+ if not recordPlayerID and not recordFamilyID:
return
- ## ===========================================================================================
+ newRecordData = PyGameDataStruct.tagDBAuctionRecord()
+ newRecordData.ItemGUID = auctionItem.ItemGUID
+ newRecordData.PlayerID = recordPlayerID
+ newRecordData.FamilyID = recordFamilyID
+ newRecordData.RecordType = recordType
+ newRecordData.RecordResult = recordResult
+ newRecordData.RecordTime = GameWorld.GetCurrentDataTimeStr()
+ newRecordData.BidderPrice = auctionItem.BidderPrice
+ newRecordData.BidderName = auctionItem.BidderName
+ newRecordData.ItemID = auctionItem.ItemID
+ newRecordData.Count = auctionItem.Count
+ newRecordData.UserData = auctionItem.UserData
+ newRecordData.UserDataLen = auctionItem.UserDataLen
+ AddNewAuctionRecord(newRecordData)
- # 保存数据 存数据库和realtimebackup
- def GetSaveData(self):
- savaData = ""
- cntData = ""
- cnt = 0
-
- GameWorld.Log("Save AuctionItem count :%s" % cnt)
- return CommFunc.WriteDWORD(cntData, cnt) + savaData
-
- # 从数据库载入数据
- def LoadPyGameData(self, datas, pos, dataslen):
- cnt, pos = CommFunc.ReadDWORD(datas, pos)
- GameWorld.Log("Load AuctionItem count :%s" % cnt)
-
- return pos
-
+ if recordFamilyID:
+ Sync_PlayerAuctionRecordInfo(None, recordType, newRecordData, recordFamilyID)
+ elif recordPlayerID:
+ recordPlayer = GameWorld.GetPlayerManager().FindPlayerByID(recordPlayerID)
+ if recordPlayer and not PlayerControl.GetIsTJG(recordPlayer):
+ Sync_PlayerAuctionRecordInfo(recordPlayer, recordType, newRecordData)
+ return
+def AddNewAuctionRecord(newRecordData):
+ playerID = newRecordData.PlayerID
+ familyID = newRecordData.FamilyID
+ recordType = newRecordData.RecordType
+ if recordType == AuctionRecordType_MyAuction:
+ keyID = playerID
+ recordDict = PyDataManager.GetAuctionRecordManager().myAuctionItemRecordDict
+ elif recordType == AuctionRecordType_FamilyAuction:
+ keyID = familyID
+ recordDict = PyDataManager.GetAuctionRecordManager().familyAuctionItemRecordDict
+ elif recordType == AuctionRecordType_MyBid:
+ keyID = playerID
+ recordDict = PyDataManager.GetAuctionRecordManager().myBidItemRecordDict
+ else:
+ return
+ recordList = recordDict.get(keyID, [])
+ maxCount = min(50, IpyGameDataPY.GetFuncCfg("AuctionHouse", 3))
+ if len(recordList) >= maxCount:
+ del recordList[0]
+ recordList.append(newRecordData)
+ recordDict[keyID] = recordList
+ return
+##-------------------------------------- 拍卖关注 ------------------------------------------------
+
+def GetPlayerAuctionAttention(attentionMgr, playerID):
+ ## 获取玩家关注的物品ID列表
+ if playerID not in attentionMgr.playerAttentionDict:
+ return []
+ attentionObj = attentionMgr.playerAttentionDict[playerID]
+ attentionItemIDList = attentionObj.AttentionItemIDList
+ return attentionItemIDList
+
+def AddPlayerAuctionAttention(attentionMgr, playerID, itemID):
+ ## 添加玩家关注的物品ID
+ if playerID not in attentionMgr.playerAttentionDict:
+ dbData = PyGameDataStruct.tagDBAuctionAttention()
+ dbData.PlayerID = playerID
+ __InitAuctionAttentionAttrEx(dbData)
+ attentionMgr.playerAttentionDict[playerID] = dbData
+ attentionObj = attentionMgr.playerAttentionDict[playerID]
+ attentionItemIDList = attentionObj.AttentionItemIDList
+ if len(attentionItemIDList) >= IpyGameDataPY.GetFuncCfg("AuctionHouse", 5):
+ GameWorld.DebugLog("关注拍品数达到上限!", playerID)
+ return
+ if itemID in attentionItemIDList:
+ return True
+ attentionItemIDList.append(itemID)
+ attentionObj.AttentionInfo = str(attentionItemIDList)
+ attentionObj.AttentionLen = len(attentionObj.AttentionInfo)
+ return True
+
+def DelPlayerAuctionAttention(attentionMgr, playerID, itemID):
+ ## 删除玩家关注的物品ID
+ if playerID not in attentionMgr.playerAttentionDict:
+ return
+ attentionObj = attentionMgr.playerAttentionDict[playerID]
+ attentionItemIDList = attentionObj.AttentionItemIDList
+ if itemID not in attentionItemIDList:
+ return
+ attentionItemIDList.remove(itemID)
+ attentionObj.AttentionInfo = str(attentionItemIDList)
+ attentionObj.AttentionLen = len(attentionObj.AttentionInfo)
+ return True
+
+def OnLoadAuctionAttentionDataEx(attentionData):
+ ## 加载拍卖关注表时附加处理
+ __InitAuctionAttentionAttrEx(attentionData)
+ return
+
+def __InitAuctionAttentionAttrEx(attentionData):
+ ## 初始化拍卖关注实例附加属性
+ setattr(attentionData, "AttentionItemIDList", [] if not attentionData.AttentionInfo else json.loads(attentionData.AttentionInfo))
+ return
+
+##-------------------------------------------------------------------------------------------------
+
+def OnLoadAuctionItemDataEx(dbData):
+ ## 加载拍卖物品表时附加处理
+ __InitAuctionItemAttrEx(dbData)
+ playerID = dbData.PlayerID
+ familyID = dbData.FamilyID
+ bidderID = dbData.BidderID
+
+ pyAuctionItemMgr = PyDataManager.GetAuctionItemManager()
+ pyAuctionItemMgr.allAuctionItemByEndTimeList.append(dbData)
+
+ if dbData.AuctionType == AuctionType_World:
+ pyAuctionItemMgr.worldAuctionItemList.append(dbData)
+
+ if familyID:
+ familyItemList = pyAuctionItemMgr.familyAuctionItemDict.get(familyID, [])
+ familyItemList.append(dbData)
+ pyAuctionItemMgr.familyAuctionItemDict[familyID] = familyItemList
+
+ if playerID:
+ myItemList = pyAuctionItemMgr.myAuctionItemDict.get(playerID, [])
+ myItemList.append(dbData)
+ pyAuctionItemMgr.myAuctionItemDict[playerID] = myItemList
+
+ if str(playerID) in dbData.BidderIDInfo:
+ if playerID == bidderID:
+ nowBidItemList = pyAuctionItemMgr.nowBiddingAuctionItemDict.get(playerID, [])
+ nowBidItemList.append(dbData)
+ pyAuctionItemMgr.nowBiddingAuctionItemDict[playerID] = nowBidItemList
+ else:
+ hisBidItemList = pyAuctionItemMgr.hisBiddingAuctionItemDict.get(playerID, [])
+ hisBidItemList.append(dbData)
+ pyAuctionItemMgr.hisBiddingAuctionItemDict[playerID] = hisBidItemList
+
+ return
+
+def OnLoadAuctionItemDataOK():
+ ## 加载拍卖物品表完成后的处理
+ __SortAuctionitem()
+ return
+
+def __InitAuctionItemAttrEx(auctionItem, ipyData=None):
+ ## 初始化拍品实例附加属性
+ if not ipyData:
+ ipyData = IpyGameDataPY.GetIpyGameData("AuctionItem", auctionItem.ItemID)
+ setattr(auctionItem, "Sortpriority", 99999 - (0 if not ipyData else ipyData.GetSortpriority())) # 排序优先级归组
+ setattr(auctionItem, "BiddingQueryID", 0) # 当前正在竞价的玩家ID
+ setattr(auctionItem, "BiddingQueryTick", 0) # 当前正在竞价的tick
+ setattr(auctionItem, "EndTime", 0) # 结束竞价time值
+
+ __SetAuctionItemEndTime(auctionItem, ipyData)
+ return True
+
+def __SetAuctionItemEndTime(auctionItem, ipyData):
+ ## 更新拍品结束竞价time值
+ if not ipyData:
+ return
+ addTimeStr = auctionItem.AddTime
+ auctionType = auctionItem.AuctionType
+ addTime = GameWorld.ChangeTimeStrToNum(addTimeStr)
+ noticeMinutes = ipyData.GetNoticeSaleMinutes()
+ saleMinutes = ipyData.GetFamilySaleMinutes() if auctionType == AuctionType_Family else ipyData.GetWorldSaleMinutes()
+ auctionItem.EndTime = addTime + (noticeMinutes + saleMinutes) * 60
+
+ __AddAuctionItemEndTimeByBid(auctionItem)
+ return
+
+def __AddAuctionItemEndTimeByBid(auctionItem):
+ # 根据最后一次竞价时间进行加时
+ if not auctionItem.BidderPrice:
+ return
+ bidTime = GameWorld.ChangeTimeStrToNum(auctionItem.BiddingTime)
+ endTime = bidTime + IpyGameDataPY.GetFuncCfg("AuctionHouse", 4)
+ if endTime < auctionItem.EndTime:
+ return
+ auctionItem.EndTime = endTime
+ return True
+
+def __GetAuctionItemDRDict(auctionItem):
+ drDict = {"GUID":auctionItem.ItemGUID, "PlayerID":auctionItem.PlayerID, "FamilyID":auctionItem.FamilyID,
+ "ItemID":auctionItem.ItemID, "Count":auctionItem.Count, "AuctionType":auctionItem.AuctionType,
+ "AddTime":auctionItem.AddTime, "BiddingTime":auctionItem.BiddingTime, "BidderID":auctionItem.BidderID,
+ "BidderPrice":auctionItem.BidderPrice, "UserData":auctionItem.UserData,
+ "EndTime":"" if not auctionItem.EndTime else GameWorld.ChangeTimeNumToStr(auctionItem.EndTime),
+ "FamilyPlayerIDInfo":auctionItem.FamilyPlayerIDInfo, "BidderIDInfo":auctionItem.BidderIDInfo}
+ return drDict
+
+def GetAuctionItem(itemGUID):
+ ## 获取拍品实例
+ return PyDataManager.GetAuctionItemManager().allAuctionItemDict.get(itemGUID)
+
+def GetPlayerAuctionItemList(playerID):
+ ## 玩家拍卖中的拍品列表
+ return PyDataManager.GetAuctionItemManager().myAuctionItemDict.get(playerID, [])
+
+def GetFamilyAuctionItemList(familyID):
+ ## 仙盟拍卖中的拍品列表
+ return PyDataManager.GetAuctionItemManager().familyAuctionItemDict.get(familyID, [])
+
+def OnAuctionItemTimeProcess(curTime):
+ ## 拍卖行拍品定时处理,每秒触发一次
+ allAuctionItemByEndTimeList = PyDataManager.GetAuctionItemManager().allAuctionItemByEndTimeList
+ if not allAuctionItemByEndTimeList:
+ return
+
+ endItemList = [] # 结束竞价的拍品列表
+ moveToWorldItemList = [] # 转移到全服拍卖的仙盟拍品列表
+ doCount = len(allAuctionItemByEndTimeList)
+ while doCount > 0 and allAuctionItemByEndTimeList:
+ doCount -= 1
+ auctionItem = allAuctionItemByEndTimeList[0]
+ if curTime < auctionItem.EndTime:
+ break
+ allAuctionItemByEndTimeList.pop(0)
+
+ # 没有人竞价的仙盟拍品
+ if not auctionItem.BidderPrice and auctionItem.FamilyID and auctionItem.AuctionType == AuctionType_Family:
+ moveToWorldItemList.append(auctionItem)
+ else:
+ endItemList.append(auctionItem)
+
+ __EndAuctionItem(endItemList, "ByTime")
+ __MoveFamilyAuctionItemToWorld(moveToWorldItemList)
+ return
+
+def __MoveFamilyAuctionItemToWorld(auctionItemList):
+ ## 仙盟拍品转移到全服
+ if not auctionItemList:
+ return
+
+ curTimeStr = GameWorld.GetCurrentDataTimeStr()
+ attentionMgr = PyDataManager.GetAuctionAttentionManager()
+ auctionItemMgr = PyDataManager.GetAuctionItemManager()
+ notifyWorldAddItemList = [] # 新增全服拍品通知 [[itemGUID, itemID, playerID], ...]
+
+ for auctionItem in auctionItemList:
+ itemGUID = auctionItem.ItemGUID
+ itemID = auctionItem.ItemID
+ itemCount = auctionItem.Count
+ playerID = auctionItem.PlayerID
+ familyID = auctionItem.FamilyID
+
+ ipyData = IpyGameDataPY.GetIpyGameData("AuctionItem", itemID)
+ auctionItem.AuctionType = AuctionType_World
+ auctionItem.AddTime = curTimeStr
+ __SetAuctionItemEndTime(auctionItem, ipyData)
+
+ auctionItemMgr.allAuctionItemByEndTimeList.append(auctionItem)
+ auctionItemMgr.worldAuctionItemList.append(auctionItem)
+ notifyWorldAddItemList.append([itemGUID, itemID, playerID])
+
+ # 添加进我的关注
+ for attentionPlayerID, attentionList in auctionItemMgr.myAttentionItemDict.items():
+ if itemID not in GetPlayerAuctionAttention(attentionMgr, attentionPlayerID):
+ continue
+ if auctionItem not in attentionList:
+ attentionList.append(auctionItem)
+
+ if ipyData.GetNeedWorldNotify():
+ PlayerControl.WorldNotify(0, "Paimai4", [itemID, ipyData.GetNoticeSaleMinutes()])
+
+ drDict = {"AuctionItemInfo":__GetAuctionItemDRDict(auctionItem)}
+ DR_AuctionHouse(None, "FamilyToWorld", drDict)
+
+ GameWorld.DebugLog("仙盟拍品转移到全服: itemID=%s,itemCount=%s,familyID=%s,itemGUID=%s"
+ % (itemID, itemCount, familyID, itemGUID))
+
+ __SortAuctionitem()
+ __SyncRefreshAuctionItem(auctionItemList)
+ __NotifyAuctionPlayerAddItem(notifyWorldAddItemList)
+ return
+
+def __SortAuctionitem(isSortWorldItem=True):
+ ''' 刷新全部拍品排序
+ 后端排序
+ 1.全服拍品: 因为全服拍品数量比较大,采用只查询指定个数拍品,所以只能由后端排序后同步
+ 2.全部拍品竞价结束时间:后端需要处理竞价结束
+
+ 前端排序:
+ 1.个人拍品:个数较少,全部同步,由前端自己排序
+ 2.仙盟拍品:个数较少,全部同步,由前端自己排序
+ 3.竞价拍品:个数较少,全部同步,由前端自己整合排序,区分最高竞价、历史竞价
+ 4.关注拍品:个数较少,全部同步,由前端自己排序
+
+ 触发排序时机:
+ 1-上架新全服拍品
+ 2-仙盟拍品转移全服拍品,相当于上架新全服拍品
+ 3-竞价拍品触发加时时,需要对结束时间重排,竞价加时的只触发加时,对全服拍品的排序没有影响,故可不重拍全服拍品
+ '''
+ auctionItemMgr = PyDataManager.GetAuctionItemManager()
+ auctionItemMgr.allAuctionItemByEndTimeList.sort(key=operator.attrgetter("EndTime"))
+ if isSortWorldItem:
+ auctionItemMgr.worldAuctionItemList.sort(key=operator.attrgetter("Sortpriority", "AddTime"))
+ auctionItemMgr.worldAuctionItemQueryDict = {} # 重置全服拍品条件查询,下次有玩家查询时再重新刷新
+ return
+
+def __EndAuctionItem(endItemList, endEvent):
+ ''' 结束拍品竞拍
+ @param delItemStateDict: 删除的拍品竞拍状态
+ '''
+ if not endItemList:
+ return 0
+
+ auctionItemMgr = PyDataManager.GetAuctionItemManager()
+ clearAuctionItemList = []
+ for auctionItem in endItemList:
+ if not auctionItem:
+ continue
+
+ itemGUID = auctionItem.ItemGUID
+ itemID = auctionItem.ItemID
+ itemCount = auctionItem.Count
+ playerID = auctionItem.PlayerID
+ familyID = auctionItem.FamilyID
+ bidderID = auctionItem.BidderID # 当前竞价玩家ID
+ bidderPrice = auctionItem.BidderPrice # 当前竞价,有人竞价的话代表竞拍成功
+ endType = ""
+ # 有人竞价,成交
+ if bidderID and 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 familyID and auctionItem.FamilyPlayerIDInfo:
+ familyPlayerIDList = json.loads(auctionItem.FamilyPlayerIDInfo)
+ taxRate = IpyGameDataPY.GetFuncCfg("AuctionTaxrate", 2) # 仙盟拍品税率百分比
+ personMaxRate = IpyGameDataPY.GetFuncCfg("AuctionTaxrate", 3) # 仙盟拍品个人最大收益百分比
+ giveTotalGold = int(math.ceil(bidderPrice * (100 - taxRate) / 100.0))
+ giveMaxGold = int(math.ceil(giveTotalGold * personMaxRate / 100.0))
+ memCount = len(familyPlayerIDList)
+ giveGoldAverage = min(giveMaxGold, int(math.ceil(giveTotalGold * 1.0 / memCount))) # 有收益的人平分
+
+ # 仙盟拍品收益邮件
+ 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,
+ detail=detail, moneySource=ChConfig.Def_GiveMoney_AuctionGain)
+
+ elif playerID:
+ taxRate = IpyGameDataPY.GetFuncCfg("AuctionTaxrate", 1) # 全服拍品税率百分比
+ givePlayerGold = int(math.ceil(bidderPrice * (100 - taxRate) / 100.0))
+
+ # 个人拍卖收益邮件
+ detail = {"ItemGUID":itemGUID, "ItemID":itemID, "Count":itemCount, "BidderPrice":bidderPrice}
+ paramList = [itemID, itemID, auctionItem.BidderName, bidderPrice, taxRate, givePlayerGold]
+ PlayerCompensation.SendMailByKey("PaimaiMail5", [playerID], [], paramList, gold=givePlayerGold,
+ detail=detail, moneySource=ChConfig.Def_GiveMoney_AuctionGain)
+
+ 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])
+ else:
+ # 仙盟拍品回收
+ if familyID:
+ endType = "Recycle"
+ AddAuctionRecord(auctionItem, AuctionRecordResult_Recycle)
+ # 个人拍品流拍,物品返还
+ else:
+ 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)
+
+ drDict = {"AuctionItemInfo":__GetAuctionItemDRDict(auctionItem), "EndType":endType, "EndEvent":endEvent}
+ DR_AuctionHouse(None, "EndAuctionItem", drDict)
+
+ GameWorld.DebugLog("结束竞拍: itemID=%s,itemCount=%s,familyID=%s,endType=%s,endEvent=%s,itemGUID=%s"
+ % (itemID, itemCount, familyID, endType, endEvent, itemGUID), playerID)
+
+ auctionItemMgr.allAuctionItemDict.pop(itemGUID, None)
+
+ if auctionItem in auctionItemMgr.allAuctionItemByEndTimeList:
+ auctionItemMgr.allAuctionItemByEndTimeList.remove(auctionItem)
+
+ if auctionItem in auctionItemMgr.worldAuctionItemList:
+ auctionItemMgr.worldAuctionItemList.remove(auctionItem)
+
+ for queryItemList in auctionItemMgr.worldAuctionItemQueryDict.values():
+ if auctionItem in queryItemList:
+ queryItemList.remove(auctionItem)
+
+ if familyID and familyID in auctionItemMgr.familyAuctionItemDict:
+ familyItemList = auctionItemMgr.familyAuctionItemDict[familyID]
+ if auctionItem in familyItemList:
+ familyItemList.remove(auctionItem)
+
+ for nowBiddingItemList in auctionItemMgr.nowBiddingAuctionItemDict.values():
+ if auctionItem in nowBiddingItemList:
+ nowBiddingItemList.remove(auctionItem)
+
+ for hisBiddingItemList in auctionItemMgr.hisBiddingAuctionItemDict.values():
+ if auctionItem in hisBiddingItemList:
+ hisBiddingItemList.remove(auctionItem)
+
+ if playerID and playerID in auctionItemMgr.myAuctionItemDict:
+ playerItemList = auctionItemMgr.myAuctionItemDict[playerID]
+ if auctionItem in playerItemList:
+ playerItemList.remove(auctionItem)
+
+ for attentionItemList in auctionItemMgr.myAttentionItemDict.values():
+ if auctionItem in attentionItemList:
+ attentionItemList.remove(auctionItem)
+
+ clearItem = ChPyNetSendPack.tagGCClearAuctionItem()
+ clearItem.ItemGUID = itemGUID
+ clearAuctionItemList.append(clearItem)
+
+ if not clearAuctionItemList:
+ return 0
+ clearCount = len(clearAuctionItemList)
+
+ clientPack = ChPyNetSendPack.tagGCClearAuctionItemInfo()
+ clientPack.ClearAuctionItemList = clearAuctionItemList
+ clientPack.ClearCount = len(clientPack.ClearAuctionItemList)
+
+ playerManager = GameWorld.GetPlayerManager()
+ for i in xrange(playerManager.GetActivePlayerCount()):
+ player = playerManager.GetActivePlayerAt(i)
+ if player == None:
+ continue
+ if PlayerControl.GetIsTJG(player):
+ continue
+ NetPackCommon.SendFakePack(player, clientPack)
+
+ return clearCount
+
+def MapServer_AuctionHouseLogic(curPlayer, msgList, tick):
+ ## 地图玩家拍卖处理
+
+ playerID = 0 if not curPlayer else curPlayer.GetPlayerID()
+ queryType, queryData = msgList
+ result = []
+
+ GameWorld.Log("收到地图拍卖行信息: queryType=%s,queryData=%s" % (queryType, queryData), playerID)
+ if not GetAuctionHouseState():
+ if curPlayer:
+ PlayerControl.NotifyCode(curPlayer, "AuctionHouseClose")
+ return
+
+ # 查询玩家可否上架
+ if queryType == "AddAuctionItemQuery":
+ canSell = __CheckPlayerCanAddAuctionItem(curPlayer)
+ if not canSell:
+ return
+ result = [canSell]
+
+ # 执行上架物品
+ elif queryType == "AddAuctionItem":
+ addAuctionItemList = queryData
+ __AddAuctionItemByList(curPlayer, addAuctionItemList)
+ return
+
+ # 查询玩家可否竞价物品
+ elif queryType == "BidAuctionItemQuery":
+ itemGUID, biddingPrice = queryData
+ itemID, errInfo = __DoPlayerBidAuctionItem(curPlayer, itemGUID, biddingPrice, tick, True)
+ GameWorld.DebugLog(" itemID=%s,errInfo=%s" % (itemID, errInfo), playerID)
+ if errInfo:
+ return
+ if not itemID:
+ return
+ result = [itemID]
+
+ # 执行玩家竞价物品
+ elif queryType == "BidAuctionItem":
+ itemGUID, biddingPrice = queryData
+ itemID, errInfo = __DoPlayerBidAuctionItem(curPlayer, itemGUID, biddingPrice, tick, False)
+ if errInfo:
+ GameWorld.DebugLog(" errInfo=%s" % errInfo, playerID)
+ drDict = {"ItemGUID":itemGUID, "BiddingPrice":biddingPrice, "ErrInfo":errInfo}
+ DR_AuctionHouse(curPlayer, "BidAuctionItemError", drDict)
+
+ return
+
+ elif queryType == "ClearAuctionItem":
+ __DoGMClearAuctionItem(curPlayer)
+ return
+
+ elif queryType == "PrintAuctionItem":
+ __DoGMPrintAuctionItem(curPlayer)
+ return
+
+ resultMsg = str([queryType, queryData, result])
+ if curPlayer:
+ curPlayer.MapServer_QueryPlayerResult(0, 0, "AuctionHouse", resultMsg, len(resultMsg))
+ return
+
+def __CheckPlayerCanAddAuctionItem(curPlayer):
+ ## 检查玩家可否上架拍品
+ playerID = curPlayer.GetPlayerID()
+ maxSellCount = IpyGameDataPY.GetFuncCfg("AuctionHouse", 2)
+ if maxSellCount:
+ playerAuctionItemList = GetPlayerAuctionItemList(playerID)
+ playerSellCount = len(playerAuctionItemList)
+ canSell = playerSellCount < maxSellCount
+ if not canSell:
+ PlayerControl.NotifyCode(curPlayer, "SellCountLimit")
+ return canSell
+ return True
+
+def __AddAuctionItemByList(curPlayer, addAuctionItemList):
+ ''' 批量添加拍品
+ @param curPlayer: 可能为None
+ '''
+
+ notifyWorldAddItemList = [] # 新增全服拍品通知 [[itemGUID, itemID, playerID], ...]
+ notifyFamilyAddItemDict = {} # 新增仙盟拍品通知 {familyID:[auctionItem, ...], ...}
+ for playerID, familyID, familyPlayerIDList, itemData in addAuctionItemList:
+ if not playerID and not familyID:
+ continue
+
+ auctionItem = __DoAddAuctionItem(curPlayer, playerID, familyID, familyPlayerIDList, itemData)
+ if not auctionItem:
+ continue
+
+ if familyID:
+ familyAddItemList = notifyFamilyAddItemDict.get(familyID, [])
+ familyAddItemList.append(auctionItem)
+ notifyFamilyAddItemDict[familyID] = familyAddItemList
+ else:
+ itemGUID = auctionItem.ItemGUID
+ itemID = auctionItem.ItemID
+ notifyWorldAddItemList.append([itemGUID, itemID, playerID])
+
+ if notifyFamilyAddItemDict or notifyWorldAddItemList:
+ isSortWorldItem = notifyWorldAddItemList != []
+ __SortAuctionitem(isSortWorldItem=isSortWorldItem)
+
+ # 通知新增仙盟拍品
+ for familyID, familyAddItemList in notifyFamilyAddItemDict.items():
+ Sync_FamilyAuctionItemInfo(None, familyID, familyAddItemList)
+
+ # 通知全服拍品关注玩家
+ __NotifyAuctionPlayerAddItem(notifyWorldAddItemList)
+ return
+
+def __DoAddAuctionItem(curPlayer, playerID, familyID, familyPlayerIDList, itemData):
+ ## 添加拍品
+ itemID = itemData.get("ItemID", 0)
+ ipyData = IpyGameDataPY.GetIpyGameData("AuctionItem", itemID)
+ if not ipyData:
+ return
+
+ itemGUID = itemData.get("GUID", "")
+ auctionItem = PyGameDataStruct.tagDBAuctionItem()
+ auctionItem.ItemGUID = itemGUID
+ auctionItem.PlayerID = playerID
+ auctionItem.FamilyID = familyID
+ auctionItem.ItemID = itemID
+ auctionItem.Count = itemData.get("ItemCount", 0)
+ auctionItem.AddTime = GameWorld.GetCurrentDataTimeStr()
+ auctionItem.ItemType = itemData.get("ItemType", 0)
+ auctionItem.ItemJobLimit = itemData.get("ItemJobLimit", 0)
+ auctionItem.ItemClassLV = itemData.get("ItemClassLV", 0)
+ auctionItem.UserData = itemData.get("UserData", "")
+ auctionItem.UserDataLen = len(auctionItem.UserData)
+ auctionItem.FamilyPlayerIDInfo = str(familyPlayerIDList)
+ auctionItem.FamilyPlayerIDLen = len(auctionItem.FamilyPlayerIDInfo)
+
+ if not __InitAuctionItemAttrEx(auctionItem):
+ return
+
+ auctionItemMgr = PyDataManager.GetAuctionItemManager()
+ auctionItemMgr.allAuctionItemDict[auctionItem.ItemGUID] = auctionItem
+ 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)
+
+ # 添加进我的拍卖
+ if playerID:
+ myAuctionItemList = auctionItemMgr.myAuctionItemDict.get(playerID, [])
+ myAuctionItemList.append(auctionItem)
+ auctionItemMgr.myAuctionItemDict[playerID] = myAuctionItemList
+ if curPlayer:
+ Sync_PlayerAuctionItemInfo(curPlayer, auctionItem)
+
+ # 添加进我的关注
+ attentionMgr = PyDataManager.GetAuctionAttentionManager()
+ for attentionPlayerID, attentionList in auctionItemMgr.myAttentionItemDict.items():
+ if itemID not in GetPlayerAuctionAttention(attentionMgr, attentionPlayerID):
+ continue
+ if auctionItem not in attentionList:
+ attentionList.append(auctionItem)
+
+ if ipyData.GetNeedWorldNotify():
+ PlayerControl.WorldNotify(0, "Paimai4", [itemID, ipyData.GetNoticeSaleMinutes()])
+
+ drDict = {"AuctionItemInfo":__GetAuctionItemDRDict(auctionItem)}
+ DR_AuctionHouse(curPlayer, "AddAuctionItem", drDict)
+ GameWorld.DebugLog("上架拍品: playerID=%s,familyID=%s,%s" % (playerID, familyID, drDict), playerID)
+ GameWorld.DebugLog("更新拍品数: %s" % len(auctionItemMgr.allAuctionItemDict))
+ return auctionItem
+
+def __NotifyAuctionPlayerAddItem(notifyWorldAddItemList):
+ ## 通知关注物品的玩家新上架物品了
+ if not notifyWorldAddItemList:
+ return
+ attentionMgr = PyDataManager.GetAuctionAttentionManager()
+ playerManager = GameWorld.GetPlayerManager()
+ for i in xrange(playerManager.GetActivePlayerCount()):
+ player = playerManager.GetActivePlayerAt(i)
+ if player == None:
+ continue
+ if PlayerControl.GetIsTJG(player):
+ continue
+ playerAttentionIDList = GetPlayerAuctionAttention(attentionMgr, player.GetPlayerID())
+ if not playerAttentionIDList:
+ continue
+ infoPack = None
+ for itemGUID, itemID, playerID in notifyWorldAddItemList:
+ if playerID == player.GetPlayerID():
+ # 自己上架的物品不通知
+ continue
+ if itemID not in playerAttentionIDList:
+ continue
+ if not infoPack:
+ infoPack = ChPyNetSendPack.tagGCAddAuctionItemInfo()
+ itemInfo = ChPyNetSendPack.tagGCAddAuctionItem()
+ itemInfo.ItemGUID = itemGUID
+ itemInfo.ItemID = itemID
+ infoPack.AddAuctionItemList.append(itemInfo)
+
+ if infoPack:
+ infoPack.AddCount = len(infoPack.AddAuctionItemList)
+ NetPackCommon.SendFakePack(player, infoPack)
+ return
+
+def __DoPlayerBidAuctionItem(curPlayer, itemGUID, biddingPrice, tick, isOnlyCheck):
+ ''' 玩家竞价物品
+ @param curPlayer: 竞价的玩家
+ @param itemGUID: 拍品GUID
+ @param biddingPrice: 竞价
+ @param isOnlyCheck: 是否仅检查可否竞价
+ '''
+
+ errInfo = ""
+ itemID = 0
+
+ auctionItem = GetAuctionItem(itemGUID)
+ if not auctionItem:
+ # 拍品不存在
+ PlayerControl.NotifyCode(curPlayer, "Paimai3")
+ errInfo = "not auctionItem"
+ return itemID, errInfo
+ itemID = auctionItem.ItemID
+ ipyData = IpyGameDataPY.GetIpyGameData("AuctionItem", itemID)
+ if not ipyData:
+ errInfo = "not ipyData"
+ return itemID, errInfo
+ playerID = curPlayer.GetPlayerID()
+ addTimeStr = auctionItem.AddTime
+ auctionType = auctionItem.AuctionType # 0-全服拍品,1-仙盟拍品
+ addTime = GameWorld.ChangeTimeStrToNum(addTimeStr)
+ curTime = int(time.time())
+ passMinutes = (curTime - addTime) / 60
+ noticeMinutes = ipyData.GetNoticeSaleMinutes()
+ if passMinutes < noticeMinutes:
+ GameWorld.ErrLog("拍品尚未开放竞价! itemGUID=%s,itemID=%s,addTimeStr=%s" % (itemGUID, itemID, addTimeStr), playerID)
+ errInfo = "in notice time"
+ return itemID, errInfo
+ if auctionType == AuctionType_Family:
+ itemFamilyID = auctionItem.FamilyID
+ playerFamilyID = curPlayer.GetFamilyID()
+ if not playerFamilyID or playerFamilyID != itemFamilyID:
+ GameWorld.ErrLog("该拍品为仙盟私有拍品,非本仙盟人员不可竞拍! itemGUID=%s,itemID=%s,itemFamilyID=%s,playerFamilyID=%s"
+ % (itemGUID, itemID, itemFamilyID, playerFamilyID), playerID)
+ errInfo = "is family auction item"
+ return itemID, errInfo
+ if curTime >= auctionItem.EndTime:
+ GameWorld.ErrLog("拍品已结束竞价! itemGUID=%s,itemID=%s,addTimeStr=%s" % (itemGUID, itemID, addTimeStr), playerID)
+ errInfo = "end bid"
+ return itemID, errInfo
+
+ nextPrice = ipyData.GetBasePrice() if not auctionItem.BidderPrice else (auctionItem.BidderPrice + ipyData.GetBiddingAdd())
+ buyoutPrice = ipyData.GetBuyoutPrice() # 允许没有一口价的,代表可以一直竞价
+ nextPrice = nextPrice if not buyoutPrice else min(nextPrice, buyoutPrice) # 不超过一口价
+ if not (biddingPrice == nextPrice or (buyoutPrice and biddingPrice == buyoutPrice)):
+ # 竞价价格错误
+ PlayerControl.NotifyCode(curPlayer, "Paimai2")
+ errInfo = "bid price error! biddingPrice=%s,nextPrice=%s,buyoutPrice=%s,itemGUID=%s,itemID=%s" % (biddingPrice, nextPrice, buyoutPrice, itemGUID, itemID)
+ return itemID, errInfo
+
+ if isOnlyCheck:
+ queryTick = auctionItem.BiddingQueryTick
+ if queryTick and tick - queryTick < 10000:
+ # 有玩家正在竞价,请稍等
+ PlayerControl.NotifyCode(curPlayer, "Paimai1")
+ errInfo = "other player bidding"
+ return itemID, errInfo
+ auctionItem.BiddingQueryID = playerID
+ auctionItem.BiddingQueryTick = tick
+ return itemID, errInfo
+
+ if auctionItem.BiddingQueryID != playerID:
+ PlayerControl.NotifyCode(curPlayer, "Paimai2")
+ errInfo = "bidding player error"
+ return itemID, errInfo
+
+ lastBidderID = auctionItem.BidderID
+ lastBidderPrice = auctionItem.BidderPrice
+ itemCount = auctionItem.Count
+
+ isBuyout = buyoutPrice and biddingPrice >= buyoutPrice # 大于等于一口价,直接成交
+
+ auctionItemMgr = PyDataManager.GetAuctionItemManager()
+ nowBiddingAuctionItemDict = auctionItemMgr.nowBiddingAuctionItemDict
+ hisBiddingAuctionItemDict = auctionItemMgr.hisBiddingAuctionItemDict
+
+ # 邮件返还上个竞价者
+ if lastBidderID and lastBidderPrice:
+ detail = {"ItemID":itemID, "ItemGUID":itemGUID, "Count":itemCount}
+ if isBuyout:
+ # 竞拍失败,仅通知
+ paramList = [itemID, itemID, lastBidderPrice]
+ PlayerCompensation.SendMailByKey("PaimaiMail2", [lastBidderID], [], paramList, gold=lastBidderPrice,
+ detail=detail, moneySource=ChConfig.Def_GiveMoney_AuctionBidReturn)
+ else:
+ # 竞拍失败,可继续竞价邮件
+ paramList = [itemID, itemID, lastBidderPrice, itemGUID]
+ PlayerCompensation.SendMailByKey("PaimaiMail1", [lastBidderID], [], paramList, gold=lastBidderPrice,
+ detail=detail, moneySource=ChConfig.Def_GiveMoney_AuctionBidReturn)
+ AddAuctionRecord(auctionItem, AuctionRecordResult_BidFail)
+
+ isSyncBiddingItem = False
+ nowBiddingAuctionItemList = nowBiddingAuctionItemDict.get(lastBidderID, [])
+ if auctionItem in nowBiddingAuctionItemList:
+ nowBiddingAuctionItemList.remove(auctionItem)
+ nowBiddingAuctionItemDict[lastBidderID] = nowBiddingAuctionItemList
+ isSyncBiddingItem = True
+ hisBiddingAuctionItemList = hisBiddingAuctionItemDict.get(lastBidderID, [])
+ if auctionItem not in hisBiddingAuctionItemList:
+ hisBiddingAuctionItemList.append(auctionItem)
+ hisBiddingAuctionItemDict[lastBidderID] = hisBiddingAuctionItemList
+ isSyncBiddingItem = True
+ if isSyncBiddingItem:
+ lastBidder = GameWorld.GetPlayerManager().FindPlayerByID(lastBidderID)
+ if lastBidder and not PlayerControl.GetIsTJG(lastBidder):
+ Sync_PlayerBiddingItemInfo(lastBidder, auctionItem)
+
+ # 更新竞价信息
+ auctionItem.BiddingQueryID = 0
+ auctionItem.BiddingTick = 0
+ auctionItem.BiddingTime = GameWorld.GetCurrentDataTimeStr()
+ auctionItem.BidderID = playerID
+ auctionItem.BidderName = curPlayer.GetName()
+ auctionItem.BidderPrice = biddingPrice
+ isSyncBiddingItem = False
+ nowBiddingAuctionItemList = nowBiddingAuctionItemDict.get(playerID, [])
+ if auctionItem not in nowBiddingAuctionItemList:
+ nowBiddingAuctionItemList.append(auctionItem)
+ nowBiddingAuctionItemDict[playerID] = nowBiddingAuctionItemList
+ isSyncBiddingItem = True
+ hisBiddingAuctionItemList = hisBiddingAuctionItemDict.get(playerID, [])
+ if auctionItem in hisBiddingAuctionItemList:
+ hisBiddingAuctionItemList.remove(auctionItem)
+ hisBiddingAuctionItemDict[playerID] = hisBiddingAuctionItemList
+ isSyncBiddingItem = True
+ if isSyncBiddingItem:
+ Sync_PlayerBiddingItemInfo(curPlayer, auctionItem)
+
+ # 添加历史竞价者
+ if str(playerID) not in auctionItem.BidderIDInfo:
+ auctionItem.BidderIDInfo += "%s|" % playerID
+ auctionItem.BidderIDLen = len(auctionItem.BidderIDInfo)
+
+ GameWorld.DebugLog("玩家竞价拍品: itemGUID=%s,itemID=%s,isBuyout=%s,lastBidderID=%s,lastBidderPrice=%s,bidderIDInfo=%s"
+ % (itemGUID, itemID, isBuyout, lastBidderID, lastBidderPrice, auctionItem.BidderIDInfo), playerID)
+
+ if isBuyout:
+ __EndAuctionItem([auctionItem], "Buyout")
+ else:
+ if __AddAuctionItemEndTimeByBid(auctionItem):
+ __SortAuctionitem(isSortWorldItem=False)
+
+ drDict = {"AuctionItemInfo":__GetAuctionItemDRDict(auctionItem)}
+ DR_AuctionHouse(curPlayer, "BidAuctionItem", drDict)
+
+ __SyncRefreshAuctionItem([auctionItem])
+
+ return itemID, errInfo
+
+def __SyncRefreshAuctionItem(auctionItemList):
+ ''' // B5 08 拍卖行刷新拍品 #tagGCRefreshAuctionItemInfo
+ 1-仙盟拍品转移到全服时通知; 2-拍品有人竞价时刷新
+ '''
+
+ refreshAuctionItemList = []
+
+ for auctionItem in auctionItemList:
+ refreshItem = ChPyNetSendPack.tagGCRefreshAuctionItem()
+ refreshItem.ItemGUID = auctionItem.ItemGUID
+ refreshItem.AuctionType = auctionItem.AuctionType
+ refreshItem.AddTime = auctionItem.AddTime
+ refreshItem.BidderID = auctionItem.BidderID
+ refreshItem.BidderPrice = auctionItem.BidderPrice
+ refreshAuctionItemList.append(refreshItem)
+
+ if not refreshAuctionItemList:
+ return
+
+ clientPack = ChPyNetSendPack.tagGCRefreshAuctionItemInfo()
+ clientPack.RefreshAuctionItemList = refreshAuctionItemList
+ clientPack.RefreshCount = len(clientPack.RefreshAuctionItemList)
+ playerManager = GameWorld.GetPlayerManager()
+ for i in xrange(playerManager.GetActivePlayerCount()):
+ player = playerManager.GetActivePlayerAt(i)
+ if player == None:
+ continue
+ if PlayerControl.GetIsTJG(player):
+ continue
+ NetPackCommon.SendFakePack(player, clientPack)
+
+ return
+
+def __DoGMClearAuctionItem(curPlayer):
+ if curPlayer.GetGMLevel() != 90:
+ return
+
+ allAuctionItemByEndTimeList = PyDataManager.GetAuctionItemManager().allAuctionItemByEndTimeList
+ if not allAuctionItemByEndTimeList:
+ GameWorld.DebugAnswer(curPlayer, "当前没有拍品!")
+ return
+
+ endItemList = []
+ for auctionItem in allAuctionItemByEndTimeList:
+ endItemList.append(auctionItem)
+
+ clearCount = __EndAuctionItem(endItemList, "GMClear")
+
+ GameWorld.DebugAnswer(curPlayer, "清空拍品数=%s" % clearCount)
+ return
+
+def __DoGMPrintAuctionItem(curPlayer):
+ if curPlayer.GetGMLevel() != 90:
+ return
+
+ auctionItemMgr = PyDataManager.GetAuctionItemManager()
+ allAuctionItemByEndTimeList = auctionItemMgr.allAuctionItemByEndTimeList
+ GameWorld.DebugLog("TimeList总拍品数: =%s" % len(allAuctionItemByEndTimeList))
+ for i, auctionItem in enumerate(allAuctionItemByEndTimeList):
+ GameWorld.DebugLog(" i=%s, %s" % (i, __GetAuctionItemDRDict(auctionItem)))
+
+ GameWorld.DebugLog("AllDict总拍品数: =%s" % len(auctionItemMgr.allAuctionItemDict))
+
+ GameWorld.DebugLog("全服拍品个数: =%s" % len(auctionItemMgr.worldAuctionItemList))
+ for familyID, familyItemList in auctionItemMgr.familyAuctionItemDict.items():
+ GameWorld.DebugLog("仙盟拍品个数: familyID=%s, %s" % (familyID, len(familyItemList)))
+
+ for playerID, myItemList in auctionItemMgr.myAuctionItemDict.items():
+ GameWorld.DebugLog("玩家拍品个数: playerID=%s, %s" % (playerID, len(myItemList)))
+
+ for playerID, nowBiddingItemList in auctionItemMgr.nowBiddingAuctionItemDict.items():
+ GameWorld.DebugLog("玩家最高竞价拍品个数: playerID=%s, %s" % (playerID, len(nowBiddingItemList)))
+
+ for playerID, hisBiddingItemList in auctionItemMgr.hisBiddingAuctionItemDict.items():
+ GameWorld.DebugLog("玩家历史竞价拍品个数: playerID=%s, %s" % (playerID, len(hisBiddingItemList)))
+
+ for playerID, attentionItemList in auctionItemMgr.myAttentionItemDict.items():
+ GameWorld.DebugLog("玩家关注拍品个数: playerID=%s, %s" % (playerID, len(attentionItemList)))
+
+ return
+
+#// B5 10 拍卖行查询拍卖中的物品 #tagCGQueryAuctionItem
+#
+#struct tagCGQueryAuctionItem
+#{
+# tagHead Head;
+# BYTE Job; //过滤职业,0为不限制
+# BYTE ItemTypeCount;
+# DWORD ItemTypeList[ItemTypeCount]; //指定的物品类型
+# BYTE ClassLV; //过滤阶数,0为不限制
+# BYTE SpecItemIDCount; //指定物品ID个数
+# DWORD SpecItemIDList[SpecItemIDCount]; //指定物品ID
+# char FromItemGUID[40]; //从哪个物品开始查询
+# BYTE QueryDir; //查询方向,1-往后查,2-往前查
+# BYTE QueryCount; //查询个数,0为全部
+#};
+def OnQueryAuctionItem(index, clientData, tick):
+ curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+ job = clientData.Job
+ itemTypeList = clientData.ItemTypeList
+ classLV = clientData.ClassLV
+ specItemIDList = clientData.SpecItemIDList
+ fromItemGUID = clientData.FromItemGUID
+ queryDir = clientData.QueryDir
+ queryCount = clientData.QueryCount
+ __Sync_WorldAuctionItemQueryResult(curPlayer, job, itemTypeList, classLV, specItemIDList, fromItemGUID, queryDir, queryCount)
+ return
+
+#// B5 17 拍卖行查询定位目标拍品 #tagCGQueryTagAuctionItem
+#
+#struct tagCGQueryTagAuctionItem
+#{
+# tagHead Head;
+# char ItemGUID[40];
+# DWORD ItemID;
+#};
+def OnQueryTagAuctionItem(index, clientData, tick):
+ curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+ tagItemGUID = clientData.ItemGUID
+ queryDir = 3
+ __Sync_WorldAuctionItemQueryResult(curPlayer, fromItemGUID=tagItemGUID, queryDir=queryDir)
+ return
+
+def __Sync_WorldAuctionItemQueryResult(curPlayer, job=0, itemTypeList=[], classLV=0, specItemIDList=[], fromItemGUID="", queryDir=1, queryCount=10):
+ ## 根据过滤条件同步全服拍品列表,目前仅全服拍品需要通过查询服务器获得,个人拍品及仙盟拍品由于个数较少直接由上线或变更时主动同步
+
+ fromAuctionItem = None
+ if fromItemGUID:
+ fromAuctionItem = GetAuctionItem(fromItemGUID)
+ if not fromAuctionItem:
+ GameWorld.DebugLog("查询的目标拍品不存在! fromItemGUID=%s" % fromItemGUID)
+ PlayerControl.NotifyCode(curPlayer, "Paimai5")
+ return
+
+ # {(job, (itemType, ...), itemClassLV, (itemID, ...)):[tagDBAuctionItem, ...], ...}
+ queryKey = (job, tuple(itemTypeList), classLV, tuple(specItemIDList))
+ auctionItemMgr = PyDataManager.GetAuctionItemManager()
+ worldAuctionItemQueryDict = auctionItemMgr.worldAuctionItemQueryDict
+ if queryKey not in worldAuctionItemQueryDict:
+ # 载入对应查询条件拍品缓存
+ auctionItemQueryList = []
+ for worldAuctionItem in auctionItemMgr.worldAuctionItemList:
+ if job and worldAuctionItem.ItemJobLimit != job:
+ continue
+ if itemTypeList and worldAuctionItem.ItemType not in itemTypeList:
+ continue
+ if classLV and worldAuctionItem.ItemClassLV != classLV:
+ continue
+ if specItemIDList and worldAuctionItem.ItemID not in specItemIDList:
+ continue
+ auctionItemQueryList.append(worldAuctionItem)
+ worldAuctionItemQueryDict[queryKey] = auctionItemQueryList
+ else:
+ auctionItemQueryList = worldAuctionItemQueryDict[queryKey]
+ queryTotalCount = len(auctionItemQueryList)
+
+ fromIndex = 0
+ if fromAuctionItem:
+ if fromAuctionItem not in auctionItemQueryList:
+ GameWorld.ErrLog("查询的目标拍品不在所在的过滤的条件里! fromItemGUID=%s" % fromItemGUID)
+ PlayerControl.NotifyCode(curPlayer, "Paimai5")
+ return
+ fromIndex = auctionItemQueryList.index(fromAuctionItem)
+
+ # 向前查,其他的默认向后查
+ if queryDir == 2:
+ startIndex = max(0, fromIndex - queryCount + 1)
+ syncItemList = auctionItemQueryList[startIndex:fromIndex + 1]
+ queryRemainlCount = startIndex
+ # 向后查
+ else:
+ syncItemList = auctionItemQueryList[fromIndex:fromIndex + queryCount]
+ queryRemainlCount = max(0, queryTotalCount - fromIndex - queryCount)
+
+ clientPack = ChPyNetSendPack.tagGCAuctionItemInfo()
+ clientPack.Job = job
+ clientPack.ItemTypeList = itemTypeList
+ clientPack.ItemTypeCount = len(clientPack.ItemTypeList)
+ clientPack.ClassLV = classLV
+ clientPack.SpecItemIDList = specItemIDList
+ clientPack.SpecItemIDCount = len(clientPack.SpecItemIDList)
+ clientPack.FromItemGUID = fromItemGUID
+ clientPack.QueryDir = queryDir
+ clientPack.QueryCount = queryCount
+ clientPack.QueryRemainlCount = queryRemainlCount
+ clientPack.AuctionItemList = []
+ for auctionItem in syncItemList:
+ itemInfo = ChPyNetSendPack.tagGCAuctionItem()
+ itemInfo.ItemGUID = auctionItem.ItemGUID
+ itemInfo.FamilyID = auctionItem.FamilyID
+ itemInfo.ItemID = auctionItem.ItemID
+ itemInfo.ItemCount = auctionItem.Count
+ itemInfo.AddTime = auctionItem.AddTime
+ itemInfo.BidderPrice = auctionItem.BidderPrice
+ itemInfo.UserData = auctionItem.UserData
+ itemInfo.UserDataLen = auctionItem.UserDataLen
+ clientPack.AuctionItemList.append(itemInfo)
+ clientPack.AuctionItemCount = len(clientPack.AuctionItemList)
+ NetPackCommon.SendFakePack(curPlayer, clientPack)
+ return
+
+#// B5 12 拍卖行查询拍卖记录 #tagCGQueryAuctionRecord
+#
+#struct tagCGQueryAuctionRecord
+#{
+# tagHead Head;
+# BYTE RecordType; //记录类型 0-我的拍品记录 1-仙盟拍品记录 2-我的竞拍记录
+#};
+def OnQueryAuctionRecord(index, clientData, tick):
+ curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+ recordType = clientData.RecordType
+ Sync_PlayerAuctionRecordInfo(curPlayer, recordType, None, curPlayer.GetFamilyID())
+ return
+
+#// B5 16 拍卖行查询关注中的拍品 #tagCGQueryAttentionAuctionItem
+#
+#struct tagCGQueryAttentionAuctionItem
+#{
+# tagHead Head;
+#};
+def OnQueryAttentionAuctionItem(index, clientData, tick):
+ curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+ playerID = curPlayer.GetPlayerID()
+
+ auctionItemMgr = PyDataManager.GetAuctionItemManager()
+ myAttentionItemDict = auctionItemMgr.myAttentionItemDict
+ if playerID in myAttentionItemDict:
+ attentionItemList = myAttentionItemDict[playerID]
+ else:
+ attentionItemList = []
+ attentionMgr = PyDataManager.GetAuctionAttentionManager()
+ attentionItemIDList = GetPlayerAuctionAttention(attentionMgr, playerID)
+ if attentionItemIDList:
+ for auctionItem in auctionItemMgr.worldAuctionItemList:
+ if auctionItem.ItemID not in attentionItemIDList:
+ continue
+ attentionItemList.append(auctionItem)
+ myAttentionItemDict[playerID] = attentionItemList
+
+ clientPack = ChPyNetSendPack.tagGCAttentionAuctionItemInfo()
+ clientPack.AuctionItemList = []
+ for attentionItem in attentionItemList:
+ itemObj = ChPyNetSendPack.tagGCAttentionAuctionItem()
+ itemObj.ItemGUID = attentionItem.ItemGUID
+ itemObj.FamilyID = attentionItem.FamilyID
+ itemObj.ItemID = attentionItem.ItemID
+ itemObj.ItemCount = attentionItem.Count
+ itemObj.AddTime = attentionItem.AddTime
+ itemObj.BidderPrice = attentionItem.BidderPrice
+ itemObj.UserData = attentionItem.UserData
+ itemObj.UserDataLen = attentionItem.UserDataLen
+ clientPack.AuctionItemList.append(itemObj)
+ clientPack.AuctionItemCount = len(clientPack.AuctionItemList)
+ NetPackCommon.SendFakePack(curPlayer, clientPack)
+ return
+
+#// B5 18 拍卖行修改关注物品 #tagCGAttentionAuctionItemChange
+#
+#struct tagCGAttentionAuctionItemChange
+#{
+# tagHead Head;
+# DWORD ItemID;
+# BYTE IsAttention; //是否关注,取消关注发0
+#};
+def OnAttentionAuctionItemChange(index, clientData, tick):
+ curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
+ playerID = curPlayer.GetPlayerID()
+ itemID = clientData.ItemID
+ isAttention = clientData.IsAttention
+
+ attentionMgr = PyDataManager.GetAuctionAttentionManager()
+ if isAttention:
+ if not AddPlayerAuctionAttention(attentionMgr, playerID, itemID):
+ return
+ else:
+ if not DelPlayerAuctionAttention(attentionMgr, playerID, itemID):
+ return
+ Sync_PlayerAttentionAuctionItemID(curPlayer, True)
+
+ # 关注信息变更,清空关注拍品实例缓存
+ auctionItemMgr = PyDataManager.GetAuctionItemManager()
+ auctionItemMgr.myAttentionItemDict.pop(playerID, None)
+ return
+
+def Sync_FamilyAuctionItemInfo(curPlayer, familyID, itemInfoList=[]):
+ # // B5 05 拍卖行仙盟拍卖中的物品信息 #tagGCFamilyAuctionItemInfo
+
+ if not familyID:
+ return
+
+ if not itemInfoList:
+ itemInfoList = GetFamilyAuctionItemList(familyID)
+
+ if not itemInfoList:
+ return
+
+ itemInfoPack = ChPyNetSendPack.tagGCFamilyAuctionItemInfo()
+ itemInfoPack.AuctionItemList = []
+ for auctionItem in itemInfoList:
+ packItem = ChPyNetSendPack.tagGCFamilyAuctionItem()
+ packItem.ItemGUID = auctionItem.ItemGUID
+ packItem.FamilyID = auctionItem.FamilyID
+ packItem.ItemID = auctionItem.ItemID
+ packItem.ItemCount = auctionItem.Count
+ packItem.AddTime = auctionItem.AddTime
+ packItem.BidderPrice = auctionItem.BidderPrice
+ packItem.UserData = auctionItem.UserData
+ packItem.UserDataLen = auctionItem.UserDataLen
+ packItem.FamilyPlayerIDInfo = auctionItem.FamilyPlayerIDInfo
+ packItem.FamilyPlayerIDLen = auctionItem.FamilyPlayerIDLen
+ packItem.AuctionType = auctionItem.AuctionType
+ itemInfoPack.AuctionItemList.append(packItem)
+ itemInfoPack.AuctionItemCount = len(itemInfoPack.AuctionItemList)
+
+ if curPlayer:
+ NetPackCommon.SendFakePack(curPlayer, itemInfoPack)
+ else:
+ PlayerFamily.SendFamilyFakePack(familyID, itemInfoPack)
+ return
+
+def Sync_PlayerAuctionItemInfo(curPlayer, auctionItem=None):
+ # // B5 02 拍卖行玩家拍卖中的物品信息 #tagGCPlayerAuctionItemInfo
+
+ if auctionItem:
+ syncItemList = [auctionItem]
+ else:
+ syncItemList = GetPlayerAuctionItemList(curPlayer.GetPlayerID())
+
+ if not syncItemList:
+ return
+
+ itemInfoPack = ChPyNetSendPack.tagGCPlayerAuctionItemInfo()
+ itemInfoPack.AuctionItemList = []
+ for auctionItem in syncItemList:
+ packItem = ChPyNetSendPack.tagGCPlayerAuctionItem()
+ packItem.ItemGUID = auctionItem.ItemGUID
+ packItem.FamilyID = auctionItem.FamilyID
+ packItem.ItemID = auctionItem.ItemID
+ packItem.ItemCount = auctionItem.Count
+ packItem.AddTime = auctionItem.AddTime
+ packItem.BidderPrice = auctionItem.BidderPrice
+ packItem.UserData = auctionItem.UserData
+ packItem.UserDataLen = auctionItem.UserDataLen
+ itemInfoPack.AuctionItemList.append(packItem)
+ itemInfoPack.AuctionItemCount = len(itemInfoPack.AuctionItemList)
+ NetPackCommon.SendFakePack(curPlayer, itemInfoPack)
+ return
+
+def Sync_PlayerAuctionRecordInfo(curPlayer, recordType, newRecordData=None, familyID=0):
+ ## B5 03 拍卖行玩家拍卖记录 #tagGCPlayerAuctionRecordInfo
+ if recordType == AuctionRecordType_MyAuction and curPlayer:
+ syncRecordList = [newRecordData] if newRecordData else GetMyAuctionItemRecord(curPlayer.GetPlayerID())
+ elif recordType == AuctionRecordType_FamilyAuction and familyID:
+ syncRecordList = [newRecordData] if newRecordData else GetFamilyAuctionItemRecord(familyID)
+ elif recordType == AuctionRecordType_MyBid and curPlayer:
+ syncRecordList = [newRecordData] if newRecordData else GetMyBiddingItemRecord(curPlayer.GetPlayerID())
+ else:
+ return
+
+ clientPack = ChPyNetSendPack.tagGCPlayerAuctionRecordInfo()
+ clientPack.AuctionRecordList = []
+ for recordData in syncRecordList:
+ record = ChPyNetSendPack.tagGCPlayerAuctionRecord()
+ record.ItemGUID = recordData.ItemGUID
+ record.FamilyID = recordData.FamilyID
+ record.RecordType = recordData.RecordType
+ record.RecordResult = recordData.RecordResult
+ record.RecordTime = recordData.RecordTime
+ record.BidderPrice = recordData.BidderPrice
+ record.BidderName = recordData.BidderName
+ record.ItemID = recordData.ItemID
+ record.ItemCount = recordData.Count
+ record.UserData = recordData.UserData
+ record.UserDataLen = recordData.UserDataLen
+ clientPack.AuctionRecordList.append(record)
+ clientPack.Count = len(clientPack.AuctionRecordList)
+
+ if curPlayer:
+ NetPackCommon.SendFakePack(curPlayer, clientPack)
+ elif familyID and recordType == AuctionRecordType_FamilyAuction:
+ PlayerFamily.SendFamilyFakePack(familyID, clientPack)
+ return
+
+def Sync_PlayerBiddingItemInfo(curPlayer, auctionItem=None):
+ #// B5 10 拍卖行玩家竞价中的物品信息 #tagGCBiddingItemInfo
+ # 上线同步、玩家相关的竞价拍品竞价变更时同步
+
+ if auctionItem:
+ syncItemList = [auctionItem]
+ else:
+ playerID = curPlayer.GetPlayerID()
+ auctionItemMgr = PyDataManager.GetAuctionItemManager()
+ nowBiddingAuctionItemList = auctionItemMgr.nowBiddingAuctionItemDict.get(playerID, [])
+ hisBiddingAuctionItemList = auctionItemMgr.hisBiddingAuctionItemDict.get(playerID, [])
+ syncItemList = nowBiddingAuctionItemList + hisBiddingAuctionItemList
+
+ if not syncItemList:
+ return
+
+ itemInfoPack = ChPyNetSendPack.tagGCBiddingItemInfo()
+ itemInfoPack.AuctionItemList = []
+ for auctionItem in syncItemList:
+ packItem = ChPyNetSendPack.tagGCBiddingItem()
+ packItem.ItemGUID = auctionItem.ItemGUID
+ packItem.FamilyID = auctionItem.FamilyID
+ packItem.ItemID = auctionItem.ItemID
+ packItem.ItemCount = auctionItem.Count
+ packItem.AddTime = auctionItem.AddTime
+ packItem.BidderID = auctionItem.BidderID
+ packItem.BidderPrice = auctionItem.BidderPrice
+ packItem.UserData = auctionItem.UserData
+ packItem.UserDataLen = auctionItem.UserDataLen
+ itemInfoPack.AuctionItemList.append(packItem)
+ itemInfoPack.AuctionItemCount = len(itemInfoPack.AuctionItemList)
+ NetPackCommon.SendFakePack(curPlayer, itemInfoPack)
+ return
+
+def Sync_PlayerAttentionAuctionItemID(curPlayer, isForce=False):
+ # // B5 07 拍卖行关注的物品ID #tagGCAttentionAuctionItemID
+ attentionMgr = PyDataManager.GetAuctionAttentionManager()
+ attentionItemIDList = GetPlayerAuctionAttention(attentionMgr, curPlayer.GetPlayerID())
+ if not attentionItemIDList and not isForce:
+ return
+ clientPack = ChPyNetSendPack.tagGCAttentionAuctionItemID()
+ clientPack.AttentionItemIDList = attentionItemIDList
+ clientPack.AttentionCount = len(clientPack.AttentionItemIDList)
+ NetPackCommon.SendFakePack(curPlayer, clientPack)
+ return
+
+def DR_AuctionHouse(curPlayer, eventName, drDict):
+ accID = "" if not curPlayer else curPlayer.GetAccID()
+ playerID = 0 if not curPlayer else curPlayer.GetPlayerID()
+ dataDict = {"EventName":eventName, "PlayerID":playerID, "AccID":accID}
+ dataDict.update(drDict)
+ DataRecordPack.SendEventPack("AuctionHouse", dataDict, curPlayer)
+ return
--
Gitblit v1.8.0