| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
| #-------------------------------------------------------------------------------  | 
| #  | 
| #-------------------------------------------------------------------------------  | 
| #  | 
| ##@package PlayerAutoCheckOnline  | 
| #  | 
| # @todo: ·´Íâ¹ÒÑéÖ¤£¬Óë¿Í»§¶Ë×Ô¶¯½»»¥  | 
| # @author Alee  | 
| # @date 2010-05-31 21:30  | 
| # @version 2.8  | 
| #  | 
| # ÏêϸÃèÊö: ·´Íâ¹ÒÑéÖ¤£¬Óë¿Í»§¶Ë×Ô¶¯½»»¥  | 
|   | 
| # @change: "2011-05-31 21:30" Alee Ð޸Ļشð´íÎóµÄʱºò²»ÔÙÖØ·¢Í¼Æ¬£¬ÒÀÈ»ÊÇÉÏÒ»´ÎµÄ  | 
| # @change: "2011-06-01 00:05" Alee »Ø´ðÕýÈ·Í˳öʼþ  | 
| # @change: "2011-06-02 13:20" Alee ÄÚÍøÕ˺Å90²»ÑéÖ¤Íâ¹Ò  | 
| # @change: "2011-06-02 18:30" panwei ÄÚÍøÕ˺Å90²»ÑéÖ¤Íâ¹Ò  | 
| # @change: "2011-06-07 15:00" Alee ·ÀÍâ¹ÒÐÞ¸Ä  | 
| # @change: "2011-06-08 11:00" Alee ·ÀÍâ¹ÒÐÞ¸Ä  | 
| # @change: "2011-06-09 18:00" Alee Ìí¼Ó¶ÁÈ¡´úÂë¼ÓÃÜ·ÀÍâ¹Ò  | 
| # @change: "2011-06-10 14:30" Alee ÐÞ¸ÄÎªËæ»ú»ñÈ¡±àÂë¼ÓÃÜÑéÖ¤  | 
| # @change: "2011-06-13 17:00" Alee Í¼ÐÎÑéÖ¤Âë²»»Ø¸´ÔòËã´íÎó´ÎÊý¼Ó1  | 
| # @change: "2011-06-17 11:00" Alee ¼ÓÃܺ¯Êý×ªÒÆ  | 
|   | 
| # @change: "2011-06-23 13:40" Alee Ëæ»úÉú³ÉÑéÖ¤ÂëÖØÔØ  | 
| # @change: "2011-07-04 17:00" Alee ×Ô¶¯¼ì²âÍâ¹Ò¸ÄΪһ¶Îʱ¼äÄÚ²»»Ø¸´Á¬·¢3´Î  | 
| # @change: "2011-07-15 19:30" Alee ·À·¶¹Ø±Õ »Ö¸´Õý³£  | 
| # @change: "2011-07-25 19:00" Alee ±ÜÃâÊä³ö¿Í»§¶ËµÄ×Ö·û´®µ¼Ö´íÎó  | 
| # @change: "2011-09-01 18:30" Alee ·â°üÐÞ¸Ä  | 
|   | 
| # @change: "2011-10-17 19:50" Alee PY·â°üÔÝʱ¹Ø±Õ¹¦ÄÜ  | 
| # @change: "2012-03-06 15:00" jiang ×Öµäkey¸Ä³ÉChConfigÖÐ  | 
| # @change: "2012-06-26 18:00" jiang ²¹Æëoss¼Ç¼  | 
| #---------------------------------------------------------------------  | 
| """Version = 2012-06-26 18:00"""  | 
| #------------------------------------------------------------------------------   | 
|   | 
| import GameWorld  | 
| import IPY_GameWorld  | 
| import ReadChConfig  | 
| import ChConfig  | 
| import ShareDefine  | 
| import PlayerControl  | 
| import ReadCaptchaImage  | 
| import PlayerGMOper  | 
| import DataRecordPack  | 
|   | 
| import random  | 
| import binascii  | 
| import md5  | 
| import math  | 
|   | 
| #×Ô¶¯¼ì²â»Ø´ð´íÎó´ÎÊý  | 
| Def_AutoCheck_ErrCnt = 5  | 
|   | 
| #´íÎó±êʶ  | 
| Def_Error_Mark = -1  | 
|   | 
| #×Ô¶¯¼ì²â¿ªÆô±êʶ  | 
| Def_AutoCheck_Mark_Open = 1  | 
| #ͼÐÎÑéÖ¤Â뿪Æô±êʶ  | 
| Def_Captcha_Mark_Open = 1  | 
|   | 
| #C/S·ÀÍâ¹Ò×Ô¶¯Ñé֤״̬  | 
| Def_AutoCheck_Safe = 0  | 
| Def_AutoCheck_WaitAnswer = 1  | 
|   | 
| #ͼÐÎÑéÖ¤ÂëµÈ´ý±êʶ  | 
| Def_Captcha_Safe = 0  | 
| Def_Captcha_WaitAnswer = 1  | 
|   | 
| #×Ô¶¯¼ì²â²»»Ø¸´µÄ´ÎÊý  | 
| Def_AutoCheck_NoAnswerCount = 3  | 
|   | 
| ##·ÀÍâ¹Ò¼ì²â  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ÎÞÒâÒå  | 
| def HackDefense(curPlayer, tick):  | 
|     return  | 
|     #ÄÚÍøÕ˺Ų»ÑéÖ¤  | 
|     if curPlayer.GetGMLevel() == ChConfig.Def_GM_LV_God:  | 
|         ResumePlayerNormal(curPlayer)  | 
|         return  | 
|       | 
|     #×Ô¶¯¼ì²â  | 
|     AutoCheckCheater(curPlayer, tick)  | 
|     #ͼÐÎÑéÖ¤  | 
|     CaptchaWaitAnswer(curPlayer, tick)  | 
|   | 
| ##Íæ¼Ò´ÓSB»Ö¸´Õý³£  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @return ÎÞÒâÒå  | 
| def ResumePlayerNormal(curPlayer):  | 
|     if curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_AutoCheckHack_State) != ChConfig.Def_AutoCheck_State_Danger:  | 
|         return  | 
|       | 
|     #Çå¿Õ´íÎó´ÎÊý  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_AutoCheckHack_ErrCnt, 0)  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_AutoCheckHack_Wait, Def_AutoCheck_Safe)  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_AutoCheckHack_State, ChConfig.Def_AutoCheck_State_Safe)  | 
|     return  | 
|   | 
| ##·ÀÍâ¹Ò×Ô¶¯¼ì²â  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ÎÞÒâÒå  | 
| def AutoCheckCheater(curPlayer, tick):  | 
|     if ReadChConfig.GetEvalChConfig("AutoCheck_Open") != Def_AutoCheck_Mark_Open:  | 
|         ResumePlayerNormal(curPlayer)  | 
|         return  | 
|       | 
|     DoLogic_AutoCheck_Send(curPlayer, tick)  | 
|   | 
|     DoLogic_AutoCheck_WaitRece(curPlayer, tick)  | 
|   | 
| ##»ñµÃ×Ô¶¯¼ì²âÀàÐÍ  | 
| # @param ÎÞ  | 
| # @return ¼ì²âÀàÐÍ  | 
| def GetAutoCheckType():  | 
|     randList = ReadChConfig.GetEvalChConfig('ChoiceAutoCheckType')  | 
|       | 
|     return GameWorld.GetResultByRandomList(randList)  | 
|     #return random.choice((ShareDefine.Def_AutoCheck_BigNum, ShareDefine.Def_AutoCheck_PyCode))  | 
|   | 
| ##»ñµÃ×Ô¶¯¼ì²âÊý¾Ý  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param checkType ×Ô¶¯¼ì²âÀàÐÍ  | 
| # @return ¼ì²âÊý¾Ý£¬¸½¼ÓÐÅÏ¢  | 
| def GetAutoCheckNum(curPlayer, checkType):  | 
|     rand = random.randint(0, 1000000)  | 
|       | 
|     if checkType == ShareDefine.Def_AutoCheck_BigNum:  | 
|         return rand, ''  | 
|     elif checkType == ShareDefine.Def_AutoCheck_PyCode:  | 
|         return GetPYCodeAndResult(curPlayer, rand)  | 
|       | 
|     else:  | 
|         GameWorld.ErrLog('GetAutoCheckNum½»»¥Ñé֤ѡÔñÀàÐÍ´íÎó£¬ÀàÐÍ %s'%checkType)  | 
|       | 
|     return Def_Error_Mark, ''  | 
|   | 
|   | 
| ##»ñµÃ¼ì²âµÄÊý¾ÝºÍ´úÂë¼ÓÃÜÐÅÏ¢  | 
| # @param curPlayer, Íæ¼ÒʵÀý  | 
| # @param rand Ëæ»úÊý  | 
| # @return ¼ì²âµÄÊý¾ÝºÍ´úÂë¼ÓÃÜÐÅÏ¢  | 
| def GetPYCodeAndResult(curPlayer, rand):  | 
|     #ÅäÖÃÎļþÖжÁȡ·¾¶£¬ÔÙ¶ÁÈ¡´úÂëÎļþ  | 
|     randList = ReadChConfig.GetEvalChConfig("PYCodePath")  | 
|       | 
|     filePath = GameWorld.GetResultByRandomList(randList)  | 
|     codeStr = ReadChConfig.GetEvalChConfig(filePath)  | 
|       | 
|     #±àÒë´úÂ룬¼ÆËã½á¹ûÓ¦¸ÃΪһ¸öÕûÊý£¬²Å¿ÉÒÔ´æ×ÖµäÖÐ  | 
|     exec(codeStr)  | 
|       | 
|     #GameWorld.Log("µ±Ç°Ê¹ÓõĴúÂëÎļþÊÇ %s"%filePath)  | 
|       | 
|     return GetCodeStrExecResult(curPlayer, str(rand)), str(rand) + \  | 
|                                 ShareDefine.Def_Pack_Split + GotoHeaven(codeStr, rand)  | 
|       | 
|   | 
| ##»ñµÃ·â°ü×Ö·û´®  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param checkType ×Ô¶¯¼ì²âÀàÐÍ  | 
| # @param checkNum ¼ì²âÊý¾Ý   | 
| # @return ·â°ü×Ö·û´®  | 
| def GetAutoCheckMsg(curPlayer, checkType, checkNum, annexStr):  | 
|     if checkType == ShareDefine.Def_AutoCheck_BigNum:  | 
|         return GetBigNumPackStr(checkNum, checkType)  | 
|     elif checkType == ShareDefine.Def_AutoCheck_PyCode:  | 
|         return GetPYCodePackStr(checkType, annexStr)  | 
|       | 
|     else:  | 
|         GameWorld.ErrLog('GetAutoCheckMsg½»»¥Ñé֤ѡÔñÀàÐÍ´íÎó£¬ÀàÐÍ %s'%checkType)  | 
|           | 
|     return ''  | 
|   | 
|   | 
| ##»ñµÃÊý×Ö¼ÆËãµÄ×Ö·û´®·â°ü  | 
| # @param checkType ×Ô¶¯¼ì²âÀàÐÍ  | 
| # @param checkNum ¼ì²âÊý¾Ý   | 
| # @return ·â°ü×Ö·û´®  | 
| def GetBigNumPackStr(checkNum, checkType):  | 
|     checkMsg = checkNum * 30 + 2  | 
|       | 
|     return ShareDefine.Def_AutoCheck_SendMsg%(checkType, checkMsg)  | 
|   | 
|   | 
| ##»ñµÃPY´úÂëµÄ×Ö·û´®·â°ü  | 
| # @param checkType ×Ô¶¯¼ì²âÀàÐÍ  | 
| # @param checkNum ¼ì²âÊý¾Ý   | 
| # @return ·â°ü×Ö·û´®  | 
| def GetPYCodePackStr(checkType, annexStr):  | 
|     return ShareDefine.Def_AutoCheck_SendMsg%(checkType, annexStr)  | 
|       | 
|   | 
| ##×Ö·û´®¼ÓÃÜ  | 
| # @param codeStr Î´¼ÓÃÜ×Ö·û  | 
| # @param rand Ëæ»úÊý  | 
| # @return ¼ÓÃÜ×Ö·û  | 
| def GotoHeaven(codeStr, rand):  | 
|     tmpList = []  | 
|     tmpList_2 = []  | 
|       | 
|     pos = rand//ShareDefine.Def_Cheater_PosArg  | 
|     num = rand%ShareDefine.Def_Cheater_CharArg  | 
|   | 
|     tmpCount = 0  | 
|     for cha in codeStr:  | 
|         if tmpCount == pos:  | 
|             tmpList.append(num)  | 
|           | 
|         #Òì»òºó£¬½«µÍÎ»ÒÆÖ²¸ßλ2´Î£¨È·±£ÊÇ8룩  | 
|         tmpNum = ord(cha)^ShareDefine.Def_Cheater_Mirror  | 
|         tmpNum = tmpNum>>1 | ((tmpNum & 0x1)<<7)  | 
|         tmpNum = tmpNum>>1 | ((tmpNum & 0x1)<<7)  | 
|           | 
|         tmpList.append(tmpNum)  | 
|   | 
|         tmpCount += 1  | 
|       | 
|     for num in tmpList:  | 
|         tmpList_2.append(chr(num))  | 
|       | 
|     return ''.join(tmpList_2)  | 
|   | 
| ##×Ô¶¯¼ì²â·¢ËÍ·â°ü  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ÎÞÒâÒå  | 
| def DoLogic_AutoCheck_Send(curPlayer, tick):  | 
|     #µôÏßÇеØÍ¼ÑéÖ¤  | 
|     lastCheckTick = curPlayer.GetTickByType(ChConfig.TYPE_Player_Tick_AutoCheck_SendTick)  | 
|       | 
|     if lastCheckTick != 0 and tick - lastCheckTick \  | 
|     < ChConfig.TYPE_Player_Tick_Time[ChConfig.TYPE_Player_Tick_AutoCheck_SendTick]:  | 
|         return  | 
|       | 
|     SendAutoCheck(curPlayer, tick)  | 
|   | 
| ##·¢ËÍ·ÀÍâ¹Ò×Ô¶¯¼ì²â  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param tick Ê±¼ä´Á  | 
| # @return None  | 
| def SendAutoCheck(curPlayer, tick):  | 
|     checkType = GetAutoCheckType()  | 
|       | 
| #    GameWorld.Log("·¢Ë͵ÄÑéÖ¤ÀàÐÍΪ %s"%checkType)  | 
|       | 
|     #¼ì²âÊý¾ÝºÍ¸½¼ÓÐÅÏ¢  | 
|     checkNum, annexStr = GetAutoCheckNum(curPlayer, checkType)  | 
|       | 
|     #ûÓн»»¥µÄÀàÐÍ  | 
|     if checkNum == Def_Error_Mark:  | 
|         return  | 
|       | 
|     #Çå¿Õ´íÎó´ÎÊý  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_AutoCheckHack_ErrCnt, 0)  | 
|       | 
|     checkMsg = GetAutoCheckMsg(curPlayer, checkType, checkNum, annexStr)  | 
|       | 
|     if checkMsg == '':  | 
|         return  | 
|       | 
|     #¼ÇÂ¼Ëæ»úÔ´ ÀàÐͺ͵ȴý±êʶ, Í¨Öª¿Í»§¶Ë  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_AutoCheckHack_Type, checkType)  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_AutoCheckHack_Source, checkNum)   | 
|   | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_AutoCheckHack_Wait, Def_AutoCheck_WaitAnswer)  | 
|     curPlayer.SendFakePack(checkMsg, len(checkMsg))  | 
|       | 
|     #¼ÆÊ±  | 
|     curPlayer.SetTickByType(ChConfig.TYPE_Player_Tick_AutoCheck_SendTick, tick)  | 
|     curPlayer.SetTickByType(ChConfig.TYPE_Player_Tick_AutoCheck_ReceTick, tick)  | 
|   | 
|     #GameWorld.Log("·¢ËÍÑéÖ¤")  | 
|   | 
| ##×Ô¶¯¼ì²âµÈ´ý»Ø¸´·â°ü  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ÎÞÒâÒå  | 
| def DoLogic_AutoCheck_WaitRece(curPlayer, tick):  | 
|     waitRece = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_AutoCheckHack_Wait)  | 
|       | 
|     #²»ÊǵȴýÏìÓ¦ÖÐ  | 
|     if waitRece != Def_AutoCheck_WaitAnswer:  | 
|         return  | 
|       | 
|     waitStartTick = curPlayer.GetTickByType(ChConfig.TYPE_Player_Tick_AutoCheck_ReceTick)  | 
|       | 
| #    GameWorld.Log("µÈ´ý»Ø¸´ %s"%(tick - waitStartTick))  | 
|     if tick - waitStartTick < ChConfig.TYPE_Player_Tick_Time[ChConfig.TYPE_Player_Tick_AutoCheck_ReceTick]:  | 
|         return  | 
|       | 
|     noAnswerCount = curPlayer.GetDictByKey(ChConfig.Def_Player_AutoCheck_Count)  | 
|     if noAnswerCount >= Def_AutoCheck_NoAnswerCount:  | 
|         SetPlayerSB(curPlayer)  | 
|         return  | 
|       | 
|     curPlayer.SetDict(ChConfig.Def_Player_AutoCheck_Count, noAnswerCount + 1)  | 
|     SendAutoCheck(curPlayer, tick)  | 
|   | 
| ##Íæ¼ÒÉèÖóÉSB״̬  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @return  ÎÞÒâÒå  | 
| def SetPlayerSB(curPlayer):  | 
|     #ÉèÖøÃÕ˺ÅΪΣÏպŠ | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_AutoCheckHack_State, ChConfig.Def_AutoCheck_State_Danger)  | 
|     PlayerControl.SetSight(curPlayer, ChConfig.Def_PlayerSight_Hack)  | 
|       | 
|     DataRecordPack.SetPlayerSBState(curPlayer, ChConfig.Def_PlayerSight_Hack)  | 
|       | 
|     GameWorld.Log('Íæ¼Ò(%s), ±»¼ø¶¨Ê¹ÓÃÍâ¹Ò£¬½ÇÉ«±äSB'%curPlayer.GetName(), curPlayer.GetID())  | 
|       | 
|     #½â³ýµÈ´ý»Ø°ü״̬  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_AutoCheckHack_Wait, Def_AutoCheck_Safe)  | 
|   | 
| ##½»»¥¼ì²â´íÎó´ÎÊýµÄ´¦Àí  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @return ÎÞÒâÒå  | 
| def DoLogicAutoCheckErr(curPlayer):  | 
|     errCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_AutoCheckHack_ErrCnt) + 1  | 
|   | 
|     #ͬһ¸öÎÊÌâÖлشð´ÎÊý´íÎó¹ý¶àÔòÉèÖóÉSBºÅ£¬»áÔÚÏÂÒ»´ÎÎÊÌâǰÇå¿Õ´íÎó´ÎÊý  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_AutoCheckHack_ErrCnt, errCnt)  | 
|       | 
|     if errCnt < Def_AutoCheck_ErrCnt:  | 
|         return  | 
|       | 
|     #GameWorld.Log("×Ô¶¯¼ì²â£¬»Ø´ð´íÎó´ÎÊý¹ý¶à")  | 
|     SetPlayerSB(curPlayer)  | 
|       | 
| ##×Ô¶¯¼ì²âµÈ´ý»Ø¸´·â°ü  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param packType ÑéÖ¤ÀàÐÍ  | 
| # @param packMsg ÊÕ±¨Êý¾Ý  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ÎÞÒâÒå  | 
| def AutoCheckWaitAnswer(curPlayer, packType, packMsg, tick):  | 
|     #ϵͳ¹Ø±ÕÔò²»Àí²Ç  | 
|     if ReadChConfig.GetEvalChConfig("AutoCheck_Open") != Def_AutoCheck_Mark_Open:  | 
|         return  | 
|       | 
|     #²»Êǵȴý»Ø´ðÖв»Àí²Ç  | 
|     if curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_AutoCheckHack_Wait) == Def_AutoCheck_Safe:  | 
|         return  | 
|       | 
|     checkType = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_AutoCheckHack_Type)  | 
|       | 
|     #ÑéÖ¤´íÎó´ÎÊý¡£±ÜÃâ±»Íâ¹Ò²âÊÔ  | 
|     if not IsAutoCheckAnswer(curPlayer, packType, checkType, packMsg):  | 
|         DoLogicAutoCheckErr(curPlayer)  | 
|         return  | 
|       | 
|     #½â³ý½ÇɫΣÏÕ״̬  | 
|     if curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_AutoCheckHack_State) \  | 
|                                       == ChConfig.Def_AutoCheck_State_Danger:  | 
|           | 
|         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_AutoCheckHack_State,   | 
|                                        ChConfig.Def_AutoCheck_State_Safe)  | 
|           | 
|         PlayerControl.SetSight(curPlayer, ChConfig.Def_PlayerSight_Default)  | 
|           | 
|         DataRecordPack.SetPlayerSBState(curPlayer, ChConfig.Def_AutoCheck_State_Safe)  | 
|       | 
|     curPlayer.SetDict(ChConfig.Def_Player_AutoCheck_Count, 0)  | 
|     #½â״̬  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_AutoCheckHack_Wait, Def_AutoCheck_Safe)  | 
|   | 
|   | 
| ##¼ì²é»Ø¸´´ð°¸ÊÇ·ñÕýÈ·  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param packType ·â°üÀàÐÍ  | 
| # @param checkType ¼ìÑéÀàÐÍ  | 
| # @param packMsg ·â°ü×Ö·û´®  | 
| # @return BOOL  | 
| def IsAutoCheckAnswer(curPlayer, packType, checkType, packMsg):  | 
|     if packType != checkType:  | 
|         return False  | 
|       | 
|     checkNum = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_AutoCheckHack_Source)   | 
|       | 
|     #GameWorld.Log("½»»¥½á¹û%s : %s  - %s"%(checkType, GetAutoCheckParseResult(curPlayer, checkType, checkNum), packMsg))  | 
|     if GetAutoCheckParseResult(curPlayer, checkType, checkNum) != packMsg:  | 
|         return False  | 
|       | 
|     return True  | 
|        | 
|       | 
| ##»ñµÃ¼ÓÃܽá¹û  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param checkType ×Ô¶¯¼ì²âÀàÐÍ  | 
| # @param checkNum ×Ô¶¯¼ì²âÊý¾Ý  | 
| # @return ¼ÓÃܽá¹û  | 
| def GetAutoCheckParseResult(curPlayer, checkType, checkNum):  | 
|     if checkType == ShareDefine.Def_AutoCheck_BigNum:  | 
|         return GetPreventPluginMsg(curPlayer, str(checkNum))  | 
|     elif checkType == ShareDefine.Def_AutoCheck_PyCode:  | 
|         return md5.md5(str(checkNum)).hexdigest()  | 
|     else:  | 
|         GameWorld.ErrLog("GetAutoCheckParseResult ÀàÐÍ´íÎó, Íæ¼Ò: %s ½«±äSB"%curPlayer.GetName(), curPlayer.GetID())  | 
|           | 
|     return ''  | 
|   | 
|   | 
| ##·ÀÍâ¹Ò¼ì²â  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param fakePackMsg ·â°üÐÅÏ¢  | 
| # @param playerID Íæ¼ÒID  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ÎÞÒâÒå  | 
| def AutoCheckOnline(curPlayer, fakePackMsg, playerID, tick):  | 
|     if ShareDefine.Def_Pack_Split not in fakePackMsg:  | 
|         GameWorld.ErrLog("×Ô¶¨Òå·â°üÊý¾Ý¸ñʽÒì³£", playerID)  | 
|         return  | 
|       | 
|     tmpList = fakePackMsg.split(ShareDefine.Def_Pack_Split, 1)  | 
|       | 
|     packType, packMsg = tmpList  | 
|       | 
|     packType = packType[1:]  | 
|     if not packType.isdigit():  | 
|         GameWorld.ErrLog("×Ô¶¨Òå·â°üÀàÐÍÊý¾Ý´íÎó %s"%packType, playerID)  | 
|         return  | 
|       | 
|     packType = int(packType)  | 
|       | 
|     if packType in [ShareDefine.Def_AutoCheck_BigNum, ShareDefine.Def_AutoCheck_PyCode]:  | 
|         AutoCheckWaitAnswer(curPlayer, packType, packMsg, tick)  | 
|           | 
|     elif packType == ShareDefine.Def_AutoCheck_Captcha:  | 
|         CaptchaAnswer(curPlayer, packMsg, tick)  | 
|           | 
|     else:  | 
|         GameWorld.ErrLog("×Ô¶¨Òå·â°ü£¬Î´ÖªµÄ·ÀÍâ¹ÒÑéÖ¤ÀàÐÍ %s"%packType, playerID)  | 
|           | 
|     return  | 
|   | 
| #===============================================================================  | 
| ##ͼÐÎÑéÖ¤Âë»Ø¸´  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param packMsg ·â°üÊý¾Ý  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ÎÞÒâÒå  | 
| def CaptchaAnswer(curPlayer, packMsg, tick):  | 
|     tmpList = packMsg.split(ShareDefine.Def_Pack_Split, 1)  | 
|       | 
|     if len(tmpList) != 2:  | 
|         GameWorld.ErrLog("·â°üͼÐÎÑéÖ¤Âë¸ñʽÒì³£Òì³£ %s"%packMsg)  | 
|         return  | 
|       | 
|     queryType, captchaMsg = tmpList  | 
|     if not queryType.isdigit():  | 
|         GameWorld.ErrLog("·â°üͼÐÎÑéÖ¤ ÀàÐÍ´íÎó %s"%tmpList)  | 
|         return  | 
|       | 
|     queryType = int(queryType)  | 
|       | 
|     if queryType == ShareDefine.Def_Captcha_Refresh:  | 
|         #Ë¢ÐÂͼÐÎÑéÖ¤Âë  | 
|         if tick - curPlayer.GetTickByType(ChConfig.TYPE_Player_Tick_Captcha_Refresh) \  | 
|         < ChConfig.TYPE_Player_Tick_Time[ChConfig.TYPE_Player_Tick_Captcha_Refresh]:  | 
|             return  | 
|           | 
|         curPlayer.SetTickByType(ChConfig.TYPE_Player_Tick_Captcha_Refresh, tick)  | 
|           | 
|         SendCaptcha(curPlayer, ShareDefine.Def_Captcha_Reset, tick, False)  | 
|       | 
|     elif queryType == ShareDefine.Def_Captcha_Query:  | 
|           | 
|         answer = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_Captcha_Answer)  | 
|           | 
|         #»Ø¸´ÐÅÏ¢  | 
|         if answer != GetPlusCrc32(captchaMsg):  | 
|             #»Ø´ð´íÎó  | 
|             CaptchaAnswerErr(curPlayer, tick)  | 
|             return  | 
|           | 
|         #»Ø´ðÕýÈ·  | 
|         SendCaptcha(curPlayer, ShareDefine.Def_Captcha_Right, tick, False)  | 
|         #»Ö¸´°²È«×´Ì¬  | 
|         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_Captcha_WaitSign, Def_Captcha_Safe)  | 
|         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_Captcha_ErrCount, 0)  | 
|           | 
|         if curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_Frist_Lock) != 1 \  | 
|         and curPlayer.GetPlayerAction() == IPY_GameWorld.paEvent:  | 
|             #½â³ýËø¶¨  | 
|             curPlayer.ExitEvent()  | 
|           | 
|     return  | 
|   | 
| ##ͼÐÎÑéÖ¤Âë»Ø¸´´íÎó´¦Àí  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param tick Ê±¼ä´Á  | 
| # @param isNotify ÊÇ·ñ֪ͨ¿Í»§¶Ë´íÎó  | 
| # @return ÊÇ·ñ·âºÅ  | 
| def CaptchaAnswerErr(curPlayer, tick, isNotify=True):  | 
|     return True  | 
|     #¼Ç¼´íÎó´ÎÊý  | 
|     errCount = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_Captcha_ErrCount) + 1  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_Captcha_ErrCount, errCount)  | 
|       | 
|     if isNotify:  | 
|         #ÿ´Î´íÎ󶼸æË߿ͻ§¶Ë½á¹û  | 
|         SendCaptcha(curPlayer, ShareDefine.Def_Captcha_Error, tick, False)  | 
|       | 
|     #´íÎó´ÎÊýÅж¨  | 
|     if errCount < ReadChConfig.GetEvalChConfig("Captcha_ErrCount"):  | 
|         return False  | 
|       | 
| #        PlayerControl.NotifyCode(curPlayer, "Old_andyshao_202580", [Def_Captcha_ErrCount])  | 
|   | 
|     #»Ö¸´°²È«×´Ì¬  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_Captcha_WaitSign, Def_Captcha_Safe)  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_Captcha_ErrCount, 0)  | 
|       | 
|     PlayerGMOper.ClosePlayerByAccIDEx(curPlayer, ReadChConfig.GetEvalChConfig("Captcha_SealTime"),   | 
|                                           "Captcha Err MaxCount", 1100)  | 
|   | 
|     return True  | 
|   | 
|       | 
|   | 
| ##Íæ¼ÒµÇ½·¢ÑéÖ¤  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ÎÞÒâÒå  | 
| def PlayerLoginCaptcha(curPlayer, tick):  | 
|     return  | 
|     if ReadChConfig.GetEvalChConfig("Captcha_Open") != Def_Captcha_Mark_Open:  | 
|         return  | 
|       | 
|     #ÄÚÍøÕ˺Ų»ÑéÖ¤  | 
|     if curPlayer.GetGMLevel() == ChConfig.Def_GM_LV_God:  | 
|         return  | 
|       | 
|     SendCaptcha(curPlayer, ShareDefine.Def_Captcha_First, tick)  | 
|   | 
|   | 
| ##·¢ËÍͼÐÎÑéÖ¤ÐÅÏ¢  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param captchaType Í¼ÐÎÑéÖ¤ÀàÐÍ  | 
| # @param tick Ê±¼ä´Á  | 
| # @param refresh ÊÇ·ñÖØÐ¼ÆÊ±  | 
| # @return ÎÞÒâÒå  | 
| def SendCaptcha(curPlayer, captchaType, tick, refresh=True):  | 
|   | 
|     #³õʼ»¯  | 
|     captchaAnswer, captchaMsg = 0, '0'  | 
|       | 
|     #»Ø´ðÕýÈ·»òÕß´íÎóÒª»Ø·¢ ²»ÔÙȡͼƬ  | 
|     if captchaType in [ShareDefine.Def_Captcha_Right, ShareDefine.Def_Captcha_Error]:  | 
|         captchaAnswer, captchaMsg = 1, '0'  | 
|     else:  | 
|         captchaAnswer, captchaMsg = ReadCaptchaImage.GetCaptchaImage()  | 
|           | 
|         if captchaAnswer == 0:  | 
|             GameWorld.ErrLog("ÎÞ·¨»ñµÃͼÐÎÑéÖ¤Âë Îļþ:%s "%(captchaAnswer))  | 
|             return  | 
|       | 
|         #ÕýÈ·»òÕß´íÎó ÉÏÒ»´ÎµÄ´æ´¢ÂëºÅ¼ÓÃܲ»±ä  | 
|         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_Captcha_Answer, GetPlusCrc32(captchaAnswer))  | 
|       | 
|     errCount = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_Captcha_ErrCount)  | 
|       | 
|     #Îļþ¼ÓÃÜ  | 
|     captchaMsg = GotoHeaven(captchaMsg, ShareDefine.Def_Effect_PHY)  | 
|     msgContent = ShareDefine.Def_CaptchaS_SendMsg%(captchaType, errCount, captchaMsg)  | 
|     sendMsg = ShareDefine.Def_AutoCheck_SendMsg%(ShareDefine.Def_AutoCheck_Captcha, msgContent)  | 
|       | 
|     #GameWorld.Log("%s----------·¢ËÍͼÐÎÑéÖ¤ %s"%(curPlayer.GetPlayerName(), captchaAnswer))  | 
|     curPlayer.SendFakePack(sendMsg, len(sendMsg))  | 
|       | 
|     if refresh:  | 
|         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_Captcha_WaitTick, tick)  | 
|         PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_Captcha_WaitSign, Def_Captcha_WaitAnswer)  | 
|   | 
|   | 
| ##µÈ´ý»Ø¸´Í¼ÐÎÑéÖ¤ÐÅÏ¢  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @param tick Ê±¼ä´Á  | 
| # @return ÎÞÒâÒå  | 
| def CaptchaWaitAnswer(curPlayer, tick):      | 
|     if ReadChConfig.GetEvalChConfig("Captcha_Open") != Def_Captcha_Mark_Open:  | 
|         return  | 
|       | 
|     #°²È«ÆÚ¼ä²»¼ì²â  | 
|     if curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_Captcha_WaitSign) == Def_Captcha_Safe:  | 
|         return  | 
|       | 
|     #ÅжÏʱ¼ä  | 
|     if tick - curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_Captcha_WaitTick) \  | 
|     < ReadChConfig.GetEvalChConfig("Captcha_WaitTime"):  | 
|         return  | 
|       | 
|     #»Ö¸´°²È«×´Ì¬  | 
|     PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_Captcha_WaitSign, Def_Captcha_Safe)  | 
|       | 
|     #ûÓзâºÅ¾ÍÕý³£ÌßÏÂÈ¥  | 
|     if not CaptchaAnswerErr(curPlayer, tick, False):  | 
|         curPlayer.Kick(IPY_GameWorld.disGMKick)  | 
|       | 
|   | 
| ##»ñÈ¡CRC½á¹û £¬´æÓÚÊý¾Ý¿â  | 
| # @param msg ×Ö·û´®  | 
| # @return CRC½á¹û  | 
| def GetPlusCrc32(msg):  | 
|     #ȫСд  | 
|     msg = str(msg).lower()  | 
|     num = binascii.crc32(msg)  | 
|   | 
|     #´æÊý¾Ý¿â£¬½«Êý¾ÝËõС  | 
|     return num & 0x7fffffff  | 
|   | 
| ##·ÀÍâ¹ÒÅжÏÊÇ·ñËø¶¨  | 
| # @param curPlayer Íæ¼ÒʵÀý  | 
| # @return bool  | 
| def CheckBeginEvent(curPlayer):  | 
|     return False  | 
|     #ÄÚÍøÕ˺Ų»ÑéÖ¤  | 
|     if curPlayer.GetGMLevel() == ChConfig.Def_GM_LV_God:  | 
|         return False  | 
|   | 
|     return (curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_Captcha_WaitSign) == Def_Captcha_WaitAnswer\  | 
|                     and ReadChConfig.GetEvalChConfig("Captcha_Open") == Def_Captcha_Mark_Open)  | 
|   | 
|   | 
| ### ·ÀÍâ¹ÒͨѶ¼ÓÃÜ  | 
| ##  @param curPlayer Íæ¼Ò  | 
| ##  @param inMsg ´«ÈëµÄ×Ö·û´®  | 
| ##  @param ¼ÓÃܺóµÄ×Ö·û´®  | 
| ##  @return None  | 
| def GetPreventPluginMsg(curPlayer, inMsg):  | 
|     key = "Çë¹Ò²É¼¯£¬²»Òª´ò¹Ö"  | 
|     md5Msg = md5.md5(inMsg).hexdigest()  | 
|     # È¡ascii×îСºÍ×î´óµÄ×Ö·û  | 
|     minChar = min(md5Msg)  | 
|     randChar = md5Msg[10]    #²»ÄÜÈ¡×î´óºÍ×îС£¬ÒòΪ³öÏÖÏàͬ¼¸ÂÊÌ«¸ß  | 
|       | 
|     # ³õʼ: md5ÂëÀïasciiÂë×îСµÄÊÇ"0"£¬ÆäasciiΪ32, ascii×î´óºÍ×îС×Ö·ûÏà¼ÓÖÁÉÙ64,2µÄ64´Î·½¿Ï¶¨´óÓÚ50ÒÚ  | 
|     # µÚÒ»´ÎÐÞ¸Ä: ¶Ô64ÇóÓà ÔÙ¼ÓÉÏ64£¬±£Ö¤³¬¹ý50ÒÚ  | 
|     curPower = (ord(minChar) + ord(randChar))%64 + 64  | 
|       | 
|     curJob = curPlayer.GetJob()  | 
|     curSex = curPlayer.GetSex()  | 
|   | 
|     tmpNum = curJob*2%3  | 
|       | 
|     floatNum = 0.123456  | 
|     if tmpNum == 0:  | 
|         floatNum = float(curJob*3)/7  | 
|     elif tmpNum == 1:  | 
|         floatNum = float(curJob*curSex + 1)/7  | 
|       | 
|     # ±£ÁôÁùλСÊý   | 
|     floatNum = round(floatNum, 6)  | 
|     calValue = math.pow(2, curPower) + floatNum  | 
|       | 
|     #²»¹ÜÊÇÓà%s %f str() repr() ÕûÊý²¿·Ö¹ý´ó¶¼»áÔì³É½á¹û²»ÊÇÔ¤ÆÚµÄ  | 
|     return md5.md5(md5.md5("%s"%floatNum).hexdigest() + md5.md5('%s'%calValue).hexdigest() \  | 
|                    + str(calValue) + key + md5Msg).hexdigest()  | 
|   |