#!/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  
 |