fix: __INTELLISENSE__ version import (VSC).

change: Format all /db files, db/Main, db/DBManager, db/Monarch.
add: PgConnectionPool, PgAsyncQuery.
This commit is contained in:
WildEgo 2025-06-07 20:38:53 +01:00
parent 4bc4a79a4b
commit 93d8f2a0be
52 changed files with 4633 additions and 4324 deletions

72
.vscode/settings.json vendored
View File

@ -13,10 +13,78 @@
"xstring": "cpp",
"xtree": "cpp",
"xutility": "cpp",
"sstream": "cpp"
"sstream": "cpp",
"fstream": "cpp",
"atomic": "cpp",
"hash_map": "cpp",
"bit": "cpp",
"bitset": "cpp",
"cctype": "cpp",
"charconv": "cpp",
"chrono": "cpp",
"cinttypes": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"codecvt": "cpp",
"compare": "cpp",
"complex": "cpp",
"concepts": "cpp",
"condition_variable": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"map": "cpp",
"set": "cpp",
"string": "cpp",
"unordered_map": "cpp",
"unordered_set": "cpp",
"exception": "cpp",
"expected": "cpp",
"algorithm": "cpp",
"functional": "cpp",
"iterator": "cpp",
"memory": "cpp",
"memory_resource": "cpp",
"numeric": "cpp",
"optional": "cpp",
"random": "cpp",
"ratio": "cpp",
"source_location": "cpp",
"string_view": "cpp",
"system_error": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"format": "cpp",
"future": "cpp",
"iomanip": "cpp",
"iosfwd": "cpp",
"iostream": "cpp",
"istream": "cpp",
"limits": "cpp",
"mutex": "cpp",
"new": "cpp",
"numbers": "cpp",
"ostream": "cpp",
"ranges": "cpp",
"semaphore": "cpp",
"shared_mutex": "cpp",
"span": "cpp",
"stdexcept": "cpp",
"stop_token": "cpp",
"streambuf": "cpp",
"thread": "cpp",
"typeinfo": "cpp",
"variant": "cpp"
},
"editor.formatOnSave": false,
// "editor.formatOnSave": false,
"vcpkg.target.useManifest": false,
"C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools",
"cmake.configureArgs": [
"-DVCPKG_MANIFEST_MODE=OFF",
"-DVCPKG_APPLOCAL_DEPS=ON",

View File

@ -1,5 +1,7 @@
# The list
- [ ] Database initialization
- [x] Main (Most important duh)
- [ ] ClientManager
- [ ] ClientManagerBoot
- [ ] ClientManagerEventFlag
@ -7,9 +9,9 @@
- [ ] ClientManagerHorseName
- [ ] ClientManagerLogin
- [ ] ClientManagerPlayer
- [ ] DBManager
- [x] DBManager
- [ ] GuildManager
- [ ] ItemAwardManager
- [ ] ItemIDRangeManager
- [ ] Marriage
- [ ] Monarch
- [x] Monarch

View File

@ -38,8 +38,8 @@ void CItemCache::Delete()
if (m_data.vnum == 0)
return;
//char szQuery[QUERY_MAX_LEN];
//szQuery[QUERY_MAX_LEN] = '\0';
// char szQuery[QUERY_MAX_LEN];
// szQuery[QUERY_MAX_LEN] = '\0';
SPDLOG_TRACE("ItemCache::Delete : DELETE {}", m_data.id);
m_data.vnum = 0;
@ -47,8 +47,8 @@ void CItemCache::Delete()
m_lastUpdateTime = time(0);
OnFlush();
//m_bNeedQuery = false;
//m_lastUpdateTime = time(0) - m_expireTime; // 바로 타임아웃 되도록 하자.
// m_bNeedQuery = false;
// m_lastUpdateTime = time(0) - m_expireTime; // 바로 타임아웃 되도록 하자.
}
void CItemCache::OnFlush()
@ -70,7 +70,7 @@ void CItemCache::OnFlush()
memset(&alSockets, 0, sizeof(int) * ITEM_SOCKET_MAX_NUM);
memset(&aAttr, 0, sizeof(TPlayerItemAttribute) * ITEM_ATTRIBUTE_MAX_NUM);
TPlayerItem * p = &m_data;
TPlayerItem *p = &m_data;
if (memcmp(alSockets, p->alSockets, sizeof(int) * ITEM_SOCKET_MAX_NUM))
isSocket = true;
@ -139,7 +139,7 @@ void CItemCache::OnFlush()
CDBManager::instance().ReturnQuery(szItemQuery, QID_ITEM_SAVE, 0, NULL);
//g_item_info.Add(p->vnum);
// g_item_info.Add(p->vnum);
++g_item_count;
}
@ -179,7 +179,7 @@ CItemPriceListTableCache::CItemPriceListTableCache()
m_expireTime = std::min(s_nMinFlushSec, g_iItemPriceListTableCacheFlushSeconds);
}
void CItemPriceListTableCache::UpdateList(const TItemPriceListTable* pUpdateList)
void CItemPriceListTableCache::UpdateList(const TItemPriceListTable *pUpdateList)
{
//
// 이미 캐싱된 아이템과 중복된 아이템을 찾고 중복되지 않는 이전 정보는 tmpvec 에 넣는다.
@ -189,7 +189,7 @@ void CItemPriceListTableCache::UpdateList(const TItemPriceListTable* pUpdateList
for (uint idx = 0; idx < m_data.byCount; ++idx)
{
const TItemPriceInfo* pos = pUpdateList->aPriceInfo;
const TItemPriceInfo *pos = pUpdateList->aPriceInfo;
for (; pos != pUpdateList->aPriceInfo + pUpdateList->byCount && m_data.aPriceInfo[idx].dwVnum != pos->dwVnum; ++pos)
;

View File

@ -6,7 +6,7 @@
class CItemCache : public cache<TPlayerItem>
{
public:
public:
CItemCache();
virtual ~CItemCache();
@ -16,7 +16,7 @@ class CItemCache : public cache<TPlayerItem>
class CPlayerTableCache : public cache<TPlayerTable>
{
public:
public:
CPlayerTableCache();
virtual ~CPlayerTableCache();
@ -31,10 +31,9 @@ class CPlayerTableCache : public cache<TPlayerTable>
* @brief class
* @version 05/06/10 Bang2ni - First release.
*/
class CItemPriceListTableCache : public cache< TItemPriceListTable >
class CItemPriceListTableCache : public cache<TItemPriceListTable>
{
public:
public:
/// Constructor
/**
* .
@ -48,13 +47,12 @@ class CItemPriceListTableCache : public cache< TItemPriceListTable >
* .
* .
*/
void UpdateList(const TItemPriceListTable* pUpdateList);
void UpdateList(const TItemPriceListTable *pUpdateList);
/// 가격정보를 DB 에 기록한다.
virtual void OnFlush(void);
private:
private:
static const int s_nMinFlushSec; ///< Minimum cache expire time
};
// END_OF_MYSHOP_PRICE_LIST

File diff suppressed because it is too large Load Diff

View File

@ -20,14 +20,14 @@ class CItemPriceListTableCache;
class CPacketInfo
{
public:
public:
void Add(int header);
void Reset();
std::map<int, int> m_map_info;
};
size_t CreatePlayerSaveQuery(char * pszQuery, size_t querySize, TPlayerTable * pkTab);
size_t CreatePlayerSaveQuery(char *pszQuery, size_t querySize, TPlayerTable *pkTab);
static void AcceptConnection(evconnlistener *listener, evutil_socket_t fd, sockaddr *address, int socklen, void *ctx);
static void AcceptError(evconnlistener *listener, void *ctx);
@ -37,13 +37,13 @@ static void DescEventHandler(bufferevent *bev, short events, void *ctx);
class CClientManager : public singleton<CClientManager>
{
public:
public:
typedef std::list<CPeer *> TPeerList;
typedef std::unordered_map<DWORD, CPlayerTableCache *> TPlayerTableCacheMap;
typedef std::unordered_map<DWORD, CItemCache *> TItemCacheMap;
typedef std::unordered_set<CItemCache *, std::hash<CItemCache*> > TItemCacheSet;
typedef std::unordered_set<CItemCache *, std::hash<CItemCache *>> TItemCacheSet;
typedef std::unordered_map<DWORD, TItemCacheSet *> TItemCacheSetPtrMap;
typedef std::unordered_map<DWORD, CItemPriceListTableCache*> TItemPriceListCacheMap;
typedef std::unordered_map<DWORD, CItemPriceListTableCache *> TItemPriceListCacheMap;
typedef std::unordered_map<short, BYTE> TChannelStatusMap;
// MYSHOP_PRICE_LIST
@ -52,7 +52,7 @@ class CClientManager : public singleton<CClientManager>
* first: Peer handle
* second: ID
*/
typedef std::pair< DWORD, DWORD > TItemPricelistReqInfo;
typedef std::pair<DWORD, DWORD> TItemPricelistReqInfo;
// END_OF_MYSHOP_PRICE_LIST
class ClientHandleInfo
@ -66,8 +66,8 @@ class CClientManager : public singleton<CClientManager>
char safebox_password[SAFEBOX_PASSWORD_MAX_LEN + 1];
char ip[MAX_HOST_LENGTH + 1];
TAccountTable * pAccountTable;
TSafeboxTable * pSafebox;
TAccountTable *pAccountTable;
TSafeboxTable *pSafebox;
ClientHandleInfo(DWORD argHandle, DWORD dwPID = 0)
{
@ -76,7 +76,7 @@ class CClientManager : public singleton<CClientManager>
pAccountTable = NULL;
player_id = dwPID;
};
//독일선물기능용 생성자
// 독일선물기능용 생성자
ClientHandleInfo(DWORD argHandle, DWORD dwPID, DWORD accountId)
{
dwHandle = argHandle;
@ -96,7 +96,7 @@ class CClientManager : public singleton<CClientManager>
}
};
public:
public:
CClientManager();
~CClientManager();
@ -106,7 +106,7 @@ class CClientManager : public singleton<CClientManager>
void MainLoop();
void Quit();
void SetTablePostfix(const char* c_pszTablePostfix);
void SetTablePostfix(const char *c_pszTablePostfix);
void SetPlayerIDStart(int iIDStart);
int GetPlayerIDStart() { return m_iPlayerIDStart; }
@ -120,15 +120,15 @@ class CClientManager : public singleton<CClientManager>
void SendAllGuildSkillRechargePacket();
void SendTime();
CPlayerTableCache * GetPlayerCache(DWORD id);
void PutPlayerCache(TPlayerTable * pNew);
CPlayerTableCache *GetPlayerCache(DWORD id);
void PutPlayerCache(TPlayerTable *pNew);
void CreateItemCacheSet(DWORD dwID);
TItemCacheSet * GetItemCacheSet(DWORD dwID);
TItemCacheSet *GetItemCacheSet(DWORD dwID);
void FlushItemCacheSet(DWORD dwID);
CItemCache * GetItemCache(DWORD id);
void PutItemCache(TPlayerItem * pNew, bool bSkipQuery = false);
CItemCache *GetItemCache(DWORD id);
void PutItemCache(TPlayerItem *pNew, bool bSkipQuery = false);
bool DeleteItemCache(DWORD id);
void UpdatePlayerCache();
@ -140,7 +140,7 @@ class CClientManager : public singleton<CClientManager>
* @param [in] dwID .( ID)
* @return
*/
CItemPriceListTableCache* GetItemPriceListCache(DWORD dwID);
CItemPriceListTableCache *GetItemPriceListCache(DWORD dwID);
/// 가격정보 리스트 캐시를 넣는다.
/**
@ -148,14 +148,12 @@ class CClientManager : public singleton<CClientManager>
*
* Update replace .
*/
void PutItemPriceListCache(const TItemPriceListTable* pItemPriceList);
void PutItemPriceListCache(const TItemPriceListTable *pItemPriceList);
/// Flush 시간이 만료된 아이템 가격정보 리스트 캐시를 Flush 해주고 캐시에서 삭제한다.
void UpdateItemPriceListCache(void);
// END_OF_MYSHOP_PRICE_LIST
void SendGuildSkillUsable(DWORD guild_id, DWORD dwSkillVnum, bool bUsable);
void SetCacheFlushCountLimit(int iLimit);
@ -163,26 +161,26 @@ class CClientManager : public singleton<CClientManager>
template <class Func>
Func for_each_peer(Func f);
CPeer * GetAnyPeer();
CPeer *GetAnyPeer();
void ForwardPacket(BYTE header, const void* data, int size, BYTE bChannel = 0, CPeer * except = NULL);
void ForwardPacket(BYTE header, const void *data, int size, BYTE bChannel = 0, CPeer *except = NULL);
void SendNotice(const char * c_pszFormat, ...);
void SendNotice(const char *c_pszFormat, ...);
std::string GetCommand(char* str); //독일선물기능에서 명령어 얻는 함수
void ItemAward(CPeer * peer, char* login); //독일 선물 기능
std::string GetCommand(char *str); // 독일선물기능에서 명령어 얻는 함수
void ItemAward(CPeer *peer, char *login); // 독일 선물 기능
CPeer * AddPeer(bufferevent* bufev, sockaddr* addr);
void RemovePeer(CPeer * pPeer);
CPeer * GetPeer(IDENT ident);
CPeer * GetAuthPeer();
CPeer *AddPeer(bufferevent *bufev, sockaddr *addr);
void RemovePeer(CPeer *pPeer);
CPeer *GetPeer(IDENT ident);
CPeer *GetAuthPeer();
void ProcessPackets(CPeer * peer);
void ProcessPackets(CPeer *peer);
protected:
protected:
void Destroy();
private:
private:
bool InitializeTables();
bool InitializeShopTable();
bool InitializeMobTable();
@ -204,55 +202,55 @@ class CClientManager : public singleton<CClientManager>
bool MirrorMobTableIntoDB();
bool MirrorItemTableIntoDB();
int AnalyzeQueryResult(SQLMsg * msg);
int AnalyzeErrorMsg(CPeer * peer, SQLMsg * msg);
int AnalyzeQueryResult(SQLMsg *msg);
int AnalyzeErrorMsg(CPeer *peer, SQLMsg *msg);
int Process();
CLoginData * GetLoginData(DWORD dwKey);
CLoginData * GetLoginDataByLogin(const char * c_pszLogin);
CLoginData * GetLoginDataByAID(DWORD dwAID);
CLoginData *GetLoginData(DWORD dwKey);
CLoginData *GetLoginDataByLogin(const char *c_pszLogin);
CLoginData *GetLoginDataByAID(DWORD dwAID);
void InsertLoginData(CLoginData * pkLD);
void DeleteLoginData(CLoginData * pkLD);
void InsertLoginData(CLoginData *pkLD);
void DeleteLoginData(CLoginData *pkLD);
bool InsertLogonAccount(const char * c_pszLogin, DWORD dwHandle, const char * c_pszIP);
bool DeleteLogonAccount(const char * c_pszLogin, DWORD dwHandle);
bool FindLogonAccount(const char * c_pszLogin);
bool InsertLogonAccount(const char *c_pszLogin, DWORD dwHandle, const char *c_pszIP);
bool DeleteLogonAccount(const char *c_pszLogin, DWORD dwHandle);
bool FindLogonAccount(const char *c_pszLogin);
void GuildCreate(CPeer * peer, DWORD dwGuildID);
void GuildSkillUpdate(CPeer * peer, TPacketGuildSkillUpdate* p);
void GuildExpUpdate(CPeer * peer, TPacketGuildExpUpdate* p);
void GuildAddMember(CPeer * peer, TPacketGDGuildAddMember* p);
void GuildChangeGrade(CPeer * peer, TPacketGuild* p);
void GuildRemoveMember(CPeer * peer, TPacketGuild* p);
void GuildChangeMemberData(CPeer * peer, TPacketGuildChangeMemberData* p);
void GuildDisband(CPeer * peer, TPacketGuild * p);
void GuildWar(CPeer * peer, TPacketGuildWar * p);
void GuildWarScore(CPeer * peer, TPacketGuildWarScore * p);
void GuildChangeLadderPoint(TPacketGuildLadderPoint* p);
void GuildUseSkill(TPacketGuildUseSkill* p);
void GuildDepositMoney(TPacketGDGuildMoney* p);
void GuildWithdrawMoney(CPeer* peer, TPacketGDGuildMoney* p);
void GuildWithdrawMoneyGiveReply(TPacketGDGuildMoneyWithdrawGiveReply* p);
void GuildWarBet(TPacketGDGuildWarBet * p);
void GuildChangeMaster(TPacketChangeGuildMaster* p);
void GuildCreate(CPeer *peer, DWORD dwGuildID);
void GuildSkillUpdate(CPeer *peer, TPacketGuildSkillUpdate *p);
void GuildExpUpdate(CPeer *peer, TPacketGuildExpUpdate *p);
void GuildAddMember(CPeer *peer, TPacketGDGuildAddMember *p);
void GuildChangeGrade(CPeer *peer, TPacketGuild *p);
void GuildRemoveMember(CPeer *peer, TPacketGuild *p);
void GuildChangeMemberData(CPeer *peer, TPacketGuildChangeMemberData *p);
void GuildDisband(CPeer *peer, TPacketGuild *p);
void GuildWar(CPeer *peer, TPacketGuildWar *p);
void GuildWarScore(CPeer *peer, TPacketGuildWarScore *p);
void GuildChangeLadderPoint(TPacketGuildLadderPoint *p);
void GuildUseSkill(TPacketGuildUseSkill *p);
void GuildDepositMoney(TPacketGDGuildMoney *p);
void GuildWithdrawMoney(CPeer *peer, TPacketGDGuildMoney *p);
void GuildWithdrawMoneyGiveReply(TPacketGDGuildMoneyWithdrawGiveReply *p);
void GuildWarBet(TPacketGDGuildWarBet *p);
void GuildChangeMaster(TPacketChangeGuildMaster *p);
void SetGuildWarEndTime(DWORD guild_id1, DWORD guild_id2, time_t tEndTime);
void QUERY_BOOT(CPeer * peer, TPacketGDBoot * p);
void QUERY_BOOT(CPeer *peer, TPacketGDBoot *p);
void QUERY_LOGIN(CPeer * peer, DWORD dwHandle, SLoginPacket* data);
void QUERY_LOGOUT(CPeer * peer, DWORD dwHandle, const char *);
void QUERY_LOGIN(CPeer *peer, DWORD dwHandle, SLoginPacket *data);
void QUERY_LOGOUT(CPeer *peer, DWORD dwHandle, const char *);
void RESULT_LOGIN(CPeer * peer, SQLMsg *msg);
void RESULT_LOGIN(CPeer *peer, SQLMsg *msg);
void QUERY_PLAYER_LOAD(CPeer * peer, DWORD dwHandle, TPlayerLoadPacket*);
void RESULT_COMPOSITE_PLAYER(CPeer * peer, SQLMsg * pMsg, DWORD dwQID);
void RESULT_PLAYER_LOAD(CPeer * peer, MYSQL_RES * pRes, ClientHandleInfo * pkInfo);
void RESULT_ITEM_LOAD(CPeer * peer, MYSQL_RES * pRes, DWORD dwHandle, DWORD dwPID);
void RESULT_QUEST_LOAD(CPeer * pkPeer, MYSQL_RES * pRes, DWORD dwHandle, DWORD dwPID);
void RESULT_AFFECT_LOAD(CPeer * pkPeer, MYSQL_RES * pRes, DWORD dwHandle);
void QUERY_PLAYER_LOAD(CPeer *peer, DWORD dwHandle, TPlayerLoadPacket *);
void RESULT_COMPOSITE_PLAYER(CPeer *peer, SQLMsg *pMsg, DWORD dwQID);
void RESULT_PLAYER_LOAD(CPeer *peer, MYSQL_RES *pRes, ClientHandleInfo *pkInfo);
void RESULT_ITEM_LOAD(CPeer *peer, MYSQL_RES *pRes, DWORD dwHandle, DWORD dwPID);
void RESULT_QUEST_LOAD(CPeer *pkPeer, MYSQL_RES *pRes, DWORD dwHandle, DWORD dwPID);
void RESULT_AFFECT_LOAD(CPeer *pkPeer, MYSQL_RES *pRes, DWORD dwHandle);
// PLAYER_INDEX_CREATE_BUG_FIX
void RESULT_PLAYER_INDEX_CREATE(CPeer *pkPeer, SQLMsg *msg);
@ -266,7 +264,7 @@ class CClientManager : public singleton<CClientManager>
*
* peer .
*/
void RESULT_PRICELIST_LOAD(CPeer* peer, SQLMsg* pMsg);
void RESULT_PRICELIST_LOAD(CPeer *peer, SQLMsg *pMsg);
/// 가격정보 업데이트를 위한 로드 쿼리에 대한 Result 처리
/**
@ -274,82 +272,81 @@ class CClientManager : public singleton<CClientManager>
*
* .
*/
void RESULT_PRICELIST_LOAD_FOR_UPDATE(SQLMsg* pMsg);
void RESULT_PRICELIST_LOAD_FOR_UPDATE(SQLMsg *pMsg);
// END_OF_MYSHOP_PRICE_LIST
void QUERY_PLAYER_SAVE(CPeer * peer, DWORD dwHandle, TPlayerTable*);
void QUERY_PLAYER_SAVE(CPeer *peer, DWORD dwHandle, TPlayerTable *);
void __QUERY_PLAYER_CREATE(CPeer * peer, DWORD dwHandle, TPlayerCreatePacket *);
void __QUERY_PLAYER_DELETE(CPeer * peer, DWORD dwHandle, TPlayerDeletePacket *);
void __RESULT_PLAYER_DELETE(CPeer * peer, SQLMsg* msg);
void __QUERY_PLAYER_CREATE(CPeer *peer, DWORD dwHandle, TPlayerCreatePacket *);
void __QUERY_PLAYER_DELETE(CPeer *peer, DWORD dwHandle, TPlayerDeletePacket *);
void __RESULT_PLAYER_DELETE(CPeer *peer, SQLMsg *msg);
void QUERY_PLAYER_COUNT(CPeer * pkPeer, TPlayerCountPacket *);
void QUERY_PLAYER_COUNT(CPeer *pkPeer, TPlayerCountPacket *);
void QUERY_ITEM_SAVE(CPeer * pkPeer, const char * c_pData);
void QUERY_ITEM_DESTROY(CPeer * pkPeer, const char * c_pData);
void QUERY_ITEM_FLUSH(CPeer * pkPeer, const char * c_pData);
void QUERY_ITEM_SAVE(CPeer *pkPeer, const char *c_pData);
void QUERY_ITEM_DESTROY(CPeer *pkPeer, const char *c_pData);
void QUERY_ITEM_FLUSH(CPeer *pkPeer, const char *c_pData);
void QUERY_QUEST_SAVE(CPeer *pkPeer, TQuestTable *, DWORD dwLen);
void QUERY_ADD_AFFECT(CPeer *pkPeer, TPacketGDAddAffect *p);
void QUERY_REMOVE_AFFECT(CPeer *pkPeer, TPacketGDRemoveAffect *p);
void QUERY_QUEST_SAVE(CPeer * pkPeer, TQuestTable *, DWORD dwLen);
void QUERY_ADD_AFFECT(CPeer * pkPeer, TPacketGDAddAffect * p);
void QUERY_REMOVE_AFFECT(CPeer * pkPeer, TPacketGDRemoveAffect * p);
void QUERY_SAFEBOX_LOAD(CPeer *pkPeer, DWORD dwHandle, TSafeboxLoadPacket *, bool bMall);
void QUERY_SAFEBOX_SAVE(CPeer *pkPeer, TSafeboxTable *pTable);
void QUERY_SAFEBOX_CHANGE_SIZE(CPeer *pkPeer, DWORD dwHandle, TSafeboxChangeSizePacket *p);
void QUERY_SAFEBOX_CHANGE_PASSWORD(CPeer *pkPeer, DWORD dwHandle, TSafeboxChangePasswordPacket *p);
void QUERY_SAFEBOX_LOAD(CPeer * pkPeer, DWORD dwHandle, TSafeboxLoadPacket *, bool bMall);
void QUERY_SAFEBOX_SAVE(CPeer * pkPeer, TSafeboxTable * pTable);
void QUERY_SAFEBOX_CHANGE_SIZE(CPeer * pkPeer, DWORD dwHandle, TSafeboxChangeSizePacket * p);
void QUERY_SAFEBOX_CHANGE_PASSWORD(CPeer * pkPeer, DWORD dwHandle, TSafeboxChangePasswordPacket * p);
void RESULT_SAFEBOX_LOAD(CPeer *pkPeer, SQLMsg *msg);
void RESULT_SAFEBOX_CHANGE_SIZE(CPeer *pkPeer, SQLMsg *msg);
void RESULT_SAFEBOX_CHANGE_PASSWORD(CPeer *pkPeer, SQLMsg *msg);
void RESULT_SAFEBOX_CHANGE_PASSWORD_SECOND(CPeer *pkPeer, SQLMsg *msg);
void RESULT_SAFEBOX_LOAD(CPeer * pkPeer, SQLMsg * msg);
void RESULT_SAFEBOX_CHANGE_SIZE(CPeer * pkPeer, SQLMsg * msg);
void RESULT_SAFEBOX_CHANGE_PASSWORD(CPeer * pkPeer, SQLMsg * msg);
void RESULT_SAFEBOX_CHANGE_PASSWORD_SECOND(CPeer * pkPeer, SQLMsg * msg);
void QUERY_EMPIRE_SELECT(CPeer *pkPeer, DWORD dwHandle, TEmpireSelectPacket *p);
void QUERY_SETUP(CPeer *pkPeer, DWORD dwHandle, const char *c_pData);
void QUERY_EMPIRE_SELECT(CPeer * pkPeer, DWORD dwHandle, TEmpireSelectPacket * p);
void QUERY_SETUP(CPeer * pkPeer, DWORD dwHandle, const char * c_pData);
void SendPartyOnSetup(CPeer *peer);
void SendPartyOnSetup(CPeer * peer);
void QUERY_FLUSH_CACHE(CPeer *pkPeer, const char *c_pData);
void QUERY_FLUSH_CACHE(CPeer * pkPeer, const char * c_pData);
void QUERY_PARTY_CREATE(CPeer * peer, TPacketPartyCreate* p);
void QUERY_PARTY_DELETE(CPeer * peer, TPacketPartyDelete* p);
void QUERY_PARTY_ADD(CPeer * peer, TPacketPartyAdd* p);
void QUERY_PARTY_REMOVE(CPeer * peer, TPacketPartyRemove* p);
void QUERY_PARTY_STATE_CHANGE(CPeer * peer, TPacketPartyStateChange* p);
void QUERY_PARTY_SET_MEMBER_LEVEL(CPeer * peer, TPacketPartySetMemberLevel* p);
void QUERY_PARTY_CREATE(CPeer *peer, TPacketPartyCreate *p);
void QUERY_PARTY_DELETE(CPeer *peer, TPacketPartyDelete *p);
void QUERY_PARTY_ADD(CPeer *peer, TPacketPartyAdd *p);
void QUERY_PARTY_REMOVE(CPeer *peer, TPacketPartyRemove *p);
void QUERY_PARTY_STATE_CHANGE(CPeer *peer, TPacketPartyStateChange *p);
void QUERY_PARTY_SET_MEMBER_LEVEL(CPeer *peer, TPacketPartySetMemberLevel *p);
void QUERY_RELOAD_PROTO();
void QUERY_CHANGE_NAME(CPeer * peer, DWORD dwHandle, TPacketGDChangeName * p);
void GetPlayerFromRes(TPlayerTable * player_table, MYSQL_RES* res);
void QUERY_CHANGE_NAME(CPeer *peer, DWORD dwHandle, TPacketGDChangeName *p);
void GetPlayerFromRes(TPlayerTable *player_table, MYSQL_RES *res);
void QUERY_LOGIN_KEY(CPeer * pkPeer, TPacketGDLoginKey * p);
void QUERY_LOGIN_KEY(CPeer *pkPeer, TPacketGDLoginKey *p);
void AddGuildPriv(TPacketGiveGuildPriv* p);
void AddEmpirePriv(TPacketGiveEmpirePriv* p);
void AddCharacterPriv(TPacketGiveCharacterPriv* p);
void AddGuildPriv(TPacketGiveGuildPriv *p);
void AddEmpirePriv(TPacketGiveEmpirePriv *p);
void AddCharacterPriv(TPacketGiveCharacterPriv *p);
void MoneyLog(TPacketMoneyLog* p);
void MoneyLog(TPacketMoneyLog *p);
void QUERY_AUTH_LOGIN(CPeer * pkPeer, DWORD dwHandle, TPacketGDAuthLogin * p);
void QUERY_AUTH_LOGIN(CPeer *pkPeer, DWORD dwHandle, TPacketGDAuthLogin *p);
void QUERY_LOGIN_BY_KEY(CPeer * pkPeer, DWORD dwHandle, TPacketGDLoginByKey * p);
void RESULT_LOGIN_BY_KEY(CPeer * peer, SQLMsg * msg);
void QUERY_LOGIN_BY_KEY(CPeer *pkPeer, DWORD dwHandle, TPacketGDLoginByKey *p);
void RESULT_LOGIN_BY_KEY(CPeer *peer, SQLMsg *msg);
void ChargeCash(const TRequestChargeCash * p);
void ChargeCash(const TRequestChargeCash *p);
void LoadEventFlag();
void SetEventFlag(TPacketSetEventFlag* p);
void SendEventFlagsOnSetup(CPeer* peer);
void SetEventFlag(TPacketSetEventFlag *p);
void SendEventFlagsOnSetup(CPeer *peer);
// 결혼
void MarriageAdd(TPacketMarriageAdd * p);
void MarriageUpdate(TPacketMarriageUpdate * p);
void MarriageRemove(TPacketMarriageRemove * p);
void MarriageAdd(TPacketMarriageAdd *p);
void MarriageUpdate(TPacketMarriageUpdate *p);
void MarriageRemove(TPacketMarriageRemove *p);
void WeddingRequest(TPacketWeddingRequest * p);
void WeddingReady(TPacketWeddingReady * p);
void WeddingEnd(TPacketWeddingEnd * p);
void WeddingRequest(TPacketWeddingRequest *p);
void WeddingReady(TPacketWeddingReady *p);
void WeddingEnd(TPacketWeddingEnd *p);
// MYSHOP_PRICE_LIST
// 개인상점 가격정보
@ -358,7 +355,7 @@ class CClientManager : public singleton<CClientManager>
/**
* @param [in] pPacket
*/
void MyshopPricelistUpdate(const TPacketMyshopPricelistHeader* pPacket);
void MyshopPricelistUpdate(const TPacketMyshopPricelistHeader *pPacket);
/// 아이템 가격정보 리스트 요청 패킷(HEADER_GD_MYSHOP_PRICELIST_REQ) 처리함수
/**
@ -366,25 +363,25 @@ class CClientManager : public singleton<CClientManager>
* @param [in] dwHandle peer
* @param [in] dwPlayerID ID
*/
void MyshopPricelistRequest(CPeer* peer, DWORD dwHandle, DWORD dwPlayerID);
void MyshopPricelistRequest(CPeer *peer, DWORD dwHandle, DWORD dwPlayerID);
// END_OF_MYSHOP_PRICE_LIST
// Building
void CreateObject(TPacketGDCreateObject * p);
void CreateObject(TPacketGDCreateObject *p);
void DeleteObject(DWORD dwID);
void UpdateLand(DWORD * pdw);
void UpdateLand(DWORD *pdw);
// BLOCK_CHAT
void BlockChat(TPacketBlockChat * p);
void BlockChat(TPacketBlockChat *p);
// END_OF_BLOCK_CHAT
private:
private:
int m_looping;
event_base * m_base = nullptr;
evconnlistener * m_listener = nullptr;
event_base *m_base = nullptr;
evconnlistener *m_listener = nullptr;
TPeerList m_peerList;
CPeer * m_pkAuthPeer;
CPeer *m_pkAuthPeer;
// LoginKey, LoginData pair
typedef std::unordered_map<DWORD, CLoginData *> TLoginDataByLoginKey;
@ -412,10 +409,10 @@ class CClientManager : public singleton<CClientManager>
std::map<DWORD, TItemTable *> m_map_itemTableByVnum;
int m_iShopTableSize;
TShopTable * m_pShopTable;
TShopTable *m_pShopTable;
int m_iRefineTableSize;
TRefineTable* m_pRefineTable;
TRefineTable *m_pRefineTable;
std::vector<TSkillTable> m_vec_skillTable;
std::vector<TBanwordTable> m_vec_banwordTable;
@ -445,7 +442,7 @@ class CClientManager : public singleton<CClientManager>
BYTE bRole;
BYTE bLevel;
TPartyInfo() :bRole(0), bLevel(0)
TPartyInfo() : bRole(0), bLevel(0)
{
}
};
@ -462,48 +459,47 @@ class CClientManager : public singleton<CClientManager>
int m_iCacheFlushCount;
int m_iCacheFlushCountLimit;
private :
private:
TItemIDRangeTable m_itemRange;
public :
public:
bool InitializeNowItemID();
DWORD GetItemID();
DWORD GainItemID();
TItemIDRangeTable GetItemRange() { return m_itemRange; }
//BOOT_LOCALIZATION
public:
// BOOT_LOCALIZATION
public:
/* 로컬 정보 초기화
**/
bool InitializeLocalization();
private:
private:
std::vector<tLocale> m_vec_Locale;
//END_BOOT_LOCALIZATION
//ADMIN_MANAGER
// END_BOOT_LOCALIZATION
// ADMIN_MANAGER
bool __GetAdminInfo(const char *szIP, std::vector<tAdminInfo> & rAdminVec);
bool __GetHostInfo(std::vector<std::string> & rIPVec);
//END_ADMIN_MANAGER
bool __GetAdminInfo(const char *szIP, std::vector<tAdminInfo> &rAdminVec);
bool __GetHostInfo(std::vector<std::string> &rIPVec);
// END_ADMIN_MANAGER
//RELOAD_ADMIN
void ReloadAdmin(CPeer * peer, TPacketReloadAdmin * p);
//END_RELOAD_ADMIN
void BreakMarriage(CPeer * peer, const char * data);
// RELOAD_ADMIN
void ReloadAdmin(CPeer *peer, TPacketReloadAdmin *p);
// END_RELOAD_ADMIN
void BreakMarriage(CPeer *peer, const char *data);
struct TLogoutPlayer
{
DWORD pid;
time_t time;
bool operator < (const TLogoutPlayer & r)
bool operator<(const TLogoutPlayer &r)
{
return (pid < r.pid);
}
};
typedef std::unordered_map<DWORD, TLogoutPlayer*> TLogoutPlayerMap;
typedef std::unordered_map<DWORD, TLogoutPlayer *> TLogoutPlayerMap;
TLogoutPlayerMap m_map_logout;
void InsertLogoutPlayer(DWORD pid);
@ -513,39 +509,38 @@ class CClientManager : public singleton<CClientManager>
void FlushPlayerCacheSet(DWORD pid);
//MONARCH
void Election(CPeer * peer, DWORD dwHandle, const char * p);
void Candidacy(CPeer * peer, DWORD dwHandle, const char * p);
void AddMonarchMoney(CPeer * peer, DWORD dwHandle, const char * p);
void TakeMonarchMoney(CPeer * peer, DWORD dwHandle, const char * p);
void ComeToVote(CPeer * peer, DWORD dwHandle, const char * p);
void RMCandidacy(CPeer * peer, DWORD dwHandle, const char * p);
void SetMonarch(CPeer * peer, DWORD dwHandle, const char * p);
void RMMonarch(CPeer * peer, DWORD dwHandle, const char * p);
// MONARCH
void Election(CPeer *peer, DWORD dwHandle, const char *p);
void Candidacy(CPeer *peer, DWORD dwHandle, const char *p);
void AddMonarchMoney(CPeer *peer, DWORD dwHandle, const char *p);
void TakeMonarchMoney(CPeer *peer, DWORD dwHandle, const char *p);
void ComeToVote(CPeer *peer, DWORD dwHandle, const char *p);
void RMCandidacy(CPeer *peer, DWORD dwHandle, const char *p);
void SetMonarch(CPeer *peer, DWORD dwHandle, const char *p);
void RMMonarch(CPeer *peer, DWORD dwHandle, const char *p);
void DecMonarchMoney(CPeer *peer, DWORD dwHandle, const char *p);
// END_MONARCH
void DecMonarchMoney(CPeer * peer, DWORD dwHandle, const char * p);
//END_MONARCH
void ChangeMonarchLord(CPeer *peer, DWORD dwHandle, TPacketChangeMonarchLord *info);
void ChangeMonarchLord(CPeer* peer, DWORD dwHandle, TPacketChangeMonarchLord* info);
void SendSpareItemIDRange(CPeer *peer);
void SendSpareItemIDRange(CPeer* peer);
void UpdateHorseName(TPacketUpdateHorseName* data, CPeer* peer);
void AckHorseName(DWORD dwPID, CPeer* peer);
void UpdateHorseName(TPacketUpdateHorseName *data, CPeer *peer);
void AckHorseName(DWORD dwPID, CPeer *peer);
void DeleteLoginKey(TPacketDC *data);
void ResetLastPlayerID(const TPacketNeedLoginLogInfo* data);
//delete gift notify icon
void DeleteAwardId(TPacketDeleteAwardID* data);
void UpdateChannelStatus(TChannelStatus* pData);
void RequestChannelStatus(CPeer* peer, DWORD dwHandle);
void ResetLastPlayerID(const TPacketNeedLoginLogInfo *data);
// delete gift notify icon
void DeleteAwardId(TPacketDeleteAwardID *data);
void UpdateChannelStatus(TChannelStatus *pData);
void RequestChannelStatus(CPeer *peer, DWORD dwHandle);
};
template<class Func>
template <class Func>
Func CClientManager::for_each_peer(Func f)
{
TPeerList::iterator it;
for (it = m_peerList.begin(); it!=m_peerList.end();++it)
for (it = m_peerList.begin(); it != m_peerList.end(); ++it)
{
f(*it);
}

View File

@ -97,7 +97,6 @@ bool CClientManager::InitializeTables()
return false;
}
return true;
}
@ -110,7 +109,7 @@ bool CClientManager::InitializeRefineTable()
GetTablePostfix());
std::unique_ptr<SQLMsg> pkMsg(CDBManager::instance().DirectQuery(query));
SQLResult * pRes = pkMsg->Get();
SQLResult *pRes = pkMsg->Get();
if (!pRes->uiNumRows)
return true;
@ -118,7 +117,7 @@ bool CClientManager::InitializeRefineTable()
if (m_pRefineTable)
{
SPDLOG_DEBUG("RELOAD: refine_proto");
delete [] m_pRefineTable;
delete[] m_pRefineTable;
m_pRefineTable = NULL;
}
@ -127,17 +126,17 @@ bool CClientManager::InitializeRefineTable()
m_pRefineTable = new TRefineTable[m_iRefineTableSize];
memset(m_pRefineTable, 0, sizeof(TRefineTable) * m_iRefineTableSize);
TRefineTable* prt = m_pRefineTable;
TRefineTable *prt = m_pRefineTable;
MYSQL_ROW data;
while ((data = mysql_fetch_row(pRes->pSQLResult)))
{
//const char* s_szQuery = "SELECT src_vnum, result_vnum, cost, prob, "
// const char* s_szQuery = "SELECT src_vnum, result_vnum, cost, prob, "
//"vnum0, count0, vnum1, count1, vnum2, count2, vnum3, count3, vnum4, count4 "
int col = 0;
//prt->src_vnum = atoi(data[col++]);
//prt->result_vnum = atoi(data[col++]);
// prt->src_vnum = atoi(data[col++]);
// prt->result_vnum = atoi(data[col++]);
str_to_number(prt->id, data[col++]);
str_to_number(prt->cost, data[col++]);
str_to_number(prt->prob, data[col++]);
@ -162,8 +161,8 @@ bool CClientManager::InitializeRefineTable()
class FCompareVnum
{
public:
bool operator () (const TEntityTable & a, const TEntityTable & b) const
public:
bool operator()(const TEntityTable &a, const TEntityTable &b) const
{
return (a.dwVnum < b.dwVnum);
}
@ -172,9 +171,9 @@ class FCompareVnum
bool CClientManager::InitializeMobTable()
{
//================== 함수 설명 ==================//
//1. 요약 : 'mob_proto.txt', 'mob_proto_test.txt', 'mob_names.txt' 파일을 읽고,
// 1. 요약 : 'mob_proto.txt', 'mob_proto_test.txt', 'mob_names.txt' 파일을 읽고,
// (!)[mob_table] 테이블 오브젝트를 생성한다. (타입 : TMobTable)
//2. 순서
// 2. 순서
// 1) 'mob_names.txt' 파일을 읽어서 (a)[localMap](vnum:name) 맵을 만든다.
// 2) 'mob_proto_test.txt'파일과 (a)[localMap] 맵으로
// (b)[test_map_mobTableByVnum](vnum:TMobTable) 맵을 생성한다.
@ -185,7 +184,7 @@ bool CClientManager::InitializeMobTable()
// (b)[test_map_mobTableByVnum],(!)[mob_table] 모두에 있는 row는
// (b)[test_map_mobTableByVnum]의 것을 사용한다.
// 4) (b)[test_map_mobTableByVnum]의 row중, (!)[mob_table]에 없는 것을 추가한다.
//3. 테스트
// 3. 테스트
// 1)'mob_proto.txt' 정보가 mob_table에 잘 들어갔는지. -> 완료
// 2)'mob_names.txt' 정보가 mob_table에 잘 들어갔는지.
// 3)'mob_proto_test.txt' 에서 [겹치는] 정보가 mob_table 에 잘 들어갔는지.
@ -193,53 +192,56 @@ bool CClientManager::InitializeMobTable()
// 5) (최종) 게임 클라이언트에서 제대로 작동 하는지.
//_______________________________________________//
//===============================================//
// 1) 'mob_names.txt' 파일을 읽어서 (a)[localMap] 맵을 만든다.
//<(a)localMap 맵 생성>
map<int,const char*> localMap;
map<int, const char *> localMap;
bool isNameFile = true;
//<파일 읽기>
cCsvTable nameData;
if(!nameData.Load("mob_names.txt",'\t'))
if (!nameData.Load("mob_names.txt", '\t'))
{
SPDLOG_ERROR("mob_names.txt Failed to read the file");
isNameFile = false;
} else {
nameData.Next(); //설명row 생략.
while(nameData.Next()) {
}
else
{
nameData.Next(); // 설명row 생략.
while (nameData.Next())
{
localMap[atoi(nameData.AsStringByIndex(0))] = nameData.AsStringByIndex(1);
}
}
//________________________________________________//
//===============================================//
// 2) 'mob_proto_test.txt'파일과 (a)localMap 맵으로
// (b)[test_map_mobTableByVnum](vnum:TMobTable) 맵을 생성한다.
//0.
set<int> vnumSet; //테스트용 파일 데이터중, 신규여부 확인에 사용.
//1. 파일 읽어오기
// 0.
set<int> vnumSet; // 테스트용 파일 데이터중, 신규여부 확인에 사용.
// 1. 파일 읽어오기
bool isTestFile = true;
cCsvTable test_data;
if(!test_data.Load("mob_proto_test.txt",'\t'))
if (!test_data.Load("mob_proto_test.txt", '\t'))
{
SPDLOG_ERROR("No test file exists, proceed as is.");
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(); //설명 로우 넘어가기.
if (isTestFile)
{
test_data.Next(); // 설명 로우 넘어가기.
//ㄱ. 테스트 몬스터 테이블 생성.
TMobTable * test_mob_table = NULL;
int test_MobTableSize = test_data.m_File.GetRowCount()-1;
// ㄱ. 테스트 몬스터 테이블 생성.
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()) {
// ㄴ. 테스트 몬스터 테이블에 값을 넣고, 맵에까지 넣기.
while (test_data.Next())
{
if (!Set_Proto_Mob_Table(test_mob_table, test_data, localMap))
{
@ -248,10 +250,8 @@ bool CClientManager::InitializeMobTable()
test_map_mobTableByVnum.insert(std::map<DWORD, TMobTable *>::value_type(test_mob_table->dwVnum, test_mob_table));
++test_mob_table;
}
}
// 3) 'mob_proto.txt' 파일과 (a)[localMap] 맵으로
@ -261,42 +261,45 @@ bool CClientManager::InitializeMobTable()
// (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 Failed to read the file");
return false;
}
data.Next(); //설명 row 넘어가기
//2. (!)[mob_table] 생성하기
//2.1 새로 추가되는 갯수를 파악
int addNumber = 0;
while(data.Next()) {
int vnum = atoi(data.AsStringByIndex(0));
std::map<DWORD, TMobTable *>::iterator it_map_mobTable;
it_map_mobTable = test_map_mobTableByVnum.find(vnum);
if(it_map_mobTable != test_map_mobTableByVnum.end()) {
addNumber++;
}
}
//data를 다시 첫줄로 옮긴다.(다시 읽어온다;;)
data.Destroy();
if(!data.Load("mob_proto.txt",'\t'))
if (!data.Load("mob_proto.txt", '\t'))
{
SPDLOG_ERROR("mob_proto.txt Failed to read the file");
return false;
}
data.Next(); //맨 윗줄 제외 (아이템 칼럼을 설명하는 부분)
//2.2 크기에 맞게 mob_table 생성
data.Next(); // 설명 row 넘어가기
// 2. (!)[mob_table] 생성하기
// 2.1 새로 추가되는 갯수를 파악
int addNumber = 0;
while (data.Next())
{
int vnum = atoi(data.AsStringByIndex(0));
std::map<DWORD, TMobTable *>::iterator it_map_mobTable;
it_map_mobTable = test_map_mobTableByVnum.find(vnum);
if (it_map_mobTable != test_map_mobTableByVnum.end())
{
addNumber++;
}
}
// data를 다시 첫줄로 옮긴다.(다시 읽어온다;;)
data.Destroy();
if (!data.Load("mob_proto.txt", '\t'))
{
SPDLOG_ERROR("mob_proto.txt Failed to read the file");
return false;
}
data.Next(); // 맨 윗줄 제외 (아이템 칼럼을 설명하는 부분)
// 2.2 크기에 맞게 mob_table 생성
if (!m_vec_mobTable.empty())
{
SPDLOG_DEBUG("RELOAD: mob_proto");
m_vec_mobTable.clear();
}
m_vec_mobTable.resize(data.m_File.GetRowCount()-1 + addNumber);
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 데이터 채우기
TMobTable *mob_table = &m_vec_mobTable[0];
// 2.3 데이터 채우기
while (data.Next())
{
int col = 0;
@ -304,11 +307,13 @@ bool CClientManager::InitializeMobTable()
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()) {
if (it_map_mobTable == test_map_mobTableByVnum.end())
{
isSameRow = false;
}
//같은 row 가 있으면 (b)에서 읽어온다.
if(isSameRow) {
// 같은 row 가 있으면 (b)에서 읽어온다.
if (isSameRow)
{
TMobTable *tempTable = it_map_mobTable->second;
mob_table->dwVnum = tempTable->dwVnum;
@ -357,7 +362,6 @@ bool CClientManager::InitializeMobTable()
mob_table->dwDrainSP = tempTable->dwDrainSP;
mob_table->dwPolymorphItemVnum = tempTable->dwPolymorphItemVnum;
mob_table->Skills[0].bLevel = tempTable->Skills[0].bLevel;
mob_table->Skills[0].dwVnum = tempTable->Skills[0].dwVnum;
mob_table->Skills[1].bLevel = tempTable->Skills[1].bLevel;
@ -374,46 +378,45 @@ bool CClientManager::InitializeMobTable()
mob_table->bGodSpeedPoint = tempTable->bGodSpeedPoint;
mob_table->bDeathBlowPoint = tempTable->bDeathBlowPoint;
mob_table->bRevivePoint = tempTable->bRevivePoint;
} else {
}
else
{
if (!Set_Proto_Mob_Table(mob_table, data, localMap))
{
SPDLOG_ERROR("Mob proto table setup failed.");
}
}
//셋에 vnum 추가
// 셋에 vnum 추가
vnumSet.insert(mob_table->dwVnum);
SPDLOG_TRACE("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);
++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'))
if (!test_data.Load("mob_proto_test.txt", '\t'))
{
SPDLOG_ERROR("No test file exists, proceed as is.");
isTestFile = false;
}
if(isTestFile) {
test_data.Next(); //설명 로우 넘어가기.
while (test_data.Next()) //테스트 데이터 각각을 훑어나가며,새로운 것을 추가한다.
if (isTestFile)
{
//중복되는 부분이면 넘어간다.
test_data.Next(); // 설명 로우 넘어가기.
while (test_data.Next()) // 테스트 데이터 각각을 훑어나가며,새로운 것을 추가한다.
{
// 중복되는 부분이면 넘어간다.
set<int>::iterator itVnum;
itVnum=vnumSet.find(atoi(test_data.AsStringByIndex(0)));
if (itVnum != vnumSet.end()) {
itVnum = vnumSet.find(atoi(test_data.AsStringByIndex(0)));
if (itVnum != vnumSet.end())
{
continue;
}
@ -424,7 +427,6 @@ bool CClientManager::InitializeMobTable()
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);
++mob_table;
}
}
sort(m_vec_mobTable.begin(), m_vec_mobTable.end(), FCompareVnum());
@ -436,7 +438,7 @@ bool CClientManager::InitializeShopTable()
MYSQL_ROW data;
int col;
static const char * s_szQuery =
static const char *s_szQuery =
"SELECT "
"shop.vnum, "
"shop.npc_vnum, "
@ -449,7 +451,7 @@ bool CClientManager::InitializeShopTable()
// shop의 vnum은 있는데 shop_item 이 없을경우... 실패로 처리되니 주의 요망.
// 고처야할부분
SQLResult * pRes2 = pkMsg2->Get();
SQLResult *pRes2 = pkMsg2->Get();
if (!pRes2->uiNumRows)
{
@ -461,11 +463,11 @@ bool CClientManager::InitializeShopTable()
if (m_pShopTable)
{
delete [] (m_pShopTable);
delete[] (m_pShopTable);
m_pShopTable = NULL;
}
TShopTable * shop_table = m_pShopTable;
TShopTable *shop_table = m_pShopTable;
while ((data = mysql_fetch_row(pRes2->pSQLResult)))
{
@ -490,7 +492,7 @@ bool CClientManager::InitializeShopTable()
if (!data[col]) // 아이템이 하나도 없으면 NULL이 리턴 되므로..
continue;
TShopItemTable * pItem = &shop_table->items[shop_table->byItemCount];
TShopItemTable *pItem = &shop_table->items[shop_table->byItemCount];
str_to_number(pItem->vnum, data[col++]);
str_to_number(pItem->count, data[col++]);
@ -519,13 +521,13 @@ bool CClientManager::InitializeQuestItemTable()
{
using namespace std;
static const char * s_szQuery = "SELECT vnum, name, %s FROM quest_item_proto ORDER BY vnum";
static const char *s_szQuery = "SELECT vnum, name, %s FROM quest_item_proto ORDER BY vnum";
char query[1024];
snprintf(query, sizeof(query), s_szQuery, g_stLocaleNameColumn.c_str());
std::unique_ptr<SQLMsg> pkMsg(CDBManager::instance().DirectQuery(query));
SQLResult * pRes = pkMsg->Get();
SQLResult *pRes = pkMsg->Get();
if (!pRes->uiNumRows)
{
@ -595,21 +597,22 @@ bool CClientManager::InitializeItemTable()
// 5) (Final) Verify that it works correctly in the game client.
//_______________________________________________//
//=================================================================================//
// 1) Read the 'item_names.txt' file to create (a) [localMap] (vnum:name) map.
//=================================================================================//
bool isNameFile = true;
map<int,const char*> localMap;
map<int, const char *> localMap;
cCsvTable nameData;
if(!nameData.Load("item_names.txt",'\t'))
if (!nameData.Load("item_names.txt", '\t'))
{
SPDLOG_ERROR("item_names.txt Failed to read the file");
isNameFile = false;
} else {
}
else
{
nameData.Next();
while(nameData.Next()) {
while (nameData.Next())
{
localMap[atoi(nameData.AsStringByIndex(0))] = nameData.AsStringByIndex(1);
}
}
@ -622,22 +625,24 @@ bool CClientManager::InitializeItemTable()
map<DWORD, TItemTable *> test_map_itemTableByVnum;
// 1. Read the file.
cCsvTable test_data;
if(!test_data.Load("item_proto_test.txt",'\t'))
if (!test_data.Load("item_proto_test.txt", '\t'))
{
SPDLOG_ERROR("item_proto_test.txt Failed to read the file");
//return false;
} else {
test_data.Next(); //설명 로우 넘어가기.
// return false;
}
else
{
test_data.Next(); // 설명 로우 넘어가기.
// 2. Create the test item table.
TItemTable * test_item_table = NULL;
int test_itemTableSize = test_data.m_File.GetRowCount()-1;
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. Insert values into the test item table and populate the map.
while(test_data.Next()) {
while (test_data.Next())
{
if (!Set_Proto_Item_Table(test_item_table, test_data, localMap))
{
@ -646,12 +651,10 @@ bool CClientManager::InitializeItemTable()
test_map_itemTableByVnum.insert(std::map<DWORD, TItemTable *>::value_type(test_item_table->dwVnum, test_item_table));
test_item_table++;
}
}
//______________________________________________________________________//
//========================================================================//
// 3) Using the 'item_proto.txt' file and the (a) [localMap] map,
// create the (!) [item_table] and <m_map_itemTableByVnum>.
@ -666,7 +669,7 @@ bool CClientManager::InitializeItemTable()
// Read the file.
cCsvTable data;
if(!data.Load("item_proto.txt",'\t'))
if (!data.Load("item_proto.txt", '\t'))
{
SPDLOG_ERROR("item_proto.txt Failed to read the file");
return false;
@ -683,17 +686,19 @@ bool CClientManager::InitializeItemTable()
//===== Create item table =====//
// Determine the number of newly added items.
int addNumber = 0;
while(data.Next()) {
while (data.Next())
{
int vnum = atoi(data.AsStringByIndex(0));
std::map<DWORD, TItemTable *>::iterator it_map_itemTable;
it_map_itemTable = test_map_itemTableByVnum.find(vnum);
if(it_map_itemTable != test_map_itemTableByVnum.end()) {
if (it_map_itemTable != test_map_itemTableByVnum.end())
{
addNumber++;
}
}
// Move the data back to the first line (re-read it;;)
data.Destroy();
if(!data.Load("item_proto.txt",'\t'))
if (!data.Load("item_proto.txt", '\t'))
{
SPDLOG_ERROR("item_proto.txt Failed to read the file");
return false;
@ -704,7 +709,7 @@ bool CClientManager::InitializeItemTable()
memset(&m_vec_itemTable[0], 0, sizeof(TItemTable) * m_vec_itemTable.size());
int testValue = m_vec_itemTable.size();
TItemTable * item_table = &m_vec_itemTable[0];
TItemTable *item_table = &m_vec_itemTable[0];
while (data.Next())
{
@ -712,17 +717,17 @@ 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 (it_map_itemTable == test_map_itemTableByVnum.end())
{
// Store data for each column
if (!Set_Proto_Item_Table(item_table, data, localMap))
{
SPDLOG_ERROR("Item proto table setup failed.");
}
} else { // $$$$$$$$$$$$$$$$$$$$$ There is test item information!
}
else
{ // $$$$$$$$$$$$$$$$$$$$$ There is test item information!
TItemTable *tempTable = it_map_itemTable->second;
item_table->dwVnum = tempTable->dwVnum;
@ -737,8 +742,8 @@ bool CClientManager::InitializeItemTable()
item_table->dwImmuneFlag = tempTable->dwImmuneFlag;
item_table->dwGold = tempTable->dwGold;
item_table->dwShopBuyPrice = tempTable->dwShopBuyPrice;
item_table->dwRefinedVnum =tempTable->dwRefinedVnum;
item_table->wRefineSet =tempTable->wRefineSet;
item_table->dwRefinedVnum = tempTable->dwRefinedVnum;
item_table->wRefineSet = tempTable->wRefineSet;
item_table->bAlterToMagicItemPct = tempTable->bAlterToMagicItemPct;
item_table->cLimitRealTimeFirstUseIndex = -1;
item_table->cLimitTimerBasedOnWearIndex = -1;
@ -770,7 +775,6 @@ bool CClientManager::InitializeItemTable()
item_table->sAddonType = tempTable->sAddonType;
item_table->bWeight = tempTable->bWeight;
}
vnumSet.insert(item_table->dwVnum);
m_map_itemTableByVnum.insert(std::map<DWORD, TItemTable *>::value_type(item_table->dwVnum, item_table));
@ -782,19 +786,22 @@ bool CClientManager::InitializeItemTable()
// 4) Add rows from (b) [test_map_itemTableByVnum] that do not exist in (!) [item_table].
//========================================================================//
test_data.Destroy();
if(!test_data.Load("item_proto_test.txt",'\t'))
if (!test_data.Load("item_proto_test.txt", '\t'))
{
SPDLOG_ERROR("item_proto_test.txt Failed to read the file");
//return false;
} else {
// return false;
}
else
{
test_data.Next(); // Skip the description row.
while (test_data.Next()) // Iterate through each test data entry and add new ones.
{
// Skip if its a duplicate.
set<int>::iterator itVnum;
itVnum=vnumSet.find(atoi(test_data.AsStringByIndex(0)));
if (itVnum != vnumSet.end()) {
itVnum = vnumSet.find(atoi(test_data.AsStringByIndex(0)));
if (itVnum != vnumSet.end())
{
continue;
}
@ -803,16 +810,12 @@ bool CClientManager::InitializeItemTable()
SPDLOG_ERROR("Item proto table setup failed.");
}
m_map_itemTableByVnum.insert(std::map<DWORD, TItemTable *>::value_type(item_table->dwVnum, item_table));
item_table++;
}
}
// QUEST_ITEM_PROTO_DISABLE
// InitializeQuestItemTable();
// END_OF_QUEST_ITEM_PROTO_DISABLE
@ -823,7 +826,7 @@ bool CClientManager::InitializeItemTable()
while (it != m_vec_itemTable.end())
{
TItemTable * item_table = &(*(it++));
TItemTable *item_table = &(*(it++));
SPDLOG_TRACE("ITEM: #{:<5} {:24} {:24} VAL: {} {} {} {} {} {} WEAR {} ANTI {} IMMUNE {} REFINE {} REFINE_SET {} MAGIC_PCT {}",
item_table->dwVnum,
@ -848,7 +851,6 @@ bool CClientManager::InitializeItemTable()
return true;
}
bool CClientManager::InitializeSkillTable()
{
char query[4096];
@ -863,7 +865,7 @@ bool CClientManager::InitializeSkillTable()
GetTablePostfix());
std::unique_ptr<SQLMsg> pkMsg(CDBManager::instance().DirectQuery(query));
SQLResult * pRes = pkMsg->Get();
SQLResult *pRes = pkMsg->Get();
if (!pRes->uiNumRows)
{
@ -945,7 +947,7 @@ bool CClientManager::InitializeBanwordTable()
std::unique_ptr<SQLMsg> pkMsg(CDBManager::instance().DirectQuery("SELECT word FROM banword"));
SQLResult * pRes = pkMsg->Get();
SQLResult *pRes = pkMsg->Get();
if (pRes->uiNumRows == 0)
return true;
@ -975,7 +977,7 @@ bool CClientManager::InitializeItemAttrTable()
GetTablePostfix());
std::unique_ptr<SQLMsg> pkMsg(CDBManager::instance().DirectQuery(query));
SQLResult * pRes = pkMsg->Get();
SQLResult *pRes = pkMsg->Get();
if (!pRes->uiNumRows)
{
@ -1049,7 +1051,7 @@ bool CClientManager::InitializeItemRareTable()
GetTablePostfix());
std::unique_ptr<SQLMsg> pkMsg(CDBManager::instance().DirectQuery(query));
SQLResult * pRes = pkMsg->Get();
SQLResult *pRes = pkMsg->Get();
if (!pRes->uiNumRows)
{
@ -1127,7 +1129,7 @@ bool CClientManager::InitializeLandTable()
GetTablePostfix());
std::unique_ptr<SQLMsg> pkMsg(CDBManager::instance().DirectQuery(query));
SQLResult * pRes = pkMsg->Get();
SQLResult *pRes = pkMsg->Get();
if (!m_vec_kLandTable.empty())
{
@ -1166,28 +1168,28 @@ bool CClientManager::InitializeLandTable()
return true;
}
void parse_pair_number_string(const char * c_pszString, std::vector<std::pair<int, int> > & vec)
void parse_pair_number_string(const char *c_pszString, std::vector<std::pair<int, int>> &vec)
{
// format: 10,1/20,3/300,50
const char * t = c_pszString;
const char * p = strchr(t, '/');
const char *t = c_pszString;
const char *p = strchr(t, '/');
std::pair<int, int> k;
char szNum[32 + 1];
char * comma;
char *comma;
while (p)
{
if (isdigit(*t))
{
strlcpy(szNum, t, std::min<size_t>(sizeof(szNum), (p-t)+1));
strlcpy(szNum, t, std::min<size_t>(sizeof(szNum), (p - t) + 1));
comma = strchr(szNum, ',');
if (comma)
{
*comma = '\0';
str_to_number(k.second, comma+1);
str_to_number(k.second, comma + 1);
}
else
k.second = 0;
@ -1204,12 +1206,12 @@ void parse_pair_number_string(const char * c_pszString, std::vector<std::pair<in
{
strlcpy(szNum, t, sizeof(szNum));
comma = strchr(const_cast<char*>(t), ',');
comma = strchr(const_cast<char *>(t), ',');
if (comma)
{
*comma = '\0';
str_to_number(k.second, comma+1);
str_to_number(k.second, comma + 1);
}
else
k.second = 0;
@ -1230,7 +1232,7 @@ bool CClientManager::InitializeObjectProto()
GetTablePostfix());
std::unique_ptr<SQLMsg> pkMsg(CDBManager::instance().DirectQuery(query));
SQLResult * pRes = pkMsg->Get();
SQLResult *pRes = pkMsg->Get();
if (!m_vec_kObjectProto.empty())
{
@ -1254,12 +1256,12 @@ bool CClientManager::InitializeObjectProto()
str_to_number(t.dwVnum, data[col++]);
str_to_number(t.dwPrice, data[col++]);
std::vector<std::pair<int, int> > vec;
std::vector<std::pair<int, int>> vec;
parse_pair_number_string(data[col++], vec);
for (unsigned int i = 0; i < OBJECT_MATERIAL_MAX_NUM && i < vec.size(); ++i)
{
std::pair<int, int> & r = vec[i];
std::pair<int, int> &r = vec[i];
t.kMaterials[i].dwItemVnum = r.first;
t.kMaterials[i].dwCount = r.second;
@ -1279,7 +1281,7 @@ bool CClientManager::InitializeObjectProto()
str_to_number(t.dwDependOnGroupVnum, data[col++]);
t.lNPCX = 0;
t.lNPCY = std::max(t.lRegion[1], t.lRegion[3])+300;
t.lNPCY = std::max(t.lRegion[1], t.lRegion[3]) + 300;
// END_OF_ADD_BUILDING_NPC
SPDLOG_TRACE("OBJ_PROTO: vnum {} price {} mat {} {}",
@ -1299,7 +1301,7 @@ bool CClientManager::InitializeObjectTable()
snprintf(query, sizeof(query), "SELECT id, land_id, vnum, map_index, x, y, x_rot, y_rot, z_rot, life FROM object%s ORDER BY id", GetTablePostfix());
std::unique_ptr<SQLMsg> pkMsg(CDBManager::instance().DirectQuery(query));
SQLResult * pRes = pkMsg->Get();
SQLResult *pRes = pkMsg->Get();
if (!m_map_pkObjectTable.empty())
{
@ -1312,7 +1314,7 @@ bool CClientManager::InitializeObjectTable()
if (pRes->uiNumRows > 0)
while ((data = mysql_fetch_row(pRes->pSQLResult)))
{
TObject * k = new TObject;
TObject *k = new TObject;
memset(k, 0, sizeof(TObject));
@ -1349,7 +1351,7 @@ bool CClientManager::MirrorMobTableIntoDB()
{
for (itertype(m_vec_mobTable) it = m_vec_mobTable.begin(); it != m_vec_mobTable.end(); it++)
{
const TMobTable& t = *it;
const TMobTable &t = *it;
char query[4096];
if (g_stLocaleNameColumn == "name")
{
@ -1388,7 +1390,7 @@ bool CClientManager::MirrorMobTableIntoDB()
")",
GetTablePostfix(), /*g_stLocaleNameColumn.c_str(),*/
t.dwVnum, t.szName, /*t.szLocaleName, */t.bType, t.bRank, t.bBattleType, t.bLevel, t.bSize, t.dwAIFlag, t.dwRaceFlag, t.dwImmuneFlag,
t.dwVnum, t.szName, /*t.szLocaleName, */ t.bType, t.bRank, t.bBattleType, t.bLevel, t.bSize, t.dwAIFlag, t.dwRaceFlag, t.dwImmuneFlag,
t.bOnClickType, t.bEmpire, t.dwDropItemVnum, t.dwResurrectionVnum, t.szFolder,
t.bStr, t.bDex, t.bCon, t.bInt, t.dwDamageRange[0], t.dwDamageRange[1], t.dwMaxHP, t.bRegenCycle, t.bRegenPercent, t.dwExp,
@ -1400,8 +1402,7 @@ bool CClientManager::MirrorMobTableIntoDB()
t.Skills[0].dwVnum, t.Skills[0].bLevel, t.Skills[1].dwVnum, t.Skills[1].bLevel, t.Skills[2].dwVnum, t.Skills[2].bLevel,
t.Skills[3].dwVnum, t.Skills[3].bLevel, t.Skills[4].dwVnum, t.Skills[4].bLevel,
t.bBerserkPoint, t.bStoneSkinPoint, t.bGodSpeedPoint, t.bDeathBlowPoint, t.bRevivePoint
);
t.bBerserkPoint, t.bStoneSkinPoint, t.bGodSpeedPoint, t.bDeathBlowPoint, t.bRevivePoint);
}
else
{
@ -1452,8 +1453,7 @@ bool CClientManager::MirrorMobTableIntoDB()
t.Skills[0].dwVnum, t.Skills[0].bLevel, t.Skills[1].dwVnum, t.Skills[1].bLevel, t.Skills[2].dwVnum, t.Skills[2].bLevel,
t.Skills[3].dwVnum, t.Skills[3].bLevel, t.Skills[4].dwVnum, t.Skills[4].bLevel,
t.bBerserkPoint, t.bStoneSkinPoint, t.bGodSpeedPoint, t.bDeathBlowPoint, t.bRevivePoint
);
t.bBerserkPoint, t.bStoneSkinPoint, t.bGodSpeedPoint, t.bDeathBlowPoint, t.bRevivePoint);
}
CDBManager::instance().AsyncQuery(query);
@ -1467,7 +1467,7 @@ bool CClientManager::MirrorItemTableIntoDB()
{
if (g_stLocaleNameColumn != "name")
{
const TItemTable& t = *it;
const TItemTable &t = *it;
char query[4096];
snprintf(query, sizeof(query),
"replace into item_proto%s ("
@ -1495,7 +1495,7 @@ bool CClientManager::MirrorItemTableIntoDB()
}
else
{
const TItemTable& t = *it;
const TItemTable &t = *it;
char query[4096];
snprintf(query, sizeof(query),
"replace into item_proto%s ("

View File

@ -12,7 +12,7 @@ void CClientManager::LoadEventFlag()
snprintf(szQuery, sizeof(szQuery), "SELECT szName, lValue FROM quest%s WHERE dwPID = 0", GetTablePostfix());
std::unique_ptr<SQLMsg> pmsg(CDBManager::instance().DirectQuery(szQuery));
SQLResult* pRes = pmsg->Get();
SQLResult *pRes = pmsg->Get();
if (pRes->uiNumRows)
{
MYSQL_ROW row;
@ -28,7 +28,7 @@ void CClientManager::LoadEventFlag()
}
}
void CClientManager::SetEventFlag(TPacketSetEventFlag* p)
void CClientManager::SetEventFlag(TPacketSetEventFlag *p)
{
ForwardPacket(HEADER_DG_SET_EVENT_FLAG, p, sizeof(TPacketSetEventFlag));
@ -54,7 +54,7 @@ void CClientManager::SetEventFlag(TPacketSetEventFlag* p)
GetTablePostfix(), p->szFlagName, p->lValue);
szQuery[1023] = '\0';
//CDBManager::instance().ReturnQuery(szQuery, QID_QUEST_SAVE, 0, NULL);
// CDBManager::instance().ReturnQuery(szQuery, QID_QUEST_SAVE, 0, NULL);
CDBManager::instance().AsyncQuery(szQuery);
SPDLOG_DEBUG("HEADER_GD_SET_EVENT_FLAG : Changed CClientmanager::SetEventFlag({} {}) ", p->szFlagName, p->lValue);
return;
@ -62,7 +62,7 @@ void CClientManager::SetEventFlag(TPacketSetEventFlag* p)
SPDLOG_DEBUG("HEADER_GD_SET_EVENT_FLAG : No Changed CClientmanager::SetEventFlag({} {}) ", p->szFlagName, p->lValue);
}
void CClientManager::SendEventFlagsOnSetup(CPeer* peer)
void CClientManager::SendEventFlagsOnSetup(CPeer *peer)
{
typeof(m_map_lEventFlag.begin()) it;
for (it = m_map_lEventFlag.begin(); it != m_map_lEventFlag.end(); ++it)
@ -74,4 +74,3 @@ void CClientManager::SendEventFlagsOnSetup(CPeer* peer)
peer->Encode(&p, sizeof(TPacketSetEventFlag));
}
}

View File

@ -7,8 +7,7 @@
#include "QID.h"
#include "GuildManager.h"
void CClientManager::GuildCreate(CPeer * peer, DWORD dwGuildID)
void CClientManager::GuildCreate(CPeer *peer, DWORD dwGuildID)
{
SPDLOG_DEBUG("GuildCreate {}", dwGuildID);
ForwardPacket(HEADER_DG_GUILD_LOAD, &dwGuildID, sizeof(DWORD));
@ -16,13 +15,13 @@ void CClientManager::GuildCreate(CPeer * peer, DWORD dwGuildID)
CGuildManager::instance().Load(dwGuildID);
}
void CClientManager::GuildChangeGrade(CPeer* peer, TPacketGuild* p)
void CClientManager::GuildChangeGrade(CPeer *peer, TPacketGuild *p)
{
SPDLOG_DEBUG("GuildChangeGrade {} {}", p->dwGuild, p->dwInfo);
ForwardPacket(HEADER_DG_GUILD_CHANGE_GRADE, p, sizeof(TPacketGuild));
}
void CClientManager::GuildAddMember(CPeer* peer, TPacketGDGuildAddMember * p)
void CClientManager::GuildAddMember(CPeer *peer, TPacketGDGuildAddMember *p)
{
CGuildManager::instance().TouchGuild(p->dwGuild);
SPDLOG_DEBUG("GuildAddMember {} {}", p->dwGuild, p->dwPID);
@ -65,7 +64,7 @@ void CClientManager::GuildAddMember(CPeer* peer, TPacketGDGuildAddMember * p)
ForwardPacket(HEADER_DG_GUILD_ADD_MEMBER, &dg, sizeof(TPacketDGGuildMember));
}
void CClientManager::GuildRemoveMember(CPeer* peer, TPacketGuild* p)
void CClientManager::GuildRemoveMember(CPeer *peer, TPacketGuild *p)
{
SPDLOG_DEBUG("GuildRemoveMember {} {}", p->dwGuild, p->dwInfo);
@ -73,31 +72,31 @@ void CClientManager::GuildRemoveMember(CPeer* peer, TPacketGuild* p)
snprintf(szQuery, sizeof(szQuery), "DELETE FROM guild_member%s WHERE pid=%u and guild_id=%u", GetTablePostfix(), p->dwInfo, p->dwGuild);
CDBManager::instance().AsyncQuery(szQuery);
snprintf(szQuery, sizeof(szQuery), "REPLACE INTO quest%s (dwPID, szName, szState, lValue) VALUES(%u, 'guild_manage', 'withdraw_time', %u)", GetTablePostfix(), p->dwInfo, (DWORD) GetCurrentTime());
snprintf(szQuery, sizeof(szQuery), "REPLACE INTO quest%s (dwPID, szName, szState, lValue) VALUES(%u, 'guild_manage', 'withdraw_time', %u)", GetTablePostfix(), p->dwInfo, (DWORD)GetCurrentTime());
CDBManager::instance().AsyncQuery(szQuery);
ForwardPacket(HEADER_DG_GUILD_REMOVE_MEMBER, p, sizeof(TPacketGuild));
}
void CClientManager::GuildSkillUpdate(CPeer* peer, TPacketGuildSkillUpdate* p)
void CClientManager::GuildSkillUpdate(CPeer *peer, TPacketGuildSkillUpdate *p)
{
SPDLOG_DEBUG("GuildSkillUpdate {}", p->amount);
ForwardPacket(HEADER_DG_GUILD_SKILL_UPDATE, p, sizeof(TPacketGuildSkillUpdate));
}
void CClientManager::GuildExpUpdate(CPeer* peer, TPacketGuildExpUpdate* p)
void CClientManager::GuildExpUpdate(CPeer *peer, TPacketGuildExpUpdate *p)
{
SPDLOG_DEBUG("GuildExpUpdate {}", p->amount);
ForwardPacket(HEADER_DG_GUILD_EXP_UPDATE, p, sizeof(TPacketGuildExpUpdate), 0, peer);
}
void CClientManager::GuildChangeMemberData(CPeer* peer, TPacketGuildChangeMemberData* p)
void CClientManager::GuildChangeMemberData(CPeer *peer, TPacketGuildChangeMemberData *p)
{
SPDLOG_DEBUG("GuildChangeMemberData {} {} {} {}", p->pid, p->offer, p->level, p->grade);
ForwardPacket(HEADER_DG_GUILD_CHANGE_MEMBER_DATA, p, sizeof(TPacketGuildChangeMemberData), 0, peer);
}
void CClientManager::GuildDisband(CPeer* peer, TPacketGuild* p)
void CClientManager::GuildDisband(CPeer *peer, TPacketGuild *p)
{
SPDLOG_DEBUG("GuildDisband {}", p->dwGuild);
@ -109,7 +108,7 @@ void CClientManager::GuildDisband(CPeer* peer, TPacketGuild* p)
snprintf(szQuery, sizeof(szQuery), "DELETE FROM guild_grade%s WHERE guild_id=%u", GetTablePostfix(), p->dwGuild);
CDBManager::instance().AsyncQuery(szQuery);
snprintf(szQuery, sizeof(szQuery), "REPLACE INTO quest%s (dwPID, szName, szState, lValue) SELECT pid, 'guild_manage', 'withdraw_time', %u FROM guild_member%s WHERE guild_id = %u", GetTablePostfix(), (DWORD) GetCurrentTime(), GetTablePostfix(), p->dwGuild);
snprintf(szQuery, sizeof(szQuery), "REPLACE INTO quest%s (dwPID, szName, szState, lValue) SELECT pid, 'guild_manage', 'withdraw_time', %u FROM guild_member%s WHERE guild_id = %u", GetTablePostfix(), (DWORD)GetCurrentTime(), GetTablePostfix(), p->dwGuild);
CDBManager::instance().AsyncQuery(szQuery);
snprintf(szQuery, sizeof(szQuery), "DELETE FROM guild_member%s WHERE guild_id=%u", GetTablePostfix(), p->dwGuild);
@ -121,22 +120,22 @@ void CClientManager::GuildDisband(CPeer* peer, TPacketGuild* p)
ForwardPacket(HEADER_DG_GUILD_DISBAND, p, sizeof(TPacketGuild));
}
const char* __GetWarType(int n)
const char *__GetWarType(int n)
{
switch (n)
{
case 0 :
case 0:
return "\xEF\xBF\xBD\xD0\xBF\xEF\xBF\xBD"; // 패왕
case 1 :
case 1:
return "\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD"; // 맹장
case 2 :
case 2:
return "\xEF\xBF\xBD\xEF\xBF\xBD\xC8\xA3"; // 수호
default :
default:
return "\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\x20\xEF\xBF\xBD\xEF\xBF\xBD\xC8\xA3"; // 없는 번호
}
}
void CClientManager::GuildWar(CPeer* peer, TPacketGuildWar* p)
void CClientManager::GuildWar(CPeer *peer, TPacketGuildWar *p)
{
switch (p->bWar)
{
@ -189,7 +188,7 @@ void CClientManager::GuildWar(CPeer* peer, TPacketGuildWar* p)
CGuildManager::instance().RecvWarEnd(p->dwGuildFrom, p->dwGuildTo);
return; // NOTE: RecvWarEnd에서 패킷을 보내므로 따로 브로드캐스팅 하지 않는다.
case GUILD_WAR_CANCEL :
case GUILD_WAR_CANCEL:
SPDLOG_DEBUG("GuildWar: GUILD_WAR_CANCEL type({}) guild({} - {})", __GetWarType(p->bType), p->dwGuildFrom, p->dwGuildTo);
CGuildManager::instance().CancelWar(p->dwGuildFrom, p->dwGuildTo);
break;
@ -198,18 +197,18 @@ void CClientManager::GuildWar(CPeer* peer, TPacketGuildWar* p)
ForwardPacket(HEADER_DG_GUILD_WAR, p, sizeof(TPacketGuildWar));
}
void CClientManager::GuildWarScore(CPeer* peer, TPacketGuildWarScore * p)
void CClientManager::GuildWarScore(CPeer *peer, TPacketGuildWarScore *p)
{
CGuildManager::instance().UpdateScore(p->dwGuildGainPoint, p->dwGuildOpponent, p->lScore, p->lBetScore);
}
void CClientManager::GuildChangeLadderPoint(TPacketGuildLadderPoint* p)
void CClientManager::GuildChangeLadderPoint(TPacketGuildLadderPoint *p)
{
SPDLOG_DEBUG("GuildChangeLadderPoint Recv {} {}", p->dwGuild, p->lChange);
CGuildManager::instance().ChangeLadderPoint(p->dwGuild, p->lChange);
}
void CClientManager::GuildUseSkill(TPacketGuildUseSkill* p)
void CClientManager::GuildUseSkill(TPacketGuildUseSkill *p)
{
SPDLOG_DEBUG("GuildUseSkill Recv {} {}", p->dwGuild, p->dwSkillVnum);
CGuildManager::instance().UseSkill(p->dwGuild, p->dwSkillVnum, p->dwCooltime);
@ -218,7 +217,7 @@ void CClientManager::GuildUseSkill(TPacketGuildUseSkill* p)
void CClientManager::SendGuildSkillUsable(DWORD guild_id, DWORD dwSkillVnum, bool bUsable)
{
SPDLOG_DEBUG("SendGuildSkillUsable Send {} {} {}", guild_id, dwSkillVnum, bUsable?"true":"false");
SPDLOG_DEBUG("SendGuildSkillUsable Send {} {} {}", guild_id, dwSkillVnum, bUsable ? "true" : "false");
TPacketGuildSkillUsableChange p;
@ -229,7 +228,7 @@ void CClientManager::SendGuildSkillUsable(DWORD guild_id, DWORD dwSkillVnum, boo
ForwardPacket(HEADER_DG_GUILD_SKILL_USABLE_CHANGE, &p, sizeof(TPacketGuildSkillUsableChange));
}
void CClientManager::GuildChangeMaster(TPacketChangeGuildMaster* p)
void CClientManager::GuildChangeMaster(TPacketChangeGuildMaster *p)
{
if (CGuildManager::instance().ChangeMaster(p->dwGuildID, p->idFrom, p->idTo) == true)
{
@ -241,4 +240,3 @@ void CClientManager::GuildChangeMaster(TPacketChangeGuildMaster* p)
ForwardPacket(HEADER_DG_ACK_CHANGE_GUILD_MASTER, &packet, sizeof(packet));
}
}

View File

@ -2,7 +2,7 @@
#include "stdafx.h"
#include "ClientManager.h"
void CClientManager::UpdateHorseName(TPacketUpdateHorseName* data, CPeer* peer)
void CClientManager::UpdateHorseName(TPacketUpdateHorseName *data, CPeer *peer)
{
char szQuery[512];
@ -13,7 +13,7 @@ void CClientManager::UpdateHorseName(TPacketUpdateHorseName* data, CPeer* peer)
ForwardPacket(HEADER_DG_UPDATE_HORSE_NAME, data, sizeof(TPacketUpdateHorseName), 0, peer);
}
void CClientManager::AckHorseName(DWORD dwPID, CPeer* peer)
void CClientManager::AckHorseName(DWORD dwPID, CPeer *peer)
{
char szQuery[512];
@ -26,7 +26,7 @@ void CClientManager::AckHorseName(DWORD dwPID, CPeer* peer)
if (pmsg->Get()->uiNumRows == 0)
{
memset(packet.szHorseName, 0, sizeof (packet.szHorseName));
memset(packet.szHorseName, 0, sizeof(packet.szHorseName));
}
else
{
@ -37,4 +37,3 @@ void CClientManager::AckHorseName(DWORD dwPID, CPeer* peer)
peer->EncodeHeader(HEADER_DG_ACK_HORSE_NAME, 0, sizeof(TPacketUpdateHorseName));
peer->Encode(&packet, sizeof(TPacketUpdateHorseName));
}

View File

@ -9,10 +9,10 @@
#include "Cache.h"
extern std::string g_stLocale;
extern bool CreatePlayerTableFromRes(MYSQL_RES * res, TPlayerTable * pkTab);
extern bool CreatePlayerTableFromRes(MYSQL_RES *res, TPlayerTable *pkTab);
extern int g_test_server;
bool CClientManager::InsertLogonAccount(const char * c_pszLogin, DWORD dwHandle, const char * c_pszIP)
bool CClientManager::InsertLogonAccount(const char *c_pszLogin, DWORD dwHandle, const char *c_pszIP)
{
char szLogin[LOGIN_MAX_LEN + 1];
trim_and_lower(c_pszLogin, szLogin, sizeof(szLogin));
@ -22,7 +22,7 @@ bool CClientManager::InsertLogonAccount(const char * c_pszLogin, DWORD dwHandle,
if (m_map_kLogonAccount.end() != it)
return false;
CLoginData * pkLD = GetLoginDataByLogin(c_pszLogin);
CLoginData *pkLD = GetLoginDataByLogin(c_pszLogin);
if (!pkLD)
return false;
@ -34,7 +34,7 @@ bool CClientManager::InsertLogonAccount(const char * c_pszLogin, DWORD dwHandle,
return true;
}
bool CClientManager::DeleteLogonAccount(const char * c_pszLogin, DWORD dwHandle)
bool CClientManager::DeleteLogonAccount(const char *c_pszLogin, DWORD dwHandle)
{
char szLogin[LOGIN_MAX_LEN + 1];
trim_and_lower(c_pszLogin, szLogin, sizeof(szLogin));
@ -44,7 +44,7 @@ bool CClientManager::DeleteLogonAccount(const char * c_pszLogin, DWORD dwHandle)
if (it == m_map_kLogonAccount.end())
return false;
CLoginData * pkLD = it->second;
CLoginData *pkLD = it->second;
if (pkLD->GetConnectedPeerHandle() != dwHandle)
{
@ -66,7 +66,7 @@ bool CClientManager::DeleteLogonAccount(const char * c_pszLogin, DWORD dwHandle)
return true;
}
bool CClientManager::FindLogonAccount(const char * c_pszLogin)
bool CClientManager::FindLogonAccount(const char *c_pszLogin)
{
char szLogin[LOGIN_MAX_LEN + 1];
trim_and_lower(c_pszLogin, szLogin, sizeof(szLogin));
@ -77,9 +77,9 @@ bool CClientManager::FindLogonAccount(const char * c_pszLogin)
return true;
}
void CClientManager::QUERY_LOGIN_BY_KEY(CPeer * pkPeer, DWORD dwHandle, TPacketGDLoginByKey * p)
void CClientManager::QUERY_LOGIN_BY_KEY(CPeer *pkPeer, DWORD dwHandle, TPacketGDLoginByKey *p)
{
CLoginData * pkLoginData = GetLoginData(p->dwLoginKey);
CLoginData *pkLoginData = GetLoginData(p->dwLoginKey);
char szLogin[LOGIN_MAX_LEN + 1];
trim_and_lower(p->szLogin, szLogin, sizeof(szLogin));
@ -90,7 +90,7 @@ void CClientManager::QUERY_LOGIN_BY_KEY(CPeer * pkPeer, DWORD dwHandle, TPacketG
return;
}
TAccountTable & r = pkLoginData->GetAccountRef();
TAccountTable &r = pkLoginData->GetAccountRef();
if (FindLogonAccount(r.login))
{
@ -111,7 +111,7 @@ void CClientManager::QUERY_LOGIN_BY_KEY(CPeer * pkPeer, DWORD dwHandle, TPacketG
if (memcmp(pkLoginData->GetClientKey(), p->adwClientKey, sizeof(DWORD) * 4))
{
const DWORD * pdwClientKey = pkLoginData->GetClientKey();
const DWORD *pdwClientKey = pkLoginData->GetClientKey();
SPDLOG_DEBUG("LOGIN_BY_KEY client key differ {} {} {} {} {}, {} {} {} {}",
r.login,
@ -122,7 +122,7 @@ void CClientManager::QUERY_LOGIN_BY_KEY(CPeer * pkPeer, DWORD dwHandle, TPacketG
return;
}
TAccountTable * pkTab = new TAccountTable;
TAccountTable *pkTab = new TAccountTable;
memset(pkTab, 0, sizeof(TAccountTable));
pkTab->id = r.id;
@ -131,7 +131,7 @@ void CClientManager::QUERY_LOGIN_BY_KEY(CPeer * pkPeer, DWORD dwHandle, TPacketG
strlcpy(pkTab->social_id, r.social_id, sizeof(pkTab->social_id));
strlcpy(pkTab->status, "OK", sizeof(pkTab->status));
ClientHandleInfo * info = new ClientHandleInfo(dwHandle);
ClientHandleInfo *info = new ClientHandleInfo(dwHandle);
info->pAccountTable = pkTab;
strlcpy(info->ip, p->szIP, sizeof(info->ip));
@ -141,10 +141,10 @@ void CClientManager::QUERY_LOGIN_BY_KEY(CPeer * pkPeer, DWORD dwHandle, TPacketG
CDBManager::instance().ReturnQuery(szQuery, QID_LOGIN_BY_KEY, pkPeer->GetHandle(), info);
}
void CClientManager::RESULT_LOGIN_BY_KEY(CPeer * peer, SQLMsg * msg)
void CClientManager::RESULT_LOGIN_BY_KEY(CPeer *peer, SQLMsg *msg)
{
CQueryInfo * qi = (CQueryInfo *) msg->pvUserData;
ClientHandleInfo * info = (ClientHandleInfo *) qi->pvData;
CQueryInfo *qi = (CQueryInfo *)msg->pvUserData;
ClientHandleInfo *info = (ClientHandleInfo *)qi->pvData;
if (msg->uiSQLErrno != 0)
{
@ -169,7 +169,7 @@ void CClientManager::RESULT_LOGIN_BY_KEY(CPeer * peer, SQLMsg * msg)
SPDLOG_DEBUG("RESULT_LOGIN_BY_KEY FAIL player_index's NULL : ID:{}", account_id);
// PLAYER_INDEX_CREATE_BUG_FIX
//snprintf(szQuery, sizeof(szQuery), "INSERT IGNORE INTO player_index%s (id) VALUES(%lu)", GetTablePostfix(), info->pAccountTable->id);
// snprintf(szQuery, sizeof(szQuery), "INSERT IGNORE INTO player_index%s (id) VALUES(%lu)", GetTablePostfix(), info->pAccountTable->id);
snprintf(szQuery, sizeof(szQuery), "INSERT INTO player_index%s (id) VALUES(%u)", GetTablePostfix(), info->pAccountTable->id);
CDBManager::instance().ReturnQuery(szQuery, QID_PLAYER_INDEX_CREATE, peer->GetHandle(), info);
// END_PLAYER_INDEX_CREATE_BUF_FIX
@ -205,10 +205,10 @@ void CClientManager::RESULT_LOGIN_BY_KEY(CPeer * peer, SQLMsg * msg)
}
// PLAYER_INDEX_CREATE_BUG_FIX
void CClientManager::RESULT_PLAYER_INDEX_CREATE(CPeer * pkPeer, SQLMsg * msg)
void CClientManager::RESULT_PLAYER_INDEX_CREATE(CPeer *pkPeer, SQLMsg *msg)
{
CQueryInfo * qi = (CQueryInfo *) msg->pvUserData;
ClientHandleInfo * info = (ClientHandleInfo *) qi->pvData;
CQueryInfo *qi = (CQueryInfo *)msg->pvUserData;
ClientHandleInfo *info = (ClientHandleInfo *)qi->pvData;
char szQuery[QUERY_MAX_LEN];
snprintf(szQuery, sizeof(szQuery), "SELECT pid1, pid2, pid3, pid4, empire FROM player_index%s WHERE id=%u", GetTablePostfix(),
@ -217,7 +217,7 @@ void CClientManager::RESULT_PLAYER_INDEX_CREATE(CPeer * pkPeer, SQLMsg * msg)
}
// END_PLAYER_INDEX_CREATE_BUG_FIX
TAccountTable * CreateAccountTableFromRes(MYSQL_RES * res)
TAccountTable *CreateAccountTableFromRes(MYSQL_RES *res)
{
char input_pwd[PASSWD_MAX_LEN + 1];
MYSQL_ROW row = NULL;
@ -226,7 +226,7 @@ TAccountTable * CreateAccountTableFromRes(MYSQL_RES * res)
row = mysql_fetch_row(res);
col = 0;
TAccountTable * pkTab = new TAccountTable;
TAccountTable *pkTab = new TAccountTable;
memset(pkTab, 0, sizeof(TAccountTable));
// 첫번째 컬럼 것만 참고 한다 (JOIN QUERY를 위한 것 임)
@ -251,7 +251,7 @@ TAccountTable * CreateAccountTableFromRes(MYSQL_RES * res)
return pkTab;
}
void CreateAccountPlayerDataFromRes(MYSQL_RES * pRes, TAccountTable * pkTab)
void CreateAccountPlayerDataFromRes(MYSQL_RES *pRes, TAccountTable *pkTab)
{
if (!pRes)
return;
@ -273,8 +273,8 @@ void CreateAccountPlayerDataFromRes(MYSQL_RES * pRes, TAccountTable * pkTab)
{
if (pkTab->players[j].dwID == player_id)
{
CPlayerTableCache * pc = CClientManager::instance().GetPlayerCache(player_id);
TPlayerTable * pt = pc ? pc->Get(false) : NULL;
CPlayerTableCache *pc = CClientManager::instance().GetPlayerCache(player_id);
TPlayerTable *pt = pc ? pc->Get(false) : NULL;
if (pt)
{
@ -346,10 +346,10 @@ void CreateAccountPlayerDataFromRes(MYSQL_RES * pRes, TAccountTable * pkTab)
}
}
void CClientManager::RESULT_LOGIN(CPeer * peer, SQLMsg * msg)
void CClientManager::RESULT_LOGIN(CPeer *peer, SQLMsg *msg)
{
CQueryInfo * qi = (CQueryInfo *) msg->pvUserData;
ClientHandleInfo * info = (ClientHandleInfo *) qi->pvData;
CQueryInfo *qi = (CQueryInfo *)msg->pvUserData;
ClientHandleInfo *info = (ClientHandleInfo *)qi->pvData;
if (info->account_index == 0)
{
@ -420,14 +420,13 @@ void CClientManager::RESULT_LOGIN(CPeer * peer, SQLMsg * msg)
if (msg->Get()->uiNumRows > 0)
CreateAccountPlayerDataFromRes(msg->Get()->pSQLResult, info->pAccountTable);
//PREVENT_COPY_ITEM
CLoginData * p = GetLoginDataByLogin(info->pAccountTable->login);
// PREVENT_COPY_ITEM
CLoginData *p = GetLoginDataByLogin(info->pAccountTable->login);
memcpy(&p->GetAccountRef(), info->pAccountTable, sizeof(TAccountTable));
//END_PREVENT_COPY_ITEM
// END_PREVENT_COPY_ITEM
peer->EncodeHeader(HEADER_DG_LOGIN_SUCCESS, info->dwHandle, sizeof(TAccountTable));
peer->Encode(info->pAccountTable, sizeof(TAccountTable));
}
delete info->pAccountTable;
@ -436,14 +435,14 @@ void CClientManager::RESULT_LOGIN(CPeer * peer, SQLMsg * msg)
}
}
void CClientManager::QUERY_LOGOUT(CPeer * peer, DWORD dwHandle,const char * data)
void CClientManager::QUERY_LOGOUT(CPeer *peer, DWORD dwHandle, const char *data)
{
TLogoutPacket* packet = (TLogoutPacket*)data;
TLogoutPacket *packet = (TLogoutPacket *)data;
if (!*packet->login)
return;
CLoginData * pLoginData = GetLoginDataByLogin(packet->login);
CLoginData *pLoginData = GetLoginDataByLogin(packet->login);
if (pLoginData == NULL)
return;
@ -471,7 +470,7 @@ void CClientManager::QUERY_LOGOUT(CPeer * peer, DWORD dwHandle,const char * data
}
}
void CClientManager::QUERY_CHANGE_NAME(CPeer * peer, DWORD dwHandle, TPacketGDChangeName * p)
void CClientManager::QUERY_CHANGE_NAME(CPeer *peer, DWORD dwHandle, TPacketGDChangeName *p)
{
char queryStr[QUERY_MAX_LEN];
@ -518,4 +517,3 @@ void CClientManager::QUERY_CHANGE_NAME(CPeer * peer, DWORD dwHandle, TPacketGDCh
strlcpy(pdg.name, p->name, sizeof(pdg.name));
peer->Encode(&pdg, sizeof(TPacketDGChangeName));
}

View File

@ -5,9 +5,9 @@
#include "DBManager.h"
#include "QID.h"
void CClientManager::QUERY_PARTY_CREATE(CPeer* peer, TPacketPartyCreate* p)
void CClientManager::QUERY_PARTY_CREATE(CPeer *peer, TPacketPartyCreate *p)
{
TPartyMap & pm = m_map_pkChannelParty[peer->GetChannel()];
TPartyMap &pm = m_map_pkChannelParty[peer->GetChannel()];
if (pm.find(p->dwLeaderPID) == pm.end())
{
@ -21,9 +21,9 @@ void CClientManager::QUERY_PARTY_CREATE(CPeer* peer, TPacketPartyCreate* p)
}
}
void CClientManager::QUERY_PARTY_DELETE(CPeer* peer, TPacketPartyDelete* p)
void CClientManager::QUERY_PARTY_DELETE(CPeer *peer, TPacketPartyDelete *p)
{
TPartyMap& pm = m_map_pkChannelParty[peer->GetChannel()];
TPartyMap &pm = m_map_pkChannelParty[peer->GetChannel()];
itertype(pm) it = pm.find(p->dwLeaderPID);
if (it == pm.end())
@ -37,9 +37,9 @@ void CClientManager::QUERY_PARTY_DELETE(CPeer* peer, TPacketPartyDelete* p)
SPDLOG_DEBUG("PARTY Delete [{}]", p->dwLeaderPID);
}
void CClientManager::QUERY_PARTY_ADD(CPeer* peer, TPacketPartyAdd* p)
void CClientManager::QUERY_PARTY_ADD(CPeer *peer, TPacketPartyAdd *p)
{
TPartyMap & pm = m_map_pkChannelParty[peer->GetChannel()];
TPartyMap &pm = m_map_pkChannelParty[peer->GetChannel()];
itertype(pm) it = pm.find(p->dwLeaderPID);
if (it == pm.end())
@ -58,14 +58,14 @@ void CClientManager::QUERY_PARTY_ADD(CPeer* peer, TPacketPartyAdd* p)
SPDLOG_ERROR("PARTY Add - Already [{}] in party [{}]", p->dwPID, p->dwLeaderPID);
}
void CClientManager::QUERY_PARTY_REMOVE(CPeer* peer, TPacketPartyRemove* p)
void CClientManager::QUERY_PARTY_REMOVE(CPeer *peer, TPacketPartyRemove *p)
{
TPartyMap & pm = m_map_pkChannelParty[peer->GetChannel()];
TPartyMap &pm = m_map_pkChannelParty[peer->GetChannel()];
itertype(pm) it = pm.find(p->dwLeaderPID);
if (it == pm.end())
{
SPDLOG_ERROR("PARTY Remove - Non exists [{}] cannot remove [{}]",p->dwLeaderPID, p->dwPID);
SPDLOG_ERROR("PARTY Remove - Non exists [{}] cannot remove [{}]", p->dwLeaderPID, p->dwPID);
return;
}
@ -81,14 +81,14 @@ void CClientManager::QUERY_PARTY_REMOVE(CPeer* peer, TPacketPartyRemove* p)
SPDLOG_ERROR("PARTY Remove - Cannot find [{}] in party [{}]", p->dwPID, p->dwLeaderPID);
}
void CClientManager::QUERY_PARTY_STATE_CHANGE(CPeer* peer, TPacketPartyStateChange* p)
void CClientManager::QUERY_PARTY_STATE_CHANGE(CPeer *peer, TPacketPartyStateChange *p)
{
TPartyMap & pm = m_map_pkChannelParty[peer->GetChannel()];
TPartyMap &pm = m_map_pkChannelParty[peer->GetChannel()];
itertype(pm) it = pm.find(p->dwLeaderPID);
if (it == pm.end())
{
SPDLOG_ERROR("PARTY StateChange - Non exists [{}] cannot state change [{}]",p->dwLeaderPID, p->dwPID);
SPDLOG_ERROR("PARTY StateChange - Non exists [{}] cannot state change [{}]", p->dwLeaderPID, p->dwPID);
return;
}
@ -106,17 +106,17 @@ void CClientManager::QUERY_PARTY_STATE_CHANGE(CPeer* peer, TPacketPartyStateChan
pit->second.bRole = 0;
ForwardPacket(HEADER_DG_PARTY_STATE_CHANGE, p, sizeof(TPacketPartyStateChange), peer->GetChannel(), peer);
SPDLOG_DEBUG("PARTY StateChange [{}] at [{}] from {} {}",p->dwPID, p->dwLeaderPID, p->bRole, p->bFlag);
SPDLOG_DEBUG("PARTY StateChange [{}] at [{}] from {} {}", p->dwPID, p->dwLeaderPID, p->bRole, p->bFlag);
}
void CClientManager::QUERY_PARTY_SET_MEMBER_LEVEL(CPeer* peer, TPacketPartySetMemberLevel* p)
void CClientManager::QUERY_PARTY_SET_MEMBER_LEVEL(CPeer *peer, TPacketPartySetMemberLevel *p)
{
TPartyMap & pm = m_map_pkChannelParty[peer->GetChannel()];
TPartyMap &pm = m_map_pkChannelParty[peer->GetChannel()];
itertype(pm) it = pm.find(p->dwLeaderPID);
if (it == pm.end())
{
SPDLOG_ERROR("PARTY SetMemberLevel - Non exists [{}] cannot level change [{}]",p->dwLeaderPID, p->dwPID);
SPDLOG_ERROR("PARTY SetMemberLevel - Non exists [{}] cannot level change [{}]", p->dwLeaderPID, p->dwPID);
return;
}
@ -131,5 +131,5 @@ void CClientManager::QUERY_PARTY_SET_MEMBER_LEVEL(CPeer* peer, TPacketPartySetMe
pit->second.bLevel = p->bLevel;
ForwardPacket(HEADER_DG_PARTY_SET_MEMBER_LEVEL, p, sizeof(TPacketPartySetMemberLevel), peer->GetChannel());
SPDLOG_DEBUG("PARTY SetMemberLevel pid [{}] level {}",p->dwPID, p->bLevel);
SPDLOG_DEBUG("PARTY SetMemberLevel pid [{}] level {}", p->dwPID, p->bLevel);
}

View File

@ -18,7 +18,7 @@ extern int g_test_server;
//
// Check all SELECT syntax on item table before change this function!!!
//
bool CreateItemTableFromRes(MYSQL_RES * res, std::vector<TPlayerItem> * pVec, DWORD dwPID)
bool CreateItemTableFromRes(MYSQL_RES *res, std::vector<TPlayerItem> *pVec, DWORD dwPID)
{
if (!res)
{
@ -39,7 +39,7 @@ bool CreateItemTableFromRes(MYSQL_RES * res, std::vector<TPlayerItem> * pVec, DW
for (int i = 0; i < rows; ++i)
{
MYSQL_ROW row = mysql_fetch_row(res);
TPlayerItem & item = pVec->at(i);
TPlayerItem &item = pVec->at(i);
int cur = 0;
@ -67,7 +67,7 @@ bool CreateItemTableFromRes(MYSQL_RES * res, std::vector<TPlayerItem> * pVec, DW
return true;
}
size_t CreatePlayerSaveQuery(char * pszQuery, size_t querySize, TPlayerTable * pkTab)
size_t CreatePlayerSaveQuery(char *pszQuery, size_t querySize, TPlayerTable *pkTab)
{
size_t queryLen;
@ -112,8 +112,7 @@ size_t CreatePlayerSaveQuery(char * pszQuery, size_t querySize, TPlayerTable * p
"horse_hp = %d, "
"horse_hp_droptime = %u, "
"horse_stamina = %d, "
"horse_skill_point = %d, "
,
"horse_skill_point = %d, ",
GetTablePostfix(),
pkTab->job,
pkTab->voice,
@ -168,21 +167,21 @@ size_t CreatePlayerSaveQuery(char * pszQuery, size_t querySize, TPlayerTable * p
return queryLen;
}
CPlayerTableCache * CClientManager::GetPlayerCache(DWORD id)
CPlayerTableCache *CClientManager::GetPlayerCache(DWORD id)
{
TPlayerTableCacheMap::iterator it = m_map_playerCache.find(id);
if (it == m_map_playerCache.end())
return NULL;
TPlayerTable* pTable = it->second->Get(false);
TPlayerTable *pTable = it->second->Get(false);
pTable->logoff_interval = GetCurrentTime() - it->second->GetLastUpdateTime();
return it->second;
}
void CClientManager::PutPlayerCache(TPlayerTable * pNew)
void CClientManager::PutPlayerCache(TPlayerTable *pNew)
{
CPlayerTableCache * c;
CPlayerTableCache *c;
c = GetPlayerCache(pNew->id);
@ -198,15 +197,15 @@ void CClientManager::PutPlayerCache(TPlayerTable * pNew)
/*
* PLAYER LOAD
*/
void CClientManager::QUERY_PLAYER_LOAD(CPeer * peer, DWORD dwHandle, TPlayerLoadPacket * packet)
void CClientManager::QUERY_PLAYER_LOAD(CPeer *peer, DWORD dwHandle, TPlayerLoadPacket *packet)
{
CPlayerTableCache * c;
TPlayerTable * pTab;
CPlayerTableCache *c;
TPlayerTable *pTab;
//
// 한 계정에 속한 모든 캐릭터들 캐쉬처리
//
CLoginData * pLoginData = GetLoginDataByAID(packet->account_id);
CLoginData *pLoginData = GetLoginDataByAID(packet->account_id);
if (pLoginData)
{
@ -225,11 +224,11 @@ void CClientManager::QUERY_PLAYER_LOAD(CPeer * peer, DWORD dwHandle, TPlayerLoad
//----------------------------------
if ((c = GetPlayerCache(packet->player_id)))
{
CLoginData * pkLD = GetLoginDataByAID(packet->account_id);
CLoginData *pkLD = GetLoginDataByAID(packet->account_id);
if (!pkLD || pkLD->IsPlay())
{
SPDLOG_DEBUG("PLAYER_LOAD_ERROR: LoginData {} IsPlay {}", (void*) pkLD, pkLD ? pkLD->IsPlay() : 0);
SPDLOG_DEBUG("PLAYER_LOAD_ERROR: LoginData {} IsPlay {}", (void *)pkLD, pkLD ? pkLD->IsPlay() : 0);
peer->EncodeHeader(HEADER_DG_PLAYER_LOAD_FAILED, dwHandle, 0);
return;
}
@ -247,15 +246,17 @@ void CClientManager::QUERY_PLAYER_LOAD(CPeer * peer, DWORD dwHandle, TPlayerLoad
TPacketNeedLoginLogInfo logInfo;
logInfo.dwPlayerID = packet->player_id;
pkLD->SetLastPlayerID( packet->player_id );
pkLD->SetLastPlayerID(packet->player_id);
peer->EncodeHeader( HEADER_DG_NEED_LOGIN_LOG, dwHandle, sizeof(TPacketNeedLoginLogInfo) );
peer->Encode( &logInfo, sizeof(TPacketNeedLoginLogInfo) );
peer->EncodeHeader(HEADER_DG_NEED_LOGIN_LOG, dwHandle, sizeof(TPacketNeedLoginLogInfo));
peer->Encode(&logInfo, sizeof(TPacketNeedLoginLogInfo));
}
char szQuery[1024] = { 0, };
char szQuery[1024] = {
0,
};
TItemCacheSet * pSet = GetItemCacheSet(pTab->id);
TItemCacheSet *pSet = GetItemCacheSet(pTab->id);
SPDLOG_DEBUG("[PLAYER_LOAD] ID {} pid {} gold {} ", pTab->name, pTab->id, pTab->gold);
@ -278,8 +279,8 @@ void CClientManager::QUERY_PLAYER_LOAD(CPeer * peer, DWORD dwHandle, TPlayerLoad
while (it != pSet->end())
{
CItemCache * c = *it++;
TPlayerItem * p = c->Get();
CItemCache *c = *it++;
TPlayerItem *p = c->Get();
if (p->vnum) // vnum이 없으면 삭제된 아이템이다.
memcpy(&s_items[dwCount++], p, sizeof(TPlayerItem));
@ -298,7 +299,7 @@ void CClientManager::QUERY_PLAYER_LOAD(CPeer * peer, DWORD dwHandle, TPlayerLoad
"SELECT dwPID,szName,szState,lValue FROM quest%s WHERE dwPID=%d AND lValue<>0",
GetTablePostfix(), pTab->id);
CDBManager::instance().ReturnQuery(szQuery, QID_QUEST, peer->GetHandle(), new ClientHandleInfo(dwHandle,0,packet->account_id));
CDBManager::instance().ReturnQuery(szQuery, QID_QUEST, peer->GetHandle(), new ClientHandleInfo(dwHandle, 0, packet->account_id));
// Affect
snprintf(szQuery, sizeof(szQuery),
@ -337,8 +338,8 @@ void CClientManager::QUERY_PLAYER_LOAD(CPeer * peer, DWORD dwHandle, TPlayerLoad
peer->GetHandle(),
new ClientHandleInfo(dwHandle, pTab->id));
}
//ljw
//return;
// ljw
// return;
}
//----------------------------------
// 2. 유저정보가 DBCache 에 없음 : DB에서
@ -361,7 +362,7 @@ void CClientManager::QUERY_PLAYER_LOAD(CPeer * peer, DWORD dwHandle, TPlayerLoad
"UNIX_TIMESTAMP(NOW())-UNIX_TIMESTAMP(last_play),horse_skill_point FROM player%s WHERE id=%d",
GetTablePostfix(), packet->player_id);
ClientHandleInfo * pkInfo = new ClientHandleInfo(dwHandle, packet->player_id);
ClientHandleInfo *pkInfo = new ClientHandleInfo(dwHandle, packet->player_id);
pkInfo->account_id = packet->account_id;
CDBManager::instance().ReturnQuery(queryStr, QID_PLAYER, peer->GetHandle(), pkInfo);
@ -380,8 +381,8 @@ void CClientManager::QUERY_PLAYER_LOAD(CPeer * peer, DWORD dwHandle, TPlayerLoad
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도 넘겨준다
CDBManager::instance().ReturnQuery(queryStr, QID_QUEST, peer->GetHandle(), new ClientHandleInfo(dwHandle, packet->player_id, packet->account_id));
// 독일 선물 기능에서 item_award테이블에서 login 정보를 얻기위해 account id도 넘겨준다
//--------------------------------------------------------------
// AFFECT 가져오기
//--------------------------------------------------------------
@ -390,50 +391,48 @@ void CClientManager::QUERY_PLAYER_LOAD(CPeer * peer, DWORD dwHandle, TPlayerLoad
GetTablePostfix(), packet->player_id);
CDBManager::instance().ReturnQuery(queryStr, QID_AFFECT, peer->GetHandle(), new ClientHandleInfo(dwHandle, packet->player_id));
}
}
void CClientManager::ItemAward(CPeer * peer,char* login)
void CClientManager::ItemAward(CPeer *peer, char *login)
{
char login_t[LOGIN_MAX_LEN + 1] = "";
strlcpy(login_t,login,LOGIN_MAX_LEN + 1);
std::set<TItemAward *> * pSet = ItemAwardManager::instance().GetByLogin(login_t);
if(pSet == NULL)
strlcpy(login_t, login, LOGIN_MAX_LEN + 1);
std::set<TItemAward *> *pSet = ItemAwardManager::instance().GetByLogin(login_t);
if (pSet == NULL)
return;
typeof(pSet->begin()) it = pSet->begin(); //taken_time이 NULL인것들 읽어옴
while(it != pSet->end() )
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); //명령어 얻는 과정에서 토큰쓰면 원본도 토큰화 되기 때문
TItemAward *pItemAward = *(it++);
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도 복사
ForwardPacket(HEADER_DG_ITEMAWARD_INFORMER,&giftData,sizeof(TPacketItemAwardInfromer));
strcpy(giftData.login, pItemAward->szLogin); // 로그인 아이디 복사
strcpy(giftData.command, command); // 명령어 복사
giftData.vnum = pItemAward->dwVnum; // 아이템 vnum도 복사
ForwardPacket(HEADER_DG_ITEMAWARD_INFORMER, &giftData, sizeof(TPacketItemAwardInfromer));
}
}
}
std::string CClientManager::GetCommand(char* str)
std::string CClientManager::GetCommand(char *str)
{
char command[20] = "";
char* tok;
char *tok;
if( str[0] == '[' )
if (str[0] == '[')
{
tok = strtok(str,"]");
strcat(command,&tok[1]);
tok = strtok(str, "]");
strcat(command, &tok[1]);
}
return command;
}
bool CreatePlayerTableFromRes(MYSQL_RES * res, TPlayerTable * pkTab)
bool CreatePlayerTableFromRes(MYSQL_RES *res, TPlayerTable *pkTab)
{
if (mysql_num_rows(res) == 0) // 데이터 없음
return false;
@ -530,12 +529,12 @@ bool CreatePlayerTableFromRes(MYSQL_RES * res, TPlayerTable * pkTab)
return true;
}
void CClientManager::RESULT_COMPOSITE_PLAYER(CPeer * peer, SQLMsg * pMsg, DWORD dwQID)
void CClientManager::RESULT_COMPOSITE_PLAYER(CPeer *peer, SQLMsg *pMsg, DWORD dwQID)
{
CQueryInfo * qi = (CQueryInfo *) pMsg->pvUserData;
std::unique_ptr<ClientHandleInfo> info((ClientHandleInfo *) qi->pvData);
CQueryInfo *qi = (CQueryInfo *)pMsg->pvUserData;
std::unique_ptr<ClientHandleInfo> info((ClientHandleInfo *)qi->pvData);
MYSQL_RES * pSQLResult = pMsg->Get()->pSQLResult;
MYSQL_RES *pSQLResult = pMsg->Get()->pSQLResult;
if (!pSQLResult)
{
SPDLOG_ERROR("null MYSQL_RES QID {}", dwQID);
@ -559,19 +558,19 @@ 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얻기
ClientHandleInfo* temp1 = info.get();
// aid얻기
ClientHandleInfo *temp1 = info.get();
if (temp1 == NULL)
break;
CLoginData* pLoginData1 = GetLoginDataByAID(temp1->account_id); //
//독일 선물 기능
if( pLoginData1->GetAccountRef().login == NULL)
CLoginData *pLoginData1 = GetLoginDataByAID(temp1->account_id); //
// 독일 선물 기능
if (pLoginData1->GetAccountRef().login == NULL)
break;
if( pLoginData1 == NULL )
if (pLoginData1 == NULL)
break;
SPDLOG_DEBUG("info of pLoginData1 before call ItemAwardfunction {}", (void*) pLoginData1);
ItemAward(peer,pLoginData1->GetAccountRef().login);
SPDLOG_DEBUG("info of pLoginData1 before call ItemAwardfunction {}", (void *)pLoginData1);
ItemAward(peer, pLoginData1->GetAccountRef().login);
}
break;
@ -612,10 +611,9 @@ void CClientManager::RESULT_COMPOSITE_PLAYER(CPeer * peer, SQLMsg * pMsg, DWORD
break;
*/
}
}
void CClientManager::RESULT_PLAYER_LOAD(CPeer * peer, MYSQL_RES * pRes, ClientHandleInfo * pkInfo)
void CClientManager::RESULT_PLAYER_LOAD(CPeer *peer, MYSQL_RES *pRes, ClientHandleInfo *pkInfo)
{
TPlayerTable tab;
@ -625,11 +623,11 @@ void CClientManager::RESULT_PLAYER_LOAD(CPeer * peer, MYSQL_RES * pRes, ClientHa
return;
}
CLoginData * pkLD = GetLoginDataByAID(pkInfo->account_id);
CLoginData *pkLD = GetLoginDataByAID(pkInfo->account_id);
if (!pkLD || pkLD->IsPlay())
{
SPDLOG_DEBUG("PLAYER_LOAD_ERROR: LoginData {} IsPlay {}", (void*) pkLD, pkLD ? pkLD->IsPlay() : 0);
SPDLOG_DEBUG("PLAYER_LOAD_ERROR: LoginData {} IsPlay {}", (void *)pkLD, pkLD ? pkLD->IsPlay() : 0);
peer->EncodeHeader(HEADER_DG_PLAYER_LOAD_FAILED, pkInfo->dwHandle, 0);
return;
}
@ -645,24 +643,24 @@ void CClientManager::RESULT_PLAYER_LOAD(CPeer * peer, MYSQL_RES * pRes, ClientHa
TPacketNeedLoginLogInfo logInfo;
logInfo.dwPlayerID = tab.id;
pkLD->SetLastPlayerID( tab.id );
pkLD->SetLastPlayerID(tab.id);
peer->EncodeHeader( HEADER_DG_NEED_LOGIN_LOG, pkInfo->dwHandle, sizeof(TPacketNeedLoginLogInfo) );
peer->Encode( &logInfo, sizeof(TPacketNeedLoginLogInfo) );
peer->EncodeHeader(HEADER_DG_NEED_LOGIN_LOG, pkInfo->dwHandle, sizeof(TPacketNeedLoginLogInfo));
peer->Encode(&logInfo, sizeof(TPacketNeedLoginLogInfo));
}
}
void CClientManager::RESULT_ITEM_LOAD(CPeer * peer, MYSQL_RES * pRes, DWORD dwHandle, DWORD dwPID)
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
@ -678,7 +676,7 @@ void CClientManager::RESULT_ITEM_LOAD(CPeer * peer, MYSQL_RES * pRes, DWORD dwHa
}
}
void CClientManager::RESULT_AFFECT_LOAD(CPeer * peer, MYSQL_RES * pRes, DWORD dwHandle)
void CClientManager::RESULT_AFFECT_LOAD(CPeer *peer, MYSQL_RES *pRes, DWORD dwHandle)
{
int iNumRows;
@ -694,7 +692,7 @@ void CClientManager::RESULT_AFFECT_LOAD(CPeer * peer, MYSQL_RES * pRes, DWORD dw
for (int i = 0; i < iNumRows; ++i)
{
TPacketAffectElement & r = s_elements[i];
TPacketAffectElement &r = s_elements[i];
row = mysql_fetch_row(pRes);
if (dwPID == 0)
@ -718,7 +716,7 @@ void CClientManager::RESULT_AFFECT_LOAD(CPeer * peer, MYSQL_RES * pRes, DWORD dw
peer->Encode(&s_elements[0], sizeof(TPacketAffectElement) * dwCount);
}
void CClientManager::RESULT_QUEST_LOAD(CPeer * peer, MYSQL_RES * pRes, DWORD dwHandle, DWORD pid)
void CClientManager::RESULT_QUEST_LOAD(CPeer *peer, MYSQL_RES *pRes, DWORD dwHandle, DWORD pid)
{
int iNumRows;
@ -737,7 +735,7 @@ void CClientManager::RESULT_QUEST_LOAD(CPeer * peer, MYSQL_RES * pRes, DWORD dwH
for (int i = 0; i < iNumRows; ++i)
{
TQuestTable & r = s_table[i];
TQuestTable &r = s_table[i];
row = mysql_fetch_row(pRes);
@ -759,7 +757,7 @@ void CClientManager::RESULT_QUEST_LOAD(CPeer * peer, MYSQL_RES * pRes, DWORD dwH
/*
* PLAYER SAVE
*/
void CClientManager::QUERY_PLAYER_SAVE(CPeer * peer, DWORD dwHandle, TPlayerTable * pkTab)
void CClientManager::QUERY_PLAYER_SAVE(CPeer *peer, DWORD dwHandle, TPlayerTable *pkTab)
{
SPDLOG_TRACE("PLAYER_SAVE: {}", pkTab->name);
@ -772,7 +770,7 @@ static time_by_id_map_t s_createTimeByAccountID;
/*
* PLAYER CREATE
*/
void CClientManager::__QUERY_PLAYER_CREATE(CPeer *peer, DWORD dwHandle, TPlayerCreatePacket* packet)
void CClientManager::__QUERY_PLAYER_CREATE(CPeer *peer, DWORD dwHandle, TPlayerCreatePacket *packet)
{
char queryStr[QUERY_MAX_LEN];
int queryLen;
@ -807,7 +805,8 @@ void CClientManager::__QUERY_PLAYER_CREATE(CPeer *peer, DWORD dwHandle, TPlayerC
MYSQL_ROW row = mysql_fetch_row(pMsg0->Get()->pSQLResult);
DWORD dwPID = 0; str_to_number(dwPID, row[0]);
DWORD dwPID = 0;
str_to_number(dwPID, row[0]);
if (row[0] && dwPID > 0)
{
peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_ALREADY, dwHandle, 0);
@ -942,12 +941,12 @@ void CClientManager::__QUERY_PLAYER_CREATE(CPeer *peer, DWORD dwHandle, TPlayerC
/*
* PLAYER DELETE
*/
void CClientManager::__QUERY_PLAYER_DELETE(CPeer* peer, DWORD dwHandle, TPlayerDeletePacket* packet)
void CClientManager::__QUERY_PLAYER_DELETE(CPeer *peer, DWORD dwHandle, TPlayerDeletePacket *packet)
{
if (!packet->login[0] || !packet->player_id || packet->account_index >= PLAYER_PER_ACCOUNT)
return;
CLoginData * ld = GetLoginDataByLogin(packet->login);
CLoginData *ld = GetLoginDataByLogin(packet->login);
if (!ld)
{
@ -956,7 +955,7 @@ void CClientManager::__QUERY_PLAYER_DELETE(CPeer* peer, DWORD dwHandle, TPlayerD
return;
}
TAccountTable & r = ld->GetAccountRef();
TAccountTable &r = ld->GetAccountRef();
// block for japan
if (g_stLocale != "sjis")
@ -971,10 +970,10 @@ void CClientManager::__QUERY_PLAYER_DELETE(CPeer* peer, DWORD dwHandle, TPlayerD
return;
}
CPlayerTableCache * pkPlayerCache = GetPlayerCache(packet->player_id);
CPlayerTableCache *pkPlayerCache = GetPlayerCache(packet->player_id);
if (pkPlayerCache)
{
TPlayerTable * pTab = pkPlayerCache->Get();
TPlayerTable *pTab = pkPlayerCache->Get();
if (pTab->level >= m_iPlayerDeleteLevelLimit)
{
@ -999,7 +998,7 @@ void CClientManager::__QUERY_PLAYER_DELETE(CPeer* peer, DWORD dwHandle, TPlayerD
snprintf(szQuery, sizeof(szQuery), "SELECT p.id, p.level, p.name FROM player_index%s AS i, player%s AS p WHERE pid%u=%u AND pid%u=p.id",
GetTablePostfix(), GetTablePostfix(), packet->account_index + 1, packet->player_id, packet->account_index + 1);
ClientHandleInfo * pi = new ClientHandleInfo(dwHandle, packet->player_id);
ClientHandleInfo *pi = new ClientHandleInfo(dwHandle, packet->player_id);
pi->account_index = packet->account_index;
SPDLOG_DEBUG("PLAYER_DELETE TRY: {} {} pid{}", packet->login, packet->player_id, packet->account_index + 1);
@ -1009,10 +1008,10 @@ void CClientManager::__QUERY_PLAYER_DELETE(CPeer* peer, DWORD dwHandle, TPlayerD
//
// @version 05/06/10 Bang2ni - 플레이어 삭제시 가격정보 리스트 삭제 추가.
//
void CClientManager::__RESULT_PLAYER_DELETE(CPeer *peer, SQLMsg* msg)
void CClientManager::__RESULT_PLAYER_DELETE(CPeer *peer, SQLMsg *msg)
{
CQueryInfo * qi = (CQueryInfo *) msg->pvUserData;
ClientHandleInfo * pi = (ClientHandleInfo *) qi->pvData;
CQueryInfo *qi = (CQueryInfo *)msg->pvUserData;
ClientHandleInfo *pi = (ClientHandleInfo *)qi->pvData;
if (msg->Get() && msg->Get()->uiNumRows)
{
@ -1066,7 +1065,7 @@ void CClientManager::__RESULT_PLAYER_DELETE(CPeer *peer, SQLMsg* msg)
snprintf(account_index_string, sizeof(account_index_string), "player_id%d", m_iPlayerIDStart + pi->account_index);
// 플레이어 테이블을 캐쉬에서 삭제한다.
CPlayerTableCache * pkPlayerCache = GetPlayerCache(pi->player_id);
CPlayerTableCache *pkPlayerCache = GetPlayerCache(pi->player_id);
if (pkPlayerCache)
{
@ -1075,7 +1074,7 @@ void CClientManager::__RESULT_PLAYER_DELETE(CPeer *peer, SQLMsg* msg)
}
// 아이템들을 캐쉬에서 삭제한다.
TItemCacheSet * pSet = GetItemCacheSet(pi->player_id);
TItemCacheSet *pSet = GetItemCacheSet(pi->player_id);
if (pSet)
{
@ -1083,7 +1082,7 @@ void CClientManager::__RESULT_PLAYER_DELETE(CPeer *peer, SQLMsg* msg)
while (it != pSet->end())
{
CItemCache * pkItemCache = *it++;
CItemCache *pkItemCache = *it++;
DeleteItemCache(pkItemCache->Get()->id);
}
@ -1144,7 +1143,7 @@ void CClientManager::__RESULT_PLAYER_DELETE(CPeer *peer, SQLMsg* msg)
}
}
void CClientManager::QUERY_ADD_AFFECT(CPeer * peer, TPacketGDAddAffect * p)
void CClientManager::QUERY_ADD_AFFECT(CPeer *peer, TPacketGDAddAffect *p)
{
char queryStr[QUERY_MAX_LEN];
/*
@ -1180,7 +1179,7 @@ void CClientManager::QUERY_ADD_AFFECT(CPeer * peer, TPacketGDAddAffect * p)
CDBManager::instance().AsyncQuery(queryStr);
}
void CClientManager::QUERY_REMOVE_AFFECT(CPeer * peer, TPacketGDRemoveAffect * p)
void CClientManager::QUERY_REMOVE_AFFECT(CPeer *peer, TPacketGDRemoveAffect *p)
{
char queryStr[QUERY_MAX_LEN];
@ -1205,7 +1204,7 @@ void CClientManager::InsertLogoutPlayer(DWORD pid)
return;
}
TLogoutPlayer * pLogout = new TLogoutPlayer;
TLogoutPlayer *pLogout = new TLogoutPlayer;
pLogout->pid = pid;
pLogout->time = time(0);
m_map_logout.insert(std::make_pair(pid, pLogout));
@ -1234,7 +1233,7 @@ void CClientManager::UpdateLogoutPlayer()
while (it != m_map_logout.end())
{
TLogoutPlayer* pLogout = it->second;
TLogoutPlayer *pLogout = it->second;
if (now - g_iLogoutSeconds > pLogout->time)
{
@ -1255,11 +1254,10 @@ void CClientManager::FlushPlayerCacheSet(DWORD pid)
if (it != m_map_playerCache.end())
{
CPlayerTableCache * c = it->second;
CPlayerTableCache *c = it->second;
m_map_playerCache.erase(it);
c->Flush();
delete c;
}
}

View File

@ -80,7 +80,7 @@ bool CConfig::GetWord(FILE *fp, char *tar)
return (i != 0);
}
bool CConfig::GetLine(FILE* fp, char*dest)
bool CConfig::GetLine(FILE *fp, char *dest)
{
int c;
int i = 0;
@ -94,12 +94,12 @@ bool CConfig::GetLine(FILE* fp, char*dest)
return true;
}
bool CConfig::LoadFile(const char* filename)
bool CConfig::LoadFile(const char *filename)
{
char szTmp[256];
char comment[256];
FILE * fp = fopen(filename, "rb");
FILE *fp = fopen(filename, "rb");
if (fp == NULL)
return false;
@ -138,18 +138,16 @@ bool CConfig::LoadFile(const char* filename)
GetLine(fp, szTmp);
m_valueMap.insert(TValueMap::value_type(comment, szTmp));
mode = 0;
}
// ITEM_ID_RANGE_END
}
// 파일 닫는 부분.
fclose(fp);
return true;
}
std::string * CConfig::Search(const char* key)
std::string *CConfig::Search(const char *key)
{
itertype(m_valueMap) i = m_valueMap.find(key);
@ -159,24 +157,24 @@ std::string * CConfig::Search(const char* key)
return (&i->second);
}
bool CConfig::GetParam(const char*key, int index, DWORD *Param)
bool CConfig::GetParam(const char *key, int index, DWORD *Param)
{
std::string * pstStr = Search(key);
std::string *pstStr = Search(key);
if (!pstStr)
return false;
char szParam[5][32];
sscanf(pstStr->c_str(), "%s %s %s %s %s", szParam[0],szParam[1],szParam[2],szParam[3],szParam[4]);
sscanf(pstStr->c_str(), "%s %s %s %s %s", szParam[0], szParam[1], szParam[2], szParam[3], szParam[4]);
str_to_number(*Param, szParam[index]);
SPDLOG_DEBUG("GetParam {}", *Param);
return true;
}
const char * CConfig::Get(const char* key)
const char *CConfig::Get(const char *key)
{
std::string * pstStr = Search(key);
std::string *pstStr = Search(key);
if (!pstStr)
{
@ -187,8 +185,7 @@ const char * CConfig::Get(const char* key)
return pstStr->c_str();
}
bool CConfig::GetValue(const char * key, int* dest)
bool CConfig::GetValue(const char *key, int *dest)
{
if (!Search(key))
return false;
@ -197,7 +194,7 @@ bool CConfig::GetValue(const char * key, int* dest)
return true;
}
bool CConfig::GetValue(const char * key, float *dest)
bool CConfig::GetValue(const char *key, float *dest)
{
if (!Search(key))
return false;
@ -206,7 +203,7 @@ bool CConfig::GetValue(const char * key, float *dest)
return true;
}
bool CConfig::GetValue(const char * key, DWORD *dest)
bool CConfig::GetValue(const char *key, DWORD *dest)
{
if (!Search(key))
return false;
@ -215,16 +212,16 @@ bool CConfig::GetValue(const char * key, DWORD *dest)
return true;
}
bool CConfig::GetValue(const char * key, BYTE *dest)
bool CConfig::GetValue(const char *key, BYTE *dest)
{
if (!Search(key))
return false;
*dest = *(BYTE *) Get(key);
*dest = *(BYTE *)Get(key);
return true;
}
bool CConfig::GetValue(const char * key, char *dest, size_t destSize)
bool CConfig::GetValue(const char *key, char *dest, size_t destSize)
{
if (!Search(key))
return false;
@ -237,7 +234,7 @@ bool CConfig::GetValue(const char * key, char *dest, size_t destSize)
return true;
}
bool CConfig::GetTwoValue(const char* key, DWORD * dest1, DWORD *dest2)
bool CConfig::GetTwoValue(const char *key, DWORD *dest1, DWORD *dest2)
{
if (!GetParam(key, 0, dest1))
return false;
@ -247,4 +244,3 @@ bool CConfig::GetTwoValue(const char* key, DWORD * dest1, DWORD *dest2)
return true;
}

View File

@ -5,29 +5,29 @@ typedef std::map<std::string, std::string> TValueMap;
class CConfig : public singleton<CConfig>
{
public:
public:
CConfig();
~CConfig();
bool LoadFile(const char* filename);
bool GetValue(const char* key, int* dest);
bool GetValue(const char* key, float* dest);
bool GetValue(const char* key, DWORD* dest);
bool GetValue(const char* key, BYTE* dest);
bool GetValue(const char* key, char* dest, size_t destSize);
bool GetWord(FILE* fp, char* dest);
bool GetLine(FILE* fp, char* dest);
bool GetTwoValue(const char* key, DWORD * dest1, DWORD *dest2);
void NextLine(FILE* fp);
bool LoadFile(const char *filename);
bool GetValue(const char *key, int *dest);
bool GetValue(const char *key, float *dest);
bool GetValue(const char *key, DWORD *dest);
bool GetValue(const char *key, BYTE *dest);
bool GetValue(const char *key, char *dest, size_t destSize);
bool GetWord(FILE *fp, char *dest);
bool GetLine(FILE *fp, char *dest);
bool GetTwoValue(const char *key, DWORD *dest1, DWORD *dest2);
void NextLine(FILE *fp);
private:
private:
void Destroy();
bool GetParam(const char*key,int index, DWORD *Param);
bool GetParam(const char *key, int index, DWORD *Param);
const char * Get(const char* key);
std::string * Search(const char* key);
const char *Get(const char *key);
std::string *Search(const char *key);
private:
private:
TValueMap m_valueMap;
};

View File

@ -4,9 +4,9 @@
#include <algorithm>
#ifndef Assert
#include <assert.h>
#define Assert assert
#define LogToFile (void)(0);
#include <assert.h>
#define Assert assert
#define LogToFile (void)(0);
#endif
namespace
@ -39,7 +39,7 @@ namespace
/// \param name 셀 이름
/// \param index 셀 인덱스
////////////////////////////////////////////////////////////////////////////////
void cCsvAlias::AddAlias(const char* name, size_t index)
void cCsvAlias::AddAlias(const char *name, size_t index)
{
std::string converted(Lower(name));
@ -64,7 +64,7 @@ void cCsvAlias::Destroy()
/// \param index 숫자 인덱스
/// \return const char* 이름
////////////////////////////////////////////////////////////////////////////////
const char* cCsvAlias::operator [] (size_t index) const
const char *cCsvAlias::operator[](size_t index) const
{
INDEX2NAME_MAP::const_iterator itr(m_Index2Name.find(index));
if (itr == m_Index2Name.end())
@ -82,7 +82,7 @@ const char* cCsvAlias::operator [] (size_t index) const
/// \param name 이름
/// \return size_t 숫자 인덱스
////////////////////////////////////////////////////////////////////////////////
size_t cCsvAlias::operator [] (const char* name) const
size_t cCsvAlias::operator[](const char *name) const
{
NAME2INDEX_MAP::const_iterator itr(m_Name2Index.find(Lower(name)));
if (itr == m_Name2Index.end())
@ -102,27 +102,31 @@ size_t cCsvAlias::operator [] (const char* name) const
/// \param quote 따옴표로 사용할 글자. 기본값은 '"'이다.
/// \return bool 무사히 로드했다면 true, 아니라면 false
////////////////////////////////////////////////////////////////////////////////
bool cCsvFile::Load(const char* fileName, const char seperator, const char quote)
bool cCsvFile::Load(const char *fileName, const char seperator, const char quote)
{
Assert(seperator != quote);
std::ifstream file(fileName, std::ios::in);
if (!file) return false;
if (!file)
return false;
Destroy(); // 기존의 데이터를 삭제
cCsvRow* row = NULL;
cCsvRow *row = NULL;
ParseState state = STATE_NORMAL;
std::string token = "";
char buf[2048+1] = {0,};
char buf[2048 + 1] = {
0,
};
while (file.good())
{
file.getline(buf, 2048);
buf[sizeof(buf)-1] = 0;
buf[sizeof(buf) - 1] = 0;
std::string line(Trim(buf));
if (line.empty() || (state == STATE_NORMAL && line[0] == '#')) continue;
if (line.empty() || (state == STATE_NORMAL && line[0] == '#'))
continue;
std::string text = std::string(line) + " "; // 파싱 lookahead 때문에 붙여준다.
size_t cur = 0;
@ -144,7 +148,7 @@ bool cCsvFile::Load(const char* fileName, const char seperator, const char quote
{
// 다음 문자가 '"' 문자라면, 즉 연속된 '"' 문자라면
// 이는 셀 내부의 '"' 문자가 치환된 것이다.
if (text[cur+1] == quote)
if (text[cur + 1] == quote)
{
token += quote;
++cur;
@ -194,14 +198,14 @@ bool cCsvFile::Load(const char* fileName, const char seperator, const char quote
if (state == STATE_NORMAL)
{
Assert(row != NULL);
row->push_back(token.substr(0, token.size()-2));
row->push_back(token.substr(0, token.size() - 2));
m_Rows.push_back(row);
token.clear();
row = NULL;
}
else
{
token = token.substr(0, token.size()-2) + "\r\n";
token = token.substr(0, token.size() - 2) + "\r\n";
}
}
@ -217,32 +221,39 @@ bool cCsvFile::Load(const char* fileName, const char seperator, const char quote
/// \param quote 따옴표로 사용할 글자. 기본값은 '"'이다.
/// \return bool 무사히 저장했다면 true, 에러가 생긴 경우에는 false
////////////////////////////////////////////////////////////////////////////////
bool cCsvFile::Save(const char* fileName, bool append, char seperator, char quote) const
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); }
if (append)
{
file.open(fileName, std::ios::out | std::ios::app);
}
else
{
file.open(fileName, std::ios::out | std::ios::trunc);
}
// 파일을 열지 못했다면, false를 리턴한다.
if (!file) return false;
if (!file)
return false;
char special_chars[5] = { seperator, quote, '\r', '\n', 0 };
char quote_escape_string[3] = { quote, quote, 0 };
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++)
for (size_t i = 0; i < m_Rows.size(); i++)
{
const cCsvRow& row = *((*this)[i]);
const cCsvRow &row = *((*this)[i]);
std::string line;
// 행 안의 모든 토큰을 횡단하면서...
for (size_t j=0; j<row.size(); j++)
for (size_t j = 0; j < row.size(); j++)
{
const std::string& token = row[j];
const std::string &token = row[j];
// 일반적인('"' 또는 ','를 포함하지 않은)
// 토큰이라면 그냥 저장하면 된다.
@ -256,17 +267,22 @@ bool cCsvFile::Save(const char* fileName, bool append, char seperator, char quot
{
line += quote;
for (size_t k=0; k<token.size(); k++)
for (size_t k = 0; k < token.size(); k++)
{
if (token[k] == quote) line += quote_escape_string;
else line += token[k];
if (token[k] == quote)
line += quote_escape_string;
else
line += token[k];
}
line += quote;
}
// 마지막 셀이 아니라면 ','를 토큰의 뒤에다 붙여줘야한다.
if (j != row.size() - 1) { line += seperator; }
if (j != row.size() - 1)
{
line += seperator;
}
}
// 라인을 출력한다.
@ -292,7 +308,7 @@ void cCsvFile::Destroy()
/// \param index 인덱스
/// \return cCsvRow* 해당 행
////////////////////////////////////////////////////////////////////////////////
cCsvRow* cCsvFile::operator [] (size_t index)
cCsvRow *cCsvFile::operator[](size_t index)
{
Assert(index < m_Rows.size());
return m_Rows[index];
@ -303,7 +319,7 @@ cCsvRow* cCsvFile::operator [] (size_t index)
/// \param index 인덱스
/// \return const cCsvRow* 해당 행
////////////////////////////////////////////////////////////////////////////////
const cCsvRow* cCsvFile::operator [] (size_t index) const
const cCsvRow *cCsvFile::operator[](size_t index) const
{
Assert(index < m_Rows.size());
return m_Rows[index];
@ -313,7 +329,7 @@ const cCsvRow* cCsvFile::operator [] (size_t index) const
/// \brief 생성자
////////////////////////////////////////////////////////////////////////////////
cCsvTable::cCsvTable()
: m_CurRow(-1)
: m_CurRow(-1)
{
}
@ -331,7 +347,7 @@ cCsvTable::~cCsvTable()
/// \param quote 따옴표로 사용할 글자. 기본값은 '"'이다.
/// \return bool 무사히 로드했다면 true, 아니라면 false
////////////////////////////////////////////////////////////////////////////////
bool cCsvTable::Load(const char* fileName, const char seperator, const char quote)
bool cCsvTable::Load(const char *fileName, const char seperator, const char quote)
{
Destroy();
return m_File.Load(fileName, seperator, quote);
@ -364,7 +380,7 @@ size_t cCsvTable::ColCount() const
////////////////////////////////////////////////////////////////////////////////
int cCsvTable::AsInt(size_t index) const
{
const cCsvRow* const row = CurRow();
const cCsvRow *const row = CurRow();
Assert(row);
Assert(index < row->size());
return row->AsInt(index);
@ -377,7 +393,7 @@ int cCsvTable::AsInt(size_t index) const
////////////////////////////////////////////////////////////////////////////////
double cCsvTable::AsDouble(size_t index) const
{
const cCsvRow* const row = CurRow();
const cCsvRow *const row = CurRow();
Assert(row);
Assert(index < row->size());
return row->AsDouble(index);
@ -388,9 +404,9 @@ double cCsvTable::AsDouble(size_t index) const
/// \param index 셀 인덱스
/// \return const char* 셀 값
////////////////////////////////////////////////////////////////////////////////
const char* cCsvTable::AsStringByIndex(size_t index) const
const char *cCsvTable::AsStringByIndex(size_t index) const
{
const cCsvRow* const row = CurRow();
const cCsvRow *const row = CurRow();
Assert(row);
Assert(index < row->size());
return row->AsString(index);
@ -412,7 +428,7 @@ void cCsvTable::Destroy()
/// 포인터를 반환하고, 더 이상 액세스 가능한 행이 없는 경우에는 NULL을
/// 반환한다.
////////////////////////////////////////////////////////////////////////////////
const cCsvRow* const cCsvTable::CurRow() const
const cCsvRow *const cCsvTable::CurRow() const
{
if (m_CurRow < 0)
{
@ -427,4 +443,3 @@ const cCsvRow* const cCsvTable::CurRow() const
return m_File[m_CurRow];
}

View File

@ -5,9 +5,9 @@
#include <vector>
#if _MSC_VER
#include <hash_map>
#include <hash_map>
#else
#include <map>
#include <map>
#endif
////////////////////////////////////////////////////////////////////////////////
@ -50,7 +50,6 @@ private:
NAME2INDEX_MAP m_Name2Index; ///< 셀 인덱스 대신으로 사용하기 위한 이름들
INDEX2NAME_MAP m_Index2Name; ///< 잘못된 alias를 검사하기 위한 추가적인 맵
public:
/// \brief 생성자
cCsvAlias() {}
@ -58,30 +57,27 @@ public:
/// \brief 소멸자
virtual ~cCsvAlias() {}
public:
/// \brief 셀을 액세스할 때, 숫자 대신 사용할 이름을 등록한다.
void AddAlias(const char* name, size_t index);
void AddAlias(const char *name, size_t index);
/// \brief 모든 데이터를 삭제한다.
void Destroy();
/// \brief 숫자 인덱스를 이름으로 변환한다.
const char* operator [] (size_t index) const;
const char *operator[](size_t index) const;
/// \brief 이름을 숫자 인덱스로 변환한다.
size_t operator [] (const char* name) const;
size_t operator[](const char *name) const;
private:
/// \brief 복사 생성자 금지
cCsvAlias(const cCsvAlias&) {}
cCsvAlias(const cCsvAlias &) {}
/// \brief 대입 연산자 금지
const cCsvAlias& operator = (const cCsvAlias&) { return *this; }
const cCsvAlias &operator=(const cCsvAlias &) { return *this; }
};
////////////////////////////////////////////////////////////////////////////////
/// \class cCsvRow
/// \brief CSV 파일의 한 행을 캡슐화한 클래스
@ -117,7 +113,6 @@ public:
/// \brief 소멸자
~cCsvRow() {}
public:
/// \brief 해당 셀의 데이터를 int 형으로 반환한다.
int AsInt(size_t index) const { return atoi(at(index).c_str()); }
@ -126,33 +121,34 @@ public:
double AsDouble(size_t index) const { return atof(at(index).c_str()); }
/// \brief 해당 셀의 데이터를 문자열로 반환한다.
const char* AsString(size_t index) const { return at(index).c_str(); }
const char *AsString(size_t index) const { return at(index).c_str(); }
/// \brief 해당하는 이름의 셀 데이터를 int 형으로 반환한다.
int AsInt(const char* name, const cCsvAlias& alias) const {
return atoi( at(alias[name]).c_str() );
int AsInt(const char *name, const cCsvAlias &alias) const
{
return atoi(at(alias[name]).c_str());
}
/// \brief 해당하는 이름의 셀 데이터를 int 형으로 반환한다.
double AsDouble(const char* name, const cCsvAlias& alias) const {
return atof( at(alias[name]).c_str() );
double AsDouble(const char *name, const cCsvAlias &alias) const
{
return atof(at(alias[name]).c_str());
}
/// \brief 해당하는 이름의 셀 데이터를 문자열로 반환한다.
const char* AsString(const char* name, const cCsvAlias& alias) const {
const char *AsString(const char *name, const cCsvAlias &alias) const
{
return at(alias[name]).c_str();
}
private:
/// \brief 복사 생성자 금지
cCsvRow(const cCsvRow&) {}
cCsvRow(const cCsvRow &) {}
/// \brief 대입 연산자 금지
const cCsvRow& operator = (const cCsvRow&) { return *this; }
const cCsvRow &operator=(const cCsvRow &) { return *this; }
};
////////////////////////////////////////////////////////////////////////////////
/// \class cCsvFile
/// \brief CSV(Comma Seperated Values) 파일을 read/write하기 위한 클래스
@ -186,11 +182,10 @@ private:
class cCsvFile
{
private:
typedef std::vector<cCsvRow*> ROWS;
typedef std::vector<cCsvRow *> ROWS;
ROWS m_Rows; ///< 행 컬렉션
public:
/// \brief 생성자
cCsvFile() {}
@ -198,36 +193,33 @@ public:
/// \brief 소멸자
virtual ~cCsvFile() { Destroy(); }
public:
/// \brief 지정된 이름의 CSV 파일을 로드한다.
bool Load(const char* fileName, const char seperator=',', const char quote='"');
bool Load(const char *fileName, const char seperator = ',', const char quote = '"');
/// \brief 가지고 있는 내용을 CSV 파일에다 저장한다.
bool Save(const char* fileName, bool append=false, char seperator=',', char quote='"') const;
bool Save(const char *fileName, bool append = false, char seperator = ',', char quote = '"') const;
/// \brief 모든 데이터를 메모리에서 삭제한다.
void Destroy();
/// \brief 해당하는 인덱스의 행을 반환한다.
cCsvRow* operator [] (size_t index);
cCsvRow *operator[](size_t index);
/// \brief 해당하는 인덱스의 행을 반환한다.
const cCsvRow* operator [] (size_t index) const;
const cCsvRow *operator[](size_t index) const;
/// \brief 행의 갯수를 반환한다.
size_t GetRowCount() const { return m_Rows.size(); }
private:
/// \brief 복사 생성자 금지
cCsvFile(const cCsvFile&) {}
cCsvFile(const cCsvFile &) {}
/// \brief 대입 연산자 금지
const cCsvFile& operator = (const cCsvFile&) { return *this; }
const cCsvFile &operator=(const cCsvFile &) { return *this; }
};
////////////////////////////////////////////////////////////////////////////////
/// \class cCsvTable
/// \brief CSV 파일을 이용해 테이블 데이터를 로드하는 경우가 많은데, 이 클래스는
@ -258,13 +250,12 @@ private:
class cCsvTable
{
public :
public:
cCsvFile m_File; ///< CSV 파일 객체
private:
cCsvAlias m_Alias; ///< 문자열을 셀 인덱스로 변환하기 위한 객체
int m_CurRow; ///< 현재 횡단 중인 행 번호
public:
/// \brief 생성자
cCsvTable();
@ -272,13 +263,12 @@ public:
/// \brief 소멸자
virtual ~cCsvTable();
public:
/// \brief 지정된 이름의 CSV 파일을 로드한다.
bool Load(const char* fileName, const char seperator=',', const char quote='"');
bool Load(const char *fileName, const char seperator = ',', const char quote = '"');
/// \brief 셀을 액세스할 때, 숫자 대신 사용할 이름을 등록한다.
void AddAlias(const char* name, size_t index) { m_Alias.AddAlias(name, index); }
void AddAlias(const char *name, size_t index) { m_Alias.AddAlias(name, index); }
/// \brief 다음 행으로 넘어간다.
bool Next();
@ -293,30 +283,29 @@ public:
double AsDouble(size_t index) const;
/// \brief 인덱스를 이용해 std::string 형으로 셀값을 반환한다.
const char* AsStringByIndex(size_t index) const;
const char *AsStringByIndex(size_t index) const;
/// \brief 셀 이름을 이용해 int 형으로 셀값을 반환한다.
int AsInt(const char* name) const { return AsInt(m_Alias[name]); }
int AsInt(const char *name) const { return AsInt(m_Alias[name]); }
/// \brief 셀 이름을 이용해 double 형으로 셀값을 반환한다.
double AsDouble(const char* name) const { return AsDouble(m_Alias[name]); }
double AsDouble(const char *name) const { return AsDouble(m_Alias[name]); }
/// \brief 셀 이름을 이용해 std::string 형으로 셀값을 반환한다.
const char* AsString(const char* name) const { return AsStringByIndex(m_Alias[name]); }
const char *AsString(const char *name) const { return AsStringByIndex(m_Alias[name]); }
/// \brief alias를 포함해 모든 데이터를 삭제한다.
void Destroy();
private:
/// \brief 현재 행을 반환한다.
const cCsvRow* const CurRow() const;
const cCsvRow *const CurRow() const;
/// \brief 복사 생성자 금지
cCsvTable(const cCsvTable&) {}
cCsvTable(const cCsvTable &) {}
/// \brief 대입 연산자 금지
const cCsvTable& operator = (const cCsvTable&) { return *this; }
const cCsvTable &operator=(const cCsvTable &) { return *this; }
};
#endif //__CSVFILE_H__

View File

@ -6,183 +6,179 @@ extern std::string g_stLocale;
CDBManager::CDBManager()
{
Initialize();
StartWorkerThread();
}
CDBManager::~CDBManager()
{
Destroy();
Quit();
}
void CDBManager::Initialize()
int CDBManager::Connect(const char *db_address, int db_port, const char *db_name, const char *user, const char *pwd)
{
for (int i = 0; i < SQL_MAX_NUM; ++i)
if (!db_address || !db_name || !user || !pwd)
return false;
try
{
m_mainSQL[i] = NULL;
m_directSQL[i] = NULL;
m_asyncSQL[i] = NULL;
}
}
m_connPool = std::make_shared<PgConnectionPool>(
db_address, db_port, db_name, user, pwd,
10, // poolSize
60 // idleTimeoutSeconds
);
void CDBManager::Destroy()
{
Clear();
// Optionally, do a test connection:
{
auto conn = m_connPool->acquire();
if (!conn || !conn->is_open())
{
SPDLOG_ERROR("Failed to open test connection to DB");
m_connPool.reset();
return false;
}
}
SPDLOG_INFO("Connected to PostgreSQL at {}:{}, DB: {}", db_address, db_port, db_name);
return true;
}
catch (const std::exception &ex)
{
SPDLOG_ERROR("Exception while connecting to DB: {}", ex.what());
return false;
}
}
void CDBManager::Clear()
{
for (int i = 0; i < SQL_MAX_NUM; ++i)
{
if (m_mainSQL[i])
{
delete m_mainSQL[i];
m_mainSQL[i] = NULL;
}
if (m_directSQL[i])
{
delete m_directSQL[i];
m_directSQL[i] = NULL;
}
if (m_asyncSQL[i])
{
delete m_asyncSQL[i];
m_asyncSQL[i] = NULL;
}
}
Initialize();
std::lock_guard<std::mutex> lock(m_queueMutex);
std::queue<std::shared_ptr<PgAsyncQuery>> empty;
m_queryQueue.swap(empty);
}
void CDBManager::Quit()
{
for (int i = 0; i < SQL_MAX_NUM; ++i)
if (m_quit.exchange(1) == 0)
{
if (m_mainSQL[i])
m_mainSQL[i]->Quit();
if (m_asyncSQL[i])
m_asyncSQL[i]->Quit();
if (m_directSQL[i])
m_directSQL[i]->Quit();
StopWorkerThread();
if (m_connPool)
{
m_connPool.reset();
}
}
}
SQLMsg * CDBManager::PopResult()
std::shared_ptr<PgConnectionPool> CDBManager::GetConnectionPool()
{
SQLMsg * p;
for (int i = 0; i < SQL_MAX_NUM; ++i)
if (m_mainSQL[i] && m_mainSQL[i]->PopResult(&p))
return p;
return NULL;
return m_connPool;
}
SQLMsg * CDBManager::PopResult(eSQL_SLOT slot)
void CDBManager::AsyncQuery(const std::string &query, const pqxx::params &params)
{
SQLMsg * p;
auto msg = std::make_shared<PgAsyncQuery>(++m_msgCounter, query, params);
if (m_mainSQL[slot] && m_mainSQL[slot]->PopResult(&p))
return p;
return NULL;
}
int CDBManager::Connect(int iSlot, const char * db_address, const int db_port, const char * db_name, const char * user, const char * pwd)
{
if (db_address == NULL || db_name == NULL)
return false;
if (iSlot < 0 || iSlot >= SQL_MAX_NUM)
return false;
SPDLOG_INFO("CREATING DIRECT_SQL");
m_directSQL[iSlot] = new CAsyncSQL2;
if (!m_directSQL[iSlot]->Setup(db_address, user, pwd, db_name, g_stLocale.c_str(), true, db_port))
{
Clear();
return false;
std::lock_guard<std::mutex> lock(m_queueMutex);
m_queryQueue.push(msg);
}
m_queueCondition.notify_one();
}
SPDLOG_INFO("CREATING MAIN_SQL");
m_mainSQL[iSlot] = new CAsyncSQL2;
if (!m_mainSQL[iSlot]->Setup(db_address, user, pwd, db_name, g_stLocale.c_str(), false, db_port))
size_t CDBManager::GetPendingQueryCount() const
{
std::lock_guard<std::mutex> lock(m_queueMutex);
return m_queryQueue.size();
}
size_t CDBManager::GetCompletedQueryCount() const
{
return m_completedQueries.load();
}
void CDBManager::ResetQueryStats()
{
m_completedQueries = 0;
}
void CDBManager::StartWorkerThread()
{
if (!m_workerRunning.exchange(true))
{
Clear();
return false;
}
SPDLOG_INFO("CREATING ASYNC_SQL");
m_asyncSQL[iSlot] = new CAsyncSQL2;
if (!m_asyncSQL[iSlot]->Setup(db_address, user, pwd, db_name, g_stLocale.c_str(), false, db_port))
{
Clear();
return false;
}
return true;
}
SQLMsg * CDBManager::DirectQuery(const char * c_pszQuery, int iSlot)
{
return m_directSQL[iSlot]->DirectQuery(c_pszQuery);
}
extern CPacketInfo g_query_info;
extern int g_query_count[2];
void CDBManager::ReturnQuery(const char * c_pszQuery, int iType, IDENT dwIdent, void * udata, int iSlot)
{
assert(iSlot < SQL_MAX_NUM);
//SPDLOG_DEBUG("ReturnQuery {}", c_pszQuery);
CQueryInfo * p = new CQueryInfo;
p->iType = iType;
p->dwIdent = dwIdent;
p->pvData = udata;
m_mainSQL[iSlot]->ReturnQuery(c_pszQuery, p);
//g_query_info.Add(iType);
++g_query_count[0];
}
void CDBManager::AsyncQuery(const char * c_pszQuery, int iSlot)
{
assert(iSlot < SQL_MAX_NUM);
m_asyncSQL[iSlot]->AsyncQuery(c_pszQuery);
++g_query_count[1];
}
unsigned int CDBManager::EscapeString(void *to, const void *from, unsigned int length, int iSlot)
{
assert(iSlot < SQL_MAX_NUM);
return mysql_real_escape_string(m_directSQL[iSlot]->GetSQLHandle(), (char *) to, (const char *) from, length);
}
void CDBManager::SetLocale(const char * szLocale)
{
const std::string stLocale(szLocale);
SPDLOG_DEBUG("SetLocale start");
for (int n = 0; n < SQL_MAX_NUM; ++n)
{
m_mainSQL[n]->SetLocale(stLocale);
m_directSQL[n]->SetLocale(stLocale);
m_asyncSQL[n]->SetLocale(stLocale);
}
SPDLOG_DEBUG("End setlocale {}", szLocale);
}
void CDBManager::QueryLocaleSet()
{
for (int n = 0; n < SQL_MAX_NUM; ++n)
{
m_mainSQL[n]->QueryLocaleSet();
m_directSQL[n]->QueryLocaleSet();
m_asyncSQL[n]->QueryLocaleSet();
m_workerThread = std::thread(&CDBManager::WorkerLoop, this);
}
}
void CDBManager::StopWorkerThread()
{
if (m_workerRunning.exchange(false))
{
m_queueCondition.notify_all();
if (m_workerThread.joinable())
{
m_workerThread.join();
}
}
}
void CDBManager::WorkerLoop()
{
SPDLOG_INFO("AsyncQuery worker thread started");
while (m_workerRunning)
{
std::shared_ptr<PgAsyncQuery> msg;
{
std::unique_lock<std::mutex> lock(m_queueMutex);
m_queueCondition.wait(lock, [this]
{ return !m_queryQueue.empty() || !m_workerRunning; });
if (!m_workerRunning && m_queryQueue.empty())
{
break;
}
if (!m_queryQueue.empty())
{
msg = m_queryQueue.front();
m_queryQueue.pop();
}
}
if (msg)
{
ProcessQuery(msg);
}
}
SPDLOG_INFO("AsyncQuery worker thread stopped");
}
void CDBManager::ProcessQuery(std::shared_ptr<PgAsyncQuery> msg)
{
try
{
if (!m_connPool)
{
throw std::runtime_error("No database connection available");
}
auto conn = m_connPool->acquire();
if (!conn)
{
throw std::runtime_error("Failed to get connection from pool");
}
pqxx::work txn(*conn);
txn.exec_params(msg->query, msg->parameters);
txn.commit();
SPDLOG_TRACE("AsyncQuery completed: {} (ID: {})", msg->query, msg->id);
}
catch (const std::exception &e)
{
SPDLOG_ERROR("AsyncQuery failed: {} (query: {}, ID: {})", e.what(), msg->query, msg->id);
}
++m_completedQueries;
}

View File

@ -1,97 +1,48 @@
// vim:ts=8 sw=4
#ifndef __INC_METIN2_DB_DBMANAGER_H__
#define __INC_METIN2_DB_DBMANAGER_H__
// 디비 커넥션 클래스의 목적은... 디비에 접속해서 쿼리보내고 결과 받아오는
// 모든 일들을 처리한다.
// 코드 by 꼬붕 후로그래머 아노아~ = _=)b
#include <libsql/include/CAsyncSQL.h>
#define SQL_SAFE_LENGTH(size) (size * 2 + 1)
#define QUERY_SAFE_LENGTH(size) (1024 + SQL_SAFE_LENGTH(size))
class CQueryInfo
{
public:
int iType;
DWORD dwIdent;
void * pvData;
};
enum eSQL_SLOT
{
SQL_PLAYER,
SQL_ACCOUNT,
SQL_COMMON,
SQL_MAX_NUM,
};
#include <libsql/include/PgConnectionPool.h>
#include <libsql/include/PgAsyncQuery.h>
#include <memory>
class CDBManager : public singleton<CDBManager>
{
protected:
void Initialize();
void Destroy();
public:
public:
CDBManager();
virtual ~CDBManager();
int Connect(const char *host, int port, const char *dbname, const char *user, const char *pass);
void Clear();
void Quit();
int Connect(int iSlot, const char * host, int port, const char* dbname, const char* user, const char* pass);
std::shared_ptr<PgConnectionPool> GetConnectionPool();
void ReturnQuery(const char * c_pszQuery, int iType, DWORD dwIdent, void * pvData, int iSlot = SQL_PLAYER);
void AsyncQuery(const char * c_pszQuery, int iSlot = SQL_PLAYER);
SQLMsg * DirectQuery(const char * c_pszQuery, int iSlot = SQL_PLAYER);
// Async Query
SQLMsg * PopResult();
SQLMsg * PopResult(eSQL_SLOT slot );
void AsyncQuery(const std::string &query, const pqxx::params &params = pqxx::params{});
unsigned int EscapeString(void * to, const void * from, unsigned int length, int iSlot = SQL_PLAYER);
size_t GetPendingQueryCount() const;
size_t GetCompletedQueryCount() const;
void ResetQueryStats();
DWORD CountReturnQuery(int i) { return m_mainSQL[i] ? m_mainSQL[i]->CountQuery() : 0; }
DWORD CountReturnResult(int i) { return m_mainSQL[i] ? m_mainSQL[i]->CountResult() : 0; }
DWORD CountReturnQueryFinished(int i) { return m_mainSQL[i] ? m_mainSQL[i]->CountQueryFinished() : 0; }
DWORD CountReturnCopiedQuery(int i) { return m_mainSQL[i] ? m_mainSQL[i]->GetCopiedQueryCount() : 0; }
private:
std::shared_ptr<PgConnectionPool> m_connPool;
std::atomic<int> m_quit{0};
DWORD CountAsyncQuery(int i) { return m_asyncSQL[i] ? m_asyncSQL[i]->CountQuery() : 0; }
DWORD CountAsyncResult(int i) { return m_asyncSQL[i] ? m_asyncSQL[i]->CountResult() : 0; }
DWORD CountAsyncQueryFinished(int i) { return m_asyncSQL[i] ? m_asyncSQL[i]->CountQueryFinished() : 0; }
DWORD CountAsyncCopiedQuery(int i) { return m_asyncSQL[i] ? m_asyncSQL[i]->GetCopiedQueryCount() : 0; }
// Async Query
void ResetCounter()
{
for (int i = 0; i < SQL_MAX_NUM; ++i)
{
if (m_mainSQL[i])
{
m_mainSQL[i]->ResetQueryFinished();
m_mainSQL[i]->ResetCopiedQueryCount();
}
void StartWorkerThread();
void StopWorkerThread();
void WorkerLoop();
void ProcessQuery(std::shared_ptr<PgAsyncQuery> msg);
if (m_asyncSQL[i])
{
m_asyncSQL[i]->ResetQueryFinished();
m_asyncSQL[i]->ResetCopiedQueryCount();
}
}
}
private:
CAsyncSQL2 * m_mainSQL[SQL_MAX_NUM];
CAsyncSQL2 * m_directSQL[SQL_MAX_NUM];
CAsyncSQL2 * m_asyncSQL[SQL_MAX_NUM];
int m_quit; // looping flag
//CHARSET
public:
void SetLocale(const char * szLocale );
void QueryLocaleSet();
private:
//END_CHARSET
std::queue<std::shared_ptr<PgAsyncQuery>> m_queryQueue;
mutable std::mutex m_queueMutex;
std::condition_variable m_queueCondition;
std::thread m_workerThread;
std::atomic<int> m_msgCounter{0};
std::atomic<size_t> m_completedQueries{0};
std::atomic<bool> m_workerRunning{false};
};
#endif

View File

@ -14,15 +14,24 @@ bool isEurope()
{
do
{
if (g_stLocale.compare("germany") == 0) break;
if (g_stLocale.compare("france") == 0) break;
if (g_stLocale.compare("italy") == 0) break;
if (g_stLocale.compare("spain") == 0) break;
if (g_stLocale.compare("uk") == 0) break;
if (g_stLocale.compare("turkey") == 0) break;
if (g_stLocale.compare("poland") == 0) break;
if (g_stLocale.compare("portugal") == 0) break;
if (g_stLocale.compare("greek") == 0) break;
if (g_stLocale.compare("germany") == 0)
break;
if (g_stLocale.compare("france") == 0)
break;
if (g_stLocale.compare("italy") == 0)
break;
if (g_stLocale.compare("spain") == 0)
break;
if (g_stLocale.compare("uk") == 0)
break;
if (g_stLocale.compare("turkey") == 0)
break;
if (g_stLocale.compare("poland") == 0)
break;
if (g_stLocale.compare("portugal") == 0)
break;
if (g_stLocale.compare("greek") == 0)
break;
return false;
} while (false);
@ -35,8 +44,10 @@ DWORD GetGuildWarWaitStartDuration()
// const int GUILD_WAR_WAIT_START_DURATION = 60;
// const int GUILD_WAR_WAIT_START_DURATION = 5;
if (isEurope() == true) return 60;
else return 5;
if (isEurope() == true)
return 60;
else
return 5;
}
DWORD GetGuildWarReserveSeconds()
@ -44,8 +55,10 @@ DWORD GetGuildWarReserveSeconds()
// const int GUILD_WAR_RESERVE_SECONDS = 180;
// const int GUILD_WAR_RESERVE_SECONDS = 10;
if (isEurope() == true) return 180;
else return 10;
if (isEurope() == true)
return 180;
else
return 10;
}
namespace
@ -65,7 +78,7 @@ namespace
p.dwGuildTo = GID2;
}
void operator() (CPeer* peer)
void operator()(CPeer *peer)
{
if (peer->GetChannel() == 0)
return;
@ -87,7 +100,7 @@ namespace
pck.lBetScore = iBetScore;
}
void operator() (CPeer* peer)
void operator()(CPeer *peer)
{
if (peer->GetChannel() == 0)
return;
@ -115,7 +128,7 @@ CGuildManager::~CGuildManager()
}
}
TGuild & CGuildManager::TouchGuild(DWORD GID)
TGuild &CGuildManager::TouchGuild(DWORD GID)
{
itertype(m_map_kGuild) it = m_map_kGuild.find(GID);
@ -127,7 +140,7 @@ TGuild & CGuildManager::TouchGuild(DWORD GID)
return m_map_kGuild[GID];
}
void CGuildManager::ParseResult(SQLResult * pRes)
void CGuildManager::ParseResult(SQLResult *pRes)
{
MYSQL_ROW row;
@ -135,7 +148,7 @@ void CGuildManager::ParseResult(SQLResult * pRes)
{
DWORD GID = strtoul(row[0], NULL, 10);
TGuild & r_info = TouchGuild(GID);
TGuild &r_info = TouchGuild(GID);
strlcpy(r_info.szName, row[1], sizeof(r_info.szName));
str_to_number(r_info.ladder_point, row[2]);
@ -214,7 +227,7 @@ int CGuildManager::GetRanking(DWORD dwGID)
return std::clamp(it->second, 0, GUILD_RANK_MAX_NUM);
}
void CGuildManager::ResultRanking(MYSQL_RES * pRes)
void CGuildManager::ResultRanking(MYSQL_RES *pRes)
{
if (!pRes)
return;
@ -228,8 +241,10 @@ void CGuildManager::ResultRanking(MYSQL_RES * pRes)
while ((row = mysql_fetch_row(pRes)))
{
DWORD dwGID = 0; str_to_number(dwGID, row[0]);
int iLadderPoint = 0; str_to_number(iLadderPoint, row[2]);
DWORD dwGID = 0;
str_to_number(dwGID, row[0]);
int iLadderPoint = 0;
str_to_number(iLadderPoint, row[2]);
if (iLadderPoint != iLastLadderPoint)
++iRank;
@ -263,7 +278,7 @@ void CGuildManager::Update()
while (!m_pqOnWar.empty() && (m_pqOnWar.top().first <= now || (m_pqOnWar.top().second && m_pqOnWar.top().second->bEnd)))
{
TGuildWarPQElement * e = m_pqOnWar.top().second;
TGuildWarPQElement *e = m_pqOnWar.top().second;
m_pqOnWar.pop();
@ -280,7 +295,7 @@ void CGuildManager::Update()
// GUILD_SKILL_COOLTIME_BUG_FIX
while (!m_pqSkill.empty() && m_pqSkill.top().first <= now)
{
const TGuildSkillUsed& s = m_pqSkill.top().second;
const TGuildSkillUsed &s = m_pqSkill.top().second;
CClientManager::instance().SendGuildSkillUsable(s.GID, s.dwSkillVnum, true);
m_pqSkill.pop();
}
@ -288,7 +303,7 @@ void CGuildManager::Update()
while (!m_pqWaitStart.empty() && m_pqWaitStart.top().first <= now)
{
const TGuildWaitStartInfo & ws = m_pqWaitStart.top().second;
const TGuildWaitStartInfo &ws = m_pqWaitStart.top().second;
m_pqWaitStart.pop();
StartWar(ws.bType, ws.GID[0], ws.GID[1], ws.pkReserve); // insert new element to m_WarMap and m_pqOnWar
@ -313,26 +328,26 @@ void CGuildManager::Update()
#define for_all(cont, it) for (typeof((cont).begin()) it = (cont).begin(); it != (cont).end(); ++it)
void CGuildManager::OnSetup(CPeer* peer)
void CGuildManager::OnSetup(CPeer *peer)
{
for_all(m_WarMap, it_cont)
for_all(it_cont->second, it)
{
DWORD g1 = it_cont->first;
DWORD g2 = it->first;
TGuildWarPQElement* p = it->second.pElement;
TGuildWarPQElement *p = it->second.pElement;
if (!p || p->bEnd)
continue;
FSendPeerWar(p->bType, GUILD_WAR_ON_WAR, g1, g2) (peer);
FSendPeerWar(p->bType, GUILD_WAR_ON_WAR, g1, g2)(peer);
FSendGuildWarScore(p->GID[0], p->GID[1], p->iScore[0], p->iBetScore[0]);
FSendGuildWarScore(p->GID[1], p->GID[0], p->iScore[1], p->iBetScore[1]);
}
for_all(m_DeclareMap, it)
{
FSendPeerWar(it->bType, GUILD_WAR_SEND_DECLARE, it->dwGuildID[0], it->dwGuildID[1]) (peer);
FSendPeerWar(it->bType, GUILD_WAR_SEND_DECLARE, it->dwGuildID[0], it->dwGuildID[1])(peer);
}
for_all(m_map_kWarReserve, it)
@ -480,7 +495,7 @@ void CGuildManager::WarEnd(DWORD GID1, DWORD GID2, bool bForceDraw)
}
TGuildWarInfo gwi = itWarMap->second;
TGuildWarPQElement * pData = gwi.pElement;
TGuildWarPQElement *pData = gwi.pElement;
if (!pData || pData->bEnd)
{
@ -540,7 +555,7 @@ void CGuildManager::RecvWarOver(DWORD dwGuildWinner, DWORD dwGuildLoser, bool bD
if (it == m_WarMap[GID1].end())
return;
TGuildWarInfo & gw = it->second;
TGuildWarInfo &gw = it->second;
// Award
if (bDraw)
@ -574,14 +589,14 @@ void CGuildManager::RecvWarEnd(DWORD GID1, DWORD GID2)
WarEnd(GID1, GID2, true); // 무조건 비정상 종료 시켜야 한다.
}
void CGuildManager::StartWar(BYTE bType, DWORD GID1, DWORD GID2, CGuildWarReserve * pkReserve)
void CGuildManager::StartWar(BYTE bType, DWORD GID1, DWORD GID2, CGuildWarReserve *pkReserve)
{
SPDLOG_DEBUG("GuildWar: StartWar({},{},{})", bType, GID1, GID2);
if (GID1 > GID2)
std::swap(GID1, GID2);
TGuildWarInfo & gw = m_WarMap[GID1][GID2]; // map insert
TGuildWarInfo &gw = m_WarMap[GID1][GID2]; // map insert
if (bType == GUILD_WAR_TYPE_FIELD)
gw.tEndTime = CClientManager::instance().GetCurrentTime() + GUILD_WAR_DURATION;
@ -606,7 +621,7 @@ void CGuildManager::UpdateScore(DWORD dwGainGID, DWORD dwOppGID, int iScoreDelta
if (it != m_WarMap[GID1].end())
{
TGuildWarPQElement * p = it->second.pElement;
TGuildWarPQElement *p = it->second.pElement;
if (!p || p->bEnd)
{
@ -658,7 +673,7 @@ void CGuildManager::RemoveDeclare(DWORD guild_from, DWORD guild_to)
if (it != m_DeclareMap.end())
m_DeclareMap.erase(it);
it = m_DeclareMap.find(TGuildDeclareInfo(0,guild_to, guild_from));
it = m_DeclareMap.find(TGuildDeclareInfo(0, guild_to, guild_from));
if (it != m_DeclareMap.end())
m_DeclareMap.erase(it);
@ -693,7 +708,7 @@ bool CGuildManager::TakeBetPrice(DWORD dwGuildTo, DWORD dwGuildFrom, int lWarPri
return true;
}
bool CGuildManager::WaitStart(TPacketGuildWar * p)
bool CGuildManager::WaitStart(TPacketGuildWar *p)
{
if (p->lWarPrice > 0)
if (!TakeBetPrice(p->dwGuildFrom, p->dwGuildTo, p->lWarPrice))
@ -731,7 +746,7 @@ void CGuildManager::ChangeLadderPoint(DWORD GID, int change)
if (it == m_map_kGuild.end())
return;
TGuild & r = it->second;
TGuild &r = it->second;
r.ladder_point += change;
@ -798,7 +813,7 @@ void CGuildManager::DepositMoney(DWORD dwGuild, INT iGold)
MoneyChange(dwGuild, it->second.gold);
}
void CGuildManager::WithdrawMoney(CPeer* peer, DWORD dwGuild, INT iGold)
void CGuildManager::WithdrawMoney(CPeer *peer, DWORD dwGuild, INT iGold)
{
itertype(m_map_kGuild) it = m_map_kGuild.find(dwGuild);
@ -841,8 +856,8 @@ void CGuildManager::WithdrawMoneyReply(DWORD dwGuild, BYTE bGiveSuccess, INT iGo
//
// 예약 길드전(관전자가 배팅할 수 있다)
//
const int c_aiScoreByLevel[GUILD_MAX_LEVEL+1] =
{
const int c_aiScoreByLevel[GUILD_MAX_LEVEL + 1] =
{
500, // level 0 = 500 probably error
500, // 1
1000,
@ -866,8 +881,8 @@ const int c_aiScoreByLevel[GUILD_MAX_LEVEL+1] =
55000,
};
const int c_aiScoreByRanking[GUILD_RANK_MAX_NUM+1] =
{
const int c_aiScoreByRanking[GUILD_RANK_MAX_NUM + 1] =
{
0,
55000, // 1위
50000,
@ -893,11 +908,10 @@ const int c_aiScoreByRanking[GUILD_RANK_MAX_NUM+1] =
void CGuildManager::BootReserveWar()
{
const char * c_apszQuery[2] =
const char *c_apszQuery[2] =
{
"SELECT id, guild1, guild2, UNIX_TIMESTAMP(time), type, warprice, initscore, bet_from, bet_to, power1, power2, handicap FROM guild_war_reservation WHERE started=1 AND winner=-1",
"SELECT id, guild1, guild2, UNIX_TIMESTAMP(time), type, warprice, initscore, bet_from, bet_to, power1, power2, handicap FROM guild_war_reservation WHERE started=0"
};
"SELECT id, guild1, guild2, UNIX_TIMESTAMP(time), type, warprice, initscore, bet_from, bet_to, power1, power2, handicap FROM guild_war_reservation WHERE started=0"};
for (int i = 0; i < 2; ++i)
{
@ -928,14 +942,14 @@ void CGuildManager::BootReserveWar()
str_to_number(t.lHandicap, row[col++]);
t.bStarted = 0;
CGuildWarReserve * pkReserve = new CGuildWarReserve(t);
CGuildWarReserve *pkReserve = new CGuildWarReserve(t);
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분 이하 남은 예약 길드전도 무승부 처리한다. (각자의 배팅액을 돌려준다)
//if (i == 0 || (int) t.dwTime - CClientManager::instance().GetCurrentTime() < 60 * 5)
if (i == 0 || (int) t.dwTime - CClientManager::instance().GetCurrentTime() < 0)
// if (i == 0 || (int) t.dwTime - CClientManager::instance().GetCurrentTime() < 60 * 5)
if (i == 0 || (int)t.dwTime - CClientManager::instance().GetCurrentTime() < 0)
{
if (i == 0)
SPDLOG_DEBUG("{} : DB was shutdowned while war is being.", buf);
@ -967,7 +981,8 @@ int GetAverageGuildMemberLevel(DWORD dwGID)
MYSQL_ROW row;
row = mysql_fetch_row(msg->Get()->pSQLResult);
int nAverageLevel = 0; str_to_number(nAverageLevel, row[0]);
int nAverageLevel = 0;
str_to_number(nAverageLevel, row[0]);
return nAverageLevel;
}
@ -982,11 +997,12 @@ int GetGuildMemberCount(DWORD dwGID)
MYSQL_ROW row;
row = mysql_fetch_row(msg->Get()->pSQLResult);
DWORD dwCount = 0; str_to_number(dwCount, row[0]);
DWORD dwCount = 0;
str_to_number(dwCount, row[0]);
return dwCount;
}
bool CGuildManager::ReserveWar(TPacketGuildWar * p)
bool CGuildManager::ReserveWar(TPacketGuildWar *p)
{
DWORD GID1 = p->dwGuildFrom;
DWORD GID2 = p->dwGuildTo;
@ -1011,7 +1027,7 @@ bool CGuildManager::ReserveWar(TPacketGuildWar * p)
int lvp, rkp, alv, mc;
// 파워 계산
TGuild & k1 = TouchGuild(GID1);
TGuild &k1 = TouchGuild(GID1);
lvp = c_aiScoreByLevel[std::min<size_t>(GUILD_MAX_LEVEL, k1.level)];
rkp = c_aiScoreByRanking[GetRanking(GID1)];
@ -1023,11 +1039,11 @@ bool CGuildManager::ReserveWar(TPacketGuildWar * p)
polyPower.SetVar("alv", alv);
polyPower.SetVar("mc", mc);
t.lPowerFrom = (int) polyPower.Eval();
t.lPowerFrom = (int)polyPower.Eval();
SPDLOG_DEBUG("GuildWar: {} lvp {} rkp {} alv {} mc {} power {}", GID1, lvp, rkp, alv, mc, t.lPowerFrom);
// 파워 계산
TGuild & k2 = TouchGuild(GID2);
TGuild &k2 = TouchGuild(GID2);
lvp = c_aiScoreByLevel[std::min<size_t>(GUILD_MAX_LEVEL, k2.level)];
rkp = c_aiScoreByRanking[GetRanking(GID2)];
@ -1039,7 +1055,7 @@ bool CGuildManager::ReserveWar(TPacketGuildWar * p)
polyPower.SetVar("alv", alv);
polyPower.SetVar("mc", mc);
t.lPowerTo = (int) polyPower.Eval();
t.lPowerTo = (int)polyPower.Eval();
SPDLOG_DEBUG("GuildWar: {} lvp {} rkp {} alv {} mc {} power {}", GID2, lvp, rkp, alv, mc, t.lPowerTo);
// 핸디캡 계산
@ -1054,7 +1070,7 @@ bool CGuildManager::ReserveWar(TPacketGuildWar * p)
polyHandicap.SetVar("pB", t.lPowerTo);
}
t.lHandicap = (int) polyHandicap.Eval();
t.lHandicap = (int)polyHandicap.Eval();
SPDLOG_DEBUG("GuildWar: handicap {}", t.lHandicap);
// 쿼리
@ -1091,15 +1107,15 @@ void CGuildManager::ProcessReserveWar()
{
itertype(m_map_kWarReserve) it2 = it++;
CGuildWarReserve * pk = it2->second;
TGuildWarReserve & r = pk->GetDataRef();
CGuildWarReserve *pk = it2->second;
TGuildWarReserve &r = pk->GetDataRef();
if (!r.bStarted && r.dwTime - 1800 <= dwCurTime) // 30분 전부터 알린다.
{
int iMin = (int) ceil((int)(r.dwTime - dwCurTime) / 60.0);
int iMin = (int)ceil((int)(r.dwTime - dwCurTime) / 60.0);
TGuild & r_1 = m_map_kGuild[r.dwGuildFrom];
TGuild & r_2 = m_map_kGuild[r.dwGuildTo];
TGuild &r_1 = m_map_kGuild[r.dwGuildFrom];
TGuild &r_2 = m_map_kGuild[r.dwGuildTo];
SPDLOG_DEBUG("GuildWar: started GID1 {} GID2 {} {} time {} min {}", r.dwGuildFrom, r.dwGuildTo, r.bStarted, dwCurTime - r.dwTime, iMin);
@ -1126,7 +1142,7 @@ void CGuildManager::ProcessReserveWar()
pck.lInitialScore = r.lInitialScore;
CClientManager::instance().ForwardPacket(HEADER_DG_GUILD_WAR, &pck, sizeof(TPacketGuildWar));
//m_map_kWarReserve.erase(it2);
// m_map_kWarReserve.erase(it2);
}
else
{
@ -1144,7 +1160,7 @@ void CGuildManager::ProcessReserveWar()
}
}
bool CGuildManager::Bet(DWORD dwID, const char * c_pszLogin, DWORD dwGold, DWORD dwGuild)
bool CGuildManager::Bet(DWORD dwID, const char *c_pszLogin, DWORD dwGold, DWORD dwGuild)
{
itertype(m_map_kWarReserve) it = m_map_kWarReserve.find(dwID);
@ -1201,7 +1217,7 @@ bool CGuildManager::ChangeMaster(DWORD dwGID, DWORD dwFrom, DWORD dwTo)
//////////////////////////////////////////////////////////////////////////////////////////
// Guild War Reserve Class
//////////////////////////////////////////////////////////////////////////////////////////
CGuildWarReserve::CGuildWarReserve(const TGuildWarReserve & rTable)
CGuildWarReserve::CGuildWarReserve(const TGuildWarReserve &rTable)
{
memcpy(&m_data, &rTable, sizeof(TGuildWarReserve));
m_iLastNoticeMin = -1;
@ -1218,10 +1234,10 @@ void CGuildWarReserve::Initialize()
if (msgbet->Get()->uiNumRows)
{
MYSQL_RES * res = msgbet->Get()->pSQLResult;
MYSQL_RES *res = msgbet->Get()->pSQLResult;
MYSQL_ROW row;
char szLogin[LOGIN_MAX_LEN+1];
char szLogin[LOGIN_MAX_LEN + 1];
DWORD dwGuild;
DWORD dwGold;
@ -1237,12 +1253,12 @@ void CGuildWarReserve::Initialize()
}
}
void CGuildWarReserve::OnSetup(CPeer * peer)
void CGuildWarReserve::OnSetup(CPeer *peer)
{
if (m_data.bStarted) // 이미 시작된 것은 보내지 않는다.
return;
FSendPeerWar(m_data.bType, GUILD_WAR_RESERVE, m_data.dwGuildFrom, m_data.dwGuildTo) (peer);
FSendPeerWar(m_data.bType, GUILD_WAR_RESERVE, m_data.dwGuildFrom, m_data.dwGuildTo)(peer);
peer->EncodeHeader(HEADER_DG_GUILD_WAR_RESERVE_ADD, 0, sizeof(TGuildWarReserve));
peer->Encode(&m_data, sizeof(TGuildWarReserve));
@ -1265,7 +1281,7 @@ void CGuildWarReserve::OnSetup(CPeer * peer)
}
}
bool CGuildWarReserve::Bet(const char * pszLogin, DWORD dwGold, DWORD dwGuild)
bool CGuildWarReserve::Bet(const char *pszLogin, DWORD dwGold, DWORD dwGuild)
{
char szQuery[1024];
@ -1456,12 +1472,12 @@ void CGuildWarReserve::End(int iScoreFrom, int iScoreTo)
continue;
}
double ratio = (double) it->second.second / dwWinnerBet;
double ratio = (double)it->second.second / dwWinnerBet;
// 10% 세금 공제 후 분배
SPDLOG_DEBUG("WAR_REWARD: {} {} ratio {}", it->first.c_str(), it->second.second, ratio);
DWORD dwGold = (DWORD) (dwTotalBet * ratio * 0.9);
DWORD dwGold = (DWORD)(dwTotalBet * ratio * 0.9);
if (iRow == 0)
iLen += snprintf(szQuery + iLen, sizeof(szQuery) - iLen, "('%s', %d, %u, NOW())",
@ -1488,4 +1504,3 @@ void CGuildWarReserve::End(int iScoreFrom, int iScoreTo)
break;
}
}

View File

@ -27,12 +27,12 @@ struct TGuildDeclareInfo
dwGuildID[1] = _dwGuildID2;
}
bool operator < (const TGuildDeclareInfo& r) const
bool operator<(const TGuildDeclareInfo &r) const
{
return dwGuildID[0] < r.dwGuildID[0] || dwGuildID[0] == r.dwGuildID[0] && dwGuildID[1] < r.dwGuildID[1];
}
TGuildDeclareInfo& operator = (const TGuildDeclareInfo& r)
TGuildDeclareInfo &operator=(const TGuildDeclareInfo &r)
{
bType = r.bType;
dwGuildID[0] = r.dwGuildID[0];
@ -47,21 +47,21 @@ struct TGuildWaitStartInfo
DWORD GID[2];
int lWarPrice;
int lInitialScore;
CGuildWarReserve * pkReserve;
CGuildWarReserve *pkReserve;
TGuildWaitStartInfo(BYTE _bType,
DWORD _g1,
DWORD _g2,
int _lWarPrice,
int _lInitialScore,
CGuildWarReserve * _pkReserve)
CGuildWarReserve *_pkReserve)
: bType(_bType), lWarPrice(_lWarPrice), lInitialScore(_lInitialScore), pkReserve(_pkReserve)
{
GID[0] = _g1;
GID[1] = _g2;
}
bool operator < (const TGuildWaitStartInfo& r) const
bool operator<(const TGuildWaitStartInfo &r) const
{
return GID[0] < r.GID[0] || GID[0] == r.GID[0] && GID[1] < r.GID[1];
}
@ -97,7 +97,7 @@ struct TGuildSkillUsed
// END_OF_GUILD_SKILL_COOLTIME_BUG_FIX
};
inline bool operator < (const TGuildSkillUsed& a, const TGuildSkillUsed& b)
inline bool operator<(const TGuildSkillUsed &a, const TGuildSkillUsed &b)
{
return a.GID < b.GID || a.GID == b.GID && a.dwSkillVnum < b.dwSkillVnum;
}
@ -109,7 +109,7 @@ typedef struct SGuild
memset(szName, 0, sizeof(szName));
}
char szName[GUILD_NAME_MAX_LEN+1];
char szName[GUILD_NAME_MAX_LEN + 1];
int ladder_point;
int win;
int draw;
@ -121,8 +121,8 @@ typedef struct SGuild
typedef struct SGuildWarInfo
{
time_t tEndTime;
TGuildWarPQElement * pElement;
CGuildWarReserve * pkReserve;
TGuildWarPQElement *pElement;
CGuildWarReserve *pkReserve;
SGuildWarInfo() : pElement(NULL)
{
@ -131,36 +131,36 @@ typedef struct SGuildWarInfo
class CGuildWarReserve
{
public:
CGuildWarReserve(const TGuildWarReserve& rTable);
public:
CGuildWarReserve(const TGuildWarReserve &rTable);
void Initialize();
TGuildWarReserve & GetDataRef()
TGuildWarReserve &GetDataRef()
{
return m_data;
}
void OnSetup(CPeer * peer);
bool Bet(const char * pszLogin, DWORD dwGold, DWORD dwGuild);
void OnSetup(CPeer *peer);
bool Bet(const char *pszLogin, DWORD dwGold, DWORD dwGuild);
void Draw();
void End(int iScoreFrom, int iScoreTo);
int GetLastNoticeMin() { return m_iLastNoticeMin; }
void SetLastNoticeMin(int iMin) { m_iLastNoticeMin = iMin; }
private:
private:
CGuildWarReserve(); // 기본 생성자를 사용하지 못하도록 의도적으로 구현하지 않음
TGuildWarReserve m_data;
// <login, <guild, gold>>
std::map<std::string, std::pair<DWORD, DWORD> > mapBet;
std::map<std::string, std::pair<DWORD, DWORD>> mapBet;
int m_iLastNoticeMin;
};
class CGuildManager : public singleton<CGuildManager>
{
public:
public:
CGuildManager();
virtual ~CGuildManager();
@ -168,12 +168,12 @@ class CGuildManager : public singleton<CGuildManager>
void Load(DWORD dwGuildID);
TGuild & TouchGuild(DWORD GID);
TGuild &TouchGuild(DWORD GID);
void Update();
void OnSetup(CPeer * peer);
void StartWar(BYTE bType, DWORD GID1, DWORD GID2, CGuildWarReserve * pkReserve = NULL);
void OnSetup(CPeer *peer);
void StartWar(BYTE bType, DWORD GID1, DWORD GID2, CGuildWarReserve *pkReserve = NULL);
void UpdateScore(DWORD guild_gain_point, DWORD guild_opponent, int iScore, int iBetScore);
@ -182,7 +182,7 @@ class CGuildManager : public singleton<CGuildManager>
bool TakeBetPrice(DWORD dwGuildTo, DWORD dwGuildFrom, int lWarPrice);
bool WaitStart(TPacketGuildWar * p);
bool WaitStart(TPacketGuildWar *p);
void RecvWarEnd(DWORD GID1, DWORD GID2);
void RecvWarOver(DWORD dwGuildWinner, DWORD dwGuildLoser, bool bDraw, int lWarPrice);
@ -193,29 +193,29 @@ class CGuildManager : public singleton<CGuildManager>
INT GetGuildGold(DWORD dwGuild);
void DepositMoney(DWORD dwGuild, INT lGold);
void WithdrawMoney(CPeer* peer, DWORD dwGuild, INT lGold);
void WithdrawMoney(CPeer *peer, DWORD dwGuild, INT lGold);
void WithdrawMoneyReply(DWORD dwGuild, BYTE bGiveSuccess, INT lGold);
void MoneyChange(DWORD dwGuild, DWORD dwGold);
void QueryRanking();
void ResultRanking(MYSQL_RES * pRes);
void ResultRanking(MYSQL_RES *pRes);
int GetRanking(DWORD dwGID);
//
// Reserve War
//
void BootReserveWar();
bool ReserveWar(TPacketGuildWar * p);
bool ReserveWar(TPacketGuildWar *p);
void ProcessReserveWar();
bool Bet(DWORD dwID, const char * c_pszLogin, DWORD dwGold, DWORD dwGuild);
bool Bet(DWORD dwID, const char *c_pszLogin, DWORD dwGold, DWORD dwGuild);
void CancelWar(DWORD GID1, DWORD GID2);
bool ChangeMaster(DWORD dwGID, DWORD dwFrom, DWORD dwTo);
private:
void ParseResult(SQLResult * pRes);
private:
void ParseResult(SQLResult *pRes);
void RemoveWar(DWORD GID1, DWORD GID2); // erase war from m_WarMap and set end on priority queue
@ -233,20 +233,20 @@ class CGuildManager : public singleton<CGuildManager>
bool IsHalfWinLadderPoint(DWORD dwGuildWinner, DWORD dwGuildLoser);
std::map<DWORD, TGuild> m_map_kGuild;
std::map<DWORD, std::map<DWORD, time_t> > m_mapGuildWarEndTime;
std::map<DWORD, std::map<DWORD, time_t>> m_mapGuildWarEndTime;
std::set<TGuildDeclareInfo> m_DeclareMap; // 선전 포고 상태를 저장
std::map<DWORD, std::map<DWORD, TGuildWarInfo> > m_WarMap;
std::map<DWORD, std::map<DWORD, TGuildWarInfo>> m_WarMap;
typedef std::pair<time_t, TGuildWarPQElement *> stPairGuildWar;
typedef std::pair<time_t, TGuildSkillUsed> stPairSkillUsed;
typedef std::pair<time_t, TGuildWaitStartInfo> stPairWaitStart;
std::priority_queue<stPairGuildWar, std::vector<stPairGuildWar>, std::greater<stPairGuildWar> >
std::priority_queue<stPairGuildWar, std::vector<stPairGuildWar>, std::greater<stPairGuildWar>>
m_pqOnWar;
std::priority_queue<stPairWaitStart, std::vector<stPairWaitStart>, std::greater<stPairWaitStart> >
std::priority_queue<stPairWaitStart, std::vector<stPairWaitStart>, std::greater<stPairWaitStart>>
m_pqWaitStart;
std::priority_queue<stPairSkillUsed, std::vector<stPairSkillUsed>, std::greater<stPairSkillUsed> >
std::priority_queue<stPairSkillUsed, std::vector<stPairSkillUsed>, std::greater<stPairSkillUsed>>
m_pqSkill;
std::map<DWORD, CGuildWarReserve *> m_map_kWarReserve;

View File

@ -6,8 +6,6 @@
#include "ClientManager.h"
DWORD g_dwLastCachedItemAwardID = 0;
ItemAwardManager::ItemAwardManager()
{
@ -24,9 +22,9 @@ void ItemAwardManager::RequestLoad()
CDBManager::instance().ReturnQuery(szQuery, QID_ITEM_AWARD_LOAD, 0, NULL);
}
void ItemAwardManager::Load(SQLMsg * pMsg)
void ItemAwardManager::Load(SQLMsg *pMsg)
{
MYSQL_RES * pRes = pMsg->Get()->pSQLResult;
MYSQL_RES *pRes = pMsg->Get()->pSQLResult;
for (uint i = 0; i < pMsg->Get()->uiNumRows; ++i)
{
@ -39,7 +37,7 @@ void ItemAwardManager::Load(SQLMsg * pMsg)
if (m_map_award.find(dwID) != m_map_award.end())
continue;
TItemAward * kData = new TItemAward;
TItemAward *kData = new TItemAward;
memset(kData, 0, sizeof(TItemAward));
kData->dwID = dwID;
@ -54,20 +52,20 @@ 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 얻기
//SPDLOG_ERROR("{}, {}",pItemAward->dwID,command);
if( !(strcmp(command,"GIFT") )) // command 가 GIFT이면
strcpy(command, CClientManager::instance().GetCommand(cmdStr).c_str()); // command 얻기
// SPDLOG_ERROR("{}, {}",pItemAward->dwID,command);
if (!(strcmp(command, "GIFT"))) // command 가 GIFT이면
{
TPacketItemAwardInfromer giftData;
strcpy(giftData.login, kData->szLogin); //로그인 아이디 복사
strcpy(giftData.command, command); //명령어 복사
giftData.vnum = kData->dwVnum; //아이템 vnum도 복사
CClientManager::instance().ForwardPacket(HEADER_DG_ITEMAWARD_INFORMER,&giftData,sizeof(TPacketItemAwardInfromer));
strcpy(giftData.login, kData->szLogin); // 로그인 아이디 복사
strcpy(giftData.command, command); // 명령어 복사
giftData.vnum = kData->dwVnum; // 아이템 vnum도 복사
CClientManager::instance().ForwardPacket(HEADER_DG_ITEMAWARD_INFORMER, &giftData, sizeof(TPacketItemAwardInfromer));
}
}
@ -75,7 +73,7 @@ void ItemAwardManager::Load(SQLMsg * pMsg)
printf("ITEM_AWARD load id %u bMall %d \n", kData->dwID, kData->bMall);
SPDLOG_DEBUG("ITEM_AWARD: load id {} login {} vnum {} count {} socket {}", kData->dwID, kData->szLogin, kData->dwVnum, kData->dwCount, kData->dwSocket0);
std::set<TItemAward *> & kSet = m_map_kSetAwardByLogin[kData->szLogin];
std::set<TItemAward *> &kSet = m_map_kSetAwardByLogin[kData->szLogin];
kSet.insert(kData);
if (dwID > g_dwLastCachedItemAwardID)
@ -83,7 +81,7 @@ void ItemAwardManager::Load(SQLMsg * pMsg)
}
}
std::set<TItemAward *> * ItemAwardManager::GetByLogin(const char * c_pszLogin)
std::set<TItemAward *> *ItemAwardManager::GetByLogin(const char *c_pszLogin)
{
itertype(m_map_kSetAwardByLogin) it = m_map_kSetAwardByLogin.find(c_pszLogin);
@ -103,7 +101,7 @@ void ItemAwardManager::Taken(DWORD dwAwardID, DWORD dwItemID)
return;
}
TItemAward * k = it->second;
TItemAward *k = it->second;
k->bTaken = true;
//
@ -118,12 +116,12 @@ void ItemAwardManager::Taken(DWORD dwAwardID, DWORD dwItemID)
CDBManager::instance().ReturnQuery(szQuery, QID_ITEM_AWARD_TAKEN, 0, NULL);
}
std::map<DWORD, TItemAward *>& ItemAwardManager::GetMapAward()
std::map<DWORD, TItemAward *> &ItemAwardManager::GetMapAward()
{
return m_map_award;
}
std::map<std::string, std::set<TItemAward *> >& ItemAwardManager::GetMapkSetAwardByLogin()
std::map<std::string, std::set<TItemAward *>> &ItemAwardManager::GetMapkSetAwardByLogin()
{
return m_map_kSetAwardByLogin;
}

View File

@ -8,36 +8,37 @@
typedef struct SItemAward
{
DWORD dwID;
char szLogin[LOGIN_MAX_LEN+1];
char szLogin[LOGIN_MAX_LEN + 1];
DWORD dwVnum;
DWORD dwCount;
DWORD dwSocket0;
DWORD dwSocket1;
DWORD dwSocket2;
char szWhy[ITEM_AWARD_WHY_MAX_LEN+1];
char szWhy[ITEM_AWARD_WHY_MAX_LEN + 1];
bool bTaken;
bool bMall;
} TItemAward;
class ItemAwardManager : public singleton<ItemAwardManager>
{
public:
public:
ItemAwardManager();
virtual ~ItemAwardManager();
void RequestLoad();
void Load(SQLMsg * pMsg);
std::set<TItemAward *> * GetByLogin(const char * c_pszLogin);
void Load(SQLMsg *pMsg);
std::set<TItemAward *> *GetByLogin(const char *c_pszLogin);
void Taken(DWORD dwAwardID, DWORD dwItemID);
// gift notify
std::map<DWORD, TItemAward *>& GetMapAward();
std::map<std::string, std::set<TItemAward *> >& GetMapkSetAwardByLogin();
private:
std::map<DWORD, TItemAward *> &GetMapAward();
std::map<std::string, std::set<TItemAward *>> &GetMapkSetAwardByLogin();
private:
// ID, ItemAward pair
std::map<DWORD, TItemAward *> m_map_award;
// PID, ItemAward pair
std::map<std::string, std::set<TItemAward *> > m_map_kSetAwardByLogin;
std::map<std::string, std::set<TItemAward *>> m_map_kSetAwardByLogin;
};
#endif

View File

@ -16,7 +16,7 @@ void CItemIDRangeManager::Build()
DWORD dwMax = 0;
TItemIDRangeTable range;
for (int i = 0; ; ++i)
for (int i = 0;; ++i)
{
dwMin = cs_dwMinimumRange * (i + 1) + 1;
dwMax = cs_dwMinimumRange * (i + 2);
@ -48,7 +48,7 @@ struct FCheckCollision
range = data;
}
void operator() (CPeer* peer)
void operator()(CPeer *peer)
{
if (hasCollision == false)
{
@ -74,7 +74,8 @@ TItemIDRangeTable CItemIDRangeManager::GetRange()
FCheckCollision f(ret);
CClientManager::instance().for_each_peer(f);
if (f.hasCollision == false) return ret;
if (f.hasCollision == false)
return ret;
}
}
@ -84,11 +85,11 @@ TItemIDRangeTable CItemIDRangeManager::GetRange()
return ret;
}
bool CItemIDRangeManager::BuildRange(DWORD dwMin, DWORD dwMax, TItemIDRangeTable& range)
bool CItemIDRangeManager::BuildRange(DWORD dwMin, DWORD dwMax, TItemIDRangeTable &range)
{
char szQuery[1024];
DWORD dwItemMaxID = 0;
SQLMsg* pMsg = NULL;
SQLMsg *pMsg = NULL;
MYSQL_ROW row;
snprintf(szQuery, sizeof(szQuery), "SELECT MAX(id) FROM item%s WHERE id >= %u and id <= %u", GetTablePostfix(), dwMin, dwMax);
@ -162,4 +163,3 @@ void CItemIDRangeManager::UpdateRange(DWORD dwMin, DWORD dwMax)
m_listData.push_back(range);
}
}

View File

@ -2,7 +2,8 @@
#ifndef __INC_METIN_II_ITEM_ID_RANGE_MANAGER_H__
#define __INC_METIN_II_ITEM_ID_RANGE_MANAGER_H__
namespace {
namespace
{
static const uint32_t cs_dwMaxItemID = 4290000000UL;
static const uint32_t cs_dwMinimumRange = 10000000UL;
static const uint32_t cs_dwMinimumRemainCount = 10000UL;
@ -10,14 +11,14 @@ namespace {
class CItemIDRangeManager : public singleton<CItemIDRangeManager>
{
private:
private:
std::list<TItemIDRangeTable> m_listData;
public:
public:
CItemIDRangeManager();
void Build();
bool BuildRange(DWORD dwMin, DWORD dwMax, TItemIDRangeTable& range);
bool BuildRange(DWORD dwMin, DWORD dwMax, TItemIDRangeTable &range);
void UpdateRange(DWORD dwMin, DWORD dwMax);
TItemIDRangeTable GetRange();

View File

@ -6,7 +6,7 @@ typedef pthread_mutex_t lock_t;
class CLock
{
public:
public:
CLock();
~CLock();
@ -16,7 +16,7 @@ class CLock
void Lock();
void Unlock();
private:
private:
lock_t m_lock;
bool m_bLocked;
};

View File

@ -17,17 +17,17 @@ CLoginData::CLoginData()
memset(&m_data, 0, sizeof(TAccountTable));
}
TAccountTable & CLoginData::GetAccountRef()
TAccountTable &CLoginData::GetAccountRef()
{
return m_data;
}
void CLoginData::SetClientKey(const DWORD * c_pdwClientKey)
void CLoginData::SetClientKey(const DWORD *c_pdwClientKey)
{
memcpy(&m_adwClientKey, c_pdwClientKey, sizeof(DWORD) * 4);
}
const DWORD * CLoginData::GetClientKey()
const DWORD *CLoginData::GetClientKey()
{
return &m_adwClientKey[0];
}
@ -62,12 +62,12 @@ DWORD CLoginData::GetLogonTime()
return m_dwLogonTime;
}
void CLoginData::SetIP(const char * c_pszIP)
void CLoginData::SetIP(const char *c_pszIP)
{
strlcpy(m_szIP, c_pszIP, sizeof(m_szIP));
}
const char * CLoginData::GetIP()
const char *CLoginData::GetIP()
{
return m_szIP;
}
@ -101,7 +101,7 @@ bool CLoginData::IsDeleted()
return m_bDeleted;
}
void CLoginData::SetPremium(DWORD * paiPremiumTimes)
void CLoginData::SetPremium(DWORD *paiPremiumTimes)
{
memcpy(m_aiPremiumTimes, paiPremiumTimes, sizeof(m_aiPremiumTimes));
}
@ -114,8 +114,7 @@ DWORD CLoginData::GetPremium(BYTE type)
return m_aiPremiumTimes[type];
}
DWORD * CLoginData::GetPremiumPtr()
DWORD *CLoginData::GetPremiumPtr()
{
return &m_aiPremiumTimes[0];
}

View File

@ -4,13 +4,13 @@
class CLoginData
{
public:
public:
CLoginData();
TAccountTable & GetAccountRef();
void SetClientKey(const DWORD * c_pdwClientKey);
TAccountTable &GetAccountRef();
void SetClientKey(const DWORD *c_pdwClientKey);
const DWORD * GetClientKey();
const DWORD *GetClientKey();
void SetKey(DWORD dwKey);
DWORD GetKey();
@ -20,8 +20,8 @@ class CLoginData
void SetLogonTime();
DWORD GetLogonTime();
void SetIP(const char * c_pszIP);
const char * GetIP();
void SetIP(const char *c_pszIP);
const char *GetIP();
void SetPlay(bool bOn);
bool IsPlay();
@ -31,19 +31,19 @@ class CLoginData
time_t GetLastPlayTime() { return m_lastPlayTime; }
void SetPremium(DWORD * paiPremiumTimes);
void SetPremium(DWORD *paiPremiumTimes);
DWORD GetPremium(BYTE type);
DWORD * GetPremiumPtr();
DWORD *GetPremiumPtr();
DWORD GetLastPlayerID() const { return m_dwLastPlayerID; }
void SetLastPlayerID(DWORD id) { m_dwLastPlayerID = id; }
private:
private:
DWORD m_dwKey;
DWORD m_adwClientKey[4];
DWORD m_dwConnectedPeerHandle;
DWORD m_dwLogonTime;
char m_szIP[MAX_HOST_LENGTH+1];
char m_szIP[MAX_HOST_LENGTH + 1];
bool m_bPlay;
bool m_bDeleted;

View File

@ -10,35 +10,33 @@
#include "Marriage.h"
#include "Monarch.h"
#include "ItemIDRangeManager.h"
#ifndef __INTELLISENSE__
#include <version.h>
#else
#include <../../../common/version.h>
#endif
#include <signal.h>
void SetTablePostfix(const char* c_pszTablePostfix);
void SetTablePostfix(const char *c_pszTablePostfix);
int Start();
std::string g_stTablePostfix;
std::string g_stLocaleNameColumn = "name";
std::string g_stLocale = "euckr";
BOOL g_test_server = false;
//단위 초
int g_iPlayerCacheFlushSeconds = 60*7;
int g_iItemCacheFlushSeconds = 60*5;
//g_iLogoutSeconds 수치는 g_iPlayerCacheFlushSeconds 와 g_iItemCacheFlushSeconds 보다 길어야 한다.
int g_iLogoutSeconds = 60*10;
// 단위 초
int g_iPlayerCacheFlushSeconds = 60 * 7;
int g_iItemCacheFlushSeconds = 60 * 5;
// g_iLogoutSeconds 수치는 g_iPlayerCacheFlushSeconds 와 g_iItemCacheFlushSeconds 보다 길어야 한다.
int g_iLogoutSeconds = 60 * 10;
// MYSHOP_PRICE_LIST
int g_iItemPriceListTableCacheFlushSeconds = 540;
// END_OF_MYSHOP_PRICE_LIST
#ifdef __FreeBSD__
extern const char * _malloc_options;
#endif
void emergency_sig(int sig)
{
if (sig == SIGSEGV)
@ -55,10 +53,6 @@ int main()
WriteVersion();
log_init();
#ifdef __FreeBSD__
_malloc_options = "A";
#endif
CConfig Config;
CDBManager DBManager;
CClientManager ClientManager;
@ -82,21 +76,23 @@ int main()
signal_timer_disable();
DBManager.Quit();
int iCount;
while (true)
{
iCount = 0;
// TODO Check if this is really needed, this should just be cleaning up queued queries
// int iCount;
iCount += CDBManager::instance().CountReturnQuery(SQL_PLAYER);
iCount += CDBManager::instance().CountAsyncQuery(SQL_PLAYER);
// while (true)
// {
// iCount = 0;
if (iCount == 0)
break;
// iCount += CDBManager::instance().CountReturnQuery(SQL_PLAYER);
// iCount += CDBManager::instance().CountAsyncQuery(SQL_PLAYER);
usleep(1000);
SPDLOG_DEBUG("WAITING_QUERY_COUNT {}", iCount);
}
// if (iCount == 0)
// break;
// usleep(1000);
// SPDLOG_DEBUG("WAITING_QUERY_COUNT {}", iCount);
// }
log_destroy();
@ -147,7 +143,7 @@ int Start()
thecore_init(heart_beat, emptybeat);
signal_timer_enable(60);
char szBuf[256+1];
char szBuf[256 + 1];
if (CConfig::instance().GetValue("LOCALE", szBuf, 256))
{
@ -185,7 +181,8 @@ int Start()
//
if (CConfig::instance().GetValue("CACHE_FLUSH_LIMIT_PER_SECOND", szBuf, 256))
{
DWORD dwVal = 0; str_to_number(dwVal, szBuf);
DWORD dwVal = 0;
str_to_number(dwVal, szBuf);
CClientManager::instance().SetCacheFlushCountLimit(dwVal);
}
@ -206,60 +203,18 @@ int Start()
char szAddr[64], szDB[64], szUser[64], szPassword[64];
int iPort;
char line[256+1];
char line[256 + 1];
if (CConfig::instance().GetValue("SQL_PLAYER", line, 256)) {
sscanf(line, " %s %s %s %s %d ", szAddr, szDB, szUser, szPassword, &iPort);
SPDLOG_DEBUG("Connecting to MySQL server (player)");
SPDLOG_DEBUG("Connecting to PostgreSQL server");
if (!CDBManager::instance().Connect(SQL_PLAYER, szAddr, iPort, szDB, szUser, szPassword)) {
SPDLOG_CRITICAL("Connection to MySQL server (player) failed!");
return false;
}
SPDLOG_INFO("Connected to MySQL server (player)");
}
else {
SPDLOG_CRITICAL("SQL_PLAYER not configured");
return false;
}
if (CConfig::instance().GetValue("SQL_ACCOUNT", line, 256)) {
sscanf(line, " %s %s %s %s %d ", szAddr, szDB, szUser, szPassword, &iPort);
SPDLOG_DEBUG("Connecting to MySQL server (account)");
if (!CDBManager::instance().Connect(SQL_ACCOUNT, szAddr, iPort, szDB, szUser, szPassword)) {
SPDLOG_CRITICAL("Connection to MySQL server (account) failed!");
return false;
}
SPDLOG_INFO("Connected to MySQL server (account)");
}
else
if (!CDBManager::instance().Connect(szAddr, iPort, szDB, szUser, szPassword))
{
SPDLOG_CRITICAL("SQL_ACCOUNT not configured");
SPDLOG_CRITICAL("Connection to PostgreSQL server failed!");
return false;
}
if (CConfig::instance().GetValue("SQL_COMMON", line, 256))
{
sscanf(line, " %s %s %s %s %d ", szAddr, szDB, szUser, szPassword, &iPort);
SPDLOG_DEBUG("Connecting to MySQL server (common)");
if (!CDBManager::instance().Connect(SQL_COMMON, szAddr, iPort, szDB, szUser, szPassword))
{
SPDLOG_CRITICAL("Connection to MySQL server (common) failed!");
return false;
}
SPDLOG_INFO("Connected to MySQL server (common)");
}
else
{
SPDLOG_CRITICAL("SQL_COMMON not configured");
return false;
}
SPDLOG_INFO("Connected to PostgreSQL server");
if (!CClientManager::instance().Initialize())
{
@ -274,7 +229,7 @@ int Start()
return true;
}
void SetTablePostfix(const char* c_pszTablePostfix)
void SetTablePostfix(const char *c_pszTablePostfix)
{
if (!c_pszTablePostfix || !*c_pszTablePostfix)
g_stTablePostfix = "";
@ -282,7 +237,7 @@ void SetTablePostfix(const char* c_pszTablePostfix)
g_stTablePostfix = c_pszTablePostfix;
}
const char * GetTablePostfix()
const char *GetTablePostfix()
{
return g_stTablePostfix.c_str();
}

View File

@ -2,8 +2,6 @@
#define __INC_MAIN_H__
int Start();
void End();
const char * GetTablePostfix();
const char * GetPlayerDBName();
const char *GetTablePostfix();
#endif

View File

@ -7,17 +7,17 @@
namespace marriage
{
const DWORD WEDDING_LENGTH = 60 * 60; // sec
bool operator < (const TWedding& lhs, const TWedding& rhs)
bool operator<(const TWedding &lhs, const TWedding &rhs)
{
return lhs.dwTime < rhs.dwTime;
}
bool operator > (const TWedding& lhs, const TWedding& rhs)
bool operator>(const TWedding &lhs, const TWedding &rhs)
{
return lhs.dwTime > rhs.dwTime;
}
bool operator > (const TWeddingInfo &lhs, const TWeddingInfo& rhs)
bool operator>(const TWeddingInfo &lhs, const TWeddingInfo &rhs)
{
return lhs.dwTime > rhs.dwTime;
}
@ -43,7 +43,7 @@ namespace marriage
unique_ptr<SQLMsg> pmsg_delete(CDBManager::instance().DirectQuery("DELETE FROM marriage WHERE is_married = 0"));
unique_ptr<SQLMsg> pmsg(CDBManager::instance().DirectQuery(szQuery));
SQLResult * pRes = pmsg->Get();
SQLResult *pRes = pmsg->Get();
SPDLOG_DEBUG("MarriageList(size={})", pRes->uiNumRows);
if (pRes->uiNumRows > 0)
@ -52,15 +52,20 @@ namespace marriage
{
MYSQL_ROW row = mysql_fetch_row(pRes->pSQLResult);
DWORD pid1 = 0; str_to_number(pid1, row[0]);
DWORD pid2 = 0; str_to_number(pid2, row[1]);
int love_point = 0; str_to_number(love_point, row[2]);
DWORD time = 0; str_to_number(time, row[3]);
BYTE is_married = 0; str_to_number(is_married, row[4]);
const char* name1 = row[5];
const char* name2 = row[6];
DWORD pid1 = 0;
str_to_number(pid1, row[0]);
DWORD pid2 = 0;
str_to_number(pid2, row[1]);
int love_point = 0;
str_to_number(love_point, row[2]);
DWORD time = 0;
str_to_number(time, row[3]);
BYTE is_married = 0;
str_to_number(is_married, row[4]);
const char *name1 = row[5];
const char *name2 = row[6];
TMarriage* pMarriage = new TMarriage(pid1, pid2, love_point, time, is_married, name1, name2);
TMarriage *pMarriage = new TMarriage(pid1, pid2, love_point, time, is_married, name1, name2);
m_Marriages.insert(pMarriage);
m_MarriageByPID.insert(make_pair(pid1, pMarriage));
m_MarriageByPID.insert(make_pair(pid2, pMarriage));
@ -71,7 +76,7 @@ namespace marriage
return true;
}
TMarriage* CManager::Get(DWORD dwPlayerID)
TMarriage *CManager::Get(DWORD dwPlayerID)
{
itertype(m_MarriageByPID) it = m_MarriageByPID.find(dwPlayerID);
@ -81,13 +86,13 @@ namespace marriage
return NULL;
}
void Align(DWORD& rPID1, DWORD& rPID2)
void Align(DWORD &rPID1, DWORD &rPID2)
{
if (rPID1 > rPID2)
std::swap(rPID1, rPID2);
}
void CManager::Add(DWORD dwPID1, DWORD dwPID2, const char* szName1, const char* szName2)
void CManager::Add(DWORD dwPID1, DWORD dwPID2, const char *szName1, const char *szName2)
{
DWORD now = CClientManager::instance().GetCurrentTime();
if (IsMarried(dwPID1) || IsMarried(dwPID2))
@ -103,7 +108,7 @@ namespace marriage
unique_ptr<SQLMsg> pmsg(CDBManager::instance().DirectQuery(szQuery));
SQLResult* res = pmsg->Get();
SQLResult *res = pmsg->Get();
if (res->uiAffectedRows == 0 || res->uiAffectedRows == (uint32_t)-1)
{
SPDLOG_ERROR("cannot insert marriage");
@ -112,7 +117,7 @@ namespace marriage
SPDLOG_DEBUG("MARRIAGE ADD {} {}", dwPID1, dwPID2);
TMarriage* pMarriage = new TMarriage(dwPID1, dwPID2, 0, now, 0, szName1, szName2);
TMarriage *pMarriage = new TMarriage(dwPID1, dwPID2, 0, now, 0, szName1, szName2);
m_Marriages.insert(pMarriage);
m_MarriageByPID.insert(make_pair(dwPID1, pMarriage));
m_MarriageByPID.insert(make_pair(dwPID2, pMarriage));
@ -128,7 +133,7 @@ namespace marriage
void CManager::Update(DWORD dwPID1, DWORD dwPID2, INT iLovePoint, BYTE byMarried)
{
TMarriage* pMarriage = Get(dwPID1);
TMarriage *pMarriage = Get(dwPID1);
if (!pMarriage || pMarriage->GetOther(dwPID1) != dwPID2)
{
SPDLOG_ERROR("not under marriage : {} {}", dwPID1, dwPID2);
@ -143,7 +148,7 @@ namespace marriage
unique_ptr<SQLMsg> pmsg(CDBManager::instance().DirectQuery(szQuery));
SQLResult* res = pmsg->Get();
SQLResult *res = pmsg->Get();
if (res->uiAffectedRows == 0 || res->uiAffectedRows == (uint32_t)-1)
{
SPDLOG_ERROR("cannot update marriage : PID:{} {}", dwPID1, dwPID2);
@ -164,7 +169,7 @@ namespace marriage
void CManager::Remove(DWORD dwPID1, DWORD dwPID2)
{
TMarriage* pMarriage = Get(dwPID1);
TMarriage *pMarriage = Get(dwPID1);
if (pMarriage)
{
@ -189,7 +194,7 @@ namespace marriage
unique_ptr<SQLMsg> pmsg(CDBManager::instance().DirectQuery(szQuery));
SQLResult* res = pmsg->Get();
SQLResult *res = pmsg->Get();
if (res->uiAffectedRows == 0 || res->uiAffectedRows == (uint32_t)-1)
{
SPDLOG_ERROR("cannot delete marriage : PID:{} {}", dwPID1, dwPID2);
@ -212,7 +217,7 @@ namespace marriage
void CManager::EngageToMarriage(DWORD dwPID1, DWORD dwPID2)
{
TMarriage* pMarriage = Get(dwPID1);
TMarriage *pMarriage = Get(dwPID1);
if (!pMarriage || pMarriage->GetOther(dwPID1) != dwPID2)
{
SPDLOG_ERROR("not under marriage : PID:{} {}", dwPID1, dwPID2);
@ -233,7 +238,7 @@ namespace marriage
unique_ptr<SQLMsg> pmsg(CDBManager::instance().DirectQuery(szQuery));
SQLResult* res = pmsg->Get();
SQLResult *res = pmsg->Get();
if (res->uiAffectedRows == 0 || res->uiAffectedRows == (uint32_t)-1)
{
SPDLOG_ERROR("cannot change engage to marriage : PID:{} {}", dwPID1, dwPID2);
@ -251,12 +256,12 @@ namespace marriage
CClientManager::instance().ForwardPacket(HEADER_DG_MARRIAGE_UPDATE, &p, sizeof(p));
}
void CManager::OnSetup(CPeer* peer)
void CManager::OnSetup(CPeer *peer)
{
// 결혼한 사람들 보내기
for (itertype(m_Marriages) it = m_Marriages.begin(); it != m_Marriages.end(); ++it)
{
TMarriage* pMarriage = *it;
TMarriage *pMarriage = *it;
{
TPacketMarriageAdd p;
@ -283,7 +288,7 @@ namespace marriage
// 결혼식 보내기
for (itertype(m_mapRunningWedding) it = m_mapRunningWedding.begin(); it != m_mapRunningWedding.end(); ++it)
{
const TWedding& t = it->second;
const TWedding &t = it->second;
TPacketWeddingReady p;
p.dwPID1 = t.dwPID1;
@ -317,7 +322,7 @@ namespace marriage
return;
}
TWedding& w = it->second;
TWedding &w = it->second;
TPacketWeddingEnd p;
p.dwPID1 = w.dwPID1;
@ -341,7 +346,7 @@ namespace marriage
if (it == m_mapRunningWedding.end())
continue;
TWedding& w = it->second;
TWedding &w = it->second;
TPacketWeddingEnd p;
p.dwPID1 = w.dwPID1;
@ -353,7 +358,7 @@ namespace marriage
if (it_marriage != m_MarriageByPID.end())
{
TMarriage* pMarriage = it_marriage->second;
TMarriage *pMarriage = it_marriage->second;
if (!pMarriage->is_married)
{
Remove(pMarriage->pid1, pMarriage->pid2);

View File

@ -39,9 +39,9 @@ namespace marriage
}
};
extern bool operator < (const TWedding& lhs, const TWedding& rhs);
extern bool operator > (const TWedding& lhs, const TWedding& rhs);
extern bool operator > (const TWeddingInfo& lhs, const TWeddingInfo& rhs);
extern bool operator<(const TWedding &lhs, const TWedding &rhs);
extern bool operator>(const TWedding &lhs, const TWedding &rhs);
extern bool operator>(const TWeddingInfo &lhs, const TWeddingInfo &rhs);
struct TMarriage
{
@ -53,7 +53,7 @@ namespace marriage
std::string name1;
std::string name2;
TMarriage(DWORD _pid1, DWORD _pid2, int _love_point, DWORD _time, BYTE _is_married, const char* name1, const char* name2)
TMarriage(DWORD _pid1, DWORD _pid2, int _love_point, DWORD _time, BYTE _is_married, const char *name1, const char *name2)
: pid1(_pid1), pid2(_pid2), love_point(_love_point), time(_time), is_married(_is_married), name1(name1), name2(name2)
{
}
@ -78,14 +78,14 @@ namespace marriage
bool Initialize();
TMarriage* Get(DWORD dwPlayerID);
TMarriage *Get(DWORD dwPlayerID);
bool IsMarried(DWORD dwPlayerID)
{
return Get(dwPlayerID) != NULL;
}
//void Reserve(DWORD dwPID1, DWORD dwPID2);
void Add(DWORD dwPID1, DWORD dwPID2, const char* szName1, const char* szName2);
// void Reserve(DWORD dwPID1, DWORD dwPID2);
void Add(DWORD dwPID1, DWORD dwPID2, const char *szName1, const char *szName2);
void Remove(DWORD dwPID1, DWORD dwPID2);
void Update(DWORD dwPID1, DWORD dwPID2, INT iLovePoint, BYTE byMarried);
@ -94,7 +94,7 @@ namespace marriage
void ReadyWedding(DWORD dwMapIndex, DWORD dwPID1, DWORD dwPID2);
void EndWedding(DWORD dwPID1, DWORD dwPID2);
void OnSetup(CPeer* peer);
void OnSetup(CPeer *peer);
void Update();
@ -102,9 +102,9 @@ namespace marriage
std::set<TMarriage *> m_Marriages;
std::map<DWORD, TMarriage *> m_MarriageByPID;
std::priority_queue<TWedding, std::vector<TWedding>, std::greater<TWedding> > m_pqWeddingStart;
std::priority_queue<TWedding, std::vector<TWedding>, std::greater<TWedding>> m_pqWeddingStart;
std::priority_queue<TWeddingInfo, std::vector<TWeddingInfo>, std::greater<TWeddingInfo> > m_pqWeddingEnd;
std::priority_queue<TWeddingInfo, std::vector<TWeddingInfo>, std::greater<TWeddingInfo>> m_pqWeddingEnd;
std::map<std::pair<DWORD, DWORD>, TWedding> m_mapRunningWedding;
};

View File

@ -22,16 +22,14 @@ bool CMonarch::VoteMonarch(DWORD pid, DWORD selectdpid)
if (it == m_map_MonarchElection.end())
{
MonarchElectionInfo * p = new MonarchElectionInfo;
MonarchElectionInfo *p = new MonarchElectionInfo;
p->pid = pid;
p->selectedpid= selectdpid;
p->selectedpid = selectdpid;
m_map_MonarchElection.insert(MAP_MONARCHELECTION::value_type(pid, p));
char szQuery[256];
snprintf(szQuery, sizeof(szQuery),
"INSERT INTO monarch_election(pid, selectedpid, electiondata) VALUES(%d, %d, now())", pid, selectdpid);
CDBManager::instance().AsyncQuery(szQuery);
CDBManager::instance().AsyncQuery(
"INSERT INTO player.monarch_election(player_id, selected_player_id, election_at) VALUES($1, $2, now())",
pqxx::params(pid, selectdpid));
return 1;
}
@ -42,7 +40,7 @@ void CMonarch::ElectMonarch()
{
int size = GetVecMonarchCandidacy().size();
int * s = new int[size];
int *s = new int[size];
itertype(m_map_MonarchElection) it = m_map_MonarchElection.begin();
@ -58,7 +56,7 @@ void CMonarch::ElectMonarch()
SPDLOG_TRACE("[MONARCH_VOTE] pid({}) come to vote candidacy pid({})", it->second->pid, m_vec_MonarchCandidacy[idx].pid);
}
delete [] s;
delete[] s;
}
bool CMonarch::IsCandidacy(DWORD pid)
@ -74,7 +72,7 @@ bool CMonarch::IsCandidacy(DWORD pid)
return true;
}
bool CMonarch::AddCandidacy(DWORD pid, const char * name)
bool CMonarch::AddCandidacy(DWORD pid, const char *name)
{
if (IsCandidacy(pid) == false)
return false;
@ -85,32 +83,31 @@ bool CMonarch::AddCandidacy(DWORD pid, const char * name)
strlcpy(info.name, name, sizeof(info.name));
m_vec_MonarchCandidacy.push_back(info);
char szQuery[256];
snprintf(szQuery, sizeof(szQuery),
"INSERT INTO monarch_candidacy(pid, date) VALUES(%d, now())", pid);
CDBManager::instance().AsyncQuery(
"INSERT INTO player.monarch_candidacy(player_id, date) VALUES($1, now())",
pqxx::params(pid));
CDBManager::instance().AsyncQuery(szQuery);
return true;
}
bool CMonarch::DelCandidacy(const char * name)
bool CMonarch::DelCandidacy(const char *name)
{
itertype(m_vec_MonarchCandidacy) it = m_vec_MonarchCandidacy.begin();
for (; it != m_vec_MonarchCandidacy.end(); ++it)
{
if (0 == strncmp(it->name, name, sizeof(it->name)))
{
char szQuery[256];
snprintf(szQuery, sizeof(szQuery),
"DELETE FROM monarch_candidacy WHERE pid=%d ", it->pid);
CDBManager::instance().AsyncQuery(szQuery);
CDBManager::instance().AsyncQuery(
"DELETE FROM player.monarch_candidacy WHERE player_id=$1",
pqxx::params(it->pid));
m_vec_MonarchCandidacy.erase(it);
m_vec_MonarchCandidacy.erase (it);
return true;
}
}
return false;
return false;
}
bool CMonarch::IsMonarch(int Empire, DWORD pid)
@ -129,10 +126,9 @@ bool CMonarch::AddMoney(int Empire, int64_t Money)
int64_t Money64 = m_MonarchInfo.money[Empire];
char szQuery[1024];
snprintf(szQuery, sizeof(szQuery), "UPDATE monarch set money=%ld where empire=%d", Money64, Empire);
CDBManager::instance().AsyncQuery(szQuery);
CDBManager::instance().AsyncQuery(
"UPDATE player.monarch SET money=$1 WHERE empire=$2",
pqxx::params(Money64, Empire));
return true;
}
@ -145,10 +141,10 @@ bool CMonarch::DecMoney(int Empire, int64_t Money)
int64_t Money64 = m_MonarchInfo.money[Empire];
char szQuery[1024];
snprintf(szQuery, sizeof(szQuery), "UPDATE monarch set money=%ld where empire=%d", Money64, Empire);
CDBManager::instance().AsyncQuery(
"UPDATE player.monarch SET money=$1 WHERE empire=$2",
pqxx::params(Money64, Empire));
CDBManager::instance().AsyncQuery(szQuery);
return true;
}
@ -162,11 +158,9 @@ bool CMonarch::TakeMoney(int Empire, DWORD pid, int64_t Money)
m_MonarchInfo.money[Empire] -= Money;
char szQuery[1024];
snprintf(szQuery, sizeof(szQuery),
"UPDATE monarch set money=%ld; where empire=%d", m_MonarchInfo.money[Empire], Empire);
CDBManager::instance().AsyncQuery(szQuery);
CDBManager::instance().AsyncQuery(
"UPDATE player.monarch SET money=$1 WHERE empire=$2",
pqxx::params(m_MonarchInfo.money[Empire], Empire));
SPDLOG_TRACE("[MONARCH] Take money empire({}) money({})", Empire, m_MonarchInfo.money[Empire]);
return true;
@ -174,121 +168,152 @@ bool CMonarch::TakeMoney(int Empire, DWORD pid, int64_t Money)
bool CMonarch::LoadMonarch()
{
MonarchInfo * p = &m_MonarchInfo;
char szQuery[256];
snprintf(szQuery, sizeof(szQuery), "SELECT empire, pid, name, money, windate FROM monarch a, player%s b where a.pid=b.id", GetTablePostfix());
SQLMsg * pMsg = CDBManager::instance().DirectQuery(szQuery, SQL_PLAYER);
MonarchInfo *p = &m_MonarchInfo;
if (pMsg->Get()->uiNumRows == 0)
auto pool = CDBManager::instance().GetConnectionPool();
auto conn = pool->acquire();
try
{
pqxx::work txn{*conn};
pqxx::result result = txn.exec("SELECT empire, player_id, name, money, win_at FROM player.monarch m, player.player p WHERE m.player_id=p.id");
std::size_t const numRows = std::size(result);
if (numRows == 0)
{
delete pMsg;
return false;
}
MYSQL_ROW row;
for (int n = 0; (row = mysql_fetch_row(pMsg->Get()->pSQLResult)) != NULL; ++n)
for (auto row : result)
{
int idx = 0;
int Empire = 0; str_to_number(Empire, row[idx++]);
int Empire = row[0].as<int>();
str_to_number(p->pid[Empire], row[1].c_str());
strlcpy(p->name[Empire], row[2].c_str(), sizeof(p->name[Empire]));
str_to_number(p->pid[Empire], row[idx++]);
strlcpy(p->name[Empire], row[idx++], sizeof(p->name[Empire]));
str_to_number(p->money[Empire], row[idx++]);
strlcpy(p->date[Empire], row[idx++], sizeof(p->date[Empire]));
str_to_number(p->money[Empire], row[3].c_str());
strlcpy(p->date[Empire], row[4].c_str(), sizeof(p->date[Empire]));
SPDLOG_TRACE("[LOAD_MONARCH] Empire {} pid {} money {} windate {}", Empire, p->pid[Empire], p->money[Empire], p->date[Empire]);
}
delete pMsg;
return true;
}
bool CMonarch::SetMonarch(const char * name)
{
MonarchInfo * p = &m_MonarchInfo;
char szQuery[256];
snprintf(szQuery, sizeof(szQuery), "SELECT empire, pid, name FROM player a where a.name = '%s'", name);
SQLMsg * pMsg = CDBManager::instance().DirectQuery(szQuery, SQL_PLAYER);
if (pMsg->Get()->uiNumRows == 0)
txn.commit();
}
catch (const std::exception &e)
{
delete pMsg;
SPDLOG_ERROR("[CMonarch::LoadMonarch] Query error: {}", e.what());
return false;
}
MYSQL_ROW row;
int Empire = 0;
for (int n = 0; (row = mysql_fetch_row(pMsg->Get()->pSQLResult)) != NULL; ++n)
{
int idx = 0;
str_to_number(Empire, row[idx++]);
return true;
}
str_to_number(p->pid[Empire], row[idx++]);
strlcpy(p->name[Empire], row[idx++], sizeof(p->name[Empire]));
p->money[Empire] = atoll(row[idx++]);
bool CMonarch::SetMonarch(const char *name)
{
MonarchInfo *p = &m_MonarchInfo;
auto pool = CDBManager::instance().GetConnectionPool();
auto conn = pool->acquire();
try
{
pqxx::work txn{*conn};
// TODO Look at this, this should probably not iterate and just get one value instead
pqxx::result result = txn.exec_params("SELECT empire, player_id, name, money FROM player.player WHERE name=$1", name);
std::size_t const numRows = std::size(result);
if (numRows == 0)
{
return false;
}
int Empire = 0;
for (auto row : result)
{
Empire = row[0].as<int>();
str_to_number(p->pid[Empire], row[1].c_str());
strlcpy(p->name[Empire], row[2].c_str(), sizeof(p->name[Empire]));
p->money[Empire] = atoll(row[3].c_str());
SPDLOG_TRACE("[Set_MONARCH] Empire {} pid {} money {} windate {}", Empire, p->pid[Empire], p->money[Empire], p->date[Empire]);
}
delete pMsg;
//db에 입력
snprintf(szQuery, sizeof(szQuery),
"REPLACE INTO monarch (empire, name, windate, money) VALUES(%d, %d, now(), %ld)", Empire, p->pid[Empire], p->money[Empire]);
txn.commit();
CDBManager::instance().AsyncQuery(
"REPLACE INTO player.monarch (empire, name, win_at, money) VALUES($1, $2, now(), $3)",
pqxx::params{Empire, p->pid[Empire], p->money[Empire]});
}
catch (const std::exception &e)
{
SPDLOG_ERROR("[CMonarch::SetMonarch] Query error: {}", e.what());
return false;
}
CDBManager::instance().AsyncQuery(szQuery, SQL_PLAYER);
return true;
}
bool CMonarch::DelMonarch(int Empire)
{
char szQuery[256];
auto pool = CDBManager::instance().GetConnectionPool();
auto conn = pool->acquire();
snprintf(szQuery, sizeof(szQuery), "DELETE from monarch where empire=%d", Empire);
SQLMsg * pMsg = CDBManager::instance().DirectQuery(szQuery, SQL_PLAYER);
if (pMsg->Get()->uiNumRows == 0)
try
{
pqxx::work txn{*conn};
pqxx::result result = txn.exec_params("DELETE FROM player.monarch WHERE empire=$1 RETURNING id", Empire);
std::size_t const numRows = std::size(result);
if (numRows == 0)
{
delete pMsg;
return false;
}
delete pMsg;
}
catch (const std::exception &e)
{
SPDLOG_ERROR("[CMonarch::DelMonarch] Query error: {}", e.what());
return false;
}
memset(m_MonarchInfo.name[Empire], 0, sizeof(m_MonarchInfo.name[Empire]));
m_MonarchInfo.money[Empire] = 0;
m_MonarchInfo.pid[Empire] = 0;
return true;
}
bool CMonarch::DelMonarch(const char * name)
bool CMonarch::DelMonarch(const char *name)
{
for (int n = 1; n < 4; ++n)
{
if (0 == strncmp(m_MonarchInfo.name[n], name, sizeof(m_MonarchInfo.name[n])))
{
char szQuery[256];
auto pool = CDBManager::instance().GetConnectionPool();
auto conn = pool->acquire();
int Empire = n;
snprintf(szQuery, sizeof(szQuery), "DELETE from monarch where name=%d", Empire);
SQLMsg * pMsg = CDBManager::instance().DirectQuery(szQuery, SQL_PLAYER);
if (pMsg->Get()->uiNumRows == 0)
try
{
pqxx::work txn{*conn};
pqxx::result result = txn.exec_params("DELETE FROM player.monarch WHERE name=$1 RETURNING empire", name);
std::size_t const numRows = std::size(result);
if (numRows == 0)
{
SPDLOG_ERROR(" DirectQuery failed({})", szQuery);
delete pMsg;
return false;
}
delete pMsg;
for (auto row : result)
{
int Empire = row[0].as<int>();
memset(m_MonarchInfo.name[Empire], 0, 32);
memset(m_MonarchInfo.name[Empire], 0, sizeof(m_MonarchInfo.name[Empire]));
m_MonarchInfo.money[Empire] = 0;
m_MonarchInfo.pid[Empire] = 0;
return true;
}
}
catch (const std::exception &e)
{
SPDLOG_ERROR("[CMonarch::DelMonarch(name)] Query error: {}", e.what());
return false;
}
return false;
}

View File

@ -10,8 +10,8 @@
class CMonarch : public singleton<CMonarch>
{
public:
typedef std::map<DWORD, MonarchElectionInfo*> MAP_MONARCHELECTION;
public:
typedef std::map<DWORD, MonarchElectionInfo *> MAP_MONARCHELECTION;
typedef std::vector<MonarchCandidacy> VEC_MONARCHCANDIDACY;
CMonarch();
@ -21,25 +21,25 @@ class CMonarch : public singleton<CMonarch>
void ElectMonarch();
bool IsCandidacy(DWORD pid);
bool AddCandidacy(DWORD pid, const char * name);
bool DelCandidacy(const char * name);
bool AddCandidacy(DWORD pid, const char *name);
bool DelCandidacy(const char *name);
bool LoadMonarch();
bool SetMonarch(const char * name);
bool SetMonarch(const char *name);
bool DelMonarch(int Empire);
bool DelMonarch(const char * name);
bool DelMonarch(const char *name);
bool IsMonarch(int Empire, DWORD pid);
bool AddMoney(int Empire, int64_t Money);
bool DecMoney(int Empire, int64_t Money);
bool TakeMoney(int Empire, DWORD pid, int64_t Money);
TMonarchInfo* GetMonarch()
TMonarchInfo *GetMonarch()
{
return &m_MonarchInfo;
}
VEC_MONARCHCANDIDACY& GetVecMonarchCandidacy()
VEC_MONARCHCANDIDACY &GetVecMonarchCandidacy()
{
return m_vec_MonarchCandidacy;
}
@ -49,14 +49,14 @@ class CMonarch : public singleton<CMonarch>
return m_vec_MonarchCandidacy.size();
}
private:
private:
int GetCandidacyIndex(DWORD pid);
MAP_MONARCHELECTION m_map_MonarchElection;
VEC_MONARCHCANDIDACY m_vec_MonarchCandidacy;
TMonarchInfo m_MonarchInfo;
MonarchElectionInfo* GetMonarchElection(DWORD pid)
MonarchElectionInfo *GetMonarchElection(DWORD pid)
{
MAP_MONARCHELECTION::iterator it = m_map_MonarchElection.find(pid);

View File

@ -13,15 +13,15 @@ CMoneyLog::~CMoneyLog()
void CMoneyLog::Save()
{
CPeer* peer = CClientManager::instance().GetAnyPeer();
CPeer *peer = CClientManager::instance().GetAnyPeer();
if (!peer)
return;
for (BYTE bType = 0; bType < MONEY_LOG_TYPE_MAX_NUM; bType ++)
for (BYTE bType = 0; bType < MONEY_LOG_TYPE_MAX_NUM; bType++)
{
typeof(m_MoneyLogContainer[bType].begin()) it;
for (it = m_MoneyLogContainer[bType].begin(); it != m_MoneyLogContainer[bType].end(); ++it)
{
//bType;
// bType;
TPacketMoneyLog p;
p.type = bType;
p.vnum = it->first;
@ -31,24 +31,6 @@ void CMoneyLog::Save()
}
m_MoneyLogContainer[bType].clear();
}
/*
CPeer* peer = GetPeer();
peer->
for (BYTE bType = 0; bType < MONEY_LOG_TYPE_MAX_NUM; bType++)
{
//"INSERT INTO money_log%s VALUES('%s', %d, %d, %d)", CClientManager::instance().GetTablePostfix(),
typeof(m_MoneyLogContainer[bType].begin()) it;
for (it = m_MoneyLogContainer[bType].begin(); it != m_MoneyLogContainer[bType].end(); ++it)
{
typeof(it->second.begin())
}
}
for (BYTE bType = 0; bType < MONEY_LOG_TYPE_MAX_NUM; bType++)
m_MoneyLogContainer[bType].clear()
*/
}
void CMoneyLog::AddLog(BYTE bType, DWORD dwVnum, int iGold)

View File

@ -6,14 +6,14 @@
class CMoneyLog : public singleton<CMoneyLog>
{
public:
public:
CMoneyLog();
virtual ~CMoneyLog();
void Save();
void AddLog(BYTE bType, DWORD dwVnum, int iGold);
private:
private:
std::map<DWORD, int> m_MoneyLogContainer[MONEY_LOG_TYPE_MAX_NUM];
};

View File

@ -61,14 +61,15 @@ void CPeer::SetUserCount(DWORD dwCount)
m_dwUserCount = dwCount;
}
bool CPeer::PeekPacket(int & iBytesProceed, BYTE & header, DWORD & dwHandle, DWORD & dwLength, const char ** data)
bool CPeer::PeekPacket(int &iBytesProceed, BYTE &header, DWORD &dwHandle, DWORD &dwLength, const char **data)
{
// Return if not enough data was received to read the header
if (GetRecvLength() < iBytesProceed + 9)
return false;
const char * buf = (const char *) GetRecvBuffer(iBytesProceed + 9);
if (!buf) {
const char *buf = (const char *)GetRecvBuffer(iBytesProceed + 9);
if (!buf)
{
SPDLOG_ERROR("PeekPacket: Failed to get network buffer!");
return false;
}
@ -78,23 +79,24 @@ bool CPeer::PeekPacket(int & iBytesProceed, BYTE & header, DWORD & dwHandle, DWO
// Read the header data
header = *(buf++);
dwHandle = *((DWORD *) buf);
dwHandle = *((DWORD *)buf);
buf += sizeof(DWORD);
dwLength = *((DWORD *) buf);
dwLength = *((DWORD *)buf);
buf += sizeof(DWORD);
// Ensure that all the data was fully received
if (iBytesProceed + dwLength + 9 > (DWORD) GetRecvLength())
if (iBytesProceed + dwLength + 9 > (DWORD)GetRecvLength())
{
SPDLOG_DEBUG("PeekPacket: not enough buffer size: len {}, recv {}",
9+dwLength, GetRecvLength()-iBytesProceed);
9 + dwLength, GetRecvLength() - iBytesProceed);
return false;
}
// Ensure that all the required data is available in a contiguous area
buf = (const char *) GetRecvBuffer(iBytesProceed + dwLength + 9);
if (!buf) {
buf = (const char *)GetRecvBuffer(iBytesProceed + dwLength + 9);
if (!buf)
{
SPDLOG_ERROR("PeekPacket: Failed to get network buffer!");
return false;
}
@ -131,7 +133,7 @@ void CPeer::SetP2PPort(WORD wPort)
m_wP2PPort = wPort;
}
void CPeer::SetMaps(LONG * pl)
void CPeer::SetMaps(LONG *pl)
{
memcpy(m_alMaps, pl, sizeof(m_alMaps));
}
@ -160,7 +162,8 @@ void CPeer::SendSpareItemIDRange()
bool CPeer::SetItemIDRange(TItemIDRangeTable itemRange)
{
if (itemRange.dwMin == 0 || itemRange.dwMax == 0 || itemRange.dwUsableItemIDMin == 0) return false;
if (itemRange.dwMin == 0 || itemRange.dwMax == 0 || itemRange.dwUsableItemIDMin == 0)
return false;
m_itemRange = itemRange;
SPDLOG_DEBUG("ItemIDRange: SET {} {} ~ {} start: {}", GetPublicIP(), m_itemRange.dwMin, m_itemRange.dwMax, m_itemRange.dwUsableItemIDMin);
@ -170,7 +173,8 @@ bool CPeer::SetItemIDRange(TItemIDRangeTable itemRange)
bool CPeer::SetSpareItemIDRange(TItemIDRangeTable itemRange)
{
if (itemRange.dwMin == 0 || itemRange.dwMax == 0 || itemRange.dwUsableItemIDMin == 0) return false;
if (itemRange.dwMin == 0 || itemRange.dwMax == 0 || itemRange.dwUsableItemIDMin == 0)
return false;
m_itemSpareRange = itemRange;
SPDLOG_DEBUG("ItemIDRange: SPARE SET {} {} ~ {} start: {}", GetPublicIP(), m_itemSpareRange.dwMin, m_itemSpareRange.dwMax,
@ -197,5 +201,3 @@ bool CPeer::CheckItemIDRangeCollision(TItemIDRangeTable itemRange)
return true;
}

View File

@ -6,11 +6,11 @@
class CPeer : public CPeerBase
{
protected:
protected:
virtual void OnAccept();
virtual void OnClose();
public:
public:
#pragma pack(1)
typedef struct _header
{
@ -29,7 +29,7 @@ class CPeer : public CPeerBase
virtual ~CPeer();
void EncodeHeader(BYTE header, DWORD dwHandle, DWORD dwSize);
bool PeekPacket(int & iBytesProceed, BYTE & header, DWORD & dwHandle, DWORD & dwLength, const char ** data);
bool PeekPacket(int &iBytesProceed, BYTE &header, DWORD &dwHandle, DWORD &dwLength, const char **data);
void EncodeReturn(BYTE header, DWORD dwHandle);
void ProcessInput();
@ -41,27 +41,27 @@ class CPeer : public CPeerBase
void SetChannel(BYTE bChannel) { m_bChannel = bChannel; }
BYTE GetChannel() { return m_bChannel; }
void SetPublicIP(const char * ip) { m_stPublicIP = ip; }
const char * GetPublicIP() { return m_stPublicIP.c_str(); }
void SetPublicIP(const char *ip) { m_stPublicIP = ip; }
const char *GetPublicIP() { return m_stPublicIP.c_str(); }
void SetListenPort(WORD wPort) { m_wListenPort = wPort; }
WORD GetListenPort() { return m_wListenPort; }
void SetInternalIP(const char * ip) { m_stInternalIP = ip; }
const char * GetInternalIP() { return m_stInternalIP.c_str(); }
void SetInternalIP(const char *ip) { m_stInternalIP = ip; }
const char *GetInternalIP() { return m_stInternalIP.c_str(); }
void SetP2PPort(WORD wPort);
WORD GetP2PPort() { return m_wP2PPort; }
void SetMaps(LONG* pl);
LONG * GetMaps() { return &m_alMaps[0]; }
void SetMaps(LONG *pl);
LONG *GetMaps() { return &m_alMaps[0]; }
bool SetItemIDRange(TItemIDRangeTable itemRange);
bool SetSpareItemIDRange(TItemIDRangeTable itemRange);
bool CheckItemIDRangeCollision(TItemIDRangeTable itemRange);
void SendSpareItemIDRange();
private:
private:
int m_state;
BYTE m_bChannel;

View File

@ -14,20 +14,23 @@ CPeerBase::~CPeerBase()
void CPeerBase::Destroy()
{
if (m_bufferevent) {
if (m_bufferevent)
{
bufferevent_free(m_bufferevent);
m_bufferevent = nullptr;
}
}
bool CPeerBase::Accept(bufferevent* bufev, sockaddr* addr)
bool CPeerBase::Accept(bufferevent *bufev, sockaddr *addr)
{
if (!bufev) {
if (!bufev)
{
SPDLOG_ERROR("Cannot accept empty bufferevent!");
return false;
}
if (m_bufferevent != nullptr) {
if (m_bufferevent != nullptr)
{
SPDLOG_ERROR("Peer is already initialized");
return false;
}
@ -36,17 +39,18 @@ bool CPeerBase::Accept(bufferevent* bufev, sockaddr* addr)
m_bufferevent = bufev;
// Get the address of the conected peer
sockaddr_in* peer;
sockaddr_in6* peer6;
sockaddr_in *peer;
sockaddr_in6 *peer6;
switch (addr->sa_family) {
switch (addr->sa_family)
{
case AF_INET:
peer = (sockaddr_in*) addr;
peer = (sockaddr_in *)addr;
inet_ntop(AF_INET, &(peer->sin_addr), m_host, INET_ADDRSTRLEN);
break;
case AF_INET6:
peer6 = (sockaddr_in6*) addr;
peer6 = (sockaddr_in6 *)addr;
inet_ntop(AF_INET, &(peer6->sin6_addr), m_host, INET6_ADDRSTRLEN);
break;
@ -82,7 +86,7 @@ void CPeerBase::EncodeDWORD(DWORD dw)
Encode(&dw, sizeof(dw));
}
void CPeerBase::Encode(const void* data, size_t size)
void CPeerBase::Encode(const void *data, size_t size)
{
if (!m_bufferevent)
{
@ -90,7 +94,8 @@ void CPeerBase::Encode(const void* data, size_t size)
return;
}
if (bufferevent_write(m_bufferevent, data, size) != 0) {
if (bufferevent_write(m_bufferevent, data, size) != 0)
{
SPDLOG_ERROR("Buffer write error!");
return;
}
@ -120,7 +125,7 @@ size_t CPeerBase::GetRecvLength()
return evbuffer_get_length(input);
}
const void * CPeerBase::GetRecvBuffer(ssize_t ensure_bytes)
const void *CPeerBase::GetRecvBuffer(ssize_t ensure_bytes)
{
if (!m_bufferevent)
{

View File

@ -3,13 +3,14 @@
#include <event2/bufferevent.h>
class CPeerBase {
class CPeerBase
{
protected:
virtual void OnAccept() = 0;
virtual void OnClose() = 0;
public:
bool Accept(bufferevent* bufev, sockaddr* addr);
bool Accept(bufferevent *bufev, sockaddr *addr);
void Close();
public:
@ -18,23 +19,23 @@ public:
void Destroy();
bufferevent * GetBufferevent() { return m_bufferevent; }
bufferevent *GetBufferevent() { return m_bufferevent; }
void EncodeBYTE(BYTE b);
void EncodeWORD(WORD w);
void EncodeDWORD(DWORD dw);
void Encode(const void* data, size_t size);
void Encode(const void *data, size_t size);
void RecvEnd(size_t proceed_bytes);
size_t GetRecvLength();
const void * GetRecvBuffer(ssize_t ensure_bytes);
const void *GetRecvBuffer(ssize_t ensure_bytes);
size_t GetSendLength();
const char * GetHost() { return m_host; }
const char *GetHost() { return m_host; }
protected:
char m_host[IP_ADDRESS_LENGTH + 1];
bufferevent * m_bufferevent;
bufferevent *m_bufferevent;
};
#endif

View File

@ -2,9 +2,9 @@
#include "PrivManager.h"
#include "ClientManager.h"
const int PRIV_DURATION = 60*60*12;
const int CHARACTER_GOOD_PRIV_DURATION = 2*60*60;
const int CHARACTER_BAD_PRIV_DURATION = 60*60;
const int PRIV_DURATION = 60 * 60 * 12;
const int CHARACTER_GOOD_PRIV_DURATION = 2 * 60 * 60;
const int CHARACTER_BAD_PRIV_DURATION = 60 * 60;
CPrivManager::CPrivManager()
{
@ -28,7 +28,7 @@ void CPrivManager::Update()
while (!m_pqPrivGuild.empty() && m_pqPrivGuild.top().first <= now)
{
TPrivGuildData* p = m_pqPrivGuild.top().second;
TPrivGuildData *p = m_pqPrivGuild.top().second;
m_pqPrivGuild.pop();
if (p->value != 0 && !p->bRemoved)
@ -39,7 +39,8 @@ void CPrivManager::Update()
// ADD_GUILD_PRIV_TIME
// 길드에 중복적으로 보너스가 설정되었을 경우 map 의 value 가 갱신(수정) 되었으므로
// TPrivGuildData 의 포인터가 같을때 실제로 삭제해 주고 게임서버들에게 cast 해 준다.
if (it != m_aPrivGuild[p->type].end() && it->second == p) {
if (it != m_aPrivGuild[p->type].end() && it->second == p)
{
m_aPrivGuild[p->type].erase(it);
SendChangeGuildPriv(p->guild_id, p->type, 0, 0);
// END_OF_ADD_GUILD_PRIV_TIME
@ -51,7 +52,7 @@ void CPrivManager::Update()
while (!m_pqPrivEmpire.empty() && m_pqPrivEmpire.top().first <= now)
{
TPrivEmpireData* p = (m_pqPrivEmpire.top().second);
TPrivEmpireData *p = (m_pqPrivEmpire.top().second);
m_pqPrivEmpire.pop();
if (p->value != 0 && !p->bRemoved)
@ -65,7 +66,7 @@ void CPrivManager::Update()
while (!m_pqPrivChar.empty() && m_pqPrivChar.top().first <= now)
{
TPrivCharData* p = (m_pqPrivChar.top().second);
TPrivCharData *p = (m_pqPrivChar.top().second);
m_pqPrivChar.pop();
if (!p->bRemoved)
@ -97,14 +98,14 @@ void CPrivManager::AddCharPriv(DWORD pid, BYTE type, int value)
return;
time_t now = CClientManager::instance().GetCurrentTime();
TPrivCharData* p = new TPrivCharData(type, value, pid);
TPrivCharData *p = new TPrivCharData(type, value, pid);
int iDuration = CHARACTER_BAD_PRIV_DURATION;
if (value > 0)
iDuration = CHARACTER_GOOD_PRIV_DURATION;
m_pqPrivChar.push(std::make_pair(now+iDuration, p));
m_pqPrivChar.push(std::make_pair(now + iDuration, p));
m_aPrivChar[type].insert(std::make_pair(pid, p));
// TODO send packet
@ -127,7 +128,7 @@ void CPrivManager::AddGuildPriv(DWORD guild_id, BYTE type, int value, time_t dur
time_t now = CClientManager::instance().GetCurrentTime();
time_t end = now + duration_sec;
TPrivGuildData * p = new TPrivGuildData(type, value, guild_id, end);
TPrivGuildData *p = new TPrivGuildData(type, value, guild_id, end);
m_pqPrivGuild.push(std::make_pair(end, p));
// ADD_GUILD_PRIV_TIME
@ -156,7 +157,7 @@ void CPrivManager::AddEmpirePriv(BYTE empire, BYTE type, int value, time_t durat
duration_sec = 0;
time_t now = CClientManager::instance().GetCurrentTime();
time_t end = now+duration_sec;
time_t end = now + duration_sec;
// 이전 설정값 무효화
// priority_queue에 들어있는 pointer == m_aaPrivEmpire[type][empire]
@ -165,7 +166,7 @@ void CPrivManager::AddEmpirePriv(BYTE empire, BYTE type, int value, time_t durat
m_aaPrivEmpire[type][empire]->bRemoved = true;
}
TPrivEmpireData * p = new TPrivEmpireData(type, value, empire, end);
TPrivEmpireData *p = new TPrivEmpireData(type, value, empire, end);
m_pqPrivEmpire.push(std::make_pair(end, p));
m_aaPrivEmpire[type][empire] = p;
@ -192,7 +193,7 @@ struct FSendChangeGuildPriv
// END_OF_ADD_GUILD_PRIV_TIME
}
void operator() (CPeer* peer)
void operator()(CPeer *peer)
{
peer->EncodeHeader(HEADER_DG_CHANGE_GUILD_PRIV, 0, sizeof(TPacketDGChangeGuildPriv));
peer->Encode(&p, sizeof(TPacketDGChangeGuildPriv));
@ -215,7 +216,7 @@ struct FSendChangeEmpirePriv
// END_OF_ADD_EMPIRE_PRIV_TIME
}
void operator ()(CPeer* peer)
void operator()(CPeer *peer)
{
peer->EncodeHeader(HEADER_DG_CHANGE_EMPIRE_PRIV, 0, sizeof(TPacketDGChangeEmpirePriv));
peer->Encode(&p, sizeof(TPacketDGChangeEmpirePriv));
@ -234,7 +235,7 @@ struct FSendChangeCharPriv
p.value = value;
p.bLog = 1;
}
void operator()(CPeer* peer)
void operator()(CPeer *peer)
{
peer->EncodeHeader(HEADER_DG_CHANGE_CHARACTER_PRIV, 0, sizeof(TPacketDGChangeCharacterPriv));
peer->Encode(&p, sizeof(TPacketDGChangeCharacterPriv));
@ -262,14 +263,14 @@ void CPrivManager::SendChangeCharPriv(DWORD pid, BYTE type, int value)
CClientManager::instance().for_each_peer(FSendChangeCharPriv(pid, type, value));
}
void CPrivManager::SendPrivOnSetup(CPeer* peer)
void CPrivManager::SendPrivOnSetup(CPeer *peer)
{
for (int i = 1; i < MAX_PRIV_NUM; ++i)
{
for (int e = 0; e < EMPIRE_MAX_NUM; ++e)
{
// ADD_EMPIRE_PRIV_TIME
TPrivEmpireData* pPrivEmpireData = m_aaPrivEmpire[i][e];
TPrivEmpireData *pPrivEmpireData = m_aaPrivEmpire[i][e];
if (pPrivEmpireData)
{
FSendChangeEmpirePriv(e, i, pPrivEmpireData->value, pPrivEmpireData->end_time_sec)(peer);
@ -277,7 +278,7 @@ void CPrivManager::SendPrivOnSetup(CPeer* peer)
// END_OF_ADD_EMPIRE_PRIV_TIME
}
for (typeof(m_aPrivGuild[i].begin()) it = m_aPrivGuild[i].begin(); it != m_aPrivGuild[i].end();++it)
for (typeof(m_aPrivGuild[i].begin()) it = m_aPrivGuild[i].begin(); it != m_aPrivGuild[i].end(); ++it)
{
// ADD_GUILD_PRIV_TIME
FSendChangeGuildPriv(it->first, i, it->second->value, it->second->end_time_sec)(peer);

View File

@ -18,7 +18,8 @@ struct TPrivEmpireData
TPrivEmpireData(BYTE type, int value, BYTE empire, time_t end_time_sec)
: type(type), value(value), bRemoved(false), empire(empire), end_time_sec(end_time_sec)
{}
{
}
// END_OF_ADD_EMPIRE_PRIV_TIME
};
@ -36,8 +37,9 @@ struct TPrivGuildData
time_t end_time_sec; ///< 지속시간
TPrivGuildData(BYTE type, int value, DWORD guild_id, time_t _end_time_sec)
: type(type), value(value), bRemoved(false), guild_id(guild_id), end_time_sec(_end_time_sec )
{}
: type(type), value(value), bRemoved(false), guild_id(guild_id), end_time_sec(_end_time_sec)
{
}
// END_OF_ADD_GUILD_PRIV_TIME
};
@ -49,7 +51,8 @@ struct TPrivCharData
DWORD pid;
TPrivCharData(BYTE type, int value, DWORD pid)
: type(type), value(value), bRemoved(false), pid(pid)
{}
{
}
};
/**
@ -57,7 +60,7 @@ struct TPrivCharData
*/
class CPrivManager : public singleton<CPrivManager>
{
public:
public:
CPrivManager();
virtual ~CPrivManager();
@ -73,10 +76,9 @@ class CPrivManager : public singleton<CPrivManager>
void Update();
void SendPrivOnSetup(CPeer* peer);
private:
void SendPrivOnSetup(CPeer *peer);
private:
// ADD_GUILD_PRIV_TIME
void SendChangeGuildPriv(DWORD guild_id, BYTE type, int value, time_t end_time_sec);
// END_OF_ADD_GUILD_PRIV_TIME
@ -88,19 +90,19 @@ class CPrivManager : public singleton<CPrivManager>
void SendChangeCharPriv(DWORD pid, BYTE type, int value);
typedef std::pair<time_t, TPrivCharData *> stPairChar;
typedef std::pair<time_t, TPrivGuildData*> stPairGuild;
typedef std::pair<time_t, TPrivEmpireData*> stPairEmpire;
typedef std::pair<time_t, TPrivGuildData *> stPairGuild;
typedef std::pair<time_t, TPrivEmpireData *> stPairEmpire;
std::priority_queue<stPairChar, std::vector<stPairChar>, std::greater<stPairChar> >
std::priority_queue<stPairChar, std::vector<stPairChar>, std::greater<stPairChar>>
m_pqPrivChar;
std::priority_queue<stPairGuild, std::vector<stPairGuild>, std::greater<stPairGuild> >
std::priority_queue<stPairGuild, std::vector<stPairGuild>, std::greater<stPairGuild>>
m_pqPrivGuild;
std::priority_queue<stPairEmpire, std::vector<stPairEmpire>, std::greater<stPairEmpire> >
std::priority_queue<stPairEmpire, std::vector<stPairEmpire>, std::greater<stPairEmpire>>
m_pqPrivEmpire;
TPrivEmpireData* m_aaPrivEmpire[MAX_PRIV_NUM][EMPIRE_MAX_NUM];
std::map<DWORD, TPrivGuildData*> m_aPrivGuild[MAX_PRIV_NUM];
std::map<DWORD, TPrivCharData*> m_aPrivChar[MAX_PRIV_NUM];
TPrivEmpireData *m_aaPrivEmpire[MAX_PRIV_NUM][EMPIRE_MAX_NUM];
std::map<DWORD, TPrivGuildData *> m_aPrivGuild[MAX_PRIV_NUM];
std::map<DWORD, TPrivCharData *> m_aPrivChar[MAX_PRIV_NUM];
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -6,7 +6,7 @@
#include "CsvReader.h"
//csv 파일을 읽어와서 아이템 테이블에 넣어준다.
// csv 파일을 읽어와서 아이템 테이블에 넣어준다.
void putItemIntoTable(); //(테이블, 테스트여부)
int get_Item_Type_Value(std::string inputString);
@ -18,8 +18,7 @@ int get_Item_Immune_Value(std::string inputString);
int get_Item_LimitType_Value(std::string inputString);
int get_Item_ApplyType_Value(std::string inputString);
//몬스터 프로토도 읽을 수 있다.
// 몬스터 프로토도 읽을 수 있다.
int get_Mob_Rank_Value(std::string inputString);
int get_Mob_Type_Value(std::string inputString);
int get_Mob_BattleType_Value(std::string inputString);
@ -30,7 +29,7 @@ int get_Mob_RaceFlag_Value(std::string inputString);
int get_Mob_ImmuneFlag_Value(std::string inputString);
//
bool Set_Proto_Mob_Table(TMobTable *mobTable, cCsvTable &csvTable, std::map<int,const char*> &nameMap);
bool Set_Proto_Item_Table(TItemTable *itemTable, cCsvTable &csvTable,std::map<int,const char*> &nameMap);
bool Set_Proto_Mob_Table(TMobTable *mobTable, cCsvTable &csvTable, std::map<int, const char *> &nameMap);
bool Set_Proto_Item_Table(TItemTable *itemTable, cCsvTable &csvTable, std::map<int, const char *> &nameMap);
#endif

View File

@ -9,7 +9,7 @@ CGrid::CGrid(int w, int h) : m_iWidth(w), m_iHeight(h)
memset(m_pGrid, 0, sizeof(char) * m_iWidth * m_iHeight);
}
CGrid::CGrid(CGrid * pkGrid, int w, int h) : m_iWidth(w), m_iHeight(h)
CGrid::CGrid(CGrid *pkGrid, int w, int h) : m_iWidth(w), m_iHeight(h)
{
m_pGrid = new char[m_iWidth * m_iHeight];
int iSize = std::min(w * h, pkGrid->m_iWidth * pkGrid->m_iHeight);
@ -18,7 +18,7 @@ CGrid::CGrid(CGrid * pkGrid, int w, int h) : m_iWidth(w), m_iHeight(h)
CGrid::~CGrid()
{
delete [] m_pGrid;
delete[] m_pGrid;
}
void CGrid::Clear()
@ -126,4 +126,3 @@ unsigned int CGrid::GetSize()
{
return m_iWidth * m_iHeight;
}

View File

@ -4,9 +4,9 @@
class CGrid
{
public:
public:
CGrid(int w, int h);
CGrid(CGrid * pkGrid, int w, int h);
CGrid(CGrid *pkGrid, int w, int h);
~CGrid();
void Clear();
@ -17,11 +17,11 @@ class CGrid
void Print();
unsigned int GetSize();
protected:
protected:
int m_iWidth;
int m_iHeight;
char * m_pGrid;
char *m_pGrid;
};
#endif

View File

@ -1,8 +1,12 @@
#include <fmt/core.h>
#ifndef __INTELLISENSE__
#include <version.h>
#else
#include <../../../common/version.h>
#endif
void WriteVersion() {
void WriteVersion()
{
fmt::println("Metin2 DB Cache version {} (rev. {}, date: {})", __COMMIT_TAG__, __REVISION__, __COMMIT_DATE__);
fmt::println("OS: {}, target arch: {}, compiler: {}", __OS_NAME__, __CPU_TARGET__, __COMPILER__);
}

View File

@ -56,7 +56,11 @@
#include "skill_power.h"
#include "SpeedServer.h"
#include "DragonSoul.h"
#ifndef __INTELLISENSE__
#include <version.h>
#else
#include <../../../common/version.h>
#endif
#include <event2/event.h>
#include <event2/listener.h>
#include <event2/dns.h>
@ -65,20 +69,6 @@
#include <execinfo.h>
#endif
//extern const char * _malloc_options;
#if defined(__FreeBSD__) && defined(DEBUG_ALLOC)
extern void (*_malloc_message)(const char* p1, const char* p2, const char* p3, const char* p4);
// FreeBSD _malloc_message replacement
void WriteMallocMessage(const char* p1, const char* p2, const char* p3, const char* p4) {
FILE* fp = ::fopen(DBGALLOC_LOG_FILENAME, "a");
if (fp == NULL) {
return;
}
::fprintf(fp, "%s %s %s %s\n", p1, p2, p3, p4);
::fclose(fp);
}
#endif
// TRAFFIC_PROFILER
static const DWORD TRAFFIC_PROFILE_FLUSH_CYCLE = 3600; ///< TrafficProfiler 의 Flush cycle. 1시간 간격
// END_OF_TRAFFIC_PROFILER
@ -90,17 +80,17 @@ int current_bytes_written = 0;
int total_bytes_written = 0;
BYTE g_bLogLevel = 0;
evconnlistener * tcp_listener = nullptr;
evconnlistener * p2p_listener = nullptr;
evconnlistener *tcp_listener = nullptr;
evconnlistener *p2p_listener = nullptr;
event_base * ev_base = nullptr;
evdns_base * dns_base = nullptr;
event_base *ev_base = nullptr;
evdns_base *dns_base = nullptr;
static void AcceptError(evconnlistener *listener, void *ctx);
static void AcceptTCPConnection(evconnlistener* listener, evutil_socket_t fd, sockaddr* address, int socklen, void* ctx);
static void AcceptP2PConnection(evconnlistener* listener, evutil_socket_t fd, sockaddr* address, int socklen, void* ctx);
static void AcceptTCPConnection(evconnlistener *listener, evutil_socket_t fd, sockaddr *address, int socklen, void *ctx);
static void AcceptP2PConnection(evconnlistener *listener, evutil_socket_t fd, sockaddr *address, int socklen, void *ctx);
int io_loop(event_base * base);
int io_loop(event_base *base);
int start(int argc, char **argv);
int idle();
@ -120,7 +110,7 @@ static DWORD s_dwProfiler[PROF_MAX_NUM];
int g_shutdown_disconnect_pulse;
int g_shutdown_disconnect_force_pulse;
int g_shutdown_core_pulse;
bool g_bShutdown=false;
bool g_bShutdown = false;
extern int speed_server;
extern void CancelReloadSpamEvent();
@ -128,16 +118,17 @@ extern void CancelReloadSpamEvent();
void ContinueOnFatalError()
{
#ifdef USE_STACKTRACE
void* array[200];
void *array[200];
std::size_t size;
char** symbols;
char **symbols;
size = backtrace(array, 200);
symbols = backtrace_symbols(array, size);
std::ostringstream oss;
oss << std::endl;
for (std::size_t i = 0; i < size; ++i) {
for (std::size_t i = 0; i < size; ++i)
{
oss << " Stack> " << symbols[i] << std::endl;
}
@ -178,7 +169,7 @@ namespace
{
struct SendDisconnectFunc
{
void operator () (LPDESC d)
void operator()(LPDESC d)
{
if (d->GetCharacter())
{
@ -190,7 +181,7 @@ namespace
struct DisconnectFunc
{
void operator () (LPDESC d)
void operator()(LPDESC d)
{
if (d->GetType() == DESC_TYPE_CONNECTOR)
return;
@ -289,13 +280,13 @@ void heartbeat(LPHEART ht, int pulse)
{
if (thecore_pulse() > g_shutdown_disconnect_pulse)
{
const DESC_MANAGER::DESC_SET & c_set_desc = DESC_MANAGER::instance().GetClientSet();
const DESC_MANAGER::DESC_SET &c_set_desc = DESC_MANAGER::instance().GetClientSet();
std::for_each(c_set_desc.begin(), c_set_desc.end(), ::SendDisconnectFunc());
g_shutdown_disconnect_pulse = INT_MAX;
}
else if (thecore_pulse() > g_shutdown_disconnect_force_pulse)
{
const DESC_MANAGER::DESC_SET & c_set_desc = DESC_MANAGER::instance().GetClientSet();
const DESC_MANAGER::DESC_SET &c_set_desc = DESC_MANAGER::instance().GetClientSet();
std::for_each(c_set_desc.begin(), c_set_desc.end(), ::DisconnectFunc());
}
else if (thecore_pulse() > g_shutdown_disconnect_force_pulse + PASSES_PER_SEC(5))
@ -305,7 +296,8 @@ void heartbeat(LPHEART ht, int pulse)
}
}
static void CleanUpForEarlyExit() {
static void CleanUpForEarlyExit()
{
CancelReloadSpamEvent();
}
@ -368,14 +360,16 @@ int main(int argc, char **argv)
CSpeedServerManager SSManager;
DSManager dsManager;
if (!start(argc, argv)) {
if (!start(argc, argv))
{
CleanUpForEarlyExit();
return 0;
}
quest::CQuestManager quest_manager;
if (!quest_manager.Initialize()) {
if (!quest_manager.Initialize())
{
CleanUpForEarlyExit();
return 0;
}
@ -391,10 +385,11 @@ int main(int argc, char **argv)
Blend_Item_init();
ani_init();
if ( g_bTrafficProfileOn )
TrafficProfiler::instance().Initialize( TRAFFIC_PROFILE_FLUSH_CYCLE, "ProfileLog" );
if (g_bTrafficProfileOn)
TrafficProfiler::instance().Initialize(TRAFFIC_PROFILE_FLUSH_CYCLE, "ProfileLog");
while (idle());
while (idle())
;
SPDLOG_INFO("<shutdown> Starting...");
g_bShutdown = true;
@ -478,15 +473,10 @@ int start(int argc, char **argv)
{
std::string st_localeServiceName;
//_malloc_options = "A";
#if defined(__FreeBSD__) && defined(DEBUG_ALLOC)
_malloc_message = WriteMallocMessage;
#endif
int ch;
while ((ch = getopt(argc, argv, "n:p:erl:tI:")) != -1)
{
char* ep = NULL;
char *ep = NULL;
switch (ch)
{
@ -537,7 +527,7 @@ int start(int argc, char **argv)
case '?':
if (strchr("Ipln", optopt))
SPDLOG_ERROR("Option -{} requires an argument.", optopt);
else if (isprint (optopt))
else if (isprint(optopt))
SPDLOG_ERROR("Unknown option `-{}'.", optopt);
else
SPDLOG_ERROR("Unknown option character `\\x{}'.", optopt);
@ -574,24 +564,28 @@ int start(int argc, char **argv)
// Initialize the network stack
// Check if the public and internal IP addresses were configured
if (g_szInternalIP.empty()) {
if (g_szInternalIP.empty())
{
SPDLOG_CRITICAL("Internal IP address could not be automatically detected. Manually set the IP and try again.");
exit(EXIT_FAILURE);
}
if (g_szPublicIP.empty()) {
if (g_szPublicIP.empty())
{
SPDLOG_CRITICAL("Public IP address could not be automatically detected. Manually set the IP and try again.");
exit(EXIT_FAILURE);
}
// Create a new libevent base and listen for new connections
ev_base = event_base_new();
if (!ev_base) {
if (!ev_base)
{
SPDLOG_CRITICAL("Libevent base initialization FAILED!");
exit(EXIT_FAILURE);
}
dns_base = evdns_base_new(ev_base, 1);
if (!dns_base) {
if (!dns_base)
{
SPDLOG_CRITICAL("Libevent DNS base initialization FAILED!");
exit(EXIT_FAILURE);
}
@ -606,10 +600,10 @@ int start(int argc, char **argv)
tcp_listener = evconnlistener_new_bind(
ev_base,
AcceptTCPConnection, nullptr,
LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, -1,
(const sockaddr*)&sin, sizeof(sin)
);
if (!tcp_listener) {
LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, -1,
(const sockaddr *)&sin, sizeof(sin));
if (!tcp_listener)
{
SPDLOG_CRITICAL("TCP listener initialization FAILED!");
exit(EXIT_FAILURE);
}
@ -624,10 +618,10 @@ int start(int argc, char **argv)
p2p_listener = evconnlistener_new_bind(
ev_base,
AcceptP2PConnection, nullptr,
LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, -1,
(const sockaddr*)&sin, sizeof(sin)
);
if (!p2p_listener) {
LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, -1,
(const sockaddr *)&sin, sizeof(sin));
if (!p2p_listener)
{
SPDLOG_CRITICAL("P2P listener initialization FAILED!");
exit(EXIT_FAILURE);
}
@ -636,7 +630,8 @@ int start(int argc, char **argv)
// Create client connections
db_clientdesc = DESC_MANAGER::instance().CreateConnectionDesc(ev_base, dns_base, db_addr, db_port, PHASE_DBCLIENT, true);
if (!g_bAuthServer) {
if (!g_bAuthServer)
{
db_clientdesc->UpdateChannelStatus(0, true);
}
@ -648,7 +643,6 @@ int start(int argc, char **argv)
g_pkAuthMasterDesc = DESC_MANAGER::instance().CreateConnectionDesc(ev_base, dns_base, g_stAuthMasterIP.c_str(), g_wAuthMasterPort, PHASE_P2P, true);
P2P_MANAGER::instance().RegisterConnector(g_pkAuthMasterDesc);
g_pkAuthMasterDesc->SetP2P(g_wAuthMasterPort, g_bChannel);
}
else
{
@ -682,22 +676,26 @@ void destroy()
regen_free();
SPDLOG_INFO("<shutdown> Closing network stack...");
if (tcp_listener) {
if (tcp_listener)
{
evconnlistener_free(tcp_listener);
tcp_listener = nullptr;
}
if (p2p_listener) {
if (p2p_listener)
{
evconnlistener_free(p2p_listener);
p2p_listener = nullptr;
}
if (dns_base) {
if (dns_base)
{
evdns_base_free(dns_base, 0);
dns_base = nullptr;
}
if (ev_base) {
if (ev_base)
{
event_base_free(ev_base);
ev_base = nullptr;
}
@ -714,12 +712,12 @@ void destroy()
int idle()
{
static struct timeval pta = { 0, 0 };
static struct timeval pta = {0, 0};
static int process_time_count = 0;
struct timeval now;
if (pta.tv_sec == 0)
gettimeofday(&pta, (struct timezone *) 0);
gettimeofday(&pta, (struct timezone *)0);
int passed_pulses;
@ -730,7 +728,8 @@ int idle()
DWORD t;
while (passed_pulses--) {
while (passed_pulses--)
{
heartbeat(thecore_heart, ++thecore_heart->pulse);
// To reduce the possibility of abort() in checkpointing
@ -743,10 +742,11 @@ int idle()
s_dwProfiler[PROF_CHR_UPDATE] += (get_dword_time() - t);
t = get_dword_time();
if (!io_loop(ev_base)) return 0;
if (!io_loop(ev_base))
return 0;
s_dwProfiler[PROF_IO] += (get_dword_time() - t);
gettimeofday(&now, (struct timezone *) 0);
gettimeofday(&now, (struct timezone *)0);
++process_time_count;
if (now.tv_sec - pta.tv_sec > 0)
@ -767,7 +767,7 @@ int idle()
current_bytes_written = 0;
process_time_count = 0;
gettimeofday(&pta, (struct timezone *) 0);
gettimeofday(&pta, (struct timezone *)0);
memset(&thecore_profiler[0], 0, sizeof(thecore_profiler));
memset(&s_dwProfiler[0], 0, sizeof(s_dwProfiler));
@ -776,7 +776,8 @@ int idle()
return 1;
}
static void AcceptError(evconnlistener *listener, void *ctx) {
static void AcceptError(evconnlistener *listener, void *ctx)
{
struct event_base *base = evconnlistener_get_base(listener);
int err = EVUTIL_SOCKET_ERROR();
SPDLOG_CRITICAL("Got an error {} ({}) on the listener. Shutting down.", err, evutil_socket_error_to_string(err));
@ -785,19 +786,19 @@ static void AcceptError(evconnlistener *listener, void *ctx) {
ShutdownOnFatalError();
}
static void AcceptTCPConnection(evconnlistener* listener, evutil_socket_t fd, sockaddr* address, int socklen, void* ctx)
static void AcceptTCPConnection(evconnlistener *listener, evutil_socket_t fd, sockaddr *address, int socklen, void *ctx)
{
// Initialize the peer
DESC_MANAGER::instance().AcceptDesc(listener, fd, address);
}
static void AcceptP2PConnection(evconnlistener* listener, evutil_socket_t fd, sockaddr* address, int socklen, void* ctx)
static void AcceptP2PConnection(evconnlistener *listener, evutil_socket_t fd, sockaddr *address, int socklen, void *ctx)
{
// Initialize the peer
DESC_MANAGER::instance().AcceptP2PDesc(listener, fd, address);
}
int io_loop(event_base * base)
int io_loop(event_base *base)
{
LPDESC d;
int num_events, event_idx;
@ -810,4 +811,3 @@ int io_loop(event_base * base)
return 1;
}

View File

@ -1,8 +1,12 @@
#include <fmt/core.h>
#ifndef __INTELLISENSE__
#include <version.h>
#else
#include <../../../common/version.h>
#endif
void WriteVersion() {
void WriteVersion()
{
fmt::println("Metin2 Game Server version {} (rev. {}, date: {})", __COMMIT_TAG__, __REVISION__, __COMMIT_DATE__);
fmt::println("OS: {}, target arch: {}, compiler: {}", __OS_NAME__, __CPU_TARGET__, __COMPILER__);
}

View File

@ -0,0 +1,15 @@
#pragma once
#include <pqxx/pqxx>
#include <string>
class PgAsyncQuery
{
public:
int id;
std::string query;
pqxx::params parameters;
PgAsyncQuery(int msgId, const std::string &sql, const pqxx::params &params = pqxx::params{})
: id(msgId), query(sql), parameters(params) {}
};

View File

@ -0,0 +1,175 @@
#pragma once
#include <pqxx/pqxx>
#include <mutex>
#include <condition_variable>
#include <queue>
#include <memory>
#include <string>
#include <vector>
#include <chrono>
#include <future>
#include <thread>
#include <atomic>
#include <map>
class PgConnectionPool
{
public:
PgConnectionPool(const char *db_address, int db_port, const char *db_name,
const char *user, const char *pwd,
size_t pool_size = 10,
std::chrono::seconds idle_timeout = std::chrono::seconds(60))
: db_address_(db_address), db_port_(db_port), db_name_(db_name),
user_(user), pwd_(pwd), max_pool_size_(pool_size),
idle_timeout_(idle_timeout), stop_cleaner_(false)
{
for (size_t i = 0; i < max_pool_size_; ++i)
{
auto conn = createConnection();
pool_.push({std::move(conn), std::chrono::steady_clock::now()});
}
// Start cleanup thread
cleaner_thread_ = std::thread(&PgConnectionPool::cleanupIdleConnections, this);
}
~PgConnectionPool()
{
stop_cleaner_ = true;
cond_.notify_all();
if (cleaner_thread_.joinable())
{
cleaner_thread_.join();
}
std::lock_guard<std::mutex> lock(mutex_);
while (!pool_.empty())
{
auto &entry = pool_.front();
if (entry.conn && entry.conn->is_open())
{
entry.conn->close();
}
pool_.pop();
}
}
// Asynchronous acquire
std::future<std::shared_ptr<pqxx::connection>> acquireAsync()
{
return std::async(std::launch::async, [this]()
{ return this->acquire(); });
}
// Blocking acquire
std::shared_ptr<pqxx::connection> acquire()
{
std::unique_lock<std::mutex> lock(mutex_);
cond_.wait(lock, [this]()
{ return !pool_.empty(); });
ConnectionEntry entry = std::move(pool_.front());
pool_.pop();
if (!entry.conn || !entry.conn->is_open())
{
entry.conn = createConnection(); // Reconnect if needed
}
return std::shared_ptr<pqxx::connection>(
entry.conn.release(),
[this](pqxx::connection *p)
{
std::lock_guard<std::mutex> lock(mutex_);
auto now = std::chrono::steady_clock::now();
if (p->is_open())
{
pool_.push({std::unique_ptr<pqxx::connection>(p), now});
}
else
{
delete p;
pool_.push({createConnection(), now});
}
cond_.notify_one();
});
}
private:
struct ConnectionEntry
{
std::unique_ptr<pqxx::connection> conn;
std::chrono::steady_clock::time_point last_used;
};
std::unique_ptr<pqxx::connection> createConnection()
{
std::string conn_str = "host=" + db_address_ +
" port=" + std::to_string(db_port_) +
" dbname=" + db_name_ +
" user=" + user_ +
" password=" + pwd_;
try
{
auto conn = std::make_unique<pqxx::connection>(conn_str);
if (!conn->is_open())
{
throw std::runtime_error("Failed to open DB connection");
}
return conn;
}
catch (const std::exception &e)
{
throw std::runtime_error(std::string("Connection error: ") + e.what());
}
}
void cleanupIdleConnections()
{
while (!stop_cleaner_)
{
std::this_thread::sleep_for(idle_timeout_ / 2); // Clean more frequently
std::lock_guard<std::mutex> lock(mutex_);
size_t current_size = pool_.size();
std::queue<ConnectionEntry> temp;
auto now = std::chrono::steady_clock::now();
while (!pool_.empty())
{
auto entry = std::move(pool_.front());
pool_.pop();
if (std::chrono::duration_cast<std::chrono::seconds>(
now - entry.last_used) > idle_timeout_)
{
if (entry.conn && entry.conn->is_open())
{
entry.conn->close();
}
}
else
{
temp.push(std::move(entry));
}
}
pool_ = std::move(temp);
cond_.notify_all();
}
}
std::string db_address_, db_name_, user_, pwd_;
int db_port_;
size_t max_pool_size_;
std::chrono::seconds idle_timeout_;
std::queue<ConnectionEntry> pool_;
std::mutex mutex_;
std::condition_variable cond_;
std::thread cleaner_thread_;
std::atomic<bool> stop_cleaner_;
};