diff options
-rw-r--r-- | ChangeLog | 14 | ||||
-rw-r--r-- | src/Makefile.am | 4 | ||||
-rw-r--r-- | src/chatchannel.cpp | 101 | ||||
-rw-r--r-- | src/chatchannel.h | 95 | ||||
-rw-r--r-- | src/chatchannelmanager.cpp | 165 | ||||
-rw-r--r-- | src/chatchannelmanager.h | 98 | ||||
-rw-r--r-- | src/chathandler.cpp | 7 | ||||
-rw-r--r-- | src/chathandler.h | 12 | ||||
-rw-r--r-- | src/dalstorage.cpp | 87 | ||||
-rw-r--r-- | src/dalstorage.h | 14 | ||||
-rw-r--r-- | src/dalstoragesql.h | 20 | ||||
-rw-r--r-- | src/state.cpp | 3 | ||||
-rw-r--r-- | src/storage.h | 18 |
13 files changed, 629 insertions, 9 deletions
@@ -1,12 +1,20 @@ +2006-01-16 Yohann Ferreira <bertram@cegetel.net> + + * src/state.cpp, src/chathandler.h, src/chathandler.cpp, + src/Makefile.am, src/chatchannel.h, src/chatchannel.cpp, + src/chatchannelmanager.h, src/chatchannelmanager.cpp, src/dalstoragesql.h, + src/dalstorage.cpp, src/storage.h, src/dalstorage.h: Chat channeling commit + part 1. Useful to get feedback before committing what's next. + 2006-01-14 Eugenio Favalli <elvenprogrammer@gmail.com> - * src/accounthandler.cpp, src/client.cpp, src/dalstorage.cpp, - src/messageout.cpp, src/defines.h: Sever returns infos about position of + * src/accounthandler.cpp, src/client.cpp, src/dalstorage.cpp, + src/messageout.cpp, src/defines.h: Server returns infos about position of the selected character (map name, coordinates). 2006-01-13 Eugenio Favalli <elvenprogrammer@gmail.com> - * src/accounthandler.cpp, src/client.cpp, src/dalstorage.cpp, + * src/accounthandler.cpp, src/client.cpp, src/dalstorage.cpp, src/defines.h, src/main.cpp, src/mapmanager.cpp, src/mapmanager.h, src/netcomputer.cpp, src/object.cpp, src/object.h, tmwserv.dev: Made minimum client version and default map id configurable, set/getMapId are diff --git a/src/Makefile.am b/src/Makefile.am index 5a85c87b..defa5b4e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -18,6 +18,10 @@ tmwserv_SOURCES = main.cpp \ accounthandler.cpp \ chathandler.h \ chathandler.cpp \ + chatchannel.h \ + chatchannel.cpp \ + chatchannelmanager.h \ + chatchannelmanager.cpp \ connectionhandler.h \ connectionhandler.cpp \ gamehandler.h \ diff --git a/src/chatchannel.cpp b/src/chatchannel.cpp new file mode 100644 index 00000000..8e02b868 --- /dev/null +++ b/src/chatchannel.cpp @@ -0,0 +1,101 @@ +/* + * 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 "chatchannel.h" + +ChatChannel::ChatChannel(): + mChannelId(0), + mChannelName("") +{ + mRegisteredUsers.clear(); +} + +ChatChannel::ChatChannel(short channelId, std::string channelName): + mChannelId(channelId), + mChannelName(channelName) +{ + mRegisteredUsers.clear(); +} + +ChatChannel::~ChatChannel() +{ + mRegisteredUsers.clear(); +} + + +const std::string +ChatChannel::getName() +{ + return mChannelName; +} + + +void +ChatChannel::setName(std::string channelName) +{ + mChannelName = channelName; +} + + +const short +ChatChannel::getChannelId() +{ + return mChannelId; +} + + +const std::list<std::string> +ChatChannel::getUserList() +{ + return mRegisteredUsers; +} + + +bool +ChatChannel::addUserInChannel(std::string playerName) +{ + // Check if the user already exists in the channel + for (std::list<std::string>::iterator i = mRegisteredUsers.begin(); i != mRegisteredUsers.end();) + { + if ( *i == playerName ) return false; + ++i; + } + mRegisteredUsers.push_back(playerName); + return true; +} + + +bool +ChatChannel::removeUserFromChannel(std::string playerName) +{ + for (std::list<std::string>::iterator i = mRegisteredUsers.begin(); i != mRegisteredUsers.end();) + { + if ( *i == playerName ) + { + mRegisteredUsers.erase(i); + return true; + } + ++i; + } + return false; +} diff --git a/src/chatchannel.h b/src/chatchannel.h new file mode 100644 index 00000000..0b35ee9f --- /dev/null +++ b/src/chatchannel.h @@ -0,0 +1,95 @@ +/* + * 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_CHATCHANNEL_H_ +#define _TMWSERV_CHATCHANNEL_H_ + +#include <list> +#include <string> + +class ChatChannel { + + public: + + /** + * Constructors + */ + ChatChannel(); + + ChatChannel(short channelId, std::string channelName); + + /** + * Destructor + */ + ~ChatChannel(); + + /** + * Get the name of the channel + */ + const std::string getName(); + + /** + * Set the name of the channel + */ + void setName(std::string channelName); + + /** + * Get the id of the channel + */ + const short getChannelId(); + + /** + * Get the list of the users registered in the channel + */ + const std::list<std::string> getUserList(); + + /** + * Add a user in the channel + */ + bool addUserInChannel(std::string playerName); + + /** + * Remove a user from the channel. + */ + bool removeUserFromChannel(std::string playerName); + + private: + + /** + * The channel id which must be unique. + */ + short mChannelId; + + /** + * The Channel's name + */ + std::string mChannelName; + + /** + * The registered user list + */ + std::list<std::string> mRegisteredUsers; + +}; + +#endif diff --git a/src/chatchannelmanager.cpp b/src/chatchannelmanager.cpp new file mode 100644 index 00000000..f5c9707f --- /dev/null +++ b/src/chatchannelmanager.cpp @@ -0,0 +1,165 @@ +/* + * 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 <map> + +#include "chatchannelmanager.h" +#include "storage.h" + +ChatChannelManager::ChatChannelManager() +{ + //Load stored public chat channels from db + tmwserv::Storage &store = tmwserv::Storage::instance("tmw"); + std::map<short, std::string> channelList = store.getChannelList(); + + for (std::map<short, std::string>::iterator i = channelList.begin(); i != channelList.end();) + { + mChatChannels.push_back(ChatChannel(i->first,i->second)); + ++i; + } +} + + +ChatChannelManager::~ChatChannelManager() +{ + tmwserv::Storage &store = tmwserv::Storage::instance("tmw"); + std::map<short, std::string> channelList; + for (std::list<ChatChannel>::iterator i = mChatChannels.begin(); i != mChatChannels.end();) + { + channelList.insert(std::make_pair(i->getChannelId(), i->getName())); + ++i; + } + store.updateChannels(channelList); + mChatChannels.clear(); +} + +short +ChatChannelManager::registerPublicChannel(std::string channelName) +{ + short channelId = 1; + for (std::list<ChatChannel>::iterator i = mChatChannels.begin(); i != mChatChannels.end();) + { + if ( i->getName() == channelName ) return 0; + // We seek the highest channelId in the public range + if ( (channelId <= i->getChannelId()) && (i->getChannelId() < 1000) ) + channelId = i->getChannelId() + 1; + ++i; + } + // Too much channels registered + if ( channelId >= 1000 ) return 0; + + // Register Channel + mChatChannels.push_back(ChatChannel(channelId,channelName)); + return channelId; +} + + +short +ChatChannelManager::registerPrivateChannel(std::string channelName) +{ + short channelId = 1000; + for (std::list<ChatChannel>::iterator i = mChatChannels.begin(); i != mChatChannels.end();) + { + if ( i->getName() == channelName ) return 0; + // We seek the highest channelId in the private range + if ( (channelId <= i->getChannelId()) && (i->getChannelId() >= 1000) ) + channelId = i->getChannelId() + 1; + ++i; + } + // Too much channels registered + if ( channelId >= 10000 ) return 0; + + // Register Channel + mChatChannels.push_back(ChatChannel(channelId,channelName)); + return channelId; +} + +bool +ChatChannelManager::removeChannel(short channelId) +{ + for (std::list<ChatChannel>::iterator i = mChatChannels.begin(); i != mChatChannels.end();) + { + if ( i->getChannelId() == channelId ) + { + mChatChannels.erase(i); + i++; + return true; + } + ++i; + } + return false; +} + + +short +ChatChannelManager::getChannelId(std::string channelName) +{ + for (std::list<ChatChannel>::iterator i = mChatChannels.begin(); i != mChatChannels.end();) + { + if ( i->getName() == channelName ) return i->getChannelId(); + ++i; + } + return 0; +} + + +std::string +ChatChannelManager::getChannelName(short channelId) +{ + for (std::list<ChatChannel>::iterator i = mChatChannels.begin(); i != mChatChannels.end();) + { + if ( i->getChannelId() == channelId ) return i->getName(); + ++i; + } + return ""; +} + + +bool +ChatChannelManager::addUserInChannel(std::string playerName, short channelId) +{ + for (std::list<ChatChannel>::iterator i = mChatChannels.begin(); i != mChatChannels.end();) + { + if ( i->getChannelId() == channelId ) + { + return i->addUserInChannel(playerName); + } + ++i; + } + return false; +} + + +bool +ChatChannelManager::removeUserFromChannel(std::string playerName, short channelId) +{ + for (std::list<ChatChannel>::iterator i = mChatChannels.begin(); i != mChatChannels.end();) + { + if ( i->getChannelId() == channelId ) + { + return i->removeUserFromChannel(playerName); + } + ++i; + } + return false; +} diff --git a/src/chatchannelmanager.h b/src/chatchannelmanager.h new file mode 100644 index 00000000..5c417698 --- /dev/null +++ b/src/chatchannelmanager.h @@ -0,0 +1,98 @@ +/* + * 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_CHATCHANNELHANDLER_H_ +#define _TMWSERV_CHATCHANNELHANDLER_H_ + +#include "chatchannel.h" + +class ChatChannelManager { + +public: + + /** + * Constructor + */ + ChatChannelManager(); + + /** + * Destructor + */ + ~ChatChannelManager(); + + /** + * Add a public channel. + * + * @return the number of the channel registered. + * 0 if the registering was unsuccessful. + */ + short registerPublicChannel(std::string channelName); + + /** + * Add a private channel. + * + * @return the number of the channel registered. + * 0 if the registering was unsuccessful. + */ + short registerPrivateChannel(std::string channelName); + + /** + * Remove a channel. + */ + bool removeChannel(short channelId); + + /** + * get the id of a channel from its name. + * + * @return the id of the channel + * 0 if it was unsuccessful. + */ + short getChannelId(std::string channelName); + + /** + * get the name of a channel from its id. + * + * @return the name of the channel + */ + std::string getChannelName(short channelId); + + /** + * Add a user in the channel + */ + bool addUserInChannel(std::string playerName, short channelId); + + /** + * Remove a user from a channel. + */ + bool removeUserFromChannel(std::string playerName, short channelId); + +private: + + /** + * The list keeping all the chat channels. + */ + std::list<ChatChannel> mChatChannels; + +}; + +#endif diff --git a/src/chathandler.cpp b/src/chathandler.cpp index ad800a31..e2f17c89 100644 --- a/src/chathandler.cpp +++ b/src/chathandler.cpp @@ -28,6 +28,12 @@ #include "utils/logger.h" #include "utils/slangsfilter.h" +ChatHandler::ChatHandler() +{ + // TODO: Implement loading public chat channels from db. + // That require adding a table for that. +} + void ChatHandler::receiveMessage(NetComputer &computer, MessageIn &message) { // If not logged in... @@ -216,4 +222,5 @@ void ChatHandler::sayInChannel(NetComputer &computer, short channel, std::string say += ": "; say += text; result.writeString(say); + } diff --git a/src/chathandler.h b/src/chathandler.h index 4c0ebdd6..d7136e77 100644 --- a/src/chathandler.h +++ b/src/chathandler.h @@ -27,6 +27,7 @@ #include "messagehandler.h" #include "netcomputer.h" #include "messagein.h" +#include "chatchannelmanager.h" /** * Manages all chat related @@ -34,6 +35,12 @@ class ChatHandler : public MessageHandler { public: + + /** + * Constructor + */ + ChatHandler(); + /** * Receives chat related messages. */ @@ -72,6 +79,11 @@ class ChatHandler : public MessageHandler */ void sayInChannel(NetComputer &computer, short channel, std::string text); + /** + * The Chat Channels instance + */ + ChatChannelManager mChatChannelManager; + }; #endif diff --git a/src/dalstorage.cpp b/src/dalstorage.cpp index 6a8159cf..d8351b0c 100644 --- a/src/dalstorage.cpp +++ b/src/dalstorage.cpp @@ -133,6 +133,7 @@ DALStorage::open(void) createTable(ITEMS_TBL_NAME, SQL_ITEMS_TABLE); createTable(WORLD_ITEMS_TBL_NAME, SQL_WORLD_ITEMS_TABLE); createTable(INVENTORIES_TBL_NAME, SQL_INVENTORIES_TABLE); + createTable(CHANNELS_TBL_NAME, SQL_CHANNELS_TABLE); } catch (const DbConnectionFailure& e) { LOG_ERROR("unable to connect to the database: " << e.what(), 0) @@ -276,7 +277,7 @@ DALStorage::getAccount(const std::string& userName) // Default map is to be 1, as not found return value will be 0. being->setMapId((int)config.getValue("defaultMap", 1)); } - + being->setXY(toUshort(strCharInfo[k][8]), toUshort(strCharInfo[k][9])); @@ -499,7 +500,7 @@ DALStorage::getMapNameFromId(const unsigned int mapId) sql << " where id = "; sql << mapId; sql << ";"; - + const dal::RecordSet& mapInfo = mDb->execSql(sql.str()); // If the map return is empty then we have no choice but to return false. @@ -518,6 +519,88 @@ DALStorage::getMapNameFromId(const unsigned int mapId) return "None"; } +const std::map<short, std::string> +DALStorage::getChannelList() +{ + // If not opened already + open(); + + // specialize the string_to functor to convert + // a string to a short. + string_to<short> toShort; + + // The formatted datas + std::map<short, std::string> channels; + + try { + std::stringstream sql; + sql << "select id, name from "; + sql << CHANNELS_TBL_NAME; + sql << ";"; + + const dal::RecordSet& channelInfo = mDb->execSql(sql.str()); + + // If the map return is empty then we have no choice but to return false. + if (channelInfo.isEmpty()) { + return channels; + } + + for ( unsigned int i = 0; i < channelInfo.rows(); ++i) + { + channels.insert(std::make_pair(toShort(channelInfo(0,0)),std::string(channelInfo(0,1)))); + } + + return channels; + } + catch (const dal::DbSqlQueryExecFailure& e) { + // TODO: throw an exception. + LOG_ERROR("SQL query failure: " << e.what(), 0); + } + + return channels; +} + +void +DALStorage::updateChannels(std::map<short, std::string> channelList) +{ + // If not opened already + open(); + + try { + // Empties the table + std::stringstream sql; + sql << "delete from " + << CHANNELS_TBL_NAME + << ";"; + + mDb->execSql(sql.str()); + + for ( std::map<short, std::string>::iterator i = channelList.begin(); + i != channelList.end();) + { + // insert registered channel if id < MAX_PUBLIC_CHANNELS; + if ( i->first < /*MAX_PUBLIC_CHANNELS*/ 1000 ) + { + sql.str(""); + sql << "insert into " + << CHANNELS_TBL_NAME + << " (id, name)" + << " values (" + << i->first << ", '" + << i->second << "');"; + + mDb->execSql(sql.str()); + } + ++i; + } + + } + catch (const dal::DbSqlQueryExecFailure& e) { + // TODO: throw an exception. + LOG_ERROR("SQL query failure: " << e.what(), 0); + } +} + /** * Save changes to the database permanently. */ diff --git a/src/dalstorage.h b/src/dalstorage.h index c2257c6e..0867ef4c 100644 --- a/src/dalstorage.h +++ b/src/dalstorage.h @@ -120,6 +120,20 @@ class DALStorage: public Storage getMapNameFromId(const unsigned int mapId); /** + * Gives the list of opened public channels registered in database + * @return a map of the public channels + */ + const std::map<short, std::string> + getChannelList(); + + /** + * apply channel differences from the list in memory + * to the one in db. + */ + void + updateChannels(std::map<short, std::string> channelList); + + /** * Save changes to the database permanently. * * @exception tmwserv::dal::DbSqlQueryExecFailure. diff --git a/src/dalstoragesql.h b/src/dalstoragesql.h index cc287fbe..84e1a57f 100644 --- a/src/dalstoragesql.h +++ b/src/dalstoragesql.h @@ -316,6 +316,26 @@ const std::string SQL_INVENTORIES_TABLE( ");" ); +/** + * TABLE: tmw_channels. + * Keeps opened public Channel list + */ +const std::string CHANNELS_TBL_NAME("tmw_channels"); +const std::string SQL_CHANNELS_TABLE( + "CREATE TABLE tmw_channels (" +#if defined (MYSQL_SUPPORT) + "id INTEGER PRIMARY KEY," + "name VARCHAR(32) NOT NULL UNIQUE" +#elif defined (SQLITE_SUPPORT) + "id INTEGER PRIMARY KEY," + "name TEXT NOT NULL UNIQUE" +#elif defined (POSTGRESQL_SUPPORT) + "id SERIAL PRIMARY KEY," + "name TEXT NOT NULL UNIQUE" +#endif + ");" +); + } // anonymous namespace diff --git a/src/state.cpp b/src/state.cpp index d49bf407..cb9a9e22 100644 --- a/src/state.cpp +++ b/src/state.cpp @@ -90,9 +90,6 @@ void State::addBeing(BeingPtr beingPtr, const unsigned int mapId) { if (!mapExists(mapId)) if (!loadMap(mapId)) return; - // WARNING: We should pass a copy there. - // Otherwise, remove being will erase one character - // from the account object. maps[mapId].beings.push_back(beingPtr); } } diff --git a/src/storage.h b/src/storage.h index 682782bf..8006a128 100644 --- a/src/storage.h +++ b/src/storage.h @@ -286,7 +286,8 @@ class Storage * * @deprecated The only purpose of using this list inside the server is * for checking for existing email addresses, which is - * covered by Storage::doesEmailAlreadyExists(). + * covered by Storage::getSameEmailNumber(). + * It could later be used for mailing list announcement. */ virtual std::list<std::string> getEmailList() = 0; @@ -313,6 +314,21 @@ class Storage getMapNameFromId(const unsigned int mapId) = 0; /** + * Gives the list of opened public channels registered in database + * @return a map of the public channels + */ + virtual const std::map<short, std::string> + getChannelList() = 0; + + /** + * apply channel differences from the list in memory + * to the one in db. + */ + virtual void + updateChannels(std::map<short, std::string> channelList) = 0; + + + /** * Saves the changes permanently. */ virtual void |