| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
| #---------------------------------------------------------------------  | 
| #  | 
| #---------------------------------------------------------------------  | 
| ##@package CreateRole  | 
| # ¶ÁÈ¡´´½¨½ÇÉ«·â°ü tagCreateRole   | 
| #  | 
| # @author Alee  | 
| # @date 2010-02-20 16:30  | 
| # @version 1.6  | 
| #  | 
| # ÐÞ¸Äʱ¼ä ÐÞ¸ÄÈË ÐÞ¸ÄÄÚÈÝ  | 
| # @change: "2013-02-20 16:30" Alee ½ÇÉ«Ãû³¤¶ÈΪ33×Ö½Ú£¬¿Í»§¶ËÈ¡Ãû×î¶à14¸ö×Ö½Ú  | 
| # @change: "2013-05-27 22:00" Alee ÏÞÖÆ¿É´´½¨Ö°Òµ  | 
| # @change: "2014-08-15 19:30" hxp ´´½Ç¸ù¾ÝµØÍ¼ÈËÊýÏÞÖÆ·ÖÁ÷  | 
| # @change: "2014-12-08 19:00" hxp Ôö¼Ó´´½ÇÁ÷Ïò  | 
| # @change: "2016-03-28 17:00" hxp ´´½ÇÈ«Ãû¸ñʽÅäÖà  | 
| # @change: "2016-08-22 18:00" hxp Ö§³ÖÐéÄâ·ÖÏßÈËÊý¿ØÖÆ  | 
| #---------------------------------------------------------------------  | 
| #"""Version = 2016-08-22 18:00"""  | 
| #---------------------------------------------------------------------  | 
| #import DataRecordPack  | 
| import IPY_GameServer  | 
| import IpyGameDataPY  | 
| import DirtyList  | 
| import GameWorld  | 
| import random  | 
| import ChConfig  | 
| import PlayerControl  | 
| import PyGameData  | 
| #---------------------------------------------------------------------  | 
| g_CreateRoleAccID = {}  | 
|   | 
| #---------------------------------------------------------------------  | 
| #===============================================================================  | 
| # //01 05 ´´½¨½ÇÉ«#tagCCreateRole  | 
| # tagCCreateRole       *   GettagCCreateRole();  | 
| #   | 
| # class   IPY_CCreateRole  | 
| # {  | 
| # public:  | 
| #   | 
| #    char *   GetName();  | 
| #   | 
| #    int      GetSex();  | 
| #   | 
| #    int      GetHair();  | 
| #   | 
| #    int      GetHairColor();  //·¢É«, ²»ÑéÖ¤  | 
| #   | 
| #    int      GetFace();  | 
| #      | 
| #    int      GetFacePic();   //Á³Æ×  | 
| #      | 
| #    int      GetPlayerType();  //1. ½ð 2. Ä¾ 3. Ë® 4. ÍÁ 5. »ð  | 
| #      | 
| #    int      GetJob();     // Ö°Òµ  | 
| # };   | 
| #===============================================================================  | 
| ## ´´½¨½ÇÉ«  | 
| #  @param index Íæ¼ÒË÷Òý  | 
| #  @param tick µ±Ç°Ê±¼ä  | 
| #  @return None  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def CreateRole(index, tick):  | 
|     GameWorld.GetPsycoFunc(__Func_CreateRole)(index, tick)  | 
|     return  | 
|   | 
| ## ´´½¨½ÇÉ«  | 
| #  @param index Íæ¼ÒË÷Òý  | 
| #  @param tick µ±Ç°Ê±¼ä  | 
| #  @return None  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def __Func_CreateRole(index, tick):  | 
|     global g_CreateRoleAccID  | 
|     curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)  | 
|     curPlayerID = curPlayer.GetID()  | 
|       | 
|     if curPlayerID > 9999:  | 
|         # ËµÃ÷½ÇÉ«´´½¨³É¹¦  | 
|         PlayerControl.NotifyCode(curPlayer, "CreatSuccess")  | 
|         return  | 
|       | 
|     if CheckIsServerCreateRoleLimit(curPlayer):  | 
|         PlayerControl.NotifyCode(curPlayer, "ServerCreateRoleLimit")  | 
|         return  | 
|       | 
|     # CD±£»¤  | 
|     createSafeTick = 3000  | 
|     accID = curPlayer.GetAccID()  | 
|   | 
|     if accID not in g_CreateRoleAccID:  | 
|         g_CreateRoleAccID[accID] = tick  | 
|     else:  | 
|         if tick - g_CreateRoleAccID[accID] < createSafeTick:  | 
|             PlayerControl.NotifyCode(curPlayer, "CreatingCharacter")  | 
|             return  | 
|         g_CreateRoleAccID[accID] = tick  | 
|           | 
|     if len(g_CreateRoleAccID) > 100 :  | 
|         # Çå¿Õ´óÓÚ3ÃëµÄ  | 
|         tmpDict = []  | 
|         for accID, safeTick in g_CreateRoleAccID.items():  | 
|             if tick - safeTick > createSafeTick + 1000:  | 
|                 tmpDict.append(accID)  | 
|           | 
|         for accID in tmpDict:  | 
|             g_CreateRoleAccID.pop(accID)  | 
|           | 
|     #»ñÈ¡·â°ü²ÎÊý  | 
|     sendPack = IPY_GameServer.IPY_CCreateRole()  | 
|       | 
|     sendPack_Name = sendPack.GetName()  | 
|     sendPack_Sex = 1 #sendPack.GetSex()  | 
|     sendPack_Hair = 10001 #sendPack.GetHair()  | 
|     sendPack_HairColor = 1 #sendPack.GetHairColor()  | 
|     #sendPack_Face = 10005 #sendPack.GetFace()  | 
|     sendPack_FacePic = 0 # ¹Ì¶¨Îª0£¬ÐèÓë¿Í»§¶ËÅäÖÃÒ»Ö  | 
|     serverID = 1 #sendPack.GetFacePic() # Á³Æ××÷ΪserverIDÓà  | 
|     sendPack_PlayerType = 1 #sendPack.GetPlayerType()  | 
|     roleType = sendPack.GetJob() # ´´½ÇʹÓÃjob×÷Ϊ½ÇÉ«Óà  | 
|     ipyData = IpyGameDataPY.GetIpyGameData("CreateRole", roleType)  | 
|     if not ipyData:  | 
|         return  | 
|     job = ipyData.GetJob()  | 
|     face = ipyData.GetFace() # Í·Ïñ  | 
|     modelMark = ipyData.GetModelMark() # ÍâÐΠ ºÍ Ê±×°ÓÐÇø±ð  | 
|     #-----------------------Ãû×ÖУÑé  | 
|     sendPack_Name = IpyGameDataPY.GetFuncCfg("CreateRole", 1) # ½«ÃüÃû¸ñʽֱ½Ó´«¸ødb´´½Ç gstCreatePlayer£¬ÒòΪÕâÀïµÄcurPlayerID²»ÊÇʵ¼ÊµÄcurPlayerID  | 
|     if not sendPack_Name:  | 
|         return  | 
|     #C++¹ýÂ˿ոñ  | 
|     #sendPack_Name = GameWorld.GetGameWorld().GetCharTrim(sendPack_Name)  | 
|       | 
|     GameWorld.Log("´´½¨½ÇÉ«: accID=%s,roleType=%s,job=%s,face=%s,modelMark=%s, name=%s" % (accID, roleType, job, face, modelMark, sendPack_Name) , curPlayerID)  | 
|       | 
|     #if not CheckPlayerName(curPlayer , sendPack_Name):  | 
|     #    #disRoleCreateError ÈËÎï´´½¨µÄʱºòÍâ¹ÛÊôÐÔ´íÎó  | 
|     #    #curPlayer.Kick(IPY_GameServer.disCreateRoleNameError)  | 
|     #    PlayerControl.NotifyCode(curPlayer, "NameError")  | 
|     #    return  | 
|       | 
|     #sendPack_Name = GameWorld.GetPlayerFullName(curPlayer, sendPack_Name, serverID)  | 
|     #if not sendPack_Name:  | 
|     #    #curPlayer.Kick(IPY_GameServer.disCreateRoleNameError)  | 
|     #    PlayerControl.NotifyCode(curPlayer, "NameError")  | 
|     #   return  | 
|       | 
|     #-----------------------ÐÔ±ðУÑé  | 
|     #===========================================================================  | 
|     # if sendPack_Sex not in [1, 2]:  | 
|     #    curPlayer.Kick(IPY_GameServer.disCreateRoleSexError)  | 
|     #    return  | 
|     #===========================================================================  | 
|       | 
|     #---------------------Ö°Òµ¼ì²é  | 
|     openJob = IpyGameDataPY.GetFuncEvalCfg("OpenJob", 1)  | 
|     if job not in openJob:  | 
|         #curPlayer.Kick(IPY_GameServer.disCreateRoleJobError)  | 
|         PlayerControl.NotifyCode(curPlayer, "CreatUnusual")  | 
|         return  | 
|   | 
|     #-----------------------·¢ÐÍУÑé  | 
| #    if sendPack_Hair not in ChConfig.Def_RoleHair[sendPack_Job][sendPack_Sex - 1]:  | 
| #        #·¢ÐÍ´íÎó  | 
| #        GameWorld.Log("Hair = %d Error!,ÌßÍæ¼ÒÏÂÏß"%(sendPack_Hair), curPlayerID)  | 
| #        curPlayer.Kick(IPY_GameServer.disCreateRoleHairError)  | 
| #        return  | 
|       | 
|     #----------------------Á³ÐÍУÑé  | 
|     #===========================================================================  | 
|     # if sendPack_Face not in ChConfig.Def_RoleFace[sendPack_Job][sendPack_Sex - 1]:  | 
|     #    #Á³ÐÍ´íÎó  | 
|     #    GameWorld.Log("Face = %d Error!,ÌßÍæ¼ÒÏÂÏß"%(sendPack_Face) , curPlayerID)  | 
|     #    curPlayer.Kick(IPY_GameServer.disCreateRoleFaceError)  | 
|     #    return  | 
|     #===========================================================================  | 
|   | 
|     #---------------------ÎåÐмì²é  | 
|     #===========================================================================  | 
|     # if sendPack_PlayerType not in range(1 , 5 + 1):  | 
|     #    curPlayer.Kick(IPY_GameServer.disCreateRolePlayerTypeError)  | 
|     #    return  | 
|     #===========================================================================  | 
|       | 
|     createMapInfo = __GetCreateRoleMapInfo(ipyData.GetCreateRoleMap())  | 
|     if not createMapInfo:  | 
|         PlayerControl.NotifyCode(curPlayer, "CreatUnusual")  | 
|         GameWorld.ErrLog("ûÓÐÖ°Òµ¶ÔÓ¦´´½ÇµØÍ¼ÐÅÏ¢:sendPack_Job=%s" % job, curPlayerID)  | 
|         return  | 
|     dataMapID, lineID, posX, posY = createMapInfo  | 
|     mapID, copyMapID = PyGameData.g_commMapLineInfo.get((dataMapID, lineID), (dataMapID, 0))  | 
|       | 
|     bornRange = 1  | 
|     posX += random.randint(-bornRange, bornRange)  | 
|     posY += random.randint(-bornRange, bornRange)  | 
|       | 
|     #GameWorld.DebugLog("SendToDBPlayerCreate dataMapID=%s,lineID=%s,posX=%s,posY=%s,mapID=%s,copyMapID=%s"   | 
|     #                   % (dataMapID, lineID, posX, posY, mapID, copyMapID))  | 
|     #¸ù¾ÝÖ°Òµ»ñµÃĬÈϵÄÊôÐÔ, #STR//Á¦Á¿ ,PNE//ÖÇÁ¦,PHY//Ãô½Ý,CON//ÌåÁ¦  | 
|     baseSTR, basePNE, basePHY, baseCON = 0, 0, 0, 0  | 
|       | 
|     curPlayer.SendToDBPlayerCreate(  | 
|                                     curPlayerID, #PlayerID,  | 
|                                     sendPack_Name, #PlayerName, //size = 14  | 
|                                     1, #inputAccState,        //0: Î´´´½¨, 1: ´´½¨OK,Õý³£µÇ¼ 2:·âºÅ 3:ÒÑɾ³ý  | 
|                                     0, #inputGMLevel   //GMµÈ¼¶, 0:²»ÊÇGM  >=1 : GMµÄµÈ¼¶  | 
|                                     sendPack_Sex, #Sex, //ÐÔ±ð  | 
|                                     sendPack_Hair, #Hair, //·¢ÐÍ, 1.±ê×¼ÐÍ£¨ÄУ© 2.ÃûÊËÐÍ 3.ÀË×ÓÐÍ 4.±ê×¼ÐÍ£¨Å®£© 5.Âí÷ÙÐÍ 6.åüÃÄÐÍ  | 
|                                     sendPack_HairColor, #HairColor, //Í··¢ÑÕÉ«, 5ÖÖ  | 
|                                     face, #Face, //»ù±¾Á³ÐÍ  | 
|                                     sendPack_FacePic, #Á³²¿Í¼Æ¬  | 
|                                     job, #Job, //Ö°Òµ  | 
|                                     1, #LV, //µÈ¼¶  | 
|                                     0, #TotalExp, //×ܾÑé  | 
|                                     0, #FamilyID, //¼Ò×å  | 
|                                     1, #Country, //¹ú¼Ò, 1.ÇØ¹ú(ÐÂÊÖ) 2.κ¹ú 3.³þ¹ú   ÕóÓª  | 
|                                     0, #Mate,  | 
|                                     0, #Gold, //½ð×Ó  | 
|                                     0, #Silver, //Òø×Ó  | 
|                                     0, #½ðƱ  | 
|                                     0, #񿮱  | 
|                                     0, #FightPoint, //Õ½¶·Öµ  | 
|                                     0, #HappyPoint, //ÓéÀÖÖµ  | 
|                                     mapID, #MapID, //½ÇÉ«ËùÔÚµØÍ¼  | 
|                                     dataMapID, #DataMapID, //µØÍ¼·ÖÏßID  | 
|                                     copyMapID, #CopyMapID, //¸±±¾µØÍ¼ID  | 
|                                     posX, #PosX, //½Çɫ׸±ê  | 
|                                     posY, #PosY,  | 
|                                     0, #State, //½Çɫ״̬   1.·â´æ 2.ËÀÍö 3.Õý³£  ÒÔºó»¹ÓÐÂ½ÐøÌí¼Ó  | 
|                                     100, #HP, //µ±Ç°HP  | 
|                                     100, #MP, //µ±Ç°MP  | 
|                                     0, #FreePoint, //δ·ÖÅäµãÊý  | 
|                                     0, #FreeSkillPoint,//δ·ÖÅä¼¼ÄܵãÊý  | 
|                                     baseSTR, #STR, //Á¦Á¿  | 
|                                     basePNE, #PNE, //ÖÇÁ¦  | 
|                                     basePHY, #PHY, //Ãô½Ý  | 
|                                     baseCON, #CON, //ÌåÁ¦  | 
|                                     "", #Setting, //Óû§É趨  | 
|                                     0, #PKValue, //PKÖµ  | 
|                                     0, #ActiveValue, //»÷ɱµÐ¹úÕóÓªÍæ¼ÒºÍNPCµÄͳ¼ÆÖµ  | 
|                                     sendPack_PlayerType, #PlayerType, //½ÇÉ«µÄÎåÐÐÊôÐÔ£¬×é¶ÓÓà1. ½ð 2. Ä¾ 3. Ë® 4. ÍÁ 5. »ð  | 
|                                     "", #ÉϴεǼʱ¼ä, ÉèÖÃΪ¿Õ, ÒԱ㴥·¢OnDayʼþ  | 
|                                     0, #ÊÇ·ñʹÓòֿâÃÜÂë  | 
|                                     "111111", #²Ö¿âÃÜÂë  | 
|                                     IPY_GameServer.TYPE_Price_Gold_Paper, #ĬÈÏʹÓÃ½ðÆ±     (½ð×Ó/½ðƱ)  | 
|                                     IPY_GameServer.TYPE_Price_Silver_Money, #ĬÈÏʹÓÃÒø×Ó     (Òø×Ó/񿮱)  | 
|                                     80, #ĬÈÏ×Ô¶¯»ØÑªÉ趨   inputHPRestoreSetting  | 
|                                     80, #ĬÈÏ×Ô¶¯»ØÄ§É趨   inputMPRestoreSetting  | 
|                                     roleType,   #½ÇÉ«  | 
|                                     modelMark   #Íâ¹Û  | 
|                                     )  | 
|       | 
|     # ´´½ÇÁ÷Ïò  | 
|     #DataRecordPack.DR_CreateRole(curPlayer.GetAccID(), sendPack_Name, sendPack_Job)  | 
|     return  | 
| #---------------------------------------------------------------------  | 
| def CheckIsServerCreateRoleLimit(curPlayer):  | 
|     ## ·þÎñÆ÷ÊÇ·ñ´´½ÇÏÞÖÆ  | 
|     groupID = GameWorld.GetServerGroupID()  | 
|     ipyDataMgr = IpyGameDataPY.IPY_Data()  | 
|     for i in xrange(ipyDataMgr.GetCreateRoleLimitServerCount()):  | 
|         ipyData = ipyDataMgr.GetCreateRoleLimitServerByIndex(i)  | 
|         if groupID in ipyData.GetLimitServerGroupIDList():  | 
|             return True  | 
|         for idA, idB in ipyData.GetLimitServerGroupIDRangeList():  | 
|             if idA <= groupID <= idB:  | 
|                 return True  | 
|     return False  | 
|   | 
| ## ¼ì²éÍæ¼ÒÃû×ÖÊÇ·ñºÏ·¨(ÕâÀïµÄPlayerNameΪ¹ýÂËÍê¿Õ¸ñµÄÃû×Ö)  | 
| #  @param curPlayer µ±Ç°Íæ¼Ò  | 
| #  @param playerName Íæ¼ÒÃû³Æ  | 
| #  @return True or False  | 
| #  @remarks º¯ÊýÏêϸ˵Ã÷.  | 
| def CheckPlayerName(curPlayer , playerName):  | 
|     if playerName.strip() == "":  | 
|         return False  | 
|       | 
|     if DirtyList.IsWordForbidden(playerName):  | 
|         GameWorld.Log('Íæ¼Ò´´½¨½Çɫʧ°Ü, Ãû×Ö²»ºÏ·¨ = %s' % (playerName))  | 
|         return False  | 
|       | 
|     playerNameLen = len(playerName)  | 
|       | 
|     if playerNameLen < ChConfig.Def_CreatRole_MinStr:  | 
|         GameWorld.Log('Íæ¼Ò´´½¨½Çɫʧ°Ü, ½ÇÉ«Ãû×Ö¹ý¶Ì = %s , %s < %s' % (playerName, playerNameLen, ChConfig.Def_CreatRole_MinStr))  | 
|         return False  | 
|       | 
|     if playerNameLen > ChConfig.Def_CreatRole_MaxStr:  | 
|         GameWorld.Log('Íæ¼Ò´´½¨½Çɫʧ°Ü, ½ÇÉ«Ãû×Ö¹ý³¤ = %s , %s > %s' % (playerName, playerNameLen, ChConfig.Def_CreatRole_MaxStr))  | 
|         return False  | 
|       | 
|     return True  | 
|   | 
| def __GetCreateRoleMapInfo(createRoleMap):  | 
|     '''»ñÈ¡´´½ÇÖØÉúÐÂÊÖ´åµØÍ¼  | 
|     @return: None  | 
|     @return: dataMapID, lineID, posX, posY  | 
|     '''  | 
|     createRoleDataMapID, posX, posY = createRoleMap  | 
|     mapShuntInfoDict = IpyGameDataPY.GetFuncEvalCfg("SetWorldPosShunt", 1) # µØÍ¼¶ÔÓ¦·ÖÁ÷ÈËÊý {dataMapID:ÈËÊý, ...}  | 
|     if createRoleDataMapID not in mapShuntInfoDict:  | 
|         return createRoleDataMapID, 0, posX, posY # Ä¬ÈÏ1Ïß  | 
|       | 
|     activityLineIndex = 0 # »î¶¯ÏßĬÈÏ1Ïß  | 
|     activityMapLineDict = IpyGameDataPY.GetFuncEvalCfg("MapLine", 2, {})  | 
|     if createRoleDataMapID in activityMapLineDict:  | 
|         activityLineIndex = max(0, activityMapLineDict[createRoleDataMapID] - 1)  | 
|           | 
|     lineMaxPlayerCount = mapShuntInfoDict[createRoleDataMapID]  | 
|     emptyLineID = None  | 
|     heavyLineList = []  | 
|       | 
|     mapServerStateManager = GameWorld.GetGameWorld().GetMapServerStateManager()  | 
|     zoneServerCnt = mapServerStateManager.GetZoneServerCnt()  | 
|     #GameWorld.DebugLog("´´½ÇÖØÉúÐÂÊÖ´åµØÍ¼×´Ì¬ zoneServerCnt=%s,job=%s,createRoleDataMapID=%s,lineMaxPlayerCount=%s"   | 
|     #                   % (zoneServerCnt, job, createRoleDataMapID, lineMaxPlayerCount))  | 
|     for zoneIndex in range(zoneServerCnt):  | 
|         zoneServerState = mapServerStateManager.GetZoneServerByIndex(zoneIndex)  | 
|         routeServerIndex = zoneServerState.GetRouteServerIndex()  | 
|         mapCount = zoneServerState.GetMapCount()  | 
|         #GameWorld.DebugLog("  ZoneServerState.routeServerIndex=%s,mapCount=%s" % (routeServerIndex, mapCount))  | 
|         for i in range(mapCount):  | 
|             mapServerState = zoneServerState.GetMapServerStateByIndex(i)  | 
|             dataMapID = mapServerState.GetMapID()  | 
|             lineCount = mapServerState.GetLineCount()  | 
|             #GameWorld.DebugLog("    MapServerState dataMapID=%s,lineCount=%s" % (dataMapID, lineCount))  | 
|             for lineIndex in range(lineCount):  | 
|                 lineState = mapServerState.GetLineByIndex(lineIndex)  | 
|                 dataMapID = lineState.GetMapID()  | 
|                 lineID = lineState.GetLineID()  | 
|                 curPlayerCnt = lineState.GetCurPlayerCnt()  | 
|                 maxPlayerCnt = lineState.GetMaxPlayerCnt()  | 
|                   | 
|                 if dataMapID != createRoleDataMapID:  | 
|                     continue  | 
|                   | 
|                 #´´½Ç²»·ÖÅäµ½·ÇÒ»ÏߵĻÏß·  | 
|                 if lineID != 0 and lineID == activityLineIndex:  | 
|                     #GameWorld.DebugLog("´´½Ç²»·ÖÅäµ½»î¶¯Ïߣ¡lineID=%s" % lineID)  | 
|                     continue  | 
|                   | 
|                 #GameWorld.DebugLog("        lineIndex=%s,lineID=%s,playerCnt=(%s/%s)" % (lineIndex, lineID, curPlayerCnt, maxPlayerCnt))  | 
|                 if curPlayerCnt >= lineMaxPlayerCount:  | 
|                     heavyLineList.append([curPlayerCnt, lineID])  | 
|                       | 
|                 elif not curPlayerCnt and emptyLineID == None:  | 
|                     emptyLineID = lineID  | 
|                       | 
|                 # ÒѾÓÐÈË£¬ÇÒ»¹Î´´ïµ½¹æ¶¨ÈËÊýµÄ£¬Ö±½ÓʹÓøÃÏß·  | 
|                 elif curPlayerCnt:  | 
|                     return createRoleDataMapID, lineID, posX, posY  | 
|                   | 
|     # ÓпÕÏß·£¬ÔòÖ±½ÓʹÓà             | 
|     if emptyLineID != None:  | 
|         return createRoleDataMapID, emptyLineID, posX, posY  | 
|       | 
|     if not heavyLineList:  | 
|         return  | 
|       | 
|     # Ã»ÓпÕÏß·ÁË£¬È¡ÈËÊý½ÏÉÙµÄ  | 
|     heavyLineList.sort()  | 
|     heavyLineID = heavyLineList[0][1]  | 
|     return createRoleDataMapID, heavyLineID, posX, posY  | 
|   | 
|   |