// QuestChange.cpp : ÄÜ¼Ö ÀÀ¿ë ÇÁ·Î±×·¥¿¡ ´ëÇÑ ÁøÀÔÁ¡À» Á¤ÀÇÇÕ´Ï´Ù. // /* ½ºÅ©¸³Æ® ±¸Á¶ REMOVE Äù½ºÆ®ID CHANGE Äù½ºÆ®ID Äù½ºÆ®ID Äù½ºÆ®ID ´Â 10Áø¼ö ȤÀº 0x·Î ½ÃÀÛÇÏ´Â 16Áø¼öÀÌ´Ù. ÁÖ¼®Àº C½ºÅ¸ÀÏÀÇ ÁÖ¼® // ¸¸ Áö¿øÇÑ´Ù */ #pragma warning(disable:4800) #include "stdafx.h" #include #include #include #include #include #include #include #include #include // Quest Script Command class CProcessQuest : public IDBCharQuestProcess { public: bool LoadScript(const char* szScriptName); private: typedef std::pair QuestChangePair; typedef std::vector QuestRemoveVector; typedef std::vector QuestChangeVector; virtual ConvertResult operator()(RylDBCommand::CCharQuest& charQuest_InOut); QuestRemoveVector m_QuestRemoveVector; QuestChangeVector m_QuestChangeVector; }; template struct match_first { bool operator () (const Data& lhs, const Data& rhs) { return lhs < rhs; } bool operator () (const Pair& lhs, const Pair& rhs) { return lhs.first < rhs.first; } bool operator () (const Data& lhs, const Pair& rhs) { return lhs < rhs.first; } bool operator () (const Pair& lhs, const Data& rhs) { return lhs.first < rhs; } }; void PrintUsage() { printf("usage : QuestChange.exe DBAddress DBName DBAccount DBPassword QuestChangeScriptName \n"); } unsigned short ConvertStringToQuestID(const char* szQuestID) { unsigned short wQuestID = 0; if (0 != szQuestID) { const char* szHexHeader = "0X"; size_t nHexHeaderLen = strlen(szHexHeader); char* szStopPtr = 0; int nBase = (0 == strncmp(szQuestID, szHexHeader, nHexHeaderLen)) ? 16 : 10; wQuestID = static_cast(strtoul(szQuestID, &szStopPtr, nBase)); } return wQuestID; } int _tmain(int argc, _TCHAR* argv[]) { if(6 != argc) { PrintUsage(); return -1; } const char* szProcessQuestScript = argv[5]; CProcessQuest processQuest; if(FAILED(processQuest.LoadScript(szProcessQuestScript))) { printf("%s ½ºÅ©¸³Æ® ·Îµå ½ÇÆÐ", szProcessQuestScript); return -1; } CoInitialize(0); HRESULT hr = S_OK; ATL::CDataSource dataSource; ATL::CSession Session; #define LOG_CONVERT0(str) { ERRLOG0(g_Log, (str)); printf(str "\n"); } #define LOG_CONVERT1(str, arg1) { ERRLOG1(g_Log, (str), (arg1)); printf(str "\n", (arg1)); } #define LOG_CONVERT2(str, arg1, arg2) { ERRLOG2(g_Log, (str), (arg1), (arg2)); printf(str "\n", (arg1), (arg2)); } if(FAILED(hr = CRylDBProcess::ConnectDB(dataSource, argv[1], argv[2], argv[3], argv[4]))) { LOG_CONVERT1("Connect DB failed : hr:0x%08X", hr); } else if(FAILED(hr = Session.Open(dataSource))) { LOG_CONVERT1("Open session failed : hr:0x%08X", hr); } else { CRylDBProcess rylDBProcess(Session); CConsoleCounter consoleCounter(1000); if (!rylDBProcess.CharQuest(processQuest, consoleCounter)) { LOG_CONVERT1("CharQuest process failed : hr:0x%08X", hr); } } INFLOG0(g_Log, "Remove Complete"); Session.Close(); dataSource.Close(); CoUninitialize(); return 0; } bool CProcessQuest::LoadScript(const char* szScriptName) { bool bResult = true; FILE* lpFile = fopen(szScriptName, "rt"); if (0 != lpFile) { const int MAX_BUFFER = 1024; char szBuffer[MAX_BUFFER]; const char* szDelimiter = "\r\n\t: "; int nLine = 0; const char* szComment = "//"; size_t nCommentLen = strlen(szComment); char* szStopPtr = 0; int nBase = 10; while(fgets(szBuffer, MAX_BUFFER - 1, lpFile)) { ++nLine; char* szCommand = strtok(szBuffer, szDelimiter); char* szQuestID = strtok(0, szDelimiter); char* szChangeID = strtok(0, szDelimiter); if (0 != szCommand && 0 != szQuestID) { strupr(szCommand); strupr(szQuestID); unsigned short wQuestID = ConvertStringToQuestID(szQuestID); if (0 != wQuestID && 0 == strcmp(szCommand, "REMOVE")) { m_QuestRemoveVector.push_back(wQuestID); } else if (0 != szChangeID && 0 == strcmp(szCommand, "CHANGE")) { strupr(szChangeID); unsigned short wChangeID = ConvertStringToQuestID(szChangeID); if (0 != wChangeID) { m_QuestChangeVector.push_back( QuestChangePair(wQuestID, wChangeID)); } } } } fclose(lpFile); } else { LOG_CONVERT1("ÆÄÀÏ ¿­±â¿¡ ½ÇÆÐÇß½À´Ï´Ù : %s", szScriptName); bResult = false; } std::sort(m_QuestRemoveVector.begin(), m_QuestRemoveVector.end()); std::sort(m_QuestChangeVector.begin(), m_QuestChangeVector.end()); return bResult; } ConvertResult CProcessQuest::operator() (RylDBCommand::CCharQuest& charQuest_InOut) { unsigned long dwCID = charQuest_InOut.GetCID(); unsigned long dwTotalChangedCount = 0; const QUEST& quest_In = charQuest_InOut.GetQuest(); const HISTORY history_In = charQuest_InOut.GetHistory(); QuestRemoveVector::iterator remove_pos = m_QuestRemoveVector.begin(); QuestRemoveVector::iterator remove_end = m_QuestRemoveVector.end(); QuestChangeVector::iterator change_pos = m_QuestChangeVector.begin(); QuestChangeVector::iterator change_end = m_QuestChangeVector.end(); QuestChangeVector::iterator change_find; if (0 < quest_In.dwSize) { unsigned long dwChangedCount = 0; QUEST quest_Out; memset(&quest_Out, 0, sizeof(QUEST)); const PktQuestDB::ExecutingQuest* lpExecutingQuestPos = reinterpret_cast(quest_In.Data); const PktQuestDB::ExecutingQuest* lpExecutingQuestEnd = reinterpret_cast(quest_In.Data + quest_In.dwSize); PktQuestDB::ExecutingQuest* lpDst = reinterpret_cast(quest_Out.Data); for(; lpExecutingQuestPos < lpExecutingQuestEnd; ++lpExecutingQuestPos) { if (std::binary_search(remove_pos, remove_end, lpExecutingQuestPos->m_wQuestID)) { // Äù½ºÆ®¸¦ º¹»çÇÏÁö ¾Ê´Â´Ù. INFLOG2(g_Log, "CID:%10u / QuestID:0x%04X / ÁøÇàÁßÀÎ Äù½ºÆ®¸¦ Á¦°ÅÇß½À´Ï´Ù", dwCID, lpExecutingQuestPos->m_wQuestID); ++dwChangedCount; } else { change_find = std::lower_bound( m_QuestChangeVector.begin(), m_QuestChangeVector.end(), lpExecutingQuestPos->m_wQuestID, match_first()); if (change_find != change_end && change_find->first == lpExecutingQuestPos->m_wQuestID) { // ÁøÇàÁßÀÎ Äù½ºÆ®ÀÇ ID°¡ º¯°æµÇ¾ú´Ù. *lpDst = *lpExecutingQuestPos; lpDst->m_wQuestID = change_find->second; INFLOG4(g_Log, "CID:%10u / QuestID:0x%04X / Phase:%d / ChangedID:0x%04X / " "ÁøÇàÁßÀÎ Äù½ºÆ®ÀÇ ID¸¦ º¯°æÇß½À´Ï´Ù", dwCID, lpExecutingQuestPos->m_wQuestID, lpExecutingQuestPos->m_cPhase, lpDst->m_wQuestID); ++dwChangedCount; } else { // ¸ñ·Ï¿¡ ¾ø´Â °æ¿ì¿¡¸¸ º¹»çÇÑ´Ù. *lpDst = *lpExecutingQuestPos; } ++lpDst; } } if (0 < dwChangedCount) { quest_Out.dwSize = static_cast( reinterpret_cast(lpDst) - quest_Out.Data); charQuest_InOut.SetQuest(quest_Out); dwTotalChangedCount += dwChangedCount; } } if (0 < history_In.dwSize) { unsigned long dwChangedCount = 0; HISTORY history_Out; memset(&history_Out, 0, sizeof(HISTORY)); const unsigned short* lpHistoryPos = reinterpret_cast(history_In.Data); const unsigned short* lpHistoryEnd = reinterpret_cast(history_In.Data + history_In.dwSize); unsigned short* lpDst = reinterpret_cast(history_Out.Data); for(; lpHistoryPos < lpHistoryEnd; ++lpHistoryPos) { if (std::binary_search(remove_pos, remove_end, *lpHistoryPos)) { // Äù½ºÆ®¸¦ º¹»çÇÏÁö ¾Ê´Â´Ù. INFLOG2(g_Log, "CID:%10u / QuestID:0x%04X / ¼öÇà ¿Ï·áµÈ Äù½ºÆ®¸¦ Á¦°ÅÇß½À´Ï´Ù", dwCID, *lpHistoryPos); ++dwChangedCount; } else { change_find = std::lower_bound( m_QuestChangeVector.begin(), m_QuestChangeVector.end(), *lpHistoryPos, match_first()); if (change_find != change_end && change_find->first == *lpHistoryPos) { // ¼öÇà ¿Ï·áµÈ Äù½ºÆ®ÀÇ ID°¡ º¯°æµÇ¾ú´Ù. ¸ÂÃç¼­ º¯°æÇØÁØ´Ù. *lpDst = change_find->second; INFLOG3(g_Log, "CID:%10u / QuestID:0x%04X / ChangedID:0x%04X / ¼öÇà ¿Ï·áµÈ Äù½ºÆ® ID º¯°æ", dwCID, *lpHistoryPos, *lpDst); ++dwChangedCount; } else { // ¸ñ·Ï¿¡ ¾ø´Â °æ¿ì¿¡¸¸ º¹»çÇÑ´Ù. *lpDst = *lpHistoryPos; } ++lpDst; } } if (0 < dwChangedCount) { history_Out.dwSize = static_cast( reinterpret_cast(lpDst) - history_Out.Data); charQuest_InOut.SetHistory(history_Out); dwTotalChangedCount += dwChangedCount; } } return (0 < dwTotalChangedCount) ? CONVERT_SUCCEEDED : CONVERT_DO_NOT_WRITE; }