| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
| #  | 
| #  | 
| ##@package PlayerDBOper.py  | 
| #  | 
| # @todo:¹ÜÀíÊý¾Ý¿â  | 
| #  | 
| # @author whx  | 
| # @date 2012-11-09 10:00  | 
| # @version 1.8  | 
| # @note:  | 
| #  | 
| # @change: "2012-11-30 19:00" hyx ReloadÊ±ÖØÐ¼ÓÔØÊý¾Ý  | 
| # @change: "2012-12-03 11:55" hyx »¹ÔÊý¾Ý±íÃû  | 
| # @change: "2012-12-29 13:30" jiang Ôö¼Ó¶ÁÈ¡±í³É¹¦ÒÔºóµÄ²Ù×÷  | 
| # @change: "2013-01-11 11:00" wdb Íò¹úÕ½±¨ÃûÐÞ¸ÄΪÔÚ¿ç·þ·þÎñÆ÷  | 
| # @change: "2015-04-02 19:00" hxp Ö§³Ö×Ô¶¨Ò幦ÄÜÀàÐÍÊý¾Ý²Ù×÷  | 
| # @change: "2015-04-09 11:00" hxp Ôö¼Ó´úÊÕÖ²ÎïÀëÏßÖ÷È˲éѯ  | 
| # @change: "2015-11-13 17:00" hxp Ôö¼ÓÍõÕßÕù°Ô  | 
| # @change: "2016-07-25 21:00" hxp ¼ò»¯´úÂë  | 
| #------------------------------------------------------------------------------   | 
| #"""Version = 2016-07-25 21:00"""  | 
| #------------------------------------------------------------------------------   | 
| import GameWorld  | 
| import ChConfig  | 
| import IPY_GameServer  | 
| import ReadChConfig  | 
| import base64  | 
| import cPickle  | 
|   | 
| #[isBase64, gbk]  | 
| EncodingList = ReadChConfig.GetEvalChConfig("EncodingTex")  | 
|   | 
| #Êý¾Ý¿â²Ù×÷ÃüÁîÁÐ±í  | 
| g_dbCommandList = []  | 
| g_proccessCmdInfo = []   | 
|   | 
| #Íæ¼Ò±í  | 
| Table_DBPlayer = "tagDBPlayer"  | 
|   | 
| #-------------------------------------------------------------------------  | 
|   | 
| #//04 04 Êý¾Ý¿â²Ù×÷½á¹û#tagDGDBOperResult  | 
| #struct tagDGDBOperResult  | 
| #{  | 
| #      tagHead     Head;  | 
| #       BYTE    Result;             //½á¹û£º1³É¹¦£¬0ʧ°Ü  | 
| #       DWORD     ResultSetLen;  | 
| #       char     ResultSet[ResultSetLen];    //½á¹û¼¯  | 
| #       DWORD     ErrorMsgLen;  | 
| #       char     ErrorMsg[ErrorMsgLen];     //´íÎóÐÅÏ¢  | 
| # };  | 
| ## DB·µ»Øµ½GameServerÐÅÏ¢  | 
| #  @param None None  | 
| #  @return None  | 
| def GetDGDBOperResultInfo(index, tick):  | 
|       | 
|     ##tagDGGeneralDBOperResult:Type: 116,Result: 1,ResultSetLen: 357,  | 
|     #ResultSet: [{u'a': 33, u'c': u'dddd', u'_id': ObjectId('50641259cd84ceddac3e6945')},   | 
|     #{u'a': 33, u'_id': ObjectId('506412cdcd84ceddac3e6946'), u'b': 33},   | 
|     #{u'a': 33, u'_id': ObjectId('506412eacd84ceddac3e6948'), u'b': 33},   | 
|     #{u'a': 33, u'_id': ObjectId('5064136acd84ceddac3e694a'), u'b': u'dfsss'},   | 
|     #{u'a': 33, u'_id': ObjectId('50641375cd84ceddac3e694b'), u'b': u'dfsss'}],  | 
|     #ErrMsgLen: 0,ErrMsg: (null),  | 
|       | 
|     dbOperResultInfo = IPY_GameServer.IPY_DGDBOperResult()  | 
|     result = dbOperResultInfo.GetResult()  #½á¹û£º1³É¹¦£¬0ʧ°Ü  | 
|       | 
|     if not result:  | 
|         #ÊÕµ½£¬ÉèÖÿÉÒÔ¼ÌÐø·¢ËÍÃüÁî  | 
|         __ResetDBOper()  | 
|         GameWorld.ErrLog("²Ù×÷DBʧ°Ü£¡£¡£¡")  | 
|         return  | 
|       | 
|     resultSet = dbOperResultInfo.GetResultSet()  | 
|       | 
|     if not resultSet:  | 
|         #ÊÕµ½£¬ÉèÖÿÉÒÔ¼ÌÐø·¢ËÍÃüÁî  | 
|         __ResetDBOper()  | 
|         return  | 
|       | 
|     resultSet = eval(resultSet.replace('ObjectId', 'str'))  | 
|     #È¡¿âת±àÂë  | 
|     resultSetList = TranslateOutDBList(resultSet)  | 
|       | 
|     #´¦Àí±í¶ÁÈ¡³É¹¦×´Ì¬  | 
|     __DoLogic_DGDBOperResult(resultSetList)  | 
|       | 
|     #ÊÕµ½£¬ÉèÖÿÉÒÔ¼ÌÐø·¢ËÍÃüÁî  | 
|     __ResetDBOper()  | 
|     return  | 
|   | 
|   | 
| ## ´¦Àí±í¶ÁÈ¡³É¹¦×´Ì¬  | 
| #  @param resultSetList: ²éѯ½á¹û  | 
| #  @return: None  | 
| def __DoLogic_DGDBOperResult(resultSetList):  | 
|     global g_proccessCmdInfo  | 
|       | 
|     if not g_proccessCmdInfo:  | 
|         return  | 
|       | 
|     callFunc, extendValueList = g_proccessCmdInfo  | 
|   | 
|     if callFunc:  | 
|         return callFunc(resultSetList, extendValueList)  | 
|       | 
|     return  | 
|   | 
|   | 
| ## Ìí¼Ó½ødb²Ù×÷ÁÐ±í  | 
| #  @param operList [type, ²Ù×÷ÃüÁî×Öµä]  | 
| #  @return None  | 
| def AddDBCommandList(operList):  | 
|     global g_dbCommandList  | 
|       | 
|     GameWorld.Log("Ìí¼ÓDBComand operList=%s"%operList)  | 
|       | 
|     g_dbCommandList.append(operList)  | 
|     return  | 
|   | 
|   | 
| ## ¶¨Ê±µ÷Óà  | 
| #  @param dictInfoList ²åÈëµÄ×ÖµäÁÐ±í  | 
| #  @return None  | 
| def PyDBProccess(tick):  | 
|     global g_dbCommandList  | 
|     global g_proccessCmdInfo  | 
|       | 
|     #ÁбíûÓÐÐÅÏ¢  | 
|     if len(g_dbCommandList) <= 0:  | 
|         return  | 
|       | 
|     #ÊÇ·ñÍ£Ö¹·¢ËÍÃüÁî  | 
|     isStopSendInfo = GameWorld.GetGameWorld().GetDictByKey(ChConfig.Def_PlayerKey_IsStopSendDBCommand)  | 
|       | 
|     #ÕýÔڵȴýDB»ØÓ¦  | 
|     if isStopSendInfo:  | 
|         sendTick = GameWorld.GetGameWorld().GetDictByKey(ChConfig.Def_PlayerKey_SendDBComTick)  | 
|         #»¹Î´30Ãë  | 
|         if tick - sendTick < ChConfig.TYPE_Tick_Time[ChConfig.TYPE_SendDBCommandTick]:   | 
|             return  | 
|           | 
|         #³¬¹ý30ÃëµÈ´ýʱ¼ä  | 
|         #¿ÉÒÔ¼ÌÐø·¢ËÍÃüÁî  | 
|         __ResetDBOper()  | 
|         GameWorld.ErrLog("wait for DB responses overtime")  | 
|         return  | 
|     #ÉèÖõȴý½á¹ûÔÙ·¢ËÍ  | 
|     GameWorld.GetGameWorld().SetDict(ChConfig.Def_PlayerKey_IsStopSendDBCommand, 1)  | 
|       | 
|     sendDict, callFunc, extendValueList = g_dbCommandList.pop(0)  | 
|       | 
|     #0£º²»·µ»Ø£¬1£ºDB·µ»ØÐÅÏ¢µ½GameServer  | 
|     sendMsg = cPickle.dumps(sendDict, 2)  | 
|     GameWorld.GetGameWorld().SendDBOper(1, sendMsg, len(sendMsg))  | 
|     GameWorld.Log("send dbcommand:%s"%sendDict)  | 
|       | 
|     g_proccessCmdInfo = [callFunc, extendValueList]  | 
|       | 
|     #ÉèÖ÷¢ËÍÃüÁîµÄʱ¼ä  | 
|     GameWorld.GetGameWorld().SetDict(ChConfig.Def_PlayerKey_SendDBComTick, tick)  | 
|       | 
|     return  | 
|           | 
|   | 
| ## ÖØÖÃÊý¾Ý¿â²Ù×÷  | 
| #  @param None  | 
| #  @return None      | 
| def __ResetDBOper():  | 
|     global g_proccessCmdInfo  | 
|     g_proccessCmdInfo = []  | 
|     GameWorld.GetGameWorld().SetDict(ChConfig.Def_PlayerKey_IsStopSendDBCommand, 0)  | 
|     return  | 
|   | 
| #operDictÊǸöPython×Öµä  | 
| #Ô¤¶¨ÒåµÄKEY:  | 
| #collection:±íÃû(±ØÐè)  | 
| #oper:²Ù×÷(±ØÐè),Ŀǰ֧³Ödrop/insert/update/remove/find  | 
| #docs:Êý¾Ý¼¯×Öµä»ò×ÖµäÁбí(·Ç±ØÐè)  | 
| #spec:Ìõ¼þ×Öµä(·Ç±ØÐè)  | 
|   | 
| ## ²åÈëÊý¾Ý¿â  | 
| #  @param collection ±íÃû  | 
| #  @param dictInfoList ²åÈëµÄ×ÖµäÁÐ±í  | 
| #  @return None  | 
| def InsertDBOper(collection, dictInfoList, callFunc=None, extendValueList=[]):  | 
|     resultList = TranslateInDBList(dictInfoList)  | 
|       | 
|     operDict = {'collection':collection, 'oper':'insert', 'docs':resultList}  | 
|       | 
|     operList = [operDict, callFunc, extendValueList]  | 
|     AddDBCommandList(operList)   | 
|     return  | 
|   | 
|   | 
| ## ²éѯÊý¾Ý  | 
| #  @param collection ±íÃû  | 
| #  @param findDict ²éÕÒµÄ×ÖµäÖµ  | 
| #  @param fields ²éѯµÄÖ¸¶¨·µ»Ø×Ö¶Î  | 
| #  @param callFunc »Øµ÷º¯Êý  | 
| #  @param extendValueList À©Õ¹ÊýÖµÁÐ±í  | 
| #  @return None  | 
| def FindDBOper(collection, findDict, fields={}, callFunc=None, extendValueList=[]):  | 
|     findDict = TranslateInDBDict(findDict)  | 
|       | 
|     operDict = {'collection':collection, 'oper':'find', 'spec':findDict, 'fields':fields}  | 
|       | 
|     operList = [operDict, callFunc, extendValueList]  | 
|     AddDBCommandList(operList)   | 
|       | 
|     return  | 
|   | 
|   | 
| ## ¸üÐÂÊý¾Ý  | 
| #  @param collection ±íÃû  | 
| #  @param tagFieldDict ¶¨Î»¼Ç¼  | 
| #  @param updateDict ¸üеÄÄÚÈÝ  | 
| #  @return None  | 
| def UpdateDBOper(collection, tagFieldDict, updateDict, callFunc=None, extendValueList=[]):  | 
|     tagFieldDict = TranslateInDBDict(tagFieldDict)  | 
|     updateDict = TranslateInDBDict(updateDict)  | 
|       | 
|     operDict = {'collection':collection, 'oper':'update', 'spec':tagFieldDict, 'docs':{'$set':updateDict}}  | 
|     operList = [operDict, callFunc, extendValueList]  | 
|     AddDBCommandList(operList)   | 
|     return  | 
|       | 
|   | 
| ## É¾³ý¼Ç¼  | 
| #  @param collection ±íÃû  | 
| #  @param tagFieldDict ¶¨Î»¼Ç¼  | 
| #  @return None  | 
| def RemoveDBOper(collection, tagFieldDict, callFunc=None, extendValueList=[]):  | 
|     tagFieldDict = TranslateInDBDict(tagFieldDict)  | 
|       | 
|     operDict = {'collection':collection, 'oper':'remove', 'spec':tagFieldDict}  | 
|     operList = [operDict, callFunc, extendValueList]  | 
|     AddDBCommandList(operList)   | 
|     return  | 
|   | 
|   | 
| ## É¾³ý±í  | 
| #  @param collection ±íÃû  | 
| #  @return None  | 
| def DropDBOper(collection, callFunc=None, extendValueList=[]):  | 
|     operDict = {'collection':collection, 'oper':'drop'}  | 
|     operList = [operDict, callFunc, extendValueList]  | 
|     AddDBCommandList(operList)    | 
|     return  | 
|   | 
|   | 
| #--------------------------³öÈë¿âתÂë------------------------------------  | 
|   | 
| ## ´æÈëÊý¾Ý¿âת»¯×Öµä±àÂë  | 
| #  @param dictInfoList Ô×ÖµäÁÐ±í  | 
| #  @return None  | 
| def TranslateInDBList(dictInfoList):  | 
|     resultList = []  | 
|       | 
|     for infoDict in dictInfoList:  | 
|         resDict = TranslateInDBDict(infoDict)  | 
|         resultList.append(resDict)  | 
|       | 
|     return resultList  | 
|   | 
|   | 
|   | 
| ## ´æÈëÊý¾Ý¿âת»¯×Öµä±àÂë  | 
| #  @param tagDict Ô×Öµä  | 
| #  @return None  | 
| def TranslateInDBDict(tagDict):  | 
|     resultDict = {}  | 
|       | 
|     for key, value in tagDict.items():  | 
|         resultDict[key] = IncomingText(value)  | 
|       | 
|     return resultDict  | 
|   | 
|   | 
| ## È¡³öÊý¾Ý¿âת»¯×Öµä±àÂë  | 
| #  @param dictInfoList Ô×ÖµäÁÐ±í  | 
| #  @return None  | 
| def TranslateOutDBList(dictInfoList):  | 
|     resultList = []  | 
|       | 
|     for infoDict in dictInfoList:  | 
|         resDict = TranslateOutDBDict(infoDict)  | 
|         resultList.append(resDict)  | 
|       | 
|     return resultList  | 
|   | 
|   | 
|   | 
| ## È¡³öÊý¾Ý¿âת»¯×Öµä±àÂë  | 
| #  @param tagDict Ô×Öµä  | 
| #  @return None  | 
| def TranslateOutDBDict(tagDict):  | 
|     resultDict = {}  | 
|       | 
|     for key, value in tagDict.items():  | 
|         resultDict[key] = OutgoingText(value)  | 
|       | 
|     return resultDict  | 
|           | 
|           | 
| ## È¡³öÊý¾Ý  | 
| #  @param text Ô×Ö·û  | 
| #  @return None  | 
| def OutgoingText(text):  | 
|     if isinstance(text, unicode):  | 
|         if EncodingList[0]:  | 
|             return base64.b64decode(text)  | 
|         return UnicodeToEncoding(EncodingList[1], text)[1]  | 
|     #²»ÊÇunicode,²»´¦Àí  | 
|     return text  | 
|   | 
|   | 
| ## Èë¿â  | 
| #  @param text Ô×Ö·û  | 
| #  @return None  | 
| def IncomingText(text):  | 
|     if isinstance(text, str):  | 
|         if EncodingList[0]:  | 
|             return base64.b64encode(text)  | 
|         return EncodingToUnicode(EncodingList[1], text)[1]  | 
|     #²»ÊÇ×Ö·û´®£¬²»´¦Àí  | 
|     return text  | 
|   | 
|   | 
| ## ±àÂë  | 
| #  @param srcEncoding ±àÂë¸ñʽ  | 
| #  @param input ×Ö·û´®  | 
| #  @return None  | 
| def EncodingToUnicode(srcEncoding, input):  | 
|     try:  | 
|         result = unicode(input, srcEncoding)    #translate to utf-8  | 
|     except:  | 
|         GameWorld.Log("##EncodingToUnicode error, input=%s, srcEncoding=%s"%(input, srcEncoding))  | 
|         return False, "error"  | 
|     return True, result  | 
|   | 
|   | 
| ## ±àÂë  | 
| #  @param srcEncoding ±àÂë¸ñʽ  | 
| #  @param input ×Ö·û´®  | 
| #  @return None  | 
| def UnicodeToEncoding(dstEncoding, input):  | 
|     try:  | 
|         result = input.encode(dstEncoding)  | 
|     except:  | 
|         GameWorld.Log("##UnicodeToEncoding error, input=%s, dstEncoding=%s"%(input, dstEncoding))  | 
|         return False, "Error"  | 
|     return True, result  |