/** * @file DealPkg.cpp * @brief 处理包实现文件 * Copyright(c) 2007,上海第九城市游戏研发部 * All rights reserved * 文件名称: DealPkg.cpp * 摘 要: 根据通信参与方以及消息中的命令字处理收到的网络消息 * 作 者: dzj * 完成日期: 2007.12.17 * */ #include "../../../Base/Utility.h" #include "../../../Base/LoadConfig/LoadSrvConfig.h" #include "DealPkg_Map.h" #include "../Player/Player.h" #include "../OtherServer/otherserver.h" #include "../AddictionPlayerList.h" #include "../PseudowireManager.h" #ifdef ACE_WIN32 #pragma warning( push ) #pragma warning( disable: 4819 ) //"type cast" pointer truncation from ??* to ?? #endif //ACE_WIN32 #include "../../../Base/PkgProc/RelationServiceProtocol.h" #ifdef ACE_WIN32 #pragma warning( pop ) #endif //ACE_WIN32 #include "../../../Base/PkgProc/ParserTool.h" #include "../mapteleport/MapTeleporterManager.h" #include "../toolmonitor/toolmonitor.h" #include "../LogManager.h" ///玩家选角色消息处理; bool CDealPlayerPkg::OnPlayerSelRole( CPlayer* pOwner, const char* pPkg, const unsigned short wPkgLen ) { TRY_BEGIN; if ( NULL == pOwner ) { D_ERROR( "OnPlayerSelRole,pOwner空\n" ); return false; } DealPlayerPkgPre( CGSelectRole, selRole, pPkg, wPkgLen ); //D_WARNING( "收到客户端:%x选角色消息\n\n", ((DWORD)(DWORD_PTR)pOwner) ); //if ( wPkgLen != sizeof(CGSelectRole) ) //{ // //收包大小错误,可能是通信两端消息结构不一致; // return false; //} //玩家选角色命令; //const CGSelectRole* selRole = (const CGSelectRole*) pPkg; //D_DEBUG( "收到玩家%s选角色消息\n", pOwner->GetAccount() ); #ifdef USE_CRYPT if ( !(pOwner->IsPlayerRobot()) ) { //非机器人,检测是否已开始加密,如仍未开始,踢下; if ( !pOwner->IsCliStRcvCrypt() ) { D_WARNING( "OnPlayerSelRole,玩家%s加密校验错,断开。。。\n", pOwner->GetAccount() ); pOwner->ReqDestorySelf(); return false; } } #endif //USE_CRYPT if ( ! (pOwner->SetCurStat( PS_ROLESELED )) ) { //选角色时置状态失败; D_WARNING( "玩家%s选角色时置状态失败\n", pOwner->GetAccount() ); pOwner->ReqDestorySelf();//断开连接; return false; } GCSelectRole returnMsg; returnMsg.sequenceID = selRole->sequenceID; //网络序列ID returnMsg.uiRoleNo = selRole->uiRoleNo;//直接返回选角色结果; if ( pOwner->SelRole( selRole->uiRoleNo ) ) { D_DEBUG( "玩家%s选角色%d成功\n", pOwner->GetAccount(), selRole->uiRoleNo ); returnMsg.byIsSelectOK = GCSelectRole::ISSELECTOK_SUCCESS; } else { D_WARNING( "玩家%s选角色%d失败\n", pOwner->GetAccount(), selRole->uiRoleNo ); returnMsg.byIsSelectOK = GCSelectRole::ISSELECTOK_FAILED; } NewSendPlayerPkg( GCSelectRole, pOwner, returnMsg ); //MsgToPut* pSelRoleMsg = CreatePlayerPkg( GCSelectRole, pOwner, returnMsg ); //pOwner->SendPkgToPlayer( pSelRoleMsg );//通知玩家其选角色结果; if ( PS_QUERY_DETAIL_INFO < pOwner->GetCurStat() ) { return false; } //D_WARNING( "向客户端%d返回选角色结果消息,选角色结果%d\n", pOwner->GetSessionID(), returnMsg.byIsSelectOK ); return true; TRY_END; return false; } ///玩家登录过程:请求随机字符串; bool CDealPlayerPkg::OnPlayerReqRdStr( CPlayer* pOwner, const char* pPkg, const unsigned short wPkgLen ) { TRY_BEGIN; if ( NULL == pOwner ) { D_ERROR( "OnPlayerReqRdStr,pOwner空\n" ); return false; } DealPlayerPkgPre( CGRequestRandomString, reqRdString, pPkg, wPkgLen ); CNewLoginSrv* pNewLoginSrv = CManNewLoginSrv::GetNewLoginSrv(); if ( NULL == pNewLoginSrv ) { //找不到登录服务器; GCSrvError srvError; srvError.errNO = 1001; NewSendPlayerPkg( GCSrvError, pOwner, srvError ); D_WARNING( "1收到玩家新登录消息时,找不到新登录服务器\n\n" ); return false; } //确保输入帐号字符串有效,需要确保协议中数组长度>可能帐号最大长度+2,目前暂时不会突破此帐号长度,以后再与客户端协调; char safeAccount[sizeof(reqRdString->strUserAccount)+2]; StructMemSet( safeAccount, 0, sizeof(safeAccount) );//确保最后两个char为0; StructMemCpy( safeAccount, reqRdString->strUserAccount, sizeof(reqRdString->strUserAccount) ); //保存帐号与密码; pOwner->SetAccount( safeAccount ); pOwner->SetPwd( "" ); #ifdef USE_CRYPT ///////////////////////////////////////////////////////////////////////////////////// //加密例外:是否机器人... const char* playerAccount = safeAccount; const char* szrobot = "Robot"; if ( strlen( playerAccount ) >= strlen(szrobot) ) { bool isRobot = true; for ( unsigned int i=0; iSetIsRobot(); } } //...加密例外:是否机器人 //////////////////////////////////////////////////////////////////////////////////////////// #endif //USE_CRYPT #ifdef USE_DSIOCP #pragma warning( push ) #pragma warning( disable: 4311 ) //"type cast" pointer truncation from ??* to ?? D_WARNING( "玩家%s新loginsrv登录,socketID:%d, dwPID:%d\n", safeAccount, pOwner->GetSessionID(), pOwner->GetPlayerDwPID() ); #pragma warning( pop ) D_WARNING_DAY( "当前gatesrv人数%d\n", CManPlayer::GetPlayerNum() ); #else //USE_DSIOCP D_WARNING_DAY( "玩家%s登录, sessionid:%d, dwPID:%d, 当前gatesrv登录人数%d\n\n", safeAccount, pOwner->GetSessionID(), pOwner->GetPlayerDwPID(), CManPlayer::GetPlayerNum() ); #endif //USE_DSIOCP if ( !pOwner->SetCurStat( PS_LOGINING ) ) { D_ERROR( "置玩家进新login状态失败\n" ); return false; } GL_ReportUserRequest playerRandomStrReq; playerRandomStrReq.gateId = pOwner->GetPlayerID().wGID; playerRandomStrReq.playerId = pOwner->GetPlayerID().dwPID; SafeStrCpy( playerRandomStrReq.userId.userId,pOwner->GetAccount() ); playerRandomStrReq.userId.userIdLen = (unsigned short) (strlen( playerRandomStrReq.userId.userId ) + 1); static unsigned int userRequestID = 0; pOwner->SetUserRequestID( ++userRequestID ); playerRandomStrReq.requestSeq = reqRdString->sequenceID; //这里更改为老张设置的ID SendMsgToNewLoginSrv( GL_ReportUserRequest, playerRandomStrReq ); //同步客户端和服务器的时间 pOwner->StartSynchTime(); MUX_BG_Monitor::Monitor_Record tmpRecord;//通知监控当前gate人数; tmpRecord.online_player_num = CManPlayer::GetPlayerNum(); tmpRecord.str_len = 0; SendMsgToMonitor< MUX_BG_Monitor::Monitor_Record >( tmpRecord ); return true; TRY_END; return false; } ///玩家登录过程:发来md5校验值; bool CDealPlayerPkg::OnPlayerUserMd5Value( CPlayer* pOwner, const char* pPkg, const unsigned short wPkgLen ) { TRY_BEGIN; if ( NULL == pOwner ) { D_ERROR( "OnPlayerUserMd5Value,pOwner空\n" ); return false; } DealPlayerPkgPre( CGUserMD5Value, userMd5Value, pPkg, wPkgLen ); /********************************************************************\ * * hym暂时关掉 防沉迷系统 * \********************************************************************/ /* CNewLoginSrv* pNewLoginSrv = CManNewLoginSrv::GetNewLoginSrv(); if ( NULL == pNewLoginSrv ) { //找不到登录服务器; GCSrvError srvError; srvError.errNO = 1001; NewSendPlayerPkg( GCSrvError, pOwner, srvError ); //MsgToPut* pErrMsg = CreatePlayerPkg( GCSrvError, pOwner, srvError ); //pOwner->SendPkgToPlayer( pErrMsg );//通知玩家没有对应的mapsrv; D_WARNING( "2收到玩家新登录消息时,找不到新登录服务器\n\n" ); return false; } */ D_DEBUG( "收到玩家%s的md5校验值\n", pOwner->GetAccount() ); //将玩家md5校验值转loginsrv; GL_CheckUserMD5Request playerMd5Value; playerMd5Value.gateId = pOwner->GetPlayerID().wGID; playerMd5Value.playerId = pOwner->GetPlayerID().dwPID; SafeStrCpy( playerMd5Value.userId.userId,pOwner->GetAccount() ); playerMd5Value.userId.userIdLen = (unsigned short) (strlen( playerMd5Value.userId.userId ) + 1); static unsigned int userMd5ID = 0; pOwner->SetUserMd5ID( ++userMd5ID ); //playerMd5Value.requestSeq = ++userMd5ID; playerMd5Value.requestSeq = userMd5Value->sequenceID; //这里设置成老张用的ID playerMd5Value.md5Value.md5ValueLen = userMd5Value->md5ValueSize; if ( sizeof(playerMd5Value.md5Value.md5Value) < playerMd5Value.md5Value.md5ValueLen ) { D_WARNING( "OnPlayerUserMd5Value,玩家%s发来的md5校验值超长,长度:%d\n", pOwner->GetAccount(), playerMd5Value.md5Value.md5ValueLen ); return false; } //#ifdef ACE_WIN32 // memcpy_s( playerMd5Value.md5Value.md5Value, sizeof(playerMd5Value.md5Value.md5Value), userMd5Value->md5Value, playerMd5Value.md5Value.md5ValueLen ); //#else //ACE_WIN32 StructMemCpy( playerMd5Value.md5Value.md5Value, userMd5Value->md5Value, playerMd5Value.md5Value.md5ValueLen ); //#endif //ACE_WIN32 //MsgToPut* pLoginMsg = CreateNewLoginSrvPkg( GL_CheckUserMD5Request, pNewLoginSrv, playerMd5Value ); //pNewLoginSrv->SendPkgToSrv( pLoginMsg ); SendMsgToNewLoginSrv( GL_CheckUserMD5Request, playerMd5Value ); return true; TRY_END; return false; } //todo wcj 2011.01.04 似乎没用到,暂时删除 ///玩家登录消息处理; //bool CDealPlayerPkg::OnPlayerLogin( CPlayer* pOwner, const char* pPkg, const unsigned short wPkgLen ) //{ // TRY_BEGIN; // // if ( NULL == pOwner ) // { // D_ERROR( "OnPlayerLogin,pOwner空\n" ); // return false; // } // // DealPlayerPkgPre( CGLogin, tmpLogin, pPkg, wPkgLen ); // //if ( wPkgLen != sizeof(CGLogin) ) // //{ // // //收包大小错误,可能是通信两端消息结构不一致; // // return false; // //} // ////玩家登录命令; // //const CGLogin* tmpLogin = (const CGLogin*) pPkg; // // //保存帐号与密码; // pOwner->SetAccount( tmpLogin->strUserAccount );//同时,目前在该函数中确定玩家登录的mapsrv; // pOwner->SetPwd( tmpLogin->strUserPassword ); // //#ifdef USE_DSIOCP //#pragma warning( push ) //#pragma warning( disable: 4311 ) //"type cast" pointer truncation from ??* to ?? // D_WARNING( "玩家%s登录,socketID:%d, dwPID:%x\n", tmpLogin->strUserAccount, pOwner->GetSessionID(), (DWORD)pOwner ); //#pragma warning( pop ) // D_WARNING_DAY( "当前gatesrv人数%d\n", CManPlayer::GetPlayerNum() ); //#else //USE_DSIOCP // D_WARNING_DAY( "玩家%s请求登录, 当前gatesrv登录人数%d\n\n", tmpLogin->strUserAccount, CManPlayer::GetPlayerNum() ); //#endif //USE_DSIOCP // // CLoginSrv* pLoginSrv = CManLoginSrvs::GetLoginserver(); // if ( NULL == pLoginSrv ) // { // //找不到登录服务器; // GCSrvError srvError; // srvError.errNO = 1001; // NewSendPlayerPkg( GCSrvError, pOwner, srvError ); // //MsgToPut* pErrMsg = CreatePlayerPkg( GCSrvError, pOwner, srvError ); // //pOwner->SendPkgToPlayer( pErrMsg );//通知玩家没有对应的mapsrv; // D_WARNING( "收到玩家登录消息时,找不到登录服务器\n\n" ); // return false; // } // // if ( !pOwner->SetCurStat( PS_LOGINING ) ) // { // D_ERROR( "置玩家进login状态失败\n" ); // return false; // } // // GLPlayerLogin glLogin; // glLogin.playerID = pOwner->GetPlayerID(); // SafeStrCpy( glLogin.szAccount, pOwner->GetAccount() ); // SafeStrCpy( glLogin.szPassword, pOwner->GetPwd() ); // // //MsgToPut* pLoginMsg = CreateSrvPkg( GLPlayerLogin, pLoginSrv, glLogin ); // //pLoginSrv->SendPkgToSrv( pLoginMsg ); // SendMsgToSrv( GLPlayerLogin, pLoginSrv, glLogin ); // // return true; // TRY_END; // return false; //} bool CDealPlayerPkg::OnPlayerCreateRole( CPlayer* pOwner, const char* pPkg, const unsigned short wPkgLen ) { TRY_BEGIN; if ( NULL == pOwner ) { D_ERROR( "OnPlayerCreateRole,pOwner空\n" ); return false; } #ifdef DS_EPOLL if ( wPkgLen != sizeof(CGCreateRole) ) { return false; }; CGCreateRole* createRole = (CGCreateRole*) pPkg; #else DealPlayerPkgPre( CGCreateRole, createRole, pPkg, wPkgLen ); #endif #ifdef USE_CRYPT if ( !(pOwner->IsPlayerRobot()) ) { //非机器人,检测是否已开始加密,如仍未开始,踢下; if ( !pOwner->IsCliStRcvCrypt() ) { D_WARNING( "OnPlayerCreateRole,玩家%s加密校验错,断开。。。\n", pOwner->GetAccount() ); pOwner->ReqDestorySelf(); return false; } } #endif //USE_CRYPT D_DEBUG("玩家%s 发送请求,创建角色%s\n", pOwner->GetAccount(),createRole->strNickName ); if (pOwner->GetRoleNum() >= 4) { D_WARNING( "玩家发创建角色个数超过客户端界面显示个数\n\n" ); // 返回玩家创建较色失败 GCCreateRole createRoleFail; StructMemSet( createRoleFail, 0x0, sizeof(createRoleFail) ); createRoleFail.byIsOK = GCCreateRole::ISSELECTOK_FAILED; NewSendPlayerPkg( GCCreateRole, pOwner, createRoleFail ); return false; } bool isCreateSuc = true; unsigned int nickNameLen = sizeof(createRole->strNickName) - 2; createRole->strNickName[nickNameLen] = '\0'; createRole->strNickName[nickNameLen + 1 ] = '\0'; for ( unsigned int i = 0 ; i< createRole->nameSize && isCreateSuc ; ) { if ( i >= ARRAY_SIZE(createRole->strNickName) ) { D_ERROR( "CDealPlayerPkg::OnPlayerCreateRole, i(%d) >= ARRAY_SIZE(createRole->strNickName)\n", i ); return false; } char ch = createRole->strNickName[i]; if ( ch < 0 )//后面一个字符应该和前面一个字符组成双字节 { i++; if ( i == createRole->nameSize )//字符串的最后一位不应该为双字节的第一个字节 { isCreateSuc = false; D_ERROR("玩家%s创建的角色姓名 %s 最后一个字节为双字节的第一个字节\n", pOwner->GetAccount(),createRole->strNickName); break; } if ( ch == -95 ) { char ch2 = createRole->strNickName[i]; if( ch2 == -95 )//如果前一字节和后一字节的编码都是-95, 则证明是全角的空格 { D_ERROR("玩家%s创建的角色%s含有全角空格,无法创建角色\n",pOwner->GetAccount(),createRole->strNickName ); isCreateSuc = false; } } i++; } else { if ( ch == 32 ) { D_ERROR("玩家%s创建的角色%s含有半角空格,无法创建角色\n",pOwner->GetAccount(),createRole->strNickName ); isCreateSuc = false; } i++; } } if( !isCreateSuc ) { D_DEBUG("玩家%s 创建角色 %s 失败,字符编码为: ", pOwner->GetAccount() ,createRole->strNickName ); for ( unsigned int i = 0 ; i < createRole->nameSize ; i++ ) { if ( i >= ARRAY_SIZE(createRole->strNickName) ) { D_ERROR( "CDealPlayerPkg::OnPlayerCreateRole2, i(%d) >= ARRAY_SIZE(createRole->strNickName)\n", i ); return false; } char ch = createRole->strNickName[i]; D_DEBUG("%c_", ch ); } D_DEBUG("\n"); } //向DBSrv请求创建玩家角色信息; CDbSrv* pDbSrv = CManDbSrvs::GetDbsrvByAccount( pOwner->GetAccount() ); if ( NULL == pDbSrv ) { GCSrvError srvError; srvError.errNO = 1001; NewSendPlayerPkg( GCSrvError, pOwner, srvError ); D_WARNING( "玩家发创建角色请求时,找不到玩家所在的dbsrvd\n\n" ); return false; } GDNewPlayerInfo newPlayerInfo; newPlayerInfo.sequenceID = createRole->sequenceID; newPlayerInfo.playerID = pOwner->GetPlayerID(); SafeStrCpy( newPlayerInfo.szAccount, pOwner->GetAccount() ); SafeStrCpy( newPlayerInfo.strNickName, createRole->strNickName) newPlayerInfo.wRace = createRole->wRace; newPlayerInfo.wSex = createRole->wSex; newPlayerInfo.nClass = createRole->nClass; newPlayerInfo.nFace = createRole->nFace; newPlayerInfo.nHair = createRole->nHair; newPlayerInfo.usPortrait = createRole->usPortrait; //MsgToPut* pReqCreateRole = CreateSrvPkg( GDNewPlayerInfo, pDbSrv, newPlayerInfo ); //pDbSrv->SendPkgToSrv( pReqCreateRole ); SendMsgToSrv( GDNewPlayerInfo, pDbSrv, newPlayerInfo ); D_DEBUG("玩家%s 创建角色 %s 在GateSrv验证成功,发往DBSrv\n", pOwner->GetAccount(),createRole->strNickName ); return true; TRY_END; return false; } bool CDealPlayerPkg::OnPlayerDeleteRole( CPlayer* pOwner, const char* pPkg, const unsigned short wPkgLen ) { TRY_BEGIN; if(NULL == pOwner) { D_ERROR( "OnPlayerDeleteRole,pOwner空\n" ); return false; } DealPlayerPkgPre( CGDeleteRole, pCGDeleteRole, pPkg, wPkgLen ); //if ( wPkgLen != sizeof(CGDeleteRole) ) //{ // //收包大小错误,可能是通信两端消息结构不一致; // return false; //} #ifdef USE_CRYPT if ( !(pOwner->IsPlayerRobot()) ) { //非机器人,检测是否已开始加密,如仍未开始,踢下; if ( !pOwner->IsCliStRcvCrypt() ) { D_WARNING( "OnPlayerDeleteRole,玩家%s加密校验错,断开。。。\n", pOwner->GetAccount() ); pOwner->ReqDestorySelf(); return false; } } #endif //USE_CRYPT GCPlayerRole roleInfo; if(pOwner->GetRoleInfoLogin(pCGDeleteRole->usRoleIndex, roleInfo)) { CRelationSrv* pSrv = CManRelationSrvs::GetRelationserver(); if( NULL == pSrv ) { GCSrvError srvError; srvError.errNO = 1001; NewSendPlayerPkg( GCSrvError, pOwner, srvError ); //MsgToPut* pErrMsg = CreatePlayerPkg( GCSrvError, pOwner, srvError ); //pOwner->SendPkgToPlayer( pErrMsg ); D_WARNING( "玩家发删除角色请求时,找不到relationSrv\n" ); return false; } UnionOwnerCheckRequest unionOwnerCheckReq; unionOwnerCheckReq.gateId = pOwner->GetPlayerID().wGID; unionOwnerCheckReq.playerId = pOwner->GetPlayerID().dwPID; unionOwnerCheckReq.uiid = roleInfo.playerInfo.uiID; //MsgToPut* pUnionOwnerCheck = CreateRelationPkg( UnionOwnerCheckRequest, pSrv, unionOwnerCheckReq ); //pSrv->SendPkgToSrv(pUnionOwnerCheck); SendMsgToRelationSrv( UnionOwnerCheckRequest, unionOwnerCheckReq ); } else { GCDeleteRole gcDeleteRole; gcDeleteRole.byIsOK = GCDeleteRole::OP_FAILED; gcDeleteRole.wRoleNo = pCGDeleteRole->usRoleIndex; NewSendPlayerPkg( GCDeleteRole, pOwner, gcDeleteRole ); //MsgToPut* pGCDeleteRole = CreatePlayerPkg( GCDeleteRole, pOwner, gcDeleteRole ); //pOwner->SendPkgToPlayer( pGCDeleteRole ); } /*CDbSrv* pDbSrv = CManDbSrvs::GetDbsrvByAccount( pOwner->GetAccount() ); if ( NULL == pDbSrv ) { GCSrvError srvError; srvError.errNO = 1001; NewSendPlayerPkg( GCSrvError, pOwner, srvError ); //MsgToPut* pErrMsg = CreatePlayerPkg( GCSrvError, pOwner, srvError ); //if ( NULL != pOwner ) //{ // pOwner->SendPkgToPlayer( pErrMsg );//通知玩家没有对应的dbsrv; //} D_WARNING( "玩家发删除角色请求时,找不到玩家所在的dbsrvd\n\n" ); return false; } //const CGDeleteRole *pCGDeleteRole = (const CGDeleteRole *)pPkg; GDDeletePlayerInfo deletePlayerInfo; deletePlayerInfo.playerID = pOwner->GetPlayerID(); //判断指定的角色是否存在? GCPlayerRole roleInfo; if(pOwner->GetRoleInfoLogin(pCGDeleteRole->usRoleIndex, roleInfo)) { deletePlayerInfo.uiPlayerInfoID = roleInfo.playerInfo.uiID; MsgToPut* pGDDeleteRole = CreateSrvPkg( GDDeletePlayerInfo, pDbSrv, deletePlayerInfo ); pDbSrv->SendPkgToSrv( pGDDeleteRole ); //发送给RelationSrv,通知删除玩家 CRelationSrv* pRelationSrv = CManRelationSrvs::GetRelationserver(); if( pRelationSrv ) { G_R_DelPlayer delPlayer; delPlayer.uiid = roleInfo.playerInfo.uiID; MsgToPut* pNewMsg = CreateRelationPkg( G_R_DelPlayer, pRelationSrv, delPlayer ); pRelationSrv->SendPkgToSrv( pNewMsg ); } //通知所有的mapsrv删除该排行榜玩家 GMPlayerDeleteRole removePlayer; removePlayer.race = roleInfo.playerInfo.ucRace; removePlayer.playerUID = roleInfo.playerInfo.uiID; CManMapSrvs::SendBroadcastMsg( &removePlayer ); GFOnPlayerDeleteRole onDelRole; onDelRole.race = roleInfo.playerInfo.ucRace; onDelRole.playerUID = roleInfo.playerInfo.uiID; SendMsgToFunctionSrv( GFOnPlayerDeleteRole, onDelRole ); } else { GCDeleteRole gcDeleteRole; gcDeleteRole.byIsOK = GCDeleteRole::OP_FAILED; gcDeleteRole.wRoleNo = pCGDeleteRole->usRoleIndex; CPlayer* pPlayer = CManPlayer::FindPlayer( deletePlayerInfo.playerID.dwPID ); if ( NULL == pPlayer ) { D_WARNING( "收到dbsrv发来玩家相关信息时,在本GateSrv中找不到对应玩家\n" ); return false; } NewSendPlayerPkg( GCDeleteRole, pPlayer, gcDeleteRole ); //MsgToPut* pGCDeleteRole = CreatePlayerPkg( GCDeleteRole, pPlayer, gcDeleteRole ); //pPlayer->SendPkgToPlayer( pGCDeleteRole ); }*/ return true; TRY_END return false; }