forked from metin2/server
Add project files.
This commit is contained in:
37
db/CMakeLists.txt
Normal file
37
db/CMakeLists.txt
Normal file
@ -0,0 +1,37 @@
|
||||
cmake_minimum_required(VERSION 3.8)
|
||||
|
||||
project(db CXX)
|
||||
|
||||
file(GLOB_RECURSE sources
|
||||
src/*.cpp src/*.h
|
||||
)
|
||||
|
||||
|
||||
include_directories(${PROJECT_BINARY_DIR}/src/)
|
||||
|
||||
include_directories(src/)
|
||||
|
||||
# Find dependencies
|
||||
find_package(libmysql REQUIRED)
|
||||
find_package(Boost REQUIRED)
|
||||
|
||||
add_executable(${PROJECT_NAME} ${sources})
|
||||
|
||||
# Link dependencies if found
|
||||
if (libmysql_FOUND)
|
||||
target_link_libraries (${PROJECT_NAME} ${MYSQL_LIBRARIES})
|
||||
endif (libmysql_FOUND)
|
||||
|
||||
if (Boost_FOUND)
|
||||
include_directories(${Boost_INCLUDE_DIRS})
|
||||
target_link_libraries (${PROJECT_NAME} ${Boost_LIBRARIES} ${Boost_SYSTEM_LIBRARY})
|
||||
endif (Boost_FOUND)
|
||||
|
||||
if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
|
||||
# Pthreads
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package (Threads REQUIRED)
|
||||
target_link_libraries (${PROJECT_NAME} Threads::Threads)
|
||||
endif (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} libpoly libsql libthecore)
|
719
db/src/AuctionManager.cpp
Normal file
719
db/src/AuctionManager.cpp
Normal file
@ -0,0 +1,719 @@
|
||||
#include "stdafx.h"
|
||||
#ifdef __AUCTION__
|
||||
|
||||
#include "DBManager.h"
|
||||
#include "Peer.h"
|
||||
#include "AuctionManager.h"
|
||||
|
||||
void MyBidBoard::Boot (CPeer* peer)
|
||||
{
|
||||
peer->EncodeWORD(sizeof(DWORD) + sizeof(DWORD) + sizeof(int));
|
||||
peer->EncodeWORD(Size());
|
||||
|
||||
for (TMyBidBoard::iterator pc_it = pc_map.begin(); pc_it != pc_map.end(); pc_it++)
|
||||
{
|
||||
TItemMap* item_map = pc_it->second;
|
||||
for (TItemMap::iterator it = item_map->begin(); it != item_map->end(); it++)
|
||||
{
|
||||
peer->Encode(&(pc_it->first), sizeof(DWORD));
|
||||
peer->Encode(&(it->first), sizeof(DWORD));
|
||||
peer->Encode(&(it->second), sizeof(int));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t MyBidBoard::Size ()
|
||||
{
|
||||
size_t size = 0;
|
||||
for (TMyBidBoard::iterator it = pc_map.begin(); it != pc_map.end(); it++)
|
||||
{
|
||||
size += it->second->size();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
int MyBidBoard::GetMoney (DWORD player_id, DWORD item_id)
|
||||
{
|
||||
TMyBidBoard::iterator pc_it = pc_map.find (player_id);
|
||||
if (pc_it == pc_map.end())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
TItemMap* item_map = pc_it->second;
|
||||
TItemMap::iterator it = item_map->find (item_id);
|
||||
if (it == item_map->end())
|
||||
return -1;
|
||||
else
|
||||
return it->second;
|
||||
}
|
||||
|
||||
bool MyBidBoard::Delete (DWORD player_id, DWORD item_id)
|
||||
{
|
||||
TMyBidBoard::iterator pc_it = pc_map.find (player_id);
|
||||
if (pc_it == pc_map.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
TItemMap* item_map = pc_it->second;
|
||||
TItemMap::iterator it = item_map->find (item_id);
|
||||
if (it == item_map->end())
|
||||
return false;
|
||||
else
|
||||
{
|
||||
item_map->erase(it);
|
||||
}
|
||||
char szQuery[512];
|
||||
snprintf(szQuery, sizeof(szQuery), "DELETE FROM my_bid WHERE player_id = %d and item_id = %d", player_id, item_id);
|
||||
CDBManager::instance().AsyncQuery(szQuery);
|
||||
return true;
|
||||
}
|
||||
|
||||
void MyBidBoard::Insert (DWORD player_id, DWORD item_id, int money)
|
||||
{
|
||||
TMyBidBoard::iterator pc_it = pc_map.find (player_id);
|
||||
TItemMap* item_map;
|
||||
if (pc_it == pc_map.end())
|
||||
{
|
||||
item_map = new TItemMap();
|
||||
pc_map.insert (TMyBidBoard::value_type (player_id, item_map));
|
||||
}
|
||||
else
|
||||
item_map = pc_it->second;
|
||||
|
||||
TItemMap::iterator it = item_map->find (item_id);
|
||||
if (it == item_map->end())
|
||||
{
|
||||
item_map->insert (TItemMap::value_type (item_id, money));
|
||||
}
|
||||
else
|
||||
{
|
||||
it->second = money;
|
||||
}
|
||||
char szQuery[512];
|
||||
snprintf(szQuery, sizeof(szQuery), "REPLACE INTO my_bid VALUES (%d, %d, %d)", player_id, item_id, money);
|
||||
CDBManager::instance().AsyncQuery(szQuery);
|
||||
}
|
||||
|
||||
AuctionManager::AuctionManager()
|
||||
{
|
||||
}
|
||||
|
||||
AuctionManager::~AuctionManager()
|
||||
{
|
||||
}
|
||||
|
||||
void AuctionManager::Initialize()
|
||||
{ auction_item_cache_map.clear();
|
||||
LoadAuctionItem();
|
||||
LoadAuctionInfo();
|
||||
LoadSaleInfo();
|
||||
LoadWishInfo();
|
||||
LoadMyBidInfo();
|
||||
}
|
||||
|
||||
void AuctionManager::LoadAuctionItem()
|
||||
{
|
||||
char szQuery[512];
|
||||
snprintf(szQuery, sizeof(szQuery),
|
||||
"SELECT id, owner_id, count, vnum, socket0, socket1, socket2, "
|
||||
"attrtype0, attrvalue0, "
|
||||
"attrtype1, attrvalue1, "
|
||||
"attrtype2, attrvalue2, "
|
||||
"attrtype3, attrvalue3, "
|
||||
"attrtype4, attrvalue4, "
|
||||
"attrtype5, attrvalue5, "
|
||||
"attrtype6, attrvalue6 "
|
||||
"FROM item WHERE window = 'AUCTION'");
|
||||
|
||||
SQLMsg *msg = CDBManager::instance().DirectQuery(szQuery);
|
||||
|
||||
MYSQL_RES *res = msg->Get()->pSQLResult;
|
||||
|
||||
if (!res)
|
||||
{
|
||||
return;
|
||||
}
|
||||
int rows;
|
||||
|
||||
if ((rows = mysql_num_rows(res)) <= 0) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < rows; ++i)
|
||||
{
|
||||
MYSQL_ROW row = mysql_fetch_row(res);
|
||||
TPlayerItem item;
|
||||
|
||||
int cur = 0;
|
||||
|
||||
str_to_number(item.id, row[cur++]);
|
||||
str_to_number(item.owner, row[cur++]);
|
||||
item.window = AUCTION;
|
||||
str_to_number(item.count, row[cur++]);
|
||||
str_to_number(item.vnum, row[cur++]);
|
||||
str_to_number(item.alSockets[0], row[cur++]);
|
||||
str_to_number(item.alSockets[1], row[cur++]);
|
||||
str_to_number(item.alSockets[2], row[cur++]);
|
||||
|
||||
for (int j = 0; j < ITEM_ATTRIBUTE_MAX_NUM; j++)
|
||||
{
|
||||
str_to_number(item.aAttr[j].bType, row[cur++]);
|
||||
str_to_number(item.aAttr[j].sValue, row[cur++]);
|
||||
}
|
||||
InsertItemCache(&item, true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void AuctionManager::LoadAuctionInfo()
|
||||
{
|
||||
char szQuery[512];
|
||||
snprintf(szQuery, sizeof(szQuery),
|
||||
"select * from auction");
|
||||
|
||||
SQLMsg *msg = CDBManager::instance().DirectQuery(szQuery);
|
||||
|
||||
MYSQL_RES *res = msg->Get()->pSQLResult;
|
||||
|
||||
if (!res)
|
||||
{
|
||||
return;
|
||||
}
|
||||
int rows;
|
||||
|
||||
if ((rows = mysql_num_rows(res)) <= 0) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < rows; ++i)
|
||||
{
|
||||
MYSQL_ROW row = mysql_fetch_row(res);
|
||||
TAuctionItemInfo auctionItemInfo;
|
||||
|
||||
int cur = 0;
|
||||
|
||||
str_to_number(auctionItemInfo.item_num, row[cur++]);
|
||||
str_to_number(auctionItemInfo.offer_price, row[cur++]);
|
||||
str_to_number(auctionItemInfo.price, row[cur++]);
|
||||
str_to_number(auctionItemInfo.offer_id, row[cur++]);
|
||||
thecore_memcpy (auctionItemInfo.shown_name, (char*)row[cur], strlen((char*)row[cur]) +1);
|
||||
cur++;
|
||||
str_to_number(auctionItemInfo.empire, row[cur++]);
|
||||
str_to_number(auctionItemInfo.expired_time, row[cur++]);
|
||||
str_to_number(auctionItemInfo.item_id, row[cur++]);
|
||||
str_to_number(auctionItemInfo.bidder_id, row[cur++]);
|
||||
|
||||
InsertAuctionItemInfoCache(&auctionItemInfo, true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void AuctionManager::LoadSaleInfo()
|
||||
{
|
||||
char szQuery[512];
|
||||
snprintf(szQuery, sizeof(szQuery),
|
||||
"select * from sale");
|
||||
|
||||
SQLMsg *msg = CDBManager::instance().DirectQuery(szQuery);
|
||||
|
||||
MYSQL_RES *res = msg->Get()->pSQLResult;
|
||||
|
||||
if (!res)
|
||||
{
|
||||
return;
|
||||
}
|
||||
int rows;
|
||||
|
||||
if ((rows = mysql_num_rows(res)) <= 0) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < rows; ++i)
|
||||
{
|
||||
MYSQL_ROW row = mysql_fetch_row(res);
|
||||
TSaleItemInfo saleItemInfo;
|
||||
|
||||
int cur = 0;
|
||||
|
||||
str_to_number(saleItemInfo.item_num, row[cur++]);
|
||||
str_to_number(saleItemInfo.offer_price, row[cur++]);
|
||||
str_to_number(saleItemInfo.price, row[cur++]);
|
||||
str_to_number(saleItemInfo.offer_id, row[cur++]);
|
||||
thecore_memcpy (saleItemInfo.shown_name, (char*)row[cur], strlen((char*)row[cur]) +1);
|
||||
cur++;
|
||||
str_to_number(saleItemInfo.empire, row[cur++]);
|
||||
str_to_number(saleItemInfo.expired_time, row[cur++]);
|
||||
str_to_number(saleItemInfo.item_id, row[cur++]);
|
||||
str_to_number(saleItemInfo.wisher_id, row[cur++]);
|
||||
|
||||
InsertSaleItemInfoCache(&saleItemInfo, true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
void AuctionManager::LoadWishInfo()
|
||||
{
|
||||
char szQuery[512];
|
||||
snprintf(szQuery, sizeof(szQuery),
|
||||
"select * from wish");
|
||||
|
||||
SQLMsg *msg = CDBManager::instance().DirectQuery(szQuery);
|
||||
|
||||
MYSQL_RES *res = msg->Get()->pSQLResult;
|
||||
|
||||
if (!res)
|
||||
{
|
||||
return;
|
||||
}
|
||||
int rows;
|
||||
|
||||
if ((rows = mysql_num_rows(res)) <= 0) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < rows; ++i)
|
||||
{
|
||||
MYSQL_ROW row = mysql_fetch_row(res);
|
||||
TWishItemInfo wishItemInfo;
|
||||
|
||||
int cur = 0;
|
||||
|
||||
str_to_number(wishItemInfo.item_num, row[cur++]);
|
||||
str_to_number(wishItemInfo.offer_price, row[cur++]);
|
||||
str_to_number(wishItemInfo.price, row[cur++]);
|
||||
str_to_number(wishItemInfo.offer_id, row[cur++]);
|
||||
thecore_memcpy (wishItemInfo.shown_name, (char*)row[cur], strlen((char*)row[cur]) +1);
|
||||
cur++;
|
||||
str_to_number(wishItemInfo.empire, row[cur++]);
|
||||
str_to_number(wishItemInfo.expired_time, row[cur++]);
|
||||
|
||||
InsertWishItemInfoCache(&wishItemInfo, true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void AuctionManager::LoadMyBidInfo ()
|
||||
{
|
||||
char szQuery[512];
|
||||
snprintf(szQuery, sizeof(szQuery),
|
||||
"select * from my_bid");
|
||||
|
||||
SQLMsg *msg = CDBManager::instance().DirectQuery(szQuery);
|
||||
|
||||
MYSQL_RES *res = msg->Get()->pSQLResult;
|
||||
|
||||
if (!res)
|
||||
{
|
||||
return;
|
||||
}
|
||||
int rows;
|
||||
|
||||
if ((rows = mysql_num_rows(res)) <= 0) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < rows; ++i)
|
||||
{
|
||||
MYSQL_ROW row = mysql_fetch_row(res);
|
||||
|
||||
int cur = 0;
|
||||
DWORD player_id;
|
||||
DWORD item_id;
|
||||
int money;
|
||||
|
||||
str_to_number(player_id, row[cur++]);
|
||||
str_to_number(item_id, row[cur++]);
|
||||
str_to_number(money, row[cur++]);
|
||||
|
||||
InsertMyBid (player_id, item_id, money);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
inline CItemCache* AuctionManager::GetItemCache(DWORD item_id)
|
||||
{
|
||||
TItemCacheMap::iterator it = auction_item_cache_map.find (item_id);
|
||||
if (it == auction_item_cache_map.end())
|
||||
return NULL;
|
||||
else
|
||||
return it->second;
|
||||
}
|
||||
|
||||
void AuctionManager::Boot(CPeer* peer)
|
||||
{
|
||||
peer->EncodeWORD(sizeof(TPlayerItem));
|
||||
peer->EncodeWORD(auction_item_cache_map.size());
|
||||
|
||||
itertype(auction_item_cache_map) auction_item_cache_map_it = auction_item_cache_map.begin();
|
||||
|
||||
while (auction_item_cache_map_it != auction_item_cache_map.end())
|
||||
peer->Encode((auction_item_cache_map_it++)->second->Get(), sizeof(TPlayerItem));
|
||||
|
||||
Auction.Boot(peer);
|
||||
Sale.Boot(peer);
|
||||
Wish.Boot(peer);
|
||||
MyBid.Boot(peer);
|
||||
}
|
||||
|
||||
bool AuctionManager::InsertItemCache(CItemCache *item_cache, bool bSkipQuery)
|
||||
{
|
||||
CItemCache* c = GetItemCache (item_cache->Get(false)->id);
|
||||
if (c != NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
auction_item_cache_map.insert(TItemCacheMap::value_type(item_cache->Get(true)->id, item_cache));
|
||||
item_cache->OnFlush();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AuctionManager::InsertItemCache(TPlayerItem * pNew, bool bSkipQuery)
|
||||
{
|
||||
CItemCache* c = GetItemCache (pNew->id);
|
||||
if (c != NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
c = new CItemCache();
|
||||
|
||||
c->Put(pNew, bSkipQuery);
|
||||
|
||||
auction_item_cache_map.insert(TItemCacheMap::value_type(pNew->id, c));
|
||||
c->Flush();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AuctionManager::DeleteItemCache(DWORD item_id)
|
||||
{
|
||||
CItemCache* c = GetItemCache (item_id);
|
||||
if (c == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
c->Delete();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
AuctionResult AuctionManager::EnrollInAuction(CItemCache* item_cache, TAuctionItemInfo &item_info)
|
||||
{
|
||||
CItemCache* c = GetItemCache (item_info.item_id);
|
||||
if (c != NULL)
|
||||
{
|
||||
sys_err ("item id : %d is already in AuctionManager", item_info.item_id);
|
||||
return AUCTION_FAIL;
|
||||
}
|
||||
|
||||
if (!Auction.InsertItemInfo (&item_info))
|
||||
{
|
||||
sys_err ("item id : %d is already in AuctionBoard", item_info.item_id);
|
||||
return AUCTION_FAIL;
|
||||
}
|
||||
|
||||
item_cache->Get()->window = AUCTION;
|
||||
item_cache->Get()->pos = 9999999;
|
||||
|
||||
InsertItemCache (item_cache);
|
||||
|
||||
return AUCTION_SUCCESS;
|
||||
}
|
||||
|
||||
AuctionResult AuctionManager::EnrollInSale(CItemCache* item_cache, TSaleItemInfo &item_info)
|
||||
{
|
||||
CItemCache* c = GetItemCache (item_info.item_id);
|
||||
if (c != NULL)
|
||||
{
|
||||
sys_err ("item id : %d is already in AuctionManager", item_info.item_id);
|
||||
return AUCTION_FAIL;
|
||||
}
|
||||
|
||||
if (!Wish.GetItemInfoCache (WishBoard::Key (item_info.item_num, item_info.wisher_id)))
|
||||
{
|
||||
sys_err ("item_num : %d, wisher_id : %d is not in wish auction.", item_info.item_num, item_info.wisher_id);
|
||||
return AUCTION_FAIL;
|
||||
}
|
||||
|
||||
if (!Sale.InsertItemInfo (&item_info))
|
||||
{
|
||||
sys_err ("item id : %d is already in SaleBoard", item_info.item_id);
|
||||
return AUCTION_FAIL;
|
||||
}
|
||||
|
||||
item_cache->Get()->window = AUCTION;
|
||||
item_cache->Get()->pos = 999999;
|
||||
|
||||
InsertItemCache (item_cache);
|
||||
|
||||
return AUCTION_SUCCESS;
|
||||
}
|
||||
|
||||
AuctionResult AuctionManager::EnrollInWish(TWishItemInfo &item_info)
|
||||
{
|
||||
if (!Wish.InsertItemInfo (&item_info))
|
||||
{
|
||||
sys_err ("wisher_id : %d, item_num : %d is already in WishBoard", item_info.offer_id, item_info.item_num);
|
||||
return AUCTION_FAIL;
|
||||
}
|
||||
|
||||
return AUCTION_SUCCESS;
|
||||
}
|
||||
|
||||
AuctionResult AuctionManager::Bid(DWORD bidder_id, const char* bidder_name, DWORD item_id, DWORD bid_price)
|
||||
{
|
||||
CItemCache* c = GetItemCache (item_id);
|
||||
if (c == NULL)
|
||||
{
|
||||
sys_err ("item id : %d does not exist in auction.", item_id);
|
||||
return AUCTION_FAIL;
|
||||
}
|
||||
|
||||
if (MyBid.GetMoney (bidder_id, item_id) != 0)
|
||||
{
|
||||
return AUCTION_ALREADY_IN;
|
||||
}
|
||||
|
||||
CAuctionItemInfoCache* item_cache = Auction.GetItemInfoCache(item_id);
|
||||
TAuctionItemInfo* item_info = item_cache->Get(false);
|
||||
|
||||
if (item_info->is_expired())
|
||||
{
|
||||
return AUCTION_EXPIRED;
|
||||
}
|
||||
|
||||
if ((double)bid_price < (double)item_info->get_bid_price() * 1.05)
|
||||
{
|
||||
return AUCTION_NOT_ENOUGH_MONEY;
|
||||
}
|
||||
|
||||
item_info->set_bid_price(bid_price);
|
||||
item_info->bidder_id = bidder_id;
|
||||
item_info->set_bidder_name (bidder_name);
|
||||
item_cache->OnFlush();
|
||||
|
||||
InsertMyBid (bidder_id, item_id, bid_price);
|
||||
|
||||
return AUCTION_SUCCESS;
|
||||
}
|
||||
|
||||
AuctionResult AuctionManager::Impur(DWORD purchaser_id, const char* purchaser_name, DWORD item_id)
|
||||
{
|
||||
CItemCache* c = GetItemCache (item_id);
|
||||
if (c == NULL)
|
||||
{
|
||||
sys_err ("item id : %d does not exist in auction.", item_id);
|
||||
return AUCTION_FAIL;
|
||||
}
|
||||
|
||||
CAuctionItemInfoCache* item_cache = Auction.GetItemInfoCache(item_id);
|
||||
TAuctionItemInfo* item_info = item_cache->Get(false);
|
||||
|
||||
if (item_info->is_expired())
|
||||
{
|
||||
return AUCTION_EXPIRED;
|
||||
}
|
||||
|
||||
// <20>ﱸ <20>ع<EFBFBD><D8B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD>, <20><><EFBFBD>Ŵ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||||
item_info->expired_time = 0;
|
||||
item_info->bidder_id = purchaser_id;
|
||||
item_info->set_bidder_name (purchaser_name);
|
||||
item_info->set_bid_price (item_info->get_impur_price());
|
||||
item_cache->OnFlush();
|
||||
|
||||
return AUCTION_SUCCESS;
|
||||
}
|
||||
|
||||
AuctionResult AuctionManager::GetAuctionedItem (DWORD actor_id, DWORD item_id, TPlayerItem& item)
|
||||
{
|
||||
CItemCache* c = GetItemCache (item_id);
|
||||
if (c == NULL)
|
||||
{
|
||||
sys_err ("item id : %d does not exist in auction.", item_id);
|
||||
return AUCTION_FAIL;
|
||||
}
|
||||
|
||||
CAuctionItemInfoCache* item_info_cache = Auction.GetItemInfoCache(item_id);
|
||||
if (item_info_cache == NULL)
|
||||
{
|
||||
sys_err ("how can this accident happen?");
|
||||
return AUCTION_FAIL;
|
||||
}
|
||||
|
||||
TAuctionItemInfo* item_info = item_info_cache->Get(false);
|
||||
|
||||
if (!item_info->is_expired())
|
||||
{
|
||||
return AUCTION_NOT_EXPIRED;
|
||||
}
|
||||
|
||||
thecore_memcpy(&item, c->Get(), sizeof(TPlayerItem));
|
||||
|
||||
return AUCTION_SUCCESS;
|
||||
}
|
||||
|
||||
AuctionResult AuctionManager::BuySoldItem (DWORD actor_id, DWORD item_id, TPlayerItem& item)
|
||||
{
|
||||
CItemCache* c = GetItemCache (item_id);
|
||||
if (c == NULL)
|
||||
{
|
||||
sys_err ("item id : %d does not exist in auction.", item_id);
|
||||
return AUCTION_FAIL;
|
||||
}
|
||||
|
||||
CSaleItemInfoCache* item_info_cache = Sale.GetItemInfoCache(item_id);
|
||||
if (item_info_cache == NULL)
|
||||
{
|
||||
sys_err ("how can this accident happen?");
|
||||
return AUCTION_FAIL;
|
||||
}
|
||||
|
||||
TSaleItemInfo* item_info = item_info_cache->Get(false);
|
||||
|
||||
thecore_memcpy(&item, c->Get(), sizeof(TPlayerItem));
|
||||
|
||||
return AUCTION_SUCCESS;
|
||||
}
|
||||
|
||||
AuctionResult AuctionManager::CancelAuction (DWORD actor_id, DWORD item_id, TPlayerItem& item)
|
||||
{
|
||||
CItemCache* c = GetItemCache (item_id);
|
||||
if (c == NULL)
|
||||
{
|
||||
sys_err ("item id : %d does not exist in auction.", item_id);
|
||||
return AUCTION_FAIL;
|
||||
}
|
||||
|
||||
CAuctionItemInfoCache* item_info_cache = Auction.GetItemInfoCache(item_id);
|
||||
if (item_info_cache == NULL)
|
||||
{
|
||||
sys_err ("how can this accident happen?");
|
||||
return AUCTION_FAIL;
|
||||
}
|
||||
TAuctionItemInfo* item_info = item_info_cache->Get(false);
|
||||
|
||||
thecore_memcpy(&item, c->Get(), sizeof(TPlayerItem));
|
||||
|
||||
return AUCTION_SUCCESS;
|
||||
}
|
||||
|
||||
AuctionResult AuctionManager::CancelWish (DWORD actor_id, DWORD item_num)
|
||||
{
|
||||
if (!Wish.DeleteItemInfoCache (WishBoard::Key (actor_id, item_num)))
|
||||
{
|
||||
return AUCTION_FAIL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return AUCTION_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
AuctionResult AuctionManager::CancelSale (DWORD actor_id, DWORD item_id, TPlayerItem& item)
|
||||
{
|
||||
CItemCache* c = GetItemCache (item_id);
|
||||
if (c == NULL)
|
||||
{
|
||||
sys_err ("item id : %d does not exist in auction.", item_id);
|
||||
return AUCTION_FAIL;
|
||||
}
|
||||
|
||||
CSaleItemInfoCache* item_info_cache = Sale.GetItemInfoCache(item_id);
|
||||
if (item_info_cache == NULL)
|
||||
{
|
||||
sys_err ("how can this accident happen?");
|
||||
return AUCTION_FAIL;
|
||||
}
|
||||
TSaleItemInfo* item_info = item_info_cache->Get(false);
|
||||
|
||||
thecore_memcpy(&item, c->Get(), sizeof(TPlayerItem));
|
||||
|
||||
return AUCTION_SUCCESS;
|
||||
}
|
||||
|
||||
AuctionResult AuctionManager::DeleteAuctionItem (DWORD actor_id, DWORD item_id)
|
||||
{
|
||||
if (DeleteItemCache (item_id) == false)
|
||||
{
|
||||
sys_err ("item id : %d does not exist in auction.", item_id);
|
||||
return AUCTION_FAIL;
|
||||
}
|
||||
|
||||
if (Auction.DeleteItemInfoCache (item_id) == NULL)
|
||||
{
|
||||
sys_err ("how can this accident happen?");
|
||||
return AUCTION_FAIL;
|
||||
}
|
||||
return AUCTION_SUCCESS;
|
||||
}
|
||||
|
||||
AuctionResult AuctionManager::DeleteSaleItem (DWORD actor_id, DWORD item_id)
|
||||
{
|
||||
if (DeleteItemCache (item_id) == false)
|
||||
{
|
||||
sys_err ("item id : %d does not exist in auction.", item_id);
|
||||
return AUCTION_FAIL;
|
||||
}
|
||||
|
||||
if (Sale.DeleteItemInfoCache (item_id) == NULL)
|
||||
{
|
||||
sys_err ("how can this accident happen?");
|
||||
return AUCTION_FAIL;
|
||||
}
|
||||
return AUCTION_SUCCESS;
|
||||
}
|
||||
|
||||
AuctionResult AuctionManager::ReBid(DWORD bidder_id, const char* bidder_name, DWORD item_id, DWORD bid_price)
|
||||
{
|
||||
CItemCache* c = GetItemCache (item_id);
|
||||
if (c == NULL)
|
||||
{
|
||||
sys_err ("item id : %d does not exist in auction.", item_id);
|
||||
return AUCTION_FAIL;
|
||||
}
|
||||
|
||||
int money = MyBid.GetMoney (bidder_id, item_id);
|
||||
if (money == -1)
|
||||
{
|
||||
return AUCTION_NOT_IN;
|
||||
}
|
||||
|
||||
CAuctionItemInfoCache* item_cache = Auction.GetItemInfoCache(item_id);
|
||||
TAuctionItemInfo* item_info = item_cache->Get(false);
|
||||
|
||||
if (item_info->is_expired())
|
||||
{
|
||||
return AUCTION_EXPIRED;
|
||||
}
|
||||
|
||||
if ((double)(bid_price + money) < (double)item_info->get_bid_price() * 1.05)
|
||||
{
|
||||
return AUCTION_NOT_ENOUGH_MONEY;
|
||||
}
|
||||
|
||||
item_info->set_bid_price(bid_price + money);
|
||||
item_info->bidder_id = bidder_id;
|
||||
item_info->set_bidder_name (bidder_name);
|
||||
item_cache->OnFlush();
|
||||
|
||||
InsertMyBid (bidder_id, item_id, money + bid_price);
|
||||
|
||||
return AUCTION_SUCCESS;
|
||||
}
|
||||
|
||||
AuctionResult AuctionManager::BidCancel (DWORD bidder_id, DWORD item_id)
|
||||
{
|
||||
if (MyBid.Delete (bidder_id, item_id))
|
||||
{
|
||||
return AUCTION_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return AUCTION_NOT_IN;
|
||||
}
|
||||
}
|
||||
#endif
|
370
db/src/AuctionManager.h
Normal file
370
db/src/AuctionManager.h
Normal file
@ -0,0 +1,370 @@
|
||||
#ifdef __AUCTION__
|
||||
|
||||
#ifndef __INC_AUCTION_MANAGER_H__
|
||||
#define __INC_AUCTION_MANAGER_H__
|
||||
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include "Cache.h"
|
||||
#include "../../common/auction_table.h"
|
||||
|
||||
class CItemCache;
|
||||
class CAuctionItemInfoCache;
|
||||
class CSaleItemInfoCache;
|
||||
class CWishItemInfoCache;
|
||||
|
||||
template<>
|
||||
class hash<std::pair <DWORD, DWORD> >
|
||||
{ // hash functor
|
||||
public:
|
||||
typedef std::pair <DWORD, DWORD> _Kty;
|
||||
|
||||
size_t operator()(const _Kty& _Keyval) const
|
||||
{ // hash _Keyval to size_t value by pseudorandomizing transform
|
||||
ldiv_t _Qrem = ldiv((size_t)_Keyval.first + (size_t)_Keyval.second, 127773);
|
||||
|
||||
_Qrem.rem = 16807 * _Qrem.rem - 2836 * _Qrem.quot;
|
||||
if (_Qrem.rem < 0)
|
||||
_Qrem.rem += 2147483647;
|
||||
return ((size_t)_Qrem.rem);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class AuctionBoard
|
||||
{
|
||||
public:
|
||||
typedef DWORD Key;
|
||||
typedef CAuctionItemInfoCache ItemInfoCache;
|
||||
typedef TAuctionItemInfo ItemInfo;
|
||||
|
||||
|
||||
public:
|
||||
AuctionBoard() {}
|
||||
~AuctionBoard() {}
|
||||
|
||||
void Boot(CPeer* peer)
|
||||
{
|
||||
peer->EncodeWORD(sizeof(ItemInfo));
|
||||
peer->EncodeWORD(item_cache_map.size());
|
||||
|
||||
TItemInfoCacheMap::iterator it = item_cache_map.begin();
|
||||
|
||||
while (it != item_cache_map.end())
|
||||
peer->Encode((it++)->second->Get(), sizeof(ItemInfo));
|
||||
}
|
||||
|
||||
size_t Size()
|
||||
{
|
||||
return item_cache_map.size();
|
||||
}
|
||||
|
||||
ItemInfoCache* GetItemInfoCache (Key key)
|
||||
{
|
||||
TItemInfoCacheMap::iterator it = item_cache_map.find (key);
|
||||
if (it == item_cache_map.end())
|
||||
return NULL;
|
||||
else
|
||||
return it->second;
|
||||
}
|
||||
|
||||
bool DeleteItemInfoCache (Key key)
|
||||
{
|
||||
TItemInfoCacheMap::iterator it = item_cache_map.find (key);
|
||||
if (it == item_cache_map.end())
|
||||
return false;
|
||||
else
|
||||
{
|
||||
it->second->Delete();
|
||||
item_cache_map.erase(it);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool InsertItemInfo (ItemInfo *pNew, bool bSkipQuery = false)
|
||||
{
|
||||
ItemInfoCache* c = GetItemInfoCache (Key (pNew->item_id));
|
||||
if (c != NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
c = new ItemInfoCache();
|
||||
|
||||
c->Put(pNew, bSkipQuery);
|
||||
|
||||
item_cache_map.insert(TItemInfoCacheMap::value_type(pNew->item_id, c));
|
||||
c->Flush();
|
||||
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
typedef boost::unordered_map <Key, ItemInfoCache *> TItemInfoCacheMap;
|
||||
TItemInfoCacheMap item_cache_map;
|
||||
};
|
||||
|
||||
class SaleBoard
|
||||
{
|
||||
public:
|
||||
typedef DWORD Key;
|
||||
typedef CSaleItemInfoCache ItemInfoCache;
|
||||
typedef TSaleItemInfo ItemInfo;
|
||||
|
||||
SaleBoard() {}
|
||||
~SaleBoard() {}
|
||||
|
||||
void Boot(CPeer* peer)
|
||||
{
|
||||
peer->EncodeWORD(sizeof(ItemInfo));
|
||||
peer->EncodeWORD(item_cache_map.size());
|
||||
|
||||
TItemInfoCacheMap::iterator it = item_cache_map.begin();
|
||||
|
||||
while (it != item_cache_map.end())
|
||||
peer->Encode((it++)->second->Get(), sizeof(ItemInfo));
|
||||
}
|
||||
|
||||
size_t Size()
|
||||
{
|
||||
return item_cache_map.size();
|
||||
}
|
||||
|
||||
ItemInfoCache* GetItemInfoCache (Key key)
|
||||
{
|
||||
TItemInfoCacheMap::iterator it = item_cache_map.find (key);
|
||||
if (it == item_cache_map.end())
|
||||
return NULL;
|
||||
else
|
||||
return it->second;
|
||||
}
|
||||
|
||||
bool DeleteItemInfoCache (Key key)
|
||||
{
|
||||
TItemInfoCacheMap::iterator it = item_cache_map.find (key);
|
||||
if (it == item_cache_map.end())
|
||||
return false;
|
||||
else
|
||||
{
|
||||
it->second->Delete();
|
||||
item_cache_map.erase(it);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool InsertItemInfo (ItemInfo *pNew, bool bSkipQuery = false)
|
||||
{
|
||||
ItemInfoCache* c = GetItemInfoCache (Key (pNew->item_id));
|
||||
if (c != NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
c = new ItemInfoCache();
|
||||
|
||||
c->Put(pNew, bSkipQuery);
|
||||
|
||||
item_cache_map.insert(TItemInfoCacheMap::value_type(pNew->item_id, c));
|
||||
c->Flush();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
typedef boost::unordered_map <Key, ItemInfoCache *> TItemInfoCacheMap;
|
||||
TItemInfoCacheMap item_cache_map;
|
||||
};
|
||||
|
||||
class WishBoard
|
||||
{
|
||||
public:
|
||||
typedef std::pair <DWORD, DWORD> Key;
|
||||
typedef CWishItemInfoCache ItemInfoCache;
|
||||
typedef TWishItemInfo ItemInfo;
|
||||
|
||||
WishBoard() {}
|
||||
virtual ~WishBoard() {}
|
||||
|
||||
void Boot(CPeer* peer)
|
||||
{
|
||||
peer->EncodeWORD(sizeof(ItemInfo));
|
||||
peer->EncodeWORD(item_cache_map.size());
|
||||
|
||||
TItemInfoCacheMap::iterator it = item_cache_map.begin();
|
||||
|
||||
while (it != item_cache_map.end())
|
||||
peer->Encode((it++)->second->Get(), sizeof(ItemInfo));
|
||||
}
|
||||
|
||||
size_t Size()
|
||||
{
|
||||
return item_cache_map.size();
|
||||
}
|
||||
|
||||
ItemInfoCache* GetItemInfoCache (Key key)
|
||||
{
|
||||
TItemInfoCacheMap::iterator it = item_cache_map.find (key);
|
||||
if (it == item_cache_map.end())
|
||||
return NULL;
|
||||
else
|
||||
return it->second;
|
||||
}
|
||||
|
||||
bool DeleteItemInfoCache (Key key)
|
||||
{
|
||||
TItemInfoCacheMap::iterator it = item_cache_map.find (key);
|
||||
if (it == item_cache_map.end())
|
||||
return false;
|
||||
else
|
||||
{
|
||||
it->second->Delete();
|
||||
item_cache_map.erase(it);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool InsertItemInfo (ItemInfo *pNew, bool bSkipQuery = false)
|
||||
{
|
||||
ItemInfoCache* c = GetItemInfoCache (Key (pNew->item_num, pNew->offer_id));
|
||||
if (c != NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
c = new ItemInfoCache();
|
||||
|
||||
c->Put(pNew, bSkipQuery);
|
||||
|
||||
item_cache_map.insert(TItemInfoCacheMap::value_type(Key (pNew->item_num, pNew->offer_id), c));
|
||||
c->Flush();
|
||||
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
typedef boost::unordered_map <Key, ItemInfoCache *> TItemInfoCacheMap;
|
||||
TItemInfoCacheMap item_cache_map;
|
||||
};
|
||||
|
||||
// pc<70><63> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ߴ<EFBFBD> <20><><EFBFBD>Ÿ<EFBFBD> <20><><EFBFBD><EFBFBD>.
|
||||
class MyBidBoard
|
||||
{
|
||||
public:
|
||||
MyBidBoard() {}
|
||||
~MyBidBoard() {}
|
||||
|
||||
void Boot(CPeer* peer);
|
||||
size_t Size();
|
||||
|
||||
int GetMoney (DWORD player_id, DWORD item_id);
|
||||
bool Delete (DWORD player_id, DWORD item_id);
|
||||
// <20>̹<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||||
void Insert (DWORD player_id, DWORD item_id, int money);
|
||||
|
||||
private:
|
||||
typedef std::map <DWORD, int> TItemMap;
|
||||
typedef boost::unordered_map <DWORD, TItemMap*> TMyBidBoard;
|
||||
TMyBidBoard pc_map;
|
||||
};
|
||||
|
||||
class AuctionManager : public singleton <AuctionManager>
|
||||
{
|
||||
private:
|
||||
// auction<6F><6E> <20><><EFBFBD>ϵ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>۵<EFBFBD>.
|
||||
typedef boost::unordered_map<DWORD, CItemCache *> TItemCacheMap;
|
||||
TItemCacheMap auction_item_cache_map;
|
||||
|
||||
// auction<6F><6E> <20><><EFBFBD>ϵ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>̺<EFBFBD><CCBA><EFBFBD> <20><><EFBFBD>Ե<EFBFBD><D4B5><EFBFBD> <20>ʴ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20>͵<EFBFBD>
|
||||
AuctionBoard Auction;
|
||||
SaleBoard Sale;
|
||||
WishBoard Wish;
|
||||
MyBidBoard MyBid;
|
||||
|
||||
public:
|
||||
AuctionManager();
|
||||
~AuctionManager();
|
||||
|
||||
void Initialize ();
|
||||
void LoadAuctionItem ();
|
||||
|
||||
void LoadAuctionInfo ();
|
||||
void LoadSaleInfo ();
|
||||
void LoadWishInfo ();
|
||||
void LoadMyBidInfo ();
|
||||
|
||||
void Boot(CPeer* peer);
|
||||
|
||||
bool InsertItemCache (CItemCache *item_cache, bool bSkipQuery = false);
|
||||
bool InsertItemCache (TPlayerItem * pNew, bool bSkipQuery = false);
|
||||
bool DeleteItemCache (DWORD item_id);
|
||||
CItemCache* GetItemCache (DWORD item_id);
|
||||
|
||||
size_t GetAuctionItemSize()
|
||||
{
|
||||
return auction_item_cache_map.size();
|
||||
}
|
||||
size_t GetAuctionSize()
|
||||
{
|
||||
return Auction.Size();
|
||||
}
|
||||
size_t GetSaleSize()
|
||||
{
|
||||
return Sale.Size();
|
||||
}
|
||||
size_t GetWishSize()
|
||||
{
|
||||
return Wish.Size();
|
||||
}
|
||||
size_t GetMyBidSize()
|
||||
{
|
||||
return MyBid.Size();
|
||||
}
|
||||
|
||||
void InsertAuctionItemInfoCache (TAuctionItemInfo *pNew, bool bSkipQuery = false)
|
||||
{
|
||||
Auction.InsertItemInfo (pNew, bSkipQuery);
|
||||
}
|
||||
CAuctionItemInfoCache* GetAuctionItemInfoCache (DWORD item_id)
|
||||
{
|
||||
return Auction.GetItemInfoCache(item_id);
|
||||
}
|
||||
|
||||
void InsertSaleItemInfoCache (TSaleItemInfo *pNew, bool bSkipQuery = false)
|
||||
{
|
||||
Sale.InsertItemInfo (pNew, bSkipQuery);
|
||||
}
|
||||
CSaleItemInfoCache* GetSaleItemInfoCache (DWORD item_id)
|
||||
{
|
||||
return Sale.GetItemInfoCache(item_id);
|
||||
}
|
||||
|
||||
void InsertWishItemInfoCache (TWishItemInfo *pNew, bool bSkipQuery = false)
|
||||
{
|
||||
Wish.InsertItemInfo (pNew, bSkipQuery);
|
||||
}
|
||||
CWishItemInfoCache* GetWishItemInfoCache (DWORD item_id, DWORD wisher_id)
|
||||
{
|
||||
return Wish.GetItemInfoCache(WishBoard::Key (item_id, wisher_id));
|
||||
}
|
||||
|
||||
void InsertMyBid (DWORD player_id, DWORD item_id, DWORD money)
|
||||
{
|
||||
MyBid.Insert (player_id, item_id, money);
|
||||
}
|
||||
|
||||
AuctionResult EnrollInAuction(CItemCache* item_cache, TAuctionItemInfo &item_info);
|
||||
AuctionResult EnrollInSale(CItemCache* item_cache, TSaleItemInfo &item_info);
|
||||
AuctionResult EnrollInWish(TWishItemInfo &item_info);
|
||||
AuctionResult Bid(DWORD bidder_id, const char* bidder_name, DWORD item_id, DWORD bid_price);
|
||||
AuctionResult Impur(DWORD purchaser_id, const char* purchaser_name, DWORD item_id);
|
||||
AuctionResult GetAuctionedItem (DWORD actor_id, DWORD item_id, TPlayerItem& item);
|
||||
AuctionResult BuySoldItem (DWORD actor_id, DWORD item_id, TPlayerItem& item);
|
||||
AuctionResult CancelAuction (DWORD actor_id, DWORD item_id, TPlayerItem& item);
|
||||
AuctionResult CancelWish (DWORD actor_id, DWORD item_num);
|
||||
AuctionResult CancelSale (DWORD actor_id, DWORD item_id, TPlayerItem& item);
|
||||
AuctionResult DeleteAuctionItem (DWORD actor_id, DWORD item_id);
|
||||
AuctionResult DeleteSaleItem (DWORD actor_id, DWORD item_id);
|
||||
AuctionResult ReBid(DWORD bidder_id, const char* bidder_name, DWORD item_id, DWORD bid_price);
|
||||
AuctionResult BidCancel (DWORD bidder_id, DWORD item_id);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
214
db/src/BlockCountry.cpp
Normal file
214
db/src/BlockCountry.cpp
Normal file
@ -0,0 +1,214 @@
|
||||
// vim:ts=4 sw=4
|
||||
/*********************************************************************
|
||||
* date : 2007.05.31
|
||||
* file : BlockCountry.cpp
|
||||
* author : mhh
|
||||
* description :
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "BlockCountry.h"
|
||||
|
||||
#include "DBManager.h"
|
||||
|
||||
#define DO_ALL_BLOCK_IP(iter) \
|
||||
for ((iter) = m_block_ip.begin(); (iter) != m_block_ip.end(); ++(iter))
|
||||
|
||||
#define DO_ALL_BLOCK_EXCEPTION(iter) \
|
||||
for ((iter) = m_block_exception.begin(); (iter) != m_block_exception.end(); ++(iter))
|
||||
|
||||
CBlockCountry::CBlockCountry()
|
||||
{
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
CBlockCountry::~CBlockCountry()
|
||||
{
|
||||
BLOCK_IP *block_ip;
|
||||
BLOCK_IP_VECTOR::iterator iter;
|
||||
|
||||
DO_ALL_BLOCK_IP(iter)
|
||||
{
|
||||
block_ip = *iter;
|
||||
delete block_ip;
|
||||
}
|
||||
|
||||
m_block_ip.clear();
|
||||
}
|
||||
|
||||
|
||||
bool CBlockCountry::Load()
|
||||
{
|
||||
// load blocked ip
|
||||
{
|
||||
char szQuery[256];
|
||||
snprintf(szQuery, sizeof(szQuery), "SELECT IP_FROM, IP_TO, COUNTRY_NAME FROM iptocountry");
|
||||
SQLMsg * pMsg = CDBManager::instance().DirectQuery(szQuery, SQL_ACCOUNT);
|
||||
|
||||
if (pMsg->Get()->uiNumRows == 0)
|
||||
{
|
||||
sys_err(" DirectQuery failed(%s)", szQuery);
|
||||
delete pMsg;
|
||||
return false;
|
||||
}
|
||||
|
||||
MYSQL_ROW row;
|
||||
for (int n = 0; (row = mysql_fetch_row(pMsg->Get()->pSQLResult)) != NULL; ++n)
|
||||
{
|
||||
BLOCK_IP *block_ip = new BLOCK_IP;
|
||||
block_ip->ip_from = strtoul(row[0], NULL, 10);
|
||||
block_ip->ip_to = strtoul(row[1], NULL, 10);
|
||||
strlcpy(block_ip->country, row[2], sizeof(block_ip->country));
|
||||
|
||||
m_block_ip.push_back(block_ip);
|
||||
sys_log(0, "BLOCKED_IP : %u - %u", block_ip->ip_from, block_ip->ip_to);
|
||||
|
||||
}
|
||||
delete pMsg;
|
||||
}
|
||||
|
||||
|
||||
// load block exception account
|
||||
{
|
||||
char szQuery[256];
|
||||
snprintf(szQuery, sizeof(szQuery), "SELECT login FROM block_exception");
|
||||
SQLMsg * pMsg = CDBManager::instance().DirectQuery(szQuery, SQL_ACCOUNT);
|
||||
|
||||
if (pMsg->Get()->uiNumRows == 0)
|
||||
{
|
||||
sys_err(" DirectQuery failed(%s)", szQuery);
|
||||
delete pMsg;
|
||||
return true;
|
||||
}
|
||||
|
||||
MYSQL_ROW row;
|
||||
for (int n = 0; (row = mysql_fetch_row(pMsg->Get()->pSQLResult)) != NULL; ++n)
|
||||
{
|
||||
const char *login = row[0];
|
||||
|
||||
m_block_exception.push_back(strdup(login));
|
||||
|
||||
sys_log(0, "BLOCK_EXCEPTION = %s", login);
|
||||
|
||||
}
|
||||
delete pMsg;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CBlockCountry::IsBlockedCountryIp(const char *user_ip)
|
||||
{
|
||||
BLOCK_IP* block_ip;
|
||||
BLOCK_IP_VECTOR::iterator iter;
|
||||
struct in_addr st_addr;
|
||||
|
||||
#ifndef __WIN32__
|
||||
if (0 == inet_aton(user_ip, &st_addr))
|
||||
#else
|
||||
unsigned long in_address;
|
||||
in_address = inet_addr(user_ip);
|
||||
st_addr.s_addr = in_address;
|
||||
if (INADDR_NONE == in_address)
|
||||
#endif
|
||||
return true; // <20><><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD>ó<EFBFBD><C3B3>
|
||||
|
||||
DO_ALL_BLOCK_IP(iter)
|
||||
{
|
||||
block_ip = *iter;
|
||||
|
||||
if (st_addr.s_addr >= block_ip->ip_from && st_addr.s_addr <= block_ip->ip_to)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CBlockCountry::SendBlockedCountryIp(CPeer *peer)
|
||||
{
|
||||
sys_log(0, "SendBlockedCountryIp start");
|
||||
BLOCK_IP *block_ip;
|
||||
BLOCK_IP_VECTOR::iterator iter;
|
||||
TPacketBlockCountryIp packet;
|
||||
|
||||
DO_ALL_BLOCK_IP(iter)
|
||||
{
|
||||
block_ip = *iter;
|
||||
|
||||
packet.ip_from = block_ip->ip_from;
|
||||
packet.ip_to = block_ip->ip_to;
|
||||
|
||||
peer->EncodeHeader(HEADER_DG_BLOCK_COUNTRY_IP, 0, sizeof(TPacketBlockCountryIp));
|
||||
peer->Encode(&packet, sizeof(packet));
|
||||
}
|
||||
|
||||
sys_log(0, "[DONE] CBlockCountry::SendBlockedCountryIp() : count = %d",
|
||||
m_block_ip.size());
|
||||
sys_log(0, "SendBlockedCountryIp end");
|
||||
} /* end of CBlockCountry::SendBlockedCountryIp() */
|
||||
|
||||
|
||||
void CBlockCountry::SendBlockException(CPeer *peer)
|
||||
{
|
||||
BLOCK_EXCEPTION_VECTOR::iterator iter;
|
||||
|
||||
DO_ALL_BLOCK_EXCEPTION(iter)
|
||||
{
|
||||
const char *login = *iter;
|
||||
|
||||
this->SendBlockExceptionOne(peer, login, BLOCK_EXCEPTION_CMD_ADD);
|
||||
}
|
||||
} /* end of CBlockCountry::SendBlockException() */
|
||||
|
||||
void CBlockCountry::SendBlockExceptionOne(CPeer *peer, const char *login, BYTE cmd)
|
||||
{
|
||||
if (NULL == peer || NULL == login)
|
||||
return;
|
||||
|
||||
if (BLOCK_EXCEPTION_CMD_ADD != cmd && BLOCK_EXCEPTION_CMD_DEL != cmd)
|
||||
return;
|
||||
|
||||
TPacketBlockException packet;
|
||||
|
||||
packet.cmd = cmd;
|
||||
strlcpy(packet.login, login, sizeof(packet.login));
|
||||
|
||||
peer->EncodeHeader(HEADER_DG_BLOCK_EXCEPTION, 0, sizeof(TPacketBlockException));
|
||||
peer->Encode(&packet, sizeof(packet));
|
||||
}
|
||||
|
||||
void CBlockCountry::AddBlockException(const char *login)
|
||||
{
|
||||
BLOCK_EXCEPTION_VECTOR::iterator iter;
|
||||
DO_ALL_BLOCK_EXCEPTION(iter)
|
||||
{
|
||||
const char *saved_login = *iter;
|
||||
|
||||
if (!strcmp(saved_login, login))
|
||||
return;
|
||||
}
|
||||
|
||||
m_block_exception.push_back(strdup(login));
|
||||
return;
|
||||
}
|
||||
|
||||
void CBlockCountry::DelBlockException(const char *login)
|
||||
{
|
||||
BLOCK_EXCEPTION_VECTOR::iterator iter;
|
||||
DO_ALL_BLOCK_EXCEPTION(iter)
|
||||
{
|
||||
const char *saved_login = *iter;
|
||||
|
||||
if (!strcmp(saved_login, login))
|
||||
{
|
||||
::free((void*)saved_login);
|
||||
m_block_exception.erase(iter);
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
44
db/src/BlockCountry.h
Normal file
44
db/src/BlockCountry.h
Normal file
@ -0,0 +1,44 @@
|
||||
// vim: ts=4 sw=4
|
||||
// Date : 2007.05.31
|
||||
// File : BlockCountry.h
|
||||
// Author : mhh
|
||||
// Description :
|
||||
|
||||
#ifndef __INC_METIN_II_BLOCKCOUNTRY_H__
|
||||
#define __INC_METIN_II_BLOCKCOUNTRY_H__
|
||||
|
||||
#include "Peer.h"
|
||||
|
||||
#define MAX_COUNTRY_NAME_LENGTH 50
|
||||
|
||||
class CBlockCountry : public singleton<CBlockCountry>
|
||||
{
|
||||
private:
|
||||
struct BLOCK_IP
|
||||
{
|
||||
DWORD ip_from;
|
||||
DWORD ip_to;
|
||||
char country[MAX_COUNTRY_NAME_LENGTH + 1];
|
||||
};
|
||||
|
||||
typedef std::vector<BLOCK_IP*> BLOCK_IP_VECTOR;
|
||||
BLOCK_IP_VECTOR m_block_ip;
|
||||
|
||||
typedef std::vector<const char*> BLOCK_EXCEPTION_VECTOR;
|
||||
BLOCK_EXCEPTION_VECTOR m_block_exception;
|
||||
|
||||
public:
|
||||
CBlockCountry();
|
||||
~CBlockCountry();
|
||||
|
||||
public:
|
||||
bool Load();
|
||||
bool IsBlockedCountryIp(const char *user_ip);
|
||||
void SendBlockedCountryIp(CPeer *peer);
|
||||
void SendBlockException(CPeer *peer);
|
||||
void SendBlockExceptionOne(CPeer *peer, const char *login, BYTE cmd);
|
||||
void AddBlockException(const char *login);
|
||||
void DelBlockException(const char *login);
|
||||
};
|
||||
|
||||
#endif
|
365
db/src/Cache.cpp
Normal file
365
db/src/Cache.cpp
Normal file
@ -0,0 +1,365 @@
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "Cache.h"
|
||||
|
||||
#include "QID.h"
|
||||
#include "ClientManager.h"
|
||||
#ifdef __AUCTION__
|
||||
#include "AuctionManager.h"
|
||||
#endif
|
||||
#include "Main.h"
|
||||
|
||||
extern CPacketInfo g_item_info;
|
||||
extern int g_iPlayerCacheFlushSeconds;
|
||||
extern int g_iItemCacheFlushSeconds;
|
||||
extern int g_test_server;
|
||||
// MYSHOP_PRICE_LIST
|
||||
extern int g_iItemPriceListTableCacheFlushSeconds;
|
||||
// END_OF_MYSHOP_PRICE_LIST
|
||||
//
|
||||
extern int g_item_count;
|
||||
const int auctionMinFlushSec = 1800;
|
||||
|
||||
CItemCache::CItemCache()
|
||||
{
|
||||
m_expireTime = MIN(1800, g_iItemCacheFlushSeconds);
|
||||
}
|
||||
|
||||
CItemCache::~CItemCache()
|
||||
{
|
||||
}
|
||||
|
||||
// <20>̰<EFBFBD> <20>̻<EFBFBD><CCBB>ѵ<EFBFBD>...
|
||||
// Delete<74><65> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, Cache<68><65> <20><><EFBFBD><EFBFBD><EFBFBD>ؾ<EFBFBD> <20>ϴ°<CFB4> <20>ƴѰ<C6B4>???
|
||||
// <20>ٵ<EFBFBD> Cache<68><65> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20>κ<EFBFBD><CEBA><EFBFBD> <20><><EFBFBD><EFBFBD>.
|
||||
// <20><> ã<><C3A3> <20>ǰ<EFBFBD>?
|
||||
// <20>̷<EFBFBD><CCB7><EFBFBD> <20>س<EFBFBD><D8B3><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD> <20>ð<EFBFBD><C3B0><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>...
|
||||
// <20>̹<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ε<EFBFBD>... Ȯ<>λ<EFBFBD><CEBB><EFBFBD>??????
|
||||
// fixme
|
||||
// by rtsummit
|
||||
void CItemCache::Delete()
|
||||
{
|
||||
if (m_data.vnum == 0)
|
||||
return;
|
||||
|
||||
//char szQuery[QUERY_MAX_LEN];
|
||||
//szQuery[QUERY_MAX_LEN] = '\0';
|
||||
if (g_test_server)
|
||||
sys_log(0, "ItemCache::Delete : DELETE %u", m_data.id);
|
||||
|
||||
m_data.vnum = 0;
|
||||
m_bNeedQuery = true;
|
||||
m_lastUpdateTime = time(0);
|
||||
OnFlush();
|
||||
|
||||
//m_bNeedQuery = false;
|
||||
//m_lastUpdateTime = time(0) - m_expireTime; // <20>ٷ<EFBFBD> Ÿ<>Ӿƿ<D3BE> <20>ǵ<EFBFBD><C7B5><EFBFBD> <20><><EFBFBD><EFBFBD>.
|
||||
}
|
||||
|
||||
void CItemCache::OnFlush()
|
||||
{
|
||||
if (m_data.vnum == 0) // vnum<75><6D> 0<≯<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>϶<EFBFBD><CFB6><EFBFBD> ǥ<>õ<EFBFBD> <20><><EFBFBD>̴<EFBFBD>.
|
||||
{
|
||||
char szQuery[QUERY_MAX_LEN];
|
||||
snprintf(szQuery, sizeof(szQuery), "DELETE FROM item%s WHERE id=%u", GetTablePostfix(), m_data.id);
|
||||
CDBManager::instance().ReturnQuery(szQuery, QID_ITEM_DESTROY, 0, NULL);
|
||||
|
||||
if (g_test_server)
|
||||
sys_log(0, "ItemCache::Flush : DELETE %u %s", m_data.id, szQuery);
|
||||
}
|
||||
else
|
||||
{
|
||||
long alSockets[ITEM_SOCKET_MAX_NUM];
|
||||
TPlayerItemAttribute aAttr[ITEM_ATTRIBUTE_MAX_NUM];
|
||||
bool isSocket = false, isAttr = false;
|
||||
|
||||
memset(&alSockets, 0, sizeof(long) * ITEM_SOCKET_MAX_NUM);
|
||||
memset(&aAttr, 0, sizeof(TPlayerItemAttribute) * ITEM_ATTRIBUTE_MAX_NUM);
|
||||
|
||||
TPlayerItem * p = &m_data;
|
||||
|
||||
if (memcmp(alSockets, p->alSockets, sizeof(long) * ITEM_SOCKET_MAX_NUM))
|
||||
isSocket = true;
|
||||
|
||||
if (memcmp(aAttr, p->aAttr, sizeof(TPlayerItemAttribute) * ITEM_ATTRIBUTE_MAX_NUM))
|
||||
isAttr = true;
|
||||
|
||||
char szColumns[QUERY_MAX_LEN];
|
||||
char szValues[QUERY_MAX_LEN];
|
||||
char szUpdate[QUERY_MAX_LEN];
|
||||
|
||||
int iLen = snprintf(szColumns, sizeof(szColumns), "id, owner_id, window, pos, count, vnum");
|
||||
|
||||
int iValueLen = snprintf(szValues, sizeof(szValues), "%u, %u, %d, %d, %u, %u",
|
||||
p->id, p->owner, p->window, p->pos, p->count, p->vnum);
|
||||
|
||||
int iUpdateLen = snprintf(szUpdate, sizeof(szUpdate), "owner_id=%u, window=%d, pos=%d, count=%u, vnum=%u",
|
||||
p->owner, p->window, p->pos, p->count, p->vnum);
|
||||
|
||||
if (isSocket)
|
||||
{
|
||||
iLen += snprintf(szColumns + iLen, sizeof(szColumns) - iLen, ", socket0, socket1, socket2");
|
||||
iValueLen += snprintf(szValues + iValueLen, sizeof(szValues) - iValueLen,
|
||||
", %lu, %lu, %lu", p->alSockets[0], p->alSockets[1], p->alSockets[2]);
|
||||
iUpdateLen += snprintf(szUpdate + iUpdateLen, sizeof(szUpdate) - iUpdateLen,
|
||||
", socket0=%lu, socket1=%lu, socket2=%lu", p->alSockets[0], p->alSockets[1], p->alSockets[2]);
|
||||
}
|
||||
|
||||
if (isAttr)
|
||||
{
|
||||
iLen += snprintf(szColumns + iLen, sizeof(szColumns) - iLen,
|
||||
", attrtype0, attrvalue0, attrtype1, attrvalue1, attrtype2, attrvalue2, attrtype3, attrvalue3"
|
||||
", attrtype4, attrvalue4, attrtype5, attrvalue5, attrtype6, attrvalue6");
|
||||
|
||||
iValueLen += snprintf(szValues + iValueLen, sizeof(szValues) - iValueLen,
|
||||
", %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d",
|
||||
p->aAttr[0].bType, p->aAttr[0].sValue,
|
||||
p->aAttr[1].bType, p->aAttr[1].sValue,
|
||||
p->aAttr[2].bType, p->aAttr[2].sValue,
|
||||
p->aAttr[3].bType, p->aAttr[3].sValue,
|
||||
p->aAttr[4].bType, p->aAttr[4].sValue,
|
||||
p->aAttr[5].bType, p->aAttr[5].sValue,
|
||||
p->aAttr[6].bType, p->aAttr[6].sValue);
|
||||
|
||||
iUpdateLen += snprintf(szUpdate + iUpdateLen, sizeof(szUpdate) - iUpdateLen,
|
||||
", attrtype0=%d, attrvalue0=%d"
|
||||
", attrtype1=%d, attrvalue1=%d"
|
||||
", attrtype2=%d, attrvalue2=%d"
|
||||
", attrtype3=%d, attrvalue3=%d"
|
||||
", attrtype4=%d, attrvalue4=%d"
|
||||
", attrtype5=%d, attrvalue5=%d"
|
||||
", attrtype6=%d, attrvalue6=%d",
|
||||
p->aAttr[0].bType, p->aAttr[0].sValue,
|
||||
p->aAttr[1].bType, p->aAttr[1].sValue,
|
||||
p->aAttr[2].bType, p->aAttr[2].sValue,
|
||||
p->aAttr[3].bType, p->aAttr[3].sValue,
|
||||
p->aAttr[4].bType, p->aAttr[4].sValue,
|
||||
p->aAttr[5].bType, p->aAttr[5].sValue,
|
||||
p->aAttr[6].bType, p->aAttr[6].sValue);
|
||||
}
|
||||
|
||||
char szItemQuery[QUERY_MAX_LEN + QUERY_MAX_LEN];
|
||||
snprintf(szItemQuery, sizeof(szItemQuery), "REPLACE INTO item%s (%s) VALUES(%s)", GetTablePostfix(), szColumns, szValues);
|
||||
|
||||
if (g_test_server)
|
||||
sys_log(0, "ItemCache::Flush :REPLACE (%s)", szItemQuery);
|
||||
|
||||
CDBManager::instance().ReturnQuery(szItemQuery, QID_ITEM_SAVE, 0, NULL);
|
||||
|
||||
//g_item_info.Add(p->vnum);
|
||||
++g_item_count;
|
||||
}
|
||||
|
||||
m_bNeedQuery = false;
|
||||
}
|
||||
|
||||
//
|
||||
// CPlayerTableCache
|
||||
//
|
||||
CPlayerTableCache::CPlayerTableCache()
|
||||
{
|
||||
m_expireTime = MIN(1800, g_iPlayerCacheFlushSeconds);
|
||||
}
|
||||
|
||||
CPlayerTableCache::~CPlayerTableCache()
|
||||
{
|
||||
}
|
||||
|
||||
void CPlayerTableCache::OnFlush()
|
||||
{
|
||||
if (g_test_server)
|
||||
sys_log(0, "PlayerTableCache::Flush : %s", m_data.name);
|
||||
|
||||
char szQuery[QUERY_MAX_LEN];
|
||||
CreatePlayerSaveQuery(szQuery, sizeof(szQuery), &m_data);
|
||||
CDBManager::instance().ReturnQuery(szQuery, QID_PLAYER_SAVE, 0, NULL);
|
||||
}
|
||||
|
||||
// MYSHOP_PRICE_LIST
|
||||
//
|
||||
// CItemPriceListTableCache class implementation
|
||||
//
|
||||
|
||||
const int CItemPriceListTableCache::s_nMinFlushSec = 1800;
|
||||
|
||||
CItemPriceListTableCache::CItemPriceListTableCache()
|
||||
{
|
||||
m_expireTime = MIN(s_nMinFlushSec, g_iItemPriceListTableCacheFlushSeconds);
|
||||
}
|
||||
|
||||
void CItemPriceListTableCache::UpdateList(const TItemPriceListTable* pUpdateList)
|
||||
{
|
||||
//
|
||||
// <20>̹<EFBFBD> ij<>̵<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>۰<EFBFBD> <20>ߺ<EFBFBD><DFBA><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ã<><C3A3> <20>ߺ<EFBFBD><DFBA><EFBFBD><EFBFBD><EFBFBD> <20>ʴ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> tmpvec <20><> <20>ִ´<D6B4>.
|
||||
//
|
||||
|
||||
std::vector<TItemPriceInfo> tmpvec;
|
||||
|
||||
for (uint idx = 0; idx < m_data.byCount; ++idx)
|
||||
{
|
||||
const TItemPriceInfo* pos = pUpdateList->aPriceInfo;
|
||||
for (; pos != pUpdateList->aPriceInfo + pUpdateList->byCount && m_data.aPriceInfo[idx].dwVnum != pos->dwVnum; ++pos)
|
||||
;
|
||||
|
||||
if (pos == pUpdateList->aPriceInfo + pUpdateList->byCount)
|
||||
tmpvec.push_back(m_data.aPriceInfo[idx]);
|
||||
}
|
||||
|
||||
//
|
||||
// pUpdateList <20><> m_data <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> tmpvec <20><> <20>տ<EFBFBD><D5BF><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ŭ <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
//
|
||||
|
||||
if (pUpdateList->byCount > SHOP_PRICELIST_MAX_NUM)
|
||||
{
|
||||
sys_err("Count overflow!");
|
||||
return;
|
||||
}
|
||||
|
||||
m_data.byCount = pUpdateList->byCount;
|
||||
|
||||
thecore_memcpy(m_data.aPriceInfo, pUpdateList->aPriceInfo, sizeof(TItemPriceInfo) * pUpdateList->byCount);
|
||||
|
||||
int nDeletedNum; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
|
||||
if (pUpdateList->byCount < SHOP_PRICELIST_MAX_NUM)
|
||||
{
|
||||
size_t sizeAddOldDataSize = SHOP_PRICELIST_MAX_NUM - pUpdateList->byCount;
|
||||
|
||||
if (tmpvec.size() < sizeAddOldDataSize)
|
||||
sizeAddOldDataSize = tmpvec.size();
|
||||
|
||||
thecore_memcpy(m_data.aPriceInfo + pUpdateList->byCount, &tmpvec[0], sizeof(TItemPriceInfo) * sizeAddOldDataSize);
|
||||
m_data.byCount += sizeAddOldDataSize;
|
||||
|
||||
nDeletedNum = tmpvec.size() - sizeAddOldDataSize;
|
||||
}
|
||||
else
|
||||
nDeletedNum = tmpvec.size();
|
||||
|
||||
m_bNeedQuery = true;
|
||||
|
||||
sys_log(0,
|
||||
"ItemPriceListTableCache::UpdateList : OwnerID[%u] Update [%u] Items, Delete [%u] Items, Total [%u] Items",
|
||||
m_data.dwOwnerID, pUpdateList->byCount, nDeletedNum, m_data.byCount);
|
||||
}
|
||||
|
||||
void CItemPriceListTableCache::OnFlush()
|
||||
{
|
||||
char szQuery[QUERY_MAX_LEN];
|
||||
|
||||
//
|
||||
// <20><> ij<><C4B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ڿ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> DB <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
//
|
||||
|
||||
snprintf(szQuery, sizeof(szQuery), "DELETE FROM myshop_pricelist%s WHERE owner_id = %u", GetTablePostfix(), m_data.dwOwnerID);
|
||||
CDBManager::instance().ReturnQuery(szQuery, QID_ITEMPRICE_DESTROY, 0, NULL);
|
||||
|
||||
//
|
||||
// ij<><C4B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> DB <20><> <20><><EFBFBD><EFBFBD>.
|
||||
//
|
||||
|
||||
for (int idx = 0; idx < m_data.byCount; ++idx)
|
||||
{
|
||||
snprintf(szQuery, sizeof(szQuery),
|
||||
"INSERT INTO myshop_pricelist%s(owner_id, item_vnum, price) VALUES(%u, %u, %u)",
|
||||
GetTablePostfix(), m_data.dwOwnerID, m_data.aPriceInfo[idx].dwVnum, m_data.aPriceInfo[idx].dwPrice);
|
||||
CDBManager::instance().ReturnQuery(szQuery, QID_ITEMPRICE_SAVE, 0, NULL);
|
||||
}
|
||||
|
||||
sys_log(0, "ItemPriceListTableCache::Flush : OwnerID[%u] Update [%u]Items", m_data.dwOwnerID, m_data.byCount);
|
||||
|
||||
m_bNeedQuery = false;
|
||||
}
|
||||
// END_OF_MYSHOP_PRICE_LIST
|
||||
#ifdef __AUCTION__
|
||||
CAuctionItemInfoCache::CAuctionItemInfoCache()
|
||||
{
|
||||
m_expireTime = MIN (auctionMinFlushSec, g_iItemCacheFlushSeconds);
|
||||
}
|
||||
|
||||
CAuctionItemInfoCache::~CAuctionItemInfoCache()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CAuctionItemInfoCache::Delete()
|
||||
{
|
||||
if (m_data.item_num == 0)
|
||||
return;
|
||||
|
||||
if (g_test_server)
|
||||
sys_log(0, "CAuctionItemInfoCache::Delete : DELETE %u", m_data.item_id);
|
||||
|
||||
m_data.item_num = 0;
|
||||
m_bNeedQuery = true;
|
||||
m_lastUpdateTime = time(0);
|
||||
OnFlush();
|
||||
delete this;
|
||||
}
|
||||
|
||||
void CAuctionItemInfoCache::OnFlush()
|
||||
{
|
||||
char szQuery[QUERY_MAX_LEN];
|
||||
|
||||
if (m_data.item_num == 0)
|
||||
{
|
||||
snprintf(szQuery, sizeof(szQuery), "DELETE FROM auction where item_id = %d", m_data.item_id);
|
||||
CDBManager::instance().AsyncQuery(szQuery);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(szQuery, sizeof(szQuery), "REPLACE INTO auction VALUES (%u, %d, %d, %u, \"%s\", %u, %u, %u, %u)",
|
||||
m_data.item_num, m_data.offer_price, m_data.price, m_data.offer_id, m_data.shown_name, (DWORD)m_data.empire, (DWORD)m_data.expired_time,
|
||||
m_data.item_id, m_data.bidder_id);
|
||||
|
||||
CDBManager::instance().AsyncQuery(szQuery);
|
||||
}
|
||||
}
|
||||
|
||||
CSaleItemInfoCache::CSaleItemInfoCache()
|
||||
{
|
||||
m_expireTime = MIN (auctionMinFlushSec, g_iItemCacheFlushSeconds);
|
||||
}
|
||||
|
||||
CSaleItemInfoCache::~CSaleItemInfoCache()
|
||||
{
|
||||
}
|
||||
|
||||
void CSaleItemInfoCache::Delete()
|
||||
{
|
||||
}
|
||||
|
||||
void CSaleItemInfoCache::OnFlush()
|
||||
{
|
||||
char szQuery[QUERY_MAX_LEN];
|
||||
|
||||
snprintf(szQuery, sizeof(szQuery), "REPLACE INTO sale VALUES (%u, %d, %d, %u, \"%s\", %u, %u, %u, %u)",
|
||||
m_data.item_num, m_data.offer_price, m_data.price, m_data.offer_id, m_data.shown_name, (DWORD)m_data.empire, (DWORD)m_data.expired_time,
|
||||
m_data.item_id, m_data.wisher_id);
|
||||
|
||||
CDBManager::instance().AsyncQuery(szQuery);
|
||||
}
|
||||
|
||||
CWishItemInfoCache::CWishItemInfoCache()
|
||||
{
|
||||
m_expireTime = MIN (auctionMinFlushSec, g_iItemCacheFlushSeconds);
|
||||
}
|
||||
|
||||
CWishItemInfoCache::~CWishItemInfoCache()
|
||||
{
|
||||
}
|
||||
|
||||
void CWishItemInfoCache::Delete()
|
||||
{
|
||||
}
|
||||
|
||||
void CWishItemInfoCache::OnFlush()
|
||||
{
|
||||
char szQuery[QUERY_MAX_LEN];
|
||||
|
||||
snprintf(szQuery, sizeof(szQuery), "REPLACE INTO wish VALUES (%u, %d, %d, %u, \"%s\", %u, %d)",
|
||||
m_data.item_num, m_data.offer_price, m_data.price, m_data.offer_id, m_data.shown_name, (DWORD)m_data.empire, (DWORD)m_data.expired_time);
|
||||
|
||||
CDBManager::instance().AsyncQuery(szQuery);
|
||||
}
|
||||
#endif
|
97
db/src/Cache.h
Normal file
97
db/src/Cache.h
Normal file
@ -0,0 +1,97 @@
|
||||
// vim:ts=8 sw=4
|
||||
#ifndef __INC_DB_CACHE_H__
|
||||
#define __INC_DB_CACHE_H__
|
||||
|
||||
#include "../../common/cache.h"
|
||||
#include "../../common/auction_table.h"
|
||||
|
||||
class CItemCache : public cache<TPlayerItem>
|
||||
{
|
||||
public:
|
||||
CItemCache();
|
||||
virtual ~CItemCache();
|
||||
|
||||
void Delete();
|
||||
virtual void OnFlush();
|
||||
};
|
||||
|
||||
class CPlayerTableCache : public cache<TPlayerTable>
|
||||
{
|
||||
public:
|
||||
CPlayerTableCache();
|
||||
virtual ~CPlayerTableCache();
|
||||
|
||||
virtual void OnFlush();
|
||||
|
||||
DWORD GetLastUpdateTime() { return m_lastUpdateTime; }
|
||||
};
|
||||
|
||||
// MYSHOP_PRICE_LIST
|
||||
/**
|
||||
* @class CItemPriceListTableCache
|
||||
* @brief <09><><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD> ij<><C4B3> class
|
||||
* @version 05/06/10 Bang2ni - First release.
|
||||
*/
|
||||
class CItemPriceListTableCache : public cache< TItemPriceListTable >
|
||||
{
|
||||
public:
|
||||
|
||||
/// Constructor
|
||||
/**
|
||||
* ij<><C4B3> <20><><EFBFBD><EFBFBD> <20>ð<EFBFBD><C3B0><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
*/
|
||||
CItemPriceListTableCache(void);
|
||||
|
||||
/// <20><><EFBFBD><EFBFBD>Ʈ <20><><EFBFBD><EFBFBD>
|
||||
/**
|
||||
* @param [in] pUpdateList <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ
|
||||
*
|
||||
* ij<>õ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD> á<><C3A1> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ij<>̵<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ڿ<EFBFBD><DABF><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
*/
|
||||
void UpdateList(const TItemPriceListTable* pUpdateList);
|
||||
|
||||
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> DB <20><> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
virtual void OnFlush(void);
|
||||
|
||||
private:
|
||||
|
||||
static const int s_nMinFlushSec; ///< Minimum cache expire time
|
||||
};
|
||||
// END_OF_MYSHOP_PRICE_LIST
|
||||
#ifdef __AUCTION__
|
||||
|
||||
class CAuctionItemInfoCache : public cache <TAuctionItemInfo>
|
||||
{
|
||||
public:
|
||||
typedef TWishItemInfo value_type;
|
||||
CAuctionItemInfoCache();
|
||||
virtual ~CAuctionItemInfoCache();
|
||||
|
||||
void Delete();
|
||||
virtual void OnFlush();
|
||||
};
|
||||
|
||||
class CSaleItemInfoCache : public cache <TSaleItemInfo>
|
||||
{
|
||||
public:
|
||||
typedef TWishItemInfo value_type;
|
||||
CSaleItemInfoCache();
|
||||
virtual ~CSaleItemInfoCache();
|
||||
|
||||
void Delete();
|
||||
virtual void OnFlush();
|
||||
};
|
||||
|
||||
class CWishItemInfoCache : public cache <TWishItemInfo>
|
||||
{
|
||||
public:
|
||||
typedef TWishItemInfo value_type;
|
||||
CWishItemInfoCache();
|
||||
virtual ~CWishItemInfoCache();
|
||||
|
||||
void Delete();
|
||||
virtual void OnFlush();
|
||||
};
|
||||
#endif
|
||||
#endif
|
4984
db/src/ClientManager.cpp
Normal file
4984
db/src/ClientManager.cpp
Normal file
File diff suppressed because it is too large
Load Diff
578
db/src/ClientManager.h
Normal file
578
db/src/ClientManager.h
Normal file
@ -0,0 +1,578 @@
|
||||
// vim:ts=8 sw=4
|
||||
#ifndef __INC_CLIENTMANAGER_H__
|
||||
#define __INC_CLIENTMANAGER_H__
|
||||
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include <boost/unordered_set.hpp>
|
||||
|
||||
#include "../../common/stl.h"
|
||||
#include "../../common/building.h"
|
||||
#include "../../common/auction_table.h"
|
||||
|
||||
#include "Peer.h"
|
||||
#include "DBManager.h"
|
||||
#include "LoginData.h"
|
||||
|
||||
class CPlayerTableCache;
|
||||
class CItemCache;
|
||||
class CItemPriceListTableCache;
|
||||
|
||||
class CPacketInfo
|
||||
{
|
||||
public:
|
||||
void Add(int header);
|
||||
void Reset();
|
||||
|
||||
std::map<int, int> m_map_info;
|
||||
};
|
||||
|
||||
size_t CreatePlayerSaveQuery(char * pszQuery, size_t querySize, TPlayerTable * pkTab);
|
||||
|
||||
class CClientManager : public CNetBase, public singleton<CClientManager>
|
||||
{
|
||||
public:
|
||||
typedef std::list<CPeer *> TPeerList;
|
||||
typedef boost::unordered_map<DWORD, CPlayerTableCache *> TPlayerTableCacheMap;
|
||||
typedef boost::unordered_map<DWORD, CItemCache *> TItemCacheMap;
|
||||
typedef boost::unordered_set<CItemCache *, boost::hash<CItemCache*> > TItemCacheSet;
|
||||
typedef boost::unordered_map<DWORD, TItemCacheSet *> TItemCacheSetPtrMap;
|
||||
typedef boost::unordered_map<DWORD, CItemPriceListTableCache*> TItemPriceListCacheMap;
|
||||
typedef boost::unordered_map<short, BYTE> TChannelStatusMap;
|
||||
|
||||
// MYSHOP_PRICE_LIST
|
||||
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ <20><>û <20><><EFBFBD><EFBFBD>
|
||||
/**
|
||||
* first: Peer handle
|
||||
* second: <20><>û<EFBFBD><C3BB> <20>÷<EFBFBD><C3B7>̾<EFBFBD><CCBE><EFBFBD> ID
|
||||
*/
|
||||
typedef std::pair< DWORD, DWORD > TItemPricelistReqInfo;
|
||||
// END_OF_MYSHOP_PRICE_LIST
|
||||
|
||||
class ClientHandleInfo
|
||||
{
|
||||
public:
|
||||
DWORD dwHandle;
|
||||
DWORD account_id;
|
||||
DWORD player_id;
|
||||
BYTE account_index;
|
||||
char login[LOGIN_MAX_LEN + 1];
|
||||
char safebox_password[SAFEBOX_PASSWORD_MAX_LEN + 1];
|
||||
char ip[MAX_HOST_LENGTH + 1];
|
||||
|
||||
TAccountTable * pAccountTable;
|
||||
TSafeboxTable * pSafebox;
|
||||
|
||||
ClientHandleInfo(DWORD argHandle, DWORD dwPID = 0)
|
||||
{
|
||||
dwHandle = argHandle;
|
||||
pSafebox = NULL;
|
||||
pAccountTable = NULL;
|
||||
player_id = dwPID;
|
||||
};
|
||||
//<2F><><EFBFBD>ϼ<EFBFBD><CFBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɿ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
ClientHandleInfo(DWORD argHandle, DWORD dwPID, DWORD accountId)
|
||||
{
|
||||
dwHandle = argHandle;
|
||||
pSafebox = NULL;
|
||||
pAccountTable = NULL;
|
||||
player_id = dwPID;
|
||||
account_id = accountId;
|
||||
};
|
||||
|
||||
~ClientHandleInfo()
|
||||
{
|
||||
if (pSafebox)
|
||||
{
|
||||
delete pSafebox;
|
||||
pSafebox = NULL;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
CClientManager();
|
||||
~CClientManager();
|
||||
|
||||
bool Initialize();
|
||||
time_t GetCurrentTime();
|
||||
|
||||
void MainLoop();
|
||||
void Quit();
|
||||
|
||||
void SetTablePostfix(const char* c_pszTablePostfix);
|
||||
void SetPlayerIDStart(int iIDStart);
|
||||
int GetPlayerIDStart() { return m_iPlayerIDStart; }
|
||||
|
||||
int GetPlayerDeleteLevelLimit() { return m_iPlayerDeleteLevelLimit; }
|
||||
|
||||
void SetChinaEventServer(bool flag) { m_bChinaEventServer = flag; }
|
||||
bool IsChinaEventServer() { return m_bChinaEventServer; }
|
||||
|
||||
DWORD GetUserCount(); // <20><><EFBFBD>ӵ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
|
||||
|
||||
void SendAllGuildSkillRechargePacket();
|
||||
void SendTime();
|
||||
|
||||
CPlayerTableCache * GetPlayerCache(DWORD id);
|
||||
void PutPlayerCache(TPlayerTable * pNew);
|
||||
|
||||
void CreateItemCacheSet(DWORD dwID);
|
||||
TItemCacheSet * GetItemCacheSet(DWORD dwID);
|
||||
void FlushItemCacheSet(DWORD dwID);
|
||||
|
||||
CItemCache * GetItemCache(DWORD id);
|
||||
void PutItemCache(TPlayerItem * pNew, bool bSkipQuery = false);
|
||||
bool DeleteItemCache(DWORD id);
|
||||
|
||||
void UpdatePlayerCache();
|
||||
void UpdateItemCache();
|
||||
|
||||
// MYSHOP_PRICE_LIST
|
||||
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ ij<>ø<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>´<EFBFBD>.
|
||||
/**
|
||||
* @param [in] dwID <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.(<28>÷<EFBFBD><C3B7>̾<EFBFBD> ID)
|
||||
* @return <09><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ ij<><C4B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
*/
|
||||
CItemPriceListTableCache* GetItemPriceListCache(DWORD dwID);
|
||||
|
||||
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ ij<>ø<EFBFBD> <20>ִ´<D6B4>.
|
||||
/**
|
||||
* @param [in] pItemPriceList ij<>ÿ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ
|
||||
*
|
||||
* ij<>ð<EFBFBD> <20>̹<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Update <20><> <20>ƴ<EFBFBD> replace <20>Ѵ<EFBFBD>.
|
||||
*/
|
||||
void PutItemPriceListCache(const TItemPriceListTable* pItemPriceList);
|
||||
|
||||
|
||||
/// Flush <20>ð<EFBFBD><C3B0><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ ij<>ø<EFBFBD> Flush <20><><EFBFBD>ְ<EFBFBD> ij<>ÿ<EFBFBD><C3BF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
void UpdateItemPriceListCache(void);
|
||||
// END_OF_MYSHOP_PRICE_LIST
|
||||
|
||||
|
||||
void SendGuildSkillUsable(DWORD guild_id, DWORD dwSkillVnum, bool bUsable);
|
||||
|
||||
void SetCacheFlushCountLimit(int iLimit);
|
||||
|
||||
template <class Func>
|
||||
Func for_each_peer(Func f);
|
||||
|
||||
CPeer * GetAnyPeer();
|
||||
|
||||
void ForwardPacket(BYTE header, const void* data, int size, BYTE bChannel = 0, CPeer * except = NULL);
|
||||
|
||||
void SendNotice(const char * c_pszFormat, ...);
|
||||
|
||||
char* GetCommand(char* str); //<2F><><EFBFBD>ϼ<EFBFBD><CFBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɿ<EFBFBD><C9BF><EFBFBD> <20><><EFBFBD>ɾ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>Լ<EFBFBD>
|
||||
void ItemAward(CPeer * peer, char* login); //<2F><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
|
||||
protected:
|
||||
void Destroy();
|
||||
|
||||
private:
|
||||
bool InitializeTables();
|
||||
bool InitializeShopTable();
|
||||
bool InitializeMobTable();
|
||||
bool InitializeItemTable();
|
||||
bool InitializeQuestItemTable();
|
||||
bool InitializeSkillTable();
|
||||
bool InitializeRefineTable();
|
||||
bool InitializeBanwordTable();
|
||||
bool InitializeItemAttrTable();
|
||||
bool InitializeItemRareTable();
|
||||
bool InitializeLandTable();
|
||||
bool InitializeObjectProto();
|
||||
bool InitializeObjectTable();
|
||||
bool InitializeMonarch();
|
||||
|
||||
// mob_proto.txt, item_proto.txt<78><74><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> mob_proto, item_proto<74><6F> real db<64><62> <20>ݿ<EFBFBD>.
|
||||
// item_proto, mob_proto<74><6F> db<64><62> <20>ݿ<EFBFBD><DDBF><EFBFBD><EFBFBD><EFBFBD> <20>ʾƵ<CABE>, <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ư<EFBFBD><C6B0>µ<EFBFBD><C2B5><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,
|
||||
// <09><EFBFBD><EEBFB5> <20><EFBFBD><EEBFA1> db<64><62> item_proto, mob_proto<74><6F> <20>о<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD><DFBB>Ѵ<EFBFBD>.
|
||||
bool MirrorMobTableIntoDB();
|
||||
bool MirrorItemTableIntoDB();
|
||||
|
||||
void AddPeer(socket_t fd);
|
||||
void RemovePeer(CPeer * pPeer);
|
||||
CPeer * GetPeer(IDENT ident);
|
||||
|
||||
int AnalyzeQueryResult(SQLMsg * msg);
|
||||
int AnalyzeErrorMsg(CPeer * peer, SQLMsg * msg);
|
||||
|
||||
int Process();
|
||||
|
||||
void ProcessPackets(CPeer * peer);
|
||||
|
||||
CLoginData * GetLoginData(DWORD dwKey);
|
||||
CLoginData * GetLoginDataByLogin(const char * c_pszLogin);
|
||||
CLoginData * GetLoginDataByAID(DWORD dwAID);
|
||||
|
||||
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);
|
||||
|
||||
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_LOGIN(CPeer * peer, DWORD dwHandle, SLoginPacket* data);
|
||||
void QUERY_LOGOUT(CPeer * peer, DWORD dwHandle, const char *);
|
||||
|
||||
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);
|
||||
|
||||
// PLAYER_INDEX_CREATE_BUG_FIX
|
||||
void RESULT_PLAYER_INDEX_CREATE(CPeer *pkPeer, SQLMsg *msg);
|
||||
// END_PLAYER_INDEX_CREATE_BUG_FIX
|
||||
|
||||
// MYSHOP_PRICE_LIST
|
||||
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ε<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> Result ó<><C3B3>
|
||||
/**
|
||||
* @param peer <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>û<EFBFBD><C3BB> Game server <20><> peer <20><>ü <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @param pMsg <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Result <20><> <20><><EFBFBD><EFBFBD> <20><>ü<EFBFBD><C3BC> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
*
|
||||
* <20>ε<EFBFBD><CEB5><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> ij<>ÿ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> peer <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD><EFBFBD>ش<EFBFBD>.
|
||||
*/
|
||||
void RESULT_PRICELIST_LOAD(CPeer* peer, SQLMsg* pMsg);
|
||||
|
||||
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD> <20>ε<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> Result ó<><C3B3>
|
||||
/**
|
||||
* @param pMsg <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Result <20><> <20><><EFBFBD><EFBFBD> <20><>ü<EFBFBD><C3BC> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
*
|
||||
* <20>ε<EFBFBD><CEB5><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ ij<>ø<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ <20>Ѵ<EFBFBD>.
|
||||
*/
|
||||
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_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_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_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 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 QUERY_HIGHSCORE_REGISTER(CPeer * peer, TPacketGDHighscore* data);
|
||||
void RESULT_HIGHSCORE_REGISTER(CPeer * pkPeer, SQLMsg * msg);
|
||||
|
||||
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_RELOAD_PROTO();
|
||||
|
||||
void QUERY_CHANGE_NAME(CPeer * peer, DWORD dwHandle, TPacketGDChangeName * p);
|
||||
void GetPlayerFromRes(TPlayerTable * player_table, MYSQL_RES* res);
|
||||
|
||||
void QUERY_SMS(CPeer * pkPeer, TPacketGDSMS * p);
|
||||
void QUERY_LOGIN_KEY(CPeer * pkPeer, TPacketGDLoginKey * p);
|
||||
|
||||
void AddGuildPriv(TPacketGiveGuildPriv* p);
|
||||
void AddEmpirePriv(TPacketGiveEmpirePriv* p);
|
||||
void AddCharacterPriv(TPacketGiveCharacterPriv* p);
|
||||
|
||||
void MoneyLog(TPacketMoneyLog* 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 ChargeCash(const TRequestChargeCash * p);
|
||||
|
||||
void LoadEventFlag();
|
||||
void SetEventFlag(TPacketSetEventFlag* p);
|
||||
void SendEventFlagsOnSetup(CPeer* peer);
|
||||
|
||||
void BillingExpire(TPacketBillingExpire * p);
|
||||
void BillingCheck(const char * data);
|
||||
|
||||
void SendAllLoginToBilling();
|
||||
void SendLoginToBilling(CLoginData * pkLD, bool bLogin);
|
||||
|
||||
// <20><>ȥ
|
||||
void MarriageAdd(TPacketMarriageAdd * p);
|
||||
void MarriageUpdate(TPacketMarriageUpdate * p);
|
||||
void MarriageRemove(TPacketMarriageRemove * p);
|
||||
|
||||
void WeddingRequest(TPacketWeddingRequest * p);
|
||||
void WeddingReady(TPacketWeddingReady * p);
|
||||
void WeddingEnd(TPacketWeddingEnd * p);
|
||||
|
||||
// MYSHOP_PRICE_LIST
|
||||
// <20><><EFBFBD>λ<EFBFBD><CEBB><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ <20><>Ŷ(HEADER_GD_MYSHOP_PRICELIST_UPDATE) ó<><C3B3><EFBFBD>Լ<EFBFBD>
|
||||
/**
|
||||
* @param [in] pPacket <20><>Ŷ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
*/
|
||||
void MyshopPricelistUpdate(const TPacketMyshopPricelistHeader* pPacket);
|
||||
|
||||
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ <20><>û <20><>Ŷ(HEADER_GD_MYSHOP_PRICELIST_REQ) ó<><C3B3><EFBFBD>Լ<EFBFBD>
|
||||
/**
|
||||
* @param peer <20><>Ŷ<EFBFBD><C5B6> <20><><EFBFBD><EFBFBD> Game server <20><> peer <20><>ü<EFBFBD><C3BC> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @param [in] dwHandle <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>û<EFBFBD><C3BB> peer <20><> <20>ڵ<EFBFBD>
|
||||
* @param [in] dwPlayerID <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20><>û<EFBFBD><C3BB> <20>÷<EFBFBD><C3B7>̾<EFBFBD><CCBE><EFBFBD> ID
|
||||
*/
|
||||
void MyshopPricelistRequest(CPeer* peer, DWORD dwHandle, DWORD dwPlayerID);
|
||||
// END_OF_MYSHOP_PRICE_LIST
|
||||
|
||||
// Building
|
||||
void CreateObject(TPacketGDCreateObject * p);
|
||||
void DeleteObject(DWORD dwID);
|
||||
void UpdateLand(DWORD * pdw);
|
||||
|
||||
// VCard
|
||||
void VCard(TPacketGDVCard * p);
|
||||
void VCardProcess();
|
||||
|
||||
// BLOCK_CHAT
|
||||
void BlockChat(TPacketBlockChat * p);
|
||||
// END_OF_BLOCK_CHAT
|
||||
|
||||
private:
|
||||
int m_looping;
|
||||
socket_t m_fdAccept; // <20><><EFBFBD><EFBFBD> <20><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
TPeerList m_peerList;
|
||||
|
||||
CPeer * m_pkAuthPeer;
|
||||
|
||||
// LoginKey, LoginData pair
|
||||
typedef boost::unordered_map<DWORD, CLoginData *> TLoginDataByLoginKey;
|
||||
TLoginDataByLoginKey m_map_pkLoginData;
|
||||
|
||||
// Login LoginData pair
|
||||
typedef boost::unordered_map<std::string, CLoginData *> TLoginDataByLogin;
|
||||
TLoginDataByLogin m_map_pkLoginDataByLogin;
|
||||
|
||||
// AccountID LoginData pair
|
||||
typedef boost::unordered_map<DWORD, CLoginData *> TLoginDataByAID;
|
||||
TLoginDataByAID m_map_pkLoginDataByAID;
|
||||
|
||||
// Login LoginData pair (<28><><EFBFBD><EFBFBD> <20>α<EFBFBD><CEB1><EFBFBD> <20>Ǿ<EFBFBD><C7BE>ִ<EFBFBD> <20><><EFBFBD><EFBFBD>)
|
||||
typedef boost::unordered_map<std::string, CLoginData *> TLogonAccountMap;
|
||||
TLogonAccountMap m_map_kLogonAccount;
|
||||
|
||||
int m_iPlayerIDStart;
|
||||
int m_iPlayerDeleteLevelLimit;
|
||||
int m_iPlayerDeleteLevelLimitLower;
|
||||
bool m_bChinaEventServer;
|
||||
|
||||
std::vector<TMobTable> m_vec_mobTable;
|
||||
std::vector<TItemTable> m_vec_itemTable;
|
||||
std::map<DWORD, TItemTable *> m_map_itemTableByVnum;
|
||||
|
||||
int m_iShopTableSize;
|
||||
TShopTable * m_pShopTable;
|
||||
|
||||
int m_iRefineTableSize;
|
||||
TRefineTable* m_pRefineTable;
|
||||
|
||||
std::vector<TSkillTable> m_vec_skillTable;
|
||||
std::vector<TBanwordTable> m_vec_banwordTable;
|
||||
std::vector<TItemAttrTable> m_vec_itemAttrTable;
|
||||
std::vector<TItemAttrTable> m_vec_itemRareTable;
|
||||
|
||||
std::vector<building::TLand> m_vec_kLandTable;
|
||||
std::vector<building::TObjectProto> m_vec_kObjectProto;
|
||||
std::map<DWORD, building::TObject *> m_map_pkObjectTable;
|
||||
|
||||
std::queue<TPacketGDVCard> m_queue_vcard;
|
||||
|
||||
bool m_bShutdowned;
|
||||
|
||||
TPlayerTableCacheMap m_map_playerCache; // <20>÷<EFBFBD><C3B7>̾<EFBFBD> id<69><64> key
|
||||
|
||||
TItemCacheMap m_map_itemCache; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> id<69><64> key
|
||||
TItemCacheSetPtrMap m_map_pkItemCacheSetPtr; // <20>÷<EFBFBD><C3B7>̾<EFBFBD> id<69><64> key, <20><> <20>÷<EFBFBD><C3B7>̾ <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ij<><C4B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ֳ<EFBFBD>?
|
||||
|
||||
// MYSHOP_PRICE_LIST
|
||||
/// <20>÷<EFBFBD><C3B7>̾ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ map. key: <20>÷<EFBFBD><C3B7>̾<EFBFBD> ID, value: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ ij<><C4B3>
|
||||
TItemPriceListCacheMap m_mapItemPriceListCache; ///< <20>÷<EFBFBD><C3B7>̾ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ
|
||||
// END_OF_MYSHOP_PRICE_LIST
|
||||
|
||||
TChannelStatusMap m_mChannelStatus;
|
||||
|
||||
struct TPartyInfo
|
||||
{
|
||||
BYTE bRole;
|
||||
BYTE bLevel;
|
||||
|
||||
TPartyInfo() :bRole(0), bLevel(0)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::map<DWORD, TPartyInfo> TPartyMember;
|
||||
typedef std::map<DWORD, TPartyMember> TPartyMap;
|
||||
typedef std::map<BYTE, TPartyMap> TPartyChannelMap;
|
||||
TPartyChannelMap m_map_pkChannelParty;
|
||||
|
||||
typedef std::map<std::string, long> TEventFlagMap;
|
||||
TEventFlagMap m_map_lEventFlag;
|
||||
|
||||
BYTE m_bLastHeader;
|
||||
int m_iCacheFlushCount;
|
||||
int m_iCacheFlushCountLimit;
|
||||
|
||||
private :
|
||||
TItemIDRangeTable m_itemRange;
|
||||
|
||||
public :
|
||||
bool InitializeNowItemID();
|
||||
DWORD GetItemID();
|
||||
DWORD GainItemID();
|
||||
TItemIDRangeTable GetItemRange() { return m_itemRange; }
|
||||
|
||||
//BOOT_LOCALIZATION
|
||||
public:
|
||||
/* <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ʱ<EFBFBD>ȭ
|
||||
**/
|
||||
bool InitializeLocalization();
|
||||
|
||||
private:
|
||||
std::vector<tLocale> m_vec_Locale;
|
||||
//END_BOOT_LOCALIZATION
|
||||
//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);
|
||||
|
||||
struct TLogoutPlayer
|
||||
{
|
||||
DWORD pid;
|
||||
time_t time;
|
||||
|
||||
bool operator < (const TLogoutPlayer & r)
|
||||
{
|
||||
return (pid < r.pid);
|
||||
}
|
||||
};
|
||||
|
||||
typedef boost::unordered_map<DWORD, TLogoutPlayer*> TLogoutPlayerMap;
|
||||
TLogoutPlayerMap m_map_logout;
|
||||
|
||||
void InsertLogoutPlayer(DWORD pid);
|
||||
void DeleteLogoutPlayer(DWORD pid);
|
||||
void UpdateLogoutPlayer();
|
||||
void UpdateItemCacheSet(DWORD pid);
|
||||
|
||||
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);
|
||||
|
||||
|
||||
void DecMonarchMoney(CPeer * peer, DWORD dwHandle, const char * p);
|
||||
//END_MONARCH
|
||||
|
||||
void ChangeMonarchLord(CPeer* peer, DWORD dwHandle, TPacketChangeMonarchLord* info);
|
||||
void BlockException(TPacketBlockException *data);
|
||||
|
||||
void SendSpareItemIDRange(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);
|
||||
#ifdef __AUCTION__
|
||||
void EnrollInAuction (CPeer * peer, DWORD owner_id, AuctionEnrollProductInfo* data);
|
||||
void EnrollInSale (CPeer * peer, DWORD owner_id, AuctionEnrollSaleInfo* data);
|
||||
void EnrollInWish (CPeer * peer, DWORD wisher_id, AuctionEnrollWishInfo* data);
|
||||
void AuctionBid (CPeer * peer, DWORD bidder_id, AuctionBidInfo* data);
|
||||
void AuctionImpur (CPeer * peer, DWORD purchaser_id, AuctionImpurInfo* data);
|
||||
void AuctionGetAuctionedItem (CPeer * peer, DWORD actor_id, DWORD item_id);
|
||||
void AuctionBuySoldItem (CPeer * peer, DWORD actor_id, DWORD item_id);
|
||||
void AuctionCancelAuction (CPeer * peer, DWORD actor_id, DWORD item_id);
|
||||
void AuctionCancelWish (CPeer * peer, DWORD actor_id, DWORD item_num);
|
||||
void AuctionCancelSale (CPeer * peer, DWORD actor_id, DWORD item_id);
|
||||
void AuctionDeleteAuctionItem (CPeer * peer, DWORD actor_id, DWORD item_id);
|
||||
void AuctionDeleteSaleItem (CPeer * peer, DWORD actor_id, DWORD item_id);
|
||||
void AuctionReBid (CPeer * peer, DWORD bidder_id, AuctionBidInfo* data);
|
||||
void AuctionBidCancel (CPeer * peer, DWORD bidder_id, DWORD item_id);
|
||||
#endif
|
||||
};
|
||||
|
||||
template<class Func>
|
||||
Func CClientManager::for_each_peer(Func f)
|
||||
{
|
||||
TPeerList::iterator it;
|
||||
for (it = m_peerList.begin(); it!=m_peerList.end();++it)
|
||||
{
|
||||
f(*it);
|
||||
}
|
||||
return f;
|
||||
}
|
||||
#endif
|
1524
db/src/ClientManagerBoot.cpp
Normal file
1524
db/src/ClientManagerBoot.cpp
Normal file
File diff suppressed because it is too large
Load Diff
77
db/src/ClientManagerEventFlag.cpp
Normal file
77
db/src/ClientManagerEventFlag.cpp
Normal file
@ -0,0 +1,77 @@
|
||||
// vim:ts=4 sw=4
|
||||
#include "stdafx.h"
|
||||
#include "ClientManager.h"
|
||||
#include "Main.h"
|
||||
#include "Config.h"
|
||||
#include "DBManager.h"
|
||||
#include "QID.h"
|
||||
|
||||
void CClientManager::LoadEventFlag()
|
||||
{
|
||||
char szQuery[1024];
|
||||
snprintf(szQuery, sizeof(szQuery), "SELECT szName, lValue FROM quest%s WHERE dwPID = 0", GetTablePostfix());
|
||||
std::auto_ptr<SQLMsg> pmsg(CDBManager::instance().DirectQuery(szQuery));
|
||||
|
||||
SQLResult* pRes = pmsg->Get();
|
||||
if (pRes->uiNumRows)
|
||||
{
|
||||
MYSQL_ROW row;
|
||||
while ((row = mysql_fetch_row(pRes->pSQLResult)))
|
||||
{
|
||||
TPacketSetEventFlag p;
|
||||
strlcpy(p.szFlagName, row[0], sizeof(p.szFlagName));
|
||||
str_to_number(p.lValue, row[1]);
|
||||
sys_log(0, "EventFlag Load %s %d", p.szFlagName, p.lValue);
|
||||
m_map_lEventFlag.insert(std::make_pair(std::string(p.szFlagName), p.lValue));
|
||||
ForwardPacket(HEADER_DG_SET_EVENT_FLAG, &p, sizeof(TPacketSetEventFlag));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CClientManager::SetEventFlag(TPacketSetEventFlag* p)
|
||||
{
|
||||
ForwardPacket(HEADER_DG_SET_EVENT_FLAG, p, sizeof(TPacketSetEventFlag));
|
||||
|
||||
bool bChanged = false;
|
||||
|
||||
typeof(m_map_lEventFlag.begin()) it = m_map_lEventFlag.find(p->szFlagName);
|
||||
if (it == m_map_lEventFlag.end())
|
||||
{
|
||||
bChanged = true;
|
||||
m_map_lEventFlag.insert(std::make_pair(std::string(p->szFlagName), p->lValue));
|
||||
}
|
||||
else if (it->second != p->lValue)
|
||||
{
|
||||
bChanged = true;
|
||||
it->second = p->lValue;
|
||||
}
|
||||
|
||||
if (bChanged)
|
||||
{
|
||||
char szQuery[1024];
|
||||
snprintf(szQuery, sizeof(szQuery),
|
||||
"REPLACE INTO quest%s (dwPID, szName, szState, lValue) VALUES(0, '%s', '', %ld)",
|
||||
GetTablePostfix(), p->szFlagName, p->lValue);
|
||||
szQuery[1023] = '\0';
|
||||
|
||||
//CDBManager::instance().ReturnQuery(szQuery, QID_QUEST_SAVE, 0, NULL);
|
||||
CDBManager::instance().AsyncQuery(szQuery);
|
||||
sys_log(0, "HEADER_GD_SET_EVENT_FLAG : Changed CClientmanager::SetEventFlag(%s %d) ", p->szFlagName, p->lValue);
|
||||
return;
|
||||
}
|
||||
sys_log(0, "HEADER_GD_SET_EVENT_FLAG : No Changed CClientmanager::SetEventFlag(%s %d) ", p->szFlagName, p->lValue);
|
||||
}
|
||||
|
||||
void CClientManager::SendEventFlagsOnSetup(CPeer* peer)
|
||||
{
|
||||
typeof(m_map_lEventFlag.begin()) it;
|
||||
for (it = m_map_lEventFlag.begin(); it != m_map_lEventFlag.end(); ++it)
|
||||
{
|
||||
TPacketSetEventFlag p;
|
||||
strlcpy(p.szFlagName, it->first.c_str(), sizeof(p.szFlagName));
|
||||
p.lValue = it->second;
|
||||
peer->EncodeHeader(HEADER_DG_SET_EVENT_FLAG, 0, sizeof(TPacketSetEventFlag));
|
||||
peer->Encode(&p, sizeof(TPacketSetEventFlag));
|
||||
}
|
||||
}
|
||||
|
244
db/src/ClientManagerGuild.cpp
Normal file
244
db/src/ClientManagerGuild.cpp
Normal file
@ -0,0 +1,244 @@
|
||||
// vim:ts=4 sw=4
|
||||
#include "stdafx.h"
|
||||
#include "ClientManager.h"
|
||||
#include "Main.h"
|
||||
#include "Config.h"
|
||||
#include "DBManager.h"
|
||||
#include "QID.h"
|
||||
#include "GuildManager.h"
|
||||
|
||||
|
||||
void CClientManager::GuildCreate(CPeer * peer, DWORD dwGuildID)
|
||||
{
|
||||
sys_log(0, "GuildCreate %u", dwGuildID);
|
||||
ForwardPacket(HEADER_DG_GUILD_LOAD, &dwGuildID, sizeof(DWORD));
|
||||
|
||||
CGuildManager::instance().Load(dwGuildID);
|
||||
}
|
||||
|
||||
void CClientManager::GuildChangeGrade(CPeer* peer, TPacketGuild* p)
|
||||
{
|
||||
sys_log(0, "GuildChangeGrade %u %u", p->dwGuild, p->dwInfo);
|
||||
ForwardPacket(HEADER_DG_GUILD_CHANGE_GRADE, p, sizeof(TPacketGuild));
|
||||
}
|
||||
|
||||
void CClientManager::GuildAddMember(CPeer* peer, TPacketGDGuildAddMember * p)
|
||||
{
|
||||
CGuildManager::instance().TouchGuild(p->dwGuild);
|
||||
sys_log(0, "GuildAddMember %u %u", p->dwGuild, p->dwPID);
|
||||
|
||||
char szQuery[512];
|
||||
|
||||
snprintf(szQuery, sizeof(szQuery),
|
||||
"INSERT INTO guild_member%s VALUES(%u, %u, %d, 0, 0)",
|
||||
GetTablePostfix(), p->dwPID, p->dwGuild, p->bGrade);
|
||||
|
||||
std::auto_ptr<SQLMsg> pmsg_insert(CDBManager::instance().DirectQuery(szQuery));
|
||||
|
||||
snprintf(szQuery, sizeof(szQuery),
|
||||
"SELECT pid, grade, is_general, offer, level, job, name FROM guild_member%s, player%s WHERE guild_id = %u and pid = id and pid = %u", GetTablePostfix(), GetTablePostfix(), p->dwGuild, p->dwPID);
|
||||
|
||||
std::auto_ptr<SQLMsg> pmsg(CDBManager::instance().DirectQuery(szQuery));
|
||||
|
||||
if (pmsg->Get()->uiNumRows == 0)
|
||||
{
|
||||
sys_err("Query failed when getting guild member data %s", pmsg->stQuery.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
MYSQL_ROW row = mysql_fetch_row(pmsg->Get()->pSQLResult);
|
||||
|
||||
if (!row[0] || !row[1])
|
||||
return;
|
||||
|
||||
TPacketDGGuildMember dg;
|
||||
|
||||
dg.dwGuild = p->dwGuild;
|
||||
str_to_number(dg.dwPID, row[0]);
|
||||
str_to_number(dg.bGrade, row[1]);
|
||||
str_to_number(dg.isGeneral, row[2]);
|
||||
str_to_number(dg.dwOffer, row[3]);
|
||||
str_to_number(dg.bLevel, row[4]);
|
||||
str_to_number(dg.bJob, row[5]);
|
||||
strlcpy(dg.szName, row[6], sizeof(dg.szName));
|
||||
|
||||
ForwardPacket(HEADER_DG_GUILD_ADD_MEMBER, &dg, sizeof(TPacketDGGuildMember));
|
||||
}
|
||||
|
||||
void CClientManager::GuildRemoveMember(CPeer* peer, TPacketGuild* p)
|
||||
{
|
||||
sys_log(0, "GuildRemoveMember %u %u", p->dwGuild, p->dwInfo);
|
||||
|
||||
char szQuery[512];
|
||||
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());
|
||||
CDBManager::instance().AsyncQuery(szQuery);
|
||||
|
||||
ForwardPacket(HEADER_DG_GUILD_REMOVE_MEMBER, p, sizeof(TPacketGuild));
|
||||
}
|
||||
|
||||
void CClientManager::GuildSkillUpdate(CPeer* peer, TPacketGuildSkillUpdate* p)
|
||||
{
|
||||
sys_log(0, "GuildSkillUpdate %d", p->amount);
|
||||
ForwardPacket(HEADER_DG_GUILD_SKILL_UPDATE, p, sizeof(TPacketGuildSkillUpdate));
|
||||
}
|
||||
|
||||
void CClientManager::GuildExpUpdate(CPeer* peer, TPacketGuildExpUpdate* p)
|
||||
{
|
||||
sys_log(0, "GuildExpUpdate %d", p->amount);
|
||||
ForwardPacket(HEADER_DG_GUILD_EXP_UPDATE, p, sizeof(TPacketGuildExpUpdate), 0, peer);
|
||||
}
|
||||
|
||||
void CClientManager::GuildChangeMemberData(CPeer* peer, TPacketGuildChangeMemberData* p)
|
||||
{
|
||||
sys_log(0, "GuildChangeMemberData %u %u %d %d", 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)
|
||||
{
|
||||
sys_log(0, "GuildDisband %u", p->dwGuild);
|
||||
|
||||
char szQuery[512];
|
||||
|
||||
snprintf(szQuery, sizeof(szQuery), "DELETE FROM guild%s WHERE id=%u", GetTablePostfix(), p->dwGuild);
|
||||
CDBManager::instance().AsyncQuery(szQuery);
|
||||
|
||||
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);
|
||||
CDBManager::instance().AsyncQuery(szQuery);
|
||||
|
||||
snprintf(szQuery, sizeof(szQuery), "DELETE FROM guild_member%s WHERE guild_id=%u", GetTablePostfix(), p->dwGuild);
|
||||
CDBManager::instance().AsyncQuery(szQuery);
|
||||
|
||||
snprintf(szQuery, sizeof(szQuery), "DELETE FROM guild_comment%s WHERE guild_id=%u", GetTablePostfix(), p->dwGuild);
|
||||
CDBManager::instance().AsyncQuery(szQuery);
|
||||
|
||||
ForwardPacket(HEADER_DG_GUILD_DISBAND, p, sizeof(TPacketGuild));
|
||||
}
|
||||
|
||||
const char* __GetWarType(int n)
|
||||
{
|
||||
switch (n)
|
||||
{
|
||||
case 0 :
|
||||
return "<EFBFBD>п<EFBFBD>";
|
||||
case 1 :
|
||||
return "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>";
|
||||
case 2 :
|
||||
return "<EFBFBD><EFBFBD>ȣ";
|
||||
default :
|
||||
return "<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ȣ";
|
||||
}
|
||||
}
|
||||
|
||||
void CClientManager::GuildWar(CPeer* peer, TPacketGuildWar* p)
|
||||
{
|
||||
switch (p->bWar)
|
||||
{
|
||||
case GUILD_WAR_SEND_DECLARE:
|
||||
sys_log(0, "GuildWar: GUILD_WAR_SEND_DECLARE type(%s) guild(%d - %d)", __GetWarType(p->bType), p->dwGuildFrom, p->dwGuildTo);
|
||||
CGuildManager::instance().AddDeclare(p->bType, p->dwGuildFrom, p->dwGuildTo);
|
||||
break;
|
||||
|
||||
case GUILD_WAR_REFUSE:
|
||||
sys_log(0, "GuildWar: GUILD_WAR_REFUSE type(%s) guild(%d - %d)", __GetWarType(p->bType), p->dwGuildFrom, p->dwGuildTo);
|
||||
CGuildManager::instance().RemoveDeclare(p->dwGuildFrom, p->dwGuildTo);
|
||||
break;
|
||||
/*
|
||||
case GUILD_WAR_WAIT_START:
|
||||
CGuildManager::instance().RemoveDeclare(p->dwGuildFrom, p->dwGuildTo);
|
||||
|
||||
if (!CGuildManager::instance().WaitStart(p))
|
||||
p->bWar = GUILD_WAR_CANCEL;
|
||||
|
||||
break;
|
||||
*/
|
||||
|
||||
case GUILD_WAR_WAIT_START:
|
||||
sys_log(0, "GuildWar: GUILD_WAR_WAIT_START type(%s) guild(%d - %d)", __GetWarType(p->bType), p->dwGuildFrom, p->dwGuildTo);
|
||||
case GUILD_WAR_RESERVE: // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
if (p->bWar != GUILD_WAR_WAIT_START)
|
||||
sys_log(0, "GuildWar: GUILD_WAR_RESERVE type(%s) guild(%d - %d)", __GetWarType(p->bType), p->dwGuildFrom, p->dwGuildTo);
|
||||
CGuildManager::instance().RemoveDeclare(p->dwGuildFrom, p->dwGuildTo);
|
||||
|
||||
if (!CGuildManager::instance().ReserveWar(p))
|
||||
p->bWar = GUILD_WAR_CANCEL;
|
||||
else
|
||||
p->bWar = GUILD_WAR_RESERVE;
|
||||
|
||||
break;
|
||||
|
||||
case GUILD_WAR_ON_WAR: // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>Ų<EFBFBD><C5B2>. (<28>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD><EFBFBD> <20>ٷ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><>)
|
||||
sys_log(0, "GuildWar: GUILD_WAR_ON_WAR type(%s) guild(%d - %d)", __GetWarType(p->bType), p->dwGuildFrom, p->dwGuildTo);
|
||||
CGuildManager::instance().RemoveDeclare(p->dwGuildFrom, p->dwGuildTo);
|
||||
CGuildManager::instance().StartWar(p->bType, p->dwGuildFrom, p->dwGuildTo);
|
||||
break;
|
||||
|
||||
case GUILD_WAR_OVER: // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
sys_log(0, "GuildWar: GUILD_WAR_OVER type(%s) guild(%d - %d)", __GetWarType(p->bType), p->dwGuildFrom, p->dwGuildTo);
|
||||
CGuildManager::instance().RecvWarOver(p->dwGuildFrom, p->dwGuildTo, p->bType, p->lWarPrice);
|
||||
break;
|
||||
|
||||
case GUILD_WAR_END: // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
sys_log(0, "GuildWar: GUILD_WAR_END type(%s) guild(%d - %d)", __GetWarType(p->bType), p->dwGuildFrom, p->dwGuildTo);
|
||||
CGuildManager::instance().RecvWarEnd(p->dwGuildFrom, p->dwGuildTo);
|
||||
return; // NOTE: RecvWarEnd<6E><64><EFBFBD><EFBFBD> <20><>Ŷ<EFBFBD><C5B6> <20><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ε<EFBFBD>ij<EFBFBD><C4B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ʴ´<CAB4>.
|
||||
|
||||
case GUILD_WAR_CANCEL :
|
||||
sys_log(0, "GuildWar: GUILD_WAR_CANCEL type(%s) guild(%d - %d)", __GetWarType(p->bType), p->dwGuildFrom, p->dwGuildTo);
|
||||
CGuildManager::instance().CancelWar(p->dwGuildFrom, p->dwGuildTo);
|
||||
break;
|
||||
}
|
||||
|
||||
ForwardPacket(HEADER_DG_GUILD_WAR, p, sizeof(TPacketGuildWar));
|
||||
}
|
||||
|
||||
void CClientManager::GuildWarScore(CPeer* peer, TPacketGuildWarScore * p)
|
||||
{
|
||||
CGuildManager::instance().UpdateScore(p->dwGuildGainPoint, p->dwGuildOpponent, p->lScore, p->lBetScore);
|
||||
}
|
||||
|
||||
void CClientManager::GuildChangeLadderPoint(TPacketGuildLadderPoint* p)
|
||||
{
|
||||
sys_log(0, "GuildChangeLadderPoint Recv %u %d", p->dwGuild, p->lChange);
|
||||
CGuildManager::instance().ChangeLadderPoint(p->dwGuild, p->lChange);
|
||||
}
|
||||
|
||||
void CClientManager::GuildUseSkill(TPacketGuildUseSkill* p)
|
||||
{
|
||||
sys_log(0, "GuildUseSkill Recv %u %d", p->dwGuild, p->dwSkillVnum);
|
||||
CGuildManager::instance().UseSkill(p->dwGuild, p->dwSkillVnum, p->dwCooltime);
|
||||
SendGuildSkillUsable(p->dwGuild, p->dwSkillVnum, false);
|
||||
}
|
||||
|
||||
void CClientManager::SendGuildSkillUsable(DWORD guild_id, DWORD dwSkillVnum, bool bUsable)
|
||||
{
|
||||
sys_log(0, "SendGuildSkillUsable Send %u %d %s", guild_id, dwSkillVnum, bUsable?"true":"false");
|
||||
|
||||
TPacketGuildSkillUsableChange p;
|
||||
|
||||
p.dwGuild = guild_id;
|
||||
p.dwSkillVnum = dwSkillVnum;
|
||||
p.bUsable = bUsable;
|
||||
|
||||
ForwardPacket(HEADER_DG_GUILD_SKILL_USABLE_CHANGE, &p, sizeof(TPacketGuildSkillUsableChange));
|
||||
}
|
||||
|
||||
void CClientManager::GuildChangeMaster(TPacketChangeGuildMaster* p)
|
||||
{
|
||||
if (CGuildManager::instance().ChangeMaster(p->dwGuildID, p->idFrom, p->idTo) == true)
|
||||
{
|
||||
TPacketChangeGuildMaster packet;
|
||||
packet.dwGuildID = p->dwGuildID;
|
||||
packet.idFrom = 0;
|
||||
packet.idTo = 0;
|
||||
|
||||
ForwardPacket(HEADER_DG_ACK_CHANGE_GUILD_MASTER, &packet, sizeof(packet));
|
||||
}
|
||||
}
|
||||
|
40
db/src/ClientManagerHorseName.cpp
Normal file
40
db/src/ClientManagerHorseName.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
// vim:ts=4 sw=4
|
||||
#include "stdafx.h"
|
||||
#include "ClientManager.h"
|
||||
|
||||
void CClientManager::UpdateHorseName(TPacketUpdateHorseName* data, CPeer* peer)
|
||||
{
|
||||
char szQuery[512];
|
||||
|
||||
snprintf(szQuery, sizeof(szQuery), "REPLACE INTO horse_name VALUES(%u, '%s')", data->dwPlayerID, data->szHorseName);
|
||||
|
||||
std::auto_ptr<SQLMsg> pmsg_insert(CDBManager::instance().DirectQuery(szQuery));
|
||||
|
||||
ForwardPacket(HEADER_DG_UPDATE_HORSE_NAME, data, sizeof(TPacketUpdateHorseName), 0, peer);
|
||||
}
|
||||
|
||||
void CClientManager::AckHorseName(DWORD dwPID, CPeer* peer)
|
||||
{
|
||||
char szQuery[512];
|
||||
|
||||
snprintf(szQuery, sizeof(szQuery), "SELECT name FROM horse_name WHERE id = %u", dwPID);
|
||||
|
||||
std::auto_ptr<SQLMsg> pmsg(CDBManager::instance().DirectQuery(szQuery));
|
||||
|
||||
TPacketUpdateHorseName packet;
|
||||
packet.dwPlayerID = dwPID;
|
||||
|
||||
if (pmsg->Get()->uiNumRows == 0)
|
||||
{
|
||||
memset(packet.szHorseName, 0, sizeof (packet.szHorseName));
|
||||
}
|
||||
else
|
||||
{
|
||||
MYSQL_ROW row = mysql_fetch_row(pmsg->Get()->pSQLResult);
|
||||
strlcpy(packet.szHorseName, row[0], sizeof(packet.szHorseName));
|
||||
}
|
||||
|
||||
peer->EncodeHeader(HEADER_DG_ACK_HORSE_NAME, 0, sizeof(TPacketUpdateHorseName));
|
||||
peer->Encode(&packet, sizeof(TPacketUpdateHorseName));
|
||||
}
|
||||
|
544
db/src/ClientManagerLogin.cpp
Normal file
544
db/src/ClientManagerLogin.cpp
Normal file
@ -0,0 +1,544 @@
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "ClientManager.h"
|
||||
|
||||
#include "Main.h"
|
||||
#include "Config.h"
|
||||
#include "QID.h"
|
||||
#include "Cache.h"
|
||||
|
||||
extern std::string g_stLocale;
|
||||
extern bool CreatePlayerTableFromRes(MYSQL_RES * res, TPlayerTable * pkTab);
|
||||
extern int g_test_server;
|
||||
extern int g_log;
|
||||
|
||||
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));
|
||||
|
||||
itertype(m_map_kLogonAccount) it = m_map_kLogonAccount.find(szLogin);
|
||||
|
||||
if (m_map_kLogonAccount.end() != it)
|
||||
return false;
|
||||
|
||||
CLoginData * pkLD = GetLoginDataByLogin(c_pszLogin);
|
||||
|
||||
if (!pkLD)
|
||||
return false;
|
||||
|
||||
pkLD->SetConnectedPeerHandle(dwHandle);
|
||||
pkLD->SetIP(c_pszIP);
|
||||
|
||||
m_map_kLogonAccount.insert(TLogonAccountMap::value_type(szLogin, pkLD));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CClientManager::DeleteLogonAccount(const char * c_pszLogin, DWORD dwHandle)
|
||||
{
|
||||
char szLogin[LOGIN_MAX_LEN + 1];
|
||||
trim_and_lower(c_pszLogin, szLogin, sizeof(szLogin));
|
||||
|
||||
itertype(m_map_kLogonAccount) it = m_map_kLogonAccount.find(szLogin);
|
||||
|
||||
if (it == m_map_kLogonAccount.end())
|
||||
return false;
|
||||
|
||||
CLoginData * pkLD = it->second;
|
||||
|
||||
if (pkLD->GetConnectedPeerHandle() != dwHandle)
|
||||
{
|
||||
sys_err("%s tried to logout in other peer handle %lu, current handle %lu", szLogin, dwHandle, pkLD->GetConnectedPeerHandle());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pkLD->IsPlay())
|
||||
{
|
||||
pkLD->SetPlay(false);
|
||||
SendLoginToBilling(pkLD, false);
|
||||
}
|
||||
|
||||
if (pkLD->IsDeleted())
|
||||
{
|
||||
delete pkLD;
|
||||
}
|
||||
|
||||
m_map_kLogonAccount.erase(it);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CClientManager::FindLogonAccount(const char * c_pszLogin)
|
||||
{
|
||||
char szLogin[LOGIN_MAX_LEN + 1];
|
||||
trim_and_lower(c_pszLogin, szLogin, sizeof(szLogin));
|
||||
|
||||
if (m_map_kLogonAccount.end() == m_map_kLogonAccount.find(szLogin))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CClientManager::QUERY_LOGIN_BY_KEY(CPeer * pkPeer, DWORD dwHandle, TPacketGDLoginByKey * p)
|
||||
{
|
||||
#ifdef ENABLE_LIMIT_TIME
|
||||
static int s_updateCount = 0;
|
||||
static int s_curTime = time(0);
|
||||
if (s_updateCount > 100)
|
||||
{
|
||||
s_curTime = time(0);
|
||||
s_updateCount = 0;
|
||||
}
|
||||
++s_updateCount;
|
||||
|
||||
if (s_curTime >= GLOBAL_LIMIT_TIME)
|
||||
{
|
||||
sys_err("Server life time expired.");
|
||||
exit(0);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
CLoginData * pkLoginData = GetLoginData(p->dwLoginKey);
|
||||
char szLogin[LOGIN_MAX_LEN + 1];
|
||||
trim_and_lower(p->szLogin, szLogin, sizeof(szLogin));
|
||||
|
||||
if (!pkLoginData)
|
||||
{
|
||||
sys_log(0, "LOGIN_BY_KEY key not exist %s %lu", szLogin, p->dwLoginKey);
|
||||
pkPeer->EncodeReturn(HEADER_DG_LOGIN_NOT_EXIST, dwHandle);
|
||||
return;
|
||||
}
|
||||
|
||||
TAccountTable & r = pkLoginData->GetAccountRef();
|
||||
|
||||
if (FindLogonAccount(r.login))
|
||||
{
|
||||
sys_log(0, "LOGIN_BY_KEY already login %s %lu", r.login, p->dwLoginKey);
|
||||
TPacketDGLoginAlready ptog;
|
||||
strlcpy(ptog.szLogin, szLogin, sizeof(ptog.szLogin));
|
||||
pkPeer->EncodeHeader(HEADER_DG_LOGIN_ALREADY, dwHandle, sizeof(TPacketDGLoginAlready));
|
||||
pkPeer->Encode(&ptog, sizeof(TPacketDGLoginAlready));
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcasecmp(r.login, szLogin))
|
||||
{
|
||||
sys_log(0, "LOGIN_BY_KEY login differ %s %lu input %s", r.login, p->dwLoginKey, szLogin);
|
||||
pkPeer->EncodeReturn(HEADER_DG_LOGIN_NOT_EXIST, dwHandle);
|
||||
return;
|
||||
}
|
||||
|
||||
if (memcmp(pkLoginData->GetClientKey(), p->adwClientKey, sizeof(DWORD) * 4))
|
||||
{
|
||||
const DWORD * pdwClientKey = pkLoginData->GetClientKey();
|
||||
|
||||
sys_log(0, "LOGIN_BY_KEY client key differ %s %lu %lu %lu %lu, %lu %lu %lu %lu",
|
||||
r.login,
|
||||
p->adwClientKey[0], p->adwClientKey[1], p->adwClientKey[2], p->adwClientKey[3],
|
||||
pdwClientKey[0], pdwClientKey[1], pdwClientKey[2], pdwClientKey[3]);
|
||||
|
||||
pkPeer->EncodeReturn(HEADER_DG_LOGIN_NOT_EXIST, dwHandle);
|
||||
return;
|
||||
}
|
||||
|
||||
TAccountTable * pkTab = new TAccountTable;
|
||||
memset(pkTab, 0, sizeof(TAccountTable));
|
||||
|
||||
pkTab->id = r.id;
|
||||
trim_and_lower(r.login, pkTab->login, sizeof(pkTab->login));
|
||||
strlcpy(pkTab->passwd, r.passwd, sizeof(pkTab->passwd));
|
||||
strlcpy(pkTab->social_id, r.social_id, sizeof(pkTab->social_id));
|
||||
strlcpy(pkTab->status, "OK", sizeof(pkTab->status));
|
||||
|
||||
ClientHandleInfo * info = new ClientHandleInfo(dwHandle);
|
||||
info->pAccountTable = pkTab;
|
||||
strlcpy(info->ip, p->szIP, sizeof(info->ip));
|
||||
|
||||
sys_log(0, "LOGIN_BY_KEY success %s %lu %s", r.login, p->dwLoginKey, info->ip);
|
||||
char szQuery[QUERY_MAX_LEN];
|
||||
snprintf(szQuery, sizeof(szQuery), "SELECT pid1, pid2, pid3, pid4, empire FROM player_index%s WHERE id=%u", GetTablePostfix(), r.id);
|
||||
CDBManager::instance().ReturnQuery(szQuery, QID_LOGIN_BY_KEY, pkPeer->GetHandle(), info);
|
||||
}
|
||||
|
||||
void CClientManager::RESULT_LOGIN_BY_KEY(CPeer * peer, SQLMsg * msg)
|
||||
{
|
||||
CQueryInfo * qi = (CQueryInfo *) msg->pvUserData;
|
||||
ClientHandleInfo * info = (ClientHandleInfo *) qi->pvData;
|
||||
|
||||
if (msg->uiSQLErrno != 0)
|
||||
{
|
||||
peer->EncodeReturn(HEADER_DG_LOGIN_NOT_EXIST, info->dwHandle);
|
||||
delete info;
|
||||
return;
|
||||
}
|
||||
|
||||
char szQuery[QUERY_MAX_LEN];
|
||||
|
||||
if (msg->Get()->uiNumRows == 0)
|
||||
{
|
||||
DWORD account_id = info->pAccountTable->id;
|
||||
char szQuery[QUERY_MAX_LEN];
|
||||
snprintf(szQuery, sizeof(szQuery), "SELECT pid1, pid2, pid3, pid4, empire FROM player_index%s WHERE id=%u", GetTablePostfix(), account_id);
|
||||
std::auto_ptr<SQLMsg> pMsg(CDBManager::instance().DirectQuery(szQuery, SQL_PLAYER));
|
||||
|
||||
sys_log(0, "RESULT_LOGIN_BY_KEY FAIL player_index's NULL : ID:%d", account_id);
|
||||
|
||||
if (pMsg->Get()->uiNumRows == 0)
|
||||
{
|
||||
sys_log(0, "RESULT_LOGIN_BY_KEY FAIL player_index's NULL : ID:%d", 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 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
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
MYSQL_ROW row = mysql_fetch_row(msg->Get()->pSQLResult);
|
||||
|
||||
int col = 0;
|
||||
|
||||
for (; col < PLAYER_PER_ACCOUNT; ++col)
|
||||
str_to_number(info->pAccountTable->players[col].dwID, row[col]);
|
||||
|
||||
str_to_number(info->pAccountTable->bEmpire, row[col++]);
|
||||
info->account_index = 1;
|
||||
|
||||
extern std::string g_stLocale;
|
||||
if (g_stLocale == "gb2312")
|
||||
{
|
||||
snprintf(szQuery, sizeof(szQuery),
|
||||
"SELECT id, name, job, level, alignment, st, ht, dx, iq, part_main, part_hair, x, y, skill_group, change_name FROM player%s WHERE account_id=%u",
|
||||
GetTablePostfix(), info->pAccountTable->id);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(szQuery, sizeof(szQuery),
|
||||
"SELECT id, name, job, level, playtime, st, ht, dx, iq, part_main, part_hair, x, y, skill_group, change_name FROM player%s WHERE account_id=%u",
|
||||
GetTablePostfix(), info->pAccountTable->id);
|
||||
}
|
||||
|
||||
CDBManager::instance().ReturnQuery(szQuery, QID_LOGIN, peer->GetHandle(), info);
|
||||
}
|
||||
|
||||
// PLAYER_INDEX_CREATE_BUG_FIX
|
||||
void CClientManager::RESULT_PLAYER_INDEX_CREATE(CPeer * pkPeer, SQLMsg * msg)
|
||||
{
|
||||
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(),
|
||||
info->pAccountTable->id);
|
||||
CDBManager::instance().ReturnQuery(szQuery, QID_LOGIN_BY_KEY, pkPeer->GetHandle(), info);
|
||||
}
|
||||
// END_PLAYER_INDEX_CREATE_BUG_FIX
|
||||
|
||||
TAccountTable * CreateAccountTableFromRes(MYSQL_RES * res)
|
||||
{
|
||||
char input_pwd[PASSWD_MAX_LEN + 1];
|
||||
MYSQL_ROW row = NULL;
|
||||
DWORD col;
|
||||
|
||||
row = mysql_fetch_row(res);
|
||||
col = 0;
|
||||
|
||||
TAccountTable * pkTab = new TAccountTable;
|
||||
memset(pkTab, 0, sizeof(TAccountTable));
|
||||
|
||||
// ù<><C3B9>° <20>÷<EFBFBD> <20><EFBFBD> <20><><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD> (JOIN QUERY<52><59> <20><><EFBFBD><EFBFBD> <20><> <20><>)
|
||||
strlcpy(input_pwd, row[col++], sizeof(input_pwd));
|
||||
str_to_number(pkTab->id, row[col++]);
|
||||
strlcpy(pkTab->login, row[col++], sizeof(pkTab->login));
|
||||
strlcpy(pkTab->passwd, row[col++], sizeof(pkTab->passwd));
|
||||
strlcpy(pkTab->social_id, row[col++], sizeof(pkTab->social_id));
|
||||
str_to_number(pkTab->bEmpire, row[col++]);
|
||||
|
||||
for (int j = 0; j < PLAYER_PER_ACCOUNT; ++j)
|
||||
str_to_number(pkTab->players[j].dwID, row[col++]);
|
||||
|
||||
strlcpy(pkTab->status, row[col++], sizeof(pkTab->status));
|
||||
|
||||
if (strcmp(pkTab->passwd, input_pwd))
|
||||
{
|
||||
delete pkTab;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pkTab;
|
||||
}
|
||||
|
||||
void CreateAccountPlayerDataFromRes(MYSQL_RES * pRes, TAccountTable * pkTab)
|
||||
{
|
||||
if (!pRes)
|
||||
return;
|
||||
|
||||
for (DWORD i = 0; i < mysql_num_rows(pRes); ++i)
|
||||
{
|
||||
MYSQL_ROW row = mysql_fetch_row(pRes);
|
||||
int col = 0;
|
||||
|
||||
DWORD player_id = 0;
|
||||
!row[col++] ? 0 : str_to_number(player_id, row[col - 1]);
|
||||
|
||||
if (!player_id)
|
||||
continue;
|
||||
|
||||
int j;
|
||||
|
||||
for (j = 0; j < PLAYER_PER_ACCOUNT; ++j)
|
||||
{
|
||||
if (pkTab->players[j].dwID == player_id)
|
||||
{
|
||||
CPlayerTableCache * pc = CClientManager::instance().GetPlayerCache(player_id);
|
||||
TPlayerTable * pt = pc ? pc->Get(false) : NULL;
|
||||
|
||||
if (pt)
|
||||
{
|
||||
strlcpy(pkTab->players[j].szName, pt->name, sizeof(pkTab->players[j].szName));
|
||||
|
||||
pkTab->players[j].byJob = pt->job;
|
||||
pkTab->players[j].byLevel = pt->level;
|
||||
pkTab->players[j].dwPlayMinutes = pt->playtime;
|
||||
pkTab->players[j].byST = pt->st;
|
||||
pkTab->players[j].byHT = pt->ht;
|
||||
pkTab->players[j].byDX = pt->dx;
|
||||
pkTab->players[j].byIQ = pt->iq;
|
||||
pkTab->players[j].wMainPart = pt->parts[PART_MAIN];
|
||||
pkTab->players[j].wHairPart = pt->parts[PART_HAIR];
|
||||
pkTab->players[j].x = pt->x;
|
||||
pkTab->players[j].y = pt->y;
|
||||
pkTab->players[j].skill_group = pt->skill_group;
|
||||
pkTab->players[j].bChangeName = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!row[col++])
|
||||
*pkTab->players[j].szName = '\0';
|
||||
else
|
||||
strlcpy(pkTab->players[j].szName, row[col - 1], sizeof(pkTab->players[j].szName));
|
||||
|
||||
pkTab->players[j].byJob = 0;
|
||||
pkTab->players[j].byLevel = 0;
|
||||
pkTab->players[j].dwPlayMinutes = 0;
|
||||
pkTab->players[j].byST = 0;
|
||||
pkTab->players[j].byHT = 0;
|
||||
pkTab->players[j].byDX = 0;
|
||||
pkTab->players[j].byIQ = 0;
|
||||
pkTab->players[j].wMainPart = 0;
|
||||
pkTab->players[j].wHairPart = 0;
|
||||
pkTab->players[j].x = 0;
|
||||
pkTab->players[j].y = 0;
|
||||
pkTab->players[j].skill_group = 0;
|
||||
pkTab->players[j].bChangeName = 0;
|
||||
|
||||
str_to_number(pkTab->players[j].byJob, row[col++]);
|
||||
str_to_number(pkTab->players[j].byLevel, row[col++]);
|
||||
str_to_number(pkTab->players[j].dwPlayMinutes, row[col++]);
|
||||
str_to_number(pkTab->players[j].byST, row[col++]);
|
||||
str_to_number(pkTab->players[j].byHT, row[col++]);
|
||||
str_to_number(pkTab->players[j].byDX, row[col++]);
|
||||
str_to_number(pkTab->players[j].byIQ, row[col++]);
|
||||
str_to_number(pkTab->players[j].wMainPart, row[col++]);
|
||||
str_to_number(pkTab->players[j].wHairPart, row[col++]);
|
||||
str_to_number(pkTab->players[j].x, row[col++]);
|
||||
str_to_number(pkTab->players[j].y, row[col++]);
|
||||
str_to_number(pkTab->players[j].skill_group, row[col++]);
|
||||
str_to_number(pkTab->players[j].bChangeName, row[col++]);
|
||||
}
|
||||
|
||||
sys_log(0, "%s %lu %lu hair %u",
|
||||
pkTab->players[j].szName, pkTab->players[j].x, pkTab->players[j].y, pkTab->players[j].wHairPart);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
if (j == PLAYER_PER_ACCOUNT)
|
||||
sys_err("cannot find player_id on this account (login: %s id %lu account %lu %lu %lu)",
|
||||
pkTab->login, player_id,
|
||||
pkTab->players[0].dwID,
|
||||
pkTab->players[1].dwID,
|
||||
pkTab->players[2].dwID);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
void CClientManager::RESULT_LOGIN(CPeer * peer, SQLMsg * msg)
|
||||
{
|
||||
CQueryInfo * qi = (CQueryInfo *) msg->pvUserData;
|
||||
ClientHandleInfo * info = (ClientHandleInfo *) qi->pvData;
|
||||
|
||||
if (info->account_index == 0)
|
||||
{
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>?
|
||||
if (msg->Get()->uiNumRows == 0)
|
||||
{
|
||||
sys_log(0, "RESULT_LOGIN: no account");
|
||||
peer->EncodeHeader(HEADER_DG_LOGIN_NOT_EXIST, info->dwHandle, 0);
|
||||
delete info;
|
||||
return;
|
||||
}
|
||||
|
||||
info->pAccountTable = CreateAccountTableFromRes(msg->Get()->pSQLResult);
|
||||
|
||||
if (!info->pAccountTable)
|
||||
{
|
||||
sys_log(0, "RESULT_LOGIN: no account : WRONG_PASSWD");
|
||||
peer->EncodeReturn(HEADER_DG_LOGIN_WRONG_PASSWD, info->dwHandle);
|
||||
delete info;
|
||||
}
|
||||
else
|
||||
{
|
||||
++info->account_index;
|
||||
|
||||
char queryStr[512];
|
||||
extern std::string g_stLocale;
|
||||
if (g_stLocale == "gb2312")
|
||||
{
|
||||
snprintf(queryStr, sizeof(queryStr),
|
||||
"SELECT id, name, job, level, alignment, st, ht, dx, iq, part_main, part_hair, x, y, skill_group, change_name FROM player%s WHERE account_id=%u",
|
||||
GetTablePostfix(), info->pAccountTable->id);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(queryStr, sizeof(queryStr),
|
||||
"SELECT id, name, job, level, playtime, st, ht, dx, iq, part_main, part_hair, x, y, skill_group, change_name FROM player%s WHERE account_id=%u",
|
||||
GetTablePostfix(), info->pAccountTable->id);
|
||||
}
|
||||
|
||||
CDBManager::instance().ReturnQuery(queryStr, QID_LOGIN, peer->GetHandle(), info);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!info->pAccountTable) // <20>̷<EFBFBD><CCB7><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;;
|
||||
{
|
||||
peer->EncodeReturn(HEADER_DG_LOGIN_WRONG_PASSWD, info->dwHandle);
|
||||
delete info;
|
||||
return;
|
||||
}
|
||||
|
||||
// <20>ٸ<EFBFBD> <20><><EFBFBD>ؼ<EFBFBD><D8BC><EFBFBD> <20>̹<EFBFBD> <20>α<EFBFBD><CEB1><EFBFBD> <20>ع<EFBFBD><D8B9>ȴٸ<C8B4>.. <20>̹<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ߴٰ<DFB4> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
|
||||
if (!InsertLogonAccount(info->pAccountTable->login, peer->GetHandle(), info->ip))
|
||||
{
|
||||
sys_log(0, "RESULT_LOGIN: already logon %s", info->pAccountTable->login);
|
||||
|
||||
TPacketDGLoginAlready p;
|
||||
strlcpy(p.szLogin, info->pAccountTable->login, sizeof(p.szLogin));
|
||||
|
||||
peer->EncodeHeader(HEADER_DG_LOGIN_ALREADY, info->dwHandle, sizeof(TPacketDGLoginAlready));
|
||||
peer->Encode(&p, sizeof(p));
|
||||
}
|
||||
else
|
||||
{
|
||||
sys_log(0, "RESULT_LOGIN: login success %s rows: %lu", info->pAccountTable->login, msg->Get()->uiNumRows);
|
||||
|
||||
if (msg->Get()->uiNumRows > 0)
|
||||
CreateAccountPlayerDataFromRes(msg->Get()->pSQLResult, info->pAccountTable);
|
||||
|
||||
//PREVENT_COPY_ITEM
|
||||
CLoginData * p = GetLoginDataByLogin(info->pAccountTable->login);
|
||||
memcpy(&p->GetAccountRef(), info->pAccountTable, sizeof(TAccountTable));
|
||||
|
||||
//END_PREVENT_COPY_ITEM
|
||||
peer->EncodeHeader(HEADER_DG_LOGIN_SUCCESS, info->dwHandle, sizeof(TAccountTable));
|
||||
peer->Encode(info->pAccountTable, sizeof(TAccountTable));
|
||||
|
||||
}
|
||||
|
||||
delete info->pAccountTable;
|
||||
info->pAccountTable = NULL;
|
||||
delete info;
|
||||
}
|
||||
}
|
||||
|
||||
void CClientManager::QUERY_LOGOUT(CPeer * peer, DWORD dwHandle,const char * data)
|
||||
{
|
||||
TLogoutPacket* packet = (TLogoutPacket*)data;
|
||||
|
||||
if (!*packet->login)
|
||||
return;
|
||||
|
||||
CLoginData * pLoginData = GetLoginDataByLogin(packet->login);
|
||||
|
||||
if (pLoginData == NULL)
|
||||
return;
|
||||
|
||||
int pid[PLAYER_PER_ACCOUNT];
|
||||
|
||||
for (int n = 0; n < PLAYER_PER_ACCOUNT; ++n)
|
||||
{
|
||||
if (pLoginData->GetAccountRef().players[n].dwID == 0)
|
||||
{
|
||||
if (g_test_server)
|
||||
sys_log(0, "LOGOUT %s %d", packet->login, pLoginData->GetAccountRef().players[n].dwID);
|
||||
continue;
|
||||
}
|
||||
|
||||
pid[n] = pLoginData->GetAccountRef().players[n].dwID;
|
||||
|
||||
if (g_log)
|
||||
sys_log(0, "LOGOUT InsertLogoutPlayer %s %d", packet->login, pid[n]);
|
||||
|
||||
InsertLogoutPlayer(pid[n]);
|
||||
}
|
||||
|
||||
if (DeleteLogonAccount(packet->login, peer->GetHandle()))
|
||||
{
|
||||
if (g_log)
|
||||
sys_log(0, "LOGOUT %s ", packet->login);
|
||||
}
|
||||
}
|
||||
|
||||
void CClientManager::QUERY_CHANGE_NAME(CPeer * peer, DWORD dwHandle, TPacketGDChangeName * p)
|
||||
{
|
||||
char queryStr[QUERY_MAX_LEN];
|
||||
|
||||
if (g_stLocale == "sjis")
|
||||
snprintf(queryStr, sizeof(queryStr),
|
||||
"SELECT COUNT(*) as count FROM player%s WHERE name='%s' collate sjis_japanese_ci AND id <> %u",
|
||||
GetTablePostfix(), p->name, p->pid);
|
||||
else
|
||||
snprintf(queryStr, sizeof(queryStr),
|
||||
"SELECT COUNT(*) as count FROM player%s WHERE name='%s' AND id <> %u", GetTablePostfix(), p->name, p->pid);
|
||||
|
||||
std::auto_ptr<SQLMsg> pMsg(CDBManager::instance().DirectQuery(queryStr, SQL_PLAYER));
|
||||
|
||||
if (pMsg->Get()->uiNumRows)
|
||||
{
|
||||
if (!pMsg->Get()->pSQLResult)
|
||||
{
|
||||
peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_FAILED, dwHandle, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
|
||||
|
||||
if (*row[0] != '0')
|
||||
{
|
||||
peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_ALREADY, dwHandle, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
peer->EncodeHeader(HEADER_DG_PLAYER_CREATE_FAILED, dwHandle, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
snprintf(queryStr, sizeof(queryStr),
|
||||
"UPDATE player%s SET name='%s',change_name=0 WHERE id=%u", GetTablePostfix(), p->name, p->pid);
|
||||
|
||||
std::auto_ptr<SQLMsg> pMsg0(CDBManager::instance().DirectQuery(queryStr, SQL_PLAYER));
|
||||
|
||||
TPacketDGChangeName pdg;
|
||||
peer->EncodeHeader(HEADER_DG_CHANGE_NAME, dwHandle, sizeof(TPacketDGChangeName));
|
||||
pdg.pid = p->pid;
|
||||
strlcpy(pdg.name, p->name, sizeof(pdg.name));
|
||||
peer->Encode(&pdg, sizeof(TPacketDGChangeName));
|
||||
}
|
||||
|
135
db/src/ClientManagerParty.cpp
Normal file
135
db/src/ClientManagerParty.cpp
Normal file
@ -0,0 +1,135 @@
|
||||
// vim:ts=4 sw=4
|
||||
#include "stdafx.h"
|
||||
#include "ClientManager.h"
|
||||
#include "Config.h"
|
||||
#include "DBManager.h"
|
||||
#include "QID.h"
|
||||
|
||||
void CClientManager::QUERY_PARTY_CREATE(CPeer* peer, TPacketPartyCreate* p)
|
||||
{
|
||||
TPartyMap & pm = m_map_pkChannelParty[peer->GetChannel()];
|
||||
|
||||
if (pm.find(p->dwLeaderPID) == pm.end())
|
||||
{
|
||||
pm.insert(make_pair(p->dwLeaderPID, TPartyMember()));
|
||||
ForwardPacket(HEADER_DG_PARTY_CREATE, p, sizeof(TPacketPartyCreate), peer->GetChannel(), peer);
|
||||
sys_log(0, "PARTY Create [%lu]", p->dwLeaderPID);
|
||||
}
|
||||
else
|
||||
{
|
||||
sys_err("PARTY Create - Already exists [%lu]", p->dwLeaderPID);
|
||||
}
|
||||
}
|
||||
|
||||
void CClientManager::QUERY_PARTY_DELETE(CPeer* peer, TPacketPartyDelete* p)
|
||||
{
|
||||
TPartyMap& pm = m_map_pkChannelParty[peer->GetChannel()];
|
||||
itertype(pm) it = pm.find(p->dwLeaderPID);
|
||||
|
||||
if (it == pm.end())
|
||||
{
|
||||
sys_err("PARTY Delete - Non exists [%lu]", p->dwLeaderPID);
|
||||
return;
|
||||
}
|
||||
|
||||
pm.erase(it);
|
||||
ForwardPacket(HEADER_DG_PARTY_DELETE, p, sizeof(TPacketPartyDelete), peer->GetChannel(), peer);
|
||||
sys_log(0, "PARTY Delete [%lu]", p->dwLeaderPID);
|
||||
}
|
||||
|
||||
void CClientManager::QUERY_PARTY_ADD(CPeer* peer, TPacketPartyAdd* p)
|
||||
{
|
||||
TPartyMap & pm = m_map_pkChannelParty[peer->GetChannel()];
|
||||
itertype(pm) it = pm.find(p->dwLeaderPID);
|
||||
|
||||
if (it == pm.end())
|
||||
{
|
||||
sys_err("PARTY Add - Non exists [%lu]", p->dwLeaderPID);
|
||||
return;
|
||||
}
|
||||
|
||||
if (it->second.find(p->dwPID) == it->second.end())
|
||||
{
|
||||
it->second.insert(std::make_pair(p->dwPID, TPartyInfo()));
|
||||
ForwardPacket(HEADER_DG_PARTY_ADD, p, sizeof(TPacketPartyAdd), peer->GetChannel(), peer);
|
||||
sys_log(0, "PARTY Add [%lu] to [%lu]", p->dwPID, p->dwLeaderPID);
|
||||
}
|
||||
else
|
||||
sys_err("PARTY Add - Already [%lu] in party [%lu]", p->dwPID, p->dwLeaderPID);
|
||||
}
|
||||
|
||||
void CClientManager::QUERY_PARTY_REMOVE(CPeer* peer, TPacketPartyRemove* p)
|
||||
{
|
||||
TPartyMap & pm = m_map_pkChannelParty[peer->GetChannel()];
|
||||
itertype(pm) it = pm.find(p->dwLeaderPID);
|
||||
|
||||
if (it == pm.end())
|
||||
{
|
||||
sys_err("PARTY Remove - Non exists [%lu] cannot remove [%lu]",p->dwLeaderPID, p->dwPID);
|
||||
return;
|
||||
}
|
||||
|
||||
itertype(it->second) pit = it->second.find(p->dwPID);
|
||||
|
||||
if (pit != it->second.end())
|
||||
{
|
||||
it->second.erase(pit);
|
||||
ForwardPacket(HEADER_DG_PARTY_REMOVE, p, sizeof(TPacketPartyRemove), peer->GetChannel(), peer);
|
||||
sys_log(0, "PARTY Remove [%lu] to [%lu]", p->dwPID, p->dwLeaderPID);
|
||||
}
|
||||
else
|
||||
sys_err("PARTY Remove - Cannot find [%lu] in party [%lu]", p->dwPID, p->dwLeaderPID);
|
||||
}
|
||||
|
||||
void CClientManager::QUERY_PARTY_STATE_CHANGE(CPeer* peer, TPacketPartyStateChange* p)
|
||||
{
|
||||
TPartyMap & pm = m_map_pkChannelParty[peer->GetChannel()];
|
||||
itertype(pm) it = pm.find(p->dwLeaderPID);
|
||||
|
||||
if (it == pm.end())
|
||||
{
|
||||
sys_err("PARTY StateChange - Non exists [%lu] cannot state change [%lu]",p->dwLeaderPID, p->dwPID);
|
||||
return;
|
||||
}
|
||||
|
||||
itertype(it->second) pit = it->second.find(p->dwPID);
|
||||
|
||||
if (pit == it->second.end())
|
||||
{
|
||||
sys_err("PARTY StateChange - Cannot find [%lu] in party [%lu]", p->dwPID, p->dwLeaderPID);
|
||||
return;
|
||||
}
|
||||
|
||||
if (p->bFlag)
|
||||
pit->second.bRole = p->bRole;
|
||||
else
|
||||
pit->second.bRole = 0;
|
||||
|
||||
ForwardPacket(HEADER_DG_PARTY_STATE_CHANGE, p, sizeof(TPacketPartyStateChange), peer->GetChannel(), peer);
|
||||
sys_log(0, "PARTY StateChange [%lu] at [%lu] from %d %d",p->dwPID, p->dwLeaderPID, p->bRole, p->bFlag);
|
||||
}
|
||||
|
||||
void CClientManager::QUERY_PARTY_SET_MEMBER_LEVEL(CPeer* peer, TPacketPartySetMemberLevel* p)
|
||||
{
|
||||
TPartyMap & pm = m_map_pkChannelParty[peer->GetChannel()];
|
||||
itertype(pm) it = pm.find(p->dwLeaderPID);
|
||||
|
||||
if (it == pm.end())
|
||||
{
|
||||
sys_err("PARTY SetMemberLevel - Non exists [%lu] cannot level change [%lu]",p->dwLeaderPID, p->dwPID);
|
||||
return;
|
||||
}
|
||||
|
||||
itertype(it->second) pit = it->second.find(p->dwPID);
|
||||
|
||||
if (pit == it->second.end())
|
||||
{
|
||||
sys_err("PARTY SetMemberLevel - Cannot find [%lu] in party [%lu]", p->dwPID, p->dwLeaderPID);
|
||||
return;
|
||||
}
|
||||
|
||||
pit->second.bLevel = p->bLevel;
|
||||
|
||||
ForwardPacket(HEADER_DG_PARTY_SET_MEMBER_LEVEL, p, sizeof(TPacketPartySetMemberLevel), peer->GetChannel());
|
||||
sys_log(0, "PARTY SetMemberLevel pid [%lu] level %d",p->dwPID, p->bLevel);
|
||||
}
|
1357
db/src/ClientManagerPlayer.cpp
Normal file
1357
db/src/ClientManagerPlayer.cpp
Normal file
File diff suppressed because it is too large
Load Diff
250
db/src/Config.cpp
Normal file
250
db/src/Config.cpp
Normal file
@ -0,0 +1,250 @@
|
||||
#include "stdafx.h"
|
||||
#include "Config.h"
|
||||
|
||||
CConfig::CConfig()
|
||||
{
|
||||
}
|
||||
|
||||
CConfig::~CConfig()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
void CConfig::Destroy()
|
||||
{
|
||||
m_valueMap.clear();
|
||||
}
|
||||
|
||||
void CConfig::NextLine(FILE *fp)
|
||||
{
|
||||
int c;
|
||||
|
||||
while ((c = fgetc(fp)) != EOF)
|
||||
{
|
||||
if (c == '\n')
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool CConfig::GetWord(FILE *fp, char *tar)
|
||||
{
|
||||
int i = 0;
|
||||
int c;
|
||||
|
||||
int semicolon_mode = 0;
|
||||
|
||||
while ((c = fgetc(fp)) != EOF)
|
||||
{
|
||||
if (c == 13)
|
||||
continue;
|
||||
|
||||
if (semicolon_mode)
|
||||
{
|
||||
if (c == '"')
|
||||
{
|
||||
tar[i] = '\0';
|
||||
return true;
|
||||
}
|
||||
|
||||
tar[i++] = c;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
if (c == '"')
|
||||
{
|
||||
semicolon_mode = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == ' ' || c == '\t' || c == '\n')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ((c == ' ' || c == '\t' || c == '\n'))
|
||||
{
|
||||
// <20><>.
|
||||
tar[i] = '\0';
|
||||
return true;
|
||||
}
|
||||
|
||||
tar[i] = c;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
return (i != 0);
|
||||
}
|
||||
|
||||
bool CConfig::GetLine(FILE* fp, char*dest)
|
||||
{
|
||||
int c;
|
||||
int i = 0;
|
||||
while ((c = fgetc(fp)) != EOF)
|
||||
{
|
||||
if (c == '\n')
|
||||
return true;
|
||||
dest[i] = c;
|
||||
++i;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CConfig::LoadFile(const char* filename)
|
||||
{
|
||||
char szTmp[256];
|
||||
char comment[256];
|
||||
|
||||
FILE * fp = fopen(filename, "rb");
|
||||
|
||||
if (fp == NULL)
|
||||
return false;
|
||||
|
||||
int mode = 0;
|
||||
|
||||
while (GetWord(fp, szTmp))
|
||||
{
|
||||
if (strcmp(szTmp, "//") == 0)
|
||||
{
|
||||
NextLine(fp);
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case 0:
|
||||
strlcpy(comment, szTmp, sizeof(comment));
|
||||
++mode;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (*szTmp == '=')
|
||||
++mode;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
mode = 0;
|
||||
m_valueMap.insert(TValueMap::value_type(comment, szTmp));
|
||||
break;
|
||||
}
|
||||
|
||||
// ITEM_ID_RANGE
|
||||
if (mode == 2 && strcmp(comment, "ITEM_ID_RANGE") == 0)
|
||||
{
|
||||
GetLine(fp, szTmp);
|
||||
m_valueMap.insert(TValueMap::value_type(comment, szTmp));
|
||||
mode = 0;
|
||||
|
||||
}
|
||||
// ITEM_ID_RANGE_END
|
||||
}
|
||||
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> <20>ݴ<EFBFBD> <20>κ<EFBFBD>.
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string * CConfig::Search(const char* key)
|
||||
{
|
||||
itertype(m_valueMap) i = m_valueMap.find(key);
|
||||
|
||||
if (i == m_valueMap.end())
|
||||
return NULL;
|
||||
else
|
||||
return (&i->second);
|
||||
}
|
||||
|
||||
bool CConfig::GetParam(const char*key, int index, DWORD *Param)
|
||||
{
|
||||
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]);
|
||||
|
||||
str_to_number(*Param, szParam[index]);
|
||||
|
||||
sys_log(0, "GetParam %d", *Param);
|
||||
return true;
|
||||
}
|
||||
const char * CConfig::Get(const char* key)
|
||||
{
|
||||
std::string * pstStr = Search(key);
|
||||
|
||||
if (!pstStr)
|
||||
{
|
||||
static std::string stTemp = "";
|
||||
return stTemp.c_str();
|
||||
}
|
||||
|
||||
return pstStr->c_str();
|
||||
}
|
||||
|
||||
|
||||
bool CConfig::GetValue(const char * key, int* dest)
|
||||
{
|
||||
if (!Search(key))
|
||||
return false;
|
||||
|
||||
str_to_number(*dest, Get(key));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CConfig::GetValue(const char * key, float *dest)
|
||||
{
|
||||
if (!Search(key))
|
||||
return false;
|
||||
|
||||
str_to_number(*dest, Get(key));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CConfig::GetValue(const char * key, DWORD *dest)
|
||||
{
|
||||
if (!Search(key))
|
||||
return false;
|
||||
|
||||
str_to_number(*dest, Get(key));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CConfig::GetValue(const char * key, BYTE *dest)
|
||||
{
|
||||
if (!Search(key))
|
||||
return false;
|
||||
|
||||
*dest = *(BYTE *) Get(key);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CConfig::GetValue(const char * key, char *dest, size_t destSize)
|
||||
{
|
||||
if (!Search(key))
|
||||
return false;
|
||||
|
||||
strlcpy(dest, Get(key), destSize);
|
||||
|
||||
if (!*dest)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CConfig::GetTwoValue(const char* key, DWORD * dest1, DWORD *dest2)
|
||||
{
|
||||
if (!GetParam(key, 0, dest1))
|
||||
return false;
|
||||
|
||||
if (!GetParam(key, 1, dest2))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
34
db/src/Config.h
Normal file
34
db/src/Config.h
Normal file
@ -0,0 +1,34 @@
|
||||
#ifndef __INC_CONFIG_H__
|
||||
#define __INC_CONFIG_H__
|
||||
|
||||
typedef std::map<std::string, std::string> TValueMap;
|
||||
|
||||
class CConfig : public singleton<CConfig>
|
||||
{
|
||||
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);
|
||||
|
||||
private:
|
||||
void Destroy();
|
||||
bool GetParam(const char*key,int index, DWORD *Param);
|
||||
|
||||
const char * Get(const char* key);
|
||||
std::string * Search(const char* key);
|
||||
|
||||
private:
|
||||
TValueMap m_valueMap;
|
||||
};
|
||||
|
||||
#endif
|
430
db/src/CsvReader.cpp
Normal file
430
db/src/CsvReader.cpp
Normal file
@ -0,0 +1,430 @@
|
||||
#include "stdafx.h"
|
||||
#include "CsvReader.h"
|
||||
#include <fstream>
|
||||
#include <algorithm>
|
||||
|
||||
#ifndef Assert
|
||||
#include <assert.h>
|
||||
#define Assert assert
|
||||
#define LogToFile (void)(0);
|
||||
#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
/// <20>Ľ̿<C4BD> state <20><><EFBFBD>Ű<EFBFBD>
|
||||
enum ParseState
|
||||
{
|
||||
STATE_NORMAL = 0, ///< <20>Ϲ<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
STATE_QUOTE ///< <20><><EFBFBD><EFBFBD>ǥ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
};
|
||||
|
||||
/// <20><><EFBFBD>ڿ<EFBFBD> <20>¿<EFBFBD><C2BF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ؼ<EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
|
||||
std::string Trim(std::string str)
|
||||
{
|
||||
str = str.erase(str.find_last_not_of(" \t\r\n") + 1);
|
||||
str = str.erase(0, str.find_first_not_of(" \t\r\n"));
|
||||
return str;
|
||||
}
|
||||
|
||||
/// \brief <20>־<EFBFBD><D6BE><EFBFBD> <20><><EFBFBD>忡 <20>ִ<EFBFBD> <20><><EFBFBD>ĺ<EFBFBD><C4BA><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ҹ<EFBFBD><D2B9>ڷ<EFBFBD> <20>ٲ۴<D9B2>.
|
||||
std::string Lower(std::string original)
|
||||
{
|
||||
std::transform(original.begin(), original.end(), original.begin(), tolower);
|
||||
return original;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \brief <20><><EFBFBD><EFBFBD> <20><EFBFBD><D7BC><EFBFBD><EFBFBD><EFBFBD> <20><>, <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20≯<EFBFBD><CCB8><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
/// \param name <20><> <20≯<EFBFBD>
|
||||
/// \param index <20><> <20>ε<EFBFBD><CEB5><EFBFBD>
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void cCsvAlias::AddAlias(const char* name, size_t index)
|
||||
{
|
||||
std::string converted(Lower(name));
|
||||
|
||||
Assert(m_Name2Index.find(converted) == m_Name2Index.end());
|
||||
Assert(m_Index2Name.find(index) == m_Index2Name.end());
|
||||
|
||||
m_Name2Index.insert(NAME2INDEX_MAP::value_type(converted, index));
|
||||
m_Index2Name.insert(INDEX2NAME_MAP::value_type(index, name));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \brief <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void cCsvAlias::Destroy()
|
||||
{
|
||||
m_Name2Index.clear();
|
||||
m_Index2Name.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \brief <20><><EFBFBD><EFBFBD> <20>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD> <20≯<EFBFBD><CCB8><EFBFBD><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
|
||||
/// \param index <20><><EFBFBD><EFBFBD> <20>ε<EFBFBD><CEB5><EFBFBD>
|
||||
/// \return const char* <20≯<EFBFBD>
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
const char* cCsvAlias::operator [] (size_t index) const
|
||||
{
|
||||
INDEX2NAME_MAP::const_iterator itr(m_Index2Name.find(index));
|
||||
if (itr == m_Index2Name.end())
|
||||
{
|
||||
LogToFile(NULL, "cannot find suitable conversion for %d", index);
|
||||
Assert(false && "cannot find suitable conversion");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return itr->second.c_str();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \brief <20≯<EFBFBD><CCB8><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
|
||||
/// \param name <20≯<EFBFBD>
|
||||
/// \return size_t <20><><EFBFBD><EFBFBD> <20>ε<EFBFBD><CEB5><EFBFBD>
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
size_t cCsvAlias::operator [] (const char* name) const
|
||||
{
|
||||
NAME2INDEX_MAP::const_iterator itr(m_Name2Index.find(Lower(name)));
|
||||
if (itr == m_Name2Index.end())
|
||||
{
|
||||
LogToFile(NULL, "cannot find suitable conversion for %s", name);
|
||||
Assert(false && "cannot find suitable conversion");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return itr->second;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \brief <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20≯<EFBFBD><CCB8><EFBFBD> CSV <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ε<EFBFBD><CEB5>Ѵ<EFBFBD>.
|
||||
/// \param fileName CSV <20><><EFBFBD><EFBFBD> <20≯<EFBFBD>
|
||||
/// \param seperator <20>ʵ<EFBFBD> <20>и<EFBFBD><D0B8>ڷ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>. <20>⺻<EFBFBD><E2BABB><EFBFBD><EFBFBD> ','<27>̴<EFBFBD>.
|
||||
/// \param quote <20><><EFBFBD><EFBFBD>ǥ<EFBFBD><C7A5> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>. <20>⺻<EFBFBD><E2BABB><EFBFBD><EFBFBD> '"'<27>̴<EFBFBD>.
|
||||
/// \return bool <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ε<EFBFBD><CEB5>ߴٸ<DFB4> true, <20>ƴ϶<C6B4><CFB6><EFBFBD> false
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
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;
|
||||
|
||||
Destroy(); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
|
||||
cCsvRow* row = NULL;
|
||||
ParseState state = STATE_NORMAL;
|
||||
std::string token = "";
|
||||
char buf[2048+1] = {0,};
|
||||
|
||||
while (file.good())
|
||||
{
|
||||
file.getline(buf, 2048);
|
||||
buf[sizeof(buf)-1] = 0;
|
||||
|
||||
std::string line(Trim(buf));
|
||||
if (line.empty() || (state == STATE_NORMAL && line[0] == '#')) continue;
|
||||
|
||||
std::string text = std::string(line) + " "; // <20>Ľ<EFBFBD> lookahead <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ٿ<EFBFBD><D9BF>ش<EFBFBD>.
|
||||
size_t cur = 0;
|
||||
|
||||
while (cur < text.size())
|
||||
{
|
||||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD>尡 QUOTE <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>,
|
||||
if (state == STATE_QUOTE)
|
||||
{
|
||||
// '"' <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>̴<EFBFBD>.
|
||||
// 1. <20><> <20><><EFBFBD>ο<EFBFBD> Ư<><C6AF> <20><><EFBFBD>ڰ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20≯<EFBFBD> <20>˸<EFBFBD><CBB8><EFBFBD> <20><> <20>¿<EFBFBD><C2BF><EFBFBD> <20><>
|
||||
// 2. <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> '"' <20><><EFBFBD>ڰ<EFBFBD> '"' 2<><32><EFBFBD><EFBFBD> ġȯ<C4A1><C8AF> <20><>
|
||||
// <20><> <20><> ù<><C3B9>° <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ִ<EFBFBD> <20><><EFBFBD><EFBFBD> CSV <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̶<EFBFBD><CCB6><EFBFBD>,
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> STATE_NORMAL<41><4C> <20>ɸ<EFBFBD><C9B8><EFBFBD> <20>Ǿ<EFBFBD><C7BE>ִ<EFBFBD>.
|
||||
// <20><EFBFBD><D7B7>Ƿ<EFBFBD> <20><><EFBFBD>⼭ <20>ɸ<EFBFBD><C9B8><EFBFBD> <20><><EFBFBD><EFBFBD> 1<><31><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>쳪, 2<><32> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>̴<EFBFBD>.
|
||||
// 2<><32><EFBFBD><EFBFBD> <20><><EFBFBD>쿡<EFBFBD><ECBFA1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> '"' <20><><EFBFBD>ڰ<EFBFBD> 2<><32><EFBFBD><EFBFBD> <20><>Ÿ<EFBFBD><C5B8><EFBFBD><EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1<><31><EFBFBD><EFBFBD>
|
||||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD>쿡<EFBFBD><ECBFA1> <20>ƴϴ<C6B4>. <20≯<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ؼ<EFBFBD> <20>ڵ带 ¥<><C2A5>...
|
||||
if (text[cur] == quote)
|
||||
{
|
||||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ڰ<EFBFBD> '"' <20><><EFBFBD>ڶ<EFBFBD><DAB6><EFBFBD>, <20><> <20><><EFBFBD>ӵ<EFBFBD> '"' <20><><EFBFBD>ڶ<EFBFBD><DAB6><EFBFBD>
|
||||
// <20>̴<EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> '"' <20><><EFBFBD>ڰ<EFBFBD> ġȯ<C4A1><C8AF> <20><><EFBFBD>̴<EFBFBD>.
|
||||
if (text[cur+1] == quote)
|
||||
{
|
||||
token += quote;
|
||||
++cur;
|
||||
}
|
||||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ڰ<EFBFBD> '"' <20><><EFBFBD>ڰ<EFBFBD> <20>ƴ϶<C6B4><CFB6><EFBFBD>
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> '"'<27><><EFBFBD>ڴ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>˸<EFBFBD><CBB8><EFBFBD> <20><><EFBFBD>ڶ<EFBFBD><DAB6><EFBFBD> <20><> <20><> <20>ִ<EFBFBD>.
|
||||
else
|
||||
{
|
||||
state = STATE_NORMAL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
token += text[cur];
|
||||
}
|
||||
}
|
||||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD>尡 NORMAL <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>,
|
||||
else if (state == STATE_NORMAL)
|
||||
{
|
||||
if (row == NULL)
|
||||
row = new cCsvRow();
|
||||
|
||||
// ',' <20><><EFBFBD>ڸ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ٸ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ǹ<EFBFBD><C7B9>Ѵ<EFBFBD>.
|
||||
// <20><>ū<EFBFBD><C5AB><EFBFBD>μ<EFBFBD> <20><> <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE><EFBFBD>ٰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ְ<EFBFBD>, <20><>ū<EFBFBD><C5AB> <20>ʱ<EFBFBD>ȭ<EFBFBD>Ѵ<EFBFBD>.
|
||||
if (text[cur] == seperator)
|
||||
{
|
||||
row->push_back(token);
|
||||
token.clear();
|
||||
}
|
||||
// '"' <20><><EFBFBD>ڸ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ٸ<EFBFBD>, QUOTE <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
|
||||
else if (text[cur] == quote)
|
||||
{
|
||||
state = STATE_QUOTE;
|
||||
}
|
||||
// <20>ٸ<EFBFBD> <20>Ϲ<EFBFBD> <20><><EFBFBD>ڶ<EFBFBD><DAB6><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ū<EFBFBD><C5AB><EFBFBD>ٰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>δ<EFBFBD>.
|
||||
else
|
||||
{
|
||||
token += text[cur];
|
||||
}
|
||||
}
|
||||
|
||||
++cur;
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ',' <20><><EFBFBD>ڰ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>⼭ <20>߰<EFBFBD><DFB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
// <20><>, ó<><C3B3><EFBFBD><EFBFBD> <20>Ľ<EFBFBD> lookahead <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>̽<EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
|
||||
if (state == STATE_NORMAL)
|
||||
{
|
||||
Assert(row != NULL);
|
||||
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";
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \brief <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ִ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> CSV <20><><EFBFBD>Ͽ<EFBFBD><CFBF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
/// \param fileName CSV <20><><EFBFBD><EFBFBD> <20≯<EFBFBD>
|
||||
/// \param append true<75><65> <20><><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>Ͽ<EFBFBD><CFBF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>δ<EFBFBD>. false<73><65> <20><><EFBFBD>쿡<EFBFBD><ECBFA1>
|
||||
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD>, <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
|
||||
/// \param seperator <20>ʵ<EFBFBD> <20>и<EFBFBD><D0B8>ڷ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>. <20>⺻<EFBFBD><E2BABB><EFBFBD><EFBFBD> ','<27>̴<EFBFBD>.
|
||||
/// \param quote <20><><EFBFBD><EFBFBD>ǥ<EFBFBD><C7A5> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>. <20>⺻<EFBFBD><E2BABB><EFBFBD><EFBFBD> '"'<27>̴<EFBFBD>.
|
||||
/// \return bool <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ߴٸ<DFB4> true, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>쿡<EFBFBD><ECBFA1> false
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool cCsvFile::Save(const char* fileName, bool append, char seperator, char quote) const
|
||||
{
|
||||
Assert(seperator != quote);
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD>忡 <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>÷<EFBFBD><C3B7><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
std::ofstream file;
|
||||
if (append) { file.open(fileName, std::ios::out | std::ios::app); }
|
||||
else { file.open(fileName, std::ios::out | std::ios::trunc); }
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ߴٸ<DFB4>, false<73><65> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
if (!file) return false;
|
||||
|
||||
char special_chars[5] = { seperator, quote, '\r', '\n', 0 };
|
||||
char quote_escape_string[3] = { quote, quote, 0 };
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> Ⱦ<><C8BE><EFBFBD>ϸ鼭...
|
||||
for (size_t i=0; i<m_Rows.size(); i++)
|
||||
{
|
||||
const cCsvRow& row = *((*this)[i]);
|
||||
|
||||
std::string line;
|
||||
|
||||
// <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ū<EFBFBD><C5AB> Ⱦ<><C8BE><EFBFBD>ϸ鼭...
|
||||
for (size_t j=0; j<row.size(); j++)
|
||||
{
|
||||
const std::string& token = row[j];
|
||||
|
||||
// <20>Ϲ<EFBFBD><CFB9><EFBFBD><EFBFBD><EFBFBD>('"' <20>Ǵ<EFBFBD> ','<27><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>)
|
||||
// <20><>ū<EFBFBD>̶<EFBFBD><CCB6><EFBFBD> <20>׳<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϸ<EFBFBD> <20>ȴ<EFBFBD>.
|
||||
if (token.find_first_of(special_chars) == std::string::npos)
|
||||
{
|
||||
line += token;
|
||||
}
|
||||
// Ư<><C6AF><EFBFBD><EFBFBD><EFBFBD>ڸ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ū<EFBFBD>̶<EFBFBD><CCB6><EFBFBD> <20><><EFBFBD>ڿ<EFBFBD> <20>¿쿡 '"'<27><> <20>ٿ<EFBFBD><D9BF>ְ<EFBFBD>,
|
||||
// <20><><EFBFBD>ڿ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> '"'<27><> <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
else
|
||||
{
|
||||
line += quote;
|
||||
|
||||
for (size_t k=0; k<token.size(); k++)
|
||||
{
|
||||
if (token[k] == quote) line += quote_escape_string;
|
||||
else line += token[k];
|
||||
}
|
||||
|
||||
line += quote;
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ƴ϶<C6B4><CFB6><EFBFBD> ','<27><> <20><>ū<EFBFBD><C5AB> <20>ڿ<EFBFBD><DABF><EFBFBD> <20>ٿ<EFBFBD><D9BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
if (j != row.size() - 1) { line += seperator; }
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
file << line << std::endl;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \brief <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><DEB8><F0B8AEBF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void cCsvFile::Destroy()
|
||||
{
|
||||
for (ROWS::iterator itr(m_Rows.begin()); itr != m_Rows.end(); ++itr)
|
||||
delete *itr;
|
||||
|
||||
m_Rows.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \brief <20>ش<EFBFBD><D8B4>ϴ<EFBFBD> <20>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
|
||||
/// \param index <20>ε<EFBFBD><CEB5><EFBFBD>
|
||||
/// \return cCsvRow* <20>ش<EFBFBD> <20><>
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
cCsvRow* cCsvFile::operator [] (size_t index)
|
||||
{
|
||||
Assert(index < m_Rows.size());
|
||||
return m_Rows[index];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \brief <20>ش<EFBFBD><D8B4>ϴ<EFBFBD> <20>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
|
||||
/// \param index <20>ε<EFBFBD><CEB5><EFBFBD>
|
||||
/// \return const cCsvRow* <20>ش<EFBFBD> <20><>
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
const cCsvRow* cCsvFile::operator [] (size_t index) const
|
||||
{
|
||||
Assert(index < m_Rows.size());
|
||||
return m_Rows[index];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \brief <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
cCsvTable::cCsvTable()
|
||||
: m_CurRow(-1)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \brief <20>Ҹ<EFBFBD><D2B8><EFBFBD>
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
cCsvTable::~cCsvTable()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \brief <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20≯<EFBFBD><CCB8><EFBFBD> CSV <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ε<EFBFBD><CEB5>Ѵ<EFBFBD>.
|
||||
/// \param fileName CSV <20><><EFBFBD><EFBFBD> <20≯<EFBFBD>
|
||||
/// \param seperator <20>ʵ<EFBFBD> <20>и<EFBFBD><D0B8>ڷ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>. <20>⺻<EFBFBD><E2BABB><EFBFBD><EFBFBD> ','<27>̴<EFBFBD>.
|
||||
/// \param quote <20><><EFBFBD><EFBFBD>ǥ<EFBFBD><C7A5> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>. <20>⺻<EFBFBD><E2BABB><EFBFBD><EFBFBD> '"'<27>̴<EFBFBD>.
|
||||
/// \return bool <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ε<EFBFBD><CEB5>ߴٸ<DFB4> true, <20>ƴ϶<C6B4><CFB6><EFBFBD> false
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool cCsvTable::Load(const char* fileName, const char seperator, const char quote)
|
||||
{
|
||||
Destroy();
|
||||
return m_File.Load(fileName, seperator, quote);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \brief <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ѿ<D1BE><EEB0A3>.
|
||||
/// \return bool <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ѿ <20><><EFBFBD><EFBFBD> true<75><65> <20><>ȯ<EFBFBD>ϰ<EFBFBD>, <20><> <20>̻<EFBFBD>
|
||||
/// <20>Ѿ <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʴ<EFBFBD> <20><><EFBFBD>쿡<EFBFBD><ECBFA1> false<73><65> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool cCsvTable::Next()
|
||||
{
|
||||
// 20<32><30><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ȣ<><C8A3><EFBFBD>ϸ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>÷ΰ<C3B7> <20>Ͼ<CFBE>ٵ<EFBFBD>...<2E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
|
||||
return ++m_CurRow < (int)m_File.GetRowCount() ? true : false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \brief <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD>ڸ<EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
|
||||
/// \return size_t <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD>
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
size_t cCsvTable::ColCount() const
|
||||
{
|
||||
return CurRow()->size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \brief <20>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD> <20>̿<EFBFBD><CCBF><EFBFBD> int <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
|
||||
/// \param index <20><> <20>ε<EFBFBD><CEB5><EFBFBD>
|
||||
/// \return int <20><> <20><>
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int cCsvTable::AsInt(size_t index) const
|
||||
{
|
||||
const cCsvRow* const row = CurRow();
|
||||
Assert(row);
|
||||
Assert(index < row->size());
|
||||
return row->AsInt(index);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \brief <20>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD> <20>̿<EFBFBD><CCBF><EFBFBD> double <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
|
||||
/// \param index <20><> <20>ε<EFBFBD><CEB5><EFBFBD>
|
||||
/// \return double <20><> <20><>
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
double cCsvTable::AsDouble(size_t index) const
|
||||
{
|
||||
const cCsvRow* const row = CurRow();
|
||||
Assert(row);
|
||||
Assert(index < row->size());
|
||||
return row->AsDouble(index);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \brief <20>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD> <20>̿<EFBFBD><CCBF><EFBFBD> std::string <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
|
||||
/// \param index <20><> <20>ε<EFBFBD><CEB5><EFBFBD>
|
||||
/// \return const char* <20><> <20><>
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
const char* cCsvTable::AsStringByIndex(size_t index) const
|
||||
{
|
||||
const cCsvRow* const row = CurRow();
|
||||
Assert(row);
|
||||
Assert(index < row->size());
|
||||
return row->AsString(index);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \brief alias<61><73> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void cCsvTable::Destroy()
|
||||
{
|
||||
m_File.Destroy();
|
||||
m_Alias.Destroy();
|
||||
m_CurRow = -1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \brief <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
|
||||
/// \return const cCsvRow* <20><EFBFBD><D7BC><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20><><EFBFBD>쿡<EFBFBD><ECBFA1> <20><> <20><><EFBFBD><EFBFBD>
|
||||
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD>ϰ<EFBFBD>, <20><> <20>̻<EFBFBD> <20><EFBFBD><D7BC><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>쿡<EFBFBD><ECBFA1> NULL<4C><4C>
|
||||
/// <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
const cCsvRow* const cCsvTable::CurRow() const
|
||||
{
|
||||
if (m_CurRow < 0)
|
||||
{
|
||||
Assert(false && "call Next() first!");
|
||||
return NULL;
|
||||
}
|
||||
else if (m_CurRow >= (int)m_File.GetRowCount())
|
||||
{
|
||||
Assert(false && "no more rows!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return m_File[m_CurRow];
|
||||
}
|
||||
|
322
db/src/CsvReader.h
Normal file
322
db/src/CsvReader.h
Normal file
@ -0,0 +1,322 @@
|
||||
#ifndef __CSVFILE_H__
|
||||
#define __CSVFILE_H__
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#if _MSC_VER
|
||||
#include <hash_map>
|
||||
#else
|
||||
#include <map>
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \class cCsvAlias
|
||||
/// \brief CSV <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><EFBFBD><DFBB>ϴ<EFBFBD> <20>ε<EFBFBD><CEB5><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>̱<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
/// <20><><EFBFBD><EFBFBD> <20><>ü.
|
||||
///
|
||||
/// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> 0<><30> <20>÷<EFBFBD><C3B7><EFBFBD> A<><41> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD>, 1<><31> <20>÷<EFBFBD><C3B7><EFBFBD> B<><42> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
/// <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> <20>־<EFBFBD><D6BE>µ<EFBFBD>...
|
||||
///
|
||||
/// <pre>
|
||||
/// int a = row.AsInt(0);
|
||||
/// int b = row.AsInt(1);
|
||||
/// </pre>
|
||||
///
|
||||
/// <20><> <20><><EFBFBD>̿<EFBFBD> C<><43> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20>÷<EFBFBD><C3B7><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>, <20>ϵ<EFBFBD><CFB5>ڵ<EFBFBD><DAB5>Ǿ<EFBFBD> <20>ִ<EFBFBD>
|
||||
/// 1<><31><EFBFBD><EFBFBD> ã<>Ƽ<EFBFBD> <20><><EFBFBD>ľ<EFBFBD> <20>ϴµ<CFB4>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD><DFBB>ϱ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>۾<EFBFBD><DBBE>̴<EFBFBD>.
|
||||
///
|
||||
/// <pre>
|
||||
/// int a = row.AsInt(0);
|
||||
/// int c = row.AsInt(1);
|
||||
/// int b = row.AsInt(2); <-- <20><> <20>κ<EFBFBD><CEBA><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ű<EFBFBD><C5B0><EFBFBD><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
|
||||
/// </pre>
|
||||
///
|
||||
/// <20><> <20>κ<EFBFBD><CEBA><EFBFBD> <20><><EFBFBD>ڿ<EFBFBD><DABF><EFBFBD> ó<><C3B3><EFBFBD>ϸ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EEB0A1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ణ<EFBFBD>̳<EFBFBD><CCB3><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>
|
||||
/// <20>ִ<EFBFBD>.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class cCsvAlias
|
||||
{
|
||||
private:
|
||||
#if _MSC_VER
|
||||
typedef stdext::hash_map<std::string, size_t> NAME2INDEX_MAP;
|
||||
typedef stdext::hash_map<size_t, std::string> INDEX2NAME_MAP;
|
||||
#else
|
||||
typedef std::map<std::string, size_t> NAME2INDEX_MAP;
|
||||
typedef std::map<size_t, std::string> INDEX2NAME_MAP;
|
||||
#endif
|
||||
|
||||
NAME2INDEX_MAP m_Name2Index; ///< <20><> <20>ε<EFBFBD><CEB5><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD> <20><><EFBFBD><EFBFBD> <20≯<EFBFBD><CCB8><EFBFBD>
|
||||
INDEX2NAME_MAP m_Index2Name; ///< <20>߸<EFBFBD><DFB8><EFBFBD> alias<61><73> <20>˻<EFBFBD><CBBB>ϱ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>߰<EFBFBD><DFB0><EFBFBD><EFBFBD><EFBFBD> <20><>
|
||||
|
||||
|
||||
public:
|
||||
/// \brief <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
cCsvAlias() {}
|
||||
|
||||
/// \brief <20>Ҹ<EFBFBD><D2B8><EFBFBD>
|
||||
virtual ~cCsvAlias() {}
|
||||
|
||||
|
||||
public:
|
||||
/// \brief <20><><EFBFBD><EFBFBD> <20><EFBFBD><D7BC><EFBFBD><EFBFBD><EFBFBD> <20><>, <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20≯<EFBFBD><CCB8><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
void AddAlias(const char* name, size_t index);
|
||||
|
||||
/// \brief <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
void Destroy();
|
||||
|
||||
/// \brief <20><><EFBFBD><EFBFBD> <20>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD> <20≯<EFBFBD><CCB8><EFBFBD><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
|
||||
const char* operator [] (size_t index) const;
|
||||
|
||||
/// \brief <20≯<EFBFBD><CCB8><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
|
||||
size_t operator [] (const char* name) const;
|
||||
|
||||
|
||||
private:
|
||||
/// \brief <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
cCsvAlias(const cCsvAlias&) {}
|
||||
|
||||
/// \brief <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
const cCsvAlias& operator = (const cCsvAlias&) { return *this; }
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \class cCsvRow
|
||||
/// \brief CSV <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> ĸ<><C4B8>ȭ<EFBFBD><C8AD> Ŭ<><C5AC><EFBFBD><EFBFBD>
|
||||
///
|
||||
/// CSV<53><56> <20>⺻ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>̴<EFBFBD> <20>ϳ<EFBFBD><CFB3><EFBFBD> <20><><EFBFBD><EFBFBD> ',' <20><><EFBFBD>ڷ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>̴<EFBFBD>.
|
||||
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><> <20>ȿ<EFBFBD> Ư<><C6AF> <20><><EFBFBD>ڷ<EFBFBD> <20><><EFBFBD>̴<EFBFBD> ',' <20><><EFBFBD>ڳ<EFBFBD> '"' <20><><EFBFBD>ڰ<EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD>,
|
||||
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ణ <20>̻<EFBFBD><CCBB>ϰ<EFBFBD> <20><><EFBFBD>Ѵ<EFBFBD>. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><>ȭ<EFBFBD><C8AD> <20><><EFBFBD>̴<EFBFBD>.
|
||||
///
|
||||
/// <pre>
|
||||
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>̴<EFBFBD> <20><><EFBFBD><EFBFBD> | <20><><EFBFBD><EFBFBD> CSV <20><><EFBFBD>Ͽ<EFBFBD> <20><><EFBFBD><EFBFBD>ִ<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
/// ---------------------+----------------------------------------------------
|
||||
/// ItemPrice | ItemPrice
|
||||
/// Item,Price | "Item,Price"
|
||||
/// Item"Price | "Item""Price"
|
||||
/// "ItemPrice" | """ItemPrice"""
|
||||
/// "Item,Price" | """Item,Price"""
|
||||
/// Item",Price | "Item"",Price"
|
||||
/// </pre>
|
||||
///
|
||||
/// <20><> <20><><EFBFBD>μ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><> <20>ִ<EFBFBD>.
|
||||
/// - <20><> <20><><EFBFBD>ο<EFBFBD> ',' <20>Ǵ<EFBFBD> '"' <20><><EFBFBD>ڰ<EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD>, <20><> <20>¿쿡 '"' <20><><EFBFBD>ڰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||||
/// - <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> '"' <20><><EFBFBD>ڴ<EFBFBD> 2<><32><EFBFBD><EFBFBD> ġȯ<C4A1>ȴ<EFBFBD>.
|
||||
///
|
||||
/// \sa cCsvFile
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class cCsvRow : public std::vector<std::string>
|
||||
{
|
||||
public:
|
||||
/// \brief <20>⺻ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
cCsvRow() {}
|
||||
|
||||
/// \brief <20>Ҹ<EFBFBD><D2B8><EFBFBD>
|
||||
~cCsvRow() {}
|
||||
|
||||
|
||||
public:
|
||||
/// \brief <20>ش<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> int <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
|
||||
int AsInt(size_t index) const { return atoi(at(index).c_str()); }
|
||||
|
||||
/// \brief <20>ش<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> double <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
|
||||
double AsDouble(size_t index) const { return atof(at(index).c_str()); }
|
||||
|
||||
/// \brief <20>ش<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ڿ<EFBFBD><DABF><EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
|
||||
const char* AsString(size_t index) const { return at(index).c_str(); }
|
||||
|
||||
/// \brief <20>ش<EFBFBD><D8B4>ϴ<EFBFBD> <20≯<EFBFBD><CCB8><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> int <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
|
||||
int AsInt(const char* name, const cCsvAlias& alias) const {
|
||||
return atoi( at(alias[name]).c_str() );
|
||||
}
|
||||
|
||||
/// \brief <20>ش<EFBFBD><D8B4>ϴ<EFBFBD> <20≯<EFBFBD><CCB8><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> int <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
|
||||
double AsDouble(const char* name, const cCsvAlias& alias) const {
|
||||
return atof( at(alias[name]).c_str() );
|
||||
}
|
||||
|
||||
/// \brief <20>ش<EFBFBD><D8B4>ϴ<EFBFBD> <20≯<EFBFBD><CCB8><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ڿ<EFBFBD><DABF><EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
|
||||
const char* AsString(const char* name, const cCsvAlias& alias) const {
|
||||
return at(alias[name]).c_str();
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
/// \brief <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
cCsvRow(const cCsvRow&) {}
|
||||
|
||||
/// \brief <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
const cCsvRow& operator = (const cCsvRow&) { return *this; }
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \class cCsvFile
|
||||
/// \brief CSV(Comma Seperated Values) <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> read/write<74>ϱ<EFBFBD> <20><><EFBFBD><EFBFBD> Ŭ<><C5AC><EFBFBD><EFBFBD>
|
||||
///
|
||||
/// <b>sample</b>
|
||||
/// <pre>
|
||||
/// cCsvFile file;
|
||||
///
|
||||
/// cCsvRow row1, row2, row3;
|
||||
/// row1.push_back("ItemPrice");
|
||||
/// row1.push_back("Item,Price");
|
||||
/// row1.push_back("Item\"Price");
|
||||
///
|
||||
/// row2.reserve(3);
|
||||
/// row2[0] = "\"ItemPrice\"";
|
||||
/// row2[1] = "\"Item,Price\"";
|
||||
/// row2[2] = "Item\",Price\"";
|
||||
///
|
||||
/// row3 = "\"ItemPrice\"\"Item,Price\"Item\",Price\"";
|
||||
///
|
||||
/// file.add(row1);
|
||||
/// file.add(row2);
|
||||
/// file.add(row3);
|
||||
/// file.save("test.csv", false);
|
||||
/// </pre>
|
||||
///
|
||||
/// \todo <20><><EFBFBD>Ͽ<EFBFBD><CFBF><EFBFBD><EFBFBD><EFBFBD> <20>о<EFBFBD><D0BE><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ƴ϶<C6B4>, <20><EFBFBD><DEB8><EFBFBD> <20>ҽ<EFBFBD><D2BD>κ<EFBFBD><CEBA><EFBFBD> <20>д<EFBFBD> <20>Լ<EFBFBD><D4BC><EFBFBD>
|
||||
/// <20>־<EFBFBD><D6BE><EFBFBD> <20><> <20><> <20>ϴ<EFBFBD>.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class cCsvFile
|
||||
{
|
||||
private:
|
||||
typedef std::vector<cCsvRow*> ROWS;
|
||||
|
||||
ROWS m_Rows; ///< <20><> <20>÷<EFBFBD><C3B7><EFBFBD>
|
||||
|
||||
|
||||
public:
|
||||
/// \brief <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
cCsvFile() {}
|
||||
|
||||
/// \brief <20>Ҹ<EFBFBD><D2B8><EFBFBD>
|
||||
virtual ~cCsvFile() { Destroy(); }
|
||||
|
||||
|
||||
public:
|
||||
/// \brief <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20≯<EFBFBD><CCB8><EFBFBD> CSV <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ε<EFBFBD><CEB5>Ѵ<EFBFBD>.
|
||||
bool Load(const char* fileName, const char seperator=',', const char quote='"');
|
||||
|
||||
/// \brief <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ִ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> CSV <20><><EFBFBD>Ͽ<EFBFBD><CFBF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
bool Save(const char* fileName, bool append=false, char seperator=',', char quote='"') const;
|
||||
|
||||
/// \brief <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><DEB8><F0B8AEBF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
void Destroy();
|
||||
|
||||
/// \brief <20>ش<EFBFBD><D8B4>ϴ<EFBFBD> <20>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
|
||||
cCsvRow* operator [] (size_t index);
|
||||
|
||||
/// \brief <20>ش<EFBFBD><D8B4>ϴ<EFBFBD> <20>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
|
||||
const cCsvRow* operator [] (size_t index) const;
|
||||
|
||||
/// \brief <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
|
||||
size_t GetRowCount() const { return m_Rows.size(); }
|
||||
|
||||
|
||||
private:
|
||||
/// \brief <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
cCsvFile(const cCsvFile&) {}
|
||||
|
||||
/// \brief <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
const cCsvFile& operator = (const cCsvFile&) { return *this; }
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// \class cCsvTable
|
||||
/// \brief CSV <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>̿<EFBFBD><CCBF><EFBFBD> <20><><EFBFBD>̺<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ε<EFBFBD><CEB5>ϴ<EFBFBD> <20><><EFBFBD>찡 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><> Ŭ<><C5AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
/// <20><> <20>۾<EFBFBD><DBBE><EFBFBD> <20><> <20><> <20><><EFBFBD><EFBFBD> <20>ϱ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ƿ<EFBFBD><C6BF>Ƽ Ŭ<><C5AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||||
///
|
||||
/// CSV <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ε<EFBFBD><CEB5>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD>, <20><><EFBFBD>ڸ<EFBFBD> <20>̿<EFBFBD><CCBF><EFBFBD> <20><><EFBFBD><EFBFBD> <20><EFBFBD><D7BC><EFBFBD><EFBFBD>ؾ<EFBFBD> <20>ϴµ<CFB4>, CSV
|
||||
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ٲ<EFBFBD><D9B2><EFBFBD> <20><><EFBFBD><EFBFBD>, <20><> <20><><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>. <20><> <20>۾<EFBFBD><DBBE><EFBFBD> <20><>
|
||||
/// <20>Ű<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>䱸<EFBFBD>ϴ<EFBFBD> <20><><EFBFBD>ٰ<EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD><DFBB>ϱ<EFBFBD> <20><><EFBFBD><EFBFBD>. <20><EFBFBD><D7B7>Ƿ<EFBFBD> <20><><EFBFBD>ڷ<EFBFBD>
|
||||
/// <20><EFBFBD><D7BC><EFBFBD><EFBFBD>ϱ⺸<CFB1>ٴ<EFBFBD> <20><><EFBFBD>ڿ<EFBFBD><DABF><EFBFBD> <20><EFBFBD><D7BC><EFBFBD><EFBFBD>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>ణ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ٰ<EFBFBD> <20><> <20><> <20>ִ<EFBFBD>.
|
||||
///
|
||||
/// <b>sample</b>
|
||||
/// <pre>
|
||||
/// cCsvTable table;
|
||||
///
|
||||
/// table.alias(0, "ItemClass");
|
||||
/// table.alias(1, "ItemType");
|
||||
///
|
||||
/// if (table.load("test.csv"))
|
||||
/// {
|
||||
/// while (table.next())
|
||||
/// {
|
||||
/// std::string item_class = table.AsString("ItemClass");
|
||||
/// int item_type = table.AsInt("ItemType");
|
||||
/// }
|
||||
/// }
|
||||
/// </pre>
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class cCsvTable
|
||||
{
|
||||
public :
|
||||
cCsvFile m_File; ///< CSV <20><><EFBFBD><EFBFBD> <20><>ü
|
||||
private:
|
||||
cCsvAlias m_Alias; ///< <20><><EFBFBD>ڿ<EFBFBD><DABF><EFBFBD> <20><> <20>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD>ϱ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ü
|
||||
int m_CurRow; ///< <20><><EFBFBD><EFBFBD> Ⱦ<><C8BE> <20><><EFBFBD><EFBFBD> <20><> <20><>ȣ
|
||||
|
||||
|
||||
public:
|
||||
/// \brief <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
cCsvTable();
|
||||
|
||||
/// \brief <20>Ҹ<EFBFBD><D2B8><EFBFBD>
|
||||
virtual ~cCsvTable();
|
||||
|
||||
|
||||
public:
|
||||
/// \brief <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20≯<EFBFBD><CCB8><EFBFBD> CSV <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ε<EFBFBD><CEB5>Ѵ<EFBFBD>.
|
||||
bool Load(const char* fileName, const char seperator=',', const char quote='"');
|
||||
|
||||
/// \brief <20><><EFBFBD><EFBFBD> <20><EFBFBD><D7BC><EFBFBD><EFBFBD><EFBFBD> <20><>, <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20≯<EFBFBD><CCB8><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
void AddAlias(const char* name, size_t index) { m_Alias.AddAlias(name, index); }
|
||||
|
||||
/// \brief <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ѿ<D1BE><EEB0A3>.
|
||||
bool Next();
|
||||
|
||||
/// \brief <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD>ڸ<EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
|
||||
size_t ColCount() const;
|
||||
|
||||
/// \brief <20>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD> <20>̿<EFBFBD><CCBF><EFBFBD> int <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
|
||||
int AsInt(size_t index) const;
|
||||
|
||||
/// \brief <20>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD> <20>̿<EFBFBD><CCBF><EFBFBD> double <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
|
||||
double AsDouble(size_t index) const;
|
||||
|
||||
/// \brief <20>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD> <20>̿<EFBFBD><CCBF><EFBFBD> std::string <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
|
||||
const char* AsStringByIndex(size_t index) const;
|
||||
|
||||
/// \brief <20><> <20≯<EFBFBD><CCB8><EFBFBD> <20>̿<EFBFBD><CCBF><EFBFBD> int <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
|
||||
int AsInt(const char* name) const { return AsInt(m_Alias[name]); }
|
||||
|
||||
/// \brief <20><> <20≯<EFBFBD><CCB8><EFBFBD> <20>̿<EFBFBD><CCBF><EFBFBD> double <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
|
||||
double AsDouble(const char* name) const { return AsDouble(m_Alias[name]); }
|
||||
|
||||
/// \brief <20><> <20≯<EFBFBD><CCB8><EFBFBD> <20>̿<EFBFBD><CCBF><EFBFBD> std::string <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
|
||||
const char* AsString(const char* name) const { return AsStringByIndex(m_Alias[name]); }
|
||||
|
||||
/// \brief alias<61><73> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||||
void Destroy();
|
||||
|
||||
|
||||
private:
|
||||
/// \brief <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ȯ<EFBFBD>Ѵ<EFBFBD>.
|
||||
const cCsvRow* const CurRow() const;
|
||||
|
||||
/// \brief <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
cCsvTable(const cCsvTable&) {}
|
||||
|
||||
/// \brief <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
const cCsvTable& operator = (const cCsvTable&) { return *this; }
|
||||
};
|
||||
|
||||
#endif //__CSVFILE_H__
|
188
db/src/DBManager.cpp
Normal file
188
db/src/DBManager.cpp
Normal file
@ -0,0 +1,188 @@
|
||||
#include "stdafx.h"
|
||||
#include "DBManager.h"
|
||||
#include "ClientManager.h"
|
||||
|
||||
extern std::string g_stLocale;
|
||||
|
||||
CDBManager::CDBManager()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
CDBManager::~CDBManager()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
void CDBManager::Initialize()
|
||||
{
|
||||
for (int i = 0; i < SQL_MAX_NUM; ++i)
|
||||
{
|
||||
m_mainSQL[i] = NULL;
|
||||
m_directSQL[i] = NULL;
|
||||
m_asyncSQL[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void CDBManager::Destroy()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
void CDBManager::Quit()
|
||||
{
|
||||
for (int i = 0; i < SQL_MAX_NUM; ++i)
|
||||
{
|
||||
if (m_mainSQL[i])
|
||||
m_mainSQL[i]->Quit();
|
||||
|
||||
if (m_asyncSQL[i])
|
||||
m_asyncSQL[i]->Quit();
|
||||
|
||||
if (m_directSQL[i])
|
||||
m_directSQL[i]->Quit();
|
||||
}
|
||||
}
|
||||
|
||||
SQLMsg * CDBManager::PopResult()
|
||||
{
|
||||
SQLMsg * p;
|
||||
|
||||
for (int i = 0; i < SQL_MAX_NUM; ++i)
|
||||
if (m_mainSQL[i] && m_mainSQL[i]->PopResult(&p))
|
||||
return p;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SQLMsg * CDBManager::PopResult(eSQL_SLOT slot)
|
||||
{
|
||||
SQLMsg * p;
|
||||
|
||||
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;
|
||||
|
||||
sys_log(0, "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;
|
||||
}
|
||||
|
||||
|
||||
sys_log(0, "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))
|
||||
{
|
||||
Clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
sys_log(0, "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);
|
||||
//sys_log(0, "ReturnQuery %s", 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 long CDBManager::EscapeString(void *to, const void *from, unsigned long 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);
|
||||
sys_log(0, "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);
|
||||
}
|
||||
sys_log(0, "End setlocale %s", 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();
|
||||
}
|
||||
}
|
||||
|
100
db/src/DBManager.h
Normal file
100
db/src/DBManager.h
Normal file
@ -0,0 +1,100 @@
|
||||
// vim:ts=8 sw=4
|
||||
#ifndef __INC_METIN2_DB_DBMANAGER_H__
|
||||
#define __INC_METIN2_DB_DBMANAGER_H__
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> Ŀ<>ؼ<EFBFBD> Ŭ<><C5AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>... <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ؼ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ƿ<DEBE><C6BF><EFBFBD>
|
||||
// <20><><EFBFBD><EFBFBD> <20>ϵ<EFBFBD><CFB5><EFBFBD> ó<><C3B3><EFBFBD>Ѵ<EFBFBD>.
|
||||
// <20>ڵ<EFBFBD> by <20><><EFBFBD><EFBFBD> <20>ķα<CEB1><D7B7><EFBFBD> <20>Ƴ<EFBFBD><C6B3><EFBFBD>~ = _=)b
|
||||
#include <mysql/mysql.h>
|
||||
|
||||
#include "../../libsql/AsyncSQL.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_HOTBACKUP,
|
||||
SQL_MAX_NUM,
|
||||
};
|
||||
|
||||
class CDBManager : public singleton<CDBManager>
|
||||
{
|
||||
protected:
|
||||
void Initialize();
|
||||
void Destroy();
|
||||
|
||||
public:
|
||||
CDBManager();
|
||||
virtual ~CDBManager();
|
||||
|
||||
void Clear();
|
||||
void Quit();
|
||||
|
||||
int Connect(int iSlot, const char * host, int port, const char* dbname, const char* user, const char* pass);
|
||||
|
||||
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);
|
||||
|
||||
SQLMsg * PopResult();
|
||||
SQLMsg * PopResult(eSQL_SLOT slot );
|
||||
|
||||
unsigned long EscapeString(void * to, const void * from, unsigned long length, int iSlot = SQL_PLAYER);
|
||||
|
||||
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; }
|
||||
|
||||
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; }
|
||||
|
||||
void ResetCounter()
|
||||
{
|
||||
for (int i = 0; i < SQL_MAX_NUM; ++i)
|
||||
{
|
||||
if (m_mainSQL[i])
|
||||
{
|
||||
m_mainSQL[i]->ResetQueryFinished();
|
||||
m_mainSQL[i]->ResetCopiedQueryCount();
|
||||
}
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
#endif
|
1491
db/src/GuildManager.cpp
Normal file
1491
db/src/GuildManager.cpp
Normal file
File diff suppressed because it is too large
Load Diff
260
db/src/GuildManager.h
Normal file
260
db/src/GuildManager.h
Normal file
@ -0,0 +1,260 @@
|
||||
// vim:ts=8 sw=4
|
||||
#ifndef __INC_GUILD_MANAGER_H
|
||||
#define __INC_GUILD_MANAGER_H
|
||||
|
||||
#include "Peer.h"
|
||||
#include <queue>
|
||||
#include <utility>
|
||||
#include "../../libsql/libsql.h"
|
||||
#include "../../libpoly/Poly.h"
|
||||
|
||||
enum
|
||||
{
|
||||
GUILD_WARP_WAR_CHANNEL = 99
|
||||
};
|
||||
|
||||
class CGuildWarReserve;
|
||||
|
||||
struct TGuildDeclareInfo
|
||||
{
|
||||
BYTE bType;
|
||||
DWORD dwGuildID[2];
|
||||
|
||||
TGuildDeclareInfo(BYTE _bType, DWORD _dwGuildID1, DWORD _dwGuildID2)
|
||||
: bType(_bType)
|
||||
{
|
||||
dwGuildID[0] = _dwGuildID1;
|
||||
dwGuildID[1] = _dwGuildID2;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
bType = r.bType;
|
||||
dwGuildID[0] = r.dwGuildID[0];
|
||||
dwGuildID[1] = r.dwGuildID[1];
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
struct TGuildWaitStartInfo
|
||||
{
|
||||
BYTE bType;
|
||||
DWORD GID[2];
|
||||
long lWarPrice;
|
||||
long lInitialScore;
|
||||
CGuildWarReserve * pkReserve;
|
||||
|
||||
TGuildWaitStartInfo(BYTE _bType,
|
||||
DWORD _g1,
|
||||
DWORD _g2,
|
||||
long _lWarPrice,
|
||||
long _lInitialScore,
|
||||
CGuildWarReserve * _pkReserve)
|
||||
: bType(_bType), lWarPrice(_lWarPrice), lInitialScore(_lInitialScore), pkReserve(_pkReserve)
|
||||
{
|
||||
GID[0] = _g1;
|
||||
GID[1] = _g2;
|
||||
}
|
||||
|
||||
bool operator < (const TGuildWaitStartInfo& r) const
|
||||
{
|
||||
return GID[0] < r.GID[0] || GID[0] == r.GID[0] && GID[1] < r.GID[1];
|
||||
}
|
||||
};
|
||||
|
||||
struct TGuildWarPQElement
|
||||
{
|
||||
bool bEnd;
|
||||
BYTE bType;
|
||||
DWORD GID[2];
|
||||
DWORD iScore[2];
|
||||
DWORD iBetScore[2];
|
||||
|
||||
TGuildWarPQElement(BYTE _bType, DWORD GID1, DWORD GID2) : bEnd(false), bType(_bType)
|
||||
{
|
||||
bType = _bType;
|
||||
GID[0] = GID1;
|
||||
GID[1] = GID2;
|
||||
iScore[0] = iScore[1] = 0;
|
||||
iBetScore[0] = iBetScore[1] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct TGuildSkillUsed
|
||||
{
|
||||
DWORD GID;
|
||||
DWORD dwSkillVnum;
|
||||
|
||||
// GUILD_SKILL_COOLTIME_BUG_FIX
|
||||
TGuildSkillUsed(DWORD _GID, DWORD _dwSkillVnum) : GID(_GID), dwSkillVnum(_dwSkillVnum)
|
||||
{
|
||||
}
|
||||
// END_OF_GUILD_SKILL_COOLTIME_BUG_FIX
|
||||
};
|
||||
|
||||
inline bool operator < (const TGuildSkillUsed& a, const TGuildSkillUsed& b)
|
||||
{
|
||||
return a.GID < b.GID || a.GID == b.GID && a.dwSkillVnum < b.dwSkillVnum;
|
||||
}
|
||||
|
||||
typedef struct SGuild
|
||||
{
|
||||
SGuild() : ladder_point(0), win(0), draw(0), loss(0), gold(0), level(0)
|
||||
{
|
||||
memset(szName, 0, sizeof(szName));
|
||||
}
|
||||
|
||||
char szName[GUILD_NAME_MAX_LEN+1];
|
||||
int ladder_point;
|
||||
int win;
|
||||
int draw;
|
||||
int loss;
|
||||
int gold;
|
||||
int level;
|
||||
} TGuild;
|
||||
|
||||
typedef struct SGuildWarInfo
|
||||
{
|
||||
time_t tEndTime;
|
||||
TGuildWarPQElement * pElement;
|
||||
CGuildWarReserve * pkReserve;
|
||||
|
||||
SGuildWarInfo() : pElement(NULL)
|
||||
{
|
||||
}
|
||||
} TGuildWarInfo;
|
||||
|
||||
class CGuildWarReserve
|
||||
{
|
||||
public:
|
||||
CGuildWarReserve(const TGuildWarReserve& rTable);
|
||||
|
||||
void Initialize();
|
||||
|
||||
TGuildWarReserve & GetDataRef()
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
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:
|
||||
CGuildWarReserve(); // <20>⺻ <20><><EFBFBD><EFBFBD><EFBFBD>ڸ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD> <20>ǵ<EFBFBD><C7B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
|
||||
TGuildWarReserve m_data;
|
||||
// <login, <guild, gold>>
|
||||
std::map<std::string, std::pair<DWORD, DWORD> > mapBet;
|
||||
int m_iLastNoticeMin;
|
||||
};
|
||||
|
||||
class CGuildManager : public singleton<CGuildManager>
|
||||
{
|
||||
public:
|
||||
CGuildManager();
|
||||
virtual ~CGuildManager();
|
||||
|
||||
void Initialize();
|
||||
|
||||
void Load(DWORD dwGuildID);
|
||||
|
||||
TGuild & TouchGuild(DWORD GID);
|
||||
|
||||
void Update();
|
||||
|
||||
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);
|
||||
|
||||
void AddDeclare(BYTE bType, DWORD guild_from, DWORD guild_to);
|
||||
void RemoveDeclare(DWORD guild_from, DWORD guild_to);
|
||||
|
||||
bool TakeBetPrice(DWORD dwGuildTo, DWORD dwGuildFrom, long lWarPrice);
|
||||
|
||||
bool WaitStart(TPacketGuildWar * p);
|
||||
|
||||
void RecvWarEnd(DWORD GID1, DWORD GID2);
|
||||
void RecvWarOver(DWORD dwGuildWinner, DWORD dwGuildLoser, bool bDraw, long lWarPrice);
|
||||
|
||||
void ChangeLadderPoint(DWORD GID, int change);
|
||||
|
||||
void UseSkill(DWORD dwGuild, DWORD dwSkillVnum, DWORD dwCooltime);
|
||||
|
||||
INT GetGuildGold(DWORD dwGuild);
|
||||
void DepositMoney(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);
|
||||
int GetRanking(DWORD dwGID);
|
||||
|
||||
//
|
||||
// Reserve War
|
||||
//
|
||||
void BootReserveWar();
|
||||
bool ReserveWar(TPacketGuildWar * p);
|
||||
void ProcessReserveWar();
|
||||
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);
|
||||
|
||||
void RemoveWar(DWORD GID1, DWORD GID2); // erase war from m_WarMap and set end on priority queue
|
||||
|
||||
void WarEnd(DWORD GID1, DWORD GID2, bool bDraw = false);
|
||||
|
||||
int GetLadderPoint(DWORD GID);
|
||||
|
||||
void GuildWarWin(DWORD GID);
|
||||
void GuildWarDraw(DWORD GID);
|
||||
void GuildWarLose(DWORD GID);
|
||||
|
||||
void ProcessDraw(DWORD dwGuildID1, DWORD dwGuildID2);
|
||||
void ProcessWinLose(DWORD dwGuildWinner, DWORD dwGuildLoser);
|
||||
|
||||
bool IsHalfWinLadderPoint(DWORD dwGuildWinner, DWORD dwGuildLoser);
|
||||
|
||||
std::map<DWORD, TGuild> m_map_kGuild;
|
||||
std::map<DWORD, std::map<DWORD, time_t> > m_mapGuildWarEndTime;
|
||||
|
||||
std::set<TGuildDeclareInfo> m_DeclareMap; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>¸<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
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> >
|
||||
m_pqOnWar;
|
||||
std::priority_queue<stPairWaitStart, std::vector<stPairWaitStart>, std::greater<stPairWaitStart> >
|
||||
m_pqWaitStart;
|
||||
std::priority_queue<stPairSkillUsed, std::vector<stPairSkillUsed>, std::greater<stPairSkillUsed> >
|
||||
m_pqSkill;
|
||||
|
||||
std::map<DWORD, CGuildWarReserve *> m_map_kWarReserve;
|
||||
CPoly polyPower;
|
||||
CPoly polyHandicap;
|
||||
|
||||
// GID Ranking
|
||||
std::map<DWORD, int> map_kLadderPointRankingByGID;
|
||||
};
|
||||
|
||||
#endif
|
86
db/src/HB.cpp
Normal file
86
db/src/HB.cpp
Normal file
@ -0,0 +1,86 @@
|
||||
#include "stdafx.h"
|
||||
#include "HB.h"
|
||||
#include "Main.h"
|
||||
#include "DBManager.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
PlayerHB::PlayerHB()
|
||||
{
|
||||
m_iExpireTime = 3600; // 1 hour hotbackup default.
|
||||
}
|
||||
|
||||
PlayerHB::~PlayerHB()
|
||||
{
|
||||
}
|
||||
|
||||
bool PlayerHB::Initialize()
|
||||
{
|
||||
char szQuery[128];
|
||||
snprintf(szQuery, sizeof(szQuery), "SHOW CREATE TABLE player%s", GetTablePostfix());
|
||||
|
||||
std::auto_ptr<SQLMsg> pMsg(CDBManager::instance().DirectQuery(szQuery));
|
||||
|
||||
if (pMsg->Get()->uiNumRows == 0)
|
||||
return false;
|
||||
|
||||
MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
|
||||
m_stCreateTableQuery = row[1];
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// @version 05/07/05 Bang2ni - id <20><> <20>ش<EFBFBD><D8B4>ϴ<EFBFBD> data <20><> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> data <20><> insert <20>ϴ<EFBFBD><CFB4>ڵ<EFBFBD> <20>߰<EFBFBD>.
|
||||
//
|
||||
void PlayerHB::Put(DWORD id)
|
||||
{
|
||||
itertype(m_map_data) it = m_map_data.find(id);
|
||||
|
||||
if (it == m_map_data.end())
|
||||
{
|
||||
Query(id);
|
||||
m_map_data.insert(std::pair< DWORD, time_t >(id, get_dword_time()));
|
||||
return;
|
||||
}
|
||||
|
||||
if (time(0) - it->second > m_iExpireTime)
|
||||
Query(id);
|
||||
}
|
||||
|
||||
//
|
||||
// @version 05/07/05 Bang2ni - Query string <20><><EFBFBD>۰<EFBFBD> <20>۾Ƽ<DBBE> <20>÷<EFBFBD><C3B7><EFBFBD>.
|
||||
//
|
||||
bool PlayerHB::Query(DWORD id)
|
||||
{
|
||||
time_t ct = time(0);
|
||||
struct tm curr_tm = *localtime(&ct);
|
||||
char szTableName[64];
|
||||
snprintf(szTableName, sizeof(szTableName), "hb_%02d%02d%02d%02d_player%s",
|
||||
curr_tm.tm_year - 100, curr_tm.tm_mon + 1, curr_tm.tm_mday, curr_tm.tm_hour, GetTablePostfix());
|
||||
|
||||
char szQuery[4096];
|
||||
|
||||
if (m_stTableName.compare(szTableName))
|
||||
{
|
||||
char szFind[32];
|
||||
snprintf(szFind, sizeof(szFind), "CREATE TABLE `player%s`", GetTablePostfix());
|
||||
int pos = m_stCreateTableQuery.find(szFind);
|
||||
|
||||
if (pos < 0)
|
||||
{
|
||||
sys_err("cannot find %s ", szFind);
|
||||
// sys_err("cannot find %s in %s", szFind, m_stCreateTableQuery.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
snprintf(szQuery, sizeof(szQuery), "CREATE TABLE IF NOT EXISTS %s%s", szTableName, m_stCreateTableQuery.c_str() + strlen(szFind));
|
||||
// sys_log(0, "%s", szQuery);
|
||||
std::auto_ptr<SQLMsg> pMsg(CDBManager::instance().DirectQuery(szQuery, SQL_HOTBACKUP));
|
||||
m_stTableName = szTableName;
|
||||
}
|
||||
|
||||
snprintf(szQuery, sizeof(szQuery), "REPLACE INTO %s SELECT * FROM %splayer%s WHERE id=%u", m_stTableName.c_str(), GetPlayerDBName(), GetTablePostfix(), id);
|
||||
CDBManager::instance().AsyncQuery(szQuery, SQL_HOTBACKUP);
|
||||
return true;
|
||||
}
|
||||
|
24
db/src/HB.h
Normal file
24
db/src/HB.h
Normal file
@ -0,0 +1,24 @@
|
||||
// vim:ts=8 sw=4
|
||||
#ifndef __INC_METIN_II_PLAYERHB_H__
|
||||
#define __INC_METIN_II_PLAYERHB_H__
|
||||
|
||||
class PlayerHB : public singleton<PlayerHB>
|
||||
{
|
||||
public:
|
||||
PlayerHB();
|
||||
virtual ~PlayerHB();
|
||||
|
||||
bool Initialize();
|
||||
|
||||
void Put(DWORD id);
|
||||
|
||||
private:
|
||||
bool Query(DWORD id);
|
||||
|
||||
std::map<DWORD, time_t> m_map_data;
|
||||
std::string m_stCreateTableQuery;
|
||||
std::string m_stTableName;
|
||||
int m_iExpireTime;
|
||||
};
|
||||
|
||||
#endif
|
129
db/src/ItemAwardManager.cpp
Normal file
129
db/src/ItemAwardManager.cpp
Normal file
@ -0,0 +1,129 @@
|
||||
#include "stdafx.h"
|
||||
#include "QID.h"
|
||||
#include "DBManager.h"
|
||||
#include "ItemAwardManager.h"
|
||||
#include "Peer.h"
|
||||
|
||||
#include "ClientManager.h"
|
||||
|
||||
|
||||
|
||||
DWORD g_dwLastCachedItemAwardID = 0;
|
||||
ItemAwardManager::ItemAwardManager()
|
||||
{
|
||||
}
|
||||
|
||||
ItemAwardManager::~ItemAwardManager()
|
||||
{
|
||||
}
|
||||
|
||||
void ItemAwardManager::RequestLoad()
|
||||
{
|
||||
char szQuery[QUERY_MAX_LEN];
|
||||
snprintf(szQuery, sizeof(szQuery), "SELECT id,login,vnum,count,socket0,socket1,socket2,mall,why FROM item_award WHERE taken_time IS NULL and id > %d", g_dwLastCachedItemAwardID);
|
||||
CDBManager::instance().ReturnQuery(szQuery, QID_ITEM_AWARD_LOAD, 0, NULL);
|
||||
}
|
||||
|
||||
void ItemAwardManager::Load(SQLMsg * pMsg)
|
||||
{
|
||||
MYSQL_RES * pRes = pMsg->Get()->pSQLResult;
|
||||
|
||||
for (uint i = 0; i < pMsg->Get()->uiNumRows; ++i)
|
||||
{
|
||||
MYSQL_ROW row = mysql_fetch_row(pRes);
|
||||
int col = 0;
|
||||
|
||||
DWORD dwID = 0;
|
||||
str_to_number(dwID, row[col++]);
|
||||
|
||||
if (m_map_award.find(dwID) != m_map_award.end())
|
||||
continue;
|
||||
|
||||
TItemAward * kData = new TItemAward;
|
||||
memset(kData, 0, sizeof(TItemAward));
|
||||
|
||||
kData->dwID = dwID;
|
||||
trim_and_lower(row[col++], kData->szLogin, sizeof(kData->szLogin));
|
||||
str_to_number(kData->dwVnum, row[col++]);
|
||||
str_to_number(kData->dwCount, row[col++]);
|
||||
str_to_number(kData->dwSocket0, row[col++]);
|
||||
str_to_number(kData->dwSocket1, row[col++]);
|
||||
str_to_number(kData->dwSocket2, row[col++]);
|
||||
str_to_number(kData->bMall, row[col++]);
|
||||
|
||||
if (row[col])
|
||||
{
|
||||
strlcpy(kData->szWhy, row[col], sizeof(kData->szWhy));
|
||||
//<2F><><EFBFBD><EFBFBD> <20>߿<EFBFBD> why<68>ݷ뿡 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
char* whyStr = kData->szWhy; //why <20>ݷ<EFBFBD> <20>б<EFBFBD>
|
||||
char cmdStr[100] = ""; //why<68>ݷ뿡<DDB7><EBBFA1> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ӽ<EFBFBD> <20><><EFBFBD>ڿ<EFBFBD><DABF><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD>
|
||||
strcpy(cmdStr,whyStr); //<2F><><EFBFBD>ɾ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ū<EFBFBD><C5AB><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ūȭ <20>DZ<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
char command[20] = "";
|
||||
strcpy(command,CClientManager::instance().GetCommand(cmdStr)); // command <20><><EFBFBD><EFBFBD>
|
||||
//sys_err("%d, %s",pItemAward->dwID,command);
|
||||
if( !(strcmp(command,"GIFT") )) // command <20><> GIFT<46≯<EFBFBD>
|
||||
{
|
||||
TPacketItemAwardInfromer giftData;
|
||||
strcpy(giftData.login, kData->szLogin); //<2F>α<EFBFBD><CEB1><EFBFBD> <20><><EFBFBD>̵<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
strcpy(giftData.command, command); //<2F><><EFBFBD>ɾ<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
giftData.vnum = kData->dwVnum; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> vnum<75><6D> <20><><EFBFBD><EFBFBD>
|
||||
CClientManager::instance().ForwardPacket(HEADER_DG_ITEMAWARD_INFORMER,&giftData,sizeof(TPacketItemAwardInfromer));
|
||||
}
|
||||
}
|
||||
|
||||
m_map_award.insert(std::make_pair(dwID, kData));
|
||||
|
||||
printf("ITEM_AWARD load id %u bMall %d \n", kData->dwID, kData->bMall);
|
||||
sys_log(0, "ITEM_AWARD: load id %lu login %s vnum %lu count %u socket %lu", kData->dwID, kData->szLogin, kData->dwVnum, kData->dwCount, kData->dwSocket0);
|
||||
std::set<TItemAward *> & kSet = m_map_kSetAwardByLogin[kData->szLogin];
|
||||
kSet.insert(kData);
|
||||
|
||||
if (dwID > g_dwLastCachedItemAwardID)
|
||||
g_dwLastCachedItemAwardID = dwID;
|
||||
}
|
||||
}
|
||||
|
||||
std::set<TItemAward *> * ItemAwardManager::GetByLogin(const char * c_pszLogin)
|
||||
{
|
||||
itertype(m_map_kSetAwardByLogin) it = m_map_kSetAwardByLogin.find(c_pszLogin);
|
||||
|
||||
if (it == m_map_kSetAwardByLogin.end())
|
||||
return NULL;
|
||||
|
||||
return &it->second;
|
||||
}
|
||||
|
||||
void ItemAwardManager::Taken(DWORD dwAwardID, DWORD dwItemID)
|
||||
{
|
||||
itertype(m_map_award) it = m_map_award.find(dwAwardID);
|
||||
|
||||
if (it == m_map_award.end())
|
||||
{
|
||||
sys_log(0, "ITEM_AWARD: Taken ID not exist %lu", dwAwardID);
|
||||
return;
|
||||
}
|
||||
|
||||
TItemAward * k = it->second;
|
||||
k->bTaken = true;
|
||||
|
||||
//
|
||||
// Update taken_time in database to prevent not to give him again.
|
||||
//
|
||||
char szQuery[QUERY_MAX_LEN];
|
||||
|
||||
snprintf(szQuery, sizeof(szQuery),
|
||||
"UPDATE item_award SET taken_time=NOW(),item_id=%u WHERE id=%u AND taken_time IS NULL",
|
||||
dwItemID, dwAwardID);
|
||||
|
||||
CDBManager::instance().ReturnQuery(szQuery, QID_ITEM_AWARD_TAKEN, 0, NULL);
|
||||
}
|
||||
|
||||
std::map<DWORD, TItemAward *>& ItemAwardManager::GetMapAward()
|
||||
{
|
||||
return m_map_award;
|
||||
}
|
||||
|
||||
std::map<std::string, std::set<TItemAward *> >& ItemAwardManager::GetMapkSetAwardByLogin()
|
||||
{
|
||||
return m_map_kSetAwardByLogin;
|
||||
}
|
43
db/src/ItemAwardManager.h
Normal file
43
db/src/ItemAwardManager.h
Normal file
@ -0,0 +1,43 @@
|
||||
// vim:ts=8 sw=4
|
||||
#ifndef __INC_ITEM_AWARD_H
|
||||
#define __INC_ITEM_AWARD_H
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include "Peer.h"
|
||||
|
||||
typedef struct SItemAward
|
||||
{
|
||||
DWORD dwID;
|
||||
char szLogin[LOGIN_MAX_LEN+1];
|
||||
DWORD dwVnum;
|
||||
DWORD dwCount;
|
||||
DWORD dwSocket0;
|
||||
DWORD dwSocket1;
|
||||
DWORD dwSocket2;
|
||||
char szWhy[ITEM_AWARD_WHY_MAX_LEN+1];
|
||||
bool bTaken;
|
||||
bool bMall;
|
||||
} TItemAward;
|
||||
|
||||
class ItemAwardManager : public singleton<ItemAwardManager>
|
||||
{
|
||||
public:
|
||||
ItemAwardManager();
|
||||
virtual ~ItemAwardManager();
|
||||
|
||||
void RequestLoad();
|
||||
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:
|
||||
// ID, ItemAward pair
|
||||
std::map<DWORD, TItemAward *> m_map_award;
|
||||
// PID, ItemAward pair
|
||||
std::map<std::string, std::set<TItemAward *> > m_map_kSetAwardByLogin;
|
||||
};
|
||||
|
||||
#endif
|
165
db/src/ItemIDRangeManager.cpp
Normal file
165
db/src/ItemIDRangeManager.cpp
Normal file
@ -0,0 +1,165 @@
|
||||
#include "stdafx.h"
|
||||
#include "ItemIDRangeManager.h"
|
||||
#include "Main.h"
|
||||
#include "DBManager.h"
|
||||
#include "ClientManager.h"
|
||||
#include "Peer.h"
|
||||
|
||||
CItemIDRangeManager::CItemIDRangeManager()
|
||||
{
|
||||
m_listData.clear();
|
||||
}
|
||||
|
||||
void CItemIDRangeManager::Build()
|
||||
{
|
||||
DWORD dwMin = 0;
|
||||
DWORD dwMax = 0;
|
||||
TItemIDRangeTable range;
|
||||
|
||||
for (int i = 0; ; ++i)
|
||||
{
|
||||
dwMin = cs_dwMinimumRange * (i + 1) + 1;
|
||||
dwMax = cs_dwMinimumRange * (i + 2);
|
||||
|
||||
if (dwMax == cs_dwMaxItemID)
|
||||
break;
|
||||
|
||||
if (CClientManager::instance().GetItemRange().dwMin <= dwMin &&
|
||||
CClientManager::instance().GetItemRange().dwMax >= dwMax)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (BuildRange(dwMin, dwMax, range) == true)
|
||||
{
|
||||
m_listData.push_back(range);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct FCheckCollision
|
||||
{
|
||||
bool hasCollision;
|
||||
TItemIDRangeTable range;
|
||||
|
||||
FCheckCollision(TItemIDRangeTable data)
|
||||
{
|
||||
hasCollision = false;
|
||||
range = data;
|
||||
}
|
||||
|
||||
void operator() (CPeer* peer)
|
||||
{
|
||||
if (hasCollision == false)
|
||||
{
|
||||
hasCollision = peer->CheckItemIDRangeCollision(range);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TItemIDRangeTable CItemIDRangeManager::GetRange()
|
||||
{
|
||||
TItemIDRangeTable ret;
|
||||
ret.dwMin = 0;
|
||||
ret.dwMax = 0;
|
||||
ret.dwUsableItemIDMin = 0;
|
||||
|
||||
if (m_listData.size() > 0)
|
||||
{
|
||||
while (m_listData.size() > 0)
|
||||
{
|
||||
ret = m_listData.front();
|
||||
m_listData.pop_front();
|
||||
|
||||
FCheckCollision f(ret);
|
||||
CClientManager::instance().for_each_peer(f);
|
||||
|
||||
if (f.hasCollision == false) return ret;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 10; ++i)
|
||||
sys_err("ItemIDRange: NO MORE ITEM ID RANGE");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool CItemIDRangeManager::BuildRange(DWORD dwMin, DWORD dwMax, TItemIDRangeTable& range)
|
||||
{
|
||||
char szQuery[1024];
|
||||
DWORD dwItemMaxID = 0;
|
||||
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);
|
||||
|
||||
pMsg = CDBManager::instance().DirectQuery(szQuery);
|
||||
|
||||
if (pMsg != NULL)
|
||||
{
|
||||
if (pMsg->Get()->uiNumRows > 0)
|
||||
{
|
||||
row = mysql_fetch_row(pMsg->Get()->pSQLResult);
|
||||
str_to_number(dwItemMaxID, row[0]);
|
||||
}
|
||||
delete pMsg;
|
||||
}
|
||||
|
||||
if (dwItemMaxID == 0)
|
||||
dwItemMaxID = dwMin;
|
||||
else
|
||||
dwItemMaxID++;
|
||||
|
||||
if ((dwMax < dwItemMaxID) || (dwMax - dwItemMaxID < cs_dwMinimumRemainCount))
|
||||
{
|
||||
sys_log(0, "ItemIDRange: Build %u ~ %u start: %u\tNOT USE remain count is below %u",
|
||||
dwMin, dwMax, dwItemMaxID, cs_dwMinimumRemainCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
range.dwMin = dwMin;
|
||||
range.dwMax = dwMax;
|
||||
range.dwUsableItemIDMin = dwItemMaxID;
|
||||
|
||||
snprintf(szQuery, sizeof(szQuery), "SELECT COUNT(*) FROM item%s WHERE id >= %u AND id <= %u",
|
||||
GetTablePostfix(), range.dwUsableItemIDMin, range.dwMax);
|
||||
|
||||
pMsg = CDBManager::instance().DirectQuery(szQuery);
|
||||
|
||||
if (pMsg != NULL)
|
||||
{
|
||||
if (pMsg->Get()->uiNumRows > 0)
|
||||
{
|
||||
DWORD count = 0;
|
||||
row = mysql_fetch_row(pMsg->Get()->pSQLResult);
|
||||
str_to_number(count, row[0]);
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
sys_err("ItemIDRange: Build: %u ~ %u\thave a item", range.dwUsableItemIDMin, range.dwMax);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
sys_log(0, "ItemIDRange: Build: %u ~ %u start:%u", range.dwMin, range.dwMax, range.dwUsableItemIDMin);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
delete pMsg;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CItemIDRangeManager::UpdateRange(DWORD dwMin, DWORD dwMax)
|
||||
{
|
||||
TItemIDRangeTable range;
|
||||
|
||||
if (BuildRange(dwMin, dwMax, range) == true)
|
||||
{
|
||||
m_listData.push_back(range);
|
||||
}
|
||||
}
|
||||
|
24
db/src/ItemIDRangeManager.h
Normal file
24
db/src/ItemIDRangeManager.h
Normal file
@ -0,0 +1,24 @@
|
||||
// vim:ts=4 sw=4
|
||||
#ifndef __INC_METIN_II_ITEM_ID_RANGE_MANAGER_H__
|
||||
#define __INC_METIN_II_ITEM_ID_RANGE_MANAGER_H__
|
||||
|
||||
class CItemIDRangeManager : public singleton<CItemIDRangeManager>
|
||||
{
|
||||
private :
|
||||
const static DWORD cs_dwMaxItemID = 4290000000UL;
|
||||
const static DWORD cs_dwMinimumRange = 10000000UL;
|
||||
const static DWORD cs_dwMinimumRemainCount = 10000UL;
|
||||
|
||||
std::list<TItemIDRangeTable> m_listData;
|
||||
|
||||
public :
|
||||
CItemIDRangeManager();
|
||||
|
||||
void Build();
|
||||
bool BuildRange(DWORD dwMin, DWORD dwMax, TItemIDRangeTable& range);
|
||||
void UpdateRange(DWORD dwMin, DWORD dwMax);
|
||||
|
||||
TItemIDRangeTable GetRange();
|
||||
};
|
||||
|
||||
#endif
|
60
db/src/Lock.cpp
Normal file
60
db/src/Lock.cpp
Normal file
@ -0,0 +1,60 @@
|
||||
#include "stdafx.h"
|
||||
#include "Lock.h"
|
||||
|
||||
CLock::CLock()
|
||||
{
|
||||
}
|
||||
|
||||
CLock::~CLock()
|
||||
{
|
||||
}
|
||||
|
||||
void CLock::Initialize()
|
||||
{
|
||||
m_bLocked = false;
|
||||
#ifndef __WIN32__
|
||||
pthread_mutex_init(&m_lock, NULL);
|
||||
#else
|
||||
::InitializeCriticalSection(&m_lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CLock::Destroy()
|
||||
{
|
||||
assert(!m_bLocked && "lock didn't released");
|
||||
#ifndef __WIN32__
|
||||
pthread_mutex_destroy(&m_lock);
|
||||
#else
|
||||
::DeleteCriticalSection(&m_lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
int CLock::Trylock()
|
||||
{
|
||||
#ifndef __WIN32__
|
||||
return pthread_mutex_trylock(&m_lock);
|
||||
#else
|
||||
return ::TryEnterCriticalSection(&m_lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CLock::Lock()
|
||||
{
|
||||
#ifndef __WIN32__
|
||||
pthread_mutex_lock(&m_lock);
|
||||
#else
|
||||
::EnterCriticalSection(&m_lock);
|
||||
#endif
|
||||
m_bLocked = true;
|
||||
}
|
||||
|
||||
void CLock::Unlock()
|
||||
{
|
||||
assert(m_bLocked && "lock didn't issued");
|
||||
m_bLocked = false;
|
||||
#ifndef __WIN32__
|
||||
pthread_mutex_unlock(&m_lock);
|
||||
#else
|
||||
::LeaveCriticalSection(&m_lock);
|
||||
#endif
|
||||
}
|
27
db/src/Lock.h
Normal file
27
db/src/Lock.h
Normal file
@ -0,0 +1,27 @@
|
||||
// vim:ts=8 sw=4
|
||||
#ifndef __INC_LOCK_H__
|
||||
#define __INC_LOCK_H__
|
||||
|
||||
#ifdef __WIN32__
|
||||
typedef CRITICAL_SECTION lock_t;
|
||||
#else
|
||||
typedef pthread_mutex_t lock_t;
|
||||
#endif
|
||||
|
||||
class CLock
|
||||
{
|
||||
public:
|
||||
CLock();
|
||||
~CLock();
|
||||
|
||||
void Initialize();
|
||||
void Destroy();
|
||||
int Trylock();
|
||||
void Lock();
|
||||
void Unlock();
|
||||
|
||||
private:
|
||||
lock_t m_lock;
|
||||
bool m_bLocked;
|
||||
};
|
||||
#endif
|
123
db/src/LoginData.cpp
Normal file
123
db/src/LoginData.cpp
Normal file
@ -0,0 +1,123 @@
|
||||
#include "stdafx.h"
|
||||
#include "LoginData.h"
|
||||
#include "ClientManager.h"
|
||||
|
||||
CLoginData::CLoginData()
|
||||
{
|
||||
m_dwKey = 0;
|
||||
memset(m_adwClientKey, 0, sizeof(m_adwClientKey));
|
||||
m_dwConnectedPeerHandle = 0;
|
||||
m_dwLogonTime = 0;
|
||||
memset(m_szIP, 0, sizeof(m_szIP));
|
||||
m_bPlay = false;
|
||||
m_bDeleted = false;
|
||||
m_bBillType = 0;
|
||||
m_dwBillID = 0;
|
||||
m_lastPlayTime = 0;
|
||||
m_dwLastPlayerID = 0;
|
||||
|
||||
memset(&m_data, 0, sizeof(TAccountTable));
|
||||
}
|
||||
|
||||
TAccountTable & CLoginData::GetAccountRef()
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
void CLoginData::SetClientKey(const DWORD * c_pdwClientKey)
|
||||
{
|
||||
thecore_memcpy(&m_adwClientKey, c_pdwClientKey, sizeof(DWORD) * 4);
|
||||
}
|
||||
|
||||
const DWORD * CLoginData::GetClientKey()
|
||||
{
|
||||
return &m_adwClientKey[0];
|
||||
}
|
||||
|
||||
void CLoginData::SetKey(DWORD dwKey)
|
||||
{
|
||||
m_dwKey = dwKey;
|
||||
}
|
||||
|
||||
DWORD CLoginData::GetKey()
|
||||
{
|
||||
return m_dwKey;
|
||||
}
|
||||
|
||||
void CLoginData::SetConnectedPeerHandle(DWORD dwHandle)
|
||||
{
|
||||
m_dwConnectedPeerHandle = dwHandle;
|
||||
}
|
||||
|
||||
DWORD CLoginData::GetConnectedPeerHandle()
|
||||
{
|
||||
return m_dwConnectedPeerHandle;
|
||||
}
|
||||
|
||||
void CLoginData::SetLogonTime()
|
||||
{
|
||||
m_dwLogonTime = get_dword_time();
|
||||
}
|
||||
|
||||
DWORD CLoginData::GetLogonTime()
|
||||
{
|
||||
return m_dwLogonTime;
|
||||
}
|
||||
|
||||
void CLoginData::SetIP(const char * c_pszIP)
|
||||
{
|
||||
strlcpy(m_szIP, c_pszIP, sizeof(m_szIP));
|
||||
}
|
||||
|
||||
const char * CLoginData::GetIP()
|
||||
{
|
||||
return m_szIP;
|
||||
}
|
||||
|
||||
void CLoginData::SetPlay(bool bOn)
|
||||
{
|
||||
if (bOn)
|
||||
{
|
||||
sys_log(0, "SetPlay on %lu %s", GetKey(), m_data.login);
|
||||
SetLogonTime();
|
||||
}
|
||||
else
|
||||
sys_log(0, "SetPlay off %lu %s", GetKey(), m_data.login);
|
||||
|
||||
m_bPlay = bOn;
|
||||
m_lastPlayTime = CClientManager::instance().GetCurrentTime();
|
||||
}
|
||||
|
||||
bool CLoginData::IsPlay()
|
||||
{
|
||||
return m_bPlay;
|
||||
}
|
||||
|
||||
void CLoginData::SetDeleted(bool bSet)
|
||||
{
|
||||
m_bDeleted = bSet;
|
||||
}
|
||||
|
||||
bool CLoginData::IsDeleted()
|
||||
{
|
||||
return m_bDeleted;
|
||||
}
|
||||
|
||||
void CLoginData::SetPremium(int * paiPremiumTimes)
|
||||
{
|
||||
thecore_memcpy(m_aiPremiumTimes, paiPremiumTimes, sizeof(m_aiPremiumTimes));
|
||||
}
|
||||
|
||||
int CLoginData::GetPremium(BYTE type)
|
||||
{
|
||||
if (type >= PREMIUM_MAX_NUM)
|
||||
return 0;
|
||||
|
||||
return m_aiPremiumTimes[type];
|
||||
}
|
||||
|
||||
int * CLoginData::GetPremiumPtr()
|
||||
{
|
||||
return &m_aiPremiumTimes[0];
|
||||
}
|
||||
|
66
db/src/LoginData.h
Normal file
66
db/src/LoginData.h
Normal file
@ -0,0 +1,66 @@
|
||||
// vim:ts=8 sw=4
|
||||
#ifndef __INC_METIN_II_DB_LOGINDATA_H__
|
||||
#define __INC_METIN_II_DB_LOGINDATA_H__
|
||||
|
||||
class CLoginData
|
||||
{
|
||||
public:
|
||||
CLoginData();
|
||||
|
||||
TAccountTable & GetAccountRef();
|
||||
void SetClientKey(const DWORD * c_pdwClientKey);
|
||||
|
||||
const DWORD * GetClientKey();
|
||||
void SetKey(DWORD dwKey);
|
||||
DWORD GetKey();
|
||||
|
||||
void SetConnectedPeerHandle(DWORD dwHandle);
|
||||
DWORD GetConnectedPeerHandle();
|
||||
|
||||
void SetLogonTime();
|
||||
DWORD GetLogonTime();
|
||||
|
||||
void SetIP(const char * c_pszIP);
|
||||
const char * GetIP();
|
||||
|
||||
void SetPlay(bool bOn);
|
||||
bool IsPlay();
|
||||
|
||||
void SetDeleted(bool bSet);
|
||||
bool IsDeleted();
|
||||
|
||||
void SetBillID(DWORD id) { m_dwBillID = id; }
|
||||
DWORD GetBillID() { return m_dwBillID; }
|
||||
|
||||
void SetBillType(BYTE type) { m_bBillType = type; }
|
||||
BYTE GetBillType() { return m_bBillType; }
|
||||
|
||||
time_t GetLastPlayTime() { return m_lastPlayTime; }
|
||||
|
||||
void SetPremium(int * paiPremiumTimes);
|
||||
int GetPremium(BYTE type);
|
||||
int * GetPremiumPtr();
|
||||
|
||||
DWORD GetLastPlayerID() const { return m_dwLastPlayerID; }
|
||||
void SetLastPlayerID(DWORD id) { m_dwLastPlayerID = id; }
|
||||
|
||||
private:
|
||||
DWORD m_dwKey;
|
||||
DWORD m_adwClientKey[4];
|
||||
DWORD m_dwConnectedPeerHandle;
|
||||
DWORD m_dwLogonTime;
|
||||
char m_szIP[MAX_HOST_LENGTH+1];
|
||||
bool m_bPlay;
|
||||
bool m_bDeleted;
|
||||
|
||||
BYTE m_bBillType;
|
||||
DWORD m_dwBillID;
|
||||
time_t m_lastPlayTime;
|
||||
int m_aiPremiumTimes[PREMIUM_MAX_NUM];
|
||||
|
||||
DWORD m_dwLastPlayerID;
|
||||
|
||||
TAccountTable m_data;
|
||||
};
|
||||
|
||||
#endif
|
430
db/src/Main.cpp
Normal file
430
db/src/Main.cpp
Normal file
@ -0,0 +1,430 @@
|
||||
#include "stdafx.h"
|
||||
#include "Config.h"
|
||||
#include "Peer.h"
|
||||
#include "DBManager.h"
|
||||
#include "ClientManager.h"
|
||||
#include "GuildManager.h"
|
||||
#include "ItemAwardManager.h"
|
||||
#include "HB.h"
|
||||
#include "PrivManager.h"
|
||||
#include "MoneyLog.h"
|
||||
#include "Marriage.h"
|
||||
#include "Monarch.h"
|
||||
#include "BlockCountry.h"
|
||||
#include "ItemIDRangeManager.h"
|
||||
#ifdef __AUCTION__
|
||||
#include "AuctionManager.h"
|
||||
#endif
|
||||
#include <signal.h>
|
||||
|
||||
void SetPlayerDBName(const char* c_pszPlayerDBName);
|
||||
void SetTablePostfix(const char* c_pszTablePostfix);
|
||||
int Start();
|
||||
|
||||
std::string g_stTablePostfix;
|
||||
std::string g_stLocaleNameColumn = "name";
|
||||
std::string g_stLocale = "euckr";
|
||||
std::string g_stPlayerDBName = "";
|
||||
|
||||
|
||||
bool g_bHotBackup = false;
|
||||
BOOL g_test_server = false;
|
||||
|
||||
//<2F><><EFBFBD><EFBFBD> <20><>
|
||||
int g_iPlayerCacheFlushSeconds = 60*7;
|
||||
int g_iItemCacheFlushSeconds = 60*5;
|
||||
|
||||
//g_iLogoutSeconds <20><>ġ<EFBFBD><C4A1> g_iPlayerCacheFlushSeconds <20><> g_iItemCacheFlushSeconds <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
|
||||
int g_iLogoutSeconds = 60*10;
|
||||
|
||||
int g_log = 1;
|
||||
|
||||
|
||||
// MYSHOP_PRICE_LIST
|
||||
int g_iItemPriceListTableCacheFlushSeconds = 540;
|
||||
// END_OF_MYSHOP_PRICE_LIST
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
extern const char * _malloc_options;
|
||||
#endif
|
||||
|
||||
extern void WriteVersion();
|
||||
|
||||
void emergency_sig(int sig)
|
||||
{
|
||||
if (sig == SIGSEGV)
|
||||
sys_log(0, "SIGNAL: SIGSEGV");
|
||||
else if (sig == SIGUSR1)
|
||||
sys_log(0, "SIGNAL: SIGUSR1");
|
||||
|
||||
if (sig == SIGSEGV)
|
||||
abort();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
WriteVersion();
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
_malloc_options = "A";
|
||||
#endif
|
||||
|
||||
CConfig Config;
|
||||
CNetPoller poller;
|
||||
CDBManager DBManager;
|
||||
CClientManager ClientManager;
|
||||
PlayerHB player_hb;
|
||||
CGuildManager GuildManager;
|
||||
CPrivManager PrivManager;
|
||||
CMoneyLog MoneyLog;
|
||||
ItemAwardManager ItemAwardManager;
|
||||
marriage::CManager MarriageManager;
|
||||
CMonarch Monarch;
|
||||
CBlockCountry BlockCountry;
|
||||
CItemIDRangeManager ItemIDRangeManager;
|
||||
#ifdef __AUCTION__
|
||||
AuctionManager auctionManager;
|
||||
#endif
|
||||
if (!Start())
|
||||
return 1;
|
||||
|
||||
GuildManager.Initialize();
|
||||
MarriageManager.Initialize();
|
||||
BlockCountry.Load();
|
||||
ItemIDRangeManager.Build();
|
||||
#ifdef __AUCTION__
|
||||
AuctionManager::instance().Initialize();
|
||||
#endif
|
||||
sys_log(0, "Metin2DBCacheServer Start\n");
|
||||
|
||||
CClientManager::instance().MainLoop();
|
||||
|
||||
signal_timer_disable();
|
||||
|
||||
DBManager.Quit();
|
||||
int iCount;
|
||||
|
||||
while (1)
|
||||
{
|
||||
iCount = 0;
|
||||
|
||||
iCount += CDBManager::instance().CountReturnQuery(SQL_PLAYER);
|
||||
iCount += CDBManager::instance().CountAsyncQuery(SQL_PLAYER);
|
||||
|
||||
if (iCount == 0)
|
||||
break;
|
||||
|
||||
usleep(1000);
|
||||
sys_log(0, "WAITING_QUERY_COUNT %d", iCount);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void emptybeat(LPHEART heart, int pulse)
|
||||
{
|
||||
if (!(pulse % heart->passes_per_sec)) // 1<>ʿ<EFBFBD> <20>ѹ<EFBFBD>
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// @version 05/06/13 Bang2ni - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ij<><C4B3> flush timeout <20><><EFBFBD><EFBFBD> <20>߰<EFBFBD>.
|
||||
//
|
||||
int Start()
|
||||
{
|
||||
if (!CConfig::instance().LoadFile("conf.txt"))
|
||||
{
|
||||
fprintf(stderr, "Loading conf.txt failed.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CConfig::instance().GetValue("TEST_SERVER", &g_test_server))
|
||||
{
|
||||
fprintf(stderr, "Real Server\n");
|
||||
}
|
||||
else
|
||||
fprintf(stderr, "Test Server\n");
|
||||
|
||||
if (!CConfig::instance().GetValue("LOG", &g_log))
|
||||
{
|
||||
fprintf(stderr, "Log Off");
|
||||
g_log= 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_log = 1;
|
||||
fprintf(stderr, "Log On");
|
||||
}
|
||||
|
||||
|
||||
int tmpValue;
|
||||
|
||||
int heart_beat = 50;
|
||||
if (!CConfig::instance().GetValue("CLIENT_HEART_FPS", &heart_beat))
|
||||
{
|
||||
fprintf(stderr, "Cannot find CLIENT_HEART_FPS configuration.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
log_set_expiration_days(3);
|
||||
|
||||
if (CConfig::instance().GetValue("LOG_KEEP_DAYS", &tmpValue))
|
||||
{
|
||||
tmpValue = MINMAX(3, tmpValue, 30);
|
||||
log_set_expiration_days(tmpValue);
|
||||
fprintf(stderr, "Setting log keeping days to %d\n", tmpValue);
|
||||
}
|
||||
|
||||
thecore_init(heart_beat, emptybeat);
|
||||
signal_timer_enable(60);
|
||||
|
||||
char szBuf[256+1];
|
||||
|
||||
if (CConfig::instance().GetValue("LOCALE", szBuf, 256))
|
||||
{
|
||||
g_stLocale = szBuf;
|
||||
sys_log(0, "LOCALE set to %s", g_stLocale.c_str());
|
||||
|
||||
// CHINA_DISABLE_HOTBACKUP
|
||||
if ("gb2312" == g_stLocale)
|
||||
{
|
||||
sys_log(0, "CIBN_LOCALE: DISABLE_HOTBACKUP");
|
||||
g_bHotBackup = false;
|
||||
}
|
||||
// END_OF_CHINA_DISABLE_HOTBACKUP
|
||||
}
|
||||
|
||||
int iDisableHotBackup;
|
||||
if (CConfig::instance().GetValue("DISABLE_HOTBACKUP", &iDisableHotBackup))
|
||||
{
|
||||
if (iDisableHotBackup)
|
||||
{
|
||||
sys_log(0, "CONFIG: DISABLE_HOTBACKUP");
|
||||
g_bHotBackup = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!CConfig::instance().GetValue("TABLE_POSTFIX", szBuf, 256))
|
||||
{
|
||||
sys_err("TABLE_POSTFIX not configured use default");
|
||||
szBuf[0] = '\0';
|
||||
}
|
||||
|
||||
SetTablePostfix(szBuf);
|
||||
|
||||
if (CConfig::instance().GetValue("PLAYER_CACHE_FLUSH_SECONDS", szBuf, 256))
|
||||
{
|
||||
str_to_number(g_iPlayerCacheFlushSeconds, szBuf);
|
||||
sys_log(0, "PLAYER_CACHE_FLUSH_SECONDS: %d", g_iPlayerCacheFlushSeconds);
|
||||
}
|
||||
|
||||
if (CConfig::instance().GetValue("ITEM_CACHE_FLUSH_SECONDS", szBuf, 256))
|
||||
{
|
||||
str_to_number(g_iItemCacheFlushSeconds, szBuf);
|
||||
sys_log(0, "ITEM_CACHE_FLUSH_SECONDS: %d", g_iItemCacheFlushSeconds);
|
||||
}
|
||||
|
||||
// MYSHOP_PRICE_LIST
|
||||
if (CConfig::instance().GetValue("ITEM_PRICELIST_CACHE_FLUSH_SECONDS", szBuf, 256))
|
||||
{
|
||||
str_to_number(g_iItemPriceListTableCacheFlushSeconds, szBuf);
|
||||
sys_log(0, "ITEM_PRICELIST_CACHE_FLUSH_SECONDS: %d", g_iItemPriceListTableCacheFlushSeconds);
|
||||
}
|
||||
// END_OF_MYSHOP_PRICE_LIST
|
||||
//
|
||||
if (CConfig::instance().GetValue("CACHE_FLUSH_LIMIT_PER_SECOND", szBuf, 256))
|
||||
{
|
||||
DWORD dwVal = 0; str_to_number(dwVal, szBuf);
|
||||
CClientManager::instance().SetCacheFlushCountLimit(dwVal);
|
||||
}
|
||||
|
||||
int iIDStart;
|
||||
if (!CConfig::instance().GetValue("PLAYER_ID_START", &iIDStart))
|
||||
{
|
||||
sys_err("PLAYER_ID_START not configured");
|
||||
return false;
|
||||
}
|
||||
|
||||
CClientManager::instance().SetPlayerIDStart(iIDStart);
|
||||
|
||||
if (CConfig::instance().GetValue("NAME_COLUMN", szBuf, 256))
|
||||
{
|
||||
fprintf(stderr, "%s %s", g_stLocaleNameColumn.c_str(), szBuf);
|
||||
g_stLocaleNameColumn = szBuf;
|
||||
}
|
||||
|
||||
char szAddr[64], szDB[64], szUser[64], szPassword[64];
|
||||
int iPort;
|
||||
char line[256+1];
|
||||
|
||||
if (CConfig::instance().GetValue("SQL_PLAYER", line, 256))
|
||||
{
|
||||
sscanf(line, " %s %s %s %s %d ", szAddr, szDB, szUser, szPassword, &iPort);
|
||||
sys_log(0, "connecting to MySQL server (player)");
|
||||
|
||||
int iRetry = 5;
|
||||
|
||||
do
|
||||
{
|
||||
if (CDBManager::instance().Connect(SQL_PLAYER, szAddr, iPort, szDB, szUser, szPassword))
|
||||
{
|
||||
sys_log(0, " OK");
|
||||
break;
|
||||
}
|
||||
|
||||
sys_log(0, " failed, retrying in 5 seconds");
|
||||
fprintf(stderr, " failed, retrying in 5 seconds");
|
||||
sleep(5);
|
||||
} while (iRetry--);
|
||||
fprintf(stderr, "Success PLAYER\n");
|
||||
SetPlayerDBName(szDB);
|
||||
}
|
||||
else
|
||||
{
|
||||
sys_err("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);
|
||||
sys_log(0, "connecting to MySQL server (account)");
|
||||
|
||||
int iRetry = 5;
|
||||
|
||||
do
|
||||
{
|
||||
if (CDBManager::instance().Connect(SQL_ACCOUNT, szAddr, iPort, szDB, szUser, szPassword))
|
||||
{
|
||||
sys_log(0, " OK");
|
||||
break;
|
||||
}
|
||||
|
||||
sys_log(0, " failed, retrying in 5 seconds");
|
||||
fprintf(stderr, " failed, retrying in 5 seconds");
|
||||
sleep(5);
|
||||
} while (iRetry--);
|
||||
fprintf(stderr, "Success ACCOUNT\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
sys_err("SQL_ACCOUNT not configured");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (CConfig::instance().GetValue("SQL_COMMON", line, 256))
|
||||
{
|
||||
sscanf(line, " %s %s %s %s %d ", szAddr, szDB, szUser, szPassword, &iPort);
|
||||
sys_log(0, "connecting to MySQL server (common)");
|
||||
|
||||
int iRetry = 5;
|
||||
|
||||
do
|
||||
{
|
||||
if (CDBManager::instance().Connect(SQL_COMMON, szAddr, iPort, szDB, szUser, szPassword))
|
||||
{
|
||||
sys_log(0, " OK");
|
||||
break;
|
||||
}
|
||||
|
||||
sys_log(0, " failed, retrying in 5 seconds");
|
||||
fprintf(stderr, " failed, retrying in 5 seconds");
|
||||
sleep(5);
|
||||
} while (iRetry--);
|
||||
fprintf(stderr, "Success COMMON\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
sys_err("SQL_COMMON not configured");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (CConfig::instance().GetValue("SQL_HOTBACKUP", line, 256))
|
||||
{
|
||||
sscanf(line, " %s %s %s %s %d ", szAddr, szDB, szUser, szPassword, &iPort);
|
||||
sys_log(0, "connecting to MySQL server (hotbackup)");
|
||||
|
||||
int iRetry = 5;
|
||||
|
||||
do
|
||||
{
|
||||
if (CDBManager::instance().Connect(SQL_HOTBACKUP, szAddr, iPort, szDB, szUser, szPassword))
|
||||
{
|
||||
sys_log(0, " OK");
|
||||
break;
|
||||
}
|
||||
|
||||
sys_log(0, " failed, retrying in 5 seconds");
|
||||
fprintf(stderr, " failed, retrying in 5 seconds");
|
||||
sleep(5);
|
||||
}
|
||||
while (iRetry--);
|
||||
|
||||
fprintf(stderr, "Success HOTBACKUP\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
sys_err("SQL_HOTBACKUP not configured");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CNetPoller::instance().Create())
|
||||
{
|
||||
sys_err("Cannot create network poller");
|
||||
return false;
|
||||
}
|
||||
|
||||
sys_log(0, "ClientManager initialization.. ");
|
||||
|
||||
if (!CClientManager::instance().Initialize())
|
||||
{
|
||||
sys_log(0, " failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
sys_log(0, " OK");
|
||||
|
||||
if (!PlayerHB::instance().Initialize())
|
||||
{
|
||||
sys_err("cannot initialize player hotbackup");
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifndef __WIN32__
|
||||
signal(SIGUSR1, emergency_sig);
|
||||
#endif
|
||||
signal(SIGSEGV, emergency_sig);
|
||||
return true;
|
||||
}
|
||||
|
||||
void SetTablePostfix(const char* c_pszTablePostfix)
|
||||
{
|
||||
if (!c_pszTablePostfix || !*c_pszTablePostfix)
|
||||
g_stTablePostfix = "";
|
||||
else
|
||||
g_stTablePostfix = c_pszTablePostfix;
|
||||
}
|
||||
|
||||
const char * GetTablePostfix()
|
||||
{
|
||||
return g_stTablePostfix.c_str();
|
||||
}
|
||||
|
||||
void SetPlayerDBName(const char* c_pszPlayerDBName)
|
||||
{
|
||||
if (! c_pszPlayerDBName || ! *c_pszPlayerDBName)
|
||||
g_stPlayerDBName = "";
|
||||
else
|
||||
{
|
||||
g_stPlayerDBName = c_pszPlayerDBName;
|
||||
g_stPlayerDBName += ".";
|
||||
}
|
||||
}
|
||||
|
||||
const char * GetPlayerDBName()
|
||||
{
|
||||
return g_stPlayerDBName.c_str();
|
||||
}
|
||||
|
9
db/src/Main.h
Normal file
9
db/src/Main.h
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef __INC_MAIN_H__
|
||||
#define __INC_MAIN_H__
|
||||
|
||||
int Start();
|
||||
void End();
|
||||
const char * GetTablePostfix();
|
||||
const char * GetPlayerDBName();
|
||||
|
||||
#endif
|
382
db/src/Marriage.cpp
Normal file
382
db/src/Marriage.cpp
Normal file
@ -0,0 +1,382 @@
|
||||
#include "stdafx.h"
|
||||
#include "Marriage.h"
|
||||
#include "Main.h"
|
||||
#include "DBManager.h"
|
||||
#include "ClientManager.h"
|
||||
|
||||
namespace marriage
|
||||
{
|
||||
const DWORD WEDDING_LENGTH = 60 * 60; // sec
|
||||
bool operator < (const TWedding& lhs, const TWedding& rhs)
|
||||
{
|
||||
return lhs.dwTime < rhs.dwTime;
|
||||
}
|
||||
|
||||
bool operator > (const TWedding& lhs, const TWedding& rhs)
|
||||
{
|
||||
return lhs.dwTime > rhs.dwTime;
|
||||
}
|
||||
|
||||
bool operator > (const TWeddingInfo &lhs, const TWeddingInfo& rhs)
|
||||
{
|
||||
return lhs.dwTime > rhs.dwTime;
|
||||
}
|
||||
|
||||
using namespace std;
|
||||
|
||||
CManager::CManager()
|
||||
{
|
||||
}
|
||||
|
||||
CManager::~CManager()
|
||||
{
|
||||
}
|
||||
|
||||
bool CManager::Initialize()
|
||||
{
|
||||
char szQuery[1024];
|
||||
|
||||
snprintf(szQuery, sizeof(szQuery),
|
||||
"SELECT pid1, pid2, love_point, time, is_married, p1.name, p2.name FROM marriage, player%s as p1, player%s as p2 WHERE p1.id = pid1 AND p2.id = pid2",
|
||||
GetTablePostfix(), GetTablePostfix());
|
||||
|
||||
auto_ptr<SQLMsg> pmsg_delete(CDBManager::instance().DirectQuery("DELETE FROM marriage WHERE is_married = 0"));
|
||||
auto_ptr<SQLMsg> pmsg(CDBManager::instance().DirectQuery(szQuery));
|
||||
|
||||
SQLResult * pRes = pmsg->Get();
|
||||
sys_log(0, "MarriageList(size=%lu)", pRes->uiNumRows);
|
||||
|
||||
if (pRes->uiNumRows > 0)
|
||||
{
|
||||
for (uint uiRow = 0; uiRow != pRes->uiNumRows; ++uiRow)
|
||||
{
|
||||
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];
|
||||
|
||||
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));
|
||||
|
||||
sys_log(0, "Marriage %lu: LP:%d TM:%u ST:%d %10lu:%16s %10lu:%16s ", uiRow, love_point, time, is_married, pid1, name1, pid2, name2);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
TMarriage* CManager::Get(DWORD dwPlayerID)
|
||||
{
|
||||
itertype(m_MarriageByPID) it = m_MarriageByPID.find(dwPlayerID);
|
||||
|
||||
if (it != m_MarriageByPID.end())
|
||||
return it->second;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
DWORD now = CClientManager::instance().GetCurrentTime();
|
||||
if (IsMarried(dwPID1) || IsMarried(dwPID2))
|
||||
{
|
||||
sys_err("cannot marry already married character. %d - %d", dwPID1, dwPID2);
|
||||
return;
|
||||
}
|
||||
|
||||
Align(dwPID1, dwPID2);
|
||||
|
||||
char szQuery[512];
|
||||
snprintf(szQuery, sizeof(szQuery), "INSERT INTO marriage(pid1, pid2, love_point, time) VALUES (%u, %u, 0, %u)", dwPID1, dwPID2, now);
|
||||
|
||||
auto_ptr<SQLMsg> pmsg(CDBManager::instance().DirectQuery(szQuery));
|
||||
|
||||
SQLResult* res = pmsg->Get();
|
||||
if (res->uiAffectedRows == 0 || res->uiAffectedRows == (uint32_t)-1)
|
||||
{
|
||||
sys_err("cannot insert marriage");
|
||||
return;
|
||||
}
|
||||
|
||||
sys_log(0, "MARRIAGE ADD %u %u", dwPID1, dwPID2);
|
||||
|
||||
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));
|
||||
|
||||
TPacketMarriageAdd p;
|
||||
p.dwPID1 = dwPID1;
|
||||
p.dwPID2 = dwPID2;
|
||||
p.tMarryTime = now;
|
||||
strlcpy(p.szName1, szName1, sizeof(p.szName1));
|
||||
strlcpy(p.szName2, szName2, sizeof(p.szName2));
|
||||
CClientManager::instance().ForwardPacket(HEADER_DG_MARRIAGE_ADD, &p, sizeof(p));
|
||||
}
|
||||
|
||||
void CManager::Update(DWORD dwPID1, DWORD dwPID2, INT iLovePoint, BYTE byMarried)
|
||||
{
|
||||
TMarriage* pMarriage = Get(dwPID1);
|
||||
if (!pMarriage || pMarriage->GetOther(dwPID1) != dwPID2)
|
||||
{
|
||||
sys_err("not under marriage : %u %u", dwPID1, dwPID2);
|
||||
return;
|
||||
}
|
||||
|
||||
Align(dwPID1, dwPID2);
|
||||
|
||||
char szQuery[512];
|
||||
snprintf(szQuery, sizeof(szQuery), "UPDATE marriage SET love_point = %d, is_married = %d WHERE pid1 = %u AND pid2 = %u",
|
||||
iLovePoint, byMarried, pMarriage->pid1, pMarriage->pid2);
|
||||
|
||||
auto_ptr<SQLMsg> pmsg(CDBManager::instance().DirectQuery(szQuery));
|
||||
|
||||
SQLResult* res = pmsg->Get();
|
||||
if (res->uiAffectedRows == 0 || res->uiAffectedRows == (uint32_t)-1)
|
||||
{
|
||||
sys_err("cannot update marriage : PID:%u %u", dwPID1, dwPID2);
|
||||
return;
|
||||
}
|
||||
|
||||
sys_log(0, "MARRIAGE UPDATE PID:%u %u LP:%u ST:%d", dwPID1, dwPID2, iLovePoint, byMarried);
|
||||
pMarriage->love_point = iLovePoint;
|
||||
pMarriage->is_married = byMarried;
|
||||
|
||||
TPacketMarriageUpdate p;
|
||||
p.dwPID1 = dwPID1;
|
||||
p.dwPID2 = dwPID2;
|
||||
p.iLovePoint = pMarriage->love_point;
|
||||
p.byMarried = pMarriage->is_married;
|
||||
CClientManager::instance().ForwardPacket(HEADER_DG_MARRIAGE_UPDATE, &p, sizeof(p));
|
||||
}
|
||||
|
||||
void CManager::Remove(DWORD dwPID1, DWORD dwPID2)
|
||||
{
|
||||
TMarriage* pMarriage = Get(dwPID1);
|
||||
|
||||
if (pMarriage)
|
||||
{
|
||||
sys_log(0, "Break Marriage pid1 %d pid2 %d Other %d", dwPID1, dwPID2, pMarriage->GetOther(dwPID1));
|
||||
}
|
||||
if (!pMarriage || pMarriage->GetOther(dwPID1) != dwPID2)
|
||||
{
|
||||
itertype(m_MarriageByPID) it = m_MarriageByPID.begin();
|
||||
|
||||
for (; it != m_MarriageByPID.end(); ++it)
|
||||
{
|
||||
sys_log(0, "Marriage List pid1 %d pid2 %d", it->second->pid1, it->second->pid2);
|
||||
}
|
||||
sys_err("not under marriage : PID:%u %u", dwPID1, dwPID2);
|
||||
return;
|
||||
}
|
||||
|
||||
Align(dwPID1, dwPID2);
|
||||
|
||||
char szQuery[512];
|
||||
snprintf(szQuery, sizeof(szQuery), "DELETE FROM marriage WHERE pid1 = %u AND pid2 = %u", dwPID1, dwPID2);
|
||||
|
||||
auto_ptr<SQLMsg> pmsg(CDBManager::instance().DirectQuery(szQuery));
|
||||
|
||||
SQLResult* res = pmsg->Get();
|
||||
if (res->uiAffectedRows == 0 || res->uiAffectedRows == (uint32_t)-1)
|
||||
{
|
||||
sys_err("cannot delete marriage : PID:%u %u", dwPID1, dwPID2);
|
||||
return;
|
||||
}
|
||||
|
||||
sys_log(0, "MARRIAGE REMOVE PID:%u %u", dwPID1, dwPID2);
|
||||
|
||||
m_Marriages.erase(pMarriage);
|
||||
m_MarriageByPID.erase(dwPID1);
|
||||
m_MarriageByPID.erase(dwPID2);
|
||||
|
||||
TPacketMarriageRemove p;
|
||||
p.dwPID1 = dwPID1;
|
||||
p.dwPID2 = dwPID2;
|
||||
CClientManager::instance().ForwardPacket(HEADER_DG_MARRIAGE_REMOVE, &p, sizeof(p));
|
||||
|
||||
delete pMarriage;
|
||||
}
|
||||
|
||||
void CManager::EngageToMarriage(DWORD dwPID1, DWORD dwPID2)
|
||||
{
|
||||
TMarriage* pMarriage = Get(dwPID1);
|
||||
if (!pMarriage || pMarriage->GetOther(dwPID1) != dwPID2)
|
||||
{
|
||||
sys_err("not under marriage : PID:%u %u", dwPID1, dwPID2);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pMarriage->is_married)
|
||||
{
|
||||
sys_err("already married, cannot change engage to marry : PID:%u %u", dwPID1, dwPID2);
|
||||
return;
|
||||
}
|
||||
|
||||
Align(dwPID1, dwPID2);
|
||||
|
||||
char szQuery[512];
|
||||
snprintf(szQuery, sizeof(szQuery), "UPDATE marriage SET is_married = 1 WHERE pid1 = %u AND pid2 = %u",
|
||||
pMarriage->pid1, pMarriage->pid2);
|
||||
|
||||
auto_ptr<SQLMsg> pmsg(CDBManager::instance().DirectQuery(szQuery));
|
||||
|
||||
SQLResult* res = pmsg->Get();
|
||||
if (res->uiAffectedRows == 0 || res->uiAffectedRows == (uint32_t)-1)
|
||||
{
|
||||
sys_err("cannot change engage to marriage : PID:%u %u", dwPID1, dwPID2);
|
||||
return;
|
||||
}
|
||||
|
||||
sys_log(0, "MARRIAGE ENGAGE->MARRIAGE PID:%u %u", dwPID1, dwPID2);
|
||||
pMarriage->is_married = 1;
|
||||
|
||||
TPacketMarriageUpdate p;
|
||||
p.dwPID1 = dwPID1;
|
||||
p.dwPID2 = dwPID2;
|
||||
p.iLovePoint = pMarriage->love_point;
|
||||
p.byMarried = pMarriage->is_married;
|
||||
CClientManager::instance().ForwardPacket(HEADER_DG_MARRIAGE_UPDATE, &p, sizeof(p));
|
||||
}
|
||||
|
||||
void CManager::OnSetup(CPeer* peer)
|
||||
{
|
||||
// <20><>ȥ<EFBFBD><C8A5> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
for (itertype(m_Marriages) it = m_Marriages.begin(); it != m_Marriages.end(); ++it)
|
||||
{
|
||||
TMarriage* pMarriage = *it;
|
||||
|
||||
{
|
||||
TPacketMarriageAdd p;
|
||||
p.dwPID1 = pMarriage->pid1;
|
||||
p.dwPID2 = pMarriage->pid2;
|
||||
p.tMarryTime = pMarriage->time;
|
||||
strlcpy(p.szName1, pMarriage->name1.c_str(), sizeof(p.szName1));
|
||||
strlcpy(p.szName2, pMarriage->name2.c_str(), sizeof(p.szName2));
|
||||
peer->EncodeHeader(HEADER_DG_MARRIAGE_ADD, 0, sizeof(p));
|
||||
peer->Encode(&p, sizeof(p));
|
||||
}
|
||||
|
||||
{
|
||||
TPacketMarriageUpdate p;
|
||||
p.dwPID1 = pMarriage->pid1;
|
||||
p.dwPID2 = pMarriage->pid2;
|
||||
p.iLovePoint = pMarriage->love_point;
|
||||
p.byMarried = pMarriage->is_married;
|
||||
peer->EncodeHeader(HEADER_DG_MARRIAGE_UPDATE, 0, sizeof(p));
|
||||
peer->Encode(&p, sizeof(p));
|
||||
}
|
||||
}
|
||||
|
||||
// <20><>ȥ<EFBFBD><C8A5> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
for (itertype(m_mapRunningWedding) it = m_mapRunningWedding.begin(); it != m_mapRunningWedding.end(); ++it)
|
||||
{
|
||||
const TWedding& t = it->second;
|
||||
|
||||
TPacketWeddingReady p;
|
||||
p.dwPID1 = t.dwPID1;
|
||||
p.dwPID2 = t.dwPID2;
|
||||
p.dwMapIndex = t.dwMapIndex;
|
||||
|
||||
peer->EncodeHeader(HEADER_DG_WEDDING_READY, 0, sizeof(p));
|
||||
peer->Encode(&p, sizeof(p));
|
||||
|
||||
TPacketWeddingStart p2;
|
||||
p2.dwPID1 = t.dwPID1;
|
||||
p2.dwPID2 = t.dwPID2;
|
||||
|
||||
peer->EncodeHeader(HEADER_DG_WEDDING_START, 0, sizeof(p2));
|
||||
peer->Encode(&p2, sizeof(p2));
|
||||
}
|
||||
}
|
||||
|
||||
void CManager::ReadyWedding(DWORD dwMapIndex, DWORD dwPID1, DWORD dwPID2)
|
||||
{
|
||||
DWORD dwStartTime = CClientManager::instance().GetCurrentTime();
|
||||
m_pqWeddingStart.push(TWedding(dwStartTime + 5, dwMapIndex, dwPID1, dwPID2));
|
||||
}
|
||||
|
||||
void CManager::EndWedding(DWORD dwPID1, DWORD dwPID2)
|
||||
{
|
||||
itertype(m_mapRunningWedding) it = m_mapRunningWedding.find(make_pair(dwPID1, dwPID2));
|
||||
if (it == m_mapRunningWedding.end())
|
||||
{
|
||||
sys_err("try to end wedding %u %u", dwPID1, dwPID2);
|
||||
return;
|
||||
}
|
||||
|
||||
TWedding& w = it->second;
|
||||
|
||||
TPacketWeddingEnd p;
|
||||
p.dwPID1 = w.dwPID1;
|
||||
p.dwPID2 = w.dwPID2;
|
||||
CClientManager::instance().ForwardPacket(HEADER_DG_WEDDING_END, &p, sizeof(p));
|
||||
m_mapRunningWedding.erase(it);
|
||||
}
|
||||
|
||||
void CManager::Update()
|
||||
{
|
||||
DWORD now = CClientManager::instance().GetCurrentTime();
|
||||
|
||||
if (!m_pqWeddingEnd.empty())
|
||||
{
|
||||
while (!m_pqWeddingEnd.empty() && m_pqWeddingEnd.top().dwTime <= now)
|
||||
{
|
||||
TWeddingInfo wi = m_pqWeddingEnd.top();
|
||||
m_pqWeddingEnd.pop();
|
||||
|
||||
itertype(m_mapRunningWedding) it = m_mapRunningWedding.find(make_pair(wi.dwPID1, wi.dwPID2));
|
||||
if (it == m_mapRunningWedding.end())
|
||||
continue;
|
||||
|
||||
TWedding& w = it->second;
|
||||
|
||||
TPacketWeddingEnd p;
|
||||
p.dwPID1 = w.dwPID1;
|
||||
p.dwPID2 = w.dwPID2;
|
||||
CClientManager::instance().ForwardPacket(HEADER_DG_WEDDING_END, &p, sizeof(p));
|
||||
m_mapRunningWedding.erase(it);
|
||||
|
||||
itertype(m_MarriageByPID) it_marriage = m_MarriageByPID.find(w.dwPID1);
|
||||
|
||||
if (it_marriage != m_MarriageByPID.end())
|
||||
{
|
||||
TMarriage* pMarriage = it_marriage->second;
|
||||
if (!pMarriage->is_married)
|
||||
{
|
||||
Remove(pMarriage->pid1, pMarriage->pid2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!m_pqWeddingStart.empty())
|
||||
{
|
||||
while (!m_pqWeddingStart.empty() && m_pqWeddingStart.top().dwTime <= now)
|
||||
{
|
||||
TWedding w = m_pqWeddingStart.top();
|
||||
m_pqWeddingStart.pop();
|
||||
|
||||
TPacketWeddingStart p;
|
||||
p.dwPID1 = w.dwPID1;
|
||||
p.dwPID2 = w.dwPID2;
|
||||
CClientManager::instance().ForwardPacket(HEADER_DG_WEDDING_START, &p, sizeof(p));
|
||||
|
||||
w.dwTime += WEDDING_LENGTH;
|
||||
m_pqWeddingEnd.push(TWeddingInfo(w.dwTime, w.dwPID1, w.dwPID2));
|
||||
m_mapRunningWedding.insert(make_pair(make_pair(w.dwPID1, w.dwPID2), w));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
113
db/src/Marriage.h
Normal file
113
db/src/Marriage.h
Normal file
@ -0,0 +1,113 @@
|
||||
// vim: ts=4 sw=4
|
||||
#ifndef __MARRIAGE_H
|
||||
#define __MARRIAGE_H
|
||||
|
||||
#include <set>
|
||||
#include <queue>
|
||||
#include <deque>
|
||||
|
||||
#include "Peer.h"
|
||||
|
||||
namespace marriage
|
||||
{
|
||||
struct TWeddingInfo
|
||||
{
|
||||
DWORD dwTime;
|
||||
DWORD dwPID1;
|
||||
DWORD dwPID2;
|
||||
TWeddingInfo(DWORD time, DWORD pid1, DWORD pid2)
|
||||
: dwTime(time),
|
||||
dwPID1(pid1),
|
||||
dwPID2(pid2)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct TWedding
|
||||
{
|
||||
DWORD dwTime;
|
||||
DWORD dwMapIndex;
|
||||
DWORD dwPID1;
|
||||
DWORD dwPID2;
|
||||
|
||||
TWedding(DWORD time, DWORD dwMapIndex, DWORD pid1, DWORD pid2)
|
||||
: dwTime(time),
|
||||
dwMapIndex(dwMapIndex),
|
||||
dwPID1(pid1),
|
||||
dwPID2(pid2)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
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
|
||||
{
|
||||
DWORD pid1;
|
||||
DWORD pid2;
|
||||
int love_point;
|
||||
DWORD time;
|
||||
BYTE is_married; // false : <20><>ȥ <20><><EFBFBD><EFBFBD>, true : <20><>ȥ <20><><EFBFBD><EFBFBD>
|
||||
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)
|
||||
: pid1(_pid1), pid2(_pid2), love_point(_love_point), time(_time), is_married(_is_married), name1(name1), name2(name2)
|
||||
{
|
||||
}
|
||||
|
||||
DWORD GetOther(DWORD PID)
|
||||
{
|
||||
if (pid1 == PID)
|
||||
return pid2;
|
||||
|
||||
if (pid2 == PID)
|
||||
return pid1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
class CManager : public singleton<CManager>
|
||||
{
|
||||
public:
|
||||
CManager();
|
||||
virtual ~CManager();
|
||||
|
||||
bool Initialize();
|
||||
|
||||
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 Remove(DWORD dwPID1, DWORD dwPID2);
|
||||
void Update(DWORD dwPID1, DWORD dwPID2, INT iLovePoint, BYTE byMarried);
|
||||
|
||||
void EngageToMarriage(DWORD dwPID1, DWORD dwPID2);
|
||||
|
||||
void ReadyWedding(DWORD dwMapIndex, DWORD dwPID1, DWORD dwPID2);
|
||||
void EndWedding(DWORD dwPID1, DWORD dwPID2);
|
||||
|
||||
void OnSetup(CPeer* peer);
|
||||
|
||||
void Update();
|
||||
|
||||
private:
|
||||
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<TWeddingInfo, std::vector<TWeddingInfo>, std::greater<TWeddingInfo> > m_pqWeddingEnd;
|
||||
|
||||
std::map<std::pair<DWORD, DWORD>, TWedding> m_mapRunningWedding;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
309
db/src/Monarch.cpp
Normal file
309
db/src/Monarch.cpp
Normal file
@ -0,0 +1,309 @@
|
||||
#include "Monarch.h"
|
||||
#include "../../common/utils.h"
|
||||
#include "Main.h"
|
||||
#include "ClientManager.h"
|
||||
|
||||
extern int g_test_server;
|
||||
|
||||
CMonarch::CMonarch()
|
||||
{
|
||||
memset(&m_MonarchInfo, 0, sizeof(MonarchInfo));
|
||||
}
|
||||
|
||||
CMonarch::~CMonarch()
|
||||
{
|
||||
}
|
||||
|
||||
bool CMonarch::VoteMonarch(DWORD pid, DWORD selectdpid)
|
||||
{
|
||||
MAP_MONARCHELECTION::iterator it = m_map_MonarchElection.find(pid);
|
||||
|
||||
if (it == m_map_MonarchElection.end())
|
||||
{
|
||||
MonarchElectionInfo * p = new MonarchElectionInfo;
|
||||
p->pid = pid;
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CMonarch::ElectMonarch()
|
||||
{
|
||||
int size = GetVecMonarchCandidacy().size();
|
||||
|
||||
int * s = new int[size];
|
||||
|
||||
itertype(m_map_MonarchElection) it = m_map_MonarchElection.begin();
|
||||
|
||||
int idx = 0;
|
||||
|
||||
for (; it != m_map_MonarchElection.end(); ++it)
|
||||
{
|
||||
if ((idx = GetCandidacyIndex(it->second->pid)) < 0)
|
||||
continue;
|
||||
|
||||
++s[idx];
|
||||
|
||||
if (g_test_server)
|
||||
sys_log (0, "[MONARCH_VOTE] pid(%d) come to vote candidacy pid(%d)", it->second->pid, m_vec_MonarchCandidacy[idx].pid);
|
||||
}
|
||||
|
||||
delete [] s;
|
||||
}
|
||||
|
||||
bool CMonarch::IsCandidacy(DWORD pid)
|
||||
{
|
||||
VEC_MONARCHCANDIDACY::iterator it = m_vec_MonarchCandidacy.begin();
|
||||
|
||||
for (; it != m_vec_MonarchCandidacy.end(); ++it)
|
||||
{
|
||||
if (it->pid == pid)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMonarch::AddCandidacy(DWORD pid, const char * name)
|
||||
{
|
||||
if (IsCandidacy(pid) == false)
|
||||
return false;
|
||||
|
||||
MonarchCandidacy info;
|
||||
|
||||
info.pid = pid;
|
||||
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(szQuery);
|
||||
return true;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
m_vec_MonarchCandidacy.erase (it);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
bool CMonarch::IsMonarch(int Empire, DWORD pid)
|
||||
{
|
||||
if (m_MonarchInfo.pid[Empire] != pid)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMonarch::AddMoney(int Empire, int64_t Money)
|
||||
{
|
||||
if (m_MonarchInfo.money[Empire] + Money > 2000000000)
|
||||
return true;
|
||||
|
||||
m_MonarchInfo.money[Empire] += Money;
|
||||
|
||||
int64_t Money64 = m_MonarchInfo.money[Empire];
|
||||
|
||||
char szQuery[1024];
|
||||
snprintf(szQuery, sizeof(szQuery), "UPDATE monarch set money=%lld where empire=%d", Money64, Empire);
|
||||
|
||||
CDBManager::instance().AsyncQuery(szQuery);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMonarch::DecMoney(int Empire, int64_t Money)
|
||||
{
|
||||
if (m_MonarchInfo.money[Empire] - Money < 0)
|
||||
return false;
|
||||
m_MonarchInfo.money[Empire] -= Money;
|
||||
|
||||
int64_t Money64 = m_MonarchInfo.money[Empire];
|
||||
|
||||
char szQuery[1024];
|
||||
snprintf(szQuery, sizeof(szQuery), "UPDATE monarch set money=%lld where empire=%d", Money64, Empire);
|
||||
|
||||
CDBManager::instance().AsyncQuery(szQuery);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMonarch::TakeMoney(int Empire, DWORD pid, int64_t Money)
|
||||
{
|
||||
if (IsMonarch(Empire, pid) == false)
|
||||
return false;
|
||||
|
||||
if (m_MonarchInfo.money[Empire] < Money)
|
||||
return false;
|
||||
|
||||
m_MonarchInfo.money[Empire] -= Money;
|
||||
|
||||
char szQuery[1024];
|
||||
snprintf(szQuery, sizeof(szQuery),
|
||||
"UPDATE monarch set money=%lld; where empire=%d", m_MonarchInfo.money[Empire], Empire);
|
||||
|
||||
CDBManager::instance().AsyncQuery(szQuery);
|
||||
|
||||
if (g_test_server)
|
||||
sys_log(0, "[MONARCH] Take money empire(%d) money(%lld)", Empire, m_MonarchInfo.money[Empire]);
|
||||
return true;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (pMsg->Get()->uiNumRows == 0)
|
||||
{
|
||||
delete pMsg;
|
||||
return false;
|
||||
}
|
||||
|
||||
MYSQL_ROW row;
|
||||
for (int n = 0; (row = mysql_fetch_row(pMsg->Get()->pSQLResult)) != NULL; ++n)
|
||||
{
|
||||
int idx = 0;
|
||||
int Empire = 0; str_to_number(Empire, row[idx++]);
|
||||
|
||||
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]));
|
||||
|
||||
if (g_test_server)
|
||||
sys_log(0, "[LOAD_MONARCH] Empire %d pid %d money %lld windate %s", 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)
|
||||
{
|
||||
delete pMsg;
|
||||
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++]);
|
||||
|
||||
str_to_number(p->pid[Empire], row[idx++]);
|
||||
strlcpy(p->name[Empire], row[idx++], sizeof(p->name[Empire]));
|
||||
p->money[Empire] = atoll(row[idx++]);
|
||||
|
||||
if (g_test_server)
|
||||
sys_log(0, "[Set_MONARCH] Empire %d pid %d money %lld windate %s", Empire, p->pid[Empire], p->money[Empire], p->date[Empire]);
|
||||
}
|
||||
delete pMsg;
|
||||
|
||||
//db<64><62> <20>Է<EFBFBD>
|
||||
snprintf(szQuery, sizeof(szQuery),
|
||||
"REPLACE INTO monarch (empire, name, windate, money) VALUES(%d, %d, now(), %lld)", Empire, p->pid[Empire], p->money[Empire]);
|
||||
|
||||
CDBManager::instance().AsyncQuery(szQuery, SQL_PLAYER);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMonarch::DelMonarch(int Empire)
|
||||
{
|
||||
char szQuery[256];
|
||||
|
||||
snprintf(szQuery, sizeof(szQuery), "DELETE from monarch where empire=%d", Empire);
|
||||
SQLMsg * pMsg = CDBManager::instance().DirectQuery(szQuery, SQL_PLAYER);
|
||||
|
||||
if (pMsg->Get()->uiNumRows == 0)
|
||||
{
|
||||
delete pMsg;
|
||||
return false;
|
||||
}
|
||||
|
||||
delete pMsg;
|
||||
|
||||
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)
|
||||
{
|
||||
for (int n = 1; n < 4; ++n)
|
||||
{
|
||||
if (0 == strncmp(m_MonarchInfo.name[n], name, sizeof(m_MonarchInfo.name[n])))
|
||||
{
|
||||
char szQuery[256];
|
||||
|
||||
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)
|
||||
{
|
||||
sys_err(" DirectQuery failed(%s)", szQuery);
|
||||
delete pMsg;
|
||||
return false;
|
||||
}
|
||||
|
||||
delete pMsg;
|
||||
|
||||
memset(m_MonarchInfo.name[Empire], 0, 32);
|
||||
m_MonarchInfo.money[Empire] = 0;
|
||||
m_MonarchInfo.pid[Empire] = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int CMonarch::GetCandidacyIndex(DWORD pid)
|
||||
{
|
||||
itertype(m_vec_MonarchCandidacy) it = m_vec_MonarchCandidacy.begin();
|
||||
|
||||
for (int n = 0; it != m_vec_MonarchCandidacy.end(); ++it, ++n)
|
||||
{
|
||||
if (it->pid == pid)
|
||||
return n;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
70
db/src/Monarch.h
Normal file
70
db/src/Monarch.h
Normal file
@ -0,0 +1,70 @@
|
||||
// vim: ts=4 sw=4
|
||||
#ifndef METIN2_MONARCH_H
|
||||
#define METIN2_MONARCH_H
|
||||
|
||||
#include "../../libthecore/include/stdafx.h"
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include "../../common/singleton.h"
|
||||
#include "../../common/tables.h"
|
||||
|
||||
class CMonarch : public singleton<CMonarch>
|
||||
{
|
||||
public:
|
||||
typedef std::map<DWORD, MonarchElectionInfo*> MAP_MONARCHELECTION;
|
||||
typedef std::vector<MonarchCandidacy> VEC_MONARCHCANDIDACY;
|
||||
|
||||
CMonarch();
|
||||
virtual ~CMonarch();
|
||||
|
||||
bool VoteMonarch(DWORD pid, DWORD selectedpid);
|
||||
void ElectMonarch();
|
||||
|
||||
bool IsCandidacy(DWORD pid);
|
||||
bool AddCandidacy(DWORD pid, const char * name);
|
||||
bool DelCandidacy(const char * name);
|
||||
|
||||
bool LoadMonarch();
|
||||
bool SetMonarch(const char * name);
|
||||
bool DelMonarch(int Empire);
|
||||
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()
|
||||
{
|
||||
return &m_MonarchInfo;
|
||||
}
|
||||
|
||||
VEC_MONARCHCANDIDACY& GetVecMonarchCandidacy()
|
||||
{
|
||||
return m_vec_MonarchCandidacy;
|
||||
}
|
||||
|
||||
size_t MonarchCandidacySize()
|
||||
{
|
||||
return m_vec_MonarchCandidacy.size();
|
||||
}
|
||||
|
||||
private:
|
||||
int GetCandidacyIndex(DWORD pid);
|
||||
|
||||
MAP_MONARCHELECTION m_map_MonarchElection;
|
||||
VEC_MONARCHCANDIDACY m_vec_MonarchCandidacy;
|
||||
TMonarchInfo m_MonarchInfo;
|
||||
|
||||
MonarchElectionInfo* GetMonarchElection(DWORD pid)
|
||||
{
|
||||
MAP_MONARCHELECTION::iterator it = m_map_MonarchElection.find(pid);
|
||||
|
||||
if (it != m_map_MonarchElection.end())
|
||||
return it->second;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
57
db/src/MoneyLog.cpp
Normal file
57
db/src/MoneyLog.cpp
Normal file
@ -0,0 +1,57 @@
|
||||
#include "stdafx.h"
|
||||
#include "MoneyLog.h"
|
||||
#include "ClientManager.h"
|
||||
#include "Peer.h"
|
||||
|
||||
CMoneyLog::CMoneyLog()
|
||||
{
|
||||
}
|
||||
|
||||
CMoneyLog::~CMoneyLog()
|
||||
{
|
||||
}
|
||||
|
||||
void CMoneyLog::Save()
|
||||
{
|
||||
CPeer* peer = CClientManager::instance().GetAnyPeer();
|
||||
if (!peer)
|
||||
return;
|
||||
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;
|
||||
TPacketMoneyLog p;
|
||||
p.type = bType;
|
||||
p.vnum = it->first;
|
||||
p.gold = it->second;
|
||||
peer->EncodeHeader(HEADER_DG_MONEY_LOG, 0, sizeof(p));
|
||||
peer->Encode(&p, sizeof(p));
|
||||
}
|
||||
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)
|
||||
{
|
||||
m_MoneyLogContainer[bType][dwVnum] += iGold;
|
||||
}
|
20
db/src/MoneyLog.h
Normal file
20
db/src/MoneyLog.h
Normal file
@ -0,0 +1,20 @@
|
||||
// vim: ts=8 sw=4
|
||||
#ifndef __INC_MONEY_LOG
|
||||
#define __INC_MONEY_LOG
|
||||
|
||||
#include <map>
|
||||
|
||||
class CMoneyLog : public singleton<CMoneyLog>
|
||||
{
|
||||
public:
|
||||
CMoneyLog();
|
||||
virtual ~CMoneyLog();
|
||||
|
||||
void Save();
|
||||
void AddLog(BYTE bType, DWORD dwVnum, int iGold);
|
||||
|
||||
private:
|
||||
std::map<DWORD, int> m_MoneyLogContainer[MONEY_LOG_TYPE_MAX_NUM];
|
||||
};
|
||||
|
||||
#endif
|
54
db/src/NetBase.cpp
Normal file
54
db/src/NetBase.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
#include "stdafx.h"
|
||||
#include "NetBase.h"
|
||||
#include "Config.h"
|
||||
#include "ClientManager.h"
|
||||
|
||||
LPFDWATCH CNetBase::m_fdWatcher = NULL;
|
||||
|
||||
CNetBase::CNetBase()
|
||||
{
|
||||
}
|
||||
|
||||
CNetBase::~CNetBase()
|
||||
{
|
||||
}
|
||||
|
||||
CNetPoller::CNetPoller()
|
||||
{
|
||||
}
|
||||
|
||||
CNetPoller::~CNetPoller()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
bool CNetPoller::Create()
|
||||
{
|
||||
sys_log(1, "NetPoller::Create()");
|
||||
|
||||
if (m_fdWatcher)
|
||||
return true;
|
||||
|
||||
m_fdWatcher = fdwatch_new(512);
|
||||
|
||||
if (!m_fdWatcher)
|
||||
{
|
||||
Destroy();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CNetPoller::Destroy()
|
||||
{
|
||||
sys_log(1, "NetPoller::Destroy()");
|
||||
|
||||
if (m_fdWatcher)
|
||||
{
|
||||
fdwatch_delete(m_fdWatcher);
|
||||
m_fdWatcher = NULL;
|
||||
}
|
||||
|
||||
thecore_destroy();
|
||||
}
|
25
db/src/NetBase.h
Normal file
25
db/src/NetBase.h
Normal file
@ -0,0 +1,25 @@
|
||||
// vim: ts=8 sw=4
|
||||
#ifndef __INC_NETWORKBASE_H__
|
||||
#define __INC_NETWORKBASE_H__
|
||||
|
||||
class CNetBase
|
||||
{
|
||||
public:
|
||||
CNetBase();
|
||||
virtual ~CNetBase();
|
||||
|
||||
protected:
|
||||
static LPFDWATCH m_fdWatcher;
|
||||
};
|
||||
|
||||
class CNetPoller : public CNetBase, public singleton<CNetPoller>
|
||||
{
|
||||
public:
|
||||
CNetPoller();
|
||||
virtual ~CNetPoller();
|
||||
|
||||
bool Create();
|
||||
void Destroy();
|
||||
};
|
||||
|
||||
#endif
|
197
db/src/Peer.cpp
Normal file
197
db/src/Peer.cpp
Normal file
@ -0,0 +1,197 @@
|
||||
#include "stdafx.h"
|
||||
#include "Peer.h"
|
||||
#include "ItemIDRangeManager.h"
|
||||
|
||||
CPeer::CPeer()
|
||||
{
|
||||
m_state = 0;
|
||||
m_bChannel = 0;
|
||||
m_dwHandle = 0;
|
||||
m_dwUserCount = 0;
|
||||
m_wListenPort = 0;
|
||||
m_wP2PPort = 0;
|
||||
|
||||
memset(m_alMaps, 0, sizeof(m_alMaps));
|
||||
|
||||
m_itemRange.dwMin = m_itemRange.dwMax = m_itemRange.dwUsableItemIDMin = 0;
|
||||
m_itemSpareRange.dwMin = m_itemSpareRange.dwMax = m_itemSpareRange.dwUsableItemIDMin = 0;
|
||||
}
|
||||
|
||||
CPeer::~CPeer()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
void CPeer::OnAccept()
|
||||
{
|
||||
m_state = STATE_PLAYING;
|
||||
|
||||
static DWORD current_handle = 0;
|
||||
m_dwHandle = ++current_handle;
|
||||
|
||||
sys_log(0, "Connection accepted. (host: %s handle: %u fd: %d)", m_host, m_dwHandle, m_fd);
|
||||
}
|
||||
|
||||
void CPeer::OnConnect()
|
||||
{
|
||||
sys_log(0, "Connection established. (host: %s handle: %u fd: %d)", m_host, m_dwHandle, m_fd);
|
||||
m_state = STATE_PLAYING;
|
||||
}
|
||||
|
||||
void CPeer::OnClose()
|
||||
{
|
||||
m_state = STATE_CLOSE;
|
||||
|
||||
sys_log(0, "Connection closed. (host: %s)", m_host);
|
||||
sys_log(0, "ItemIDRange: returned. %u ~ %u", m_itemRange.dwMin, m_itemRange.dwMax);
|
||||
|
||||
CItemIDRangeManager::instance().UpdateRange(m_itemRange.dwMin, m_itemRange.dwMax);
|
||||
|
||||
m_itemRange.dwMin = 0;
|
||||
m_itemRange.dwMax = 0;
|
||||
m_itemRange.dwUsableItemIDMin = 0;
|
||||
}
|
||||
|
||||
DWORD CPeer::GetHandle()
|
||||
{
|
||||
return m_dwHandle;
|
||||
}
|
||||
|
||||
DWORD CPeer::GetUserCount()
|
||||
{
|
||||
return m_dwUserCount;
|
||||
}
|
||||
|
||||
void CPeer::SetUserCount(DWORD dwCount)
|
||||
{
|
||||
m_dwUserCount = dwCount;
|
||||
}
|
||||
|
||||
bool CPeer::PeekPacket(int & iBytesProceed, BYTE & header, DWORD & dwHandle, DWORD & dwLength, const char ** data)
|
||||
{
|
||||
if (GetRecvLength() < iBytesProceed + 9)
|
||||
return false;
|
||||
|
||||
const char * buf = (const char *) GetRecvBuffer();
|
||||
buf += iBytesProceed;
|
||||
|
||||
header = *(buf++);
|
||||
|
||||
dwHandle = *((DWORD *) buf);
|
||||
buf += sizeof(DWORD);
|
||||
|
||||
dwLength = *((DWORD *) buf);
|
||||
buf += sizeof(DWORD);
|
||||
|
||||
//sys_log(0, "%d header %d handle %u length %u", GetRecvLength(), header, dwHandle, dwLength);
|
||||
if (iBytesProceed + dwLength + 9 > (DWORD) GetRecvLength())
|
||||
{
|
||||
sys_log(0, "PeekPacket: not enough buffer size: len %u, recv %d",
|
||||
9+dwLength, GetRecvLength()-iBytesProceed);
|
||||
return false;
|
||||
}
|
||||
|
||||
*data = buf;
|
||||
iBytesProceed += dwLength + 9;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CPeer::EncodeHeader(BYTE header, DWORD dwHandle, DWORD dwSize)
|
||||
{
|
||||
HEADER h;
|
||||
|
||||
sys_log(1, "EncodeHeader %u handle %u size %u", header, dwHandle, dwSize);
|
||||
|
||||
h.bHeader = header;
|
||||
h.dwHandle = dwHandle;
|
||||
h.dwSize = dwSize;
|
||||
|
||||
Encode(&h, sizeof(HEADER));
|
||||
}
|
||||
|
||||
void CPeer::EncodeReturn(BYTE header, DWORD dwHandle)
|
||||
{
|
||||
EncodeHeader(header, dwHandle, 0);
|
||||
}
|
||||
|
||||
int CPeer::Send()
|
||||
{
|
||||
if (m_state == STATE_CLOSE)
|
||||
return -1;
|
||||
|
||||
return (CPeerBase::Send());
|
||||
}
|
||||
|
||||
void CPeer::SetP2PPort(WORD wPort)
|
||||
{
|
||||
m_wP2PPort = wPort;
|
||||
}
|
||||
|
||||
void CPeer::SetMaps(long * pl)
|
||||
{
|
||||
thecore_memcpy(m_alMaps, pl, sizeof(m_alMaps));
|
||||
}
|
||||
|
||||
void CPeer::SendSpareItemIDRange()
|
||||
{
|
||||
if (m_itemSpareRange.dwMin == 0 || m_itemSpareRange.dwMax == 0 || m_itemSpareRange.dwUsableItemIDMin == 0)
|
||||
{
|
||||
EncodeHeader(HEADER_DG_ACK_SPARE_ITEM_ID_RANGE, 0, sizeof(TItemIDRangeTable));
|
||||
Encode(&m_itemSpareRange, sizeof(TItemIDRangeTable));
|
||||
}
|
||||
else
|
||||
{
|
||||
SetItemIDRange(m_itemSpareRange);
|
||||
|
||||
if (SetSpareItemIDRange(CItemIDRangeManager::instance().GetRange()) == false)
|
||||
{
|
||||
sys_log(0, "ItemIDRange: spare range set error");
|
||||
m_itemSpareRange.dwMin = m_itemSpareRange.dwMax = m_itemSpareRange.dwUsableItemIDMin = 0;
|
||||
}
|
||||
|
||||
EncodeHeader(HEADER_DG_ACK_SPARE_ITEM_ID_RANGE, 0, sizeof(TItemIDRangeTable));
|
||||
Encode(&m_itemSpareRange, sizeof(TItemIDRangeTable));
|
||||
}
|
||||
}
|
||||
|
||||
bool CPeer::SetItemIDRange(TItemIDRangeTable itemRange)
|
||||
{
|
||||
if (itemRange.dwMin == 0 || itemRange.dwMax == 0 || itemRange.dwUsableItemIDMin == 0) return false;
|
||||
|
||||
m_itemRange = itemRange;
|
||||
sys_log(0, "ItemIDRange: SET %s %u ~ %u start: %u", GetPublicIP(), m_itemRange.dwMin, m_itemRange.dwMax, m_itemRange.dwUsableItemIDMin);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CPeer::SetSpareItemIDRange(TItemIDRangeTable itemRange)
|
||||
{
|
||||
if (itemRange.dwMin == 0 || itemRange.dwMax == 0 || itemRange.dwUsableItemIDMin == 0) return false;
|
||||
|
||||
m_itemSpareRange = itemRange;
|
||||
sys_log(0, "ItemIDRange: SPARE SET %s %u ~ %u start: %u", GetPublicIP(), m_itemSpareRange.dwMin, m_itemSpareRange.dwMax,
|
||||
m_itemSpareRange.dwUsableItemIDMin);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CPeer::CheckItemIDRangeCollision(TItemIDRangeTable itemRange)
|
||||
{
|
||||
if (m_itemRange.dwMin < itemRange.dwMax && m_itemRange.dwMax > itemRange.dwMin)
|
||||
{
|
||||
sys_err("ItemIDRange: Collision!! this %u ~ %u check %u ~ %u",
|
||||
m_itemRange.dwMin, m_itemRange.dwMax, itemRange.dwMin, itemRange.dwMax);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_itemSpareRange.dwMin < itemRange.dwMax && m_itemSpareRange.dwMax > itemRange.dwMin)
|
||||
{
|
||||
sys_err("ItemIDRange: Collision with spare range this %u ~ %u check %u ~ %u",
|
||||
m_itemSpareRange.dwMin, m_itemSpareRange.dwMax, itemRange.dwMin, itemRange.dwMax);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
79
db/src/Peer.h
Normal file
79
db/src/Peer.h
Normal file
@ -0,0 +1,79 @@
|
||||
// vim: ts=8 sw=4
|
||||
#ifndef __INC_PEER_H__
|
||||
#define __INC_PEER_H__
|
||||
|
||||
#include "PeerBase.h"
|
||||
|
||||
class CPeer : public CPeerBase
|
||||
{
|
||||
protected:
|
||||
virtual void OnAccept();
|
||||
virtual void OnClose();
|
||||
virtual void OnConnect();
|
||||
|
||||
public:
|
||||
#pragma pack(1)
|
||||
typedef struct _header
|
||||
{
|
||||
BYTE bHeader;
|
||||
DWORD dwHandle;
|
||||
DWORD dwSize;
|
||||
} HEADER;
|
||||
#pragma pack()
|
||||
enum EState
|
||||
{
|
||||
STATE_CLOSE = 0,
|
||||
STATE_PLAYING = 1
|
||||
};
|
||||
|
||||
CPeer();
|
||||
virtual ~CPeer();
|
||||
|
||||
void EncodeHeader(BYTE header, DWORD dwHandle, DWORD dwSize);
|
||||
bool PeekPacket(int & iBytesProceed, BYTE & header, DWORD & dwHandle, DWORD & dwLength, const char ** data);
|
||||
void EncodeReturn(BYTE header, DWORD dwHandle);
|
||||
|
||||
void ProcessInput();
|
||||
int Send();
|
||||
|
||||
DWORD GetHandle();
|
||||
DWORD GetUserCount();
|
||||
void SetUserCount(DWORD dwCount);
|
||||
|
||||
void SetPublicIP(const char * ip) { m_stPublicIP = ip; }
|
||||
const char * GetPublicIP() { return m_stPublicIP.c_str(); }
|
||||
|
||||
void SetChannel(BYTE bChannel) { m_bChannel = bChannel; }
|
||||
BYTE GetChannel() { return m_bChannel; }
|
||||
|
||||
void SetListenPort(WORD wPort) { m_wListenPort = wPort; }
|
||||
WORD GetListenPort() { return m_wListenPort; }
|
||||
|
||||
void SetP2PPort(WORD wPort);
|
||||
WORD GetP2PPort() { return m_wP2PPort; }
|
||||
|
||||
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:
|
||||
int m_state;
|
||||
|
||||
BYTE m_bChannel;
|
||||
DWORD m_dwHandle;
|
||||
DWORD m_dwUserCount;
|
||||
WORD m_wListenPort; // <20><><EFBFBD>Ӽ<EFBFBD><D3BC><EFBFBD><EFBFBD><EFBFBD> Ŭ<><C5AC><EFBFBD>̾<EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD> listen <20>ϴ<EFBFBD> <20><>Ʈ
|
||||
WORD m_wP2PPort; // <20><><EFBFBD>Ӽ<EFBFBD><D3BC><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>Ӽ<EFBFBD><D3BC><EFBFBD> P2P <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> listen <20>ϴ<EFBFBD> <20><>Ʈ
|
||||
long m_alMaps[32]; // <20> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> <20>ִ°<D6B4>?
|
||||
|
||||
TItemIDRangeTable m_itemRange;
|
||||
TItemIDRangeTable m_itemSpareRange;
|
||||
|
||||
std::string m_stPublicIP;
|
||||
};
|
||||
|
||||
#endif
|
214
db/src/PeerBase.cpp
Normal file
214
db/src/PeerBase.cpp
Normal file
@ -0,0 +1,214 @@
|
||||
#include "stdafx.h"
|
||||
#include "PeerBase.h"
|
||||
|
||||
CPeerBase::CPeerBase() : m_fd(INVALID_SOCKET), m_BytesRemain(0), m_outBuffer(NULL), m_inBuffer(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
CPeerBase::~CPeerBase()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
void CPeerBase::Disconnect()
|
||||
{
|
||||
if (m_fd != INVALID_SOCKET)
|
||||
{
|
||||
fdwatch_del_fd(m_fdWatcher, m_fd);
|
||||
|
||||
socket_close(m_fd);
|
||||
m_fd = INVALID_SOCKET;
|
||||
}
|
||||
}
|
||||
|
||||
void CPeerBase::Destroy()
|
||||
{
|
||||
Disconnect();
|
||||
|
||||
if (m_outBuffer)
|
||||
{
|
||||
buffer_delete(m_outBuffer);
|
||||
m_outBuffer = NULL;
|
||||
}
|
||||
|
||||
if (m_inBuffer)
|
||||
{
|
||||
buffer_delete(m_inBuffer);
|
||||
m_inBuffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool CPeerBase::Accept(socket_t fd_accept)
|
||||
{
|
||||
struct sockaddr_in peer;
|
||||
|
||||
if ((m_fd = socket_accept(fd_accept, &peer)) == INVALID_SOCKET)
|
||||
{
|
||||
Destroy();
|
||||
return false;
|
||||
}
|
||||
|
||||
//socket_block(m_fd);
|
||||
socket_sndbuf(m_fd, 233016);
|
||||
socket_rcvbuf(m_fd, 233016);
|
||||
|
||||
strlcpy(m_host, inet_ntoa(peer.sin_addr), sizeof(m_host));
|
||||
m_outBuffer = buffer_new(DEFAULT_PACKET_BUFFER_SIZE);
|
||||
m_inBuffer = buffer_new(MAX_INPUT_LEN);
|
||||
|
||||
if (!m_outBuffer || !m_inBuffer)
|
||||
{
|
||||
Destroy();
|
||||
return false;
|
||||
}
|
||||
|
||||
fdwatch_add_fd(m_fdWatcher, m_fd, this, FDW_READ, false);
|
||||
|
||||
OnAccept();
|
||||
sys_log(0, "ACCEPT FROM %s", inet_ntoa(peer.sin_addr));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CPeerBase::Connect(const char* host, WORD port)
|
||||
{
|
||||
strlcpy(m_host, host, sizeof(m_host));
|
||||
|
||||
if ((m_fd = socket_connect(host, port)) == INVALID_SOCKET)
|
||||
return false;
|
||||
|
||||
m_outBuffer = buffer_new(DEFAULT_PACKET_BUFFER_SIZE);
|
||||
|
||||
if (!m_outBuffer)
|
||||
{
|
||||
Destroy();
|
||||
return false;
|
||||
}
|
||||
|
||||
fdwatch_add_fd(m_fdWatcher, m_fd, this, FDW_READ, false);
|
||||
|
||||
OnConnect();
|
||||
return true;
|
||||
}
|
||||
|
||||
void CPeerBase::Close()
|
||||
{
|
||||
OnClose();
|
||||
}
|
||||
|
||||
void CPeerBase::EncodeBYTE(BYTE b)
|
||||
{
|
||||
if (!m_outBuffer)
|
||||
{
|
||||
sys_err("Not ready to write");
|
||||
return;
|
||||
}
|
||||
|
||||
buffer_write(m_outBuffer, &b, 1);
|
||||
fdwatch_add_fd(m_fdWatcher, m_fd, this, FDW_WRITE, true);
|
||||
}
|
||||
|
||||
void CPeerBase::EncodeWORD(WORD w)
|
||||
{
|
||||
if (!m_outBuffer)
|
||||
{
|
||||
sys_err("Not ready to write");
|
||||
return;
|
||||
}
|
||||
|
||||
buffer_write(m_outBuffer, &w, 2);
|
||||
fdwatch_add_fd(m_fdWatcher, m_fd, this, FDW_WRITE, true);
|
||||
}
|
||||
|
||||
void CPeerBase::EncodeDWORD(DWORD dw)
|
||||
{
|
||||
if (!m_outBuffer)
|
||||
{
|
||||
sys_err("Not ready to write");
|
||||
return;
|
||||
}
|
||||
|
||||
buffer_write(m_outBuffer, &dw, 4);
|
||||
fdwatch_add_fd(m_fdWatcher, m_fd, this, FDW_WRITE, true);
|
||||
}
|
||||
|
||||
void CPeerBase::Encode(const void* data, DWORD size)
|
||||
{
|
||||
if (!m_outBuffer)
|
||||
{
|
||||
sys_err("Not ready to write");
|
||||
return;
|
||||
}
|
||||
|
||||
buffer_write(m_outBuffer, data, size);
|
||||
fdwatch_add_fd(m_fdWatcher, m_fd, this, FDW_WRITE, true);
|
||||
}
|
||||
|
||||
int CPeerBase::Recv()
|
||||
{
|
||||
if (!m_inBuffer)
|
||||
{
|
||||
sys_err("input buffer nil");
|
||||
return -1;
|
||||
}
|
||||
|
||||
buffer_adjust_size(m_inBuffer, MAX_INPUT_LEN >> 2);
|
||||
int bytes_to_read = buffer_has_space(m_inBuffer);
|
||||
ssize_t bytes_read = socket_read(m_fd, (char *) buffer_write_peek(m_inBuffer), bytes_to_read);
|
||||
|
||||
if (bytes_read < 0)
|
||||
{
|
||||
sys_err("socket_read failed %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
else if (bytes_read == 0)
|
||||
return 0;
|
||||
|
||||
buffer_write_proceed(m_inBuffer, bytes_read);
|
||||
m_BytesRemain = buffer_size(m_inBuffer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void CPeerBase::RecvEnd(int proceed_bytes)
|
||||
{
|
||||
buffer_read_proceed(m_inBuffer, proceed_bytes);
|
||||
m_BytesRemain = buffer_size(m_inBuffer);
|
||||
}
|
||||
|
||||
int CPeerBase::GetRecvLength()
|
||||
{
|
||||
return m_BytesRemain;
|
||||
}
|
||||
|
||||
const void * CPeerBase::GetRecvBuffer()
|
||||
{
|
||||
return buffer_read_peek(m_inBuffer);
|
||||
}
|
||||
|
||||
int CPeerBase::GetSendLength()
|
||||
{
|
||||
return buffer_size(m_outBuffer);
|
||||
}
|
||||
|
||||
int CPeerBase::Send()
|
||||
{
|
||||
if (buffer_size(m_outBuffer) <= 0)
|
||||
return 0;
|
||||
|
||||
int iBufferLeft = fdwatch_get_buffer_size(m_fdWatcher, m_fd);
|
||||
int iBytesToWrite = MIN(iBufferLeft, buffer_size(m_outBuffer));
|
||||
|
||||
if (iBytesToWrite == 0)
|
||||
return 0;
|
||||
|
||||
int result = socket_write(m_fd, (const char *) buffer_read_peek(m_outBuffer), iBytesToWrite);
|
||||
|
||||
if (result == 0)
|
||||
{
|
||||
buffer_read_proceed(m_outBuffer, iBytesToWrite);
|
||||
|
||||
if (buffer_size(m_outBuffer) != 0)
|
||||
fdwatch_add_fd(m_fdWatcher, m_fd, this, FDW_WRITE, true);
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
61
db/src/PeerBase.h
Normal file
61
db/src/PeerBase.h
Normal file
@ -0,0 +1,61 @@
|
||||
// vim: ts=8 sw=4
|
||||
#ifndef __INC_PEERBASE_H__
|
||||
#define __INC_PEERBASE_H__
|
||||
|
||||
#include "NetBase.h"
|
||||
|
||||
class CPeerBase : public CNetBase
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
MAX_HOST_LENGTH = 30,
|
||||
MAX_INPUT_LEN = 1024 * 1024 * 2,
|
||||
DEFAULT_PACKET_BUFFER_SIZE = 1024 * 1024 * 2
|
||||
};
|
||||
|
||||
protected:
|
||||
virtual void OnAccept() = 0;
|
||||
virtual void OnConnect() = 0;
|
||||
virtual void OnClose() = 0;
|
||||
|
||||
public:
|
||||
bool Accept(socket_t accept_fd);
|
||||
bool Connect(const char* host, WORD port);
|
||||
void Close();
|
||||
|
||||
public:
|
||||
CPeerBase();
|
||||
virtual ~CPeerBase();
|
||||
|
||||
void Disconnect();
|
||||
void Destroy();
|
||||
|
||||
socket_t GetFd() { return m_fd; }
|
||||
|
||||
void EncodeBYTE(BYTE b);
|
||||
void EncodeWORD(WORD w);
|
||||
void EncodeDWORD(DWORD dw);
|
||||
void Encode(const void* data, DWORD size);
|
||||
int Send();
|
||||
|
||||
int Recv();
|
||||
void RecvEnd(int proceed_bytes);
|
||||
int GetRecvLength();
|
||||
const void * GetRecvBuffer();
|
||||
|
||||
int GetSendLength();
|
||||
|
||||
const char * GetHost() { return m_host; }
|
||||
|
||||
protected:
|
||||
char m_host[MAX_HOST_LENGTH + 1];
|
||||
socket_t m_fd;
|
||||
|
||||
private:
|
||||
int m_BytesRemain;
|
||||
LPBUFFER m_outBuffer;
|
||||
LPBUFFER m_inBuffer;
|
||||
};
|
||||
|
||||
#endif
|
291
db/src/PrivManager.cpp
Normal file
291
db/src/PrivManager.cpp
Normal file
@ -0,0 +1,291 @@
|
||||
#include "stdafx.h"
|
||||
#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;
|
||||
|
||||
CPrivManager::CPrivManager()
|
||||
{
|
||||
for (int type = 0; type < MAX_PRIV_NUM; ++type)
|
||||
{
|
||||
for (int empire = 0; empire < EMPIRE_MAX_NUM; ++empire)
|
||||
m_aaPrivEmpire[type][empire] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
CPrivManager::~CPrivManager()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// @version 05/06/07 Bang2ni - <20>ߺ<EFBFBD><DFBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD>忡 <20><><EFBFBD><EFBFBD> ó<><C3B3>
|
||||
//
|
||||
void CPrivManager::Update()
|
||||
{
|
||||
time_t now = CClientManager::instance().GetCurrentTime();
|
||||
|
||||
while (!m_pqPrivGuild.empty() && m_pqPrivGuild.top().first <= now)
|
||||
{
|
||||
TPrivGuildData* p = m_pqPrivGuild.top().second;
|
||||
m_pqPrivGuild.pop();
|
||||
|
||||
if (p->value != 0 && !p->bRemoved)
|
||||
{
|
||||
|
||||
typeof(m_aPrivGuild[p->type].begin()) it = m_aPrivGuild[p->type].find(p->guild_id);
|
||||
|
||||
// ADD_GUILD_PRIV_TIME
|
||||
// <20><><EFBFBD>忡 <20>ߺ<EFBFBD><DFBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ǿ<EFBFBD><C7BE><EFBFBD> <20><><EFBFBD><EFBFBD> map <20><> value <20><> <20><><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD>) <20>Ǿ<EFBFBD><C7BE><EFBFBD><EFBFBD>Ƿ<EFBFBD>
|
||||
// TPrivGuildData <20><> <20><><EFBFBD><EFBFBD><EFBFBD>Ͱ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ְ<EFBFBD> <20><><EFBFBD>Ӽ<EFBFBD><D3BC><EFBFBD><EFBFBD>鿡<EFBFBD><E9BFA1> cast <20><> <20>ش<EFBFBD>.
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
delete p;
|
||||
}
|
||||
|
||||
while (!m_pqPrivEmpire.empty() && m_pqPrivEmpire.top().first <= now)
|
||||
{
|
||||
TPrivEmpireData* p = (m_pqPrivEmpire.top().second);
|
||||
m_pqPrivEmpire.pop();
|
||||
|
||||
if (p->value != 0 && !p->bRemoved)
|
||||
{
|
||||
SendChangeEmpirePriv(p->empire, p->type, 0, 0);
|
||||
m_aaPrivEmpire[p->type][p->empire] = 0;
|
||||
}
|
||||
|
||||
delete p;
|
||||
}
|
||||
|
||||
while (!m_pqPrivChar.empty() && m_pqPrivChar.top().first <= now)
|
||||
{
|
||||
TPrivCharData* p = (m_pqPrivChar.top().second);
|
||||
m_pqPrivChar.pop();
|
||||
|
||||
if (!p->bRemoved)
|
||||
{
|
||||
// TODO send packet
|
||||
SendChangeCharPriv(p->pid, p->type, 0);
|
||||
typeof(m_aPrivChar[p->type].begin()) it = m_aPrivChar[p->type].find(p->pid);
|
||||
if (it != m_aPrivChar[p->type].end())
|
||||
m_aPrivChar[p->type].erase(it);
|
||||
}
|
||||
delete p;
|
||||
}
|
||||
}
|
||||
|
||||
void CPrivManager::AddCharPriv(DWORD pid, BYTE type, int value)
|
||||
{
|
||||
if (MAX_PRIV_NUM <= type)
|
||||
{
|
||||
sys_err("PRIV_MANAGER: AddCharPriv: wrong char priv type(%u) recved", type);
|
||||
return;
|
||||
}
|
||||
|
||||
typeof(m_aPrivChar[type].begin()) it = m_aPrivChar[type].find(pid);
|
||||
|
||||
if (it != m_aPrivChar[type].end())
|
||||
return;
|
||||
|
||||
if (!value)
|
||||
return;
|
||||
|
||||
time_t now = CClientManager::instance().GetCurrentTime();
|
||||
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_aPrivChar[type].insert(std::make_pair(pid, p));
|
||||
|
||||
// TODO send packet
|
||||
sys_log(0, "AddCharPriv %d %d %d", pid, type, value);
|
||||
SendChangeCharPriv(pid, type, value);
|
||||
}
|
||||
|
||||
//
|
||||
// @version 05/06/07 Bang2ni - <20>̹<EFBFBD> <20><><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD>忡 <20><><EFBFBD>ʽ<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
//
|
||||
void CPrivManager::AddGuildPriv(DWORD guild_id, BYTE type, int value, time_t duration_sec)
|
||||
{
|
||||
if (MAX_PRIV_NUM <= type)
|
||||
{
|
||||
sys_err("PRIV_MANAGER: AddGuildPriv: wrong guild priv type(%u) recved", type);
|
||||
return;
|
||||
}
|
||||
|
||||
typeof(m_aPrivGuild[type].begin()) it = m_aPrivGuild[type].find(guild_id);
|
||||
|
||||
time_t now = CClientManager::instance().GetCurrentTime();
|
||||
time_t end = now + duration_sec;
|
||||
TPrivGuildData * p = new TPrivGuildData(type, value, guild_id, end);
|
||||
m_pqPrivGuild.push(std::make_pair(end, p));
|
||||
|
||||
// ADD_GUILD_PRIV_TIME
|
||||
// <20>̹<EFBFBD> <20><><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ִٸ<D6B4> map <20><> value <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ش<EFBFBD>.
|
||||
// <20><><EFBFBD><EFBFBD> value <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD> priority queue <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD>.
|
||||
if (it != m_aPrivGuild[type].end())
|
||||
it->second = p;
|
||||
else
|
||||
m_aPrivGuild[type].insert(std::make_pair(guild_id, p));
|
||||
|
||||
SendChangeGuildPriv(guild_id, type, value, end);
|
||||
// END_OF_ADD_GUILD_PRIV_TIME
|
||||
|
||||
sys_log(0, "Guild Priv guild(%d) type(%d) value(%d) duration_sec(%d)", guild_id, type, value, duration_sec);
|
||||
}
|
||||
|
||||
void CPrivManager::AddEmpirePriv(BYTE empire, BYTE type, int value, time_t duration_sec)
|
||||
{
|
||||
if (MAX_PRIV_NUM <= type)
|
||||
{
|
||||
sys_err("PRIV_MANAGER: AddEmpirePriv: wrong empire priv type(%u) recved", type);
|
||||
return;
|
||||
}
|
||||
|
||||
if (duration_sec < 0)
|
||||
duration_sec = 0;
|
||||
|
||||
time_t now = CClientManager::instance().GetCurrentTime();
|
||||
time_t end = now+duration_sec;
|
||||
|
||||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ȿȭ
|
||||
// priority_queue<75><65> <20><><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD> pointer == m_aaPrivEmpire[type][empire]
|
||||
{
|
||||
if (m_aaPrivEmpire[type][empire])
|
||||
m_aaPrivEmpire[type][empire]->bRemoved = true;
|
||||
}
|
||||
|
||||
TPrivEmpireData * p = new TPrivEmpireData(type, value, empire, end);
|
||||
m_pqPrivEmpire.push(std::make_pair(end, p));
|
||||
m_aaPrivEmpire[type][empire] = p;
|
||||
|
||||
// ADD_EMPIRE_PRIV_TIME
|
||||
SendChangeEmpirePriv(empire, type, value, end);
|
||||
// END_OF_ADD_EMPIRE_PRIV_TIME
|
||||
|
||||
sys_log(0, "Empire Priv empire(%d) type(%d) value(%d) duration_sec(%d)", empire, type, value, duration_sec);
|
||||
}
|
||||
|
||||
/**
|
||||
* @version 05/06/08 Bang2ni - <20><><EFBFBD>ӽð<D3BD> <20>߰<EFBFBD>
|
||||
*/
|
||||
struct FSendChangeGuildPriv
|
||||
{
|
||||
FSendChangeGuildPriv(DWORD guild_id, BYTE type, int value, time_t end_time_sec)
|
||||
{
|
||||
p.guild_id = guild_id;
|
||||
p.type = type;
|
||||
p.value = value;
|
||||
p.bLog = 1;
|
||||
// ADD_GUILD_PRIV_TIME
|
||||
p.end_time_sec = end_time_sec;
|
||||
// END_OF_ADD_GUILD_PRIV_TIME
|
||||
}
|
||||
|
||||
void operator() (CPeer* peer)
|
||||
{
|
||||
peer->EncodeHeader(HEADER_DG_CHANGE_GUILD_PRIV, 0, sizeof(TPacketDGChangeGuildPriv));
|
||||
peer->Encode(&p, sizeof(TPacketDGChangeGuildPriv));
|
||||
p.bLog = 0;
|
||||
}
|
||||
|
||||
TPacketDGChangeGuildPriv p;
|
||||
};
|
||||
|
||||
struct FSendChangeEmpirePriv
|
||||
{
|
||||
FSendChangeEmpirePriv(BYTE empire, BYTE type, int value, time_t end_time_sec)
|
||||
{
|
||||
p.empire = empire;
|
||||
p.type = type;
|
||||
p.value = value;
|
||||
p.bLog = 1;
|
||||
// ADD_EMPIRE_PRIV_TIME
|
||||
p.end_time_sec = end_time_sec;
|
||||
// END_OF_ADD_EMPIRE_PRIV_TIME
|
||||
}
|
||||
|
||||
void operator ()(CPeer* peer)
|
||||
{
|
||||
peer->EncodeHeader(HEADER_DG_CHANGE_EMPIRE_PRIV, 0, sizeof(TPacketDGChangeEmpirePriv));
|
||||
peer->Encode(&p, sizeof(TPacketDGChangeEmpirePriv));
|
||||
p.bLog = 0;
|
||||
}
|
||||
|
||||
TPacketDGChangeEmpirePriv p;
|
||||
};
|
||||
|
||||
struct FSendChangeCharPriv
|
||||
{
|
||||
FSendChangeCharPriv(DWORD pid, BYTE type, int value)
|
||||
{
|
||||
p.pid = pid;
|
||||
p.type = type;
|
||||
p.value = value;
|
||||
p.bLog = 1;
|
||||
}
|
||||
void operator()(CPeer* peer)
|
||||
{
|
||||
peer->EncodeHeader(HEADER_DG_CHANGE_CHARACTER_PRIV, 0, sizeof(TPacketDGChangeCharacterPriv));
|
||||
peer->Encode(&p, sizeof(TPacketDGChangeCharacterPriv));
|
||||
p.bLog = 0;
|
||||
}
|
||||
TPacketDGChangeCharacterPriv p;
|
||||
};
|
||||
|
||||
// ADD_GUILD_PRIV_TIME
|
||||
void CPrivManager::SendChangeGuildPriv(DWORD guild_id, BYTE type, int value, time_t end_time_sec)
|
||||
{
|
||||
CClientManager::instance().for_each_peer(FSendChangeGuildPriv(guild_id, type, value, end_time_sec));
|
||||
}
|
||||
// END_OF_ADD_GUILD_PRIV_TIME
|
||||
|
||||
// ADD_EMPIRE_PRIV_TIME
|
||||
void CPrivManager::SendChangeEmpirePriv(BYTE empire, BYTE type, int value, time_t end_time_sec)
|
||||
{
|
||||
CClientManager::instance().for_each_peer(FSendChangeEmpirePriv(empire, type, value, end_time_sec));
|
||||
}
|
||||
// END_OF_ADD_EMPIRE_PRIV_TIME
|
||||
|
||||
void CPrivManager::SendChangeCharPriv(DWORD pid, BYTE type, int value)
|
||||
{
|
||||
CClientManager::instance().for_each_peer(FSendChangeCharPriv(pid, type, value));
|
||||
}
|
||||
|
||||
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];
|
||||
if (pPrivEmpireData)
|
||||
{
|
||||
FSendChangeEmpirePriv(e, i, pPrivEmpireData->value, pPrivEmpireData->end_time_sec)(peer);
|
||||
}
|
||||
// END_OF_ADD_EMPIRE_PRIV_TIME
|
||||
}
|
||||
|
||||
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);
|
||||
// END_OF_ADD_GUILD_PRIV_TIME
|
||||
}
|
||||
for (typeof(m_aPrivChar[i].begin()) it = m_aPrivChar[i].begin(); it != m_aPrivChar[i].end(); ++it)
|
||||
{
|
||||
FSendChangeCharPriv(it->first, i, it->second->value)(peer);
|
||||
}
|
||||
}
|
||||
}
|
106
db/src/PrivManager.h
Normal file
106
db/src/PrivManager.h
Normal file
@ -0,0 +1,106 @@
|
||||
// vim: ts=8 sw=4
|
||||
#ifndef __INC_PRIV_MANAGER_H
|
||||
#define __INC_PRIV_MANAGER_H
|
||||
|
||||
#include "Peer.h"
|
||||
#include <queue>
|
||||
#include <utility>
|
||||
|
||||
struct TPrivEmpireData
|
||||
{
|
||||
BYTE type;
|
||||
int value;
|
||||
bool bRemoved;
|
||||
BYTE empire;
|
||||
|
||||
// ADD_EMPIRE_PRIV_TIME
|
||||
time_t end_time_sec;
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
/**
|
||||
* @version 05/06/08 Bang2ni - <20><><EFBFBD>ӽð<D3BD> <20>߰<EFBFBD>
|
||||
*/
|
||||
struct TPrivGuildData
|
||||
{
|
||||
BYTE type;
|
||||
int value;
|
||||
bool bRemoved;
|
||||
DWORD guild_id;
|
||||
|
||||
// ADD_GUILD_PRIV_TIME
|
||||
time_t end_time_sec; ///< <20><><EFBFBD>ӽð<D3BD>
|
||||
|
||||
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 )
|
||||
{}
|
||||
// END_OF_ADD_GUILD_PRIV_TIME
|
||||
};
|
||||
|
||||
struct TPrivCharData
|
||||
{
|
||||
BYTE type;
|
||||
int value;
|
||||
bool bRemoved;
|
||||
DWORD pid;
|
||||
TPrivCharData(BYTE type, int value, DWORD pid)
|
||||
: type(type), value(value), bRemoved(false), pid(pid)
|
||||
{}
|
||||
};
|
||||
|
||||
/**
|
||||
* @version 05/06/08 Bang2ni - Guild privilege <20><><EFBFBD><EFBFBD> <20>Լ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>ð<EFBFBD> <20>߰<EFBFBD>
|
||||
*/
|
||||
class CPrivManager : public singleton<CPrivManager>
|
||||
{
|
||||
public:
|
||||
CPrivManager();
|
||||
virtual ~CPrivManager();
|
||||
|
||||
// ADD_GUILD_PRIV_TIME
|
||||
void AddGuildPriv(DWORD guild_id, BYTE type, int value, time_t time_sec);
|
||||
// END_OF_ADD_GUILD_PRIV_TIME
|
||||
|
||||
// ADD_EMPIRE_PRIV_TIME
|
||||
void AddEmpirePriv(BYTE empire, BYTE type, int value, time_t time_sec);
|
||||
// END_OF_ADD_EMPIRE_PRIV_TIME
|
||||
|
||||
void AddCharPriv(DWORD pid, BYTE type, int value);
|
||||
|
||||
void Update();
|
||||
|
||||
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
|
||||
|
||||
// ADD_EMPIRE_PRIV_TIME
|
||||
void SendChangeEmpirePriv(BYTE empire, BYTE type, int value, time_t end_time_sec);
|
||||
// END_OF_ADD_EMPIRE_PRIV_TIME
|
||||
|
||||
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;
|
||||
|
||||
std::priority_queue<stPairChar, std::vector<stPairChar>, std::greater<stPairChar> >
|
||||
m_pqPrivChar;
|
||||
std::priority_queue<stPairGuild, std::vector<stPairGuild>, std::greater<stPairGuild> >
|
||||
m_pqPrivGuild;
|
||||
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];
|
||||
};
|
||||
|
||||
#endif
|
838
db/src/ProtoReader.cpp
Normal file
838
db/src/ProtoReader.cpp
Normal file
@ -0,0 +1,838 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#include <math.h>
|
||||
#include "ProtoReader.h"
|
||||
|
||||
#include "CsvReader.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
inline string trim_left(const string& str)
|
||||
{
|
||||
string::size_type n = str.find_first_not_of(" \t\v\n\r");
|
||||
return n == string::npos ? str : str.substr(n, str.length());
|
||||
}
|
||||
|
||||
inline string trim_right(const string& str)
|
||||
{
|
||||
string::size_type n = str.find_last_not_of(" \t\v\n\r");
|
||||
return n == string::npos ? str : str.substr(0, n + 1);
|
||||
}
|
||||
|
||||
string trim(const string& str){return trim_left(trim_right(str));}
|
||||
|
||||
static string* StringSplit(string strOrigin, string strTok)
|
||||
{
|
||||
int cutAt; //<2F>ڸ<EFBFBD><DAB8><EFBFBD><EFBFBD><EFBFBD>ġ
|
||||
int index = 0; //<2F><><EFBFBD>ڿ<EFBFBD><DABF>ε<EFBFBD><CEB5><EFBFBD>
|
||||
string* strResult = new string[30]; //<2F><><EFBFBD><EFBFBD>return <20>Һ<EFBFBD><D2BA><EFBFBD>
|
||||
|
||||
//strTok<6F><6B>ã<EFBFBD><C3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݺ<EFBFBD>
|
||||
while ((cutAt = strOrigin.find_first_of(strTok)) != strOrigin.npos)
|
||||
{
|
||||
if (cutAt > 0) //<2F>ڸ<EFBFBD><DAB8><EFBFBD><EFBFBD><EFBFBD>ġ<EFBFBD><C4A1>0<EFBFBD><30><EFBFBD><EFBFBD>ũ<EFBFBD><C5A9>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
|
||||
{
|
||||
strResult[index++] = strOrigin.substr(0, cutAt); //<2F><><EFBFBD><EFBFBD><EFBFBD>迭<EFBFBD><E8BFAD><EFBFBD>߰<EFBFBD>
|
||||
}
|
||||
strOrigin = strOrigin.substr(cutAt+1); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڸ<EFBFBD><DAB8>κ<EFBFBD><CEBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѳ<EFBFBD><D1B3><EFBFBD><EFBFBD><EFBFBD>
|
||||
}
|
||||
|
||||
if(strOrigin.length() > 0) //<2F><><EFBFBD><EFBFBD><EFBFBD>̾<EFBFBD><CCBE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
{
|
||||
strResult[index++] = strOrigin.substr(0, cutAt); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>迭<EFBFBD><E8BFAD><EFBFBD>߰<EFBFBD>
|
||||
}
|
||||
|
||||
for( int i=0;i<index;i++)
|
||||
{
|
||||
strResult[i] = trim(strResult[i]);
|
||||
}
|
||||
|
||||
return strResult; //<2F><><EFBFBD><EFBFBD>return
|
||||
}
|
||||
|
||||
|
||||
|
||||
int get_Item_Type_Value(string inputString)
|
||||
{
|
||||
string arType[] = {"ITEM_NONE", "ITEM_WEAPON",
|
||||
"ITEM_ARMOR", "ITEM_USE",
|
||||
"ITEM_AUTOUSE", "ITEM_MATERIAL",
|
||||
"ITEM_SPECIAL", "ITEM_TOOL",
|
||||
"ITEM_LOTTERY", "ITEM_ELK", //10<31><30>
|
||||
|
||||
"ITEM_METIN", "ITEM_CONTAINER",
|
||||
"ITEM_FISH", "ITEM_ROD",
|
||||
"ITEM_RESOURCE", "ITEM_CAMPFIRE",
|
||||
"ITEM_UNIQUE", "ITEM_SKILLBOOK",
|
||||
"ITEM_QUEST", "ITEM_POLYMORPH", //20<32><30>
|
||||
|
||||
"ITEM_TREASURE_BOX", "ITEM_TREASURE_KEY",
|
||||
"ITEM_SKILLFORGET", "ITEM_GIFTBOX",
|
||||
"ITEM_PICK", "ITEM_HAIR",
|
||||
"ITEM_TOTEM", "ITEM_BLEND",
|
||||
"ITEM_COSTUME", "ITEM_DS", //30<33><30>
|
||||
|
||||
"ITEM_SPECIAL_DS", "ITEM_EXTRACT",
|
||||
"ITEM_SECONDARY_COIN", //33<33><33>
|
||||
|
||||
"ITEM_RING",
|
||||
"ITEM_BELT", //35<33><35> (EItemTypes <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ġ<><C4A1> 34)
|
||||
};
|
||||
|
||||
|
||||
int retInt = -1;
|
||||
//cout << "Type : " << typeStr << " -> ";
|
||||
for (int j=0;j<sizeof(arType)/sizeof(arType[0]);j++) {
|
||||
string tempString = arType[j];
|
||||
if (inputString.find(tempString)!=string::npos && tempString.find(inputString)!=string::npos) {
|
||||
//cout << j << " ";
|
||||
retInt = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//cout << endl;
|
||||
|
||||
return retInt;
|
||||
|
||||
}
|
||||
|
||||
int get_Item_SubType_Value(int type_value, string inputString)
|
||||
{
|
||||
static string arSub1[] = { "WEAPON_SWORD", "WEAPON_DAGGER", "WEAPON_BOW", "WEAPON_TWO_HANDED",
|
||||
"WEAPON_BELL", "WEAPON_FAN", "WEAPON_ARROW", "WEAPON_MOUNT_SPEAR"};
|
||||
static string arSub2[] = { "ARMOR_BODY", "ARMOR_HEAD", "ARMOR_SHIELD", "ARMOR_WRIST", "ARMOR_FOOTS",
|
||||
"ARMOR_NECK", "ARMOR_EAR", "ARMOR_NUM_TYPES"};
|
||||
static string arSub3[] = { "USE_POTION", "USE_TALISMAN", "USE_TUNING", "USE_MOVE", "USE_TREASURE_BOX", "USE_MONEYBAG", "USE_BAIT",
|
||||
"USE_ABILITY_UP", "USE_AFFECT", "USE_CREATE_STONE", "USE_SPECIAL", "USE_POTION_NODELAY", "USE_CLEAR",
|
||||
"USE_INVISIBILITY", "USE_DETACHMENT", "USE_BUCKET", "USE_POTION_CONTINUE", "USE_CLEAN_SOCKET",
|
||||
"USE_CHANGE_ATTRIBUTE", "USE_ADD_ATTRIBUTE", "USE_ADD_ACCESSORY_SOCKET", "USE_PUT_INTO_ACCESSORY_SOCKET",
|
||||
"USE_ADD_ATTRIBUTE2", "USE_RECIPE", "USE_CHANGE_ATTRIBUTE2", "USE_BIND", "USE_UNBIND", "USE_TIME_CHARGE_PER", "USE_TIME_CHARGE_FIX", "USE_PUT_INTO_BELT_SOCKET", "USE_PUT_INTO_RING_SOCKET"};
|
||||
static string arSub4[] = { "AUTOUSE_POTION", "AUTOUSE_ABILITY_UP", "AUTOUSE_BOMB", "AUTOUSE_GOLD", "AUTOUSE_MONEYBAG", "AUTOUSE_TREASURE_BOX"};
|
||||
static string arSub5[] = { "MATERIAL_LEATHER", "MATERIAL_BLOOD", "MATERIAL_ROOT", "MATERIAL_NEEDLE", "MATERIAL_JEWEL",
|
||||
"MATERIAL_DS_REFINE_NORMAL", "MATERIAL_DS_REFINE_BLESSED", "MATERIAL_DS_REFINE_HOLLY"};
|
||||
static string arSub6[] = { "SPECIAL_MAP", "SPECIAL_KEY", "SPECIAL_DOC", "SPECIAL_SPIRIT"};
|
||||
static string arSub7[] = { "TOOL_FISHING_ROD" };
|
||||
static string arSub8[] = { "LOTTERY_TICKET", "LOTTERY_INSTANT" };
|
||||
static string arSub10[] = { "METIN_NORMAL", "METIN_GOLD" };
|
||||
static string arSub12[] = { "FISH_ALIVE", "FISH_DEAD"};
|
||||
static string arSub14[] = { "RESOURCE_FISHBONE", "RESOURCE_WATERSTONEPIECE", "RESOURCE_WATERSTONE", "RESOURCE_BLOOD_PEARL",
|
||||
"RESOURCE_BLUE_PEARL", "RESOURCE_WHITE_PEARL", "RESOURCE_BUCKET", "RESOURCE_CRYSTAL", "RESOURCE_GEM",
|
||||
"RESOURCE_STONE", "RESOURCE_METIN", "RESOURCE_ORE" };
|
||||
static string arSub16[] = { "UNIQUE_NONE", "UNIQUE_BOOK", "UNIQUE_SPECIAL_RIDE", "UNIQUE_3", "UNIQUE_4", "UNIQUE_5",
|
||||
"UNIQUE_6", "UNIQUE_7", "UNIQUE_8", "UNIQUE_9", "USE_SPECIAL"};
|
||||
static string arSub28[] = { "COSTUME_BODY", "COSTUME_HAIR" };
|
||||
static string arSub29[] = { "DS_SLOT1", "DS_SLOT2", "DS_SLOT3", "DS_SLOT4", "DS_SLOT5", "DS_SLOT6" };
|
||||
static string arSub31[] = { "EXTRACT_DRAGON_SOUL", "EXTRACT_DRAGON_HEART" };
|
||||
|
||||
static string* arSubType[] = {0, //0
|
||||
arSub1, //1
|
||||
arSub2, //2
|
||||
arSub3, //3
|
||||
arSub4, //4
|
||||
arSub5, //5
|
||||
arSub6, //6
|
||||
arSub7, //7
|
||||
arSub8, //8
|
||||
0, //9
|
||||
arSub10, //10
|
||||
0, //11
|
||||
arSub12, //12
|
||||
0, //13
|
||||
arSub14, //14
|
||||
0, //15
|
||||
arSub16, //16
|
||||
0, //17
|
||||
0, //18
|
||||
0, //19
|
||||
0, //20
|
||||
0, //21
|
||||
0, //22
|
||||
0, //23
|
||||
0, //24
|
||||
0, //25
|
||||
0, //26
|
||||
0, //27
|
||||
arSub28, //28
|
||||
arSub29, //29
|
||||
arSub29, //30
|
||||
arSub31, //31
|
||||
0, //32
|
||||
0, //33 <20><><EFBFBD><EFBFBD>
|
||||
0, //34 <20><>Ʈ
|
||||
};
|
||||
static int arNumberOfSubtype[_countof(arSubType)] = {
|
||||
0,
|
||||
sizeof(arSub1)/sizeof(arSub1[0]),
|
||||
sizeof(arSub2)/sizeof(arSub2[0]),
|
||||
sizeof(arSub3)/sizeof(arSub3[0]),
|
||||
sizeof(arSub4)/sizeof(arSub4[0]),
|
||||
sizeof(arSub5)/sizeof(arSub5[0]),
|
||||
sizeof(arSub6)/sizeof(arSub6[0]),
|
||||
sizeof(arSub7)/sizeof(arSub7[0]),
|
||||
sizeof(arSub8)/sizeof(arSub8[0]),
|
||||
0,
|
||||
sizeof(arSub10)/sizeof(arSub10[0]),
|
||||
0,
|
||||
sizeof(arSub12)/sizeof(arSub12[0]),
|
||||
0,
|
||||
sizeof(arSub14)/sizeof(arSub14[0]),
|
||||
0,
|
||||
sizeof(arSub16)/sizeof(arSub16[0]),
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
sizeof(arSub28)/sizeof(arSub28[0]),
|
||||
sizeof(arSub29)/sizeof(arSub29[0]),
|
||||
sizeof(arSub29)/sizeof(arSub29[0]),
|
||||
sizeof(arSub31)/sizeof(arSub31[0]),
|
||||
0, // 32
|
||||
0, // 33 <20><><EFBFBD><EFBFBD>
|
||||
0, // 34 <20><>Ʈ
|
||||
};
|
||||
|
||||
|
||||
assert(_countof(arSubType) > type_value && "Subtype rule: Out of range!!");
|
||||
|
||||
// assert <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>..
|
||||
if (_countof(arSubType) <= type_value)
|
||||
{
|
||||
sys_err("SubType : Out of range!! (type_value: %d, count of registered subtype: %d", type_value, _countof(arSubType));
|
||||
return -1;
|
||||
}
|
||||
|
||||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ÿ<><C5B8><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ÿ<EFBFBD><C5B8> <20><EFBFBD>̰<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD><CFB4><EFBFBD> <20>˾ƺ<CBBE><C6BA><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0 <20><><EFBFBD><EFBFBD>
|
||||
if (arSubType[type_value]==0) {
|
||||
return 0;
|
||||
}
|
||||
//
|
||||
|
||||
int retInt = -1;
|
||||
//cout << "SubType : " << subTypeStr << " -> ";
|
||||
for (int j=0;j<arNumberOfSubtype[type_value];j++) {
|
||||
string tempString = arSubType[type_value][j];
|
||||
string tempInputString = trim(inputString);
|
||||
if (tempInputString.compare(tempString)==0)
|
||||
{
|
||||
//cout << j << " ";
|
||||
retInt = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//cout << endl;
|
||||
|
||||
return retInt;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int get_Item_AntiFlag_Value(string inputString)
|
||||
{
|
||||
|
||||
string arAntiFlag[] = {"ANTI_FEMALE", "ANTI_MALE", "ANTI_MUSA", "ANTI_ASSASSIN", "ANTI_SURA", "ANTI_MUDANG",
|
||||
"ANTI_GET", "ANTI_DROP", "ANTI_SELL", "ANTI_EMPIRE_A", "ANTI_EMPIRE_B", "ANTI_EMPIRE_C",
|
||||
"ANTI_SAVE", "ANTI_GIVE", "ANTI_PKDROP", "ANTI_STACK", "ANTI_MYSHOP", "ANTI_SAFEBOX"};
|
||||
|
||||
|
||||
int retValue = 0;
|
||||
string* arInputString = StringSplit(inputString, "|"); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ܾ<DCBE><EEBAB0> <20>ɰ<EFBFBD> <20>迭.
|
||||
for(int i =0;i<sizeof(arAntiFlag)/sizeof(arAntiFlag[0]);i++) {
|
||||
string tempString = arAntiFlag[i];
|
||||
for (int j=0; j<30 ; j++) //<2F>ִ<EFBFBD> 30<33><30> <20>ܾ<EFBFBD><DCBE><EFBFBD><EFBFBD><EFBFBD>. (<28>ϵ<EFBFBD><CFB5>ڵ<EFBFBD>)
|
||||
{
|
||||
string tempString2 = arInputString[j];
|
||||
if (tempString2.compare(tempString)==0) { //<2F><>ġ<EFBFBD>ϴ<EFBFBD><CFB4><EFBFBD> Ȯ<><C8AE>.
|
||||
retValue = retValue + pow((float)2,(float)i);
|
||||
}
|
||||
|
||||
if(tempString2.compare("") == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
delete []arInputString;
|
||||
//cout << "AntiFlag : " << antiFlagStr << " -> " << retValue << endl;
|
||||
|
||||
return retValue;
|
||||
}
|
||||
|
||||
int get_Item_Flag_Value(string inputString)
|
||||
{
|
||||
|
||||
string arFlag[] = {"ITEM_TUNABLE", "ITEM_SAVE", "ITEM_STACKABLE", "COUNT_PER_1GOLD", "ITEM_SLOW_QUERY", "ITEM_UNIQUE",
|
||||
"ITEM_MAKECOUNT", "ITEM_IRREMOVABLE", "CONFIRM_WHEN_USE", "QUEST_USE", "QUEST_USE_MULTIPLE",
|
||||
"QUEST_GIVE", "ITEM_QUEST", "LOG", "STACKABLE", "SLOW_QUERY", "REFINEABLE", "IRREMOVABLE", "ITEM_APPLICABLE"};
|
||||
|
||||
|
||||
int retValue = 0;
|
||||
string* arInputString = StringSplit(inputString, "|"); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ܾ<DCBE><EEBAB0> <20>ɰ<EFBFBD> <20>迭.
|
||||
for(int i =0;i<sizeof(arFlag)/sizeof(arFlag[0]);i++) {
|
||||
string tempString = arFlag[i];
|
||||
for (int j=0; j<30 ; j++) //<2F>ִ<EFBFBD> 30<33><30> <20>ܾ<EFBFBD><DCBE><EFBFBD><EFBFBD><EFBFBD>. (<28>ϵ<EFBFBD><CFB5>ڵ<EFBFBD>)
|
||||
{
|
||||
string tempString2 = arInputString[j];
|
||||
if (tempString2.compare(tempString)==0) { //<2F><>ġ<EFBFBD>ϴ<EFBFBD><CFB4><EFBFBD> Ȯ<><C8AE>.
|
||||
retValue = retValue + pow((float)2,(float)i);
|
||||
}
|
||||
|
||||
if(tempString2.compare("") == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
delete []arInputString;
|
||||
//cout << "Flag : " << flagStr << " -> " << retValue << endl;
|
||||
|
||||
return retValue;
|
||||
}
|
||||
|
||||
int get_Item_WearFlag_Value(string inputString)
|
||||
{
|
||||
|
||||
string arWearrFlag[] = {"WEAR_BODY", "WEAR_HEAD", "WEAR_FOOTS", "WEAR_WRIST", "WEAR_WEAPON", "WEAR_NECK", "WEAR_EAR", "WEAR_SHIELD", "WEAR_UNIQUE",
|
||||
"WEAR_ARROW", "WEAR_HAIR", "WEAR_ABILITY"};
|
||||
|
||||
|
||||
int retValue = 0;
|
||||
string* arInputString = StringSplit(inputString, "|"); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ܾ<DCBE><EEBAB0> <20>ɰ<EFBFBD> <20>迭.
|
||||
for(int i =0;i<sizeof(arWearrFlag)/sizeof(arWearrFlag[0]);i++) {
|
||||
string tempString = arWearrFlag[i];
|
||||
for (int j=0; j<30 ; j++) //<2F>ִ<EFBFBD> 30<33><30> <20>ܾ<EFBFBD><DCBE><EFBFBD><EFBFBD><EFBFBD>. (<28>ϵ<EFBFBD><CFB5>ڵ<EFBFBD>)
|
||||
{
|
||||
string tempString2 = arInputString[j];
|
||||
if (tempString2.compare(tempString)==0) { //<2F><>ġ<EFBFBD>ϴ<EFBFBD><CFB4><EFBFBD> Ȯ<><C8AE>.
|
||||
retValue = retValue + pow((float)2,(float)i);
|
||||
}
|
||||
|
||||
if(tempString2.compare("") == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
delete []arInputString;
|
||||
//cout << "WearFlag : " << wearFlagStr << " -> " << retValue << endl;
|
||||
|
||||
return retValue;
|
||||
}
|
||||
|
||||
int get_Item_Immune_Value(string inputString)
|
||||
{
|
||||
|
||||
string arImmune[] = {"PARA","CURSE","STUN","SLEEP","SLOW","POISON","TERROR"};
|
||||
|
||||
int retValue = 0;
|
||||
string* arInputString = StringSplit(inputString, "|"); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ܾ<DCBE><EEBAB0> <20>ɰ<EFBFBD> <20>迭.
|
||||
for(int i =0;i<sizeof(arImmune)/sizeof(arImmune[0]);i++) {
|
||||
string tempString = arImmune[i];
|
||||
for (int j=0; j<30 ; j++) //<2F>ִ<EFBFBD> 30<33><30> <20>ܾ<EFBFBD><DCBE><EFBFBD><EFBFBD><EFBFBD>. (<28>ϵ<EFBFBD><CFB5>ڵ<EFBFBD>)
|
||||
{
|
||||
string tempString2 = arInputString[j];
|
||||
if (tempString2.compare(tempString)==0) { //<2F><>ġ<EFBFBD>ϴ<EFBFBD><CFB4><EFBFBD> Ȯ<><C8AE>.
|
||||
retValue = retValue + pow((float)2,(float)i);
|
||||
}
|
||||
|
||||
if(tempString2.compare("") == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
delete []arInputString;
|
||||
//cout << "Immune : " << immuneStr << " -> " << retValue << endl;
|
||||
|
||||
return retValue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int get_Item_LimitType_Value(string inputString)
|
||||
{
|
||||
string arLimitType[] = {"LIMIT_NONE", "LEVEL", "STR", "DEX", "INT", "CON", "PC_BANG", "REAL_TIME", "REAL_TIME_FIRST_USE", "TIMER_BASED_ON_WEAR"};
|
||||
|
||||
int retInt = -1;
|
||||
//cout << "LimitType : " << limitTypeStr << " -> ";
|
||||
for (int j=0;j<sizeof(arLimitType)/sizeof(arLimitType[0]);j++) {
|
||||
string tempString = arLimitType[j];
|
||||
string tempInputString = trim(inputString);
|
||||
if (tempInputString.compare(tempString)==0)
|
||||
{
|
||||
//cout << j << " ";
|
||||
retInt = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//cout << endl;
|
||||
|
||||
return retInt;
|
||||
}
|
||||
|
||||
|
||||
int get_Item_ApplyType_Value(string inputString)
|
||||
{
|
||||
string arApplyType[] = {"APPLY_NONE", "APPLY_MAX_HP", "APPLY_MAX_SP", "APPLY_CON", "APPLY_INT", "APPLY_STR", "APPLY_DEX", "APPLY_ATT_SPEED",
|
||||
"APPLY_MOV_SPEED", "APPLY_CAST_SPEED", "APPLY_HP_REGEN", "APPLY_SP_REGEN", "APPLY_POISON_PCT", "APPLY_STUN_PCT",
|
||||
"APPLY_SLOW_PCT", "APPLY_CRITICAL_PCT", "APPLY_PENETRATE_PCT", "APPLY_ATTBONUS_HUMAN", "APPLY_ATTBONUS_ANIMAL",
|
||||
"APPLY_ATTBONUS_ORC", "APPLY_ATTBONUS_MILGYO", "APPLY_ATTBONUS_UNDEAD", "APPLY_ATTBONUS_DEVIL", "APPLY_STEAL_HP",
|
||||
"APPLY_STEAL_SP", "APPLY_MANA_BURN_PCT", "APPLY_DAMAGE_SP_RECOVER", "APPLY_BLOCK", "APPLY_DODGE", "APPLY_RESIST_SWORD",
|
||||
"APPLY_RESIST_TWOHAND", "APPLY_RESIST_DAGGER", "APPLY_RESIST_BELL", "APPLY_RESIST_FAN", "APPLY_RESIST_BOW", "APPLY_RESIST_FIRE",
|
||||
"APPLY_RESIST_ELEC", "APPLY_RESIST_MAGIC", "APPLY_RESIST_WIND", "APPLY_REFLECT_MELEE", "APPLY_REFLECT_CURSE", "APPLY_POISON_REDUCE",
|
||||
"APPLY_KILL_SP_RECOVER", "APPLY_EXP_DOUBLE_BONUS", "APPLY_GOLD_DOUBLE_BONUS", "APPLY_ITEM_DROP_BONUS", "APPLY_POTION_BONUS",
|
||||
"APPLY_KILL_HP_RECOVER", "APPLY_IMMUNE_STUN", "APPLY_IMMUNE_SLOW", "APPLY_IMMUNE_FALL", "APPLY_SKILL", "APPLY_BOW_DISTANCE",
|
||||
"APPLY_ATT_GRADE_BONUS", "APPLY_DEF_GRADE_BONUS", "APPLY_MAGIC_ATT_GRADE", "APPLY_MAGIC_DEF_GRADE", "APPLY_CURSE_PCT",
|
||||
"APPLY_MAX_STAMINA", "APPLY_ATTBONUS_WARRIOR", "APPLY_ATTBONUS_ASSASSIN", "APPLY_ATTBONUS_SURA", "APPLY_ATTBONUS_SHAMAN",
|
||||
"APPLY_ATTBONUS_MONSTER", "APPLY_MALL_ATTBONUS", "APPLY_MALL_DEFBONUS", "APPLY_MALL_EXPBONUS", "APPLY_MALL_ITEMBONUS",
|
||||
"APPLY_MALL_GOLDBONUS", "APPLY_MAX_HP_PCT", "APPLY_MAX_SP_PCT", "APPLY_SKILL_DAMAGE_BONUS", "APPLY_NORMAL_HIT_DAMAGE_BONUS",
|
||||
"APPLY_SKILL_DEFEND_BONUS", "APPLY_NORMAL_HIT_DEFEND_BONUS", "APPLY_PC_BANG_EXP_BONUS", "APPLY_PC_BANG_DROP_BONUS",
|
||||
"APPLY_EXTRACT_HP_PCT", "APPLY_RESIST_WARRIOR", "APPLY_RESIST_ASSASSIN", "APPLY_RESIST_SURA", "APPLY_RESIST_SHAMAN",
|
||||
"APPLY_ENERGY", "APPLY_DEF_GRADE", "APPLY_COSTUME_ATTR_BONUS", "APPLY_MAGIC_ATTBONUS_PER", "APPLY_MELEE_MAGIC_ATTBONUS_PER",
|
||||
"APPLY_RESIST_ICE", "APPLY_RESIST_EARTH", "APPLY_RESIST_DARK", "APPLY_ANTI_CRITICAL_PCT", "APPLY_ANTI_PENETRATE_PCT",
|
||||
};
|
||||
|
||||
int retInt = -1;
|
||||
//cout << "ApplyType : " << applyTypeStr << " -> ";
|
||||
for (int j=0;j<sizeof(arApplyType)/sizeof(arApplyType[0]);j++) {
|
||||
string tempString = arApplyType[j];
|
||||
string tempInputString = trim(inputString);
|
||||
if (tempInputString.compare(tempString)==0)
|
||||
{
|
||||
//cout << j << " ";
|
||||
retInt = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//cout << endl;
|
||||
|
||||
return retInt;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>䵵 <20>д´<D0B4>.
|
||||
|
||||
|
||||
int get_Mob_Rank_Value(string inputString)
|
||||
{
|
||||
string arRank[] = {"PAWN", "S_PAWN", "KNIGHT", "S_KNIGHT", "BOSS", "KING"};
|
||||
|
||||
int retInt = -1;
|
||||
//cout << "Rank : " << rankStr << " -> ";
|
||||
for (int j=0;j<sizeof(arRank)/sizeof(arRank[0]);j++) {
|
||||
string tempString = arRank[j];
|
||||
string tempInputString = trim(inputString);
|
||||
if (tempInputString.compare(tempString)==0)
|
||||
{
|
||||
//cout << j << " ";
|
||||
retInt = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//cout << endl;
|
||||
|
||||
return retInt;
|
||||
}
|
||||
|
||||
|
||||
int get_Mob_Type_Value(string inputString)
|
||||
{
|
||||
string arType[] = { "MONSTER", "NPC", "STONE", "WARP", "DOOR", "BUILDING", "PC", "POLYMORPH_PC", "HORSE", "GOTO"};
|
||||
|
||||
int retInt = -1;
|
||||
//cout << "Type : " << typeStr << " -> ";
|
||||
for (int j=0;j<sizeof(arType)/sizeof(arType[0]);j++) {
|
||||
string tempString = arType[j];
|
||||
string tempInputString = trim(inputString);
|
||||
if (tempInputString.compare(tempString)==0)
|
||||
{
|
||||
//cout << j << " ";
|
||||
retInt = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//cout << endl;
|
||||
|
||||
return retInt;
|
||||
}
|
||||
|
||||
int get_Mob_BattleType_Value(string inputString)
|
||||
{
|
||||
string arBattleType[] = { "MELEE", "RANGE", "MAGIC", "SPECIAL", "POWER", "TANKER", "SUPER_POWER", "SUPER_TANKER"};
|
||||
|
||||
int retInt = -1;
|
||||
//cout << "Battle Type : " << battleTypeStr << " -> ";
|
||||
for (int j=0;j<sizeof(arBattleType)/sizeof(arBattleType[0]);j++) {
|
||||
string tempString = arBattleType[j];
|
||||
string tempInputString = trim(inputString);
|
||||
if (tempInputString.compare(tempString)==0)
|
||||
{
|
||||
//cout << j << " ";
|
||||
retInt = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//cout << endl;
|
||||
|
||||
return retInt;
|
||||
}
|
||||
|
||||
int get_Mob_Size_Value(string inputString)
|
||||
{
|
||||
string arSize[] = { "SAMLL", "MEDIUM", "BIG"};
|
||||
|
||||
int retInt = 0;
|
||||
//cout << "Size : " << sizeStr << " -> ";
|
||||
for (int j=0;j<sizeof(arSize)/sizeof(arSize[0]);j++) {
|
||||
string tempString = arSize[j];
|
||||
string tempInputString = trim(inputString);
|
||||
if (tempInputString.compare(tempString)==0)
|
||||
{
|
||||
//cout << j << " ";
|
||||
retInt = j + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//cout << endl;
|
||||
|
||||
return retInt;
|
||||
}
|
||||
|
||||
int get_Mob_AIFlag_Value(string inputString)
|
||||
{
|
||||
string arAIFlag[] = {"AGGR","NOMOVE","COWARD","NOATTSHINSU","NOATTCHUNJO","NOATTJINNO","ATTMOB","BERSERK","STONESKIN","GODSPEED","DEATHBLOW","REVIVE"};
|
||||
|
||||
|
||||
int retValue = 0;
|
||||
string* arInputString = StringSplit(inputString, ","); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ܾ<DCBE><EEBAB0> <20>ɰ<EFBFBD> <20>迭.
|
||||
for(int i =0;i<sizeof(arAIFlag)/sizeof(arAIFlag[0]);i++) {
|
||||
string tempString = arAIFlag[i];
|
||||
for (int j=0; j<30 ; j++) //<2F>ִ<EFBFBD> 30<33><30> <20>ܾ<EFBFBD><DCBE><EFBFBD><EFBFBD><EFBFBD>. (<28>ϵ<EFBFBD><CFB5>ڵ<EFBFBD>)
|
||||
{
|
||||
string tempString2 = arInputString[j];
|
||||
if (tempString2.compare(tempString)==0) { //<2F><>ġ<EFBFBD>ϴ<EFBFBD><CFB4><EFBFBD> Ȯ<><C8AE>.
|
||||
retValue = retValue + pow((float)2,(float)i);
|
||||
}
|
||||
|
||||
if(tempString2.compare("") == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
delete []arInputString;
|
||||
//cout << "AIFlag : " << aiFlagStr << " -> " << retValue << endl;
|
||||
|
||||
return retValue;
|
||||
}
|
||||
int get_Mob_RaceFlag_Value(string inputString)
|
||||
{
|
||||
string arRaceFlag[] = {"ANIMAL","UNDEAD","DEVIL","HUMAN","ORC","MILGYO","INSECT","FIRE","ICE","DESERT","TREE",
|
||||
"ATT_ELEC","ATT_FIRE","ATT_ICE","ATT_WIND","ATT_EARTH","ATT_DARK"};
|
||||
|
||||
int retValue = 0;
|
||||
string* arInputString = StringSplit(inputString, ","); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ܾ<DCBE><EEBAB0> <20>ɰ<EFBFBD> <20>迭.
|
||||
for(int i =0;i<sizeof(arRaceFlag)/sizeof(arRaceFlag[0]);i++) {
|
||||
string tempString = arRaceFlag[i];
|
||||
for (int j=0; j<30 ; j++) //<2F>ִ<EFBFBD> 30<33><30> <20>ܾ<EFBFBD><DCBE><EFBFBD><EFBFBD><EFBFBD>. (<28>ϵ<EFBFBD><CFB5>ڵ<EFBFBD>)
|
||||
{
|
||||
string tempString2 = arInputString[j];
|
||||
if (tempString2.compare(tempString)==0) { //<2F><>ġ<EFBFBD>ϴ<EFBFBD><CFB4><EFBFBD> Ȯ<><C8AE>.
|
||||
retValue = retValue + pow((float)2,(float)i);
|
||||
}
|
||||
|
||||
if(tempString2.compare("") == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
delete []arInputString;
|
||||
//cout << "Race Flag : " << raceFlagStr << " -> " << retValue << endl;
|
||||
|
||||
return retValue;
|
||||
}
|
||||
int get_Mob_ImmuneFlag_Value(string inputString)
|
||||
{
|
||||
string arImmuneFlag[] = {"STUN","SLOW","FALL","CURSE","POISON","TERROR", "REFLECT"};
|
||||
|
||||
int retValue = 0;
|
||||
string* arInputString = StringSplit(inputString, ","); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ܾ<DCBE><EEBAB0> <20>ɰ<EFBFBD> <20>迭.
|
||||
for(int i =0;i<sizeof(arImmuneFlag)/sizeof(arImmuneFlag[0]);i++) {
|
||||
string tempString = arImmuneFlag[i];
|
||||
for (int j=0; j<30 ; j++) //<2F>ִ<EFBFBD> 30<33><30> <20>ܾ<EFBFBD><DCBE><EFBFBD><EFBFBD><EFBFBD>. (<28>ϵ<EFBFBD><CFB5>ڵ<EFBFBD>)
|
||||
{
|
||||
string tempString2 = arInputString[j];
|
||||
if (tempString2.compare(tempString)==0) { //<2F><>ġ<EFBFBD>ϴ<EFBFBD><CFB4><EFBFBD> Ȯ<><C8AE>.
|
||||
retValue = retValue + pow((float)2,(float)i);
|
||||
}
|
||||
|
||||
if(tempString2.compare("") == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
delete []arInputString;
|
||||
//cout << "Immune Flag : " << immuneFlagStr << " -> " << retValue << endl;
|
||||
|
||||
|
||||
return retValue;
|
||||
}
|
||||
|
||||
|
||||
#ifndef __DUMP_PROTO__
|
||||
|
||||
//<2F><> <20><><EFBFBD>̺<EFBFBD><CCBA><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ش<EFBFBD>.
|
||||
bool Set_Proto_Mob_Table(TMobTable *mobTable, cCsvTable &csvTable,std::map<int,const char*> &nameMap)
|
||||
{
|
||||
int col = 0;
|
||||
str_to_number(mobTable->dwVnum, csvTable.AsStringByIndex(col++));
|
||||
strlcpy(mobTable->szName, csvTable.AsStringByIndex(col++), sizeof(mobTable->szName));
|
||||
|
||||
//3. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20≯<EFBFBD> <20>־<EFBFBD><D6BE>ֱ<EFBFBD>.
|
||||
map<int,const char*>::iterator it;
|
||||
it = nameMap.find(mobTable->dwVnum);
|
||||
if (it != nameMap.end()) {
|
||||
const char * localeName = it->second;
|
||||
strlcpy(mobTable->szLocaleName, localeName, sizeof (mobTable->szLocaleName));
|
||||
} else {
|
||||
strlcpy(mobTable->szLocaleName, mobTable->szName, sizeof (mobTable->szLocaleName));
|
||||
}
|
||||
|
||||
//RANK
|
||||
int rankValue = get_Mob_Rank_Value(csvTable.AsStringByIndex(col++));
|
||||
mobTable->bRank = rankValue;
|
||||
//TYPE
|
||||
int typeValue = get_Mob_Type_Value(csvTable.AsStringByIndex(col++));
|
||||
mobTable->bType = typeValue;
|
||||
//BATTLE_TYPE
|
||||
int battleTypeValue = get_Mob_BattleType_Value(csvTable.AsStringByIndex(col++));
|
||||
mobTable->bBattleType = battleTypeValue;
|
||||
|
||||
str_to_number(mobTable->bLevel, csvTable.AsStringByIndex(col++));
|
||||
//SIZE
|
||||
int sizeValue = get_Mob_Size_Value(csvTable.AsStringByIndex(col++));
|
||||
mobTable->bSize = sizeValue;
|
||||
//AI_FLAG
|
||||
int aiFlagValue = get_Mob_AIFlag_Value(csvTable.AsStringByIndex(col++));
|
||||
mobTable->dwAIFlag = aiFlagValue;
|
||||
//mount_capacity;
|
||||
col++;
|
||||
//RACE_FLAG
|
||||
int raceFlagValue = get_Mob_RaceFlag_Value(csvTable.AsStringByIndex(col++));
|
||||
mobTable->dwRaceFlag = raceFlagValue;
|
||||
//IMMUNE_FLAG
|
||||
int immuneFlagValue = get_Mob_ImmuneFlag_Value(csvTable.AsStringByIndex(col++));
|
||||
mobTable->dwImmuneFlag = immuneFlagValue;
|
||||
|
||||
str_to_number(mobTable->bEmpire, csvTable.AsStringByIndex(col++)); //col = 11
|
||||
|
||||
strlcpy(mobTable->szFolder, csvTable.AsStringByIndex(col++), sizeof(mobTable->szFolder));
|
||||
|
||||
str_to_number(mobTable->bOnClickType, csvTable.AsStringByIndex(col++));
|
||||
|
||||
str_to_number(mobTable->bStr, csvTable.AsStringByIndex(col++));
|
||||
str_to_number(mobTable->bDex, csvTable.AsStringByIndex(col++));
|
||||
str_to_number(mobTable->bCon, csvTable.AsStringByIndex(col++));
|
||||
str_to_number(mobTable->bInt, csvTable.AsStringByIndex(col++));
|
||||
str_to_number(mobTable->dwDamageRange[0], csvTable.AsStringByIndex(col++));
|
||||
str_to_number(mobTable->dwDamageRange[1], csvTable.AsStringByIndex(col++));
|
||||
str_to_number(mobTable->dwMaxHP, csvTable.AsStringByIndex(col++));
|
||||
str_to_number(mobTable->bRegenCycle, csvTable.AsStringByIndex(col++));
|
||||
str_to_number(mobTable->bRegenPercent, csvTable.AsStringByIndex(col++));
|
||||
str_to_number(mobTable->dwGoldMin, csvTable.AsStringByIndex(col++));
|
||||
str_to_number(mobTable->dwGoldMax, csvTable.AsStringByIndex(col++));
|
||||
str_to_number(mobTable->dwExp, csvTable.AsStringByIndex(col++));
|
||||
str_to_number(mobTable->wDef, csvTable.AsStringByIndex(col++));
|
||||
str_to_number(mobTable->sAttackSpeed, csvTable.AsStringByIndex(col++));
|
||||
str_to_number(mobTable->sMovingSpeed, csvTable.AsStringByIndex(col++));
|
||||
str_to_number(mobTable->bAggresiveHPPct, csvTable.AsStringByIndex(col++));
|
||||
str_to_number(mobTable->wAggressiveSight, csvTable.AsStringByIndex(col++));
|
||||
str_to_number(mobTable->wAttackRange, csvTable.AsStringByIndex(col++));
|
||||
|
||||
str_to_number(mobTable->dwDropItemVnum, csvTable.AsStringByIndex(col++)); //32
|
||||
str_to_number(mobTable->dwResurrectionVnum, csvTable.AsStringByIndex(col++));
|
||||
for (int i = 0; i < MOB_ENCHANTS_MAX_NUM; ++i)
|
||||
str_to_number(mobTable->cEnchants[i], csvTable.AsStringByIndex(col++));
|
||||
|
||||
for (int i = 0; i < MOB_RESISTS_MAX_NUM; ++i)
|
||||
str_to_number(mobTable->cResists[i], csvTable.AsStringByIndex(col++));
|
||||
|
||||
str_to_number(mobTable->fDamMultiply, csvTable.AsStringByIndex(col++));
|
||||
str_to_number(mobTable->dwSummonVnum, csvTable.AsStringByIndex(col++));
|
||||
str_to_number(mobTable->dwDrainSP, csvTable.AsStringByIndex(col++));
|
||||
|
||||
//Mob_Color
|
||||
++col;
|
||||
|
||||
str_to_number(mobTable->dwPolymorphItemVnum, csvTable.AsStringByIndex(col++));
|
||||
|
||||
str_to_number(mobTable->Skills[0].bLevel, csvTable.AsStringByIndex(col++));
|
||||
str_to_number(mobTable->Skills[0].dwVnum, csvTable.AsStringByIndex(col++));
|
||||
str_to_number(mobTable->Skills[1].bLevel, csvTable.AsStringByIndex(col++));
|
||||
str_to_number(mobTable->Skills[1].dwVnum, csvTable.AsStringByIndex(col++));
|
||||
str_to_number(mobTable->Skills[2].bLevel, csvTable.AsStringByIndex(col++));
|
||||
str_to_number(mobTable->Skills[2].dwVnum, csvTable.AsStringByIndex(col++));
|
||||
str_to_number(mobTable->Skills[3].bLevel, csvTable.AsStringByIndex(col++));
|
||||
str_to_number(mobTable->Skills[3].dwVnum, csvTable.AsStringByIndex(col++));
|
||||
str_to_number(mobTable->Skills[4].bLevel, csvTable.AsStringByIndex(col++));
|
||||
str_to_number(mobTable->Skills[4].dwVnum, csvTable.AsStringByIndex(col++));
|
||||
|
||||
str_to_number(mobTable->bBerserkPoint, csvTable.AsStringByIndex(col++));
|
||||
str_to_number(mobTable->bStoneSkinPoint, csvTable.AsStringByIndex(col++));
|
||||
str_to_number(mobTable->bGodSpeedPoint, csvTable.AsStringByIndex(col++));
|
||||
str_to_number(mobTable->bDeathBlowPoint, csvTable.AsStringByIndex(col++));
|
||||
str_to_number(mobTable->bRevivePoint, csvTable.AsStringByIndex(col++));
|
||||
|
||||
sys_log(0, "MOB #%-5d %-24s level: %-3u rank: %u empire: %d", mobTable->dwVnum, mobTable->szLocaleName, mobTable->bLevel, mobTable->bRank, mobTable->bEmpire);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Set_Proto_Item_Table(TItemTable *itemTable, cCsvTable &csvTable,std::map<int,const char*> &nameMap)
|
||||
{
|
||||
int col = 0;
|
||||
|
||||
int dataArray[33];
|
||||
for (int i=0; i<sizeof(dataArray)/sizeof(dataArray[0]);i++) {
|
||||
int validCheck = 0;
|
||||
if (i==2) {
|
||||
dataArray[i] = get_Item_Type_Value(csvTable.AsStringByIndex(col));
|
||||
validCheck = dataArray[i];
|
||||
} else if (i==3) {
|
||||
dataArray[i] = get_Item_SubType_Value(dataArray[i-1], csvTable.AsStringByIndex(col));
|
||||
validCheck = dataArray[i];
|
||||
} else if (i==5) {
|
||||
dataArray[i] = get_Item_AntiFlag_Value(csvTable.AsStringByIndex(col));
|
||||
validCheck = dataArray[i];
|
||||
} else if (i==6) {
|
||||
dataArray[i] = get_Item_Flag_Value(csvTable.AsStringByIndex(col));
|
||||
validCheck = dataArray[i];
|
||||
} else if (i==7) {
|
||||
dataArray[i] = get_Item_WearFlag_Value(csvTable.AsStringByIndex(col));
|
||||
validCheck = dataArray[i];
|
||||
} else if (i==8) {
|
||||
dataArray[i] = get_Item_Immune_Value(csvTable.AsStringByIndex(col));
|
||||
validCheck = dataArray[i];
|
||||
} else if (i==14) {
|
||||
dataArray[i] = get_Item_LimitType_Value(csvTable.AsStringByIndex(col));
|
||||
validCheck = dataArray[i];
|
||||
} else if (i==16) {
|
||||
dataArray[i] = get_Item_LimitType_Value(csvTable.AsStringByIndex(col));
|
||||
validCheck = dataArray[i];
|
||||
} else if (i==18) {
|
||||
dataArray[i] = get_Item_ApplyType_Value(csvTable.AsStringByIndex(col));
|
||||
validCheck = dataArray[i];
|
||||
} else if (i==20) {
|
||||
dataArray[i] = get_Item_ApplyType_Value(csvTable.AsStringByIndex(col));
|
||||
validCheck = dataArray[i];
|
||||
} else if (i==22) {
|
||||
dataArray[i] = get_Item_ApplyType_Value(csvTable.AsStringByIndex(col));
|
||||
validCheck = dataArray[i];
|
||||
} else {
|
||||
str_to_number(dataArray[i], csvTable.AsStringByIndex(col));
|
||||
}
|
||||
|
||||
if (validCheck == -1)
|
||||
{
|
||||
std::ostringstream dataStream;
|
||||
|
||||
for (int j = 0; j < i; ++j)
|
||||
dataStream << dataArray[j] << ",";
|
||||
|
||||
//fprintf(stderr, "ItemProto Reading Failed : Invalid value.\n");
|
||||
sys_err("ItemProto Reading Failed : Invalid value. (index: %d, col: %d, value: %s)", i, col, csvTable.AsStringByIndex(col));
|
||||
sys_err("\t%d ~ %d Values: %s", 0, i, dataStream.str().c_str());
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
col = col + 1;
|
||||
}
|
||||
|
||||
// vnum <20><> vnum range <20>б<EFBFBD>.
|
||||
{
|
||||
std::string s(csvTable.AsStringByIndex(0));
|
||||
int pos = s.find("~");
|
||||
// vnum <20>ʵ忡 '~'<27><> <20><><EFBFBD>ٸ<EFBFBD> <20>н<EFBFBD>
|
||||
if (std::string::npos == pos)
|
||||
{
|
||||
itemTable->dwVnum = dataArray[0];
|
||||
itemTable->dwVnumRange = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string s_start_vnum (s.substr(0, pos));
|
||||
std::string s_end_vnum (s.substr(pos +1 ));
|
||||
|
||||
int start_vnum = atoi(s_start_vnum.c_str());
|
||||
int end_vnum = atoi(s_end_vnum.c_str());
|
||||
if (0 == start_vnum || (0 != end_vnum && end_vnum < start_vnum))
|
||||
{
|
||||
sys_err ("INVALID VNUM %s", s.c_str());
|
||||
return false;
|
||||
}
|
||||
itemTable->dwVnum = start_vnum;
|
||||
itemTable->dwVnumRange = end_vnum - start_vnum;
|
||||
}
|
||||
}
|
||||
|
||||
strlcpy(itemTable->szName, csvTable.AsStringByIndex(1), sizeof(itemTable->szName));
|
||||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20≯<EFBFBD> <20>־<EFBFBD><D6BE>ֱ<EFBFBD>.
|
||||
map<int,const char*>::iterator it;
|
||||
it = nameMap.find(itemTable->dwVnum);
|
||||
if (it != nameMap.end()) {
|
||||
const char * localeName = it->second;
|
||||
strlcpy(itemTable->szLocaleName, localeName, sizeof (itemTable->szLocaleName));
|
||||
} else {
|
||||
strlcpy(itemTable->szLocaleName, itemTable->szName, sizeof (itemTable->szLocaleName));
|
||||
}
|
||||
itemTable->bType = dataArray[2];
|
||||
itemTable->bSubType = dataArray[3];
|
||||
itemTable->bSize = dataArray[4];
|
||||
itemTable->dwAntiFlags = dataArray[5];
|
||||
itemTable->dwFlags = dataArray[6];
|
||||
itemTable->dwWearFlags = dataArray[7];
|
||||
itemTable->dwImmuneFlag = dataArray[8];
|
||||
itemTable->dwGold = dataArray[9];
|
||||
itemTable->dwShopBuyPrice = dataArray[10];
|
||||
itemTable->dwRefinedVnum = dataArray[11];
|
||||
itemTable->wRefineSet = dataArray[12];
|
||||
itemTable->bAlterToMagicItemPct = dataArray[13];
|
||||
itemTable->cLimitRealTimeFirstUseIndex = -1;
|
||||
itemTable->cLimitTimerBasedOnWearIndex = -1;
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ITEM_LIMIT_MAX_NUM; ++i)
|
||||
{
|
||||
itemTable->aLimits[i].bType = dataArray[14+i*2];
|
||||
itemTable->aLimits[i].lValue = dataArray[15+i*2];
|
||||
|
||||
if (LIMIT_REAL_TIME_START_FIRST_USE == itemTable->aLimits[i].bType)
|
||||
itemTable->cLimitRealTimeFirstUseIndex = (char)i;
|
||||
|
||||
if (LIMIT_TIMER_BASED_ON_WEAR == itemTable->aLimits[i].bType)
|
||||
itemTable->cLimitTimerBasedOnWearIndex = (char)i;
|
||||
|
||||
}
|
||||
|
||||
for (i = 0; i < ITEM_APPLY_MAX_NUM; ++i)
|
||||
{
|
||||
itemTable->aApplies[i].bType = dataArray[18+i*2];
|
||||
itemTable->aApplies[i].lValue = dataArray[19+i*2];
|
||||
}
|
||||
|
||||
for (i = 0; i < ITEM_VALUES_MAX_NUM; ++i)
|
||||
itemTable->alValues[i] = dataArray[24+i];
|
||||
|
||||
//column for 'Specular'
|
||||
itemTable->bGainSocketPct = dataArray[31];
|
||||
itemTable->sAddonType = dataArray[32];
|
||||
|
||||
//test
|
||||
str_to_number(itemTable->bWeight, "0");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
36
db/src/ProtoReader.h
Normal file
36
db/src/ProtoReader.h
Normal file
@ -0,0 +1,36 @@
|
||||
#ifndef __Item_CSV_READER_H__
|
||||
#define __Item_CSV_READER_H__
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
||||
#include "CsvReader.h"
|
||||
|
||||
//csv <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>о<EFBFBD><D0BE>ͼ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>̺<EFBFBD><CCBA><EFBFBD> <20>־<EFBFBD><D6BE>ش<EFBFBD>.
|
||||
void putItemIntoTable(); //(<28><><EFBFBD>̺<EFBFBD>, <20><EFBFBD>Ʈ<EFBFBD><C6AE><EFBFBD><EFBFBD>)
|
||||
|
||||
int get_Item_Type_Value(std::string inputString);
|
||||
int get_Item_SubType_Value(int type_value, std::string inputString);
|
||||
int get_Item_AntiFlag_Value(std::string inputString);
|
||||
int get_Item_Flag_Value(std::string inputString);
|
||||
int get_Item_WearFlag_Value(std::string inputString);
|
||||
int get_Item_Immune_Value(std::string inputString);
|
||||
int get_Item_LimitType_Value(std::string inputString);
|
||||
int get_Item_ApplyType_Value(std::string inputString);
|
||||
|
||||
|
||||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>䵵 <20><><EFBFBD><EFBFBD> <20><> <20>ִ<EFBFBD>.
|
||||
int get_Mob_Rank_Value(std::string inputString);
|
||||
int get_Mob_Type_Value(std::string inputString);
|
||||
int get_Mob_BattleType_Value(std::string inputString);
|
||||
|
||||
int get_Mob_Size_Value(std::string inputString);
|
||||
int get_Mob_AIFlag_Value(std::string inputString);
|
||||
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);
|
||||
|
||||
#endif
|
39
db/src/QID.h
Normal file
39
db/src/QID.h
Normal file
@ -0,0 +1,39 @@
|
||||
#ifndef __INC_METIN_II_DB_QID_H__
|
||||
#define __INC_METIN_II_DB_QID_H__
|
||||
|
||||
/**
|
||||
* @version 05/06/10 Bang2ni - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>߰<EFBFBD>(QID_ITEMPRICE_XXX)
|
||||
*/
|
||||
enum QID
|
||||
{
|
||||
QID_PLAYER, // 0
|
||||
QID_ITEM, // 1
|
||||
QID_QUEST, // 2
|
||||
QID_AFFECT, // 3
|
||||
QID_LOGIN, // 4
|
||||
QID_SAFEBOX_LOAD, // 5
|
||||
QID_SAFEBOX_CHANGE_SIZE, // 6
|
||||
QID_SAFEBOX_CHANGE_PASSWORD, // 7
|
||||
QID_SAFEBOX_CHANGE_PASSWORD_SECOND, // 8
|
||||
QID_SAFEBOX_SAVE, // 9
|
||||
QID_ITEM_SAVE, // 10
|
||||
QID_ITEM_DESTROY, // 11
|
||||
QID_QUEST_SAVE, // 12
|
||||
QID_PLAYER_SAVE, // 13
|
||||
QID_HIGHSCORE_REGISTER, // 14
|
||||
QID_PLAYER_DELETE, // 15
|
||||
QID_LOGIN_BY_KEY, // 16
|
||||
QID_PLAYER_INDEX_CREATE, // 17
|
||||
QID_ITEM_AWARD_LOAD, // 18
|
||||
QID_ITEM_AWARD_TAKEN, // 19
|
||||
QID_GUILD_RANKING, // 20
|
||||
|
||||
// MYSHOP_PRICE_LIST
|
||||
QID_ITEMPRICE_SAVE, ///< 21, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
QID_ITEMPRICE_DESTROY, ///< 22, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
QID_ITEMPRICE_LOAD_FOR_UPDATE, ///< 23, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ε<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
QID_ITEMPRICE_LOAD, ///< 24, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ε<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
// END_OF_MYSHOP_PRICE_LIST
|
||||
};
|
||||
|
||||
#endif
|
130
db/src/grid.cpp
Normal file
130
db/src/grid.cpp
Normal file
@ -0,0 +1,130 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "../../libthecore/include/memcpy.h"
|
||||
#include "../../common/stl.h"
|
||||
#include "grid.h"
|
||||
|
||||
CGrid::CGrid(int w, int h) : m_iWidth(w), m_iHeight(h)
|
||||
{
|
||||
m_pGrid = new char[m_iWidth * m_iHeight];
|
||||
memset(m_pGrid, 0, sizeof(char) * m_iWidth * m_iHeight);
|
||||
}
|
||||
|
||||
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);
|
||||
thecore_memcpy(m_pGrid, pkGrid->m_pGrid, sizeof(char) * iSize);
|
||||
}
|
||||
|
||||
CGrid::~CGrid()
|
||||
{
|
||||
delete [] m_pGrid;
|
||||
}
|
||||
|
||||
void CGrid::Clear()
|
||||
{
|
||||
memset(m_pGrid, 0, sizeof(char) * m_iWidth * m_iHeight);
|
||||
}
|
||||
|
||||
int CGrid::FindBlank(int w, int h)
|
||||
{
|
||||
// ũ<>Ⱑ <20><> ũ<>ٸ<EFBFBD> Ȯ<><C8AE><EFBFBD><EFBFBD> <20>ʿ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>׳<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||||
if (w > m_iWidth || h > m_iHeight)
|
||||
return -1;
|
||||
|
||||
int iRow;
|
||||
|
||||
for (iRow = 0; iRow < m_iHeight; ++iRow)
|
||||
{
|
||||
for (int iCol = 0; iCol < m_iWidth; ++iCol)
|
||||
{
|
||||
int iIndex = iRow * m_iWidth + iCol;
|
||||
|
||||
if (IsEmpty(iIndex, w, h))
|
||||
return iIndex;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool CGrid::Put(int iPos, int w, int h)
|
||||
{
|
||||
if (!IsEmpty(iPos, w, h))
|
||||
return false;
|
||||
|
||||
for (int y = 0; y < h; ++y)
|
||||
{
|
||||
int iStart = iPos + (y * m_iWidth);
|
||||
m_pGrid[iStart] = true;
|
||||
|
||||
int x = 1;
|
||||
while (x < w)
|
||||
m_pGrid[iStart + x++] = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CGrid::Get(int iPos, int w, int h)
|
||||
{
|
||||
if (iPos >= m_iWidth * m_iHeight)
|
||||
return;
|
||||
|
||||
for (int y = 0; y < h; ++y)
|
||||
{
|
||||
int iStart = iPos + (y * m_iWidth);
|
||||
m_pGrid[iStart] = false;
|
||||
|
||||
int x = 1;
|
||||
while (x < w)
|
||||
m_pGrid[iStart + x++] = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool CGrid::IsEmpty(int iPos, int w, int h)
|
||||
{
|
||||
int iRow = iPos / m_iWidth;
|
||||
|
||||
// Grid <20><><EFBFBD><EFBFBD><EFBFBD>ΰ<EFBFBD><CEB0><EFBFBD> <20><><EFBFBD><EFBFBD> <20>˻<EFBFBD>
|
||||
if (iRow + h > m_iHeight)
|
||||
return false;
|
||||
|
||||
if (iPos + w > iRow * m_iWidth + m_iWidth)
|
||||
return false;
|
||||
|
||||
for (int y = 0; y < h; ++y)
|
||||
{
|
||||
int iStart = iPos + (y * m_iWidth);
|
||||
|
||||
if (m_pGrid[iStart])
|
||||
return false;
|
||||
|
||||
int x = 1;
|
||||
while (x < w)
|
||||
if (m_pGrid[iStart + x++])
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CGrid::Print()
|
||||
{
|
||||
printf("Grid %p\n", this);
|
||||
|
||||
for (int y = 0; y < m_iHeight; ++y)
|
||||
{
|
||||
for (int x = 0; x < m_iWidth; ++x)
|
||||
printf("%d", m_pGrid[y * m_iWidth + x]);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int CGrid::GetSize()
|
||||
{
|
||||
return m_iWidth * m_iHeight;
|
||||
}
|
||||
|
27
db/src/grid.h
Normal file
27
db/src/grid.h
Normal file
@ -0,0 +1,27 @@
|
||||
// vim: ts=8 sw=4
|
||||
#ifndef __INC_METIN_II_GRID_H__
|
||||
#define __INC_METIN_II_GRID_H__
|
||||
|
||||
class CGrid
|
||||
{
|
||||
public:
|
||||
CGrid(int w, int h);
|
||||
CGrid(CGrid * pkGrid, int w, int h);
|
||||
~CGrid();
|
||||
|
||||
void Clear();
|
||||
int FindBlank(int w, int h);
|
||||
bool IsEmpty(int iPos, int w, int h);
|
||||
bool Put(int iPos, int w, int h);
|
||||
void Get(int iPos, int w, int h);
|
||||
void Print();
|
||||
unsigned int GetSize();
|
||||
|
||||
protected:
|
||||
int m_iWidth;
|
||||
int m_iHeight;
|
||||
|
||||
char * m_pGrid;
|
||||
};
|
||||
|
||||
#endif
|
20
db/src/stdafx.h
Normal file
20
db/src/stdafx.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef __INC_METiN_II_DBSERV_STDAFX_H__
|
||||
#define __INC_METiN_II_DBSERV_STDAFX_H__
|
||||
|
||||
#include "../../libthecore/include/stdafx.h"
|
||||
|
||||
#ifndef __WIN32__
|
||||
#include <semaphore.h>
|
||||
#else
|
||||
#define isdigit iswdigit
|
||||
#define isspace iswspace
|
||||
#endif
|
||||
|
||||
#include "../../common/length.h"
|
||||
#include "../../common/tables.h"
|
||||
#include "../../common/singleton.h"
|
||||
#include "../../common/utils.h"
|
||||
#include "../../common/stl.h"
|
||||
#include "../../common/service.h"
|
||||
|
||||
#endif
|
22
db/src/version.cpp
Normal file
22
db/src/version.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void WriteVersion()
|
||||
{
|
||||
#ifndef __WIN32__
|
||||
FILE* fp(fopen("VERSION.txt", "w"));
|
||||
|
||||
if (NULL != fp)
|
||||
{
|
||||
fprintf(fp, "game perforce revision: %s\n", __P4_VERSION__);
|
||||
fprintf(fp, "%s@%s:%s\n", __USER__, __HOSTNAME__, __PWD__);
|
||||
fclose(fp);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "cannot open VERSION.txt\n");
|
||||
exit(0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
Reference in New Issue
Block a user