From 25914cddf606e683a4226f46b56f800400d633d3 Mon Sep 17 00:00:00 2001 From: Guillaume Melquiond Date: Thu, 30 Aug 2007 16:20:33 +0000 Subject: Got rid of abstract storage and reference-counted pointers. Fixed lifetime of accounts and characters in server memory. Cleaned some code. --- ChangeLog | 24 +++ src/Makefile.am | 7 +- src/account-server/account.cpp | 50 +---- src/account-server/account.hpp | 37 +--- src/account-server/accountclient.cpp | 20 +- src/account-server/accountclient.hpp | 19 +- src/account-server/accounthandler.cpp | 112 +++++----- src/account-server/accounthandler.hpp | 7 +- src/account-server/character.cpp | 42 ++++ src/account-server/character.hpp | 192 +++++++++++++++++ src/account-server/characterdata.cpp | 41 ---- src/account-server/characterdata.hpp | 185 ---------------- src/account-server/dalstorage.cpp | 320 +++++++--------------------- src/account-server/dalstorage.hpp | 82 ++++---- src/account-server/dalstoragesql.hpp | 1 + src/account-server/guild.cpp | 2 + src/account-server/guild.hpp | 18 +- src/account-server/guildmanager.cpp | 2 + src/account-server/guildmanager.hpp | 8 +- src/account-server/main-account.cpp | 38 ++-- src/account-server/serverhandler.cpp | 99 ++++----- src/account-server/serverhandler.hpp | 14 +- src/account-server/storage.cpp | 65 ------ src/account-server/storage.hpp | 373 --------------------------------- src/chat-server/chatchannelmanager.cpp | 11 +- src/chat-server/chathandler.cpp | 21 +- src/utils/countedptr.h | 167 --------------- 27 files changed, 574 insertions(+), 1383 deletions(-) create mode 100644 src/account-server/character.cpp create mode 100644 src/account-server/character.hpp delete mode 100644 src/account-server/characterdata.cpp delete mode 100644 src/account-server/characterdata.hpp delete mode 100644 src/account-server/storage.cpp delete mode 100644 src/account-server/storage.hpp delete mode 100644 src/utils/countedptr.h diff --git a/ChangeLog b/ChangeLog index d63a3064..f3a691da 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +2007-08-29 Guillaume Melquiond + + * src/account-server/storage.hpp, src/account-server/storage.cpp, + src/account-server/main-account.cpp: Removed abstract Storage. Relied + on SQL-based implementation only. + * src/account-server/characterdata.hpp, + src/account-server/characterdata.cpp: Renamed class and files to just + Character. + * src/utils/countedptr.h: Got rid of reference-counted pointers. + * src/account-server/dalstorage.hpp, src/account-server/dalstorage.cpp: + Fixed permanent memory usage for accounts and characters loaded once. + * src/account-server/serverhandler.cpp: Improved robustness to game + server messages. + * src/chat-server/chathandler.cpp, src/account-server/guildmanager.cpp, + src/chat-server/chatchannelmanager.cpp, src/account-server/account.hpp, + src/account-server/accounthandler.hpp, src/account-server/guild.cpp, + src/account-server/accountclient.hpp, src/account-server/guild.hpp, + src/account-server/guildmanager.hpp, src/account-server/account.cpp, + src/account-server/serverhandler.hpp, src/Makefile.am, + src/account-server/dalstoragesql.hpp, + src/account-server/accounthandler.cpp, + src/account-server/accountclient.cpp: Fixed fallout from previous + patches. + 2007-08-29 Guillaume Melquiond * data/scripts/libtmw.lua: Fixed race condition between quest_reply and diff --git a/src/Makefile.am b/src/Makefile.am index d24b3042..f63ef660 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -18,8 +18,8 @@ tmwserv_account_SOURCES = \ account-server/accountclient.cpp \ account-server/accounthandler.hpp \ account-server/accounthandler.cpp \ - account-server/characterdata.hpp \ - account-server/characterdata.cpp \ + account-server/character.hpp \ + account-server/character.cpp \ account-server/dalstorage.hpp \ account-server/dalstorage.cpp \ account-server/dalstoragesql.hpp \ @@ -29,8 +29,6 @@ tmwserv_account_SOURCES = \ account-server/guildmanager.h \ account-server/serverhandler.hpp \ account-server/serverhandler.cpp \ - account-server/storage.hpp \ - account-server/storage.cpp \ chat-server/chathandler.hpp \ chat-server/chathandler.cpp \ chat-server/chatclient.hpp \ @@ -55,7 +53,6 @@ tmwserv_account_SOURCES = \ net/netcomputer.hpp \ net/netcomputer.cpp \ serialize/characterdata.hpp \ - utils/countedptr.h \ utils/functors.h \ utils/logger.h \ utils/logger.cpp \ diff --git a/src/account-server/account.cpp b/src/account-server/account.cpp index 883654f6..bddcf4f9 100644 --- a/src/account-server/account.cpp +++ b/src/account-server/account.cpp @@ -27,32 +27,16 @@ #include "account-server/accountclient.hpp" #include "utils/functors.h" -/** - * Constructor with initial account info. - */ -Account::Account(const std::string& name, - const std::string& password, - const std::string& email, - int level, - int id) - : mName(name), - mPassword(password), - mEmail(email), - mCharacters(), - mID(id), - mLevel(level) -{ - // NOOP -} - - /** * Destructor. */ Account::~Account() { - // mCharacters is a list of smart pointers which will take care about - // deallocating the memory so nothing to deallocate here :) + for (Characters::iterator i = mCharacters.begin(), + i_end = mCharacters.end(); i != i_end; ++i) + { + delete *i; + } } @@ -69,12 +53,9 @@ Account::setCharacters(const Characters& characters) /** * Add a new character. */ -void -Account::addCharacter(CharacterPtr character) +void Account::addCharacter(Character *character) { - if (character.get() != 0) { - mCharacters.push_back(character); - } + mCharacters.push_back(character); } /** @@ -85,28 +66,13 @@ bool Account::delCharacter(std::string const &name) Characters::iterator end = mCharacters.end(), it = std::find_if(mCharacters.begin(), end, - std::bind2nd(obj_name_is(), name)); + std::bind2nd(obj_name_is(), name)); if (it == end) return false; mCharacters.erase(it); return true; } - -/** - * Get a character by name. - */ -CharacterPtr Account::getCharacter(const std::string& name) -{ - Characters::iterator - end = mCharacters.end(), - it = std::find_if(mCharacters.begin(), end, - std::bind2nd(obj_name_is(), name)); - - if (it != end) return *it; - return CharacterPtr(); -} - void Account::setID(int id) { assert(mID < 0); diff --git a/src/account-server/account.hpp b/src/account-server/account.hpp index 7c5b5703..dfc5210f 100644 --- a/src/account-server/account.hpp +++ b/src/account-server/account.hpp @@ -24,9 +24,9 @@ #define _TMWSERV_ACCOUNT_H_ #include +#include -#include "account-server/characterdata.hpp" -#include "utils/countedptr.h" +#include "account-server/character.hpp" /** * Notes: @@ -47,18 +47,10 @@ class Account { public: /** - * Constructor with initial account info. - * - * @param name the user name. - * @param password the user password. - * @param email the user email. + * Constructor. */ - Account(const std::string& name, - const std::string& password, - const std::string& email, - int level, - int id = -1); - + Account(int id = -1): mID(id) + {} /** * Destructor. @@ -152,8 +144,7 @@ class Account * * @param character the new character. */ - void - addCharacter(CharacterPtr character); + void addCharacter(Character *character); /** * Remove a character. @@ -180,14 +171,6 @@ class Account Characters const &getCharacters() const { return mCharacters; } - /** - * Get a character by name. - * - * @return the character if found, NULL otherwise. - */ - CharacterPtr - getCharacter(const std::string& name); - /** * Get account ID. * @@ -203,7 +186,6 @@ class Account void setID(int); private: - Account(); Account(Account const &rhs); Account &operator=(Account const &rhs); @@ -217,11 +199,6 @@ class Account unsigned char mLevel; /**< account level */ }; - -/** - * Type definition for a smart pointer to Account. - */ -typedef utils::CountedPtr AccountPtr; - +typedef std::vector< Account * > Accounts; #endif // _TMWSERV_ACCOUNT_H_ diff --git a/src/account-server/accountclient.cpp b/src/account-server/accountclient.cpp index 383a809d..04bd6d59 100644 --- a/src/account-server/accountclient.cpp +++ b/src/account-server/accountclient.cpp @@ -23,15 +23,13 @@ #include "account-server/accountclient.hpp" -#include "account-server/account.hpp" #include "account-server/accounthandler.hpp" -#include "account-server/characterdata.hpp" AccountClient::AccountClient(ENetPeer *peer): NetComputer(peer), status(CLIENT_LOGIN), - mAccountPtr(NULL), - mCharacterPtr(NULL) + mAccount(NULL), + mCharacter(NULL) { } @@ -41,26 +39,26 @@ AccountClient::~AccountClient() } -void AccountClient::setAccount(AccountPtr acc) +void AccountClient::setAccount(Account *acc) { unsetAccount(); - mAccountPtr = acc; + mAccount = acc; } -void AccountClient::setCharacter(CharacterPtr ch) +void AccountClient::setCharacter(Character *ch) { unsetCharacter(); - mCharacterPtr = ch; + mCharacter = ch; } void AccountClient::unsetAccount() { unsetCharacter(); - mAccountPtr = AccountPtr(NULL); + delete mAccount; + mAccount = NULL; } void AccountClient::unsetCharacter() { - if (mCharacterPtr.get() == NULL) return; - mCharacterPtr = CharacterPtr(NULL); + mCharacter = NULL; } diff --git a/src/account-server/accountclient.hpp b/src/account-server/accountclient.hpp index f64d0ba0..a2c17c0e 100644 --- a/src/account-server/accountclient.hpp +++ b/src/account-server/accountclient.hpp @@ -27,7 +27,7 @@ #include #include "account-server/account.hpp" -#include "account-server/characterdata.hpp" +#include "account-server/character.hpp" #include "net/netcomputer.hpp" class AccountHandler; @@ -59,8 +59,7 @@ class AccountClient : public NetComputer /** * Set the account associated with the connection */ - void - setAccount(AccountPtr acc); + void setAccount(Account *acc); /** * Unset the account associated with the connection @@ -71,14 +70,14 @@ class AccountClient : public NetComputer /** * Get account associated with the connection. */ - AccountPtr - getAccount() const { return mAccountPtr; } + Account *getAccount() const + { return mAccount; } /** * Set the selected character associated with connection. */ void - setCharacter(CharacterPtr ch); + setCharacter(Character *ch); /** * Deselect the character associated with connection. @@ -89,17 +88,17 @@ class AccountClient : public NetComputer /** * Get character associated with the connection */ - CharacterPtr - getCharacter() const { return mCharacterPtr; } + Character *getCharacter() const + { return mCharacter; } int status; private: /** Account associated with connection */ - AccountPtr mAccountPtr; + Account *mAccount; /** Selected character */ - CharacterPtr mCharacterPtr; + Character *mCharacter; }; #endif diff --git a/src/account-server/accounthandler.cpp b/src/account-server/accounthandler.cpp index edb72b7e..9e809588 100644 --- a/src/account-server/accounthandler.cpp +++ b/src/account-server/accounthandler.cpp @@ -28,11 +28,11 @@ #include "point.h" #include "account-server/account.hpp" #include "account-server/accountclient.hpp" -#include "account-server/characterdata.hpp" +#include "account-server/character.hpp" +#include "account-server/dalstorage.hpp" #include "account-server/guild.hpp" #include "account-server/guildmanager.hpp" #include "account-server/serverhandler.hpp" -#include "account-server/storage.hpp" #include "chat-server/chathandler.hpp" #include "net/connectionhandler.hpp" #include "net/messagein.hpp" @@ -149,12 +149,12 @@ AccountHandler::processMessage(NetComputer *comp, MessageIn &message) } } -void AccountHandler::sendCharacterData(AccountClient &computer, int slot, CharacterData const &ch) +void AccountHandler::sendCharacterData(AccountClient &computer, int slot, Character const &ch) { MessageOut charInfo(APMSG_CHAR_INFO); charInfo.writeByte(slot); charInfo.writeString(ch.getName()); - charInfo.writeByte((int)ch.getGender()); + charInfo.writeByte(ch.getGender()); charInfo.writeByte(ch.getHairStyle()); charInfo.writeByte(ch.getHairColor()); charInfo.writeByte(ch.getLevel()); @@ -207,10 +207,9 @@ AccountHandler::handleLoginMessage(AccountClient &computer, MessageIn &msg) } // Check if the account exists - Storage &store = Storage::instance("tmw"); - AccountPtr acc = store.getAccount(username); + Account *acc = storage->getAccount(username); - if (!acc.get() || acc->getPassword() != password) + if (!acc || acc->getPassword() != password) { reply.writeByte(ERRMSG_INVALID_ARGUMENT); computer.send(reply); @@ -225,7 +224,7 @@ AccountHandler::handleLoginMessage(AccountClient &computer, MessageIn &msg) computer.send(reply); // Acknowledge login // Return information about available characters - Characters &chars = computer.getAccount()->getCharacters(); + Characters &chars = acc->getCharacters(); // Send characters list for (unsigned int i = 0; i < chars.size(); i++) @@ -320,31 +319,30 @@ AccountHandler::handleRegisterMessage(AccountClient &computer, MessageIn &msg) { reply.writeByte(ERRMSG_INVALID_ARGUMENT); } + // Check whether the account already exists. + else if (storage->getAccount(username)) + { + reply.writeByte(REGISTER_EXISTS_USERNAME); + } + // Find out whether the email is already in use. + else if (storage->doesEmailAddressExist(email)) + { + reply.writeByte(REGISTER_EXISTS_EMAIL); + } else { - Storage &store = Storage::instance("tmw"); - AccountPtr accPtr = store.getAccount(username); + Account *acc = new Account; + acc->setName(username); + acc->setPassword(password); + acc->setEmail(email); + acc->setLevel(AL_NORMAL); - // Check whether the account already exists. - if (accPtr.get()) - { - reply.writeByte(REGISTER_EXISTS_USERNAME); - } - // Find out whether the email is already in use. - else if (store.doesEmailAddressExist(email)) - { - reply.writeByte(REGISTER_EXISTS_EMAIL); - } - else - { - AccountPtr acc(new Account(username, password, email, AL_NORMAL)); - store.addAccount(acc); - reply.writeByte(ERRMSG_OK); + storage->addAccount(acc); + reply.writeByte(ERRMSG_OK); - // Associate account with connection - computer.setAccount(acc); - computer.status = CLIENT_CONNECTED; - } + // Associate account with connection + computer.setAccount(acc); + computer.status = CLIENT_CONNECTED; } computer.send(reply); @@ -375,10 +373,9 @@ AccountHandler::handleUnregisterMessage(AccountClient &computer, } // See if the account exists - Storage &store = Storage::instance("tmw"); - AccountPtr accPtr = store.getAccount(username); + Account *acc = storage->getAccount(username); - if (!accPtr.get() || accPtr->getPassword() != password) + if (!acc || acc->getPassword() != password) { reply.writeByte(ERRMSG_INVALID_ARGUMENT); computer.send(reply); @@ -387,14 +384,13 @@ AccountHandler::handleUnregisterMessage(AccountClient &computer, // Delete account and associated characters LOG_DEBUG("Unregistered \"" << username - << "\", AccountID: " << accPtr->getID()); - store.delAccount(accPtr); + << "\", AccountID: " << acc->getID()); + storage->delAccount(acc); reply.writeByte(ERRMSG_OK); // If the account to delete is the current account we're loggedin // on, get out of it in memory. - if (computer.getAccount().get() != NULL && - computer.getAccount()->getName() == username) + if (computer.getAccount() && computer.getAccount()->getName() == username) { computer.unsetAccount(); computer.status = CLIENT_LOGIN; @@ -407,8 +403,7 @@ handleEmailChangeMessage(AccountClient &computer, MessageIn &msg) { MessageOut reply(APMSG_EMAIL_CHANGE_RESPONSE); - if (computer.status != CLIENT_CONNECTED || - computer.getAccount().get() == NULL) + if (computer.status != CLIENT_CONNECTED || !computer.getAccount()) { reply.writeByte(ERRMSG_NO_LOGIN); computer.send(reply); @@ -417,8 +412,6 @@ handleEmailChangeMessage(AccountClient &computer, MessageIn &msg) std::string email = msg.readString(); - Storage &store = Storage::instance("tmw"); - if (!stringFilter->isEmailValid(email)) { reply.writeByte(ERRMSG_INVALID_ARGUMENT); @@ -427,7 +420,7 @@ handleEmailChangeMessage(AccountClient &computer, MessageIn &msg) { reply.writeByte(ERRMSG_INVALID_ARGUMENT); } - else if (store.doesEmailAddressExist(email)) + else if (storage->doesEmailAddressExist(email)) { reply.writeByte(EMAILCHG_EXISTS_EMAIL); } @@ -444,8 +437,7 @@ handleEmailGetMessage(AccountClient &computer) { MessageOut reply(APMSG_EMAIL_GET_RESPONSE); - if (computer.status != CLIENT_CONNECTED || - computer.getAccount().get() == NULL) + if (computer.status != CLIENT_CONNECTED || !computer.getAccount()) { reply.writeByte(ERRMSG_NO_LOGIN); computer.send(reply); @@ -467,8 +459,7 @@ AccountHandler::handlePasswordChangeMessage(AccountClient &computer, MessageOut reply(APMSG_PASSWORD_CHANGE_RESPONSE); - if (computer.status != CLIENT_CONNECTED || - computer.getAccount().get() == NULL) + if (computer.status != CLIENT_CONNECTED || !computer.getAccount()) { reply.writeByte(ERRMSG_NO_LOGIN); } @@ -505,8 +496,7 @@ AccountHandler::handleCharacterCreateMessage(AccountClient &computer, MessageOut reply(APMSG_CHAR_CREATE_RESPONSE); - if (computer.status != CLIENT_CONNECTED || - computer.getAccount().get() == NULL) + if (computer.status != CLIENT_CONNECTED || !computer.getAccount()) { reply.writeByte(ERRMSG_NO_LOGIN); } @@ -537,8 +527,7 @@ AccountHandler::handleCharacterCreateMessage(AccountClient &computer, } else { - Storage &store = Storage::instance("tmw"); - if (store.doesCharacterNameExist(name)) + if (storage->doesCharacterNameExist(name)) { reply.writeByte(CREATE_EXISTS_NAME); computer.send(reply); @@ -586,9 +575,10 @@ AccountHandler::handleCharacterCreateMessage(AccountClient &computer, } else { - CharacterPtr newCharacter(new CharacterData(name)); + Character *newCharacter = new Character(name); for (int i = CHAR_ATTR_BEGIN; i < CHAR_ATTR_END; ++i) newCharacter->setAttribute(i, attributes[i - CHAR_ATTR_BEGIN]); + newCharacter->setAccount(computer.getAccount()); newCharacter->setLevel(1); newCharacter->setGender(gender); newCharacter->setHairStyle(hairStyle); @@ -602,7 +592,7 @@ AccountHandler::handleCharacterCreateMessage(AccountClient &computer, LOG_INFO("Character " << name << " was created for " << computer.getAccount()->getName() << "'s account."); - store.flush(computer.getAccount()); // flush changes + storage->flush(computer.getAccount()); // flush changes reply.writeByte(ERRMSG_OK); computer.send(reply); @@ -621,8 +611,7 @@ handleCharacterSelectMessage(AccountClient &computer, MessageIn &msg) { MessageOut reply(APMSG_CHAR_SELECT_RESPONSE); - if (computer.status != CLIENT_CONNECTED || - computer.getAccount().get() == NULL) + if (computer.status != CLIENT_CONNECTED || !computer.getAccount()) { reply.writeByte(ERRMSG_NO_LOGIN); computer.send(reply); @@ -654,7 +643,7 @@ handleCharacterSelectMessage(AccountClient &computer, MessageIn &msg) // set character computer.setCharacter(chars[charNum]); - CharacterPtr selectedChar = computer.getCharacter(); + Character *selectedChar = computer.getCharacter(); reply.writeByte(ERRMSG_OK); LOG_DEBUG(selectedChar->getName() << " is trying to enter the servers."); @@ -680,8 +669,7 @@ handleCharacterDeleteMessage(AccountClient &computer, MessageIn &msg) { MessageOut reply(APMSG_CHAR_DELETE_RESPONSE); - if (computer.status != CLIENT_CONNECTED || - computer.getAccount().get() == NULL) + if (computer.status != CLIENT_CONNECTED || !computer.getAccount()) { reply.writeByte(ERRMSG_NO_LOGIN); computer.send(reply); @@ -702,15 +690,14 @@ handleCharacterDeleteMessage(AccountClient &computer, MessageIn &msg) // Delete the character. If the character to delete is the current // character, get off of it in memory. - if (computer.getCharacter().get() != NULL && - computer.getCharacter()->getName() == chars[charNum].get()->getName()) + std::string const &deletedCharacter = chars[charNum]->getName(); + if (computer.getCharacter() && + computer.getCharacter()->getName() == deletedCharacter) computer.unsetCharacter(); - std::string deletedCharacter = chars[charNum].get()->getName(); computer.getAccount()->delCharacter(deletedCharacter); - Storage &store = Storage::instance("tmw"); - store.flush(computer.getAccount()); + storage->flush(computer.getAccount()); LOG_INFO(deletedCharacter << ": Character deleted..."); @@ -725,8 +712,7 @@ AccountHandler::tokenMatched(AccountClient *computer, int accountID) MessageOut reply(APMSG_RECONNECT_RESPONSE); // Check if the account exists - Storage &store = Storage::instance("tmw"); - AccountPtr acc = store.getAccountByID(accountID); + Account *acc = storage->getAccount(accountID); // Associate account with connection computer->setAccount(acc); diff --git a/src/account-server/accounthandler.hpp b/src/account-server/accounthandler.hpp index 61e81103..9762ca6d 100644 --- a/src/account-server/accounthandler.hpp +++ b/src/account-server/accounthandler.hpp @@ -28,7 +28,7 @@ #include "utils/tokencollector.hpp" class AccountClient; -class CharacterData; +class Character; /** * Manages the data stored in user accounts and provides a reliable interface @@ -95,7 +95,7 @@ class AccountHandler : public ConnectionHandler private: - void sendCharacterData(AccountClient &, int, CharacterData const &); + void sendCharacterData(AccountClient &, int, Character const &); void handleLoginMessage(AccountClient &computer, MessageIn &msg); @@ -133,8 +133,7 @@ class AccountHandler : public ConnectionHandler /** * Send guild join for each guild the player belongs to. */ - void - handleGuildJoining(AccountClient &computer, CharacterData *character); + void handleGuildJoining(AccountClient &computer, Character *character); }; extern AccountHandler * accountHandler; diff --git a/src/account-server/character.cpp b/src/account-server/character.cpp new file mode 100644 index 00000000..e9a40987 --- /dev/null +++ b/src/account-server/character.cpp @@ -0,0 +1,42 @@ +/* + * The Mana World Server + * Copyright 2007 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or any later version. + * + * The Mana World is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with The Mana World; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#include "account-server/character.hpp" + +#include "account-server/account.hpp" + +Character::Character(std::string const &name, int id): + mName(name), mDatabaseID(id), mAccountID(-1), mAccount(NULL), mPos(0,0), mMapId(0), + mGender(0), mHairStyle(0), mHairColor(0), mLevel(0), mAccountLevel(0) +{ + for (int i = 0; i < CHAR_ATTR_NB; ++i) + { + mAttributes[i] = 0; + } +} + +void Character::setAccount(Account *acc) +{ + mAccount = acc; + mAccountID = acc->getID(); + mAccountLevel = acc->getLevel(); +} diff --git a/src/account-server/character.hpp b/src/account-server/character.hpp new file mode 100644 index 00000000..52233b92 --- /dev/null +++ b/src/account-server/character.hpp @@ -0,0 +1,192 @@ +/* + * The Mana World Server + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or any later version. + * + * The Mana World is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with The Mana World; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + +#ifndef _TMWSERV_CHARACTERDATA +#define _TMWSERV_CHARACTERDATA + +#include +#include + +#include "defines.h" +#include "point.h" +#include "common/inventorydata.hpp" + +class Account; +class MessageIn; + +class Character +{ + public: + + Character(std::string const &name, int id = -1); + + /** + * Get and set methods + */ + + /** Gets the database id of the character. */ + int + getDatabaseID() const { return mDatabaseID; } + + /** Sets the database id of the character. */ + void + setDatabaseID(int id) { mDatabaseID = id; } + + /** Gets the account the character belongs to. */ + Account *getAccount() const + { return mAccount; } + + /** Sets the account the character belongs to, and related fields. */ + void setAccount(Account *ptr); + + /** Gets the ID of the account the character belongs to. */ + int getAccountID() const + { return mAccountID; } + + /** Sets the ID of the account the character belongs to. */ + void setAccountID(int id) + { mAccountID = id; } + + /** Gets the name of the character. */ + std::string const & + getName() const { return mName; } + + /** Sets the name of the character. */ + void + setName(const std::string& name) { mName = name; } + + /** Gets the gender of the character (male / female). */ + int + getGender() const { return mGender; } + + /** Sets the gender of the character (male / female). */ + void + setGender(int gender) { mGender = gender; } + + /** Gets the hairstyle of the character. */ + int + getHairStyle() const { return mHairStyle; } + + /** Sets the hairstyle of the character. */ + void + setHairStyle(int style) { mHairStyle = style; } + + /** Gets the haircolor of the character. */ + int + getHairColor() const { return mHairColor; } + + /** Sets the haircolor of the character. */ + void + setHairColor(int color) { mHairColor = color; } + + /** Gets the account level of the user. */ + int getAccountLevel() const + { return mAccountLevel; } + + /** + * Sets the account level of the user. + * @param force ensure the level is not modified by a game server. + */ + void setAccountLevel(int l, bool force = false) + { if (force) mAccountLevel = l; } + + /** Gets the level of the character. */ + int + getLevel() const { return mLevel; } + + /** Sets the level of the character. */ + void + setLevel(int level) { mLevel = level; } + + /** Gets the value of a base attribute of the character. */ + int getAttribute(int n) const + { return mAttributes[n - CHAR_ATTR_BEGIN]; } + + /** Sets the value of a base attribute of the character. */ + void setAttribute(int n, int value) + { mAttributes[n - CHAR_ATTR_BEGIN] = value; } + + /** Gets the Id of the map that the character is on. */ + int + getMapId() const { return mMapId; } + + /** Sets the Id of the map that the character is on. */ + void + setMapId(int mapId) { mMapId = mapId; } + + /** Gets the position of the character on the map. */ + Point const & + getPosition() const { return mPos; } + + /** Sets the position of the character on the map. */ + void + setPosition(const Point &p) { mPos = p; } + + /** Add a guild to the character */ + void addGuild(const std::string &name) { mGuilds.push_back(name); } + + /** Returns a list of guilds the player belongs to */ + std::vector + getGuilds() const { return mGuilds; } + + /** + * Gets a reference on the possessions. + */ + Possessions const &getPossessions() const + { return mPossessions; } + + /** + * Gets a reference on the possessions. + */ + Possessions &getPossessions() + { return mPossessions; } + + private: + Character(Character const &); + Character &operator=(Character const &); + + Possessions mPossessions; //!< All the possesions of the character. + std::string mName; //!< Name of the character. + int mDatabaseID; //!< Character database ID. + int mAccountID; //!< Account ID of the owner. + Account *mAccount; //!< Account owning the character. + Point mPos; //!< Position the being is at. + unsigned short mAttributes[CHAR_ATTR_NB]; //!< Attributes. + unsigned short mMapId; //!< Map the being is on. + unsigned char mGender; //!< Gender of the being. + unsigned char mHairStyle; //!< Hair style of the being. + unsigned char mHairColor; //!< Hair color of the being. + unsigned char mLevel; //!< Level of the being. + unsigned char mAccountLevel; //!< Level of the associated account. + + std::vector mGuilds; //!< All the guilds the player + //!< belongs to. +}; + +// Utility typedefs + +/** + * Type definition for a list of Characters. + */ +typedef std::vector< Character * > Characters; + +#endif diff --git a/src/account-server/characterdata.cpp b/src/account-server/characterdata.cpp deleted file mode 100644 index 0e140e3c..00000000 --- a/src/account-server/characterdata.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* - * The Mana World Server - * Copyright 2007 The Mana World Development Team - * - * This file is part of The Mana World. - * - * The Mana World is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or any later version. - * - * The Mana World is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with The Mana World; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id$ - */ - -#include "account-server/characterdata.hpp" - -#include "account-server/dalstorage.hpp" - -CharacterData::CharacterData(std::string const &name, int id): - mName(name), mDatabaseID(id), mAccountID(-1), mPos(0,0), mMapId(0), - mGender(0), mHairStyle(0), mHairColor(0), mLevel(0) -{ - for (int i = 0; i < CHAR_ATTR_NB; ++i) - { - mAttributes[i] = 0; - } -} - -int CharacterData::getAccountLevel() const -{ - AccountPtr acc = Storage::instance("tmw").getAccountByID(mAccountID); - return acc->getLevel(); -} diff --git a/src/account-server/characterdata.hpp b/src/account-server/characterdata.hpp deleted file mode 100644 index b1b19d3a..00000000 --- a/src/account-server/characterdata.hpp +++ /dev/null @@ -1,185 +0,0 @@ -/* - * The Mana World Server - * Copyright 2004 The Mana World Development Team - * - * This file is part of The Mana World. - * - * The Mana World is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or any later version. - * - * The Mana World is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with The Mana World; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id$ - */ - -#ifndef _TMWSERV_CHARACTERDATA -#define _TMWSERV_CHARACTERDATA - -#include -#include - -#include "defines.h" -#include "point.h" -#include "common/inventorydata.hpp" -#include "utils/countedptr.h" - -class MessageIn; - -class CharacterData -{ - public: - - CharacterData(std::string const &name, int id = -1); - - /** - * Get and set methods - */ - - /** Gets the database id of the character. */ - int - getDatabaseID() const { return mDatabaseID; } - - /** Sets the database id of the character. */ - void - setDatabaseID(int id) { mDatabaseID = id; } - - /** Gets the account id of the account the character belongs to. */ - int - getAccountID() const { return mAccountID; } - - /** Sets the account id of the account the character belongs to. */ - void - setAccountID(int id) { mAccountID = id; } - - /** Gets the name of the character. */ - std::string const & - getName() const { return mName; } - - /** Sets the name of the character. */ - void - setName(const std::string& name) { mName = name; } - - /** Gets the gender of the character (male / female). */ - int - getGender() const { return mGender; } - - /** Sets the gender of the character (male / female). */ - void - setGender(int gender) { mGender = gender; } - - /** Gets the hairstyle of the character. */ - int - getHairStyle() const { return mHairStyle; } - - /** Sets the hairstyle of the character. */ - void - setHairStyle(int style) { mHairStyle = style; } - - /** Gets the haircolor of the character. */ - int - getHairColor() const { return mHairColor; } - - /** Sets the haircolor of the character. */ - void - setHairColor(int color) { mHairColor = color; } - - /** Gets the account level of the user. */ - int getAccountLevel() const; - - /** Sets the account level of the user. */ - void setAccountLevel(int) - { /* Ignored as we do not trust game servers that much. */ } - - /** Gets the level of the character. */ - int - getLevel() const { return mLevel; } - - /** Sets the level of the character. */ - void - setLevel(int level) { mLevel = level; } - - /** Gets the value of a base attribute of the character. */ - int getAttribute(int n) const - { return mAttributes[n - CHAR_ATTR_BEGIN]; } - - /** Sets the value of a base attribute of the character. */ - void setAttribute(int n, int value) - { mAttributes[n - CHAR_ATTR_BEGIN] = value; } - - /** Gets the Id of the map that the character is on. */ - int - getMapId() const { return mMapId; } - - /** Sets the Id of the map that the character is on. */ - void - setMapId(int mapId) { mMapId = mapId; } - - /** Gets the position of the character on the map. */ - Point const & - getPosition() const { return mPos; } - - /** Sets the position of the character on the map. */ - void - setPosition(const Point &p) { mPos = p; } - - /** Add a guild to the character */ - void addGuild(const std::string &name) { mGuilds.push_back(name); } - - /** Returns a list of guilds the player belongs to */ - std::vector - getGuilds() const { return mGuilds; } - - /** - * Gets a reference on the possessions. - */ - Possessions const &getPossessions() const - { return mPossessions; } - - /** - * Gets a reference on the possessions. - */ - Possessions &getPossessions() - { return mPossessions; } - - private: - CharacterData(CharacterData const &); - CharacterData &operator=(CharacterData const &); - - Possessions mPossessions; //!< All the possesions of the character. - std::string mName; //!< Name of the character. - int mDatabaseID; //!< Character database ID. - //!< (-1) if not set yet. - int mAccountID; //!< Account ID of the account the character - //!< belongs to. (-1) if not set yet. - Point mPos; //!< Position the being is at. - unsigned short mAttributes[CHAR_ATTR_NB]; //!< Attributes. - unsigned short mMapId; //!< Map the being is on. - unsigned char mGender; //!< Gender of the being. - unsigned char mHairStyle; //!< Hair style of the being. - unsigned char mHairColor; //!< Hair color of the being. - unsigned char mLevel; //!< Level of the being. - - std::vector mGuilds; //!< All the guilds the player - //!< belongs to. -}; - -// Utility typedefs -/** - * Type definition for a smart pointer to CharacterData. - */ -typedef utils::CountedPtr< CharacterData > CharacterPtr; - -/** - * Type definition for a list of Characters. - */ -typedef std::vector< CharacterPtr > Characters; - -#endif diff --git a/src/account-server/dalstorage.cpp b/src/account-server/dalstorage.cpp index 5709fb76..6e3886a3 100644 --- a/src/account-server/dalstorage.cpp +++ b/src/account-server/dalstorage.cpp @@ -20,72 +20,22 @@ * $Id$ */ -#include "account-server/dalstorage.hpp" - #include +#include "account-server/dalstorage.hpp" + #include "configuration.h" #include "point.h" -#include "account-server/characterdata.hpp" +#include "account-server/account.hpp" #include "account-server/guild.hpp" #include "account-server/guildmanager.hpp" #include "account-server/dalstoragesql.hpp" +#include "chat-server/chatchannel.hpp" #include "dal/dalexcept.h" #include "dal/dataproviderfactory.h" #include "utils/functors.h" #include "utils/logger.h" -/** - * Functor used to search an Account by name in Accounts. - */ -class account_by_name -{ - public: - account_by_name(const std::string& name) - : mName(name) - {} - - bool operator()(std::pair const &elem) const - { return elem.second->getName() == mName; } - - private: - std::string mName; /**< the name to look for */ -}; - -/** - * Functor used to search a character by ID in Characters. - */ -class character_by_id -{ - public: - character_by_id(int id) - : mID(id) - {} - - bool operator()(CharacterPtr const &elem) const - { return elem->getDatabaseID() == mID; } - - private: - int mID; /**< the ID to look for */ -}; - -/** - * Functor used to search a character by name in Characters. - */ -class character_by_name -{ -public: - character_by_name(const std::string &name) - : mName(name) - {} - - bool operator()(CharacterPtr const &elem) const - { return elem->getName() == mName; } - -private: - std::string mName; /**< the name to look for */ -}; - /** * Constructor. */ @@ -105,6 +55,7 @@ DALStorage::~DALStorage() if (mDb->isConnected()) { close(); } + delete mDb; // mAccounts and mCharacters contain smart pointers that will deallocate // the memory so nothing else to do here :) @@ -124,7 +75,7 @@ void DALStorage::open() using namespace dal; static bool dbFileShown = false; - std::string dbFile(getName()); + std::string dbFile = "tmw"; try { // open a connection to the database. #if defined (MYSQL_SUPPORT) || defined (POSTGRESQL_SUPPORT) @@ -193,8 +144,6 @@ void DALStorage::open() catch (const DbSqlQueryExecFailure& e) { LOG_ERROR("(DALStorage::open #2) SQL query failure: " << e.what()); } - - mIsOpen = mDb->isConnected(); } @@ -204,25 +153,19 @@ void DALStorage::open() void DALStorage::close() { mDb->disconnect(); - mIsOpen = mDb->isConnected(); } -AccountPtr DALStorage::getAccountBySQL(std::string const &query) +Account *DALStorage::getAccountBySQL(std::string const &query) { - // connect to the database (if not connected yet). - open(); - - using namespace dal; - try { - const RecordSet& accountInfo = mDb->execSql(query); + dal::RecordSet const &accountInfo = mDb->execSql(query); // if the account is not even in the database then // we have no choice but to return nothing. if (accountInfo.isEmpty()) { - return AccountPtr(NULL); + return NULL; } // specialize the string_to functor to convert @@ -232,18 +175,17 @@ AccountPtr DALStorage::getAccountBySQL(std::string const &query) // create an Account instance // and initialize it with information about the user. - AccountPtr account(new Account(accountInfo(0, 1), - accountInfo(0, 2), - accountInfo(0, 3), - toUint(accountInfo(0, 4)), id)); - - mAccounts.insert(std::make_pair(id, account)); + Account *account = new Account(id); + account->setName(accountInfo(0, 1)); + account->setPassword(accountInfo(0, 2)); + account->setEmail(accountInfo(0, 3)); + account->setLevel(toUint(accountInfo(0, 4))); // load the characters associated with the account. std::ostringstream sql; sql << "select id from " << CHARACTERS_TBL_NAME << " where user_id = '" << id << "';"; - RecordSet const &charInfo = mDb->execSql(sql.str()); + dal::RecordSet const &charInfo = mDb->execSql(sql.str()); if (!charInfo.isEmpty()) { @@ -261,10 +203,9 @@ AccountPtr DALStorage::getAccountBySQL(std::string const &query) for (int k = 0; k < size; ++k) { - CharacterPtr ptr = getCharacter(characterIDs[k]); - if (ptr.get()) + if (Character *ptr = getCharacter(characterIDs[k], account)) { - characters.push_back(getCharacter(characterIDs[k])); + characters.push_back(ptr); } else { @@ -277,9 +218,9 @@ AccountPtr DALStorage::getAccountBySQL(std::string const &query) return account; } - catch (const DbSqlQueryExecFailure& e) + catch (dal::DbSqlQueryExecFailure const &e) { - return AccountPtr(NULL); // TODO: Throw exception here + return NULL; // TODO: Throw exception here } } @@ -287,17 +228,8 @@ AccountPtr DALStorage::getAccountBySQL(std::string const &query) /** * Get an account by user name. */ -AccountPtr -DALStorage::getAccount(const std::string& userName) +Account *DALStorage::getAccount(std::string const &userName) { - // look for the account in the list first. - Accounts::iterator it_end = mAccounts.end(), - it = std::find_if(mAccounts.begin(), it_end, account_by_name(userName)); - - if (it != it_end) - return it->second; - - // the account was not in the list, look for it in the database. std::ostringstream sql; sql << "select * from " << ACCOUNTS_TBL_NAME << " where username = \"" << userName << "\";"; return getAccountBySQL(sql.str()); @@ -307,51 +239,37 @@ DALStorage::getAccount(const std::string& userName) /** * Get an account by ID. */ -AccountPtr -DALStorage::getAccountByID(int accountID) +Account *DALStorage::getAccount(int accountID) { - // look for the account in the list first. - Accounts::iterator it = mAccounts.find(accountID); - - if (it != mAccounts.end()) - return it->second; - - // the account was not in the list, look for it in the database. std::ostringstream sql; sql << "select * from " << ACCOUNTS_TBL_NAME << " where id = '" << accountID << "';"; return getAccountBySQL(sql.str()); } -CharacterPtr DALStorage::getCharacterBySQL(std::string const &query) +Character *DALStorage::getCharacterBySQL(std::string const &query, Account *owner) { - // connect to the database (if not connected yet). - open(); - - CharacterData *character; + Character *character; // specialize the string_to functor to convert // a string to an unsigned int. string_to< unsigned > toUint; - using namespace dal; - try { - RecordSet const &charInfo = mDb->execSql(query); + dal::RecordSet const &charInfo = mDb->execSql(query); // if the character is not even in the database then // we have no choice but to return nothing. if (charInfo.isEmpty()) { - return CharacterPtr(NULL); + return NULL; } // specialize the string_to functor to convert // a string to an unsigned short. string_to< unsigned short > toUshort; - character = new CharacterData(charInfo(0, 2), toUint(charInfo(0, 0))); - character->setAccountID(toUint(charInfo(0, 1))); + character = new Character(charInfo(0, 2), toUint(charInfo(0, 0))); character->setGender(toUshort(charInfo(0, 3))); character->setHairStyle(toUshort(charInfo(0, 4))); character->setHairColor(toUshort(charInfo(0, 5))); @@ -376,11 +294,28 @@ CharacterPtr DALStorage::getCharacterBySQL(std::string const &query) // Default map is to be 1, as not found return value will be 0. character->setMapId((int)config.getValue("defaultMap", 1)); } + + /* Fill the account-related fields. Last step, as it may require a new + SQL query. */ + if (owner) + { + character->setAccount(owner); + } + else + { + int id = toUint(charInfo(0, 1)); + character->setAccountID(id); + std::ostringstream s; + s << "select level from tmw_accounts where id = '" << id << "';"; + dal::RecordSet const &levelInfo = mDb->execSql(s.str()); + character->setAccountLevel(toUint(levelInfo(0, 0)), true); + } + } - catch (const DbSqlQueryExecFailure& e) + catch (dal::DbSqlQueryExecFailure const &e) { LOG_ERROR("(DALStorage::getCharacter #1) SQL query failure: " << e.what()); - return CharacterPtr(NULL); + return NULL; } try @@ -389,7 +324,7 @@ CharacterPtr DALStorage::getCharacterBySQL(std::string const &query) sql << " select * from " << INVENTORIES_TBL_NAME << " where owner_id = '" << character->getDatabaseID() << "' order by slot asc;"; - RecordSet const &itemInfo = mDb->execSql(sql.str()); + dal::RecordSet const &itemInfo = mDb->execSql(sql.str()); if (!itemInfo.isEmpty()) { Possessions &poss = character->getPossessions(); @@ -425,39 +360,30 @@ CharacterPtr DALStorage::getCharacterBySQL(std::string const &query) } } } - catch (const DbSqlQueryExecFailure& e) + catch (dal::DbSqlQueryExecFailure const &e) { LOG_ERROR("(DALStorage::getCharacter #2) SQL query failure: " << e.what()); } - CharacterPtr ptr(character); - mCharacters.push_back(ptr); - return ptr; + return character; } /** * Gets a character by database ID. */ -CharacterPtr DALStorage::getCharacter(int id) +Character *DALStorage::getCharacter(int id, Account *owner) { - // look for the character in the list first. - Characters::iterator it_end = mCharacters.end(), - it = std::find_if(mCharacters.begin(), it_end, character_by_id(id)); - - if (it != it_end) - return *it; - - // the account was not in the list, look for it in the database. std::ostringstream sql; sql << "select * from " << CHARACTERS_TBL_NAME << " where id = '" << id << "';"; - return getCharacterBySQL(sql.str()); + return getCharacterBySQL(sql.str(), owner); } +#if 0 /** -* Gets a character by character name. + * Gets a character by character name. */ -CharacterPtr DALStorage::getCharacter(const std::string &name) +Character *DALStorage::getCharacter(const std::string &name) { // look for the character in the list first. Characters::iterator it_end = mCharacters.end(), @@ -471,16 +397,15 @@ CharacterPtr DALStorage::getCharacter(const std::string &name) sql << "select * from " << CHARACTERS_TBL_NAME << " where name = '" << name << "';"; return getCharacterBySQL(sql.str()); } +#endif +#if 0 /** * Return the list of all Emails addresses. */ std::list DALStorage::getEmailList() { - // If not opened already - open(); - std::list emailList; try { @@ -507,6 +432,7 @@ DALStorage::getEmailList() return emailList; } +#endif /** * Tells if the email address already exists @@ -514,9 +440,6 @@ DALStorage::getEmailList() */ bool DALStorage::doesEmailAddressExist(std::string const &email) { - // If not opened already - open(); - try { std::ostringstream sql; sql << "select count(email) from " << ACCOUNTS_TBL_NAME @@ -541,9 +464,6 @@ bool DALStorage::doesEmailAddressExist(std::string const &email) */ bool DALStorage::doesCharacterNameExist(const std::string& name) { - // If not opened already - open(); - try { std::ostringstream sql; sql << "select count(name) from " << CHARACTERS_TBL_NAME @@ -563,12 +483,8 @@ bool DALStorage::doesCharacterNameExist(const std::string& name) return true; } -bool -DALStorage::updateCharacter(CharacterPtr character) +bool DALStorage::updateCharacter(Character *character) { - // If not opened already - open(); - // Update the database Character data (see CharacterData for details) try { @@ -821,7 +737,7 @@ DALStorage::createTable(const std::string& tblName, /** * Add an account to the database. */ -void DALStorage::addAccount(AccountPtr const &account) +void DALStorage::addAccount(Account *account) { assert(account->getCharacters().size() == 0); @@ -849,23 +765,12 @@ void DALStorage::addAccount(AccountPtr const &account) string_to toUint; unsigned id = toUint(accountInfo(0, 0)); account->setID(id); - mAccounts.insert(std::make_pair(id, account)); -} - -/** - * Update all the accounts from the database. - */ -void DALStorage::flushAll() -{ - for (Accounts::iterator i = mAccounts.begin(), - i_end = mAccounts.end(); i != i_end; ++i) - flush(i->second); } /** * Update an account from the database. */ -void DALStorage::flush(AccountPtr const &account) +void DALStorage::flush(Account *account) { assert(account->getID() >= 0); @@ -891,7 +796,12 @@ void DALStorage::flush(AccountPtr const &account) for (Characters::const_iterator it = characters.begin(), it_end = characters.end(); it != it_end; ++it) { - if ((*it)->getDatabaseID() < 0) { + if ((*it)->getDatabaseID() >= 0) + { + updateCharacter(*it); + } + else + { std::ostringstream sqlInsertCharactersTable; // insert the character // This assumes that the characters name has been checked for @@ -919,39 +829,8 @@ void DALStorage::flush(AccountPtr const &account) << (*it)->getAttribute(CHAR_ATTR_CHARISMA) << ");"; mDb->execSql(sqlInsertCharactersTable.str()); - } else { - std::ostringstream sqlUpdateCharactersTable; - sqlUpdateCharactersTable - << "update " << CHARACTERS_TBL_NAME - << " set name = \"" << (*it)->getName() << "\", " - << " gender = " << (*it)->getGender() << ", " - << " hair_style = " << (int)(*it)->getHairStyle() << ", " - << " hair_color = " << (int)(*it)->getHairColor() << ", " - << " level = " << (int)(*it)->getLevel() << ", " - << " money = " << (*it)->getPossessions().money << ", " - << " x = " << (*it)->getPosition().x << ", " - << " y = " << (*it)->getPosition().y << ", " - << " map_id = " << (*it)->getMapId() << ", " - << " str = " << (*it)->getAttribute(CHAR_ATTR_STRENGTH) << ", " - << " agi = " << (*it)->getAttribute(CHAR_ATTR_AGILITY) << ", " - << " dex = " << (*it)->getAttribute(CHAR_ATTR_DEXTERITY) << ", " - << " vit = " << (*it)->getAttribute(CHAR_ATTR_VITALITY) << ", " -#if defined(MYSQL_SUPPORT) || defined(POSTGRESQL_SUPPORT) - << " `int` = " -#else - << " int = " -#endif - << (*it)->getAttribute(CHAR_ATTR_INTELLIGENCE) << ", " - << " will = " << (*it)->getAttribute(CHAR_ATTR_WILLPOWER) << ", " - << " charisma = " << (*it)->getAttribute(CHAR_ATTR_CHARISMA) - << " where id = " << (*it)->getDatabaseID() << ";"; - - mDb->execSql(sqlUpdateCharactersTable.str()); - } - if ((*it)->getDatabaseID() < 0) - { - // get the character's id + // Update the character ID. std::ostringstream sqlSelectIdCharactersTable; sqlSelectIdCharactersTable << "select id from " << CHARACTERS_TBL_NAME @@ -969,8 +848,6 @@ void DALStorage::flush(AccountPtr const &account) // error has occured } } - - // TODO: inventories. } // Existing characters in memory have been inserted or updated in database. @@ -1038,13 +915,10 @@ void DALStorage::flush(AccountPtr const &account) /** * Delete an account and its associated data from the database. */ -void DALStorage::delAccount(AccountPtr const &account) +void DALStorage::delAccount(Account *account) { - using namespace dal; - account->setCharacters(Characters()); flush(account); - mAccounts.erase(account->getID()); // delete the account. std::ostringstream sql; @@ -1053,27 +927,11 @@ void DALStorage::delAccount(AccountPtr const &account) mDb->execSql(sql.str()); } -/** - * Unload an account from memory. - */ -void DALStorage::unloadAccount(AccountPtr const &account) -{ - flush(account); - mAccounts.erase(account->getID()); -} - /** * Add a guild */ void DALStorage::addGuild(Guild* guild) { -#if defined (SQLITE_SUPPORT) - // Reopen the db in this thread for sqlite, to avoid - // Library Call out of sequence problem due to thread safe. - close(); -#endif - open(); - std::ostringstream insertSql; insertSql << "insert into " << GUILDS_TBL_NAME << " (name) " @@ -1114,13 +972,6 @@ void DALStorage::removeGuild(Guild* guild) */ void DALStorage::addGuildMember(int guildId, const std::string &memberName) { -#if defined (SQLITE_SUPPORT) - // Reopen the db in this thread for sqlite, to avoid - // Library Call out of sequence problem due to thread safe. - close(); -#endif - open(); - std::ostringstream sql; try @@ -1143,13 +994,6 @@ void DALStorage::addGuildMember(int guildId, const std::string &memberName) */ void DALStorage::removeGuildMember(int guildId, const std::string &memberName) { -#if defined (SQLITE_SUPPORT) - // Reopen the db in this thread for sqlite, to avoid - // Library Call out of sequence problem due to thread safe. - close(); -#endif - open(); - std::ostringstream sql; try @@ -1166,18 +1010,13 @@ void DALStorage::removeGuildMember(int guildId, const std::string &memberName) } } +// Guild members should not be stored by name in the database. +#if 0 /** * get a list of guilds */ std::list DALStorage::getGuildList() { -#if defined (SQLITE_SUPPORT) - // Reopen the db in this thread for sqlite, to avoid - // Library Call out of sequence problem due to thread safe. - close(); -#endif - open(); - std::list guilds; std::stringstream sql; string_to toShort; @@ -1220,9 +1059,9 @@ std::list DALStorage::getGuildList() for (unsigned int j = 0; j < memberInfo.rows(); ++j) { - CharacterPtr character = getCharacter(memberInfo(j,0)); + Character *character = getCharacter(memberInfo(j,0)); character->addGuild((*itr)->getName()); - (*itr)->addMember(character.get()); + (*itr)->addMember(character); } } } @@ -1233,25 +1072,21 @@ std::list DALStorage::getGuildList() return guilds; } +#endif std::string DALStorage::getQuestVar(int id, std::string const &name) { - // connect to the database (if not connected yet). - open(); - - using namespace dal; - try { std::ostringstream query; query << "select value from " << QUESTS_TBL_NAME << " where owner_id = '" << id << "' and name = '" << name << "';"; - RecordSet const &info = mDb->execSql(query.str()); + dal::RecordSet const &info = mDb->execSql(query.str()); if (!info.isEmpty()) return info(0, 0); } - catch (DbSqlQueryExecFailure const &e) + catch (dal::DbSqlQueryExecFailure const &e) { LOG_ERROR("(DALStorage::getQuestVar) SQL query failure: " << e.what()); } @@ -1262,11 +1097,6 @@ std::string DALStorage::getQuestVar(int id, std::string const &name) void DALStorage::setQuestVar(int id, std::string const &name, std::string const &value) { - // connect to the database (if not connected yet). - open(); - - using namespace dal; - try { std::ostringstream query1; @@ -1283,7 +1113,7 @@ void DALStorage::setQuestVar(int id, std::string const &name, << id << "', '" << name << "', '" << value << "');"; mDb->execSql(query2.str()); } - catch (DbSqlQueryExecFailure const &e) + catch (dal::DbSqlQueryExecFailure const &e) { LOG_ERROR("(DALStorage::setQuestVar) SQL query failure: " << e.what()); } diff --git a/src/account-server/dalstorage.hpp b/src/account-server/dalstorage.hpp index c25b3fc2..00ba58cc 100644 --- a/src/account-server/dalstorage.hpp +++ b/src/account-server/dalstorage.hpp @@ -24,10 +24,14 @@ #ifndef _TMWSERV_DALSTORAGE_H_ #define _TMWSERV_DALSTORAGE_H_ -#include "account-server/characterdata.hpp" -#include "account-server/storage.hpp" +#include +#include + #include "dal/dataprovider.h" +class Account; +class Character; +class ChatChannel; class Guild; /** @@ -37,13 +41,21 @@ class Guild; * - this class cannot be instanciated nor duplicated in order to force * a user class to use the Storage singleton. */ -class DALStorage: public Storage +class DALStorage { - // friend so that Storage can call the constructor. - friend class Storage; + public: + /** + * Constructor. + */ + DALStorage(); + + + /** + * Destructor. + */ + ~DALStorage(); - public: /** * Connect to the database and initialize it if necessary. */ @@ -63,8 +75,7 @@ class DALStorage: public Storage * * @return the account associated to the user name. */ - AccountPtr - getAccount(const std::string& userName); + Account *getAccount(const std::string& userName); /** * Get an account by ID. @@ -73,18 +84,19 @@ class DALStorage: public Storage * * @return the account associated with the ID. */ - AccountPtr - getAccountByID(int accountID); + Account *getAccount(int accountID); /** * Gets a character by database ID. * * @param id the ID of the character. + * @param owner the account the character is in. * * @return the character associated to the ID. */ - CharacterPtr getCharacter(int id); - + Character *getCharacter(int id, Account *owner); + +#if 0 /** * Gets a character by character name. * @@ -92,7 +104,8 @@ class DALStorage: public Storage * * @return the character associated to the name */ - CharacterPtr getCharacter(const std::string &name); + Character *getCharacter(const std::string &name); +#endif /** * Add a new account. @@ -100,7 +113,7 @@ class DALStorage: public Storage * @param account the new account. */ void - addAccount(const AccountPtr& account); + addAccount(Account *account); /** @@ -108,21 +121,16 @@ class DALStorage: public Storage * * @param account the account to delete. */ - void delAccount(AccountPtr const &account); - - /** - * Flush and unload an account. - * - * @param account the account to unload. - */ - void unloadAccount(AccountPtr const &account); + void delAccount(Account *account); +#if 0 /** * Get the list of Emails in the accounts list. * @return the list of Email's Addresses. */ std::list getEmailList(); +#endif /** * Tells if the email address already exists. @@ -144,7 +152,7 @@ class DALStorage: public Storage * returns true if succefull, false otherwise. */ bool - updateCharacter(CharacterPtr ptr); + updateCharacter(Character *ptr); /** * Gives the list of opened public channels registered in database @@ -201,7 +209,7 @@ class DALStorage: public Storage * @exception tmwserv::dal::DbSqlQueryExecFailure. */ void flushAll(); - void flush(AccountPtr const &); + void flush(Account *); /** * Gets the value of a quest variable. @@ -215,18 +223,6 @@ class DALStorage: public Storage private: - /** - * Constructor. - */ - DALStorage(); - - - /** - * Destructor. - */ - ~DALStorage(); - - /** * Copy constructor. */ @@ -260,20 +256,22 @@ class DALStorage: public Storage * * @return the account found by the query */ - AccountPtr getAccountBySQL(std::string const &query); + Account *getAccountBySQL(std::string const &query); /** * Gets a character by character name. * - * @param query the query for the character + * @param query the query for the character. + * @param owner the account the character is in. * - * @return the character found by the query + * @return the character found by the query. */ - CharacterPtr getCharacterBySQL(const std::string &query); + Character *getCharacterBySQL(std::string const &query, Account *owner); - - std::auto_ptr mDb; /**< the data provider */ + dal::DataProvider *mDb; /**< the data provider */ }; +extern DALStorage *storage; + #endif // _TMWSERV_DALSTORAGE_H_ diff --git a/src/account-server/dalstoragesql.hpp b/src/account-server/dalstoragesql.hpp index c4d8ad7d..93ae7759 100644 --- a/src/account-server/dalstoragesql.hpp +++ b/src/account-server/dalstoragesql.hpp @@ -76,6 +76,7 @@ static char const *SQL_ACCOUNTS_TABLE = "level TINYINT UNSIGNED NOT NULL," "banned TINYINT UNSIGNED NOT NULL," "INDEX (id)" +#error "Incorrect definition. Please fix the types." #elif defined (SQLITE_SUPPORT) "id INTEGER PRIMARY KEY," "username TEXT NOT NULL UNIQUE," diff --git a/src/account-server/guild.cpp b/src/account-server/guild.cpp index cf864161..d2173a03 100644 --- a/src/account-server/guild.cpp +++ b/src/account-server/guild.cpp @@ -20,6 +20,7 @@ * $Id$ */ +#if 0 #include "guild.hpp" #include "account-server/characterdata.hpp" @@ -88,3 +89,4 @@ bool Guild::checkInGuild(const std::string &name) } return false; } +#endif diff --git a/src/account-server/guild.hpp b/src/account-server/guild.hpp index 2116e1ef..c361c374 100644 --- a/src/account-server/guild.hpp +++ b/src/account-server/guild.hpp @@ -26,7 +26,7 @@ #include #include -class CharacterData; +class Character; /** * A guild and its members. @@ -34,7 +34,7 @@ class CharacterData; class Guild { public: - typedef std::list guildMembers; + typedef std::list guildMembers; /** * Constructor. @@ -49,22 +49,22 @@ class Guild /** * Add a member to the guild. */ - void addMember(CharacterData* player); + void addMember(Character *player); /** * Remove a member from the guild. */ - void removeMember(CharacterData* player); + void removeMember(Character *player); /** * Check player is the leader of the guild. */ - bool checkLeader(CharacterData* player); + bool checkLeader(Character *player); /** * Set the ID of the guild. */ - void setId(short id) + void setId(int id) { mId = id; } /** @@ -86,13 +86,13 @@ class Guild /** * Returns the ID of the guild. */ - short getId() const + int getId() const { return mId; } /** * Returns the total number of members in the guild. */ - short totalMembers() const + int totalMembers() const { return mMembers.size(); } /** @@ -108,7 +108,7 @@ class Guild private: short mId; std::string mName; - std::list mMembers; + std::list mMembers; std::list mInvited; }; diff --git a/src/account-server/guildmanager.cpp b/src/account-server/guildmanager.cpp index 6105704c..5bdb341c 100644 --- a/src/account-server/guildmanager.cpp +++ b/src/account-server/guildmanager.cpp @@ -20,6 +20,7 @@ * $Id$ */ +#if 0 #include "guildmanager.hpp" #include "account-server/characterdata.hpp" @@ -122,3 +123,4 @@ bool GuildManager::doesExist(const std::string &name) { return findByName(name) != NULL; } +#endif diff --git a/src/account-server/guildmanager.hpp b/src/account-server/guildmanager.hpp index 60df3d79..f9f55312 100644 --- a/src/account-server/guildmanager.hpp +++ b/src/account-server/guildmanager.hpp @@ -22,8 +22,8 @@ #include +class Character; class Guild; -class CharacterData; /** * Guild manager takes care of creating, removing and modifying guilds. @@ -44,7 +44,7 @@ class GuildManager /** * Creates a guild. */ - short createGuild(const std::string &name, CharacterData *player); + short createGuild(const std::string &name, Character *player); /** * Removes a guild. @@ -54,12 +54,12 @@ class GuildManager /** * Adds a member to a guild. */ - void addGuildMember(short guildId, CharacterData *player); + void addGuildMember(short guildId, Character *player); /** * Removes a member from a guild. */ - void removeGuildMember(short guildId, CharacterData *player); + void removeGuildMember(short guildId, Character *player); /** * Returns the guild with the given id. O(n) diff --git a/src/account-server/main-account.cpp b/src/account-server/main-account.cpp index a53e693d..1aacf2fb 100644 --- a/src/account-server/main-account.cpp +++ b/src/account-server/main-account.cpp @@ -36,7 +36,7 @@ #include "account-server/accounthandler.hpp" #include "account-server/guildmanager.hpp" #include "account-server/serverhandler.hpp" -#include "account-server/storage.hpp" +#include "account-server/dalstorage.hpp" #include "chat-server/chatchannelmanager.hpp" #include "chat-server/chathandler.hpp" #include "net/connectionhandler.hpp" @@ -56,6 +56,9 @@ Configuration config; /**< XML config reader */ utils::StringFilter *stringFilter; /**< Slang's Filter */ +/** Database handler. */ +DALStorage *storage; + /** Account message handler */ AccountHandler *accountHandler; @@ -67,12 +70,12 @@ ServerHandler *serverHandler; /** Chat Channels Manager */ ChatChannelManager *chatChannelManager; - + /** Guild Manager */ GuildManager *guildManager; /** Callback used when SIGQUIT signal is received. */ -void closeGracefully(int dummy) +void closeGracefully(int) { running = false; } @@ -143,13 +146,20 @@ void initialize() LOG_INFO("Using Config File: " << configPath); LOG_INFO("Using Log File: " << logPath); + // Open database. + storage = new DALStorage; + storage->open(); + // --- Initialize the managers // Initialize the slang's and double quotes filter. stringFilter = new StringFilter(&config); // Initialize the Chat channels manager - chatChannelManager = new ChatChannelManager(); + chatChannelManager = new ChatChannelManager; + +#if 0 // Initialise the guild manager - guildManager = new GuildManager(); + guildManager = new GuildManager; +#endif // --- Initialize the global handlers // FIXME: Make the global handlers global vars or part of a bigger @@ -164,11 +174,6 @@ void initialize() exit(2); } - // Initialize configuration defaults - config.setValue("dbuser", ""); - config.setValue("dbpass", ""); - config.setValue("dbhost", ""); - // Initialize the processor utility functions utils::processor::init(); @@ -196,10 +201,12 @@ void deinitialize() // Destroy Managers delete chatChannelManager; +#if 0 delete guildManager; +#endif // Get rid of persistent data storage - Storage::destroy(); + delete storage; PHYSFS_deinit(); } @@ -229,7 +236,7 @@ void parseOptions(int argc, char *argv[]) { "help", no_argument, 0, 'h' }, { "verbosity", required_argument, 0, 'v' }, { "port", required_argument, 0, 'p' }, - { 0 } + { 0, 0, 0, 0 } }; while (optind < argc) { @@ -286,13 +293,6 @@ int main(int argc, char *argv[]) return 3; } - // Create storage wrapper - Storage& store = Storage::instance("tmw"); - store.setUser(config.getValue("dbuser", "")); - store.setPassword(config.getValue("dbpass", "")); - store.close(); - store.open(); - while (running) { accountHandler->process(50); chatHandler->process(50); diff --git a/src/account-server/serverhandler.cpp b/src/account-server/serverhandler.cpp index 6c428e4a..492bd16c 100644 --- a/src/account-server/serverhandler.cpp +++ b/src/account-server/serverhandler.cpp @@ -24,13 +24,11 @@ #include #include -#include "account-server/accountclient.hpp" -#include "account-server/characterdata.hpp" -#include "account-server/guildmanager.hpp" #include "account-server/serverhandler.hpp" -#include "account-server/storage.hpp" -#include "chat-server/chathandler.hpp" -#include "chat-server/chatchannelmanager.hpp" + +#include "account-server/accountclient.hpp" +#include "account-server/character.hpp" +#include "account-server/dalstorage.hpp" #include "net/messagein.hpp" #include "net/messageout.hpp" #include "net/netcomputer.hpp" @@ -78,7 +76,7 @@ bool ServerHandler::getGameServerFromMap(unsigned mapId, std::string &address, return true; } -void ServerHandler::registerGameClient(std::string const &token, CharacterPtr ptr) +void ServerHandler::registerGameClient(std::string const &token, Character *ptr) { unsigned mapId = ptr->getMapId(); @@ -130,22 +128,22 @@ void ServerHandler::processMessage(NetComputer *comp, MessageIn &msg) case GAMSG_PLAYER_DATA: { LOG_DEBUG("GAMSG_PLAYER_DATA"); - Storage &store = Storage::instance("tmw"); int id = msg.readLong(); - CharacterPtr ptr = store.getCharacter(id); - if (ptr.get()) + if (Character *ptr = storage->getCharacter(id, NULL)) { deserializeCharacterData(*ptr, msg); - if (!store.updateCharacter(ptr)) - LOG_ERROR("Failed to update character " << - ptr->getDatabaseID() << '.'); + if (!storage->updateCharacter(ptr)) + { + LOG_ERROR("Failed to update character " + << id << '.'); + } + delete ptr; } else { - LOG_ERROR("Received data for non-existing character " << - ptr->getDatabaseID() << '.'); + LOG_ERROR("Received data for non-existing character " + << id << '.'); } - } break; case GAMSG_REDIRECT: @@ -153,48 +151,59 @@ void ServerHandler::processMessage(NetComputer *comp, MessageIn &msg) LOG_DEBUG("GAMSG_REDIRECT"); int id = msg.readLong(); std::string magic_token(utils::getMagicToken()); - Storage &store = Storage::instance("tmw"); - CharacterPtr ptr = store.getCharacter(id); - std::string address; - short port; - if (serverHandler->getGameServerFromMap(ptr->getMapId(), address, - port)) + if (Character *ptr = storage->getCharacter(id, NULL)) { - registerGameClient(magic_token, ptr); - result.writeShort(AGMSG_REDIRECT_RESPONSE); - result.writeLong(ptr->getDatabaseID()); - result.writeString(magic_token, MAGIC_TOKEN_LENGTH); - result.writeString(address); - result.writeShort(port); + std::string address; + short port; + if (serverHandler->getGameServerFromMap + (ptr->getMapId(), address, port)) + { + registerGameClient(magic_token, ptr); + result.writeShort(AGMSG_REDIRECT_RESPONSE); + result.writeLong(ptr->getDatabaseID()); + result.writeString(magic_token, MAGIC_TOKEN_LENGTH); + result.writeString(address); + result.writeShort(port); + } + else + { + LOG_ERROR("Server Change: No game server for map " << + ptr->getMapId() << "."); + } + delete ptr; } else { - LOG_ERROR("Server Change: No game server for map " << - ptr->getMapId() << "."); + LOG_ERROR("Received data for non-existing character " + << id << '.'); } } break; case GAMSG_PLAYER_RECONNECT: { LOG_DEBUG("GAMSG_PLAYER_RECONNECT"); - int characterID = msg.readLong(); + int id = msg.readLong(); std::string magic_token = msg.readString(MAGIC_TOKEN_LENGTH); - Storage &store = Storage::instance("tmw"); - CharacterPtr ptr = store.getCharacter(characterID); - - int accountID = ptr->getAccountID(); - accountHandler-> + if (Character *ptr = storage->getCharacter(id, NULL)) + { + int accountID = ptr->getAccountID(); + accountHandler-> mTokenCollector.addPendingConnect(magic_token, accountID); - + delete ptr; + } + else + { + LOG_ERROR("Received data for non-existing character " + << id << '.'); + } } break; case GAMSG_GET_QUEST: { int id = msg.readLong(); std::string name = msg.readString(); - Storage &store = Storage::instance("tmw"); - std::string value = store.getQuestVar(id, name); + std::string value = storage->getQuestVar(id, name); result.writeShort(AGMSG_GET_QUEST_RESPONSE); result.writeLong(id); result.writeString(name); @@ -206,8 +215,7 @@ void ServerHandler::processMessage(NetComputer *comp, MessageIn &msg) int id = msg.readLong(); std::string name = msg.readString(); std::string value = msg.readString(); - Storage &store = Storage::instance("tmw"); - store.setQuestVar(id, name, value); + storage->setQuestVar(id, name, value); } break; #if 0 @@ -431,7 +439,6 @@ void ServerHandler::enterChannel(const std::string &name, chatHandler->sendGuildEnterChannel(result, player->getName()); } -#endif void ServerHandler::sendInvite(const std::string &invitedName, const std::string &inviterName, @@ -440,10 +447,4 @@ void ServerHandler::sendInvite(const std::string &invitedName, // TODO: Separate account and chat server chatHandler->sendGuildInvite(invitedName, inviterName, guildName); } - -CharacterPtr ServerHandler::getCharacter(const std::string &name) -{ - Storage &store = Storage::instance("tmw"); - CharacterPtr character = store.getCharacter(name); - return character; -} +#endif diff --git a/src/account-server/serverhandler.hpp b/src/account-server/serverhandler.hpp index 5c57f03b..ec537dbd 100644 --- a/src/account-server/serverhandler.hpp +++ b/src/account-server/serverhandler.hpp @@ -26,9 +26,8 @@ #include #include "account-server/accounthandler.hpp" -#include "account-server/characterdata.hpp" +#include "account-server/character.hpp" #include "net/connectionhandler.hpp" -#include "utils/countedptr.h" class AccountClient; @@ -53,17 +52,20 @@ class ServerHandler: public ConnectionHandler /** * Sends a magic token and character data to the relevant game server. */ - void registerGameClient(std::string const &, CharacterPtr); - + void registerGameClient(std::string const &, Character *); + +// There is no rationale for having a character name, but not its ID. +#if 0 /** * Get character (temp used by chat server). */ CharacterPtr getCharacter(const std::string &name); - +#endif + /** * Make client join the specified guild channel */ - void enterChannel(const std::string &guildName, CharacterData *player); + void enterChannel(const std::string &guildName, Character *player); protected: /** diff --git a/src/account-server/storage.cpp b/src/account-server/storage.cpp deleted file mode 100644 index efa6ca91..00000000 --- a/src/account-server/storage.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* - * The Mana World Server - * Copyright 2004 The Mana World Development Team - * - * This file is part of The Mana World. - * - * The Mana World is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or any later version. - * - * The Mana World is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with The Mana World; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id$ - */ - -#include "account-server/dalstorage.hpp" -#include "account-server/storage.hpp" - -// initialize the static attributes. -Storage* Storage::mInstance = 0; -std::string Storage::mName(""); -std::string Storage::mUser(""); -std::string Storage::mPassword(""); - - -/** - * Create an instance of Storage. - */ -Storage& -Storage::instance(const std::string& name) -{ - if (mInstance == 0) { - mInstance = new DALStorage(); - - // set the name of the storage. - mName = name; - } - - return (*mInstance); -} - -/** - * Delete the instance. - */ -void -Storage::destroy() -{ - if (mInstance != 0) { - delete mInstance; - mInstance = 0; - } - - // reset the attributes. - mName = ""; - mUser = ""; - mPassword = ""; -} - diff --git a/src/account-server/storage.hpp b/src/account-server/storage.hpp deleted file mode 100644 index d436fa1f..00000000 --- a/src/account-server/storage.hpp +++ /dev/null @@ -1,373 +0,0 @@ -/* - * The Mana World Server - * Copyright 2004 The Mana World Development Team - * - * This file is part of The Mana World. - * - * The Mana World is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or any later version. - * - * The Mana World is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with The Mana World; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id$ - */ - - -#ifndef _TMWSERV_STORAGE_H_ -#define _TMWSERV_STORAGE_H_ - -#include -#include - -#include "account-server/account.hpp" -#include "account-server/characterdata.hpp" -#include "account-server/guild.hpp" -#include "chat-server/chatchannel.hpp" - -/** - * Data type for the list of accounts. - */ -typedef std::map Accounts; - - -/** - * A storage to load and persist dynamic data. - * - * Notes: - * - this class implements the singleton design pattern. - * - destroy() must be called at least once before the application - * exits or else there will be a memory leak. - */ -class Storage -{ - public: - /** - * Create a named instance of Storage. - * - * @param name the name of the storage. - * - * @return the unique instance of Storage. - * - * @exception std::bad_alloc if the instance cannot be created. - * - * Notes: - * - it is up to the underlying implementation of Storage to - * decide about what to do with the name, it could serve as the - * name of the database or the name of the file into which the - * storage will be dumped to. - * - the name of the storage is saved only when it's the first - * invocation of instance() or only when instance() is invoked - * after destroy(). - */ - static Storage& - instance(const std::string& name); - - - /** - * Delete the storage. - */ - static void - destroy(); - - - /** - * Open the storage for read/write access. - * - * Depending on the underlying implementation of Storage, opening - * a storage would mean either opening a file or connecting to a - * database. - */ - virtual void - open() = 0; - - - /** - * Close the storage. - * - * Depending on the underlying implementation of Storage, closing - * a storage would mean either closing a file or disconnecting from - * a database. - */ - virtual void - close(void) = 0; - - - /** - * Check if the storage is open. - * - * @return true if the storage is open. - */ - bool isOpen() const - { return mIsOpen; } - - - /** - * Get the storage name. - * - * @return the storage name. - */ - std::string const &getName() const - { return mName; } - - - /** - * Set a user name for the storage. - * - * Depending on the underlying implementation of Storage, setting - * the user name may have no effect (e.g. DALStorage running on - * SQLite). - * - * @param userName the user name. - */ - void setUser(const std::string& userName) - { mUser = userName; } - - - /** - * Get the user name. - * - * @return the user name (it may be an empty string if not set - * previously). - */ - std::string const &getUser() const - { return mUser; } - - - /** - * Set a user password for the storage. - * - * Depending on the underlying implementation of Storage, setting - * the user password may have no effect (e.g. DALStorage running on - * SQLite). - * - * @param password the user password. - */ - void setPassword(const std::string& password) - { mPassword = password; } - - - /** - * Get the user password. - * - * @return the user password (it may be an empty string if not set - * previously). - */ - std::string const &getPassword() const - { return mPassword; } - - - /** - * Get an account by user name. - * - * @param userName the owner of the account. - * - * @return the account associated to the user name. - */ - virtual AccountPtr - getAccount(const std::string& userName) = 0; - - /** - * Get an account by ID. - * - * @param accountID the ID of the account. - * - * @return the account associated with the ID. - */ - virtual AccountPtr - getAccountByID(int accountID) = 0; - - /** - * Gets a character by database ID. - * - * @param id the ID of the character. - * - * @return the character associated to the ID. - */ - virtual CharacterPtr getCharacter(int id) = 0; - - /** - * Gets a character by name. - * - * @param name the name of the character. - * - * @return the character associated to the name. - */ - virtual CharacterPtr getCharacter(const std::string &name) = 0; - - /** - * Add a new account. - * - * @param account the new account. - */ - virtual void - addAccount(const AccountPtr& account) = 0; - - /** - * Delete an account. - * - * @param account the account to delete. - */ - virtual void - delAccount(AccountPtr const &account) = 0; - - /** - * Flush and unload an account. - * - * @param account the account to unload. - */ - virtual void - unloadAccount(AccountPtr const &account) = 0; - - /** - * Get the list of Emails in the accounts list. - * @return the list of Email's Addresses. - * - * @deprecated The only purpose of using this list inside the server is - * for checking for existing email addresses, which is - * covered by Storage::getSameEmailNumber(). - * It could later be used for mailing list announcement. - */ - virtual - std::list getEmailList() = 0; - - /** - * Tells if the email address already exists. - * @return true if the email address exists. - */ - virtual bool doesEmailAddressExist(std::string const &email) = 0; - - /** - * Tells if the character's name already exists - * @return true if character's name exists. - */ - virtual bool doesCharacterNameExist(std::string const &name) = 0; - - /** - * Updates the data for a single character, does not update the - * owning account or the characters name. - * Primary usage should be storing characterdata received from a - * game server. - * returns true if succefull, false otherwise. - */ - virtual bool - updateCharacter(CharacterPtr ptr) = 0; - - /** - * Gives the list of opened public channels registered in database - * @return a map of the public channels - */ - virtual std::map - getChannelList() = 0; - - /** - * apply channel differences from the list in memory - * to the one in db. - */ - virtual void - updateChannels(std::map& channelList) = 0; - - /** - * Add a new guild - * - */ - virtual void - addGuild(Guild* guild) = 0; - - /** - * Delete a guild - * - */ - virtual void - removeGuild(Guild* guild) = 0; - - /** - * Add member to guild - * - */ - virtual void - addGuildMember(int guild_id, const std::string &member_name) = 0; - - /** - * Remove member from guild - */ - virtual void - removeGuildMember(int guildId, const std::string &memberName) = 0; - - /** - * Get guild list - *@return a list of guilds - * - */ - virtual std::list - getGuildList() = 0; - - /** - * Saves the changes to all the accounts permanently. - */ - virtual void flushAll() = 0; - - /** - * Saves the changes to one account permanently. - */ - virtual void flush(AccountPtr const &account) = 0; - - /** - * Gets the value of a quest variable. - */ - virtual std::string getQuestVar(int id, std::string const &) = 0; - - /** - * Sets the value of a quest variable. - */ - virtual void setQuestVar(int id, std::string const &, - std::string const &) = 0; - - - protected: - /** - * Default constructor. - */ - Storage() {} - - - /** - * Destructor. - */ - virtual ~Storage() {} - - - /** - * Copy constructor. - */ - Storage(const Storage& rhs); - - - /** - * Assignment operator. - */ - Storage& - operator=(const Storage& rhs); - - - protected: - Accounts mAccounts; /**< list of accounts in memory */ - Characters mCharacters; /**< the loaded characters */ - bool mIsOpen; /**< flag is true if the storage is open */ - - - private: - static Storage* mInstance; /**< the unique instance of Storage */ - static std::string mName; /**< the name of the storage */ - static std::string mUser; /**< the user name */ - static std::string mPassword; /**< the user password */ -}; - -#endif // _TMWSERV_STORAGE_H_ diff --git a/src/chat-server/chatchannelmanager.cpp b/src/chat-server/chatchannelmanager.cpp index dd161976..ca2be7f5 100644 --- a/src/chat-server/chatchannelmanager.cpp +++ b/src/chat-server/chatchannelmanager.cpp @@ -23,23 +23,22 @@ #include -#include "account-server/storage.hpp" #include "chat-server/chatchannelmanager.hpp" + +#include "defines.h" +#include "account-server/dalstorage.hpp" #include "chat-server/chatclient.hpp" ChatChannelManager::ChatChannelManager() { // Load stored public chat channels from db - Storage &store = Storage::instance("tmw"); - mChatChannels = store.getChannelList(); + mChatChannels = storage->getChannelList(); } ChatChannelManager::~ChatChannelManager() { - Storage &store = Storage::instance("tmw"); - store.updateChannels(mChatChannels); - mChatChannels.clear(); + storage->updateChannels(mChatChannels); } int diff --git a/src/chat-server/chathandler.cpp b/src/chat-server/chathandler.cpp index 88b8864b..efa6129a 100644 --- a/src/chat-server/chathandler.cpp +++ b/src/chat-server/chathandler.cpp @@ -24,7 +24,6 @@ #include #include "defines.h" -#include "account-server/characterdata.hpp" #include "account-server/guild.hpp" #include "account-server/guildmanager.hpp" #include "account-server/serverhandler.hpp" @@ -312,11 +311,13 @@ ChatHandler::handleRegisterChannelMessage(ChatClient &client, MessageIn &msg) { reply.writeByte(ERRMSG_INVALID_ARGUMENT); } +#if 0 else if (guildManager->doesExist(channelName)) { // Channel already exists reply.writeByte(ERRMSG_INVALID_ARGUMENT); } +#endif else { // We attempt to create a new channel @@ -375,12 +376,6 @@ ChatHandler::handleUnregisterChannelMessage(ChatClient &client, MessageIn &msg) else if (channelId < (signed) MAX_PUBLIC_CHANNELS_RANGE) { // Public channel - - // Get character based on name - CharacterPtr character = - serverHandler->getCharacter(client.characterName); - const std::string &channelName = channel->getName(); - if (client.accountLevel == AL_ADMIN || client.accountLevel == AL_GM) { warnUsersAboutPlayerEventInChat( @@ -390,6 +385,9 @@ ChatHandler::handleUnregisterChannelMessage(ChatClient &client, MessageIn &msg) else reply.writeByte(ERRMSG_FAILURE); } +/* The chat server should not access directly to the objects of the account + server, so that they can be splitted later, if needed. */ +#if 0 else if (guildManager->doesExist(channelName)) { Guild *guild = guildManager->findByName(channelName); @@ -408,6 +406,7 @@ ChatHandler::handleUnregisterChannelMessage(ChatClient &client, MessageIn &msg) reply.writeByte(ERRMSG_INSUFFICIENT_RIGHTS); } } +#endif else { reply.writeByte(ERRMSG_INSUFFICIENT_RIGHTS); @@ -455,11 +454,13 @@ void ChatHandler::handleEnterChannelMessage(ChatClient &client, MessageIn &msg) short channelId = chatChannelManager->getChannelId(channelName); ChatChannel *channel = chatChannelManager->getChannel(channelId); +#if 0 // TODO: b_lindeijer: Currently, the client has to join its guild channels // explicitly by sending 'enter channel' messages. This should be // changed to implicitly joining relevant guild channels right after // login. Guild *guild = guildManager->findByName(channelName); +#endif if (!channelId || !channel) { @@ -471,20 +472,24 @@ void ChatHandler::handleEnterChannelMessage(ChatClient &client, MessageIn &msg) // Incorrect password (should probably have its own return value) reply.writeByte(ERRMSG_INVALID_ARGUMENT); } +#if 0 else if (guild && !guild->checkInGuild(client.characterName)) { // Player tried to join a guild channel of a guild he's not a member of reply.writeByte(ERRMSG_INVALID_ARGUMENT); } +#endif else { if (channel->addUser(&client)) { +#if 0 // In the case of a guild, send user joined message. if (guild) { sendUserJoined(channel, client.characterName); } +#endif reply.writeByte(ERRMSG_OK); // The user entered the channel, now give him the channel @@ -542,6 +547,7 @@ ChatHandler::handleQuitChannelMessage(ChatClient &client, MessageIn &msg) client.characterName, CHAT_EVENT_LEAVING_PLAYER); +#if 0 // TODO: b_lindeijer: Clients aren't supposed to quit guild // channels explicitly, this should rather happen // implicitly. See similar note at handling 'enter channel' @@ -553,6 +559,7 @@ ChatHandler::handleQuitChannelMessage(ChatClient &client, MessageIn &msg) // Send a user left message sendUserLeft(channel, client.characterName); } +#endif } client.send(reply); diff --git a/src/utils/countedptr.h b/src/utils/countedptr.h deleted file mode 100644 index 3edc9c3d..00000000 --- a/src/utils/countedptr.h +++ /dev/null @@ -1,167 +0,0 @@ -/* - * The Mana World Server - * Copyright 2004 The Mana World Development Team - * - * This file is part of The Mana World. - * - * The Mana World is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or any later version. - * - * The Mana World is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with The Mana World; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * $Id$ - */ - - -#ifndef _TMWSERV_COUNTED_PTR_H_ -#define _TMWSERV_COUNTED_PTR_H_ - -namespace utils -{ - - -/** - * Class for counted reference semantics. It deletes the object to which it - * refers when the last CountedPtr that refers to it is destroyed. - * - * @copyright Nicolai M. Josuttis - * (The C++ standard library: a tutorial and reference). - * - * Notes from kindjal: - * - should we use the Boost's shared_ptr instead? - * - reference-counted smart pointers are very useful if we want automatic - * memory management with STL containers (e.g. vector of pointers). - */ -template -class CountedPtr -{ - public: - /** - * Constructor. - * Initialize pointer with existing pointer. - * - * It is required that the pointer p is a return value of new. - */ - explicit - CountedPtr(T* p = 0) - : ptr(p), - count(new long(1)) - { - // NOOP - } - - - /** - * Destructor. - * Delete value if this was the last owner. - */ - ~CountedPtr(void) - throw() - { - dispose(); - } - - - /** - * Copy pointer (one more owner). - */ - CountedPtr(const CountedPtr& p) - throw() - : ptr(p.ptr), - count(p.count) - { - ++*count; - } - - /** - * Copy pointer with static cast (one more owner). - */ - template - explicit CountedPtr(const CountedPtr& p) - throw() - : ptr(static_cast(p.ptr)), - count(p.count) - { - ++*count; - } - - /** - * Assignment (unshare old and share new value). - */ - CountedPtr& - operator=(const CountedPtr& p) - throw() - { - if (this != &p) { - dispose(); - ptr = p.ptr; - count = p.count; - ++*count; - } - - return *this; - } - - /** - * Access the value to which the pointer refers. - */ - T& - operator*(void) const - throw() - { - return *ptr; - } - - - /** - * Access the pointer. - */ - T* - operator->(void) const - throw() - { - return ptr; - } - - - /** - * Get the pointer (mimic std::auto_ptr::get()). - */ - T* - get(void) const - throw() - { - return ptr; - } - - - private: - /** - * Manage the counter and free memory. - */ - void - dispose(void) - { - if (--*count == 0) { - delete count; - delete ptr; - } - } - - T* ptr; /**< pointer to the value */ - long* count; /**< shared number of owners */ - - template friend class CountedPtr; -}; - -} // namespace utils - -#endif // _TMWSERV_COUNTED_PTR_H_ -- cgit v1.2.3-60-g2f50