fix db cpp encoding
This commit is contained in:
parent
d471d99a24
commit
dd74eafc24
|
@ -135,7 +135,7 @@ void AuctionManager::LoadAuctionItem()
|
|||
}
|
||||
int rows;
|
||||
|
||||
if ((rows = mysql_num_rows(res)) <= 0) // 데이터 없음
|
||||
if ((rows = mysql_num_rows(res)) <= 0) // 데이터 없음
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -182,7 +182,7 @@ void AuctionManager::LoadAuctionInfo()
|
|||
}
|
||||
int rows;
|
||||
|
||||
if ((rows = mysql_num_rows(res)) <= 0) // 데이터 없음
|
||||
if ((rows = mysql_num_rows(res)) <= 0) // 데이터 없음
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -226,7 +226,7 @@ void AuctionManager::LoadSaleInfo()
|
|||
}
|
||||
int rows;
|
||||
|
||||
if ((rows = mysql_num_rows(res)) <= 0) // 데이터 없음
|
||||
if ((rows = mysql_num_rows(res)) <= 0) // 데이터 없음
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -269,7 +269,7 @@ void AuctionManager::LoadWishInfo()
|
|||
}
|
||||
int rows;
|
||||
|
||||
if ((rows = mysql_num_rows(res)) <= 0) // 데이터 없음
|
||||
if ((rows = mysql_num_rows(res)) <= 0) // 데이터 없음
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -311,7 +311,7 @@ void AuctionManager::LoadMyBidInfo ()
|
|||
}
|
||||
int rows;
|
||||
|
||||
if ((rows = mysql_num_rows(res)) <= 0) // 데이터 없음
|
||||
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;
|
||||
}
|
||||
|
||||
// 즉구 해버렸으므로, 경매는 끝났다.
|
||||
// 즉구 해버렸으므로, 경매는 끝났다.
|
||||
item_info->expired_time = 0;
|
||||
item_info->bidder_id = purchaser_id;
|
||||
item_info->set_bidder_name (purchaser_name);
|
||||
|
|
|
@ -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; // 아이피가 괴상하니 일단 블럭처리
|
||||
return true; // 아이피가 괴상하니 일단 블럭처리
|
||||
|
||||
DO_ALL_BLOCK_IP(iter)
|
||||
{
|
||||
|
|
|
@ -29,12 +29,12 @@ CItemCache::~CItemCache()
|
|||
{
|
||||
}
|
||||
|
||||
// 이거 이상한데...
|
||||
// Delete를 했으면, Cache도 해제해야 하는것 아닌가???
|
||||
// 근데 Cache를 해제하는 부분이 없어.
|
||||
// 못 찾은 건가?
|
||||
// 이렇게 해놓으면, 계속 시간이 될 때마다 아이템을 계속 지워...
|
||||
// 이미 사라진 아이템인데... 확인사살??????
|
||||
// 이거 이상한데...
|
||||
// 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; // 바로 타임아웃 되도록 하자.
|
||||
//m_lastUpdateTime = time(0) - m_expireTime; // 바로 타임아웃 되도록 하자.
|
||||
}
|
||||
|
||||
void CItemCache::OnFlush()
|
||||
{
|
||||
if (m_data.vnum == 0) // vnum이 0이면 삭제하라고 표시된 것이다.
|
||||
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)
|
||||
{
|
||||
//
|
||||
// 이미 캐싱된 아이템과 중복된 아이템을 찾고 중복되지 않는 이전 정보는 tmpvec 에 넣는다.
|
||||
// 이미 캐싱된 아이템과 중복된 아이템을 찾고 중복되지 않는 이전 정보는 tmpvec 에 넣는다.
|
||||
//
|
||||
|
||||
std::vector<TItemPriceInfo> tmpvec;
|
||||
|
@ -202,7 +202,7 @@ void CItemPriceListTableCache::UpdateList(const TItemPriceListTable* pUpdateList
|
|||
}
|
||||
|
||||
//
|
||||
// pUpdateList 를 m_data 에 복사하고 남은 공간을 tmpvec 의 앞에서 부터 남은 만큼 복사한다.
|
||||
// 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; // 삭제된 가격정보의 갯수
|
||||
int nDeletedNum; // 삭제된 가격정보의 갯수
|
||||
|
||||
if (pUpdateList->byCount < SHOP_PRICELIST_MAX_NUM)
|
||||
{
|
||||
|
@ -244,14 +244,14 @@ void CItemPriceListTableCache::OnFlush()
|
|||
char szQuery[QUERY_MAX_LEN];
|
||||
|
||||
//
|
||||
// 이 캐시의 소유자에 대한 기존에 DB 에 저장된 아이템 가격정보를 모두 삭제한다.
|
||||
// 이 캐시의 소유자에 대한 기존에 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);
|
||||
|
||||
//
|
||||
// 캐시의 내용을 모두 DB 에 쓴다.
|
||||
// 캐시의 내용을 모두 DB 에 쓴다.
|
||||
//
|
||||
|
||||
for (int idx = 0; idx < m_data.byCount; ++idx)
|
||||
|
|
|
@ -248,7 +248,7 @@ bool CClientManager::Initialize()
|
|||
|
||||
LoadEventFlag();
|
||||
|
||||
// database character-set을 강제로 맞춤
|
||||
// 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);
|
||||
|
||||
// 메인루프
|
||||
// 메인루프
|
||||
while (!m_bShutdowned)
|
||||
{
|
||||
while ((tmp = CDBManager::instance().PopResult()))
|
||||
|
@ -275,7 +275,7 @@ void CClientManager::MainLoop()
|
|||
}
|
||||
|
||||
//
|
||||
// 메인루프 종료처리
|
||||
// 메인루프 종료처리
|
||||
//
|
||||
SPDLOG_DEBUG("MainLoop exited, Starting cache flushing");
|
||||
|
||||
|
@ -283,7 +283,7 @@ void CClientManager::MainLoop()
|
|||
|
||||
itertype(m_map_playerCache) it = m_map_playerCache.begin();
|
||||
|
||||
//플레이어 테이블 캐쉬 플러쉬
|
||||
//플레이어 테이블 캐쉬 플러쉬
|
||||
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();
|
||||
//아이템 플러쉬
|
||||
//아이템 플러쉬
|
||||
while (it2 != m_map_itemCache.end())
|
||||
{
|
||||
CItemCache * c = (it2++)->second;
|
||||
|
@ -307,7 +307,7 @@ void CClientManager::MainLoop()
|
|||
|
||||
// MYSHOP_PRICE_LIST
|
||||
//
|
||||
// 개인상점 아이템 가격 리스트 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 패킷이 바뀔때마다 번호를 올리도록 한다.
|
||||
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;
|
||||
|
||||
// 여기에서 사용하는 account_index는 쿼리 순서를 말한다.
|
||||
// 첫번째 패스워드 알아내기 위해 하는 쿼리가 0
|
||||
// 두번째 실제 데이터를 얻어놓는 쿼리가 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);
|
||||
|
||||
// 비밀번호가 틀리면..
|
||||
// 비밀번호가 틀리면..
|
||||
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)
|
|||
}
|
||||
|
||||
|
||||
// 쿼리에 에러가 있었으므로 응답할 경우 창고가 비어있는 것 처럼
|
||||
// 보이기 때문에 창고가 아얘 안열리는게 나음
|
||||
// 쿼리에 에러가 있었으므로 응답할 경우 창고가 비어있는 것 처럼
|
||||
// 보이기 때문에 창고가 아얘 안열리는게 나음
|
||||
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:
|
||||
// 무시무시하지만 이전에 하던 걸 고치기는 무섭고...
|
||||
// 그래서 그냥 하드 코딩. 선물 상자용 자동물약 아이템들.
|
||||
// 무시무시하지만 이전에 하던 걸 고치기는 무섭고...
|
||||
// 그래서 그냥 하드 코딩. 선물 상자용 자동물약 아이템들.
|
||||
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를 사이즈로 임시로 사용
|
||||
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 에서 로드한 정보를 Cache 에 저장
|
||||
// DB 에서 로드한 정보를 Cache 에 저장
|
||||
//
|
||||
|
||||
TItemPriceListTable table;
|
||||
|
@ -1007,7 +1007,7 @@ void CClientManager::RESULT_PRICELIST_LOAD(CPeer* peer, SQLMsg* pMsg)
|
|||
PutItemPriceListCache(&table);
|
||||
|
||||
//
|
||||
// 로드한 데이터를 Game server 에 전송
|
||||
// 로드한 데이터를 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 에서 로드한 정보를 Cache 에 저장
|
||||
// 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, // 신수국
|
||||
21, // 천조국
|
||||
41 // 진노국
|
||||
1, // 신수국
|
||||
21, // 천조국
|
||||
41 // 진노국
|
||||
};
|
||||
|
||||
// FIXME share with game
|
||||
DWORD g_start_position[4][2]=
|
||||
{
|
||||
{ 0, 0 },
|
||||
{ 469300, 964200 }, // 신수국
|
||||
{ 55700, 157900 }, // 천조국
|
||||
{ 969600, 278400 } // 진노국
|
||||
{ 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);
|
||||
|
||||
//
|
||||
// 어떤 맵이 어떤 서버에 있는지 보내기
|
||||
// 어떤 맵이 어떤 서버에 있는지 보내기
|
||||
//
|
||||
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());
|
||||
|
||||
//
|
||||
// 셋업 : 접속한 피어에 다른 피어들이 접속하게 만든다. (P2P 컨넥션 생성)
|
||||
// 셋업 : 접속한 피어에 다른 피어들이 접속하게 만든다. (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;
|
||||
|
||||
// 채널이 0이라면 아직 SETUP 패킷이 오지 않은 피어 또는 auth라고 간주할 수 있음
|
||||
// 채널이 0이라면 아직 SETUP 패킷이 오지 않은 피어 또는 auth라고 간주할 수 있음
|
||||
if (0 == tmp->GetChannel())
|
||||
continue;
|
||||
|
||||
|
@ -1287,7 +1287,7 @@ void CClientManager::QUERY_SETUP(CPeer * peer, DWORD dwHandle, const char * c_pD
|
|||
}
|
||||
|
||||
//
|
||||
// 로그인 및 빌링정보 보내기
|
||||
// 로그인 및 빌링정보 보내기
|
||||
//
|
||||
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;
|
||||
|
||||
// 창고면 캐쉬하지 않고, 캐쉬에 있던 것도 빼버려야 한다.
|
||||
// auction은 이 루트를 타지 않아야 한다. EnrollInAuction을 타야한다.
|
||||
// 창고면 캐쉬하지 않고, 캐쉬에 있던 것도 빼버려야 한다.
|
||||
// auction은 이 루트를 타지 않아야 한다. EnrollInAuction을 타야한다.
|
||||
|
||||
if (p->window == SAFEBOX || p->window == MALL)
|
||||
{
|
||||
|
@ -1495,7 +1495,7 @@ void CClientManager::PutItemCache(TPlayerItem * pNew, bool bSkipQuery)
|
|||
|
||||
c = GetItemCache(pNew->id);
|
||||
|
||||
// 아이템 새로 생성
|
||||
// 아이템 새로 생성
|
||||
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));
|
||||
}
|
||||
// 있을시
|
||||
// 있을시
|
||||
else
|
||||
{
|
||||
SPDLOG_TRACE("ITEM_CACHE: PutItemCache ==> Have Cache");
|
||||
|
||||
// 소유자가 틀리면
|
||||
// 소유자가 틀리면
|
||||
if (pNew->owner != c->Get()->owner)
|
||||
{
|
||||
// 이미 이 아이템을 가지고 있었던 유저로 부터 아이템을 삭제한다.
|
||||
// 이미 이 아이템을 가지고 있었던 유저로 부터 아이템을 삭제한다.
|
||||
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)
|
|||
}
|
||||
}
|
||||
|
||||
// 새로운 정보 업데이트
|
||||
// 새로운 정보 업데이트
|
||||
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
|
||||
{
|
||||
// 현재 소유자가 없으므로 바로 저장해야 다음 접속이 올 때 SQL에 쿼리하여
|
||||
// 받을 수 있으므로 바로 저장한다.
|
||||
// 현재 소유자가 없으므로 바로 저장해야 다음 접속이 올 때 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도 업데이트
|
||||
// Item Cache도 업데이트
|
||||
UpdateItemCacheSet(c->Get()->id);
|
||||
}
|
||||
else if (c->CheckFlushTimeout())
|
||||
|
@ -1617,7 +1617,7 @@ void CClientManager::UpdateItemCache()
|
|||
{
|
||||
CItemCache * c = (it++)->second;
|
||||
|
||||
// 아이템은 Flush만 한다.
|
||||
// 아이템은 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) // 아무도 가진 사람이 없었다면, 비동기 쿼리
|
||||
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 - 지속시간 추가
|
||||
* @version 05/06/08 Bang2ni - 지속시간 추가
|
||||
*/
|
||||
void CClientManager::AddGuildPriv(TPacketGiveGuildPriv* p)
|
||||
{
|
||||
|
@ -2220,8 +2220,8 @@ void CClientManager::WeddingEnd(TPacketWeddingEnd * p)
|
|||
}
|
||||
|
||||
//
|
||||
// 캐시에 가격정보가 있으면 캐시를 업데이트 하고 캐시에 가격정보가 없다면
|
||||
// 우선 기존의 데이터를 로드한 뒤에 기존의 정보로 캐시를 만들고 새로 받은 가격정보를 업데이트 한다.
|
||||
// 캐시에 가격정보가 있으면 캐시를 업데이트 하고 캐시에 가격정보가 없다면
|
||||
// 우선 기존의 데이터를 로드한 뒤에 기존의 정보로 캐시를 만들고 새로 받은 가격정보를 업데이트 한다.
|
||||
//
|
||||
void CClientManager::MyshopPricelistUpdate(const TPacketMyshopPricelistHeader* pPacket)
|
||||
{
|
||||
|
@ -2262,7 +2262,7 @@ void CClientManager::MyshopPricelistUpdate(const TPacketMyshopPricelistHeader* p
|
|||
}
|
||||
|
||||
// MYSHOP_PRICE_LIST
|
||||
// 캐시된 가격정보가 있으면 캐시를 읽어 바로 전송하고 캐시에 정보가 없으면 DB 에 쿼리를 한다.
|
||||
// 캐시된 가격정보가 있으면 캐시를 읽어 바로 전송하고 캐시에 정보가 없으면 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: //< 후보 제거 (운영자)
|
||||
case HEADER_GD_RMCANDIDACY: //< 후보 제거 (운영자)
|
||||
RMCandidacy(peer, dwHandle, data);
|
||||
break;
|
||||
|
||||
case HEADER_GD_SETMONARCH: ///<군주설정 (운영자)
|
||||
case HEADER_GD_SETMONARCH: ///<군주설정 (운영자)
|
||||
SetMonarch(peer, dwHandle, data);
|
||||
break;
|
||||
|
||||
case HEADER_GD_RMMONARCH: ///<군주삭제
|
||||
case HEADER_GD_RMMONARCH: ///<군주삭제
|
||||
RMMonarch(peer, dwHandle, data);
|
||||
break;
|
||||
//END_MONARCH
|
||||
|
@ -2864,9 +2864,9 @@ CPeer * CClientManager::GetAnyPeer()
|
|||
return m_peerList.front();
|
||||
}
|
||||
|
||||
// DB 매니저로 부터 받은 결과를 처리한다.
|
||||
// DB 매니저로 부터 받은 결과를 처리한다.
|
||||
//
|
||||
// @version 05/06/10 Bang2ni - 가격정보 관련 쿼리(QID_ITEMPRICE_XXX) 추가
|
||||
// @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 초 * 60 분
|
||||
int avg = g_dwUsageAvg / 3600; // 60 초 * 60 분
|
||||
|
||||
fp = fopen("usage.txt", "a+");
|
||||
|
||||
|
@ -3017,7 +3017,7 @@ int CClientManager::Process()
|
|||
++thecore_heart->pulse;
|
||||
|
||||
/*
|
||||
//30분마다 변경
|
||||
//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;
|
||||
|
||||
|
||||
//플레이어 플러쉬
|
||||
//플레이어 플러쉬
|
||||
UpdatePlayerCache();
|
||||
//아이템 플러쉬
|
||||
//아이템 플러쉬
|
||||
UpdateItemCache();
|
||||
//로그아웃시 처리- 캐쉬셋 플러쉬
|
||||
//로그아웃시 처리- 캐쉬셋 플러쉬
|
||||
UpdateLogoutPlayer();
|
||||
|
||||
// MYSHOP_PRICE_LIST
|
||||
|
@ -3169,13 +3169,13 @@ int CClientManager::Process()
|
|||
/////////////////////////////////////////////////////////////////
|
||||
}
|
||||
|
||||
if (!(thecore_heart->pulse % (thecore_heart->passes_per_sec * 60))) // 60초에 한번
|
||||
if (!(thecore_heart->pulse % (thecore_heart->passes_per_sec * 60))) // 60초에 한번
|
||||
{
|
||||
// 유니크 아이템을 위한 시간을 보낸다.
|
||||
// 유니크 아이템을 위한 시간을 보낸다.
|
||||
CClientManager::instance().SendTime();
|
||||
}
|
||||
|
||||
if (!(thecore_heart->pulse % (thecore_heart->passes_per_sec * 3600))) // 한시간에 한번
|
||||
if (!(thecore_heart->pulse % (thecore_heart->passes_per_sec * 3600))) // 한시간에 한번
|
||||
{
|
||||
CMoneyLog::instance().Save();
|
||||
}
|
||||
|
@ -3190,7 +3190,7 @@ int CClientManager::Process()
|
|||
|
||||
DWORD CClientManager::GetUserCount()
|
||||
{
|
||||
// 단순히 로그인 카운트를 센다.. --;
|
||||
// 단순히 로그인 카운트를 센다.. --;
|
||||
return m_map_kLogonAccount.size();
|
||||
}
|
||||
|
||||
|
@ -3250,7 +3250,7 @@ bool CClientManager::InitializeNowItemID()
|
|||
{
|
||||
DWORD dwMin, dwMax;
|
||||
|
||||
//아이템 ID를 초기화 한다.
|
||||
//아이템 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 일경우 모든서버에 운영자 권한을 갖는다.
|
||||
//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만 맵에서 지운다.
|
||||
// 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;
|
||||
}
|
||||
// 현재 시각 + 24시간 후.
|
||||
// 현재 시각 + 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
|
||||
{
|
||||
// 아이템 케시를 Auction에 등록 했으니 ClientManager에서는 뺀다.
|
||||
// 아이템 케시를 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;
|
||||
}
|
||||
// 현재 시각 + 24시간 후.
|
||||
// 현재 시각 + 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
|
||||
{
|
||||
// 아이템 케시를 Auction에 등록 했으니 ClientManager에서는 뺀다.
|
||||
// 아이템 케시를 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);
|
||||
|
||||
// 현재 시각 + 24시간 후.
|
||||
// 현재 시각 + 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는 이전 입찰금액에 더해서 입찰한다.
|
||||
// ReBid에선 data->bid_price가 이전 입찰가에 더해져서
|
||||
// 그 금액으로 rebid하는 것.
|
||||
// 이렇게 한 이유는 rebid에 실패 했을 때,
|
||||
// 유저의 호주머니에서 뺀 돈을 돌려주기 편하게 하기 위함이다.
|
||||
// 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());
|
||||
}
|
||||
// 이건 FAIL이 떠서는 안돼.
|
||||
// FAIL이 뜰 수가 없는게, MyBid에 있는 bidder_id에 대한 컨텐츠는 bidder_id만이 접근 할 수 있거든?
|
||||
// 그러므로 다른 것이 다 정상적으로 작동한다고 가정 한다면
|
||||
// 한 게임 서버 내에서 bidder_id로 MyBid를 수정한다 할 지라도, 그건 동기화 문제가 없어.
|
||||
// 다른 게임 서버에 똑같은 bidder_id를 가진 놈이 있을 수가 없으니까.
|
||||
// 그러므로 그 게임 서버에서 BidCancel 명령을 db에 날렸다는 것은,
|
||||
// 이미 그 부분에 대해서는 검사가 완벽하다는 것이야.
|
||||
// 그래도 혹시나 싶어서, 디버깅을 위해 fail 코드를 남겨둔다.
|
||||
// 이건 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);
|
||||
|
||||
// 이건 FAIL이 떠서는 안돼.
|
||||
// FAIL이 뜰 수가 없는게, MyBid에 있는 bidder_id에 대한 컨텐츠는 bidder_id만이 접근 할 수 있거든?
|
||||
// 그러므로 다른 것이 다 정상적으로 작동한다고 가정 한다면
|
||||
// 한 게임 서버 내에서 bidder_id로 MyBid를 수정한다 할 지라도, 그건 동기화 문제가 없어.
|
||||
// 다른 게임 서버에 똑같은 bidder_id를 가진 놈이 있을 수가 없으니까.
|
||||
// 그러므로 그 게임 서버에서 BidCancel 명령을 db에 날렸다는 것은,
|
||||
// 이미 그 부분에 대해서는 검사가 완벽하다는 것이야.
|
||||
// 그래도 혹시나 싶어서, 디버깅을 위해 fail 코드를 남겨둔다.
|
||||
// 이건 FAIL이 떠서는 안돼.
|
||||
// FAIL이 뜰 수가 없는게, MyBid에 있는 bidder_id에 대한 컨텐츠는 bidder_id만이 접근 할 수 있거든?
|
||||
// 그러므로 다른 것이 다 정상적으로 작동한다고 가정 한다면
|
||||
// 한 게임 서버 내에서 bidder_id로 MyBid를 수정한다 할 지라도, 그건 동기화 문제가 없어.
|
||||
// 다른 게임 서버에 똑같은 bidder_id를 가진 놈이 있을 수가 없으니까.
|
||||
// 그러므로 그 게임 서버에서 BidCancel 명령을 db에 날렸다는 것은,
|
||||
// 이미 그 부분에 대해서는 검사가 완벽하다는 것이야.
|
||||
// 그래도 혹시나 싶어서, 디버깅을 위해 fail 코드를 남겨둔다.
|
||||
if (result <= AUCTION_FAIL)
|
||||
{
|
||||
TPacketDGResultAuction enroll_result;
|
||||
|
|
|
@ -171,42 +171,42 @@ class FCompareVnum
|
|||
|
||||
bool CClientManager::InitializeMobTable()
|
||||
{
|
||||
//================== 함수 설명 ==================//
|
||||
//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_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' 파일을 읽어서 (a)[localMap] 맵을 만든다.
|
||||
//<(a)localMap 맵 생성>
|
||||
// 1) 'mob_names.txt' 파일을 읽어서 (a)[localMap] 맵을 만든다.
|
||||
//<(a)localMap 맵 생성>
|
||||
map<int,const char*> localMap;
|
||||
bool isNameFile = true;
|
||||
//<파일 읽기>
|
||||
//<파일 읽기>
|
||||
cCsvTable nameData;
|
||||
if(!nameData.Load("mob_names.txt",'\t'))
|
||||
{
|
||||
SPDLOG_ERROR("mob_names.txt 파일을 읽어오지 못했습니다");
|
||||
SPDLOG_ERROR("mob_names.txt 파일을 읽어오지 못했습니다");
|
||||
isNameFile = false;
|
||||
} else {
|
||||
nameData.Next(); //설명row 생략.
|
||||
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'파일과 (a)localMap 맵으로
|
||||
// (b)[test_map_mobTableByVnum](vnum:TMobTable) 맵을 생성한다.
|
||||
// 2) 'mob_proto_test.txt'파일과 (a)localMap 맵으로
|
||||
// (b)[test_map_mobTableByVnum](vnum:TMobTable) 맵을 생성한다.
|
||||
//0.
|
||||
set<int> vnumSet; //테스트용 파일 데이터중, 신규여부 확인에 사용.
|
||||
//1. 파일 읽어오기
|
||||
set<int> vnumSet; //테스트용 파일 데이터중, 신규여부 확인에 사용.
|
||||
//1. 파일 읽어오기
|
||||
bool isTestFile = true;
|
||||
cCsvTable test_data;
|
||||
if(!test_data.Load("mob_proto_test.txt",'\t'))
|
||||
{
|
||||
SPDLOG_ERROR("테스트 파일이 없습니다. 그대로 진행합니다.");
|
||||
SPDLOG_ERROR("테스트 파일이 없습니다. 그대로 진행합니다.");
|
||||
isTestFile = false;
|
||||
}
|
||||
//2. (c)[test_map_mobTableByVnum](vnum:TMobTable) 맵 생성.
|
||||
//2. (c)[test_map_mobTableByVnum](vnum:TMobTable) 맵 생성.
|
||||
map<DWORD, TMobTable *> test_map_mobTableByVnum;
|
||||
if (isTestFile) {
|
||||
test_data.Next(); //설명 로우 넘어가기.
|
||||
test_data.Next(); //설명 로우 넘어가기.
|
||||
|
||||
//ㄱ. 테스트 몬스터 테이블 생성.
|
||||
//ㄱ. 테스트 몬스터 테이블 생성.
|
||||
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);
|
||||
|
||||
//ㄴ. 테스트 몬스터 테이블에 값을 넣고, 맵에까지 넣기.
|
||||
//ㄴ. 테스트 몬스터 테이블에 값을 넣고, 맵에까지 넣기.
|
||||
while(test_data.Next()) {
|
||||
|
||||
if (!Set_Proto_Mob_Table(test_mob_table, test_data, localMap))
|
||||
{
|
||||
SPDLOG_ERROR("몹 프로토 테이블 셋팅 실패.");
|
||||
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' 파일과 (a)[localMap] 맵으로
|
||||
// (!)[mob_table] 테이블을 만든다.
|
||||
// <참고>
|
||||
// 각 row 들 중,
|
||||
// (b)[test_map_mobTableByVnum],(!)[mob_table] 모두에 있는 row는
|
||||
// (b)[test_map_mobTableByVnum]의 것을 사용한다.
|
||||
// 3) 'mob_proto.txt' 파일과 (a)[localMap] 맵으로
|
||||
// (!)[mob_table] 테이블을 만든다.
|
||||
// <참고>
|
||||
// 각 row 들 중,
|
||||
// (b)[test_map_mobTableByVnum],(!)[mob_table] 모두에 있는 row는
|
||||
// (b)[test_map_mobTableByVnum]의 것을 사용한다.
|
||||
|
||||
//1. 파일 읽기.
|
||||
//1. 파일 읽기.
|
||||
cCsvTable data;
|
||||
if(!data.Load("mob_proto.txt",'\t')) {
|
||||
SPDLOG_ERROR("mob_proto.txt 파일을 읽어오지 못했습니다");
|
||||
SPDLOG_ERROR("mob_proto.txt 파일을 읽어오지 못했습니다");
|
||||
return false;
|
||||
}
|
||||
data.Next(); //설명 row 넘어가기
|
||||
//2. (!)[mob_table] 생성하기
|
||||
//2.1 새로 추가되는 갯수를 파악
|
||||
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를 다시 첫줄로 옮긴다.(다시 읽어온다;;)
|
||||
//data를 다시 첫줄로 옮긴다.(다시 읽어온다;;)
|
||||
data.Destroy();
|
||||
if(!data.Load("mob_proto.txt",'\t'))
|
||||
{
|
||||
SPDLOG_ERROR("mob_proto.txt 파일을 읽어오지 못했습니다");
|
||||
SPDLOG_ERROR("mob_proto.txt 파일을 읽어오지 못했습니다");
|
||||
return false;
|
||||
}
|
||||
data.Next(); //맨 윗줄 제외 (아이템 칼럼을 설명하는 부분)
|
||||
//2.2 크기에 맞게 mob_table 생성
|
||||
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 데이터 채우기
|
||||
//2.3 데이터 채우기
|
||||
while (data.Next())
|
||||
{
|
||||
int col = 0;
|
||||
//(b)[test_map_mobTableByVnum]에 같은 row가 있는지 조사.
|
||||
//(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;
|
||||
}
|
||||
//같은 row 가 있으면 (b)에서 읽어온다.
|
||||
//같은 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("몹 프로토 테이블 셋팅 실패.");
|
||||
SPDLOG_ERROR("몹 프로토 테이블 셋팅 실패.");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//셋에 vnum 추가
|
||||
//셋에 vnum 추가
|
||||
vnumSet.insert(mob_table->dwVnum);
|
||||
|
||||
|
||||
|
@ -395,22 +395,22 @@ bool CClientManager::InitializeMobTable()
|
|||
//_____________________________________________________//
|
||||
|
||||
|
||||
// 4) (b)[test_map_mobTableByVnum]의 row중, (!)[mob_table]에 없는 것을 추가한다.
|
||||
//파일 다시 읽어오기.
|
||||
// 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("테스트 파일이 없습니다. 그대로 진행합니다.");
|
||||
SPDLOG_ERROR("테스트 파일이 없습니다. 그대로 진행합니다.");
|
||||
isTestFile = false;
|
||||
}
|
||||
if(isTestFile) {
|
||||
test_data.Next(); //설명 로우 넘어가기.
|
||||
test_data.Next(); //설명 로우 넘어가기.
|
||||
|
||||
while (test_data.Next()) //테스트 데이터 각각을 훑어나가며,새로운 것을 추가한다.
|
||||
while (test_data.Next()) //테스트 데이터 각각을 훑어나가며,새로운 것을 추가한다.
|
||||
{
|
||||
//중복되는 부분이면 넘어간다.
|
||||
//중복되는 부분이면 넘어간다.
|
||||
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("몹 프로토 테이블 셋팅 실패.");
|
||||
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의 vnum은 있는데 shop_item 이 없을경우... 실패로 처리되니 주의 요망.
|
||||
// 고처야할부분
|
||||
// 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]) // 아이템이 하나도 없으면 NULL이 리턴 되므로..
|
||||
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 테이블에 있는 것들은 모두 ITEM_QUEST 유형
|
||||
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()
|
||||
{
|
||||
//================== 함수 설명 ==================//
|
||||
//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_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' 파일을 읽어서 (a)[localMap](vnum:name) 맵을 만든다.
|
||||
// 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 파일을 읽어오지 못했습니다");
|
||||
SPDLOG_ERROR("item_names.txt 파일을 읽어오지 못했습니다");
|
||||
isNameFile = false;
|
||||
} else {
|
||||
nameData.Next();
|
||||
|
@ -614,32 +614,32 @@ bool CClientManager::InitializeItemTable()
|
|||
//_________________________________________________________________//
|
||||
|
||||
//=================================================================//
|
||||
// 2) 'item_proto_text.txt'파일과 (a)[localMap] 맵으로
|
||||
// (b)[test_map_itemTableByVnum](vnum:TItemTable) 맵을 생성한다.
|
||||
// 2) 'item_proto_text.txt'파일과 (a)[localMap] 맵으로
|
||||
// (b)[test_map_itemTableByVnum](vnum:TItemTable) 맵을 생성한다.
|
||||
//=================================================================//
|
||||
map<DWORD, TItemTable *> test_map_itemTableByVnum;
|
||||
//1. 파일 읽어오기.
|
||||
//1. 파일 읽어오기.
|
||||
cCsvTable test_data;
|
||||
if(!test_data.Load("item_proto_test.txt",'\t'))
|
||||
{
|
||||
SPDLOG_ERROR("item_proto_test.txt 파일을 읽어오지 못했습니다");
|
||||
SPDLOG_ERROR("item_proto_test.txt 파일을 읽어오지 못했습니다");
|
||||
//return false;
|
||||
} else {
|
||||
test_data.Next(); //설명 로우 넘어가기.
|
||||
test_data.Next(); //설명 로우 넘어가기.
|
||||
|
||||
//2. 테스트 아이템 테이블 생성.
|
||||
//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. 테스트 아이템 테이블에 값을 넣고, 맵에까지 넣기.
|
||||
//3. 테스트 아이템 테이블에 값을 넣고, 맵에까지 넣기.
|
||||
while(test_data.Next()) {
|
||||
|
||||
|
||||
if (!Set_Proto_Item_Table(test_item_table, test_data, localMap))
|
||||
{
|
||||
SPDLOG_ERROR("아이템 프로토 테이블 셋팅 실패.");
|
||||
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' 파일과 (a)[localMap] 맵으로
|
||||
// (!)[item_table], <m_map_itemTableByVnum>을 만든다.
|
||||
// <참고>
|
||||
// 각 row 들 중,
|
||||
// (b)[test_map_itemTableByVnum],(!)[mob_table] 모두에 있는 row는
|
||||
// (b)[test_map_itemTableByVnum]의 것을 사용한다.
|
||||
// 3) 'item_proto.txt' 파일과 (a)[localMap] 맵으로
|
||||
// (!)[item_table], <m_map_itemTableByVnum>을 만든다.
|
||||
// <참고>
|
||||
// 각 row 들 중,
|
||||
// (b)[test_map_itemTableByVnum],(!)[mob_table] 모두에 있는 row는
|
||||
// (b)[test_map_itemTableByVnum]의 것을 사용한다.
|
||||
//========================================================================//
|
||||
|
||||
//vnum들을 저장할 셋. 새로운 테스트 아이템을 판별할때 사용된다.
|
||||
//vnum들을 저장할 셋. 새로운 테스트 아이템을 판별할때 사용된다.
|
||||
set<int> vnumSet;
|
||||
|
||||
//파일 읽어오기.
|
||||
//파일 읽어오기.
|
||||
cCsvTable data;
|
||||
if(!data.Load("item_proto.txt",'\t'))
|
||||
{
|
||||
SPDLOG_ERROR("item_proto.txt 파일을 읽어오지 못했습니다");
|
||||
SPDLOG_ERROR("item_proto.txt 파일을 읽어오지 못했습니다");
|
||||
return false;
|
||||
}
|
||||
data.Next(); //맨 윗줄 제외 (아이템 칼럼을 설명하는 부분)
|
||||
data.Next(); //맨 윗줄 제외 (아이템 칼럼을 설명하는 부분)
|
||||
|
||||
if (!m_vec_itemTable.empty())
|
||||
{
|
||||
|
@ -678,8 +678,8 @@ bool CClientManager::InitializeItemTable()
|
|||
m_map_itemTableByVnum.clear();
|
||||
}
|
||||
|
||||
//===== 아이템 테이블 생성 =====//
|
||||
//새로 추가되는 갯수를 파악한다.
|
||||
//===== 아이템 테이블 생성 =====//
|
||||
//새로 추가되는 갯수를 파악한다.
|
||||
int addNumber = 0;
|
||||
while(data.Next()) {
|
||||
int vnum = atoi(data.AsStringByIndex(0));
|
||||
|
@ -689,14 +689,14 @@ bool CClientManager::InitializeItemTable()
|
|||
addNumber++;
|
||||
}
|
||||
}
|
||||
//data를 다시 첫줄로 옮긴다.(다시 읽어온다;;)
|
||||
//data를 다시 첫줄로 옮긴다.(다시 읽어온다;;)
|
||||
data.Destroy();
|
||||
if(!data.Load("item_proto.txt",'\t'))
|
||||
{
|
||||
SPDLOG_ERROR("item_proto.txt 파일을 읽어오지 못했습니다");
|
||||
SPDLOG_ERROR("item_proto.txt 파일을 읽어오지 못했습니다");
|
||||
return false;
|
||||
}
|
||||
data.Next(); //맨 윗줄 제외 (아이템 칼럼을 설명하는 부분)
|
||||
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()) {
|
||||
//각 칼럼 데이터 저장
|
||||
//각 칼럼 데이터 저장
|
||||
|
||||
if (!Set_Proto_Item_Table(item_table, data, localMap))
|
||||
{
|
||||
SPDLOG_ERROR("아이템 프로토 테이블 셋팅 실패.");
|
||||
SPDLOG_ERROR("아이템 프로토 테이블 셋팅 실패.");
|
||||
}
|
||||
|
||||
|
||||
|
||||
} else { //$$$$$$$$$$$$$$$$$$$$$$$ 테스트 아이템 정보가 있다!
|
||||
} else { //$$$$$$$$$$$$$$$$$$$$$$$ 테스트 아이템 정보가 있다!
|
||||
TItemTable *tempTable = it_map_itemTable->second;
|
||||
|
||||
item_table->dwVnum = tempTable->dwVnum;
|
||||
|
@ -777,19 +777,19 @@ bool CClientManager::InitializeItemTable()
|
|||
//_______________________________________________________________________//
|
||||
|
||||
//========================================================================//
|
||||
// 4) (b)[test_map_itemTableByVnum]의 row중, (!)[item_table]에 없는 것을 추가한다.
|
||||
// 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 파일을 읽어오지 못했습니다");
|
||||
SPDLOG_ERROR("item_proto_test.txt 파일을 읽어오지 못했습니다");
|
||||
//return false;
|
||||
} else {
|
||||
test_data.Next(); //설명 로우 넘어가기.
|
||||
test_data.Next(); //설명 로우 넘어가기.
|
||||
|
||||
while (test_data.Next()) //테스트 데이터 각각을 훑어나가며,새로운 것을 추가한다.
|
||||
while (test_data.Next()) //테스트 데이터 각각을 훑어나가며,새로운 것을 추가한다.
|
||||
{
|
||||
//중복되는 부분이면 넘어간다.
|
||||
//중복되는 부분이면 넘어간다.
|
||||
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("아이템 프로토 테이블 셋팅 실패.");
|
||||
SPDLOG_ERROR("아이템 프로토 테이블 셋팅 실패.");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -126,13 +126,13 @@ const char* __GetWarType(int n)
|
|||
switch (n)
|
||||
{
|
||||
case 0 :
|
||||
return "패왕";
|
||||
return "\xEF\xBF\xBD\xD0\xBF\xEF\xBF\xBD"; // 패왕
|
||||
case 1 :
|
||||
return "맹장";
|
||||
return "\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD"; // 맹장
|
||||
case 2 :
|
||||
return "수호";
|
||||
return "\xEF\xBF\xBD\xEF\xBF\xBD\xC8\xA3"; // 수호
|
||||
default :
|
||||
return "없는 번호";
|
||||
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: // 길드전 예약
|
||||
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: // 길드전을 시작 시킨다. (필드전은 바로 시작 됨)
|
||||
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: // 길드전 정상 종료
|
||||
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: // 길드전 비정상 종료
|
||||
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에서 패킷을 보내므로 따로 브로드캐스팅 하지 않는다.
|
||||
return; // NOTE: RecvWarEnd에서 패킷을 보내므로 따로 브로드캐스팅 하지 않는다.
|
||||
|
||||
case GUILD_WAR_CANCEL :
|
||||
SPDLOG_DEBUG("GuildWar: GUILD_WAR_CANCEL type({}) guild({} - {})", __GetWarType(p->bType), p->dwGuildFrom, p->dwGuildTo);
|
||||
|
|
|
@ -230,7 +230,7 @@ TAccountTable * CreateAccountTableFromRes(MYSQL_RES * res)
|
|||
TAccountTable * pkTab = new TAccountTable;
|
||||
memset(pkTab, 0, sizeof(TAccountTable));
|
||||
|
||||
// 첫번째 컬럼 것만 참고 한다 (JOIN QUERY를 위한 것 임)
|
||||
// 첫번째 컬럼 것만 참고 한다 (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)
|
||||
{
|
||||
// 계정이 없네?
|
||||
// 계정이 없네?
|
||||
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) // 이럴리는 없겠지만;;
|
||||
if (!info->pAccountTable) // 이럴리는 없겠지만;;
|
||||
{
|
||||
peer->EncodeReturn(HEADER_DG_LOGIN_WRONG_PASSWD, info->dwHandle);
|
||||
delete info;
|
||||
return;
|
||||
}
|
||||
|
||||
// 다른 컨넥션이 이미 로그인 해버렸다면.. 이미 접속했다고 보내야 한다.
|
||||
// 다른 컨넥션이 이미 로그인 해버렸다면.. 이미 접속했다고 보내야 한다.
|
||||
if (!InsertLogonAccount(info->pAccountTable->login, peer->GetHandle(), info->ip))
|
||||
{
|
||||
SPDLOG_DEBUG("RESULT_LOGIN: already logon {}", info->pAccountTable->login);
|
||||
|
|
|
@ -31,7 +31,7 @@ bool CreateItemTableFromRes(MYSQL_RES * res, std::vector<TPlayerItem> * pVec, DW
|
|||
|
||||
int rows;
|
||||
|
||||
if ((rows = mysql_num_rows(res)) <= 0) // 데이터 없음
|
||||
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 로 바꾸기 위한 임시 공간
|
||||
// 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;
|
||||
|
||||
//
|
||||
// 한 계정에 속한 모든 캐릭터들 캐쉬처리
|
||||
// 한 계정에 속한 모든 캐릭터들 캐쉬처리
|
||||
//
|
||||
CLoginData * pLoginData = GetLoginDataByAID(packet->account_id);
|
||||
|
||||
|
@ -222,12 +222,12 @@ void CClientManager::QUERY_PLAYER_LOAD(CPeer * peer, DWORD dwHandle, TPlayerLoad
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// 1. 유저정보가 DBCache 에 존재 : DBCache에서
|
||||
// 2. 유저정보가 DBCache 에 없음 : DB에서
|
||||
// 1. 유저정보가 DBCache 에 존재 : DBCache에서
|
||||
// 2. 유저정보가 DBCache 에 없음 : DB에서
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
//----------------------------------
|
||||
// 1. 유저정보가 DBCache 에 존재 : DBCache에서
|
||||
// 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);
|
||||
|
||||
//--------------------------------------------
|
||||
// 아이템 & AFFECT & QUEST 로딩 :
|
||||
// 아이템 & AFFECT & QUEST 로딩 :
|
||||
//--------------------------------------------
|
||||
// 1) 아이템이 DBCache 에 존재 : DBCache 에서 가져옴
|
||||
// 2) 아이템이 DBCache 에 없음 : DB 에서 가져옴
|
||||
// 1) 아이템이 DBCache 에 존재 : DBCache 에서 가져옴
|
||||
// 2) 아이템이 DBCache 에 없음 : DB 에서 가져옴
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// 1) 아이템이 DBCache 에 존재 : DBCache 에서 가져옴
|
||||
// 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이 없으면 삭제된 아이템이다.
|
||||
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) 아이템이 DBCache 에 없음 : DB 에서 가져옴
|
||||
// 2) 아이템이 DBCache 에 없음 : DB 에서 가져옴
|
||||
/////////////////////////////////////////////
|
||||
else
|
||||
{
|
||||
|
@ -348,7 +348,7 @@ void CClientManager::QUERY_PLAYER_LOAD(CPeer * peer, DWORD dwHandle, TPlayerLoad
|
|||
//return;
|
||||
}
|
||||
//----------------------------------
|
||||
// 2. 유저정보가 DBCache 에 없음 : DB에서
|
||||
// 2. 유저정보가 DBCache 에 없음 : DB에서
|
||||
//----------------------------------
|
||||
else
|
||||
{
|
||||
|
@ -357,7 +357,7 @@ void CClientManager::QUERY_PLAYER_LOAD(CPeer * peer, DWORD dwHandle, TPlayerLoad
|
|||
char queryStr[QUERY_MAX_LEN];
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// 캐릭터 정보 얻어오기 : 무조건 DB에서
|
||||
// 캐릭터 정보 얻어오기 : 무조건 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);
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// 아이템 가져오기
|
||||
// 아이템 가져오기
|
||||
//--------------------------------------------------------------
|
||||
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 가져오기
|
||||
// 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));
|
||||
//독일 선물 기능에서 item_award테이블에서 login 정보를 얻기위해 account id도 넘겨준다
|
||||
//독일 선물 기능에서 item_award테이블에서 login 정보를 얻기위해 account id도 넘겨준다
|
||||
//--------------------------------------------------------------
|
||||
// AFFECT 가져오기
|
||||
// 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이 NULL인것들 읽어옴
|
||||
typeof(pSet->begin()) it = pSet->begin(); //taken_time이 NULL인것들 읽어옴
|
||||
while(it != pSet->end() )
|
||||
{
|
||||
TItemAward * pItemAward = *(it++);
|
||||
char* whyStr = pItemAward->szWhy; //why 콜룸 읽기
|
||||
char cmdStr[100] = ""; //why콜룸에서 읽은 값을 임시 문자열에 복사해둠
|
||||
strcpy(cmdStr,whyStr); //명령어 얻는 과정에서 토큰쓰면 원본도 토큰화 되기 때문
|
||||
char* whyStr = pItemAward->szWhy; //why 콜룸 읽기
|
||||
char cmdStr[100] = ""; //why콜룸에서 읽은 값을 임시 문자열에 복사해둠
|
||||
strcpy(cmdStr,whyStr); //명령어 얻는 과정에서 토큰쓰면 원본도 토큰화 되기 때문
|
||||
char command[20] = "";
|
||||
strcpy(command,GetCommand(cmdStr).c_str()); // command 얻기
|
||||
if( !(strcmp(command,"GIFT") )) // command 가 GIFT이면
|
||||
strcpy(command,GetCommand(cmdStr).c_str()); // command 얻기
|
||||
if( !(strcmp(command,"GIFT") )) // command 가 GIFT이면
|
||||
{
|
||||
TPacketItemAwardInfromer giftData;
|
||||
strcpy(giftData.login, pItemAward->szLogin); //로그인 아이디 복사
|
||||
strcpy(giftData.command, command); //명령어 복사
|
||||
giftData.vnum = pItemAward->dwVnum; //아이템 vnum도 복사
|
||||
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) // 데이터 없음
|
||||
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 통솔력
|
||||
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 관통저항
|
||||
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얻기
|
||||
//aid얻기
|
||||
ClientHandleInfo* temp1 = info.get();
|
||||
if (temp1 == NULL)
|
||||
break;
|
||||
|
||||
CLoginData* pLoginData1 = GetLoginDataByAID(temp1->account_id); //
|
||||
//독일 선물 기능
|
||||
//독일 선물 기능
|
||||
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에서 아이템 정보를 읽어온다.
|
||||
//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을 만든다
|
||||
//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); // 로드한 것은 따로 저장할 필요 없으므로, 인자 bSkipQuery에 true를 넣는다.
|
||||
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) // 데이터 없음
|
||||
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;
|
||||
|
||||
// 한 계정에 X초 내로 캐릭터 생성을 할 수 없다.
|
||||
// 한 계정에 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 - 플레이어 삭제시 가격정보 리스트 삭제 추가.
|
||||
// @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;
|
||||
}
|
||||
|
||||
// 삭제 성공
|
||||
// 삭제 성공
|
||||
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);
|
||||
|
||||
// 플레이어 테이블을 캐쉬에서 삭제한다.
|
||||
// 플레이어 테이블을 캐쉬에서 삭제한다.
|
||||
CPlayerTableCache * pkPlayerCache = GetPlayerCache(pi->player_id);
|
||||
|
||||
if (pkPlayerCache)
|
||||
|
@ -1089,7 +1089,7 @@ void CClientManager::__RESULT_PLAYER_DELETE(CPeer *peer, SQLMsg* msg)
|
|||
delete pkPlayerCache;
|
||||
}
|
||||
|
||||
// 아이템들을 캐쉬에서 삭제한다.
|
||||
// 아이템들을 캐쉬에서 삭제한다.
|
||||
TItemCacheSet * pSet = GetItemCacheSet(pi->player_id);
|
||||
|
||||
if (pSet)
|
||||
|
@ -1152,7 +1152,7 @@ void CClientManager::__RESULT_PLAYER_DELETE(CPeer *peer, SQLMsg* msg)
|
|||
}
|
||||
else
|
||||
{
|
||||
// 삭제 실패
|
||||
// 삭제 실패
|
||||
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)
|
||||
{
|
||||
// 새로운 하이스코어를 삽입
|
||||
// 새로운 하이스코어를 삽입
|
||||
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: 이곳에서 하이스코어가 업데이트 되었는지 체크하여 공지를 뿌려야한다.
|
||||
// TODO: 이곳에서 하이스코어가 업데이트 되었는지 체크하여 공지를 뿌려야한다.
|
||||
delete pi;
|
||||
}
|
||||
|
||||
|
@ -1280,10 +1280,10 @@ void CClientManager::InsertLogoutPlayer(DWORD pid)
|
|||
{
|
||||
TLogoutPlayerMap::iterator it = m_map_logout.find(pid);
|
||||
|
||||
// 존재하지 않을경우 추가
|
||||
// 존재하지 않을경우 추가
|
||||
if (it != m_map_logout.end())
|
||||
{
|
||||
// 존재할경우 시간만 갱신
|
||||
// 존재할경우 시간만 갱신
|
||||
SPDLOG_TRACE("LOGOUT: Update player time pid({})", pid);
|
||||
|
||||
it->second->time = time(0);
|
||||
|
|
|
@ -67,7 +67,7 @@ bool CConfig::GetWord(FILE *fp, char *tar)
|
|||
|
||||
if ((c == ' ' || c == '\t' || c == '\n'))
|
||||
{
|
||||
// 텝.
|
||||
// 텝.
|
||||
tar[i] = '\0';
|
||||
return true;
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ bool CConfig::LoadFile(const char* filename)
|
|||
}
|
||||
|
||||
|
||||
// 파일 닫는 부분.
|
||||
// 파일 닫는 부분.
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -11,14 +11,14 @@
|
|||
|
||||
namespace
|
||||
{
|
||||
/// 파싱용 state 열거값
|
||||
/// 파싱용 state 열거값
|
||||
enum ParseState
|
||||
{
|
||||
STATE_NORMAL = 0, ///< 일반 상태
|
||||
STATE_QUOTE ///< 따옴표 뒤의 상태
|
||||
STATE_NORMAL = 0, ///< 일반 상태
|
||||
STATE_QUOTE ///< 따옴표 뒤의 상태
|
||||
};
|
||||
|
||||
/// 문자열 좌우의 공백을 제거해서 반환한다.
|
||||
/// 문자열 좌우의 공백을 제거해서 반환한다.
|
||||
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 주어진 문장에 있는 알파벳을 모두 소문자로 바꾼다.
|
||||
/// \brief 주어진 문장에 있는 알파벳을 모두 소문자로 바꾼다.
|
||||
std::string Lower(std::string original)
|
||||
{
|
||||
std::transform(original.begin(), original.end(), original.begin(), tolower);
|
||||
|
@ -35,9 +35,9 @@ namespace
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \brief 셀을 액세스할 때, 숫자 대신 사용할 이름을 등록한다.
|
||||
/// \param name 셀 이름
|
||||
/// \param index 셀 인덱스
|
||||
/// \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 모든 데이터를 삭제한다.
|
||||
/// \brief 모든 데이터를 삭제한다.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void cCsvAlias::Destroy()
|
||||
{
|
||||
|
@ -60,9 +60,9 @@ void cCsvAlias::Destroy()
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \brief 숫자 인덱스를 이름으로 변환한다.
|
||||
/// \param index 숫자 인덱스
|
||||
/// \return const char* 이름
|
||||
/// \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 이름을 숫자 인덱스로 변환한다.
|
||||
/// \param name 이름
|
||||
/// \return size_t 숫자 인덱스
|
||||
/// \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 지정된 이름의 CSV 파일을 로드한다.
|
||||
/// \param fileName CSV 파일 이름
|
||||
/// \param seperator 필드 분리자로 사용할 글자. 기본값은 ','이다.
|
||||
/// \param quote 따옴표로 사용할 글자. 기본값은 '"'이다.
|
||||
/// \return bool 무사히 로드했다면 true, 아니라면 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(); // 기존의 데이터를 삭제
|
||||
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) + " "; // 파싱 lookahead 때문에 붙여준다.
|
||||
std::string text = std::string(line) + " "; // 파싱 lookahead 때문에 붙여준다.
|
||||
size_t cur = 0;
|
||||
|
||||
while (cur < text.size())
|
||||
{
|
||||
// 현재 모드가 QUOTE 모드일 때,
|
||||
// 현재 모드가 QUOTE 모드일 때,
|
||||
if (state == STATE_QUOTE)
|
||||
{
|
||||
// '"' 문자의 종류는 두 가지이다.
|
||||
// 1. 셀 내부에 특수 문자가 있을 경우 이를 알리는 셀 좌우의 것
|
||||
// 2. 셀 내부의 '"' 문자가 '"' 2개로 치환된 것
|
||||
// 이 중 첫번째 경우의 좌측에 있는 것은 CSV 파일이 정상적이라면,
|
||||
// 무조건 STATE_NORMAL에 걸리게 되어있다.
|
||||
// 그러므로 여기서 걸리는 것은 1번의 우측 경우나, 2번 경우 뿐이다.
|
||||
// 2번의 경우에는 무조건 '"' 문자가 2개씩 나타난다. 하지만 1번의
|
||||
// 우측 경우에는 아니다. 이를 바탕으로 해서 코드를 짜면...
|
||||
// '"' 문자의 종류는 두 가지이다.
|
||||
// 1. 셀 내부에 특수 문자가 있을 경우 이를 알리는 셀 좌우의 것
|
||||
// 2. 셀 내부의 '"' 문자가 '"' 2개로 치환된 것
|
||||
// 이 중 첫번째 경우의 좌측에 있는 것은 CSV 파일이 정상적이라면,
|
||||
// 무조건 STATE_NORMAL에 걸리게 되어있다.
|
||||
// 그러므로 여기서 걸리는 것은 1번의 우측 경우나, 2번 경우 뿐이다.
|
||||
// 2번의 경우에는 무조건 '"' 문자가 2개씩 나타난다. 하지만 1번의
|
||||
// 우측 경우에는 아니다. 이를 바탕으로 해서 코드를 짜면...
|
||||
if (text[cur] == quote)
|
||||
{
|
||||
// 다음 문자가 '"' 문자라면, 즉 연속된 '"' 문자라면
|
||||
// 이는 셀 내부의 '"' 문자가 치환된 것이다.
|
||||
// 다음 문자가 '"' 문자라면, 즉 연속된 '"' 문자라면
|
||||
// 이는 셀 내부의 '"' 문자가 치환된 것이다.
|
||||
if (text[cur+1] == quote)
|
||||
{
|
||||
token += quote;
|
||||
++cur;
|
||||
}
|
||||
// 다음 문자가 '"' 문자가 아니라면
|
||||
// 현재의 '"'문자는 셀의 끝을 알리는 문자라고 할 수 있다.
|
||||
// 다음 문자가 '"' 문자가 아니라면
|
||||
// 현재의 '"'문자는 셀의 끝을 알리는 문자라고 할 수 있다.
|
||||
else
|
||||
{
|
||||
state = STATE_NORMAL;
|
||||
|
@ -161,25 +161,25 @@ bool cCsvFile::Load(const char* fileName, const char seperator, const char quote
|
|||
token += text[cur];
|
||||
}
|
||||
}
|
||||
// 현재 모드가 NORMAL 모드일 때,
|
||||
// 현재 모드가 NORMAL 모드일 때,
|
||||
else if (state == STATE_NORMAL)
|
||||
{
|
||||
if (row == NULL)
|
||||
row = new cCsvRow();
|
||||
|
||||
// ',' 문자를 만났다면 셀의 끝의 의미한다.
|
||||
// 토큰으로서 셀 리스트에다가 집어넣고, 토큰을 초기화한다.
|
||||
// ',' 문자를 만났다면 셀의 끝의 의미한다.
|
||||
// 토큰으로서 셀 리스트에다가 집어넣고, 토큰을 초기화한다.
|
||||
if (text[cur] == seperator)
|
||||
{
|
||||
row->push_back(token);
|
||||
token.clear();
|
||||
}
|
||||
// '"' 문자를 만났다면, QUOTE 모드로 전환한다.
|
||||
// '"' 문자를 만났다면, QUOTE 모드로 전환한다.
|
||||
else if (text[cur] == quote)
|
||||
{
|
||||
state = STATE_QUOTE;
|
||||
}
|
||||
// 다른 일반 문자라면 현재 토큰에다가 덧붙인다.
|
||||
// 다른 일반 문자라면 현재 토큰에다가 덧붙인다.
|
||||
else
|
||||
{
|
||||
token += text[cur];
|
||||
|
@ -189,8 +189,8 @@ bool cCsvFile::Load(const char* fileName, const char seperator, const char quote
|
|||
++cur;
|
||||
}
|
||||
|
||||
// 마지막 셀은 끝에 ',' 문자가 없기 때문에 여기서 추가해줘야한다.
|
||||
// 단, 처음에 파싱 lookahead 때문에 붙인 스페이스 문자 두 개를 뗀다.
|
||||
// 마지막 셀은 끝에 ',' 문자가 없기 때문에 여기서 추가해줘야한다.
|
||||
// 단, 처음에 파싱 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 가지고 있는 내용을 CSV 파일에다 저장한다.
|
||||
/// \param fileName CSV 파일 이름
|
||||
/// \param append true일 경우, 기존의 파일에다 덧붙인다. false인 경우에는
|
||||
/// 기존의 파일 내용을 삭제하고, 새로 쓴다.
|
||||
/// \param seperator 필드 분리자로 사용할 글자. 기본값은 ','이다.
|
||||
/// \param quote 따옴표로 사용할 글자. 기본값은 '"'이다.
|
||||
/// \return bool 무사히 저장했다면 true, 에러가 생긴 경우에는 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);
|
||||
|
||||
// 출력 모드에 따라 파일을 적당한 플래그로 생성한다.
|
||||
// 출력 모드에 따라 파일을 적당한 플래그로 생성한다.
|
||||
std::ofstream file;
|
||||
if (append) { file.open(fileName, std::ios::out | std::ios::app); }
|
||||
else { file.open(fileName, std::ios::out | std::ios::trunc); }
|
||||
|
||||
// 파일을 열지 못했다면, false를 리턴한다.
|
||||
// 파일을 열지 못했다면, false를 리턴한다.
|
||||
if (!file) return false;
|
||||
|
||||
char special_chars[5] = { seperator, quote, '\r', '\n', 0 };
|
||||
char quote_escape_string[3] = { quote, quote, 0 };
|
||||
|
||||
// 모든 행을 횡단하면서...
|
||||
// 모든 행을 횡단하면서...
|
||||
for (size_t i=0; i<m_Rows.size(); i++)
|
||||
{
|
||||
const cCsvRow& row = *((*this)[i]);
|
||||
|
||||
std::string line;
|
||||
|
||||
// 행 안의 모든 토큰을 횡단하면서...
|
||||
// 행 안의 모든 토큰을 횡단하면서...
|
||||
for (size_t j=0; j<row.size(); j++)
|
||||
{
|
||||
const std::string& token = row[j];
|
||||
|
||||
// 일반적인('"' 또는 ','를 포함하지 않은)
|
||||
// 토큰이라면 그냥 저장하면 된다.
|
||||
// 일반적인('"' 또는 ','를 포함하지 않은)
|
||||
// 토큰이라면 그냥 저장하면 된다.
|
||||
if (token.find_first_of(special_chars) == std::string::npos)
|
||||
{
|
||||
line += token;
|
||||
}
|
||||
// 특수문자를 포함한 토큰이라면 문자열 좌우에 '"'를 붙여주고,
|
||||
// 문자열 내부의 '"'를 두 개로 만들어줘야한다.
|
||||
// 특수문자를 포함한 토큰이라면 문자열 좌우에 '"'를 붙여주고,
|
||||
// 문자열 내부의 '"'를 두 개로 만들어줘야한다.
|
||||
else
|
||||
{
|
||||
line += quote;
|
||||
|
@ -265,11 +265,11 @@ bool cCsvFile::Save(const char* fileName, bool append, char seperator, char quot
|
|||
line += quote;
|
||||
}
|
||||
|
||||
// 마지막 셀이 아니라면 ','를 토큰의 뒤에다 붙여줘야한다.
|
||||
// 마지막 셀이 아니라면 ','를 토큰의 뒤에다 붙여줘야한다.
|
||||
if (j != row.size() - 1) { line += seperator; }
|
||||
}
|
||||
|
||||
// 라인을 출력한다.
|
||||
// 라인을 출력한다.
|
||||
file << line << std::endl;
|
||||
}
|
||||
|
||||
|
@ -277,7 +277,7 @@ bool cCsvFile::Save(const char* fileName, bool append, char seperator, char quot
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \brief 모든 데이터를 메모리에서 삭제한다.
|
||||
/// \brief 모든 데이터를 메모리에서 삭제한다.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void cCsvFile::Destroy()
|
||||
{
|
||||
|
@ -288,9 +288,9 @@ void cCsvFile::Destroy()
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \brief 해당하는 인덱스의 행을 반환한다.
|
||||
/// \param index 인덱스
|
||||
/// \return cCsvRow* 해당 행
|
||||
/// \brief 해당하는 인덱스의 행을 반환한다.
|
||||
/// \param index 인덱스
|
||||
/// \return cCsvRow* 해당 행
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
cCsvRow* cCsvFile::operator [] (size_t index)
|
||||
{
|
||||
|
@ -299,9 +299,9 @@ cCsvRow* cCsvFile::operator [] (size_t index)
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \brief 해당하는 인덱스의 행을 반환한다.
|
||||
/// \param index 인덱스
|
||||
/// \return const cCsvRow* 해당 행
|
||||
/// \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 생성자
|
||||
/// \brief 생성자
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
cCsvTable::cCsvTable()
|
||||
: m_CurRow(-1)
|
||||
|
@ -318,18 +318,18 @@ cCsvTable::cCsvTable()
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \brief 소멸자
|
||||
/// \brief 소멸자
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
cCsvTable::~cCsvTable()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \brief 지정된 이름의 CSV 파일을 로드한다.
|
||||
/// \param fileName CSV 파일 이름
|
||||
/// \param seperator 필드 분리자로 사용할 글자. 기본값은 ','이다.
|
||||
/// \param quote 따옴표로 사용할 글자. 기본값은 '"'이다.
|
||||
/// \return bool 무사히 로드했다면 true, 아니라면 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 다음 행으로 넘어간다.
|
||||
/// \return bool 다음 행으로 무사히 넘어간 경우 true를 반환하고, 더 이상
|
||||
/// 넘어갈 행이 존재하지 않는 경우에는 false를 반환한다.
|
||||
/// \brief 다음 행으로 넘어간다.
|
||||
/// \return bool 다음 행으로 무사히 넘어간 경우 true를 반환하고, 더 이상
|
||||
/// 넘어갈 행이 존재하지 않는 경우에는 false를 반환한다.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool cCsvTable::Next()
|
||||
{
|
||||
// 20억번 정도 호출하면 오버플로가 일어날텐데...괜찮겠지?
|
||||
// 20억번 정도 호출하면 오버플로가 일어날텐데...괜찮겠지?
|
||||
return ++m_CurRow < (int)m_File.GetRowCount() ? true : false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \brief 현재 행의 셀 숫자를 반환한다.
|
||||
/// \return size_t 현재 행의 셀 숫자
|
||||
/// \brief 현재 행의 셀 숫자를 반환한다.
|
||||
/// \return size_t 현재 행의 셀 숫자
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
size_t cCsvTable::ColCount() const
|
||||
{
|
||||
|
@ -358,9 +358,9 @@ size_t cCsvTable::ColCount() const
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \brief 인덱스를 이용해 int 형으로 셀 값을 반환한다.
|
||||
/// \param index 셀 인덱스
|
||||
/// \return int 셀 값
|
||||
/// \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 인덱스를 이용해 double 형으로 셀 값을 반환한다.
|
||||
/// \param index 셀 인덱스
|
||||
/// \return double 셀 값
|
||||
/// \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 인덱스를 이용해 std::string 형으로 셀 값을 반환한다.
|
||||
/// \param index 셀 인덱스
|
||||
/// \return const char* 셀 값
|
||||
/// \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를 포함해 모든 데이터를 삭제한다.
|
||||
/// \brief alias를 포함해 모든 데이터를 삭제한다.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void cCsvTable::Destroy()
|
||||
{
|
||||
|
@ -407,10 +407,10 @@ void cCsvTable::Destroy()
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \brief 현재 행을 반환한다.
|
||||
/// \return const cCsvRow* 액세스가 가능한 현재 행이 존재하는 경우에는 그 행의
|
||||
/// 포인터를 반환하고, 더 이상 액세스 가능한 행이 없는 경우에는 NULL을
|
||||
/// 반환한다.
|
||||
/// \brief 현재 행을 반환한다.
|
||||
/// \return const cCsvRow* 액세스가 가능한 현재 행이 존재하는 경우에는 그 행의
|
||||
/// 포인터를 반환하고, 더 이상 액세스 가능한 행이 없는 경우에는 NULL을
|
||||
/// 반환한다.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
const cCsvRow* const cCsvTable::CurRow() const
|
||||
{
|
||||
|
|
|
@ -242,7 +242,7 @@ void CGuildManager::ResultRanking(MYSQL_RES * pRes)
|
|||
|
||||
void CGuildManager::Update()
|
||||
{
|
||||
ProcessReserveWar(); // 예약 전쟁 처리
|
||||
ProcessReserveWar(); // 예약 전쟁 처리
|
||||
|
||||
time_t now = CClientManager::instance().GetCurrentTime();
|
||||
|
||||
|
@ -462,7 +462,7 @@ void CGuildManager::RemoveWar(DWORD GID1, DWORD GID2)
|
|||
}
|
||||
|
||||
//
|
||||
// 길드전 비정상 종료 및 필드전 종료
|
||||
// 길드전 비정상 종료 및 필드전 종료
|
||||
//
|
||||
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) // 강제 무승부가 아닐 경우에는 점수를 체크한다.
|
||||
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 // 강제 무승부일 경우에는 무조건 무승부
|
||||
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 서버에서 자체적으로 끝낼 때도 있기 때문에 따로 패킷을 보내줘야 한다.
|
||||
// DB 서버에서 자체적으로 끝낼 때도 있기 때문에 따로 패킷을 보내줘야 한다.
|
||||
CClientManager::instance().for_each_peer(FSendPeerWar(0, GUILD_WAR_END, GID1, GID2));
|
||||
|
||||
RemoveWar(GID1, GID2);
|
||||
}
|
||||
|
||||
//
|
||||
// 길드전 정상 종료
|
||||
// 길드전 정상 종료
|
||||
//
|
||||
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); // 무조건 비정상 종료 시켜야 한다.
|
||||
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 보내기
|
||||
// Packet 보내기
|
||||
TPacketGuildLadder p;
|
||||
|
||||
p.dwGuild = GID;
|
||||
|
@ -808,7 +808,7 @@ void CGuildManager::WithdrawMoney(CPeer* peer, DWORD dwGuild, INT iGold)
|
|||
return;
|
||||
}
|
||||
|
||||
// 돈이있으니 출금하고 올려준다
|
||||
// 돈이있으니 출금하고 올려준다
|
||||
if (it->second.gold >= iGold)
|
||||
{
|
||||
it->second.gold -= iGold;
|
||||
|
@ -839,7 +839,7 @@ void CGuildManager::WithdrawMoneyReply(DWORD dwGuild, BYTE bGiveSuccess, INT iGo
|
|||
}
|
||||
|
||||
//
|
||||
// 예약 길드전(관전자가 배팅할 수 있다)
|
||||
// 예약 길드전(관전자가 배팅할 수 있다)
|
||||
//
|
||||
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위
|
||||
55000, // 1위
|
||||
50000,
|
||||
45000,
|
||||
40000,
|
||||
|
@ -878,7 +878,7 @@ const int c_aiScoreByRanking[GUILD_RANK_MAX_NUM+1] =
|
|||
28000,
|
||||
24000,
|
||||
21000,
|
||||
18000, // 10위
|
||||
18000, // 10위
|
||||
15000,
|
||||
12000,
|
||||
10000,
|
||||
|
@ -888,7 +888,7 @@ const int c_aiScoreByRanking[GUILD_RANK_MAX_NUM+1] =
|
|||
3000,
|
||||
2000,
|
||||
1000,
|
||||
500 // 20위
|
||||
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 이면 길드전 도중 DB가 튕긴 것이므로 무승부 처리한다.
|
||||
// 또는, 5분 이하 남은 예약 길드전도 무승부 처리한다. (각자의 배팅액을 돌려준다)
|
||||
// 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;
|
||||
|
||||
// 파워 계산
|
||||
// 파워 계산
|
||||
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);
|
||||
|
||||
// 파워 계산
|
||||
// 파워 계산
|
||||
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);
|
||||
|
||||
// 핸디캡 계산
|
||||
// 핸디캡 계산
|
||||
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);
|
||||
|
||||
// 쿼리
|
||||
// 쿼리
|
||||
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분 전부터 알린다.
|
||||
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 길드와 %s 길드의 전쟁이 약 %d분 후 시작 됩니다!", 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 곤삔뵨 %s 곤삔돨곤삔濫轢쉥瞳 %d롸爐빈역迦!", 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) // 이미 시작된 것은 보내지 않는다.
|
||||
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)
|
|||
}
|
||||
|
||||
//
|
||||
// 무승부 처리: 대부분 승부가 나야 정상이지만, 서버 문제 등 특정 상황일 경우에는
|
||||
// 무승부 처리가 있어야 한다.
|
||||
// 무승부 처리: 대부분 승부가 나야 정상이지만, 서버 문제 등 특정 상황일 경우에는
|
||||
// 무승부 처리가 있어야 한다.
|
||||
//
|
||||
void CGuildWarReserve::Draw()
|
||||
{
|
||||
|
@ -1458,7 +1460,7 @@ void CGuildWarReserve::End(int iScoreFrom, int iScoreTo)
|
|||
|
||||
double ratio = (double) it->second.second / dwWinnerBet;
|
||||
|
||||
// 10% 세금 공제 후 분배
|
||||
// 10% 세금 공제 후 분배
|
||||
SPDLOG_DEBUG("WAR_REWARD: {} {} ratio {}", it->first.c_str(), it->second.second, ratio);
|
||||
|
||||
DWORD dwGold = (DWORD) (dwTotalBet * ratio * 0.9);
|
||||
|
|
|
@ -30,7 +30,7 @@ bool PlayerHB::Initialize()
|
|||
}
|
||||
|
||||
//
|
||||
// @version 05/07/05 Bang2ni - id 에 해당하는 data 가 없을 때 쿼리하고 data 를 insert 하는코드 추가.
|
||||
// @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 버퍼가 작아서 늘려줌.
|
||||
// @version 05/07/05 Bang2ni - Query string 버퍼가 작아서 늘려줌.
|
||||
//
|
||||
bool PlayerHB::Query(DWORD id)
|
||||
{
|
||||
|
|
|
@ -54,19 +54,19 @@ void ItemAwardManager::Load(SQLMsg * pMsg)
|
|||
if (row[col])
|
||||
{
|
||||
strlcpy(kData->szWhy, row[col], sizeof(kData->szWhy));
|
||||
//게임 중에 why콜룸에 변동이 생기면
|
||||
char* whyStr = kData->szWhy; //why 콜룸 읽기
|
||||
char cmdStr[100] = ""; //why콜룸에서 읽은 값을 임시 문자열에 복사해둠
|
||||
strcpy(cmdStr,whyStr); //명령어 얻는 과정에서 토큰쓰면 원본도 토큰화 되기 때문
|
||||
//게임 중에 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 얻기
|
||||
strcpy(command,CClientManager::instance().GetCommand(cmdStr).c_str()); // command 얻기
|
||||
//SPDLOG_ERROR("{}, {}",pItemAward->dwID,command);
|
||||
if( !(strcmp(command,"GIFT") )) // command 가 GIFT이면
|
||||
if( !(strcmp(command,"GIFT") )) // command 가 GIFT이면
|
||||
{
|
||||
TPacketItemAwardInfromer giftData;
|
||||
strcpy(giftData.login, kData->szLogin); //로그인 아이디 복사
|
||||
strcpy(giftData.command, command); //명령어 복사
|
||||
giftData.vnum = kData->dwVnum; //아이템 vnum도 복사
|
||||
strcpy(giftData.login, kData->szLogin); //로그인 아이디 복사
|
||||
strcpy(giftData.command, command); //명령어 복사
|
||||
giftData.vnum = kData->dwVnum; //아이템 vnum도 복사
|
||||
CClientManager::instance().ForwardPacket(HEADER_DG_ITEMAWARD_INFORMER,&giftData,sizeof(TPacketItemAwardInfromer));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,11 +31,11 @@ std::string g_stPlayerDBName = "";
|
|||
bool g_bHotBackup = false;
|
||||
BOOL g_test_server = false;
|
||||
|
||||
//단위 초
|
||||
//단위 초
|
||||
int g_iPlayerCacheFlushSeconds = 60*7;
|
||||
int g_iItemCacheFlushSeconds = 60*5;
|
||||
|
||||
//g_iLogoutSeconds 수치는 g_iPlayerCacheFlushSeconds 와 g_iItemCacheFlushSeconds 보다 길어야 한다.
|
||||
//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초에 한번
|
||||
if (!(pulse % heart->passes_per_sec)) // 1초에 한번
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// @version 05/06/13 Bang2ni - 아이템 가격정보 캐시 flush timeout 설정 추가.
|
||||
// @version 05/06/13 Bang2ni - 아이템 가격정보 캐시 flush timeout 설정 추가.
|
||||
//
|
||||
int Start()
|
||||
{
|
||||
|
|
|
@ -253,7 +253,7 @@ namespace marriage
|
|||
|
||||
void CManager::OnSetup(CPeer* peer)
|
||||
{
|
||||
// 결혼한 사람들 보내기
|
||||
// 결혼한 사람들 보내기
|
||||
for (itertype(m_Marriages) it = m_Marriages.begin(); it != m_Marriages.end(); ++it)
|
||||
{
|
||||
TMarriage* pMarriage = *it;
|
||||
|
@ -280,7 +280,7 @@ namespace marriage
|
|||
}
|
||||
}
|
||||
|
||||
// 결혼식 보내기
|
||||
// 결혼식 보내기
|
||||
for (itertype(m_mapRunningWedding) it = m_mapRunningWedding.begin(); it != m_mapRunningWedding.end(); ++it)
|
||||
{
|
||||
const TWedding& t = it->second;
|
||||
|
|
|
@ -233,7 +233,7 @@ bool CMonarch::SetMonarch(const char * name)
|
|||
}
|
||||
delete pMsg;
|
||||
|
||||
//db에 입력
|
||||
//db에 입력
|
||||
snprintf(szQuery, sizeof(szQuery),
|
||||
"REPLACE INTO monarch (empire, name, windate, money) VALUES(%d, %d, now(), %ld)", Empire, p->pid[Empire], p->money[Empire]);
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ CPrivManager::~CPrivManager()
|
|||
}
|
||||
|
||||
//
|
||||
// @version 05/06/07 Bang2ni - 중복적으로 보너스가 적용 된 길드에 대한 처리
|
||||
// @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
|
||||
// 길드에 중복적으로 보너스가 설정되었을 경우 map 의 value 가 갱신(수정) 되었으므로
|
||||
// TPrivGuildData 의 포인터가 같을때 실제로 삭제해 주고 게임서버들에게 cast 해 준다.
|
||||
// 길드에 중복적으로 보너스가 설정되었을 경우 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 - 이미 보너스가 적용 된 길드에 보너스 설정
|
||||
// @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
|
||||
// 이미 보너스가 설정되 있다면 map 의 value 를 갱신해 준다.
|
||||
// 이전 value 의 포인터는 priority queue 에서 삭제될 때 해제된다.
|
||||
// 이미 보너스가 설정되 있다면 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;
|
||||
|
||||
// 이전 설정값 무효화
|
||||
// priority_queue에 들어있는 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 - 지속시간 추가
|
||||
* @version 05/06/08 Bang2ni - 지속시간 추가
|
||||
*/
|
||||
struct FSendChangeGuildPriv
|
||||
{
|
||||
|
|
|
@ -25,23 +25,23 @@ string trim(const string& str){return trim_left(trim_right(str));}
|
|||
|
||||
static string* StringSplit(string strOrigin, string strTok)
|
||||
{
|
||||
int cutAt; //자르는위치
|
||||
int index = 0; //문자열인덱스
|
||||
string* strResult = new string[30]; //결과return 할변수
|
||||
int cutAt; //자르는위치
|
||||
int index = 0; //문자열인덱스
|
||||
string* strResult = new string[30]; //결과return 할변수
|
||||
|
||||
//strTok을찾을때까지반복
|
||||
//strTok을찾을때까지반복
|
||||
while ((cutAt = strOrigin.find_first_of(strTok)) != strOrigin.npos)
|
||||
{
|
||||
if (cutAt > 0) //자르는위치가0보다크면(성공시)
|
||||
if (cutAt > 0) //자르는위치가0보다크면(성공시)
|
||||
{
|
||||
strResult[index++] = strOrigin.substr(0, cutAt); //결과배열에추가
|
||||
strResult[index++] = strOrigin.substr(0, cutAt); //결과배열에추가
|
||||
}
|
||||
strOrigin = strOrigin.substr(cutAt+1); //원본은자른부분제외한나머지
|
||||
strOrigin = strOrigin.substr(cutAt+1); //원본은자른부분제외한나머지
|
||||
}
|
||||
|
||||
if(strOrigin.length() > 0) //원본이아직남았으면
|
||||
if(strOrigin.length() > 0) //원본이아직남았으면
|
||||
{
|
||||
strResult[index++] = strOrigin.substr(0, cutAt); //나머지를결과배열에추가
|
||||
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; //결과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개
|
||||
"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개
|
||||
"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개
|
||||
"ITEM_COSTUME", "ITEM_DS", //30개
|
||||
|
||||
"ITEM_SPECIAL_DS", "ITEM_EXTRACT",
|
||||
"ITEM_SECONDARY_COIN", //33개
|
||||
"ITEM_SECONDARY_COIN", //33개
|
||||
|
||||
"ITEM_RING",
|
||||
"ITEM_BELT", //35개 (EItemTypes 값으로 치면 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 반지
|
||||
0, //34 벨트
|
||||
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 반지
|
||||
0, // 34 벨트
|
||||
0, // 33 반지
|
||||
0, // 34 벨트
|
||||
};
|
||||
|
||||
|
||||
assert(_countof(arSubType) > type_value && "Subtype rule: Out of range!!");
|
||||
|
||||
// assert 안 먹히는 듯..
|
||||
// assert 안 먹히는 듯..
|
||||
if (_countof(arSubType) <= type_value)
|
||||
{
|
||||
SPDLOG_ERROR("SubType : Out of range!! (type_value: {}, count of registered subtype: {}", type_value, _countof(arSubType));
|
||||
return -1;
|
||||
}
|
||||
|
||||
//아이템 타입의 서브타입 어레이가 존재하는지 알아보고, 없으면 0 리턴
|
||||
//아이템 타입의 서브타입 어레이가 존재하는지 알아보고, 없으면 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, "|"); //프로토 정보 내용을 단어별로 쪼갠 배열.
|
||||
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++) //최대 30개 단어까지. (하드코딩)
|
||||
for (int j=0; j<30 ; j++) //최대 30개 단어까지. (하드코딩)
|
||||
{
|
||||
string tempString2 = arInputString[j];
|
||||
if (tempString2.compare(tempString)==0) { //일치하는지 확인.
|
||||
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, "|"); //프로토 정보 내용을 단어별로 쪼갠 배열.
|
||||
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++) //최대 30개 단어까지. (하드코딩)
|
||||
for (int j=0; j<30 ; j++) //최대 30개 단어까지. (하드코딩)
|
||||
{
|
||||
string tempString2 = arInputString[j];
|
||||
if (tempString2.compare(tempString)==0) { //일치하는지 확인.
|
||||
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, "|"); //프로토 정보 내용을 단어별로 쪼갠 배열.
|
||||
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++) //최대 30개 단어까지. (하드코딩)
|
||||
for (int j=0; j<30 ; j++) //최대 30개 단어까지. (하드코딩)
|
||||
{
|
||||
string tempString2 = arInputString[j];
|
||||
if (tempString2.compare(tempString)==0) { //일치하는지 확인.
|
||||
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, "|"); //프로토 정보 내용을 단어별로 쪼갠 배열.
|
||||
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++) //최대 30개 단어까지. (하드코딩)
|
||||
for (int j=0; j<30 ; j++) //최대 30개 단어까지. (하드코딩)
|
||||
{
|
||||
string tempString2 = arInputString[j];
|
||||
if (tempString2.compare(tempString)==0) { //일치하는지 확인.
|
||||
if (tempString2.compare(tempString)==0) { //일치하는지 확인.
|
||||
retValue = retValue + pow((float)2,(float)i);
|
||||
}
|
||||
|
||||
|
@ -414,7 +414,7 @@ int get_Item_ApplyType_Value(string inputString)
|
|||
}
|
||||
|
||||
|
||||
//몬스터 프로토도 읽는다.
|
||||
//몬스터 프로토도 읽는다.
|
||||
|
||||
|
||||
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, ","); //프로토 정보 내용을 단어별로 쪼갠 배열.
|
||||
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++) //최대 30개 단어까지. (하드코딩)
|
||||
for (int j=0; j<30 ; j++) //최대 30개 단어까지. (하드코딩)
|
||||
{
|
||||
string tempString2 = arInputString[j];
|
||||
if (tempString2.compare(tempString)==0) { //일치하는지 확인.
|
||||
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, ","); //프로토 정보 내용을 단어별로 쪼갠 배열.
|
||||
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++) //최대 30개 단어까지. (하드코딩)
|
||||
for (int j=0; j<30 ; j++) //최대 30개 단어까지. (하드코딩)
|
||||
{
|
||||
string tempString2 = arInputString[j];
|
||||
if (tempString2.compare(tempString)==0) { //일치하는지 확인.
|
||||
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, ","); //프로토 정보 내용을 단어별로 쪼갠 배열.
|
||||
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++) //최대 30개 단어까지. (하드코딩)
|
||||
for (int j=0; j<30 ; j++) //최대 30개 단어까지. (하드코딩)
|
||||
{
|
||||
string tempString2 = arInputString[j];
|
||||
if (tempString2.compare(tempString)==0) { //일치하는지 확인.
|
||||
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__
|
||||
|
||||
//몹 테이블을 셋팅해준다.
|
||||
//몹 테이블을 셋팅해준다.
|
||||
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. 지역별 이름 넣어주기.
|
||||
//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 및 vnum range 읽기.
|
||||
// vnum 및 vnum range 읽기.
|
||||
{
|
||||
std::string s(csvTable.AsStringByIndex(0));
|
||||
int pos = s.find("~");
|
||||
// vnum 필드에 '~'가 없다면 패스
|
||||
// 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));
|
||||
//지역별 이름 넣어주기.
|
||||
//지역별 이름 넣어주기.
|
||||
map<int,const char*>::iterator it;
|
||||
it = nameMap.find(itemTable->dwVnum);
|
||||
if (it != nameMap.end()) {
|
||||
|
|
|
@ -28,7 +28,7 @@ void CGrid::Clear()
|
|||
|
||||
int CGrid::FindBlank(int w, int h)
|
||||
{
|
||||
// 크기가 더 크다면 확인할 필요 없이 그냥 리턴
|
||||
// 크기가 더 크다면 확인할 필요 없이 그냥 리턴
|
||||
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 안쪽인가를 먼저 검사
|
||||
// Grid 안쪽인가를 먼저 검사
|
||||
if (iRow + h > m_iHeight)
|
||||
return false;
|
||||
|
||||
|
|
Loading…
Reference in New Issue