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 ); } }
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() ); }
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, ""); } }
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); } }
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); }
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); }
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; }
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 */ }
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(); */ }
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; }