summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--src/account-server/account.cpp2
-rw-r--r--src/account-server/dalstorage.cpp106
-rw-r--r--src/account-server/main-account.cpp13
-rw-r--r--src/game-server/main-game.cpp10
-rw-r--r--src/game-server/mapmanager.cpp8
6 files changed, 99 insertions, 49 deletions
diff --git a/ChangeLog b/ChangeLog
index cf975b1b..e7f2db76 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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