/** * client.h * Copyright (C) 2002 Daniel Karrels * Orlando Bassotto * * This program 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 (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. * * $Id: client.h,v 1.59 2005/09/29 17:40:06 kewlio Exp $ */ #ifndef __CLIENT_H #define __CLIENT_H "$Id: client.h,v 1.59 2005/09/29 17:40:06 kewlio Exp $" #include #include #include #include "NetworkTarget.h" #include "server.h" #include "iClient.h" #include "events.h" #include "TimerHandler.h" namespace gnuworld { /** * This is the public concrete base class that represents * a client that may connect to this server. To build a new * services client, simple subclass this class, inheriting * much functionality and state, and overloading a few * appropriate functions. * This has proven to be extremely easy: I built a functioning * services client in 11 minutes, though it didn't do much :) */ class xClient : public TimerHandler, public NetworkTarget { /// Let xServer access our protected members. friend class xServer ; /// Let xNetwork access our protected members. friend class xNetwork ; public: /** * Declare the type for the xClient's internal * mode representation. Note that this typedef * is deliberately public. */ typedef iClient::modeType modeType ; /** * Construct a new xClient from a config file. */ xClient( const std::string& ) ; /** * The primary purpose of this method is do call the * deallocation methods of any xClient's which are storing * data in the customDataMap. * Client responsibilities: * Removing all timers registered with the xServer * Removing all custom data members held in the iClient's */ virtual ~xClient() ; /** * This method must call xServer::BurstChannel() with appropriate * channel modes for any channel it wishes to own. */ virtual void BurstChannels() ; /** * BurstGlines is called before eob, for the client to burst * all of its glines */ virtual bool BurstGlines() ; /** * Kill will issue a KILL command to the network for * the given iClient (network generic client). */ virtual bool Kill( iClient*, const std::string& ) ; /** * QuoteAsServer will send data to the network as the * server itself. Try to avoid using this method. */ virtual bool QuoteAsServer( const std::string& Command ); /** * Write a string of data to the network. */ virtual bool Write( const std::string& s ) { return QuoteAsServer( s ) ; } /** * Write a string of data to the network. */ virtual bool Write( const std::stringstream& s ) { return QuoteAsServer( s.str() ) ; } /** * Write a variable length argument list to the network. */ virtual bool Write( const char*, ... ) ; /** * This method will change modes in a channel. * If the fourth argument is true, then the modes will be * changed as the server, otherwise the client will set * the modes (joining and parting the channel if necessary). * Removing mode 'k' expects an argument, but it doesn't matter * what the argument is. * Removing mode 'l' requires NO argument to be issued. */ virtual bool Mode( const std::string& chanName, const std::string& modes, const std::string& args, bool modeAsServer = false ) ; /** * This method will change modes in a channel. * If the fourth argument is true, then the modes will be * changed as the server, otherwise the client will set * the modes (joining and parting the channel if necessary). * Removing mode 'k' expects an argument, but it doesn't matter * what the argument is. * Removing mode 'l' requires NO argument to be issued. */ virtual bool Mode( Channel*, const std::string& modes, const std::string& args, bool modeAsServer = false ) ; /** * Mode is used to set the bot's modes. If connected to the * network already, these new modes will be written to the * network. */ virtual bool Mode( const std::string& Mode ) ; /** * Issue a clearmode (CM) for the given channel and update * all internal structures. * This method will also post a channel event for each * mode. */ virtual bool ClearMode( Channel* theChan, const std::string& modes, bool modeAsServer = false ) ; /** * OnConnect is called when the server connects to the * network, during burst time. The client's NICK * information has already been sent to the network. */ virtual void OnConnect() ; /** * Invoked when the uplink has been terminated. */ virtual void OnDisconnect() ; /** * This method is invoked when the server has been requested * to shutdown. If currently connected to the network, this * method gives xClient's a chance to gracefully QUIT from * the network, or whatever other processing is useful. * To force data to be written before final shutdown (again, * if connected), set xServer::FlushData(). * Timers will be executed after this method is invoked, once, * depending upon target time of course :) */ virtual void OnShutdown( const std::string& reason ) ; /** * Invoked after the client has been loaded, perform * initialization stuff here. */ virtual void OnAttach() ; /** * This method will be invoked when the server is unloading * the client for whatever reason. */ virtual void OnDetach( const std::string& = std::string( "Server Shutdown") ) ; /** * OnKill() is called when the client has been KILL'd. */ virtual void OnKill() ; /** * This method is called when a network client performs * a whois on this xClient. */ virtual void OnWhois( iClient* sourceClient, iClient* targetClient ) ; /** * This method is called when a network client invites * a services client to a channel. */ virtual void OnInvite( iClient* sourceClient, Channel* theChan ); /** * OnEvent is called when a network event occurs. * To receive a particular event, the client must * first register for that event with the xServer. */ virtual void OnEvent( const eventType& theEvent, void* Data1 = NULL, void* Data2 = NULL, void* Data3 = NULL, void* Data4 = NULL ) ; /** * OnChannelEvent is called when a requested channel * event occurs. */ virtual void OnChannelEvent( const channelEventType&, Channel*, void* Data1 = NULL, void* Data2 = NULL, void* Data3 = NULL, void* Data4 = NULL ) ; /** * This method is called when a kick occurs on a channel * for which this client is registered to receive events. * The srcClient may be NULL, as the ircu protocol still * allows servers to issue KICK commands. * The authoritative variable is true if the kick * transaction is complete, false otherwise. If it is false, * then the destClient is still on the channel pending * a PART from its server, and it is in the ZOMBIE state. */ virtual void OnNetworkKick( Channel* theChan, iClient* srcClient, // may be NULL iClient* destClient, const std::string& kickMessage, bool authoritative ) ; /** * This method is invoked when one or more "simple" (no argument) * channel modes are set or unset. * The ChannelUser* (source) user may be NULL if the modes * are being changed by a server. */ virtual void OnChannelMode( Channel*, ChannelUser*, const xServer::modeVectorType& ) ; /** * This method is invoked when a user sets or removes * channel mode l (limit). Keep in mind that the * source ChannelUser may be NULL if a server is * setting the mode. * If the mode is being removed, the limit argument * will be 0. */ virtual void OnChannelModeL( Channel*, bool polarity, ChannelUser*, const unsigned int& ) ; /** * This method is invoked when a user sets or removes * channel mode k (key). Keep in mind that the * source ChannelUser may be NULL if a server is * setting the mode. * If the mode is being removed, the key argument will * be empty. */ virtual void OnChannelModeK( Channel*, bool polarity, ChannelUser*, const std::string& ) ; /** * This method is invoked when a user sets or removes * channel mode A (Apass). Keep in mind that the * source ChannelUser may be NULL if a server is * setting the mode. * If the mode is being removed, the Apass argument will * be empty. */ virtual void OnChannelModeA( Channel*, bool polarity, ChannelUser*, const std::string& ) ; /** * This method is invoked when a user sets or removes * channel mode U (Upass). Keep in mind that the * source ChannelUser may be NULL if a server is * setting the mode. * If the mode is being removed, the Upass argument will * be empty. */ virtual void OnChannelModeU( Channel*, bool polarity, ChannelUser*, const std::string& ) ; /** * This method is invoked when a user sets or removes * one or more channel mode (o). Keep in mind that the * source ChannelUser may be NULL if a server is * setting the mode. */ virtual void OnChannelModeO( Channel*, ChannelUser*, const xServer::opVectorType& ) ; /** * This method is invoked when a user sets or removes * one or more channel mode (h). Keep in mind that the * source ChannelUser may be NULL if a server is * setting the mode. */ virtual void OnChannelModeH( Channel*, ChannelUser*, const xServer::opVectorType& ) ; /** * This method is invoked when a user sets or removes * one or more channel mode (v). Keep in mind that the * source ChannelUser may be NULL if a server is * setting the mode. */ virtual void OnChannelModeV( Channel*, ChannelUser*, const xServer::voiceVectorType& ) ; /** * This method is invoked when a user sets or removes * one or more channel mode (b). Keep in mind that the * source ChannelUser may be NULL if a server is * setting the mode. */ virtual void OnChannelModeB( Channel*, ChannelUser*, const xServer::banVectorType& ) ; /** * This method is called for each signal that occurs * in the system. There is no registration needed to * receive signals, just overload this method. Be * sure to end the method with a call to the base * class OnSignal (or the closest base class). */ virtual void OnSignal( int ) ; /** * OnCTCP is called when a CTCP command is issued to * the client. */ virtual void OnCTCP( iClient* Sender, const std::string& CTCP, const std::string& Message, bool Secure = false ) ; /** * OnFakeCTCP is called when a CTCP command is issued to * one of this xClient's fake clients. */ virtual void OnFakeCTCP( iClient* Sender, iClient* fakeClient, const std::string& CTCP, const std::string& Message, bool Secure = false ) ; /** * This method is called when a channel CTCP occurs * in a channel in which an xClient resides, and the * xClient is user mode -d. */ virtual void OnChannelCTCP( iClient* Sender, Channel* theChan, const std::string& CTCPCommand, const std::string& Message ) ; /** * This method is called when a channel CTCP occurs * in a channel in which an xClient resides, and the * xClient is user mode -d. */ virtual void OnFakeChannelCTCP( iClient* Sender, iClient* fakeClient, Channel* theChan, const std::string& CTCPCommand, const std::string& Message ) ; /** * OnPrivateMessage is called when a PRIVMSG command * is issued to the client. */ virtual void OnPrivateMessage( iClient* Sender, const std::string& Message, bool secure = false ) ; /** * Invoked when a private message arives for a fake client * owned by this xClient. */ virtual void OnFakePrivateMessage( iClient* Sender, iClient* Target, const std::string& Message, bool secure = false ) ; /** * This method is called when a channel message occurs * in a channel in which an xClient resides, and the * xClient is user mode -d. */ virtual void OnChannelMessage( iClient* Sender, Channel* theChan, const std::string& Message ) ; /** * Invoked when a fake client in a channel receives * a channel message. */ virtual void OnFakeChannelMessage( iClient* Sender, iClient* Target, Channel* theChan, const std::string& Message ) ; /** * OnPrivateNotice is called when a NOTICE command * is issued to the client. */ virtual void OnPrivateNotice( iClient* Sender, const std::string& Message, bool secure = false ) ; /** * Invoked when a private notice arives for a fake client * owned by this xClient. */ virtual void OnFakePrivateNotice( iClient* Sender, iClient* Target, const std::string& Message, bool secure = false ) ; /** * OnChannelNotice is called when a module receives * channel notice, and is mode -d. */ virtual void OnChannelNotice( iClient* Sender, Channel* theChan, const std::string& Message ) ; /** * Invoked when a fake client in a channel receives * a channel notice. */ virtual void OnFakeChannelNotice( iClient* Sender, iClient* Target, Channel* theChan, const std::string& Message ) ; /** * OnServerMessage is called when a server messages * a client. */ virtual void OnServerMessage( iServer* Sender, const std::string& Message, bool secure = false ) ; /** * Handle a timer event. The first argument is the * handle for the timer registration, and the second is * the arguments that were passed when registering the * timer. * This method overloads the pure virtual TimerHandler * base class method declaration. */ virtual void OnTimer( const xServer::timerID& , void* ) ; /** * A timer has been destroyed by the server (such as during * a shutdown). Perform cleanup for the timer here. */ virtual void OnTimerDestroy( xServer::timerID, void* ) ; /* Utility methods */ /** * Op a user on a channel, join/part the channel if necessary. */ virtual bool Op( Channel*, iClient* ) ; /** * Op one or more users on a channel, join/part the channel * if necessary. */ virtual bool Op( Channel*, const std::vector< iClient* >& ) ; /** * HalfOp a user on a channel, join/part the channel if necessary. */ virtual bool HalfOp( Channel*, iClient* ) ; /** * HalfOp one or more users on a channel, join/part the channel * if necessary. */ virtual bool HalfOp( Channel*, const std::vector< iClient* >& ) ; /** * Voice a user on a channel, join/part the channel if necessary. */ virtual bool Voice( Channel*, iClient* ) ; /** * Voice one or more users on a channel, join/part the channel * if necessary. */ virtual bool Voice( Channel*, const std::vector< iClient* >& ) ; /** * Deop a user on a channel, join/part the channel if necessary. */ virtual bool DeOp( Channel*, iClient* ) ; /** * Deop a user on a channel, join/part the channel if necessary. */ virtual bool DeOp( Channel*, const std::vector< iClient* >& ) ; /** * DeHalfOp a user on a channel, join/part the channel if necessary. */ virtual bool DeHalfOp( Channel*, iClient* ) ; /** * DeHalfOp one or more users on a channel, join/part the channel */ virtual bool DeHalfOp( Channel*, const std::vector< iClient* >& ) ; /** * Devoice a user on a channel, join/part the channel if necessary. */ virtual bool DeVoice( Channel*, iClient* ) ; /** * Devoice one or more users on a channel, join/part the channel * if necessary. */ virtual bool DeVoice( Channel*, const std::vector< iClient* >& ) ; /** * Set a ban on a channel, join/part the channel if necessary. */ virtual bool Ban( Channel*, iClient* ) ; /** * Set a ban on a channel, join/part the channel if necessary. */ virtual bool Ban( Channel*, const std::vector< iClient* >& ) ; /** * Ban kick a client from a channel for the given reason. */ virtual bool BanKick( Channel*, iClient*, const std::string& ) ; /** * Remove a channel ban. */ virtual bool UnBan( Channel*, const std::string& ) ; /** * Kick a user from a channel, join/part if necessary. */ virtual bool Kick( Channel*, iClient*, const std::string& ) ; /** * Kick several users from a channel, join/part if necessary. */ virtual bool Kick( Channel*, const std::vector< iClient* >&, const std::string& ) ; /** * Set the topic in a channel, joining, opping, and parting * the client if necessary. */ virtual bool Topic( Channel*, const std::string& ) ; /** * Join will cause the client to join a channel. */ virtual bool Join( const std::string& chanName, const std::string& modes = std::string(), const time_t& joinTime = 0, bool getOps = false ) ; /** * Join the given channel. */ virtual bool Join( Channel* theChan, const std::string& modes = std::string(), const time_t& joinTime = 0, bool getOps = false ) ; /** * This method is called when the bot joins a channel. */ virtual void OnJoin( Channel* ) ; /** * This method is called when the bot joins a channel. */ virtual void OnJoin( const std::string& ) ; /** * Part will cause the client to part a channel. */ virtual bool Part( const std::string&, const std::string& = std::string() ) ; /** * Part the given channel. */ virtual bool Part( Channel* ) ; /** * This method is called when the bot parts a channel. */ virtual void OnPart( Channel* ) ; /** * This method is called when the bot parts a channel. */ virtual void OnPart( const std::string& ) ; /** * Invite a user to a channel. Join the channel if necessary * (and then part). */ virtual bool Invite( iClient*, const std::string& ) ; /** * Invite a user to a channel. Join the channel if necessary * (and then part). */ virtual bool Invite( iClient*, Channel* ) ; /** * Return true if the bot is on the given channel. */ virtual bool isOnChannel( const std::string& chanName ) const ; /** * Return true if the bot is on the given channel. */ virtual bool isOnChannel( const Channel* theChan ) const ; /** * DoCTCP will issue a CTCP (reply) to the given iClient. */ virtual bool DoCTCP( iClient* Target, const std::string& CTCP, const std::string& Message ) ; /** * DoFakeCTCP will issue a CTCP (reply) to the given * iClient with a fake client interface. */ virtual bool DoFakeCTCP( const iClient* Target, const iClient* srcClient, const std::string& CTCP, const std::string& Message ) ; /** * Message will PRIVMSG a string of data to the given iClient. */ virtual bool Message( const iClient* Target, const char* Message, ... ) ; /** * Message an iClient with a fake client interface. */ virtual bool FakeMessage( const iClient* Target, const iClient* srcClient, const std::string& Message ) ; /** * Message a channel with a fake client interface. */ virtual bool FakeMessage( const Channel* theChan, const iClient* srcClient, const std::string& Message ) ; /** * Notice an iClient with a fake client interface. */ virtual bool FakeNotice( const iClient* Target, const iClient* srcClient, const std::string& Message ) ; /** * Notice a channel with a fake client interface. */ virtual bool FakeNotice( const Channel* theChan, const iClient* srcClient, const std::string& Message ) ; /** * Message will PRIVMSG a string of data to the given iClient. */ virtual bool Message( const iClient* Target, const std::string& Message ) ; /** * This format of Message will write a string of data * to a channel. */ virtual bool Message( const std::string& Channel, const char* Message, ... ) ; /** * This format of Message will write a string of data * to a channel. */ virtual bool Message( const std::string& Channel, const std::string& Message ) ; /** * This format of Message will write a string of data * to a channel. */ virtual bool Message( const Channel* theChan, const std::string& Message ) ; /** * Have this module message a channel. */ virtual bool Message( const Channel* theChan, const char* Format, ... ) ; /** * Notice will send a NOTICE command to the given iClient. */ virtual bool Notice( const iClient* Target, const char* Message, ... ) ; /** * Notice will send a NOTICE command to the given iClient. */ virtual bool Notice( const iClient* Target, const std::string& ) ; /** * This Notice() signature will send a channel NOTICE. */ virtual bool Notice( const std::string& Channel, const char* Message, ... ) ; /** * This Notice() signature will send a channel NOTICE. */ virtual bool Notice( const Channel* theChan, const char* Message, ... ) ; /** * This Notice() signature will send a channel NOTICE. */ virtual bool Notice( const Channel*, const std::string& ) ; /** * Notice channel operators with given message. */ virtual bool NoticeChannelOps( const Channel* theChan, const char* Message, ... ) ; /** * Notice channel operators with given message. */ virtual bool NoticeChannelOps( const std::string& chanName, const char* Message, ... ) ; /** * Have this bot send a global wallops message. */ virtual bool Wallops( const std::string& ) ; /** * Have this bot send a global wallops message. */ virtual bool Wallops( const char* Format, ... ) ; /** * Have the server send a wallops. */ virtual bool WallopsAsServer( const std::string& ) ; /** * Have the server send a wallops. */ virtual bool WallopsAsServer( const char* Format, ... ) ; /** * Return this xClient's network instance (iClient*). */ inline iClient* getInstance() const { return me ; } /** * Return this bot's nick name. */ inline const std::string& getNickName() const { return nickName ; } /** * Retrieve this bot's user name. */ inline const std::string& getUserName() const { return userName ; } /** * Retrieve this bot's host name. */ inline const std::string& getHostName() const { return hostName ; } /** * Retrieve this bot's description. */ inline const std::string& getDescription() const { return userDescription ; } /** * Retrieve this bot's uplink's numeric, integer format. */ unsigned int getUplinkIntYY() const { return MyUplink->getIntYY() ; } /** * Retrieve this bot's uplink's highest client count * numeric, integer format. */ inline unsigned int getUplinkIntXXX() const { return MyUplink->getIntXXX() ; } /** * Retrieve this bot's uplink's numeric, character * array format. */ inline const std::string getUplinkCharYY() const { return MyUplink->getCharYY() ; } /** * Retrieve this bot's uplink's client count numeric, * character array format. */ inline const std::string getUplinkCharXXX() const { return MyUplink->getCharXXX() ; } /** * Retrieve this bot's uplink's network numeric, * std::string format. */ inline const std::string getUplinkCharYYXXX() const { return MyUplink->getCharYYXXX() ; } /** * Retrieve this bot's uplink's server name. */ inline const std::string& getUplinkName() const { return MyUplink->getName() ; } /** * Retrieve this bot's uplink's description. */ inline const std::string& getUplinkDescription() const { return MyUplink->getDescription() ; } /** * Accessor method for the bot's user modes. */ virtual std::string getModes() const ; /** * Return true if an arbitrary mode is set, false otherwise. */ inline bool getMode( const modeType& whichMode ) const { return ((mode & whichMode) == whichMode) ; } /** * Obtain a pointer to the single xServer instance, which * is the uplink of every services bot. * Use of this method is discouraged. */ inline xServer* getUplink() const { return MyUplink ; } /** * Return the name of the configuration file from which this * client derived its configuration information. */ inline const std::string& getConfigFileName() const { return configFileName ; } /** * Return true if the server is connected to a network. */ inline bool isConnected() const { return (MyUplink && MyUplink->isConnected()) ; } /** * Utility method for outputting client information to * a gnuworld logging stream. */ friend ELog& operator<<( ELog& out, const xClient& theClient ) { out << theClient.nickName << '!' << theClient.userName << '@' << theClient.hostName << " Numeric: " << theClient.getCharYYXXX() << ", int YY/XXX/YYXXX: " << theClient.getIntYY() << '/' << theClient.getIntXXX() << '/' << theClient.getIntYYXXX() ; return out ; } protected: /** * Allow sub classes to call default constructor * This method is defined in the source file. */ xClient() ; /** * Disallow copying. * This method is declared, but NOT defined. */ xClient( const xClient& ) ; /** * Disallow default assignment. * This method is declared, but NOT defined. */ xClient operator=( const xClient& ) ; /** * This method is called by the xServer, and its purpose is * to reset its iClient instance. */ inline void resetInstance() { me = 0 ; } /** * This method is called to add a channel to the bot's * internal channel database; typically called from * OnJoin(). This is used to maintain the integrity * of isOnChannel() calls. */ virtual bool addChan( Channel* ) ; /** * This method is called to remove a channel from the * bot's internal database; typically called from OnPart(). * This is used to maintain the integrity of isOnChannel() * calls. */ virtual bool removeChan( Channel* ) ; /** * This method sets the iClient instance of this xClient. */ virtual void setInstance( iClient* me ) { this->me = me ; } /** * The iClient representation of this xClient. * This variable will be set by xNetwork once the * xClient links to the xServer. */ iClient* me ; /** * MyUplink is a pointer to the xServer to which this * client is attached. */ xServer *MyUplink ; /** * This bot's nick name. */ std::string nickName ; /** * This bot's user name. */ std::string userName ; /** * This bot's host name. */ std::string hostName ; /** * This bot's description. */ std::string userDescription ; /** * Connected is true when we are connected to an xServer. * It says nothing of whether the xServer is connected * to a network. */ bool Connected ; /** * This is the user mode of this client. */ modeType mode ; /** * The name of the config file from which this client read * its configuration information. */ std::string configFileName ; } ; } // namespace gnuworld #endif // __CLIENT_H