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>
663 lines
20 KiB
C++
663 lines
20 KiB
C++
// NewItemMapMaker.cpp : 콘솔 응용 프로그램에 대한 진입점을 정의합니다.
|
|
//
|
|
|
|
#include <BaseLibrary/Log/ServerLog.h>
|
|
#include <BaseLibrary/Utility/Math/Math.h>
|
|
#include <RylServerLibrary/DB/DBComponent.h>
|
|
|
|
#include <RylGameLibrary/Item/ItemMgr.h>
|
|
#include <RylGameLibrary/Item/Item.h>
|
|
#include <RylGameLibrary/Item/Container/ContainerConstant.h>
|
|
#include <RylGameLibrary/Item/Container/ItemContainer.h>
|
|
|
|
#include <Network/Packet/PacketStruct/UnifiedCharPacket.h>
|
|
|
|
#include <list>
|
|
#include <map>
|
|
#include <string>
|
|
#include <ctime>
|
|
#include <fstream>
|
|
#include <iostream>
|
|
|
|
using namespace std;
|
|
|
|
// 함수
|
|
const char* szItemMapLog = "ItemMapLog.Log";
|
|
const char* szScriptFileName = "ItemScript.txt";
|
|
|
|
|
|
#include <GameGuardLib/ggsrv.h>
|
|
|
|
// edith 2009.08.11 게임가드 2.5 업그레이드
|
|
GGAUTHS_API void NpLog(int mode, char* msg)
|
|
{
|
|
}
|
|
|
|
GGAUTHS_API void GGAuthUpdateCallback(PGG_UPREPORT report)
|
|
{
|
|
}
|
|
|
|
|
|
class CMakeItemMap
|
|
{
|
|
public:
|
|
|
|
CMakeItemMap()
|
|
: m_dwUserNum(0),
|
|
m_eAgentServerType(UnifiedConst::ROW)
|
|
{
|
|
|
|
}
|
|
|
|
bool Initialize(const char* szDBServerName, const char* szDBName,
|
|
const char* szDBAccount, const char* szDBPass, UnifiedConst::AgentServerType agentServerType);
|
|
|
|
bool Process();
|
|
|
|
protected:
|
|
|
|
enum
|
|
{
|
|
MAX_TABLE_NAME = 256,
|
|
MAX_QUERY_LENGTH = 8192
|
|
};
|
|
|
|
bool CreateItemMapTable();
|
|
bool ConstructUIDCIDMap();
|
|
bool ProcessStore();
|
|
bool ProcessCharacterItems();
|
|
bool LogItemInfoToDB(unsigned long dwUID, unsigned long dwCID, Item::CItem* lpItem);
|
|
|
|
typedef map<unsigned long, unsigned long> CIDUIDMap; // Key = CID, Value = UID
|
|
|
|
CDBComponent m_ReadDB;
|
|
CDBComponent m_WriteDB;
|
|
|
|
CIDUIDMap m_CIDUIDMap;
|
|
|
|
unsigned long m_dwUserNum;
|
|
|
|
char m_szTableName[MAX_TABLE_NAME];
|
|
char m_szQuery[MAX_QUERY_LENGTH];
|
|
|
|
UnifiedConst::AgentServerType m_eAgentServerType;
|
|
};
|
|
|
|
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
CMakeItemMap Make;
|
|
|
|
if (argc != 6)
|
|
{
|
|
cout << "Usage : NewItemMapMaker.exe DB서버주소 DB이름 DB계정 DB패스워드 "
|
|
"서버타입(ROW:22/Part2통합(한국):23/Part2통합(중국):24)" << endl;
|
|
return 0;
|
|
}
|
|
|
|
UnifiedConst::AgentServerType eAgentServerType =
|
|
static_cast<UnifiedConst::AgentServerType>(atoi(argv[5]));
|
|
|
|
switch(eAgentServerType)
|
|
{
|
|
case UnifiedConst::ROW:
|
|
case UnifiedConst::Part2Unified:
|
|
case UnifiedConst::Part2Selectable:
|
|
|
|
break;
|
|
|
|
default:
|
|
cout << "[알 수 없는 서버타입]" << endl;
|
|
return -1;
|
|
}
|
|
|
|
if (!Make.Initialize(argv[1], argv[2], argv[3], argv[4], eAgentServerType))
|
|
{
|
|
cout << "[DB 연결 실패]" << endl;
|
|
return -1;
|
|
}
|
|
|
|
cout << "[DB 연결 성공]" << endl;
|
|
|
|
time_t CurrentTime = time(NULL);
|
|
DETLOG1(g_Log, "현재시간 : %s", ctime(&CurrentTime));
|
|
|
|
// 스크립트 읽기
|
|
if (!Item::CItemMgr::GetInstance().LoadItemProtoType(szScriptFileName))
|
|
{
|
|
cout << "[스크립트 로드 실패]" << endl;
|
|
return -1;
|
|
}
|
|
|
|
cout << "[스크립트 로드 성공]" << endl;
|
|
|
|
Make.Process();
|
|
|
|
CurrentTime = time(NULL);
|
|
DETLOG1(g_Log, "종료시간 : %s", ctime(&CurrentTime));
|
|
|
|
cout << "Press Enter Key" << endl;
|
|
|
|
string temp;
|
|
getline(cin, temp);
|
|
return 0;
|
|
}
|
|
|
|
|
|
bool CMakeItemMap::Initialize(const char* szDBServerName,
|
|
const char* szDBName,
|
|
const char* szDBAccount,
|
|
const char* szDBPass,
|
|
UnifiedConst::AgentServerType eAgentServerType)
|
|
{
|
|
// 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_eAgentServerType = eAgentServerType;
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CMakeItemMap::Process()
|
|
{
|
|
if(CreateItemMapTable() && ConstructUIDCIDMap())
|
|
{
|
|
if(ProcessStore())
|
|
{
|
|
return ProcessCharacterItems();
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool CMakeItemMap::CreateItemMapTable()
|
|
{
|
|
SYSTEMTIME sysTime;
|
|
GetLocalTime(&sysTime);
|
|
|
|
_snprintf(m_szTableName, MAX_TABLE_NAME, "ItemMap%04d%02d%02d%02d%02d%02d",
|
|
sysTime.wYear, sysTime.wMonth, sysTime.wDay,
|
|
sysTime.wHour, sysTime.wMinute, sysTime.wSecond);
|
|
|
|
int nResult = _snprintf(m_szQuery, MAX_QUERY_LENGTH,
|
|
|
|
"CREATE TABLE %s ("
|
|
"ITEM_SERIAL BIGINT NULL DEFAULT(0),"
|
|
"OWNER_UID INT NULL DEFAULT(0),"
|
|
"OWNER_CID INT NULL DEFAULT(0),"
|
|
"PROTOTYPE_ID SMALLINT NULL DEFAULT(0),"
|
|
"RUNE_SOCKET SMALLINT NULL DEFAULT(0),"
|
|
"UPGRADE_LEVEL TINYINT NULL DEFAULT(0),"
|
|
"NUM_OR_DURABILITY TINYINT NULL DEFAULT(0),"
|
|
"MAX_NUM_OR_DURABILITY TINYINT NULL DEFAULT(0),"
|
|
"ITEM_GRADE TINYINT NULL DEFAULT(0),"
|
|
"ITEM_GRADE_PLUS TINYINT NULL DEFAULT(0),"
|
|
"MAX_SOCKET_NUM TINYINT NULL DEFAULT(0),"
|
|
"SOCKET_01 TINYINT NULL DEFAULT(0),"
|
|
"SOCKET_02 TINYINT NULL DEFAULT(0),"
|
|
"SOCKET_03 TINYINT NULL DEFAULT(0),"
|
|
"SOCKET_04 TINYINT NULL DEFAULT(0),"
|
|
"SOCKET_05 TINYINT NULL DEFAULT(0),"
|
|
"SOCKET_06 TINYINT NULL DEFAULT(0),"
|
|
"SOCKET_07 TINYINT NULL DEFAULT(0),"
|
|
"SOCKET_08 TINYINT NULL DEFAULT(0),"
|
|
"ATT_MIN_DAMAGE SMALLINT NULL DEFAULT(0),"
|
|
"ATT_MAX_DAMAGE SMALLINT NULL DEFAULT(0),"
|
|
"ATT_ARMOUR SMALLINT NULL DEFAULT(0),"
|
|
"ATT_HIT_RATE SMALLINT NULL DEFAULT(0),"
|
|
"ATT_EVADE SMALLINT NULL DEFAULT(0),"
|
|
"ATT_MAX_HP SMALLINT NULL DEFAULT(0),"
|
|
"ATT_HP_REGEN SMALLINT NULL DEFAULT(0),"
|
|
"ATT_MAX_MP SMALLINT NULL DEFAULT(0),"
|
|
"ATT_MP_REGEN SMALLINT NULL DEFAULT(0),"
|
|
"ATT_CRITICAL SMALLINT NULL DEFAULT(0),"
|
|
"ATT_BLOCK SMALLINT NULL DEFAULT(0),"
|
|
"ATT_SPEED SMALLINT NULL DEFAULT(0),"
|
|
"ATT_MAGIC_POWER SMALLINT NULL DEFAULT(0),"
|
|
"ATT_MAGIC_RESIST SMALLINT NULL DEFAULT(0))"
|
|
, m_szTableName);
|
|
|
|
if(0 < nResult)
|
|
{
|
|
if(m_WriteDB.ExecuteQuery(m_szQuery))
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
ERRLOG1(g_Log, "쿼리 실패 : 테이블 생성 실패 : %s", m_szQuery);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ERRLOG0(g_Log, "쿼리 만들기 : 테이블 생성 실패");
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool CMakeItemMap::ConstructUIDCIDMap()
|
|
{
|
|
char szQuery[OleDB::MaxQueryTextLen];
|
|
|
|
switch(m_eAgentServerType)
|
|
{
|
|
case UnifiedConst::ROW:
|
|
case UnifiedConst::Part2Unified:
|
|
_snprintf(szQuery, OleDB::MaxQueryTextLen,
|
|
"Select UID, NewCID From TblUnifiedCharList where OldServerGroupID = %d", m_eAgentServerType);
|
|
break;
|
|
|
|
case UnifiedConst::Part2Selectable:
|
|
_snprintf(szQuery, OleDB::MaxQueryTextLen, "Select UID, NewCID From TblUnifiedCharList");
|
|
break;
|
|
|
|
default:
|
|
cout << "[알 수 없는 서버 타입입니다 : " << m_eAgentServerType << endl;
|
|
return false;
|
|
}
|
|
|
|
szQuery[OleDB::MaxQueryTextLen - 1] = 0;
|
|
|
|
cout << "[UIDCID맵 제작 시작]" << endl;
|
|
|
|
if(!m_ReadDB.ExecuteQuery(szQuery))
|
|
{
|
|
cout << "[UIDCID맵 쿼리 실패]" << endl;
|
|
return false;
|
|
}
|
|
|
|
#pragma pack(1)
|
|
struct UserInfoData
|
|
{
|
|
unsigned long m_dwUID;
|
|
unsigned long m_dwCID;
|
|
};
|
|
#pragma pack()
|
|
|
|
const int MAX_ROWS = 1024;
|
|
int nGetRows = 0;
|
|
|
|
UserInfoData userInfoData[MAX_ROWS];
|
|
memset(&userInfoData, 0, sizeof(UserInfoData) * MAX_ROWS);
|
|
|
|
while (m_ReadDB.GetData((void**)&userInfoData, sizeof(UserInfoData), MAX_ROWS, &nGetRows))
|
|
{
|
|
if(0 == nGetRows)
|
|
{
|
|
break;
|
|
}
|
|
|
|
for(UserInfoData* lpUserInfoData = userInfoData;
|
|
0 < nGetRows; --nGetRows, ++lpUserInfoData)
|
|
{
|
|
if(0 != lpUserInfoData->m_dwCID)
|
|
{
|
|
m_CIDUIDMap.insert(std::make_pair(
|
|
lpUserInfoData->m_dwCID, lpUserInfoData->m_dwUID));
|
|
}
|
|
|
|
++m_dwUserNum;
|
|
}
|
|
|
|
memset(&userInfoData, 0, sizeof(UserInfoData) * MAX_ROWS);
|
|
}
|
|
|
|
cout << "[맵 제작 완료]" << endl;
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CMakeItemMap::ProcessStore()
|
|
{
|
|
const int MAX_QUERY = 2;
|
|
char szQuery[MAX_QUERY][OleDB::MaxQueryTextLen];
|
|
|
|
switch(m_eAgentServerType)
|
|
{
|
|
case UnifiedConst::ROW:
|
|
case UnifiedConst::Part2Unified:
|
|
_snprintf(szQuery[0], OleDB::MaxQueryTextLen,
|
|
"SELECT UID, Store FROM TblUnifiedItemStore1 WHERE OldServerGroupID = %d", m_eAgentServerType);
|
|
|
|
_snprintf(szQuery[1], OleDB::MaxQueryTextLen,
|
|
"SELECT UID, Store FROM TblUnifiedItemStore2 WHERE OldServerGroupID = %d", m_eAgentServerType);
|
|
break;
|
|
|
|
case UnifiedConst::Part2Selectable:
|
|
_snprintf(szQuery[0], OleDB::MaxQueryTextLen, "SELECT UID, Store FROM TblUnifiedItemStore1");
|
|
_snprintf(szQuery[1], OleDB::MaxQueryTextLen, "SELECT UID, Store FROM TblUnifiedItemStore2");
|
|
break;
|
|
|
|
default:
|
|
cout << "[알 수 없는 서버 타입입니다 : " << m_eAgentServerType << endl;
|
|
return false;
|
|
}
|
|
|
|
|
|
#pragma pack(1)
|
|
struct StoreData
|
|
{
|
|
unsigned long m_dwUID;
|
|
STORE m_StoreData;
|
|
};
|
|
#pragma pack()
|
|
|
|
cout << "[StoreInfo] 컨버팅 시작" << endl;
|
|
DETLOG0(g_Log, "창고 컨버팅 시작(에러시 CID대신 UID기록)");
|
|
|
|
Item::CArrayContainer StoreContainer;
|
|
Item::CArrayContainer::iterator begin, end;
|
|
|
|
StoreContainer.Initialize(0,
|
|
ContainerConstant::DEPOSIT_WIDTH,
|
|
ContainerConstant::DEPOSIT_HEIGHT,
|
|
ContainerConstant::MAX_DEPOSIT_TAB);
|
|
|
|
unsigned long dwCurrentUserNum = 0;
|
|
|
|
for(int nQueryCount = 0; nQueryCount < MAX_QUERY; ++nQueryCount)
|
|
{
|
|
if(!m_ReadDB.ExecuteQuery(szQuery[nQueryCount]))
|
|
{
|
|
cout << "[ItemStore맵 쿼리 실패] : "
|
|
<< szQuery[nQueryCount] << " : " << m_ReadDB.GetErrorString() << endl;
|
|
|
|
return false;
|
|
}
|
|
|
|
const int MAX_ROWS = 10240;
|
|
int nGetRows = 0;
|
|
|
|
StoreData* storeData = new StoreData[MAX_ROWS];
|
|
|
|
memset(storeData, 0, sizeof(StoreData) * MAX_ROWS);
|
|
|
|
while (m_ReadDB.GetData((void**)storeData, sizeof(StoreData), MAX_ROWS, &nGetRows))
|
|
{
|
|
if(0 == nGetRows)
|
|
{
|
|
break;
|
|
}
|
|
|
|
dwCurrentUserNum += nGetRows;
|
|
|
|
for(StoreData* lpStoreData = storeData;
|
|
0 < nGetRows; --nGetRows, ++lpStoreData)
|
|
{
|
|
unsigned long dwUID = lpStoreData->m_dwUID;
|
|
|
|
StoreContainer.ClearItems();
|
|
StoreContainer.SetCID(dwUID);
|
|
|
|
if(sizeof(DWORD) <= lpStoreData->m_StoreData.dwSize)
|
|
{
|
|
lpStoreData->m_StoreData.dwSize -= sizeof(DWORD);
|
|
}
|
|
|
|
if(0 < lpStoreData->m_StoreData.dwSize)
|
|
{
|
|
if (!StoreContainer.SerializeIn(
|
|
lpStoreData->m_StoreData.Data,
|
|
lpStoreData->m_StoreData.dwSize))
|
|
{
|
|
cout << "[UID:" << dwUID << "] 창고 : " << nQueryCount + 1 << "작성 실패" << endl;
|
|
}
|
|
else
|
|
{
|
|
begin = StoreContainer.begin();
|
|
end = StoreContainer.end();
|
|
|
|
for(; begin != end; ++begin)
|
|
{
|
|
Item::CItem* lpItem = *begin;
|
|
if(NULL != lpItem)
|
|
{
|
|
LogItemInfoToDB(dwUID, 0, lpItem);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
cout << dwCurrentUserNum << "/" << m_dwUserNum << endl;
|
|
memset(storeData, 0, sizeof(StoreData) * MAX_ROWS);
|
|
}
|
|
|
|
delete [] storeData;
|
|
}
|
|
|
|
cout << endl << "[StoreInfo] 컨버팅 끝" << endl;
|
|
DETLOG0(g_Log, "창고 컨버팅 끝");
|
|
return true;
|
|
}
|
|
|
|
bool CMakeItemMap::ProcessCharacterItems()
|
|
{
|
|
const char* szQuery = "Select a.CID, a.Equip, a.Inventory, a.Extra, b.Exchange, b.TempInven "
|
|
"From CharItem a join CharItemEX b on a.CID = b.CID";
|
|
|
|
#pragma pack(1)
|
|
struct CharData
|
|
{
|
|
unsigned long m_dwCID;
|
|
EQUIP m_Equip;
|
|
INVEN m_Inventory;
|
|
EXTRA m_Extra;
|
|
EXCHANGE m_Exchange;
|
|
TEMPINVEN m_TempInven;
|
|
};
|
|
#pragma pack()
|
|
|
|
struct ContainerData
|
|
{
|
|
unsigned long m_dwSize;
|
|
char* m_lpData;
|
|
};
|
|
|
|
cout << "[CharItemInfo] 컨버팅 시작" << endl;
|
|
DETLOG0(g_Log, "캐릭터 아이템 컨버팅 시작");
|
|
|
|
Item::CListContainer Equip;
|
|
Item::CListContainer Extra;
|
|
Item::CArrayContainer Inventory;
|
|
Item::CArrayContainer Exchange;
|
|
Item::CListContainer TempInven;
|
|
|
|
Item::CItemContainer::iterator first, last;
|
|
|
|
Equip.Initialize(0, Item::EquipmentPos::MAX_EQUPMENT_POS);
|
|
Extra.Initialize(0, Item::ExtraSpacePos::MAX_EXTRA_SPACE_NUM);
|
|
|
|
Inventory.Initialize(0,
|
|
ContainerConstant::INVENTORY_WIDTH,
|
|
ContainerConstant::INVENTORY_HEIGHT,
|
|
ContainerConstant::MAX_INVENTORY_TAB);
|
|
|
|
Exchange.Initialize(0,
|
|
ContainerConstant::EXCHANGE_WIDTH,
|
|
ContainerConstant::EXCHANGE_HEIGHT, 1);
|
|
|
|
TempInven.Initialize(0, Item::MAX_TEMP_INVEN_ITEM_NUM);
|
|
|
|
const int MAX_CONTAINER = 5;
|
|
Item::CItemContainer* lpItemContainers[MAX_CONTAINER] =
|
|
{ &Equip, &Inventory, &Extra, &Exchange, &TempInven };
|
|
|
|
if(!m_ReadDB.ExecuteQuery(szQuery))
|
|
{
|
|
cout << "[ItemStore맵 쿼리 실패] : " << m_ReadDB.GetErrorString() << endl;
|
|
return false;
|
|
}
|
|
|
|
CIDUIDMap::iterator uiditr;
|
|
CIDUIDMap::iterator enditr = m_CIDUIDMap.end();
|
|
|
|
const int MAX_ROWS = 10240;
|
|
int nGetRows = 0;
|
|
CharData* charData = new CharData[MAX_ROWS];
|
|
memset(charData, 0, sizeof(CharData) * MAX_ROWS);
|
|
|
|
unsigned long dwCharNum = 0;
|
|
|
|
while(m_ReadDB.GetData((void**)charData, sizeof(CharData), MAX_ROWS, &nGetRows))
|
|
{
|
|
if(0 == nGetRows)
|
|
{
|
|
break;
|
|
}
|
|
|
|
for(CharData* lpCharData = charData;
|
|
0 < nGetRows; --nGetRows, ++lpCharData)
|
|
{
|
|
unsigned long dwCID = lpCharData->m_dwCID;
|
|
|
|
uiditr = m_CIDUIDMap.find(dwCID);
|
|
unsigned long dwUID = uiditr != enditr ? uiditr->second : 0;
|
|
|
|
if(0 != dwUID)
|
|
{
|
|
++dwCharNum;
|
|
|
|
ContainerData containerData[MAX_CONTAINER] =
|
|
{
|
|
{ lpCharData->m_Equip.dwSize, lpCharData->m_Equip.Data },
|
|
{ lpCharData->m_Inventory.dwSize, lpCharData->m_Inventory.Data },
|
|
{ lpCharData->m_Extra.dwSize, lpCharData->m_Extra.Data },
|
|
{ lpCharData->m_Exchange.dwSize, lpCharData->m_Exchange.Data },
|
|
{ lpCharData->m_TempInven.dwSize, lpCharData->m_TempInven.Data }
|
|
};
|
|
|
|
for(int nCount = 0; nCount < MAX_CONTAINER; ++nCount)
|
|
{
|
|
if(sizeof(DWORD) <= containerData[nCount].m_dwSize)
|
|
{
|
|
containerData[nCount].m_dwSize -= sizeof(DWORD);
|
|
}
|
|
|
|
if(0 < containerData[nCount].m_dwSize)
|
|
{
|
|
lpItemContainers[nCount]->ClearItems();
|
|
lpItemContainers[nCount]->SetCID(dwCID);
|
|
|
|
if(!lpItemContainers[nCount]->SerializeIn(
|
|
containerData[nCount].m_lpData, containerData[nCount].m_dwSize))
|
|
{
|
|
cout << "[UID:" << dwUID << "]" << "[CID:" << dwCID << "]" << "아이템 데이터 작성 실패" << endl;
|
|
}
|
|
else
|
|
{
|
|
first = lpItemContainers[nCount]->begin();
|
|
last = lpItemContainers[nCount]->end();
|
|
|
|
for(; first != last; ++first)
|
|
{
|
|
Item::CItem* lpItem = *first;
|
|
if(NULL != lpItem)
|
|
{
|
|
LogItemInfoToDB(dwUID, dwCID, lpItem);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
cout << dwCharNum << "/" << static_cast<unsigned int>(m_CIDUIDMap.size()) << endl;
|
|
memset(charData, 0, sizeof(CharData) * MAX_ROWS);
|
|
}
|
|
|
|
delete [] charData;
|
|
|
|
cout << endl << "[CharItemInfo] 컨버팅 끝" << endl;
|
|
DETLOG0(g_Log, "캐릭터 아이템 컨버팅 끝");
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CMakeItemMap::LogItemInfoToDB(unsigned long dwUID, unsigned long dwCID, Item::CItem* lpItem)
|
|
{
|
|
int nRuneSocket = 0;
|
|
int nUpgradeStep = 0;
|
|
int nMaxSocketNum = 0;
|
|
int nItemGrade = Item::EquipType::MAX_GRADE;
|
|
int nItemGradePlus = 0;
|
|
|
|
unsigned char cSocket[Item::EquipmentInfo::MAX_SOCKET_NUM];
|
|
short usAttribute[Item::Attribute::MAX_ATTRIBUTE_NUM];
|
|
|
|
std::fill_n(cSocket, size_t(Item::EquipmentInfo::MAX_SOCKET_NUM), 0);
|
|
std::fill_n(usAttribute, size_t(Item::Attribute::MAX_ATTRIBUTE_NUM), 0);
|
|
|
|
Item::CEquipment* lpEquipment = Item::CEquipment::DowncastToEquipment(lpItem);
|
|
if(NULL != lpEquipment)
|
|
{
|
|
//nRuneSocket = lpEquipment->GetRuneSocket();
|
|
nUpgradeStep = lpEquipment->GetUpgradeLevel();
|
|
nMaxSocketNum = lpEquipment->GetMaxSocketNum();
|
|
|
|
nItemGrade = lpEquipment->GetItemGrade().m_eItemGrade;
|
|
nItemGradePlus = lpEquipment->GetItemGrade().m_cPlus;
|
|
|
|
lpEquipment->GetSocket(cSocket, Item::EquipmentInfo::MAX_SOCKET_NUM);
|
|
lpEquipment->GetAttribute(usAttribute, Item::Attribute::MAX_ATTRIBUTE_NUM);
|
|
}
|
|
|
|
int nResult = _snprintf(m_szQuery, MAX_QUERY_LENGTH, "INSERT INTO %s "
|
|
" values (%I64d, %d, %d, %u, %u, %u, %u, %u, %u, %u, %u",
|
|
m_szTableName, lpItem->GetUID(), dwUID, dwCID, lpItem->GetPrototypeID(),
|
|
nRuneSocket, nUpgradeStep, lpItem->GetNumOrDurability(), lpItem->GetMaxNumOrDurability(),
|
|
nItemGrade, nItemGradePlus, nMaxSocketNum);
|
|
|
|
int nLength = nResult;
|
|
|
|
for(int nCount = 0; nCount < Item::EquipmentInfo::MAX_SOCKET_NUM && 0 < nResult; ++nCount)
|
|
{
|
|
nResult = _snprintf(m_szQuery + nLength, MAX_QUERY_LENGTH - nLength, ", %d", cSocket[nCount]);
|
|
nLength += nResult;
|
|
}
|
|
|
|
for(int nCount = Item::Attribute::MIN_DAMAGE;
|
|
nCount < Item::Attribute::MAX_ATTRIBUTE_NUM && 0 < nResult; ++nCount)
|
|
{
|
|
nResult = _snprintf(m_szQuery + nLength, MAX_QUERY_LENGTH - nLength, ", %d", usAttribute[nCount]);
|
|
nLength += nResult;
|
|
}
|
|
|
|
if(0 < nResult && 0 < nLength && nLength < MAX_QUERY_LENGTH - 3)
|
|
{
|
|
m_szQuery[nLength] = ')';
|
|
m_szQuery[nLength + 1] = '\0';
|
|
|
|
if(m_WriteDB.ExecuteQuery(m_szQuery))
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
ERRLOG5(g_Log, "UID:%d/CID:%d/ItemUID:0x%016I64X/ItemPrototype:%6d 쿼리 실패 : %s",
|
|
dwUID, dwCID, lpItem->GetUID(), lpItem->GetPrototypeID(), m_WriteDB.GetErrorString());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Log
|
|
ERRLOG4(g_Log, "UID:%d/CID:%d/ItemUID:0x%016I64X/ItemPrototype:%6d 쿼리 만들기 실패",
|
|
dwUID, dwCID, lpItem->GetUID(), lpItem->GetPrototypeID());
|
|
}
|
|
|
|
return false;
|
|
} |