summaryrefslogtreecommitdiff
path: root/src/chat-server
diff options
context:
space:
mode:
authorGuillaume Melquiond <guillaume.melquiond@gmail.com>2007-07-28 20:14:23 +0000
committerGuillaume Melquiond <guillaume.melquiond@gmail.com>2007-07-28 20:14:23 +0000
commite166458f5425316f4f48aadd7007917ab876be17 (patch)
tree7ccc27db50bb6600cc4fee074485e3b886e58049 /src/chat-server
parent32337eb103384ed8bdb7a43ee54ab550680db62b (diff)
downloadmanaserv-e166458f5425316f4f48aadd7007917ab876be17.tar.gz
manaserv-e166458f5425316f4f48aadd7007917ab876be17.tar.bz2
manaserv-e166458f5425316f4f48aadd7007917ab876be17.tar.xz
manaserv-e166458f5425316f4f48aadd7007917ab876be17.zip
Replaced user names by client pointers when handling channels, in order to reduce lookups in ChatHandler::sendInChannel.
Diffstat (limited to 'src/chat-server')
-rw-r--r--src/chat-server/chatchannel.cpp50
-rw-r--r--src/chat-server/chatchannel.hpp38
-rw-r--r--src/chat-server/chatchannelmanager.cpp41
-rw-r--r--src/chat-server/chatchannelmanager.hpp16
-rw-r--r--src/chat-server/chatclient.hpp7
-rw-r--r--src/chat-server/chathandler.cpp38
6 files changed, 86 insertions, 104 deletions
diff --git a/src/chat-server/chatchannel.cpp b/src/chat-server/chatchannel.cpp
index e8afda13..073a8028 100644
--- a/src/chat-server/chatchannel.cpp
+++ b/src/chat-server/chatchannel.cpp
@@ -22,68 +22,48 @@
*/
#include "chat-server/chatchannel.hpp"
+#include "chat-server/chatclient.hpp"
-ChatChannel::ChatChannel(short id,
+ChatChannel::ChatChannel(int id,
const std::string &name,
const std::string &announcement,
- const std::string &password,
- bool privacy):
+ const std::string &password):
mId(id),
mName(name),
mAnnouncement(announcement),
- mPassword(password),
- mPrivate(privacy)
+ mPassword(password)
{
- if (announcement == "")
- mAnnouncement = "None";
- if (password == "")
- mPassword = "None";
}
-void
-ChatChannel::setName(const std::string &name)
-{
- mName = name;
-}
-
-void
-ChatChannel::setAnnouncement(const std::string &announcement)
-{
- if (announcement == "")
- mAnnouncement = "None";
- else
- mAnnouncement = announcement;
-}
-
-void
-ChatChannel::setPassword(const std::string &password)
-{
- if (password == "")
- mPassword = "None";
- else
- mPassword = password;
-}
-
-bool ChatChannel::addUser(const std::string &user)
+bool ChatChannel::addUser(ChatClient *user)
{
// Check if the user already exists in the channel
ChannelUsers::const_iterator i = mRegisteredUsers.begin(),
i_end = mRegisteredUsers.end();
if (std::find(i, i_end, user) != i_end) return false;
mRegisteredUsers.push_back(user);
+ user->channels.push_back(this);
return true;
}
-bool ChatChannel::removeUser(const std::string &user)
+bool ChatChannel::removeUser(ChatClient *user)
{
ChannelUsers::iterator i_end = mRegisteredUsers.end(),
i = std::find(mRegisteredUsers.begin(), i_end, user);
if (i == i_end) return false;
mRegisteredUsers.erase(i);
+ std::vector< ChatChannel * > &channels = user->channels;
+ channels.erase(std::find(channels.begin(), channels.end(), this));
return true;
}
void ChatChannel::removeAllUsers()
{
+ for (ChannelUsers::const_iterator i = mRegisteredUsers.begin(),
+ i_end = mRegisteredUsers.end(); i != i_end; ++i)
+ {
+ std::vector< ChatChannel * > &channels = (*i)->channels;
+ channels.erase(std::find(channels.begin(), channels.end(), this));
+ }
mRegisteredUsers.clear();
}
diff --git a/src/chat-server/chatchannel.hpp b/src/chat-server/chatchannel.hpp
index 44914324..d92f3c6a 100644
--- a/src/chat-server/chatchannel.hpp
+++ b/src/chat-server/chatchannel.hpp
@@ -27,6 +27,8 @@
#include <string>
#include <vector>
+class ChatClient;
+
/**
* A chat channel. Optionally a channel is private, in which case a password is
* required to join it.
@@ -37,36 +39,29 @@
*
* @todo <b>b_lindeijer:</b> It would be nicer when some more logic could be
* placed in this class to remove some weight from the ChatHandler.
- * Referencing ChatClient instances would also be nicer than to store
- * only the names of the characters.
*/
class ChatChannel
{
public:
- typedef std::vector<std::string> ChannelUsers;
+ typedef std::vector< ChatClient * > ChannelUsers;
/**
* Constructor.
*
- * @todo <b>b_lindeijer:</b> I would say a channel can be defined as
- * private when a non-empty password is set, in which case we can
- * get rid of the privacy parameter.
- *
* @param name the name of the channel.
* @param announcement a welcome message.
* @param password password (for private channels).
* @param privacy whether this channel is private.
*/
- ChatChannel(short id,
+ ChatChannel(int id,
const std::string &name,
- const std::string &announcement = "",
- const std::string &password = "",
- bool privacy = false);
+ const std::string &announcement = std::string(),
+ const std::string &password = std::string());
/**
* Get the ID of the channel.
*/
- short getId() const
+ int getId() const
{ return mId; }
/**
@@ -91,22 +86,25 @@ class ChatChannel
* Returns whether this channel is private.
*/
bool isPrivate() const
- { return mPrivate; }
+ { return !mPassword.empty(); }
/**
* Sets the name of the channel.
*/
- void setName(const std::string &channelName);
+ void setName(const std::string &channelName)
+ { mName = channelName; }
/**
* Sets the announcement string of the channel.
*/
- void setAnnouncement(const std::string &channelAnnouncement);
+ void setAnnouncement(const std::string &channelAnnouncement)
+ { mAnnouncement = channelAnnouncement; }
/**
* Sets the password of the channel.
*/
- void setPassword(const std::string &channelPassword);
+ void setPassword(const std::string &channelPassword)
+ { mPassword = channelPassword; }
/**
* Gets the list of the users registered in the channel.
@@ -119,14 +117,14 @@ class ChatChannel
*
* @return whether the user was successfully added
*/
- bool addUser(const std::string &name);
+ bool addUser(ChatClient *);
/**
* Removes a user from the channel.
*
* @return whether the user was successfully removed
*/
- bool removeUser(const std::string &name);
+ bool removeUser(ChatClient *);
/**
* Empties a channel from its users (admin included).
@@ -134,13 +132,11 @@ class ChatChannel
void removeAllUsers();
private:
- short mId; /**< The ID of the channel. */
+ unsigned short mId; /**< The ID of the channel. */
std::string mName; /**< The name of the channel. */
std::string mAnnouncement; /**< Welcome message. */
std::string mPassword; /**< The channel password. */
ChannelUsers mRegisteredUsers; /**< Users in this channel. */
-
- bool mPrivate; /**< Whether the channel is private. */
};
#endif
diff --git a/src/chat-server/chatchannelmanager.cpp b/src/chat-server/chatchannelmanager.cpp
index dbae5516..dd161976 100644
--- a/src/chat-server/chatchannelmanager.cpp
+++ b/src/chat-server/chatchannelmanager.cpp
@@ -25,6 +25,7 @@
#include "account-server/storage.hpp"
#include "chat-server/chatchannelmanager.hpp"
+#include "chat-server/chatclient.hpp"
ChatChannelManager::ChatChannelManager()
{
@@ -41,12 +42,12 @@ ChatChannelManager::~ChatChannelManager()
mChatChannels.clear();
}
-short
+int
ChatChannelManager::registerPublicChannel(const std::string &channelName,
const std::string &channelAnnouncement,
const std::string &channelPassword)
{
- short channelId = 1;
+ int channelId = 1;
for (ChatChannelIterator i = mChatChannels.begin(),
end = mChatChannels.end(); i != end; ++i)
{
@@ -56,14 +57,14 @@ ChatChannelManager::registerPublicChannel(const std::string &channelName,
// We seek the highest channelId in the public range
if (channelId <= i->first &&
- i->first < (signed) MAX_PUBLIC_CHANNELS_RANGE)
+ i->first < MAX_PUBLIC_CHANNELS_RANGE)
{
channelId = i->first + 1;
}
}
// Too much channels registered
- if (channelId >= (signed) MAX_PUBLIC_CHANNELS_RANGE)
+ if (channelId >= MAX_PUBLIC_CHANNELS_RANGE)
return 0;
// Register channel
@@ -71,18 +72,17 @@ ChatChannelManager::registerPublicChannel(const std::string &channelName,
ChatChannel(channelId,
channelName,
channelAnnouncement,
- channelPassword,
- false)));
+ channelPassword)));
return channelId;
}
-short
+int
ChatChannelManager::registerPrivateChannel(const std::string &channelName,
const std::string &channelAnnouncement,
const std::string &channelPassword)
{
- short channelId = MAX_PUBLIC_CHANNELS_RANGE;
+ int channelId = MAX_PUBLIC_CHANNELS_RANGE;
for (ChatChannelIterator i = mChatChannels.begin(),
end = mChatChannels.end(); i != end; ++i)
@@ -95,19 +95,18 @@ ChatChannelManager::registerPrivateChannel(const std::string &channelName,
}
// Too much channels registered
- if (channelId >= (signed) MAX_PRIVATE_CHANNELS_RANGE) return 0;
+ if (channelId >= MAX_PRIVATE_CHANNELS_RANGE) return 0;
// Register Channel
mChatChannels.insert(std::make_pair(channelId,
ChatChannel(channelId,
channelName,
channelAnnouncement,
- channelPassword,
- true)));
+ channelPassword)));
return channelId;
}
-bool ChatChannelManager::removeChannel(short channelId)
+bool ChatChannelManager::removeChannel(int channelId)
{
ChatChannelIterator i = mChatChannels.find(channelId);
if (i == mChatChannels.end()) return false;
@@ -133,7 +132,7 @@ std::list<const ChatChannel*> ChatChannelManager::getPublicChannels()
return channels;
}
-short ChatChannelManager::getChannelId(std::string const &channelName)
+int ChatChannelManager::getChannelId(std::string const &channelName)
{
for (ChatChannels::const_iterator i = mChatChannels.begin(),
i_end = mChatChannels.end();
@@ -144,24 +143,26 @@ short ChatChannelManager::getChannelId(std::string const &channelName)
return 0;
}
-ChatChannel* ChatChannelManager::getChannel(short channelId)
+ChatChannel* ChatChannelManager::getChannel(int channelId)
{
ChatChannelIterator i = mChatChannels.find(channelId);
if (i != mChatChannels.end()) return &i->second;
return NULL;
}
-void ChatChannelManager::removeUserFromAllChannels(const std::string &user)
+void ChatChannelManager::removeUserFromAllChannels(ChatClient *user)
{
- for (ChatChannelIterator i = mChatChannels.begin(),
- i_end = mChatChannels.end();
- i != i_end; ++i)
+ // Local copy as they will be destroyed under our feet.
+ std::vector<ChatChannel *> channels = user->channels;
+ // Reverse iterator to reduce load on vector operations.
+ for (std::vector<ChatChannel *>::const_reverse_iterator
+ i = channels.rbegin(), i_end = channels.rend(); i != i_end; ++i)
{
- i->second.removeUser(user);
+ (*i)->removeUser(user);
}
}
-bool ChatChannelManager::channelExists(short channelId)
+bool ChatChannelManager::channelExists(int channelId)
{
return mChatChannels.find(channelId) != mChatChannels.end();
}
diff --git a/src/chat-server/chatchannelmanager.hpp b/src/chat-server/chatchannelmanager.hpp
index eeca3d1e..fe11d68f 100644
--- a/src/chat-server/chatchannelmanager.hpp
+++ b/src/chat-server/chatchannelmanager.hpp
@@ -53,7 +53,7 @@ class ChatChannelManager
* @return the ID of the registered channel, or 0 if the registering
* was unsuccessful.
*/
- short registerPublicChannel(const std::string &channelName,
+ int registerPublicChannel(const std::string &channelName,
const std::string &channelAnnouncement,
const std::string &channelPassword);
@@ -69,14 +69,14 @@ class ChatChannelManager
* @return the ID of the registered channel, or 0 if the registering
* was unsuccessful.
*/
- short registerPrivateChannel(const std::string &channelName,
+ int registerPrivateChannel(const std::string &channelName,
const std::string &channelAnnouncement,
const std::string &channelPassword);
/**
* Remove a channel.
*/
- bool removeChannel(short channelId);
+ bool removeChannel(int channelId);
/**
* Returns a list containing all public channels.
@@ -90,31 +90,31 @@ class ChatChannelManager
*
* @return the id of the channel, 0 if it was unsuccessful.
*/
- short getChannelId(const std::string &channelName);
+ int getChannelId(const std::string &channelName);
/**
* Returns the chat channel with the given channel ID.
*
* @return The chat channel, or NULL when it doesn't exist.
*/
- ChatChannel* getChannel(short channelId);
+ ChatChannel* getChannel(int channelId);
/**
* Remove a user from all channels. Used at logout.
*
* @see ChatChannel::removeUserFromChannel
*/
- void removeUserFromAllChannels(std::string const &userName);
+ void removeUserFromAllChannels(ChatClient *);
/**
* Returns whether a channel exists.
*
* @param channelId a channel ID
*/
- bool channelExists(short channelId);
+ bool channelExists(int channelId);
private:
- typedef std::map<short, ChatChannel> ChatChannels;
+ typedef std::map<unsigned short, ChatChannel> ChatChannels;
typedef ChatChannels::iterator ChatChannelIterator;
/**
diff --git a/src/chat-server/chatclient.hpp b/src/chat-server/chatclient.hpp
index c9578a50..40622afe 100644
--- a/src/chat-server/chatclient.hpp
+++ b/src/chat-server/chatclient.hpp
@@ -24,8 +24,14 @@
#ifndef _TMWSERV_CHATCLIENT_H_
#define _TMWSERV_CHATCLIENT_H_
+#include <string>
+#include <vector>
+
+#include "defines.h"
#include "net/netcomputer.hpp"
+class ChatChannel;
+
/**
* A client connected to the chat server. Via this class, the chat server
* keeps track of the character name and account level of a client.
@@ -43,6 +49,7 @@ class ChatClient : public NetComputer
}
std::string characterName;
+ std::vector< ChatChannel * > channels;
AccountLevel accountLevel;
};
diff --git a/src/chat-server/chathandler.cpp b/src/chat-server/chathandler.cpp
index 8d64f223..d202dd99 100644
--- a/src/chat-server/chathandler.cpp
+++ b/src/chat-server/chathandler.cpp
@@ -104,7 +104,8 @@ NetComputer *ChatHandler::computerConnected(ENetPeer *peer)
void ChatHandler::computerDisconnected(NetComputer *computer)
{
// Remove user from all channels
- chatChannelManager->removeUserFromAllChannels(((ChatClient*)computer)->characterName);
+ chatChannelManager->
+ removeUserFromAllChannels(static_cast<ChatClient*>(computer));
ChatPendingClients::iterator i_end = pendingClients.end();
for (ChatPendingClients::iterator i = pendingClients.begin();
i != i_end; ++i)
@@ -152,7 +153,7 @@ void ChatHandler::processMessage(NetComputer *comp, MessageIn &message)
result.writeShort(CPMSG_CONNECT_RESPONSE);
result.writeByte(ERRMSG_OK);
computer.send(result);
- sendGuildRejoin(computer);
+ // sendGuildRejoin(computer);
return;
}
@@ -380,7 +381,7 @@ ChatHandler::handleRegisterChannelMessage(ChatClient &client, MessageIn &msg)
// update the password and the announcement in it and also to
// remove it.
ChatChannel *channel = chatChannelManager->getChannel(channelId);
- channel->addUser(client.characterName);
+ channel->addUser(&client);
reply.writeByte(ERRMSG_OK);
reply.writeShort(channelId);
@@ -456,7 +457,7 @@ ChatHandler::handleUnregisterChannelMessage(ChatClient &client, MessageIn &msg)
const ChatChannel::ChannelUsers &userList = channel->getUserList();
ChatChannel::ChannelUsers::const_iterator i = userList.begin();
- if (*i != client.characterName)
+ if (*i != &client)
{
reply.writeByte(ERRMSG_INSUFFICIENT_RIGHTS);
}
@@ -514,7 +515,7 @@ ChatHandler::handleEnterChannelMessage(ChatClient &client, MessageIn &msg)
}
else
{
- if (channel->addUser(client.characterName))
+ if (channel->addUser(&client))
{
// In the case of a guild, send user joined message.
if (guild)
@@ -534,7 +535,7 @@ ChatHandler::handleEnterChannelMessage(ChatClient &client, MessageIn &msg)
i_end = users.end();
i != i_end; ++i)
{
- reply.writeString(*i);
+ reply.writeString((*i)->characterName);
}
// Send an CPMSG_UPDATE_CHANNEL to warn other clients a user went
// in the channel.
@@ -563,7 +564,7 @@ ChatHandler::handleQuitChannelMessage(ChatClient &client, MessageIn &msg)
{
reply.writeByte(ERRMSG_INVALID_ARGUMENT);
}
- else if (!channel->removeUser(client.characterName))
+ else if (!channel->removeUser(&client))
{
reply.writeByte(ERRMSG_FAILURE);
}
@@ -632,12 +633,12 @@ ChatHandler::handleListChannelUsersMessage(ChatClient &client, MessageIn &msg)
if (channel)
{
- const ChatChannel::ChannelUsers &channelUsers = channel->getUserList();
+ const ChatChannel::ChannelUsers &users = channel->getUserList();
- // Add a user at a time
- for (unsigned int i = 0; i < channelUsers.size(); ++i)
+ for (ChatChannel::ChannelUsers::const_iterator
+ i = users.begin(), i_end = users.end(); i != i_end; ++i)
{
- reply.writeString(channelUsers[i]);
+ reply.writeString((*i)->characterName);
}
}
@@ -649,7 +650,7 @@ ChatHandler::handleDisconnectMessage(ChatClient &client, MessageIn &msg)
{
MessageOut reply(CPMSG_DISCONNECT_RESPONSE);
reply.writeByte(ERRMSG_OK);
- chatChannelManager->removeUserFromAllChannels(client.characterName);
+ chatChannelManager->removeUserFromAllChannels(&client);
client.send(reply);
}
@@ -689,15 +690,10 @@ void ChatHandler::sendInChannel(ChatChannel *channel, MessageOut &msg)
{
const ChatChannel::ChannelUsers &users = channel->getUserList();
- for (NetComputers::iterator i = clients.begin(), i_end = clients.end();
- i != i_end; ++i)
+ for (ChatChannel::ChannelUsers::const_iterator
+ i = users.begin(), i_end = users.end(); i != i_end; ++i)
{
- const std::string &name = static_cast<ChatClient*>(*i)->characterName;
- std::vector<std::string>::const_iterator j_end = users.end();
-
- // If the being is in the channel, send it
- if (std::find(users.begin(), j_end, name) != j_end)
- (*i)->send(msg);
+ (*i)->send(msg);
}
}
@@ -740,6 +736,7 @@ void ChatHandler::sendGuildInvite(const std::string &invitedName,
}
}
+#if 0
void ChatHandler::sendGuildRejoin(ChatClient &client)
{
// Get character based on name.
@@ -767,6 +764,7 @@ void ChatHandler::sendGuildRejoin(ChatClient &client)
serverHandler->enterChannel(guild->getName(), character.get());
}
}
+#endif
void ChatHandler::sendUserJoined(ChatChannel *channel, const std::string &name)
{