From: <arn...@us...> - 2006-06-17 22:24:50
|
Revision: 617 Author: arnetheduck Date: 2006-06-17 15:24:01 -0700 (Sat, 17 Jun 2006) ViewCVS: http://svn.sourceforge.net/dcplusplus/?rev=617&view=rev Log Message: ----------- Partial commit, more to come in a few minutes Modified Paths: -------------- dcplusplus/trunk/Example.xml dcplusplus/trunk/changelog.txt dcplusplus/trunk/client/AdcHub.cpp dcplusplus/trunk/client/AdcHub.h dcplusplus/trunk/client/BufferedSocket.cpp dcplusplus/trunk/client/Client.cpp dcplusplus/trunk/client/Client.h dcplusplus/trunk/client/ClientManager.cpp dcplusplus/trunk/client/ClientManager.h dcplusplus/trunk/client/CryptoManager.cpp dcplusplus/trunk/client/CryptoManager.h dcplusplus/trunk/client/DCPlusPlus.cpp dcplusplus/trunk/client/FavoriteUser.h dcplusplus/trunk/client/NmdcHub.cpp dcplusplus/trunk/client/NmdcHub.h dcplusplus/trunk/client/QueueManager.cpp dcplusplus/trunk/client/SSLSocket.cpp dcplusplus/trunk/client/SSLSocket.h dcplusplus/trunk/client/SettingsManager.cpp dcplusplus/trunk/client/SettingsManager.h dcplusplus/trunk/client/StringDefs.cpp dcplusplus/trunk/client/StringDefs.h dcplusplus/trunk/client/User.cpp dcplusplus/trunk/client/User.h dcplusplus/trunk/client/Util.cpp dcplusplus/trunk/client/Util.h dcplusplus/trunk/windows/CommandDlg.cpp dcplusplus/trunk/windows/CommandDlg.h dcplusplus/trunk/windows/HubFrame.cpp dcplusplus/trunk/windows/MainFrm.cpp dcplusplus/trunk/windows/QueuePage.cpp dcplusplus/trunk/windows/UPnP.cpp dcplusplus/trunk/windows/UPnP.h Modified: dcplusplus/trunk/Example.xml =================================================================== --- dcplusplus/trunk/Example.xml 2006-06-17 15:40:35 UTC (rev 616) +++ dcplusplus/trunk/Example.xml 2006-06-17 22:24:01 UTC (rev 617) @@ -130,6 +130,7 @@ <String Name="File">File</String> <String Name="Files">Files</String> <String Name="FileHasNoTth">This file has no TTH</String> + <String Name="FileIsAlreadyQueued">This file is already queued</String> <String Name="FileListDiff">Subtract list</String> <String Name="FileListRefreshFailed">File list refresh failed: </String> <String Name="FileListRefreshFinished">File list refresh finished</String> @@ -406,6 +407,7 @@ <String Name="SettingsDefaultAwayMsg">Default away message</String> <String Name="SettingsDirect">Direct connection</String> <String Name="SettingsDirectories">Directories</String> + <String Name="SettingsDontDlAlreadyQueued">Don't download files already in the queue</String> <String Name="SettingsDontDlAlreadyShared">Don't download files already in share</String> <String Name="SettingsDownloadDirectory">Default download directory</String> <String Name="SettingsDownloadLimits">Limits</String> Modified: dcplusplus/trunk/changelog.txt =================================================================== --- dcplusplus/trunk/changelog.txt 2006-06-17 15:40:35 UTC (rev 616) +++ dcplusplus/trunk/changelog.txt 2006-06-17 22:24:01 UTC (rev 617) @@ -14,8 +14,11 @@ * [bug 959] Code cleanup (thanks pothead) * [bug 966] Max hash speed fixed when fast hashing method is not used (thanks steven sheehy) * [bug 967] Fixed path case-sensitivity issue (thanks steven sheehy) +* Fixed auto-reconnect +* [bug 936] Fixed duplicate entries in search hubs +* Fixed some hub title display issues +* Some code spring cleanup - -- 0.691 2006-06-03 -- * Links to bugzilla in html changelog * [bug 122] Added userlist filter (thanks trem) Modified: dcplusplus/trunk/client/AdcHub.cpp =================================================================== --- dcplusplus/trunk/client/AdcHub.cpp 2006-06-17 15:40:35 UTC (rev 616) +++ dcplusplus/trunk/client/AdcHub.cpp 2006-06-17 22:24:01 UTC (rev 617) @@ -29,7 +29,7 @@ #include "Util.h" #include "UserCommand.h" #include "FavoriteManager.h" -#include "SSLSocket.h" +#include "CryptoManager.h" const string AdcHub::CLIENT_PROTOCOL("ADC/0.10"); const string AdcHub::SECURE_CLIENT_PROTOCOL("ADCS/0.10"); @@ -453,8 +453,8 @@ ADDPARAM("ID", ClientManager::getInstance()->getMyCID().toBase32()); ADDPARAM("PD", ClientManager::getInstance()->getMyPID().toBase32()); - ADDPARAM("NI", getMyIdentity().getNick()); - ADDPARAM("DE", getMyIdentity().getDescription()); + ADDPARAM("NI", getCurrentNick()); + ADDPARAM("DE", getCurrentDescription()); ADDPARAM("SL", Util::toString(SETTING(SLOTS))); ADDPARAM("SS", ShareManager::getInstance()->getShareSizeString()); ADDPARAM("SF", Util::toString(ShareManager::getInstance()->getSharedFiles())); @@ -478,7 +478,7 @@ } string su; - if(SSLSocketFactory::getInstance()->hasCerts()) { + if(CryptoManager::getInstance()->hasCerts()) { su += ADCS_FEATURE + ","; } @@ -548,17 +548,6 @@ fire(ClientListener::Failed(), this, aLine); } -void AdcHub::on(TimerManagerListener::Second, u_int32_t aTick) throw() { - if(socket && (getLastActivity() + getReconnDelay() * 1000) < aTick) { - // Nothing's happened for ~120 seconds, check if we're connected, if not, try to connect... - if(!isConnected()) { - // Try to reconnect... - if(reconnect && !getAddress().empty()) - Client::connect(); - } - } -} - void AdcHub::send(const AdcCommand& cmd) { dcassert(socket); if(!socket) Modified: dcplusplus/trunk/client/AdcHub.h =================================================================== --- dcplusplus/trunk/client/AdcHub.h 2006-06-17 15:40:35 UTC (rev 616) +++ dcplusplus/trunk/client/AdcHub.h 2006-06-17 22:24:01 UTC (rev 617) @@ -30,7 +30,7 @@ class ClientManager; -class AdcHub : public Client, public CommandHandler<AdcHub>, private TimerManagerListener { +class AdcHub : public Client, public CommandHandler<AdcHub> { public: using Client::send; @@ -119,7 +119,6 @@ virtual void on(Connected) throw(); virtual void on(Line, const string& aLine) throw(); virtual void on(Failed, const string& aLine) throw(); - virtual void on(TimerManagerListener::Second, u_int32_t aTick) throw(); }; #endif // !defined(ADC_HUB_H) Modified: dcplusplus/trunk/client/BufferedSocket.cpp =================================================================== --- dcplusplus/trunk/client/BufferedSocket.cpp 2006-06-17 15:40:35 UTC (rev 616) +++ dcplusplus/trunk/client/BufferedSocket.cpp 2006-06-17 22:24:01 UTC (rev 617) @@ -27,6 +27,7 @@ #include "Streams.h" #include "SSLSocket.h" +#include "CryptoManager.h" // Polling is used for tasks...should be fixed... #define POLL_TIMEOUT 250 @@ -75,7 +76,7 @@ dcassert(!sock); dcdebug("BufferedSocket::accept() %p\n", (void*)this); - sock = secure ? SSLSocketFactory::getInstance()->getClientSocket() : new Socket; + sock = secure ? CryptoManager::getInstance()->getClientSocket() : new Socket; sock->accept(srv); if(SETTING(SOCKET_IN_BUFFER) > 0) @@ -103,7 +104,7 @@ dcassert(!sock); dcdebug("BufferedSocket::connect() %p\n", (void*)this); - sock = secure ? SSLSocketFactory::getInstance()->getClientSocket() : new Socket; + sock = secure ? CryptoManager::getInstance()->getClientSocket() : new Socket; sock->create(); if(SETTING(SOCKET_IN_BUFFER) >= 1024) Modified: dcplusplus/trunk/client/Client.cpp =================================================================== --- dcplusplus/trunk/client/Client.cpp 2006-06-17 15:40:35 UTC (rev 616) +++ dcplusplus/trunk/client/Client.cpp 2006-06-17 22:24:01 UTC (rev 617) @@ -29,20 +29,31 @@ Client::Counts Client::counts; Client::Client(const string& hubURL, char separator_, bool secure_) : - reconnDelay(120), lastActivity(0), registered(false), socket(NULL), + myIdentity(ClientManager::getInstance()->getMe(), 0), + reconnDelay(120), lastActivity(GET_TICK()), registered(false), autoReconnect(true), socket(0), hubUrl(hubURL), port(0), separator(separator_), secure(secure_), countType(COUNT_UNCOUNTED) { string file; Util::decodeUrl(hubURL, address, port, file); + + TimerManager::getInstance()->addListener(this); } Client::~Client() throw() { dcassert(!socket); + TimerManager::getInstance()->removeListener(this); updateCounts(true); } +void Client::reconnect() { + disconnect(true); + setAutoReconnect(true); + resetActivtiy(); +} + void Client::shutdown() { + if(socket) { BufferedSocket::putSocket(socket); socket = 0; @@ -52,29 +63,32 @@ void Client::reloadSettings(bool updateNick) { FavoriteHubEntry* hub = FavoriteManager::getInstance()->getFavoriteHubEntry(getHubUrl()); if(hub) { - if(updateNick) - getMyIdentity().setNick(checkNick(hub->getNick(true))); + if(updateNick) { + setCurrentNick(checkNick(hub->getNick(true))); + } + if(!hub->getUserDescription().empty()) { - getMyIdentity().setDescription(hub->getUserDescription()); + setCurrentDescription(hub->getUserDescription()); } else { - getMyIdentity().setDescription(SETTING(DESCRIPTION)); + setCurrentDescription(SETTING(DESCRIPTION)); } setPassword(hub->getPassword()); } else { - getMyIdentity().setNick(checkNick(SETTING(NICK))); - getMyIdentity().setDescription(SETTING(DESCRIPTION)); + setCurrentNick(checkNick(SETTING(NICK))); + setCurrentDescription(SETTING(DESCRIPTION)); } - getMyIdentity().setUser(ClientManager::getInstance()->getMe()); - getMyIdentity().setHubUrl(getHubUrl()); } void Client::connect() { if(socket) BufferedSocket::putSocket(socket); + setAutoReconnect(true); setReconnDelay(120 + Util::rand(0, 60)); reloadSettings(true); setRegistered(false); + setMyIdentity(Identity()); + setHubIdentity(Identity()); try { socket = BufferedSocket::getSocket(separator); @@ -97,10 +111,6 @@ socket->disconnect(graceLess); } -void Client::updateActivity() { - lastActivity = GET_TICK(); -} - void Client::updateCounts(bool aRemove) { // We always remove the count and then add the correct one if requested... if(countType == COUNT_NORMAL) { @@ -117,7 +127,7 @@ if(getMyIdentity().isOp()) { Thread::safeInc(counts.op); countType = COUNT_OP; - } else if(registered) { + } else if(getMyIdentity().isRegistered()) { Thread::safeInc(counts.registered); countType = COUNT_REGISTERED; } else { @@ -145,3 +155,10 @@ return Util::getLocalIp(); return lip; } + +void Client::on(Second, u_int32_t aTick) throw() { + if(getAutoReconnect() && !isConnected() && (getLastActivity() + getReconnDelay() * 1000) < aTick) { + // Try to reconnect... + connect(); + } +} Modified: dcplusplus/trunk/client/Client.h =================================================================== --- dcplusplus/trunk/client/Client.h 2006-06-17 15:40:35 UTC (rev 616) +++ dcplusplus/trunk/client/Client.h 2006-06-17 22:24:01 UTC (rev 617) @@ -26,6 +26,7 @@ #include "User.h" #include "BufferedSocket.h" #include "SettingsManager.h" +#include "TimerManager.h" class Client; class AdcCommand; @@ -77,7 +78,7 @@ }; /** Yes, this should probably be called a Hub */ -class Client : public Speaker<ClientListener>, public BufferedSocketListener { +class Client : public Speaker<ClientListener>, public BufferedSocketListener, protected TimerManagerListener { public: typedef Client* Ptr; typedef list<Ptr> List; @@ -125,6 +126,8 @@ return sm; } + void reconnect(); + void shutdown(); void send(const string& aMessage) { send(aMessage.c_str(), aMessage.length()); } @@ -140,7 +143,6 @@ const string& getHubName() const { return getHubIdentity().getNick().empty() ? getHubUrl() : getHubIdentity().getNick(); } const string& getHubDescription() const { return getHubIdentity().getDescription(); } - Identity& getMyIdentity() { return myIdentity; } Identity& getHubIdentity() { return hubIdentity; } const string& getHubUrl() const { return hubUrl; } @@ -152,7 +154,10 @@ GETSET(u_int32_t, reconnDelay, ReconnDelay); GETSET(u_int32_t, lastActivity, LastActivity); GETSET(bool, registered, Registered); + GETSET(bool, autoReconnect, AutoReconnect); + GETSET(string, currentNick, CurrentNick); + GETSET(string, currentDescription, CurrentDescription); protected: friend class ClientManager; Client(const string& hubURL, char separator, bool secure_); @@ -171,13 +176,17 @@ Counts lastCounts; void updateCounts(bool aRemove); - void updateActivity(); + void updateActivity() { lastActivity = GET_TICK(); } + void resetActivtiy() { lastActivity = 0; } /** Reload details from favmanager or settings */ void reloadSettings(bool updateNick); virtual string checkNick(const string& nick) = 0; + // TimerManagerListener + virtual void on(Second, u_int32_t aTick) throw(); + private: enum CountType { @@ -196,12 +205,13 @@ u_int16_t port; char separator; bool secure; - CountType countType; // BufferedSocketListener virtual void on(Connecting) throw() { fire(ClientListener::Connecting(), this); } virtual void on(Connected) throw() { updateActivity(); ip = socket->getIp(); fire(ClientListener::Connected(), this); } + + }; #endif // !defined(CLIENT_H) Modified: dcplusplus/trunk/client/ClientManager.cpp =================================================================== --- dcplusplus/trunk/client/ClientManager.cpp 2006-06-17 15:40:35 UTC (rev 616) +++ dcplusplus/trunk/client/ClientManager.cpp 2006-06-17 22:24:01 UTC (rev 617) @@ -405,14 +405,6 @@ SearchManager::getInstance()->respond(adc, from); } -Identity ClientManager::getIdentity(const User::Ptr& aUser) { - OnlineIter i = onlineUsers.find(aUser->getCID()); - if(i != onlineUsers.end()) { - return i->second->getIdentity(); - } - return Identity(aUser, Util::emptyString, 0); -} - void ClientManager::search(int aSizeMode, int64_t aSize, int aFileType, const string& aString, const string& aToken) { Lock l(cs); Modified: dcplusplus/trunk/client/ClientManager.h =================================================================== --- dcplusplus/trunk/client/ClientManager.h 2006-06-17 15:40:35 UTC (rev 616) +++ dcplusplus/trunk/client/ClientManager.h 2006-06-17 22:24:01 UTC (rev 617) @@ -89,8 +89,6 @@ void lock() throw() { cs.enter(); } void unlock() throw() { cs.leave(); } - Identity getIdentity(const User::Ptr& aUser); - Client::List& getClients() { return clients; } string getCachedIp() const { Lock l(cs); return cachedIp; } Modified: dcplusplus/trunk/client/CryptoManager.cpp =================================================================== --- dcplusplus/trunk/client/CryptoManager.cpp 2006-06-17 15:40:35 UTC (rev 616) +++ dcplusplus/trunk/client/CryptoManager.cpp 2006-06-17 22:24:01 UTC (rev 617) @@ -24,13 +24,118 @@ #include "BitInputStream.h" #include "BitOutputStream.h" #include "ResourceManager.h" +#include "LogManager.h" +#include <openssl/ssl.h> + #ifdef _WIN32 #include "../bzip2/bzlib.h" #else #include <bzlib.h> #endif +CryptoManager::CryptoManager() +: + clientContext(SSL_CTX_new(TLSv1_client_method())), + serverContext(SSL_CTX_new(TLSv1_server_method())), + dh(DH_new()), + certsLoaded(false), + lock("EXTENDEDPROTOCOLABCABCABCABCABCABC"), + pk("DCPLUSPLUS" VERSIONSTRING "ABCABC") +{ + static unsigned char dh512_p[] = + { + 0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75, + 0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F, + 0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3, + 0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12, + 0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C, + 0x47,0x74,0xE8,0x33, + }; + + static unsigned char dh512_g[] = + { + 0x02, + }; + + if(dh) { + dh->p = BN_bin2bn(dh512_p, sizeof(dh512_p), 0); + dh->g = BN_bin2bn(dh512_g, sizeof(dh512_g), 0); + + if (!dh->p || !dh->g) { + DH_free(dh); + dh = 0; + } else { + SSL_CTX_set_tmp_dh(serverContext, dh); + } + } +} + +CryptoManager::~CryptoManager() { + if(serverContext) + SSL_CTX_free(serverContext); + if(clientContext) + SSL_CTX_free(clientContext); + if(dh) + DH_free(dh); +} + + +void CryptoManager::loadCertificates() throw() { + SSL_CTX_set_verify(serverContext, SSL_VERIFY_NONE, 0); + SSL_CTX_set_verify(clientContext, SSL_VERIFY_NONE, 0); + + if(!SETTING(SSL_CERTIFICATE_FILE).empty()) { + if(SSL_CTX_use_certificate_file(serverContext, SETTING(SSL_CERTIFICATE_FILE).c_str(), SSL_FILETYPE_PEM) != SSL_SUCCESS) { + LogManager::getInstance()->message("Failed to load certificate file"); + return; + } + if(SSL_CTX_use_certificate_file(clientContext, SETTING(SSL_CERTIFICATE_FILE).c_str(), SSL_FILETYPE_PEM) != SSL_SUCCESS) { + LogManager::getInstance()->message("Failed to load certificate file"); + return; + } + } + + if(!SETTING(SSL_PRIVATE_KEY_FILE).empty()) { + if(SSL_CTX_use_PrivateKey_file(serverContext, SETTING(SSL_PRIVATE_KEY_FILE).c_str(), SSL_FILETYPE_PEM) != SSL_SUCCESS) { + LogManager::getInstance()->message("Failed to load private key"); + return; + } + if(SSL_CTX_use_PrivateKey_file(clientContext, SETTING(SSL_PRIVATE_KEY_FILE).c_str(), SSL_FILETYPE_PEM) != SSL_SUCCESS) { + LogManager::getInstance()->message("Failed to load private key"); + return; + } + } + +#ifdef _WIN32 + WIN32_FIND_DATA data; + HANDLE hFind; + + hFind = FindFirstFile(Text::toT(SETTING(SSL_TRUSTED_CERTIFICATES_PATH) + "*.pem").c_str(), &data); + if(hFind != INVALID_HANDLE_VALUE) { + do { + if(SSL_CTX_load_verify_locations(clientContext, (SETTING(SSL_TRUSTED_CERTIFICATES_PATH) + Text::fromT(data.cFileName)).c_str(), NULL) != SSL_SUCCESS) { + LogManager::getInstance()->message("Failed to load trusted certificate from " + Text::fromT(data.cFileName)); + } + } while(FindNextFile(hFind, &data)); + + FindClose(hFind); + } +#else +#error todo +#endif + certsLoaded = true; +} + + +SSLSocket* CryptoManager::getClientSocket() throw(SocketException) { + return new SSLSocket(clientContext); +} +SSLSocket* CryptoManager::getServerSocket() throw(SocketException) { + return new SSLSocket(serverContext); +} + + void CryptoManager::decodeBZ2(const u_int8_t* is, size_t sz, string& os) throw (CryptoException) { bz_stream bs = { 0 }; Modified: dcplusplus/trunk/client/CryptoManager.h =================================================================== --- dcplusplus/trunk/client/CryptoManager.h 2006-06-17 15:40:35 UTC (rev 616) +++ dcplusplus/trunk/client/CryptoManager.h 2006-06-17 22:24:01 UTC (rev 617) @@ -29,6 +29,7 @@ #include "Singleton.h" #include "FastAlloc.h" #include "version.h" +#include "SSLSocket.h" STANDARD_EXCEPTION(CryptoException); @@ -79,12 +80,18 @@ void decodeHuffman(const u_int8_t* /*is*/, string& /*os*/, const size_t /*len*/) throw(CryptoException); void decodeBZ2(const u_int8_t* is, size_t sz, string& os) throw(CryptoException); + + SSLSocket* getClientSocket() throw(SocketException); + SSLSocket* getServerSocket() throw(SocketException); + + void loadCertificates() throw(); + bool hasCerts() const { return certsLoaded; } private: friend class Singleton<CryptoManager>; - CryptoManager() : lock("EXTENDEDPROTOCOLABCABCABCABCABCABC"), pk("DCPLUSPLUS" VERSIONSTRING "ABCABC") { } - virtual ~CryptoManager() { } + CryptoManager(); + virtual ~CryptoManager(); class Leaf : public FastAlloc<Leaf> { public: @@ -108,6 +115,11 @@ } }; + SSL_CTX* clientContext; + SSL_CTX* serverContext; + DH* dh; + bool certsLoaded; + const string lock; const string pk; Modified: dcplusplus/trunk/client/DCPlusPlus.cpp =================================================================== --- dcplusplus/trunk/client/DCPlusPlus.cpp 2006-06-17 15:40:35 UTC (rev 616) +++ dcplusplus/trunk/client/DCPlusPlus.cpp 2006-06-17 22:24:01 UTC (rev 617) @@ -33,7 +33,6 @@ #include "SettingsManager.h" #include "FinishedManager.h" #include "ADLSearch.h" -#include "SSLSocket.h" #include "StringTokenizer.h" @@ -61,7 +60,6 @@ QueueManager::newInstance(); FinishedManager::newInstance(); ADLSearchManager::newInstance(); - SSLSocketFactory::newInstance(); SettingsManager::getInstance()->load(); @@ -70,7 +68,7 @@ } FavoriteManager::getInstance()->load(); - SSLSocketFactory::getInstance()->loadCertificates(); + CryptoManager::getInstance()->loadCertificates(); if(f != NULL) (*f)(p, STRING(HASH_DATABASE)); @@ -93,7 +91,6 @@ SettingsManager::getInstance()->save(); - SSLSocketFactory::deleteInstance(); ADLSearchManager::deleteInstance(); FinishedManager::deleteInstance(); ShareManager::deleteInstance(); Modified: dcplusplus/trunk/client/FavoriteUser.h =================================================================== --- dcplusplus/trunk/client/FavoriteUser.h 2006-06-17 15:40:35 UTC (rev 616) +++ dcplusplus/trunk/client/FavoriteUser.h 2006-06-17 22:24:01 UTC (rev 617) @@ -37,7 +37,7 @@ User::Ptr& getUser() { return user; } - void update(const OnlineUser& info) { setNick(info.getIdentity().getNick()); setUrl(info.getIdentity().getHubUrl()); } + void update(const OnlineUser& info); GETSET(User::Ptr, user, User); GETSET(string, nick, Nick); Modified: dcplusplus/trunk/client/NmdcHub.cpp =================================================================== --- dcplusplus/trunk/client/NmdcHub.cpp 2006-06-17 15:40:35 UTC (rev 616) +++ dcplusplus/trunk/client/NmdcHub.cpp 2006-06-17 22:24:01 UTC (rev 617) @@ -33,18 +33,15 @@ #include "StringTokenizer.h" NmdcHub::NmdcHub(const string& aHubURL) : Client(aHubURL, '|', false), supportFlags(0), state(STATE_CONNECT), - reconnect(true), lastUpdate(0) + lastUpdate(0) { - TimerManager::getInstance()->addListener(this); } NmdcHub::~NmdcHub() throw() { - TimerManager::getInstance()->removeListener(this); clearUsers(); } void NmdcHub::connect() { - reconnect = true; supportFlags = 0; lastMyInfoA.clear(); lastMyInfoB.clear(); @@ -89,8 +86,6 @@ User::Ptr p; if(aNick == getMyNick()) { p = ClientManager::getInstance()->getMe(); - getMyIdentity().setUser(p); - getMyIdentity().setHubUrl(getHubUrl()); } else { p = ClientManager::getInstance()->getUser(aNick, getHubUrl()); } @@ -99,6 +94,9 @@ Lock l(cs); u = users.insert(make_pair(aNick, new OnlineUser(p, *this, 0))).first->second; u->getIdentity().setNick(aNick); + if(u->getUser() == getMyIdentity().getUser()) { + setMyIdentity(u->getIdentity()); + } } ClientManager::getInstance()->putOnline(*u); @@ -190,12 +188,12 @@ // Check if we're being banned... if(state != STATE_CONNECTED) { if(Util::findSubString(aLine, "banned") != string::npos) { - reconnect = false; + setAutoReconnect(false); } } - string line = fromNmdc(aLine); + string line = fromAcp(aLine); // @todo Decrypt who the message is from... - fire(ClientListener::StatusMessage(), this, Util::validateMessage(fromNmdc(aLine), true)); + fire(ClientListener::StatusMessage(), this, unescape(fromAcp(aLine))); return; } @@ -207,7 +205,7 @@ cmd = aLine; } else { cmd = aLine.substr(0, x); - param = fromNmdc(aLine.substr(x+1)); + param = fromAcp(aLine.substr(x+1)); } if(cmd == "$Search") { @@ -321,7 +319,7 @@ if(j == string::npos) return; - string tmpDesc = Util::validateMessage(param.substr(i, j-i), true); + string tmpDesc = unescape(param.substr(i, j-i)); // Look for a tag... if(tmpDesc.size() > 0 && tmpDesc[tmpDesc.size()-1] == '>') { x = tmpDesc.rfind('<'); @@ -353,7 +351,7 @@ if(j == string::npos) return; - u.getIdentity().setEmail(Util::validateMessage(param.substr(i, j-i), true)); + u.getIdentity().setEmail(unescape(param.substr(i, j-i)); i = j + 1; j = param.find('$', i); @@ -361,8 +359,9 @@ return; u.getIdentity().setBytesShared(param.substr(i, j-i)); - if(u.getUser() == getMyIdentity().getUser()) + if(u.getUser() == getMyIdentity().getUser()) { setMyIdentity(u.getIdentity()); + } fire(ClientListener::UserUpdated(), this, u); } else if(cmd == "$Quit") { @@ -428,11 +427,11 @@ // Hack - first word goes to hub name, rest to description string::size_type i = param.find(' '); if(i == string::npos) { - getHubIdentity().setNick(param); + getHubIdentity().setNick(unescape(param)); getHubIdentity().setDescription(Util::emptyString); } else { - getHubIdentity().setNick(param.substr(0, i)); - getHubIdentity().setDescription(param.substr(i+1)); + getHubIdentity().setNick(unescape(param.substr(0, i))); + getHubIdentity().setDescription(unescape(param.substr(i+1))); } fire(ClientListener::HubUpdated(), this); } else if(cmd == "$Supports") { @@ -470,7 +469,7 @@ string name = param.substr(i, j-i); i = j+1; string command = param.substr(i, param.length() - i); - fire(ClientListener::UserCommand(), this, type, ctx, Util::validateMessage(name, true, false), Util::validateMessage(command, true, false)); + fire(ClientListener::UserCommand(), this, type, ctx, unescape(name), unescape(command)); } } else if(cmd == "$Lock") { if(state != STATE_LOCK) { @@ -478,7 +477,7 @@ } state = STATE_HELLO; - // Param must not be fromNmdc'd... + // Param must not be fromAcp'd... param = aLine.substr(6); if(!param.empty()) { @@ -562,6 +561,9 @@ continue; u->getIdentity().setIp(it->substr(j+1)); + if(u->getUser() == getMyIdentity().getUser()) { + setMyIdentity(u->getIdentity()); + } v.push_back(u); } @@ -584,10 +586,10 @@ string tmp; // Let's assume 10 characters per nick... tmp.reserve(v.size() * (11 + 10 + getMyNick().length())); - string n = ' ' + toNmdc(getMyNick()) + '|'; + string n = ' ' + toAcp(getMyNick()) + '|'; for(OnlineUser::List::const_iterator i = v.begin(); i != v.end(); ++i) { tmp += "$GetINFO "; - tmp += toNmdc((*i)->getIdentity().getNick()); + tmp += toAcp((*i)->getIdentity().getNick()); tmp += n; } if(!tmp.empty()) { @@ -607,8 +609,9 @@ continue; OnlineUser& ou = getUser(*it); ou.getIdentity().setOp(true); - if(*it == getMyNick()) - getMyIdentity().setOp(true); + if(ou.getUser() == getMyIdentity().getUser()) { + setMyIdentity(ou.getIdentity()); + } v.push_back(&ou); } @@ -650,13 +653,15 @@ OnlineUser* to = findUser(getMyNick()); if(replyTo == NULL || from == NULL || to == NULL) { - fire(ClientListener::StatusMessage(), this, Util::validateMessage(param.substr(i), true)); + fire(ClientListener::StatusMessage(), this, unescape(param.substr(i))); } else { string msg = param.substr(j + 2); - fire(ClientListener::PrivateMessage(), this, *from, *to, *replyTo, Util::validateMessage(param.substr(j + 2), true)); + fire(ClientListener::PrivateMessage(), this, *from, *to, *replyTo, unescape(param.substr(j + 2))); } } else if(cmd == "$GetPass") { - setRegistered(true); + OnlineUser& ou = getUser(getMyNick()); + ou.getIdentity().set("RG", "1"); + setMyIdentity(ou.getIdentity()); fire(ClientListener::GetPassword(), this); } else if(cmd == "$BadPass") { fire(ClientListener::BadPassword(), this); @@ -681,18 +686,18 @@ checkstate(); dcdebug("NmdcHub::connectToMe %s\n", aUser.getIdentity().getNick().c_str()); ConnectionManager::getInstance()->nmdcExpect(aUser.getIdentity().getNick(), getMyNick(), getHubUrl()); - send("$ConnectToMe " + toNmdc(aUser.getIdentity().getNick()) + " " + getLocalIp() + ":" + Util::toString(ConnectionManager::getInstance()->getPort()) + "|"); + send("$ConnectToMe " + toAcp(aUser.getIdentity().getNick()) + " " + getLocalIp() + ":" + Util::toString(ConnectionManager::getInstance()->getPort()) + "|"); } void NmdcHub::revConnectToMe(const OnlineUser& aUser) { checkstate(); dcdebug("NmdcHub::revConnectToMe %s\n", aUser.getIdentity().getNick().c_str()); - send("$RevConnectToMe " + toNmdc(getMyNick()) + " " + toNmdc(aUser.getIdentity().getNick()) + "|"); + send("$RevConnectToMe " + toAcp(getMyNick()) + " " + toAcp(aUser.getIdentity().getNick()) + "|"); } void NmdcHub::hubMessage(const string& aMessage) { checkstate(); - send(toNmdc( "<" + getMyNick() + "> " + Util::validateMessage(aMessage, false) + "|" ) ); + send(toAcp( "<" + getMyNick() + "> " + escape(aMessage) + "|" ) ); } void NmdcHub::myInfo(bool alwaysSend) { @@ -726,9 +731,9 @@ string uMin = (SETTING(MIN_UPLOAD_SPEED) == 0) ? Util::emptyString : tmp5 + Util::toString(SETTING(MIN_UPLOAD_SPEED)); string myInfoA = - "$MyINFO $ALL " + toNmdc(checkNick(getMyNick())) + " " + toNmdc(Util::validateMessage(getMyIdentity().getDescription(), false)) + + "$MyINFO $ALL " + toAcp(getCurrentNick()) + " " + toAcp(NmdcHub::validateMessage(getCurrentDescription(), false)) + tmp1 + VERSIONSTRING + tmp2 + modeChar + tmp3 + getCounts() + tmp4 + Util::toString(SETTING(SLOTS)) + uMin + - ">$ $" + SETTING(UPLOAD_SPEED) + "\x01$" + toNmdc(Util::validateMessage(SETTING(EMAIL), false)) + '$'; + ">$ $" + SETTING(UPLOAD_SPEED) + "\x01$" + toAcp(NmdcHub::validateMessage(SETTING(EMAIL), false)) + '$'; string myInfoB = ShareManager::getInstance()->getShareSizeString() + "$|"; if(lastMyInfoA != myInfoA || alwaysSend || (lastMyInfoB != myInfoB && lastUpdate + 15*60*1000 < GET_TICK()) ){ @@ -750,7 +755,7 @@ AutoArray<char> buf((char*)NULL); char c1 = (aSizeType == SearchManager::SIZE_DONTCARE) ? 'F' : 'T'; char c2 = (aSizeType == SearchManager::SIZE_ATLEAST) ? 'F' : 'T'; - string tmp = Util::validateMessage(toNmdc((aFileType == SearchManager::TYPE_TTH) ? "TTH:" + aString : aString), false); + string tmp = NmdcHub::validateMessage(toAcp((aFileType == SearchManager::TYPE_TTH) ? "TTH:" + aString : aString), false); string::size_type i; while((i = tmp.find(' ')) != string::npos) { tmp[i] = '$'; @@ -762,15 +767,76 @@ chars = sprintf(buf, "$Search %s:%d %c?%c?%s?%d?%s|", x.c_str(), (int)SearchManager::getInstance()->getPort(), c1, c2, Util::toString(aSize).c_str(), aFileType+1, tmp.c_str()); } else { buf = new char[getMyNick().length() + aString.length() + 64]; - chars = sprintf(buf, "$Search Hub:%s %c?%c?%s?%d?%s|", toNmdc(getMyNick()).c_str(), c1, c2, Util::toString(aSize).c_str(), aFileType+1, tmp.c_str()); + chars = sprintf(buf, "$Search Hub:%s %c?%c?%s?%d?%s|", toAcp(getMyNick()).c_str(), c1, c2, Util::toString(aSize).c_str(), aFileType+1, tmp.c_str()); } send(buf, chars); } +string NmdcHub::validateMessage(string tmp, bool reverse, bool checkNewLines) { + string::size_type i = 0; + + if(reverse) { + while( (i = tmp.find("$", i)) != string::npos) { + tmp.replace(i, 5, "$"); + i++; + } + i = 0; + while( (i = tmp.find("|", i)) != string::npos) { + tmp.replace(i, 6, "|"); + i++; + } + i = 0; + while( (i = tmp.find("&", i)) != string::npos) { + tmp.replace(i, 5, "&"); + i++; + } + if(checkNewLines) { + // Check all '<' and '[' after newlines... + i = 0; + while( (i = tmp.find('\n', i)) != string::npos) { + if(i + 1 < tmp.length()) { + if(tmp[i+1] == '[' || tmp[i+1] == '<') { + tmp.insert(i+1, "- "); + i += 2; + } + } + i++; + } + } + } else { + i = 0; + while( (i = tmp.find("&", i)) != string::npos) { + tmp.replace(i, 1, "&"); + i += 4; + } + i = 0; + while( (i = tmp.find("$", i)) != string::npos) { + tmp.replace(i, 1, "&"); + i += 4; + } + i = 0; + while( (i = tmp.find("|", i)) != string::npos) { + tmp.replace(i, 1, "&"); + i += 4; + } + i = 0; + while( (i = tmp.find('$', i)) != string::npos) { + tmp.replace(i, 1, "$"); + i += 4; + } + i = 0; + while( (i = tmp.find('|', i)) != string::npos) { + tmp.replace(i, 1, "|"); + i += 5; + } + } + return tmp; +} + void NmdcHub::privateMessage(const OnlineUser& aUser, const string& aMessage) { checkstate(); - send("$To: " + toNmdc(aUser.getIdentity().getNick()) + " From: " + toNmdc(getMyNick()) + " $" + toNmdc(Util::validateMessage("<" + getMyNick() + "> " + aMessage, false)) + "|"); + send("$To: " + toAcp(aUser.getIdentity().getNick()) + " From: " + toAcp(getMyNick()) + " $" + toAcp(NmdcHub::validateMessage("<" + getMyNick() + "> " + aMessage, false)) + "|"); // Emulate a returning message... Lock l(cs); NickIter i = users.find(getMyNick()); @@ -779,18 +845,12 @@ } // TimerManagerListener -void NmdcHub::on(TimerManagerListener::Second, u_int32_t aTick) throw() { - if(socket && (getLastActivity() + getReconnDelay() * 1000) < aTick) { - // Nothing's happened for ~120 seconds, check if we're connected, if not, try to connect... - if(isConnected()) { - // Try to send something for the fun of it... - dcdebug("Testing writing...\n"); - send("|", 1); - } else { - // Try to reconnect... - if(reconnect && !getAddress().empty()) - connect(); - } +void NmdcHub::on(Second, u_int32_t aTick) throw() { + + if(isConnected() && (getLastActivity() + getReconnDelay() * 1000) < aTick) { + // Try to send something for the fun of it... + dcdebug("Testing writing...\n"); + send("|", 1); } { Lock l(cs); @@ -803,6 +863,8 @@ flooders.pop_front(); } } + + Client::on(Second(), aTick); } // BufferedSocketListener Modified: dcplusplus/trunk/client/NmdcHub.h =================================================================== --- dcplusplus/trunk/client/NmdcHub.h 2006-06-17 15:40:35 UTC (rev 616) +++ dcplusplus/trunk/client/NmdcHub.h 2006-06-17 22:24:01 UTC (rev 617) @@ -33,7 +33,7 @@ class ClientManager; -class NmdcHub : public Client, private TimerManagerListener, private Flags +class NmdcHub : public Client, private Flags { public: using Client::send; @@ -44,18 +44,21 @@ virtual void hubMessage(const string& aMessage); virtual void privateMessage(const OnlineUser& aUser, const string& aMessage); - virtual void sendUserCmd(const string& aUserCmd) throw() { send(toNmdc(aUserCmd)); } + virtual void sendUserCmd(const string& aUserCmd) throw() { send(toAcp(aUserCmd)); } virtual void search(int aSizeType, int64_t aSize, int aFileType, const string& aString, const string& aToken); - virtual void password(const string& aPass) { send("$MyPass " + toNmdc(aPass) + "|"); } + virtual void password(const string& aPass) { send("$MyPass " + toAcp(aPass) + "|"); } virtual void info(bool force) { myInfo(force); } virtual size_t getUserCount() const { Lock l(cs); return users.size(); } virtual int64_t getAvailable() const; - virtual string escape(string const& str) const { return Util::validateMessage(str, false); } + virtual string escape(string const& str) const; + virtual string unescape(const string& str) const; virtual void send(const AdcCommand&) { dcassert(0); } + static string validateMessage(string tmp, bool reverse, bool checkNewLines); + GETSET(int, supportFlags, SupportFlags); private: friend class ClientManager; @@ -79,7 +82,6 @@ NickMap users; - bool reconnect; u_int32_t lastUpdate; string lastMyInfoA, lastMyInfoB; @@ -102,10 +104,10 @@ OnlineUser* findUser(const string& aNick); void putUser(const string& aNick); - string fromNmdc(const string& str) const { return Text::acpToUtf8(str); } - string toNmdc(const string& str) const { return Text::utf8ToAcp(str); } + string fromAcp(const string& str) const { return Text::acpToUtf8(str); } + string toAcp(const string& str) const { return Text::utf8ToAcp(str); } - void validateNick(const string& aNick) { send("$ValidateNick " + toNmdc(aNick) + "|"); } + void validateNick(const string& aNick) { send("$ValidateNick " + toAcp(aNick) + "|"); } void key(const string& aKey) { send("$Key " + aKey + "|"); } void version() { send("$Version 1,0091|"); } void getNickList() { send("$GetNickList|"); } @@ -119,7 +121,7 @@ virtual string checkNick(const string& aNick); // TimerManagerListener - virtual void on(TimerManagerListener::Second, u_int32_t aTick) throw(); + virtual void on(Second, u_int32_t aTick) throw(); virtual void on(Line, const string& l) throw() { onLine(l); } virtual void on(Failed, const string&) throw(); Modified: dcplusplus/trunk/client/QueueManager.cpp =================================================================== --- dcplusplus/trunk/client/QueueManager.cpp 2006-06-17 15:40:35 UTC (rev 616) +++ dcplusplus/trunk/client/QueueManager.cpp 2006-06-17 22:24:01 UTC (rev 617) @@ -489,7 +489,9 @@ q->setTTH(new TTHValue(*root)); } else if(!(*root == *q->getTTH())) { throw QueueException(STRING(FILE_WITH_DIFFERENT_TTH)); - } + } else if(BOOLSETTING(DONT_DL_ALREADY_QUEUED)) { + throw QueueException(STRING(FILE_IS_ALREADY_QUEUED)); + } } q->setFlag(aFlags); Modified: dcplusplus/trunk/client/SSLSocket.cpp =================================================================== --- dcplusplus/trunk/client/SSLSocket.cpp 2006-06-17 15:40:35 UTC (rev 616) +++ dcplusplus/trunk/client/SSLSocket.cpp 2006-06-17 22:24:01 UTC (rev 617) @@ -25,102 +25,7 @@ #include <openssl/ssl.h> -SSLSocketFactory::SSLSocketFactory() -: clientContext(SSL_CTX_new(TLSv1_client_method())), - serverContext(SSL_CTX_new(TLSv1_server_method())), - dh(DH_new()), - certsLoaded(false) -{ - static unsigned char dh512_p[] = - { - 0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75, - 0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F, - 0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3, - 0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12, - 0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C, - 0x47,0x74,0xE8,0x33, - }; - static unsigned char dh512_g[] = - { - 0x02, - }; - - if(dh) { - dh->p = BN_bin2bn(dh512_p, sizeof(dh512_p), 0); - dh->g = BN_bin2bn(dh512_g, sizeof(dh512_g), 0); - - if (!dh->p || !dh->g) { - DH_free(dh); - dh = 0; - } else { - SSL_CTX_set_tmp_dh(serverContext, dh); - } - } -} - -void SSLSocketFactory::loadCertificates() throw() { - SSL_CTX_set_verify(serverContext, SSL_VERIFY_NONE, 0); - SSL_CTX_set_verify(clientContext, SSL_VERIFY_NONE, 0); - - if(!SETTING(SSL_CERTIFICATE_FILE).empty()) { - if(SSL_CTX_use_certificate_file(serverContext, SETTING(SSL_CERTIFICATE_FILE).c_str(), SSL_FILETYPE_PEM) != SSL_SUCCESS) { - LogManager::getInstance()->message("Failed to load certificate file"); - return; - } - if(SSL_CTX_use_certificate_file(clientContext, SETTING(SSL_CERTIFICATE_FILE).c_str(), SSL_FILETYPE_PEM) != SSL_SUCCESS) { - LogManager::getInstance()->message("Failed to load certificate file"); - return; - } - } - - if(!SETTING(SSL_PRIVATE_KEY_FILE).empty()) { - if(SSL_CTX_use_PrivateKey_file(serverContext, SETTING(SSL_PRIVATE_KEY_FILE).c_str(), SSL_FILETYPE_PEM) != SSL_SUCCESS) { - LogManager::getInstance()->message("Failed to load private key"); - return; - } - if(SSL_CTX_use_PrivateKey_file(clientContext, SETTING(SSL_PRIVATE_KEY_FILE).c_str(), SSL_FILETYPE_PEM) != SSL_SUCCESS) { - LogManager::getInstance()->message("Failed to load private key"); - return; - } - } - -#ifdef _WIN32 - WIN32_FIND_DATA data; - HANDLE hFind; - - hFind = FindFirstFile(Text::toT(SETTING(SSL_TRUSTED_CERTIFICATES_PATH) + "*.pem").c_str(), &data); - if(hFind != INVALID_HANDLE_VALUE) { - do { - if(SSL_CTX_load_verify_locations(clientContext, (SETTING(SSL_TRUSTED_CERTIFICATES_PATH) + Text::fromT(data.cFileName)).c_str(), NULL) != SSL_SUCCESS) { - LogManager::getInstance()->message("Failed to load trusted certificate from " + Text::fromT(data.cFileName)); - } - } while(FindNextFile(hFind, &data)); - - FindClose(hFind); - } -#else -#error todo -#endif - certsLoaded = true; -} - -SSLSocketFactory::~SSLSocketFactory() { - if(serverContext) - SSL_CTX_free(serverContext); - if(clientContext) - SSL_CTX_free(clientContext); - if(dh) - DH_free(dh); -} - -SSLSocket* SSLSocketFactory::getClientSocket() throw(SocketException) { - return new SSLSocket(clientContext); -} -SSLSocket* SSLSocketFactory::getServerSocket() throw(SocketException) { - return new SSLSocket(serverContext); -} - SSLSocket::SSLSocket(SSL_CTX* context) throw(SocketException) : ctx(context), ssl(0) { } Modified: dcplusplus/trunk/client/SSLSocket.h =================================================================== --- dcplusplus/trunk/client/SSLSocket.h 2006-06-17 15:40:35 UTC (rev 616) +++ dcplusplus/trunk/client/SSLSocket.h 2006-06-17 22:24:01 UTC (rev 617) @@ -32,23 +32,8 @@ using namespace yaSSL; -class SSLSocketFactory : public Singleton<SSLSocketFactory> { -public: - SSLSocketFactory(); - virtual ~SSLSocketFactory(); +class CryptoManager; - SSLSocket* getClientSocket() throw(SocketException); - SSLSocket* getServerSocket() throw(SocketException); - - void loadCertificates() throw(); - bool hasCerts() const { return certsLoaded; } -private: - SSL_CTX* clientContext; - SSL_CTX* serverContext; - DH* dh; - bool certsLoaded; -}; - class SSLSocket : public Socket { public: virtual ~SSLSocket() throw() {} @@ -61,7 +46,7 @@ virtual void shutdown() throw(); virtual void close() throw(); private: - friend class SSLSocketFactory; + friend class CryptoManager; SSLSocket(SSL_CTX* context) throw(SocketException); SSLSocket(const SSLSocket&); Modified: dcplusplus/trunk/client/SettingsManager.cpp =================================================================== --- dcplusplus/trunk/client/SettingsManager.cpp 2006-06-17 15:40:35 UTC (rev 616) +++ dcplusplus/trunk/client/SettingsManager.cpp 2006-06-17 22:24:01 UTC (rev 617) @@ -74,6 +74,7 @@ "BoldHub", "BoldPm", "BoldSearch", "SocketInBuffer", "SocketOutBuffer", "OnlyDlTthFiles", "OpenWaitingUsers", "BoldWaitingUsers", "OpenSystemLog", "BoldSystemLog", "AutoRefreshTime", "UseSsl", "AutoSearchLimit", "AltSortOrder", "AutoKickNoFavs", "PromptPassword", "SpyFrameIgnoreTthSearches", + "DontDlAlreadyQueued", "SENTRY", // Int64 "TotalUpload", "TotalDownload", @@ -258,6 +259,7 @@ setDefault(AUTO_KICK_NO_FAVS, false); setDefault(PROMPT_PASSWORD, false); setDefault(SPY_FRAME_IGNORE_TTH_SEARCHES, false); + setDefault(DONT_DL_ALREADY_QUEUED, false); #ifdef _WIN32 setDefault(MAIN_WINDOW_STATE, SW_SHOWNORMAL); Modified: dcplusplus/trunk/client/SettingsManager.h =================================================================== --- dcplusplus/trunk/client/SettingsManager.h 2006-06-17 15:40:35 UTC (rev 616) +++ dcplusplus/trunk/client/SettingsManager.h 2006-06-17 22:24:01 UTC (rev 617) @@ -89,7 +89,8 @@ NO_IP_OVERRIDE, SEARCH_ONLY_FREE_SLOTS, LAST_SEARCH_TYPE, BOLD_FINISHED_DOWNLOADS, BOLD_FINISHED_UPLOADS, BOLD_QUEUE, BOLD_HUB, BOLD_PM, BOLD_SEARCH, SOCKET_IN_BUFFER, SOCKET_OUT_BUFFER, ONLY_DL_TTH_FILES, OPEN_WAITING_USERS, BOLD_WAITING_USERS, OPEN_SYSTEM_LOG, BOLD_SYSTEM_LOG, AUTO_REFRESH_TIME, - USE_SSL, AUTO_SEARCH_LIMIT, ALT_SORT_ORDER, AUTO_KICK_NO_FAVS, PROMPT_PASSWORD, SPY_FRAME_IGNORE_TTH_SEARCHES, + USE_SSL, AUTO_SEARCH_LIMIT, ALT_SORT_ORDER, AUTO_KICK_NO_FAVS, PROMPT_PASSWORD, SPY_FRAME_IGNORE_TTH_SEARCHES, + DONT_DL_ALREADY_QUEUED, INT_LAST }; enum Int64Setting { INT64_FIRST = INT_LAST + 1, Modified: dcplusplus/trunk/client/StringDefs.cpp =================================================================== --- dcplusplus/trunk/client/StringDefs.cpp 2006-06-17 15:40:35 UTC (rev 616) +++ dcplusplus/trunk/client/StringDefs.cpp 2006-06-17 22:24:01 UTC (rev 617) @@ -131,6 +131,7 @@ "File", "Files", "This file has no TTH", +"This file is already queued", "Subtract list", "File list refresh failed: ", "File list refresh finished", @@ -407,6 +408,7 @@ "Default away message", "Direct connection", "Directories", +"Don't download files already in the queue", "Don't download files already in share", "Default download directory", "Limits", @@ -740,6 +742,7 @@ "File", "Files", "FileHasNoTth", +"FileIsAlreadyQueued", "FileListDiff", "FileListRefreshFailed", "FileListRefreshFinished", @@ -1016,6 +1019,7 @@ "SettingsDefaultAwayMsg", "SettingsDirect", "SettingsDirectories", +"SettingsDontDlAlreadyQueued", "SettingsDontDlAlreadyShared", "SettingsDownloadDirectory", "SettingsDownloadLimits", Modified: dcplusplus/trunk/client/StringDefs.h =================================================================== --- dcplusplus/trunk/client/StringDefs.h 2006-06-17 15:40:35 UTC (rev 616) +++ dcplusplus/trunk/client/StringDefs.h 2006-06-17 22:24:01 UTC (rev 617) @@ -134,6 +134,7 @@ FILE, // "File" FILES, // "Files" FILE_HAS_NO_TTH, // "This file has no TTH" + FILE_IS_ALREADY_QUEUED, // "This file is already queued" FILE_LIST_DIFF, // "Subtract list" FILE_LIST_REFRESH_FAILED, // "File list refresh failed: " FILE_LIST_REFRESH_FINISHED, // "File list refresh finished" @@ -410,6 +411,7 @@ SETTINGS_DEFAULT_AWAY_MSG, // "Default away message" SETTINGS_DIRECT, // "Direct connection" SETTINGS_DIRECTORIES, // "Directories" + SETTINGS_DONT_DL_ALREADY_QUEUED, // "Don't download files already in the queue" SETTINGS_DONT_DL_ALREADY_SHARED, // "Don't download files already in share" SETTINGS_DOWNLOAD_DIRECTORY, // "Default download directory" SETTINGS_DOWNLOAD_LIMITS, // "Limits" Modified: dcplusplus/trunk/client/User.cpp =================================================================== --- dcplusplus/trunk/client/User.cpp 2006-06-17 15:40:35 UTC (rev 616) +++ dcplusplus/trunk/client/User.cpp 2006-06-17 22:24:01 UTC (rev 617) @@ -22,8 +22,9 @@ #include "User.h" #include "Client.h" #include "StringTokenizer.h" +#include "FavoriteUser.h" -OnlineUser::OnlineUser(const User::Ptr& ptr, Client& client_, u_int32_t sid_) : user(ptr), identity(ptr, client_.getHubUrl(), sid_), client(&client_) { +OnlineUser::OnlineUser(const User::Ptr& ptr, Client& client_, u_int32_t sid_) : identity(ptr, sid_), client(&client_) { } @@ -64,3 +65,8 @@ } return false; } + +void FavoriteUser::update(const OnlineUser& info) { + setNick(info.getIdentity().getNick()); + setUrl(info.getClient().getHubUrl()); +} Modified: dcplusplus/trunk/client/User.h =================================================================== --- dcplusplus/trunk/client/User.h 2006-06-17 15:40:35 UTC (rev 616) +++ dcplusplus/trunk/client/User.h 2006-06-17 22:24:01 UTC (rev 617) @@ -98,9 +98,9 @@ }; Identity() : sid(0) { } - Identity(const User::Ptr& ptr, const string& aHubUrl, u_int32_t aSID) : user(ptr), hubUrl(aHubUrl), sid(aSID) { } - Identity(const Identity& rhs) : ::Flags(rhs), user(rhs.user), hubUrl(rhs.hubUrl), sid(rhs.sid), info(rhs.info) { } - Identity& operator=(const Identity& rhs) { user = rhs.user; hubUrl = rhs.hubUrl; sid = rhs.sid; info = rhs.info; return *this; } + Identity(const User::Ptr& ptr, u_int32_t aSID) : user(ptr), sid(aSID) { } + Identity(const Identity& rhs) : ::Flags(rhs), user(rhs.user), sid(rhs.sid), info(rhs.info) { } + Identity& operator=(const Identity& rhs) { user = rhs.user; sid = rhs.sid; info = rhs.info; return *this; } #define GS(n, x) const string& get##n() const { return get(x); } void set##n(const string& v) { set(x, v); } GS(Nick, "NI") @@ -127,8 +127,10 @@ bool supports(const string& name) const; bool isHub() const { return !get("HU").empty(); } bool isOp() const { return !get("OP").empty(); } + bool isRegistered() const { return !get("RG").empty(); } bool isHidden() const { return !get("HI").empty(); } bool isBot() const { return !get("BO").empty(); } + bool isAway() const { return !get("AW").empty(); } bool isTcpActive() const { return !getIp().empty() || (user->isSet(User::NMDC) && !user->isSet(User::PASSIVE)); } bool isUdpActive() const { return !getIp().empty() && !getUdpPort().empty(); } @@ -151,12 +153,10 @@ void getParams(StringMap& map, const string& prefix, bool compatibility) const; User::Ptr& getUser() { return user; } GETSET(User::Ptr, user, User); - GETSET(string, hubUrl, HubUrl); GETSET(u_int32_t, sid, SID); private: typedef map<short, string> InfMap; typedef InfMap::iterator InfIter; - InfMap info; }; @@ -170,15 +170,15 @@ OnlineUser(const User::Ptr& ptr, Client& client_, u_int32_t sid_); - operator User::Ptr&() { return user; } - operator const User::Ptr&() const { return user; } + operator User::Ptr&() { return getUser(); } + operator const User::Ptr&() const { return getUser(); } - User::Ptr& getUser() { return user; } + User::Ptr& getUser() { return getIdentity().getUser(); } + const User::Ptr& getUser() const { return getIdentity().getUser(); } Identity& getIdentity() { return identity; } Client& getClient() { return *client; } const Client& getClient() const { return *client; } - GETSET(User::Ptr, user, User); GETSET(Identity, identity, Identity); private: friend class NmdcHub; Modified: dcplusplus/trunk/client/Util.cpp =================================================================== --- dcplusplus/trunk/client/Util.cpp 2006-06-17 15:40:35 UTC (rev 616) +++ dcplusplus/trunk/client/Util.cpp 2006-06-17 22:24:01 UTC (rev 617) @@ -173,67 +173,6 @@ #endif // _WIN32 } -string Util::validateMessage(string tmp, bool reverse, bool checkNewLines) { - string::size_type i = 0; - - if(reverse) { - while( (i = tmp.find("$", i)) != string::npos) { - tmp.replace(i, 5, "$"); - i++; - } - i = 0; - while( (i = tmp.find("|", i)) != string::npos) { - tmp.replace(i, 6, "|"); - i++; - } - i = 0; - while( (i = tmp.find("&", i)) != string::npos) { - tmp.replace(i, 5, "&"); - i++; - } - if(checkNewLines) { - // Check all '<' and '[' after newlines... - i = 0; - while( (i = tmp.find('\n', i)) != string::npos) { - if(i + 1 < tmp.length()) { - if(tmp[i+1] == '[' || tmp[i+1] == '<') { - tmp.insert(i+1, "- "); - i += 2; - } - } - i++; - } - } - } else { - i = 0; - while( (i = tmp.find("&", i)) != string::npos) { - tmp.replace(i, 1, "&"); - i += 4; - } - i = 0; - while( (i = tmp.find("$", i)) != string::npos) { - tmp.replace(i, 1, "&"); - i += 4; - } - i = 0; - while( (i = tmp.find("|", i)) != string::npos) { - tmp.replace(i, 1, "&"); - i += 4; - } - i = 0; - while( (i = tmp.find('$', i)) != string::npos) { - tmp.replace(i, 1, "$"); - i += 4; - } - i = 0; - while( (i = tmp.find('|', i)) != string::npos) { - tmp.replace(i, 1, "|"); - i += 5; - } - } - return tmp; -} - #ifdef _WIN32 static const char badChars[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, Modified: dcplusplus/trunk/client/Util.h =================================================================== --- dcplusplus/trunk/client/Util.h 2006-06-17 15:40:35 UTC (rev 616) +++ dcplusplus/trunk/client/Util.h 2006-06-17 22:24:01 UTC (rev 617) @@ -489,8 +489,6 @@ static int stricmp(const wstring& a, const wstring& b) { return stricmp(a.c_str(), b.c_str()); } static int strnicmp(const wstring& a, const wstring& b, size_t n) { return strnicmp(a.c_str(), b.c_str(), n); } - static string validateMessage(string tmp, bool reverse, bool checkNewLines = true); - static string getOsVersion(); static string getIpCountry (string IP); Modified: dcplusplus/trunk/windows/CommandDlg.cpp =================================================================== --- dcplusplus/trunk/windows/CommandDlg.cpp 2006-06-17 15:40:35 UTC (rev 616) +++ dcplusplus/trunk/windows/CommandDlg.cpp 2006-06-17 22:24:01 UTC (rev 617) @@ -84,7 +84,7 @@ dcassert(i != string::npos); tstring to = command.substr(5, i-5); string::size_type cmd_pos = command.find(_T('>'), 5) + 2; - tstring cmd = Text::toT(Util::validateMessage(Text::fromT(command.substr(cmd_pos, command.length()-cmd_pos-1)), true, false)); + tstring cmd = Text::toT(NmdcHub::validateMessage(Text::fromT(command.substr(cmd_pos, command.length()-cmd_pos-1)), true, false)); ctrlPM.SetCheck(BST_CHECKED); ctrlNick.SetWindowText(to.c_str()); ctrlCommand.SetWindowText(cmd.c_str()); @@ -94,7 +94,7 @@ { // Looks like a chat thing... string::size_type cmd_pos = command.find(_T('>')) + 2; - tstring cmd = Text::toT(Util::validateMessage(Text::fromT(command.substr(cmd_pos, command.length()-cmd_pos-1)), true, false)); + tstring cmd = Text::toT(NmdcHub::validateMessage(Text::fromT(command.substr(cmd_pos, command.length()-cmd_pos-1)), true, false)); ctrlChat.SetCheck(BST_CHECKED); ctrlCommand.SetWindowText(cmd.c_str()); } else { Modified: dcplusplus/trunk/windows/CommandDlg.h =================================================================== --- dcplusplus/trunk/windows/CommandDlg.h 2006-06-17 15:40:35 UTC (rev 616) +++ dcplusplus/trunk/windows/CommandDlg.h 2006-06-17 22:24:01 UTC (rev 617) @@ -103,12 +103,12 @@ command = buf; } else if(type == 2) { ctrlCommand.GetWindowText(buf, BUF_LEN - 1); - command = Text::toT("<%[myNI]> " + Util::validateMessage(Text::fromT(buf), false) + "|"); + command = Text::toT("<%[myNI]> " + NmdcHub::validateMessage(Text::fromT(buf), false) + "|"); } else if(type == 3) { ctrlNick.GetWindowText(buf, BUF_LEN - 1); tstring to(buf); ctrlCommand.GetWindowText(buf, BUF_LEN - 1); - command = _T("$To: ") + to + _T(" From: %[myNI] $<%[myNI]> ") + Text::toT(Util::validateMessage(Text::fromT(buf), false)) + _T("|"); + command = _T("$To: ") + to + _T(" From: %[myNI] $<%[myNI]> ") + Text::toT(NmdcHub::validateMessage(Text::fromT(buf), false)) + _T("|"); } } void updateControls() { Modified: dcplusplus/trunk/windows/HubFrame.cpp =================================================================== --- dcplusplus/trunk/windows/HubFrame.cpp 2006-06-17 15:40:35 UTC (rev 616) +++ dcplusplus/trunk/windows/HubFrame.cpp 2006-06-17 22:24:01 UTC (rev 617) @@ -960,10 +960,7 @@ } LRESULT HubFrame::onFileReconnect(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) { - client->disconnect(false); - clearUserList(); - clearTaskList(); - client->connect(); + client->reconnect(); return 0; } @@ -1190,7 +1187,7 @@ } } -void HubFrame::on(TimerManagerListener::Second, DWORD /*aTick*/) throw() { +void HubFrame::on(Second, DWORD /*aTick*/) throw() { updateStatusBar(); if(updateUsers) { updateUsers = false; @@ -1245,7 +1242,12 @@ speak(GET_PASSWORD); } void HubFrame::on(HubUpdated, Client*) throw() { - speak(SET_WINDOW_TITLE, Util::validateMessage(client->getHubName() + " " + client->getHubDescription(), true, false) + " (" + client->getHubUrl() + ")"); + string hubName = client->getHubName(); + if(!client->getHubDescription().empty()) { + hubName += " - " + client->getHubDescription(); + } + hubName += " (" + client->getHubUrl() + ")"; + speak(SET_WINDOW_TITLE, hubName); } void HubFrame::on(Message, Client*, const OnlineUser& from, const string& msg) throw() { speak(ADD_CHAT_LINE, Util::toDOS("<" + from.getIdentity().getNick() + "> " + msg)); Modified: dcplusplus/trunk/windows/MainFrm.cpp =================================================================== --- dcplusplus/trunk/windows/MainFrm.cpp 2006-06-17 15:40:35 UTC (rev 616) +++ dcplusplus/trunk/windows/MainFrm.cpp 2006-06-17 22:24:01 UTC (rev 617) @@ -554,8 +554,8 @@ { PropertiesDlg dlg(m_hWnd, SettingsManager::getInstance()); - short lastPort = (short)SETTING(TCP_PORT); - short lastUDP = (short)SETTING(UDP_PORT); + unsigned short lastPort = (unsigned short)SETTING(TCP_PORT); + unsigned short lastUDP = (unsigned short)SETTING(UDP_PORT); int lastConn = SETTING(INCOMING_CONNECTIONS); if(dlg.DoModal(m_hWnd) == IDOK) Modified: dcplusplus/trunk/windows/QueuePage.cpp =================================================================== --- dcplusplus/trunk/windows/QueuePage.cpp 2006-06-17 15:40:35 UTC (rev 616) +++ dcplusplus/trunk/windows/QueuePage.cpp 2006-06-17 22:24:01 UTC (rev 617) @@ -78,6 +78,7 @@ { SettingsManager::ANTI_FRAG, ResourceManager::SETTINGS_ANTI_FRAG }, { SettingsManager::ADVANCED_RESUME, ResourceManager::SETTINGS_ADVANCED_RESUME }, { SettingsManager::ONLY_DL_TTH_FILES, ResourceManager::SETTINGS_ONLY_DL_TTH_FILES }, + { SettingsManager::DONT_DL_ALREADY_QUEUED, ResourceManager::SETTINGS_DONT_DL_ALREADY_QUEUED }, { 0, ResourceManager::SETTINGS_AUTO_AWAY } }; Modified: dcplusplus/trunk/windows/UPnP.cpp =================================================================== --- dcplusplus/trunk/windows/UPnP.cpp 2006-06-17 15:40:35 UTC (rev 616) +++ dcplusplus/trunk/windows/UPnP.cpp 2006-06-17 22:24:01 UTC (rev 617) @@ -24,7 +24,7 @@ #include <atlconv.h> #include "../client/Util.h" -UPnP::UPnP(const string theIPAddress, const string theProtocol, const string theDescription, const short thePort) { +UPnP::UPnP(const string theIPAddress, const string theProtocol, const string theDescription, const unsigned short thePort) { // need some messy string conversions in here // to convert STL::string to BSTR type strings // required for the UPnP code. Modified: dcplusplus/trunk/windows/UPnP.h =================================================================== --- dcplusplus/trunk/windows/UPnP.h 2006-06-17 15:40:35 UTC (rev 616) +++ dcplusplus/trunk/windows/UPnP.h 2006-06-17 22:24:01 UTC (rev 617) @@ -28,7 +28,7 @@ class UPnP { public: - UPnP( const string, const string, const string, const short ); + UPnP( const string, const string, const string, const unsigned short ); ~UPnP(); HRESULT OpenPorts(); HRESULT ClosePorts(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |