void MMatchServer::OnAdminRequestSwitchLadderGame(const MUID& uidAdmin, const bool bEnabled) { MMatchObject* pObj = GetObject(uidAdmin); if (!IsEnabledObject(pObj)) return; // 관리자 권한을 가진 사람이 아니면 연결을 끊는다. if (!IsAdminGrade(pObj)) { // DisconnectObject(uidAdmin); return; } MGetServerConfig()->SetEnabledCreateLadderGame(bEnabled); char szMsg[256] = "설정되었습니다."; Announce(pObj, szMsg); }
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::OnMatchLoginFromDBAgent(const MUID& CommUID, const char* szLoginID, const char* szName, int nSex, bool bFreeLoginIP, unsigned long nChecksumPack) { #ifndef LOCALE_NHNUSA MCommObject* pCommObj = (MCommObject*)m_CommRefCache.GetRef(CommUID); if (pCommObj == NULL) return; string strCountryCode3; CheckIsValidIP( CommUID, pCommObj->GetIPString(), strCountryCode3, false ); const char* pUserID = szLoginID; char szPassword[16] = ""; // 패스워드는 없다 char szCertificate[16] = ""; const char* pName = szName; int nAge = 20; bool bCheckPremiumIP = MGetServerConfig()->CheckPremiumIP(); const char* szIP = pCommObj->GetIPString(); DWORD dwIP = pCommObj->GetIP(); // Async DB MAsyncDBJob_GetLoginInfo* pNewJob = new MAsyncDBJob_GetLoginInfo(CommUID); pNewJob->Input(new MMatchAccountInfo, new MMatchAccountPenaltyInfo, pUserID, szPassword, szCertificate, pName, nAge, nSex, bFreeLoginIP, nChecksumPack, bCheckPremiumIP, szIP, dwIP, strCountryCode3); PostAsyncJob(pNewJob); #endif }
bool CCMatchLocale::OnInit() { m_bCheckAntiHackCrack = false; switch (m_iCountry) { case CCC_KOREA: break; case CCC_US: break; case CCC_JAPAN: { // int nGameCode = MGetServerConfig()->GetNJDBAgentGameCode(); // int nServerCode = MGetServerConfig()->GetServerID(); // m_pDBAgentClient = new MNJ_DBAgentClient(nGameCode, nServerCode); // ConnectToDBAgent(); // 일본 넷마블판만 DBAgent에 접속한다. } break; case CCC_BRAZIL: break; case CCC_INDIA: break; } #ifdef _XTRAP // XTrap Crack을 체크한다. if( MGetServerConfig()->IsUseXTrap() ) m_bCheckAntiHackCrack = true; #endif return true; }
void MAsyncDBJob_GetLoginInfo::Run(void* pContext) { _ASSERT(m_pAccountInfo); MMatchDBMgr* pDBMgr = (MMatchDBMgr*)pContext; // 원래 계정은 넷마블에 있으므로 해당 계정이 없으면 새로 생성한다. if (!pDBMgr->GetLoginInfo(m_szUserID, &m_nAID, m_szDBPassword)) { int nGunzSex; // 건즈디비의 성별값은 넷마블 성별값과 반대이다. if (m_nSex == 0) nGunzSex = 1; else nGunzSex = 0; int nCert = 0; if (strlen(m_szCertificate) > 0) { if (m_szCertificate[0] == '1') nCert =1; } pDBMgr->CreateAccount(m_szUserID, m_szUniqueID, nCert, m_szName, m_nAge, nGunzSex); pDBMgr->GetLoginInfo(m_szUserID, &m_nAID, m_szDBPassword); } // 계정 정보를 읽는다. if (!pDBMgr->GetAccountInfo(m_nAID, m_pAccountInfo, MGetServerConfig()->GetServerID())) { SetResult(MASYNC_RESULT_FAILED); return; } // 계정 페널티 정보를 읽는다. - 2010-08-10 홍기주 if( !pDBMgr->GetAccountPenaltyInfo(m_nAID, m_pAccountPenaltyInfo) ) { SetResult(MASYNC_RESULT_FAILED); return; } // 프리미엄 IP를 체크한다. if (m_bCheckPremiumIP) { bool bIsPremiumIP = false; bool bExistPremiumIPCache = false; bExistPremiumIPCache = MPremiumIPCache()->CheckPremiumIP(m_dwIP, bIsPremiumIP); // 만약 캐쉬에 없으면 직접 DB에서 찾도록 한다. if (!bExistPremiumIPCache) { if (pDBMgr->CheckPremiumIP(m_szIP, bIsPremiumIP)) { // 결과를 캐쉬에 저장 MPremiumIPCache()->AddIP(m_dwIP, bIsPremiumIP); } else { MPremiumIPCache()->OnDBFailed(); } } //if (bIsPremiumIP) m_pAccountInfo->m_nPGrade = MMPG_PREMIUM_IP; } SetResult(MASYNC_RESULT_SUCCEED); }
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 */ }
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; }
void MAsyncDBJob_GetCharInfo::Run(void* pContext) { _ASSERT(m_pCharInfo); MMatchDBMgr* pDBMgr = (MMatchDBMgr*)pContext; //int nWaitHourDiff; if (!pDBMgr->GetCharInfoByAID(m_nAID, m_nCharIndex, m_pCharInfo)) { SetResult(MASYNC_RESULT_FAILED); return; } unsigned int nEquipedItemID[MMCIP_END]; unsigned int nEquipedItemCIID[MMCIP_END]; if( !pDBMgr->GetCharEquipmentInfoByAID(m_nAID, m_nCharIndex, nEquipedItemID, nEquipedItemCIID)) { SetResult(MASYNC_RESULT_FAILED); return; } for(int i = 0; i < MMCIP_END; i++) { m_pCharInfo->m_nEquipedItemCIID[i] = nEquipedItemCIID[i]; } #ifdef _DELETE_CLAN // 클랜에 가입된 캐릭터이면 폐쇄요청된 클랜인지 검사를 해줘야 한다. if( 0 != m_pCharInfo->m_ClanInfo.m_nClanID ) { /* // nWaitHourDiff의 값이 0이면 정상 클랜. // 0 이상이면 폐쇄요청이 접수된 클랜이다. // 폐쇄 요청된 클랜을 정상 클랜으로 바꿔주기 위해서는, // Clan테이블의 DeleteDate를 NULL로 셋팅해 줘야 한다. - by SungE. if( UNDEFINE_DELETE_HOUR == nWaitHourDiff ) { // 정상 클랜. } else if( 0 > nWaitHourDiff ) { SetDeleteState( MMCDS_WAIT ); } //else if( MAX_WAIT_CLAN_DELETE_HOUR < nWaitHourDiff ) //{ // // 클랜정보를 DB에서 삭제. // // 이작업은 DB의 Agent server작업으로 일괄 처리히한다. //} else if( 0 <= nWaitHourDiff) { // 아직 DB는 삭제하지 않고, 유저만 일반 유저로 처리함. SetDeleteState( MMCDS_NORMAL ); m_pCharInfo->m_ClanInfo.Clear(); } */ } #endif // 디비에서 아이템 정보를 가져온다. // 이것은 퍼포먼스 문제로 나중에 플레이어가 자기 아이템 보기 할때만 가져와야 할듯 m_pCharInfo->ClearItems(); if (!pDBMgr->GetCharItemInfo(m_pCharInfo)) { SetResult(MASYNC_RESULT_FAILED); return; } #ifdef _QUEST_ITEM if( MSM_TEST == MGetServerConfig()->GetServerMode() ) { m_pCharInfo->m_QuestItemList.Clear(); if( !pDBMgr->GetCharQuestItemInfo(m_pCharInfo) ) { mlog( "MAsyncDBJob_GetCharInfo::Run - 디비에서 퀘스트 아이템 목록을 가져오는데 실패했음.\n" ); SetResult(MASYNC_RESULT_FAILED); return; } } #endif if( !pDBMgr->GetCharBRInfoAll(m_pCharInfo->m_nCID, m_pCharInfo->GetBRInfoMap()) ) { SetResult(MASYNC_RESULT_FAILED); return; } SetResult(MASYNC_RESULT_SUCCEED); }
void MAsyncDBJob_InsertQuestGameLog::Run( void* pContext ) { if( MSM_TEST == MGetServerConfig()->GetServerMode() ) { MMatchDBMgr* pDBMgr = reinterpret_cast< MMatchDBMgr* >( pContext ); int nQGLID; // 우선 퀘스트 게임 로그를 저장함. if( !pDBMgr->InsertQuestGameLog(m_szStageName, m_nScenarioID, m_nMasterCID, m_PlayersCID[0], m_PlayersCID[1], m_PlayersCID[2], m_nTotalRewardQItemCount, m_nElapsedPlayTime, nQGLID) ) { SetResult(MASYNC_RESULT_FAILED); return; } // 유니크 아이템에 관한 데이터는 QUniqueItemLog에 따로 저장을 해줘야 함. int i; int nCID; int nQIID; int nQUItemCount; QItemLogMapIter itQUItem, endQUItem; vector< MQuestPlayerLogInfo* >::iterator itPlayer, endPlayer; itPlayer = m_Player.begin(); endPlayer = m_Player.end(); for( ; itPlayer != endPlayer; ++itPlayer ) { if( (*itPlayer)->GetUniqueItemList().empty() ) continue; // 유니크 아이템을 가지고 있지 않으면 무시. nCID = (*itPlayer)->GetCID(); itQUItem = (*itPlayer)->GetUniqueItemList().begin(); endQUItem = (*itPlayer)->GetUniqueItemList().end(); for( ; itQUItem != endQUItem; ++itQUItem ) { nQIID = itQUItem->first; nQUItemCount = itQUItem->second; for( i = 0; i < nQUItemCount; ++i ) { if( !pDBMgr->InsertQUniqueGameLog(nQGLID, nCID, nQIID) ) { mlog( "MAsyncDBJob_InsertQuestGameLog::Run - 유니크 아이템 로그 저장 실패. CID:%d QIID:%d\n", nCID, nQIID ); SetResult(MASYNC_RESULT_FAILED); } } } // 작업이 끝난 정보는 메모리에서 삭제한다. delete (*itPlayer); } } m_Player.clear(); SetResult(MASYNC_RESULT_SUCCEED); }
bool DBQuestCachingData::DoUpdateDBCharQuestItemInfo() { // 퀘스트 서버인지 먼저 검사. if( MSM_TEST != MGetServerConfig()->GetServerMode() ) return false; // 정상적인 Object인지 검사. if( !IsEnabledObject(m_pObject) ) return false; // 현재 상태가 업데이트 가능한지 검사. if( !IsRequestUpdate() ) { // 다음 업데이트를 검사를 위해서 마지막 업데이트 검사 시간을 저장해 놓음. m_dwLastUpdateTime = timeGetTime(); return false; } MAsyncDBJob_UpdateQuestItemInfo* pAsyncJob = new MAsyncDBJob_UpdateQuestItemInfo(m_pObject->GetUID()); if( 0 == pAsyncJob ) { mlog( "DBQuestCachingData::DoUpdateDBCharQuestItemInfo - QuestItemUpdate async작업 실패.\n" ); return false; } if( !pAsyncJob->Input(m_pObject->GetCharInfo()->m_nCID, m_pObject->GetCharInfo()->m_QuestItemList, m_pObject->GetCharInfo()->m_QMonsterBible) ) { return false; } MMatchServer::GetInstance()->PostAsyncJob( pAsyncJob ); #ifdef _DEBUG { // 업데이트 정보가 정상적으로 되는지 로그를 남김. char szDbgOut[ 1000 ] = {0}; MQuestItemMap::iterator it, end; strcat( szDbgOut, "Quest Item Caching UpdateDB\n" ); strcat( szDbgOut, m_pObject->GetName() ); strcat( szDbgOut, "\n" ); it = m_pObject->GetCharInfo()->m_QuestItemList.begin(); end = m_pObject->GetCharInfo()->m_QuestItemList.end(); for( ; it != end; ++it ) { char tmp[ 100 ] = {0}; sprintf( tmp, "%s : %d\n", it->second->GetDesc()->m_szQuestItemName, it->second->GetCount() ); strcat( szDbgOut, tmp ); } strcat( szDbgOut, "\n" ); MMatchServer::GetInstance()->LOG( MMatchServer::LOG_PROG, szDbgOut ); } #endif // 업데이트가 성공하면 다음 검사를 위해서 다시 설정함. Reset(); return true; }
void MMatchEventFactoryManager::ParseEvent( MXmlElement& chrElement ) { char szAttrName[ 128 ]; char szAttrValue[ 256 ]; DWORD dwEventListID = 0; DWORD dwEventID = 0; string strEventName; string strAnnounce; EVENT_TYPE EventType; DWORD dwElapsedTime = 0; DWORD dwPercent = 0; DWORD dwRate = 0; vector< EventServerType > vServerType; vector< EventGameType > vGameType; SYSTEMTIME Start, End; float fXPBonusRatio = 0.0f; float fBPBonusRatio = 0.0f; vector< EventPartTime > EventPartTimeVec; memset( &Start, 0, sizeof(SYSTEMTIME) ); memset( &End, 0, sizeof(SYSTEMTIME) ); const int nAttrCnt = chrElement.GetAttributeCount(); for( int i = 0; i < nAttrCnt; ++i ) { chrElement.GetAttribute( i, szAttrName, szAttrValue ); if( 0 == stricmp(EL_EVENT_LIST_ID, szAttrName) ) { dwEventListID = static_cast< DWORD >( atoi(szAttrValue) ); ASSERT( 0 < dwEventListID ); continue; } if( 0 == stricmp(EL_EVENTID, szAttrName) ) { dwEventID = static_cast< DWORD >( atol(szAttrValue) ); if( NULL == MMatchEventDescManager::GetInstance().Find(dwEventID) ) { ASSERT( 0 && "Event.xml에 없는 Event ID입니다." ); mlog( "MMatchEventFactoryManager::ParseEvent - Event.xml에 없는 Event ID(%u)입니다.\n", dwEventID ); return; } continue; } if( 0 == stricmp(EL_NAME, szAttrName) ) { strEventName = MGetStringResManager()->GetString( string(szAttrValue) ); continue; } if( 0 == stricmp(EL_EVENTTYPE, szAttrName) ) { EventType = static_cast< EVENT_TYPE >( atoi(szAttrValue) ); continue; } if( 0 == stricmp(EL_ELAPSEDTIME, szAttrName) ) { dwElapsedTime = static_cast< DWORD >( atoi(szAttrValue) ); continue; } if( 0 == stricmp(EL_PERCENT, szAttrName) ) { dwPercent = static_cast< DWORD >( atol(szAttrValue) ); continue; } if( 0 == stricmp(EL_RATE, szAttrName) ) { dwRate = static_cast< DWORD >( atol(szAttrValue) ); continue; } if( 0 == stricmp(EL_ANNOUNCE, szAttrName) ) { strAnnounce = MGetStringResManager()->GetString( string(szAttrValue) ); continue; } if( 0 == stricmp(EL_XPBONUS_RATIO, szAttrName) ) { fXPBonusRatio = static_cast<float>( atoi(szAttrValue) ) / 100.0f; continue; } if( 0 == stricmp(EL_BPBONUS_RATIO, szAttrName) ) { fBPBonusRatio = static_cast<float>( atoi(szAttrValue) ) / 100.0f; continue; } } MXmlElement chrNode; char szTag[ 128 ]; const int nChrNodeCnt = chrElement.GetChildNodeCount(); EventPartTimeVec.clear(); for( int j = 0; j < nChrNodeCnt; ++j ) { chrNode = chrElement.GetChildNode( j ); chrNode.GetTagName( szTag ); if (szTag[0] == '#') continue; if( 0 == stricmp(EL_SERVERTYPE, szTag) ) { ParseServerType( chrNode, vServerType ); continue; } if( 0 == stricmp(EL_GAMETYPE, szTag) ) { ParseGameType( chrNode, vGameType ); continue; } if( 0 == stricmp(EL_STARTTIME, szTag) ) { ParseStartEndTime( chrNode, Start ); continue; } if( 0 == stricmp(EL_ENDTIME, szTag) ) { ParseStartEndTime( chrNode, End ); continue; } if( 0 == stricmp(EL_PART_TIME, szTag) ) { ParseEventPartTime(chrNode, EventPartTimeVec ); continue; } } // check start end time. if( !CheckUsableEventTimeByEndTime(End) ) { #ifdef _DEBUG mlog( "Time out Event(%u:%u.%u.%u.%u~%u.%u.%u.%u)\n", dwEventID, Start.wYear, Start.wMonth, Start.wDay, Start.wHour, End.wYear, End.wMonth, End.wDay, End.wHour ); #endif return; } // check server type. vector< EventServerType >::iterator itSvrTyp, endSvrTyp; bool bUseEvent = false; endSvrTyp = vServerType.end(); for( itSvrTyp = vServerType.begin(); itSvrTyp != endSvrTyp; ++itSvrTyp ) { // 모든 서버에 적용. if( MSM_ALL == itSvrTyp->ServerType ) { bUseEvent = true; continue; } // 현제 서버 타입에만 적용. if( MGetServerConfig()->GetServerMode() == itSvrTyp->ServerType ) { bUseEvent = true; continue; } } ASSERT( (0 < Start.wYear) && (0 < Start.wMonth) && (0 < Start.wDay) && (0 <= Start.wHour) && (0 < End.wYear) && (0 < End.wMonth) && (0 < End.wDay) && (0 <= End.wHour) ); // check game type. if( bUseEvent ) { EventData ed; vector< EventGameType >::iterator itGmTyp, endGmTyp; endGmTyp = vGameType.end(); for( itGmTyp = vGameType.begin(); itGmTyp != endGmTyp; ++itGmTyp ) { // insert event. ed.dwEventListID = dwEventListID; ed.dwEventID = dwEventID; ed.EventType = EventType; ed.dwGameType = itGmTyp->GameType; ed.ServerType = MGetServerConfig()->GetServerMode(); ed.dwElapsedTime = dwElapsedTime; ed.dwPercent = dwPercent; ed.dwRate = dwRate; ed.Start = Start; ed.End = End; ed.strName = strEventName; ed.strAnnounce = strAnnounce; ed.fXPBonusRatio = fXPBonusRatio; ed.fBPBonusRatio = fBPBonusRatio; ed.EventPartTimeVec.swap( EventPartTimeVec ); InsertEvent( ed ); ++m_LoadEventSize; } } }