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>
1678 lines
53 KiB
C++
1678 lines
53 KiB
C++
// RebalanceOverItem.cpp : 콘솔 응용 프로그램에 대한 진입점을 정의합니다.
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "RebalanceOverItem.h"
|
|
#include "RebalanceQuery.h"
|
|
|
|
#define LOG_CONVERT0(str) { SERLOG0(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)); }
|
|
#define LOG_CONVERT3(str, arg1, arg2, arg3) { ERRLOG3(g_Log, (str), (arg1), (arg2), (arg3)); printf(str "\n", (arg1), (arg2), (arg3))); }
|
|
#define LOG_CONVERT4(str, arg1, arg2, arg3, arg4) { ERRLOG4(g_Log, (str), (arg1), (arg2), (arg3), (arg4)); printf(str "\n", (arg1), (arg2), (arg3), (arg4)); }
|
|
|
|
// 보상 관련 계산 수식
|
|
#define CALC_REWARDSTONE(value) ((value) * 10)
|
|
#define CALC_REWARDGOLD(value, arg1) ((value) / 8.0f * (arg1))
|
|
|
|
//CServerLog g_ItemLog("Remain-CSV_");
|
|
//CServerLog g_CalcLog("Reward-Calc_");
|
|
//CServerLog g_RewardLog("Reward-Result_");
|
|
//CServerLog g_Rebalance("Rebalance");
|
|
//CServerLog g_UIDCID("UIDCID");
|
|
CServerLog g_ItemList("OverItemList");
|
|
|
|
using namespace Item;
|
|
|
|
class CDBRebalanceOverItem :
|
|
public IDBCharInfoProcess,
|
|
public IDBCharItemProcess,
|
|
public IDBCharItemExProcess,
|
|
public IDBStoreProcess
|
|
{
|
|
public:
|
|
CDBRebalanceOverItem(ATL::CSession& session, Item::CItemMgr& ItemMgr, CDBItemSerialMgr& dbItemSerialMgr)
|
|
: m_Session(session), m_ItemMgr(ItemMgr), m_DBItemSerialMgr(dbItemSerialMgr), m_nOverItem(0) { }
|
|
~CDBRebalanceOverItem() { }
|
|
|
|
void SetUnified(const char* szFlag) { m_bUnified = (atoi(szFlag) != 0); }
|
|
bool GetUnified() { return m_bUnified; }
|
|
void SetSimulate(const char* szFlag) { m_bSimulated = (atoi(szFlag) != 0); }
|
|
bool GetSimulate() { return m_bSimulated; }
|
|
HRESULT SetTarget();
|
|
|
|
void StampRemainLog();
|
|
void PrintItemOptionList();
|
|
|
|
enum ProcessResult
|
|
{
|
|
FAILED = 0,
|
|
SUCCESS = 1,
|
|
SKIPPED = 2
|
|
};
|
|
|
|
private:
|
|
enum RewardItem
|
|
{
|
|
RHATARIUM = 2005,
|
|
RHATARIUM_COUPON = 10591,
|
|
GOLD_COUPON = 10592
|
|
};
|
|
|
|
enum Ratio
|
|
{
|
|
COUPONTORHATARIUM = 10,
|
|
COUPONTOGOLD = 100000000
|
|
};
|
|
|
|
enum MaxLimit
|
|
{
|
|
MAX_NAME = 1024,
|
|
MAX_ITEMSTACK = 200
|
|
};
|
|
|
|
typedef struct _CharInfo
|
|
{
|
|
unsigned long dwUID;
|
|
char szName[MAX_NAME];
|
|
} sCharInfo, *lpCharInfo;
|
|
|
|
typedef std::map<unsigned long, unsigned long> StoneRewardMap;
|
|
typedef std::map<unsigned long, unsigned __int64> GoldRewardMap;
|
|
typedef std::map<unsigned long, sCharInfo> CIDUIDMAP;
|
|
|
|
ATL::CSession& m_Session;
|
|
StoneRewardMap m_StoneMap;
|
|
GoldRewardMap m_GoldMap;
|
|
CIDUIDMAP m_CIDUIDMap;
|
|
|
|
Item::CItemMgr& m_ItemMgr;
|
|
CDBItemSerialMgr& m_DBItemSerialMgr;
|
|
bool m_bUnified;
|
|
bool m_bSimulated;
|
|
unsigned int m_nOverItem;
|
|
|
|
private:
|
|
virtual ConvertResult operator() (RylDBCommand::CCharData& charData_inOut);
|
|
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);
|
|
|
|
ProcessResult SetTargetAndCalcReward(unsigned long dwUID, unsigned long dwCID,
|
|
const char* szOriginalData, unsigned long dwOriginalSize);
|
|
|
|
void ReserveItemPos(RebalanceLib::CItemChecker& itemChecker, const char* szOriginalData, unsigned long dwOriginalSize);
|
|
|
|
bool RewardStone(unsigned long dwUID, unsigned long dwCID, RebalanceLib::CItemChecker& itemChecker,
|
|
const char* szPosition, char* szData_InOut, const unsigned long dwMaxDataSize, unsigned long& dwDataSize_InOut);
|
|
bool RewardGold(unsigned long dwKey, const char* szPosition, unsigned long& dwGold_InOut);
|
|
bool RewardGoldCoupon(unsigned long dwKey, RebalanceLib::CItemChecker& itemChecker,
|
|
const char* szPosition, char* szData_InOut, const unsigned long dwMaxDataSize, unsigned long& dwDataSize_InOut);
|
|
bool RewardGoldAndCoupon(unsigned long dwKey, unsigned long& dwGold_InOut, RebalanceLib::CItemChecker& itemChecker,
|
|
const char* szPosition, char* szData_InOut, const unsigned long dwMaxDataSize, unsigned long& dwDataSize_InOut);
|
|
|
|
void PrintItemOption(Item::CEquipment* lpEquipment, short* lpAttribute, unsigned long dwKey);
|
|
|
|
bool TransferReward();
|
|
|
|
void CalcReward(const Item::CItemType::ArrayType eEquipType, Item::CEquipment* lpEquipment, short* lpAttrFactor, short* lpAttrValue,
|
|
unsigned long& dwStone, unsigned __int64& dwGold, unsigned long dwKey);
|
|
void AddReward(unsigned long dwUIDCID, unsigned long dwStone, unsigned __int64 dwGold);
|
|
|
|
float CalcAttribute(Item::CEquipment* lpEquipment, Item::Attribute::Type eAttributeType, unsigned long dwKey, short attrFactor, short attrValue);
|
|
void GetAttrString(Item::Attribute::Type eAttributeType, char* lpString);
|
|
|
|
bool IsExistCID(const unsigned long dwCID);
|
|
bool IsExistUID(const unsigned long dwUID);
|
|
unsigned long GetUIDByCID(const unsigned long dwCID);
|
|
bool GetCharNameByCID(const unsigned long dwCID, char* szCharName);
|
|
};
|
|
|
|
void PrintUsage()
|
|
{
|
|
printf("usage : RebalanceOverItem.exe DBAddress DBName DBAccount DBPassword ServerGroupNum(0~9) FlagUnified(0/1) FlagSimulate(0/1)\n");
|
|
}
|
|
|
|
int _tmain(int argc, _TCHAR* argv[])
|
|
{
|
|
bool bError = FALSE;
|
|
|
|
if(8 != argc)
|
|
{
|
|
PrintUsage();
|
|
return -1;
|
|
}
|
|
|
|
if(!Item::CItemMgr::GetInstance().LoadItemProtoType("./ItemScript.txt"))
|
|
{
|
|
LOG_CONVERT0("ItemScript.txt load failed\n");
|
|
return -1;
|
|
}
|
|
|
|
CoInitialize(0);
|
|
g_SessionLog.Disable(0xFFFFFFFF);
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
ATL::CDataSource ds;
|
|
ATL::CSession session;
|
|
CDBItemSerialMgr dbItemSerialMgr;
|
|
SERVER_ID serverID;
|
|
|
|
serverID.sID.Type = CServerSetup::AuthServer;
|
|
serverID.sID.Group = static_cast<char>(atoi(argv[5]));
|
|
serverID.sID.Channel = 0;
|
|
serverID.sID.ID = 0;
|
|
|
|
|
|
// 데이터베이스 오픈
|
|
if(FAILED(hr = CRylDBProcess::ConnectDB(ds, argv[1], argv[2], argv[3], argv[4])))
|
|
{
|
|
LOG_CONVERT1("Connect DB failed : hr:0x%08X", hr);
|
|
}
|
|
else if(FAILED(hr = session.Open(ds)))
|
|
{
|
|
LOG_CONVERT1("Open session failed : hr:0x%08X", hr);
|
|
}
|
|
else if(FAILED(hr = dbItemSerialMgr.ClearAllSerialDB(session)))
|
|
{
|
|
LOG_CONVERT1("Clear itemSerial failed : hr:0x%08X", hr);
|
|
}
|
|
else if(FAILED(hr = dbItemSerialMgr.LoadItemSerialDB(session, serverID.dwID)))
|
|
{
|
|
LOG_CONVERT1("Insert itemSerial 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(100);
|
|
CDBRebalanceOverItem processItem(session, Item::CItemMgr::GetInstance(), dbItemSerialMgr);
|
|
|
|
processItem.SetUnified(argv[6]);
|
|
processItem.SetSimulate(argv[7]);
|
|
processItem.SetTarget();
|
|
processItem.PrintItemOptionList();
|
|
|
|
LOG_CONVERT0("Start Reward");
|
|
|
|
const int MAX_QUERY_BUFFER = 1024;
|
|
char szQueryBuffer[MAX_QUERY_BUFFER];
|
|
int nServerType;
|
|
|
|
if(processItem.GetUnified())
|
|
{
|
|
nServerType = 23;
|
|
}
|
|
else
|
|
{
|
|
nServerType = 22;
|
|
}
|
|
|
|
_snprintf(szQueryBuffer, MAX_QUERY_BUFFER, QUERYZ::Char,
|
|
"CharItemEx",
|
|
"Char1 as CID", nServerType,
|
|
"Char2 as CID", nServerType,
|
|
"Char3 as CID", nServerType,
|
|
"Char4 as CID", nServerType,
|
|
"Char5 as CID", nServerType,
|
|
"A.CID = B.CID"
|
|
);
|
|
|
|
szQueryBuffer[MAX_QUERY_BUFFER - 1] = '\0';
|
|
|
|
SERLOG0(g_Log, "StartCharItemEx");
|
|
if (FAILED(hr = dbProcess.CharItemEx(processItem, consoleCounter, szQueryBuffer)))
|
|
{
|
|
LOG_CONVERT1("CharItemEx process failed : hr:0x%08x", hr);
|
|
bError = TRUE;
|
|
}
|
|
|
|
_snprintf(szQueryBuffer, MAX_QUERY_BUFFER, QUERYZ::Char,
|
|
"CharItem",
|
|
"Char1 as CID", nServerType,
|
|
"Char2 as CID", nServerType,
|
|
"Char3 as CID", nServerType,
|
|
"Char4 as CID", nServerType,
|
|
"Char5 as CID", nServerType,
|
|
"A.CID = B.CID"
|
|
);
|
|
|
|
szQueryBuffer[MAX_QUERY_BUFFER - 1] = '\0';
|
|
|
|
SERLOG0(g_Log, "StartCharItem");
|
|
if (FAILED(hr = dbProcess.CharItem(processItem, consoleCounter, szQueryBuffer)))
|
|
{
|
|
LOG_CONVERT1("Add Reward(Inven Stone/Gold) process failed : hr:0x%08x", hr);
|
|
bError = TRUE;
|
|
}
|
|
|
|
_snprintf(szQueryBuffer, MAX_QUERY_BUFFER, QUERYZ::Char,
|
|
"CharInfo",
|
|
"Char1 as CID", nServerType,
|
|
"Char2 as CID", nServerType,
|
|
"Char3 as CID", nServerType,
|
|
"Char4 as CID", nServerType,
|
|
"Char5 as CID", nServerType,
|
|
"A.CID = B.CID"
|
|
);
|
|
|
|
szQueryBuffer[MAX_QUERY_BUFFER - 1] = '\0';
|
|
|
|
|
|
SERLOG0(g_Log, "StartCharInfo");
|
|
if (FAILED(hr = dbProcess.CharInfo(processItem, consoleCounter, szQueryBuffer)))
|
|
{
|
|
LOG_CONVERT1("Add Reward(CharacterInfo Gold) process failed : hr:0x%08x", hr);
|
|
bError = TRUE;
|
|
}
|
|
|
|
_snprintf(szQueryBuffer, MAX_QUERY_BUFFER, QUERYZ::Store,
|
|
"TblUnifiedItemStore2",
|
|
"UID", nServerType,
|
|
"UID", nServerType,
|
|
"UID", nServerType,
|
|
"UID", nServerType,
|
|
"UID", nServerType,
|
|
"A.UID = B.UID"
|
|
);
|
|
|
|
szQueryBuffer[MAX_QUERY_BUFFER - 1] = '\0';
|
|
|
|
|
|
SERLOG0(g_Log, "StartStore2");
|
|
if (FAILED(hr = dbProcess.UnifiedStore2(processItem, consoleCounter, szQueryBuffer)))
|
|
{
|
|
LOG_CONVERT1("Add Reward(UnfiedStore1 Stone) process failed : hr:0x%08x", hr);
|
|
bError = TRUE;
|
|
}
|
|
|
|
_snprintf(szQueryBuffer, MAX_QUERY_BUFFER, QUERYZ::Store,
|
|
"TblUnifiedItemStore1",
|
|
"UID", nServerType,
|
|
"UID", nServerType,
|
|
"UID", nServerType,
|
|
"UID", nServerType,
|
|
"UID", nServerType,
|
|
"A.UID = B.UID"
|
|
);
|
|
|
|
szQueryBuffer[MAX_QUERY_BUFFER - 1] = '\0';
|
|
|
|
SERLOG0(g_Log, "StartStore1");
|
|
if (FAILED(hr = dbProcess.UnifiedStore1(processItem, consoleCounter, szQueryBuffer)))
|
|
{
|
|
LOG_CONVERT1("Add Reward(UnfiedStore1 Stone/Gold) process failed : hr:0x%08x", hr);
|
|
bError = TRUE;
|
|
}
|
|
|
|
// 보상되지 않은 내역 로그 추출
|
|
processItem.StampRemainLog();
|
|
}
|
|
catch(...)
|
|
{
|
|
bError = TRUE;
|
|
|
|
LOG_CONVERT0("Exception occured! rollback transaction now!");
|
|
|
|
if(FAILED(hr = session.Abort()))
|
|
{
|
|
LOG_CONVERT1("Rollback transaction failed! : hr:0x%08x", hr);
|
|
}
|
|
else
|
|
{
|
|
SERLOG1(g_Log, "Rollback transaction succeeded! : hr:0x%08x", hr);
|
|
}
|
|
}
|
|
|
|
SERLOG0(g_Log, "Commit transaction now!");
|
|
|
|
if(FAILED(hr = session.Commit()))
|
|
{
|
|
LOG_CONVERT1("Commit transaction failed! : hr:0x%08x", hr);
|
|
}
|
|
else
|
|
{
|
|
SERLOG1(g_Log, "Commit transaction succeeded! : hr:0x%08x", hr);
|
|
}
|
|
}
|
|
|
|
session.Close();
|
|
ds.Close();
|
|
|
|
CoUninitialize();
|
|
|
|
if(true == bError)
|
|
{
|
|
LOG_CONVERT0("Rebalance incomplete!!");
|
|
return -1;
|
|
}
|
|
else
|
|
{
|
|
LOG_CONVERT0("Rebalance Complete");
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void CDBRebalanceOverItem::StampRemainLog()
|
|
{
|
|
unsigned long dwUIDCID = 0, dwStone = 0;
|
|
unsigned __int64 dwGold = 0;
|
|
unsigned int nCntStone = 0, nCntGold = 0;
|
|
size_t nMapStone = m_StoneMap.size(), nMapGold = m_GoldMap.size();
|
|
|
|
StoneRewardMap::iterator stone_pos = m_StoneMap.begin();
|
|
StoneRewardMap::iterator stone_end = m_StoneMap.end();
|
|
|
|
//SERLOG0(g_ItemLog, "보상되지 않은 값들입니다. CSV 형태로 찍히니 엑셀로 보는게 편할듯.");
|
|
//SERLOG2(g_ItemLog, "%-20s: %u개 발견.", "오버 아이템", m_nOverItem);
|
|
//SERLOG3(g_ItemLog, "%-20s: 제련석 %u건, 골드 %u건", "잔여 보상 데이터", nMapStone, nMapGold);
|
|
|
|
//ERRLOG0(g_ItemLog, "\tdwKey\tStone\tGold\t\t\t\t");
|
|
for(; stone_pos != stone_end; ++stone_pos)
|
|
{
|
|
dwUIDCID = stone_pos->first;
|
|
dwStone = stone_pos->second;
|
|
dwGold = 0;
|
|
++nCntStone;
|
|
|
|
GoldRewardMap::iterator itr = m_GoldMap.find(dwUIDCID);
|
|
|
|
if (m_GoldMap.end() != itr)
|
|
{
|
|
dwGold = itr->second;
|
|
++nCntGold;
|
|
|
|
m_GoldMap.erase(itr);
|
|
}
|
|
|
|
//ERRLOG3(g_ItemLog, "\t%u\t%u\t%u\t\t\t\t", dwUIDCID, dwStone, dwGold);
|
|
}
|
|
|
|
GoldRewardMap::iterator gold_pos = m_GoldMap.begin();
|
|
GoldRewardMap::iterator gold_end = m_GoldMap.end();
|
|
|
|
for(; gold_pos != gold_end; ++gold_pos)
|
|
{
|
|
dwUIDCID = gold_pos->first;
|
|
dwStone = 0;
|
|
dwGold = gold_pos->second;
|
|
++nCntGold;
|
|
|
|
/*ERRLOG3(g_ItemLog, "\t%u\t%u\t%u\t\t\t\t", dwUIDCID, dwStone, dwGold);*/
|
|
}
|
|
|
|
/*SERLOG4(g_ItemLog, "Checksum. nCntStone(%u)/nMapStone(%u) nCntGold(%u)/nMapGold(%u)", nCntStone, nMapStone, nCntGold, nMapGold);*/
|
|
}
|
|
|
|
ConvertResult CDBRebalanceOverItem::operator() (RylDBCommand::CCharItem& charItem_InOut)
|
|
{
|
|
unsigned long dwCID = charItem_InOut.GetCID();
|
|
ProcessResult nResult[3] = { FAILED };
|
|
|
|
const EQUIP& equip_In = charItem_InOut.GetEquip();
|
|
const INVEN& inven_In = charItem_InOut.GetInven();
|
|
const EXTRA& extra_In = charItem_InOut.GetExtra();
|
|
|
|
if(FAILED == (nResult[0] = SetTargetAndCalcReward(0, dwCID,
|
|
equip_In.Data, equip_In.dwSize)))
|
|
{
|
|
LOG_CONVERT1("CID:%10u / Equip convert failed", dwCID);
|
|
return CONVERT_FAILED;
|
|
}
|
|
else if(FAILED == (nResult[1] = SetTargetAndCalcReward(0, dwCID,
|
|
extra_In.Data, extra_In.dwSize)))
|
|
{
|
|
LOG_CONVERT1("CID:%10u / Extra convert failed", dwCID);
|
|
return CONVERT_FAILED;
|
|
}
|
|
else if(FAILED == (nResult[2] = SetTargetAndCalcReward(0, dwCID,
|
|
inven_In.Data, inven_In.dwSize)))
|
|
{
|
|
LOG_CONVERT1("CID:%10u / Inventory convert failed", dwCID);
|
|
return CONVERT_FAILED;
|
|
}
|
|
|
|
//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));
|
|
|
|
//equip_Out.dwSize = EQUIP::MAX_EQUIP_SIZE;
|
|
//inven_Out.dwSize = INVEN::MAX_INVEN_SIZE;
|
|
//extra_Out.dwSize = EXTRA::MAX_EXTRA_SIZE;
|
|
|
|
//memcpy(&equip_Out, &equip_In, sizeof(EQUIP));
|
|
//memcpy(&inven_Out, &inven_In, sizeof(INVEN));
|
|
//memcpy(&extra_Out, &extra_In, sizeof(EXTRA));
|
|
|
|
//RebalanceLib::CItemArrayChecker<
|
|
// ContainerConstant::INVENTORY_WIDTH,
|
|
// ContainerConstant::INVENTORY_HEIGHT,
|
|
// ContainerConstant::MAX_INVENTORY_TAB> invenChecker(TakeType::TS_INVEN);
|
|
|
|
//invenChecker.FillTab(3);
|
|
|
|
//ReserveItemPos(invenChecker, inven_In.Data, inven_In.dwSize);
|
|
|
|
//if(!RewardGoldCoupon(dwCID, invenChecker, "[INVEN]", inven_Out.Data, INVEN::MAX_INVEN_SIZE, inven_Out.dwSize) && 0 != inven_Out.dwSize)
|
|
//{
|
|
// LOG_CONVERT1("CID:%10u / Gold reward failed", dwCID);
|
|
// return CONVERT_FAILED;
|
|
//}
|
|
//else if(!RewardStone(0, dwCID, invenChecker, "[INVEN]", inven_Out.Data, INVEN::MAX_INVEN_SIZE, inven_Out.dwSize) && 0 != inven_Out.dwSize)
|
|
//{
|
|
// LOG_CONVERT1("CID:%10u / Stone reward failed", dwCID);
|
|
// return CONVERT_FAILED;
|
|
//}
|
|
|
|
/*if(false == GetSimulate())
|
|
{
|
|
charItem_InOut.SetInven(inven_Out);
|
|
|
|
return CONVERT_SUCCEEDED;
|
|
}
|
|
else
|
|
{
|
|
return CONVERT_DO_NOT_WRITE;
|
|
}*/
|
|
return CONVERT_DO_NOT_WRITE;
|
|
}
|
|
|
|
ConvertResult CDBRebalanceOverItem::operator() (RylDBCommand::CCharData& charData_InOut)
|
|
{
|
|
//unsigned long dwCID = charData_InOut.GetCID();
|
|
//unsigned long dwGold = charData_InOut.GetGold();
|
|
|
|
//SERLOG1(g_Log, "CharInfo Start : %u", dwCID);
|
|
//// 보상 전용 프로세스이므로 보상 처리 상황이 아니면 실행해서는 안된다.
|
|
//if(!RewardGold(dwCID, "[CHARINFO]", dwGold))
|
|
//{
|
|
// LOG_CONVERT1("CID:%10u / Gold reward failed", dwCID);
|
|
// return CONVERT_FAILED;
|
|
//}
|
|
//else
|
|
//{
|
|
// if(false == GetSimulate())
|
|
// {
|
|
// charData_InOut.SetGold(dwGold);
|
|
|
|
// return CONVERT_SUCCEEDED;
|
|
// }
|
|
// else
|
|
// {
|
|
// return CONVERT_DO_NOT_WRITE;
|
|
// }
|
|
//}
|
|
return CONVERT_DO_NOT_WRITE;
|
|
}
|
|
|
|
ConvertResult CDBRebalanceOverItem::operator() (RylDBCommand::CCharItemEx& charItemEx_InOut)
|
|
{
|
|
unsigned long dwCID = charItemEx_InOut.GetCID();
|
|
ProcessResult nResult[2] = { FAILED };
|
|
|
|
const EXCHANGE& exchange_In = charItemEx_InOut.GetExchange();
|
|
const TEMPINVEN& tempInven_In = charItemEx_InOut.GetTempInven();
|
|
|
|
if(FAILED == (nResult[0] = SetTargetAndCalcReward(0, dwCID,
|
|
exchange_In.Data, exchange_In.dwSize)))
|
|
{
|
|
LOG_CONVERT1("CID:%10u / Exchange convert failed", dwCID);
|
|
return CONVERT_FAILED;
|
|
}
|
|
else if(FAILED == (nResult[1] = SetTargetAndCalcReward(0, dwCID,
|
|
tempInven_In.Data, tempInven_In.dwSize)))
|
|
{
|
|
LOG_CONVERT1("CID:%10u / TempInven convert failed", dwCID);
|
|
return CONVERT_FAILED;
|
|
}
|
|
|
|
return CONVERT_DO_NOT_WRITE;
|
|
}
|
|
|
|
ConvertResult CDBRebalanceOverItem::operator() (RylDBCommand::CUnifiedStore1& unifiedStore1_InOut)
|
|
{
|
|
unsigned long dwUID = unifiedStore1_InOut.GetUID();
|
|
ProcessResult nResult = FAILED;
|
|
|
|
if(GetUnified() && 23 != unifiedStore1_InOut.GetOldServerGroupID())
|
|
{
|
|
return CONVERT_DO_NOT_WRITE;
|
|
}
|
|
|
|
const STORE& store_In = unifiedStore1_InOut.GetStore();
|
|
|
|
|
|
if(FAILED == (nResult = SetTargetAndCalcReward(dwUID, 0,
|
|
store_In.Data, store_In.dwSize)))
|
|
{
|
|
LOG_CONVERT2("UID:%10u / OldServerGroupID:%d / Store convert failed",
|
|
dwUID, unifiedStore1_InOut.GetOldServerGroupID());
|
|
return CONVERT_FAILED;
|
|
}
|
|
|
|
/*STORE store_Out;
|
|
memset(&store_Out, 0, sizeof(STORE));
|
|
store_Out.dwSize = STORE::MAX_STORE_SIZE;
|
|
memcpy(&store_Out, &store_In, sizeof(STORE));
|
|
|
|
unsigned long dwGold = unifiedStore1_InOut.GetGold();
|
|
|
|
RebalanceLib::CItemArrayChecker<
|
|
ContainerConstant::DEPOSIT_WIDTH,
|
|
ContainerConstant::DEPOSIT_HEIGHT,
|
|
ContainerConstant::MAX_DEPOSIT_TAB> storeChecker(TakeType::TS_DEPOSIT);
|
|
|
|
storeChecker.FillTab(2);
|
|
storeChecker.FillTab(3);
|
|
|
|
ReserveItemPos(storeChecker, store_In.Data, store_In.dwSize);
|
|
|
|
if(!RewardGoldAndCoupon(dwUID, dwGold, storeChecker, "[UNIFIED_STORE1]", store_Out.Data, STORE::MAX_STORE_SIZE, store_Out.dwSize))
|
|
{
|
|
LOG_CONVERT2("UID:%10u / OldServerGroupID:%d / Gold reward failed",
|
|
dwUID, unifiedStore1_InOut.GetOldServerGroupID());
|
|
|
|
}
|
|
else if(!RewardStone(dwUID, 0, storeChecker, "[UNIFIED_STORE1]", store_Out.Data, STORE::MAX_STORE_SIZE, store_Out.dwSize))
|
|
{
|
|
LOG_CONVERT2("UID:%10u / OldServerGroupID:%d / Stone reward failed",
|
|
dwUID, unifiedStore1_InOut.GetOldServerGroupID());
|
|
}*/
|
|
|
|
/*if(false == GetSimulate())
|
|
{
|
|
unifiedStore1_InOut.SetGold(dwGold);
|
|
unifiedStore1_InOut.SetStore(store_Out);
|
|
|
|
return CONVERT_SUCCEEDED;
|
|
}
|
|
else
|
|
{
|
|
return CONVERT_DO_NOT_WRITE;
|
|
}*/
|
|
return CONVERT_DO_NOT_WRITE;
|
|
}
|
|
|
|
ConvertResult CDBRebalanceOverItem::operator() (RylDBCommand::CUnifiedStore2& unifiedStore2_InOut)
|
|
{
|
|
TransferReward();
|
|
|
|
unsigned long dwUID = unifiedStore2_InOut.GetUID();
|
|
ProcessResult nResult = FAILED;
|
|
|
|
if(GetUnified() && 23 != unifiedStore2_InOut.GetOldServerGroupID())
|
|
{
|
|
return CONVERT_DO_NOT_WRITE;
|
|
}
|
|
|
|
const STORE& store_In = unifiedStore2_InOut.GetStore();
|
|
|
|
if(FAILED == (nResult = SetTargetAndCalcReward(dwUID, 0,
|
|
store_In.Data, store_In.dwSize)))
|
|
{
|
|
LOG_CONVERT2("UID:%10u / OldServerGroupID:%d / Store convert failed",
|
|
dwUID, unifiedStore2_InOut.GetOldServerGroupID());
|
|
return CONVERT_FAILED;
|
|
}
|
|
|
|
/*STORE store_Out;
|
|
memset(&store_Out, 0, sizeof(STORE));
|
|
store_Out.dwSize = STORE::MAX_STORE_SIZE;
|
|
memcpy(&store_Out, &store_In, sizeof(STORE));
|
|
|
|
RebalanceLib::CItemArrayChecker<
|
|
ContainerConstant::DEPOSIT_WIDTH,
|
|
ContainerConstant::DEPOSIT_HEIGHT,
|
|
ContainerConstant::MAX_DEPOSIT_TAB> storeChecker(TakeType::TS_DEPOSIT);
|
|
|
|
storeChecker.FillTab(0);
|
|
storeChecker.FillTab(1);
|
|
|
|
ReserveItemPos(storeChecker, store_In.Data, store_In.dwSize);
|
|
|
|
if(!RewardGoldCoupon(dwUID, storeChecker, "[UNIFIED_STORE2]", store_Out.Data, STORE::MAX_STORE_SIZE, store_Out.dwSize))
|
|
{
|
|
LOG_CONVERT2("UID:%10u / OldServerGroupID:%d / GoldCoupon reward failed",
|
|
dwUID, unifiedStore2_InOut.GetOldServerGroupID());
|
|
}
|
|
else if(!RewardStone(dwUID, 0, storeChecker, "[UNIFIED_STORE2]", store_Out.Data, STORE::MAX_STORE_SIZE, store_Out.dwSize))
|
|
{
|
|
LOG_CONVERT2("UID:%10u / OldServerGroupID:%d / Stone reward failed",
|
|
dwUID, unifiedStore2_InOut.GetOldServerGroupID());
|
|
}*/
|
|
|
|
//if(false == GetSimulate())
|
|
//{
|
|
// unifiedStore2_InOut.SetStore(store_Out);
|
|
// return CONVERT_SUCCEEDED;
|
|
//}
|
|
//else
|
|
//{
|
|
// return CONVERT_DO_NOT_WRITE;
|
|
//}
|
|
return CONVERT_DO_NOT_WRITE;
|
|
}
|
|
|
|
CDBRebalanceOverItem::ProcessResult CDBRebalanceOverItem::SetTargetAndCalcReward(unsigned long dwUID, unsigned long dwCID,
|
|
const char* szOriginalData, unsigned long dwOriginalSize)
|
|
{
|
|
const char* szPos = szOriginalData;
|
|
const char* szEnd = szOriginalData + dwOriginalSize;
|
|
|
|
bool bConvert = FALSE;
|
|
|
|
char szString[20] = {0};
|
|
|
|
Item::CEquipment* lpEquipment = NULL;
|
|
|
|
Item::Grade::GradeInfo convertedGrade;
|
|
|
|
if(0 != dwUID || 0 != dwCID)
|
|
{
|
|
unsigned long dwKey = (0 !=dwUID) ? dwUID : dwCID;
|
|
|
|
/*SERLOG1(g_UIDCID, "dwKey : %10u", dwKey);*/
|
|
|
|
for(; szPos < szEnd;)
|
|
{
|
|
const Item::ItemData* lpItemData = reinterpret_cast<const Item::ItemData*>(szPos);
|
|
const Item::ItemInfo* lpItemInfo = m_ItemMgr.GetItemInfo(lpItemData->m_usProtoTypeID);
|
|
|
|
if(0 == lpItemInfo)
|
|
{
|
|
LOG_CONVERT4("UID:%10u / CID:%10u / Serial:0x%016I64X / ProtoType:%6d / Script has not this item",
|
|
dwUID, dwCID, lpItemData->m_dwUID, lpItemData->m_usProtoTypeID);
|
|
|
|
return SKIPPED;
|
|
}
|
|
else if(0 != (lpItemInfo->m_DetailData.m_dwFlags & Item::DetailData::EQUIP) &&
|
|
sizeof(Item::ItemData) + sizeof(Item::EquipmentInfo) <= lpItemData->m_cItemSize)
|
|
{
|
|
// 장비인 경우 아이템 컨버팅을 한다.
|
|
// 아래에 해당하는 아이템은 컨버트 하지 않는다.
|
|
switch(lpItemInfo->m_DetailData.m_cItemType)
|
|
{
|
|
case Item::ItemType::SHIRT:
|
|
case Item::ItemType::TUNIC:
|
|
case Item::ItemType::CON_HELM:
|
|
case Item::ItemType::CON_GLOVE:
|
|
case Item::ItemType::CON_BOOTS:
|
|
case Item::ItemType::DEX_HELM:
|
|
case Item::ItemType::DEX_GLOVE:
|
|
case Item::ItemType::DEX_BOOTS:
|
|
case Item::ItemType::CON_HEAD:
|
|
case Item::ItemType::CON_PELVIS:
|
|
case Item::ItemType::CON_PROTECT_A:
|
|
case Item::ItemType::DEX_HEAD:
|
|
case Item::ItemType::DEX_PELVIS:
|
|
case Item::ItemType::DEX_PROTECT_A:
|
|
case Item::ItemType::NECKLACE:
|
|
case Item::ItemType::RING:
|
|
case Item::ItemType::RUNE:
|
|
bConvert = FALSE;
|
|
break;
|
|
default:
|
|
bConvert = TRUE;
|
|
break;
|
|
}
|
|
|
|
lpEquipment = static_cast<Item::CEquipment*>(Item::CItemFactory::GetInstance().CreateTempItem(*lpItemInfo));
|
|
|
|
if(NULL == lpEquipment)
|
|
{
|
|
LOG_CONVERT4("UID:%10u / CID:%10u / Serial:0x%016I64X / ProtoType:%6d / Class allocation failed",
|
|
dwUID, dwCID, lpItemData->m_dwUID, lpItemData->m_usProtoTypeID);
|
|
|
|
return FAILED;
|
|
}
|
|
else
|
|
{
|
|
short AttrFactor[ Item::Attribute::MAX_ATTRIBUTE_NUM ] = {0};
|
|
short AttrValue[ Item::Attribute::MAX_ATTRIBUTE_NUM ] = {0};
|
|
|
|
const Item::CItemType::ArrayType eEquipType =
|
|
Item::CItemType::GetEquipType(lpItemInfo->m_DetailData.m_dwFlags);
|
|
|
|
lpEquipment->GetLimitValue(AttrValue);
|
|
lpEquipment->SetUID(lpItemData->m_dwUID);
|
|
|
|
size_t DataSize_InOut = 0;
|
|
|
|
DataSize_InOut = sizeof(Item::ItemData);
|
|
|
|
if(false == lpEquipment->SerializeIn(reinterpret_cast<const char*>(lpItemData), DataSize_InOut))
|
|
{
|
|
LOG_CONVERT4("UID:%10u / CID:%10u / Serial:0x%016I64X / ProtoType:%6d / Serializein failed",
|
|
dwUID, dwCID, lpItemData->m_dwUID, lpItemData->m_usProtoTypeID);
|
|
|
|
return FAILED;
|
|
}
|
|
else
|
|
{
|
|
Item::Grade::GradeInfo itemGrade = lpEquipment->GetItemGrade();
|
|
|
|
if(Item::EquipType::S_GRADE == itemGrade.m_eItemGrade && true == bConvert)
|
|
{
|
|
++m_nOverItem;
|
|
|
|
lpEquipment->GetSubRuneAttribute(AttrFactor);
|
|
|
|
// 아이템 옵션 로그 출력
|
|
PrintItemOption(lpEquipment, AttrFactor, dwKey);
|
|
|
|
//// 보상 값 계산
|
|
//unsigned long dwStone = 0;
|
|
//unsigned __int64 dwGold = 0;
|
|
//CalcReward(eEquipType, lpEquipment, AttrFactor, AttrValue, dwStone, dwGold, dwKey);
|
|
|
|
// 보상 내용 저장
|
|
/*AddReward(dwKey, dwStone, dwGold);*/
|
|
}
|
|
}
|
|
}
|
|
|
|
if(NULL != lpEquipment)
|
|
{
|
|
Item::CItemFactory::GetInstance().DeleteItem(lpEquipment);
|
|
lpEquipment = NULL;
|
|
}
|
|
}
|
|
|
|
szPos += lpItemData->m_cItemSize;
|
|
}
|
|
}
|
|
|
|
return SUCCESS;
|
|
}
|
|
|
|
void CDBRebalanceOverItem::ReserveItemPos(RebalanceLib::CItemChecker& itemChecker, const char* szOriginalData, unsigned long dwOriginalSize)
|
|
{
|
|
const char* szPos = szOriginalData;
|
|
const char* szEnd = szOriginalData + dwOriginalSize;
|
|
|
|
for(; szPos < szEnd;)
|
|
{
|
|
const Item::ItemData* lpItemData = reinterpret_cast<const Item::ItemData*>(szPos);
|
|
const Item::ItemInfo* lpItemInfo = m_ItemMgr.GetItemInfo(lpItemData->m_usProtoTypeID);
|
|
|
|
if(0 == lpItemInfo)
|
|
{
|
|
ERRLOG2(g_Log, "Serial:0x%016I64X / ProtoType:%6d / Script has not this item",
|
|
lpItemData->m_dwUID, lpItemData->m_usProtoTypeID);
|
|
}
|
|
else
|
|
{
|
|
itemChecker.Set(lpItemData->m_ItemPos,
|
|
lpItemInfo->m_DetailData.m_cXSize, lpItemInfo->m_DetailData.m_cYSize);
|
|
|
|
}
|
|
|
|
szPos += lpItemData->m_cItemSize;
|
|
}
|
|
}
|
|
|
|
bool CDBRebalanceOverItem::TransferReward()
|
|
{
|
|
|
|
unsigned long dwCID, dwUID;
|
|
StoneRewardMap::iterator stone_itr_UID;
|
|
GoldRewardMap::iterator gold_itr_UID;
|
|
StoneRewardMap::iterator stone_itr_Temp;
|
|
GoldRewardMap::iterator gold_itr_Temp;
|
|
|
|
for (StoneRewardMap::iterator itr = m_StoneMap.begin(); itr != m_StoneMap.end(); ++itr)
|
|
{
|
|
if (IsExistCID(itr->first))
|
|
{
|
|
dwCID = itr->first;
|
|
dwUID = GetUIDByCID(dwCID);
|
|
if (0 != dwUID)
|
|
{
|
|
stone_itr_UID = m_StoneMap.find(dwUID);
|
|
|
|
if(m_StoneMap.end() == stone_itr_UID)
|
|
{
|
|
m_StoneMap.insert(std::make_pair(dwUID, itr->second));
|
|
}
|
|
else
|
|
{
|
|
stone_itr_UID->second += itr->second;
|
|
}
|
|
itr->second = 0;
|
|
stone_itr_Temp = itr;
|
|
itr++;
|
|
m_StoneMap.erase(stone_itr_Temp);
|
|
}
|
|
else
|
|
{
|
|
/*ERRLOG4(g_RewardLog, "StoneTransfer Fail CID : %10u, itr_CID : 0x%10x / UID : %10u, itr_UID : 0x%10x",
|
|
dwCID, itr, dwUID, stone_itr_UID);*/
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (GoldRewardMap::iterator itr = m_GoldMap.begin(); itr != m_GoldMap.end(); ++itr)
|
|
{
|
|
if (IsExistCID(itr->first))
|
|
{
|
|
dwCID = itr->first;
|
|
dwUID = GetUIDByCID(dwCID);
|
|
if (0 != dwUID)
|
|
{
|
|
gold_itr_UID = m_GoldMap.find(dwUID);
|
|
|
|
if(m_GoldMap.end() == gold_itr_UID)
|
|
{
|
|
if(_UI64_MAX >= itr->second)
|
|
{
|
|
m_GoldMap.insert(std::make_pair(dwUID, itr->second));
|
|
}
|
|
else
|
|
{
|
|
m_GoldMap.insert(std::make_pair(dwUID, _UI64_MAX));
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
if(_UI64_MAX >= gold_itr_UID->second + itr->second)
|
|
{
|
|
gold_itr_UID->second += itr->second;
|
|
}
|
|
else
|
|
{
|
|
gold_itr_UID->second = _UI64_MAX;
|
|
}
|
|
|
|
}
|
|
|
|
itr->second = 0;
|
|
gold_itr_Temp = itr;
|
|
itr++;
|
|
m_GoldMap.erase(gold_itr_Temp);
|
|
|
|
}
|
|
else
|
|
{
|
|
/*ERRLOG4(g_RewardLog, "GoldTransfer Fail CID : %10u, itr_CID : 0x%10x / UID : %10u, itr_UID : 0x%10x",
|
|
dwCID, itr, dwUID, gold_itr_UID);*/
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CDBRebalanceOverItem::RewardStone(unsigned long dwUID, unsigned long dwCID, RebalanceLib::CItemChecker& itemChecker,
|
|
const char* szPosition, char* szData_InOut, const unsigned long dwMaxDataSize, unsigned long& dwDataSize_InOut)
|
|
{
|
|
unsigned long dwKey = (0 !=dwUID) ? dwUID : dwCID;
|
|
unsigned long dwReward = 0, dwStone = 0;
|
|
StoneRewardMap::iterator pos = m_StoneMap.find(dwKey);
|
|
Item::ItemPos itemPos;
|
|
|
|
char* szDataPos = szData_InOut + dwDataSize_InOut;
|
|
const char* szDataEnd = szData_InOut + dwMaxDataSize;
|
|
|
|
if(pos != m_StoneMap.end())
|
|
{
|
|
dwStone = pos->second;
|
|
|
|
while(0 < dwStone &&
|
|
szDataPos + sizeof(Item::ItemData) < szDataEnd &&
|
|
itemChecker.FindEmptyPos(itemPos, 1, 1))
|
|
{
|
|
Item::ItemData Rhatarium;
|
|
memset(&Rhatarium, 0, sizeof(Item::ItemData));
|
|
|
|
unsigned long dwAmountStone = 0;
|
|
unsigned long dwAmountResult = 0;
|
|
|
|
if (COUPONTORHATARIUM <= dwStone)
|
|
{
|
|
dwAmountStone = (dwStone / COUPONTORHATARIUM) * COUPONTORHATARIUM;
|
|
|
|
if(MAX_ITEMSTACK * COUPONTORHATARIUM <= dwAmountStone)
|
|
{
|
|
dwAmountStone = MAX_ITEMSTACK * COUPONTORHATARIUM;
|
|
}
|
|
|
|
dwStone -= dwAmountStone;
|
|
dwReward += dwAmountStone;
|
|
dwAmountResult = dwAmountStone / COUPONTORHATARIUM;
|
|
Rhatarium.m_usProtoTypeID = RHATARIUM_COUPON;
|
|
}
|
|
else
|
|
{
|
|
dwAmountStone = dwStone;
|
|
dwStone -= dwAmountStone;
|
|
dwReward += dwAmountStone;
|
|
dwAmountResult = dwAmountStone;
|
|
Rhatarium.m_usProtoTypeID = RHATARIUM;
|
|
}
|
|
|
|
Rhatarium.m_dwUID = m_DBItemSerialMgr.GetNewItemSerial();
|
|
Rhatarium.m_ItemPos = itemPos;
|
|
Rhatarium.m_cNumOrDurability = static_cast<unsigned char>(dwAmountResult);
|
|
Rhatarium.m_cItemSize = sizeof(Item::ItemData);
|
|
|
|
memcpy(szDataPos, &Rhatarium, sizeof(Item::ItemData));
|
|
szDataPos += sizeof(Item::ItemData);
|
|
dwDataSize_InOut += static_cast<unsigned long>(sizeof(Item::ItemData));
|
|
|
|
itemChecker.Set(itemPos, 1, 1);
|
|
|
|
if(Rhatarium.m_usProtoTypeID == RHATARIUM)
|
|
{
|
|
/*SERLOG6(g_RewardLog, "[Key - %8u] %s Reward Stone [ItemUID:0x%016I64X / ItemQuantity:%10u ItemPos:(%d:0x%03X)]",
|
|
dwKey, szPosition, Rhatarium.m_dwUID, dwAmountResult, Rhatarium.m_ItemPos.m_cPos, Rhatarium.m_ItemPos.m_cIndex);*/
|
|
}
|
|
else if(Rhatarium.m_usProtoTypeID == RHATARIUM_COUPON)
|
|
{
|
|
/*SERLOG6(g_RewardLog, "[Key - %8u] %s Reward StoneCoupon [ItemUID:0x%016I64X / ItemQuantity:%10u ItemPos:(%d:0x%03X)]",
|
|
dwKey, szPosition, Rhatarium.m_dwUID, dwAmountResult, Rhatarium.m_ItemPos.m_cPos, Rhatarium.m_ItemPos.m_cIndex);*/
|
|
}
|
|
|
|
}
|
|
|
|
dwDataSize_InOut = static_cast<unsigned long>(szDataPos - szData_InOut);
|
|
|
|
if(0 == dwStone)
|
|
{
|
|
pos->second = dwStone;
|
|
m_StoneMap.erase(pos);
|
|
/*SERLOG2(g_RewardLog, "[Key - %8u] ----Success : Reward %10u Stone", dwKey, dwReward);*/
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
/*ERRLOG4(g_RewardLog, "[Key - %8u] -----Failed : Reward %10u Stone overflow(%10u), Remain Stone(%10u)",
|
|
dwKey, pos->second, dwReward, dwStone);*/
|
|
pos->second = dwStone;
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
bool CDBRebalanceOverItem::RewardGold(unsigned long dwKey, const char* szPosition, unsigned long& dwGold_InOut)
|
|
{
|
|
GoldRewardMap::iterator pos = m_GoldMap.find(dwKey);
|
|
|
|
unsigned __int64 dwReward = 0, dwGold = 0;
|
|
|
|
if(pos != m_GoldMap.end())
|
|
{
|
|
dwGold = pos->second;
|
|
|
|
unsigned long dwAmountGold = static_cast<unsigned long>(dwGold % COUPONTOGOLD);
|
|
|
|
if(ULONG_MAX - dwGold_InOut >= dwAmountGold)
|
|
{
|
|
dwGold_InOut += dwAmountGold;
|
|
dwGold -= static_cast<unsigned __int64>(dwAmountGold);
|
|
pos->second = dwGold;
|
|
//SERLOG2(g_RewardLog, "[Key - %8u] ----Success : Reward %10u Gold", dwKey, dwAmountGold);
|
|
|
|
if(dwGold == 0)
|
|
{
|
|
m_GoldMap.erase(pos);
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
else
|
|
{
|
|
/*ERRLOG3(g_RewardLog, "[Key - %8u] -----Failed : Reward %16I64u Gold overflow(%10u)", dwKey, pos->second, dwAmountGold);*/
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
bool CDBRebalanceOverItem::RewardGoldCoupon(unsigned long dwKey, RebalanceLib::CItemChecker& itemChecker,
|
|
const char* szPosition, char* szData_InOut, const unsigned long dwMaxDataSize, unsigned long& dwDataSize_InOut)
|
|
{
|
|
unsigned __int64 dwReward = 0, dwGold= 0;
|
|
GoldRewardMap::iterator pos = m_GoldMap.find(dwKey);
|
|
Item::ItemPos itemPos;
|
|
|
|
char* szDataPos = szData_InOut + dwDataSize_InOut;
|
|
const char* szDataEnd = szData_InOut + dwMaxDataSize;
|
|
Item::ItemData GoldCoupon;
|
|
|
|
if(pos != m_GoldMap.end())
|
|
{
|
|
dwGold = pos->second;
|
|
|
|
unsigned long dwAmountCoupon = 0;
|
|
|
|
while(COUPONTOGOLD <= dwGold && szDataPos + sizeof(Item::ItemData) < szDataEnd && itemChecker.FindEmptyPos(itemPos, 1, 1))
|
|
{
|
|
memset(&GoldCoupon, 0, sizeof(Item::ItemData));
|
|
|
|
GoldCoupon.m_usProtoTypeID = GOLD_COUPON;
|
|
GoldCoupon.m_dwUID = m_DBItemSerialMgr.GetNewItemSerial();
|
|
GoldCoupon.m_ItemPos = itemPos;
|
|
GoldCoupon.m_cNumOrDurability = static_cast<unsigned char>(1);
|
|
GoldCoupon.m_cItemSize = sizeof(Item::ItemData);
|
|
|
|
memcpy(szDataPos, &GoldCoupon, sizeof(Item::ItemData));
|
|
szDataPos += sizeof(Item::ItemData);
|
|
dwDataSize_InOut += static_cast<unsigned long>(sizeof(Item::ItemData));
|
|
itemChecker.Set(itemPos, 1, 1);
|
|
|
|
dwGold -= COUPONTOGOLD;
|
|
dwReward += COUPONTOGOLD;
|
|
++dwAmountCoupon;
|
|
}
|
|
|
|
/*SERLOG6(g_RewardLog, "[Key - %8u] %s Reward GoldCoupon [ItemUID:0x%016I64X / ItemQuantity:%10u ItemPos:(%d:0x%03X)]",
|
|
dwKey, szPosition, GoldCoupon.m_dwUID, dwAmountCoupon, GoldCoupon.m_ItemPos.m_cPos, GoldCoupon.m_ItemPos.m_cIndex);*/
|
|
|
|
dwDataSize_InOut = static_cast<unsigned long>(szDataPos - szData_InOut);
|
|
|
|
if(COUPONTOGOLD > dwGold)
|
|
{
|
|
pos->second = dwGold;
|
|
if(dwReward/COUPONTOGOLD)
|
|
{
|
|
/*SERLOG2(g_RewardLog, "[Key - %8u] ----Success : Reward %16I64u Gold", dwKey, dwReward);*/
|
|
}
|
|
if(0 == dwGold)
|
|
{
|
|
m_GoldMap.erase(pos);
|
|
}
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
/*ERRLOG4(g_RewardLog, "[Key - %8u] -----Failed : Reward %16I64u GoldCoupon overflow(%16I64u), Remain Gold(%16I64u)",
|
|
dwKey, pos->second/COUPONTOGOLD, dwReward/COUPONTOGOLD, dwGold);*/
|
|
pos->second = dwGold;
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
bool CDBRebalanceOverItem::RewardGoldAndCoupon(unsigned long dwKey, unsigned long& dwGold_InOut, RebalanceLib::CItemChecker& itemChecker,
|
|
const char* szPosition, char* szData_InOut, const unsigned long dwMaxDataSize, unsigned long& dwDataSize_InOut)
|
|
{
|
|
if(RewardGold(dwKey, szPosition, dwGold_InOut) &&
|
|
RewardGoldCoupon(dwKey, itemChecker, szPosition, szData_InOut, dwMaxDataSize, dwDataSize_InOut))
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
void CDBRebalanceOverItem::AddReward(unsigned long dwKey, unsigned long dwStone, unsigned __int64 dwGold)
|
|
{
|
|
StoneRewardMap::iterator stone_pos = m_StoneMap.find(dwKey);
|
|
GoldRewardMap::iterator gold_pos = m_GoldMap.find(dwKey);
|
|
bool bPrint = false;
|
|
|
|
if(0 < dwStone)
|
|
{
|
|
if(m_StoneMap.end() == stone_pos)
|
|
{
|
|
m_StoneMap.insert(std::make_pair(dwKey, CALC_REWARDSTONE(dwStone)));
|
|
bPrint = false;
|
|
}
|
|
else
|
|
{
|
|
stone_pos->second += CALC_REWARDSTONE(dwStone);
|
|
bPrint = true;
|
|
}
|
|
|
|
if(0 < dwGold)
|
|
{
|
|
dwGold = static_cast<unsigned __int64>(CALC_REWARDGOLD(dwGold, dwStone));
|
|
|
|
if(m_GoldMap.end() == gold_pos)
|
|
{
|
|
if(_UI64_MAX >= dwGold)
|
|
{
|
|
m_GoldMap.insert(std::make_pair(dwKey, dwGold));
|
|
bPrint = false;
|
|
}
|
|
else
|
|
{
|
|
m_GoldMap.insert(std::make_pair(dwKey, _UI64_MAX));
|
|
dwGold = _UI64_MAX;
|
|
bPrint = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(_UI64_MAX >= dwGold + gold_pos->second)
|
|
{
|
|
gold_pos->second += dwGold;
|
|
bPrint = (bPrint & true);
|
|
}
|
|
else
|
|
{
|
|
gold_pos->second = _UI64_MAX;
|
|
dwGold = _UI64_MAX;
|
|
bPrint = (bPrint & true);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
/*SERLOG3(g_CalcLog, "[Key - %8u] -- Reward Stone %5u / Gold %16I64u",
|
|
dwKey, CALC_REWARDSTONE(dwStone), dwGold);*/
|
|
|
|
if(true == bPrint)
|
|
{
|
|
/*SERLOG3(g_CalcLog, "[Key - %8u] -- Total Reward Stone %5u / Gold %16I64u",
|
|
dwKey, stone_pos->second, gold_pos->second);*/
|
|
}
|
|
}
|
|
|
|
void CDBRebalanceOverItem::CalcReward(const Item::CItemType::ArrayType eEquipType, Item::CEquipment* lpEquipment, short* lpAttrFactor, short* lpAttrValue,
|
|
unsigned long& dwStone, unsigned __int64& dwGold, unsigned long dwKey)
|
|
{
|
|
float fTempFactor = 0;
|
|
float fTempFactor2 = 0;
|
|
long dwTempStone = 0;
|
|
|
|
dwStone = 0;
|
|
dwGold = 0;
|
|
|
|
/*SERLOG5(g_CalcLog, "[Key - %8u / UID - 0x%016I64X(%5u)] -- %s(%s)",
|
|
dwKey, lpEquipment->GetUID(), lpEquipment->GetItemInfo().m_usProtoTypeID, lpEquipment->GetItemInfo().m_SpriteData.m_szName, lpEquipment->GetItemInfo().m_StringData.m_szTypeName);*/
|
|
|
|
// 제련석 계산
|
|
switch(eEquipType)
|
|
{
|
|
case Item::CItemType::DAGGER_TYPE:
|
|
case Item::CItemType::ONEHANDED_TYPE:
|
|
case Item::CItemType::LONGRANGE_TYPE:
|
|
case Item::CItemType::TWOHANDED_TYPE:
|
|
case Item::CItemType::STAFF_TYPE:
|
|
// 무기류, 스태프/사이드류 공통 #1 : 크리티컬 / 3
|
|
fTempFactor = CalcAttribute(lpEquipment, Item::Attribute::Type::CRITICAL, dwKey, lpAttrFactor[Item::Attribute::Type::CRITICAL], lpAttrValue[Item::Attribute::Type::CRITICAL]);
|
|
dwTempStone = std::max(static_cast<unsigned long>(ceil(fTempFactor / 3.0f)), 0UL);
|
|
dwTempStone = std::max(dwTempStone, 0L);
|
|
dwStone += dwTempStone;
|
|
|
|
/*SERLOG4(g_CalcLog, "[Key - %8u / UID - 0x%016I64X(%5u)] Critical : Reward Stone %5u",
|
|
dwKey, lpEquipment->GetUID(), lpEquipment->GetItemInfo().m_usProtoTypeID, dwTempStone);*/
|
|
|
|
// 무기류, 스태프/사이드류 공통 #2 : 명중률 / 12
|
|
fTempFactor = CalcAttribute(lpEquipment, Item::Attribute::Type::HIT_RATE, dwKey, lpAttrFactor[Item::Attribute::Type::HIT_RATE], lpAttrValue[Item::Attribute::Type::HIT_RATE]);
|
|
dwTempStone = std::max(static_cast<unsigned long>(ceil(fTempFactor / 12.0f)), 0UL);
|
|
dwTempStone = std::max(dwTempStone, 0L);
|
|
dwStone += dwTempStone;
|
|
|
|
/*SERLOG4(g_CalcLog, "[Key - %8u / UID - 0x%016I64X(%5u)] Hitrate : Reward Stone %5u",
|
|
dwKey, lpEquipment->GetUID(), lpEquipment->GetItemInfo().m_usProtoTypeID, dwTempStone);*/
|
|
|
|
switch(eEquipType)
|
|
{
|
|
case Item::CItemType::DAGGER_TYPE:
|
|
case Item::CItemType::ONEHANDED_TYPE:
|
|
case Item::CItemType::LONGRANGE_TYPE:
|
|
case Item::CItemType::TWOHANDED_TYPE:
|
|
// 무기류 공통 #1 : MP회복 / 3
|
|
fTempFactor = CalcAttribute(lpEquipment, Item::Attribute::Type::MP_REGEN, dwKey, lpAttrFactor[Item::Attribute::Type::MP_REGEN], lpAttrValue[Item::Attribute::Type::MP_REGEN]);
|
|
dwTempStone = std::max(static_cast<unsigned long>(ceil(fTempFactor / 3.0f)), 0UL);
|
|
dwTempStone = std::max(dwTempStone, 0L);
|
|
dwStone += dwTempStone;
|
|
|
|
//SERLOG4(g_CalcLog, "[Key - %8u / UID - 0x%016I64X(%5u)] MPRegen : Reward Stone %5u",
|
|
// dwKey, lpEquipment->GetUID(), lpEquipment->GetItemInfo().m_usProtoTypeID, dwTempStone);
|
|
|
|
// 무기류 공통 #2 : 최대MP / 3
|
|
fTempFactor = CalcAttribute(lpEquipment, Item::Attribute::Type::MAX_MP, dwKey, lpAttrFactor[Item::Attribute::Type::MAX_MP], lpAttrValue[Item::Attribute::Type::MAX_MP]);
|
|
dwTempStone = std::max(static_cast<unsigned long>(ceil(fTempFactor / 3.0f)), 0UL);
|
|
dwTempStone = std::max(dwTempStone, 0L);
|
|
dwStone += dwTempStone;
|
|
|
|
/*SERLOG4(g_CalcLog, "[Key - %8u / UID - 0x%016I64X(%5u)] MaxMP : Reward Stone %5u",
|
|
dwKey, lpEquipment->GetUID(), lpEquipment->GetItemInfo().m_usProtoTypeID, dwTempStone);*/
|
|
|
|
fTempFactor = std::max(CalcAttribute(lpEquipment, Item::Attribute::Type::MIN_DAMAGE, dwKey, lpAttrFactor[Item::Attribute::Type::MIN_DAMAGE], lpAttrValue[Item::Attribute::Type::MIN_DAMAGE]),
|
|
CalcAttribute(lpEquipment, Item::Attribute::Type::MAX_DAMAGE, dwKey, lpAttrFactor[Item::Attribute::Type::MAX_DAMAGE], lpAttrValue[Item::Attribute::Type::MAX_DAMAGE]));
|
|
switch(eEquipType)
|
|
{
|
|
case Item::CItemType::DAGGER_TYPE:
|
|
// 단검류 추가 : MAX(최소 데미지, 최대 데미지) / 3
|
|
dwTempStone = std::max(static_cast<unsigned long>(ceil(fTempFactor / 3.0f)), 0UL);
|
|
break;
|
|
case Item::CItemType::ONEHANDED_TYPE:
|
|
case Item::CItemType::LONGRANGE_TYPE:
|
|
// 한손무기류, 장거리무기류 추가 : MAX(최소 데미지, 최대 데미지) / 6
|
|
dwTempStone = std::max(static_cast<unsigned long>(ceil(fTempFactor / 6.0f)), 0UL);
|
|
break;
|
|
case Item::CItemType::TWOHANDED_TYPE:
|
|
// 양손무기류 추가 : MAX(최소 데미지, 최대 데미지) / 9
|
|
dwTempStone = std::max(static_cast<unsigned long>(ceil(fTempFactor / 9.0f)), 0UL);
|
|
break;
|
|
}
|
|
dwTempStone = std::max(dwTempStone, 0L);
|
|
dwStone += dwTempStone;
|
|
|
|
/*SERLOG4(g_CalcLog, "[Key - %8u / UID - 0x%016I64X(%5u)] Damage : Reward Stone %5u",
|
|
dwKey, lpEquipment->GetUID(), lpEquipment->GetItemInfo().m_usProtoTypeID, dwTempStone);*/
|
|
|
|
break;
|
|
|
|
case Item::CItemType::STAFF_TYPE:
|
|
// 스태프, 사이드류 추가 #1 : 마법력 / 15 or 최대 데미지 / 9
|
|
fTempFactor = CalcAttribute(lpEquipment, Item::Attribute::Type::MAGIC_POWER, dwKey, lpAttrFactor[Item::Attribute::Type::MAGIC_POWER], lpAttrValue[Item::Attribute::Type::MAGIC_POWER]);
|
|
fTempFactor2 = CalcAttribute(lpEquipment, Item::Attribute::Type::MAX_DAMAGE, dwKey, lpAttrFactor[Item::Attribute::Type::MAX_DAMAGE], lpAttrValue[Item::Attribute::Type::MAX_DAMAGE]);
|
|
|
|
if (fTempFactor > fTempFactor2)
|
|
{
|
|
dwTempStone = std::max(static_cast<unsigned long>(ceil(fTempFactor / 15.0f)), 0UL);
|
|
dwTempStone = std::max(dwTempStone, 0L);
|
|
dwStone += dwTempStone;
|
|
|
|
/*SERLOG4(g_CalcLog, "[Key - %8u / UID - 0x%016I64X(%5u)] MagicPower : Reward Stone %5u",
|
|
dwKey, lpEquipment->GetUID(), lpEquipment->GetItemInfo().m_usProtoTypeID, dwTempStone);*/
|
|
}
|
|
else
|
|
{
|
|
dwTempStone = std::max(static_cast<unsigned long>(ceil(fTempFactor2 / 9.0f)), 0UL);
|
|
dwTempStone = std::max(dwTempStone, 0L);
|
|
dwStone += dwTempStone;
|
|
|
|
/*SERLOG4(g_CalcLog, "[Key - %8u / UID - 0x%016I64X(%5u)] Max_Damage : Reward Stone %5u",
|
|
dwKey, lpEquipment->GetUID(), lpEquipment->GetItemInfo().m_usProtoTypeID, dwTempStone);*/
|
|
}
|
|
|
|
// 스태프, 사이드류 추가 #2 : MP회복 / 6
|
|
fTempFactor = CalcAttribute(lpEquipment, Item::Attribute::Type::MP_REGEN, dwKey, lpAttrFactor[Item::Attribute::Type::MP_REGEN], lpAttrValue[Item::Attribute::Type::MP_REGEN]);
|
|
dwTempStone = std::max(static_cast<unsigned long>(ceil(fTempFactor / 6.0f)), 0UL);
|
|
dwTempStone = std::max(dwTempStone, 0L);
|
|
dwStone += dwTempStone;
|
|
|
|
/*SERLOG4(g_CalcLog, "[Key - %8u / UID - 0x%016I64X(%5u)] MPRegen : Reward Stone %5u",
|
|
dwKey, lpEquipment->GetUID(), lpEquipment->GetItemInfo().m_usProtoTypeID, dwTempStone);*/
|
|
|
|
// 스태프, 사이드류 추가 #3 : 최대MP / 6
|
|
fTempFactor = CalcAttribute(lpEquipment, Item::Attribute::Type::MAX_MP, dwKey, lpAttrFactor[Item::Attribute::Type::MAX_MP], lpAttrValue[Item::Attribute::Type::MAX_MP]);
|
|
dwTempStone = std::max(static_cast<unsigned long>(ceil(fTempFactor / 6.0f)), 0UL);
|
|
dwTempStone = std::max(dwTempStone, 0L);
|
|
dwStone += dwTempStone;
|
|
|
|
/*SERLOG4(g_CalcLog, "[Key - %8u / UID - 0x%016I64X(%5u)] MaxMP : Reward Stone %5u",
|
|
dwKey, lpEquipment->GetUID(), lpEquipment->GetItemInfo().m_usProtoTypeID, dwTempStone);*/
|
|
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case Item::CItemType::ARMOUR_TYPE:
|
|
case Item::CItemType::SHIELD_TYPE:
|
|
// 방어구류 방패와가드암 공통 : 최대HP / 3
|
|
fTempFactor = CalcAttribute(lpEquipment, Item::Attribute::Type::MAX_HP, dwKey, lpAttrFactor[Item::Attribute::Type::MAX_HP], lpAttrValue[Item::Attribute::Type::MAX_HP]);
|
|
dwTempStone = std::max(static_cast<unsigned long>(ceil(fTempFactor / 3.0f)), 0UL);
|
|
dwTempStone = std::max(dwTempStone, 0L);
|
|
dwStone += dwTempStone;
|
|
|
|
/*SERLOG4(g_CalcLog, "[Key - %8u / UID - 0x%016I64X(%5u)] MaxHP : Reward Stone %5u",
|
|
dwKey, lpEquipment->GetUID(), lpEquipment->GetItemInfo().m_usProtoTypeID, dwTempStone);*/
|
|
|
|
// 방어구류 방패와가드암 공통 : HP회복 / 3
|
|
fTempFactor = CalcAttribute(lpEquipment, Item::Attribute::Type::HP_REGEN, dwKey, lpAttrFactor[Item::Attribute::Type::HP_REGEN], lpAttrValue[Item::Attribute::Type::HP_REGEN]);
|
|
dwTempStone = std::max(static_cast<unsigned long>(ceil(fTempFactor / 3.0f)), 0UL);
|
|
dwTempStone = std::max(dwTempStone, 0L);
|
|
dwStone += dwTempStone;
|
|
|
|
/*SERLOG4(g_CalcLog, "[Key - %8u / UID - 0x%016I64X(%5u)] HPRegen : Reward Stone %5u",
|
|
dwKey, lpEquipment->GetUID(), lpEquipment->GetItemInfo().m_usProtoTypeID, dwTempStone);*/
|
|
|
|
switch(eEquipType)
|
|
{
|
|
case Item::CItemType::ARMOUR_TYPE:
|
|
// 방어구류 추가 #1 : 회피 / 3
|
|
fTempFactor = CalcAttribute(lpEquipment, Item::Attribute::Type::EVADE, dwKey, lpAttrFactor[Item::Attribute::Type::EVADE], lpAttrValue[Item::Attribute::Type::EVADE]);
|
|
dwTempStone = std::max(static_cast<unsigned long>(ceil(fTempFactor / 3.0f)), 0UL);
|
|
dwTempStone = std::max(dwTempStone, 0L);
|
|
dwStone += dwTempStone;
|
|
|
|
/*SERLOG4(g_CalcLog, "[Key - %8u / UID - 0x%016I64X(%5u)] Evade : Reward Stone %5u",
|
|
dwKey, lpEquipment->GetUID(), lpEquipment->GetItemInfo().m_usProtoTypeID, dwTempStone);*/
|
|
|
|
// 방어구류 추가 #2 : 마법저항 / 3
|
|
fTempFactor = CalcAttribute(lpEquipment, Item::Attribute::Type::MAGIC_RESIST, dwKey, lpAttrFactor[Item::Attribute::Type::MAGIC_RESIST], lpAttrValue[Item::Attribute::Type::MAGIC_RESIST]);
|
|
dwTempStone = std::max(static_cast<unsigned long>(ceil(fTempFactor / 3.0f)), 0UL);
|
|
dwTempStone = std::max(dwTempStone, 0L);
|
|
dwStone += dwTempStone;
|
|
|
|
/*SERLOG4(g_CalcLog, "[Key - %8u / UID - 0x%016I64X(%5u)] MagicResist : Reward Stone %5u",
|
|
dwKey, lpEquipment->GetUID(), lpEquipment->GetItemInfo().m_usProtoTypeID, dwTempStone);*/
|
|
|
|
// 방어구류 추가 #3 : 방어력 / 6
|
|
fTempFactor = CalcAttribute(lpEquipment, Item::Attribute::Type::ARMOR, dwKey, lpAttrFactor[Item::Attribute::Type::ARMOR], lpAttrValue[Item::Attribute::Type::ARMOR]);
|
|
dwTempStone = std::max(static_cast<unsigned long>(ceil(fTempFactor / 6.0f)), 0UL);
|
|
dwTempStone = std::max(dwTempStone, 0L);
|
|
dwStone += dwTempStone;
|
|
|
|
/*SERLOG4(g_CalcLog, "[Key - %8u / UID - 0x%016I64X(%5u)] Armor : Reward Stone %5u",
|
|
dwKey, lpEquipment->GetUID(), lpEquipment->GetItemInfo().m_usProtoTypeID, dwTempStone);*/
|
|
|
|
break;
|
|
|
|
case Item::CItemType::SHIELD_TYPE:
|
|
// 방패와가드암류 추가 #1 : 최대MP / 3
|
|
fTempFactor = CalcAttribute(lpEquipment, Item::Attribute::Type::MAX_MP, dwKey, lpAttrFactor[Item::Attribute::Type::MAX_MP], lpAttrValue[Item::Attribute::Type::MAX_MP]);
|
|
dwTempStone = std::max(static_cast<unsigned long>(ceil(fTempFactor / 3.0f)), 0UL);
|
|
dwTempStone = std::max(dwTempStone, 0L);
|
|
dwStone += dwTempStone;
|
|
|
|
/*SERLOG4(g_CalcLog, "[Key - %8u / UID - 0x%016I64X(%5u)] MaxMP : Reward Stone %5u",
|
|
dwKey, lpEquipment->GetUID(), lpEquipment->GetItemInfo().m_usProtoTypeID, dwTempStone);*/
|
|
|
|
// 방패와가드암류 추가 #2 : MP회복 / 3
|
|
fTempFactor = CalcAttribute(lpEquipment, Item::Attribute::Type::MP_REGEN, dwKey, lpAttrFactor[Item::Attribute::Type::MP_REGEN], lpAttrValue[Item::Attribute::Type::MP_REGEN]);
|
|
dwTempStone = std::max(static_cast<unsigned long>(ceil(fTempFactor / 3.0f)), 0UL);
|
|
dwTempStone = std::max(dwTempStone, 0L);
|
|
dwStone += dwTempStone;
|
|
|
|
/*SERLOG4(g_CalcLog, "[Key - %8u / UID - 0x%016I64X(%5u)] MPRegen : Reward Stone %5u",
|
|
dwKey, lpEquipment->GetUID(), lpEquipment->GetItemInfo().m_usProtoTypeID, dwTempStone);*/
|
|
|
|
// 방패와가드암류 추가 #3 : 블록 / 3
|
|
fTempFactor = CalcAttribute(lpEquipment, Item::Attribute::Type::BLOCK, dwKey, lpAttrFactor[Item::Attribute::Type::BLOCK], lpAttrValue[Item::Attribute::Type::BLOCK]);
|
|
dwTempStone = std::max(static_cast<unsigned long>(ceil(fTempFactor / 3.0f)), 0UL);
|
|
dwTempStone = std::max(dwTempStone, 0L);
|
|
dwStone += dwTempStone;
|
|
|
|
/*SERLOG4(g_CalcLog, "[Key - %8u / UID - 0x%016I64X(%5u)] Block : Reward Stone %5u",
|
|
dwKey, lpEquipment->GetUID(), lpEquipment->GetItemInfo().m_usProtoTypeID, dwTempStone);*/
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
// 골드 계산
|
|
lpEquipment->Repair();
|
|
dwGold = lpEquipment->GetBuyPrice();
|
|
}
|
|
|
|
float CDBRebalanceOverItem::CalcAttribute(Item::CEquipment* lpEquipment, Item::Attribute::Type eAttributeType, unsigned long dwKey, short attrFactor, short attrValue)
|
|
{
|
|
float fTempFactor = static_cast<float>(attrFactor - attrValue);
|
|
char szString[20] = {0};
|
|
|
|
GetAttrString(eAttributeType, szString);
|
|
|
|
/*SERLOG7(g_CalcLog, "[Key - %8u / UID - 0x%016I64X(%5u)] %-15s : %u - %u = %f",
|
|
dwKey, lpEquipment->GetUID(), lpEquipment->GetItemInfo().m_usProtoTypeID, szString, attrFactor, attrValue, fTempFactor);*/
|
|
|
|
return fTempFactor;
|
|
}
|
|
|
|
void CDBRebalanceOverItem::GetAttrString(Item::Attribute::Type eAttributeType, char* lpString)
|
|
{
|
|
const char MAX_STRING = 20;
|
|
|
|
switch(eAttributeType)
|
|
{
|
|
case Item::Attribute::MIN_DAMAGE: _snprintf(lpString, MAX_STRING, "MinDamage"); break;
|
|
case Item::Attribute::MAX_DAMAGE: _snprintf(lpString, MAX_STRING, "MaxDamage"); break;
|
|
case Item::Attribute::ARMOR: _snprintf(lpString, MAX_STRING, "Armor"); break;
|
|
case Item::Attribute::HIT_RATE: _snprintf(lpString, MAX_STRING, "HitRate"); break;
|
|
case Item::Attribute::EVADE: _snprintf(lpString, MAX_STRING, "Evade"); break;
|
|
case Item::Attribute::MAX_HP: _snprintf(lpString, MAX_STRING, "MaxHP"); break;
|
|
case Item::Attribute::HP_REGEN: _snprintf(lpString, MAX_STRING, "HPRegen"); break;
|
|
case Item::Attribute::MAX_MP: _snprintf(lpString, MAX_STRING, "MaxMP"); break;
|
|
case Item::Attribute::MP_REGEN: _snprintf(lpString, MAX_STRING, "MPRegen"); break;
|
|
case Item::Attribute::CRITICAL: _snprintf(lpString, MAX_STRING, "Critical"); break;
|
|
case Item::Attribute::BLOCK: _snprintf(lpString, MAX_STRING, "Block"); break;
|
|
case Item::Attribute::SPEED: _snprintf(lpString, MAX_STRING, "Speed"); break;
|
|
case Item::Attribute::MAGIC_POWER: _snprintf(lpString, MAX_STRING, "MagicPower"); break;
|
|
case Item::Attribute::MAGIC_RESIST: _snprintf(lpString, MAX_STRING, "MagicResist"); break;
|
|
case Item::Attribute::RUNE: _snprintf(lpString, MAX_STRING, "Rune"); break;
|
|
case Item::Attribute::FROST: _snprintf(lpString, MAX_STRING, "Frost"); break;
|
|
case Item::Attribute::FIRE: _snprintf(lpString, MAX_STRING, "Fire"); break;
|
|
case Item::Attribute::ELECTRO: _snprintf(lpString, MAX_STRING, "Electro"); break;
|
|
case Item::Attribute::DARKNESS: _snprintf(lpString, MAX_STRING, "Darkness"); break;
|
|
default: _snprintf(lpString, MAX_STRING, "Unknown"); break;
|
|
}
|
|
}
|
|
|
|
HRESULT CDBRebalanceOverItem::SetTarget()
|
|
{
|
|
const int MAX_QUERY_BUFFER = 1024;
|
|
char szQueryBuffer[MAX_QUERY_BUFFER];
|
|
int nServerType;
|
|
sCharInfo itemCharInfo = {0};
|
|
|
|
if(GetUnified())
|
|
{
|
|
nServerType = 23;
|
|
}
|
|
else
|
|
{
|
|
nServerType = 22;
|
|
}
|
|
|
|
_snprintf(szQueryBuffer, MAX_QUERY_BUFFER,
|
|
"SELECT A.CID, B.UID, CAST(A.Name AS CHAR(1024)) FROM CharInfo A "
|
|
"INNER JOIN (SELECT UID, Char1 as CID FROM UserInfo WHERE OldServerGroupID = %d AND Char1 > 0 UNION ALL "
|
|
"SELECT UID, Char2 as CID FROM UserInfo WHERE OldServerGroupID = %d AND Char2 > 0 UNION ALL "
|
|
"SELECT UID, Char3 as CID FROM UserInfo WHERE OldServerGroupID = %d AND Char3 > 0 UNION ALL "
|
|
"SELECT UID, Char4 as CID FROM UserInfo WHERE OldServerGroupID = %d AND Char4 > 0 UNION ALL "
|
|
"SELECT UID, Char5 as CID FROM UserInfo WHERE OldServerGroupID = %d AND Char5 > 0 ) B "
|
|
"ON A.CID = B.CID",
|
|
nServerType, nServerType, nServerType, nServerType, nServerType);
|
|
|
|
szQueryBuffer[MAX_QUERY_BUFFER - 1] = 0;
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
ATL::CCommand<ATL::CDynamicAccessor,
|
|
ATL::CBulkRowset, ATL::CMultipleResults> getCIDUID;
|
|
|
|
getCIDUID.SetRows(1000000);
|
|
|
|
|
|
if (FAILED(hr = getCIDUID.Open(m_Session, szQueryBuffer)))
|
|
{
|
|
LOG_CONVERT1("Get Target from UserInfo failed : hr:0x%08x", hr);
|
|
}
|
|
else
|
|
{
|
|
int nCount = 0;
|
|
|
|
DWORD nCID = 0;
|
|
|
|
hr = getCIDUID.MoveFirst( );
|
|
while (SUCCEEDED(hr) && hr != DB_S_ENDOFROWSET)
|
|
{
|
|
memset(&itemCharInfo, 0, sizeof(sCharInfo));
|
|
|
|
getCIDUID.GetValue(1, &nCID);
|
|
getCIDUID.GetValue(2, &(itemCharInfo.dwUID));
|
|
/*getCIDUID.GetValue(3, itemCharInfo.szName);*/
|
|
|
|
m_CIDUIDMap.insert(CIDUIDMAP::value_type(nCID, itemCharInfo));
|
|
hr = getCIDUID.MoveNext();
|
|
|
|
if (0 == (++nCount % 1000)) { printf("Read UID,CID info : %d\n", nCount); }
|
|
}
|
|
|
|
printf("Read UID,CID info success : %d\n", nCount);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
bool CDBRebalanceOverItem::IsExistCID(const unsigned long dwCID)
|
|
{
|
|
CIDUIDMAP::iterator itr = m_CIDUIDMap.find(dwCID);
|
|
if (itr == m_CIDUIDMap.end())
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
bool CDBRebalanceOverItem::IsExistUID(const unsigned long dwUID)
|
|
{
|
|
for (CIDUIDMAP::iterator itr = m_CIDUIDMap.begin(); itr != m_CIDUIDMap.end(); ++itr)
|
|
{
|
|
sCharInfo itemCharInfo = itr->second;
|
|
if(dwUID == itemCharInfo.dwUID)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
unsigned long CDBRebalanceOverItem::GetUIDByCID(const unsigned long dwCID)
|
|
{
|
|
for (CIDUIDMAP::iterator itr = m_CIDUIDMap.begin(); itr != m_CIDUIDMap.end(); ++itr)
|
|
{
|
|
if(dwCID == itr->first)
|
|
{
|
|
sCharInfo itemCharInfo = itr->second;
|
|
return itemCharInfo.dwUID;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
bool CDBRebalanceOverItem::GetCharNameByCID(const unsigned long dwCID, char* szCharName)
|
|
{
|
|
for (CIDUIDMAP::iterator itr = m_CIDUIDMap.begin(); itr != m_CIDUIDMap.end(); ++itr)
|
|
{
|
|
if(dwCID == itr->first)
|
|
{
|
|
sCharInfo itemCharInfo = itr->second;
|
|
szCharName = itemCharInfo.szName;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void CDBRebalanceOverItem::PrintItemOptionList()
|
|
{
|
|
char szMessage[1024] = {0}, szAttribute[64] = {0};
|
|
int nPrintNum = 0;
|
|
|
|
nPrintNum = sprintf(szMessage, "\t\tItemUID\tdwUID\tdwCID\tPrototypeID\tItemName\tTypeName\t");
|
|
|
|
|
|
for(int i = Item::Attribute::MIN_DAMAGE; i < Item::Attribute::MP_REGEN + 1; i++)
|
|
{
|
|
ZeroMemory(szAttribute, sizeof(char) * 64);
|
|
GetAttrString(static_cast<Item::Attribute::Type>(i), szAttribute);
|
|
|
|
nPrintNum += sprintf(szMessage + nPrintNum, "%s\t", szAttribute);
|
|
}
|
|
|
|
for(i = Item::Attribute::MAGIC_POWER; i < Item::Attribute::MAGIC_RESIST + 1; i++)
|
|
{
|
|
ZeroMemory(szAttribute, sizeof(char) * 64);
|
|
GetAttrString(static_cast<Item::Attribute::Type>(i), szAttribute);
|
|
|
|
nPrintNum += sprintf(szMessage + nPrintNum, "%s\t", szAttribute);
|
|
}
|
|
|
|
for(i = Item::Attribute::CRITICAL; i < Item::Attribute::SPEED + 1; i++)
|
|
{
|
|
ZeroMemory(szAttribute, sizeof(char) * 64);
|
|
GetAttrString(static_cast<Item::Attribute::Type>(i), szAttribute);
|
|
|
|
nPrintNum += sprintf(szMessage + nPrintNum, "%s\t", szAttribute);
|
|
}
|
|
|
|
SERLOG0(g_ItemList, szMessage);
|
|
}
|
|
|
|
void CDBRebalanceOverItem::PrintItemOption(Item::CEquipment* lpEquipment, short* lpAttribute, unsigned long dwKey)
|
|
{
|
|
if(NULL == lpAttribute || NULL == lpEquipment)
|
|
{
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
char szMessage[2048] = {0};
|
|
char* szCharName = 0;
|
|
int nPrintNum = 0;
|
|
unsigned long dwUID = 0;
|
|
unsigned long dwCID = 0;
|
|
|
|
if(IsExistCID(dwKey))
|
|
{
|
|
dwCID = dwKey;
|
|
dwUID = GetUIDByCID(dwCID);
|
|
if(!GetCharNameByCID(dwCID, szCharName))
|
|
{
|
|
ERRLOG1(g_ItemList, "CID(%u) is not converted to CharName", dwKey);
|
|
}
|
|
}
|
|
else if(IsExistUID(dwKey))
|
|
{
|
|
dwUID = dwKey;
|
|
}
|
|
else
|
|
{
|
|
ERRLOG1(g_ItemList, "dwKey(%u) is not exist in UID & CIDMAP", dwKey);
|
|
}
|
|
|
|
nPrintNum += sprintf(szMessage, "\t\t0x%016I64X\t%u\t%u\t%u\t%s\t%s\t",
|
|
lpEquipment->GetUID(), dwUID, dwCID, lpEquipment->GetPrototypeID(),
|
|
lpEquipment->GetItemInfo().m_SpriteData.m_szName, lpEquipment->GetItemTypeName());
|
|
|
|
for(int i = Item::Attribute::MIN_DAMAGE; i < Item::Attribute::MP_REGEN + 1; i++)
|
|
{
|
|
nPrintNum += sprintf(szMessage + nPrintNum, "%u\t", lpAttribute[i]);
|
|
}
|
|
|
|
for(i = Item::Attribute::MAGIC_POWER; i < Item::Attribute::MAGIC_RESIST + 1; i++)
|
|
{
|
|
nPrintNum += sprintf(szMessage + nPrintNum, "%u\t", lpAttribute[i]);
|
|
}
|
|
|
|
for(i = Item::Attribute::CRITICAL; i < Item::Attribute::SPEED + 1; i++)
|
|
{
|
|
nPrintNum += sprintf(szMessage + nPrintNum, "%u\t", lpAttribute[i]);
|
|
}
|
|
|
|
SERLOG0(g_ItemList, szMessage);
|
|
}
|
|
} |