Files
Client/Server/DBProcess/RylDBLibrary/RylDBLibrary.cpp
LGram16 dd97ddec92 Restructure repository to include all source folders
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>
2025-11-29 20:17:20 +09:00

423 lines
11 KiB
C++

#include "RylDBLibrary.h"
#include "RylDBStoreCommand.h"
#include "RylDBCharCommand.h"
#include <Log/ServerLog.h>
#include <Network/Packet/PacketStruct/ServerInfo.h>
#include <sqloledb.h>
const int MAX_READ_NUM = 100000;
CNoneCounter& CNoneCounter::GetInstance()
{
static CNoneCounter noneCounter;
return noneCounter;
}
bool CConsoleCounter::ShowCounter(const char* szProcessName, int nCount, bool bForceWrite)
{
if(bForceWrite || 0 == (nCount % m_nCounterPerLine))
{
printf("[%s] : %12d\n", szProcessName, nCount);
}
return true;
}
HRESULT CRylDBProcess::ConnectDB(ATL::CDataSource& ds, const char* szDBAddress, const char* szDBName,
const char* szDBAccount, const char* szDBPassword)
{
ATL::CDBPropSet dsPropSet;
dsPropSet.SetGUID(DBPROPSET_DBINIT);
dsPropSet.AddProperty(DBPROP_INIT_DATASOURCE, szDBAddress);
dsPropSet.AddProperty(DBPROP_INIT_CATALOG, szDBName);
dsPropSet.AddProperty(DBPROP_AUTH_USERID, szDBAccount);
dsPropSet.AddProperty(DBPROP_AUTH_PASSWORD, szDBPassword);
// 데이터베이스 오픈
return ds.Open(CLSID_SQLOLEDB, &dsPropSet, 1);
}
template<class CAccessorData, class IDBProcess>
HRESULT EnumerateTable(ATL::CSession& dataSession,
const char* szTableName,
IDBProcess& dbProcess,
IShowCounter& showCounter)
{
ATL::CTable< CAccessor<CAccessorData>, CBulkRowset> data;
CDBPropSet dbPropSet;
dbPropSet.SetGUID(DBPROPSET_ROWSET);
dbPropSet.AddProperty(DBPROP_IRowsetUpdate, true);
HRESULT hr = S_OK;
data.SetRows(MAX_READ_NUM);
if (FAILED(hr = data.Open(dataSession, szTableName, &dbPropSet, 1)))
{
ERRLOG2(g_Log, "hr:0x%08X / %s table open failed", hr, szTableName);
}
else
{
CAccessorData oldData;
bool bUpdate = false;
int nCount = 0;
// 테이블 여는 데 성공했다. 돌면서 처리한다.
while(S_OK == (hr = data.MoveNext()))
{
oldData = data;
data.AdjustSize(false);
switch(dbProcess(data))
{
case CONVERT_FAILED:
data.LogError(RylDBCommand::DBERR_CONVERT_FAILED, hr);
bUpdate = false;
break;
case CONVERT_SUCCEEDED:
bUpdate = (oldData != data);
break;
case CONVERT_DO_NOT_WRITE:
bUpdate = false;
break;
case CONVERT_FORCE_WRITE:
bUpdate = true;
}
data.AdjustSize(true);
if (bUpdate)
{
if (FAILED(hr = data.SetData(1)))
{
data.LogError(RylDBCommand::DBERR_SETDATA_FAILED, hr);
}
else if (FAILED(hr = data.Update()))
{
data.LogError(RylDBCommand::DBERR_UPDATE_FAILED, hr);
}
}
showCounter.ShowCounter(szTableName, ++nCount, false);
data.Init();
}
showCounter.ShowCounter(szTableName, ++nCount, true);
g_Log.Flush();
}
return hr;
}
template<class CAccessorData, class IDBProcess>
HRESULT EnumerateCommand(ATL::CSession& dataSession,
char* szTableName,
char* szQuery,
IDBProcess& dbProcess,
IShowCounter& showCounter)
{
ATL::CCommand<CAccessor<CAccessorData>, CBulkRowset, CMultipleResults> data;
CDBPropSet dbPropSet;
dbPropSet.SetGUID(DBPROPSET_ROWSET);
/*dbPropSet.AddProperty(DBPROP_IRowsetUpdate, true);
dbPropSet.AddProperty(DBPROP_UPDATABILITY, DBPROPVAL_UP_CHANGE);
*/
HRESULT hr = S_OK;
data.SetRows(MAX_READ_NUM);
if (FAILED(hr = data.Open(dataSession, szQuery, &dbPropSet)))
{
ERRLOG2(g_Log, "hr:0x%08X / %s table open failed", hr, szTableName);
}
else
{
CAccessorData oldData;
bool bUpdate = false;
int nCount = 0;
// 테이블 여는 데 성공했다. 돌면서 처리한다.
while(S_OK == (hr = data.MoveNext()))
{
oldData = data;
data.AdjustSize(false);
switch(dbProcess(data))
{
case CONVERT_FAILED:
data.LogError(RylDBCommand::DBERR_CONVERT_FAILED, hr);
bUpdate = false;
break;
case CONVERT_SUCCEEDED:
bUpdate = (oldData != data);
break;
case CONVERT_DO_NOT_WRITE:
bUpdate = false;
break;
case CONVERT_FORCE_WRITE:
bUpdate = true;
}
data.AdjustSize(true);
if (bUpdate)
{
if (FAILED(hr = data.SetData(1)))
{
data.LogError(RylDBCommand::DBERR_SETDATA_FAILED, hr);
}
else if (FAILED(hr = data.Update()))
{
data.LogError(RylDBCommand::DBERR_UPDATE_FAILED, hr);
}
}
showCounter.ShowCounter(szTableName, ++nCount, false);
data.Init();
}
showCounter.ShowCounter(szTableName, ++nCount, true);
g_Log.Flush();
}
return hr;
}
HRESULT CRylDBProcess::CharInfo(IDBCharInfoProcess& charInfoProcess, IShowCounter& showCounter, char* szQuery)
{
if(NULL == szQuery)
{
return EnumerateTable<RylDBCommand::CCharData, IDBCharInfoProcess>(
m_DataSession, "CharInfo", charInfoProcess, showCounter);
}
else
{
return EnumerateCommand<RylDBCommand::CCharData, IDBCharInfoProcess>(
m_DataSession, "CharInfo", szQuery, charInfoProcess, showCounter);
}
}
HRESULT CRylDBProcess::CharSkill(IDBCharSkillProcess& charSkillProcess, IShowCounter& showCounter, char* szQuery)
{
if(NULL == szQuery)
{
return EnumerateTable<RylDBCommand::CSkillData, IDBCharSkillProcess>(
m_DataSession, "CharSkill", charSkillProcess, showCounter);
}
}
HRESULT CRylDBProcess::CharItem(IDBCharItemProcess& charItemProcess, IShowCounter& showCounter, char* szQuery)
{
if(NULL == szQuery)
{
return EnumerateTable<RylDBCommand::CCharItem, IDBCharItemProcess>(
m_DataSession, "CharItem", charItemProcess, showCounter);
}
else
{
return EnumerateCommand<RylDBCommand::CCharItem, IDBCharItemProcess>(
m_DataSession, "CharItem", szQuery, charItemProcess, showCounter);
}
}
HRESULT CRylDBProcess::CharItemEx(IDBCharItemExProcess& charItemExProcess, IShowCounter& showCounter, char* szQuery)
{
if(NULL == szQuery)
{
return EnumerateTable<RylDBCommand::CCharItemEx, IDBCharItemExProcess>(
m_DataSession, "CharItemEx", charItemExProcess, showCounter);
}
else
{
return EnumerateCommand<RylDBCommand::CCharItemEx, IDBCharItemExProcess>(
m_DataSession, "CharItemEx", szQuery, charItemExProcess, showCounter);
}
}
HRESULT CRylDBProcess::CharQuest(IDBCharQuestProcess& charQuestProcess, IShowCounter& showCounter, char* szQuery)
{
if(NULL == szQuery)
{
return EnumerateTable<RylDBCommand::CCharQuest, IDBCharQuestProcess>(
m_DataSession, "Quest", charQuestProcess, showCounter);
}
}
HRESULT CRylDBProcess::Party(IDBPartyProcess& partyProcess, IShowCounter& showCounter, char* szQuery)
{
if(NULL == szQuery)
{
return EnumerateTable<RylDBCommand::CPartyData, IDBPartyProcess>(
m_DataSession, "PartyInfo", partyProcess, showCounter);
}
}
HRESULT CRylDBProcess::Friend(IDBFriendProcess& friendProcess, IShowCounter& showCounter, char* szQuery)
{
if(NULL == szQuery)
{
return EnumerateTable<RylDBCommand::CFriendData, IDBFriendProcess>(
m_DataSession, "Friend", friendProcess, showCounter);
}
}
HRESULT CRylDBProcess::UnifiedStore1(IDBStoreProcess& storeProcess, IShowCounter& showCounter, char* szQuery)
{
if(NULL == szQuery)
{
return EnumerateTable<RylDBCommand::CUnifiedStore1, IDBStoreProcess>(
m_DataSession, "TblUnifiedItemStore1", storeProcess, showCounter);
}
else
{
return EnumerateCommand<RylDBCommand::CUnifiedStore1, IDBStoreProcess>(
m_DataSession, "TblUnifiedItemStore1", szQuery, storeProcess, showCounter);
}
}
HRESULT CRylDBProcess::UnifiedStore2(IDBStoreProcess& storeProcess, IShowCounter& showCounter, char* szQuery)
{
if(NULL == szQuery)
{
return EnumerateTable<RylDBCommand::CUnifiedStore2, IDBStoreProcess>(
m_DataSession, "TblUnifiedItemStore2", storeProcess, showCounter);
}
else
{
return EnumerateCommand<RylDBCommand::CUnifiedStore2, IDBStoreProcess>(
m_DataSession, "TblUnifiedItemStore2", szQuery, storeProcess, showCounter);
}
}
HRESULT CRylDBProcess::UnifiedCharList(IDBUnifiedCharInfoProcess& process, IShowCounter& showCounter, char* szQuery)
{
if(NULL == szQuery)
{
return EnumerateTable<RylDBCommand::CUnifiedCharList, IDBUnifiedCharInfoProcess>(
m_DataSession, "TblUnifiedCharLIst", process, showCounter);
}
}
CDBItemSerialMgr::CDBItemSerialMgr()
: m_dwItemSerial(0LL), m_dwServerID(0)
{
}
CDBItemSerialMgr::~CDBItemSerialMgr()
{
}
bool CDBItemSerialMgr::SetItemSerial(unsigned __int64 dwItemSerial)
{
if(m_dwItemSerial < dwItemSerial)
{
m_dwItemSerial = dwItemSerial;
return true;
}
return false;
}
HRESULT CDBItemSerialMgr::LoadItemSerialDB(ATL::CSession& DBSession, unsigned long dwServerID)
{
m_dwItemSerial = 0LL;
m_dwServerID = dwServerID;
HRESULT hr = S_OK;
const int MAX_QUERY_LEN = 512;
char szQuery[MAX_QUERY_LEN];
_snprintf(szQuery, MAX_QUERY_LEN - 1,
"SELECT Server, Item FROM ItemUID WHERE Server = %d", dwServerID);
ATL::CCommand< CAccessor< RylDBCommand::CReadItemSerial >, CRowset, CMultipleResults > itemCommand;
if (FAILED(hr = itemCommand.Open(DBSession, szQuery)))
{
return hr;
}
if(S_OK != itemCommand.MoveNext())
{
itemCommand.Close();
SERVER_ID serverID;
serverID.dwID = dwServerID;
// 아이템 시리얼 막 커지는 건 버그였음.. 전과 같이 존 / 채널 2byte체제로 간다.
m_dwItemSerial = ((static_cast<unsigned __int64>(serverID.GetZone()) << 56) & 0xFF00000000000000LL) |
((static_cast<unsigned __int64>(serverID.GetChannel()) << 48) & 0x00FF000000000000LL);
ATL::CCommand< CAccessor< RylDBCommand::CUpdateItemSerial> > insertCommand;
insertCommand.SetServerID(dwServerID);
insertCommand.SetItemSerial(m_dwItemSerial);
// 등록되지 않은 서버
if (FAILED(hr = insertCommand.Open(DBSession,
L"INSERT INTO ItemUID (Item, Server) VALUES(?, ?)")))
{
ERRLOG1(g_Log, "ServerID:0x%08X / 아이템 시리얼 얻기 실패 - Insert실패", m_dwServerID);
}
}
else
{
m_dwItemSerial = itemCommand.GetItemSerial();
}
return hr;
}
HRESULT CDBItemSerialMgr::SaveItemSerialDB(ATL::CSession& DBSession, unsigned long dwServerID)
{
HRESULT hr = S_OK;
if(m_dwServerID != dwServerID)
{
ERRLOG2(g_Log, "OldServerID:0x%08X / NewServerID:0x%08X / 아이템 시리얼 저장 실패 : 서버 ID가 다릅니다",
m_dwServerID, dwServerID);
hr = E_FAIL;
}
else
{
ATL::CCommand< CAccessor<RylDBCommand::CUpdateItemSerial> > updateItemSerial;
updateItemSerial.SetServerID(dwServerID);
updateItemSerial.SetItemSerial(m_dwItemSerial);
if (FAILED(hr = updateItemSerial.Open(DBSession,
L"UPDATE ItemUID SET Item=? WHERE Server=?")))
{
ERRLOG2(g_Log, "ServerID:0x%08X / ItemSerial : 0x016I64X / 아이템 시리얼 저장 실패 : DB에 시리얼 저장 실패",
m_dwServerID, m_dwItemSerial);
}
}
return hr;
}
HRESULT CDBItemSerialMgr::ClearAllSerialDB(ATL::CSession& DBSession)
{
ATL::CCommand<> deleteCommand;
return deleteCommand.Open(DBSession, L"DELETE FROM ItemUID");
}