summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog13
-rw-r--r--src/Makefile.am4
-rw-r--r--src/accounthandler.cpp79
-rw-r--r--src/accounthandler.h6
-rw-r--r--src/chatchannel.cpp5
-rw-r--r--src/chatchannel.h5
-rw-r--r--src/chatchannelmanager.cpp58
-rw-r--r--src/chatchannelmanager.h43
-rw-r--r--src/chathandler.cpp181
-rw-r--r--src/chathandler.h23
-rw-r--r--src/client.cpp4
-rw-r--r--src/connectionhandler.cpp21
-rw-r--r--src/connectionhandler.h6
-rw-r--r--src/dalstoragesql.h12
-rw-r--r--src/defines.h66
-rw-r--r--src/main.cpp8
-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
diff --git a/ChangeLog b/ChangeLog
index f33a8dfe..11e70b23 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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