| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
| #-------------------------------------------------------------------------------  | 
| #  | 
| ##@package GameWorldMineArea  | 
| #  | 
| # @todo:¿óÎ︣µØ  | 
| # @author hxp  | 
| # @date 2024-03-07  | 
| # @version 1.0  | 
| #  | 
| # ÏêϸÃèÊö: ¿óÎ︣µØ  | 
| #  | 
| #-------------------------------------------------------------------------------  | 
| #"""Version = 2024-03-07 19:30"""  | 
| #-------------------------------------------------------------------------------  | 
|   | 
| import GameWorld  | 
| import NetPackCommon  | 
| import PyDataManager  | 
| import ChPyNetSendPack  | 
| import PyGameDataStruct  | 
| import PlayerCompensation  | 
| import PlayerViewCache  | 
| import PlayerDBGSEvent  | 
| import PlayerControl  | 
| import IpyGameDataPY  | 
| import ShareDefine  | 
| import CommFunc  | 
|       | 
| import operator  | 
| import random  | 
| import time  | 
| import uuid  | 
|   | 
| Def_FakeAreaCount = 50 # ¼ÙÈ˸£µØ¸öÊý£¬Ò»°ã¾ÍǰÆÚÓÐÓã¬ÉÏÏߺóÖ»Äܵ÷´ó£¬²»µ÷С  | 
|   | 
| Def_RecordMax = 50 # Ã¿¸öÍæ¼Ò±£Áô×î½ü50Ìõ¼Ç¼  | 
|   | 
| Def_PositionMax = 100 # ×î´ó¾àÀ룬¸ñ  | 
| Def_PositionMid = Def_PositionMax / 2 # Öмä¾àÀë  | 
|   | 
| # ÎïÆ·ÊµÀý¶îÍâÊôÐÔÃû  | 
| MineItemAttr_MoveSpeed = "MoveSpeed"  | 
| MineItemAttr_EndTime = "EndTime"  | 
| MineItemAttr_HelpTick = "HelpTick"  | 
|   | 
| # ÎïÆ·ÀàÐÍ  | 
| MineType_Normal = 0 # ³£¹æÎïÆ·  | 
| MineType_Super = 1 # ³¬¼¶ÎïÆ·  | 
|   | 
| # ¸£µØ¼Ç¼ÀàÐÍ  | 
| MineAreaRecordType_Pull = 1 # ÀÎïÆ·  | 
| MineAreaRecordType_BeRobbed = 2 # ±»ÈËÇÀ  | 
|   | 
| MineAreaAwardGetTick = "MineAreaAwardGetTick"  | 
| NeighborAreaRefreshTick = "NeighborAreaRefreshTick"  | 
|   | 
| class DBPyMineAreaAwardManager(object):  | 
|     ## ¸£µØ½±Àø½áËã¹ÜÀí  | 
|       | 
|     def __init__(self):  | 
|         self.playerAreaAwardDict = {} # {playerID:{GUID:tagDBPyMineAreaAward, ...}, ...}  | 
|         return  | 
|       | 
|     def AddPlayerAreaAward(self, awardData):  | 
|         playerID = awardData.PlayerID  | 
|         if playerID not in self.playerAreaAwardDict:  | 
|             self.playerAreaAwardDict[playerID] = {}  | 
|         awardDict = self.playerAreaAwardDict[playerID]  | 
|         awardDict[awardData.GUID] = awardData  | 
|         return  | 
|       | 
|     # ±£´æÊý¾Ý ´æÊý¾Ý¿âºÍrealtimebackup  | 
|     def GetSaveData(self):  | 
|         savaData = ""  | 
|         cntData = ""  | 
|         cnt = 0  | 
|           | 
|         for awardDict in self.playerAreaAwardDict.values():  | 
|             for awardData in awardDict.values():  | 
|                 cnt += 1  | 
|                 savaData += awardData.getBuffer()  | 
|                   | 
|         GameWorld.Log("Save DBPyMineAreaAward count :%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("Load DBPyMineAreaAward count :%s" % cnt)  | 
|           | 
|         self.playerAreaAwardDict = {}  | 
|           | 
|         for _ in xrange(cnt):  | 
|             awardData = PyGameDataStruct.tagDBPyMineAreaAward()  | 
|             awardData.clear()  | 
|             pos += awardData.readData(datas, pos, dataslen)  | 
|               | 
|             self.AddPlayerAreaAward(awardData)  | 
|               | 
|         return pos  | 
|       | 
| class DBPyMineAreaRecordManager(object):  | 
|     ## ¸£µØ¿óÎï¼Ç¼¹ÜÀí  | 
|       | 
|     def __init__(self):  | 
|         self.playerMineRecordListDict = {} # {playerID:[tagDBPyMineAreaRecord, ...], ...}  | 
|         return  | 
|       | 
|     def AddPlayerRecord(self, recordData):  | 
|         playerID = recordData.PlayerID  | 
|         if playerID not in self.playerMineRecordListDict:  | 
|             self.playerMineRecordListDict[playerID] = []  | 
|         recordList = self.playerMineRecordListDict[playerID]  | 
|         recordList.append(recordData)  | 
|         return recordList  | 
|       | 
|     # ±£´æÊý¾Ý ´æÊý¾Ý¿âºÍrealtimebackup  | 
|     def GetSaveData(self):  | 
|         savaData = ""  | 
|         cntData = ""  | 
|         cnt = 0  | 
|           | 
|         for recordList in self.playerMineRecordListDict.values():  | 
|             for recordData in recordList:  | 
|                 cnt += 1  | 
|                 savaData += recordData.getBuffer()  | 
|                           | 
|         GameWorld.Log("Save DBPyMineAreaRecord count :%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("Load DBPyMineAreaRecord count :%s" % cnt)  | 
|           | 
|         self.playerMineRecordListDict = {}  | 
|           | 
|         for _ in xrange(cnt):  | 
|             recordData = PyGameDataStruct.tagDBPyMineAreaRecord()  | 
|             recordData.clear()  | 
|             pos += recordData.readData(datas, pos, dataslen)  | 
|               | 
|             self.AddPlayerRecord(recordData)  | 
|               | 
|         return pos  | 
|       | 
| class DBPyMineAreaItemManager(object):  | 
|     ## ¸£µØ¿óÎï¹ÜÀí  | 
|       | 
|     def __init__(self):  | 
|         self.Clear()  | 
|         return  | 
|       | 
|     def Clear(self):  | 
|         self.playerMineItemDict = {} # Íæ¼Ò¸£µØÎïÆ·ÐÅÏ¢ {playerID:{index:tagDBPyMineAreaItem, ...}, ...}  | 
|         self.allMineItemByEndTimeList = [] # ¸ù¾Ý½áÊøÊ±¼äÅÅÐòµÄËùÓпóÎï [tagDBPyMineAreaItem, ...]  | 
|         self.pullingItemListDict = {} # Íæ¼ÒÀÈ¡ÖеÄÎïÆ·ÐÅÏ¢ {playerID:[tagDBPyMineAreaItem, ...], ...}  | 
|         self.freeSuperItemList = [] # Ã»ÈËÀµÄ³¬¼¶ÎïÆ·ÊµÀýÁбí [tagDBPyMineAreaItem, ...]  | 
|         self.endSelfItemList = [] # À×Ô¼ºÎïÆ·Íê½áʵÀýÁбí [tagDBPyMineAreaItem, ...]  | 
|         self.endRobItemList = [] # ±»ÇÀ½ÙÎïÆ·Íê½áʵÀýÁбí [tagDBPyMineAreaItem, ...]  | 
|         self.realAreaPlayerIDList = [] # ÕæÊµ¸£µØÍæ¼ÒIDÁÐ±í  | 
|         self.fackAreaPlayerIDList = [] # ¼ÙÈ˸£µØÍæ¼ÒIDÁÐ±í  | 
|         self.viewAreaPlayerIDDict = {} # ÕýÔڲ鿴ij¸ö¸£µØÖеÄÍæ¼ÒID {areaPlayerID:[viewPlayerID, ...], ...}  | 
|           | 
|         self.neighborIDListDict = {} # Íæ¼ÒÖÜΧ¸£µØÍæ¼ÒIDÁбí {playerID:[playerID, ...], ...}  | 
|         self.socialIDListDict = {} # Íæ¼ÒÓйØÏµµÀÓѸ£µØÍæ¼ÒIDÁбí {playerID:[playerID, ...], ...} playerIDÁÐ±íµ¹Ðò  | 
|         return  | 
|       | 
|     def AddViewAreaPlayerID(self, viewPlayerID, areaPlayerID):  | 
|         if areaPlayerID not in self.viewAreaPlayerIDDict:  | 
|             self.viewAreaPlayerIDDict[areaPlayerID] = []  | 
|         viewPlayerIDList = self.viewAreaPlayerIDDict[areaPlayerID]  | 
|         if viewPlayerID not in viewPlayerIDList:  | 
|             viewPlayerIDList.append(viewPlayerID)  | 
|         return  | 
|     def DelViewAreaPlayerID(self, viewPlayerID):  | 
|         for viewPlayerIDList in self.viewAreaPlayerIDDict.values():  | 
|             if viewPlayerID in viewPlayerIDList:  | 
|                 viewPlayerIDList.remove(viewPlayerID)  | 
|         return  | 
|       | 
|     def AddPlayerPullingItem(self, playerID, mineItemData):  | 
|         if playerID not in self.pullingItemListDict:  | 
|             self.pullingItemListDict[playerID] = []  | 
|         pullingItemList = self.pullingItemListDict[playerID]  | 
|         if mineItemData not in pullingItemList:  | 
|             pullingItemList.append(mineItemData)  | 
|         if mineItemData in self.freeSuperItemList:  | 
|             self.freeSuperItemList.remove(mineItemData)  | 
|         return  | 
|       | 
|     def RemovePlayerPullingItem(self, playerID, mineItemData):  | 
|         if playerID not in self.pullingItemListDict:  | 
|             self.pullingItemListDict[playerID] = []  | 
|         pullingItemList = self.pullingItemListDict[playerID]  | 
|         if mineItemData in pullingItemList:  | 
|             pullingItemList.remove(mineItemData)  | 
|         return  | 
|       | 
|     def ClearMineItem(self, mineItemData):  | 
|         '''Çå³ý¿óÎ½öÇå³ýÊý¾Ý£¬¶ÔÏó±£Áô£¬Çå³ýºó MineID Îª0  | 
|         @param mineItemData: PyGameDataStruct.tagDBPyMineAreaItem()  | 
|         '''  | 
|         if mineItemData in self.allMineItemByEndTimeList:  | 
|             self.allMineItemByEndTimeList.remove(mineItemData)  | 
|         if mineItemData.PlayerID:  | 
|             self.RemovePlayerPullingItem(mineItemData.PlayerID, mineItemData)  | 
|         if mineItemData.RobPlayerID:  | 
|             self.RemovePlayerPullingItem(mineItemData.RobPlayerID, mineItemData)  | 
|         if mineItemData in self.freeSuperItemList:  | 
|             self.freeSuperItemList.remove(mineItemData)  | 
|         self.InitMineItem(mineItemData, mineItemData.PlayerID, mineItemData.Index)  | 
|         return  | 
|       | 
|     def InitMineItem(self, mineItemData, playerID, index, mineID=0, mineType=0, position=""):  | 
|         ## ¿óÎï³õʼ»¯  | 
|         mineItemData.clear()  | 
|         mineItemData.PlayerID = playerID  | 
|         mineItemData.Index = index  | 
|         mineItemData.MineID = mineID  | 
|         mineItemData.MineType = mineType  | 
|         mineItemData.UpdTime = int(time.time())  | 
|         mineItemData.Position = "%s" % position  | 
|         mineItemData.PosLen = len(mineItemData.Position)  | 
|           | 
|         # ²»Èë¿âµÄÊôÐÔ  | 
|         setattr(mineItemData, MineItemAttr_EndTime, 0)  | 
|         setattr(mineItemData, MineItemAttr_MoveSpeed, 0)  | 
|         setattr(mineItemData, MineItemAttr_HelpTick, 0)  | 
|         return  | 
|       | 
|     def GetMineItem(self, playerID, index):  | 
|         '''»ñÈ¡Íæ¼Ò¸£µØ¿óÎï  | 
|         @param playerID: ¸£µØÍæ¼ÒID  | 
|         @param index: ¿óÎïËùÔÚ¸£µØË÷Òý  | 
|         @return: PyGameDataStruct.tagDBPyMineAreaItem()  | 
|         '''  | 
|         if playerID not in self.playerMineItemDict:  | 
|             self.playerMineItemDict[playerID] = {}  | 
|         itemDict = self.playerMineItemDict[playerID]  | 
|         if index in itemDict:  | 
|             mineItemData = itemDict[index]  | 
|         else:  | 
|             mineItemData = PyGameDataStruct.tagDBPyMineAreaItem()  | 
|             self.InitMineItem(mineItemData, playerID, index)  | 
|             itemDict[index] = mineItemData  | 
|             self.AddMineAreaPlayerID(playerID)  | 
|               | 
|         return mineItemData  | 
|       | 
|     def AddMineAreaPlayerID(self, playerID):  | 
|         if playerID > Def_FakeAreaCount:  | 
|             if playerID not in self.realAreaPlayerIDList:  | 
|                 self.realAreaPlayerIDList.append(playerID)  | 
|         else:  | 
|             if playerID not in self.fackAreaPlayerIDList:  | 
|                 self.fackAreaPlayerIDList.append(playerID)  | 
|         return  | 
|       | 
|     # ±£´æÊý¾Ý ´æÊý¾Ý¿âºÍrealtimebackup  | 
|     def GetSaveData(self):  | 
|         savaData = ""  | 
|         cntData = ""  | 
|         cnt = 0  | 
|           | 
|         for itemDict in self.playerMineItemDict.values():  | 
|             for mineItemData in itemDict.values():  | 
|                 cnt += 1  | 
|                 savaData += mineItemData.getBuffer()  | 
|                   | 
|         GameWorld.Log("Save DBPyMineAreaItem count :%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("Load DBPyMineAreaItem count :%s" % cnt)  | 
|           | 
|         self.Clear()  | 
|           | 
|         for _ in xrange(cnt):  | 
|             mineItemData = PyGameDataStruct.tagDBPyMineAreaItem()  | 
|             mineItemData.clear()  | 
|             pos += mineItemData.readData(datas, pos, dataslen)  | 
|               | 
|             playerID = mineItemData.PlayerID  | 
|             index = mineItemData.Index  | 
|             if playerID not in self.playerMineItemDict:  | 
|                 self.playerMineItemDict[playerID] = {}  | 
|             itemDict = self.playerMineItemDict[playerID]  | 
|             itemDict[index] = mineItemData  | 
|             # Æô¶¯Ö±½Ó¸²¸ÇÍ¬Íæ¼ÒË÷ÒýλÊý¾Ý£¬ÕâÀï´æÔÚÒ»¸öÎÊÌ⣬ºÏ·þºó¼ÙÈËÍæ¼ÒIDÊÇÖØ¸´µÄ£¬Ò»°ãÊÇзþµÄÌæ»»¾É·þµÄ¼ÙÈË  | 
|               | 
|         OnLoadMineItemOK()  | 
|         return pos  | 
|       | 
| def DoOnDayEx():  | 
|     if GameWorld.IsCrossServer():  | 
|         return  | 
|     '''  | 
|             ´ý´¦Àí£ººÏ·þ±¾Éí»áɾ³ý²¿·ÖÍæ¼ÒÊý¾Ý£¬Ö®ºóÈç¹û¶à´ÎºÏ·þºóÊý¾ÝÁ¿½Ï´óÔÙ¿¼ÂÇ´¦Àí  | 
|     1. É¾³ý1ÐÇÆÚǰµÄ×Ô¼ºÀÎïÆ·¼Ç¼£¬ÖÁÉÙ±£Áô×î½ü10Ìõ±»ÈËÇÀ¼Ç¼  | 
|     2. É¾³ý1ÐÇÆÚǰδÁìÈ¡µÄ½±Àø¼Ç¼  | 
|     3. Çå³ý³¬¹ý1ÐÇÆÚûÓиüи£µØ¼Ç¼µÄÍæ¼ÒÊý¾Ý£¬±£µ×±£Áôx¸öÍæ¼Ò  | 
|     '''  | 
| #    socialAreaMax = IpyGameDataPY.GetFuncCfg("MineAreaRob", 1) # µÀÓѸ£µØ¸öÊý  | 
| #    inValidSeconds = 7 * 24 * 3600  | 
| #    curTime = int(time.time())  | 
| #    outofDateTime = curTime - inValidSeconds  | 
| #    delPlayerIDList = []  | 
| #    recordMgr = PyDataManager.GetDBPyMineAreaRecordManager()  | 
| #    for playerID, recordList in recordMgr.playerMineRecordListDict.items():  | 
| #        isActiveAreaPlayer = False  | 
| #        beRobbedPlayerIDList = []  | 
| #        for recordData in recordList[::-1]: # ·´Ðò´¦Àí              | 
| #            if recordData.RecordTime > outofDateTime:  | 
| #                isActiveAreaPlayer = True # ½üÆÚÄÚ»¹ÓмǼµÄÊÓΪ¸£µØ»îÔ¾Íæ¼Ò£¬ÎÞÂÛÖ÷¶¯»ò±»ÇÀ¼Ç¼  | 
| #            if recordData.RecordType == MineAreaRecordType_BeRobbed:  | 
| #                # ÖÁÉÙ±£Áô±»x¸ö²»Í¬Íæ¼ÒÇÀµÄ¼Ç¼£¬ÓÃÓÚ¸üйØÐĵÀÓѸ£µØ  | 
| #                tagPlayerID = recordData.TagPlayerID  | 
| #                if len(beRobbedPlayerIDList) < socialAreaMax and tagPlayerID not in beRobbedPlayerIDList:  | 
| #                    beRobbedPlayerIDList.append(tagPlayerID)  | 
| #                    continue  | 
| #            if recordData.RecordTime <= outofDateTime:  | 
| #                recordList.remove(recordData) # É¾³ý¹ýÆÚÊý¾Ý  | 
| #                  | 
| #        if not isActiveAreaPlayer:  | 
| #            if playerID not in delPlayerIDList:  | 
| #                delPlayerIDList.append(playerID)  | 
|     return  | 
|   | 
| def DoMineAreaFuncOpen(curPlayer):  | 
|     ## ¸£µØ¹¦ÄÜ¿ªÆô  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     __DoMineItemRefresh(playerID, curPlayer)  | 
|     return  | 
|   | 
| def OnPlayerLogin(curPlayer):  | 
|     if GameWorld.IsCrossServer():  | 
|         return  | 
|     playerID = curPlayer.GetPlayerID()  | 
|       | 
|     # ×Ô¼º¸£µØÊý¾Ý  | 
|     mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()  | 
|     if playerID in mineItemMgr.playerMineItemDict:  | 
|         NetPackCommon.SendFakePack(curPlayer, __GetMineAreaInfoPack([[playerID, []]]))  | 
|           | 
|     # ÀÈ¡ÖеÄÎïÆ·Êý¾Ý  | 
|     SyncPullingAreaMineInfo(curPlayer)  | 
|       | 
|     # ÓÐδÁìÈ¡µÄ½áËã½±Àø  | 
|     awardMgr = PyDataManager.GetDBPyMineAreaAwardManager()  | 
|     awardDict = awardMgr.playerAreaAwardDict.get(playerID, {})  | 
|     if awardDict:  | 
|         SyncMineAwardAward(curPlayer)  | 
|           | 
|     return  | 
|   | 
| def OnLoadMineItemOK():  | 
|     if GameWorld.IsCrossServer():  | 
|         return  | 
|       | 
|     refreshIndexList = range(IpyGameDataPY.GetFuncCfg("MineAreaBase", 1))  | 
|     mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()  | 
|     for areaPlayerID, itemDict in mineItemMgr.playerMineItemDict.items():  | 
|         emptyIndexList = []  | 
|         for index in refreshIndexList:  | 
|             if index not in itemDict:  | 
|                 emptyIndexList.append(index)  | 
|                 continue  | 
|             mineItemData = itemDict[index]  | 
|             if not mineItemData or not mineItemData.MineID:  | 
|                 emptyIndexList.append(index)  | 
|                 continue  | 
|               | 
|             # ¿óÎï³õʼÊý¾Ý´¦Àí  | 
|             mineType = mineItemData.MineType  | 
|             workerCount = mineItemData.WorkerCount  | 
|             robPlayerID = mineItemData.RobPlayerID  | 
|             robWorkerCount = mineItemData.RobWorkerCount  | 
|               | 
|             mineItemMgr.AddMineAreaPlayerID(areaPlayerID)  | 
|               | 
|             if mineType == MineType_Super and not workerCount and not robWorkerCount and mineItemData not in mineItemMgr.freeSuperItemList:  | 
|                 mineItemMgr.freeSuperItemList.append(mineItemData)  | 
|                   | 
|             if workerCount:  | 
|                 mineItemMgr.AddPlayerPullingItem(areaPlayerID, mineItemData)  | 
|                   | 
|             if robPlayerID and robWorkerCount:  | 
|                 mineItemMgr.AddPlayerPullingItem(robPlayerID, mineItemData)      | 
|                   | 
|             __RefreshMineItemSpeed(mineItemData)  | 
|               | 
|         if emptyIndexList:  | 
|             GameWorld.DebugLog("Æô¶¯Ä¬Èϲ¹³ä¿ÕλÖÃÎïÆ·: areaPlayerID=%s,emptyIndexList=%s" % (areaPlayerID, emptyIndexList))  | 
|             __DoMineItemRefresh(areaPlayerID, refreshIndexList=emptyIndexList)  | 
|               | 
|     __SortMineItem()  | 
|     __MakeFackArea()  | 
|     return  | 
|   | 
| def __MakeFackArea():  | 
|     # Éú³É¼ÙÈ˸£µØÊý¾Ý  | 
|     mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()  | 
|     if len(mineItemMgr.playerMineItemDict) >= Def_FakeAreaCount:  | 
|         return  | 
|     needFackCount = Def_FakeAreaCount - len(mineItemMgr.playerMineItemDict)  | 
|     fackPlayerID = 0  | 
|     while needFackCount > 0 and fackPlayerID < Def_FakeAreaCount:  | 
|         fackPlayerID += 1  | 
|         if fackPlayerID in mineItemMgr.playerMineItemDict:  | 
|             continue  | 
|         if __DoMineItemRefresh(fackPlayerID, isNotify=False):  | 
|             GameWorld.DebugLog("ÐÂÔö¸£µØ¼ÙÈË: %s" % fackPlayerID)  | 
|             needFackCount -= 1  | 
|     return  | 
|   | 
| def __SortMineItem():  | 
|     mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()  | 
|     mineItemMgr.allMineItemByEndTimeList.sort(key=operator.attrgetter(MineItemAttr_EndTime))  | 
|     return  | 
|   | 
| def __RefreshMineItemPosition(mineItemData, curTime):  | 
|     ## Ë¢Ð¿óÎï×ø±ê  | 
|     playerID = mineItemData.PlayerID  | 
|     index = mineItemData.Index  | 
|     mineID = mineItemData.MineID  | 
|     curPos = GameWorld.ToFloat(mineItemData.Position, Def_PositionMid)  | 
|     if not playerID or not mineID:  | 
|         return curPos  | 
|       | 
|     curWorkerCount = mineItemData.WorkerCount  | 
|     robWorkerCount = mineItemData.RobWorkerCount  | 
|     if not curWorkerCount and not robWorkerCount:  | 
|         return curPos  | 
|     moveSpeed = getattr(mineItemData, MineItemAttr_MoveSpeed, 0)  | 
|     if not moveSpeed:  | 
|         return curPos  | 
|     passSeconds = curTime - mineItemData.UpdTime  | 
|     if passSeconds <= 0 or not moveSpeed:  | 
|         return curPos  | 
|       | 
|     moveDir = -1 if curWorkerCount >= robWorkerCount else 1 # Òƶ¯·½Ïò£¬-1-Ï£» 1-ÉÏ  | 
|     moveDist = moveSpeed * passSeconds * moveDir  | 
|     updPos = min(max(0, curPos + moveDist), Def_PositionMax)  | 
|     mineItemData.Position = "%s" % updPos  | 
|     mineItemData.PosLen = len(mineItemData.Position)  | 
|     mineItemData.UpdTime = curTime  | 
|     GameWorld.DebugLog("¸üпóÎï×ø±ê: playerID=%s,index=%s,mineID=%s,curWorkerCount=%s,robWorkerCount=%s,curPos=%s,moveSpeed=%s,passSeconds=%s,moveDist=%s,updPos=%s"   | 
|                        % (playerID, index, mineID, curWorkerCount, robWorkerCount, curPos, moveSpeed, passSeconds, moveDist, updPos))  | 
|     return updPos  | 
|   | 
| def __RefreshMineItemSpeed(mineItemData, isSort=False):  | 
|     ## Ë¢Ð¿óÎïËÙ¶È¡¢Íê³Éʱ¼ä  | 
|     playerID = mineItemData.PlayerID  | 
|     index = mineItemData.Index  | 
|     mineID = mineItemData.MineID  | 
|     if not playerID or not mineID:  | 
|         return  | 
|       | 
|     curPos = GameWorld.ToFloat(mineItemData.Position, Def_PositionMid)  | 
|     allMineItemByEndTimeList = PyDataManager.GetDBPyMineAreaItemManager().allMineItemByEndTimeList  | 
|     curWorkerCount = mineItemData.WorkerCount  | 
|     robWorkerCount = mineItemData.RobWorkerCount  | 
|     if not curWorkerCount and not robWorkerCount:  | 
|         setattr(mineItemData, MineItemAttr_EndTime, 0)  | 
|         setattr(mineItemData, MineItemAttr_MoveSpeed, 0)  | 
|         if mineItemData in allMineItemByEndTimeList:  | 
|             allMineItemByEndTimeList.remove(mineItemData)  | 
|         return  | 
|       | 
|     GameWorld.DebugLog("¸üпóÎïʱ¼äËÙ¶È: playerID=%s,index=%s,mineID=%s,curWorkerCount=%s,robWorkerCount=%s,curPos=%s"   | 
|                        % (playerID, index, mineID, curWorkerCount, robWorkerCount, curPos))  | 
|     curWorkerState = mineItemData.WorkerState  | 
|     robWorkerState = mineItemData.RobWorkerState  | 
|     ret = __calcMineItemSpeed(mineID, curPos, curWorkerCount, curWorkerState, robWorkerCount, robWorkerState)  | 
|     if not ret:  | 
|         return  | 
|     moveSpeed, needSeconds = ret  | 
|       | 
|     updTime = mineItemData.UpdTime  | 
|     endTime = updTime + needSeconds  | 
|     GameWorld.DebugLog("    updTime=%s,needSeconds=%s,endTime=%s"   | 
|                        % (GameWorld.ChangeTimeNumToStr(updTime), needSeconds, GameWorld.ChangeTimeNumToStr(endTime)))  | 
|       | 
|     setattr(mineItemData, MineItemAttr_EndTime, endTime)  | 
|     setattr(mineItemData, MineItemAttr_MoveSpeed, moveSpeed)  | 
|       | 
|     if mineItemData not in allMineItemByEndTimeList:  | 
|         allMineItemByEndTimeList.append(mineItemData)  | 
|     if isSort:  | 
|         __SortMineItem()  | 
|     return True  | 
|   | 
| def __calcMineItemSpeed(mineID, curPos, curWorkerCount, curWorkerState, robWorkerCount, robWorkerState):  | 
|     ## ¼ÆËãÀÎïÆ·ËÙ¶È£¬ÕâÀïÖ»´¦Àí¼ÆËãÂß¼£¬Êµ¼ÊÓ¦ÓÃÓɵ÷ÓÃÕß¾ö¶¨  | 
|     # @param return: moveSpeed, needSeconds »ò  Òì³£·µ»ØNone  | 
|     if not curWorkerCount and not robWorkerCount:  | 
|         return 0, 0  | 
|       | 
|     ipyData = IpyGameDataPY.GetIpyGameData("MineAreaItem", mineID)  | 
|     if not ipyData:  | 
|         return  | 
|     itemWeight = ipyData.GetItemWeight()  | 
|       | 
|     moveDir = -1 if curWorkerCount >= robWorkerCount else 1 # Òƶ¯·½Ïò£¬-1-Ï£» 1-ÉÏ  | 
|       | 
|     # Ï - À»Ø  | 
|     if moveDir == -1:  | 
|         dist = curPos # »¹ÐèÒÆ¶¯¾àÀë  | 
|         workerState = curWorkerState  | 
|         workerCount, batWorkerCount = curWorkerCount, robWorkerCount  | 
|     # ÉÏ - ÇÀ½Ù  | 
|     else:  | 
|         dist = Def_PositionMax - curPos  | 
|         workerState = robWorkerState  | 
|         workerCount, batWorkerCount = robWorkerCount, curWorkerCount  | 
|           | 
|     workerStateTimeList = IpyGameDataPY.GetFuncEvalCfg("MineAreaWorkCalc", 1) # Æ£ÀÍ״̬µ¥Î»ºÄʱÁÐ±í  | 
|     workerCountRatioList = IpyGameDataPY.GetFuncEvalCfg("MineAreaWorkCalc", 2) # ÈËÊýºÄʱ±ÈÂÊÁÐ±í  | 
|     workerBattleRatioList = IpyGameDataPY.GetFuncEvalCfg("MineAreaWorkCalc", 3) # ¶Ô¿¹ÈËÊýºÄʱ±ÈÂÊÁÐ±í  | 
|       | 
|     baseTime = workerStateTimeList[len(workerStateTimeList) - 1] if workerState >= len(workerStateTimeList) else workerStateTimeList[workerState]  | 
|     workRatio = workerCountRatioList[len(workerCountRatioList) - 1] if workerCount > len(workerCountRatioList) else workerCountRatioList[workerCount - 1]  | 
|     battleRatio = 1 # Ã»È˶Կ¹Ê±£¬Ä¬ÈÏ1  | 
|     if batWorkerCount > 0:  | 
|         battleRatio = workerBattleRatioList[len(workerBattleRatioList) - 1] if batWorkerCount > len(workerBattleRatioList) else workerBattleRatioList[batWorkerCount - 1]  | 
|           | 
|     needSeconds = int(dist * itemWeight * baseTime * workRatio * battleRatio) # »¹Ð蹤×÷ʱ³¤£¬Ãë  | 
|     if needSeconds <= 0:  | 
|         return 0, 0  | 
|       | 
|     moveSpeed = dist / float(needSeconds) # Òƶ¯ËÙ¶È  x¸ñ/Ãë  | 
|     needHms = "%02d:%02d:%02d" % (needSeconds / 3600, needSeconds % 3600 / 60, needSeconds % 60)  | 
|       | 
|     GameWorld.DebugLog("    mineID=%s,curPos=%s,curWorkerCount=%s,curWorkerState=%s,robWorkerCount=%s,robWorkerState=%s"   | 
|                        % (mineID, curPos, curWorkerCount, curWorkerState, robWorkerCount, robWorkerState))  | 
|     GameWorld.DebugLog("    moveDir=%s,dist=%s,itemWeight=%s,baseTime=%s,workRatio=%s,battleRatio=%s,needSeconds=%s(%s),moveSpeed=%s"   | 
|                        % (moveDir, dist, itemWeight, baseTime, workRatio, battleRatio, needSeconds, needHms, moveSpeed))  | 
|     return moveSpeed, needSeconds  | 
|   | 
| def OnProcessOnMinute():  | 
|     ## ¶¨Ê±´¦Àí£¬Ã¿·ÖÖÓÒ»´Î  | 
|     __Process_SysRefresh()  | 
|     return  | 
|   | 
| def __Process_SysRefresh():  | 
|     ## ÏµÍ³¶¨Ê±Ë¢Ð  | 
|     sysRefreshHMList = IpyGameDataPY.GetFuncEvalCfg("MineAreaSysRefresh", 1)  | 
|     if not sysRefreshHMList:  | 
|         return  | 
|     dayTime = GameWorld.GetServerTime()  | 
|     curHourMinute = [dayTime.hour, dayTime.minute]  | 
|     if curHourMinute not in sysRefreshHMList:  | 
|         return  | 
|     GameWorld.Log("¸£µØÏµÍ³¶¨Ê±Ë¢ÐÂ! %s" % str(curHourMinute))  | 
|     mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()  | 
|     for playerID in mineItemMgr.playerMineItemDict.keys():  | 
|         __DoMineItemRefresh(playerID, isSys=True)  | 
|     return  | 
|   | 
| def OnMineItemTimeProcess(curTime, tick):  | 
|     ## ¶¨Ê±´¦Àí£¬Ã¿Ãë´¥·¢Ò»´Î  | 
|       | 
|     mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()  | 
|     __Process_EndItemRefresh(mineItemMgr.endSelfItemList, IpyGameDataPY.GetFuncCfg("MineAreaSysRefresh", 2), curTime)  | 
|     __Process_EndItemRefresh(mineItemMgr.endRobItemList, IpyGameDataPY.GetFuncCfg("MineAreaSysRefresh", 3), curTime)  | 
|     __Process_SuperItem(curTime)  | 
|     __Process_MineItemByEndTimeList(curTime)  | 
|     return  | 
|   | 
| def __Process_EndItemRefresh(endItemList, refreshCD, curTime):  | 
|     ## ¶¨Ê±´¦Àí¿ÕλÖÃÎïÆ·Ë¢Ð  | 
|     if not endItemList:  | 
|         return  | 
|     doCount = len(endItemList)  | 
|     index = 0  | 
|     while doCount > 0 and index < len(endItemList):  | 
|         doCount -= 1  | 
|         mineItemData = endItemList[index]  | 
|         if not mineItemData or mineItemData.MineID:  | 
|             # None »ò ÒѾÓÐÎïÆ·ÁË£¬²»ÔÙ´¦Àí£¬Ö±½ÓÒÆ³ý  | 
|             endItemList.pop(index)  | 
|             continue  | 
|         UpdTime = mineItemData.UpdTime  | 
|         if curTime - UpdTime < refreshCD:  | 
|             # ÒòΪÊǰ´½áÊøÏȺó˳ÐòÌí¼ÓµÄ£¬ËùÒÔÖ»Òª»¹ÔÚCD£¬ÔòºóÃæµÄÒ»¶¨Ò²ÊÇCDÖÐ  | 
|             break  | 
|         areaPlayerID = mineItemData.PlayerID  | 
|         itemIndex = mineItemData.Index  | 
|         if __DoMineItemRefresh(areaPlayerID, refreshIndexList=[itemIndex]):  | 
|             endItemList.pop(index) # ³É¹¦Ë¢ÐºóÖ±½ÓÒÆ³ý  | 
|             continue  | 
|         index += 1  | 
|     return  | 
|   | 
| def __Process_SuperItem(curTime):  | 
|     ## ¶¨Ê±´¦Àí³¬¼¶ÎïÆ·  | 
|     mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()  | 
|     freeSuperItemList = mineItemMgr.freeSuperItemList  | 
|     if not freeSuperItemList:  | 
|         return  | 
|     superItemExistSeconds = IpyGameDataPY.GetFuncCfg("MineAreaSuperItem", 1)  | 
|       | 
|     doCount = len(freeSuperItemList)  | 
|     index = 0  | 
|     while doCount > 0 and freeSuperItemList:  | 
|         doCount -= 1  | 
|         mineItemData = freeSuperItemList[index]  | 
|         if not mineItemData or mineItemData.WorkerCount or mineItemData.RobWorkerCount:  | 
|             # None »ò ÒѾÓÐÈËÔÙÀÁË£¬²»ÔÙ´¦Àí£¬Ö±½ÓÒÆ³ý  | 
|             freeSuperItemList.pop(index)  | 
|             continue  | 
|         UpdTime = mineItemData.UpdTime  | 
|         if curTime - UpdTime < superItemExistSeconds:  | 
|             break  | 
|         areaPlayerID = mineItemData.PlayerID  | 
|         itemIndex = mineItemData.Index  | 
|         GameWorld.DebugLog("³¬¼¶ÎïÆ·¹ýÆÚ! areaPlayerID=%s,itemIndex=%s" % (areaPlayerID, itemIndex))  | 
|         mineItemMgr.ClearMineItem(mineItemData)  | 
|         __OnEndSelfItem(mineItemMgr, mineItemData, areaPlayerID, itemIndex)  | 
|         SyncMineAreaItemInfo(areaPlayerID, [itemIndex])  | 
|           | 
|     return  | 
|   | 
| def __Process_MineItemByEndTimeList(curTime):  | 
|     ## ¶¨Ê±´¦ÀíÀʱ¼äµ½ÎïÆ·  | 
|     allMineItemByEndTimeList = PyDataManager.GetDBPyMineAreaItemManager().allMineItemByEndTimeList  | 
|     if not allMineItemByEndTimeList:  | 
|         return  | 
|     index = 0  | 
|     doCount = len(allMineItemByEndTimeList)  | 
|     while doCount > 0 and allMineItemByEndTimeList:  | 
|         doCount -= 1  | 
|         mineItemData = allMineItemByEndTimeList[index]  | 
|         endTime = getattr(mineItemData, MineItemAttr_EndTime, 0)  | 
|         if curTime < endTime:  | 
|             break  | 
|           | 
|         ret = __EndMineItemByTime(mineItemData.PlayerID, mineItemData.Index, curTime)  | 
|         if ret == None:  | 
|             if index < len(allMineItemByEndTimeList):  | 
|                 allMineItemByEndTimeList.pop(index)  | 
|         elif ret == False:  | 
|             index += 1  | 
|     return  | 
|   | 
| def __EndMineItemByTime(areaPlayerID, itemIndex, curTime):  | 
|     ## ¸ù¾Ýʱ¼ä½áÊø¿óÎï  | 
|     ## @return: ÊÇ·ñ½áÊø£¬None-Òì³£Çé¿ö  | 
|     mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()  | 
|     mineItemData = mineItemMgr.GetMineItem(areaPlayerID, itemIndex)  | 
|     mineID = mineItemData.MineID  | 
|     if not mineID:  | 
|         return  | 
|       | 
|     useWorkerCount = 1  | 
|     notifyPlayerIDListEx = []  | 
|     curPos = __RefreshMineItemPosition(mineItemData, curTime)      | 
|     # ¼æÈÝ1¸ñ  | 
|     # ×Ô¼ºÀ»Ø  | 
|     if curPos <= 1:  | 
|         awardPlayerID = areaPlayerID  | 
|         useWorkerCount = mineItemData.WorkerCount  | 
|     # ÇÀ½ÙÀ×ß  | 
|     elif curPos >= Def_PositionMax - 1:  | 
|         awardPlayerID = mineItemData.RobPlayerID  | 
|         useWorkerCount = mineItemData.RobWorkerCount  | 
|         notifyPlayerIDListEx = [awardPlayerID]  | 
|     else:  | 
|         return False  | 
|       | 
|     ipyData = IpyGameDataPY.GetIpyGameData("MineAreaItem", mineID)  | 
|     if not ipyData:  | 
|         return  | 
|       | 
|     # ½±ÀøÍæ¼Ò²¢²»Ò»¶¨ÔÚÏߣ¬Í³Ò»Ìí¼Ó½ø½±Àø£¬ÓÉÍæ¼ÒÇëÇó½áËã  | 
|     awardData = PyGameDataStruct.tagDBPyMineAreaAward()  | 
|     awardData.GUID = str(uuid.uuid1())  | 
|     awardData.GUIDLen = len(awardData.GUID)  | 
|     awardData.PlayerID = awardPlayerID  | 
|     awardData.AwardTime = int(time.time())  | 
|     awardData.MineID = mineID  | 
|     awardData.WorkerCount = useWorkerCount  | 
|     awardData.AreaPlayerID = areaPlayerID  | 
|     PyDataManager.GetDBPyMineAreaAwardManager().AddPlayerAreaAward(awardData)  | 
|     # Í¨ÖªÓн±Àø  | 
|     awardPlayer = GameWorld.GetPlayerManager().FindPlayerByID(awardPlayerID)  | 
|     if awardPlayer:  | 
|         SyncMineAwardAward(awardPlayer)  | 
|           | 
|     GameWorld.DebugLog("¸ù¾Ýʱ¼ä½áÊøÎïÆ·: areaPlayerID=%s,itemIndex=%s,mineID=%s,awardPlayerID=%s"   | 
|                        % (areaPlayerID, itemIndex, mineID, awardPlayerID))  | 
|       | 
|     mineItemMgr.ClearMineItem(mineItemData)  | 
|       | 
|     #Ôö¼Ó¼Ç¼  | 
|     AddMineItemRecord(awardPlayerID, MineAreaRecordType_Pull, areaPlayerID, mineID, curTime)  | 
|     if areaPlayerID != awardPlayerID:  | 
|         AddMineItemRecord(areaPlayerID, MineAreaRecordType_BeRobbed, awardPlayerID, mineID, curTime)  | 
|           | 
|         # ±»ÇÀµÄ  | 
|         if IpyGameDataPY.GetFuncCfg("MineAreaSysRefresh", 3) > 0:  | 
|             mineItemMgr.endRobItemList.append(mineItemData)  | 
|         else:  | 
|             __DoMineItemRefresh(areaPlayerID, isNotify=False, refreshIndexList=[itemIndex])  | 
|     else:  | 
|         # À×Ô¼ºµÄ  | 
|         __OnEndSelfItem(mineItemMgr, mineItemData, areaPlayerID, itemIndex)  | 
|           | 
|     SyncMineAreaItemInfo(areaPlayerID, [itemIndex], notifyPlayerIDListEx)  | 
|     return True  | 
|   | 
| def __OnEndSelfItem(mineItemMgr, mineItemData, areaPlayerID, itemIndex):  | 
|     # ×Ô¼ºµÄÎïÆ·½áÊø£¬°üº¬×Ô¼ºÀµÄ£¬×Ô¼ºÏûʧµÄ£¨È糬¼¶ÎïÆ·£©£¬²»º¬±»ÇÀµÄ  | 
|     if IpyGameDataPY.GetFuncCfg("MineAreaSysRefresh", 2) > 0:  | 
|         mineItemMgr.endSelfItemList.append(mineItemData)  | 
|     else:  | 
|         __DoMineItemRefresh(areaPlayerID, isNotify=False, refreshIndexList=[itemIndex])  | 
|     return  | 
|   | 
| def AddMineItemRecord(playerID, recordType, tagPlayerID, mineID, curTime):  | 
|     if playerID <= Def_FakeAreaCount:  | 
|         # ¼ÙÈ˲»¼Ç¼  | 
|         return  | 
|     recordData = PyGameDataStruct.tagDBPyMineAreaRecord()  | 
|     recordData.PlayerID = playerID  | 
|     recordData.RecordType = recordType  | 
|     recordData.TagPlayerID = tagPlayerID  | 
|     recordData.MineID = mineID  | 
|     recordData.RecordTime = curTime  | 
|       | 
|     recordMgr = PyDataManager.GetDBPyMineAreaRecordManager()  | 
|     recordList = recordMgr.AddPlayerRecord(recordData)  | 
|       | 
|     # ±»ÈËÇÀ£¬¸üйØÏµ¸£µØID¼Ç¼  | 
|     if recordData.RecordType == MineAreaRecordType_BeRobbed:  | 
|         __DoUpdSocialPlayerIDList(playerID)  | 
|       | 
|     if len(recordList) > Def_RecordMax:  | 
|         recordList.pop(0) # É¾³ý×îÔçÒ»Ìõ  | 
|     return  | 
|   | 
| def __DoUpdSocialPlayerIDList(playerID):  | 
|     ## ¸üÐÂÓйØÏµµÄµÀÓÑIDÁÐ±í  | 
|     recordMgr = PyDataManager.GetDBPyMineAreaRecordManager()  | 
|     recordList = recordMgr.playerMineRecordListDict.get(playerID, [])  | 
|       | 
|     socialAreaMax = IpyGameDataPY.GetFuncCfg("MineAreaRob", 1) # µÀÓѸ£µØ¸öÊý  | 
|     socialIDList = [] # ·´Ðò  | 
|     for recData in recordList[::-1]:  | 
|         if recData.RecordType != MineAreaRecordType_BeRobbed:  | 
|             ## ÓÅÏȱ£Áô±»ÇÀ¼Ç¼¹ØÏµÍæ¼Ò  | 
|             continue  | 
|         if recData.TagPlayerID not in socialIDList:  | 
|             socialIDList.append(recData.TagPlayerID)  | 
|             if len(socialIDList) >= socialAreaMax:  | 
|                 break  | 
|               | 
|     mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()  | 
|     socialIDListBef = mineItemMgr.socialIDListDict.get(playerID, [])  | 
|     # ÓÅÏÈʹÓÃÀúÊ·¼Ç¼  | 
|     if len(socialIDList) < socialAreaMax:  | 
|         for socialIDBef in socialIDListBef:  | 
|             if socialIDBef not in socialIDList:  | 
|                 socialIDList.append(socialIDBef)  | 
|                 if len(socialIDList) >= socialAreaMax:  | 
|                     break  | 
|                   | 
|     # ÓÅÏÈËæ»úÕæÈË  | 
|     if len(socialIDList) < socialAreaMax and mineItemMgr.realAreaPlayerIDList:  | 
|         random.shuffle(mineItemMgr.realAreaPlayerIDList)  | 
|         for areaPlayerID in mineItemMgr.realAreaPlayerIDList:  | 
|             if areaPlayerID not in socialIDList and areaPlayerID != playerID:  | 
|                 socialIDList.append(areaPlayerID)  | 
|                 if len(socialIDList) >= socialAreaMax:  | 
|                     break  | 
|                   | 
|     # ²»¹»²¹³ä¼ÙÈË  | 
|     if len(socialIDList) < socialAreaMax and mineItemMgr.fackAreaPlayerIDList:  | 
|         random.shuffle(mineItemMgr.fackAreaPlayerIDList)  | 
|         for areaPlayerID in mineItemMgr.fackAreaPlayerIDList:  | 
|             if areaPlayerID not in socialIDList:  | 
|                 socialIDList.append(areaPlayerID)  | 
|                 if len(socialIDList) >= socialAreaMax:  | 
|                     break  | 
|                   | 
|     mineItemMgr.socialIDListDict[playerID] = socialIDList  | 
|     return socialIDList  | 
|   | 
| def OnTurnFightRequest(curPlayer, mapID, funcLineID, tagPlayerID, valueList):  | 
|       | 
|     # Ò¡È˰ïÖúÇëÇó¡¢×Ô¼ºÇý¸ÏÇëÇó  | 
|     if funcLineID == 0 or funcLineID == 1:  | 
|         return __OnMineHelpRequest(curPlayer, mapID, funcLineID, tagPlayerID, valueList)  | 
|       | 
|     return  | 
|   | 
| def OnTurnFightOver(curPlayer, mapID, funcLineID, tagPlayerID, valueList, fightRet, awardItemList):  | 
|       | 
|     # Ò¡È˰ïÖú½á¹û¡¢×Ô¼ºÇý¸Ï½á¹û  | 
|     if funcLineID == 0 or funcLineID == 1:  | 
|         return __OnMineHelpOver(curPlayer, mapID, funcLineID, tagPlayerID, valueList, fightRet, awardItemList)  | 
|           | 
|     return  | 
|   | 
| def __OnMineHelpRequest(curPlayer, mapID, funcLineID, tagPlayerID, valueList):  | 
|     # Ò¡È˰ïÖúÇëÇó¡¢×Ô¼ºÇý¸ÏÇëÇó  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     if not valueList or len(valueList) < 2:  | 
|         GameWorld.DebugLog("ûÓÐÖ¸¶¨valueList!", playerID)  | 
|         return  | 
|     areaPlayerID = valueList[0]  | 
|     itemIndex = valueList[1]  | 
|       | 
|     if funcLineID == 0:  | 
|         if playerID == areaPlayerID:  | 
|             GameWorld.DebugLog("²»ÄܰïÖú×Ô¼º! areaPlayerID=%s" % areaPlayerID, playerID)  | 
|             return  | 
|     elif funcLineID == 1:  | 
|         if playerID != areaPlayerID:  | 
|             GameWorld.DebugLog("²»ÊÇ×Ô¼ºµÄ¸£µØ£¬ÎÞ·¨×Ô¼ºÇý¸Ï! areaPlayerID=%s" % areaPlayerID, playerID)  | 
|             return  | 
|           | 
|     mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()  | 
|     mineItemData = mineItemMgr.GetMineItem(areaPlayerID, itemIndex)  | 
|     mineID = mineItemData.MineID  | 
|     if not mineID:  | 
|         # ¸Ã×ÊÔ´ÒÑÏûʧ  | 
|         PlayerControl.NotifyCode(curPlayer, "MineDisappeared")  | 
|         return  | 
|       | 
|     robPlayerID = mineItemData.RobPlayerID  | 
|     if not robPlayerID or robPlayerID != tagPlayerID:  | 
|         # µ±Ç°×ÊÔ´ÎÞÕù¶áÕß»òÒѱ»ÆäËûÍæ¼ÒÍê³É  | 
|         PlayerControl.NotifyCode(curPlayer, "MineHelpFinished")  | 
|         return  | 
|       | 
|     tick = GameWorld.GetGameWorld().GetTick()  | 
|     helpTick = getattr(mineItemData, MineItemAttr_HelpTick, 0)  | 
|     if helpTick and tick - helpTick < 10000:  | 
|         GameWorld.DebugLog("ÒѾÓÐÆäËûÈËÔÚ°ïÖúÖÐ!", playerID)  | 
|         return  | 
|     setattr(mineItemData, MineItemAttr_HelpTick, tick)  | 
|       | 
|     return True  | 
|   | 
| def __OnMineHelpOver(curPlayer, mapID, funcLineID, tagPlayerID, valueList, fightRet, awardItemList):  | 
|     # Ò¡È˰ïÖú½á¹û¡¢×Ô¼ºÇý¸Ï½á¹û  | 
|       | 
|     playerID = curPlayer.GetPlayerID()  | 
|     helpPlayerName = curPlayer.GetName()  | 
|       | 
|     areaPlayerID = valueList[0]  | 
|     itemIndex = valueList[1]  | 
|     isWin = fightRet[0]  | 
|       | 
|     mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()  | 
|     mineItemData = mineItemMgr.GetMineItem(areaPlayerID, itemIndex)  | 
|     setattr(mineItemData, MineItemAttr_HelpTick, 0)  | 
|       | 
|     if not isWin:  | 
|         #GameWorld.DebugLog("°ïÖúʧ°Ü")  | 
|         return  | 
|       | 
|     robPlayerID = mineItemData.RobPlayerID  | 
|     # ¸Ï×ßÇÀ¶áÕß  | 
|     if robPlayerID and robPlayerID == tagPlayerID:  | 
|         __DoCancelPull(tagPlayerID, areaPlayerID, itemIndex, "out")  | 
|       | 
|     # °ïÖúµÄ·¢½±  | 
|     if funcLineID == 0:  | 
|         robCacheDict = PlayerViewCache.GetCachePropDataDict(PlayerViewCache.FindViewCache(tagPlayerID))  | 
|         robPlayerName = robCacheDict.get("Name", "")  | 
|           | 
|         areaCacheDict = PlayerViewCache.GetCachePropDataDict(PlayerViewCache.FindViewCache(areaPlayerID))  | 
|         areaPlayerName = areaCacheDict.get("Name", "")  | 
|           | 
|         # Óʼþ·¢·Å½±Àø  | 
|         PlayerCompensation.SendMailByKey("MineHelpAward", [playerID], awardItemList, [areaPlayerName, robPlayerName])  | 
|           | 
|         # Í¨Öª¸£µØÍæ¼Ò  | 
|         PlayerCompensation.SendMailByKey("MineHelpReqOK", [areaPlayerID], [], [helpPlayerName, robPlayerName])  | 
|           | 
|     # ×Ô¼ºÇý¸ÏµÄ  | 
|     elif funcLineID == 1:  | 
|         # ×Ô¼ºÇý¸ÏµÄ£¬²»ÓÃÔÙ֪ͨµØÍ¼£¬Ö±½Óreturn  | 
|         return  | 
|       | 
|     return True  | 
|   | 
| def MapServer_MineArea(curPlayer, msgList):  | 
|     mapID = curPlayer.GetRealMapID()  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     GameWorld.DebugLog("MapServer_MineArea mapID=%s,msgList=%s" % (mapID, msgList), playerID)  | 
|     if not msgList:  | 
|         return  | 
|       | 
|     msgType, dataMsg = msgList  | 
|     ret = None  | 
|       | 
|     # ÀÎïÆ·  | 
|     if msgType == "Pull":  | 
|         __DoPullItem(playerID, curPlayer, dataMsg)  | 
|   | 
|     # Ë¢Ð¸£µØÎïÆ·  | 
|     elif msgType == "MineItemRefresh":  | 
|         playerID, isSuper = dataMsg  | 
|         __DoMineItemRefresh(playerID, curPlayer, isSuper=isSuper)  | 
|   | 
|     # µØÍ¼½áËã½±ÀøOK  | 
|     elif msgType == "MineAreaAwardGetOK":  | 
|         __DoMineAreaAwardGetOK(curPlayer, dataMsg)  | 
|           | 
|     if ret == None:  | 
|         return  | 
|     return msgList + [ret]  | 
|   | 
| def __DoPullItem(playerID, curPlayer, dataMsg):  | 
|     areaPlayerID, itemIndex, workerCount, workerState, workerTotal, isPreview = dataMsg  | 
|     if itemIndex < 0 or itemIndex >= IpyGameDataPY.GetFuncCfg("MineAreaBase", 1):  | 
|         GameWorld.ErrLog("²»´æÔڸø£µØÎïÆ·Î»ÖÃË÷Òý! itemIndex=%s" % itemIndex)  | 
|         return  | 
|     if workerCount <= 0:  | 
|         if not isPreview:  | 
|             __DoCancelPull(playerID, areaPlayerID, itemIndex, "cancel")  | 
|         return  | 
|     GameWorld.DebugLog("ÇëÇ󸣵ØÀÎïÆ·! areaPlayerID=%s,itemIndex=%s,workerCount=%s,workerState=%s,workerTotal=%s,isPreview=%s"   | 
|                        % (areaPlayerID, itemIndex, workerCount, workerState, workerTotal, isPreview), playerID)  | 
|     mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()  | 
|     mineItemData = mineItemMgr.GetMineItem(areaPlayerID, itemIndex)  | 
|     mineID = mineItemData.MineID  | 
|     if not mineID:  | 
|         GameWorld.ErrLog("¸Ã¸£µØÎ»ÖÃûÓпóÎÎÞ·¨ÀÈ¡! areaPlayerID=%s,itemIndex=%s" % (areaPlayerID, itemIndex), playerID)  | 
|         return  | 
|       | 
|     if mineItemData.MineType == MineType_Super:  | 
|         if playerID != areaPlayerID:  | 
|             GameWorld.DebugLog("¸£µØ³¬¼¶ÎïÆ·£¬½ö×Ô¼º¿ÉÀ! areaPlayerID=%s,itemIndex=%s" % (areaPlayerID, itemIndex), playerID)  | 
|             return  | 
|           | 
|     ipyData = IpyGameDataPY.GetIpyGameData("MineAreaItem", mineID)  | 
|     if not ipyData:  | 
|         return  | 
|     itemLV = ipyData.GetItemLV()  | 
|     itemLVWorkerMaxList = IpyGameDataPY.GetFuncEvalCfg("MineAreaBase", 3)  | 
|     assignMax = itemLVWorkerMaxList[itemLV - 1] if itemLV <= len(itemLVWorkerMaxList) else itemLVWorkerMaxList[-1] # ×î´ó¿ÉÉϹ¤ÈËÊý  | 
|       | 
|     atWorkCount = 0 # ÒѾÔÚÆäËûÎïÆ·¹¤×÷µÄ¹¤ÈËÊý  | 
|     pullingItemList = mineItemMgr.pullingItemListDict.get(playerID, [])  | 
|     for pullItemData in pullingItemList:  | 
|         if pullItemData.PlayerID == areaPlayerID and pullItemData.Index == itemIndex:  | 
|             # ¶ÔͬһÎïÆ·²Ù×÷£¬²»Ë㹤×÷ÈËÊý£¬¿ÉÄÜÊÇÐÞ¸ÄÈËÊý  | 
|             continue  | 
|         if pullItemData.PlayerID == playerID:  | 
|             atWorkCount += pullItemData.WorkerCount  | 
|         elif pullItemData.RobPlayerID == playerID:  | 
|             atWorkCount += pullItemData.RobWorkerCount  | 
|             if pullItemData.PlayerID == areaPlayerID:  | 
|                 GameWorld.DebugLog("²»ÄÜͬʱÇÀ½Ùͬ¸öÈ˶à¸öÎïÆ·! ÒѾÔÚÇÀ¸£µØÎ»ÖÃ: areaPlayerID=%s,index=%s" % (areaPlayerID, pullItemData.Index), playerID)  | 
|                 return  | 
|     freeWorkerCount = workerTotal - atWorkCount # ¿ÕÏй¤ÈËÊý  | 
|       | 
|     assignWorkerCount = min(freeWorkerCount, assignMax, workerCount) # Êµ¼Ê¿ÉÅÉDzµÄ¹¤ÈËÊý  | 
|     if assignWorkerCount <= 0:  | 
|         GameWorld.DebugLog("ûÓй¤ÈË¿ÉÅÉDz! atWorkCount=%s,workerTotal=%s,assignWorkerCount=%s" % (atWorkCount, workerTotal, assignWorkerCount), playerID)  | 
|         return  | 
|       | 
|     curTime = int(time.time())  | 
|     # ÏÈË¢ÐÂÏÂÎïÆ·×îÐÂλÖà  | 
|     __RefreshMineItemPosition(mineItemData, curTime)  | 
|       | 
|     if isPreview:  | 
|         ## Ô¤ÀÀËÙ¶Èʱ¼ä  | 
|         curPos = GameWorld.ToFloat(mineItemData.Position, Def_PositionMid)  | 
|         if playerID == areaPlayerID:  | 
|             curWorkerCount = assignWorkerCount  | 
|             curWorkerState = workerState  | 
|             robWorkerCount = mineItemData.RobWorkerCount  | 
|             robWorkerState = mineItemData.RobWorkerState  | 
|         else:  | 
|             curWorkerCount = mineItemData.WorkerCount  | 
|             curWorkerState = mineItemData.WorkerState  | 
|             robWorkerCount = assignWorkerCount  | 
|             robWorkerState = workerState  | 
|         ret = __calcMineItemSpeed(mineID, curPos, curWorkerCount, curWorkerState, robWorkerCount, robWorkerState)  | 
|         if not ret:  | 
|             return  | 
|         _, needSeconds = ret  | 
|         if curPlayer:  | 
|             clientPack = ChPyNetSendPack.tagGCMineItemPullPreviewRet()  | 
|             clientPack.PlayerID = areaPlayerID  | 
|             clientPack.ItemIndex = itemIndex  | 
|             clientPack.WorkerCount = assignWorkerCount  | 
|             clientPack.NeedSeconds = needSeconds  | 
|             NetPackCommon.SendFakePack(curPlayer, clientPack)  | 
|         return  | 
|       | 
|     notifyPlayerIDListEx = []  | 
|     # Ìæ»»ÐÂÊý¾Ý  | 
|     if playerID == areaPlayerID:  | 
|         mineItemData.WorkerCount = assignWorkerCount  | 
|         mineItemData.WorkerState = workerState  | 
|     else:  | 
|         mineItemData.RobPlayerID = playerID  | 
|         mineItemData.RobWorkerCount = assignWorkerCount  | 
|         mineItemData.RobWorkerState = workerState  | 
|         notifyPlayerIDListEx = [playerID]  | 
|     mineItemData.UpdTime = curTime  | 
|       | 
|     mineItemMgr.AddPlayerPullingItem(playerID, mineItemData)  | 
|       | 
|     # ÖØÐÂË¢ÐÂÏÂËÙ¶Èʱ¼ä  | 
|     __RefreshMineItemSpeed(mineItemData, True)  | 
|       | 
|     SyncMineAreaItemInfo(areaPlayerID, [itemIndex], notifyPlayerIDListEx)  | 
|     return  | 
|   | 
| def __DoCancelPull(playerID, areaPlayerID, itemIndex, reason=""):  | 
|     ## È¡ÏûÀÈ¡  | 
|     mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()  | 
|     mineItemData = mineItemMgr.GetMineItem(areaPlayerID, itemIndex)  | 
|     mineID = mineItemData.MineID  | 
|     if not mineID:  | 
|         return  | 
|       | 
|     notifyPlayerIDListEx = []  | 
|       | 
|     if mineItemData.MineType == MineType_Super:  | 
|         mineItemMgr.ClearMineItem(mineItemData)  | 
|         __OnEndSelfItem(mineItemMgr, mineItemData, areaPlayerID, itemIndex)  | 
|     else:  | 
|         curTime = int(time.time())  | 
|         # ÏÈË¢ÐÂÏÂÎïÆ·×îÐÂλÖà  | 
|         __RefreshMineItemPosition(mineItemData, curTime)  | 
|           | 
|         # Ìæ»»ÐÂÊý¾Ý  | 
|         if playerID == areaPlayerID:  | 
|             mineItemData.WorkerCount = 0  | 
|             mineItemData.WorkerState = 0  | 
|         else:  | 
|             mineItemData.RobPlayerID = 0  | 
|             mineItemData.RobWorkerCount = 0  | 
|             mineItemData.RobWorkerState = 0  | 
|             notifyPlayerIDListEx = [playerID]  | 
|         mineItemData.UpdTime = curTime  | 
|           | 
|         mineItemMgr.RemovePlayerPullingItem(playerID, mineItemData)  | 
|           | 
|         # ÖØÐÂË¢ÐÂÏÂËÙ¶Èʱ¼ä  | 
|         __RefreshMineItemSpeed(mineItemData, True)  | 
|           | 
|     SyncMineAreaItemInfo(areaPlayerID, [itemIndex], notifyPlayerIDListEx)  | 
|     curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)  | 
|     if curPlayer:  | 
|         MapServer_QueryPlayerResult(curPlayer, "MineAreaCancelPull", [areaPlayerID, reason])  | 
|     return  | 
|   | 
| def __DoMineItemRefresh(areaPlayerID, areaPlayer=None, isSys=False, isSuper=False, isNotify=True, refreshIndexList=None, setPosition=None, setItemLV=None, setMineID=None):  | 
|     '''ˢи£µØÎïÆ·  | 
|     @param areaPlayerID: ¸£µØÍæ¼ÒID£¬¿ÉÄÜÊǼÙÈË  | 
|     @param areaPlayer: ¸£µØÍæ¼ÒʵÀý  | 
|     @param isSuper: ÊÇ·ñ³¬¼¶Ë¢Ð£¬Ä¬ÈÏË¢1¸öʱЧÂú¼¶ÎïÆ·£¬Ä¬ÈÏ×Ô¼º¿É²É£¬È¡ÏûºóÏûʧ£¬Ê±¼äµ½Ã»²ÉÒ²Ïûʧ  | 
|     @param refreshIndexList: Ö¸¶¨Ö»Ë¢Î»ÖÃË÷ÒýÁÐ±í£¬Ã»ÓÐÖ¸¶¨ÔòֻˢпÉË¢Ð嵀  | 
|     @param setPosition: Ö¸¶¨×ø±êλÖã¬Ã»ÓÐÖ¸¶¨ÔòËæ»ú  | 
|     @param setItemLV: Ö¸¶¨Ö»Ë¢Ä³¸öµÈ¼¶ÎïÆ·£¬Ã»ÓÐÖ¸¶¨ÔòËæ»ú  | 
|     @param setMineID: Ö¸¶¨Ö»Ë¢Ä³¸öID£¬Ã»ÓÐÖ¸¶¨ÔòËæ»ú  | 
|     '''  | 
|       | 
|     GameWorld.DebugLog("ˢи£µØÎïÆ·: refreshIndexList=%s,isSys=%s,isSuper=%s" % (refreshIndexList, isSys, isSuper), areaPlayerID)  | 
|     if setPosition or setItemLV or setMineID:  | 
|         GameWorld.DebugLog("    setPosition=%s,setItemLV=%s,setMineID=%s" % (setPosition, setItemLV, setMineID), areaPlayerID)  | 
|           | 
|     playerLV = 0  | 
|     if areaPlayerID > Def_FakeAreaCount:  | 
|         if areaPlayer and areaPlayer.GetPlayerID() == areaPlayerID:  | 
|             playerLV = areaPlayer.GetLV()  | 
|         else:  | 
|             tagCacheDict = PlayerViewCache.GetCachePropDataDict(PlayerViewCache.FindViewCache(areaPlayerID))  | 
|             playerLV = tagCacheDict.get("LV", 0)  | 
|         GameWorld.DebugLog("    È¡Íæ¼ÒµÈ¼¶ playerLV=%s" % (playerLV), areaPlayerID)  | 
|           | 
|     if not playerLV:  | 
|         # È¡ÊÀ½çµÈ¼¶  | 
|         playerLV = max(1, PlayerDBGSEvent.GetDBGSTrig_ByKey(ShareDefine.Def_Notify_WorldKey_WorldAverageLv))  | 
|         GameWorld.DebugLog("    È¡ÊÀ½çµÈ¼¶ playerLV=%s" % (playerLV), areaPlayerID)  | 
|           | 
|     randWeightList = []  | 
|     randWeightListSuper = []  | 
|     ipyDataMgr = IpyGameDataPY.IPY_Data()  | 
|     for index in range(ipyDataMgr.GetMineAreaItemCount()):  | 
|         ipyData = ipyDataMgr.GetMineAreaItemByIndex(index)  | 
|         mineID = ipyData.GetMineID()  | 
|         limitLV = ipyData.GetLimitLV()  | 
|         if limitLV and playerLV < limitLV:  | 
|             continue  | 
|         if setItemLV and setItemLV != ipyData.GetItemLV():  | 
|             continue  | 
|         if setMineID and setMineID != mineID:  | 
|             continue  | 
|           | 
|         weight = ipyData.GetRefreshWeightSuper()  | 
|         if weight:  | 
|             randWeightListSuper.append([weight, ipyData])  | 
|               | 
|         weight = ipyData.GetRefreshWeightSys() if isSys else ipyData.GetRefreshWeight()  | 
|         if weight:  | 
|             randWeightList.append([weight, ipyData])  | 
|               | 
|     #GameWorld.DebugLog("    randWeightList=%s" % randWeightList, areaPlayerID)  | 
|     #GameWorld.DebugLog("    randWeightListSuper=%s" % randWeightListSuper, areaPlayerID)  | 
|     if not randWeightList and not randWeightListSuper:  | 
|         return  | 
|       | 
|     mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()  | 
|     randDist = IpyGameDataPY.GetFuncCfg("MineAreaBase", 2)  | 
|     superCount = 0  | 
|     superCountMax = 1 # Ã¿´ÎË¢ÐÂ×î´óË¢³ö³¬¼¶ÎïÆ·ÊýÁ¿£¬ÒѾˢгöµÄ²»¼ÆËãÔÚÄÚ  | 
|       | 
|     refreshDict = {}  | 
|     if not refreshIndexList:  | 
|         refreshIndexList = range(IpyGameDataPY.GetFuncCfg("MineAreaBase", 1))  | 
|     for index in refreshIndexList:  | 
|         mineItemData = mineItemMgr.GetMineItem(areaPlayerID, index)  | 
|         if mineItemData.MineID and (mineItemData.WorkerCount or mineItemData.RobWorkerCount):  | 
|             # ÓÐÈËÁË£¬²»Ë¢Ð  | 
|             continue  | 
|           | 
|         randIpyData = None  | 
|         mineType = MineType_Normal  | 
|           | 
|         if isSuper and superCount < superCountMax:  | 
|             randIpyData = GameWorld.GetResultByWeightList(randWeightListSuper)  | 
|             if randIpyData:  | 
|                 superCount += 1  | 
|                 mineType = MineType_Super  | 
|         else:  | 
|             randIpyData = GameWorld.GetResultByWeightList(randWeightList)  | 
|               | 
|         if not randIpyData:  | 
|             continue  | 
|         randMineID = randIpyData.GetMineID()  | 
|         itemLV = randIpyData.GetItemLV()  | 
|           | 
|         if setPosition:  | 
|             position = min(Def_PositionMax - 1, max(1, setPosition))  | 
|         else:  | 
|             position = random.randint(Def_PositionMid - randDist, Def_PositionMid + randDist) # Ëæ»úλÖà  | 
|         mineItemMgr.InitMineItem(mineItemData, areaPlayerID, index, randMineID, mineType, position)  | 
|           | 
|         if mineType == MineType_Super and mineItemData not in mineItemMgr.freeSuperItemList:  | 
|             mineItemMgr.freeSuperItemList.append(mineItemData)  | 
|               | 
|         refreshDict[index] = {"randMineID":randMineID, "position":position, "mineType":mineType, "itemLV":itemLV}  | 
|         GameWorld.DebugLog("    index=%s,randMineID=%s,position=%s,mineType=%s,itemLV=%s" % (index, randMineID, position, mineType, itemLV), areaPlayerID)  | 
|           | 
|     if isNotify and refreshDict:  | 
|         SyncMineAreaItemInfo(areaPlayerID, refreshDict.keys())  | 
|     return refreshDict  | 
|   | 
| #// B0 33 ¸£µØ²é¿´ #tagCGMineAreaView  | 
| #  | 
| #struct    tagCGMineAreaView  | 
| #{  | 
| #    tagHead        Head;  | 
| #    BYTE        QueryType;    // ²éѯͬ²½ÀàÐÍ£º0-ºó¶ËÖ÷¶¯Í¬²½£»1-²é¿´Ö¸¶¨¸£µØ£»2-²é¿´µÀÓѸ£µØÁÐ±í£»3-²é¿´ÖÜÎ§Ëæ»ú¸£µØÁÐ±í£»4-Í˳öËûÈ˸£µØ£»5-²é¿´¼Ç¼  | 
| #    DWORD        QueryValue;    // ²éѯֵ£¬ÀàÐÍ1ʱ-·¢ËÍÄ¿±êÍæ¼ÒID£»3ʱ-·¢ËÍÊÇ·ñÖØÐÂËæ»ú  | 
| #};  | 
| def OnMineAreaView(index, clientData, tick):  | 
|     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  | 
|     playerID = curPlayer.GetPlayerID()  | 
|       | 
|     queryType = clientData.QueryType  | 
|     queryValue = clientData.QueryValue  | 
|       | 
|     # ²é¿´Ö¸¶¨¸£µØ  | 
|     if queryType == 1:  | 
|         areaPlayerID = queryValue if queryValue > 0 else  playerID  | 
|         mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()  | 
|         if areaPlayerID not in mineItemMgr.playerMineItemDict:  | 
|             GameWorld.DebugLog("²»´æÔڸø£µØ! areaPlayerID=%s" % areaPlayerID)  | 
|             return  | 
|         if playerID != areaPlayerID:  | 
|             mineItemMgr.AddViewAreaPlayerID(playerID, areaPlayerID)  | 
|               | 
|         clientPack = __GetMineAreaInfoPack([[areaPlayerID, []]], queryType, queryValue)  | 
|         NetPackCommon.SendFakePack(curPlayer, clientPack)  | 
|           | 
|     # ²é¿´µÀÓѸ£µØÁÐ±í  | 
|     elif queryType == 2:  | 
|         SyncSocialAreaInfo(curPlayer, queryType, queryValue)  | 
|                   | 
|     # ²é¿´ÖÜÎ§Ëæ»ú¸£µØÁÐ±í  | 
|     elif queryType == 3:  | 
|         SyncNeighborAreaInfo(curPlayer, tick, queryType, queryValue)  | 
|           | 
|     # Í˳öËûÈ˸£µØ  | 
|     elif queryType == 4:  | 
|         PyDataManager.GetDBPyMineAreaItemManager().DelViewAreaPlayerID(playerID)  | 
|           | 
|     # ²é¿´¼Ç¼  | 
|     elif queryType == 5:  | 
|         SyncAreaRecord(curPlayer)  | 
|           | 
|     return  | 
|   | 
| def SyncMineAreaItemInfo(areaPlayerID, mineIndexList, notifyPlayerIDListEx=None):  | 
|     '''ij¸ö¸£µØÎïÆ·±ä¸üʱͬ²½£¬»áͬ²½¸øÏà¹ØÍæ¼Ò  | 
|     @param areaPlayerID: ¸£µØÍæ¼ÒID£¬¿ÉÄÜÊǼÙÈË  | 
|     @param mineIndexList: ÐèҪͬ²½µÄ¿óÎïË÷Òý  | 
|     @param notifyPlayerIDListEx: ¶îÍâÐèҪ֪ͨµÄÍæ¼ÒIDÁÐ±í  | 
|     '''  | 
|     if not mineIndexList:  | 
|         return  | 
|       | 
|     notifyPlayerIDList = [] # Í¬²½¸øÏà¹ØµÄÍæ¼Ò£¬Ä¬Èϰüº¬×Ô¼º  | 
|     mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()  | 
|       | 
|     # ×Ô¼º£¬¼ÙÈ˲»Óà  | 
|     if areaPlayerID > Def_FakeAreaCount:  | 
|         notifyPlayerIDList.append(areaPlayerID)  | 
|           | 
|     # ÁбíÖÐ  | 
|     for playerID, socialIDList in mineItemMgr.socialIDListDict.items():  | 
|         if areaPlayerID in socialIDList:  | 
|             notifyPlayerIDList.append(playerID)  | 
|     for playerID, neighborIDList in mineItemMgr.neighborIDListDict.items():  | 
|         if areaPlayerID in neighborIDList:  | 
|             notifyPlayerIDList.append(playerID)  | 
|               | 
|     # ÇÀ½ÙÖÐ  | 
|     for index in mineIndexList:  | 
|         mineItemData = mineItemMgr.GetMineItem(areaPlayerID, index)  | 
|         if mineItemData.RobPlayerID:  | 
|             notifyPlayerIDList.append(mineItemData.RobPlayerID)  | 
|               | 
|     # ²é¿´ÖÐ  | 
|     if areaPlayerID in mineItemMgr.viewAreaPlayerIDDict:  | 
|         notifyPlayerIDList += mineItemMgr.viewAreaPlayerIDDict[areaPlayerID]  | 
|           | 
|     # ¶îÍâµÄ  | 
|     if notifyPlayerIDListEx:  | 
|         notifyPlayerIDList += notifyPlayerIDListEx  | 
|           | 
|     if not notifyPlayerIDList:  | 
|         return  | 
|       | 
|     clientPack = __GetMineAreaInfoPack([[areaPlayerID, mineIndexList]])  | 
|     # È¥ÖØÍ¬²½  | 
|     playerManager = GameWorld.GetPlayerManager()  | 
|     for playerID in set(notifyPlayerIDList):  | 
|         if playerID <= Def_FakeAreaCount:  | 
|             continue  | 
|         curPlayer = playerManager.FindPlayerByID(playerID)  | 
|         if curPlayer == None or not curPlayer.GetInitOK():  | 
|             continue  | 
|         if PlayerControl.GetIsTJG(curPlayer):  | 
|             continue  | 
|         NetPackCommon.SendFakePack(curPlayer, clientPack)  | 
|     return  | 
|   | 
| def SyncSocialAreaInfo(curPlayer, queryType=0, queryValue=0):  | 
|     ## Í¬²½ÓйØÏµµÄµÀÓѸ£µØÁÐ±í  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()  | 
|     if playerID in mineItemMgr.socialIDListDict:  | 
|         socialIDList = mineItemMgr.socialIDListDict[playerID]  | 
|     else:  | 
|         socialIDList = __DoUpdSocialPlayerIDList(playerID)  | 
|           | 
|     areaMineList = [[areaPlayerID, []] for areaPlayerID in socialIDList]  | 
|     clientPack = __GetMineAreaInfoPack(areaMineList, queryType, queryValue)  | 
|     NetPackCommon.SendFakePack(curPlayer, clientPack)  | 
|     return  | 
|   | 
| def SyncNeighborAreaInfo(curPlayer, tick, queryType=0, queryValue=0):  | 
|     ## Í¬²½ÖÜÎ§Ëæ»ú¸£µØÁÐ±í  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     isRefresh = queryValue  | 
|     mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()  | 
|     neighborIDList = mineItemMgr.neighborIDListDict.get(playerID, [])  | 
|     neighborIDListBef = neighborIDList  | 
|     if isRefresh:  | 
|         refreshCD = IpyGameDataPY.GetFuncCfg("MineAreaRob", 3) * 1000  | 
|         if refreshCD:  | 
|             if tick - curPlayer.GetDictByKey(NeighborAreaRefreshTick) < refreshCD:  | 
|                 GameWorld.Log("ÖÜÎ§Ëæ»ú¸£µØË¢ÐÂCDÖУ¡", playerID)  | 
|                 return  | 
|             curPlayer.SetDict(NeighborAreaRefreshTick, tick)  | 
|         neighborIDList = [] # ÖÿÕÖØÐÂËæ»ú  | 
|     else:  | 
|         neighborIDList = mineItemMgr.neighborIDListDict.get(playerID, [])  | 
|           | 
|     if not neighborIDList:  | 
|         # ÓÅÏÈËæ»úÕæÈË  | 
|         random.shuffle(mineItemMgr.realAreaPlayerIDList)  | 
|         random.shuffle(mineItemMgr.fackAreaPlayerIDList)  | 
|         areaPlayerIDList = mineItemMgr.realAreaPlayerIDList + mineItemMgr.fackAreaPlayerIDList  | 
|         if playerID in areaPlayerIDList:  | 
|             areaPlayerIDList.remove(playerID)  | 
|         for neighborIDBef in neighborIDListBef: # Ö®Ç°µÄÏȲ»Ëæ»ú  | 
|             if neighborIDBef in areaPlayerIDList:  | 
|                 areaPlayerIDList.remove(neighborIDBef)  | 
|         neighborCount = IpyGameDataPY.GetFuncCfg("MineAreaRob", 2)  | 
|         neighborIDList = areaPlayerIDList[:neighborCount]  | 
|         mineItemMgr.neighborIDListDict[playerID] = neighborIDList  | 
|         GameWorld.DebugLog("Ë¢ÐÂÖÜÎ§Ëæ»ú¸£µØ: %s" % neighborIDList, playerID)  | 
|           | 
|     areaMineList = [[areaPlayerID, []] for areaPlayerID in neighborIDList]  | 
|     clientPack = __GetMineAreaInfoPack(areaMineList, queryType, queryValue)  | 
|     NetPackCommon.SendFakePack(curPlayer, clientPack)  | 
|     return  | 
|   | 
| def SyncPullingAreaMineInfo(curPlayer):  | 
|     ## Í¬²½ÀÈ¡ÖеÄÎïÆ·ÐÅÏ¢£¬½öµÇ¼ʱÖ÷¶¯Í¬²½Ò»´Î  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()  | 
|     if playerID not in mineItemMgr.pullingItemListDict:  | 
|         return  | 
|     pullingItemList = mineItemMgr.pullingItemListDict[playerID]  | 
|     if not pullingItemList:  | 
|         return  | 
|       | 
|     pullIndexDict = {}  | 
|     for mineItemData in pullingItemList:  | 
|         areaPlayerID = mineItemData.PlayerID  | 
|         if areaPlayerID not in pullIndexDict:  | 
|             pullIndexDict[areaPlayerID] = []  | 
|         indexList = pullIndexDict[areaPlayerID]  | 
|         indexList.append(mineItemData.Index)  | 
|     areaMineList = []  | 
|     for areaPlayerID, indexList in pullIndexDict.items():  | 
|         areaMineList.append([areaPlayerID, indexList])  | 
|     clientPack = __GetMineAreaInfoPack(areaMineList)  | 
|     NetPackCommon.SendFakePack(curPlayer, clientPack)  | 
|     return  | 
|   | 
| def __GetMineAreaInfoPack(areaMineList, queryType=0, queryValue=0):  | 
|     ''' »ñȡͬ²½¸£µØÏêϸÐÅÏ¢°ü  | 
|     @param areaMineList: [[areaPlayerID, mineIndexList], ...] °´Ö¸¶¨¸£µØID˳ÐòÁбí»ñÈ¡£¬mineIndexListΪ¿Õʱͬ²½¸Ã¸£µØÈ«²¿ÎïÆ·£¬·ñÔòֻͬ²½Ö¸¶¨Ë÷ÒýÎïÆ·  | 
|     '''  | 
|     mineItemMgr = PyDataManager.GetDBPyMineAreaItemManager()  | 
|     clientPack = ChPyNetSendPack.tagGCMineAreaInfo()  | 
|     clientPack.QueryType = queryType  | 
|     clientPack.QueryValue = queryValue  | 
|     clientPack.AreaList = []  | 
|     for areaPlayerID, mineIndexList in areaMineList:  | 
|         areaInfo = ChPyNetSendPack.tagGCMineArea()  | 
|         areaInfo.PlayerID = areaPlayerID  | 
|         if areaPlayerID > Def_FakeAreaCount:  | 
|             cacheDict = PlayerViewCache.GetCachePropDataDict(PlayerViewCache.FindViewCache(areaPlayerID))  | 
|             areaInfo.PlayerName = cacheDict.get("Name", "")  | 
|             areaInfo.Job = cacheDict.get("Job", 0)  | 
|             areaInfo.Face = cacheDict.get("Face", 0)  | 
|             areaInfo.FacePic = cacheDict.get("FacePic", 0)  | 
|                       | 
|         areaInfo.MineItemList = []  | 
|         if not mineIndexList:  | 
|             mineIndexList = range(IpyGameDataPY.GetFuncCfg("MineAreaBase", 1))  | 
|         for index in mineIndexList:  | 
|             mineItemData = mineItemMgr.GetMineItem(areaPlayerID, index)  | 
|             mineItem = ChPyNetSendPack.tagGCMineItem()  | 
|             mineItem.Index = index  | 
|             mineItem.MineID = mineItemData.MineID  | 
|             mineItem.MineType = mineItemData.MineType  | 
|             mineItem.UpdTime = mineItemData.UpdTime  | 
|             mineItem.Position = mineItemData.Position  | 
|             mineItem.PosLen = len(mineItem.Position)  | 
|             mineItem.MoveSpeed = "%s" % getattr(mineItemData, MineItemAttr_MoveSpeed, 0)  | 
|             mineItem.SpeedLen = len(mineItem.MoveSpeed)  | 
|             mineItem.EndTime = getattr(mineItemData, MineItemAttr_EndTime, 0)  | 
|             mineItem.WorkerCount = mineItemData.WorkerCount  | 
|             mineItem.RobPlayerID = mineItemData.RobPlayerID  | 
|             mineItem.RobWorkerCount = mineItemData.RobWorkerCount  | 
|             if mineItemData.RobPlayerID:  | 
|                 robCacheDict = PlayerViewCache.GetCachePropDataDict(PlayerViewCache.FindViewCache(mineItemData.RobPlayerID))  | 
|                 mineItem.RobPlayerName = robCacheDict.get("Name", "")  | 
|                 mineItem.RobJob = robCacheDict.get("Job", 0)  | 
|                 mineItem.RobFace = robCacheDict.get("Face", 0)  | 
|                 mineItem.RobFacePic = robCacheDict.get("FacePic", 0)  | 
|             areaInfo.MineItemList.append(mineItem)  | 
|         areaInfo.MineCount = len(areaInfo.MineItemList)  | 
|           | 
|         clientPack.AreaList.append(areaInfo)  | 
|     clientPack.AreaCount = len(clientPack.AreaList)  | 
|     return clientPack  | 
|   | 
| def SyncAreaRecord(curPlayer):  | 
|     playerID = curPlayer.GetPlayerID()  | 
|     recordMgr = PyDataManager.GetDBPyMineAreaRecordManager()  | 
|     recordList = recordMgr.playerMineRecordListDict.get(playerID, [])  | 
|       | 
|     clientPack = ChPyNetSendPack.tagGCMineAreaRecordInfo()  | 
|     clientPack.AreaRecordList = []  | 
|     for recData in recordList:  | 
|         recordInfo = ChPyNetSendPack.tagGCMineAreaRecord()  | 
|         recordInfo.RecordType = recData.RecordType  | 
|         recordInfo.TagPlayerID = recData.TagPlayerID  | 
|         recordInfo.RecordTime = recData.RecordTime  | 
|         recordInfo.MineID = recData.MineID  | 
|         if playerID != recordInfo.TagPlayerID and recordInfo.TagPlayerID > Def_FakeAreaCount:  | 
|             tagCacheDict = PlayerViewCache.GetCachePropDataDict(PlayerViewCache.FindViewCache(recordInfo.TagPlayerID))  | 
|             recordInfo.TagPlayerName = tagCacheDict.get("Name", "")  | 
|             recordInfo.TagJob = tagCacheDict.get("Job", 0)  | 
|             recordInfo.TagFace = tagCacheDict.get("Face", 0)  | 
|             recordInfo.TagFacePic = tagCacheDict.get("FacePic", 0)  | 
|         clientPack.AreaRecordList.append(recordInfo)  | 
|     clientPack.RecordCount = len(clientPack.AreaRecordList)  | 
|     NetPackCommon.SendFakePack(curPlayer, clientPack)  | 
|     return  | 
|   | 
| #// B0 34 ¸£µØÇëÇó½áËã½±Àø #tagCGMineAreaAwardGet  | 
| #  | 
| #struct    tagCGMineAreaAwardGet  | 
| #{  | 
| #    tagHead        Head;  | 
| #};  | 
| def OnMineAreaAwardGet(index, clientData, tick):  | 
|     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  | 
|     playerID = curPlayer.GetPlayerID()  | 
|       | 
|     if tick - curPlayer.GetDictByKey(MineAreaAwardGetTick) < 10000:  | 
|         GameWorld.DebugLog("½áË㸣µØ½±ÀøÇëÇóCDÖУ¡", playerID)  | 
|         return  | 
|       | 
|     awardMgr = PyDataManager.GetDBPyMineAreaAwardManager()  | 
|     awardDict = awardMgr.playerAreaAwardDict.get(playerID, {})  | 
|     if not awardDict:  | 
|         GameWorld.DebugLog("µ±Ç°¸£µØÍæ¼ÒûÓдýÁìÈ¡½±Àø£¡", playerID)  | 
|         return  | 
|       | 
|     awardItemDict = {}  | 
|     awardInfoList = []  | 
|     for GUID, awardData in awardDict.items():  | 
|         mineID = awardData.MineID  | 
|         awardTime = awardData.AwardTime  | 
|         workerCount = awardData.WorkerCount  | 
|         areaPlayerID = awardData.AreaPlayerID  | 
|         ipyData = IpyGameDataPY.GetIpyGameData("MineAreaItem", mineID)  | 
|         if not ipyData:  | 
|             continue  | 
|         itemID = ipyData.GetItemID()  | 
|         itemCount = ipyData.GetItemCount()  | 
|         itemLV = ipyData.GetItemLV()  | 
|         awardItemDict[itemID] = awardItemDict.get(itemID, 0) + itemCount  | 
|         awardInfoList.append([GUID, awardTime, workerCount, areaPlayerID, mineID, itemLV, itemID, itemCount])  | 
|           | 
|     # Í¨ÖªµØÍ¼Íæ¼Ò¸øÎïÆ·  | 
|     curPlayer.SetDict(MineAreaAwardGetTick, tick)  | 
|     MapServer_QueryPlayerResult(curPlayer, "MineAreaAwardGet", [awardInfoList])  | 
|     return  | 
|   | 
| def __DoMineAreaAwardGetOK(curPlayer, dataMsg):  | 
|       | 
|     playerID = curPlayer.GetPlayerID()  | 
|     GUIDList, awardItemList = dataMsg  | 
|     curPlayer.SetDict(MineAreaAwardGetTick, 0)  | 
|       | 
|     awardMgr = PyDataManager.GetDBPyMineAreaAwardManager()  | 
|     awardDict = awardMgr.playerAreaAwardDict.get(playerID, {})  | 
|     if not awardDict:  | 
|         return  | 
|       | 
|     for GUID in GUIDList:  | 
|         awardDict.pop(GUID, None)  | 
|           | 
|     SyncMineAwardAward(curPlayer, 1, awardItemList)  | 
|     return  | 
|   | 
| def SyncMineAwardAward(curPlayer, awardType=0, awardItemList=None):  | 
|     # @param awardType: 0-֪ͨÓн±Àø£¬Ç°¶ËÏ´νøÈ븣µØ¿ÉÇëÇó½øÐнáË㣻1-½áËã½±Àø½á¹û֪ͨ  | 
|     # @param awardItemList: ½±ÀøÐÅÏ¢ [[ÎïÆ·ID,¸öÊý,ÊÇ·ñÅÄÆ·], ...]  | 
|     clientPack = ChPyNetSendPack.tagGCMineAreaAwardInfo()  | 
|     clientPack.AwardType = awardType  | 
|     if awardItemList:  | 
|         clientPack.AwardInfo = str(awardItemList)  | 
|     clientPack.AwardLen = len(clientPack.AwardInfo)  | 
|     NetPackCommon.SendFakePack(curPlayer, clientPack)  | 
|     return  | 
|   | 
| def MapServer_QueryPlayerResult(curPlayer, queryType, queryData, ret=1):  | 
|     resultMsg = str([queryType, queryData, ret])  | 
|     curPlayer.MapServer_QueryPlayerResult(0, 0, "MineArea", resultMsg, len(resultMsg))  | 
|     GameWorld.Log("¸£µØ·¢ËÍMapServer: %s" % resultMsg, curPlayer.GetPlayerID())  | 
|     return  | 
|   | 
|      |