Move git root from Client/ to src/ to track all source code: - Client: Game client source (moved to Client/Client/) - Server: Game server source - GameTools: Development tools - CryptoSource: Encryption utilities - database: Database scripts - Script: Game scripts - rylCoder_16.02.2008_src: Legacy coder tools - GMFont, Game: Additional resources 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
319 lines
8.8 KiB
C++
319 lines
8.8 KiB
C++
// ConvertTwoNation.cpp : 콘솔 응용 프로그램에 대한 진입점을 정의합니다.
|
|
//
|
|
|
|
#pragma warning(disable:4800)
|
|
|
|
#include "stdafx.h"
|
|
#include <atldbcli.h>
|
|
#include <sqloledb.h>
|
|
#include <Log/ServerLog.h>
|
|
#include <RylDBLibrary/RylDBCharCommand.h>
|
|
#include <RylDBLibrary/RylDBLibrary.h>
|
|
|
|
#include <Community/FriendList.h>
|
|
#include <Community/BanList.h>
|
|
|
|
#include <set>
|
|
#include <string>
|
|
#include <algorithm>
|
|
#include <ctime>
|
|
#include <hash_map>
|
|
|
|
#include <boost/pool/pool_alloc.hpp>
|
|
|
|
#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<unsigned long, unsigned long,
|
|
stdext::hash_compare<unsigned long, std::less<unsigned long> >,
|
|
boost::fast_pool_allocator<std::pair<unsigned long, unsigned long> > > 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<ATL::CDynamicAccessor,
|
|
ATL::CBulkRowset, ATL::CMultipleResults> 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;
|
|
}
|
|
|