// SkillConvert.cpp : ÄÜ¼Ö ÀÀ¿ë ÇÁ·Î±×·¥¿¡ ´ëÇÑ ÁøÀÔÁ¡À» Á¤ÀÇÇÕ´Ï´Ù. // #include "stdafx.h" #include #include #include #include #include #include #include #include #include using namespace std; const int nHammerID = 0x8406; const int nFirstAidID = 0x8405; class CSkillConvert { public: CSkillConvert() : m_fSrc(NULL), m_fConverted(NULL) { } ~CSkillConvert() { if(NULL != m_fSrc) { fclose(m_fSrc); m_fSrc = NULL; } if(NULL != m_fConverted) { fclose(m_fConverted); m_fConverted = NULL; } } bool Initialize(char* szDBServerName, char* szDBName, char* szDBAccount, char* szDBPass); bool Process(); void Test(const char* szFileName); private: bool ProcessSkill(); bool ProcessSkillBook(); bool ProcessSkillLevel(); // return : ¾÷µ¥ÀÌÆ® ¿©ºÎ - ¾÷µ¥ÀÌÆ®½Ã True, ¾Æ´Ï¸é False static bool ProcessEraseHammerOfLight(unsigned long dwCID, SKILL& Skill); static int ProcessEraseHammerOfLightQuickSlot(unsigned long dwCID, QUICK& Quick); // return : ¾÷µ¥ÀÌÆ®ÇÑ ¾ÆÀÌÅÛ °¹¼ö. static int ProcessSkillBookConvert(unsigned long dwUID, unsigned long dwCID, const char* lpBuffer, int nSize); static bool RecalculateSkill(unsigned long dwCID, SKILL& Skill); static void EraseSkill(SKILL& Skill, unsigned short usErasePos); // return : ¾÷µ¥ÀÌÆ® ¿©ºÎ bool AdjustSkillLevel(SKILL& skill); bool AdjustQSlotSkillLevel(QUICK& quick); CDBComponent m_ReadDB; CDBComponent m_WriteDB; FILE* m_fSrc; FILE* m_fConverted; }; void PrintUsage() { cout << "´ÙÀ½°ú °°ÀÌ ÀÔ·ÂÇϼ¼¿ä : SkillConvert DB¼­¹öÁÖ¼Ò DBÀ̸§ DB°èÁ¤ DBÆÐ½º¿öµå" << endl << " ¶Ç´Â : SkillConvert test testFileName" << endl << endl << " Å×½ºÆ® ÆÄÀÏÀÇ Æ÷¸ËÀº ´ÙÀ½°ú °°Àº Æ÷¸ËÀÔ´Ï´Ù. ¿¢¼¿·Î ÀÛ¼ºÇÑ ÈÄ cvsÆ÷¸ËÀ¸·Î »ÌÀ¸½Ê½Ã¿À" << endl << " CID,SkillNum,SlotNum,Skill_1,Skill_1_LockCount,Skill_1_Level,Skill_2,Skill_2_LockCount,Skill_2_Level,..." << endl; } void LogSkillToFile(FILE* fWriteFile, unsigned long dwCID, SKILL& Skill) { fprintf(fWriteFile, "%d,%d,%d,", dwCID, Skill.wSkillNum, Skill.wSlotNum); for(int nSlot = 0; nSlot < SKILL::MAX_SLOT_NUM; ++nSlot) { if(0 != Skill.SSlot[nSlot].SKILLINFO.wSkill) { fprintf(fWriteFile, "0x%04x,%d,%d,", Skill.SSlot[nSlot].SKILLINFO.wSkill, Skill.SSlot[nSlot].SKILLINFO.cLockCount, Skill.SSlot[nSlot].SKILLINFO.cSkillLevel); } } fprintf(fWriteFile, "\n"); } int _tmain(int argc, _TCHAR* argv[]) { CSkillConvert Convert; if(argc == 5) { if(!Convert.Initialize(argv[1], argv[2], argv[3], argv[4])) { cout << "[DB¿¬°á ½ÇÆÐ]" << endl; return -1; } } else if(argc == 3) { if(0 == strcmp("test", argv[1])) { Convert.Test(argv[2]); } else { PrintUsage(); } return 0; } else { PrintUsage(); return 0; } cout << "[DB ¿¬°á ¼º°ø]" << endl; time_t CurrentTime = time(NULL); DETLOG1(g_Log, "ÇöÀç½Ã°£ : %s", ctime(&CurrentTime)); Convert.Process(); CurrentTime = time(NULL); DETLOG1(g_Log, "Á¾·á½Ã°£ : %s", ctime(&CurrentTime)); cout << "Press Enter Key" << endl; string temp; getline(cin, temp); return 0; } bool CSkillConvert::Initialize(char* szDBServerName, char* szDBName, char* szDBAccount, char* szDBPass) { // DB ¿¬°á if(!m_ReadDB.Connect(szDBServerName, szDBName, szDBAccount, szDBPass)) { cout << "[ReadDB ¿¬°á ½ÇÆÐ]" << endl; return false; } if(!m_WriteDB.Connect(szDBServerName, szDBName, szDBAccount, szDBPass)) { cout << "[WriteDB ¿¬°á ½ÇÆÐ]" << endl; return false; } m_fSrc = fopen("SrcSkillLog.txt", "wt"); if(NULL == m_fSrc) { return false; } m_fConverted = fopen("ConvertedSkillLog.txt", "wt"); if(NULL == m_fConverted) { return false; } return true; } bool CSkillConvert::Process() { //ProcessSkill(); //ProcessSkillBook(); ProcessSkillLevel(); return true; } bool CSkillConvert::ProcessSkill() { char* szQuery = "select UID, Skill from CharSkill"; #pragma pack(1) struct SkillData { unsigned long m_dwCID; SKILL m_Skill; }; #pragma pack() if(!m_ReadDB.ExecuteQuery(szQuery)) { cout << "[Skill Äõ¸® ½ÇÆÐ] : " << m_ReadDB.GetErrorString() << endl; return false; } const int MAX_ROWS = 10240; int nGetRows = 0; SkillData* skillData = new SkillData[MAX_ROWS]; memset(skillData, 0, sizeof(SkillData) * MAX_ROWS); while(m_ReadDB.GetData((void**)skillData, sizeof(SkillData), MAX_ROWS, &nGetRows)) { if(0 == nGetRows) { break; } for(SkillData* lpSkillData = skillData; 0 < nGetRows; --nGetRows, ++lpSkillData) { const unsigned long dwCID = lpSkillData->m_dwCID; SKILL& skill = lpSkillData->m_Skill; SKILL oldSkill = lpSkillData->m_Skill; bool bChanged = false; if(ProcessEraseHammerOfLight(dwCID, skill)) { bChanged = true; } // ¸¶Áö¸·¿¡ ÇØ ÁÙ °Í if(RecalculateSkill(dwCID, skill)) { bChanged = true; } if(bChanged) { LogSkillToFile(m_fSrc, dwCID, oldSkill); LogSkillToFile(m_fConverted, dwCID, skill); DBComponent::GameDB::UpdateCharSkill(m_WriteDB, dwCID, &skill); } } } delete [] skillData; return true; } bool CSkillConvert::ProcessEraseHammerOfLight(unsigned long dwCID, SKILL& Skill) { /* ¸®Åϰª. °íÄ¡´Â µ¥ ¼º°øÇϸé, true. 2. SKILLÀÌ, ÇØ¸Ó ¿Àºê ¶óÀÌÆ®°¡ ÀÖ´ÂÁö º»´Ù. ÇØ¸Ó ¿Àºê ¶óÀÌÆ®°¡ ÀÖ´Â °æ¿ì.. ÆÛ½ºÆ® ¿¡À̵尡 ÀÖ´ÂÁö È®ÀÎÇÑ´Ù ÆÛ½ºÆ® ¿¡À̵尡 ÀÖÀ¸¸é, ÇØ¸Ó ¿Àºê ¶óÀÌÆ®º¸´Ù ·¹º§ÀÌ ³ô°Å³ª °°´Ù - ÇØ¸Ó ¿Àºê ¶óÀÌÆ®¸¦ Áö¿î´Ù. ÇØ¸Ó ¿Àºê ¶óÀÌÆ®º¸´Ù ·¹º§ÀÌ ³·´Ù - ÆÛ½ºÆ®¿¡À̵带 Áö¿ì°í, ÇØ¸Ó¿Àºê¶óÀÌÆ®¸¦ ÆÛ½ºÆ®¿¡À̵å·Î ¹Ù²Û´Ù. ÆÛ½ºÆ® ¿¡À̵尡 ¾øÀ¸¸é, ÇØ¸Ó ¿Àºê ¶óÀÌÆ®¸¦ ÆÛ½ºÆ® ¿¡À̵å·Î ¹Ù²Û´Ù. */ if(20 < Skill.wSlotNum) { ERRLOG2(g_Log, "CID:%10d : ½ºÅ³ ½½·Ô °³¼ö°¡ ÀÌ»óÇÕ´Ï´Ù. %d°³ÀÔ´Ï´Ù.", dwCID, Skill.wSlotNum); Skill.wSlotNum = 20; } for(int nHammerPos = 0; nHammerPos < Skill.wSlotNum; ++nHammerPos) { // ÇØ¸Ó¿Àºê¶óÀÌÆ®°¡ ÀÖ´ÂÁö È®ÀÎ if(nHammerID == Skill.SSlot[nHammerPos].SKILLINFO.wSkill) { // ÆÛ½ºÆ®¿¡À̵尡 ÀÖ´ÂÁö È®ÀÎ for(int nFirstAidPos = 0; nFirstAidPos < Skill.wSlotNum; ++nFirstAidPos) { if(nFirstAidID == Skill.SSlot[nFirstAidPos].SKILLINFO.wSkill) { const int nHammerLevel = Skill.SSlot[nHammerPos].SKILLINFO.cLockCount * CSkillMgr::MAX_SKILL_LEVEL + Skill.SSlot[nHammerPos].SKILLINFO.cSkillLevel; const int nFirstAidLevel = Skill.SSlot[nFirstAidPos].SKILLINFO.cLockCount * CSkillMgr::MAX_SKILL_LEVEL + Skill.SSlot[nFirstAidPos].SKILLINFO.cSkillLevel; if(nHammerLevel <= nFirstAidLevel) { // ÆÛ½ºÆ®¿¡À̵尡 ÇØ¸Ó¿Àºê¶óÀÌÆ®º¸´Ù ·¹º§ÀÌ ³ô°Å³ª °°´Ù. - ÇØ¸Ó¿Àºê¶óÀÌÆ®¸¦ Áö¿î´Ù EraseSkill(Skill, nHammerPos); } else { // ÆÛ½ºÆ®¿¡À̵尡 ÇØ¸Ó¿Àºê¶óÀÌÆ®º¸´Ù ·¹º§ÀÌ ³·´Ù - // ÆÛ½ºÆ®¿¡À̵带 Áö¿ì°í, ÇØ¸Ó¿Àºê¶óÀÌÆ®¸¦ ÆÛ½ºÆ®¿¡À̵å·Î ¹Ù²Û´Ù. Skill.SSlot[nHammerPos].SKILLINFO.wSkill = nFirstAidID; EraseSkill(Skill, nFirstAidPos); } return true; } } // ÆÛ½ºÆ®¿¡À̵尡 ¾ø´Ù.. -> ÇØ¸Ó ¿Àºê ¶óÀÌÆ®¸¦ ÆÛ½ºÆ®¿¡À̵å·Î ¹Ù²Û´Ù. Skill.SSlot[nHammerPos].SKILLINFO.wSkill = nFirstAidID; return true; } } return false; } void CSkillConvert::EraseSkill(SKILL& Skill, unsigned short usErasePos) { if(usErasePos < Skill.wSlotNum) { const int nEraseSkillLevel = Skill.SSlot[usErasePos].SKILLINFO.cLockCount * CSkillMgr::MAX_SKILL_LEVEL + Skill.SSlot[usErasePos].SKILLINFO.cSkillLevel; int nEraseCount = usErasePos; for (; nEraseCount < Skill.wSlotNum - 1; ++nEraseCount) { Skill.SSlot[nEraseCount] = Skill.SSlot[nEraseCount + 1]; } Skill.SSlot[nEraseCount].SKILLINFO.wSkill = 0; Skill.SSlot[nEraseCount].SKILLINFO.cLockCount = 0; Skill.SSlot[nEraseCount].SKILLINFO.cSkillLevel = 0; Skill.wSkillNum -= nEraseSkillLevel; --Skill.wSlotNum; } } bool CSkillConvert::RecalculateSkill(unsigned long dwCID, SKILL& Skill) { unsigned short usOldSkillNum = Skill.wSkillNum; unsigned short usOldSlotNum = Skill.wSlotNum; unsigned short usNewSkillNum = 0; unsigned short usNewSlotNum = 0; for(int nCount = 0; nCount < SKILL::MAX_SLOT_NUM; ++nCount) { if(0 == Skill.SSlot[nCount].SKILLINFO.wSkill) { for(; nCount < SKILL::MAX_SLOT_NUM; ++nCount) { Skill.SSlot[nCount].SKILLINFO.wSkill = 0; Skill.SSlot[nCount].SKILLINFO.cLockCount = 0; Skill.SSlot[nCount].SKILLINFO.cSkillLevel = 0; } break; } else { usNewSkillNum += Skill.SSlot[nCount].SKILLINFO.cLockCount * (CSkillMgr::MAX_SKILL_LEVEL - 1) + Skill.SSlot[nCount].SKILLINFO.cSkillLevel; ++usNewSlotNum; } } if(usNewSkillNum != usOldSkillNum || usNewSlotNum != usOldSlotNum) { Skill.wSkillNum = usNewSkillNum; Skill.wSlotNum = usNewSlotNum; return true; } return false; } bool CSkillConvert::ProcessSkillBook() { char Query[MAX_PATH] = ""; int Rows = 0; STORE Store1 = {0,}; STORE Store2 = {0,}; EQUIP EquipData = {0,}; INVEN InvenData = {0,}; EXTRA ExtraData = {0,}; EXCHANGE Exchange = {0,}; typedef std::list UIDList; UIDList m_UIDList; DWORD UIDs[CDBSingleObject::MaxRowNum]; sprintf(Query, "select UID from UserInfo"); for(int StartRows = 0;; StartRows += Rows) { memset(UIDs, 0, sizeof(DWORD) * CDBSingleObject::MaxRowNum); if(!m_ReadDB.Select(Query, (void**)&UIDs, sizeof(DWORD), StartRows, CDBSingleObject::MaxRowNum, &Rows)) { ERRLOG0(g_Log, "UID ¾ò±â ½ÇÆÐ"); return false; } for(int Count = 0; Count < Rows; ++Count) { m_UIDList.push_back(UIDs[Count]); } if(Rows != CDBSingleObject::MaxRowNum) break; } DETLOG1(g_Log, "¸®½ºÆ® À¯Àú ¼ýÀÚ : %d", m_UIDList.size()); DWORD UserID = 0; USER_INFO UserInfo = {0,}; DWORD CharID[3] = {0,}; SKILL Skill; SKILL oldSkill; QUICK Quick; int nCurrentCount = 0; int nTotalCount = m_UIDList.size(); for(UIDList::iterator itr = m_UIDList.begin(); itr != m_UIDList.end(); ++itr) { UserID = *itr; memset(&UserInfo, 0, sizeof(USER_INFO)); memset(&CharID, 0, sizeof(DWORD) * 3); if(!DBComponent::GameDB::GetUserInfo(m_ReadDB, UserID, &UserInfo)) continue; CharID[0] = UserInfo.Char1; CharID[1] = UserInfo.Char2; CharID[2] = UserInfo.Char3; memset(&Store1, 0, sizeof(STORE)); memset(&Store2, 0, sizeof(STORE)); for(int Count = 0; Count < 3; ++Count) { if(0 == CharID[Count]) continue; memset(&EquipData, 0, sizeof(EQUIP)); memset(&InvenData, 0, sizeof(INVEN)); memset(&ExtraData, 0, sizeof(EXTRA)); memset(&Exchange, 0, sizeof(EXCHANGE)); // Àåºñ if(!DBComponent::GameDB::GetEquip(m_ReadDB, CharID[Count], &EquipData)) { ERRLOG2(g_Log, "Àåºñ ÀÐ±â ½ÇÆÐ UID: %d CID: %d", UserID, CharID[Count]); } else if(0 < ProcessSkillBookConvert(UserID, CharID[Count], EquipData.Data, EquipData.dwSize)) { if(!DBComponent::GameDB::UpdateEquip(m_WriteDB, CharID[Count], &EquipData)) { ERRLOG2(g_Log, "Àåºñ ¾²±â ½ÇÆÐ UID: %d CID: %d", UserID, CharID[Count]); } } // Àκ¥ if(!DBComponent::GameDB::GetInven(m_ReadDB, CharID[Count], &InvenData)) { ERRLOG2(g_Log, "Àκ¥ ÀÐ±â ½ÇÆÐ UID: %d CID: %d", UserID, CharID[Count]); } else if(0 < ProcessSkillBookConvert(UserID, CharID[Count], InvenData.Data, InvenData.dwSize)) { if(!DBComponent::GameDB::UpdateInven(m_WriteDB, CharID[Count], &InvenData)) { ERRLOG2(g_Log, "Àκ¥ ¾²±â ½ÇÆÐ UID: %d CID: %d", UserID, CharID[Count]); } } // ¿©ºÐ if(!DBComponent::GameDB::GetExtra(m_ReadDB, CharID[Count], &ExtraData)) { ERRLOG2(g_Log, "¿©ºÐ ÀÐ±â ½ÇÆÐ UID: %d CID: %d", UserID, CharID[Count]); } else if(0 < ProcessSkillBookConvert(UserID, CharID[Count], ExtraData.Data, ExtraData.dwSize)) { if(!DBComponent::GameDB::UpdateExtra(m_WriteDB, CharID[Count], &ExtraData)) { ERRLOG2(g_Log, "¿©ºÐ ¾²±â ½ÇÆÐ UID: %d CID: %d", UserID, CharID[Count]); } } // ±³È¯ if(!DBComponent::GameDB::GetExchange(m_ReadDB, CharID[Count], &Exchange)) { ERRLOG2(g_Log, "±³È¯ ÀÐ±â ½ÇÆÐ UID: %d CID: %d", UserID, CharID[Count]); } else if(0 < ProcessSkillBookConvert(UserID, CharID[Count], Exchange.Data, Exchange.dwSize)) { if(!DBComponent::GameDB::UpdateExchange(m_WriteDB, CharID[Count], &Exchange)) { ERRLOG2(g_Log, "±³È¯ ¾²±â ½ÇÆÐ UID: %d CID: %d", UserID, CharID[Count]); } } // Äü½½·Ô if(!DBComponent::GameDB::GetQuick(m_ReadDB, CharID[Count], &Quick)) { ERRLOG2(g_Log, "Äü½½·Ô ÀÐ±â ½ÇÆÐ UID:%d, CID:%d", CharID[Count], UserID); } else { if(0 < ProcessEraseHammerOfLightQuickSlot(CharID[Count], Quick)) { if(!DBComponent::GameDB::UpdateQuick(m_WriteDB, CharID[Count], &Quick)) { ERRLOG2(g_Log, "Äü½½·Ô ¾²±â ½ÇÆÐ UID:%d, CID:%d", CharID[Count], UserID); } } } // ½ºÅ³ if(!DBComponent::GameDB::GetCharSkill(m_ReadDB, CharID[Count], &Skill)) { ERRLOG2(g_Log, "½ºÅ³ ÀÐ±â ½ÇÆÐ UID:%d, CID:%d", CharID[Count], UserID); } else { oldSkill = Skill; bool bChanged = false; if(ProcessEraseHammerOfLight(CharID[Count], Skill)) { bChanged = true; } // ¸¶Áö¸·¿¡ ÇØ ÁÙ °Í if(RecalculateSkill(CharID[Count], Skill)) { bChanged = true; } if(bChanged) { LogSkillToFile(m_fSrc, CharID[Count], oldSkill); LogSkillToFile(m_fConverted, CharID[Count], Skill); if(!DBComponent::GameDB::UpdateCharSkill(m_WriteDB, CharID[Count], &Skill)) { ERRLOG2(g_Log, "½ºÅ³ ¾²±â ½ÇÆÐ UID:%d, CID:%d", CharID[Count], UserID); } } } } // â°í1 if(!DBComponent::GameDB::GetItemStore1(m_ReadDB, UserID, &Store1)) { ERRLOG1(g_Log, "â°í1 ÀÐ±â ½ÇÆÐ UID: %d", UserID); } else if(0 < ProcessSkillBookConvert(UserID, 0, Store1.Data, Store1.dwSize)) { if(!DBComponent::GameDB::UpdateItemStore1(m_WriteDB, UserID, &Store1)) { ERRLOG1(g_Log, "â°í1 ¾²±â ½ÇÆÐ UID: %d", UserID); } } // â°í 2 if(!DBComponent::GameDB::GetItemStore2(m_ReadDB, UserID, &Store2)) { ERRLOG1(g_Log, "â°í2 ÀÐ±â ½ÇÆÐ UID: %d", UserID); } else if(0 < ProcessSkillBookConvert(UserID, 0, Store2.Data, Store2.dwSize)) { if(!DBComponent::GameDB::UpdateItemStore2(m_WriteDB, UserID, &Store2)) { ERRLOG1(g_Log, "â°í2 ¾²±â ½ÇÆÐ UID: %d", UserID); } } cout << "."; if(0 != (nCurrentCount % 10000)) { cout << endl << nCurrentCount << "/" << nTotalCount << endl; } } return true; } int CSkillConvert::ProcessSkillBookConvert(unsigned long dwUID, unsigned long dwCID, const char* lpBuffer, int nSize) { const char* lpItemBuff = lpBuffer; int nItemSize = nSize; int nConvertNum = 0; int nLoopCount = 0; while(nItemSize > 0) { Item::ItemData* lpItem = (Item::ItemData*)lpItemBuff; // --------------------------------------------------------------------------------------- // ÇØ¸Ó¿Àºê¶óÀÌÆ® °è¿­ ½ºÅ³ºÏÀ» ÆÛ½ºÆ®¿¡ÀÌµå °è¿­ ½ºÅ³ºÏÀ¸·Î ¹Ù²ß´Ï´Ù. switch(lpItem->m_usProtoTypeID) { case 3558: lpItem->m_usProtoTypeID = 3553; ++nConvertNum; break; case 3559: lpItem->m_usProtoTypeID = 3554; ++nConvertNum; break; case 3560: lpItem->m_usProtoTypeID = 3555; ++nConvertNum; break; case 3561: lpItem->m_usProtoTypeID = 3556; ++nConvertNum; break; case 3562: lpItem->m_usProtoTypeID = 3557; ++nConvertNum; break; } // --------------------------------------------------------------------------------------- // ´ÙÀ½ ¾ÆÀÌÅÛÀ» ÁøÇàÇÕ´Ï´Ù. lpItemBuff += lpItem->m_cItemSize; nItemSize -= lpItem->m_cItemSize; ++nLoopCount; if(10000 < ++nLoopCount) { // ¹º°¡ ÀÌ»óÇÏ´Ù. breakÇÑ´Ù. SERLOG2(g_Log, "UID:%u/CID:%u/ ÀÌ»óÇÑ ¾ÆÀÌÅÛÀ» Áö´Ï°í ÀÖ½À´Ï´Ù. È®ÀÎÇØ ÁÖ¼¼¿ä", dwUID, dwCID); return -1; } } return nConvertNum; } int CSkillConvert::ProcessEraseHammerOfLightQuickSlot(unsigned long dwCID, QUICK& Quick) { int nErased = 0; for(int nCount = 0; nCount < QUICK::MAX_QUICK_NUM; ++nCount) { if(Quick.Slots[nCount].nType == QUICKSLOT::SKILL && (Quick.Slots[nCount].wID == nHammerID || Quick.Slots[nCount].wID == nFirstAidID)) { Quick.Slots[nCount].wID = 0; Quick.Slots[nCount].nType = QUICKSLOT::NONE; Quick.Slots[nCount].nSkillLevel = 0; Quick.Slots[nCount].nSkillLockCount = 0; ++nErased; } } return nErased; } void CSkillConvert::Test(const char* szFileName) { const char* szDelimit = ","; unsigned long dwCID = 0; SKILL Skill; FILE* fReadFile = fopen(szFileName, "rt"); if(NULL != fReadFile) { char szWriteFile[MAX_PATH]; _snprintf(szWriteFile, MAX_PATH, "Result%s", szFileName); szWriteFile[MAX_PATH - 1] = 0; FILE* fWriteFile = fopen(szWriteFile, "wt"); if(NULL != fWriteFile) { const int MAX_DATA_LEN = 4096; char szData[MAX_DATA_LEN]; while(fgets(szData, MAX_DATA_LEN, fReadFile)) { memset(&Skill, 0, sizeof(SKILL)); char* szBuffer = strtok(szData, szDelimit); if(NULL == szBuffer) { break; } dwCID = atoi(szBuffer); szBuffer = strtok(NULL, szDelimit); if(NULL == szBuffer) { break; } Skill.wSkillNum = atoi(szBuffer); szBuffer = strtok(NULL, szDelimit); if(NULL == szBuffer) { break; } Skill.wSlotNum = atoi(szBuffer); szBuffer = strtok(NULL, szDelimit); int nSlot = 0; while(NULL != szBuffer && nSlot < SKILL::MAX_SLOT_NUM) { Skill.SSlot[nSlot].SKILLINFO.wSkill = Math::Convert::Atos(szBuffer); // ½ºÅ³ ID szBuffer = strtok(NULL, szDelimit); if(NULL == szBuffer) { break; } Skill.SSlot[nSlot].SKILLINFO.cLockCount = Math::Convert::Atoc(szBuffer); szBuffer = strtok(NULL, szDelimit); if(NULL == szBuffer) { break; } Skill.SSlot[nSlot].SKILLINFO.cSkillLevel = Math::Convert::Atoc(szBuffer); ++nSlot; szBuffer = strtok(NULL, szDelimit); } ProcessEraseHammerOfLight(dwCID, Skill); RecalculateSkill(dwCID, Skill); LogSkillToFile(fWriteFile, dwCID, Skill); } fclose(fWriteFile); } fclose(fReadFile); } } bool CSkillConvert::ProcessSkillLevel() { char* szQuery = "select UID, Skill from CharSkill"; #pragma pack(1) struct SkillData { unsigned long m_dwCID; SKILL m_Skill; }; #pragma pack() if(!m_ReadDB.ExecuteQuery(szQuery)) { cout << "[Skill Äõ¸® ½ÇÆÐ] : " << m_ReadDB.GetErrorString() << endl; return false; } const int MAX_ROWS = 10240; int nGetRows = 0; SkillData* skillData = new SkillData[MAX_ROWS]; memset(skillData, 0, sizeof(SkillData) * MAX_ROWS); while(m_ReadDB.GetData((void**)skillData, sizeof(SkillData), MAX_ROWS, &nGetRows)) { if(0 == nGetRows) { break; } for(SkillData* lpSkillData = skillData; 0 < nGetRows; --nGetRows, ++lpSkillData) { const unsigned long dwCID = lpSkillData->m_dwCID; SKILL& skill = lpSkillData->m_Skill; SKILL oldSkill = lpSkillData->m_Skill; bool bChanged = false; if(AdjustSkillLevel(skill)) { bChanged = true; } // ½ºÅ³ ·¹º§À» Á¶Á¤ÇÑ´Ù. if(bChanged) { LogSkillToFile(m_fSrc, dwCID, oldSkill); LogSkillToFile(m_fConverted, dwCID, skill); DBComponent::GameDB::UpdateCharSkill(m_WriteDB, dwCID, &skill); } } } delete [] skillData; szQuery = "select UID, Quick from CharItem"; #pragma pack(1) struct QSlotData { unsigned long m_dwCID; QUICK m_Quick; }; #pragma pack() if(!m_ReadDB.ExecuteQuery(szQuery)) { cout << "[Quick Äõ¸® ½ÇÆÐ] : " << m_ReadDB.GetErrorString() << endl; return false; } nGetRows = 0; QSlotData* qslotdata = new QSlotData[MAX_ROWS]; memset(qslotdata, 0, sizeof(QSlotData) * MAX_ROWS); while(m_ReadDB.GetData((void**)qslotdata, sizeof(QSlotData), MAX_ROWS, &nGetRows)) { if(0 == nGetRows) { break; } for(QSlotData* lpQSlotData = qslotdata; 0 < nGetRows; --nGetRows, ++lpQSlotData) { const unsigned long dwCID = lpQSlotData->m_dwCID; QUICK& quick = lpQSlotData->m_Quick; QUICK oldquick = lpQSlotData->m_Quick; bool bChanged = false; if(AdjustQSlotSkillLevel(quick)) { bChanged = true; } // ½ºÅ³ ·¹º§À» Á¶Á¤ÇÑ´Ù. if(bChanged) { DBComponent::GameDB::UpdateQuick(m_WriteDB, dwCID, &quick); } } } delete [] qslotdata; return true; } bool CSkillConvert::AdjustSkillLevel(SKILL& skill) { int nChangedCount = 0; for(int nCount = 0; nCount < SKILL::MAX_SLOT_NUM; ++nCount) { if(6 == skill.SSlot[nCount].SKILLINFO.cSkillLevel) { if(skill.SSlot[nCount].SKILLINFO.cLockCount < 3) { ++skill.SSlot[nCount].SKILLINFO.cLockCount; skill.SSlot[nCount].SKILLINFO.cSkillLevel = 0; ++nChangedCount; } else { skill.SSlot[nCount].SKILLINFO.cLockCount = 3; skill.SSlot[nCount].SKILLINFO.cSkillLevel = 6; ++nChangedCount; } } } return (0 < nChangedCount); } bool CSkillConvert::AdjustQSlotSkillLevel(QUICK& quick) { int nChangedCount = 0; for(int nCount = 0; nCount < QUICK::MAX_QUICK_NUM; ++nCount) { if(QUICKSLOT::SKILL == quick.Slots[nCount].nType && 6 == quick.Slots[nCount].nSkillLevel) { if(quick.Slots[nCount].nSkillLockCount < 3) { ++quick.Slots[nCount].nSkillLockCount; quick.Slots[nCount].nSkillLevel = 0; ++nChangedCount; } else { quick.Slots[nCount].nSkillLockCount = 3; quick.Slots[nCount].nSkillLevel = 6; ++nChangedCount; } } } return (0 < nChangedCount); }