summaryrefslogtreecommitdiff
path: root/src/account-server
diff options
context:
space:
mode:
authorGuillaume Melquiond <guillaume.melquiond@gmail.com>2006-12-31 13:37:33 +0000
committerGuillaume Melquiond <guillaume.melquiond@gmail.com>2006-12-31 13:37:33 +0000
commitad002e15ffdd80b36ced71c2fb9b91366afed15d (patch)
tree7cee8a8be51b1ac6ee26ae3861cc4780f9a6b83a /src/account-server
parent723e7454e5d164b9d438a45b0446b56b72f36d83 (diff)
downloadmanaserv-ad002e15ffdd80b36ced71c2fb9b91366afed15d.tar.gz
manaserv-ad002e15ffdd80b36ced71c2fb9b91366afed15d.tar.bz2
manaserv-ad002e15ffdd80b36ced71c2fb9b91366afed15d.tar.xz
manaserv-ad002e15ffdd80b36ced71c2fb9b91366afed15d.zip
Finished implementation for warping players around servers. Thoroughly untested.
Diffstat (limited to 'src/account-server')
-rw-r--r--src/account-server/dalstorage.cpp180
-rw-r--r--src/account-server/dalstorage.hpp8
-rw-r--r--src/account-server/serverhandler.cpp15
-rw-r--r--src/account-server/storage.hpp9
4 files changed, 144 insertions, 68 deletions
diff --git a/src/account-server/dalstorage.cpp b/src/account-server/dalstorage.cpp
index 644464b3..2208a91e 100644
--- a/src/account-server/dalstorage.cpp
+++ b/src/account-server/dalstorage.cpp
@@ -48,6 +48,23 @@ class account_by_name
std::string mName; /**< the name to look for */
};
+/**
+ * Functor used to search a Player by ID in Players.
+ */
+class character_by_id
+{
+ public:
+ character_by_id(int id)
+ : mID(id)
+ {}
+
+ bool operator()(PlayerPtr const &elem) const
+ { return elem->getDatabaseID() == mID; }
+
+ private:
+ int mID; /**< the ID to look for */
+};
+
/**
* Constructor.
@@ -191,12 +208,10 @@ DALStorage::getAccount(const std::string& userName)
// the account was not in the list, look for it in the database.
try {
- std::string sql("select * from ");
- sql += ACCOUNTS_TBL_NAME;
- sql += " where username = \"";
- sql += userName;
- sql += "\";";
- const RecordSet& accountInfo = mDb->execSql(sql);
+ std::ostringstream sql;
+ sql << "select * from " << ACCOUNTS_TBL_NAME << " where username = \""
+ << userName << "\";";
+ const RecordSet& accountInfo = mDb->execSql(sql.str());
// if the account is not even in the database then
// we have no choice but to return nothing.
@@ -206,7 +221,7 @@ DALStorage::getAccount(const std::string& userName)
// specialize the string_to functor to convert
// a string to an unsigned int.
- string_to<unsigned short> toUint;
+ string_to< unsigned > toUint;
unsigned id = toUint(accountInfo(0, 0));
// create an Account instance
@@ -215,81 +230,122 @@ DALStorage::getAccount(const std::string& userName)
accountInfo(0, 2),
accountInfo(0, 3), id));
- // specialize the string_to functor to convert
- // a string to an unsigned short.
- string_to<unsigned short> toUshort;
-
mAccounts.insert(std::make_pair(id, account));
// load the characters associated with the account.
- sql = "select * from ";
- sql += CHARACTERS_TBL_NAME;
- sql += " where user_id = '";
- sql += accountInfo(0, 0);
- sql += "';";
- const RecordSet& charInfo = mDb->execSql(sql);
-
- if (!charInfo.isEmpty()) {
+ sql.str(std::string());
+ sql << "select id from " << CHARACTERS_TBL_NAME << " where user_id = '"
+ << accountInfo(0, 0) << "';";
+ RecordSet const &charInfo = mDb->execSql(sql.str());
+
+ if (!charInfo.isEmpty())
+ {
+ int size = charInfo.rows();
Players players;
- LOG_INFO(userName << "'s account has " << charInfo.rows()
- << " character(s) in database.", 1);
+ LOG_INFO(userName << "'s account has " << size
+ << " character(s) in database.", 1);
- // As the recordset functions are set to be able to get one
- // recordset at a time, we store charInfo in a temp array of
- // strings. To avoid the problem where values of charInfo were
- // erased by the values of mapInfo.
- std::string strCharInfo[charInfo.rows()][charInfo.cols()];
- for (unsigned int i = 0; i < charInfo.rows(); ++i)
+ // Two steps: it seems like multiple requests cannot be alive at the same time.
+ std::vector< unsigned > playerIDs;
+ for (int k = 0; k < size; ++k)
{
- for (unsigned int j = 0; j < charInfo.cols(); ++j)
- {
- strCharInfo[i][j] = charInfo(i,j);
- }
+ playerIDs.push_back(toUint(charInfo(k, 0)));
}
- unsigned int charRows = charInfo.rows();
-
- for (unsigned int k = 0; k < charRows; ++k) {
- PlayerPtr player(new Player(strCharInfo[k][2], toUint(strCharInfo[k][0])));
- player->setGender((Gender) toUshort(strCharInfo[k][3]));
- player->setHairStyle(toUshort(strCharInfo[k][4]));
- player->setHairColor(toUshort(strCharInfo[k][5]));
- player->setLevel(toUshort(strCharInfo[k][6]));
- player->setMoney(toUint(strCharInfo[k][7]));
- Point pos = { toUshort(strCharInfo[k][8]),
- toUshort(strCharInfo[k][9]) };
- player->setPosition(pos);
- for (int i = 0; i < NB_RSTAT; ++i)
- player->setRawStat(i, toUshort(strCharInfo[k][11 + i]));
-
- unsigned int mapId = toUint(strCharInfo[k][10]);
- if ( mapId > 0 )
- {
- player->setMapId(mapId);
- }
- else
- {
- // Set player to default map and one of the default location
- // Default map is to be 1, as not found return value will be 0.
- player->setMapId((int)config.getValue("defaultMap", 1));
- }
- mCharacters.push_back(player);
- players.push_back(player);
- } // End of for each characters
+ for (int k = 0; k < size; ++k)
+ {
+ players.push_back(getCharacter(playerIDs[k]));
+ }
account->setCharacters(players);
- } // End if there are characters.
+ }
return account;
}
- catch (const DbSqlQueryExecFailure& e) {
+ catch (const DbSqlQueryExecFailure& e)
+ {
return AccountPtr(NULL); // TODO: Throw exception here
}
}
/**
+ * Gets a character by database ID.
+ */
+PlayerPtr DALStorage::getCharacter(int id)
+{
+ // connect to the database (if not connected yet).
+ open();
+
+ // look for the character in the list first.
+ Players::iterator it_end = mCharacters.end(),
+ it = std::find_if(mCharacters.begin(), it_end, character_by_id(id));
+
+ if (it != it_end)
+ return *it;
+
+ using namespace dal;
+
+ // the account was not in the list, look for it in the database.
+ try {
+ std::ostringstream sql;
+ sql << "select * from " << CHARACTERS_TBL_NAME << " where id = '"
+ << id << "';";
+ RecordSet const &charInfo = mDb->execSql(sql.str());
+
+ // if the character is not even in the database then
+ // we have no choice but to return nothing.
+ if (charInfo.isEmpty())
+ {
+ return PlayerPtr(NULL);
+ }
+
+ // specialize the string_to functor to convert
+ // a string to an unsigned int.
+ string_to< unsigned > toUint;
+
+ // specialize the string_to functor to convert
+ // a string to an unsigned short.
+ string_to< unsigned short > toUshort;
+
+ Player *player = new Player(charInfo(0, 2), toUint(charInfo(0, 0)));
+ player->setGender((Gender)toUshort(charInfo(0, 3)));
+ player->setHairStyle(toUshort(charInfo(0, 4)));
+ player->setHairColor(toUshort(charInfo(0, 5)));
+ player->setLevel(toUshort(charInfo(0, 6)));
+ player->setMoney(toUint(charInfo(0, 7)));
+ Point pos = { toUshort(charInfo(0, 8)), toUshort(charInfo(0, 9)) };
+ player->setPosition(pos);
+ for (int i = 0; i < NB_RSTAT; ++i)
+ {
+ player->setRawStat(i, toUshort(charInfo(0, 11 + i)));
+ }
+
+ int mapId = toUint(charInfo(0, 10));
+ if (mapId > 0)
+ {
+ player->setMapId(mapId);
+ }
+ else
+ {
+ // Set player to default map and one of the default location
+ // Default map is to be 1, as not found return value will be 0.
+ player->setMapId((int)config.getValue("defaultMap", 1));
+ }
+
+ PlayerPtr ptr(player);
+ mCharacters.push_back(ptr);
+ return ptr;
+ }
+ catch (const DbSqlQueryExecFailure& e)
+ {
+ return PlayerPtr(NULL); // TODO: Throw exception here
+ }
+}
+
+
+/**
* Return the list of all Emails addresses.
*/
std::list<std::string>
diff --git a/src/account-server/dalstorage.hpp b/src/account-server/dalstorage.hpp
index 22c6c6e8..d2633e23 100644
--- a/src/account-server/dalstorage.hpp
+++ b/src/account-server/dalstorage.hpp
@@ -65,6 +65,14 @@ class DALStorage: public Storage
AccountPtr
getAccount(const std::string& userName);
+ /**
+ * Gets a character by database ID.
+ *
+ * @param id the ID of the character.
+ *
+ * @return the character associated to the ID.
+ */
+ PlayerPtr getCharacter(int id);
/**
* Add a new account.
diff --git a/src/account-server/serverhandler.cpp b/src/account-server/serverhandler.cpp
index 1b9baa44..3d3846a7 100644
--- a/src/account-server/serverhandler.cpp
+++ b/src/account-server/serverhandler.cpp
@@ -25,6 +25,7 @@
#include <sstream>
#include "account-server/serverhandler.hpp"
+#include "account-server/storage.hpp"
#include "net/messagein.hpp"
#include "net/messageout.hpp"
#include "net/netcomputer.hpp"
@@ -127,8 +128,8 @@ void ServerHandler::processMessage(NetComputer *comp, MessageIn &msg)
case GAMSG_PLAYER_DATA:
{
int id = msg.readLong();
- /*
- // TODO: get correct character and account from database
+ Storage &store = Storage::instance("tmw");
+ PlayerPtr ptr = store.getCharacter(id);
ptr->setGender((Gender)msg.readByte());
ptr->setHairStyle(msg.readByte());
ptr->setHairColor(msg.readByte());
@@ -141,7 +142,6 @@ void ServerHandler::processMessage(NetComputer *comp, MessageIn &msg)
Point pos = { x, y };
ptr->setPosition(pos);
ptr->setMapId(msg.readShort());
- */
} break;
case GAMSG_REDIRECT:
@@ -152,8 +152,8 @@ void ServerHandler::processMessage(NetComputer *comp, MessageIn &msg)
{
magic_token[i] = 1 + (int)(127 * (rand() / (RAND_MAX + 1.0)));
}
- /*
- // TODO: get correct character and account from database
+ Storage &store = Storage::instance("tmw");
+ PlayerPtr ptr = store.getCharacter(id);
std::string address;
short port;
if (serverHandler->getGameServerFromMap(ptr->getMapId(), address, port))
@@ -165,7 +165,10 @@ void ServerHandler::processMessage(NetComputer *comp, MessageIn &msg)
result.writeString(address);
result.writeShort(port);
}
- */
+ else
+ {
+ LOG_ERROR("Server Change: No game server for the map.", 0);
+ }
} break;
default:
diff --git a/src/account-server/storage.hpp b/src/account-server/storage.hpp
index fec6dcf3..d530f6f2 100644
--- a/src/account-server/storage.hpp
+++ b/src/account-server/storage.hpp
@@ -173,6 +173,15 @@ class Storage
getAccount(const std::string& userName) = 0;
/**
+ * Gets a character by database ID.
+ *
+ * @param id the ID of the character.
+ *
+ * @return the character associated to the ID.
+ */
+ virtual PlayerPtr getCharacter(int id) = 0;
+
+ /**
* Add a new account.
*
* @param account the new account.