// ConvertTwoNation.cpp : ÄÜ¼Ö ÀÀ¿ë ÇÁ·Î±×·¥¿¡ ´ëÇÑ ÁøÀÔÁ¡À» Á¤ÀÇÇÕ´Ï´Ù. // #pragma warning(disable:4800) #include "stdafx.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #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)); } class CRemoveOtherNation : public IDBFriendProcess { public: typedef stdext::hash_map >, boost::fast_pool_allocator > > CIDRaceMap; CRemoveOtherNation(ATL::CSession& session) : m_Session(session) { } ~CRemoveOtherNation() { } HRESULT Initialize(); virtual ConvertResult operator() (RylDBCommand::CFriendData& friendData); private: ATL::CSession& m_Session; CIDRaceMap m_CIDRaceMap; }; int _tmain(int argc, _TCHAR* argv[]) { // DB¿¡ ¿¬°áÇÑ´Ù. // Å×À̺íÀ» ³¯¸®°í ´Ù½Ã ¸¸µç´Ù. // ·Î±×¸¦ ºÐ¼®Çؼ­ Å×ÀÌºí¿¡ Row¸¦ ³Ö´Â´Ù. // ÇöÀç´Â ¸î¸î Log¸¸ ºÐ¼®Çؼ­ Å×ÀÌºí¿¡ ³Öµµ·Ï ÇÑ´Ù. ³ªÁß¿¡ Â÷Â÷ Ãß°¡ÇÑ´Ù. if (5 != argc) { return false; } CoInitialize(0); HRESULT hr = S_OK; ATL::CDataSource ds; ATL::CSession session; ATL::CDBPropSet dsPropSet; dsPropSet.SetGUID(DBPROPSET_DBINIT); dsPropSet.AddProperty(DBPROP_INIT_DATASOURCE, argv[1]); dsPropSet.AddProperty(DBPROP_INIT_CATALOG, argv[2]); dsPropSet.AddProperty(DBPROP_AUTH_USERID, argv[3]); dsPropSet.AddProperty(DBPROP_AUTH_PASSWORD, argv[4]); // µ¥ÀÌÅͺ£À̽º ¿ÀÇ if (FAILED(hr = ds.Open(CLSID_SQLOLEDB, &dsPropSet, 1))) { LOG_CONVERT1("Connect DB failed : hr:0%08x", hr); } else if (FAILED(hr = session.Open(ds))) { LOG_CONVERT1("Connect Session failed : hr:0x%08x", hr); } else if (FAILED(hr = session.StartTransaction())) { LOG_CONVERT1("Start transaction failed : hr:0x%08x", hr); } else { try { CRylDBProcess dbProcess(session); CConsoleCounter consoleCounter(1000); CRemoveOtherNation remove(session); if (FAILED(hr = remove.Initialize())) { LOG_CONVERT1("Data initialize failed : hr:0x%08x", hr); } else if (FAILED(hr = dbProcess.Friend(remove, consoleCounter))) { LOG_CONVERT1("Friend process failed : hr:0x%08x", hr); } } catch(...) { LOG_CONVERT0("Exception occured! rollback transaction now!"); LOG_CONVERT2("Rollback transaction %s! : hr:0x%08x", FAILED(hr = session.Abort()) ? "failed" : "succeeded", hr); } LOG_CONVERT0("Commit transaction now!"); LOG_CONVERT2("Commit transaction %s! : hr:0x%08x", FAILED(hr = session.Commit()) ? "failed" : "succeeded", hr); } session.Close(); ds.Close(); CoUninitialize(); return 0; } HRESULT CRemoveOtherNation::Initialize() { HRESULT hr = S_OK; ATL::CCommand getCharRace; getCharRace.SetRows(1000000); if (FAILED(hr = getCharRace.Open(m_Session, "SELECT CID, Race FROM dbo.CharInfo"))) { LOG_CONVERT1("Read Race from CharInfo failed : hr:0x%08x", hr); } else { int nCount = 0; DWORD nCID = 0; BYTE nRace = 0; hr = getCharRace.MoveFirst( ); while (SUCCEEDED(hr) && hr != DB_S_ENDOFROWSET) { getCharRace.GetValue(1, &nCID); getCharRace.GetValue(2, &nRace); m_CIDRaceMap.insert(CIDRaceMap::value_type(nCID, nRace)); hr = getCharRace.MoveNext(); if (0 == (++nCount % 1000)) { printf("Read race info : %d", nCount); } } } return hr; } class CRemoveTargetCID { public: CRemoveTargetCID(DWORD* dwCIDList, DWORD& dwMaxCIDNum, CRemoveOtherNation::CIDRaceMap& CIDRaceMap, DWORD dwMyRace) : m_dwCIDList(dwCIDList) , m_dwCIDNum(dwMaxCIDNum) , m_dwMaxCIDNum(dwMaxCIDNum) , m_CIDRaceMap(CIDRaceMap) , m_dwMyRace(dwMyRace) { m_dwCIDNum = 0; } void operator () (CFriendList::Rebind& rebind) { DWORD dwCID = rebind.GetCID(); CRemoveOtherNation::CIDRaceMap::iterator pos = m_CIDRaceMap.find(dwCID); CRemoveOtherNation::CIDRaceMap::iterator end = m_CIDRaceMap.end(); if (pos != end && m_dwMyRace != pos->second) { if (m_dwCIDNum < m_dwMaxCIDNum) { m_dwCIDList[m_dwCIDNum] = dwCID; ++m_dwCIDNum; } else { LOG_CONVERT1("Cannot remove friend (CID:%10d) : buffer full", dwCID); } } } void operator () (CBanList::Rebind& rebind) { DWORD dwCID = rebind.GetCID(); CRemoveOtherNation::CIDRaceMap::iterator pos = m_CIDRaceMap.find(dwCID); CRemoveOtherNation::CIDRaceMap::iterator end = m_CIDRaceMap.end(); if (pos != end && m_dwMyRace != pos->second) { if (m_dwCIDNum < m_dwMaxCIDNum) { m_dwCIDList[m_dwCIDNum] = dwCID; ++m_dwCIDNum; } else { LOG_CONVERT1("Cannot remove ban (CID:%10d) : buffer full", dwCID); } } } private: DWORD* m_dwCIDList; DWORD& m_dwCIDNum; DWORD m_dwMaxCIDNum; DWORD m_dwMyRace; CRemoveOtherNation::CIDRaceMap& m_CIDRaceMap; }; ConvertResult CRemoveOtherNation::operator() (RylDBCommand::CFriendData& friendData) { DWORD dwCID = friendData.GetCID(); CIDRaceMap::iterator pos = m_CIDRaceMap.find(dwCID); CIDRaceMap::iterator end = m_CIDRaceMap.end(); if (pos == end) { LOG_CONVERT1("CID:%10u / Cannot find race", dwCID); } else { DWORD dwMyRace = pos->second; CFriendList friendList(dwCID, 0); FRIEND myfriend = friendData.GetFriend(); if (!friendList.SerializeIn(myfriend.Data, myfriend.Info, myfriend.dwSize, myfriend.dwInfoSize)) { LOG_CONVERT1("CID:%10u / SerializeIn friend failed", dwCID); } else { // °°Àº Á¾Á·ÀÌ ¾Æ´Ñ Ä£±¸¸¦ Á¦°ÅÇÑ´Ù. DWORD dwMaxCID[CFriendList::MAX_FRIENDS_NUM]; DWORD dwMaxCIDNum = CFriendList::MAX_FRIENDS_NUM; friendList.Process(CRemoveTargetCID(dwMaxCID, dwMaxCIDNum, m_CIDRaceMap, dwMyRace)); for (DWORD dwIndex = 0; dwIndex < dwMaxCIDNum; ++dwIndex) { friendList.Remove(dwMaxCID[dwIndex]); } myfriend.dwSize = _FRIEND::MAX_FRIEND_SIZE; myfriend.dwInfoSize = _FRIEND::MAX_FRIENDINFO_SIZE; if (!friendList.SerializeOut(myfriend.Data, myfriend.Info, myfriend.dwSize, myfriend.dwInfoSize)) { LOG_CONVERT1("CID:%10u / SerializeOut friend failed", dwCID); } else { friendData.SetFriend(myfriend); } } CBanList banList(dwCID, 0); BAN myBan = friendData.GetBan(); if (!banList.SerializeIn(myBan.Data, myBan.Info, myBan.dwSize, myBan.dwInfoSize)) { LOG_CONVERT1("CID:%10u / SerializeIn ban failed", dwCID); } else { // °°Àº Á¾Á·ÀÌ ¾Æ´Ñ °ÅºÎ¸¦ Á¦°ÅÇÑ´Ù. DWORD dwMaxCID[CBanList::MAX_BAN_NUM]; DWORD dwMaxCIDNum = CBanList::MAX_BAN_NUM; banList.Process(CRemoveTargetCID(dwMaxCID, dwMaxCIDNum, m_CIDRaceMap, dwMyRace)); for (DWORD dwIndex = 0; dwIndex < dwMaxCIDNum; ++dwIndex) { banList.Remove(dwMaxCID[dwIndex]); } myBan.dwSize = _BAN::MAX_BAN_SIZE; myBan.dwInfoSize = _BAN::MAX_BANINFO_SIZE; if (!banList.SerializeOut(myBan.Data, myBan.Info, myBan.dwSize, myBan.dwInfoSize)) { LOG_CONVERT1("CID:%10u / SerializeOut ban failed", dwCID); } else { friendData.SetBan(myBan); } } } return CONVERT_SUCCEEDED; }