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 "TimerManager.h" 22 #include "Client.h" 23 #include "Singleton.h" 24 #include "SettingsManager.h" 25 #include "User.h" 26 #include "Socket.h" 27 #include "ClientManagerListener.h" 28 29 namespace dcpp { 30 31 class UserCommand; 32 33 class ClientManager : public Speaker<ClientManagerListener>, 34 private ClientListener, public Singleton<ClientManager>, 35 private TimerManagerListener 36 { 37 public: 38 Client* getClient(const string& aHubURL); 39 void putClient(Client* aClient); 40 41 size_t getUserCount() const; 42 int64_t getAvailable() const; 43 44 StringList getHubs(const CID& cid, const string& hintUrl); 45 StringList getHubNames(const CID& cid, const string& hintUrl); 46 StringList getNicks(const CID& cid, const string& hintUrl); 47 string getField(const CID& cid, const string& hintUrl, const char* field) const; 48 49 StringList getHubs(const CID& cid, const string& hintUrl, bool priv); 50 StringList getHubNames(const CID& cid, const string& hintUrl, bool priv); 51 StringList getNicks(const CID& cid, const string& hintUrl, bool priv); 52 getNicks(const HintedUser & user)53 StringList getNicks(const HintedUser& user) { return getNicks(user.user->getCID(), user.hint); } getHubNames(const HintedUser & user)54 StringList getHubNames(const HintedUser& user) { return getHubNames(user.user->getCID(), user.hint); } getHubs(const HintedUser & user)55 StringList getHubs(const HintedUser& user) { return getHubs(user.user->getCID(), user.hint); } 56 57 string getConnection(const CID& cid) const; 58 uint8_t getSlots(const CID& cid) const; 59 60 bool isConnected(const string& aUrl) const; 61 62 void search(int aSizeMode, int64_t aSize, int aFileType, const string& aString, const string& aToken, void* aOwner = 0); 63 uint64_t search(StringList& who, int aSizeMode, int64_t aSize, int aFileType, const string& aString, const string& aToken, const StringList& aExtList, void* aOwner = 0); 64 void cancelSearch(void* aOwner); 65 66 void infoUpdated(); 67 68 UserPtr getUser(const string& aNick, const string& aHubUrl) noexcept; 69 UserPtr getUser(const CID& cid) noexcept; 70 71 string findHub(const string& ipPort) const; 72 string findHubEncoding(const string& aUrl) const; 73 74 /** 75 * @param priv discard any user that doesn't match the hint. 76 * @return OnlineUser* found by CID and hint; might be only by CID if priv is false. 77 */ 78 OnlineUser* findOnlineUser(const HintedUser& user, bool priv); 79 OnlineUser* findOnlineUser(const CID& cid, const string& hintUrl, bool priv); 80 findUser(const string & aNick,const string & aHubUrl)81 UserPtr findUser(const string& aNick, const string& aHubUrl) const noexcept { return findUser(makeCid(aNick, aHubUrl)); } 82 UserPtr findUser(const CID& cid) const noexcept; 83 UserPtr findLegacyUser(const string& aNick) const noexcept; 84 isOnline(const UserPtr & aUser)85 bool isOnline(const UserPtr& aUser) const { 86 Lock l(cs); 87 return onlineUsers.find(aUser->getCID()) != onlineUsers.end(); 88 } 89 getOnlineUserIdentity(const UserPtr & aUser)90 Identity getOnlineUserIdentity(const UserPtr& aUser) const { 91 Lock l(cs); 92 OnlineMap::const_iterator i; 93 i=onlineUsers.find(aUser->getCID()); 94 if ( i != onlineUsers.end() ) 95 { 96 return i->second->getIdentity(); 97 } 98 return Identity(); 99 } 100 getBytesShared(const UserPtr & p)101 int64_t getBytesShared(const UserPtr& p) const{ 102 int64_t l_share = 0; 103 { 104 Lock l ( cs ); 105 OnlineIterC i = onlineUsers.find ( *const_cast<CID*> ( &p->getCID() ) ); 106 if ( i != onlineUsers.end() ) 107 l_share = i->second->getIdentity().getBytesShared(); 108 } 109 return l_share; 110 } 111 112 void setIPUser(const UserPtr& user, const string& IP, uint16_t udpPort = 0) { 113 if(IP.empty()) 114 return; 115 116 Lock l(cs); 117 OnlineMap::const_iterator i = onlineUsers.find(user->getCID()); 118 if ( i != onlineUsers.end() ) { 119 i->second->getIdentity().setIp(IP); 120 if(udpPort > 0) 121 i->second->getIdentity().setUdpPort(Util::toString(udpPort)); 122 } 123 } 124 125 bool isOp(const UserPtr& aUser, const string& aHubUrl) const; 126 127 /** Constructs a synthetic, hopefully unique CID */ 128 CID makeCid(const string& nick, const string& hubUrl) const noexcept; 129 130 void putOnline(OnlineUser* ou) noexcept; 131 void putOffline(OnlineUser* ou, bool disconnect = false) noexcept; 132 133 UserPtr& getMe(); 134 135 void send(AdcCommand& c, const CID& to); 136 void connect(const HintedUser& user, const string& token); 137 void privateMessage(const HintedUser& user, const string& msg, bool thirdPerson); 138 void userCommand(const HintedUser& user, const UserCommand& uc, StringMap& params, bool compatibility); 139 int getMode(const string& aHubUrl) const; 140 bool isActive(const string& aHubUrl = Util::emptyString) const { return getMode(aHubUrl) != SettingsManager::INCOMING_FIREWALL_PASSIVE; } 141 static bool ucExecuteLua(const string& cmd, StringMap& params) noexcept; 142 143 #ifdef DO_NOT_USE_MUTEX lock()144 void lock() noexcept { cs.lock(); } unlock()145 void unlock() noexcept { cs.unlock(); } 146 #else // DO_NOT_USE_MUTEX lock()147 Lock lock() { return Lock(cs); } 148 #endif // DO_NOT_USE_MUTEX 149 getClients()150 Client::List& getClients() { return clients; } 151 152 CID getMyCID(); 153 const CID& getMyPID(); 154 155 void loadUsers(); 156 void saveUsers() const; 157 void saveUser(const CID& cid); 158 #ifdef WITH_DHT 159 OnlineUserPtr findDHTNode(const CID& cid) const; 160 #endif 161 162 private: 163 typedef unordered_map<string, UserPtr> LegacyMap; 164 typedef LegacyMap::iterator LegacyIter; 165 166 typedef unordered_map<CID, UserPtr> UserMap; 167 typedef UserMap::iterator UserIter; 168 169 typedef std::pair<std::string, bool> NickMapEntry; // the boolean being true means "save this". 170 typedef unordered_map<CID, NickMapEntry> NickMap; 171 172 typedef unordered_multimap<CID, OnlineUser*> OnlineMap; 173 typedef OnlineMap::iterator OnlineIter; 174 typedef OnlineMap::const_iterator OnlineIterC; 175 typedef pair<OnlineIter, OnlineIter> OnlinePair; 176 typedef pair<OnlineIterC, OnlineIterC> OnlinePairC; 177 178 Client::List clients; 179 mutable CriticalSection cs; 180 181 UserMap users; 182 OnlineMap onlineUsers; 183 NickMap nicks; 184 185 UserPtr me; 186 187 Socket udp; 188 189 CID pid; 190 191 friend class Singleton<ClientManager>; 192 ClientManager()193 ClientManager() { 194 TimerManager::getInstance()->addListener(this); 195 } 196 ~ClientManager()197 virtual ~ClientManager() { 198 TimerManager::getInstance()->removeListener(this); 199 } 200 201 void updateNick(const OnlineUser& user) noexcept; 202 203 /// @return OnlineUser* found by CID and hint; discard any user that doesn't match the hint. findOnlineUserHint(const CID & cid,const string & hintUrl)204 OnlineUser* findOnlineUserHint(const CID& cid, const string& hintUrl) const { 205 OnlinePairC p; 206 return findOnlineUserHint(cid, hintUrl, p); 207 } 208 /** 209 * @param p OnlinePair of all the users found by CID, even those who don't match the hint. 210 * @return OnlineUser* found by CID and hint; discard any user that doesn't match the hint. 211 */ 212 OnlineUser* findOnlineUserHint(const CID& cid, const string& hintUrl, OnlinePairC& p) const; 213 getUsersFile()214 string getUsersFile() const { return Util::getPath(Util::PATH_USER_LOCAL) + "Users.xml"; } 215 216 // ClientListener 217 virtual void on(Connected, Client* c) noexcept; 218 virtual void on(UserUpdated, Client*, const OnlineUser& user) noexcept; 219 virtual void on(UsersUpdated, Client* c, const OnlineUserList&) noexcept; 220 virtual void on(Failed, Client*, const string&) noexcept; 221 virtual void on(HubUpdated, Client* c) noexcept; 222 virtual void on(HubUserCommand, Client*, int, int, const string&, const string&) noexcept; 223 virtual void on(NmdcSearch, Client* aClient, const string& aSeeker, int aSearchType, int64_t aSize, 224 int aFileType, const string& aString) noexcept; 225 virtual void on(AdcSearch, Client* c, const AdcCommand& adc, const CID& from) noexcept; 226 // TimerManagerListener 227 virtual void on(TimerManagerListener::Minute, uint64_t aTick) noexcept; 228 }; 229 230 } // namespace dcpp 231