summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGuillaume Melquiond <guillaume.melquiond@gmail.com>2007-08-17 17:20:30 +0000
committerGuillaume Melquiond <guillaume.melquiond@gmail.com>2007-08-17 17:20:30 +0000
commitea118bf61623bcfae4b405d1bb2381b8d80d2837 (patch)
tree6ce388eb6ed9c15098980e5937f691ce4b5b816e /src
parentdf2091fd748f83d34543a61d05e44f617412d9c0 (diff)
downloadmanaserv-ea118bf61623bcfae4b405d1bb2381b8d80d2837.tar.gz
manaserv-ea118bf61623bcfae4b405d1bb2381b8d80d2837.tar.xz
manaserv-ea118bf61623bcfae4b405d1bb2381b8d80d2837.zip
Used TokenCollector to manage cookies in ChatHandler.
Diffstat (limited to 'src')
-rw-r--r--src/chat-server/chathandler.cpp125
-rw-r--r--src/chat-server/chathandler.hpp56
-rw-r--r--src/defines.h6
3 files changed, 83 insertions, 104 deletions
diff --git a/src/chat-server/chathandler.cpp b/src/chat-server/chathandler.cpp
index d202dd9..8710168 100644
--- a/src/chat-server/chathandler.cpp
+++ b/src/chat-server/chathandler.cpp
@@ -39,44 +39,19 @@
#include "utils/stringfilter.h"
#include "utils/tokendispenser.hpp"
-
-struct ChatPendingLogin
-{
- std::string character;
- AccountLevel level;
- int timeout;
-};
-
-typedef std::map< std::string, ChatPendingLogin > ChatPendingLogins;
-static ChatPendingLogins pendingLogins;
-
-typedef std::map< std::string, ChatClient * > ChatPendingClients;
-static ChatPendingClients pendingClients;
-
void registerChatClient(const std::string &token,
const std::string &name,
int level)
{
- ChatPendingClients::iterator i = pendingClients.find(token);
- if (i != pendingClients.end())
- {
- ChatClient *computer = i->second;
- computer->characterName = name;
- computer->accountLevel = (AccountLevel) level;
- pendingClients.erase(i);
- MessageOut result;
- result.writeShort(CPMSG_CONNECT_RESPONSE);
- result.writeByte(ERRMSG_OK);
- computer->send(result);
- }
- else
- {
- ChatPendingLogin p;
- p.character = name;
- p.level = (AccountLevel) level;
- p.timeout = 300; // world ticks
- pendingLogins.insert(std::make_pair(token, p));
- }
+ ChatHandler::Pending *p = new ChatHandler::Pending;
+ p->character = name;
+ p->level = (AccountLevel) level;
+ chatHandler->mTokenCollector.addPendingConnect(token, p);
+}
+
+ChatHandler::ChatHandler():
+ mTokenCollector(this)
+{
}
bool ChatHandler::startListen(enet_uint16 port)
@@ -85,15 +60,27 @@ bool ChatHandler::startListen(enet_uint16 port)
return ConnectionHandler::startListen(port);
}
-void ChatHandler::removeOutdatedPending()
+void ChatHandler::deletePendingClient(ChatClient *c)
{
- ChatPendingLogins::iterator i = pendingLogins.begin(), next;
- while (i != pendingLogins.end())
- {
- next = i; ++next;
- if (--i->second.timeout <= 0) pendingLogins.erase(i);
- i = next;
- }
+ MessageOut msg(GPMSG_CONNECTION_TIMEDOUT);
+
+ // The computer will be deleted when the disconnect event is processed
+ c->disconnect(msg);
+}
+
+void ChatHandler::deletePendingConnect(Pending *p)
+{
+ delete p;
+}
+
+void ChatHandler::tokenMatched(ChatClient *c, Pending *p)
+{
+ c->characterName = p->character;
+ c->accountLevel = p->level;
+ delete p;
+ MessageOut msg(CPMSG_CONNECT_RESPONSE);
+ msg.writeByte(ERRMSG_OK);
+ c->send(msg);
}
NetComputer *ChatHandler::computerConnected(ENetPeer *peer)
@@ -101,28 +88,22 @@ NetComputer *ChatHandler::computerConnected(ENetPeer *peer)
return new ChatClient(peer);
}
-void ChatHandler::computerDisconnected(NetComputer *computer)
+void ChatHandler::computerDisconnected(NetComputer *comp)
{
- // Remove user from all channels
- chatChannelManager->
- removeUserFromAllChannels(static_cast<ChatClient*>(computer));
- ChatPendingClients::iterator i_end = pendingClients.end();
- for (ChatPendingClients::iterator i = pendingClients.begin();
- i != i_end; ++i)
+ ChatClient *computer = static_cast< ChatClient * >(comp);
+
+ if (computer->characterName.empty())
{
- if (i->second == computer)
- {
- pendingClients.erase(i);
- break;
- }
+ // Not yet fully logged in, remove it from pending clients.
+ mTokenCollector.deletePendingClient(computer);
+ }
+ else
+ {
+ // Remove user from all channels.
+ chatChannelManager->removeUserFromAllChannels(computer);
}
- delete computer;
-}
-void ChatHandler::process(enet_uint32 timeout)
-{
- ConnectionHandler::process(timeout);
- removeOutdatedPending();
+ delete computer;
}
void ChatHandler::processMessage(NetComputer *comp, MessageIn &message)
@@ -133,26 +114,9 @@ void ChatHandler::processMessage(NetComputer *comp, MessageIn &message)
if (computer.characterName.empty())
{
if (message.getId() != PCMSG_CONNECT) return;
- std::string magic_token = message.readString(MAGIC_TOKEN_LENGTH);
- ChatPendingLogins::iterator i = pendingLogins.find(magic_token);
- if (i == pendingLogins.end())
- {
- ChatPendingClients::iterator i_end = pendingClients.end();
- for (ChatPendingClients::iterator i = pendingClients.begin();
- i != i_end; ++i)
- {
- if (i->second == &computer) return;
- }
- pendingClients.insert(std::make_pair(magic_token, &computer));
- return;
- }
- computer.characterName = i->second.character;
- computer.accountLevel = i->second.level;
- pendingLogins.erase(i);
- result.writeShort(CPMSG_CONNECT_RESPONSE);
- result.writeByte(ERRMSG_OK);
- computer.send(result);
+ std::string magic_token = message.readString(MAGIC_TOKEN_LENGTH);
+ mTokenCollector.addPendingClient(magic_token, &computer);
// sendGuildRejoin(computer);
return;
}
@@ -481,8 +445,7 @@ ChatHandler::handleUnregisterChannelMessage(ChatClient &client, MessageIn &msg)
client.send(reply);
}
- void
-ChatHandler::handleEnterChannelMessage(ChatClient &client, MessageIn &msg)
+void ChatHandler::handleEnterChannelMessage(ChatClient &client, MessageIn &msg)
{
MessageOut reply(CPMSG_ENTER_CHANNEL_RESPONSE);
diff --git a/src/chat-server/chathandler.hpp b/src/chat-server/chathandler.hpp
index 72f0ef3..43e7001 100644
--- a/src/chat-server/chathandler.hpp
+++ b/src/chat-server/chathandler.hpp
@@ -29,6 +29,7 @@
#include "net/connectionhandler.hpp"
class ChatClient;
+enum AccountLevel;
/**
* Manages chat related things like private messaging, chat channel handling
@@ -40,14 +41,19 @@ class ChatClient;
*/
class ChatHandler : public ConnectionHandler
{
- public:
+
/**
- * Overridden from ConnectionHandler to also clean connected clients
- * that haven't sent in a magic token.
- *
- * @see ConnectionHandler::process
+ * Data needed for initializing a ChatClient.
*/
- void process(enet_uint32 timeout = 0);
+ struct Pending
+ {
+ std::string character;
+ AccountLevel level;
+ };
+
+ public:
+
+ ChatHandler();
/**
* Start the handler.
@@ -78,6 +84,21 @@ class ChatHandler : public ConnectionHandler
const std::string &inviterName,
const std::string &guildName);
+ /**
+ * Called by TokenCollector when a client wrongly connected.
+ */
+ void deletePendingClient(ChatClient *);
+
+ /**
+ * Called by TokenCollector when a client failed to connect.
+ */
+ void deletePendingConnect(Pending *);
+
+ /**
+ * Called by TokenCollector when a client succesfully connected.
+ */
+ void tokenMatched(ChatClient *, Pending *);
+
protected:
/**
* Process chat related messages.
@@ -147,28 +168,14 @@ class ChatHandler : public ConnectionHandler
const std::string &text);
/**
- * Sends a message to every client in a registered channel. O(c*u),
- * where <b>c</b> is the amount of connected clients and <b>u</b> the
- * number of users in the given channel.
+ * Sends a message to every client in a registered channel.
*
* @param channel the channel to send the message in, must not be NULL
* @param msg the message to be sent
- *
- * @todo <b>b_lindeijer:</b> Currently this method is looping through
- * the channel users for each connected client in order to
- * determine whether it should receive the message. It would be
- * much better to directly associate the connected clients with
- * the channel.
*/
void sendInChannel(ChatChannel *channel, MessageOut &msg);
/**
- * Removes outdated pending logins. These are connected clients that
- * still haven't sent in their magic token.
- */
- void removeOutdatedPending();
-
- /**
* Send user joined message.
*
* @param channel the channel to send the message in, must not be NULL
@@ -183,6 +190,13 @@ class ChatHandler : public ConnectionHandler
* @param name the name of the user who left
*/
void sendUserLeft(ChatChannel *channel, const std::string &name);
+
+ /**
+ * Container for pending clients and pending connections.
+ */
+ TokenCollector<ChatHandler, ChatClient *, Pending *> mTokenCollector;
+ friend void registerChatClient(const std::string &, const std::string &, int);
+
};
/**
diff --git a/src/defines.h b/src/defines.h
index 4db9b08..5d82c86 100644
--- a/src/defines.h
+++ b/src/defines.h
@@ -36,13 +36,14 @@
* It may be better to wait and see what permissions we'd want to grant to or
* take from users, and then come up with a convenient way to handle that.
*/
-typedef enum {
+enum AccountLevel
+{
AL_NORMAL, // User has regular rights
AL_ADMIN, // User can perform administrator tasks
AL_GM, // User can perform a subset of administrator tasks
AL_BANNED, // This user is currently banned
AL_RESTRICTED // User rights have been restricted
-} AccountLevel;
+};
enum
{
@@ -138,6 +139,7 @@ enum {
APMSG_CONNECTION_TIMEDOUT = 0x0070, // -
GPMSG_CONNECTION_TIMEDOUT = 0x0071, // -
+ CPMSG_CONNECTION_TIMEDOUT = 0x0072, // -
// Game
GPMSG_PLAYER_MAP_CHANGE = 0x0100, // S filename, W x, W y