fix db cpp encoding

This commit is contained in:
2024-04-01 14:20:00 +02:00
parent d471d99a24
commit dd74eafc24
19 changed files with 490 additions and 488 deletions

View File

@ -135,7 +135,7 @@ void AuctionManager::LoadAuctionItem()
}
int rows;
if ((rows = mysql_num_rows(res)) <= 0) // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
if ((rows = mysql_num_rows(res)) <= 0) // 데이터 없음
{
return;
}
@ -182,7 +182,7 @@ void AuctionManager::LoadAuctionInfo()
}
int rows;
if ((rows = mysql_num_rows(res)) <= 0) // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
if ((rows = mysql_num_rows(res)) <= 0) // 데이터 없음
{
return;
}
@ -226,7 +226,7 @@ void AuctionManager::LoadSaleInfo()
}
int rows;
if ((rows = mysql_num_rows(res)) <= 0) // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
if ((rows = mysql_num_rows(res)) <= 0) // 데이터 없음
{
return;
}
@ -269,7 +269,7 @@ void AuctionManager::LoadWishInfo()
}
int rows;
if ((rows = mysql_num_rows(res)) <= 0) // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
if ((rows = mysql_num_rows(res)) <= 0) // 데이터 없음
{
return;
}
@ -311,7 +311,7 @@ void AuctionManager::LoadMyBidInfo ()
}
int rows;
if ((rows = mysql_num_rows(res)) <= 0) // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
if ((rows = mysql_num_rows(res)) <= 0) // 데이터 없음
{
return;
}
@ -518,7 +518,7 @@ AuctionResult AuctionManager::Impur(DWORD purchaser_id, const char* purchaser_na
return AUCTION_EXPIRED;
}
// <EFBFBD><20>ع<EFBFBD><D8B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD>, <20><><EFBFBD>Ŵ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
// 즉구 해버렸으므로, 경매는 끝났다.
item_info->expired_time = 0;
item_info->bidder_id = purchaser_id;
item_info->set_bidder_name (purchaser_name);

View File

@ -114,7 +114,7 @@ bool CBlockCountry::IsBlockedCountryIp(const char *user_ip)
st_addr.s_addr = in_address;
if (INADDR_NONE == in_address)
#endif
return true; // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD>ó<EFBFBD><C3B3>
return true; // 아이피가 괴상하니 일단 블럭처리
DO_ALL_BLOCK_IP(iter)
{

View File

@ -29,12 +29,12 @@ CItemCache::~CItemCache()
{
}
// <EFBFBD>̰<EFBFBD> <20>̻<EFBFBD><CCBB>ѵ<EFBFBD>...
// Delete<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, Cache<68><65> <20><><EFBFBD><EFBFBD><EFBFBD>ؾ<EFBFBD> <20>ϴ°<CFB4> <20>ƴѰ<C6B4>???
// <EFBFBD>ٵ<EFBFBD> Cache<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20>κ<EFBFBD><CEBA><EFBFBD> <20><><EFBFBD><EFBFBD>.
// <EFBFBD><EFBFBD> ã<><C3A3> <20>ǰ<EFBFBD>?
// <EFBFBD>̷<EFBFBD><EFBFBD><EFBFBD> <20>س<EFBFBD><D8B3><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD> <20>ð<EFBFBD><C3B0><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>...
// <EFBFBD>̹<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ε<EFBFBD>... Ȯ<>λ<EFBFBD><CEBB><EFBFBD>??????
// 이거 이상한데...
// Delete를 했으면, Cache도 해제해야 하는것 아닌가???
// 근데 Cache를 해제하는 부분이 없어.
// 못 찾은 건가?
// 이렇게 해놓으면, 계속 시간이 될 때마다 아이템을 계속 지워...
// 이미 사라진 아이템인데... 확인사살??????
// fixme
// by rtsummit
void CItemCache::Delete()
@ -52,12 +52,12 @@ void CItemCache::Delete()
OnFlush();
//m_bNeedQuery = false;
//m_lastUpdateTime = time(0) - m_expireTime; // <EFBFBD>ٷ<EFBFBD> Ÿ<>Ӿƿ<D3BE> <20>ǵ<EFBFBD><C7B5><EFBFBD> <20><><EFBFBD><EFBFBD>.
//m_lastUpdateTime = time(0) - m_expireTime; // 바로 타임아웃 되도록 하자.
}
void CItemCache::OnFlush()
{
if (m_data.vnum == 0) // vnum<EFBFBD><EFBFBD> 0<≯<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>϶<EFBFBD><CFB6><EFBFBD> ǥ<>õ<EFBFBD> <20><><EFBFBD>̴<EFBFBD>.
if (m_data.vnum == 0) // vnum이 0이면 삭제하라고 표시된 것이다.
{
char szQuery[QUERY_MAX_LEN];
snprintf(szQuery, sizeof(szQuery), "DELETE FROM item%s WHERE id=%u", GetTablePostfix(), m_data.id);
@ -186,7 +186,7 @@ CItemPriceListTableCache::CItemPriceListTableCache()
void CItemPriceListTableCache::UpdateList(const TItemPriceListTable* pUpdateList)
{
//
// <EFBFBD>̹<EFBFBD> ij<>̵<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>۰<EFBFBD> <20>ߺ<EFBFBD><DFBA><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ã<><C3A3> <20>ߺ<EFBFBD><DFBA><EFBFBD><EFBFBD><EFBFBD> <20>ʴ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> tmpvec <EFBFBD><EFBFBD> <20>ִ´<D6B4>.
// 이미 캐싱된 아이템과 중복된 아이템을 찾고 중복되지 않는 이전 정보는 tmpvec 에 넣는다.
//
std::vector<TItemPriceInfo> tmpvec;
@ -202,7 +202,7 @@ void CItemPriceListTableCache::UpdateList(const TItemPriceListTable* pUpdateList
}
//
// pUpdateList <EFBFBD><EFBFBD> m_data <EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> tmpvec <20><> <20>տ<EFBFBD><D5BF><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ŭ <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
// pUpdateList m_data 에 복사하고 남은 공간을 tmpvec 의 앞에서 부터 남은 만큼 복사한다.
//
if (pUpdateList->byCount > SHOP_PRICELIST_MAX_NUM)
@ -215,7 +215,7 @@ void CItemPriceListTableCache::UpdateList(const TItemPriceListTable* pUpdateList
memcpy(m_data.aPriceInfo, pUpdateList->aPriceInfo, sizeof(TItemPriceInfo) * pUpdateList->byCount);
int nDeletedNum; // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
int nDeletedNum; // 삭제된 가격정보의 갯수
if (pUpdateList->byCount < SHOP_PRICELIST_MAX_NUM)
{
@ -244,14 +244,14 @@ void CItemPriceListTableCache::OnFlush()
char szQuery[QUERY_MAX_LEN];
//
// <EFBFBD><EFBFBD> ij<><C4B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ڿ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> DB <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
// 이 캐시의 소유자에 대한 기존에 DB 에 저장된 아이템 가격정보를 모두 삭제한다.
//
snprintf(szQuery, sizeof(szQuery), "DELETE FROM myshop_pricelist%s WHERE owner_id = %u", GetTablePostfix(), m_data.dwOwnerID);
CDBManager::instance().ReturnQuery(szQuery, QID_ITEMPRICE_DESTROY, 0, NULL);
//
// ij<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> DB <20><> <20><><EFBFBD><EFBFBD>.
// 캐시의 내용을 모두 DB 에 쓴다.
//
for (int idx = 0; idx < m_data.byCount; ++idx)

View File

@ -248,7 +248,7 @@ bool CClientManager::Initialize()
LoadEventFlag();
// database character-set<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
// database character-set을 강제로 맞춤
if (g_stLocale == "big5" || g_stLocale == "sjis")
CDBManager::instance().QueryLocaleSet();
@ -261,7 +261,7 @@ void CClientManager::MainLoop()
SPDLOG_DEBUG("ClientManager pointer is {}", (void*) this);
// <EFBFBD><EFBFBD><EFBFBD>η<EFBFBD><EFBFBD><EFBFBD>
// 메인루프
while (!m_bShutdowned)
{
while ((tmp = CDBManager::instance().PopResult()))
@ -275,7 +275,7 @@ void CClientManager::MainLoop()
}
//
// <EFBFBD><EFBFBD><EFBFBD>η<EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ó<EFBFBD><C3B3>
// 메인루프 종료처리
//
SPDLOG_DEBUG("MainLoop exited, Starting cache flushing");
@ -283,7 +283,7 @@ void CClientManager::MainLoop()
itertype(m_map_playerCache) it = m_map_playerCache.begin();
//<EFBFBD>÷<EFBFBD><EFBFBD>̾<EFBFBD> <20><><EFBFBD>̺<EFBFBD> ij<><C4B3> <20>÷<EFBFBD><C3B7><EFBFBD>
//플레이어 테이블 캐쉬 플러쉬
while (it != m_map_playerCache.end())
{
CPlayerTableCache * c = (it++)->second;
@ -295,7 +295,7 @@ void CClientManager::MainLoop()
itertype(m_map_itemCache) it2 = m_map_itemCache.begin();
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>÷<EFBFBD><C3B7><EFBFBD>
//아이템 플러쉬
while (it2 != m_map_itemCache.end())
{
CItemCache * c = (it2++)->second;
@ -307,7 +307,7 @@ void CClientManager::MainLoop()
// MYSHOP_PRICE_LIST
//
// <EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ Flush
// 개인상점 아이템 가격 리스트 Flush
//
for (itertype(m_mapItemPriceListCache) itPriceList = m_mapItemPriceListCache.begin(); itPriceList != m_mapItemPriceListCache.end(); ++itPriceList)
{
@ -327,7 +327,7 @@ void CClientManager::Quit()
void CClientManager::QUERY_BOOT(CPeer* peer, TPacketGDBoot * p)
{
const BYTE bPacketVersion = 6; // BOOT <EFBFBD><EFBFBD>Ŷ<EFBFBD><EFBFBD> <20>ٲ𶧸<D9B2><F0B6A7B8><EFBFBD> <20><>ȣ<EFBFBD><C8A3> <20>ø<EFBFBD><C3B8><EFBFBD><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
const BYTE bPacketVersion = 6; // BOOT 패킷이 바뀔때마다 번호를 올리도록 한다.
std::vector<tAdminInfo> vAdmin;
std::vector<std::string> vHost;
@ -584,9 +584,9 @@ void CClientManager::RESULT_SAFEBOX_LOAD(CPeer * pkPeer, SQLMsg * msg)
ClientHandleInfo * pi = (ClientHandleInfo *) qi->pvData;
DWORD dwHandle = pi->dwHandle;
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> account_index<65><78> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>Ѵ<EFBFBD>.
// ù<EFBFBD><EFBFBD>° <20>н<EFBFBD><D0BD><EFBFBD><EFBFBD><EFBFBD> <20>˾Ƴ<CBBE><C6B3><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0
// <EFBFBD>ι<EFBFBD>° <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1
// 여기에서 사용하는 account_index는 쿼리 순서를 말한다.
// 첫번째 패스워드 알아내기 위해 하는 쿼리가 0
// 두번째 실제 데이터를 얻어놓는 쿼리가 1
if (pi->account_index == 0)
{
@ -611,7 +611,7 @@ void CClientManager::RESULT_SAFEBOX_LOAD(CPeer * pkPeer, SQLMsg * msg)
{
MYSQL_ROW row = mysql_fetch_row(res->pSQLResult);
// <EFBFBD><EFBFBD><EFBFBD>й<EFBFBD>ȣ<EFBFBD><EFBFBD> Ʋ<><C6B2><EFBFBD><EFBFBD>..
// 비밀번호가 틀리면..
if (((!row[2] || !*row[2]) && strcmp("000000", szSafeboxPassword)) ||
((row[2] && *row[2]) && strcmp(row[2], szSafeboxPassword)))
{
@ -677,8 +677,8 @@ void CClientManager::RESULT_SAFEBOX_LOAD(CPeer * pkPeer, SQLMsg * msg)
}
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>־<EFBFBD><D6BE><EFBFBD><EFBFBD>Ƿ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> â<><C3A2><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD> <20><> ó<><C3B3>
// <EFBFBD><EFBFBD><EFBFBD>̱<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> â<><C3A2><EFBFBD><EFBFBD> <20>ƾ<EFBFBD> <20>ȿ<EFBFBD><C8BF><EFBFBD><EFBFBD>°<EFBFBD> <20><><EFBFBD><EFBFBD>
// 쿼리에 에러가 있었으므로 응답할 경우 창고가 비어있는 것 처럼
// 보이기 때문에 창고가 아얘 안열리는게 나음
if (!msg->Get()->pSQLResult)
{
SPDLOG_ERROR("null safebox result");
@ -787,8 +787,8 @@ void CClientManager::RESULT_SAFEBOX_LOAD(CPeer * pkPeer, SQLMsg * msg)
{
case 72723: case 72724: case 72725: case 72726:
case 72727: case 72728: case 72729: case 72730:
// <EFBFBD><EFBFBD><EFBFBD>ù<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ϴ<EFBFBD> <20><> <20><>ġ<EFBFBD><C4A1><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>...
// <EFBFBD>׷<EFBFBD><EFBFBD><EFBFBD> <20>׳<EFBFBD> <20>ϵ<EFBFBD> <20>ڵ<EFBFBD>. <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ڿ<EFBFBD> <20>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>۵<EFBFBD>.
// 무시무시하지만 이전에 하던 걸 고치기는 무섭고...
// 그래서 그냥 하드 코딩. 선물 상자용 자동물약 아이템들.
case 76004: case 76005: case 76021: case 76022:
case 79012: case 79013:
if (pItemAward->dwSocket2 == 0)
@ -900,7 +900,7 @@ void CClientManager::RESULT_SAFEBOX_LOAD(CPeer * pkPeer, SQLMsg * msg)
void CClientManager::QUERY_SAFEBOX_CHANGE_SIZE(CPeer * pkPeer, DWORD dwHandle, TSafeboxChangeSizePacket * p)
{
ClientHandleInfo * pi = new ClientHandleInfo(dwHandle);
pi->account_index = p->bSize; // account_index<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ӽ÷<D3BD> <20><><EFBFBD><EFBFBD>
pi->account_index = p->bSize; // account_index를 사이즈로 임시로 사용
char szQuery[QUERY_MAX_LEN];
@ -988,7 +988,7 @@ void CClientManager::RESULT_PRICELIST_LOAD(CPeer* peer, SQLMsg* pMsg)
TItemPricelistReqInfo* pReqInfo = (TItemPricelistReqInfo*)static_cast<CQueryInfo*>(pMsg->pvUserData)->pvData;
//
// DB <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ε<EFBFBD><CEB5><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Cache <20><> <20><><EFBFBD><EFBFBD>
// DB 에서 로드한 정보를 Cache 에 저장
//
TItemPriceListTable table;
@ -1007,7 +1007,7 @@ void CClientManager::RESULT_PRICELIST_LOAD(CPeer* peer, SQLMsg* pMsg)
PutItemPriceListCache(&table);
//
// <EFBFBD>ε<EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD> Game server <EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
// 로드한 데이터를 Game server 에 전송
//
TPacketMyshopPricelistHeader header;
@ -1031,7 +1031,7 @@ void CClientManager::RESULT_PRICELIST_LOAD_FOR_UPDATE(SQLMsg* pMsg)
TItemPriceListTable* pUpdateTable = (TItemPriceListTable*)static_cast<CQueryInfo*>(pMsg->pvUserData)->pvData;
//
// DB <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ε<EFBFBD><CEB5><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Cache <20><> <20><><EFBFBD><EFBFBD>
// DB 에서 로드한 정보를 Cache 에 저장
//
TItemPriceListTable table;
@ -1093,18 +1093,18 @@ void CClientManager::QUERY_EMPIRE_SELECT(CPeer * pkPeer, DWORD dwHandle, TEmpire
UINT g_start_map[4] =
{
0, // reserved
1, // <EFBFBD>ż<EFBFBD><EFBFBD><EFBFBD>
21, // õ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
41 // <EFBFBD><EFBFBD><EFBFBD>
1, // 신수국
21, // 천조국
41 // 진노국
};
// FIXME share with game
DWORD g_start_position[4][2]=
{
{ 0, 0 },
{ 469300, 964200 }, // <EFBFBD>ż<EFBFBD><EFBFBD><EFBFBD>
{ 55700, 157900 }, // õ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{ 969600, 278400 } // <EFBFBD><EFBFBD><EFBFBD>
{ 469300, 964200 }, // 신수국
{ 55700, 157900 }, // 천조국
{ 969600, 278400 } // 진노국
};
for (int i = 0; i < 3; ++i)
@ -1155,7 +1155,7 @@ void CClientManager::QUERY_SETUP(CPeer * peer, DWORD dwHandle, const char * c_pD
peer->SetMaps(p->alMaps);
//
// <EFBFBD><20><><EFBFBD><EFBFBD> <20><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ִ<EFBFBD><D6B4><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 어떤 맵이 어떤 서버에 있는지 보내기
//
TMapLocation kMapLocations;
@ -1262,7 +1262,7 @@ void CClientManager::QUERY_SETUP(CPeer * peer, DWORD dwHandle, const char * c_pD
peer->Encode(&vec_kMapLocations[0], sizeof(TMapLocation) * vec_kMapLocations.size());
//
// <EFBFBD>¾<EFBFBD> : <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ǿ <20>ٸ<EFBFBD> <20>Ǿ<EFBFBD><C7BE><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. (P2P <20><><EFBFBD>ؼ<EFBFBD> <20><><EFBFBD><EFBFBD>)
// 셋업 : 접속한 피어에 다른 피어들이 접속하게 만든다. (P2P 컨넥션 생성)
//
SPDLOG_DEBUG("SETUP: channel {} listen {} p2p {} count {}", peer->GetChannel(), p->wListenPort, p->wP2PPort, bMapCount);
@ -1278,7 +1278,7 @@ void CClientManager::QUERY_SETUP(CPeer * peer, DWORD dwHandle, const char * c_pD
if (tmp == peer)
continue;
// ä<EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0<>̶<EFBFBD><CCB6><EFBFBD> <20><><EFBFBD><EFBFBD> SETUP <20><>Ŷ<EFBFBD><C5B6> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>Ǿ<EFBFBD> <20>Ǵ<EFBFBD> auth<74><68><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD>
// 채널이 0이라면 아직 SETUP 패킷이 오지 않은 피어 또는 auth라고 간주할 수 있음
if (0 == tmp->GetChannel())
continue;
@ -1287,7 +1287,7 @@ void CClientManager::QUERY_SETUP(CPeer * peer, DWORD dwHandle, const char * c_pD
}
//
// <EFBFBD>α<EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 로그인 및 빌링정보 보내기
//
TPacketLoginOnSetup * pck = (TPacketLoginOnSetup *) c_pData;;
std::vector<TPacketBillingRepair> vec_repair;
@ -1359,8 +1359,8 @@ void CClientManager::QUERY_ITEM_SAVE(CPeer * pkPeer, const char * c_pData)
{
TPlayerItem * p = (TPlayerItem *) c_pData;
// â<EFBFBD><EFBFBD><EFBFBD><EFBFBD> ij<><C4B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʰ<EFBFBD>, ij<><C4B3><EFBFBD><EFBFBD> <20>ִ<EFBFBD> <20>͵<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
// auction<EFBFBD><EFBFBD> <20><> <20><>Ʈ<EFBFBD><C6AE> Ÿ<><C5B8> <20>ʾƾ<CABE> <20>Ѵ<EFBFBD>. EnrollInAuction<EFBFBD><EFBFBD> Ÿ<><C5B8><EFBFBD>Ѵ<EFBFBD>.
// 창고면 캐쉬하지 않고, 캐쉬에 있던 것도 빼버려야 한다.
// auction은 이 루트를 타지 않아야 한다. EnrollInAuction을 타야한다.
if (p->window == SAFEBOX || p->window == MALL)
{
@ -1495,7 +1495,7 @@ void CClientManager::PutItemCache(TPlayerItem * pNew, bool bSkipQuery)
c = GetItemCache(pNew->id);
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
// 아이템 새로 생성
if (!c)
{
SPDLOG_TRACE("ITEM_CACHE: PutItemCache ==> New CItemCache id{} vnum{} new owner{}", pNew->id, pNew->vnum, pNew->owner);
@ -1503,15 +1503,15 @@ void CClientManager::PutItemCache(TPlayerItem * pNew, bool bSkipQuery)
c = new CItemCache;
m_map_itemCache.insert(TItemCacheMap::value_type(pNew->id, c));
}
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 있을시
else
{
SPDLOG_TRACE("ITEM_CACHE: PutItemCache ==> Have Cache");
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڰ<EFBFBD> Ʋ<><C6B2><EFBFBD><EFBFBD>
// 소유자가 틀리면
if (pNew->owner != c->Get()->owner)
{
// <EFBFBD>̹<EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>־<EFBFBD><D6BE><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
// 이미 이 아이템을 가지고 있었던 유저로 부터 아이템을 삭제한다.
TItemCacheSetPtrMap::iterator it = m_map_pkItemCacheSetPtr.find(c->Get()->owner);
if (it != m_map_pkItemCacheSetPtr.end())
@ -1522,7 +1522,7 @@ void CClientManager::PutItemCache(TPlayerItem * pNew, bool bSkipQuery)
}
}
// <EFBFBD><EFBFBD><EFBFBD>ο<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ
// 새로운 정보 업데이트
c->Put(pNew, bSkipQuery);
TItemCacheSetPtrMap::iterator it = m_map_pkItemCacheSetPtr.find(c->Get()->owner);
@ -1534,8 +1534,8 @@ void CClientManager::PutItemCache(TPlayerItem * pNew, bool bSkipQuery)
}
else
{
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ڰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD> <20>ٷ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ؾ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><> SQL<51><4C> <20><><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD>
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD> <20>ٷ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
// 현재 소유자가 없으므로 바로 저장해야 다음 접속이 올 때 SQL에 쿼리하여
// 받을 수 있으므로 바로 저장한다.
SPDLOG_TRACE("ITEM_CACHE: direct save {} id {}", c->Get()->owner, c->Get()->id);
c->OnFlush();
@ -1591,7 +1591,7 @@ void CClientManager::UpdatePlayerCache()
c->Flush();
// Item Cache<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ
// Item Cache도 업데이트
UpdateItemCacheSet(c->Get()->id);
}
else if (c->CheckFlushTimeout())
@ -1617,7 +1617,7 @@ void CClientManager::UpdateItemCache()
{
CItemCache * c = (it++)->second;
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Flush<73><68> <20>Ѵ<EFBFBD>.
// 아이템은 Flush만 한다.
if (c->CheckFlushTimeout())
{
SPDLOG_TRACE("UpdateItemCache ==> Flush() vnum {} id owner {}", c->Get()->vnum, c->Get()->id, c->Get()->owner);
@ -1662,7 +1662,7 @@ void CClientManager::QUERY_ITEM_DESTROY(CPeer * pkPeer, const char * c_pData)
SPDLOG_TRACE("HEADER_GD_ITEM_DESTROY: PID {} ID {}", dwPID, dwID);
if (dwPID == 0) // <EFBFBD>ƹ<EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ٸ<EFBFBD>, <20>񵿱<EFBFBD> <20><><EFBFBD><EFBFBD>
if (dwPID == 0) // 아무도 가진 사람이 없었다면, 비동기 쿼리
CDBManager::instance().AsyncQuery(szQuery);
else
CDBManager::instance().ReturnQuery(szQuery, QID_ITEM_DESTROY, pkPeer->GetHandle(), NULL);
@ -1740,7 +1740,7 @@ void CClientManager::QUERY_RELOAD_PROTO()
// ADD_GUILD_PRIV_TIME
/**
* @version 05/06/08 Bang2ni - <EFBFBD><EFBFBD><EFBFBD>ӽð<EFBFBD> <20>߰<EFBFBD>
* @version 05/06/08 Bang2ni - 지속시간 추가
*/
void CClientManager::AddGuildPriv(TPacketGiveGuildPriv* p)
{
@ -2220,8 +2220,8 @@ void CClientManager::WeddingEnd(TPacketWeddingEnd * p)
}
//
// ij<EFBFBD>ÿ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ij<>ø<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ <20>ϰ<EFBFBD> ij<>ÿ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ٸ<EFBFBD>
// <EFBFBD><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD> <20>ε<EFBFBD><CEB5><EFBFBD> <20>ڿ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ij<>ø<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ <20>Ѵ<EFBFBD>.
// 캐시에 가격정보가 있으면 캐시를 업데이트 하고 캐시에 가격정보가 없다면
// 우선 기존의 데이터를 로드한 뒤에 기존의 정보로 캐시를 만들고 새로 받은 가격정보를 업데이트 한다.
//
void CClientManager::MyshopPricelistUpdate(const TPacketMyshopPricelistHeader* pPacket)
{
@ -2262,7 +2262,7 @@ void CClientManager::MyshopPricelistUpdate(const TPacketMyshopPricelistHeader* p
}
// MYSHOP_PRICE_LIST
// ij<EFBFBD>õ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ij<>ø<EFBFBD> <20>о<EFBFBD> <20>ٷ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> ij<>ÿ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> DB <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
// 캐시된 가격정보가 있으면 캐시를 읽어 바로 전송하고 캐시에 정보가 없으면 DB 에 쿼리를 한다.
//
void CClientManager::MyshopPricelistRequest(CPeer* peer, DWORD dwHandle, DWORD dwPlayerID)
{
@ -2655,15 +2655,15 @@ void CClientManager::ProcessPackets(CPeer * peer)
ComeToVote(peer, dwHandle, data);
break;
case HEADER_GD_RMCANDIDACY: //< <EFBFBD>ĺ<EFBFBD> <20><><EFBFBD><EFBFBD> (<28><EFBFBD><EEBFB5>)
case HEADER_GD_RMCANDIDACY: //< 후보 제거 (운영자)
RMCandidacy(peer, dwHandle, data);
break;
case HEADER_GD_SETMONARCH: ///<<EFBFBD><EFBFBD><EFBFBD>ּ<EFBFBD><EFBFBD><EFBFBD> (<28><EFBFBD><EEBFB5>)
case HEADER_GD_SETMONARCH: ///<군주설정 (운영자)
SetMonarch(peer, dwHandle, data);
break;
case HEADER_GD_RMMONARCH: ///<<EFBFBD><EFBFBD><EFBFBD>ֻ<EFBFBD><EFBFBD><EFBFBD>
case HEADER_GD_RMMONARCH: ///<군주삭제
RMMonarch(peer, dwHandle, data);
break;
//END_MONARCH
@ -2864,9 +2864,9 @@ CPeer * CClientManager::GetAnyPeer()
return m_peerList.front();
}
// DB <EFBFBD>Ŵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ó<><C3B3><EFBFBD>Ѵ<EFBFBD>.
// DB 매니저로 부터 받은 결과를 처리한다.
//
// @version 05/06/10 Bang2ni - <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>(QID_ITEMPRICE_XXX) <EFBFBD>߰<EFBFBD>
// @version 05/06/10 Bang2ni - 가격정보 관련 쿼리(QID_ITEMPRICE_XXX) 추가
int CClientManager::AnalyzeQueryResult(SQLMsg * msg)
{
CQueryInfo * qi = (CQueryInfo *) msg->pvUserData;
@ -2984,7 +2984,7 @@ void UsageLog()
char *time_s;
struct tm lt;
int avg = g_dwUsageAvg / 3600; // 60 <EFBFBD><EFBFBD> * 60 <EFBFBD><EFBFBD>
int avg = g_dwUsageAvg / 3600; // 60 * 60
fp = fopen("usage.txt", "a+");
@ -3017,7 +3017,7 @@ int CClientManager::Process()
++thecore_heart->pulse;
/*
//30<EFBFBD>и<EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
//30분마다 변경
if (((thecore_pulse() % (60 * 30 * 10)) == 0))
{
g_iPlayerCacheFlushSeconds = std::max(60, rand() % 180);
@ -3095,11 +3095,11 @@ int CClientManager::Process()
m_iCacheFlushCount = 0;
//<EFBFBD>÷<EFBFBD><EFBFBD>̾<EFBFBD> <20>÷<EFBFBD><C3B7><EFBFBD>
//플레이어 플러쉬
UpdatePlayerCache();
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>÷<EFBFBD><C3B7><EFBFBD>
//아이템 플러쉬
UpdateItemCache();
//<EFBFBD>α׾ƿ<EFBFBD><EFBFBD><EFBFBD> ó<><C3B3>- ij<><C4B3><EFBFBD><EFBFBD> <20>÷<EFBFBD><C3B7><EFBFBD>
//로그아웃시 처리- 캐쉬셋 플러쉬
UpdateLogoutPlayer();
// MYSHOP_PRICE_LIST
@ -3169,13 +3169,13 @@ int CClientManager::Process()
/////////////////////////////////////////////////////////////////
}
if (!(thecore_heart->pulse % (thecore_heart->passes_per_sec * 60))) // 60<EFBFBD>ʿ<EFBFBD> <20>ѹ<EFBFBD>
if (!(thecore_heart->pulse % (thecore_heart->passes_per_sec * 60))) // 60초에 한번
{
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ũ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ð<EFBFBD><C3B0><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
// 유니크 아이템을 위한 시간을 보낸다.
CClientManager::instance().SendTime();
}
if (!(thecore_heart->pulse % (thecore_heart->passes_per_sec * 3600))) // <EFBFBD>ѽð<EFBFBD><EFBFBD><EFBFBD> <20>ѹ<EFBFBD>
if (!(thecore_heart->pulse % (thecore_heart->passes_per_sec * 3600))) // 한시간에 한번
{
CMoneyLog::instance().Save();
}
@ -3190,7 +3190,7 @@ int CClientManager::Process()
DWORD CClientManager::GetUserCount()
{
// <EFBFBD>ܼ<EFBFBD><EFBFBD><EFBFBD> <20>α<EFBFBD><CEB1><EFBFBD> ī<><C4AB>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD>.. --;
// 단순히 로그인 카운트를 센다.. --;
return m_map_kLogonAccount.size();
}
@ -3250,7 +3250,7 @@ bool CClientManager::InitializeNowItemID()
{
DWORD dwMin, dwMax;
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ID<49><44> <20>ʱ<EFBFBD>ȭ <20>Ѵ<EFBFBD>.
//아이템 ID를 초기화 한다.
if (!CConfig::instance().GetTwoValue("ITEM_ID_RANGE", &dwMin, &dwMax))
{
SPDLOG_ERROR("conf.txt: Cannot find ITEM_ID_RANGE [start_item_id] [end_item_id]");
@ -3680,7 +3680,7 @@ bool CClientManager::InitializeLocalization()
bool CClientManager::__GetAdminInfo(const char *szIP, std::vector<tAdminInfo> & rAdminVec)
{
//szIP == NULL <EFBFBD>ϰ<EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><E7BCAD><EFBFBD><EFBFBD> <20><EFBFBD><EEBFB5> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>´<EFBFBD>.
//szIP == NULL 일경우 모든서버에 운영자 권한을 갖는다.
char szQuery[512];
snprintf(szQuery, sizeof(szQuery),
"SELECT mID,mAccount,mName,mContactIP,mServerIP,mAuthority FROM gmlist WHERE mServerIP='ALL' or mServerIP='%s'",
@ -4233,7 +4233,7 @@ void CClientManager::SendSpareItemIDRange(CPeer* peer)
}
//
// Login Key<EFBFBD><EFBFBD> <20>ʿ<EFBFBD><CABF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
// Login Key만 맵에서 지운다.
//
void CClientManager::DeleteLoginKey(TPacketDC *data)
{
@ -4346,7 +4346,7 @@ void CClientManager::EnrollInAuction (CPeer * peer, DWORD owner_id, AuctionEnrol
SPDLOG_ERROR("Player id {} doesn't have item {}.", owner_id, data->get_item_id());
return;
}
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ð<EFBFBD> + 24<32>ð<EFBFBD> <20><>.
// 현재 시각 + 24시간 후.
time_t expired_time = time(0) + 24 * 60 * 60;
TAuctionItemInfo auctioned_item_info (item->vnum, data->get_bid_price(),
data->get_impur_price(), owner_id, "", expired_time, data->get_item_id(), 0, data->get_empire());
@ -4365,7 +4365,7 @@ void CClientManager::EnrollInAuction (CPeer * peer, DWORD owner_id, AuctionEnrol
}
else
{
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ɽø<C9BD> Auction<6F><6E> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ClientManager<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
// 아이템 케시를 Auction에 등록 했으니 ClientManager에서는 뺀다.
TItemCacheSetPtrMap::iterator it = m_map_pkItemCacheSetPtr.find(item->owner);
if (it != m_map_pkItemCacheSetPtr.end())
@ -4418,7 +4418,7 @@ void CClientManager::EnrollInSale (CPeer * peer, DWORD owner_id, AuctionEnrollSa
SPDLOG_ERROR("Player id {} doesn't have item {}.", owner_id, data->get_item_id());
return;
}
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ð<EFBFBD> + 24<32>ð<EFBFBD> <20><>.
// 현재 시각 + 24시간 후.
time_t expired_time = time(0) + 24 * 60 * 60;
TSaleItemInfo sold_item_info (item->vnum, data->get_sale_price(),
owner_id, player->name, data->get_item_id(), data->get_wisher_id());
@ -4437,7 +4437,7 @@ void CClientManager::EnrollInSale (CPeer * peer, DWORD owner_id, AuctionEnrollSa
}
else
{
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ɽø<C9BD> Auction<6F><6E> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ClientManager<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
// 아이템 케시를 Auction에 등록 했으니 ClientManager에서는 뺀다.
TItemCacheSetPtrMap::iterator it = m_map_pkItemCacheSetPtr.find(item->owner);
if (it != m_map_pkItemCacheSetPtr.end())
@ -4477,7 +4477,7 @@ void CClientManager::EnrollInWish (CPeer * peer, DWORD wisher_id, AuctionEnrollW
CPlayerTableCache* player_cache = it->second;
TPlayerTable* player = player_cache->Get(false);
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ð<EFBFBD> + 24<32>ð<EFBFBD> <20><>.
// 현재 시각 + 24시간 후.
time_t expired_time = time(0) + 24 * 60 * 60;
TWishItemInfo wished_item_info (data->get_item_num(), data->get_wish_price(), wisher_id, player->name, expired_time, data->get_empire());
@ -4844,11 +4844,11 @@ void CClientManager::AuctionDeleteSaleItem (CPeer * peer, DWORD actor_id, DWORD
AuctionManager::instance().DeleteSaleItem (actor_id, item_id);
}
// ReBid<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ݾ׿<DDBE> <20><><EFBFBD>ؼ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
// ReBid<EFBFBD><EFBFBD><EFBFBD><EFBFBD> data->bid_price<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <EFBFBD><EFBFBD> <20>ݾ<EFBFBD><DDBE><EFBFBD><EFBFBD><EFBFBD> rebid<69>ϴ<EFBFBD> <20><>.
// <EFBFBD>̷<EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> rebid<69><64> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>,
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ȣ<>ָӴϿ<D3B4><CFBF><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD> <20><><EFBFBD>ϰ<EFBFBD> <20>ϱ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>̴<EFBFBD>.
// ReBid는 이전 입찰금액에 더해서 입찰한다.
// ReBid에선 data->bid_price가 이전 입찰가에 더해져서
// 그 금액으로 rebid하는 것.
// 이렇게 한 이유는 rebid에 실패 했을 때,
// 유저의 호주머니에서 뺀 돈을 돌려주기 편하게 하기 위함이다.
void CClientManager::AuctionReBid (CPeer * peer, DWORD bidder_id, AuctionBidInfo* data)
{
@ -4873,14 +4873,14 @@ void CClientManager::AuctionReBid (CPeer * peer, DWORD bidder_id, AuctionBidInfo
{
SPDLOG_DEBUG("ReBid Success. bidder_id item_id {} {}", bidder_id, data->get_item_id());
}
// <EFBFBD>̰<EFBFBD> FAIL<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ȵ<EFBFBD>.
// FAIL<EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>°<EFBFBD>, MyBid<EFBFBD><EFBFBD> <20>ִ<EFBFBD> bidder_id<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> bidder_id<69><64><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><> <20>ְŵ<D6B0>?
// <EFBFBD>׷<EFBFBD><EFBFBD>Ƿ<EFBFBD> <20>ٸ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>۵<EFBFBD><DBB5>Ѵٰ<D1B4> <20><><EFBFBD><EFBFBD> <20>Ѵٸ<D1B4>
// <EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> bidder_id<EFBFBD><EFBFBD> MyBid<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20>װ<EFBFBD> <20><><EFBFBD><EFBFBD>ȭ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
// <EFBFBD>ٸ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ȱ<EFBFBD><C8B0><EFBFBD> bidder_id<69><64> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD>.
// <EFBFBD>׷<EFBFBD><EFBFBD>Ƿ<EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> BidCancel <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> db<64><62> <20><><EFBFBD>ȴٴ<C8B4> <20><><EFBFBD><EFBFBD>,
// <EFBFBD>̹<EFBFBD> <20><> <20>κп<CEBA> <20><><EFBFBD>ؼ<EFBFBD><D8BC><EFBFBD> <20>˻簡 <20>Ϻ<EFBFBD><CFBA>ϴٴ<CFB4> <20><><EFBFBD>̾<EFBFBD>.
// <EFBFBD>׷<EFBFBD><EFBFBD><EFBFBD> Ȥ<>ó<EFBFBD> <20>;, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> fail <20>ڵ带 <20><><EFBFBD>ܵд<DCB5>.
// 이건 FAIL이 떠서는 안돼.
// FAIL이 뜰 수가 없는게, MyBid에 있는 bidder_id에 대한 컨텐츠는 bidder_id만이 접근 할 수 있거든?
// 그러므로 다른 것이 다 정상적으로 작동한다고 가정 한다면
// 한 게임 서버 내에서 bidder_id MyBid를 수정한다 할 지라도, 그건 동기화 문제가 없어.
// 다른 게임 서버에 똑같은 bidder_id를 가진 놈이 있을 수가 없으니까.
// 그러므로 그 게임 서버에서 BidCancel 명령을 db에 날렸다는 것은,
// 이미 그 부분에 대해서는 검사가 완벽하다는 것이야.
// 그래도 혹시나 싶어서, 디버깅을 위해 fail 코드를 남겨둔다.
if (result <= AUCTION_FAIL)
{
TPacketDGResultAuction enroll_result;
@ -4915,14 +4915,14 @@ void CClientManager::AuctionBidCancel (CPeer * peer, DWORD bidder_id, DWORD item
{
AuctionResult result = AuctionManager::instance().BidCancel (bidder_id, item_id);
// <EFBFBD>̰<EFBFBD> FAIL<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ȵ<EFBFBD>.
// FAIL<EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>°<EFBFBD>, MyBid<EFBFBD><EFBFBD> <20>ִ<EFBFBD> bidder_id<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> bidder_id<69><64><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><> <20>ְŵ<D6B0>?
// <EFBFBD>׷<EFBFBD><EFBFBD>Ƿ<EFBFBD> <20>ٸ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>۵<EFBFBD><DBB5>Ѵٰ<D1B4> <20><><EFBFBD><EFBFBD> <20>Ѵٸ<D1B4>
// <EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> bidder_id<EFBFBD><EFBFBD> MyBid<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20>װ<EFBFBD> <20><><EFBFBD><EFBFBD>ȭ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
// <EFBFBD>ٸ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ȱ<EFBFBD><C8B0><EFBFBD> bidder_id<69><64> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD>.
// <EFBFBD>׷<EFBFBD><EFBFBD>Ƿ<EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> BidCancel <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> db<64><62> <20><><EFBFBD>ȴٴ<C8B4> <20><><EFBFBD><EFBFBD>,
// <EFBFBD>̹<EFBFBD> <20><> <20>κп<CEBA> <20><><EFBFBD>ؼ<EFBFBD><D8BC><EFBFBD> <20>˻簡 <20>Ϻ<EFBFBD><CFBA>ϴٴ<CFB4> <20><><EFBFBD>̾<EFBFBD>.
// <EFBFBD>׷<EFBFBD><EFBFBD><EFBFBD> Ȥ<>ó<EFBFBD> <20>;, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> fail <20>ڵ带 <20><><EFBFBD>ܵд<DCB5>.
// 이건 FAIL이 떠서는 안돼.
// FAIL이 뜰 수가 없는게, MyBid에 있는 bidder_id에 대한 컨텐츠는 bidder_id만이 접근 할 수 있거든?
// 그러므로 다른 것이 다 정상적으로 작동한다고 가정 한다면
// 한 게임 서버 내에서 bidder_id MyBid를 수정한다 할 지라도, 그건 동기화 문제가 없어.
// 다른 게임 서버에 똑같은 bidder_id를 가진 놈이 있을 수가 없으니까.
// 그러므로 그 게임 서버에서 BidCancel 명령을 db에 날렸다는 것은,
// 이미 그 부분에 대해서는 검사가 완벽하다는 것이야.
// 그래도 혹시나 싶어서, 디버깅을 위해 fail 코드를 남겨둔다.
if (result <= AUCTION_FAIL)
{
TPacketDGResultAuction enroll_result;

View File

@ -171,42 +171,42 @@ class FCompareVnum
bool CClientManager::InitializeMobTable()
{
//================== <EFBFBD>Լ<EFBFBD> <20><><EFBFBD><EFBFBD> ==================//
//1. <EFBFBD><EFBFBD><EFBFBD><EFBFBD> : 'mob_proto.txt', 'mob_proto_test.txt', 'mob_names.txt' <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>а<EFBFBD>,
// (!)[mob_table] <EFBFBD><EFBFBD><EFBFBD>̺<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>. (Ÿ<><C5B8> : TMobTable)
//2. <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 1) 'mob_names.txt' <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>о (a)[localMap](vnum:name) <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
// 2) 'mob_proto_test.txt'<EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> (a)[localMap] <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// (b)[test_map_mobTableByVnum](vnum:TMobTable) <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
// 3) 'mob_proto.txt' <EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> (a)[localMap] <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// (!)[mob_table] <EFBFBD><EFBFBD><EFBFBD>̺<EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
// <<EFBFBD><EFBFBD><EFBFBD><EFBFBD>>
// <EFBFBD><EFBFBD> row <EFBFBD><EFBFBD> <20><>,
// (b)[test_map_mobTableByVnum],(!)[mob_table] <EFBFBD><EFBFBD><EFBFBD>ο<EFBFBD> <20>ִ<EFBFBD> row<EFBFBD><EFBFBD>
// (b)[test_map_mobTableByVnum]<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
// 4) (b)[test_map_mobTableByVnum]<EFBFBD><EFBFBD> row<EFBFBD><EFBFBD>, (!)[mob_table]<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>߰<EFBFBD><DFB0>Ѵ<EFBFBD>.
//3. <EFBFBD>׽<EFBFBD>Ʈ
// 1)'mob_proto.txt' <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> mob_table<EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EEB0AC><EFBFBD><EFBFBD>. -> <EFBFBD>Ϸ<EFBFBD>
// 2)'mob_names.txt' <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> mob_table<EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EEB0AC><EFBFBD><EFBFBD>.
// 3)'mob_proto_test.txt' <EFBFBD><EFBFBD><EFBFBD><EFBFBD> [<5B><>ġ<EFBFBD><C4A1>] <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> mob_table <20><> <20><> <20><><EFBFBD><EFBFBD><EEB0AC><EFBFBD><EFBFBD>.
// 4)'mob_proto_test.txt' <EFBFBD><EFBFBD><EFBFBD><EFBFBD> [<5B><><EFBFBD>ο<EFBFBD>] <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> mob_table <20><> <20><> <20><><EFBFBD><EFBFBD><EEB0AC><EFBFBD><EFBFBD>.
// 5) (<EFBFBD><EFBFBD><EFBFBD><EFBFBD>) <20><><EFBFBD><EFBFBD> Ŭ<><C5AC><EFBFBD>̾<EFBFBD>Ʈ<EFBFBD><C6AE><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>۵<EFBFBD> <20>ϴ<EFBFBD><CFB4><EFBFBD>.
//================== 함수 설명 ==================//
//1. 요약 : 'mob_proto.txt', 'mob_proto_test.txt', 'mob_names.txt' 파일을 읽고,
// (!)[mob_table] 테이블 오브젝트를 생성한다. (타입 : TMobTable)
//2. 순서
// 1) 'mob_names.txt' 파일을 읽어서 (a)[localMap](vnum:name) 맵을 만든다.
// 2) 'mob_proto_test.txt'파일과 (a)[localMap] 맵으로
// (b)[test_map_mobTableByVnum](vnum:TMobTable) 맵을 생성한다.
// 3) 'mob_proto.txt' 파일과 (a)[localMap] 맵으로
// (!)[mob_table] 테이블을 만든다.
// <참고>
// row 들 중,
// (b)[test_map_mobTableByVnum],(!)[mob_table] 모두에 있는 row
// (b)[test_map_mobTableByVnum]의 것을 사용한다.
// 4) (b)[test_map_mobTableByVnum] row, (!)[mob_table]에 없는 것을 추가한다.
//3. 테스트
// 1)'mob_proto.txt' 정보가 mob_table에 잘 들어갔는지. -> 완료
// 2)'mob_names.txt' 정보가 mob_table에 잘 들어갔는지.
// 3)'mob_proto_test.txt' 에서 [겹치는] 정보가 mob_table 에 잘 들어갔는지.
// 4)'mob_proto_test.txt' 에서 [새로운] 정보가 mob_table 에 잘 들어갔는지.
// 5) (최종) 게임 클라이언트에서 제대로 작동 하는지.
//_______________________________________________//
//===============================================//
// 1) 'mob_names.txt' <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>о (a)[localMap] <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
//<(a)localMap <EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>>
// 1) 'mob_names.txt' 파일을 읽어서 (a)[localMap] 맵을 만든다.
//<(a)localMap 맵 생성>
map<int,const char*> localMap;
bool isNameFile = true;
//<<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>б<EFBFBD>>
//<파일 읽기>
cCsvTable nameData;
if(!nameData.Load("mob_names.txt",'\t'))
{
SPDLOG_ERROR("mob_names.txt <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>о<EFBFBD><D0BE><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>߽<EFBFBD><DFBD>ϴ<EFBFBD>");
SPDLOG_ERROR("mob_names.txt 파일을 읽어오지 못했습니다");
isNameFile = false;
} else {
nameData.Next(); //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>row <20><><EFBFBD><EFBFBD>.
nameData.Next(); //설명row 생략.
while(nameData.Next()) {
localMap[atoi(nameData.AsStringByIndex(0))] = nameData.AsStringByIndex(1);
}
@ -215,35 +215,35 @@ bool CClientManager::InitializeMobTable()
//===============================================//
// 2) 'mob_proto_test.txt'<EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> (a)localMap <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// (b)[test_map_mobTableByVnum](vnum:TMobTable) <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
// 2) 'mob_proto_test.txt'파일과 (a)localMap 맵으로
// (b)[test_map_mobTableByVnum](vnum:TMobTable) 맵을 생성한다.
//0.
set<int> vnumSet; //<EFBFBD>׽<EFBFBD>Ʈ<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20>űԿ<C5B1><D4BF><EFBFBD> Ȯ<>ο<EFBFBD> <20><><EFBFBD><EFBFBD>.
//1. <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>о<EFBFBD><D0BE><EFBFBD><EFBFBD><EFBFBD>
set<int> vnumSet; //테스트용 파일 데이터중, 신규여부 확인에 사용.
//1. 파일 읽어오기
bool isTestFile = true;
cCsvTable test_data;
if(!test_data.Load("mob_proto_test.txt",'\t'))
{
SPDLOG_ERROR("<EFBFBD>׽<EFBFBD>Ʈ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>. <20>״<EFBFBD><D7B4><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>մϴ<D5B4>.");
SPDLOG_ERROR("테스트 파일이 없습니다. 그대로 진행합니다.");
isTestFile = false;
}
//2. (c)[test_map_mobTableByVnum](vnum:TMobTable) <EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
//2. (c)[test_map_mobTableByVnum](vnum:TMobTable) 맵 생성.
map<DWORD, TMobTable *> test_map_mobTableByVnum;
if (isTestFile) {
test_data.Next(); //<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ο<EFBFBD> <20>Ѿ<D1BE><EEB0A1>.
test_data.Next(); //설명 로우 넘어가기.
//<EFBFBD><EFBFBD>. <20>׽<EFBFBD>Ʈ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>̺<EFBFBD> <20><><EFBFBD><EFBFBD>.
//ㄱ. 테스트 몬스터 테이블 생성.
TMobTable * test_mob_table = NULL;
int test_MobTableSize = test_data.m_File.GetRowCount()-1;
test_mob_table = new TMobTable[test_MobTableSize];
memset(test_mob_table, 0, sizeof(TMobTable) * test_MobTableSize);
//<EFBFBD><EFBFBD>. <20>׽<EFBFBD>Ʈ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>̺<EFBFBD><CCBA><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ְ<EFBFBD>, <20>ʿ<EFBFBD><CABF><EFBFBD><EFBFBD><EFBFBD> <20>ֱ<EFBFBD>.
//ㄴ. 테스트 몬스터 테이블에 값을 넣고, 맵에까지 넣기.
while(test_data.Next()) {
if (!Set_Proto_Mob_Table(test_mob_table, test_data, localMap))
{
SPDLOG_ERROR("<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>̺<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.");
SPDLOG_ERROR("몹 프로토 테이블 셋팅 실패.");
}
test_map_mobTableByVnum.insert(std::map<DWORD, TMobTable *>::value_type(test_mob_table->dwVnum, test_mob_table));
@ -254,22 +254,22 @@ bool CClientManager::InitializeMobTable()
}
// 3) 'mob_proto.txt' <EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> (a)[localMap] <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// (!)[mob_table] <EFBFBD><EFBFBD><EFBFBD>̺<EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
// <<EFBFBD><EFBFBD><EFBFBD><EFBFBD>>
// <EFBFBD><EFBFBD> row <EFBFBD><EFBFBD> <20><>,
// (b)[test_map_mobTableByVnum],(!)[mob_table] <EFBFBD><EFBFBD><EFBFBD>ο<EFBFBD> <20>ִ<EFBFBD> row<EFBFBD><EFBFBD>
// (b)[test_map_mobTableByVnum]<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
// 3) 'mob_proto.txt' 파일과 (a)[localMap] 맵으로
// (!)[mob_table] 테이블을 만든다.
// <참고>
// row 들 중,
// (b)[test_map_mobTableByVnum],(!)[mob_table] 모두에 있는 row
// (b)[test_map_mobTableByVnum]의 것을 사용한다.
//1. <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>б<EFBFBD>.
//1. 파일 읽기.
cCsvTable data;
if(!data.Load("mob_proto.txt",'\t')) {
SPDLOG_ERROR("mob_proto.txt <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>о<EFBFBD><D0BE><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>߽<EFBFBD><DFBD>ϴ<EFBFBD>");
SPDLOG_ERROR("mob_proto.txt 파일을 읽어오지 못했습니다");
return false;
}
data.Next(); //<EFBFBD><EFBFBD><EFBFBD><EFBFBD> row <EFBFBD>Ѿ<EFBFBD><EFBFBD>
//2. (!)[mob_table] <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD>
//2.1 <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>߰<EFBFBD><DFB0>Ǵ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ľ<EFBFBD>
data.Next(); //설명 row 넘어가기
//2. (!)[mob_table] 생성하기
//2.1 새로 추가되는 갯수를 파악
int addNumber = 0;
while(data.Next()) {
int vnum = atoi(data.AsStringByIndex(0));
@ -279,15 +279,15 @@ bool CClientManager::InitializeMobTable()
addNumber++;
}
}
//data<EFBFBD><EFBFBD> <20>ٽ<EFBFBD> ù<>ٷ<EFBFBD> <20>ű<EFBFBD><C5B1><EFBFBD>.(<28>ٽ<EFBFBD> <20>о<EFBFBD><D0BE>´<EFBFBD>;;)
//data를 다시 첫줄로 옮긴다.(다시 읽어온다;;)
data.Destroy();
if(!data.Load("mob_proto.txt",'\t'))
{
SPDLOG_ERROR("mob_proto.txt <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>о<EFBFBD><D0BE><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>߽<EFBFBD><DFBD>ϴ<EFBFBD>");
SPDLOG_ERROR("mob_proto.txt 파일을 읽어오지 못했습니다");
return false;
}
data.Next(); //<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Į<><C4AE><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20>κ<EFBFBD>)
//2.2 ũ<EFBFBD><20>°<EFBFBD> mob_table <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
data.Next(); //맨 윗줄 제외 (아이템 칼럼을 설명하는 부분)
//2.2 크기에 맞게 mob_table 생성
if (!m_vec_mobTable.empty())
{
SPDLOG_DEBUG("RELOAD: mob_proto");
@ -296,18 +296,18 @@ bool CClientManager::InitializeMobTable()
m_vec_mobTable.resize(data.m_File.GetRowCount()-1 + addNumber);
memset(&m_vec_mobTable[0], 0, sizeof(TMobTable) * m_vec_mobTable.size());
TMobTable * mob_table = &m_vec_mobTable[0];
//2.3 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ä<><C3A4><EFBFBD><EFBFBD>
//2.3 데이터 채우기
while (data.Next())
{
int col = 0;
//(b)[test_map_mobTableByVnum]<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> row<6F><77> <20>ִ<EFBFBD><D6B4><EFBFBD> <20><><EFBFBD><EFBFBD>.
//(b)[test_map_mobTableByVnum]에 같은 row가 있는지 조사.
bool isSameRow = true;
std::map<DWORD, TMobTable *>::iterator it_map_mobTable;
it_map_mobTable = test_map_mobTableByVnum.find(atoi(data.AsStringByIndex(col)));
if(it_map_mobTable == test_map_mobTableByVnum.end()) {
isSameRow = false;
}
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD> row <EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (b)<29><><EFBFBD><EFBFBD> <20>о<EFBFBD><D0BE>´<EFBFBD>.
//같은 row 가 있으면 (b)에서 읽어온다.
if(isSameRow) {
TMobTable *tempTable = it_map_mobTable->second;
@ -378,13 +378,13 @@ bool CClientManager::InitializeMobTable()
if (!Set_Proto_Mob_Table(mob_table, data, localMap))
{
SPDLOG_ERROR("<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>̺<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.");
SPDLOG_ERROR("몹 프로토 테이블 셋팅 실패.");
}
}
//<EFBFBD>¿<EFBFBD> vnum <EFBFBD>߰<EFBFBD>
//셋에 vnum 추가
vnumSet.insert(mob_table->dwVnum);
@ -395,22 +395,22 @@ bool CClientManager::InitializeMobTable()
//_____________________________________________________//
// 4) (b)[test_map_mobTableByVnum]<EFBFBD><EFBFBD> row<EFBFBD><EFBFBD>, (!)[mob_table]<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>߰<EFBFBD><DFB0>Ѵ<EFBFBD>.
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ٽ<EFBFBD> <20>о<EFBFBD><D0BE><EFBFBD><EFBFBD><EFBFBD>.
// 4) (b)[test_map_mobTableByVnum] row, (!)[mob_table]에 없는 것을 추가한다.
//파일 다시 읽어오기.
test_data.Destroy();
isTestFile = true;
test_data;
if(!test_data.Load("mob_proto_test.txt",'\t'))
{
SPDLOG_ERROR("<EFBFBD>׽<EFBFBD>Ʈ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>. <20>״<EFBFBD><D7B4><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>մϴ<D5B4>.");
SPDLOG_ERROR("테스트 파일이 없습니다. 그대로 진행합니다.");
isTestFile = false;
}
if(isTestFile) {
test_data.Next(); //<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ο<EFBFBD> <20>Ѿ<D1BE><EEB0A1>.
test_data.Next(); //설명 로우 넘어가기.
while (test_data.Next()) //<EFBFBD>׽<EFBFBD>Ʈ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ⱦ<C8BE><EEB3AA><EFBFBD><EFBFBD>,<2C><><EFBFBD>ο<EFBFBD> <20><><EFBFBD><EFBFBD> <20>߰<EFBFBD><DFB0>Ѵ<EFBFBD>.
while (test_data.Next()) //테스트 데이터 각각을 훑어나가며,새로운 것을 추가한다.
{
//<EFBFBD>ߺ<EFBFBD><EFBFBD>Ǵ<EFBFBD> <20>κ<EFBFBD><CEBA≯<EFBFBD> <20>Ѿ<D1BE><EEB0A3>.
//중복되는 부분이면 넘어간다.
set<int>::iterator itVnum;
itVnum=vnumSet.find(atoi(test_data.AsStringByIndex(0)));
if (itVnum != vnumSet.end()) {
@ -419,7 +419,7 @@ bool CClientManager::InitializeMobTable()
if (!Set_Proto_Mob_Table(mob_table, test_data, localMap))
{
SPDLOG_ERROR("<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>̺<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.");
SPDLOG_ERROR("몹 프로토 테이블 셋팅 실패.");
}
SPDLOG_DEBUG("MOB #{:<5} {:24} {:24} level: {:<3} rank: {} empire: {}", mob_table->dwVnum, mob_table->szName, mob_table->szLocaleName, mob_table->bLevel, mob_table->bRank, mob_table->bEmpire);
@ -447,8 +447,8 @@ bool CClientManager::InitializeShopTable()
std::unique_ptr<SQLMsg> pkMsg2(CDBManager::instance().DirectQuery(s_szQuery));
// shop<EFBFBD><EFBFBD> vnum<EFBFBD><EFBFBD> <20>ִµ<D6B4> shop_item <EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>... <20><><EFBFBD>з<EFBFBD> ó<><C3B3><EFBFBD>Ǵ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
// <EFBFBD><EFBFBD>ó<EFBFBD><EFBFBD><EFBFBD>Һκ<EFBFBD>
// shop vnum은 있는데 shop_item 이 없을경우... 실패로 처리되니 주의 요망.
// 고처야할부분
SQLResult * pRes2 = pkMsg2->Get();
if (!pRes2->uiNumRows)
@ -487,7 +487,7 @@ bool CClientManager::InitializeShopTable()
str_to_number(shop_table->dwNPCVnum, data[col++]);
if (!data[col]) // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ϳ<EFBFBD><CFB3><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> NULL<4C><4C> <20><><EFBFBD><EFBFBD> <20>ǹǷ<C7B9>..
if (!data[col]) // 아이템이 하나도 없으면 NULL이 리턴 되므로..
continue;
TShopItemTable * pItem = &shop_table->items[shop_table->byItemCount];
@ -560,7 +560,7 @@ bool CClientManager::InitializeQuestItemTable()
continue;
}
tbl.bType = ITEM_QUEST; // quest_item_proto <EFBFBD><EFBFBD><EFBFBD>̺<EFBFBD><EFBFBD><EFBFBD> <20>ִ<EFBFBD> <20>͵<EFBFBD><CDB5><EFBFBD> <20><><EFBFBD><EFBFBD> ITEM_QUEST <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
tbl.bType = ITEM_QUEST; // quest_item_proto 테이블에 있는 것들은 모두 ITEM_QUEST 유형
tbl.bSize = 1;
m_vec_itemTable.push_back(tbl);
@ -571,39 +571,39 @@ bool CClientManager::InitializeQuestItemTable()
bool CClientManager::InitializeItemTable()
{
//================== <EFBFBD>Լ<EFBFBD> <20><><EFBFBD><EFBFBD> ==================//
//1. <EFBFBD><EFBFBD><EFBFBD><EFBFBD> : 'item_proto.txt', 'item_proto_test.txt', 'item_names.txt' <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>а<EFBFBD>,
// <item_table>(TItemTable), <m_map_itemTableByVnum> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
//2. <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 1) 'item_names.txt' <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>о (a)[localMap](vnum:name) <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
// 2) 'item_proto_text.txt'<EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> (a)[localMap] <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// (b)[test_map_itemTableByVnum](vnum:TItemTable) <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
// 3) 'item_proto.txt' <EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> (a)[localMap] <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// (!)[item_table], <m_map_itemTableByVnum><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
// <<EFBFBD><EFBFBD><EFBFBD><EFBFBD>>
// <EFBFBD><EFBFBD> row <EFBFBD><EFBFBD> <20><>,
// (b)[test_map_itemTableByVnum],(!)[mob_table] <EFBFBD><EFBFBD><EFBFBD>ο<EFBFBD> <20>ִ<EFBFBD> row<EFBFBD><EFBFBD>
// (b)[test_map_itemTableByVnum]<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
// 4) (b)[test_map_itemTableByVnum]<EFBFBD><EFBFBD> row<EFBFBD><EFBFBD>, (!)[item_table]<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>߰<EFBFBD><DFB0>Ѵ<EFBFBD>.
//3. <EFBFBD>׽<EFBFBD>Ʈ
// 1)'item_proto.txt' <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> item_table<EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EEB0AC><EFBFBD><EFBFBD>. -> <EFBFBD>Ϸ<EFBFBD>
// 2)'item_names.txt' <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> item_table<EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EEB0AC><EFBFBD><EFBFBD>.
// 3)'item_proto_test.txt' <EFBFBD><EFBFBD><EFBFBD><EFBFBD> [<5B><>ġ<EFBFBD><C4A1>] <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> item_table <20><> <20><> <20><><EFBFBD><EFBFBD><EEB0AC><EFBFBD><EFBFBD>.
// 4)'item_proto_test.txt' <EFBFBD><EFBFBD><EFBFBD><EFBFBD> [<5B><><EFBFBD>ο<EFBFBD>] <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> item_table <20><> <20><> <20><><EFBFBD><EFBFBD><EEB0AC><EFBFBD><EFBFBD>.
// 5) (<EFBFBD><EFBFBD><EFBFBD><EFBFBD>) <20><><EFBFBD><EFBFBD> Ŭ<><C5AC><EFBFBD>̾<EFBFBD>Ʈ<EFBFBD><C6AE><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>۵<EFBFBD> <20>ϴ<EFBFBD><CFB4><EFBFBD>.
//================== 함수 설명 ==================//
//1. 요약 : 'item_proto.txt', 'item_proto_test.txt', 'item_names.txt' 파일을 읽고,
// <item_table>(TItemTable), <m_map_itemTableByVnum> 오브젝트를 생성한다.
//2. 순서
// 1) 'item_names.txt' 파일을 읽어서 (a)[localMap](vnum:name) 맵을 만든다.
// 2) 'item_proto_text.txt'파일과 (a)[localMap] 맵으로
// (b)[test_map_itemTableByVnum](vnum:TItemTable) 맵을 생성한다.
// 3) 'item_proto.txt' 파일과 (a)[localMap] 맵으로
// (!)[item_table], <m_map_itemTableByVnum>을 만든다.
// <참고>
// row 들 중,
// (b)[test_map_itemTableByVnum],(!)[mob_table] 모두에 있는 row
// (b)[test_map_itemTableByVnum]의 것을 사용한다.
// 4) (b)[test_map_itemTableByVnum] row, (!)[item_table]에 없는 것을 추가한다.
//3. 테스트
// 1)'item_proto.txt' 정보가 item_table에 잘 들어갔는지. -> 완료
// 2)'item_names.txt' 정보가 item_table에 잘 들어갔는지.
// 3)'item_proto_test.txt' 에서 [겹치는] 정보가 item_table 에 잘 들어갔는지.
// 4)'item_proto_test.txt' 에서 [새로운] 정보가 item_table 에 잘 들어갔는지.
// 5) (최종) 게임 클라이언트에서 제대로 작동 하는지.
//_______________________________________________//
//=================================================================================//
// 1) 'item_names.txt' <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>о (a)[localMap](vnum:name) <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
// 1) 'item_names.txt' 파일을 읽어서 (a)[localMap](vnum:name) 맵을 만든다.
//=================================================================================//
bool isNameFile = true;
map<int,const char*> localMap;
cCsvTable nameData;
if(!nameData.Load("item_names.txt",'\t'))
{
SPDLOG_ERROR("item_names.txt <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>о<EFBFBD><D0BE><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>߽<EFBFBD><DFBD>ϴ<EFBFBD>");
SPDLOG_ERROR("item_names.txt 파일을 읽어오지 못했습니다");
isNameFile = false;
} else {
nameData.Next();
@ -614,32 +614,32 @@ bool CClientManager::InitializeItemTable()
//_________________________________________________________________//
//=================================================================//
// 2) 'item_proto_text.txt'<EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> (a)[localMap] <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// (b)[test_map_itemTableByVnum](vnum:TItemTable) <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
// 2) 'item_proto_text.txt'파일과 (a)[localMap] 맵으로
// (b)[test_map_itemTableByVnum](vnum:TItemTable) 맵을 생성한다.
//=================================================================//
map<DWORD, TItemTable *> test_map_itemTableByVnum;
//1. <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>о<EFBFBD><D0BE><EFBFBD><EFBFBD><EFBFBD>.
//1. 파일 읽어오기.
cCsvTable test_data;
if(!test_data.Load("item_proto_test.txt",'\t'))
{
SPDLOG_ERROR("item_proto_test.txt <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>о<EFBFBD><D0BE><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>߽<EFBFBD><DFBD>ϴ<EFBFBD>");
SPDLOG_ERROR("item_proto_test.txt 파일을 읽어오지 못했습니다");
//return false;
} else {
test_data.Next(); //<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ο<EFBFBD> <20>Ѿ<D1BE><EEB0A1>.
test_data.Next(); //설명 로우 넘어가기.
//2. <EFBFBD>׽<EFBFBD>Ʈ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>̺<EFBFBD> <20><><EFBFBD><EFBFBD>.
//2. 테스트 아이템 테이블 생성.
TItemTable * test_item_table = NULL;
int test_itemTableSize = test_data.m_File.GetRowCount()-1;
test_item_table = new TItemTable[test_itemTableSize];
memset(test_item_table, 0, sizeof(TItemTable) * test_itemTableSize);
//3. <EFBFBD>׽<EFBFBD>Ʈ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>̺<EFBFBD><CCBA><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ְ<EFBFBD>, <20>ʿ<EFBFBD><CABF><EFBFBD><EFBFBD><EFBFBD> <20>ֱ<EFBFBD>.
//3. 테스트 아이템 테이블에 값을 넣고, 맵에까지 넣기.
while(test_data.Next()) {
if (!Set_Proto_Item_Table(test_item_table, test_data, localMap))
{
SPDLOG_ERROR("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>̺<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.");
SPDLOG_ERROR("아이템 프로토 테이블 셋팅 실패.");
}
test_map_itemTableByVnum.insert(std::map<DWORD, TItemTable *>::value_type(test_item_table->dwVnum, test_item_table));
@ -651,25 +651,25 @@ bool CClientManager::InitializeItemTable()
//========================================================================//
// 3) 'item_proto.txt' <EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> (a)[localMap] <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// (!)[item_table], <m_map_itemTableByVnum><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
// <<EFBFBD><EFBFBD><EFBFBD><EFBFBD>>
// <EFBFBD><EFBFBD> row <EFBFBD><EFBFBD> <20><>,
// (b)[test_map_itemTableByVnum],(!)[mob_table] <EFBFBD><EFBFBD><EFBFBD>ο<EFBFBD> <20>ִ<EFBFBD> row<EFBFBD><EFBFBD>
// (b)[test_map_itemTableByVnum]<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
// 3) 'item_proto.txt' 파일과 (a)[localMap] 맵으로
// (!)[item_table], <m_map_itemTableByVnum>을 만든다.
// <참고>
// row 들 중,
// (b)[test_map_itemTableByVnum],(!)[mob_table] 모두에 있는 row
// (b)[test_map_itemTableByVnum]의 것을 사용한다.
//========================================================================//
//vnum<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>. <20><><EFBFBD>ο<EFBFBD> <20>׽<EFBFBD>Ʈ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ǻ<EFBFBD><C7BA>Ҷ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD>.
//vnum들을 저장할 셋. 새로운 테스트 아이템을 판별할때 사용된다.
set<int> vnumSet;
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>о<EFBFBD><D0BE><EFBFBD><EFBFBD><EFBFBD>.
//파일 읽어오기.
cCsvTable data;
if(!data.Load("item_proto.txt",'\t'))
{
SPDLOG_ERROR("item_proto.txt <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>о<EFBFBD><D0BE><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>߽<EFBFBD><DFBD>ϴ<EFBFBD>");
SPDLOG_ERROR("item_proto.txt 파일을 읽어오지 못했습니다");
return false;
}
data.Next(); //<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Į<><C4AE><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20>κ<EFBFBD>)
data.Next(); //맨 윗줄 제외 (아이템 칼럼을 설명하는 부분)
if (!m_vec_itemTable.empty())
{
@ -678,8 +678,8 @@ bool CClientManager::InitializeItemTable()
m_map_itemTableByVnum.clear();
}
//===== <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>̺<EFBFBD> <20><><EFBFBD><EFBFBD> =====//
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>߰<EFBFBD><DFB0>Ǵ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ľ<EFBFBD><C4BE>Ѵ<EFBFBD>.
//===== 아이템 테이블 생성 =====//
//새로 추가되는 갯수를 파악한다.
int addNumber = 0;
while(data.Next()) {
int vnum = atoi(data.AsStringByIndex(0));
@ -689,14 +689,14 @@ bool CClientManager::InitializeItemTable()
addNumber++;
}
}
//data<EFBFBD><EFBFBD> <20>ٽ<EFBFBD> ù<>ٷ<EFBFBD> <20>ű<EFBFBD><C5B1><EFBFBD>.(<28>ٽ<EFBFBD> <20>о<EFBFBD><D0BE>´<EFBFBD>;;)
//data를 다시 첫줄로 옮긴다.(다시 읽어온다;;)
data.Destroy();
if(!data.Load("item_proto.txt",'\t'))
{
SPDLOG_ERROR("item_proto.txt <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>о<EFBFBD><D0BE><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>߽<EFBFBD><DFBD>ϴ<EFBFBD>");
SPDLOG_ERROR("item_proto.txt 파일을 읽어오지 못했습니다");
return false;
}
data.Next(); //<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Į<><C4AE><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20>κ<EFBFBD>)
data.Next(); //맨 윗줄 제외 (아이템 칼럼을 설명하는 부분)
m_vec_itemTable.resize(data.m_File.GetRowCount() - 1 + addNumber);
memset(&m_vec_itemTable[0], 0, sizeof(TItemTable) * m_vec_itemTable.size());
@ -711,16 +711,16 @@ bool CClientManager::InitializeItemTable()
std::map<DWORD, TItemTable *>::iterator it_map_itemTable;
it_map_itemTable = test_map_itemTableByVnum.find(atoi(data.AsStringByIndex(col)));
if(it_map_itemTable == test_map_itemTableByVnum.end()) {
//<EFBFBD><EFBFBD> Į<><C4AE> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
//각 칼럼 데이터 저장
if (!Set_Proto_Item_Table(item_table, data, localMap))
{
SPDLOG_ERROR("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>̺<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.");
SPDLOG_ERROR("아이템 프로토 테이블 셋팅 실패.");
}
} else { //$$$$$$$$$$$$$$$$$$$$$$$ <EFBFBD>׽<EFBFBD>Ʈ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ִ<EFBFBD>!
} else { //$$$$$$$$$$$$$$$$$$$$$$$ 테스트 아이템 정보가 있다!
TItemTable *tempTable = it_map_itemTable->second;
item_table->dwVnum = tempTable->dwVnum;
@ -777,19 +777,19 @@ bool CClientManager::InitializeItemTable()
//_______________________________________________________________________//
//========================================================================//
// 4) (b)[test_map_itemTableByVnum]<EFBFBD><EFBFBD> row<EFBFBD><EFBFBD>, (!)[item_table]<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>߰<EFBFBD><DFB0>Ѵ<EFBFBD>.
// 4) (b)[test_map_itemTableByVnum] row, (!)[item_table]에 없는 것을 추가한다.
//========================================================================//
test_data.Destroy();
if(!test_data.Load("item_proto_test.txt",'\t'))
{
SPDLOG_ERROR("item_proto_test.txt <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>о<EFBFBD><D0BE><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>߽<EFBFBD><DFBD>ϴ<EFBFBD>");
SPDLOG_ERROR("item_proto_test.txt 파일을 읽어오지 못했습니다");
//return false;
} else {
test_data.Next(); //<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ο<EFBFBD> <20>Ѿ<D1BE><EEB0A1>.
test_data.Next(); //설명 로우 넘어가기.
while (test_data.Next()) //<EFBFBD>׽<EFBFBD>Ʈ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ⱦ<C8BE><EEB3AA><EFBFBD><EFBFBD>,<2C><><EFBFBD>ο<EFBFBD> <20><><EFBFBD><EFBFBD> <20>߰<EFBFBD><DFB0>Ѵ<EFBFBD>.
while (test_data.Next()) //테스트 데이터 각각을 훑어나가며,새로운 것을 추가한다.
{
//<EFBFBD>ߺ<EFBFBD><EFBFBD>Ǵ<EFBFBD> <20>κ<EFBFBD><CEBA≯<EFBFBD> <20>Ѿ<D1BE><EEB0A3>.
//중복되는 부분이면 넘어간다.
set<int>::iterator itVnum;
itVnum=vnumSet.find(atoi(test_data.AsStringByIndex(0)));
if (itVnum != vnumSet.end()) {
@ -798,7 +798,7 @@ bool CClientManager::InitializeItemTable()
if (!Set_Proto_Item_Table(item_table, test_data, localMap))
{
SPDLOG_ERROR("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>̺<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.");
SPDLOG_ERROR("아이템 프로토 테이블 셋팅 실패.");
}

View File

@ -126,13 +126,13 @@ const char* __GetWarType(int n)
switch (n)
{
case 0 :
return "<EFBFBD>п<EFBFBD>";
return "\xEF\xBF\xBD\xD0\xBF\xEF\xBF\xBD"; // 패왕
case 1 :
return "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>";
return "\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD"; // 맹장
case 2 :
return "<EFBFBD><EFBFBD>ȣ";
return "\xEF\xBF\xBD\xEF\xBF\xBD\xC8\xA3"; // 수호
default :
return "<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ȣ";
return "\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\x20\xEF\xBF\xBD\xEF\xBF\xBD\xC8\xA3"; // 없는 번호
}
}
@ -161,7 +161,7 @@ void CClientManager::GuildWar(CPeer* peer, TPacketGuildWar* p)
case GUILD_WAR_WAIT_START:
SPDLOG_DEBUG("GuildWar: GUILD_WAR_WAIT_START type({}) guild({} - {})", __GetWarType(p->bType), p->dwGuildFrom, p->dwGuildTo);
case GUILD_WAR_RESERVE: // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
case GUILD_WAR_RESERVE: // 길드전 예약
if (p->bWar != GUILD_WAR_WAIT_START)
SPDLOG_DEBUG("GuildWar: GUILD_WAR_RESERVE type({}) guild({} - {})", __GetWarType(p->bType), p->dwGuildFrom, p->dwGuildTo);
CGuildManager::instance().RemoveDeclare(p->dwGuildFrom, p->dwGuildTo);
@ -173,21 +173,21 @@ void CClientManager::GuildWar(CPeer* peer, TPacketGuildWar* p)
break;
case GUILD_WAR_ON_WAR: // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>Ų<EFBFBD><C5B2>. (<28>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD><EFBFBD> <20>ٷ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><>)
case GUILD_WAR_ON_WAR: // 길드전을 시작 시킨다. (필드전은 바로 시작 됨)
SPDLOG_DEBUG("GuildWar: GUILD_WAR_ON_WAR type({}) guild({} - {})", __GetWarType(p->bType), p->dwGuildFrom, p->dwGuildTo);
CGuildManager::instance().RemoveDeclare(p->dwGuildFrom, p->dwGuildTo);
CGuildManager::instance().StartWar(p->bType, p->dwGuildFrom, p->dwGuildTo);
break;
case GUILD_WAR_OVER: // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
case GUILD_WAR_OVER: // 길드전 정상 종료
SPDLOG_DEBUG("GuildWar: GUILD_WAR_OVER type({}) guild({} - {})", __GetWarType(p->bType), p->dwGuildFrom, p->dwGuildTo);
CGuildManager::instance().RecvWarOver(p->dwGuildFrom, p->dwGuildTo, p->bType, p->lWarPrice);
break;
case GUILD_WAR_END: // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
case GUILD_WAR_END: // 길드전 비정상 종료
SPDLOG_DEBUG("GuildWar: GUILD_WAR_END type({}) guild({} - {})", __GetWarType(p->bType), p->dwGuildFrom, p->dwGuildTo);
CGuildManager::instance().RecvWarEnd(p->dwGuildFrom, p->dwGuildTo);
return; // NOTE: RecvWarEnd<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>Ŷ<EFBFBD><C5B6> <20><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ε<EFBFBD>ij<EFBFBD><C4B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ʴ´<CAB4>.
return; // NOTE: RecvWarEnd에서 패킷을 보내므로 따로 브로드캐스팅 하지 않는다.
case GUILD_WAR_CANCEL :
SPDLOG_DEBUG("GuildWar: GUILD_WAR_CANCEL type({}) guild({} - {})", __GetWarType(p->bType), p->dwGuildFrom, p->dwGuildTo);

View File

@ -230,7 +230,7 @@ TAccountTable * CreateAccountTableFromRes(MYSQL_RES * res)
TAccountTable * pkTab = new TAccountTable;
memset(pkTab, 0, sizeof(TAccountTable));
// ù<EFBFBD><EFBFBD>° <20>÷<EFBFBD> <20>͸<EFBFBD> <20><><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD> (JOIN QUERY<52><59> <20><><EFBFBD><EFBFBD> <20><> <20><>)
// 첫번째 컬럼 것만 참고 한다 (JOIN QUERY를 위한 것 임)
strlcpy(input_pwd, row[col++], sizeof(input_pwd));
str_to_number(pkTab->id, row[col++]);
strlcpy(pkTab->login, row[col++], sizeof(pkTab->login));
@ -354,7 +354,7 @@ void CClientManager::RESULT_LOGIN(CPeer * peer, SQLMsg * msg)
if (info->account_index == 0)
{
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>?
// 계정이 없네?
if (msg->Get()->uiNumRows == 0)
{
SPDLOG_DEBUG("RESULT_LOGIN: no account");
@ -396,14 +396,14 @@ void CClientManager::RESULT_LOGIN(CPeer * peer, SQLMsg * msg)
}
else
{
if (!info->pAccountTable) // <EFBFBD>̷<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;;
if (!info->pAccountTable) // 이럴리는 없겠지만;;
{
peer->EncodeReturn(HEADER_DG_LOGIN_WRONG_PASSWD, info->dwHandle);
delete info;
return;
}
// <EFBFBD>ٸ<EFBFBD> <20><><EFBFBD>ؼ<EFBFBD><D8BC><EFBFBD> <20>̹<EFBFBD> <20>α<EFBFBD><CEB1><EFBFBD> <20>ع<EFBFBD><D8B9>ȴٸ<C8B4>.. <20>̹<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ߴٰ<DFB4> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
// 다른 컨넥션이 이미 로그인 해버렸다면.. 이미 접속했다고 보내야 한다.
if (!InsertLogonAccount(info->pAccountTable->login, peer->GetHandle(), info->ip))
{
SPDLOG_DEBUG("RESULT_LOGIN: already logon {}", info->pAccountTable->login);

View File

@ -31,7 +31,7 @@ bool CreateItemTableFromRes(MYSQL_RES * res, std::vector<TPlayerItem> * pVec, DW
int rows;
if ((rows = mysql_num_rows(res)) <= 0) // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
if ((rows = mysql_num_rows(res)) <= 0) // 데이터 없음
{
pVec->clear();
return true;
@ -158,7 +158,7 @@ size_t CreatePlayerSaveQuery(char * pszQuery, size_t querySize, TPlayerTable * p
pkTab->horse.sStamina,
pkTab->horse_skill_point);
// Binary <EFBFBD><EFBFBD> <20>ٲٱ<D9B2> <20><><EFBFBD><EFBFBD> <20>ӽ<EFBFBD> <20><><EFBFBD><EFBFBD>
// Binary 로 바꾸기 위한 임시 공간
char text[8192 + 1];
CDBManager::instance().EscapeString(text, pkTab->skills, sizeof(pkTab->skills));
@ -210,7 +210,7 @@ void CClientManager::QUERY_PLAYER_LOAD(CPeer * peer, DWORD dwHandle, TPlayerLoad
TPlayerTable * pTab;
//
// <EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ij<><C4B3><EFBFBD>͵<EFBFBD> ij<><C4B3>ó<EFBFBD><C3B3>
// 한 계정에 속한 모든 캐릭터들 캐쉬처리
//
CLoginData * pLoginData = GetLoginDataByAID(packet->account_id);
@ -222,12 +222,12 @@ void CClientManager::QUERY_PLAYER_LOAD(CPeer * peer, DWORD dwHandle, TPlayerLoad
}
//----------------------------------------------------------------
// 1. <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> DBCache <EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> : DBCache<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 2. <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> DBCache <EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> : DB<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 1. 유저정보가 DBCache 에 존재 : DBCache에서
// 2. 유저정보가 DBCache 에 없음 : DB에서
// ---------------------------------------------------------------
//----------------------------------
// 1. <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> DBCache <EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> : DBCache<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 1. 유저정보가 DBCache 에 존재 : DBCache에서
//----------------------------------
if ((c = GetPlayerCache(packet->player_id)))
{
@ -267,13 +267,13 @@ void CClientManager::QUERY_PLAYER_LOAD(CPeer * peer, DWORD dwHandle, TPlayerLoad
SPDLOG_DEBUG("[PLAYER_LOAD] ID {} pid {} gold {} ", pTab->name, pTab->id, pTab->gold);
//--------------------------------------------
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> & AFFECT & QUEST <EFBFBD>ε<EFBFBD> :
// 아이템 & AFFECT & QUEST 로딩 :
//--------------------------------------------
// 1) <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> DBCache <EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> : DBCache <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 2) <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> DBCache <EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> : DB <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 1) 아이템이 DBCache 에 존재 : DBCache 에서 가져옴
// 2) 아이템이 DBCache 에 없음 : DB 에서 가져옴
/////////////////////////////////////////////
// 1) <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> DBCache <EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> : DBCache <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 1) 아이템이 DBCache 에 존재 : DBCache 에서 가져옴
/////////////////////////////////////////////
if (pSet)
{
@ -288,7 +288,7 @@ void CClientManager::QUERY_PLAYER_LOAD(CPeer * peer, DWORD dwHandle, TPlayerLoad
CItemCache * c = *it++;
TPlayerItem * p = c->Get();
if (p->vnum) // vnum<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̴<EFBFBD>.
if (p->vnum) // vnum이 없으면 삭제된 아이템이다.
memcpy(&s_items[dwCount++], p, sizeof(TPlayerItem));
}
@ -314,7 +314,7 @@ void CClientManager::QUERY_PLAYER_LOAD(CPeer * peer, DWORD dwHandle, TPlayerLoad
CDBManager::instance().ReturnQuery(szQuery, QID_AFFECT, peer->GetHandle(), new ClientHandleInfo(dwHandle));
}
/////////////////////////////////////////////
// 2) <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> DBCache <EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> : DB <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 2) 아이템이 DBCache 에 없음 : DB 에서 가져옴
/////////////////////////////////////////////
else
{
@ -348,7 +348,7 @@ void CClientManager::QUERY_PLAYER_LOAD(CPeer * peer, DWORD dwHandle, TPlayerLoad
//return;
}
//----------------------------------
// 2. <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> DBCache <EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> : DB<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 2. 유저정보가 DBCache 에 없음 : DB에서
//----------------------------------
else
{
@ -357,7 +357,7 @@ void CClientManager::QUERY_PLAYER_LOAD(CPeer * peer, DWORD dwHandle, TPlayerLoad
char queryStr[QUERY_MAX_LEN];
//--------------------------------------------------------------
// ij<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> : <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> DB<44><42><EFBFBD><EFBFBD>
// 캐릭터 정보 얻어오기 : 무조건 DB에서
//--------------------------------------------------------------
snprintf(queryStr, sizeof(queryStr),
"SELECT "
@ -373,7 +373,7 @@ void CClientManager::QUERY_PLAYER_LOAD(CPeer * peer, DWORD dwHandle, TPlayerLoad
CDBManager::instance().ReturnQuery(queryStr, QID_PLAYER, peer->GetHandle(), pkInfo);
//--------------------------------------------------------------
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 아이템 가져오기
//--------------------------------------------------------------
snprintf(queryStr, sizeof(queryStr),
"SELECT id,window+0,pos,count,vnum,socket0,socket1,socket2,attrtype0,attrvalue0,attrtype1,attrvalue1,attrtype2,attrvalue2,attrtype3,attrvalue3,attrtype4,attrvalue4,attrtype5,attrvalue5,attrtype6,attrvalue6 "
@ -382,15 +382,15 @@ void CClientManager::QUERY_PLAYER_LOAD(CPeer * peer, DWORD dwHandle, TPlayerLoad
CDBManager::instance().ReturnQuery(queryStr, QID_ITEM, peer->GetHandle(), new ClientHandleInfo(dwHandle, packet->player_id));
//--------------------------------------------------------------
// QUEST <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// QUEST 가져오기
//--------------------------------------------------------------
snprintf(queryStr, sizeof(queryStr),
"SELECT dwPID,szName,szState,lValue FROM quest%s WHERE dwPID=%d",
GetTablePostfix(), packet->player_id);
CDBManager::instance().ReturnQuery(queryStr, QID_QUEST, peer->GetHandle(), new ClientHandleInfo(dwHandle, packet->player_id,packet->account_id));
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ɿ<EFBFBD><C9BF><EFBFBD> item_award<72><64><EFBFBD>̺<EFBFBD><CCBA><EFBFBD><EFBFBD><EFBFBD> login <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> account id<EFBFBD><EFBFBD> <20>Ѱ<EFBFBD><D1B0>ش<EFBFBD>
//독일 선물 기능에서 item_award테이블에서 login 정보를 얻기위해 account id도 넘겨준다
//--------------------------------------------------------------
// AFFECT <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// AFFECT 가져오기
//--------------------------------------------------------------
snprintf(queryStr, sizeof(queryStr),
"SELECT dwPID,bType,bApplyOn,lApplyValue,dwFlag,lDuration,lSPCost FROM affect%s WHERE dwPID=%d",
@ -407,21 +407,21 @@ void CClientManager::ItemAward(CPeer * peer,char* login)
std::set<TItemAward *> * pSet = ItemAwardManager::instance().GetByLogin(login_t);
if(pSet == NULL)
return;
typeof(pSet->begin()) it = pSet->begin(); //taken_time<EFBFBD><EFBFBD> NULL<EFBFBD>ΰ͵<EFBFBD> <20>о<EFBFBD><D0BE><EFBFBD>
typeof(pSet->begin()) it = pSet->begin(); //taken_time NULL인것들 읽어옴
while(it != pSet->end() )
{
TItemAward * pItemAward = *(it++);
char* whyStr = pItemAward->szWhy; //why <EFBFBD>ݷ<EFBFBD> <20>б<EFBFBD>
char cmdStr[100] = ""; //why<EFBFBD>ݷ뿡<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ӽ<EFBFBD> <20><><EFBFBD>ڿ<EFBFBD><DABF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD>
strcpy(cmdStr,whyStr); //<EFBFBD><EFBFBD><EFBFBD>ɾ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ū<EFBFBD><C5AB><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ūȭ <20>DZ<EFBFBD> <20><><EFBFBD><EFBFBD>
char* whyStr = pItemAward->szWhy; //why 콜룸 읽기
char cmdStr[100] = ""; //why콜룸에서 읽은 값을 임시 문자열에 복사해둠
strcpy(cmdStr,whyStr); //명령어 얻는 과정에서 토큰쓰면 원본도 토큰화 되기 때문
char command[20] = "";
strcpy(command,GetCommand(cmdStr).c_str()); // command <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if( !(strcmp(command,"GIFT") )) // command <EFBFBD><EFBFBD> GIFT<EFBFBD≯<EFBFBD>
strcpy(command,GetCommand(cmdStr).c_str()); // command 얻기
if( !(strcmp(command,"GIFT") )) // command GIFT이면
{
TPacketItemAwardInfromer giftData;
strcpy(giftData.login, pItemAward->szLogin); //<EFBFBD>α<EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>̵<EFBFBD> <20><><EFBFBD><EFBFBD>
strcpy(giftData.command, command); //<EFBFBD><EFBFBD><EFBFBD>ɾ<EFBFBD> <20><><EFBFBD><EFBFBD>
giftData.vnum = pItemAward->dwVnum; //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> vnum<75><6D> <20><><EFBFBD><EFBFBD>
strcpy(giftData.login, pItemAward->szLogin); //로그인 아이디 복사
strcpy(giftData.command, command); //명령어 복사
giftData.vnum = pItemAward->dwVnum; //아이템 vnum도 복사
ForwardPacket(HEADER_DG_ITEMAWARD_INFORMER,&giftData,sizeof(TPacketItemAwardInfromer));
}
}
@ -442,7 +442,7 @@ std::string CClientManager::GetCommand(char* str)
bool CreatePlayerTableFromRes(MYSQL_RES * res, TPlayerTable * pkTab)
{
if (mysql_num_rows(res) == 0) // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
if (mysql_num_rows(res) == 0) // 데이터 없음
return false;
memset(pkTab, 0, sizeof(TPlayerTable));
@ -529,11 +529,11 @@ bool CreatePlayerTableFromRes(MYSQL_RES * res, TPlayerTable * pkTab)
int max_point = pkTab->level - 9;
int skill_point =
std::min<int>(20, pkTab->skills[121].bLevel) + // SKILL_LEADERSHIP <EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD>
std::min<int>(20, pkTab->skills[124].bLevel) + // SKILL_MINING ä<EFBFBD><EFBFBD>
std::min<int>(10, pkTab->skills[131].bLevel) + // SKILL_HORSE_SUMMON <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȯ
std::min<int>(20, pkTab->skills[141].bLevel) + // SKILL_ADD_HP HP<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
std::min<int>(20, pkTab->skills[142].bLevel); // SKILL_RESIST_PENETRATE <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
std::min<int>(20, pkTab->skills[121].bLevel) + // SKILL_LEADERSHIP 통솔력
std::min<int>(20, pkTab->skills[124].bLevel) + // SKILL_MINING 채광
std::min<int>(10, pkTab->skills[131].bLevel) + // SKILL_HORSE_SUMMON 말소환
std::min<int>(20, pkTab->skills[141].bLevel) + // SKILL_ADD_HP HP보강
std::min<int>(20, pkTab->skills[142].bLevel); // SKILL_RESIST_PENETRATE 관통저항
pkTab->sub_skill_point = max_point - skill_point;
}
@ -573,13 +573,13 @@ void CClientManager::RESULT_COMPOSITE_PLAYER(CPeer * peer, SQLMsg * pMsg, DWORD
{
SPDLOG_DEBUG("QID_QUEST {}", info->dwHandle);
RESULT_QUEST_LOAD(peer, pSQLResult, info->dwHandle, info->player_id);
//aid<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//aid얻기
ClientHandleInfo* temp1 = info.get();
if (temp1 == NULL)
break;
CLoginData* pLoginData1 = GetLoginDataByAID(temp1->account_id); //
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
//독일 선물 기능
if( pLoginData1->GetAccountRef().login == NULL)
break;
if( pLoginData1 == NULL )
@ -670,14 +670,14 @@ void CClientManager::RESULT_PLAYER_LOAD(CPeer * peer, MYSQL_RES * pRes, ClientHa
void CClientManager::RESULT_ITEM_LOAD(CPeer * peer, MYSQL_RES * pRes, DWORD dwHandle, DWORD dwPID)
{
static std::vector<TPlayerItem> s_items;
//DB<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>о<EFBFBD><D0BE>´<EFBFBD>.
//DB에서 아이템 정보를 읽어온다.
CreateItemTableFromRes(pRes, &s_items, dwPID);
DWORD dwCount = s_items.size();
peer->EncodeHeader(HEADER_DG_ITEM_LOAD, dwHandle, sizeof(DWORD) + sizeof(TPlayerItem) * dwCount);
peer->EncodeDWORD(dwCount);
//CacheSet<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//CacheSet을 만든다
CreateItemCacheSet(dwPID);
// ITEM_LOAD_LOG_ATTACH_PID
@ -689,7 +689,7 @@ void CClientManager::RESULT_ITEM_LOAD(CPeer * peer, MYSQL_RES * pRes, DWORD dwHa
peer->Encode(&s_items[0], sizeof(TPlayerItem) * dwCount);
for (DWORD i = 0; i < dwCount; ++i)
PutItemCache(&s_items[i], true); // <EFBFBD>ε<EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʿ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD>, <20><><EFBFBD><EFBFBD> bSkipQuery<EFBFBD><EFBFBD> true<EFBFBD><EFBFBD> <20>ִ´<D6B4>.
PutItemCache(&s_items[i], true); // 로드한 것은 따로 저장할 필요 없으므로, 인자 bSkipQuery true를 넣는다.
}
}
@ -697,7 +697,7 @@ void CClientManager::RESULT_AFFECT_LOAD(CPeer * peer, MYSQL_RES * pRes, DWORD dw
{
int iNumRows;
if ((iNumRows = mysql_num_rows(pRes)) == 0) // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
if ((iNumRows = mysql_num_rows(pRes)) == 0) // 데이터 없음
return;
static std::vector<TPacketAffectElement> s_elements;
@ -793,7 +793,7 @@ void CClientManager::__QUERY_PLAYER_CREATE(CPeer *peer, DWORD dwHandle, TPlayerC
int queryLen;
DWORD player_id;
// <EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> X<><58> <20><><EFBFBD><EFBFBD> ij<><C4B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><> <20><><EFBFBD><EFBFBD>.
// 한 계정에 X초 내로 캐릭터 생성을 할 수 없다.
auto it = s_createTimeByAccountID.find(packet->account_id);
if (it != s_createTimeByAccountID.end())
@ -1022,7 +1022,7 @@ void CClientManager::__QUERY_PLAYER_DELETE(CPeer* peer, DWORD dwHandle, TPlayerD
}
//
// @version 05/06/10 Bang2ni - <EFBFBD>÷<EFBFBD><EFBFBD>̾<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ <20><><EFBFBD><EFBFBD> <20>߰<EFBFBD>.
// @version 05/06/10 Bang2ni - 플레이어 삭제시 가격정보 리스트 삭제 추가.
//
void CClientManager::__RESULT_PLAYER_DELETE(CPeer *peer, SQLMsg* msg)
{
@ -1073,14 +1073,14 @@ void CClientManager::__RESULT_PLAYER_DELETE(CPeer *peer, SQLMsg* msg)
return;
}
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
// 삭제 성공
SPDLOG_DEBUG("PLAYER_DELETE SUCCESS {}", dwPID);
char account_index_string[16];
snprintf(account_index_string, sizeof(account_index_string), "player_id%d", m_iPlayerIDStart + pi->account_index);
// <EFBFBD>÷<EFBFBD><EFBFBD>̾<EFBFBD> <20><><EFBFBD>̺<EFBFBD><CCBA><EFBFBD> ij<><C4B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
// 플레이어 테이블을 캐쉬에서 삭제한다.
CPlayerTableCache * pkPlayerCache = GetPlayerCache(pi->player_id);
if (pkPlayerCache)
@ -1089,7 +1089,7 @@ void CClientManager::__RESULT_PLAYER_DELETE(CPeer *peer, SQLMsg* msg)
delete pkPlayerCache;
}
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>۵<EFBFBD><EFBFBD><EFBFBD> ij<><C4B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
// 아이템들을 캐쉬에서 삭제한다.
TItemCacheSet * pSet = GetItemCacheSet(pi->player_id);
if (pSet)
@ -1152,7 +1152,7 @@ void CClientManager::__RESULT_PLAYER_DELETE(CPeer *peer, SQLMsg* msg)
}
else
{
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
// 삭제 실패
SPDLOG_DEBUG("PLAYER_DELETE FAIL NO ROW");
peer->EncodeHeader(HEADER_DG_PLAYER_DELETE_FAILED, pi->dwHandle, 1);
peer->EncodeBYTE(pi->account_index);
@ -1237,7 +1237,7 @@ void CClientManager::RESULT_HIGHSCORE_REGISTER(CPeer * pkPeer, SQLMsg * msg)
if (res->uiNumRows == 0)
{
// <EFBFBD><EFBFBD><EFBFBD>ο<EFBFBD> <20><><EFBFBD>̽<EFBFBD><CCBD>ھ<20><><EFBFBD><EFBFBD>
// 새로운 하이스코어를 삽입
char buf[256];
snprintf(buf, sizeof(buf), "INSERT INTO highscore%s VALUES('%s', %u, %d)", GetTablePostfix(), szBoard, pi->player_id, value);
CDBManager::instance().AsyncQuery(buf);
@ -1272,7 +1272,7 @@ void CClientManager::RESULT_HIGHSCORE_REGISTER(CPeer * pkPeer, SQLMsg * msg)
CDBManager::instance().AsyncQuery(buf);
}
}
// TODO: <EFBFBD>̰<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>̽<EFBFBD><CCBD>ھ<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ <20>Ǿ<EFBFBD><C7BE><EFBFBD><EFBFBD><EFBFBD> üũ<C3BC>Ͽ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ѷ<EFBFBD><D1B7><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
// TODO: 이곳에서 하이스코어가 업데이트 되었는지 체크하여 공지를 뿌려야한다.
delete pi;
}
@ -1280,10 +1280,10 @@ void CClientManager::InsertLogoutPlayer(DWORD pid)
{
TLogoutPlayerMap::iterator it = m_map_logout.find(pid);
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>߰<EFBFBD>
// 존재하지 않을경우 추가
if (it != m_map_logout.end())
{
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ұ<EFBFBD><EFBFBD><EFBFBD> <20>ð<EFBFBD><C3B0><EFBFBD> <20><><EFBFBD><EFBFBD>
// 존재할경우 시간만 갱신
SPDLOG_TRACE("LOGOUT: Update player time pid({})", pid);
it->second->time = time(0);

View File

@ -67,7 +67,7 @@ bool CConfig::GetWord(FILE *fp, char *tar)
if ((c == ' ' || c == '\t' || c == '\n'))
{
// <EFBFBD><EFBFBD>.
// .
tar[i] = '\0';
return true;
}
@ -144,7 +144,7 @@ bool CConfig::LoadFile(const char* filename)
}
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ݴ<EFBFBD> <20>κ<EFBFBD>.
// 파일 닫는 부분.
fclose(fp);
return true;
}

View File

@ -11,14 +11,14 @@
namespace
{
/// <EFBFBD>Ľ̿<EFBFBD> state <EFBFBD><EFBFBD><EFBFBD>Ű<EFBFBD>
/// 파싱용 state 열거값
enum ParseState
{
STATE_NORMAL = 0, ///< <EFBFBD>Ϲ<EFBFBD> <20><><EFBFBD><EFBFBD>
STATE_QUOTE ///< <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǥ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
STATE_NORMAL = 0, ///< 일반 상태
STATE_QUOTE ///< 따옴표 뒤의 상태
};
/// <EFBFBD><EFBFBD><EFBFBD>ڿ<EFBFBD> <20>¿<EFBFBD><C2BF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ؼ<EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
/// 문자열 좌우의 공백을 제거해서 반환한다.
std::string Trim(std::string str)
{
str = str.erase(str.find_last_not_of(" \t\r\n") + 1);
@ -26,7 +26,7 @@ namespace
return str;
}
/// \brief <EFBFBD>־<EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><20>ִ<EFBFBD> <20><><EFBFBD>ĺ<EFBFBD><C4BA><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ҹ<EFBFBD><D2B9>ڷ<EFBFBD> <20>ٲ۴<D9B2>.
/// \brief 주어진 문장에 있는 알파벳을 모두 소문자로 바꾼다.
std::string Lower(std::string original)
{
std::transform(original.begin(), original.end(), original.begin(), tolower);
@ -35,9 +35,9 @@ namespace
}
////////////////////////////////////////////////////////////////////////////////
/// \brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>׼<EFBFBD><D7BC><EFBFBD><EFBFBD><EFBFBD> <20><>, <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20≯<EFBFBD><CCB8><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
/// \param name <EFBFBD><EFBFBD> <20≯<EFBFBD>
/// \param index <EFBFBD><EFBFBD> <20>ε<EFBFBD><CEB5><EFBFBD>
/// \brief 셀을 액세스할 때, 숫자 대신 사용할 이름을 등록한다.
/// \param name 셀 이름
/// \param index 셀 인덱스
////////////////////////////////////////////////////////////////////////////////
void cCsvAlias::AddAlias(const char* name, size_t index)
{
@ -51,7 +51,7 @@ void cCsvAlias::AddAlias(const char* name, size_t index)
}
////////////////////////////////////////////////////////////////////////////////
/// \brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
/// \brief 모든 데이터를 삭제한다.
////////////////////////////////////////////////////////////////////////////////
void cCsvAlias::Destroy()
{
@ -60,9 +60,9 @@ void cCsvAlias::Destroy()
}
////////////////////////////////////////////////////////////////////////////////
/// \brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD> <20≯<EFBFBD><CCB8><EFBFBD><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
/// \param index <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ε<EFBFBD><CEB5><EFBFBD>
/// \return const char* <EFBFBD≯<EFBFBD>
/// \brief 숫자 인덱스를 이름으로 변환한다.
/// \param index 숫자 인덱스
/// \return const char* 이름
////////////////////////////////////////////////////////////////////////////////
const char* cCsvAlias::operator [] (size_t index) const
{
@ -78,9 +78,9 @@ const char* cCsvAlias::operator [] (size_t index) const
}
////////////////////////////////////////////////////////////////////////////////
/// \brief <EFBFBD≯<EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
/// \param name <EFBFBD≯<EFBFBD>
/// \return size_t <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ε<EFBFBD><CEB5><EFBFBD>
/// \brief 이름을 숫자 인덱스로 변환한다.
/// \param name 이름
/// \return size_t 숫자 인덱스
////////////////////////////////////////////////////////////////////////////////
size_t cCsvAlias::operator [] (const char* name) const
{
@ -96,11 +96,11 @@ size_t cCsvAlias::operator [] (const char* name) const
}
////////////////////////////////////////////////////////////////////////////////
/// \brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20≯<EFBFBD><CCB8><EFBFBD> CSV <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ε<EFBFBD><CEB5>Ѵ<EFBFBD>.
/// \param fileName CSV <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20≯<EFBFBD>
/// \param seperator <EFBFBD>ʵ<EFBFBD> <20>и<EFBFBD><D0B8>ڷ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>. <20><EFBFBD><E2BABB><EFBFBD><EFBFBD> ','<EFBFBD>̴<EFBFBD>.
/// \param quote <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǥ<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>. <20><EFBFBD><E2BABB><EFBFBD><EFBFBD> '"'<EFBFBD>̴<EFBFBD>.
/// \return bool <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ε<EFBFBD><CEB5>ߴٸ<DFB4> true, <EFBFBD>ƴ϶<EFBFBD><EFBFBD><EFBFBD> false
/// \brief 지정된 이름의 CSV 파일을 로드한다.
/// \param fileName CSV 파일 이름
/// \param seperator 필드 분리자로 사용할 글자. 기본값은 ','이다.
/// \param quote 따옴표로 사용할 글자. 기본값은 '"'이다.
/// \return bool 무사히 로드했다면 true, 아니라면 false
////////////////////////////////////////////////////////////////////////////////
bool cCsvFile::Load(const char* fileName, const char seperator, const char quote)
{
@ -109,7 +109,7 @@ bool cCsvFile::Load(const char* fileName, const char seperator, const char quote
std::ifstream file(fileName, std::ios::in);
if (!file) return false;
Destroy(); // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD> <20><><EFBFBD><EFBFBD>
Destroy(); // 기존의 데이터를 삭제
cCsvRow* row = NULL;
ParseState state = STATE_NORMAL;
@ -124,33 +124,33 @@ bool cCsvFile::Load(const char* fileName, const char seperator, const char quote
std::string line(Trim(buf));
if (line.empty() || (state == STATE_NORMAL && line[0] == '#')) continue;
std::string text = std::string(line) + " "; // <EFBFBD>Ľ<EFBFBD> lookahead <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ٿ<EFBFBD><D9BF>ش<EFBFBD>.
std::string text = std::string(line) + " "; // 파싱 lookahead 때문에 붙여준다.
size_t cur = 0;
while (cur < text.size())
{
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>尡 QUOTE <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>,
// 현재 모드가 QUOTE 모드일 때,
if (state == STATE_QUOTE)
{
// '"' <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>̴<EFBFBD>.
// 1. <EFBFBD><EFBFBD> <20><><EFBFBD>ο<EFBFBD> Ư<><C6AF> <20><><EFBFBD>ڰ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20≯<EFBFBD> <20>˸<EFBFBD><CBB8><EFBFBD> <20><> <20>¿<EFBFBD><C2BF><EFBFBD> <20><>
// 2. <EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> '"' <20><><EFBFBD>ڰ<EFBFBD> '"' 2<><32><EFBFBD><EFBFBD> ġȯ<C4A1><C8AF> <20><>
// <EFBFBD><EFBFBD> <20><> ù<><C3B9>° <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ִ<EFBFBD> <20><><EFBFBD><EFBFBD> CSV <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̶<EFBFBD><CCB6><EFBFBD>,
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> STATE_NORMAL<EFBFBD><EFBFBD> <20>ɸ<EFBFBD><C9B8><EFBFBD> <20>Ǿ<EFBFBD><C7BE>ִ<EFBFBD>.
// <EFBFBD>׷<EFBFBD><EFBFBD>Ƿ<EFBFBD> <20><><EFBFBD><20>ɸ<EFBFBD><C9B8><EFBFBD> <20><><EFBFBD><EFBFBD> 1<><31><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>쳪, 2<><32> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>̴<EFBFBD>.
// 2<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><ECBFA1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> '"' <20><><EFBFBD>ڰ<EFBFBD> 2<><32><EFBFBD><EFBFBD> <20><>Ÿ<EFBFBD><C5B8><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1<><31><EFBFBD><EFBFBD>
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><ECBFA1> <20>ƴϴ<C6B4>. <20≯<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ؼ<EFBFBD> <20>ڵ带 ¥<><C2A5>...
// '"' 문자의 종류는 두 가지이다.
// 1. 셀 내부에 특수 문자가 있을 경우 이를 알리는 셀 좌우의 것
// 2. 셀 내부의 '"' 문자가 '"' 2개로 치환된 것
// 이 중 첫번째 경우의 좌측에 있는 것은 CSV 파일이 정상적이라면,
// 무조건 STATE_NORMAL에 걸리게 되어있다.
// 그러므로 여기서 걸리는 것은 1번의 우측 경우나, 2번 경우 뿐이다.
// 2번의 경우에는 무조건 '"' 문자가 2개씩 나타난다. 하지만 1번의
// 우측 경우에는 아니다. 이를 바탕으로 해서 코드를 짜면...
if (text[cur] == quote)
{
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ڰ<EFBFBD> '"' <20><><EFBFBD>ڶ<EFBFBD><DAB6><EFBFBD>, <20><> <20><><EFBFBD>ӵ<EFBFBD> '"' <20><><EFBFBD>ڶ<EFBFBD><DAB6><EFBFBD>
// <EFBFBD>̴<EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> '"' <20><><EFBFBD>ڰ<EFBFBD> ġȯ<C4A1><C8AF> <20><><EFBFBD>̴<EFBFBD>.
// 다음 문자가 '"' 문자라면, 즉 연속된 '"' 문자라면
// 이는 셀 내부의 '"' 문자가 치환된 것이다.
if (text[cur+1] == quote)
{
token += quote;
++cur;
}
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ڰ<EFBFBD> '"' <20><><EFBFBD>ڰ<EFBFBD> <20>ƴ϶<C6B4><CFB6><EFBFBD>
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> '"'<27><><EFBFBD>ڴ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>˸<EFBFBD><CBB8><EFBFBD> <20><><EFBFBD>ڶ<EFBFBD><DAB6><EFBFBD> <20><> <20><> <20>ִ<EFBFBD>.
// 다음 문자가 '"' 문자가 아니라면
// 현재의 '"'문자는 셀의 끝을 알리는 문자라고 할 수 있다.
else
{
state = STATE_NORMAL;
@ -161,25 +161,25 @@ bool cCsvFile::Load(const char* fileName, const char seperator, const char quote
token += text[cur];
}
}
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>尡 NORMAL <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>,
// 현재 모드가 NORMAL 모드일 때,
else if (state == STATE_NORMAL)
{
if (row == NULL)
row = new cCsvRow();
// ',' <EFBFBD><EFBFBD><EFBFBD>ڸ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ٸ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ǹ<EFBFBD><C7B9>Ѵ<EFBFBD>.
// <EFBFBD><EFBFBD>ū<EFBFBD><EFBFBD><EFBFBD>μ<EFBFBD> <20><> <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE><EFBFBD>ٰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ְ<EFBFBD>, <20><>ū<EFBFBD><C5AB> <20>ʱ<EFBFBD>ȭ<EFBFBD>Ѵ<EFBFBD>.
// ',' 문자를 만났다면 셀의 끝의 의미한다.
// 토큰으로서 셀 리스트에다가 집어넣고, 토큰을 초기화한다.
if (text[cur] == seperator)
{
row->push_back(token);
token.clear();
}
// '"' <EFBFBD><EFBFBD><EFBFBD>ڸ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ٸ<EFBFBD>, QUOTE <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
// '"' 문자를 만났다면, QUOTE 모드로 전환한다.
else if (text[cur] == quote)
{
state = STATE_QUOTE;
}
// <EFBFBD>ٸ<EFBFBD> <20>Ϲ<EFBFBD> <20><><EFBFBD>ڶ<EFBFBD><DAB6><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ū<EFBFBD><C5AB><EFBFBD>ٰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>δ<EFBFBD>.
// 다른 일반 문자라면 현재 토큰에다가 덧붙인다.
else
{
token += text[cur];
@ -189,8 +189,8 @@ bool cCsvFile::Load(const char* fileName, const char seperator, const char quote
++cur;
}
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ',' <20><><EFBFBD>ڰ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><20>߰<EFBFBD><DFB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
// <EFBFBD><EFBFBD>, ó<><C3B3><EFBFBD><EFBFBD> <20>Ľ<EFBFBD> lookahead <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>̽<EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
// 마지막 셀은 끝에 ',' 문자가 없기 때문에 여기서 추가해줘야한다.
// 단, 처음에 파싱 lookahead 때문에 붙인 스페이스 문자 두 개를 뗀다.
if (state == STATE_NORMAL)
{
Assert(row != NULL);
@ -209,49 +209,49 @@ bool cCsvFile::Load(const char* fileName, const char seperator, const char quote
}
////////////////////////////////////////////////////////////////////////////////
/// \brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ִ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> CSV <20><><EFBFBD>Ͽ<EFBFBD><CFBF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
/// \param fileName CSV <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20≯<EFBFBD>
/// \param append true<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>Ͽ<EFBFBD><CFBF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>δ<EFBFBD>. false<73><65> <20><><EFBFBD><EFBFBD><ECBFA1>
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD>, <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
/// \param seperator <EFBFBD>ʵ<EFBFBD> <20>и<EFBFBD><D0B8>ڷ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>. <20><EFBFBD><E2BABB><EFBFBD><EFBFBD> ','<EFBFBD>̴<EFBFBD>.
/// \param quote <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǥ<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>. <20><EFBFBD><E2BABB><EFBFBD><EFBFBD> '"'<EFBFBD>̴<EFBFBD>.
/// \return bool <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ߴٸ<DFB4> true, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><ECBFA1> false
/// \brief 가지고 있는 내용을 CSV 파일에다 저장한다.
/// \param fileName CSV 파일 이름
/// \param append true일 경우, 기존의 파일에다 덧붙인다. false인 경우에는
/// 기존의 파일 내용을 삭제하고, 새로 쓴다.
/// \param seperator 필드 분리자로 사용할 글자. 기본값은 ','이다.
/// \param quote 따옴표로 사용할 글자. 기본값은 '"'이다.
/// \return bool 무사히 저장했다면 true, 에러가 생긴 경우에는 false
////////////////////////////////////////////////////////////////////////////////
bool cCsvFile::Save(const char* fileName, bool append, char seperator, char quote) const
{
Assert(seperator != quote);
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>÷<EFBFBD><C3B7>׷<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
// 출력 모드에 따라 파일을 적당한 플래그로 생성한다.
std::ofstream file;
if (append) { file.open(fileName, std::ios::out | std::ios::app); }
else { file.open(fileName, std::ios::out | std::ios::trunc); }
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ߴٸ<DFB4>, false<73><65> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
// 파일을 열지 못했다면, false를 리턴한다.
if (!file) return false;
char special_chars[5] = { seperator, quote, '\r', '\n', 0 };
char quote_escape_string[3] = { quote, quote, 0 };
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> Ⱦ<><C8BE><EFBFBD>ϸ鼭...
// 모든 행을 횡단하면서...
for (size_t i=0; i<m_Rows.size(); i++)
{
const cCsvRow& row = *((*this)[i]);
std::string line;
// <EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ū<EFBFBD><C5AB> Ⱦ<><C8BE><EFBFBD>ϸ鼭...
// 행 안의 모든 토큰을 횡단하면서...
for (size_t j=0; j<row.size(); j++)
{
const std::string& token = row[j];
// <EFBFBD>Ϲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>('"' <EFBFBD>Ǵ<EFBFBD> ','<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>)
// <EFBFBD><EFBFBD>ū<EFBFBD>̶<EFBFBD><EFBFBD><EFBFBD> <20>׳<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϸ<EFBFBD> <20>ȴ<EFBFBD>.
// 일반적인('"' 또는 ','를 포함하지 않은)
// 토큰이라면 그냥 저장하면 된다.
if (token.find_first_of(special_chars) == std::string::npos)
{
line += token;
}
// Ư<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڸ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ū<EFBFBD>̶<EFBFBD><CCB6><EFBFBD> <20><><EFBFBD>ڿ<EFBFBD> <20>¿쿡 '"'<27><> <20>ٿ<EFBFBD><D9BF>ְ<EFBFBD>,
// <EFBFBD><EFBFBD><EFBFBD>ڿ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> '"'<27><> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
// 특수문자를 포함한 토큰이라면 문자열 좌우에 '"'를 붙여주고,
// 문자열 내부의 '"'를 두 개로 만들어줘야한다.
else
{
line += quote;
@ -265,11 +265,11 @@ bool cCsvFile::Save(const char* fileName, bool append, char seperator, char quot
line += quote;
}
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ƴ϶<C6B4><CFB6><EFBFBD> ','<27><> <20><>ū<EFBFBD><C5AB> <20>ڿ<EFBFBD><DABF><EFBFBD> <20>ٿ<EFBFBD><D9BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
// 마지막 셀이 아니라면 ','를 토큰의 뒤에다 붙여줘야한다.
if (j != row.size() - 1) { line += seperator; }
}
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
// 라인을 출력한다.
file << line << std::endl;
}
@ -277,7 +277,7 @@ bool cCsvFile::Save(const char* fileName, bool append, char seperator, char quot
}
////////////////////////////////////////////////////////////////////////////////
/// \brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD> <20>޸𸮿<DEB8><F0B8AEBF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
/// \brief 모든 데이터를 메모리에서 삭제한다.
////////////////////////////////////////////////////////////////////////////////
void cCsvFile::Destroy()
{
@ -288,9 +288,9 @@ void cCsvFile::Destroy()
}
////////////////////////////////////////////////////////////////////////////////
/// \brief <EFBFBD>ش<EFBFBD><EFBFBD>ϴ<EFBFBD> <20>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
/// \param index <EFBFBD>ε<EFBFBD><EFBFBD><EFBFBD>
/// \return cCsvRow* <EFBFBD>ش<EFBFBD> <20><>
/// \brief 해당하는 인덱스의 행을 반환한다.
/// \param index 인덱스
/// \return cCsvRow* 해당 행
////////////////////////////////////////////////////////////////////////////////
cCsvRow* cCsvFile::operator [] (size_t index)
{
@ -299,9 +299,9 @@ cCsvRow* cCsvFile::operator [] (size_t index)
}
////////////////////////////////////////////////////////////////////////////////
/// \brief <EFBFBD>ش<EFBFBD><EFBFBD>ϴ<EFBFBD> <20>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
/// \param index <EFBFBD>ε<EFBFBD><EFBFBD><EFBFBD>
/// \return const cCsvRow* <EFBFBD>ش<EFBFBD> <20><>
/// \brief 해당하는 인덱스의 행을 반환한다.
/// \param index 인덱스
/// \return const cCsvRow* 해당 행
////////////////////////////////////////////////////////////////////////////////
const cCsvRow* cCsvFile::operator [] (size_t index) const
{
@ -310,7 +310,7 @@ const cCsvRow* cCsvFile::operator [] (size_t index) const
}
////////////////////////////////////////////////////////////////////////////////
/// \brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// \brief 생성자
////////////////////////////////////////////////////////////////////////////////
cCsvTable::cCsvTable()
: m_CurRow(-1)
@ -318,18 +318,18 @@ cCsvTable::cCsvTable()
}
////////////////////////////////////////////////////////////////////////////////
/// \brief <EFBFBD>Ҹ<EFBFBD><EFBFBD><EFBFBD>
/// \brief 소멸자
////////////////////////////////////////////////////////////////////////////////
cCsvTable::~cCsvTable()
{
}
////////////////////////////////////////////////////////////////////////////////
/// \brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20≯<EFBFBD><CCB8><EFBFBD> CSV <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ε<EFBFBD><CEB5>Ѵ<EFBFBD>.
/// \param fileName CSV <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20≯<EFBFBD>
/// \param seperator <EFBFBD>ʵ<EFBFBD> <20>и<EFBFBD><D0B8>ڷ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>. <20><EFBFBD><E2BABB><EFBFBD><EFBFBD> ','<EFBFBD>̴<EFBFBD>.
/// \param quote <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǥ<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>. <20><EFBFBD><E2BABB><EFBFBD><EFBFBD> '"'<EFBFBD>̴<EFBFBD>.
/// \return bool <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ε<EFBFBD><CEB5>ߴٸ<DFB4> true, <EFBFBD>ƴ϶<EFBFBD><EFBFBD><EFBFBD> false
/// \brief 지정된 이름의 CSV 파일을 로드한다.
/// \param fileName CSV 파일 이름
/// \param seperator 필드 분리자로 사용할 글자. 기본값은 ','이다.
/// \param quote 따옴표로 사용할 글자. 기본값은 '"'이다.
/// \return bool 무사히 로드했다면 true, 아니라면 false
////////////////////////////////////////////////////////////////////////////////
bool cCsvTable::Load(const char* fileName, const char seperator, const char quote)
{
@ -338,19 +338,19 @@ bool cCsvTable::Load(const char* fileName, const char seperator, const char quot
}
////////////////////////////////////////////////////////////////////////////////
/// \brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ѿ<D1BE><EEB0A3>.
/// \return bool <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ѿ <20><><EFBFBD><EFBFBD> true<75><65> <20><>ȯ<EFBFBD>ϰ<EFBFBD>, <20><> <20>̻<EFBFBD>
/// <EFBFBD>Ѿ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʴ<EFBFBD> <20><><EFBFBD><EFBFBD><ECBFA1> false<73><65> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
/// \brief 다음 행으로 넘어간다.
/// \return bool 다음 행으로 무사히 넘어간 경우 true를 반환하고, 더 이상
/// 넘어갈 행이 존재하지 않는 경우에는 false를 반환한다.
////////////////////////////////////////////////////////////////////////////////
bool cCsvTable::Next()
{
// 20<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ȣ<><C8A3><EFBFBD>ϸ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>÷ΰ<C3B7> <20>Ͼ<CFBE>ٵ<EFBFBD>...<2E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
// 20억번 정도 호출하면 오버플로가 일어날텐데...괜찮겠지?
return ++m_CurRow < (int)m_File.GetRowCount() ? true : false;
}
////////////////////////////////////////////////////////////////////////////////
/// \brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD>ڸ<EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
/// \return size_t <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD>
/// \brief 현재 행의 셀 숫자를 반환한다.
/// \return size_t 현재 행의 셀 숫자
////////////////////////////////////////////////////////////////////////////////
size_t cCsvTable::ColCount() const
{
@ -358,9 +358,9 @@ size_t cCsvTable::ColCount() const
}
////////////////////////////////////////////////////////////////////////////////
/// \brief <EFBFBD>ε<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>̿<EFBFBD><CCBF><EFBFBD> int <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
/// \param index <EFBFBD><EFBFBD> <20>ε<EFBFBD><CEB5><EFBFBD>
/// \return int <EFBFBD><EFBFBD> <20><>
/// \brief 인덱스를 이용해 int 형으로 셀 값을 반환한다.
/// \param index 셀 인덱스
/// \return int 셀 값
////////////////////////////////////////////////////////////////////////////////
int cCsvTable::AsInt(size_t index) const
{
@ -371,9 +371,9 @@ int cCsvTable::AsInt(size_t index) const
}
////////////////////////////////////////////////////////////////////////////////
/// \brief <EFBFBD>ε<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>̿<EFBFBD><CCBF><EFBFBD> double <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
/// \param index <EFBFBD><EFBFBD> <20>ε<EFBFBD><CEB5><EFBFBD>
/// \return double <EFBFBD><EFBFBD> <20><>
/// \brief 인덱스를 이용해 double 형으로 셀 값을 반환한다.
/// \param index 셀 인덱스
/// \return double 셀 값
////////////////////////////////////////////////////////////////////////////////
double cCsvTable::AsDouble(size_t index) const
{
@ -384,9 +384,9 @@ double cCsvTable::AsDouble(size_t index) const
}
////////////////////////////////////////////////////////////////////////////////
/// \brief <EFBFBD>ε<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>̿<EFBFBD><CCBF><EFBFBD> std::string <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
/// \param index <EFBFBD><EFBFBD> <20>ε<EFBFBD><CEB5><EFBFBD>
/// \return const char* <EFBFBD><EFBFBD> <20><>
/// \brief 인덱스를 이용해 std::string 형으로 셀 값을 반환한다.
/// \param index 셀 인덱스
/// \return const char* 셀 값
////////////////////////////////////////////////////////////////////////////////
const char* cCsvTable::AsStringByIndex(size_t index) const
{
@ -397,7 +397,7 @@ const char* cCsvTable::AsStringByIndex(size_t index) const
}
////////////////////////////////////////////////////////////////////////////////
/// \brief alias<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
/// \brief alias를 포함해 모든 데이터를 삭제한다.
////////////////////////////////////////////////////////////////////////////////
void cCsvTable::Destroy()
{
@ -407,10 +407,10 @@ void cCsvTable::Destroy()
}
////////////////////////////////////////////////////////////////////////////////
/// \brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
/// \return const cCsvRow* <EFBFBD>׼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD><ECBFA1> <20><> <20><><EFBFBD><EFBFBD>
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͸<EFBFBD> <20><>ȯ<EFBFBD>ϰ<EFBFBD>, <20><> <20>̻<EFBFBD> <20>׼<EFBFBD><D7BC><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><ECBFA1> NULL<EFBFBD><EFBFBD>
/// <EFBFBD><EFBFBD>ȯ<EFBFBD>Ѵ<EFBFBD>.
/// \brief 현재 행을 반환한다.
/// \return const cCsvRow* 액세스가 가능한 현재 행이 존재하는 경우에는 그 행의
/// 포인터를 반환하고, 더 이상 액세스 가능한 행이 없는 경우에는 NULL
/// 반환한다.
////////////////////////////////////////////////////////////////////////////////
const cCsvRow* const cCsvTable::CurRow() const
{

View File

@ -242,7 +242,7 @@ void CGuildManager::ResultRanking(MYSQL_RES * pRes)
void CGuildManager::Update()
{
ProcessReserveWar(); // <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ó<><C3B3>
ProcessReserveWar(); // 예약 전쟁 처리
time_t now = CClientManager::instance().GetCurrentTime();
@ -462,7 +462,7 @@ void CGuildManager::RemoveWar(DWORD GID1, DWORD GID2)
}
//
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20>ʵ<EFBFBD><CAB5><EFBFBD> <20><><EFBFBD><EFBFBD>
// 길드전 비정상 종료 및 필드전 종료
//
void CGuildManager::WarEnd(DWORD GID1, DWORD GID2, bool bForceDraw)
{
@ -493,7 +493,7 @@ void CGuildManager::WarEnd(DWORD GID1, DWORD GID2, bool bForceDraw)
bool bDraw = false;
if (!bForceDraw) // <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ºΰ<C2BA> <20>ƴ<EFBFBD> <20><><EFBFBD><EFBFBD><ECBFA1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> üũ<C3BC>Ѵ<EFBFBD>.
if (!bForceDraw) // 강제 무승부가 아닐 경우에는 점수를 체크한다.
{
if (pData->iScore[0] > pData->iScore[1])
{
@ -508,7 +508,7 @@ void CGuildManager::WarEnd(DWORD GID1, DWORD GID2, bool bForceDraw)
else
bDraw = true;
}
else // <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>º<EFBFBD><C2BA><EFBFBD> <20><><EFBFBD><EFBFBD><ECBFA1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>º<EFBFBD>
else // 강제 무승부일 경우에는 무조건 무승부
bDraw = true;
if (bDraw)
@ -516,14 +516,14 @@ void CGuildManager::WarEnd(DWORD GID1, DWORD GID2, bool bForceDraw)
else
ProcessWinLose(win_guild, lose_guild);
// DB <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ü<EFBFBD><C3BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ֱ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>Ŷ<EFBFBD><C5B6> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
// DB 서버에서 자체적으로 끝낼 때도 있기 때문에 따로 패킷을 보내줘야 한다.
CClientManager::instance().for_each_peer(FSendPeerWar(0, GUILD_WAR_END, GID1, GID2));
RemoveWar(GID1, GID2);
}
//
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
// 길드전 정상 종료
//
void CGuildManager::RecvWarOver(DWORD dwGuildWinner, DWORD dwGuildLoser, bool bDraw, int lWarPrice)
{
@ -571,7 +571,7 @@ void CGuildManager::RecvWarOver(DWORD dwGuildWinner, DWORD dwGuildLoser, bool bD
void CGuildManager::RecvWarEnd(DWORD GID1, DWORD GID2)
{
SPDLOG_DEBUG("GuildWar: RecvWarEnded : {} vs {}", GID1, GID2);
WarEnd(GID1, GID2, true); // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>Ѿ<EFBFBD> <20>Ѵ<EFBFBD>.
WarEnd(GID1, GID2, true); // 무조건 비정상 종료 시켜야 한다.
}
void CGuildManager::StartWar(BYTE bType, DWORD GID1, DWORD GID2, CGuildWarReserve * pkReserve)
@ -745,7 +745,7 @@ void CGuildManager::ChangeLadderPoint(DWORD GID, int change)
SPDLOG_DEBUG("GuildManager::ChangeLadderPoint {} {}", GID, r.ladder_point);
SPDLOG_DEBUG("{}", buf);
// Packet <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Packet 보내기
TPacketGuildLadder p;
p.dwGuild = GID;
@ -808,7 +808,7 @@ void CGuildManager::WithdrawMoney(CPeer* peer, DWORD dwGuild, INT iGold)
return;
}
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> <20>÷<EFBFBD><C3B7>ش<EFBFBD>
// 돈이있으니 출금하고 올려준다
if (it->second.gold >= iGold)
{
it->second.gold -= iGold;
@ -839,7 +839,7 @@ void CGuildManager::WithdrawMoneyReply(DWORD dwGuild, BYTE bGiveSuccess, INT iGo
}
//
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD>ڰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20>ִ<EFBFBD>)
// 예약 길드전(관전자가 배팅할 수 있다)
//
const int c_aiScoreByLevel[GUILD_MAX_LEVEL+1] =
{
@ -869,7 +869,7 @@ const int c_aiScoreByLevel[GUILD_MAX_LEVEL+1] =
const int c_aiScoreByRanking[GUILD_RANK_MAX_NUM+1] =
{
0,
55000, // 1<EFBFBD><EFBFBD>
55000, // 1
50000,
45000,
40000,
@ -878,7 +878,7 @@ const int c_aiScoreByRanking[GUILD_RANK_MAX_NUM+1] =
28000,
24000,
21000,
18000, // 10<EFBFBD><EFBFBD>
18000, // 10
15000,
12000,
10000,
@ -888,7 +888,7 @@ const int c_aiScoreByRanking[GUILD_RANK_MAX_NUM+1] =
3000,
2000,
1000,
500 // 20<EFBFBD><EFBFBD>
500 // 20
};
void CGuildManager::BootReserveWar()
@ -932,8 +932,8 @@ void CGuildManager::BootReserveWar()
char buf[512];
snprintf(buf, sizeof(buf), "GuildWar: BootReserveWar : step %d id %u GID1 %u GID2 %u", i, t.dwID, t.dwGuildFrom, t.dwGuildTo);
// i == 0 <EFBFBD≯<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> DB<44><42> ƨ<><C6A8> <20><><EFBFBD>̹Ƿ<CCB9> <20><><EFBFBD>º<EFBFBD> ó<><C3B3><EFBFBD>Ѵ<EFBFBD>.
// <EFBFBD>Ǵ<EFBFBD>, 5<><35> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>º<EFBFBD> ó<><C3B3><EFBFBD>Ѵ<EFBFBD>. (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>þ<EFBFBD><C3BE><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ش<EFBFBD>)
// i == 0 이면 길드전 도중 DB가 튕긴 것이므로 무승부 처리한다.
// 또는, 5분 이하 남은 예약 길드전도 무승부 처리한다. (각자의 배팅액을 돌려준다)
//if (i == 0 || (int) t.dwTime - CClientManager::instance().GetCurrentTime() < 60 * 5)
if (i == 0 || (int) t.dwTime - CClientManager::instance().GetCurrentTime() < 0)
{
@ -1010,7 +1010,7 @@ bool CGuildManager::ReserveWar(TPacketGuildWar * p)
int lvp, rkp, alv, mc;
// <EFBFBD>Ŀ<EFBFBD> <20><><EFBFBD><EFBFBD>
// 파워 계산
TGuild & k1 = TouchGuild(GID1);
lvp = c_aiScoreByLevel[std::min<size_t>(GUILD_MAX_LEVEL, k1.level)];
@ -1026,7 +1026,7 @@ bool CGuildManager::ReserveWar(TPacketGuildWar * p)
t.lPowerFrom = (int) polyPower.Eval();
SPDLOG_DEBUG("GuildWar: {} lvp {} rkp {} alv {} mc {} power {}", GID1, lvp, rkp, alv, mc, t.lPowerFrom);
// <EFBFBD>Ŀ<EFBFBD> <20><><EFBFBD><EFBFBD>
// 파워 계산
TGuild & k2 = TouchGuild(GID2);
lvp = c_aiScoreByLevel[std::min<size_t>(GUILD_MAX_LEVEL, k2.level)];
@ -1042,7 +1042,7 @@ bool CGuildManager::ReserveWar(TPacketGuildWar * p)
t.lPowerTo = (int) polyPower.Eval();
SPDLOG_DEBUG("GuildWar: {} lvp {} rkp {} alv {} mc {} power {}", GID2, lvp, rkp, alv, mc, t.lPowerTo);
// <EFBFBD>ڵ<EFBFBD>ĸ <20><><EFBFBD><EFBFBD>
// 핸디캡 계산
if (t.lPowerTo > t.lPowerFrom)
{
polyHandicap.SetVar("pA", t.lPowerTo);
@ -1057,7 +1057,7 @@ bool CGuildManager::ReserveWar(TPacketGuildWar * p)
t.lHandicap = (int) polyHandicap.Eval();
SPDLOG_DEBUG("GuildWar: handicap {}", t.lHandicap);
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 쿼리
char szQuery[512];
snprintf(szQuery, sizeof(szQuery),
@ -1094,7 +1094,7 @@ void CGuildManager::ProcessReserveWar()
CGuildWarReserve * pk = it2->second;
TGuildWarReserve & r = pk->GetDataRef();
if (!r.bStarted && r.dwTime - 1800 <= dwCurTime) // 30<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>˸<EFBFBD><CBB8><EFBFBD>.
if (!r.bStarted && r.dwTime - 1800 <= dwCurTime) // 30분 전부터 알린다.
{
int iMin = (int) ceil((int)(r.dwTime - dwCurTime) / 60.0);
@ -1135,9 +1135,11 @@ void CGuildManager::ProcessReserveWar()
pk->SetLastNoticeMin(iMin);
if (!g_stLocale.compare("euckr"))
CClientManager::instance().SendNotice("%s <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> %s <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> %d<><64> <20><> <20><><EFBFBD><EFBFBD> <20>˴ϴ<CBB4>!", r_1.szName, r_2.szName, iMin);
// "%s 길드와 %s 길드의 전쟁이 약 %d분 후 시작 됩니다!"
CClientManager::instance().SendNotice("%s \xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD %s \xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD \xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD \xEF\xBF\xBD\xEF\xBF\xBD %d\xEF\xBF\xBD\xEF\xBF\xBD \xEF\xBF\xBD\xEF\xBF\xBD \xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD \xEF\xBF\xBD\xCB\xB4\xCF\xB4\xEF\xBF\xBD!", r_1.szName, r_2.szName, iMin);
else if (!g_stLocale.compare("gb2312"))
CClientManager::instance().SendNotice("%s <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> %s <20><><EFBFBD><EFBFBD><EFBFBD>İ<EFBFBD><C4B0><EFBFBD>ս<EFBFBD><D5BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> %d<><64><EFBFBD>Ӻ<EFBFBD><D3BA><EFBFBD>ʼ!", r_1.szName, r_2.szName, iMin);
// "%s 곤삔뵨 %s 곤삔돨곤삔濫轢쉥瞳 %d롸爐빈역迦!"
CClientManager::instance().SendNotice("%s \xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD %s \xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xC4\xB0\xEF\xBF\xBD\xEF\xBF\xBD\xD5\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD %d\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xD3\xBA\xEF\xBF\xBD\xCA\xBC!", r_1.szName, r_2.szName, iMin);
}
}
}
@ -1239,7 +1241,7 @@ void CGuildWarReserve::Initialize()
void CGuildWarReserve::OnSetup(CPeer * peer)
{
if (m_data.bStarted) // <EFBFBD>̹<EFBFBD> <20><><EFBFBD>۵<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʴ´<CAB4>.
if (m_data.bStarted) // 이미 시작된 것은 보내지 않는다.
return;
FSendPeerWar(m_data.bType, GUILD_WAR_RESERVE, m_data.dwGuildFrom, m_data.dwGuildTo) (peer);
@ -1325,8 +1327,8 @@ bool CGuildWarReserve::Bet(const char * pszLogin, DWORD dwGold, DWORD dwGuild)
}
//
// <EFBFBD><EFBFBD><EFBFBD>º<EFBFBD> ó<><C3B3>: <20><><EFBFBD>κ<EFBFBD> <20>ºΰ<C2BA> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> Ư<><C6AF> <20><>Ȳ<EFBFBD><C8B2> <20><><EFBFBD><EFBFBD><ECBFA1>
// <EFBFBD><EFBFBD><EFBFBD>º<EFBFBD> ó<><C3B3><EFBFBD><EFBFBD> <20>־<EFBFBD><D6BE><EFBFBD> <20>Ѵ<EFBFBD>.
// 무승부 처리: 대부분 승부가 나야 정상이지만, 서버 문제 등 특정 상황일 경우에는
// 무승부 처리가 있어야 한다.
//
void CGuildWarReserve::Draw()
{
@ -1458,7 +1460,7 @@ void CGuildWarReserve::End(int iScoreFrom, int iScoreTo)
double ratio = (double) it->second.second / dwWinnerBet;
// 10% <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20>й<EFBFBD>
// 10% 세금 공제 후 분배
SPDLOG_DEBUG("WAR_REWARD: {} {} ratio {}", it->first.c_str(), it->second.second, ratio);
DWORD dwGold = (DWORD) (dwTotalBet * ratio * 0.9);

View File

@ -30,7 +30,7 @@ bool PlayerHB::Initialize()
}
//
// @version 05/07/05 Bang2ni - id <EFBFBD><EFBFBD> <20>ش<EFBFBD><D8B4>ϴ<EFBFBD> data <20><> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> data <EFBFBD><EFBFBD> insert <EFBFBD>ϴ<EFBFBD><EFBFBD>ڵ<EFBFBD> <20>߰<EFBFBD>.
// @version 05/07/05 Bang2ni - id 에 해당하는 data 가 없을 때 쿼리하고 data insert 하는코드 추가.
//
void PlayerHB::Put(DWORD id)
{
@ -48,7 +48,7 @@ void PlayerHB::Put(DWORD id)
}
//
// @version 05/07/05 Bang2ni - Query string <EFBFBD><EFBFBD><EFBFBD>۰<EFBFBD> <20>۾Ƽ<DBBE> <20>÷<EFBFBD><C3B7><EFBFBD>.
// @version 05/07/05 Bang2ni - Query string 버퍼가 작아서 늘려줌.
//
bool PlayerHB::Query(DWORD id)
{

View File

@ -54,19 +54,19 @@ void ItemAwardManager::Load(SQLMsg * pMsg)
if (row[col])
{
strlcpy(kData->szWhy, row[col], sizeof(kData->szWhy));
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>߿<EFBFBD> why<68>ݷ뿡 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
char* whyStr = kData->szWhy; //why <EFBFBD>ݷ<EFBFBD> <20>б<EFBFBD>
char cmdStr[100] = ""; //why<EFBFBD>ݷ뿡<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ӽ<EFBFBD> <20><><EFBFBD>ڿ<EFBFBD><DABF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD>
strcpy(cmdStr,whyStr); //<EFBFBD><EFBFBD><EFBFBD>ɾ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ū<EFBFBD><C5AB><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ūȭ <20>DZ<EFBFBD> <20><><EFBFBD><EFBFBD>
//게임 중에 why콜룸에 변동이 생기면
char* whyStr = kData->szWhy; //why 콜룸 읽기
char cmdStr[100] = ""; //why콜룸에서 읽은 값을 임시 문자열에 복사해둠
strcpy(cmdStr,whyStr); //명령어 얻는 과정에서 토큰쓰면 원본도 토큰화 되기 때문
char command[20] = "";
strcpy(command,CClientManager::instance().GetCommand(cmdStr).c_str()); // command <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
strcpy(command,CClientManager::instance().GetCommand(cmdStr).c_str()); // command 얻기
//SPDLOG_ERROR("{}, {}",pItemAward->dwID,command);
if( !(strcmp(command,"GIFT") )) // command <EFBFBD><EFBFBD> GIFT<EFBFBD≯<EFBFBD>
if( !(strcmp(command,"GIFT") )) // command GIFT이면
{
TPacketItemAwardInfromer giftData;
strcpy(giftData.login, kData->szLogin); //<EFBFBD>α<EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>̵<EFBFBD> <20><><EFBFBD><EFBFBD>
strcpy(giftData.command, command); //<EFBFBD><EFBFBD><EFBFBD>ɾ<EFBFBD> <20><><EFBFBD><EFBFBD>
giftData.vnum = kData->dwVnum; //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> vnum<75><6D> <20><><EFBFBD><EFBFBD>
strcpy(giftData.login, kData->szLogin); //로그인 아이디 복사
strcpy(giftData.command, command); //명령어 복사
giftData.vnum = kData->dwVnum; //아이템 vnum도 복사
CClientManager::instance().ForwardPacket(HEADER_DG_ITEMAWARD_INFORMER,&giftData,sizeof(TPacketItemAwardInfromer));
}
}

View File

@ -31,11 +31,11 @@ std::string g_stPlayerDBName = "";
bool g_bHotBackup = false;
BOOL g_test_server = false;
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>
//단위 초
int g_iPlayerCacheFlushSeconds = 60*7;
int g_iItemCacheFlushSeconds = 60*5;
//g_iLogoutSeconds <EFBFBD><EFBFBD>ġ<EFBFBD><EFBFBD> g_iPlayerCacheFlushSeconds <EFBFBD><EFBFBD> g_iItemCacheFlushSeconds <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
//g_iLogoutSeconds 수치는 g_iPlayerCacheFlushSeconds g_iItemCacheFlushSeconds 보다 길어야 한다.
int g_iLogoutSeconds = 60*10;
@ -122,13 +122,13 @@ int main()
void emptybeat(LPHEART heart, int pulse)
{
if (!(pulse % heart->passes_per_sec)) // 1<EFBFBD>ʿ<EFBFBD> <20>ѹ<EFBFBD>
if (!(pulse % heart->passes_per_sec)) // 1초에 한번
{
}
}
//
// @version 05/06/13 Bang2ni - <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ij<><C4B3> flush timeout <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>߰<EFBFBD>.
// @version 05/06/13 Bang2ni - 아이템 가격정보 캐시 flush timeout 설정 추가.
//
int Start()
{

View File

@ -253,7 +253,7 @@ namespace marriage
void CManager::OnSetup(CPeer* peer)
{
// <EFBFBD><EFBFBD>ȥ<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 결혼한 사람들 보내기
for (itertype(m_Marriages) it = m_Marriages.begin(); it != m_Marriages.end(); ++it)
{
TMarriage* pMarriage = *it;
@ -280,7 +280,7 @@ namespace marriage
}
}
// <EFBFBD><EFBFBD>ȥ<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 결혼식 보내기
for (itertype(m_mapRunningWedding) it = m_mapRunningWedding.begin(); it != m_mapRunningWedding.end(); ++it)
{
const TWedding& t = it->second;

View File

@ -233,7 +233,7 @@ bool CMonarch::SetMonarch(const char * name)
}
delete pMsg;
//db<EFBFBD><EFBFBD> <20>Է<EFBFBD>
//db에 입력
snprintf(szQuery, sizeof(szQuery),
"REPLACE INTO monarch (empire, name, windate, money) VALUES(%d, %d, now(), %ld)", Empire, p->pid[Empire], p->money[Empire]);

View File

@ -20,7 +20,7 @@ CPrivManager::~CPrivManager()
}
//
// @version 05/06/07 Bang2ni - <EFBFBD>ߺ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><20><><EFBFBD><EFBFBD> ó<><C3B3>
// @version 05/06/07 Bang2ni - 중복적으로 보너스가 적용 된 길드에 대한 처리
//
void CPrivManager::Update()
{
@ -37,8 +37,8 @@ void CPrivManager::Update()
typeof(m_aPrivGuild[p->type].begin()) it = m_aPrivGuild[p->type].find(p->guild_id);
// ADD_GUILD_PRIV_TIME
// <EFBFBD><EFBFBD><EFBFBD><20>ߺ<EFBFBD><DFBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ǿ<EFBFBD><C7BE><EFBFBD> <20><><EFBFBD><EFBFBD> map <EFBFBD><EFBFBD> value <EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD>) <20>Ǿ<EFBFBD><C7BE><EFBFBD><EFBFBD>Ƿ<EFBFBD>
// TPrivGuildData <EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ͱ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ְ<EFBFBD> <20><><EFBFBD>Ӽ<EFBFBD><D3BC><EFBFBD><EFBFBD><EFBFBD><E9BFA1> cast <20><> <20>ش<EFBFBD>.
// 길드에 중복적으로 보너스가 설정되었을 경우 map value 가 갱신(수정) 되었으므로
// TPrivGuildData 의 포인터가 같을때 실제로 삭제해 주고 게임서버들에게 cast 해 준다.
if (it != m_aPrivGuild[p->type].end() && it->second == p) {
m_aPrivGuild[p->type].erase(it);
SendChangeGuildPriv(p->guild_id, p->type, 0, 0);
@ -113,7 +113,7 @@ void CPrivManager::AddCharPriv(DWORD pid, BYTE type, int value)
}
//
// @version 05/06/07 Bang2ni - <EFBFBD>̹<EFBFBD> <20><><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><20><><EFBFBD>ʽ<EFBFBD> <20><><EFBFBD><EFBFBD>
// @version 05/06/07 Bang2ni - 이미 보너스가 적용 된 길드에 보너스 설정
//
void CPrivManager::AddGuildPriv(DWORD guild_id, BYTE type, int value, time_t duration_sec)
{
@ -131,8 +131,8 @@ void CPrivManager::AddGuildPriv(DWORD guild_id, BYTE type, int value, time_t dur
m_pqPrivGuild.push(std::make_pair(end, p));
// ADD_GUILD_PRIV_TIME
// <EFBFBD>̹<EFBFBD> <20><><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ִٸ<D6B4> map <EFBFBD><EFBFBD> value <EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ش<EFBFBD>.
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> value <EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD> priority queue <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD>.
// 이미 보너스가 설정되 있다면 map value 를 갱신해 준다.
// 이전 value 의 포인터는 priority queue 에서 삭제될 때 해제된다.
if (it != m_aPrivGuild[type].end())
it->second = p;
else
@ -158,8 +158,8 @@ void CPrivManager::AddEmpirePriv(BYTE empire, BYTE type, int value, time_t durat
time_t now = CClientManager::instance().GetCurrentTime();
time_t end = now+duration_sec;
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ȿȭ
// priority_queue<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD> pointer == m_aaPrivEmpire[type][empire]
// 이전 설정값 무효화
// priority_queue에 들어있는 pointer == m_aaPrivEmpire[type][empire]
{
if (m_aaPrivEmpire[type][empire])
m_aaPrivEmpire[type][empire]->bRemoved = true;
@ -177,7 +177,7 @@ void CPrivManager::AddEmpirePriv(BYTE empire, BYTE type, int value, time_t durat
}
/**
* @version 05/06/08 Bang2ni - <EFBFBD><EFBFBD><EFBFBD>ӽð<EFBFBD> <20>߰<EFBFBD>
* @version 05/06/08 Bang2ni - 지속시간 추가
*/
struct FSendChangeGuildPriv
{

View File

@ -25,23 +25,23 @@ string trim(const string& str){return trim_left(trim_right(str));}
static string* StringSplit(string strOrigin, string strTok)
{
int cutAt; //<EFBFBD>ڸ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ġ
int index = 0; //<EFBFBD><EFBFBD><EFBFBD>ڿ<EFBFBD><EFBFBD>ε<EFBFBD><EFBFBD><EFBFBD>
string* strResult = new string[30]; //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>return <EFBFBD>Һ<EFBFBD><EFBFBD><EFBFBD>
int cutAt; //자르는위치
int index = 0; //문자열인덱스
string* strResult = new string[30]; //결과return 할변수
//strTok<EFBFBD><EFBFBD>ã<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݺ<EFBFBD>
//strTok을찾을때까지반복
while ((cutAt = strOrigin.find_first_of(strTok)) != strOrigin.npos)
{
if (cutAt > 0) //<EFBFBD>ڸ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ġ<EFBFBD><EFBFBD>0<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ũ<EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
if (cutAt > 0) //자르는위치가0보다크면(성공시)
{
strResult[index++] = strOrigin.substr(0, cutAt); //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߰<EFBFBD>
strResult[index++] = strOrigin.substr(0, cutAt); //결과배열에추가
}
strOrigin = strOrigin.substr(cutAt+1); //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڸ<EFBFBD><EFBFBD>κ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
strOrigin = strOrigin.substr(cutAt+1); //원본은자른부분제외한나머지
}
if(strOrigin.length() > 0) //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̾<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if(strOrigin.length() > 0) //원본이아직남았으면
{
strResult[index++] = strOrigin.substr(0, cutAt); //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߰<EFBFBD>
strResult[index++] = strOrigin.substr(0, cutAt); //나머지를결과배열에추가
}
for( int i=0;i<index;i++)
@ -49,7 +49,7 @@ static string* StringSplit(string strOrigin, string strTok)
strResult[i] = trim(strResult[i]);
}
return strResult; //<EFBFBD><EFBFBD><EFBFBD><EFBFBD>return
return strResult; //결과return
}
@ -60,25 +60,25 @@ int get_Item_Type_Value(string inputString)
"ITEM_ARMOR", "ITEM_USE",
"ITEM_AUTOUSE", "ITEM_MATERIAL",
"ITEM_SPECIAL", "ITEM_TOOL",
"ITEM_LOTTERY", "ITEM_ELK", //10<EFBFBD><EFBFBD>
"ITEM_LOTTERY", "ITEM_ELK", //10
"ITEM_METIN", "ITEM_CONTAINER",
"ITEM_FISH", "ITEM_ROD",
"ITEM_RESOURCE", "ITEM_CAMPFIRE",
"ITEM_UNIQUE", "ITEM_SKILLBOOK",
"ITEM_QUEST", "ITEM_POLYMORPH", //20<EFBFBD><EFBFBD>
"ITEM_QUEST", "ITEM_POLYMORPH", //20
"ITEM_TREASURE_BOX", "ITEM_TREASURE_KEY",
"ITEM_SKILLFORGET", "ITEM_GIFTBOX",
"ITEM_PICK", "ITEM_HAIR",
"ITEM_TOTEM", "ITEM_BLEND",
"ITEM_COSTUME", "ITEM_DS", //30<EFBFBD><EFBFBD>
"ITEM_COSTUME", "ITEM_DS", //30
"ITEM_SPECIAL_DS", "ITEM_EXTRACT",
"ITEM_SECONDARY_COIN", //33<EFBFBD><EFBFBD>
"ITEM_SECONDARY_COIN", //33
"ITEM_RING",
"ITEM_BELT", //35<EFBFBD><EFBFBD> (EItemTypes <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ġ<><C4A1> 34)
"ITEM_BELT", //35 (EItemTypes 값으로 치면 34)
};
@ -159,8 +159,8 @@ int get_Item_SubType_Value(int type_value, string inputString)
arSub29, //30
arSub31, //31
0, //32
0, //33 <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0, //34 <EFBFBD><EFBFBD>Ʈ
0, //33 반지
0, //34 벨트
};
static int arNumberOfSubtype[_countof(arSubType)] = {
0,
@ -196,21 +196,21 @@ int get_Item_SubType_Value(int type_value, string inputString)
sizeof(arSub29)/sizeof(arSub29[0]),
sizeof(arSub31)/sizeof(arSub31[0]),
0, // 32
0, // 33 <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
0, // 34 <EFBFBD><EFBFBD>Ʈ
0, // 33 반지
0, // 34 벨트
};
assert(_countof(arSubType) > type_value && "Subtype rule: Out of range!!");
// assert <EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>..
// assert 안 먹히는 듯..
if (_countof(arSubType) <= type_value)
{
SPDLOG_ERROR("SubType : Out of range!! (type_value: {}, count of registered subtype: {}", type_value, _countof(arSubType));
return -1;
}
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ÿ<><C5B8><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ÿ<EFBFBD><C5B8> <20><EFBFBD>̰<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD><CFB4><EFBFBD> <20>˾ƺ<CBBE><C6BA><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0 <20><><EFBFBD><EFBFBD>
//아이템 타입의 서브타입 어레이가 존재하는지 알아보고, 없으면 0 리턴
if (arSubType[type_value]==0) {
return 0;
}
@ -246,13 +246,13 @@ int get_Item_AntiFlag_Value(string inputString)
int retValue = 0;
string* arInputString = StringSplit(inputString, "|"); //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ܾ<DCBE><EEBAB0> <20>ɰ<EFBFBD> <20>.
string* arInputString = StringSplit(inputString, "|"); //프로토 정보 내용을 단어별로 쪼갠 배열.
for(int i =0;i<sizeof(arAntiFlag)/sizeof(arAntiFlag[0]);i++) {
string tempString = arAntiFlag[i];
for (int j=0; j<30 ; j++) //<EFBFBD>ִ<EFBFBD> 30<33><30> <20>ܾ<EFBFBD><DCBE><EFBFBD><EFBFBD><EFBFBD>. (<28>ϵ<EFBFBD><CFB5>ڵ<EFBFBD>)
for (int j=0; j<30 ; j++) //최대 30개 단어까지. (하드코딩)
{
string tempString2 = arInputString[j];
if (tempString2.compare(tempString)==0) { //<EFBFBD><EFBFBD>ġ<EFBFBD>ϴ<EFBFBD><EFBFBD><EFBFBD> Ȯ<><C8AE>.
if (tempString2.compare(tempString)==0) { //일치하는지 확인.
retValue = retValue + pow((float)2,(float)i);
}
@ -275,13 +275,13 @@ int get_Item_Flag_Value(string inputString)
int retValue = 0;
string* arInputString = StringSplit(inputString, "|"); //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ܾ<DCBE><EEBAB0> <20>ɰ<EFBFBD> <20>.
string* arInputString = StringSplit(inputString, "|"); //프로토 정보 내용을 단어별로 쪼갠 배열.
for(int i =0;i<sizeof(arFlag)/sizeof(arFlag[0]);i++) {
string tempString = arFlag[i];
for (int j=0; j<30 ; j++) //<EFBFBD>ִ<EFBFBD> 30<33><30> <20>ܾ<EFBFBD><DCBE><EFBFBD><EFBFBD><EFBFBD>. (<28>ϵ<EFBFBD><CFB5>ڵ<EFBFBD>)
for (int j=0; j<30 ; j++) //최대 30개 단어까지. (하드코딩)
{
string tempString2 = arInputString[j];
if (tempString2.compare(tempString)==0) { //<EFBFBD><EFBFBD>ġ<EFBFBD>ϴ<EFBFBD><EFBFBD><EFBFBD> Ȯ<><C8AE>.
if (tempString2.compare(tempString)==0) { //일치하는지 확인.
retValue = retValue + pow((float)2,(float)i);
}
@ -303,13 +303,13 @@ int get_Item_WearFlag_Value(string inputString)
int retValue = 0;
string* arInputString = StringSplit(inputString, "|"); //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ܾ<DCBE><EEBAB0> <20>ɰ<EFBFBD> <20>.
string* arInputString = StringSplit(inputString, "|"); //프로토 정보 내용을 단어별로 쪼갠 배열.
for(int i =0;i<sizeof(arWearrFlag)/sizeof(arWearrFlag[0]);i++) {
string tempString = arWearrFlag[i];
for (int j=0; j<30 ; j++) //<EFBFBD>ִ<EFBFBD> 30<33><30> <20>ܾ<EFBFBD><DCBE><EFBFBD><EFBFBD><EFBFBD>. (<28>ϵ<EFBFBD><CFB5>ڵ<EFBFBD>)
for (int j=0; j<30 ; j++) //최대 30개 단어까지. (하드코딩)
{
string tempString2 = arInputString[j];
if (tempString2.compare(tempString)==0) { //<EFBFBD><EFBFBD>ġ<EFBFBD>ϴ<EFBFBD><EFBFBD><EFBFBD> Ȯ<><C8AE>.
if (tempString2.compare(tempString)==0) { //일치하는지 확인.
retValue = retValue + pow((float)2,(float)i);
}
@ -329,13 +329,13 @@ int get_Item_Immune_Value(string inputString)
string arImmune[] = {"PARA","CURSE","STUN","SLEEP","SLOW","POISON","TERROR"};
int retValue = 0;
string* arInputString = StringSplit(inputString, "|"); //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ܾ<DCBE><EEBAB0> <20>ɰ<EFBFBD> <20>.
string* arInputString = StringSplit(inputString, "|"); //프로토 정보 내용을 단어별로 쪼갠 배열.
for(int i =0;i<sizeof(arImmune)/sizeof(arImmune[0]);i++) {
string tempString = arImmune[i];
for (int j=0; j<30 ; j++) //<EFBFBD>ִ<EFBFBD> 30<33><30> <20>ܾ<EFBFBD><DCBE><EFBFBD><EFBFBD><EFBFBD>. (<28>ϵ<EFBFBD><CFB5>ڵ<EFBFBD>)
for (int j=0; j<30 ; j++) //최대 30개 단어까지. (하드코딩)
{
string tempString2 = arInputString[j];
if (tempString2.compare(tempString)==0) { //<EFBFBD><EFBFBD>ġ<EFBFBD>ϴ<EFBFBD><EFBFBD><EFBFBD> Ȯ<><C8AE>.
if (tempString2.compare(tempString)==0) { //일치하는지 확인.
retValue = retValue + pow((float)2,(float)i);
}
@ -414,7 +414,7 @@ int get_Item_ApplyType_Value(string inputString)
}
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><20>д´<D0B4>.
//몬스터 프로토도 읽는다.
int get_Mob_Rank_Value(string inputString)
@ -508,13 +508,13 @@ int get_Mob_AIFlag_Value(string inputString)
int retValue = 0;
string* arInputString = StringSplit(inputString, ","); //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ܾ<DCBE><EEBAB0> <20>ɰ<EFBFBD> <20>.
string* arInputString = StringSplit(inputString, ","); //프로토 정보 내용을 단어별로 쪼갠 배열.
for(int i =0;i<sizeof(arAIFlag)/sizeof(arAIFlag[0]);i++) {
string tempString = arAIFlag[i];
for (int j=0; j<30 ; j++) //<EFBFBD>ִ<EFBFBD> 30<33><30> <20>ܾ<EFBFBD><DCBE><EFBFBD><EFBFBD><EFBFBD>. (<28>ϵ<EFBFBD><CFB5>ڵ<EFBFBD>)
for (int j=0; j<30 ; j++) //최대 30개 단어까지. (하드코딩)
{
string tempString2 = arInputString[j];
if (tempString2.compare(tempString)==0) { //<EFBFBD><EFBFBD>ġ<EFBFBD>ϴ<EFBFBD><EFBFBD><EFBFBD> Ȯ<><C8AE>.
if (tempString2.compare(tempString)==0) { //일치하는지 확인.
retValue = retValue + pow((float)2,(float)i);
}
@ -533,13 +533,13 @@ int get_Mob_RaceFlag_Value(string inputString)
"ATT_ELEC","ATT_FIRE","ATT_ICE","ATT_WIND","ATT_EARTH","ATT_DARK"};
int retValue = 0;
string* arInputString = StringSplit(inputString, ","); //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ܾ<DCBE><EEBAB0> <20>ɰ<EFBFBD> <20>.
string* arInputString = StringSplit(inputString, ","); //프로토 정보 내용을 단어별로 쪼갠 배열.
for(int i =0;i<sizeof(arRaceFlag)/sizeof(arRaceFlag[0]);i++) {
string tempString = arRaceFlag[i];
for (int j=0; j<30 ; j++) //<EFBFBD>ִ<EFBFBD> 30<33><30> <20>ܾ<EFBFBD><DCBE><EFBFBD><EFBFBD><EFBFBD>. (<28>ϵ<EFBFBD><CFB5>ڵ<EFBFBD>)
for (int j=0; j<30 ; j++) //최대 30개 단어까지. (하드코딩)
{
string tempString2 = arInputString[j];
if (tempString2.compare(tempString)==0) { //<EFBFBD><EFBFBD>ġ<EFBFBD>ϴ<EFBFBD><EFBFBD><EFBFBD> Ȯ<><C8AE>.
if (tempString2.compare(tempString)==0) { //일치하는지 확인.
retValue = retValue + pow((float)2,(float)i);
}
@ -557,13 +557,13 @@ int get_Mob_ImmuneFlag_Value(string inputString)
string arImmuneFlag[] = {"STUN","SLOW","FALL","CURSE","POISON","TERROR", "REFLECT"};
int retValue = 0;
string* arInputString = StringSplit(inputString, ","); //<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ܾ<DCBE><EEBAB0> <20>ɰ<EFBFBD> <20>.
string* arInputString = StringSplit(inputString, ","); //프로토 정보 내용을 단어별로 쪼갠 배열.
for(int i =0;i<sizeof(arImmuneFlag)/sizeof(arImmuneFlag[0]);i++) {
string tempString = arImmuneFlag[i];
for (int j=0; j<30 ; j++) //<EFBFBD>ִ<EFBFBD> 30<33><30> <20>ܾ<EFBFBD><DCBE><EFBFBD><EFBFBD><EFBFBD>. (<28>ϵ<EFBFBD><CFB5>ڵ<EFBFBD>)
for (int j=0; j<30 ; j++) //최대 30개 단어까지. (하드코딩)
{
string tempString2 = arInputString[j];
if (tempString2.compare(tempString)==0) { //<EFBFBD><EFBFBD>ġ<EFBFBD>ϴ<EFBFBD><EFBFBD><EFBFBD> Ȯ<><C8AE>.
if (tempString2.compare(tempString)==0) { //일치하는지 확인.
retValue = retValue + pow((float)2,(float)i);
}
@ -581,14 +581,14 @@ int get_Mob_ImmuneFlag_Value(string inputString)
#ifndef __DUMP_PROTO__
//<EFBFBD><EFBFBD> <20><><EFBFBD>̺<EFBFBD><CCBA><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ش<EFBFBD>.
//몹 테이블을 셋팅해준다.
bool Set_Proto_Mob_Table(TMobTable *mobTable, cCsvTable &csvTable,std::map<int,const char*> &nameMap)
{
int col = 0;
str_to_number(mobTable->dwVnum, csvTable.AsStringByIndex(col++));
strlcpy(mobTable->szName, csvTable.AsStringByIndex(col++), sizeof(mobTable->szName));
//3. <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20≯<EFBFBD> <20>־<EFBFBD><D6BE>ֱ<EFBFBD>.
//3. 지역별 이름 넣어주기.
map<int,const char*>::iterator it;
it = nameMap.find(mobTable->dwVnum);
if (it != nameMap.end()) {
@ -749,11 +749,11 @@ bool Set_Proto_Item_Table(TItemTable *itemTable, cCsvTable &csvTable,std::map<in
col = col + 1;
}
// vnum <EFBFBD><EFBFBD> vnum range <EFBFBD>б<EFBFBD>.
// vnum vnum range 읽기.
{
std::string s(csvTable.AsStringByIndex(0));
int pos = s.find("~");
// vnum <EFBFBD>ʵ忡 '~'<EFBFBD><EFBFBD> <20><><EFBFBD>ٸ<EFBFBD> <20>н<EFBFBD>
// vnum 필드에 '~'가 없다면 패스
if (std::string::npos == pos)
{
itemTable->dwVnum = dataArray[0];
@ -777,7 +777,7 @@ bool Set_Proto_Item_Table(TItemTable *itemTable, cCsvTable &csvTable,std::map<in
}
strlcpy(itemTable->szName, csvTable.AsStringByIndex(1), sizeof(itemTable->szName));
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20≯<EFBFBD> <20>־<EFBFBD><D6BE>ֱ<EFBFBD>.
//지역별 이름 넣어주기.
map<int,const char*>::iterator it;
it = nameMap.find(itemTable->dwVnum);
if (it != nameMap.end()) {

View File

@ -28,7 +28,7 @@ void CGrid::Clear()
int CGrid::FindBlank(int w, int h)
{
// ũ<EFBFBD><20><> ũ<>ٸ<EFBFBD> Ȯ<><C8AE><EFBFBD><EFBFBD> <20>ʿ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>׳<EFBFBD> <20><><EFBFBD><EFBFBD>
// 크기가 더 크다면 확인할 필요 없이 그냥 리턴
if (w > m_iWidth || h > m_iHeight)
return -1;
@ -86,7 +86,7 @@ bool CGrid::IsEmpty(int iPos, int w, int h)
{
int iRow = iPos / m_iWidth;
// Grid <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ΰ<EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>˻<EFBFBD>
// Grid 안쪽인가를 먼저 검사
if (iRow + h > m_iHeight)
return false;