diff options
-rw-r--r-- | ChangeLog | 13 | ||||
-rw-r--r-- | src/Makefile.am | 4 | ||||
-rw-r--r-- | src/accounthandler.cpp | 79 | ||||
-rw-r--r-- | src/accounthandler.h | 6 | ||||
-rw-r--r-- | src/chatchannel.cpp | 5 | ||||
-rw-r--r-- | src/chatchannel.h | 5 | ||||
-rw-r--r-- | src/chatchannelmanager.cpp | 58 | ||||
-rw-r--r-- | src/chatchannelmanager.h | 43 | ||||
-rw-r--r-- | src/chathandler.cpp | 181 | ||||
-rw-r--r-- | src/chathandler.h | 23 | ||||
-rw-r--r-- | src/client.cpp | 4 | ||||
-rw-r--r-- | src/connectionhandler.cpp | 21 | ||||
-rw-r--r-- | src/connectionhandler.h | 6 | ||||
-rw-r--r-- | src/dalstoragesql.h | 12 | ||||
-rw-r--r-- | src/defines.h | 66 | ||||
-rw-r--r-- | src/main.cpp | 8 | ||||
-rw-r--r-- | src/utils/stringfilter.cpp (renamed from src/utils/slangsfilter.cpp) | 48 | ||||
-rw-r--r-- | src/utils/stringfilter.h (renamed from src/utils/slangsfilter.h) | 25 |
18 files changed, 471 insertions, 136 deletions
@@ -1,3 +1,16 @@ +2006-01-24 Yohann Ferreira <bertram@cegetel.net> + + * src/chathandler.cpp, src/chathandler.h, src/accounthandler.cpp, + src/dalstoragesql.h, src/defines.h, src/client.cpp, src/Makefile.am, + src/utils/slangsfilter.cpp, src/utils/slangsfilter.h, + src/utils/stringfilter.h, src/utils/stringfilter.cpp, src/main.cpp, + src/accounthandler.h, src/chatchannelmanager.cpp, + src/chatchannelmanager.h, src/chatchannel.h, src/chatchannel.cpp, + src/connectionhandler.h, src/connectionhandler.cpp: Chat Channeling + Commit part 4. Renamed the slang filter into StringFilter and moved + some code to it. Added the missing protocol values, and implemented + registering/registering of channels; More to come about it. + 2006-01-21 Yohann Ferreira <bertram@cegetel.net> * src/accounthandler.cpp, src/client.cpp, src/defines.h, diff --git a/src/Makefile.am b/src/Makefile.am index defa5b4e..90baf8b9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -81,8 +81,8 @@ tmwserv_SOURCES = main.cpp \ utils/cipher.cpp \ utils/logger.h \ utils/logger.cpp \ - utils/slangsfilter.h \ - utils/slangsfilter.cpp + utils/stringfilter.h \ + utils/stringfilter.cpp if BUILD_MYSQL tmwserv_SOURCES += dal/mysqldataprovider.h \ diff --git a/src/accounthandler.cpp b/src/accounthandler.cpp index b37bbc68..79aab94d 100644 --- a/src/accounthandler.cpp +++ b/src/accounthandler.cpp @@ -29,22 +29,12 @@ #include "messageout.h" #include "configuration.h" #include "utils/logger.h" -#include "utils/slangsfilter.h" +#include "utils/stringfilter.h" using tmwserv::Account; using tmwserv::AccountPtr; using tmwserv::Storage; -// Useful to avoid failing SQL queries cause of " in strings. -bool findDoubleQuotes(const std::string& text) -{ - for (unsigned int i = 0; i < text.length(); i++) - { - if (text[i] == '\"') return true; - } - return false; -} - /** * Generic interface convention for getting a message and sending it to the * correct subroutines. Account handler takes care of determining the @@ -83,7 +73,12 @@ void AccountHandler::receiveMessage(NetComputer &computer, MessageIn &message) result.writeByte(LOGIN_INVALID_VERSION); break; } - + if (stringFilter->findDoubleQuotes(username)) + { + result.writeByte(LOGIN_INVALID_USERNAME); + LOG_INFO(username << ": has got double quotes in it.", 1) + break; + } if (computer.getAccount().get() != NULL) { LOG_INFO("Already logged in as " << computer.getAccount()->getName() << ".", 1) @@ -185,16 +180,14 @@ void AccountHandler::receiveMessage(NetComputer &computer, MessageIn &message) } // Checking if the Name is slang's free. - - if (!slangsFilter->filterContent(username)) + if (!stringFilter->filterContent(username)) { result.writeByte(REGISTER_INVALID_USERNAME); LOG_INFO(username << ": has got bad words in it.", 1) break; } - // Checking if there are double quotes in it. - if (findDoubleQuotes(username)) + if (stringFilter->findDoubleQuotes(username)) { result.writeByte(REGISTER_INVALID_USERNAME); LOG_INFO(username << ": has got double quotes in it.", 1) @@ -221,12 +214,12 @@ void AccountHandler::receiveMessage(NetComputer &computer, MessageIn &message) result.writeByte(REGISTER_INVALID_PASSWORD); LOG_INFO(email << ": Password too short or too long.", 1) } - else if (!isEmailValid(email)) + else if (!stringFilter->isEmailValid(email)) { result.writeByte(REGISTER_INVALID_EMAIL); LOG_INFO(email << ": Email Invalid, only a@b.c format is accepted.", 1) } - if (findDoubleQuotes(email)) + if (stringFilter->findDoubleQuotes(email)) { result.writeByte(REGISTER_INVALID_EMAIL); LOG_INFO(email << ": has got double quotes in it.", 1) @@ -258,6 +251,13 @@ void AccountHandler::receiveMessage(NetComputer &computer, MessageIn &message) result.writeShort(SMSG_UNREGISTER_RESPONSE); + if (stringFilter->findDoubleQuotes(username)) + { + result.writeByte(UNREGISTER_INVALID_USERNAME); + LOG_INFO(username << ": has got double quotes in it.", 1) + break; + } + // see if the account exists tmwserv::AccountPtr accPtr = store.getAccount(username); @@ -303,17 +303,16 @@ void AccountHandler::receiveMessage(NetComputer &computer, MessageIn &message) } std::string email = message.readString(); - if ( !isEmailValid(email) ) + if (!stringFilter->isEmailValid(email)) { result.writeByte(EMAILCHG_INVALID); LOG_INFO(email << ": Invalid format, cannot change Email for " << computer.getAccount()->getName(), 1) } - if (findDoubleQuotes(email)) + else if (stringFilter->findDoubleQuotes(email)) { result.writeByte(EMAILCHG_INVALID); LOG_INFO(email << ": has got double quotes in it.", 1) - break; } else if (store.getSameEmailNumber(email) > 1) // Search if Email already exists, { // Except for the one already that is to @@ -366,17 +365,10 @@ void AccountHandler::receiveMessage(NetComputer &computer, MessageIn &message) LOG_INFO(computer.getAccount()->getName() << ": New password too long or too short.", 1) } - else if (findDoubleQuotes(password1)) + else if (stringFilter->findDoubleQuotes(password1)) { result.writeByte(PASSCHG_INVALID); LOG_INFO(password1 << ": has got double quotes in it.", 1) - break; - } - else if (findDoubleQuotes(password2)) - { - result.writeByte(PASSCHG_INVALID); - LOG_INFO(password2 << ": has got double quotes in it.", 1) - break; } else if ( password1 != password2 ) { @@ -422,14 +414,14 @@ void AccountHandler::receiveMessage(NetComputer &computer, MessageIn &message) std::string name = message.readString(); // Checking if the Name is slang's free. - if (!slangsFilter->filterContent(name)) + if (!stringFilter->filterContent(name)) { result.writeByte(CREATE_INVALID_NAME); LOG_INFO(name << ": Character has got bad words in it.", 1) break; } // Checking if the Name has got double quotes. - if (findDoubleQuotes(name)) + if (stringFilter->findDoubleQuotes(name)) { result.writeByte(CREATE_INVALID_NAME); LOG_INFO(name << ": has got double quotes in it.", 1) @@ -635,7 +627,7 @@ void AccountHandler::receiveMessage(NetComputer &computer, MessageIn &message) // Character ID = 0 to Number of Characters - 1. if (charNum >= chars.size()) { // invalid char selection - result.writeByte(DELETE_INVALID_NAME); + result.writeByte(DELETE_INVALID_ID); LOG_INFO("Character Deletion : Selection out of ID range.", 1) break; } @@ -770,26 +762,3 @@ AccountHandler::assignAccount(NetComputer &computer, tmwserv::Account *account) return TMW_SUCCESS; } - -bool -AccountHandler::isEmailValid(std::string& email) -{ - // Testing Email validity - if ( (email.length() < MIN_EMAIL_LENGTH) || (email.length() > MAX_EMAIL_LENGTH)) - { - LOG_INFO(email << ": Email too short or too long.", 1) - return false; - } - if ((email.find_first_of('@') != std::string::npos)) // Searching for an @. - { - int atpos = email.find_first_of('@'); - if (email.find_first_of('.', atpos) != std::string::npos) // Searching for a '.' after the @. - { - if (email.find_first_of(' ') == std::string::npos) // Searching if there's no spaces. - { - return true; - } - } - } - return false; -} diff --git a/src/accounthandler.h b/src/accounthandler.h index f42b424b..14f13cf3 100644 --- a/src/accounthandler.h +++ b/src/accounthandler.h @@ -55,12 +55,6 @@ class AccountHandler : public MessageHandler * Account assignment. */ int assignAccount(NetComputer &computer, tmwserv::Account *account); - - /** - * Check an Email Validity - */ - bool - isEmailValid(std::string& email); }; #endif diff --git a/src/chatchannel.cpp b/src/chatchannel.cpp index 3f0dffda..ce1f6967 100644 --- a/src/chatchannel.cpp +++ b/src/chatchannel.cpp @@ -120,3 +120,8 @@ ChatChannel::removeUserFromChannel(tmwserv::BeingPtr beingPtr) } return false; } + +void ChatChannel::removeEveryUsersFromChannel() +{ + mRegisteredUsers.clear(); +} diff --git a/src/chatchannel.h b/src/chatchannel.h index 43b722b8..997519a8 100644 --- a/src/chatchannel.h +++ b/src/chatchannel.h @@ -90,6 +90,11 @@ class ChatChannel { */ bool removeUserFromChannel(tmwserv::BeingPtr beingPtr); + /** + * Empties a channel from its users (admin included). + */ + void removeEveryUsersFromChannel(); + private: /** * The Channel's name diff --git a/src/chatchannelmanager.cpp b/src/chatchannelmanager.cpp index 280090bb..99458f47 100644 --- a/src/chatchannelmanager.cpp +++ b/src/chatchannelmanager.cpp @@ -42,7 +42,8 @@ ChatChannelManager::~ChatChannelManager() } short -ChatChannelManager::registerPublicChannel(const std::string& channelName) +ChatChannelManager::registerPublicChannel(const std::string& channelName, + const std::string& channelAnnouncement, const std::string& channelPassword) { short channelId = 1; for (std::map<short, ChatChannel>::iterator i = mChatChannels.begin(); i != mChatChannels.end();) @@ -57,13 +58,15 @@ ChatChannelManager::registerPublicChannel(const std::string& channelName) if ( channelId >= (signed)MAX_PRIVATE_CHANNELS_RANGE ) return 0; // Register Channel - mChatChannels.insert(std::make_pair(channelId,ChatChannel(channelName, "None", "None"))); + mChatChannels.insert(std::make_pair(channelId,ChatChannel(channelName, + channelAnnouncement, channelPassword))); return channelId; } short -ChatChannelManager::registerPrivateChannel(const std::string& channelName) +ChatChannelManager::registerPrivateChannel(const std::string& channelName, + const std::string& channelAnnouncement, const std::string& channelPassword) { short channelId = MAX_PRIVATE_CHANNELS_RANGE; for (std::map<short, ChatChannel>::iterator i = mChatChannels.begin(); i != mChatChannels.end();) @@ -78,7 +81,8 @@ ChatChannelManager::registerPrivateChannel(const std::string& channelName) if ( channelId >= (signed)MAX_PUBLIC_CHANNELS_RANGE ) return 0; // Register Channel - mChatChannels.insert(std::make_pair(channelId, ChatChannel(channelName, "None", "None"))); + mChatChannels.insert(std::make_pair(channelId,ChatChannel(channelName, + channelAnnouncement, channelPassword))); return channelId; } @@ -89,6 +93,9 @@ ChatChannelManager::removeChannel(const short channelId) { if ( i->first == channelId ) { + // Removing every user from the channel + i->second.removeEveryUsersFromChannel(); + // Erasing the channel now it's empty mChatChannels.erase(i); i++; return true; @@ -144,8 +151,38 @@ ChatChannelManager::getChannelPassword(const short channelId) return "None"; } +bool +ChatChannelManager::setChannelAnnouncement(const short channelId, const std::string& channelAnnouncement) +{ + for (std::map<short, ChatChannel>::iterator i = mChatChannels.begin(); i != mChatChannels.end();) + { + if ( i->first == channelId ) + { + i->second.setAnnouncement(channelAnnouncement); + return true; + } + ++i; + } + return false; +} + +bool +ChatChannelManager::setChannelPassword(const short channelId, const std::string& channelPassword) +{ + for (std::map<short, ChatChannel>::iterator i = mChatChannels.begin(); i != mChatChannels.end();) + { + if ( i->first == channelId ) + { + i->second.setPassword(channelPassword); + return true; + } + ++i; + } + return false; +} + const ChatChannel -ChatChannelManager::getChannel(const short channelId) +ChatChannelManager::_getChannel(const short channelId) { for (std::map<short, ChatChannel>::iterator i = mChatChannels.begin(); i != mChatChannels.end();) { @@ -209,3 +246,14 @@ ChatChannelManager::getUserListInChannel(const short channelId) std::vector<tmwserv::BeingPtr> emptyList; return emptyList; } + +bool +ChatChannelManager::isChannelRegistered(const short channelId) +{ + for (std::map<short, ChatChannel>::iterator i = mChatChannels.begin(); i != mChatChannels.end();) + { + if ( i->first == channelId ) return true; + ++i; + } + return false; +} diff --git a/src/chatchannelmanager.h b/src/chatchannelmanager.h index cbc340a9..3a2597f4 100644 --- a/src/chatchannelmanager.h +++ b/src/chatchannelmanager.h @@ -48,7 +48,9 @@ public: * @return the number of the channel registered. * 0 if the registering was unsuccessful. */ - short registerPublicChannel(const std::string& channelName); + short registerPublicChannel(const std::string& channelName, + const std::string& channelAnnouncement, + const std::string& channelPassword); /** * Add a private channel. @@ -56,7 +58,9 @@ public: * @return the number of the channel registered. * 0 if the registering was unsuccessful. */ - short registerPrivateChannel(const std::string& channelName); + short registerPrivateChannel(const std::string& channelName, + const std::string& channelAnnouncement, + const std::string& channelPassword); /** * Remove a channel. @@ -64,7 +68,7 @@ public: bool removeChannel(const short channelId); /** - * get the id of a channel from its name. + * Get the id of a channel from its name. * * @return the id of the channel * 0 if it was unsuccessful. @@ -72,27 +76,43 @@ public: short getChannelId(const std::string& channelName); /** - * get the name of a channel from its id. + * Get the name of a channel from its id. * * @return the name of the channel */ const std::string getChannelName(const short channelId); /** - * get the announcement string of a channel from its id. + * Get the announcement string of a channel from its id. * * @return the announcement string of the channel */ const std::string - ChatChannelManager::getChannelAnnouncement(const short channelId); + getChannelAnnouncement(const short channelId); /** - * get the password of a channel from its id. + * Set the announcement string of a channel from its id. + * + * @return the announcement string of the channel + */ + bool + setChannelAnnouncement(const short channelId, const std::string& channelAnnouncement); + + /** + * Set the announcement string of a channel from its id. + * + * @return the announcement string of the channel + */ + bool + setChannelPassword(const short channelId, const std::string& channelPassword); + + /** + * Get the password of a channel from its id. * * @return the password of the channel */ const std::string - ChatChannelManager::getChannelPassword(const short channelId); + getChannelPassword(const short channelId); /** * get the ChatChannel object from its id. @@ -100,7 +120,7 @@ public: * @return the ChatChannel object */ const ChatChannel - ChatChannelManager::getChannel(const short channelId); + _getChannel(const short channelId); /** * Add a user in a channel @@ -123,6 +143,11 @@ public: */ std::vector<tmwserv::BeingPtr> getUserListInChannel(const short channelId); + /** + * tells if a channel exists + */ + bool isChannelRegistered(const short channelId); + private: /** diff --git a/src/chathandler.cpp b/src/chathandler.cpp index d57fe8d4..082a1b6a 100644 --- a/src/chathandler.cpp +++ b/src/chathandler.cpp @@ -26,7 +26,8 @@ #include "being.h" #include "defines.h" #include "utils/logger.h" -#include "utils/slangsfilter.h" +#include "utils/stringfilter.h" +#include "chatchannelmanager.h" void ChatHandler::receiveMessage(NetComputer &computer, MessageIn &message) { @@ -61,7 +62,7 @@ void ChatHandler::receiveMessage(NetComputer &computer, MessageIn &message) // chat to people around area std::string text = message.readString(); // If it's slang clean, - if (slangsFilter->filterContent(text)) + if (stringFilter->filterContent(text)) { short channel = message.readShort(); LOG_INFO("Say: (Channel " << channel << "): " << text, 2) @@ -99,7 +100,7 @@ void ChatHandler::receiveMessage(NetComputer &computer, MessageIn &message) { std::string text = message.readString(); // If it's slang's free. - if (slangsFilter->filterContent(text)) + if (stringFilter->filterContent(text)) { // We send the message to every players in the default channel // as it is an annouce. @@ -116,7 +117,7 @@ void ChatHandler::receiveMessage(NetComputer &computer, MessageIn &message) { std::string user = message.readString(); std::string text = message.readString(); - if (slangsFilter->filterContent(text)) + if (stringFilter->filterContent(text)) { // We seek the player to whom the message is told // and send it to her/him. @@ -128,15 +129,175 @@ void ChatHandler::receiveMessage(NetComputer &computer, MessageIn &message) } } break; + // Channels handling + // ================= + case CMSG_REGISTER_CHANNEL: + { + MessageOut result; + result.writeShort(SMSG_REGISTER_CHANNEL_RESPONSE); + // 0 public, 1 private + char channelType = message.readByte(); + if (!channelType) + { + if (computer.getAccount()->getLevel() != (AccountLevels)AL_ADMIN && + computer.getAccount()->getLevel() != (AccountLevels)AL_GM) + { + result.writeByte(CHATCNL_CREATE_UNSUFFICIENT_RIGHTS); + computer.send(result.getPacket()); + return; + } + } + std::string channelName = message.readString(); + std::string channelAnnouncement = message.readString(); + std::string channelPassword = message.readString(); + // Checking datas + // Seeking double-quotes in strings + if (channelName == "" || channelName.length() > MAX_CHANNEL_NAME || + stringFilter->findDoubleQuotes(channelName)) + { + result.writeByte(CHATCNL_CREATE_INVALID_NAME); + computer.send(result.getPacket()); + return; + } + if (channelAnnouncement.length() > MAX_CHANNEL_ANNOUNCEMENT || + stringFilter->findDoubleQuotes(channelAnnouncement)) + { + result.writeByte(CHATCNL_CREATE_INVALID_ANNOUNCEMENT); + computer.send(result.getPacket()); + return; + } + if (channelPassword.length() > MAX_CHANNEL_PASSWORD || + stringFilter->findDoubleQuotes(channelPassword)) + { + result.writeByte(CHATCNL_CREATE_INVALID_PASSWORD); + computer.send(result.getPacket()); + return; + } + + // If it's slang's free. + if (stringFilter->filterContent(channelName) && + stringFilter->filterContent(channelAnnouncement)) + { + // We attempt to create a new channel + short channelId; + if (channelType) + channelId = chatChannelManager->registerPrivateChannel(channelName, + channelAnnouncement, + channelPassword); + else + channelId = chatChannelManager->registerPublicChannel(channelName, + channelAnnouncement, + channelPassword); + if (channelId != 0) + { + // We add the player as admin of this channel as he created it. + // The user registering a private channel is the only one to be able + // to update the password and the announcement in it and also to remove it. + chatChannelManager->addUserInChannel(computer.getCharacter(), channelId); + + result.writeByte(CHATCNL_CREATE_OK); + result.writeShort(channelId); + computer.send(result.getPacket()); + return; + } + else + { + result.writeByte(CHATCNL_CREATE_UNKNOWN); + computer.send(result.getPacket()); + return; + } + } + else + { + warnPlayerAboutBadWords(computer); + } + } + break; + + case CMSG_UNREGISTER_CHANNEL: + { + MessageOut result; + result.writeShort(SMSG_UNREGISTER_CHANNEL_RESPONSE); + + short channelId = message.readShort(); + if (channelId != 0) + { + // Public channels + if (channelId < (signed)MAX_PUBLIC_CHANNELS_RANGE) + { + if (computer.getAccount()->getLevel() != (AccountLevels)AL_ADMIN && + computer.getAccount()->getLevel() != (AccountLevels)AL_GM) + { + result.writeByte(CHATCNL_DEL_UNSUFFICIENT_RIGHTS); + } + else + { // if the channel actually exist + if (chatChannelManager->isChannelRegistered(channelId)) + { + // Make every user quit the channel + connectionHandler->makeUsersLeaveChannel(channelId); + if (chatChannelManager->removeChannel(channelId)) + result.writeByte(CHATCNL_DEL_OK); + else + result.writeByte(CHATCNL_DEL_UNKNOWN); + } + else + { // Couldn't remove channel because it doesn't exist + result.writeByte(CHATCNL_DEL_INVALID_ID); + } + } + } + else if (channelId < (signed)MAX_PRIVATE_CHANNELS_RANGE) + { // Private channels + if (chatChannelManager->isChannelRegistered(channelId)) + { + // We first see if the user is the admin (first user) of the channel + std::vector<tmwserv::BeingPtr> userList = + chatChannelManager->getUserListInChannel(channelId); + std::vector<tmwserv::BeingPtr>::const_iterator i = userList.begin(); + // if it's actually the private channel's admin + if ( (*i).get() == computer.getCharacter().get() ) + { + // Make every user quit the channel + connectionHandler->makeUsersLeaveChannel(channelId); + if (chatChannelManager->removeChannel(channelId)) + result.writeByte(CHATCNL_DEL_OK); + else + result.writeByte(CHATCNL_DEL_UNKNOWN); + } + else + { + result.writeByte(CHATCNL_DEL_UNSUFFICIENT_RIGHTS); + } + } + else + { + result.writeByte(CHATCNL_DEL_INVALID_ID); + } + } + else + { // Id too high or too low + result.writeByte(CHATCNL_DEL_INVALID_ID); + } + } + else + { + result.writeByte(CHATCNL_DEL_INVALID_ID); + } + computer.send(result.getPacket()); + } break; + + + default: LOG_INFO("Chat: Invalid message type", 2) break; } } -void ChatHandler::handleCommand(NetComputer &computer, std::string command) +void ChatHandler::handleCommand(NetComputer &computer, const std::string& command) { - LOG_INFO("Chat: Recieved unhandled command: " << command, 2) + LOG_INFO("Chat: Received unhandled command: " << command, 2) MessageOut result; result.writeShort(SMSG_CHAT); result.writeByte(CHATCMD_UNHANDLED_COMMAND); @@ -154,7 +315,7 @@ void ChatHandler::warnPlayerAboutBadWords(NetComputer &computer) LOG_INFO(computer.getCharacter()->getName() << " says bad words.", 2) } -void ChatHandler::announce(NetComputer &computer, std::string text) +void ChatHandler::announce(NetComputer &computer, const std::string& text) { MessageOut result; if ( computer.getAccount()->getLevel() == (AccountLevels)AL_ADMIN || @@ -176,7 +337,7 @@ void ChatHandler::announce(NetComputer &computer, std::string text) } } -void ChatHandler::sayAround(NetComputer &computer, std::string text) +void ChatHandler::sayAround(NetComputer &computer, const std::string& text) { MessageOut result; LOG_INFO( computer.getCharacter()->getName() << " says: " << text, 2) @@ -190,7 +351,7 @@ void ChatHandler::sayAround(NetComputer &computer, std::string text) connectionHandler->sendAround(computer.getCharacter(), result); } -void ChatHandler::sayToPlayer(NetComputer &computer, std::string playerName, std::string text) +void ChatHandler::sayToPlayer(NetComputer &computer, const std::string& playerName, const std::string& text) { MessageOut result; LOG_INFO( computer.getCharacter()->getName() << " says to " << playerName @@ -204,7 +365,7 @@ void ChatHandler::sayToPlayer(NetComputer &computer, std::string playerName, std connectionHandler->sendTo(playerName, result); } -void ChatHandler::sayInChannel(NetComputer &computer, short channel, std::string text) +void ChatHandler::sayInChannel(NetComputer &computer, short channel, const std::string& text) { MessageOut result; LOG_INFO( computer.getCharacter()->getName() << " says in channel " << channel diff --git a/src/chathandler.h b/src/chathandler.h index d7136e77..b4227207 100644 --- a/src/chathandler.h +++ b/src/chathandler.h @@ -27,7 +27,6 @@ #include "messagehandler.h" #include "netcomputer.h" #include "messagein.h" -#include "chatchannelmanager.h" /** * Manages all chat related @@ -35,12 +34,6 @@ class ChatHandler : public MessageHandler { public: - - /** - * Constructor - */ - ChatHandler(); - /** * Receives chat related messages. */ @@ -50,7 +43,7 @@ class ChatHandler : public MessageHandler /** * Deals with command messages */ - void handleCommand(NetComputer &computer, std::string command); + void handleCommand(NetComputer &computer, const std::string& command); /** * Tells the player to be more polite. @@ -60,30 +53,24 @@ class ChatHandler : public MessageHandler /** * Announce a message to every being in the default channel. */ - void announce(NetComputer &computer, std::string text); + void announce(NetComputer &computer, const std::string& text); /** * Display a message to every player around one's player * in the default channel. * The tile area has been set to 10 for now. */ - void sayAround(NetComputer &computer, std::string text); + void sayAround(NetComputer &computer, const std::string& text); /** * Say something private to a player. */ - void sayToPlayer(NetComputer &computer, std::string playerName, std::string text); + void sayToPlayer(NetComputer &computer, const std::string& playerName, const std::string& text); /** * Say something in a specific channel. */ - void sayInChannel(NetComputer &computer, short channel, std::string text); - - /** - * The Chat Channels instance - */ - ChatChannelManager mChatChannelManager; - + void sayInChannel(NetComputer &computer, short channel, const std::string& text); }; #endif diff --git a/src/client.cpp b/src/client.cpp index f71f9d2c..cf69b564 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -558,8 +558,8 @@ int main(int argc, char *argv[]) case DELETE_OK: std::cout << "Character deleted." << std::endl; break; - case DELETE_INVALID_NAME: - std::cout << "Character Deletion: Character's name doesn't exist." + case DELETE_INVALID_ID: + std::cout << "Character Deletion: Character's ID doesn't exist." << std::endl; break; case DELETE_NOLOGIN: diff --git a/src/connectionhandler.cpp b/src/connectionhandler.cpp index 38233a6a..c7a3d49b 100644 --- a/src/connectionhandler.cpp +++ b/src/connectionhandler.cpp @@ -317,3 +317,24 @@ unsigned int ConnectionHandler::getClientNumber() { return clients.size(); } + +void ConnectionHandler::makeUsersLeaveChannel(const short channelId) +{ + MessageOut result; + result.writeShort(SMSG_QUIT_CHANNEL_RESPONSE); + result.writeByte(CHATCNL_OUT_OK); + for (NetComputers::iterator i = clients.begin(); i != clients.end();i++) + { + const std::vector<tmwserv::BeingPtr> beingList = + chatChannelManager->getUserListInChannel(channelId); + // If the being is in the channel, send it the 'leave now' packet + for (std::vector<tmwserv::BeingPtr>::const_iterator j = beingList.begin(); + j != beingList.end(); j++) + { + if ((*i)->getCharacter().get() == (*j).get() ) + { + (*i)->send(result.getPacket()); + } + } + } +} diff --git a/src/connectionhandler.h b/src/connectionhandler.h index 08965a6a..e89d9f74 100644 --- a/src/connectionhandler.h +++ b/src/connectionhandler.h @@ -133,6 +133,12 @@ class ConnectionHandler */ unsigned int getClientNumber(); + /** + * tells a list of user they're leaving a channel. + */ + void makeUsersLeaveChannel(const short channelId); + + private: std::map<unsigned int, MessageHandler*> handlers; diff --git a/src/dalstoragesql.h b/src/dalstoragesql.h index fb214420..7614445a 100644 --- a/src/dalstoragesql.h +++ b/src/dalstoragesql.h @@ -326,18 +326,18 @@ const std::string SQL_CHANNELS_TABLE( #if defined (MYSQL_SUPPORT) "id INTEGER PRIMARY KEY," "name VARCHAR(32) NOT NULL UNIQUE," - "announcement VARCHAR(256)," - "password VARCHAR(32)" + "announcement VARCHAR(256) NOT NULL," + "password VARCHAR(32) NOT NULL" #elif defined (SQLITE_SUPPORT) "id INTEGER PRIMARY KEY," "name TEXT NOT NULL UNIQUE," - "announcement TEXT," - "password TEXT" + "announcement TEXT NOT NULL," + "password TEXT NOT NULL" #elif defined (POSTGRESQL_SUPPORT) "id SERIAL PRIMARY KEY," "name TEXT NOT NULL UNIQUE," - "announcement TEXT," - "password TEXT" + "announcement TEXT NOT NULL," + "password TEXT NOT NULL" #endif ");" ); diff --git a/src/defines.h b/src/defines.h index 7c5d1ca7..d830af7b 100644 --- a/src/defines.h +++ b/src/defines.h @@ -56,12 +56,16 @@ typedef enum { // Network related const unsigned int MAX_CLIENTS = 1024, + // Chat related /** * N.B: Private channels can't have an id less * than MAX_PUBLIC_CHANNELS_RANGE. */ MAX_PUBLIC_CHANNELS_RANGE = 1000, - MAX_PRIVATE_CHANNELS_RANGE = 10000, + MAX_PRIVATE_CHANNELS_RANGE = 10000, + MAX_CHANNEL_NAME = 15, + MAX_CHANNEL_ANNOUNCEMENT = 150, + MAX_CHANNEL_PASSWORD = 12, // Registering related MIN_LOGIN_LENGTH = 4, @@ -164,6 +168,17 @@ enum { CMSG_SAY = 0x0410, CMSG_ANNOUNCE = 0x0411, CMSG_PRIVMSG = 0x0412, + // -- Channeling + CMSG_REGISTER_CHANNEL = 0x0413, + SMSG_REGISTER_CHANNEL_RESPONSE = 0x0414, + CMSG_UNREGISTER_CHANNEL = 0x0415, + SMSG_UNREGISTER_CHANNEL_RESPONSE = 0x0416, + CMSG_UPDATE_CHANNEL = 0x0417, + SMSG_UPDATE_CHANNEL_RESPONSE = 0x0418, + CMSG_ENTER_CHANNEL = 0x0419, + SMSG_ENTER_CHANNEL_RESPONSE = 0x0420, + CMSG_QUIT_CHANNEL = 0x0421, + SMSG_QUIT_CHANNEL_RESPONSE = 0x0422, // Other SMSG_LOAD_MAP = 0x0500, @@ -231,7 +246,7 @@ enum { // Character deletion return values enum { DELETE_OK = 0, - DELETE_INVALID_NAME, + DELETE_INVALID_ID, DELETE_NO_MORE_CHARACTERS, DELETE_NOLOGIN, DELETE_UNKNOWN @@ -291,11 +306,52 @@ enum { CHATCMD_UNKNOWN }; +// Chat channels creation return values +enum { + CHATCNL_CREATE_OK = 0, + CHATCNL_CREATE_UNSUFFICIENT_RIGHTS, + CHATCNL_CREATE_INVALID_NAME, + CHATCNL_CREATE_INVALID_ANNOUNCEMENT, + CHATCNL_CREATE_INVALID_PASSWORD, + CHATCNL_CREATE_UNKNOWN +}; + +// Chat channels update return values +enum { + CHATCNL_UPD_OK = 0, + CHATCNL_UPD_UNSUFFICIENT_RIGHTS, + CHATCNL_UPD_UNKNOWN +}; + +// Chat channels deletion return values +enum { + CHATCNL_DEL_OK = 0, + CHATCNL_DEL_UNSUFFICIENT_RIGHTS, + CHATCNL_DEL_INVALID_ID, + CHATCNL_DEL_UNKNOWN +}; + +// Chat channels entering return values +enum { + CHATCNL_IN_OK = 0, + CHATCNL_IN_UNSUFFICIENT_RIGHTS, + CHATCNL_IN_BAD_PASSWORD, + CHATCNL_IN_UNKNOWN +}; + +// Chat channels leaving return values +enum { + CHATCNL_OUT_OK = 0, + CHATCNL_OUT_UNKNOWN +}; + // Object type enumeration enum { - OBJECT_ITEM = 0, - OBJECT_PLAYER, - OBJECT_MONSTER + OBJECT_ITEM = 0, // A simple item + OBJECT_ACTOR, // An item that toggle map/quest actions (doors, switchs, ...) and to speak (map panels). + OBJECT_NPC, // Non-Playable-Character is an actor capable of movement and maybe actions + OBJECT_MONSTER, // A monster (moving actor with AI. Should be able to toggle map/quest actions, too) + OBJECT_PLAYER // A normal being }; // Pickup response enumeration diff --git a/src/main.cpp b/src/main.cpp index fef59d3d..833492b2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -48,7 +48,7 @@ #include "storage.h" #include "utils/logger.h" -#include "utils/slangsfilter.h" +#include "utils/stringfilter.h" // Scripting #ifdef SCRIPT_SUPPORT @@ -88,7 +88,7 @@ Skill skillTree("base"); /**< Skill tree */ Configuration config; /**< XML config reader */ -tmwserv::utils::SlangsFilter *slangsFilter; /**< Slang's Filter */ +tmwserv::utils::StringFilter *stringFilter; /**< Slang's Filter */ /** Account message handler */ AccountHandler *accountHandler; @@ -173,7 +173,7 @@ void initialize() LOG_INFO("Using Log File: " << logPath, 0) // Initialize the slang's filter. - slangsFilter = new SlangsFilter(&config); + stringFilter = new StringFilter(&config); // Initialize the global handlers // FIXME: Make the global handlers global vars or part of a bigger @@ -253,7 +253,7 @@ void initialize() */ void deinitialize() { - delete slangsFilter; + delete stringFilter; // Write configuration file config.write(); diff --git a/src/utils/slangsfilter.cpp b/src/utils/stringfilter.cpp index a729bb93..3e72a278 100644 --- a/src/utils/slangsfilter.cpp +++ b/src/utils/stringfilter.cpp @@ -20,7 +20,8 @@ * $Id$ */ -#include "slangsfilter.h" +#include "../defines.h" +#include "stringfilter.h" #include "logger.h" namespace tmwserv @@ -28,21 +29,21 @@ namespace tmwserv namespace utils { -SlangsFilter::SlangsFilter(Configuration *config) +StringFilter::StringFilter(Configuration *config) : mInitialized(false), mConfig(config) { mSlangs.clear(); - loadFilterList(); + loadSlangFilterList(); } -SlangsFilter::~SlangsFilter() +StringFilter::~StringFilter() { - writeFilterList(); + writeSlangFilterList(); mSlangs.clear(); } -bool SlangsFilter::loadFilterList() +bool StringFilter::loadSlangFilterList() { mInitialized = false; std::string slangsList = mConfig->getValue("SlangsList", ""); @@ -70,7 +71,7 @@ bool SlangsFilter::loadFilterList() return false; } -void SlangsFilter::writeFilterList() +void StringFilter::writeSlangFilterList() { // Write the list to config std::string slangsList = ""; @@ -83,7 +84,7 @@ void SlangsFilter::writeFilterList() //mConfig->setValue("SlangsList", slangsList); } -bool SlangsFilter::filterContent(const std::string& text) +bool StringFilter::filterContent(const std::string& text) { if (mInitialized) { @@ -119,5 +120,36 @@ bool SlangsFilter::filterContent(const std::string& text) } } +bool StringFilter::isEmailValid(const std::string& email) +{ + // Testing Email validity + if ( (email.length() < MIN_EMAIL_LENGTH) || (email.length() > MAX_EMAIL_LENGTH)) + { + LOG_INFO(email << ": Email too short or too long.", 1) + return false; + } + if ((email.find_first_of('@') != std::string::npos)) // Searching for an @. + { + int atpos = email.find_first_of('@'); + if (email.find_first_of('.', atpos) != std::string::npos) // Searching for a '.' after the @. + { + if (email.find_first_of(' ') == std::string::npos) // Searching if there's no spaces. + { + return true; + } + } + } + return false; +} + +bool StringFilter::findDoubleQuotes(const std::string& text) +{ + for (unsigned int i = 0; i < text.length(); i++) + { + if (text[i] == '\"') return true; + } + return false; +} + } // ::utils } // ::tmwserv diff --git a/src/utils/slangsfilter.h b/src/utils/stringfilter.h index f7ccc33f..009bbeb4 100644 --- a/src/utils/slangsfilter.h +++ b/src/utils/stringfilter.h @@ -35,15 +35,15 @@ namespace utils /** * Used to filter content containing bad words. Like username, character's names, chat, ... */ -class SlangsFilter +class StringFilter { public: /** * ctors. */ - SlangsFilter(Configuration *config); + StringFilter(Configuration *config); - ~SlangsFilter(); + ~StringFilter(); /** * Load slang list from the config file. @@ -52,7 +52,7 @@ class SlangsFilter * */ bool - loadFilterList(); + loadSlangFilterList(); /** * Write slang list to the config file. @@ -61,7 +61,7 @@ class SlangsFilter * */ void - writeFilterList(); + writeSlangFilterList(); /** * Useful to filter slangs automatically, by instance. @@ -70,6 +70,19 @@ class SlangsFilter bool filterContent(const std::string& text); + /** + * Tells if an email is valid + */ + bool + isEmailValid(const std::string& email); + + /** + * find double quotes (") in strings. + * Very useful not to make SQL Queries bqsed on names crash + * I placed it here cause where you've got " you can have slangs... + */ + bool + findDoubleQuotes(const std::string& text); private: std::list<std::string> mSlangs; /**< the formatted Slangs list */ @@ -80,6 +93,6 @@ class SlangsFilter } // ::utils } // ::tmwserv -extern tmwserv::utils::SlangsFilter *slangsFilter; +extern tmwserv::utils::StringFilter *stringFilter; #endif |