From 256e1c97cf082750fdfbf710d681e176dd19c66c Mon Sep 17 00:00:00 2001
From: xdh <xiefantasy@qq.com>
Date: 星期二, 04 六月 2019 14:24:14 +0800
Subject: [PATCH] 7095 【2.0】【后端】专精修改,选择专精显示在界面上

---
 ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/AuctionHouse.py |  104 ++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 73 insertions(+), 31 deletions(-)

diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/AuctionHouse.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/AuctionHouse.py
index 7f3ae4f..b41462d 100644
--- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/AuctionHouse.py
+++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/AuctionHouse.py
@@ -53,6 +53,18 @@
 AuctionType_World = 0
 AuctionType_Family = 1
 
+'''
+竞价流程: 
+1. MapServer 先验证价格是否够
+2. GameServer 验证是否可以竞价
+3. MapServer 扣除玩家货币
+4. GameServer  进行竞价,变更下次竞价价格
+
+基于以上流程,所以玩家竞价时需先锁定物品,防止竞价流程未完结时其他玩家请求竞价同一拍品判断竞价价格错误
+锁定时长同样适用于拍品竞价时间结束时的保护时间
+'''
+BiddingQueryLockTick = 10000
+
 #拍卖行状态开关
 def GetAuctionHouseState(): return PlayerBourse.GetOpenState()
 
@@ -278,8 +290,9 @@
         return
     bidTime = GameWorld.ChangeTimeStrToNum(auctionItem.BiddingTime)
     endTime = bidTime + IpyGameDataPY.GetFuncCfg("AuctionHouse", 4)
-    if endTime < auctionItem.EndTime:
+    if endTime <= auctionItem.EndTime:
         return
+    GameWorld.DebugLog("拍品加时: EndTime=%s,updEndTime=%s" % (auctionItem.EndTime, endTime))
     auctionItem.EndTime = endTime
     return True
 
@@ -304,21 +317,33 @@
     ## 仙盟拍卖中的拍品列表
     return PyDataManager.GetAuctionItemManager().familyAuctionItemDict.get(familyID, [])
 
-def OnAuctionItemTimeProcess(curTime):
+def IsFamilyMemberBiddingAuctionItem(familyID, memberID):
+    ## 仙盟成员是否最高竞价拍品中
+    familyAuctionItemList = GetFamilyAuctionItemList(familyID)
+    for auctionItem in familyAuctionItemList:
+        if auctionItem.BidderID == memberID:
+            return True
+    return False
+
+def OnAuctionItemTimeProcess(curTime, tick):
     ## 拍卖行拍品定时处理,每秒触发一次
     allAuctionItemByEndTimeList = PyDataManager.GetAuctionItemManager().allAuctionItemByEndTimeList
     if not allAuctionItemByEndTimeList:
         return
     
+    index = 0
     endItemList = [] # 结束竞价的拍品列表
     moveToWorldItemList = [] # 转移到全服拍卖的仙盟拍品列表
     doCount = len(allAuctionItemByEndTimeList)
     while doCount > 0 and allAuctionItemByEndTimeList:
         doCount -= 1
-        auctionItem = allAuctionItemByEndTimeList[0]
-        if curTime < auctionItem.EndTime:
+        auctionItem = allAuctionItemByEndTimeList[index]
+        if curTime <= auctionItem.EndTime:
             break
-        allAuctionItemByEndTimeList.pop(0)
+        if auctionItem.BiddingQueryTick and tick - auctionItem.BiddingQueryTick < BiddingQueryLockTick:
+            index += 1
+            continue
+        allAuctionItemByEndTimeList.pop(index)
         
         # 没有人竞价的仙盟拍品
         if not auctionItem.BidderPrice and auctionItem.FamilyID and auctionItem.AuctionType == AuctionType_Family:
@@ -355,6 +380,8 @@
         auctionItemMgr.allAuctionItemByEndTimeList.append(auctionItem)
         auctionItemMgr.worldAuctionItemList.append(auctionItem)
         notifyWorldAddItemList.append([itemGUID, itemID, playerID])
+        
+        AddAuctionRecord(auctionItem, AuctionRecordResult_MoveToWorld)
         
         # 添加进我的关注
         for attentionPlayerID, attentionList in auctionItemMgr.myAttentionItemDict.items():
@@ -429,7 +456,7 @@
             # 竞拍成功邮件,发放物品
             paramList = [bidderPrice]
             detail = {"ItemGUID":itemGUID}
-            addItemList = [{"ItemID":itemID, "Count":itemCount, "IsBind":True, "UserData":auctionItem.UserData}]
+            addItemList = [{"ItemID":itemID, "Count":itemCount, "IsAuctionItem":False, "UserData":auctionItem.UserData}]
             PlayerCompensation.SendMailByKey("PaimaiMail3", [bidderID], addItemList, paramList, detail=detail)
             AddAuctionRecord(auctionItem, AuctionRecordResult_BidOK)
             
@@ -438,7 +465,8 @@
                 familyPlayerIDList = json.loads(auctionItem.FamilyPlayerIDInfo)
                 taxRate = IpyGameDataPY.GetFuncCfg("AuctionTaxrate", 2) # 仙盟拍品税率百分比
                 personMaxRate = IpyGameDataPY.GetFuncCfg("AuctionTaxrate", 3) # 仙盟拍品个人最大收益百分比
-                giveTotalGold = int(math.ceil(bidderPrice * (100 - taxRate) / 100.0))
+                taxGold = max(1, int(bidderPrice * taxRate / 100.0)) # 最少收税1
+                giveTotalGold = max(0, bidderPrice - taxGold)
                 giveMaxGold = int(math.ceil(giveTotalGold * personMaxRate / 100.0))
                 memCount = len(familyPlayerIDList)
                 giveGoldAverage = min(giveMaxGold, int(math.ceil(giveTotalGold * 1.0 / memCount))) # 有收益的人平分
@@ -451,7 +479,8 @@
                 
             elif playerID:
                 taxRate = IpyGameDataPY.GetFuncCfg("AuctionTaxrate", 1) # 全服拍品税率百分比
-                givePlayerGold = int(math.ceil(bidderPrice * (100 - taxRate) / 100.0))
+                taxGold = max(1, int(bidderPrice * taxRate / 100.0)) # 最少收税1
+                givePlayerGold = max(0, bidderPrice - taxGold)
                 
                 # 个人拍卖收益邮件
                 detail = {"ItemGUID":itemGUID, "ItemID":itemID, "Count":itemCount, "BidderPrice":bidderPrice}
@@ -460,6 +489,10 @@
                                                  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:
@@ -472,7 +505,7 @@
                 # 流拍返还物品邮件
                 paramList = []
                 detail = {"ItemGUID":itemGUID}
-                addItemList = [{"ItemID":itemID, "Count":itemCount, "IsBind":True, "UserData":auctionItem.UserData}]
+                addItemList = [{"ItemID":itemID, "Count":itemCount, "IsAuctionItem":False, "UserData":auctionItem.UserData}]
                 PlayerCompensation.SendMailByKey("PaimaiMail4", [playerID], addItemList, paramList, detail=detail)
                 
                 AddAuctionRecord(auctionItem, AuctionRecordResult_SellFail)
@@ -619,7 +652,8 @@
     @param curPlayer: 可能为None
     '''
     
-    notifyWorldAddItemList = [] # 新增全服拍品通知 [[itemGUID, itemID, playerID], ...]
+    isSortWorldItem = False
+    notifyAddItemList = [] # 新增拍品通知 [[itemGUID, itemID, playerID], ...]
     notifyFamilyAddItemDict = {} # 新增仙盟拍品通知 {familyID:[auctionItem, ...], ...}
     for playerID, familyID, familyPlayerIDList, itemData in addAuctionItemList:
         if not playerID and not familyID:
@@ -629,25 +663,25 @@
         if not auctionItem:
             continue
         
+        itemGUID = auctionItem.ItemGUID
+        itemID = auctionItem.ItemID
+        notifyAddItemList.append([itemGUID, itemID, playerID])
         if familyID:
             familyAddItemList = notifyFamilyAddItemDict.get(familyID, [])
             familyAddItemList.append(auctionItem)
             notifyFamilyAddItemDict[familyID] = familyAddItemList
         else:
-            itemGUID = auctionItem.ItemGUID
-            itemID = auctionItem.ItemID
-            notifyWorldAddItemList.append([itemGUID, itemID, playerID])
+            isSortWorldItem = True
             
-    if notifyFamilyAddItemDict or notifyWorldAddItemList:
-        isSortWorldItem = notifyWorldAddItemList != []
+    if notifyAddItemList:
         __SortAuctionitem(isSortWorldItem=isSortWorldItem)
         
     # 通知新增仙盟拍品
     for familyID, familyAddItemList in notifyFamilyAddItemDict.items():
         Sync_FamilyAuctionItemInfo(None, familyID, familyAddItemList)
         
-    # 通知全服拍品关注玩家
-    __NotifyAuctionPlayerAddItem(notifyWorldAddItemList)
+    # 通知拍品关注玩家
+    __NotifyAuctionPlayerAddItem(notifyAddItemList)
     return
 
 def __DoAddAuctionItem(curPlayer, playerID, familyID, familyPlayerIDList, itemData):
@@ -714,9 +748,9 @@
     GameWorld.DebugLog("更新拍品数: %s" % len(auctionItemMgr.allAuctionItemDict))
     return auctionItem
 
-def __NotifyAuctionPlayerAddItem(notifyWorldAddItemList):
+def __NotifyAuctionPlayerAddItem(notifyAddItemList):
     ## 通知关注物品的玩家新上架物品了
-    if not notifyWorldAddItemList:
+    if not notifyAddItemList:
         return
     attentionMgr = PyDataManager.GetAuctionAttentionManager()
     playerManager = GameWorld.GetPlayerManager()
@@ -730,8 +764,8 @@
         if not playerAttentionIDList:
             continue
         infoPack = None
-        for itemGUID, itemID, playerID in notifyWorldAddItemList:
-            if playerID == player.GetPlayerID():
+        for itemGUID, itemID, playerID in notifyAddItemList:
+            if playerID and playerID == player.GetPlayerID():
                 # 自己上架的物品不通知
                 continue
             if itemID not in playerAttentionIDList:
@@ -789,13 +823,13 @@
                              % (itemGUID, itemID, itemFamilyID, playerFamilyID), playerID)
             errInfo = "is family auction item"
             return itemID, errInfo
-    if curTime >= auctionItem.EndTime:
+    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 = ipyData.GetBasePrice() * auctionItem.Count if not auctionItem.BidderPrice else (auctionItem.BidderPrice + ipyData.GetBiddingAdd() * auctionItem.Count)
+    buyoutPrice = ipyData.GetBuyoutPrice() * auctionItem.Count # 允许没有一口价的,代表可以一直竞价
     nextPrice = nextPrice if not buyoutPrice else min(nextPrice, buyoutPrice) # 不超过一口价
     if not (biddingPrice == nextPrice or (buyoutPrice and biddingPrice == buyoutPrice)):
         # 竞价价格错误
@@ -805,7 +839,7 @@
     
     if isOnlyCheck:
         queryTick = auctionItem.BiddingQueryTick
-        if queryTick and tick - queryTick < 10000:
+        if queryTick and tick - queryTick < BiddingQueryLockTick:
             # 有玩家正在竞价,请稍等
             PlayerControl.NotifyCode(curPlayer, "Paimai1")
             errInfo = "other player bidding"
@@ -862,7 +896,7 @@
                 
     # 更新竞价信息
     auctionItem.BiddingQueryID = 0
-    auctionItem.BiddingTick = 0
+    auctionItem.BiddingQueryTick = 0
     auctionItem.BiddingTime = GameWorld.GetCurrentDataTimeStr()
     auctionItem.BidderID = playerID
     auctionItem.BidderName = curPlayer.GetName()
@@ -916,6 +950,7 @@
         refreshItem.AddTime = auctionItem.AddTime
         refreshItem.BidderID = auctionItem.BidderID
         refreshItem.BidderPrice = auctionItem.BidderPrice
+        refreshItem.BiddingTime = auctionItem.BiddingTime
         refreshAuctionItemList.append(refreshItem)
         
     if not refreshAuctionItemList:
@@ -1022,10 +1057,10 @@
     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
     tagItemGUID = clientData.ItemGUID
     queryDir = 3
-    __Sync_WorldAuctionItemQueryResult(curPlayer, fromItemGUID=tagItemGUID, queryDir=queryDir)
+    __Sync_WorldAuctionItemQueryResult(curPlayer, fromItemGUID=tagItemGUID, queryDir=queryDir, isNotify=True)
     return
 
-def __Sync_WorldAuctionItemQueryResult(curPlayer, job=0, itemTypeList=[], classLV=0, specItemIDList=[], fromItemGUID="", queryDir=1, queryCount=10):
+def __Sync_WorldAuctionItemQueryResult(curPlayer, job=0, itemTypeList=[], classLV=0, specItemIDList=[], fromItemGUID="", queryDir=1, queryCount=10, isNotify=False):
     ## 根据过滤条件同步全服拍品列表,目前仅全服拍品需要通过查询服务器获得,个人拍品及仙盟拍品由于个数较少直接由上线或变更时主动同步
     
     fromAuctionItem = None
@@ -1033,7 +1068,8 @@
         fromAuctionItem = GetAuctionItem(fromItemGUID)
         if not fromAuctionItem:
             GameWorld.DebugLog("查询的目标拍品不存在! fromItemGUID=%s" % fromItemGUID)
-            PlayerControl.NotifyCode(curPlayer, "Paimai5")
+            if isNotify:
+                PlayerControl.NotifyCode(curPlayer, "Paimai5")
             return
         
     # {(job, (itemType, ...), itemClassLV, (itemID, ...)):[tagDBAuctionItem, ...], ...}
@@ -1044,7 +1080,7 @@
         # 载入对应查询条件拍品缓存
         auctionItemQueryList = []
         for worldAuctionItem in auctionItemMgr.worldAuctionItemList:
-            if job and worldAuctionItem.ItemJobLimit != job:
+            if job and worldAuctionItem.ItemJobLimit != job and worldAuctionItem.ItemJobLimit:
                 continue
             if itemTypeList and worldAuctionItem.ItemType not in itemTypeList:
                 continue
@@ -1062,7 +1098,8 @@
     if fromAuctionItem:
         if fromAuctionItem not in auctionItemQueryList:
             GameWorld.ErrLog("查询的目标拍品不在所在的过滤的条件里! fromItemGUID=%s" % fromItemGUID)
-            PlayerControl.NotifyCode(curPlayer, "Paimai5")
+            if isNotify:
+                PlayerControl.NotifyCode(curPlayer, "Paimai5")
             return
         fromIndex = auctionItemQueryList.index(fromAuctionItem)
         
@@ -1096,6 +1133,7 @@
         itemInfo.ItemCount = auctionItem.Count
         itemInfo.AddTime = auctionItem.AddTime
         itemInfo.BidderPrice = auctionItem.BidderPrice
+        itemInfo.BiddingTime = auctionItem.BiddingTime
         itemInfo.UserData = auctionItem.UserData
         itemInfo.UserDataLen = auctionItem.UserDataLen
         clientPack.AuctionItemList.append(itemInfo)
@@ -1151,6 +1189,7 @@
         itemObj.ItemCount = attentionItem.Count
         itemObj.AddTime = attentionItem.AddTime
         itemObj.BidderPrice = attentionItem.BidderPrice
+        itemObj.BiddingTime = attentionItem.BiddingTime
         itemObj.UserData = attentionItem.UserData
         itemObj.UserDataLen = attentionItem.UserDataLen
         clientPack.AuctionItemList.append(itemObj)
@@ -1208,6 +1247,7 @@
         packItem.ItemCount = auctionItem.Count
         packItem.AddTime = auctionItem.AddTime
         packItem.BidderPrice = auctionItem.BidderPrice
+        packItem.BiddingTime = auctionItem.BiddingTime
         packItem.UserData = auctionItem.UserData
         packItem.UserDataLen = auctionItem.UserDataLen
         packItem.FamilyPlayerIDInfo = auctionItem.FamilyPlayerIDInfo
@@ -1243,6 +1283,7 @@
         packItem.ItemCount = auctionItem.Count
         packItem.AddTime = auctionItem.AddTime
         packItem.BidderPrice = auctionItem.BidderPrice
+        packItem.BiddingTime = auctionItem.BiddingTime
         packItem.UserData = auctionItem.UserData
         packItem.UserDataLen = auctionItem.UserDataLen
         itemInfoPack.AuctionItemList.append(packItem)
@@ -1312,6 +1353,7 @@
         packItem.AddTime = auctionItem.AddTime
         packItem.BidderID = auctionItem.BidderID
         packItem.BidderPrice = auctionItem.BidderPrice
+        packItem.BiddingTime = auctionItem.BiddingTime
         packItem.UserData = auctionItem.UserData
         packItem.UserDataLen = auctionItem.UserDataLen
         itemInfoPack.AuctionItemList.append(packItem)

--
Gitblit v1.8.0