1 /* 2 * Copyright (C) 2001-2012 Jacek Sieka, arnetheduck on gmail point com 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 */ 18 19 #pragma once 20 21 #include "compiler.h" 22 #include "forward.h" 23 #include "User.h" 24 #include "Speaker.h" 25 #include "BufferedSocketListener.h" 26 #include "TimerManager.h" 27 #include "ClientListener.h" 28 #include "Atomic.h" 29 #include "SearchQueue.h" 30 31 #ifdef LUA_SCRIPT 32 #include "ScriptManager.h" 33 #endif 34 35 namespace dcpp { 36 #ifdef LUA_SCRIPT 37 struct ClientScriptInstance : public ScriptInstance { 38 bool onHubFrameEnter(Client* aClient, const string& aLine); 39 string formatChatMessage(const string& aLine); 40 }; 41 #endif 42 class ClientBase 43 { 44 public: 45 ClientBase()46 ClientBase() : type(DIRECT_CONNECT) { } 47 48 enum P2PType { DIRECT_CONNECT, DHT }; 49 P2PType type; getType()50 P2PType getType() const { return type; } 51 virtual const string& getHubUrl() const = 0; 52 virtual string getHubName() const = 0; 53 virtual bool isOp() const = 0; 54 virtual void connect(const OnlineUser& user, const string& token) = 0; 55 virtual void privateMessage(const OnlineUser& user, const string& aMessage, bool thirdPerson = false) = 0; 56 57 }; 58 /** Yes, this should probably be called a Hub */ 59 class Client : public ClientBase, public Speaker<ClientListener>, public BufferedSocketListener, protected TimerManagerListener 60 #ifdef LUA_SCRIPT 61 , public ClientScriptInstance 62 #endif 63 { 64 public: 65 typedef Client* Ptr; 66 typedef list<Ptr> List; 67 typedef List::iterator Iter; 68 69 virtual void connect(); 70 virtual void disconnect(bool graceless); 71 72 virtual void connect(const OnlineUser& user, const string& token) = 0; 73 virtual void hubMessage(const string& aMessage, bool thirdPerson = false) = 0; 74 virtual void privateMessage(const OnlineUser& user, const string& aMessage, bool thirdPerson = false) = 0; 75 virtual void sendUserCmd(const UserCommand& command, const StringMap& params) = 0; 76 77 uint64_t search(int aSizeMode, int64_t aSize, int aFileType, const string& aString, const string& aToken, const StringList& aExtList, void* owner); cancelSearch(void * aOwner)78 void cancelSearch(void* aOwner) { searchQueue.cancelSearch(aOwner); } 79 80 virtual void password(const string& pwd) = 0; 81 virtual void info(bool force) = 0; 82 83 virtual size_t getUserCount() const = 0; 84 virtual int64_t getAvailable() const = 0; getTotalCounts()85 static int getTotalCounts() { return counts.normal + counts.registered + counts.op; } 86 virtual void send(const AdcCommand& command) = 0; 87 escape(string const & str)88 virtual string escape(string const& str) const { return str; } 89 isConnected()90 bool isConnected() const { return state != STATE_DISCONNECTED; } isReady()91 bool isReady() const { return state != STATE_CONNECTING && state != STATE_DISCONNECTED; } 92 bool isSecure() const; 93 bool isTrusted() const; 94 std::string getCipherName() const; 95 vector<uint8_t> getKeyprint() const; 96 isOp()97 bool isOp() const { return getMyIdentity().isOp(); } 98 getPort()99 uint16_t getPort() const { return port; } getAddress()100 const string& getAddress() const { return address; } 101 getIp()102 const string& getIp() const { return ip; } getIpPort()103 string getIpPort() const { return getIp() + ':' + Util::toString(port); } 104 string getLocalIp() const; 105 updated(const OnlineUser & aUser)106 void updated(const OnlineUser& aUser) { fire(ClientListener::UserUpdated(), this, aUser); } 107 getCounts()108 static string getCounts() { 109 char buf[128]; 110 return string(buf, snprintf(buf, sizeof(buf), "%ld/%ld/%ld", 111 static_cast<long>(counts.normal), 112 static_cast<long>(counts.registered), 113 static_cast<long>(counts.op))); 114 } 115 escapeParams(StringMap & sm)116 StringMap& escapeParams(StringMap& sm) { 117 for(StringMapIter i = sm.begin(); i != sm.end(); ++i) { 118 i->second = escape(i->second); 119 } 120 return sm; 121 } setSearchInterval(uint32_t aInterval)122 void setSearchInterval(uint32_t aInterval) { 123 searchQueue.interval = (aInterval + min(aInterval, (uint32_t)1)) * (uint32_t)1000; 124 } 125 getSearchInterval()126 uint32_t getSearchInterval() const { 127 return searchQueue.interval; 128 } 129 130 void reconnect(); 131 void shutdown(); 132 bool isActive() const; send(const string & aMessage)133 void send(const string& aMessage) { send(aMessage.c_str(), aMessage.length()); } 134 void send(const char* aMessage, size_t aLen); 135 getMyNick()136 string getMyNick() const { return getMyIdentity().getNick(); } getHubName()137 string getHubName() const { return getHubIdentity().getNick().empty() ? getHubUrl() : getHubIdentity().getNick(); } getHubDescription()138 string getHubDescription() const { return getHubIdentity().getDescription(); } 139 getHubIdentity()140 Identity& getHubIdentity() { return hubIdentity; } 141 getHubUrl()142 const string& getHubUrl() const { return hubUrl; } 143 144 GETSET(Identity, myIdentity, MyIdentity); 145 GETSET(Identity, hubIdentity, HubIdentity); 146 147 GETSET(string, defpassword, Password); 148 GETSET(uint32_t, reconnDelay, ReconnDelay); 149 GETSET(uint64_t, lastActivity, LastActivity); 150 GETSET(bool, registered, Registered); 151 GETSET(bool, autoReconnect, AutoReconnect); 152 GETSET(string, encoding, Encoding); 153 GETSET(string, clientId, ClientId); 154 GETSET(string, currentNick, CurrentNick); 155 GETSET(string, currentDescription, CurrentDescription); 156 getFavIp()157 string getFavIp() const { return externalIP; } 158 159 /** Reload details from favmanager or settings */ 160 void reloadSettings(bool updateNick); 161 protected: 162 friend class ClientManager; 163 Client(const string& hubURL, char separator, bool secure_); 164 virtual ~Client(); 165 struct Counts { 166 private: 167 typedef Atomic<boost::int32_t> atomic_counter_t; 168 public: 169 typedef boost::int32_t value_type; normalCounts170 Counts(value_type n = 0, value_type r = 0, value_type o = 0) : normal(n), registered(r), op(o) { } 171 atomic_counter_t normal; 172 atomic_counter_t registered; 173 atomic_counter_t op; 174 }; 175 176 enum States { 177 STATE_CONNECTING, ///< Waiting for socket to connect 178 STATE_PROTOCOL, ///< Protocol setup 179 STATE_IDENTIFY, ///< Nick setup 180 STATE_VERIFY, ///< Checking password 181 STATE_NORMAL, ///< Running 182 STATE_DISCONNECTED ///< Nothing in particular 183 } state; 184 SearchQueue searchQueue; 185 BufferedSocket* sock; 186 187 static Counts counts; 188 Counts lastCounts; 189 190 void updateCounts(bool aRemove); updateActivity()191 void updateActivity() { lastActivity = GET_TICK(); } 192 193 virtual string checkNick(const string& nick) = 0; 194 virtual void search(int aSizeMode, int64_t aSize, int aFileType, const string& aString, const string& aToken, const StringList& aExtList) = 0; 195 196 // TimerManagerListener 197 virtual void on(Second, uint64_t aTick) noexcept; 198 // BufferedSocketListener on(Connecting)199 virtual void on(Connecting) noexcept { fire(ClientListener::Connecting(), this); } 200 virtual void on(Connected) noexcept; 201 virtual void on(Line, const string& aLine) noexcept; 202 virtual void on(Failed, const string&) noexcept; 203 204 private: 205 206 enum CountType { 207 COUNT_UNCOUNTED, 208 COUNT_NORMAL, 209 COUNT_REGISTERED, 210 COUNT_OP 211 }; 212 213 Client(const Client&); 214 Client& operator=(const Client&); 215 216 string hubUrl; 217 string address; 218 string ip; 219 string localIp; 220 string keyprint; 221 uint16_t port; 222 string externalIP; 223 char separator; 224 bool secure; 225 CountType countType; 226 }; 227 228 } // namespace dcpp 229