diff options
Diffstat (limited to 'src/utils/tokencollector.h')
-rw-r--r-- | src/utils/tokencollector.h | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/src/utils/tokencollector.h b/src/utils/tokencollector.h new file mode 100644 index 00000000..3d2b653d --- /dev/null +++ b/src/utils/tokencollector.h @@ -0,0 +1,138 @@ +/* + * The Mana Server + * Copyright (C) 2007-2010 The Mana World Development Team + * + * This file is part of The Mana Server. + * + * The Mana Server is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * The Mana Server is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with The Mana Server. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef TOKENCOLLECTOR_H +#define TOKENCOLLECTOR_H + +#include <string> +#include <list> +#include <time.h> + +/** + * Base class containing the generic implementation of TokenCollector. + */ +class TokenCollectorBase +{ + struct Item + { + std::string token; /**< Cookie used by the client. */ + intptr_t data; /**< User data. */ + time_t timeStamp; /**< Creation time. */ + }; + + /** + * List containing client already connected. Newer clients are at the + * back of the list. + */ + std::list<Item> mPendingClients; + + /** + * List containing server data waiting for clients. Newer data are at + * the back of the list. + */ + std::list<Item> mPendingConnects; + + /** + * Time at which the TokenCollector performed its last check. + */ + time_t mLastCheck; + + protected: + + virtual void removedClient(intptr_t) = 0; + virtual void removedConnect(intptr_t) = 0; + virtual void foundMatch(intptr_t client, intptr_t connect) = 0; + TokenCollectorBase(); + virtual ~TokenCollectorBase(); + void insertClient(const std::string &, intptr_t); + void removeClient(intptr_t); + void insertConnect(const std::string &, intptr_t); + void removeOutdated(time_t); +}; + +/** + * Compile-time check to ensure that Client and ServerData are simple enough + * for TokenCollector. + */ +template< class T > struct _TC_CheckData; +template<> struct _TC_CheckData< int > {}; +template< class T > struct _TC_CheckData< T * > {}; + +/** + * A class for storing and matching tokens. + * + * The Handler class must provide three member functions: + * - deletePendingClient(Client), + * - deletePendingConnect(ServerData), and + * - tokenMatched(Client, ServerData). + * + * The delete members will be called whenever the collector considers that a + * token has become obsolete and it is about to remove it. + */ +template< class Handler, class Client, class ServerData > +class TokenCollector: private TokenCollectorBase +{ + + public: + + TokenCollector(Handler *h): mHandler(h) + { + _TC_CheckData<Client> ClientMustBeSimple; + (void)&ClientMustBeSimple; + _TC_CheckData<ServerData> ServerDataMustBeSimple; + (void)&ServerDataMustBeSimple; + } + + /** + * Checks if the server expected this client token. If so, calls + * Handler::tokenMatched. Otherwise marks the client as pending. + */ + void addPendingClient(const std::string &token, Client data) + { insertClient(token, (intptr_t)data); } + + /** + * Checks if a client already registered this token. If so, calls + * Handler::tokenMatched. Otherwise marks the data as pending. + */ + void addPendingConnect(const std::string &token, ServerData data) + { insertConnect(token, (intptr_t)data); } + + /** + * Removes a pending client. + * @note Does not call destroyPendingClient. + */ + void deletePendingClient(Client data) + { removeClient((intptr_t)data); } + + private: + + void removedClient(intptr_t data) + { mHandler->deletePendingClient((Client)data); } + + void removedConnect(intptr_t data) + { mHandler->deletePendingConnect((ServerData)data); } + + void foundMatch(intptr_t client, intptr_t data) + { mHandler->tokenMatched((Client)client, (ServerData)data); } + + Handler *mHandler; +}; + +#endif // TOKENCOLLECTOR_H |