| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
| #-------------------------------------------------------------------------------  | 
| #  | 
| ##@package AuctionHouse  | 
| #  | 
| # @todo:ÅÄÂôÐÐ  | 
| # @author hxp  | 
| # @date 2019-03-04  | 
| # @version 1.0  | 
| #  | 
| # ÏêϸÃèÊö: ÅÄÂôÐÐ  | 
| #  | 
| #-------------------------------------------------------------------------------  | 
| #"""Version = 2019-03-04 17:00"""  | 
| #-------------------------------------------------------------------------------  | 
| 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  | 
|   | 
| # ÅÄÂô¼Ç¼ÀàÐͶ¨Òå  | 
| 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  | 
|   | 
| '''  | 
| ¾º¼ÛÁ÷³Ì:   | 
| 1. MapServer ÏÈÑéÖ¤¼Û¸ñÊÇ·ñ¹»  | 
| 2. GameServer ÑéÖ¤ÊÇ·ñ¿ÉÒÔ¾º¼Û  | 
| 3. MapServer ¿Û³ýÍæ¼Ò»õ±Ò  | 
| 4. GameServer  ½øÐоº¼Û£¬±ä¸üÏ´ξº¼Û¼Û¸ñ  | 
|   | 
| »ùÓÚÒÔÉÏÁ÷³Ì£¬ËùÒÔÍæ¼Ò¾º¼ÛʱÐèÏÈËø¶¨ÎïÆ·£¬·ÀÖ¹¾º¼ÛÁ÷³ÌδÍê½áʱÆäËûÍæ¼ÒÇëÇ󾺼ÛͬһÅÄÆ·ÅжϾº¼Û¼Û¸ñ´íÎó  | 
| Ëø¶¨Ê±³¤Í¬ÑùÊÊÓÃÓÚÅÄÆ·¾º¼Ûʱ¼ä½áÊøÊ±µÄ±£»¤Ê±¼ä  | 
| '''  | 
| BiddingQueryLockTick = 10000  | 
|   | 
| #ÅÄÂôÐÐ״̬¿ª¹Ø  | 
| 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  | 
|       | 
|     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)  | 
|       | 
|     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  | 
|     GameWorld.DebugLog("ÅÄÆ·¼Óʱ: EndTime=%s,updEndTime=%s" % (auctionItem.EndTime, endTime))  | 
|     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 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[index]  | 
|         if curTime <= auctionItem.EndTime:  | 
|             break  | 
|         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:  | 
|             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])  | 
|           | 
|         AddAuctionRecord(auctionItem, AuctionRecordResult_MoveToWorld)  | 
|           | 
|         # Ìí¼Ó½øÎҵĹØ×¢  | 
|         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 # µ±Ç°¾º¼Û£¬ÓÐÈ˾º¼ÛµÄ»°´ú±í¾ºÅijɹ¦  | 
|         endType = ""  | 
|         # ÓÐÈ˾º¼Û£¬³É½»  | 
|         if bidderID and bidderPrice:  | 
|             endType = "OK"  | 
|               | 
|             # ¾ºÅijɹ¦Óʼþ£¬·¢·ÅÎïÆ·  | 
|             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) # ÏÉÃËÅÄÆ·¸öÈË×î´óÊÕÒæ°Ù·Ö±È  | 
|                 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))) # ÓÐÊÕÒæµÄÈËÆ½·Ö  | 
|                   | 
|                 # ÏÉÃËÅÄÆ·ÊÕÒæÓʼþ  | 
|                 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) # È«·þÅÄÆ·Ë°ÂÊ°Ù·Ö±È  | 
|                 taxGold = max(1, int(bidderPrice * taxRate / 100.0)) # ×îÉÙÊÕ˰1  | 
|                 givePlayerGold = max(0, bidderPrice - taxGold)  | 
|                   | 
|                 # ¸öÈËÅÄÂôÊÕÒæÓʼþ  | 
|                 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  | 
|     '''  | 
|       | 
|     isSortWorldItem = False  | 
|     notifyAddItemList = [] # ÐÂÔöÅÄÆ·Í¨Öª [[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  | 
|           | 
|         itemGUID = auctionItem.ItemGUID  | 
|         itemID = auctionItem.ItemID  | 
|         notifyAddItemList.append([itemGUID, itemID, playerID])  | 
|         if familyID:  | 
|             familyAddItemList = notifyFamilyAddItemDict.get(familyID, [])  | 
|             familyAddItemList.append(auctionItem)  | 
|             notifyFamilyAddItemDict[familyID] = familyAddItemList  | 
|         else:  | 
|             isSortWorldItem = True  | 
|               | 
|     if notifyAddItemList:  | 
|         __SortAuctionitem(isSortWorldItem=isSortWorldItem)  | 
|           | 
|     # Í¨ÖªÐÂÔöÏÉÃËÅÄÆ·  | 
|     for familyID, familyAddItemList in notifyFamilyAddItemDict.items():  | 
|         Sync_FamilyAuctionItemInfo(None, familyID, familyAddItemList)  | 
|           | 
|     # Í¨ÖªÅÄÆ·¹Ø×¢Íæ¼Ò  | 
|     __NotifyAuctionPlayerAddItem(notifyAddItemList)  | 
|     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(notifyAddItemList):  | 
|     ## Í¨Öª¹Ø×¢ÎïÆ·µÄÍæ¼ÒÐÂÉϼÜÎïÆ·ÁË  | 
|     if not notifyAddItemList:  | 
|         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 notifyAddItemList:  | 
|             if playerID and 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() * 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)):  | 
|         # ¾º¼Û¼Û¸ñ´íÎó  | 
|         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 < BiddingQueryLockTick:  | 
|             # ÓÐÍæ¼ÒÕýÔÚ¾º¼Û£¬ÇëÉÔµÈ  | 
|             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.BiddingQueryTick = 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  | 
|         refreshItem.BiddingTime = auctionItem.BiddingTime  | 
|         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, isNotify=True)  | 
|     return  | 
|   | 
| def __Sync_WorldAuctionItemQueryResult(curPlayer, job=0, itemTypeList=[], classLV=0, specItemIDList=[], fromItemGUID="", queryDir=1, queryCount=10, isNotify=False):  | 
|     ## ¸ù¾Ý¹ýÂËÌõ¼þͬ²½È«·þÅÄÆ·ÁÐ±í£¬Ä¿Ç°½öÈ«·þÅÄÆ·ÐèҪͨ¹ý²éѯ·þÎñÆ÷»ñµÃ£¬¸öÈËÅÄÆ·¼°ÏÉÃËÅÄÆ·ÓÉÓÚ¸öÊý½ÏÉÙÖ±½ÓÓÉÉÏÏß»ò±ä¸üʱÖ÷¶¯Í¬²½  | 
|       | 
|     fromAuctionItem = None  | 
|     if fromItemGUID:  | 
|         fromAuctionItem = GetAuctionItem(fromItemGUID)  | 
|         if not fromAuctionItem:  | 
|             GameWorld.DebugLog("²éѯµÄÄ¿±êÅÄÆ·²»´æÔÚ! fromItemGUID=%s" % fromItemGUID)  | 
|             if isNotify:  | 
|                 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)  | 
|             if isNotify:  | 
|                 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.BiddingTime = auctionItem.BiddingTime  | 
|         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.BiddingTime = attentionItem.BiddingTime  | 
|         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.BiddingTime = auctionItem.BiddingTime  | 
|         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.BiddingTime = auctionItem.BiddingTime  | 
|         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.BiddingTime = auctionItem.BiddingTime  | 
|         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  | 
|   |