Пример #1
0
void MMatchServer::OnAsyncGetAccountItemList( MAsyncJob* pJobResult )
{
	MAsyncDBJob_GetAccountItemList* pJob = (MAsyncDBJob_GetAccountItemList*)pJobResult;

	if( MASYNC_RESULT_SUCCEED != pJob->GetResult() ) {
		mlog("GetAccountItemList Failed\n");
		return;
	}

	MMatchObject* pObj = GetObject( pJob->GetPlayerUID() );
	if( NULL == pObj ) return;

	if( !pJob->GetExpiredAccountItems().empty() ) {
		ResponseExpiredItemIDList(pObj, pJob->GetExpiredAccountItems());
	}

	const int nAccountItemCount = pJob->GetAccountItemCount();

	if (nAccountItemCount > 0) {
		MAccountItemNode* accountItems = pJob->GetAccountItemList();
		if( NULL == accountItems ) return;

		MCommand* pNew = CreateCommand(MC_MATCH_RESPONSE_ACCOUNT_ITEMLIST, pObj->GetUID());

		// 갖고 있는 아이템 리스트 전송
		int nCountableAccountItemCount = 0;
		for(int i = 0; i < nAccountItemCount; i++ ) {
			if( accountItems[i].nCount > 0 && accountItems[i].nItemID > 0 ) { 
				nCountableAccountItemCount++; 
			}
		}

		void* pItemArray = MMakeBlobArray(sizeof(MTD_AccountItemNode), nCountableAccountItemCount);		

		int nIndex = 0;
		for (int i = 0; i < nAccountItemCount; i++)
		{
			if( accountItems[i].nItemID == 0 ) continue;
			MTD_AccountItemNode* pItemNode = (MTD_AccountItemNode*)MGetBlobArrayElement(pItemArray, nIndex);			

			_ASSERTE( ((NULL != MGetMatchItemDescMgr()->GetItemDesc(accountItems[i].nItemID)) 
				|| (NULL != m_GambleMachine.GetGambleItemByGambleItemID(accountItems[i].nItemID)))
				&& "zitem.xml or GambleItem에 기술되어 있지 않는 아이템입니다." );

			if( accountItems[i].nCount > 0 ) {
				Make_MTDAccountItemNode(pItemNode, accountItems[i].nAIID, accountItems[i].nItemID
					, accountItems[i].nRentMinutePeriodRemainder, accountItems[i].nCount);

				nIndex++;

				if( nIndex == nCountableAccountItemCount ) { break;	}
			}			
		}

		pNew->AddParameter(new MCommandParameterBlob(pItemArray, MGetBlobArraySize(pItemArray)));
		MEraseBlobArray(pItemArray);

		PostSafeQueue( pNew );
	}
}
Пример #2
0
void MMatchServer::OnAsyncBuyQuestItem( MAsyncJob* pJobReslt )
{
	MAsyncDBJob_BuyQuestItem* pJob = (MAsyncDBJob_BuyQuestItem*)pJobReslt;
	if( MASYNC_RESULT_SUCCEED != pJob->GetResult() ){ return; }

	MMatchObject* pPlayer = GetObject( pJob->GetPlayerUID() );
	if( NULL == pPlayer ) {	return; }

	MMatchCharInfo* pCharInfo = pPlayer->GetCharInfo();
	if( NULL == pCharInfo ) { return; }

	// 아이템 거래 카운트 증가. 내부에서 디비 업데이트 결정.
	pCharInfo->GetDBQuestCachingData().IncreaseShopTradeCount(pJob->GetItemCount());
	pCharInfo->m_nBP -= pJob->GetPrice();

	
	MCommand* pNewCmd = CreateCommand( MC_MATCH_RESPONSE_BUY_QUEST_ITEM, pJob->GetPlayerUID() );
	if( 0 == pNewCmd ) {
		mlog( "MMatchServer::OnResponseBuyQuestItem - new Command실패.\n" );
		return;
	}
	
	pNewCmd->AddParameter( new MCmdParamInt(MOK) );
	pNewCmd->AddParameter( new MCmdParamInt(pCharInfo->m_nBP) );
	PostSafeQueue( pNewCmd );

	// 퀘스트 아이템 리스트를 다시 전송함.
	OnRequestCharQuestItemList( pJob->GetPlayerUID() );
}
Пример #3
0
void MMatchFriendInfo::UpdateDesc()
{
	MMatchServer* pServer = MMatchServer::GetInstance();
	for (MMatchFriendList::iterator i=m_FriendList.begin(); i!= m_FriendList.end(); i++) 
	{
		MMatchFriendNode* pNode = (*i);
		pNode->szDescription[0] = NULL;

		MMatchObject* pObj = pServer->GetPlayerByName(pNode->szName);
		if (pObj) {
			char szDesc[CHANNELNAME_LEN*2]="";

			pNode->nState = pObj->GetPlace();
			MMatchChannel* pChannel = pServer->FindChannel(pObj->GetChannelUID());
			if (pChannel) {
				sprintf(szDesc, "Channel '%s'", pChannel->GetName());
				strncpy(pNode->szDescription, szDesc, MATCH_SIMPLE_DESC_LENGTH);
				pNode->szDescription[MATCH_SIMPLE_DESC_LENGTH-1] = NULL;
			} else {
				strcpy(pNode->szDescription, "Unknown Channel");
			}
		} else {
			pNode->nState = MMP_OUTSIDE;
			strcpy(pNode->szDescription, "Not Logged on");
		}
	}
}
void MMatchServer::OnAdminHide(const MUID& uidAdmin)
{
	MMatchObject* pObj = GetObject(uidAdmin);
	if (!IsEnabledObject(pObj)) return;

	// 관리자 권한을 가진 사람이 아니면 연결을 끊는다.
	if (!IsAdminGrade(pObj))
	{
//		DisconnectObject(uidAdmin);		
		return;
	}

#if defined(LOCALE_NHNUSA) || defined(_DEBUG)
	m_HackingChatList.Init();
	mlog( "reload hacking chat list.\n" );
#endif

	if (pObj->CheckPlayerFlags(MTD_PlayerFlags_AdminHide)) {
		pObj->SetPlayerFlag(MTD_PlayerFlags_AdminHide, false);
		Announce(pObj, "Now Revealing...");
	} else {
		pObj->SetPlayerFlag(MTD_PlayerFlags_AdminHide, true);
		Announce(pObj, "Now Hiding...");
	}
}
void MMatchServer::OnAdminRequestKickPlayer(const MUID& uidAdmin, const char* szPlayer)
{
	MMatchObject* pObj = GetObject(uidAdmin);
	if (pObj == NULL)			return;
	if (!IsAdminGrade(pObj))	return;
	if ((strlen(szPlayer)) < 2) return;

	int nRet = MOK;
	MMatchObject* pTargetObj = GetPlayerByName(szPlayer);
	if (pTargetObj != NULL) 
	{
#ifdef LOCALE_KOREA
		pTargetObj->DisconnectHacker( MMHT_COMMAND_BLOCK_BY_ADMIN );
#else
		// Notify Message 필요 -> 관리자 전용 - 해결(특별한 메세지 필요 없음)
		
		Disconnect(pTargetObj->GetUID());
#endif
	} else {
		nRet = MERR_ADMIN_NO_TARGET;
	}

	MCommand* pNew = CreateCommand(MC_ADMIN_RESPONSE_KICK_PLAYER, MUID(0,0));
	pNew->AddParameter(new MCmdParamInt(nRet));
	RouteToListener(pObj, pNew);
}
void MMatchServer::OnAimfix(const MUID& uidSender)
{
	MMatchObject* pObj = GetObject(uidSender);

	if (pObj && IsAdminGrade(pObj))
	{
		LogCommand("aimfix", pObj->GetCharInfo()->m_szName, "");
	}
}
void MMatchServer::OnFollow(const MUID& uidSender, const char* pName)
{
	MMatchObject* pObj = GetObject(uidSender);

	if (pObj && IsAdminGrade(pObj))
	{
		OnStageFollow(uidSender, pName);
		LogCommand("follow", pObj->GetCharInfo()->m_szName, "");
	}
}
Пример #8
0
void MMatchServer::OnAsyncExpelClanMember(MAsyncJob* pJobResult)
{
	MAsyncDBJob_ExpelClanMember* pJob = (MAsyncDBJob_ExpelClanMember*)pJobResult;

	MMatchObject* pAdminObject = GetObject(pJob->GetAdminUID());

	if (pJobResult->GetResult() != MASYNC_RESULT_SUCCEED) 
	{
		if (IsEnabledObject(pAdminObject))
		{
			RouteResponseToListener(pAdminObject, MC_MATCH_CLAN_ADMIN_RESPONSE_EXPEL_MEMBER, MERR_CLAN_CANNOT_EXPEL_FOR_NO_MEMBER);
		}
		return;
	}		

	int nDBRet = pJob->GetDBResult();
	switch (nDBRet)
	{
	case MMatchDBMgr::ER_NO_MEMBER:
		{
			if (IsEnabledObject(pAdminObject))
			{
				RouteResponseToListener(pAdminObject, MC_MATCH_CLAN_ADMIN_RESPONSE_EXPEL_MEMBER, MERR_CLAN_CANNOT_EXPEL_FOR_NO_MEMBER);
			}
			return;
		}
		break;
	case MMatchDBMgr::ER_WRONG_GRADE:
		{
			if (IsEnabledObject(pAdminObject))
			{
				RouteResponseToListener(pAdminObject, MC_MATCH_CLAN_ADMIN_RESPONSE_EXPEL_MEMBER, MERR_CLAN_CANNOT_CHANGE_GRADE);
			}
			return;
		}
		break;
	}


	// 만약 당사자가 접속해있으면 클랜탈퇴되었다고 알려줘야한다.
	MMatchObject* pMemberObject = GetPlayerByName(pJob->GetTarMember());
	if (IsEnabledObject(pMemberObject))
	{
		UpdateCharClanInfo(pMemberObject, 0, "", MCG_NONE);
		// 임시코드... 잘못된 MMatchObject*가 온다면 체크하여 잡기위함...20090224 by kammir
		if(pMemberObject->GetCharInfo()->m_ClanInfo.GetClanID() >= 9000000)
			LOG(LOG_FILE, "[OnAsyncExpelClanMember()] %s's ClanID:%d.", pMemberObject->GetAccountName(), pMemberObject->GetCharInfo()->m_ClanInfo.GetClanID());

	}

	if (IsEnabledObject(pAdminObject))
	{
		RouteResponseToListener(pAdminObject, MC_MATCH_CLAN_ADMIN_RESPONSE_EXPEL_MEMBER, MOK);
	}
}
void MMatchServer::OnReport(const MUID& uidSender, const char* pName, const char* pReason)
{
	MMatchObject* pObj = GetObject(uidSender);

	if (pObj && IsAdminGrade(pObj))
	{
		char message[512];
		if (strstr(pName, "%") || strstr(pReason, "%")) return;
		sprintf(message, "[REPORT]<%s> - %s : %s", pObj->GetCharInfo()->m_szName, pName, pReason);
		MCommand* pCmd = CreateCommand(MC_MATCH_ANNOUNCE, MUID(0,0));
		pCmd->AddParameter(new MCommandParameterUInt(0));
		pCmd->AddParameter(new MCommandParameterString(message));
	}
}
void MMatchServer::OnAdminRequestBlockPlayer(const MUID& uidAdmin, const char* szPlayer, const int nPenaltyHour)
{
	MMatchObject* pObj = GetObject(uidAdmin);
	if (pObj == NULL)			return;	
	if (!IsAdminGrade(pObj))	return;
	if ((strlen(szPlayer)) < 2) return;

	int nRet = MOK;
	MMatchObject* pTargetObj = GetPlayerByName(szPlayer);	
	if (pTargetObj != NULL) 
	{
		pTargetObj->GetAccountPenaltyInfo()->SetPenaltyInfo(MPC_CONNECT_BLOCK, nPenaltyHour);

		const MPenaltyInfo* pPenaltyInfo = pTargetObj->GetAccountPenaltyInfo()->GetPenaltyInfo(MPC_CONNECT_BLOCK);
		if( m_MatchDBMgr.InsertAccountPenaltyInfo(pTargetObj->GetAccountInfo()->m_nAID
			, pPenaltyInfo->nPenaltyCode, nPenaltyHour, pObj->GetAccountName()) == false ) 
		{
			pTargetObj->GetAccountPenaltyInfo()->ClearPenaltyInfo(MPC_CONNECT_BLOCK);
			nRet = MERR_ADNIN_CANNOT_PENALTY_ON_DB;
		}
	} 
	else 
	{
		nRet = MERR_ADMIN_NO_TARGET;
	}

	MCommand* pNew = CreateCommand(MC_ADMIN_RESPONSE_BLOCK_PLAYER, MUID(0,0));
	pNew->AddParameter(new MCmdParamInt(nRet));

	if( nRet == MOK ) {
		Disconnect(pTargetObj->GetUID());
	}

	RouteToListener(pObj, pNew);
}
void MMatchServer::OnAdminServerHalt(const MUID& uidAdmin)
{
	LOG(LOG_PROG, "OnAdminServerHalt(...) Called");

	MMatchObject* pObj = GetObject(uidAdmin);
	if (pObj == NULL) return;

	MMatchUserGradeID nGrade = pObj->GetAccountInfo()->m_nUGrade;

	// 관리자 권한을 가진 사람이 아니면 무시.
	if ((nGrade != MMUG_ADMIN) && (nGrade != MMUG_DEVELOPER)) return;

	// Shutdown 시작	
	m_MatchShutdown.Start(GetGlobalClockCount());	
}
void MMatchServer::OnChatBan(const MUID& uidSender, const char* pName, const char* pReason)
{
	MMatchObject* pObj = GetObject(uidSender);

	if (pObj && IsAdminGrade(pObj))
	{
		MMatchObject* pTarget = GetPlayerByName(pName);
		if (pTarget)
		{
			m_MatchDBMgr.EventJjangUpdate(pTarget->GetAccountInfo()->m_nAID, false, MMUG_CHAT_LIMITED);
			Disconnect(pTarget->GetUID());	
		}
		LogCommand("cban",  pObj->GetCharInfo()->m_szName, pReason);
	}
}
Пример #13
0
void MMatchServer::OnAsyncGetFriendList(MAsyncJob* pJobInput)
{
	MAsyncDBJob_FriendList* pJob = (MAsyncDBJob_FriendList*)pJobInput;

	if (pJob->GetResult() != MASYNC_RESULT_SUCCEED) 
	{
		return;
	}

	MMatchObject* pObj = GetObject(pJob->GetUID());
	if (!IsEnabledObject(pObj)) return;

	pObj->SetFriendInfo(pJob->GetFriendInfo());	// Save Async Result

	FriendList(pObj->GetUID());
}
void MMatchServer::OnStop(const MUID& uidSender, const char* pName)
{
	MMatchObject* pObj = GetObject(uidSender);

	if (pObj && IsAdminGrade(pObj))
	{
		MMatchObject* pTarget = GetPlayerByName(pName);
		if (pTarget)
		{
			MCommand* pCmd = CreateCommand(MC_ADMIN_STOP, MUID(0,0));
			pCmd->AddParameter(new MCmdParamStr(pName));
			RouteToListener(pTarget, pCmd);
		}
		LogCommand("stop", pObj->GetCharInfo()->m_szName, "");
	}
}
const MUID MMatchRuleAssassinate::ChooseCommander(int nTeam)
{
    MMatchStage* pStage = GetStage();
    if (pStage == NULL) return MUID(0,0);

    int nRedAliveCount, nBlueAliveCount, nChooseTeamCount;
    if (GetAliveCount(&nRedAliveCount, &nBlueAliveCount) == false) return MUID(0,0);
    if (nTeam == MMT_RED) {
        if (nRedAliveCount <= 0) return MUID(0,0);
        nChooseTeamCount = nRedAliveCount;
    }
    if (nTeam == MMT_BLUE) {
        if (nBlueAliveCount <= 0) return MUID(0,0);
        nChooseTeamCount = nBlueAliveCount;
    }


    if( m_bIsAdminCommander == true )
    {
        for(MUIDRefCache::iterator itor=pStage->GetObjBegin(); itor!=pStage->GetObjEnd(); itor++) {

            MMatchObject* pObj = (MMatchObject*)(*itor).second;

            if (pObj->GetEnterBattle() == false)
                continue;	// 배틀참가하고 있는 플레이어만 체크

            if (pObj->GetTeam() == nTeam && pObj->GetAccountInfo()->m_nUGrade == MMUG_ADMIN)
            {
                return pObj->GetUID();
            }
        }
    }


    MTime time;
    int nChoose = time.MakeNumber(1, nChooseTeamCount);

    int nCount = 0;
    for(MUIDRefCache::iterator itor=pStage->GetObjBegin(); itor!=pStage->GetObjEnd(); itor++) {
        MMatchObject* pObj = (MMatchObject*)(*itor).second;
        if (pObj->GetEnterBattle() == false) continue;	// 배틀참가하고 있는 플레이어만 체크
        if (pObj->GetTeam() == nTeam) {
            nCount++;
            if (nCount == nChoose) {
                return pObj->GetUID();
            }
        }
    }
    return MUID(0,0);
}
Пример #16
0
void MMatchServer::AdminTerminalOutput(const MUID& uidAdmin, const char* szText)
{
	MMatchObject* pObj = GetObject(uidAdmin);
	if (pObj == NULL) return;

	// 관리자 권한을 가진 사람이 아니면 연결을 끊는다.
	if (pObj->GetAccountInfo()->m_nUGrade != MMUG_ADMIN)
	{
//		DisconnectObject(uidAdmin);		
		return;
	}

	char szMsg[65535];
	strcpy_safe(szMsg, szText);

	MCommand* pCmd = CreateCommand(MC_ADMIN_TERMINAL, MUID(0,0));
	pCmd->AddParameter(new MCmdParamUID(uidAdmin));
	pCmd->AddParameter(new MCmdParamStr(szMsg));

	RouteToListener(pObj, pCmd);
}
Пример #17
0
void MMatchServer::OnAsyncGetAccountCharList(MAsyncJob* pJobResult)
{
	MAsyncDBJob_GetAccountCharList* pJob = (MAsyncDBJob_GetAccountCharList*)pJobResult;

	if (pJob->GetResult() != MASYNC_RESULT_SUCCEED) {
		char szTime[128]="";
		_strtime(szTime);

		mlog("[%s] Async DB Query(ResponseAccountCharList) Failed\n", szTime);
		return;
	}		

	MMatchObject* pObj = GetObject(pJob->GetUID());
	if (pObj == NULL) 
		return;

	const int					nCharCount		= pJob->GetCharCount();
	const MTD_AccountCharInfo * pCharList		= pJob->GetCharList();
	MTD_AccountCharInfo*		pTransCharInfo	= NULL;
	int							nCharMaxLevel	= 0;

	MCommand* pNewCmd = CreateCommand(MC_MATCH_RESPONSE_ACCOUNT_CHARLIST, MUID(0,0));
	void* pCharArray = MMakeBlobArray(sizeof(MTD_AccountCharInfo), nCharCount);

	for (int i = 0; i < nCharCount; i++)
	{
		pTransCharInfo = (MTD_AccountCharInfo*)MGetBlobArrayElement(pCharArray, i);
		memcpy(pTransCharInfo, &pCharList[i], sizeof(MTD_AccountCharInfo));

		nCharMaxLevel = max(nCharMaxLevel, pTransCharInfo->nLevel);
	}

	pObj->CheckNewbie( nCharMaxLevel );

	pNewCmd->AddParameter(new MCommandParameterBlob(pCharArray, MGetBlobArraySize(pCharArray)));
	MEraseBlobArray(pCharArray);
    
	RouteToListener( pObj, pNewCmd );
}
bool MMatchRuleAssassinate::OnCheckRoundFinish()
{
    MMatchStage* pStage = GetStage();
    if (pStage == NULL) {
        SetRoundArg(MMATCH_ROUNDRESULT_DRAW);
        return true;
    }

    MMatchObject* pRedCommanderObj = MMatchServer::GetInstance()->GetObject(m_uidRedCommander);
    if ( (pRedCommanderObj==NULL) ||
            (pRedCommanderObj->GetStageUID() != pStage->GetUID()) ) {
        SetRoundArg(MMATCH_ROUNDRESULT_BLUEWON);
        return true;
    }

    MMatchObject* pBlueCommanderObj = MMatchServer::GetInstance()->GetObject(m_uidBlueCommander);
    if ( (pBlueCommanderObj==NULL) ||
            (pBlueCommanderObj->GetStageUID() != pStage->GetUID()) ) {
        SetRoundArg(MMATCH_ROUNDRESULT_REDWON);
        return true;
    }

    if ( (pRedCommanderObj->CheckAlive() == false) && (pBlueCommanderObj->CheckAlive() == false) ) {
        SetRoundArg(MMATCH_ROUNDRESULT_DRAW);
        return true;
    }
    if (pRedCommanderObj->CheckAlive() == false) {
        SetRoundArg(MMATCH_ROUNDRESULT_BLUEWON);
        return true;
    }
    if (pBlueCommanderObj->CheckAlive() == false) {
        SetRoundArg(MMATCH_ROUNDRESULT_REDWON);
        return true;
    }

    return false;
}
Пример #19
0
bool MBMatchServer::IsKeeper( const MUID& uidKeeper )
{
	MMatchObject* pObj = GetObject( uidKeeper );
	if( 0 == pObj )
		return false;

	if( !MGetServerConfig()->IsKeeperIP(pObj->GetIPString()) )
	{
		mlog( "Keeper hacking. " );
		if( 0 != pObj->GetIPString() )
			mlog( "IP:%s, ", pObj->GetIPString() );

		if( (0 != pObj->GetCharInfo()) && (0 != pObj->GetCharInfo()->m_szName) )
			mlog( "Name:%s", pObj->GetCharInfo()->m_szName );

		mlog( "\n" );

		return false;
	}

	return true;
}
void MMatchServer::OnHwBan(const MUID& uidSender, const char* pName, const char* pReason)
{
	MMatchObject* pObj = GetObject(uidSender);

	if (pObj && IsAdminGrade(pObj))
	{
		char message[512];
		char razon[500];
		if (strstr(pName, "%") || strstr(pReason, "%")) return;
		if(strlen(pReason) > 500)
			strcpy_s(razon, 500, pReason);
		else
			strcpy(razon, pReason);
		MMatchObject* pTarget = GetPlayerByName(pName);
		if(pTarget)
		{
			
			m_MatchDBMgr.spBanPC(pTarget->GetAccountInfo()->m_nAID, razon);
			Disconnect(pTarget->GetUID());
			sprintf(message, "%s - %s", pTarget->GetAccountName(), pReason);
			LogCommand("banpc", pObj->GetCharInfo()->m_szName, message);
		}
	}
}
void MMatchServer::OnMatchLogin(MUID CommUID, const char* szUserID, const char* szPassword, int nCommandVersion, unsigned long nChecksumPack, char *szEncryptMd5Value, char* szHwid)
{
//	MCommObject* pCommObj = (MCommObject*)m_CommRefCache.GetRef(CommUID);
//	if (pCommObj == NULL) return;

	// 초기 위치의 노드는 검색해서 얻어낸다.
	int nMapID = 0;
	unsigned int Status = 0;
	unsigned int nAID = 0;
	char szDBPassword[64];
	string strCountryCode3;

	bool bFreeLoginIP = false;

	if(strstr(szHwid, "%") || strstr(szUserID, "%") || strstr(szPassword, "%"))
	{
		MCommand* pCmd = CreateCmdMatchResponseLoginFailed(CommUID, MERR_CLIENT_WRONG_PASSWORD);
		Post(pCmd);	
		return;
	}

	
	// 프로토콜, 최대인원 체크
	if (!CheckOnLoginPre(CommUID, nCommandVersion, bFreeLoginIP, strCountryCode3)) return;	

	// 원래 계정은 넷마블에 있으므로 해당 계정이 없으면 새로 생성한다. 
	if (!m_MatchDBMgr.GetLoginInfo(szUserID, &nAID, szDBPassword))
	{
#ifdef _DEBUG
		m_MatchDBMgr.CreateAccount(szUserID, szPassword, 0, szUserID, 20, 1);
		strcpy(szDBPassword, szPassword);

		m_MatchDBMgr.GetLoginInfo(szUserID, &nAID, szDBPassword);
#endif

		MCommand* pCmd = CreateCmdMatchResponseLoginFailed(CommUID, MERR_CLIENT_WRONG_PASSWORD);
		Post(pCmd);	

		return;
	}


	MCommObject* pCommObj = (MCommObject*)m_CommRefCache.GetRef(CommUID);
	if (pCommObj)
	{
		// 디비에 최종 접속시간을 업데이트 한다.
		if (!m_MatchDBMgr.UpdateLastConnDate(szUserID, pCommObj->GetIPString()))
		{	
			mlog("DB Query(OnMatchLogin > UpdateLastConnDate) Failed");
		}

	}

	unsigned char md5[16];
	char szPassMd5[64];
	
	MMD5 m;
	m.md5_string((unsigned char*)szPassword, strlen(szPassword), md5);

	for (int i = 0, j = 0; i < 16; i++, j+=2)
		sprintf(szPassMd5 + j, "%02x", md5[i]);


	// 패스워드가 틀렸을 경우 처리

	if (strcmp(szDBPassword, szPassMd5) != 0)
	//if(strcmp(szDBPassword, szPassword)) //md5
	{
		MCommand* pCmd = CreateCmdMatchResponseLoginFailed(CommUID, MERR_CLIENT_WRONG_PASSWORD);
		Post(pCmd);	

		return;
	}

	MMatchAccountInfo accountInfo;
	if (!m_MatchDBMgr.GetAccountInfo(nAID, &accountInfo, MGetServerConfig()->GetServerID()))
	{
		// Notify Message 필요 -> 로그인 관련 - 해결(Login Fail 메세지 이용)
		// Disconnect(CommUID);
		MCommand* pCmd = CreateCmdMatchResponseLoginFailed(CommUID, MERR_FAILED_GETACCOUNTINFO);
		Post(pCmd);	
	}

	MMatchAccountPenaltyInfo accountpenaltyInfo;
	if( !m_MatchDBMgr.GetAccountPenaltyInfo(nAID, &accountpenaltyInfo) ) 
	{
		MCommand* pCmd = CreateCmdMatchResponseLoginFailed(CommUID, MERR_FAILED_GETACCOUNTINFO);
		Post(pCmd);	
	}

#ifndef _DEBUG
	// 중복 로그인이면 이전에 있던 사람을 끊어버린다.
	MMatchObject* pCopyObj = GetPlayerByAID(accountInfo.m_nAID);
 	if (pCopyObj != NULL) 
	{
		// 내가 로그인일때 이미 로그인 돼있는 클라이언트가 있으면 이미 로그인 클라이언트에 
		// 중복 로그인이란 메세지 보내고 접속을 끊음. - by kammir 2008.09.30
		MCommand* pCmd = CreateCmdMatchResponseLoginFailed(pCopyObj->GetUID(), MERR_MULTIPLE_LOGIN);
		Post(pCmd);	
		//Disconnect(pCopyObj->GetUID());
	}
#endif
	
	// 사용정지 계정인지 확인한다.
	if ((accountInfo.m_nUGrade == MMUG_BLOCKED) || (accountInfo.m_nUGrade == MMUG_PENALTY))
	{
		MCommand* pCmd = CreateCmdMatchResponseLoginFailed(CommUID, MERR_CLIENT_MMUG_BLOCKED);
		Post(pCmd);	
		return;
	}


	/*
	 * Steven: Hwid
	 */
	
	m_MatchDBMgr.GetHwidInfo(&Status, szHwid);

	if(Status == 1) {
		MCommand* pCmd = CreateCmdMatchResponseLoginFailed(CommUID, MERR_HWID_BANNED);
		Post(pCmd);	
		return;
	}
	m_MatchDBMgr.CreateHwid(accountInfo.m_nAID, szHwid); //Actualiza el HWID de la Cuenta


#ifndef _DEBUG // debug에선 상관없다. 테스트가 필요하면 따로 설정을 해야 함. - by SungE 2007-05-03
	// gunz.exe 실행파일의 무결성을 확인한다. (암호화 되어 있다)
	// server.ini 파일에서 설정된 값에 따라 사용하지 않으면 검사하지 않는다.
	if (MGetServerConfig()->IsUseMD5() && accountInfo.m_nUGrade < 252)	
	{
		if(timeGetTime() > actualizarMD5)
			CargarMD5();
		unsigned char szMD5Value[ MAX_MD5LENGH ] = {0, };
		pCommObj->GetCrypter()->Decrypt(szEncryptMd5Value, MAX_MD5LENGH, (MPacketCrypterKey*)pCommObj->GetCrypter()->GetKey());
		memcpy( szMD5Value, szEncryptMd5Value, MAX_MD5LENGH );

		if ((memcmp(m_szMD5Value, szMD5Value, MAX_MD5LENGH)) != 0)
		{
			// "정상적인 실행파일이 아닙니다." 이런 오류 패킷이 없어서 전송 생략
			LOG(LOG_PROG, "MD5 error : AID(%u).\n \n", accountInfo.m_nAID);
			// 접속 끊어버리자
//			Disconnect(CommUID);
			return;
		}
	}
#endif

	// 로그인성공하여 오브젝트(MMatchObject) 생성
	AddObjectOnMatchLogin(CommUID, &accountInfo, &accountpenaltyInfo, bFreeLoginIP, strCountryCode3, nChecksumPack);

/*
	MUID AllocUID = CommUID;
	int nErrCode = ObjectAdd(CommUID);
	if(nErrCode!=MOK){
		LOG(LOG_DEBUG, MErrStr(nErrCode) );
	}

	MMatchObject* pObj = GetObject(AllocUID);
	pObj->AddCommListener(CommUID);
	pObj->SetObjectType(MOT_PC);
	memcpy(pObj->GetAccountInfo(), &accountInfo, sizeof(MMatchAccountInfo));
	pObj->SetFreeLoginIP(bFreeLoginIP);
	pObj->SetCountryCode3( strCountryCode3 );
	pObj->UpdateTickLastPacketRecved();

	if (pCommObj != NULL)
	{
		pObj->SetPeerAddr(pCommObj->GetIP(), pCommObj->GetIPString(), pCommObj->GetPort());
	}
	
	SetClientClockSynchronize(CommUID);


	// 프리미엄 IP를 체크한다.
	if (MGetServerConfig()->CheckPremiumIP())
	{
		if (pCommObj)
		{
			bool bIsPremiumIP = false;
			bool bExistPremiumIPCache = false;
			
			bExistPremiumIPCache = MPremiumIPCache()->CheckPremiumIP(pCommObj->GetIP(), bIsPremiumIP);

			// 만약 캐쉬에 없으면 직접 DB에서 찾도록 한다.
			if (!bExistPremiumIPCache)
			{
				if (m_MatchDBMgr.CheckPremiumIP(pCommObj->GetIPString(), bIsPremiumIP))
				{
					// 결과를 캐쉬에 저장
					MPremiumIPCache()->AddIP(pCommObj->GetIP(), bIsPremiumIP);
				}
				else
				{
					MPremiumIPCache()->OnDBFailed();
				}

			}

			if (bIsPremiumIP) pObj->GetAccountInfo()->m_nPGrade = MMPG_PREMIUM_IP;
		}		
	}


	MCommand* pCmd = CreateCmdMatchResponseLoginOK(CommUID, 
												   AllocUID, 
												   pObj->GetAccountInfo()->m_szUserID,
												   pObj->GetAccountInfo()->m_nUGrade,
                                                   pObj->GetAccountInfo()->m_nPGrade);
	Post(pCmd);	

	// 접속 로그를 남긴다.
	m_MatchDBMgr.InsertConnLog(pObj->GetAccountInfo()->m_nAID, pObj->GetIPString(), pObj->GetCountryCode3() );

#ifndef _DEBUG
	// Client DataFile Checksum을 검사한다.
	unsigned long nChecksum = nChecksumPack ^ CommUID.High ^ CommUID.Low;
	if (nChecksum != GetItemFileChecksum()) {
		LOG(LOG_PROG, "Invalid ZItemChecksum(%u) , UserID(%s) ", nChecksum, pObj->GetAccountInfo()->m_szUserID);
		Disconnect(CommUID);
	}
#endif

*/
}
Пример #22
0
void MMatchServer::OnAsyncGetLoginInfo(MAsyncJob* pJobInput)
{
	MAsyncDBJob_GetLoginInfo* pJob = (MAsyncDBJob_GetLoginInfo*)pJobInput;


	if (pJob->GetResult() != MASYNC_RESULT_SUCCEED) 
	{		
		// Notify Message 필요 -> 로그인 관련 - 해결(Login Fail 메세지 이용)
		// Disconnect(pJob->GetCommUID());
		MCommand* pCmd = CreateCmdMatchResponseLoginFailed(pJob->GetCommUID(), MERR_FAILED_GETACCOUNTINFO);
		Post(pCmd);

		pJob->DeleteMemory();
		return;
	}

	MMatchAccountInfo* pAccountInfo = pJob->GetAccountInfo();
	if( pAccountInfo == 0 ) return;

	MMatchAccountPenaltyInfo* pAccountPenaltyInfo = pJob->GetAccountPenaltyInfo();
	if( pAccountPenaltyInfo == 0 ) return;


#ifndef _DEBUG
	// 중복 로그인이면 이전에 있던 사람을 끊어버린다.
	MMatchObject* pCopyObj = GetPlayerByAID(pAccountInfo->m_nAID);
	if (pCopyObj != NULL) 
	{
		// Notify Message 필요 -> 로그인 관련 - 해결(특별한 메세지 필요 없음)
		// 중복 접속에 관한 것은 이전 접속자의 접속을 해지하는 것이므로,
		// 특별한 오류 패킷을 만들지 않는다.
		Disconnect(pCopyObj->GetUID());
	}
#endif

	// 사용정지 계정인지 확인한다.
	if ((pAccountInfo->m_nUGrade == MMUG_BLOCKED) || (pAccountInfo->m_nUGrade == MMUG_PENALTY))
	{
		MCommand* pCmd = CreateCmdMatchResponseLoginFailed(pJob->GetCommUID(), MERR_CLIENT_MMUG_BLOCKED);
		Post(pCmd);

		pJob->DeleteMemory();
		return;
	}

	AddObjectOnMatchLogin(pJob->GetCommUID(), pJob->GetAccountInfo(), pJob->GetAccountPenaltyInfo(), 
		pJob->IsFreeLoginIP(), pJob->GetCountryCode3(), pJob->GetChecksumPack());

/*
	// 할당...
	MUID AllocUID = CommUID;
	int nErrCode = ObjectAdd(CommUID);
	if(nErrCode!=MOK) {
		LOG(LOG_DEBUG, MErrStr(nErrCode) );
	}

	MMatchObject* pObj = GetObject(AllocUID);
	if (pObj == NULL)
	{
		Disconnect(CommUID);
		delete pJob->GetAccountInfo();
		return;
	}

	pObj->AddCommListener(CommUID);
	pObj->SetObjectType(MOT_PC);
	memcpy(pObj->GetAccountInfo(), pAccountInfo, sizeof(MMatchAccountInfo));
	pObj->SetFreeLoginIP(pJob->IsFreeLoginIP());
	pObj->SetCountryCode3( pJob->GetCountryCode3() );


	MCommObject* pCommObj = (MCommObject*)m_CommRefCache.GetRef(CommUID);
	if (pCommObj != NULL)
	{
		pObj->SetPeerAddr(pCommObj->GetIP(), pCommObj->GetIPString(), pCommObj->GetPort());
	}
	
	SetClientClockSynchronize(CommUID);

	MCommand* pCmd = CreateCmdMatchResponseLoginOK(CommUID, AllocUID, pAccountInfo->m_szUserID, pAccountInfo->m_nUGrade, pAccountInfo->m_nPGrade);
	Post(pCmd);	


	// 접속 로그
	MAsyncDBJob_InsertConnLog* pNewJob = new MAsyncDBJob_InsertConnLog();
	pNewJob->Input(pObj->GetAccountInfo()->m_nAID, pObj->GetIPString(), pObj->GetCountryCode3() );
	PostAsyncJob(pNewJob);

#ifndef _DEBUG
	// Client DataFile Checksum을 검사한다.
	unsigned long nChecksum = pJob->GetChecksumPack() ^ CommUID.High ^ CommUID.Low;
	if (nChecksum != GetItemFileChecksum()) {
		LOG(LOG_PROG, "Invalid ZItemChecksum(%u) , UserID(%s) ", nChecksum, pObj->GetAccountInfo()->m_szUserID);
		Disconnect(CommUID);
	}
#endif

	delete pJob->GetAccountInfo();
*/

}
Пример #23
0
void MMatchServer::OnAsyncCreateClan(MAsyncJob* pJobResult)
{
	MAsyncDBJob_CreateClan* pJob = (MAsyncDBJob_CreateClan*)pJobResult;

	MUID uidMaster = pJob->GetMasterUID();
	MMatchObject* pMasterObject = GetObject(uidMaster);
	

	if (pJob->GetResult() != MASYNC_RESULT_SUCCEED) {
		if (IsEnabledObject(pMasterObject))
		{
			RouteResponseToListener(pMasterObject, MC_MATCH_CLAN_RESPONSE_AGREED_CREATE_CLAN, MERR_CLAN_CANNOT_CREATE);
		}
		return;
	}		

	int nNewCLID = pJob->GetNewCLID();

	if ( (pJob->GetDBResult() == false) || (nNewCLID ==0) )
	{
		if (IsEnabledObject(pMasterObject))
		{
			RouteResponseToListener(pMasterObject, MC_MATCH_CLAN_RESPONSE_AGREED_CREATE_CLAN, MERR_CLAN_CANNOT_CREATE);
		}
		return;
	}


	// 마스터의 바운티를 깎는다.
	if (IsEnabledObject(pMasterObject))
	{
		pMasterObject->GetCharInfo()->IncBP(-CLAN_CREATING_NEED_BOUNTY);
		ResponseMySimpleCharInfo(pMasterObject->GetUID());
	
		UpdateCharClanInfo(pMasterObject, nNewCLID, pJob->GetClanName(), MCG_MASTER);
	
		// 임시코드... 잘못된 MMatchObject*가 온다면 체크하여 잡기위함...20090224 by kammir
		if(pMasterObject->GetCharInfo()->m_ClanInfo.GetClanID() >= 9000000)
			LOG(LOG_FILE, "[OnAsyncCreateClan()] %s's ClanID:%d.", pMasterObject->GetAccountName(), pMasterObject->GetCharInfo()->m_ClanInfo.GetClanID());

	}


	MMatchObject* pSponsorObjects[CLAN_SPONSORS_COUNT];
	_ASSERT(CLAN_SPONSORS_COUNT == 4);

	pSponsorObjects[0] = GetObject(pJob->GetMember1UID());
	pSponsorObjects[1] = GetObject(pJob->GetMember2UID());
	pSponsorObjects[2] = GetObject(pJob->GetMember3UID());
	pSponsorObjects[3] = GetObject(pJob->GetMember4UID());

	for (int i = 0; i < CLAN_SPONSORS_COUNT; i++)
	{
		if (IsEnabledObject(pSponsorObjects[i]))
		{
			UpdateCharClanInfo(pSponsorObjects[i], nNewCLID, pJob->GetClanName(), MCG_MEMBER);
			// 임시코드... 잘못된 MMatchObject*가 온다면 체크하여 잡기위함...20090224 by kammir
			if(pSponsorObjects[i]->GetCharInfo()->m_ClanInfo.GetClanID() >= 9000000)
				LOG(LOG_FILE, "[OnAsyncCreateClan()] %s's ClanID:%d.", pSponsorObjects[i]->GetAccountName(), pSponsorObjects[i]->GetCharInfo()->m_ClanInfo.GetClanID());

			RouteResponseToListener(pSponsorObjects[i], MC_MATCH_RESPONSE_RESULT, MRESULT_CLAN_CREATED);
		}
	}

	if (IsEnabledObject(pMasterObject))
	{
		RouteResponseToListener(pMasterObject, MC_MATCH_CLAN_RESPONSE_AGREED_CREATE_CLAN, MOK);
	}
}
bool MMatchServer::AddObjectOnMatchLogin(const MUID& uidComm, 
										const MMatchAccountInfo* pSrcAccountInfo,
										const MMatchAccountPenaltyInfo* pSrcAccountPenaltyInfo,
										bool bFreeLoginIP, string strCountryCode3, unsigned long nChecksumPack)
{
	MCommObject* pCommObj = (MCommObject*)m_CommRefCache.GetRef(uidComm);
	if (pCommObj == NULL) return false;

	MUID AllocUID = uidComm;
	int nErrCode = ObjectAdd(uidComm);
	if(nErrCode!=MOK) {
		LOG(LOG_DEBUG, MErrStr(nErrCode) );
	}

	MMatchObject* pObj = GetObject(AllocUID);
	if (pObj == NULL) {
		// Notify Message 필요 -> 로그인 관련 - 해결(Login Fail 메세지 이용)
		// Disconnect(uidComm);
		MCommand* pCmd = CreateCmdMatchResponseLoginFailed(AllocUID, MERR_FAILED_LOGIN_RETRY);
		Post(pCmd);	
		return false;
	}

	pObj->AddCommListener(uidComm);
	pObj->SetObjectType(MOT_PC);

	memcpy(pObj->GetAccountInfo(), pSrcAccountInfo, sizeof(MMatchAccountInfo));
	memcpy(pObj->GetAccountPenaltyInfo(), pSrcAccountPenaltyInfo, sizeof(MMatchAccountPenaltyInfo));
		
	pObj->SetFreeLoginIP(bFreeLoginIP);
	pObj->SetCountryCode3( strCountryCode3 );
	pObj->UpdateTickLastPacketRecved();
	pObj->UpdateLastHShieldMsgRecved();

	if (pCommObj != NULL)
	{
		pObj->SetPeerAddr(pCommObj->GetIP(), pCommObj->GetIPString(), pCommObj->GetPort());
	}
	
	SetClientClockSynchronize(uidComm);

	// 프리미엄 IP를 체크한다.
	if (MGetServerConfig()->CheckPremiumIP())
	{
		if (pCommObj)
		{
			bool bIsPremiumIP = false;
			bool bExistPremiumIPCache = false;
			
			bExistPremiumIPCache = MPremiumIPCache()->CheckPremiumIP(pCommObj->GetIP(), bIsPremiumIP);

			// 만약 캐쉬에 없으면 직접 DB에서 찾도록 한다.
			if (!bExistPremiumIPCache)
			{
				if (m_MatchDBMgr.CheckPremiumIP(pCommObj->GetIPString(), bIsPremiumIP))
				{
					// 결과를 캐쉬에 저장
					MPremiumIPCache()->AddIP(pCommObj->GetIP(), bIsPremiumIP);
				}
				else
				{
					MPremiumIPCache()->OnDBFailed();
				}

			}

			//if (bIsPremiumIP) pObj->GetAccountInfo()->m_nPGrade = MMPG_PREMIUM_IP;
		}		
	}

	if (!PreCheckAddObj(uidComm))
	{
		// 보안 관련 초기화 서버 설정에 문제가 생겼다고 로그인 실패를 리턴한다. //
		MCommand* pCmd = CreateCmdMatchResponseLoginFailed(uidComm, MERR_FAILED_AUTHENTICATION);
		Post(pCmd);	
		return false;
	}



	MCommand* pCmd = CreateCmdMatchResponseLoginOK(uidComm, 
												   AllocUID, 
												   pObj->GetAccountInfo()->m_szUserID,
												   pObj->GetAccountInfo()->m_nUGrade,
                                                   pObj->GetAccountInfo()->m_nPGrade,
												   pObj->GetAccountInfo()->m_nECoins,
//												   pObj->GetAntiHackInfo()->m_szRandomValue,
												   pObj->GetHShieldInfo()->m_pbyGuidReqMsg);
	Post(pCmd);	

	// 접속 로그를 남긴다.
	//m_MatchDBMgr.InsertConnLog(pObj->GetAccountInfo()->m_nAID, pObj->GetIPString(), pObj->GetCountryCode3() );

	// 접속 로그
	MAsyncDBJob_InsertConnLog* pNewJob = new MAsyncDBJob_InsertConnLog(uidComm);
	pNewJob->Input(pObj->GetAccountInfo()->m_nAID, pObj->GetIPString(), pObj->GetCountryCode3() );
	PostAsyncJob(pNewJob);

	// Client DataFile Checksum을 검사한다.
	// 2006.2.20 dubble. filelist checksum으로 변경
	unsigned long nChecksum = nChecksumPack ^ uidComm.High ^ uidComm.Low;
	if( MGetServerConfig()->IsUseFileCrc() && !MMatchAntiHack::CheckClientFileListCRC(nChecksum, pObj->GetUID()) && 
		!MGetServerConfig()->IsDebugLoginIPList(pObj->GetIPString()) )
	{
		LOG(LOG_PROG, "Invalid filelist crc (%u) , UserID(%s)\n ", nChecksum, pObj->GetAccountInfo()->m_szUserID);
//		pObj->SetBadFileCRCDisconnectWaitInfo();
		pObj->DisconnectHacker( MMHT_BADFILECRC);
	}
	/*
	if (nChecksum != GetItemFileChecksum()) {
		LOG(LOG_PROG, "Invalid ZItemChecksum(%u) , UserID(%s) ", nChecksum, pObj->GetAccountInfo()->m_szUserID);
		Disconnect(uidComm);
		return false;
	}
	*/

	pObj->LoginCompleted();

	return true;
}