| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
| #  | 
| #  | 
| ##@package PlayerBourse.py  | 
| #  | 
| # @todo:Íæ¼Ò½»Ò×Ëù¹ÜÀíÆ÷  | 
| #  | 
| # @author xmnathan  | 
| # @date 2010-01-01 21:30  | 
| # @version 1.5  | 
| # @note:  | 
| # @change: "2014-05-17 11:30" xmnathan Ôö¼Ó¿ª¹Ø  | 
| # @change: "2014-05-20 10:40" xmnathan Íæ¼Ò½»Ò×Ëù  | 
| # @change: "2014-05-21 20:00" xmnathan ÐÞÕý²éѯÊýÁ¿´íÎóµ¼Öµı¨´í  | 
| # @change: "2014-09-18 15:00" xmnathan Ôö¼Ó½»Ò×Á÷Ïò  | 
| # @change: "2014-10-20 18:00" xmnathan Ôö¼ÓÎïÆ·ÊÛ³ö²¹³¥ÓʼþÌáÐÑ  | 
| #------------------------------------------------------------------------------   | 
| """Version = 2014-10-20 18:00"""  | 
| #------------------------------------------------------------------------------   | 
| import GameWorld  | 
| import IPY_GameServer  | 
| import ChGameToMapPyPack  | 
| import NetPackCommon  | 
| import datetime  | 
| import PlayerDBGSEvent  | 
| import CommFunc  | 
| import PlayerControl  | 
| import DataRecordPack  | 
| import IpyGameDataPY  | 
| import PyGameDataStruct  | 
| import PyDataManager  | 
| import ChPyNetSendPack  | 
| import PyGameData  | 
|   | 
| import time  | 
| import json  | 
|   | 
|   | 
| g_lastSortTimeForQueryTypeDict = {}     #¼Ç¼¶ÔÓ¦²éѯÀàÐÍÉϴθüÐÂ×ÓË÷ÒýÁбíʱ¼ä  | 
| g_dict_Of_QueryTypeIndexList = {}       #´¢´æ¶ÔÓ¦²éѯÀàÐ͵ÄÅÅÐòÁбíµÄ×Öµä  | 
|   | 
| Def_Bourse_Buy = 0 # ¹ºÂò  | 
| Def_Bourse_Sell = 1 # Âô³ö  | 
|   | 
| #------------------------------------------------------------------------------   | 
| #½»Ò×Ëù״̬¿ª¹Ø  | 
| def GetOpenState():  | 
|     BourseDefState = IpyGameDataPY.GetFuncCfg('BourseDefState')  | 
|     return PlayerDBGSEvent.GetDBGSTrig_ByKey(PlayerDBGSEvent.Def_BourseState, BourseDefState)  | 
|       | 
| def SetOpenState(value):  | 
|     PlayerDBGSEvent.SetDBGSTrig_ByKey(PlayerDBGSEvent.Def_BourseState, value > 0)  | 
|     return  | 
| #------------------------------------------------------------------------------  | 
|   | 
| ##»ñȡָ¶¨²éѯÀàÐͶ¨ÒåÅäÖà  | 
| #  @param queryType  | 
| #  @return None  | 
| def GetBourseQueryTypeDefineDict(queryType):  | 
|     BourseQueryTypeDict = IpyGameDataPY.GetConfigEx("BourseQueryTypeDict")  | 
|     if BourseQueryTypeDict and queryType in BourseQueryTypeDict:  | 
|         return BourseQueryTypeDict[queryType]  | 
|     if not BourseQueryTypeDict:  | 
|         BourseQueryTypeDict = {}  | 
|   | 
|     ipyData = IpyGameDataPY.GetIpyGameData('MarketQuery', queryType)  | 
|     if not ipyData:  | 
|         return {}  | 
|     LimitInfo = ipyData.GetLimitInfo()  | 
|     BourseQueryTypeDict[queryType] = LimitInfo  | 
|           | 
|     IpyGameDataPY.SetConfigEx("BourseQueryTypeDict", BourseQueryTypeDict)  | 
|     return LimitInfo  | 
|       | 
| #------------------------------------------------------------------------------   | 
| ##1B 01 ²éÑ¯Íæ¼Ò½»Ò×ËùÎïÆ· tagCGQueryPlayerBourseItem  | 
| #  @param index   | 
| #  @param tick  | 
| #  @return None  | 
| def OnQueryPlayerBourseItem(index, tick):  | 
|     if not GetOpenState():  | 
|         return  | 
|     GameWorld.GetPsycoFunc(__Func_QueryPlayerBourseItem)(index, tick)  | 
|     return  | 
|   | 
| ##1B 01 ²éÑ¯Íæ¼Ò½»Ò×ËùÎïÆ· tagCGQueryPlayerBourseItem  | 
| #  @param index   | 
| #  @param tick  | 
| #  @return None  | 
| def __Func_QueryPlayerBourseItem(index, tick):  | 
|     GameWorld.DebugLog("Bourse### QueryPlayerBourseItem in")  | 
|     playerManager = GameWorld.GetPlayerManager()  | 
|     curPlayer = playerManager.GetPlayerByIndex(index)  | 
|     SyncPlayerBourseItem(curPlayer)  | 
|     GameWorld.DebugLog("Bourse### QueryPlayerBourseItem out")  | 
|       | 
| ##²éÑ¯Íæ¼Ò½»Ò×ËùÎïÆ·   | 
| #  @param curPlayer   | 
| #  @return None  | 
| def SyncPlayerBourseItem(curPlayer):  | 
|     if not GetOpenState():  | 
|         return  | 
|   | 
|     #֪ͨ¿Í»§¶ËÍæ¼Ò×Ô¼º¹Òµ¥ÎïÆ·ÁÐ±í  | 
|     curPlayer.Sync_PlayerBourseItem()  | 
|     return  | 
|   | 
| def CheckPlayerEarnings(curPlayer):  | 
|     ##Íæ¼ÒÂô³öÎïÆ·ÊÕÒæ·¢·Å  | 
|     curPlayerID = curPlayer.GetID()  | 
|     bourseManager = GameWorld.GetBourseManager()  | 
|     curPlayerItemCount = bourseManager.GetPlayerBourseItemCount(curPlayerID)  | 
|     DelItemList = []  | 
|     for i in xrange(curPlayerItemCount):  | 
|         curBourseItemData = bourseManager.GetPlayerBourseItemByIndex(curPlayerID, i)  | 
|         if not curBourseItemData:  | 
|             continue  | 
|         if curBourseItemData.GetIsSoldOut() and curBourseItemData.GetCustomerPlayerID() != 0 and \  | 
|                 curBourseItemData.GetCustomerPlayerID() != curBourseItemData.GetPlayerID():  | 
|             if __GivePlayerBourseGains(curBourseItemData):  | 
|                 DelItemList.append(curBourseItemData.GetItemGUID())  | 
|       | 
|     for itemGUID in DelItemList:  | 
|         bourseManager.DeleteByGUID(itemGUID)  | 
|     return  | 
|   | 
| ## Íæ¼ÒµÇ¼  | 
| def OnPlayerLogin(curPlayer):  | 
|     #֪ͨ½»Ò׼Ǽ  | 
|     PyDataManager.GetBourseRecordManager().SyncBourseRecord(curPlayer, True)  | 
|     #ÉÏÏß¼ì²éÂô³öµÄÎïÆ·¸øÂô¼ÒÊÕÒæ  | 
|     CheckPlayerEarnings(curPlayer)  | 
|     SyncPlayerBourseItem(curPlayer)  | 
|     return  | 
| #------------------------------------------------------------------------------    | 
| ##1B 05 ½»Ò×Ëù²éѯÉϼÜÎïÆ·#tagCGQueryBourseItemOnSale  | 
| #  @param index   | 
| #  @param tick  | 
| #  @return None  | 
| def OnQueryBourseItemOnSale(index, tick):  | 
|     if not GetOpenState():  | 
|         return  | 
|     GameWorld.GetPsycoFunc(__Func_QueryBourseItemOnSale)(index, tick)  | 
|     return  | 
|       | 
| ##1B 05 ½»Ò×Ëù²éѯÉϼÜÎïÆ·#tagCGQueryBourseItemOnSale  | 
| #  @param index   | 
| #  @param tick  | 
| #  @return None  | 
| def __Func_QueryBourseItemOnSale(index, tick):  | 
|     return  | 
|   | 
| #// B5 01 ½»Ò×Ëù²éѯÉϼÜÎïÆ·#tagCGPYQueryBourseItemOnSale  | 
| #  | 
| #struct    tagCGPYQueryBourseItemOnSale  | 
| #{  | 
| #    tagHead    Head;  | 
| #    DWORD    QueryType;    //²éѯµÄ·ÖÀà±êʶ  | 
| #    char    ItemName[33];    //ÎïÆ·Ãû£¨Ä£ºý²éѯ)  | 
| #    DWORD    ItemID;        //ÎïÆ·ID  | 
| #};  | 
| def OnPYQueryBourseItemOnSale(index, clientData, tick):  | 
|     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  | 
|     queryType = clientData.QueryType  | 
|     itemName = clientData.ItemName  | 
|     itemID = clientData.ItemID  | 
|     if itemName or itemID:  | 
|         bourseManager = GameWorld.GetBourseManager()  | 
|         bourseItemCount = bourseManager.Count()  | 
|          | 
|         #µ¹Ðò²éѯ,(×ܱí¸ù¾Ý²åÈëʱ¼äÅÅÐò£¬Ô½ÔçµÄÅÅÔÚÔ½Ç°Ãæ)  | 
|         bourseItemDataList = []  | 
|         for i in xrange(bourseItemCount - 1, -1, -1):  | 
|             curBourseItemData = bourseManager.At(i)  | 
|             if CheckBourseItemDataSaleState(curBourseItemData):  | 
|                 continue  | 
|             #GameWorld.Log("itemName=%s,curBourseItemData.GetItemName()=%s"%(itemName,curBourseItemData.GetItemName()))  | 
|             if itemName and itemName in curBourseItemData.GetItemName():  | 
|                 bourseItemDataList.append(curBourseItemData)  | 
|                 continue  | 
|             if itemID and itemID == curBourseItemData.GetItemTypeID():  | 
|                 bourseItemDataList.append(curBourseItemData)  | 
|                 continue  | 
|           | 
|         queryCount = len(bourseItemDataList)  | 
|         curPlayer.Begin_AddBourseItemOnSale(queryType, 0, queryCount, queryCount)  | 
|         for bourseItemData in bourseItemDataList:  | 
|             curPlayer.Add_BourseItemOnSale(bourseItemData)  | 
|         curPlayer.Sync_BourseItemOnSale()  | 
|         if itemID: #Èç¹ûÊDzéѯIDµÄ£¬Í¬Ê±Í¨Öª¸ÃÎïÆ·µÄ×îгɽ»¼Û  | 
|             PyDataManager.GetBourseItemLastPriceManager().SyncBourseItemPrice(curPlayer, itemID)  | 
|           | 
|     else:  | 
|         #¸ù¾Ý²éѯÀàÐÍ»ñÈ¡ÏàÓ¦»õÆ·ÁÐ±í  | 
|         queryTypeList = GetTypeList(queryType, tick)  | 
|         queryTypeCount = len(queryTypeList) #²éѯµ½µÄÎïÆ·×ÜÊý  | 
|         GameWorld.DebugLog("Bourse### QueryBourseItemOnSale queryTypeCount=%s, queryType=%s" % (queryTypeCount, queryType))  | 
|         curPlayer.Begin_AddBourseItemOnSale(queryType, 0, queryTypeCount, queryTypeCount)   | 
|         for i in xrange(queryTypeCount):  | 
|             curPlayer.Add_BourseItemOnSale(queryTypeList[i])  | 
|               | 
|         curPlayer.Sync_BourseItemOnSale()  | 
|       | 
|     GameWorld.DebugLog("Bourse### QueryBourseItemOnSale out")  | 
|     return  | 
|   | 
|   | 
| ##»ñµÃÖ¸¶¨²éѯÀàÐ͵ĻõÆ·ÁÐ±í  | 
| #  @param queryType   | 
| #  @return queryTypeList  | 
| def GetTypeList(queryType, tick):  | 
|     global g_lastSortTimeForQueryTypeDict  | 
|     global g_dict_Of_QueryTypeIndexList  | 
|       | 
|     lastSortTick = g_lastSortTimeForQueryTypeDict.get(queryType, 0)  | 
|       | 
|     queryTypeList = g_dict_Of_QueryTypeIndexList.get(queryType, None)  | 
|     Def_Sort_IndexList_Interval = IpyGameDataPY.GetFuncCfg('BourseUpdataCD')  #Îå·ÖÖÓ¸üÐÂÒ»´Î×ÓË÷ÒýÁÐ±í  | 
|     if queryTypeList == None or tick - lastSortTick > Def_Sort_IndexList_Interval:  | 
|         SortIndexList(queryType)#ÖØÐÂÅÅÐòÖ¸¶¨ÀàÐÍ  | 
|         lastSortTick = tick  | 
|         g_lastSortTimeForQueryTypeDict[queryType] = tick  | 
|           | 
|     return  g_dict_Of_QueryTypeIndexList.get(queryType, [])  | 
|   | 
| ##¶ÔÖ¸¶¨ÀàÐ͵ÄË÷ÒýÁÐ±í½øÐÐɸѡÅÅÐò  | 
| #  @param queryType   | 
| #  @return queryTypeList  | 
| def SortIndexList(queryType):  | 
|     global g_dict_Of_QueryTypeIndexList  | 
|     curQueryTypeList = []  | 
|     bourseManager = GameWorld.GetBourseManager()  | 
|     bourseItemCount = bourseManager.Count()  | 
|     #µ¹Ðò²éѯ,(×ܱí¸ù¾Ý²åÈëʱ¼äÅÅÐò£¬Ô½ÔçµÄÅÅÔÚÔ½Ç°Ãæ)  | 
|     for index in xrange(bourseItemCount - 1, -1, -1):  | 
|         curBourseItemData = bourseManager.At(index)  | 
|         if CheckBourseItemDataSaleState(curBourseItemData):  | 
|             continue  | 
|         #¸ù¾ÝÌõ¼þɸѡÎïÆ·  | 
|         if CheckQueryTypeItem(curBourseItemData, queryType):  | 
|             curQueryTypeList.append(curBourseItemData)  | 
|       | 
|     g_dict_Of_QueryTypeIndexList[queryType] = curQueryTypeList  | 
|     return     | 
|   | 
|   | 
| ##¼ì²éÎïÆ·ÊÇ·ñ·ûºÏµ±Ç°ÀàÐÍɸѡÌõ¼þ  | 
| #  @param curBourseItemData: ÎïÆ·ÊµÀý   | 
| #  @return IsSoldOut  | 
| def CheckQueryTypeItem(curBourseItemData, queryType):  | 
|     curDefineDict = GetBourseQueryTypeDefineDict(queryType)  | 
|     if curDefineDict == {}:  | 
|         return False  | 
|     #Ö¸¶¨ÎïÆ·ID  | 
|     SpecialItemIDList = curDefineDict.get("SpecialItemID", [])  | 
|     if SpecialItemIDList:  | 
|         if curBourseItemData.GetItemTypeID() not in SpecialItemIDList:  | 
|             return False  | 
|     #Ö¸¶¨ÎïÆ·ÀàÐÍ  | 
|     ItemTypeList = curDefineDict.get("ItemType", [])  | 
|     if ItemTypeList:  | 
|         if curBourseItemData.GetType() not in ItemTypeList:  | 
|             return False  | 
|     #Ö¸¶¨×°±¸×°±¸Î»Öà  | 
|     EquipPlaceList = curDefineDict.get("EquipPlace", [])  | 
|     if EquipPlaceList:  | 
|         if curBourseItemData.GetEquipPlace() not in EquipPlaceList:  | 
|             return False  | 
|     #Ö¸¶¨Ê¹ÓÃÖ°Òµ  | 
|     JobList = curDefineDict.get("Job", [])  | 
|     if JobList:  | 
|         JobLimit = curBourseItemData.GetJobLimit()  | 
|         if JobLimit not in JobList:  | 
|             return False  | 
|   | 
|     #Ö¸¶¨µÈ¼¶  | 
|     LimitUseLV = curDefineDict.get("LimitUseLV", [])  | 
|     if LimitUseLV:  | 
|         if curBourseItemData.GetUseLV() not in LimitUseLV:  | 
|             return False  | 
|           | 
|     #׿ԽÎïÆ·  | 
|     ItemQuality = curDefineDict.get("ItemQuality", [])   | 
|     if ItemQuality:  | 
|         if curBourseItemData.GetItemQuality() not in ItemQuality:  | 
|             return False  | 
|           | 
|     #Ì××°ÎïÆ·  | 
| #    IsSuite = curDefineDict.get("IsSuite", [])   | 
| #    if IsSuite:  | 
| #        if curBourseItemData.GetIsSuite() not in IsSuite:  | 
| #            return False  | 
|     return True  | 
|   | 
|   | 
| #------------------------------------------------------------------------------          | 
| ##¼ì²é¹Òµ¥ÎïÆ·ÊÇ·ñ³¬Ê±  | 
| #  @param curBourseItemData: ÎïÆ·ÊµÀý   | 
| #  @return IsSoldOut  | 
| def CheckBourseItemDataSaleState(curBourseItemData):  | 
|     if curBourseItemData.GetIsSoldOut():  | 
|         return True  | 
|   | 
|     return False  | 
|       | 
|       | 
| ##»ñµÃÓëÏÖʵʱ¼ä²î¾àµÄ·ÖÖÓÊý  | 
| # @param compareTimeStr ±È½Ïʱ¼ä×Ö·û Èç"2010-05-26 11:21:25"  | 
| # @return ·µ»ØÖµ, Ïà²îµÄ·ÖÖÓÊý  | 
| # @remarks »ñµÃÓëÏÖʵʱ¼ä²î¾àµÄ·ÖÖÓÊý  | 
| def GetPastMinute(compareTimeStr):  | 
|     curDataTime = datetime.datetime.today()  | 
|     compareDataTime = GameWorld.GetDateTimeByStr(compareTimeStr)  | 
|     if curDataTime == None or compareDataTime == None:  | 
|         return 0  | 
|     pastTimeDelta = curDataTime - compareDataTime  | 
|     #ÌìÊý * 24Сʱ * 60 ·ÖÖÓ + Ãë / 60  | 
|     return pastTimeDelta.days * 24 * 60 + pastTimeDelta.seconds / 60  | 
| #------------------------------------------------------------------------------   | 
| #//02 01 Ñ¯ÎÊÊÇ·ñ¿ÉÒÔÌí¼ÓÍæ¼Ò½»Ò×ËùÎïÆ·#tagMGCheckAddPlayerBourseItem  | 
| #{  | 
| #tagHead        Head;  | 
| #DWORD        PlayerID;  | 
| #BYTE        ItemIndex;  //ÎïÆ·ÔÚ±³°üÖÐË÷Òý  | 
| #WORD        Count;      //³öÊÛÊýÁ¿  | 
| #BYTE        PriceType;  //³öÊÛ¼Û¸ñÀàÐÍ  | 
| #DWORD        PriceCount;//³öÊÛ¼Û¸ñ  | 
| #char        Pwd[8];        //½»Ò×ÃÜÂë  | 
| #};  | 
| ##//02 01 Ñ¯ÎÊÊÇ·ñ¿ÉÒÔÌí¼ÓÍæ¼Ò½»Ò×ËùÎïÆ·#tagMGCheckAddPlayerBourseItem  | 
| #  @param routeIndex, mapID, curPackData, tick  | 
| #  @return None  | 
| def OnMGCheckAddPlayerBourseItem(routeIndex, mapID, curPackData, tick):  | 
|     GameWorld.DebugLog("Bourse### MGCheckAddPlayerBourseItem in,PlayerID %s" % curPackData.PlayerID)  | 
|     if not GetOpenState():  | 
|         return  | 
|     GameWorld.DebugLog("Bourse### MGCheckAddPlayerBourseItem PlayerID=%s ItemIndex=%s Count=%s PriceType=%s PriceCount=%s" % (curPackData.PlayerID,  | 
|                                                             curPackData.ItemIndex, curPackData.Count, curPackData.PriceType, curPackData.PriceCount))  | 
|     curPlayerID = curPackData.PlayerID   | 
|     bourseManager = GameWorld.GetBourseManager()  | 
|     count = bourseManager.GetPlayerBourseItemCount(curPlayerID)   | 
|     GameWorld.DebugLog("Bourse### MGCheckAddPlayerBourseItem now count %s" % count)     | 
|     BourseCountLimit = IpyGameDataPY.GetFuncCfg('BourseSaleLimit')  | 
|         | 
|     #//02 01 ²éÑ¯Íæ¼ÒÊÇ·ñ¿ÉÒÔÌí¼Ó½»Ò×ËùÎïÆ·½á¹û#tagGMCheckAddPlayerBourseItemResult  | 
|     sendPack = ChGameToMapPyPack.tagGMCheckAddPlayerBourseItemResult()    | 
|     sendPack.PlayerID = curPlayerID  | 
|     sendPack.ItemIndex = curPackData.ItemIndex  | 
|     sendPack.Count = curPackData.Count  | 
|     sendPack.PriceType = curPackData.PriceType  | 
|     sendPack.PriceCount = curPackData.PriceCount  | 
|     sendPack.Pwd = curPackData.Pwd  | 
|     sendPack.Result = (count < BourseCountLimit)    #·µ»Ø¿É·ñ¼ÌÐøÌí¼Ó  | 
|     NetPackCommon.SendPyPackToMapServer(routeIndex, mapID, sendPack)  | 
|     GameWorld.DebugLog("Bourse### MGCheckAddPlayerBourseItem out Result %s" % sendPack.Result)  | 
|     return  | 
|   | 
| ##//02 02 Íæ¼Ò½»Ò×ËùÌí¼Ó³öÊÛµÄÎïÆ·#tagMGAddPlayerSellBourseItem  | 
| #  @param routeIndex, mapID, curPackData, tick  | 
| #  @return None  | 
| def OnMGAddPlayerSellBourseItem(routeIndex, mapID, curPackData, tick):  | 
|     GameWorld.DebugLog("Bourse### MGAddPlayerSellBourseItem in")  | 
|     if not GetOpenState():  | 
|         return  | 
|     GameWorld.DebugLog("Bourse### MGAddPlayerSellBourseItem PlayerID %s" % (curPackData.PlayerID))  | 
|     curPlayerID = curPackData.PlayerID   | 
|     bourseManager = GameWorld.GetBourseManager()  | 
|   | 
|     curBourseRoleItem = IPY_GameServer.IpyBourseRoleItem()  | 
|     curBourseRoleItem.Count = curPackData.Count  | 
|     curBourseRoleItem.ItemID = curPackData.ItemTypeID  | 
|     curBourseRoleItem.UserData = curPackData.UserData  | 
|       | 
|     #GameWorld.DebugLog("Bourse### OnMGAddPlayerSellBourseItem UserData Src =¡¾%s¡¿ Des=¡¾%s¡¿"%(curPackData.UserData, curBourseRoleItem.UserData))  | 
|      | 
|     curBourseItem = bourseManager.AddItem(curPlayerID, curPackData.PlayerName, curBourseRoleItem)  | 
|       | 
|     #ÉèÖóöÊÛ¼Û¸ñ  | 
|     curBourseItem.SetPriceType(curPackData.PriceType)  | 
|     curBourseItem.SetPriceCount(curPackData.PriceCount)  | 
|     #´¢´æÐèÒªÓõ½µÄϵͳ±íÊý¾Ý  | 
|     curBourseItem.SetType(curPackData.Type)  | 
|     curBourseItem.SetEquipPlace(curPackData.EquipPlace)  | 
|     curBourseItem.SetLV(curPackData.LV)  | 
|     curBourseItem.SetUseLV(curPackData.UseLV)  | 
|     curBourseItem.SetJobLimit(curPackData.JobLimit)  | 
|     curBourseItem.SetItemQuality(curPackData.ItemQuality)  | 
|     curBourseItem.SetItemColor(curPackData.ItemColor)  | 
|     curBourseItem.SetItemTypeID(curPackData.ItemTypeID)  | 
|     curBourseItem.SetItemName(curPackData.ItemName.strip())  | 
|     curBourseItem.SetPwd(curPackData.Pwd.strip())  | 
|     curBourseItem.SetEquipGS(curPackData.EquipGS)  | 
|     curBourseItem.SetOperateInfo(curPackData.OperateInfo)  | 
|     #ÉèÖóöÊÛʱ¼ä  | 
|     curBourseItem.SetOnSaleTime(GameWorld.GetCurrentDataTimeStr())  | 
|     curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(curPlayerID)  | 
|     if curPlayer:  | 
|         #֪ͨ¿Í»§¶Ë Íæ¼Ò×Ô¼ºµÄ½»Òׯ·  | 
|         SyncPlayerBourseItem(curPlayer)  | 
|     #Á÷Ïò¼Ç¼  | 
|     DataRecordPack.DR_BourseAddItem(curPlayerID, curBourseItem)  | 
|     GameWorld.DebugLog("Bourse### MGAddPlayerSellBourseItem out")  | 
|     return  | 
| #------------------------------------------------------------------------------   | 
| ##//02 03 Íæ¼ÒѯÎʹºÂò½»Ò×ËùÎïÆ·#tagMGCheckBuyBourseItem  | 
| #  @param routeIndex, mapID, curPackData, tick  | 
| #  @return None  | 
| def OnMGCheckBuyBourseItem(routeIndex, mapID, curPackData, tick):  | 
|     GameWorld.DebugLog("Bourse### MGCheckBuyBourseItem in, PlayerID %s" % curPackData.PlayerID)  | 
|     if not GetOpenState():  | 
|         return  | 
|     bourseManager = GameWorld.GetBourseManager()  | 
|     curBourseItem = bourseManager.FindByGUID(curPackData.ItemGUID)  | 
|     if not curBourseItem:  | 
|         #ÎïÆ·²»´æÔÚ  | 
|         curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(curPackData.PlayerID)  | 
|         if curPlayer:  | 
|             PlayerControl.NotifyCode(curPlayer, "GeRen_liubo_403656")  | 
|         GameWorld.DebugLog("Bourse### MGCheckBuyBourseItem ItemGUID %s No Found" % (curPackData.ItemGUID))  | 
|         return   | 
|       | 
|     if curBourseItem.GetPlayerID() == curPackData.PlayerID:  | 
|         #ÊÇ×Ô¼ºµÄ¶«Î÷ ²»ÄÜÂò  | 
|         GameWorld.DebugLog("Bourse### MGCheckBuyBourseItem ItemGUID %s is SelfItem" % (curPackData.ItemGUID))  | 
|         return  | 
|     if curBourseItem.GetIsSoldOut():  | 
|         #ÎïÆ·ÒÑÊÛ³ö  | 
|         curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(curPackData.PlayerID)  | 
|         if curPlayer:  | 
|             PlayerControl.NotifyCode(curPlayer, "GeRen_liubo_403656")  | 
|         GameWorld.DebugLog("Bourse### MGCheckBuyBourseItem ItemGUID %s is SoldOut" % (curPackData.ItemGUID))  | 
|         return  | 
|     #¼ì²é½»Ò×ÃÜÂë  | 
|     if curBourseItem.GetPwd().strip() != curPackData.Pwd.strip():  | 
|         curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(curPackData.PlayerID)  | 
|         if curPlayer:  | 
|             PlayerControl.NotifyCode(curPlayer, "BoursePasswordError")  | 
|         GameWorld.DebugLog("Bourse### MGCheckBuyBourseItem ItemGUID %s  pwd is error! %s != %s" % (curPackData.ItemGUID, curBourseItem.GetPwd(), curPackData.Pwd))  | 
|         return  | 
|     #ÎïÆ·½»Ò×Ëø¶¨×´Ì¬ÅÐ¶Ï  | 
|     curTime = int(time.time())  | 
|     if curPackData.ItemGUID in PyGameData.g_bourseItemTradingTimeDict:  | 
|         if curTime - PyGameData.g_bourseItemTradingTimeDict.get(curPackData.ItemGUID, 0) < 10:  | 
|             curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(curPackData.PlayerID)  | 
|             if curPlayer:  | 
|                 PlayerControl.NotifyCode(curPlayer, "MarketNoPutaway5")  | 
|             return  | 
|     PyGameData.g_bourseItemTradingTimeDict[curPackData.ItemGUID] = curTime  | 
|       | 
|     #//02 02 Íæ¼Ò¹ºÂò½»Ò×ËùÎïÆ·²éѯ½á¹û#tagGMCheckBuyBourseItemResult  | 
|     sendPack = ChGameToMapPyPack.tagGMCheckBuyBourseItemResult()  | 
|     sendPack.PlayerID = curPackData.PlayerID  | 
|     sendPack.ItemGUID = curPackData.ItemGUID  | 
|     sendPack.PriceType = curBourseItem.GetPriceType()  | 
|     sendPack.PriceCount = curBourseItem.GetPriceCount()  | 
|     sendPack.ItemName = curBourseItem.GetItemName()  | 
|   | 
|     NetPackCommon.SendPyPackToMapServer(routeIndex, mapID, sendPack)  | 
|     GameWorld.DebugLog("Bourse### MGCheckBuyBourseItem out")  | 
|     return  | 
|   | 
|   | 
| ##//02 04 Íæ¼ÒÈ·ÈϹºÂò½»Ò×ËùÎïÆ·#tagMGBuyBourseItemSure  | 
| #  @param routeIndex, mapID, curPackData, tick  | 
| #  @return None  | 
| def OnMGBuyBourseItemSure(routeIndex, mapID, curPackData, tick):  | 
|     GameWorld.DebugLog("Bourse### MGBuyBourseItemSure in, PlayerID %s" % curPackData.PlayerID)  | 
|     if not GetOpenState():  | 
|         return  | 
|     curPlayerID = curPackData.PlayerID   | 
|     bourseManager = GameWorld.GetBourseManager()  | 
|     curBourseItem = bourseManager.FindByGUID(curPackData.ItemGUID)  | 
|     if not curBourseItem:  | 
|         #ÎïÆ·²»´æÔÚ  | 
|         GameWorld.Log("Íæ¼ÒÈ·ÈϹºÂò½»Ò×ËùÎïÆ· ÒѸ¶Ç®£¡£¬Bourse### MGBuyBourseItemSure ItemGUID %s No Found" % (curPackData.ItemGUID), curPlayerID)  | 
|         return  | 
|       | 
|     if CheckBourseItemDataSaleState(curBourseItem):  | 
|         GameWorld.Log("Íæ¼ÒÈ·ÈϹºÂò½»Ò×ËùÎïÆ· Bourse### MGBuyBourseItemSure ItemGUID %s SoldOut" % (curPackData.ItemGUID), curPlayerID)  | 
|         return  | 
|     if not curPackData.PlayerName: #Ϊ¿Õʱ´ú±íµØÍ¼ÅжϹºÂòʧ°Ü  | 
|         PyGameData.g_bourseItemTradingTimeDict.pop(curPackData.ItemGUID, 0)  | 
|         return  | 
|       | 
|     #¸øÎïÆ·//02 03 Íæ¼Ò»ñÈ¡½»Ò×ËùÎïÆ·½á¹û#tagGMGiveBourseItem  | 
|     sendPack = GetGMGiveBourseItemPack(curPlayerID, curBourseItem)  | 
|     NetPackCommon.SendPyPackToMapServer(routeIndex, mapID, sendPack)  | 
|     #ÉèÖý»Òׯ·ÎªÒÑÊÛ³ö״̬  | 
|     curBourseItem.SetIsSoldOut(True)  | 
|     curBourseItem.SetCustomerPlayerID(curPlayerID)  | 
|     curBourseItem.SetCustomerPlayerName(curPackData.PlayerName)  | 
|     soldOutTime = int(time.time())  | 
|     curBourseItem.SetSoldOutTime(str(soldOutTime))  | 
|     PyGameData.g_bourseItemTradingTimeDict.pop(curPackData.ItemGUID, 0)  | 
|     #֪ͨ¹Ë¿Í¹ºÂòÎïÆ·×´Ì¬±ä¸ü      | 
|     curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(curPlayerID)  | 
|     if curPlayer:  | 
|         curPlayer.Begin_AddBourseItemOnSale(255, 0, 1, 1)  | 
|         curPlayer.Add_BourseItemOnSale(curBourseItem)  | 
|         curPlayer.Sync_BourseItemOnSale()   | 
|           | 
|      | 
|     #¸üÐÂ×îгɽ»µ¥¼Û  | 
|     unitPrice = curBourseItem.GetPriceCount() * 1.0 / curBourseItem.GetBourseRoleItem().Count  | 
|     unitPrice = 200000000 if unitPrice < 1 else int(unitPrice) #200000000ÓÃÀ´´ú±í<1  | 
|     PyDataManager.GetBourseItemLastPriceManager().UpdateBourseItemPrice(curBourseItem.GetItemTypeID(), unitPrice)  | 
|     bourseRecordMgr = PyDataManager.GetBourseRecordManager()  | 
|     curRoleItemData = curBourseItem.GetBourseRoleItem()  | 
|     itemInfo = {"itemID":curRoleItemData.ItemID, "userData":curRoleItemData.UserData, "equipGS":curBourseItem.GetEquipGS(), "count":curRoleItemData.Count}  | 
|     bourseRecordMgr.AddBourseRecord(curPlayerID, Def_Bourse_Buy, soldOutTime, itemInfo, 0, curBourseItem.GetPriceCount())  | 
|     sellPlayerID = curBourseItem.GetPlayerID()  | 
|       | 
|     ##Á÷Ïò¼Ç¼  | 
|     DataRecordPack.DR_BourseBuyItem(curPlayerID, curBourseItem.GetPlayerID(), curBourseItem)  | 
|     if __GivePlayerBourseGains(curBourseItem):  | 
|         bourseManager.DeleteByGUID(curBourseItem.GetItemGUID())  | 
|       | 
|     curSellPlayer = GameWorld.GetPlayerManager().FindPlayerByID(sellPlayerID)  | 
|     if curSellPlayer:  | 
|         #Íæ¼ÒÔÚÏß  Ë¢ÐÂÍæ¼Ò½»Ò×ËùÎïÆ·  | 
|         SyncPlayerBourseItem(curSellPlayer)   | 
|           | 
|     GameWorld.DebugLog("Bourse### MGBuyBourseItemSure out ItemGUID %s" % (curPackData.ItemGUID))  | 
|     return  | 
|   | 
| def __GivePlayerBourseGains(curBourseItem):  | 
|     ##¶«Î÷Âô³ö£¬·¢ÖÁmapServer¸øÊÕÒæ  | 
|     curPlayerID = curBourseItem.GetPlayerID()  | 
|     curSellPlayer = GameWorld.GetPlayerManager().FindPlayerByID(curPlayerID)  | 
|     if not curSellPlayer:  | 
|         return  | 
|     #¸øÇ®  | 
|     curRoleItemData = curBourseItem.GetBourseRoleItem()  | 
|     itemInfo = {"itemID":curRoleItemData.ItemID, "userData":curRoleItemData.UserData, "equipGS":curBourseItem.GetEquipGS(), "count":curRoleItemData.Count}  | 
|     priceCount = curBourseItem.GetPriceCount()  | 
|     priceType = curBourseItem.GetPriceType()  | 
|     itemName = curBourseItem.GetItemName()  | 
|     soldOutTime = GameWorld.ToIntDef(curBourseItem.GetSoldOutTime(), 0)  | 
|     result = str([priceType, priceCount, itemName, soldOutTime, itemInfo])  | 
|     curSellPlayer.MapServer_QueryPlayerResult(0, 0, "GivePlayerBourseGains", result, len(result))  | 
|       | 
|     #Í¨ÖªÍæ¼Ò½»Ò×ËùÎïÆ·±ä¸ü  | 
|     #SyncPlayerBourseItem(curSellPlayer)  | 
|     return True  | 
|   | 
| def OnGivePlayerBourseGainsResult(curPlayer, resultInfo):  | 
|     #±£´æ½»Ò׼Ǽ  | 
|     soldOutTime, taxMoney, giveMoney, itemInfo = resultInfo  | 
|     bourseRecordMgr = PyDataManager.GetBourseRecordManager()  | 
|     bourseRecordMgr.AddBourseRecord(curPlayer.GetID(), Def_Bourse_Sell, soldOutTime, itemInfo, taxMoney, giveMoney)  | 
|       | 
|     DataRecordPack.DR_BourseGiveGains(curPlayer.GetID(), itemInfo, giveMoney, taxMoney)  | 
|     return  | 
|   | 
| #------------------------------------------------------------------------------   | 
| ##//02 05 ½»Ò×ËùÍæ¼ÒÈ¡ÏÂÕýÔÚ³öÊÛµÄÎïÆ·»ò³öÊÛÊÕÒæ#tagMGPlayerRecaptureBourseItem  | 
| #  @param routeIndex, mapID, curPackData, tick  | 
| #  @return None  | 
| def OnMGPlayerRecaptureBourseItem(routeIndex, mapID, curPackData, tick):  | 
|     GameWorld.DebugLog("Bourse### MGPlayerRecaptureBourseItem in PlayerID %s ItemGUID %s" % (curPackData.PlayerID, curPackData.ItemGUID))  | 
|     if not GetOpenState():  | 
|         return  | 
|     curPlayerID = curPackData.PlayerID   | 
|     bourseManager = GameWorld.GetBourseManager()  | 
|       | 
|     curBourseItem = bourseManager.FindByGUID(curPackData.ItemGUID)  | 
|     if not curBourseItem:  | 
|         #ÎïÆ·²»´æÔÚ  | 
|         GameWorld.DebugLog("Bourse### MGPlayerRecaptureBourseItem ItemGUID %s No Found" % (curPackData.ItemGUID))  | 
|         return   | 
|   | 
|     if curBourseItem.GetPlayerID() != curPlayerID:  | 
|         #²»ÊÇ×Ô¼ºµÄ¶«Î÷ ²»ÄÜÈ¡»Ø  | 
|         GameWorld.DebugLog("Bourse### MGPlayerRecaptureBourseItem ItemGUID %s not belong to Player %s" % (curPackData.ItemGUID, curPlayerID))  | 
|         return  | 
|     if curBourseItem.GetIsSoldOut() and curBourseItem.GetCustomerPlayerID() != 0 and \  | 
|                 curBourseItem.GetCustomerPlayerID() != curBourseItem.GetPlayerID():  | 
|           | 
|         #¸øÇ®//02 04 Íæ¼Ò»ñµÃ½»Ò×ËùÊÕÒæ#tagGMGivePlayerBourseGains  | 
| #        sendPack = ChGameToMapPyPack.tagGMGivePlayerBourseGains()  | 
| #        sendPack.PlayerID = curPlayerID  | 
| #        sendPack.MoneyType = curBourseItem.GetPriceType()  | 
| #        sendPack.MoneyCount = curBourseItem.GetPriceCount()  | 
| #        NetPackCommon.SendPyPackToMapServer(routeIndex, mapID, sendPack)  | 
| #        ##Á÷Ïò¼Ç¼  | 
| #        DataRecordPack.DR_BourseGiveGains(curPlayerID, curBourseItem)  | 
|         GameWorld.DebugLog("Bourse### MGPlayerRecaptureBourseItem ItemGUID %s GivePlayerBourseGains" % (curPackData.ItemGUID))  | 
|     else:  | 
|         if curPackData.PackSpaceCount <= 0:  | 
|             #Íæ¼Ò±³°ü¿Õ¼ä²»×ã ²»ÄܸøÎïÆ·  | 
|             GameWorld.DebugLog("Bourse### MGPlayerRecaptureBourseItem PlayerID %s noSpaceCount" % curPlayerID)  | 
|             return  | 
|         #¸øÎïÆ·//02 03 Íæ¼Ò»ñÈ¡½»Ò×ËùÎïÆ·½á¹û#tagGMGiveBourseItem  | 
|         sendPack = GetGMGiveBourseItemPack(curPlayerID, curBourseItem)  | 
|         NetPackCommon.SendPyPackToMapServer(routeIndex, mapID, sendPack)  | 
|         ##Á÷Ïò¼Ç¼  | 
|         DataRecordPack.DR_BourseCancelItem(curPlayerID, curBourseItem)  | 
|         GameWorld.DebugLog("Bourse### MGPlayerRecaptureBourseItem ItemGUID %s GiveBourseItem" % (curPackData.ItemGUID))  | 
|          | 
|     #ɾ³ý½»Òׯ·  | 
|     bourseManager.DeleteByGUID(curPackData.ItemGUID)  | 
|       | 
|     curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(curPlayerID)   | 
|     if curPlayer:  | 
|         #Í¨ÖªÍæ¼Ò½»Ò×ËùÎïÆ·±ä¸ü  | 
|         SyncPlayerBourseItem(curPlayer)    | 
|     GameWorld.DebugLog("Bourse### MGPlayerRecaptureBourseItem out")  | 
|     return  | 
|   | 
| ##¸ù¾Ý½»Ò×ËùÎïÆ·»ñÈ¡¸øÎïÆ··â°ü//02 03 Íæ¼Ò»ñÈ¡½»Ò×ËùÎïÆ·½á¹û#tagGMGiveBourseItem  | 
| #  @param curPlayerID, curBourseItem  | 
| #  @return sendPack  | 
| def GetGMGiveBourseItemPack(curPlayerID, curBourseItem):   | 
|     #//02 03 Íæ¼Ò»ñÈ¡½»Ò×ËùÎïÆ·½á¹û#tagGMGiveBourseItem   | 
|     sendPack = ChGameToMapPyPack.tagGMGiveBourseItem()  | 
|     sendPack.PlayerID = curPlayerID  | 
|     sendPack.ItemGUID = curBourseItem.GetItemGUID()  | 
|     sendPack.PriceType = curBourseItem.GetPriceType()  | 
|     sendPack.PriceCount = curBourseItem.GetPriceCount()  | 
|     if curPlayerID == curBourseItem.GetPlayerID():  | 
|         sendPack.PriceType = 0  | 
|         sendPack.PriceCount = 0   #×Ô¼ºµÄ¶«Î÷ ²»Óø¶Ç®   | 
|     curRoleItemData = curBourseItem.GetBourseRoleItem()  | 
|     sendPack.ItemID = curRoleItemData.ItemID  | 
|     sendPack.Count = curRoleItemData.Count  | 
|     sendPack.UserData = curRoleItemData.UserData  | 
|     sendPack.UserDataLen = len(curRoleItemData.UserData)  | 
|     sendPack.EquipGS = curBourseItem.GetEquipGS()  | 
|     return sendPack  | 
|   | 
| #------------------------------------------------------------------------------   | 
| ##УÑé¹ýÆÚ¹ý¾ÃÎïÆ·´¦Àí  | 
| #  @param None  | 
| #  @return None  | 
| def OverTimeItemsDeal():  | 
|     BourseSaleTimeMinute = IpyGameDataPY.GetFuncCfg('BourseSaleLimit', 2)  | 
|       | 
|     DelItemDict = {}  | 
|     bourseManager = GameWorld.GetBourseManager()  | 
|     bourseItemCount = bourseManager.Count()  | 
|     #µ¹Ðò²éѯ,(×ܱí¸ù¾Ý²åÈëʱ¼äÅÅÐò£¬Ô½ÔçµÄÅÅÔÚÔ½Ç°Ãæ)  | 
|     for index in xrange(bourseItemCount - 1, -1, -1):  | 
|         curBourseItemData = bourseManager.At(index)  | 
|         if CheckBourseItemDataSaleState(curBourseItemData):  | 
|             #ÎïÆ·ÒѳöÊÛ״̬  | 
|             continue  | 
| #        if curBourseItemData.GetPlayerID() != curBourseItemData.GetCustomerPlayerID():  | 
| #            #¹ºÂòÕßΪ³öÊÛÕß×Ô¼º  | 
| #            continue  | 
|         #УÑéÊÇ·ñ³¬Ê±  | 
|         pastMinute = GetPastMinute(curBourseItemData.GetOnSaleTime())  | 
|         if pastMinute < BourseSaleTimeMinute:  | 
|             continue  | 
|         #ÕÒµ½³¬Ê±ÒѾõÄÎïÆ·£¬É¾³ýÎïÆ·£¬·¢Ë͵½ÓʼþÖÐ  | 
|         sellPlayerID = curBourseItemData.GetPlayerID()  | 
|         bourseRoleItem = curBourseItemData.GetBourseRoleItem()  | 
|         addItemList = []  | 
|         curItemDict = {}  | 
|         curItemDict['ItemID'] = curBourseItemData.GetItemTypeID()  | 
|         curItemDict['Count'] = bourseRoleItem.Count  | 
|         curItemDict['UserData'] = bourseRoleItem.UserData  | 
|           | 
|         addItemList.append(curItemDict)  | 
|         GUID = curBourseItemData.GetItemGUID()  | 
|         if sellPlayerID in DelItemDict:  | 
|             DelItemDict[sellPlayerID].append(GUID)  | 
|         else:  | 
|             DelItemDict[sellPlayerID] = [GUID]  | 
|         #Á÷Ïò¼Ç¼  | 
|         DataRecordPack.DR_BourseDeleteOverTimeLongItem(sellPlayerID, GUID, curBourseItemData)  | 
|           | 
|         #½«ÎïÆ··¢Ë͵½²¹³¥ÓʼþÖÐ  | 
|         SendOverTimeItemMail(sellPlayerID, GUID, addItemList)  | 
|           | 
|     #ÒÆ³ý¸Ã½»Ò×ËùÎïÆ·  | 
|     for sellPlayerID, itemGUIDList in DelItemDict.items():  | 
|         for itemGUID in itemGUIDList:  | 
|             bourseManager.DeleteByGUID(itemGUID)  | 
|         curSellPlayer = GameWorld.GetPlayerManager().FindPlayerByID(sellPlayerID)  | 
|         if curSellPlayer:  | 
|             #Íæ¼ÒÔÚÏß  Ë¢ÐÂÍæ¼Ò½»Ò×ËùÎïÆ·  | 
|             SyncPlayerBourseItem(curSellPlayer)  | 
|     return  | 
|    | 
|   | 
|   | 
| ##·¢Ë͹ýÆÚ¹ý¾ÃÎïÆ·µ½Óʼþ  | 
| #  @param sellPlayerID, addItemList  | 
| #  @return None  | 
| def SendOverTimeItemMail(sellPlayerID, GUID, addItemList):  | 
|     import PlayerCompensation  | 
|       | 
|     PlayerCompensation.SendMailByKey('BourseTimeOut', [sellPlayerID], addItemList, [])  | 
|     return  | 
|       | 
|   | 
|   | 
| # ½»Ò×Ëù¼Ç¼¹ÜÀí  | 
| class BourseRecordManager(object):  | 
|       | 
|     maxRecord = IpyGameDataPY.GetFuncCfg("BourseMaxRecord") # Ã¿È˼Ǽ×î´óÊýÁ¿  | 
|       | 
|     def __init__(self):  | 
|         self.BourseRecord = {}     # {playerID:[record,..], ...} PyGameDataStruct.tagDBPyBourseRecord  | 
|         return  | 
|   | 
|     def AddBourseRecord(self, playerID, tradeType, soldOutTime, itemInfo, taxMoney, giveMoney):  | 
|         if not self.maxRecord:  | 
|             return  | 
|          | 
|         recordList = self.BourseRecord.get(playerID, [])  | 
|         if len(recordList) == self.maxRecord:  | 
|             del recordList[0] #ɾ³ýµÚÒ»Ìõ¼Ç¼  | 
|           | 
|           | 
|         userData = json.dumps(itemInfo, ensure_ascii=False)  | 
|           | 
|         record = PyGameDataStruct.tagDBPyBourseRecord()  | 
|         record.clear()  | 
|         record.PlayerID = playerID  | 
|         record.Type = tradeType   | 
|         record.Timestamp = soldOutTime#int(time.time())  | 
|         record.TradeTax = taxMoney  | 
|         record.TradeMoney = giveMoney  | 
|         record.UserData = userData  | 
|         record.UserDataLen = len(record.UserData)  | 
|         recordList.append(record)  | 
|         | 
|         self.BourseRecord[playerID] = recordList  | 
|         GameWorld.DebugLog("AddBourseRecord playerID=%s,tradeType=%s,userData=%s"   | 
|                            % (playerID, tradeType, userData), playerID)  | 
|           | 
|         # Í¬²½¿Í»§¶Ë  | 
|         curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)  | 
|         if curPlayer:  | 
|             self.SyncBourseRecord(curPlayer)  | 
|         return True  | 
|       | 
|       | 
|     def SyncBourseRecord(self, curPlayer, isAll=False):  | 
|         '''  | 
|         @param isAll: ÊÇ·ñÈ«²¿  | 
|         '''  | 
|         playerID = curPlayer.GetPlayerID()  | 
|         recordList = self.BourseRecord.get(playerID, [])  | 
|         syncList = recordList if isAll else [recordList[-1]]  | 
|         if not syncList:  | 
|             return  | 
|               | 
|         recordInfo = ChPyNetSendPack.tagGCBourseRecordInfo()  | 
|         recordInfo.Clear()  | 
|         recordInfo.RecordList = []  | 
|         for syncRecord in syncList:  | 
|             record = ChPyNetSendPack.tagGCBourseRecord()  | 
|             record.Clear()  | 
|             record.Type = syncRecord.Type  | 
|             record.Timestamp = syncRecord.Timestamp  | 
|             record.TradeTax = syncRecord.TradeTax  | 
|             record.TradeMoney = syncRecord.TradeMoney  | 
|             record.ItemData = syncRecord.UserData  | 
|             record.ItemDataLen = len(record.ItemData)  | 
|             recordInfo.RecordList.append(record)  | 
|         recordInfo.Count = len(recordInfo.RecordList)  | 
|         NetPackCommon.SendFakePack(curPlayer, recordInfo)  | 
|         return  | 
|       | 
|     # ±£´æÊý¾Ý ´æÊý¾Ý¿âºÍrealtimebackup  | 
|     def GetSaveData(self):  | 
|         savaData = ""  | 
|         cntData = ""  | 
|         cnt = 0  | 
|         for recordList in self.BourseRecord.values():  | 
|             for record in recordList:  | 
|                 cnt += 1  | 
|                 savaData += record.getBuffer()  | 
|                   | 
|         GameWorld.Log("SaveBourseRecord cnt :%s len=%s" % (cnt, len(savaData)))  | 
|         return CommFunc.WriteDWORD(cntData, cnt) + savaData  | 
|       | 
|     # ´ÓÊý¾Ý¿âÔØÈëºÃÓÑÊý¾Ý  | 
|     def LoadPyGameData(self, datas, pos, dataslen):  | 
|         cnt, pos = CommFunc.ReadDWORD(datas, pos)  | 
|         GameWorld.Log("LoadBourseRecord cnt :%s" % cnt)  | 
|           | 
|         self.BourseRecord = {}  | 
|           | 
|         for _ in xrange(cnt):  | 
|             record = PyGameDataStruct.tagDBPyBourseRecord()  | 
|             record.clear()  | 
|             pos += record.readData(datas, pos, dataslen)  | 
|               | 
|             playerID = record.PlayerID  | 
|             recordList = self.BourseRecord.get(playerID, [])  | 
|             recordList.append(record)  | 
|             self.BourseRecord[playerID] = recordList  | 
|               | 
|         return pos  | 
|   | 
| # ½»Ò×ËùÎïÆ·×î½ü³É½»µ¥¼Û¹ÜÀí  | 
| class BourseItemLastPriceManager(object):  | 
|          | 
|     def __init__(self):  | 
|         self.ItemLastPriceDict = {}     # {itemid:price, ...} PyGameDataStruct.tagDBPyBourseItemLastPrice  | 
|         return  | 
|   | 
|     def UpdateBourseItemPrice(self, itemid, price):  | 
|         itemLastPrice = PyGameDataStruct.tagDBPyBourseItemLastPrice()  | 
|         itemLastPrice.clear()  | 
|         itemLastPrice.ItemID = itemid  | 
|         itemLastPrice.LastPrice = price  | 
|         self.ItemLastPriceDict[itemid] = itemLastPrice  | 
|           | 
|         GameWorld.DebugLog("¸üн»Ò×ËùÎïÆ·×îгɽ»µ¥¼Û itemid=%s,price=%s" % (itemid, price))  | 
|         return  | 
|       | 
|       | 
|     def SyncBourseItemPrice(self, curPlayer, itemID):  | 
|         priceData = self.ItemLastPriceDict.get(itemID, None)  | 
|         if not priceData:  | 
|             return  | 
|           | 
|         priceInfo = ChPyNetSendPack.tagGCBourseItemPrice()  | 
|         priceInfo.Clear()  | 
|         priceInfo.ItemID = priceData.ItemID  | 
|         priceInfo.Price = priceData.LastPrice  | 
|         NetPackCommon.SendFakePack(curPlayer, priceInfo)  | 
|         return  | 
|       | 
|     # ±£´æÊý¾Ý ´æÊý¾Ý¿âºÍrealtimebackup  | 
|     def GetSaveData(self):  | 
|         savaData = ""  | 
|         cntData = ""  | 
|         cnt = 0  | 
|         for itemLastPrice in self.ItemLastPriceDict.values():  | 
|             cnt += 1  | 
|             savaData += itemLastPrice.getBuffer()  | 
|                   | 
|         GameWorld.Log("SaveBourseItemLastPrice cnt :%s len=%s" % (cnt, len(savaData)))  | 
|         return CommFunc.WriteDWORD(cntData, cnt) + savaData  | 
|       | 
|     # ´ÓÊý¾Ý¿âÔØÈëºÃÓÑÊý¾Ý  | 
|     def LoadPyGameData(self, datas, pos, dataslen):  | 
|         cnt, pos = CommFunc.ReadDWORD(datas, pos)  | 
|         GameWorld.Log("LoadBourseItemLastPrice cnt :%s" % cnt)  | 
|           | 
|         self.ItemLastPriceDict = {}  | 
|           | 
|         for _ in xrange(cnt):  | 
|             data = PyGameDataStruct.tagDBPyBourseItemLastPrice()  | 
|             data.clear()  | 
|             pos += data.readData(datas, pos, dataslen)  | 
|             itemid = data.ItemID  | 
|             self.ItemLastPriceDict[itemid] = data  | 
|               | 
|         return pos  |