From 8d1a34c156b363d16b979f88909ece9e44771c74 Mon Sep 17 00:00:00 2001 From: hxp <ale99527@vip.qq.com> Date: 星期四, 20 二月 2025 20:16:43 +0800 Subject: [PATCH] 10361 【越南】【英语】【BT】【GM】【砍树】仙匠大会 - 服务端(修复活动显示等级限制通知错误bug;) --- ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/AuctionHouse.py | 220 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 208 insertions(+), 12 deletions(-) diff --git a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/AuctionHouse.py b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/AuctionHouse.py index c1a2563..4b0ab3a 100644 --- a/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/AuctionHouse.py +++ b/ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/AuctionHouse.py @@ -20,6 +20,7 @@ import DataRecordPack import PyGameDataStruct import PlayerCompensation +import IPY_PlayerDefine import ChPyNetSendPack import PlayerDBGSEvent import IpyGameDataPY @@ -310,7 +311,7 @@ return # 注意: 因为GameServer没传是否套装,所以暂时按策划的ID规则来处理,最后一位代表是否套装 - if itemID % 10 == 1: + if itemID % 10 != 0: #GameWorld.DebugLog("该拍品为套装拍品,不设置系统一口价时间! itemID=%s" % (itemID)) return @@ -869,7 +870,7 @@ auctionItemMgr.sysBuyoutItemByTimeList.sort(key=operator.attrgetter("SysBuyTime")) return -def __EndAuctionItem(endItemList, endEvent): +def __EndAuctionItem(endItemList, endEvent, funcAutoBuyout=False, buyPlayer=None): ''' 结束拍品竞拍 @param delItemStateDict: 删除的拍品竞拍状态 ''' @@ -896,10 +897,20 @@ # 竞拍成功邮件,发放物品 if bidderID: + mailTypeKey = "PaimaiMail3" paramList = [bidderPrice] detail = {"ItemGUID":itemGUID} addItemList = [{"ItemID":itemID, "Count":itemCount, "IsAuctionItem":False, "UserData":auctionItem.UserData}] - PlayerCompensation.SendMailByKey("PaimaiMail3", [bidderID], addItemList, paramList, detail=detail) + if funcAutoBuyout: + # 功能自动购买的不给物品,由功能根据功能需求处理 + pass + ## 如果有玩家的,直接给到背包 + elif buyPlayer and buyPlayer.GetPlayerID() == bidderID: + mailInfo = [mailTypeKey, addItemList, paramList, detail] + resultMsg = str([itemGUID, itemID, itemCount, auctionItem.UserData, mailInfo]) + buyPlayer.MapServer_QueryPlayerResult(0, 0, "AuctionHouseGiveItem", resultMsg, len(resultMsg)) + else: + PlayerCompensation.SendMailByKey(mailTypeKey, [bidderID], addItemList, paramList, detail=detail) AddAuctionRecord(auctionItem, AuctionRecordResult_BidOK) # 拍卖成功收益,都以玩家收益向上取整 @@ -1086,6 +1097,13 @@ itemGUID = queryData[0] __DoUnsellAuctionItem(curPlayer, itemGUID) return + + # 升星自动购买 + elif queryType == "EquipStarAutoBuy": + buyResult = __DoEquipStarAutoBuyEquip(curPlayer, queryData, tick) + if buyResult == None: + return + result = buyResult elif queryType == "ClearAuctionItem": __DoGMClearAuctionItem(curPlayer) @@ -1275,12 +1293,13 @@ __EndAuctionItem([auctionItem], "Unsell") return -def __DoPlayerBidAuctionItem(curPlayer, itemGUID, biddingPrice, tick, isOnlyCheck): +def __DoPlayerBidAuctionItem(curPlayer, itemGUID, biddingPrice, tick, isOnlyCheck, funcAutoBuyout=False): ''' 玩家竞价物品 @param curPlayer: 竞价的玩家 @param itemGUID: 拍品GUID @param biddingPrice: 竞价 @param isOnlyCheck: 是否仅检查可否竞价 + @param funcAutoBuyout: 是否功能自动购买 ''' errInfo = "" @@ -1341,7 +1360,7 @@ auctionItem.BiddingQueryTick = tick return itemID, errInfo - if auctionItem.BiddingQueryID != playerID: + if not funcAutoBuyout and auctionItem.BiddingQueryID != playerID: PlayerControl.NotifyCode(curPlayer, "Paimai2") errInfo = "bidding player error" return itemID, errInfo @@ -1420,8 +1439,8 @@ auctionItemMgr.sysBuyoutItemByTimeList.remove(auctionItem) #GameWorld.DebugLog("拍品有人竞价了,移除系统一口价拍品列表!") - if isBuyout: - __EndAuctionItem([auctionItem], "Buyout") + if isBuyout: + __EndAuctionItem([auctionItem], "Buyout", funcAutoBuyout, buyPlayer=curPlayer) else: if __AddAuctionItemEndTimeByBid(auctionItem): __SortAuctionitem(isSortWorldItem=False) @@ -1432,6 +1451,183 @@ __SyncRefreshAuctionItem([auctionItem]) return itemID, errInfo + +def __DoEquipStarAutoBuyEquip(curPlayer, queryData, tick): + ## 升星自动购买 + classLV, equipPlace, curPartStar, equipPackIndex, isAutoBuyPreview, curRate, delEquipGUIDDict, delItemInfoDict, lackItemCostMoney, playerGoldPaper = queryData + GameWorld.DebugLog("升星自动购买装备: classLV=%s, equipPlace=%s, curPartStar=%s, equipPackIndex=%s" % (classLV, equipPlace, curPartStar, equipPackIndex)) + GameWorld.DebugLog(" 是否预览 %s, curRate=%s,lackItemCostMoney=%s, playerGoldPaper=%s" % (isAutoBuyPreview, curRate, lackItemCostMoney, playerGoldPaper)) + nextStar = curPartStar + 1 + ipyData = IpyGameDataPY.GetIpyGameData("EquipStarUp", classLV, equipPlace, nextStar) + if not ipyData: + return + costEquipPlaceList = ipyData.GetCostEquipPlace() + costEquipColorList = ipyData.GetCostEquipColor() + isJobLimit = ipyData.GetIsJobLimit() + unSuitRate = ipyData.GetUnSuitRate() + + curTime = int(time.time()) + fullRate = IpyGameDataPY.GetFuncCfg("EquipStarRate", 4) + autoBuyOtherClassItemDict = {} + buyEquipCostMoney = 0 + autoBuyItemList = [] + auctionItemMgr = PyDataManager.GetAuctionItemManager() + #GameWorld.DebugLog("世界拍品个数: %s" % len(auctionItemMgr.worldAuctionItemList)) + for i, worldAuctionItem in enumerate(auctionItemMgr.worldAuctionItemList): + + itemID = worldAuctionItem.ItemID + aucItemJob = worldAuctionItem.ItemJobLimit + if not aucItemJob: + #GameWorld.DebugLog(" %s 职业通用的, 不购买!itemID=%s" % (i, itemID)) + continue + if isJobLimit and aucItemJob != curPlayer.GetJob(): + #GameWorld.DebugLog(" %s 职业不可用, 不购买!itemID=%s,aucItemJob=%s != %s" % (i, itemID, aucItemJob, curPlayer.GetJob())) + continue + + itemIDStr = str(itemID) + aucItemColor = int(itemIDStr[3:4]) + aucItemPlace = int(itemIDStr[4:6]) + aucItemIsSuit = int(itemIDStr[-1]) + + if aucItemColor not in costEquipColorList: + #GameWorld.DebugLog(" %s 颜色限制, 不购买!itemID=%s,aucItemColor=%s not in %s" % (i, itemID, aucItemColor, costEquipColorList)) + continue + if aucItemPlace not in costEquipPlaceList: + #GameWorld.DebugLog(" %s 装备位限制, 不购买!itemID=%s,aucItemPlace=%s not in %s" % (i, itemID, aucItemPlace, costEquipPlaceList)) + continue + if aucItemIsSuit: + #套装不允许自动购买 + #GameWorld.DebugLog(" %s 套装, 不购买!itemID=%s" % (i, itemID)) + continue + + aucIpyData = IpyGameDataPY.GetIpyGameData("AuctionItem", itemID) + if not aucIpyData: + continue + buyoutPrice = aucIpyData.GetBuyoutPrice() + if not buyoutPrice: + #GameWorld.DebugLog(" %s 没有一口价, 不购买!itemID=%s,buyoutPrice=%s" % (i, itemID, buyoutPrice)) + continue + + if curTime > worldAuctionItem.EndTime: + #GameWorld.DebugLog(" %s 拍品已结束竞价, 不购买!itemID=%s" % (i, itemID)) + continue + + noticeMinutes = aucIpyData.GetNoticeSaleMinutes() + if noticeMinutes: + addTimeStr = worldAuctionItem.AddTime + addTime = GameWorld.ChangeTimeStrToNum(addTimeStr) + passMinutes = (curTime - addTime) / 60 + if passMinutes < noticeMinutes: + #GameWorld.DebugLog(" %s 拍品尚未开放竞价, 不购买!itemID=%s" % (i, itemID)) + continue + + aucItemClassLV = worldAuctionItem.ItemClassLV + # 本阶的直接处理 + if aucItemClassLV == classLV: + autoBuyItemList.append([worldAuctionItem, buyoutPrice]) + curRate += unSuitRate + buyEquipCostMoney += buyoutPrice + GameWorld.DebugLog(" %s 本阶优先购买!itemID=%s,classLV=%s,curRate=%s,buyoutPrice=%s,buyEquipCostMoney=%s" + % (i, itemID, classLV, curRate, buyoutPrice, buyEquipCostMoney)) + if curRate >= fullRate: + curRate = 100 + GameWorld.DebugLog(" 自动购买本阶概率已满足!curRate=%s" % (curRate)) + break + + # 其他阶的需要按阶的优先级进行处理 + else: + if aucItemClassLV not in autoBuyOtherClassItemDict: + autoBuyOtherClassItemDict[aucItemClassLV] = [] + classItemList = autoBuyOtherClassItemDict[aucItemClassLV] + classItemList.append([worldAuctionItem, buyoutPrice]) + GameWorld.DebugLog(" %s 非本阶, 暂不处理! itemID=%s,aucItemClassLV=%s" % (i, itemID, aucItemClassLV)) + + # 未满概率时再购买其他阶 + if curRate < 100: + lowClassList, highClassList = [], [] + for othClassLV in autoBuyOtherClassItemDict.keys(): + if othClassLV <= classLV: + lowClassList.append(othClassLV) + else: + highClassList.append(othClassLV) + lowClassList.sort(reverse=True) + highClassList.sort() + buyClassLVList = lowClassList + highClassList + GameWorld.DebugLog("本阶概率未满,检查购买其他阶! curRate=%s,buyClassLVList=%s" % (curRate, buyClassLVList)) + + diffClassChangeRatePerInfo = IpyGameDataPY.GetFuncEvalCfg("EquipStarRate", 1) + unSuitRateRange = IpyGameDataPY.GetFuncEvalCfg("EquipStarRate", 2) + for othClassLV in buyClassLVList: + classItemList = autoBuyOtherClassItemDict[othClassLV] + for worldAuctionItem, buyoutPrice in classItemList: + baseRate = unSuitRate + minRate, maxRate = unSuitRateRange + + costClassLV = worldAuctionItem.ItemClassLV + itemID = worldAuctionItem.ItemID + + #吞高阶 + if costClassLV > classLV: + diffClassChangeRatePer = diffClassChangeRatePerInfo[0] * (costClassLV - classLV) + addRate = int(math.ceil(round(baseRate * (100 + diffClassChangeRatePer) /100.0, 2))) + GameWorld.DebugLog(" 吞高阶 itemID=%s,costClassLV=%s,classLV=%s,baseRate=%s,diffClassChangeRatePer=%s,addRate=%s" + % (itemID, costClassLV, classLV, baseRate, diffClassChangeRatePer, addRate)) + #吞低阶 + elif costClassLV < classLV: + diffClassChangeRatePer = diffClassChangeRatePerInfo[1] * (classLV - costClassLV) + addRate = int(math.ceil(round(baseRate * (100 - diffClassChangeRatePer) /100.0, 2))) + GameWorld.DebugLog(" 吞低阶 itemID=%s,costClassLV=%s,classLV=%s,baseRate=%s,diffClassChangeRatePer=%s,addRate=%s" + % (itemID, costClassLV, classLV, baseRate, diffClassChangeRatePer, addRate)) + else: + addRate = baseRate + addRate = max(minRate, min(addRate, maxRate)) + + autoBuyItemList.append([worldAuctionItem, buyoutPrice]) + curRate += addRate + buyEquipCostMoney += buyoutPrice + GameWorld.DebugLog(" curRate=%s,buyoutPrice=%s,buyEquipCostMoney=%s" % (curRate, buyoutPrice, buyEquipCostMoney)) + if curRate >= fullRate: + GameWorld.DebugLog(" 自动购买补充其他阶概率已满足!curRate=%s" % (curRate)) + curRate = 100 + break + if curRate >= fullRate: + break + + totalCostMoney = lackItemCostMoney + buyEquipCostMoney + GameWorld.DebugLog(" lackItemCostMoney=%s,buyEquipCostMoney=%s,totalCostMoney=%s,curRate=%s" % (lackItemCostMoney, buyEquipCostMoney, totalCostMoney, curRate)) + if isAutoBuyPreview: + __SyncEquipStarAutoBuyCostInfo(curPlayer, classLV, equipPlace, curPartStar, curRate, totalCostMoney) + return + + if curRate < 100: + # 自动购买必须满概率 + # 因为确认购买不是实时的,所以存在拍卖行预览消耗装备可能被其他玩家买走导致无法满赶驴,所以这里需要补同步一次 + __SyncEquipStarAutoBuyCostInfo(curPlayer, classLV, equipPlace, curPartStar, curRate, totalCostMoney) + PlayerControl.NotifyCode(curPlayer, "AutoBuyEquipLackEquip") + return + + if playerGoldPaper < totalCostMoney: + # 因为确认购买不是实时的,所以存在拍卖行预览消耗的价格与实际购买可能出现消耗价格不一致的情况,所以这里需要补同步一次 + __SyncEquipStarAutoBuyCostInfo(curPlayer, classLV, equipPlace, curPartStar, curRate, totalCostMoney) + PlayerControl.NotifyCode(curPlayer, "AutoBuyEquipLackMoney", [IPY_PlayerDefine.TYPE_Price_Gold_Paper]) + return + + for worldAuctionItem, buyoutPrice in autoBuyItemList: + # 这里认为一定可以购买成功,不对返回值做处理,即使无法购买也认为购买成功,玩家的消耗照常扣除 + __DoPlayerBidAuctionItem(curPlayer, worldAuctionItem.ItemGUID, buyoutPrice, tick, False, funcAutoBuyout=True) + + return classLV, equipPlace, curPartStar, equipPackIndex, curRate, delEquipGUIDDict, delItemInfoDict, lackItemCostMoney, buyEquipCostMoney + +def __SyncEquipStarAutoBuyCostInfo(curPlayer, classLV, equipPlace, curPartStar, curRate, totalCostMoney): + ## 通知自动购买预览结果 + costInfo = ChPyNetSendPack.tagGCEquipStarAutoBuyCostInfo() + costInfo.ClassLV = classLV + costInfo.EquipPlace = equipPlace + costInfo.CurStar = curPartStar + costInfo.CurRate = curRate + costInfo.AutoBuyCostMoney = totalCostMoney + NetPackCommon.SendFakePack(curPlayer, costInfo) + return def __SyncRefreshAuctionItem(auctionItemList): ''' // B5 08 拍卖行刷新拍品 #tagGCRefreshAuctionItemInfo @@ -1874,11 +2070,11 @@ 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) +# 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 def DoAddFamilyAuctionItem(mapID, familyAuctionItemDict): -- Gitblit v1.8.0