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>
This commit is contained in:
561
Server/DBProcess/GiveEventReward/GiveEventReward.cpp
Normal file
561
Server/DBProcess/GiveEventReward/GiveEventReward.cpp
Normal file
@@ -0,0 +1,561 @@
|
||||
// GiveEventReward.cpp : 콘솔 응용 프로그램에 대한 진입점을 정의합니다.
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#pragma warning(disable:4800)
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include <boost/pool/pool_alloc.hpp>
|
||||
|
||||
#include <RylDBLibrary/RylDBLibrary.h>
|
||||
#include <RylDBLibrary/RylDBCharCommand.h>
|
||||
#include <RylDBLibrary/RylDBStoreCommand.h>
|
||||
|
||||
#include <Item/ItemMgr.h>
|
||||
#include <Item/Container/ContainerConstant.h>
|
||||
#include <Item/RebalanceConvert/ContainerChecker.h>
|
||||
#include <Network/Packet/PacketStruct/ServerInfo.h>
|
||||
#include <Log/ServerLog.h>
|
||||
#include <Utility/Setup/ServerSetup.h>
|
||||
|
||||
class CGiveEventReward :
|
||||
public IDBCharItemProcess,
|
||||
public IDBCharItemExProcess,
|
||||
public IDBStoreProcess
|
||||
{
|
||||
public:
|
||||
|
||||
typedef std::pair<unsigned long, unsigned long> EventItem;
|
||||
typedef std::vector<EventItem> EventItemList;
|
||||
|
||||
typedef std::pair<unsigned long, std::pair<const Item::ItemInfo*, unsigned char> > GiveItem;
|
||||
typedef std::vector<GiveItem> GiveItemList;
|
||||
|
||||
typedef std::multimap<unsigned long, GiveItem, std::less<unsigned long>,
|
||||
boost::fast_pool_allocator<std::pair<unsigned long, GiveItem> > > GiveItemMap;
|
||||
|
||||
CGiveEventReward(CDBItemSerialMgr& dbItemSerialMgr, Item::CItemMgr& newItemMgr);
|
||||
|
||||
virtual ConvertResult operator()(RylDBCommand::CCharItem& charItem_InOut);
|
||||
virtual ConvertResult operator()(RylDBCommand::CCharItemEx& charItemEx_InOut);
|
||||
virtual ConvertResult operator()(RylDBCommand::CUnifiedStore1& unifiedStore1_InOut);
|
||||
virtual ConvertResult operator()(RylDBCommand::CUnifiedStore2& unifiedStore2_InOut);
|
||||
|
||||
bool LoadScript(const char* szScriptFileName);
|
||||
|
||||
// 데이터에서 아이템을 제거하고 카운팅한다.
|
||||
void RemoveItemFromContainer(unsigned long dwUID, unsigned long dwCID,
|
||||
RebalanceLib::CItemChecker* lpItemChecker, const char* szPosition,
|
||||
const char* szData_In, unsigned long dwDataSize_In,
|
||||
char* szData_Out, unsigned long& dwDataSize_Out);
|
||||
|
||||
// 아이템을 찾아서 넣어 준다.
|
||||
void GiveItemToContainer(unsigned long dwUID, unsigned long dwCID,
|
||||
RebalanceLib::CItemChecker& itemChecker, const char* szPosition,
|
||||
char* szData_InOut, unsigned long& dwDataSize_InOut,
|
||||
unsigned long dwMaxDataSize, bool bLastChance = false);
|
||||
|
||||
private:
|
||||
|
||||
CDBItemSerialMgr& m_DBItemSerialMgr;
|
||||
Item::CItemMgr& m_newItemMgr;
|
||||
|
||||
EventItemList m_EventItemList; // first : 제거할 아이템 ID / second : 줄 아이템 Key
|
||||
GiveItemList m_GiveItemList; // first : 줄 아이템 Key / second : 줄 아이템 / 줄 아이템 개수
|
||||
|
||||
GiveItemMap m_CIDGiveItemMap; // first : CID / second : 줄 아이템 / 줄 아이템 개수
|
||||
GiveItemMap m_UIDGiveItemMap; // first : UID / second : 줄 아이템 / 줄 아이템 개수
|
||||
};
|
||||
|
||||
|
||||
void PrintUsage()
|
||||
{
|
||||
printf("usage : GiveEventReward.exe DBAddress DBName DBAccount DBPassword "
|
||||
"ServerGroupNum(0~9) RewardScriptName \n");
|
||||
}
|
||||
|
||||
int _tmain(int argc, _TCHAR* argv[])
|
||||
{
|
||||
if(7 != argc)
|
||||
{
|
||||
PrintUsage();
|
||||
return -1;
|
||||
}
|
||||
|
||||
int nServerGroup = atoi(argv[5]);
|
||||
const char* szRewardScriptName = argv[6];
|
||||
|
||||
// 아이템 스크립트 로드
|
||||
if(!Item::CItemMgr::GetInstance().LoadItemProtoType("./NewItemScript.txt"))
|
||||
{
|
||||
printf("NewItemScript.txt load failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
CDBItemSerialMgr dbItemSerialMgr;
|
||||
CGiveEventReward giveEventReward(dbItemSerialMgr, Item::CItemMgr::GetInstance());
|
||||
|
||||
// 이벤트 보상 스크립트 로드
|
||||
if(!giveEventReward.LoadScript(szRewardScriptName))
|
||||
{
|
||||
printf("%s load failed\n", szRewardScriptName);
|
||||
return -1;
|
||||
}
|
||||
|
||||
CoInitialize(0);
|
||||
|
||||
SERVER_ID serverID;
|
||||
|
||||
serverID.sID.Type = CServerSetup::AuthServer;
|
||||
serverID.sID.Group = nServerGroup;
|
||||
serverID.sID.Channel = 0;
|
||||
serverID.sID.ID = 0;
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
ATL::CDataSource dataSource;
|
||||
ATL::CSession Session;
|
||||
|
||||
#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)); }
|
||||
|
||||
if(FAILED(hr = CRylDBProcess::ConnectDB(dataSource, argv[1], argv[2], argv[3], argv[4])))
|
||||
{
|
||||
LOG_CONVERT1("Connect DB failed : hr:0x%08X", hr);
|
||||
}
|
||||
else if(FAILED(hr = Session.Open(dataSource)))
|
||||
{
|
||||
LOG_CONVERT1("Open session failed : hr:0x%08X", hr);
|
||||
}
|
||||
else if(FAILED(hr = dbItemSerialMgr.LoadItemSerialDB(Session, serverID.dwID)))
|
||||
{
|
||||
LOG_CONVERT1("Insert itemSerial failed : hr:0x%08X", hr);
|
||||
}
|
||||
else
|
||||
{
|
||||
CRylDBProcess rylDBProcess(Session);
|
||||
CConsoleCounter consoleCounter(1000);
|
||||
|
||||
if (!rylDBProcess.UnifiedStore1(giveEventReward, consoleCounter))
|
||||
{
|
||||
LOG_CONVERT1("UnifiedStore1 process failed : hr:0x%08X", hr);
|
||||
}
|
||||
else if (!rylDBProcess.UnifiedStore2(giveEventReward, consoleCounter))
|
||||
{
|
||||
LOG_CONVERT1("UnifiedStore2 process failed : hr:0x%08X", hr);
|
||||
}
|
||||
else if (!rylDBProcess.CharItem(giveEventReward, consoleCounter))
|
||||
{
|
||||
LOG_CONVERT1("CharItem process failed : hr:0x%08X", hr);
|
||||
}
|
||||
else if (!rylDBProcess.CharItemEx(giveEventReward, consoleCounter))
|
||||
{
|
||||
LOG_CONVERT1("CharItemEx process failed : hr:0x%08X", hr);
|
||||
}
|
||||
// 아이템 시리얼 최종 저장
|
||||
else if(FAILED(hr = dbItemSerialMgr.SaveItemSerialDB(Session, serverID.dwID)))
|
||||
{
|
||||
LOG_CONVERT1("ItemSerial save failed : hr:0x%08X", hr);
|
||||
}
|
||||
}
|
||||
|
||||
INFLOG0(g_Log, "Give Complete");
|
||||
|
||||
Session.Close();
|
||||
dataSource.Close();
|
||||
|
||||
CoUninitialize();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CGiveEventReward::CGiveEventReward(CDBItemSerialMgr& dbItemSerialMgr, Item::CItemMgr& newItemMgr)
|
||||
: m_DBItemSerialMgr(dbItemSerialMgr), m_newItemMgr(newItemMgr)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ConvertResult CGiveEventReward::operator()(RylDBCommand::CCharItem& charItem_InOut)
|
||||
{
|
||||
unsigned long dwCID = charItem_InOut.GetCID();
|
||||
|
||||
const EQUIP& equip_In = charItem_InOut.GetEquip();
|
||||
const INVEN& inven_In = charItem_InOut.GetInven();
|
||||
const EXTRA& extra_In = charItem_InOut.GetExtra();
|
||||
|
||||
EQUIP equip_Out;
|
||||
INVEN inven_Out;
|
||||
EXTRA extra_Out;
|
||||
|
||||
memset(&equip_Out, 0, sizeof(EQUIP));
|
||||
memset(&inven_Out, 0, sizeof(INVEN));
|
||||
memset(&extra_Out, 0, sizeof(EXTRA));
|
||||
|
||||
RebalanceLib::CItemArrayChecker<
|
||||
ContainerConstant::INVENTORY_WIDTH,
|
||||
ContainerConstant::INVENTORY_HEIGHT,
|
||||
ContainerConstant::MAX_INVENTORY_TAB> inven_checker(TakeType::TS_INVEN);
|
||||
|
||||
RemoveItemFromContainer(0, dwCID, 0, "EQUIP", equip_In.Data, equip_In.dwSize, equip_Out.Data, equip_Out.dwSize);
|
||||
RemoveItemFromContainer(0, dwCID, &inven_checker, "INVEN", inven_In.Data, inven_In.dwSize, inven_Out.Data, inven_Out.dwSize);
|
||||
RemoveItemFromContainer(0, dwCID, 0, "EXTRA", extra_In.Data, extra_In.dwSize, extra_Out.Data, extra_Out.dwSize);
|
||||
|
||||
GiveItemToContainer(0, dwCID, inven_checker, "INVEN", inven_Out.Data, inven_Out.dwSize, INVEN::MAX_INVEN_SIZE);
|
||||
|
||||
charItem_InOut.SetEquip(equip_Out);
|
||||
charItem_InOut.SetInven(inven_Out);
|
||||
charItem_InOut.SetExtra(extra_Out);
|
||||
|
||||
return CONVERT_SUCCEEDED;
|
||||
}
|
||||
|
||||
ConvertResult CGiveEventReward::operator()(RylDBCommand::CCharItemEx& charItemEx_InOut)
|
||||
{
|
||||
unsigned long dwCID = charItemEx_InOut.GetCID();
|
||||
|
||||
const EXCHANGE& exchange_In = charItemEx_InOut.GetExchange();
|
||||
const TEMPINVEN& tempInven_In = charItemEx_InOut.GetTempInven();
|
||||
|
||||
EXCHANGE exchange_Out;
|
||||
TEMPINVEN tempInven_Out;
|
||||
|
||||
memset(&exchange_Out, 0, sizeof(EXCHANGE));
|
||||
memset(&tempInven_Out, 0, sizeof(TEMPINVEN));
|
||||
|
||||
RebalanceLib::CItemListChecker<Item::MAX_TEMP_INVEN_ITEM_NUM>
|
||||
tempInvenChecker(TakeType::TS_TEMPINVEN);
|
||||
|
||||
RemoveItemFromContainer(0, dwCID, 0, "EXCHANGE",
|
||||
exchange_In.Data, exchange_In.dwSize, exchange_Out.Data, exchange_Out.dwSize);
|
||||
|
||||
RemoveItemFromContainer(0, dwCID, &tempInvenChecker, "TEMPINVEN",
|
||||
tempInven_In.Data, tempInven_In.dwSize, tempInven_Out.Data, tempInven_Out.dwSize);
|
||||
|
||||
// LAST Chance!
|
||||
GiveItemToContainer(0, dwCID, tempInvenChecker, "TEMPINVEN",
|
||||
tempInven_Out.Data, tempInven_Out.dwSize, TEMPINVEN::MAX_TEMPINVEN_SIZE, true);
|
||||
|
||||
charItemEx_InOut.SetExchange(exchange_Out);
|
||||
charItemEx_InOut.SetTempInven(tempInven_Out);
|
||||
|
||||
return CONVERT_SUCCEEDED;
|
||||
}
|
||||
|
||||
ConvertResult CGiveEventReward::operator()(RylDBCommand::CUnifiedStore1& unifiedStore1_InOut)
|
||||
{
|
||||
unsigned long dwUID = unifiedStore1_InOut.GetUID();
|
||||
|
||||
const STORE& store_In = unifiedStore1_InOut.GetStore();
|
||||
STORE store_Out;
|
||||
memset(&store_Out, 0, sizeof(STORE));
|
||||
|
||||
RebalanceLib::CItemArrayChecker<
|
||||
ContainerConstant::DEPOSIT_WIDTH,
|
||||
ContainerConstant::DEPOSIT_HEIGHT,
|
||||
ContainerConstant::MAX_DEPOSIT_TAB> depositChecker(TakeType::TS_DEPOSIT);
|
||||
|
||||
depositChecker.FillTab(2);
|
||||
depositChecker.FillTab(3);
|
||||
|
||||
RemoveItemFromContainer(dwUID, 0, &depositChecker, "UNIFIED_STORE_01",
|
||||
store_In.Data, store_In.dwSize, store_Out.Data, store_Out.dwSize);
|
||||
|
||||
GiveItemToContainer(dwUID, 0, depositChecker, "UnifiedStore1",
|
||||
store_Out.Data, store_Out.dwSize, STORE::MAX_STORE_SIZE);
|
||||
|
||||
unifiedStore1_InOut.SetStore(store_Out);
|
||||
|
||||
return CONVERT_SUCCEEDED;
|
||||
}
|
||||
|
||||
ConvertResult CGiveEventReward::operator()(RylDBCommand::CUnifiedStore2& unifiedStore2_InOut)
|
||||
{
|
||||
unsigned long dwUID = unifiedStore2_InOut.GetUID();
|
||||
|
||||
const STORE& store_In = unifiedStore2_InOut.GetStore();
|
||||
STORE store_Out;
|
||||
memset(&store_Out, 0, sizeof(STORE));
|
||||
|
||||
RebalanceLib::CItemArrayChecker<
|
||||
ContainerConstant::DEPOSIT_WIDTH,
|
||||
ContainerConstant::DEPOSIT_HEIGHT,
|
||||
ContainerConstant::MAX_DEPOSIT_TAB> depositChecker(TakeType::TS_DEPOSIT);
|
||||
|
||||
depositChecker.FillTab(0);
|
||||
depositChecker.FillTab(1);
|
||||
|
||||
RemoveItemFromContainer(dwUID, 0, &depositChecker, "UNIFIED_STORE_02",
|
||||
store_In.Data, store_In.dwSize, store_Out.Data, store_Out.dwSize);
|
||||
|
||||
GiveItemToContainer(dwUID, 0, depositChecker, "UnifiedStore2",
|
||||
store_Out.Data, store_Out.dwSize, STORE::MAX_STORE_SIZE);
|
||||
|
||||
unifiedStore2_InOut.SetStore(store_Out);
|
||||
|
||||
return CONVERT_SUCCEEDED;
|
||||
}
|
||||
|
||||
bool CGiveEventReward::LoadScript(const char* szScriptFileName)
|
||||
{
|
||||
/*
|
||||
# 파일 형식 - 주석입니다.
|
||||
|
||||
REMOVE:지울아이템ID:Key
|
||||
GIVE:Key:줄 아이템ID:개수
|
||||
GIVE:Key:줄 아이템ID:개수
|
||||
GIVE:Key:줄 아이템ID:개수
|
||||
|
||||
...
|
||||
*/
|
||||
|
||||
FILE* lpFile = fopen(szScriptFileName, "rt");
|
||||
|
||||
if (0 != lpFile)
|
||||
{
|
||||
const int MAX_BUFFER = 1024;
|
||||
char szBuffer[MAX_BUFFER];
|
||||
|
||||
const char* szDelimiter = "\r\n\t: ";
|
||||
|
||||
while(fgets(szBuffer, MAX_BUFFER - 1, lpFile))
|
||||
{
|
||||
// 한 라인씩 읽어들여 파싱을 한다.
|
||||
char* szType = strtok(szBuffer, szDelimiter);
|
||||
|
||||
if(0 != szType && '#' != szType[0])
|
||||
{
|
||||
strupr(szType);
|
||||
|
||||
if (0 == strcmp(szType, "REMOVE"))
|
||||
{
|
||||
char* szRemoveItem = strtok(0, szDelimiter);
|
||||
char* szGiveItemKey = strtok(0, szDelimiter);
|
||||
|
||||
if (0 != szRemoveItem && 0 != szGiveItemKey)
|
||||
{
|
||||
m_EventItemList.push_back(
|
||||
EventItem(atoi(szRemoveItem), atoi(szGiveItemKey)));
|
||||
}
|
||||
}
|
||||
else if (0 == strcmp(szType, "GIVE"))
|
||||
{
|
||||
char* szGiveItemKey = strtok(0, szDelimiter);
|
||||
char* szGiveItem = strtok(0, szDelimiter);
|
||||
char* szGiveItemNum = strtok(0, szDelimiter);
|
||||
|
||||
if (0 != szGiveItemKey && 0 != szGiveItem && 0 != szGiveItemNum)
|
||||
{
|
||||
GiveItem giveItem;
|
||||
|
||||
const Item::ItemInfo* lpItemInfo = m_newItemMgr.GetItemInfo(atoi(szGiveItem));
|
||||
|
||||
if (0 != lpItemInfo)
|
||||
{
|
||||
// 실제로 있는 아이템만 지급 대상으로 한다.
|
||||
giveItem.first = atoi(szGiveItemKey);
|
||||
giveItem.second.first = lpItemInfo;
|
||||
giveItem.second.second = atoi(szGiveItemNum);
|
||||
|
||||
m_GiveItemList.push_back(giveItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::sort(m_EventItemList.begin(), m_EventItemList.end());
|
||||
std::sort(m_GiveItemList.begin(), m_GiveItemList.end());
|
||||
|
||||
fclose(lpFile);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
struct CheckFirstOnly
|
||||
{
|
||||
bool operator () (
|
||||
const CGiveEventReward::EventItem& lhs,
|
||||
const CGiveEventReward::EventItem& rhs)
|
||||
{ return lhs.first < rhs.first; }
|
||||
|
||||
bool operator () (
|
||||
const CGiveEventReward::GiveItem& lhs,
|
||||
const CGiveEventReward::GiveItem& rhs)
|
||||
{ return lhs.first < rhs.first; }
|
||||
};
|
||||
|
||||
// 데이터에서 아이템을 제거하고 카운팅한다.
|
||||
void CGiveEventReward::RemoveItemFromContainer(unsigned long dwUID, unsigned long dwCID,
|
||||
RebalanceLib::CItemChecker* lpItemChecker,
|
||||
const char* szPosition,
|
||||
const char* szData_In, unsigned long dwDataSize_In,
|
||||
char* szData_Out, unsigned long& dwDataSize_Out)
|
||||
{
|
||||
const char* szDataPos = szData_In;
|
||||
const char* szDataEnd = szData_In + dwDataSize_In;
|
||||
|
||||
char* szDataPos_Out = szData_Out;
|
||||
|
||||
EventItemList::iterator pos;
|
||||
EventItemList::iterator end = m_EventItemList.end();
|
||||
|
||||
std::pair<GiveItemList::iterator, GiveItemList::iterator> give_range;
|
||||
GiveItem giveItem;
|
||||
|
||||
// 아이템을 전부 순회하며, 컨테이너를 채운다. 만일 아이템이 대상 아이템이면 채우지 않는다.
|
||||
for (; szDataPos + sizeof(Item::ItemData) <= szDataEnd; )
|
||||
{
|
||||
const Item::ItemData* lpItemData = reinterpret_cast<const Item::ItemData*>(szDataPos);
|
||||
const Item::ItemInfo* lpItemInfo = m_newItemMgr.GetItemInfo(lpItemData->m_usProtoTypeID);
|
||||
|
||||
if (0 == lpItemInfo)
|
||||
{
|
||||
ERRLOG6(g_Log, "UID:%10u / CID:%10u / ItemUID:%016I64X / PrototypeID:%6u / Num:%d / %s / "
|
||||
"스크립트에 없는 아이템이어서 제거합니다.",
|
||||
dwUID, dwCID, lpItemData->m_dwUID, lpItemData->m_usProtoTypeID,
|
||||
lpItemData->m_cNumOrDurability, szPosition);
|
||||
}
|
||||
else
|
||||
{
|
||||
pos = std::lower_bound(m_EventItemList.begin(), end,
|
||||
EventItem(lpItemData->m_usProtoTypeID, 0), CheckFirstOnly());
|
||||
|
||||
if (pos != end && pos->first == lpItemData->m_usProtoTypeID)
|
||||
{
|
||||
// 아이템이 있다. 카운팅하고 복사하지 않음
|
||||
giveItem.first = pos->second; // 줄 아이템 Key
|
||||
giveItem.second.first = 0;
|
||||
giveItem.second.second = 0;
|
||||
|
||||
give_range = std::equal_range(m_GiveItemList.begin(),
|
||||
m_GiveItemList.end(), giveItem, CheckFirstOnly());
|
||||
|
||||
for(; give_range.first != give_range.second; ++give_range.first)
|
||||
{
|
||||
for(int nCount = 0; nCount < lpItemData->m_cNumOrDurability; ++nCount)
|
||||
{
|
||||
if (0 != dwUID)
|
||||
{
|
||||
m_UIDGiveItemMap.insert(GiveItemMap::value_type(dwUID, *give_range.first));
|
||||
}
|
||||
else if(0 != dwCID)
|
||||
{
|
||||
m_CIDGiveItemMap.insert(GiveItemMap::value_type(dwCID, *give_range.first));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
INFLOG5(g_Log, "UID:%10u / CID:%10u / PrototypeID:%6u / Num:%d / %s / "
|
||||
"아이템을 지급하기 위해 컨테이너에서 제거합니다",
|
||||
dwUID, dwCID, lpItemData->m_usProtoTypeID, lpItemData->m_cNumOrDurability, szPosition);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 아이템이 없다. 체커에 세팅하고 그냥 복사한다.
|
||||
if (0 != lpItemChecker)
|
||||
{
|
||||
// 아이템 체커가 있으면 위치 미리 삽입
|
||||
lpItemChecker->Set(lpItemData->m_ItemPos,
|
||||
lpItemInfo->m_DetailData.m_cXSize,
|
||||
lpItemInfo->m_DetailData.m_cYSize);
|
||||
}
|
||||
|
||||
// 데이터를 복사한다.
|
||||
memcpy(szDataPos_Out, lpItemData, lpItemData->m_cItemSize);
|
||||
szDataPos_Out += lpItemData->m_cItemSize;
|
||||
}
|
||||
}
|
||||
|
||||
szDataPos += lpItemData->m_cItemSize;
|
||||
}
|
||||
|
||||
dwDataSize_Out = static_cast<unsigned long>(szDataPos_Out - szData_Out);
|
||||
}
|
||||
|
||||
// 아이템을 찾아서 넣어 준다.
|
||||
void CGiveEventReward::GiveItemToContainer(unsigned long dwUID, unsigned long dwCID,
|
||||
RebalanceLib::CItemChecker& itemChecker, const char* szPosition,
|
||||
char* szData_InOut, unsigned long& dwDataSize_InOut,
|
||||
unsigned long dwMaxDataSize, bool bLastChance)
|
||||
{
|
||||
unsigned long dwKey = 0;
|
||||
GiveItemMap* lpGiveItemMap = 0;
|
||||
|
||||
if (0 != dwUID)
|
||||
{
|
||||
dwKey = dwUID;
|
||||
lpGiveItemMap = &m_UIDGiveItemMap;
|
||||
}
|
||||
else if (0 != dwCID)
|
||||
{
|
||||
dwKey = dwCID;
|
||||
lpGiveItemMap = &m_CIDGiveItemMap;
|
||||
}
|
||||
|
||||
if (0 != dwKey && 0 != lpGiveItemMap)
|
||||
{
|
||||
std::pair<GiveItemMap::iterator, GiveItemMap::iterator>
|
||||
find_range = lpGiveItemMap->equal_range(dwKey);
|
||||
|
||||
for(; find_range.first != find_range.second; )
|
||||
{
|
||||
// 줄 아이템을 확보했다.
|
||||
const Item::ItemInfo* lpItemInfo = find_range.first->second.second.first;
|
||||
unsigned char cItemNum = find_range.first->second.second.second;
|
||||
|
||||
// 쪼개서 넣는다던지 하는 건 코드로는 지원하지 않는다. (스크립트에서 제어가능)
|
||||
|
||||
Item::ItemPos emptyPos;
|
||||
|
||||
if (dwDataSize_InOut + sizeof(Item::ItemData) <= dwMaxDataSize &&
|
||||
itemChecker.FindEmptyPos(emptyPos,
|
||||
lpItemInfo->m_DetailData.m_cXSize, lpItemInfo->m_DetailData.m_cYSize))
|
||||
{
|
||||
Item::ItemData* lpItemData =
|
||||
reinterpret_cast<Item::ItemData*>(szData_InOut + dwDataSize_InOut);
|
||||
|
||||
lpItemData->m_dwUID = m_DBItemSerialMgr.GetNewItemSerial();
|
||||
lpItemData->m_usProtoTypeID = lpItemInfo->m_usProtoTypeID;
|
||||
lpItemData->m_ItemPos = emptyPos;
|
||||
lpItemData->m_cItemSize = sizeof(Item::ItemData);
|
||||
lpItemData->m_cNumOrDurability = cItemNum;
|
||||
|
||||
dwDataSize_InOut += sizeof(Item::ItemData);
|
||||
|
||||
itemChecker.Set(emptyPos,
|
||||
lpItemInfo->m_DetailData.m_cXSize, lpItemInfo->m_DetailData.m_cYSize);
|
||||
|
||||
// 아이템을 넣었으니, 제거한다.
|
||||
find_range.first = lpGiveItemMap->erase(find_range.first);
|
||||
|
||||
INFLOG7(g_Log, "UID:%10u / CID:%10u / PrototypeID:%6u / Num:%d / %s / Pos:%d / Index:0x%04X / "
|
||||
"아이템을 지급했습니다.",
|
||||
dwUID, dwCID, lpItemInfo->m_usProtoTypeID, cItemNum, szPosition,
|
||||
emptyPos.m_cPos, emptyPos.m_cIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(bLastChance)
|
||||
{
|
||||
// 데이터를 더 넣을 수 없습니다.
|
||||
ERRLOG5(g_Log, "UID:%10u / CID:%10u / PrototypeID:%6u / Num:%d / %s / "
|
||||
"데이터가 꽉 찼거나, 빈 공간이 없어서 아이템을 더 넣을 수 없습니다",
|
||||
dwUID, dwCID, lpItemInfo->m_usProtoTypeID, cItemNum, szPosition);
|
||||
}
|
||||
|
||||
// 아이템을 넣을 수 없으므로 그냥 진행.
|
||||
++find_range.first;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
161
Server/DBProcess/GiveEventReward/GiveEventReward.vcproj
Normal file
161
Server/DBProcess/GiveEventReward/GiveEventReward.vcproj
Normal file
@@ -0,0 +1,161 @@
|
||||
<?xml version="1.0" encoding="ks_c_5601-1987"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="GiveEventReward"
|
||||
ProjectGUID="{023C302D-BB9F-4D5B-8809-4636313342EF}"
|
||||
SccProjectName="SAK"
|
||||
SccAuxPath="SAK"
|
||||
SccLocalPath="SAK"
|
||||
SccProvider="SAK"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../Executable/$(ConfigurationName)"
|
||||
IntermediateDirectory="../Intermediate/$(ProjectName)/$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
UseOfATL="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../;../../RylServerProject;../../RylServerProject/BaseLibrary;../../RylServerProject/RylServerLibrary;../../RylServerProject/RylGameLibrary"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="2"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="4"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)/GiveEventReward.exe"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/GiveEventReward.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../Executable/$(ConfigurationName)"
|
||||
IntermediateDirectory="../Intermediate/$(ProjectName)/$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
UseOfATL="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../;../../RylServerProject;../../RylServerProject/BaseLibrary;../../RylServerProject/RylServerLibrary;../../RylServerProject/RylGameLibrary"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
RuntimeLibrary="0"
|
||||
UsePrecompiledHeader="2"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)/GiveEventReward.exe"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="소스 파일"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
|
||||
<File
|
||||
RelativePath=".\GiveEventReward.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\stdafx.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="헤더 파일"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
|
||||
<File
|
||||
RelativePath=".\stdafx.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="리소스 파일"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath=".\ReadMe.txt">
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
32
Server/DBProcess/GiveEventReward/ReadMe.txt
Normal file
32
Server/DBProcess/GiveEventReward/ReadMe.txt
Normal file
@@ -0,0 +1,32 @@
|
||||
========================================================================
|
||||
콘솔 응용 프로그램 : GiveEventReward 프로젝트 개요
|
||||
========================================================================
|
||||
|
||||
응용 프로그램 마법사에서 이 GiveEventReward 응용 프로그램을 만들었습니다.
|
||||
이 파일에는 GiveEventReward 응용 프로그램을 구성하는 각각의 파일에
|
||||
들어 있는 요약 설명이 포함되어 있습니다.
|
||||
|
||||
|
||||
GiveEventReward.vcproj
|
||||
응용 프로그램 마법사를 사용하여 생성한 VC++ 프로젝트의 기본 프로젝트 파일입니다.
|
||||
해당 파일을 생성한 Visual C++의 버전 정보를 비롯하여
|
||||
응용 프로그램 마법사에서 선택한 플랫폼, 구성 및
|
||||
프로젝트 기능에 대한 정보가 들어 있습니다.
|
||||
|
||||
GiveEventReward.cpp
|
||||
기본 응용 프로그램 소스 파일입니다.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
기타 표준 파일:
|
||||
|
||||
StdAfx.h 및 StdAfx.cpp는
|
||||
GiveEventReward.pch라는 이름의 PCH(미리 컴파일된 헤더) 파일과
|
||||
StdAfx.obj라는 이름의 미리 컴파일된 형식 파일을 빌드하는 데 사용됩니다.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
기타 참고:
|
||||
|
||||
응용 프로그램 마법사에서 사용하는 "TODO:" 주석은 사용자가 추가하거나 사용자 지정해야 하는
|
||||
소스 코드 부분을 나타냅니다.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
8
Server/DBProcess/GiveEventReward/stdafx.cpp
Normal file
8
Server/DBProcess/GiveEventReward/stdafx.cpp
Normal file
@@ -0,0 +1,8 @@
|
||||
// stdafx.cpp : 표준 포함 파일만 들어 있는 소스 파일입니다.
|
||||
// GiveEventReward.pch는 미리 컴파일된 헤더가 됩니다.
|
||||
// stdafx.obj에는 미리 컴파일된 형식 정보가 포함됩니다.
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
// TODO: 필요한 추가 헤더는
|
||||
// 이 파일이 아닌 STDAFX.H에서 참조합니다.
|
||||
15
Server/DBProcess/GiveEventReward/stdafx.h
Normal file
15
Server/DBProcess/GiveEventReward/stdafx.h
Normal file
@@ -0,0 +1,15 @@
|
||||
// stdafx.h : 자주 사용하지만 자주 변경되지는 않는
|
||||
// 표준 시스템 포함 파일 및 프로젝트 관련 포함 파일이
|
||||
// 들어 있는 포함 파일입니다.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <tchar.h>
|
||||
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // 일부 CString 생성자는 명시적으로 선언됩니다.
|
||||
|
||||
#include <atlbase.h>
|
||||
|
||||
// TODO: 프로그램에 필요한 추가 헤더는 여기에서 참조합니다.
|
||||
Reference in New Issue
Block a user