diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | src/account-server/account.cpp | 2 | ||||
-rw-r--r-- | src/account-server/dalstorage.cpp | 106 | ||||
-rw-r--r-- | src/account-server/main-account.cpp | 13 | ||||
-rw-r--r-- | src/game-server/main-game.cpp | 10 | ||||
-rw-r--r-- | src/game-server/mapmanager.cpp | 8 |
6 files changed, 99 insertions, 49 deletions
@@ -1,3 +1,12 @@ +2007-02-01 Rogier Polak <rogier_polak@users.sourceforge.net> + + * src/account-server/main-account.cpp, + src/account-server/dalstorage.cpp, src/account-server/account.cpp, + src/game-server/mapmanager.cpp, src/game-server/main-game.cpp: + Added graceful server shutdown, chose some more sane variables names + for SQL queries and fixed a possible character collision error (patch + applied by Bjørn Lindeijer). + 2007-01-14 Björn Steinbrink <B.Steinbrink@gmx.de> * src/utils/logger.h: Unified logging macros. diff --git a/src/account-server/account.cpp b/src/account-server/account.cpp index c827a92d..256e5c73 100644 --- a/src/account-server/account.cpp +++ b/src/account-server/account.cpp @@ -116,7 +116,7 @@ Account::getPassword(void) const void Account::setEmail(const std::string& email) { - // should we check that the email address is valid first? + // Email validity is checked by Accounthandler mEmail = email; } diff --git a/src/account-server/dalstorage.cpp b/src/account-server/dalstorage.cpp index 278d28db..c4dad80f 100644 --- a/src/account-server/dalstorage.cpp +++ b/src/account-server/dalstorage.cpp @@ -630,28 +630,31 @@ void DALStorage::flush(AccountPtr const &account) // the loss of data would be minimized. // update the account. - std::ostringstream sql1; - sql1 << "update " << ACCOUNTS_TBL_NAME + std::ostringstream sqlUpdateAccountTable; + sqlUpdateAccountTable << "update " << ACCOUNTS_TBL_NAME << " set username = \"" << account->getName() << "\", " << "password = \"" << account->getPassword() << "\", " << "email = \"" << account->getEmail() << "\", " << "level = '" << account->getLevel() << "' " << "where id = '" << account->getID() << "';"; - mDb->execSql(sql1.str()); + mDb->execSql(sqlUpdateAccountTable.str()); // get the list of characters that belong to this account. Players &characters = account->getCharacters(); // insert or update the characters. for (Players::const_iterator it = characters.begin(), - it_end = characters.end(); it != it_end; ++it) { - - std::ostringstream sql3; + it_end = characters.end(); it != it_end; ++it) + { if ((*it)->getDatabaseID() < 0) { + std::ostringstream sqlInsertCharactersTable; // insert the character - sql3 << "insert into " << CHARACTERS_TBL_NAME + // This assumes that the characters name has been checked for + // uniqueness + sqlInsertCharactersTable + << "insert into " << CHARACTERS_TBL_NAME << " (user_id, name, gender, hair_style, hair_color, level, money," - " x, y, map_id, str, agi, vit, int, dex, luck) values (" + << " x, y, map_id, str, agi, vit, int, dex, luck) values (" << account->getID() << ", \"" << (*it)->getName() << "\", " << (*it)->getGender() << ", " @@ -669,22 +672,11 @@ void DALStorage::flush(AccountPtr const &account) << (*it)->getRawStat(STAT_DEXTERITY) << ", " << (*it)->getRawStat(STAT_LUCK) << ");"; - // get the character id - std::ostringstream sql2; - sql2 << "select id from " << CHARACTERS_TBL_NAME - << " where name = \"" << (*it)->getName() << "\";"; - RecordSet const &charInfo = mDb->execSql(sql2.str()); - if (charInfo.isEmpty()) { - // FIXME: this does not make any sense to me -- silene - (*it)->setDatabaseID(1); - } - else - { - string_to<unsigned int> toUint; - (*it)->setDatabaseID(toUint(charInfo(0, 0))); - } + mDb->execSql(sqlInsertCharactersTable.str()); } else { - sql3 << "update " << CHARACTERS_TBL_NAME + std::ostringstream sqlUpdateCharactersTable; + sqlUpdateCharactersTable + << "update " << CHARACTERS_TBL_NAME << " set name = \"" << (*it)->getName() << "\", " << " gender = " << (*it)->getGender() << ", " << " hair_style = " << (int)(*it)->getHairStyle() << ", " @@ -705,8 +697,30 @@ void DALStorage::flush(AccountPtr const &account) << " dex = " << (*it)->getRawStat(STAT_DEXTERITY) << ", " << " luck = " << (*it)->getRawStat(STAT_LUCK) << " where id = " << (*it)->getDatabaseID() << ";"; + + mDb->execSql(sqlUpdateCharactersTable.str()); + } + + if ((*it)->getDatabaseID() < 0) + { + // get the character's id + std::ostringstream sqlSelectIdCharactersTable; + sqlSelectIdCharactersTable + << "select id from " << CHARACTERS_TBL_NAME + << " where name = \"" << (*it)->getName() << "\";"; + RecordSet const &charInfo = + mDb->execSql(sqlSelectIdCharactersTable.str()); + + if (!charInfo.isEmpty()) { + string_to<unsigned int> toUint; + (*it)->setDatabaseID(toUint(charInfo(0, 0))); + } + else + { + // TODO: The character's name is not unique, or some other + // error has occured + } } - mDb->execSql(sql3.str()); // TODO: inventories. } @@ -718,27 +732,29 @@ void DALStorage::flush(AccountPtr const &account) // a string to an unsigned int. string_to<unsigned short> toUint; - std::ostringstream sql4; - sql4 << "select name, id from " << CHARACTERS_TBL_NAME + std::ostringstream sqlSelectNameIdCharactersTable; + sqlSelectNameIdCharactersTable + << "select name, id from " << CHARACTERS_TBL_NAME << " where user_id = '" << account->getID() << "';"; - const RecordSet& charInMemInfo = mDb->execSql(sql4.str()); + const RecordSet& charInMemInfo = + mDb->execSql(sqlSelectNameIdCharactersTable.str()); // We compare chars from memory and those existing in db, // And delete those not in mem but existing in db. bool charFound; - for ( unsigned int i = 0; i < charInMemInfo.rows(); ++i) // in database + for (unsigned int i = 0; i < charInMemInfo.rows(); ++i) // in database { charFound = false; for (Players::const_iterator it = characters.begin(), it_end = characters.end(); it != it_end; ++it) // In memory { - if ( charInMemInfo(i, 0) == (*it)->getName() ) + if (charInMemInfo(i, 0) == (*it)->getName()) { charFound = true; break; } } - if ( !charFound ) + if (!charFound) { // The char is db but not in memory, // It will be removed from database. @@ -748,22 +764,24 @@ void DALStorage::flush(AccountPtr const &account) unsigned int charId = toUint(charInMemInfo(i, 1)); // delete the inventory. - std::ostringstream sql5; - sql5 << "delete from "; - sql5 << INVENTORIES_TBL_NAME; - sql5 << " where owner_id = '"; - sql5 << charId; - sql5 << "';"; - mDb->execSql(sql5.str()); + std::ostringstream sqlDeleteInventoryTable; + sqlDeleteInventoryTable + << "delete from " + << INVENTORIES_TBL_NAME + << " where owner_id = '" + << charId + << "';"; + mDb->execSql(sqlDeleteInventoryTable.str()); // now delete the character. - std::ostringstream sql6; - sql6 << "delete from "; - sql6 << CHARACTERS_TBL_NAME; - sql6 << " where id = '"; - sql6 << charId; - sql6 << "';"; - mDb->execSql(sql6.str()); + std::ostringstream sqlDeleteCharactersTable; + sqlDeleteCharactersTable + << "delete from " + << CHARACTERS_TBL_NAME + << " where id = '" + << charId + << "';"; + mDb->execSql(sqlDeleteCharactersTable.str()); } } } diff --git a/src/account-server/main-account.cpp b/src/account-server/main-account.cpp index 0bb550a1..dc06be96 100644 --- a/src/account-server/main-account.cpp +++ b/src/account-server/main-account.cpp @@ -69,6 +69,12 @@ ServerHandler *serverHandler; /** Chat Channels Manager */ ChatChannelManager *chatChannelManager; +/** Callback used when SIGQUIT signal is received. */ +void closeGracefully(int dummy) +{ + running = false; +} + /** * Initializes the server. */ @@ -78,6 +84,10 @@ void initialize() // Reset to default segmentation fault handling for debugging purposes signal(SIGSEGV, SIG_DFL); + // Used to close via process signals + signal(SIGQUIT, closeGracefully); + signal(SIGINT, closeGracefully); + // Set enet to quit on exit. atexit(enet_deinitialize); @@ -268,7 +278,8 @@ int main(int argc, char *argv[]) int port = int(config.getValue("accountServerPort", DEFAULT_SERVER_PORT)); if (!accountHandler->startListen(port) || !serverHandler->startListen(port + 1) || - !chatHandler->startListen(port + 2)) { + !chatHandler->startListen(port + 2)) + { LOG_FATAL("Unable to create an ENet server host."); return 3; } diff --git a/src/game-server/main-game.cpp b/src/game-server/main-game.cpp index 63e1f66e..b33c4016 100644 --- a/src/game-server/main-game.cpp +++ b/src/game-server/main-game.cpp @@ -97,6 +97,12 @@ AccountConnection *accountHandler; /** Global game state */ State *gameState; +/** Callback used when SIGQUIT signal is received. */ +void closeGracefully(int dummy) +{ + running = false; +} + /** * Initializes the server. */ @@ -105,6 +111,10 @@ void initialize() // Reset to default segmentation fault handling for debugging purposes signal(SIGSEGV, SIG_DFL); + // Used to close via process signals + signal(SIGQUIT, closeGracefully); + signal(SIGINT, closeGracefully); + /* * If the path values aren't defined, we set the default * depending on the platform. diff --git a/src/game-server/mapmanager.cpp b/src/game-server/mapmanager.cpp index 1bceb8e2..dcb91363 100644 --- a/src/game-server/mapmanager.cpp +++ b/src/game-server/mapmanager.cpp @@ -88,7 +88,7 @@ MapManager::~MapManager() } } -Map *MapManager::getMap(int mapId) +Map* MapManager::getMap(int mapId) { Maps::iterator i = maps.find(mapId); assert(i != maps.end() && i->second.isActive); @@ -99,7 +99,8 @@ Map *MapManager::getMap(int mapId) map = MapReader::readMap("maps/" + file); if (!map) { - LOG_ERROR("Unable to load map \"" << file << "\" (id " << mapId << ")"); + LOG_ERROR("Unable to load map \"" << file << "\" (id " + << mapId << ")"); return NULL; } LOG_INFO("Loaded map \"" << file << "\" (id " << mapId << ")"); @@ -119,7 +120,8 @@ void MapManager::raiseActive(int mapId) Maps::iterator i = maps.find(mapId); assert(i != maps.end()); i->second.isActive = true; - LOG_INFO("Activating map \"" << i->second.fileName << "\" (id " << i->first << ")"); + LOG_INFO("Activating map \"" << i->second.fileName << "\" (id " + << i->first << ")"); } bool MapManager::isActive(int mapId) const |