void UserConnection::handlePM(const AdcCommand& c, bool echo) noexcept{ const string& message = c.getParam(0); OnlineUserPtr peer = nullptr; OnlineUserPtr me = nullptr; auto cm = ClientManager::getInstance(); { RLock l(cm->getCS()); peer = cm->findOnlineUser(user->getCID(), getHubUrl()); //try to use the same hub so nicks match to a hub, not the perfect solution for CCPM, nicks keep changing when hubs go offline. if(peer && peer->getHubUrl() != hubUrl) setHubUrl(peer->getHubUrl()); me = cm->findOnlineUser(cm->getMe()->getCID(), getHubUrl()); } if (!me || !peer){ //ChatMessage cant be formatted without the OnlineUser! disconnect(true); return; } if (echo) { std::swap(peer, me); } string tmp; auto msg = make_shared<ChatMessage>(message, peer, me, peer); if (c.getParam("TS", 1, tmp)) { msg->setTime(Util::toInt64(tmp)); } msg->setThirdPerson(c.hasFlag("ME", 1)); fire(UserConnectionListener::PrivateMessage(), this, msg); }
void Client::doRedirect() noexcept { if (redirectUrl.empty()) { return; } if (ClientManager::getInstance()->hasClient(redirectUrl)) { statusMessage(STRING(REDIRECT_ALREADY_CONNECTED), LogMessage::SEV_INFO); return; } auto newClient = ClientManager::getInstance()->redirect(getHubUrl(), redirectUrl); fire(ClientListener::Redirected(), getHubUrl(), newClient); }
Client::Client(const string& p_HubURL, char separator_, bool secure_) : m_cs(std::unique_ptr<webrtc::RWLockWrapper> (webrtc::RWLockWrapper::CreateRWLock())), m_reconnDelay(120), m_lastActivity(GET_TICK()), //registered(false), [-] IRainman fix. autoReconnect(false), m_encoding(Text::systemCharset), state(STATE_DISCONNECTED), m_client_sock(0), m_HubURL(p_HubURL), m_port(0), m_separator(separator_), m_secure(secure_), m_countType(COUNT_UNCOUNTED), m_availableBytes(0), m_exclChecks(false) // [+] IRainman fix. { dcassert(p_HubURL == Text::toLower(p_HubURL)); const auto l_my_user = new User(ClientManager::getMyCID()); const auto l_hub_user = new User(CID()); #ifdef PPA_INCLUDE_LASTIP_AND_USER_RATIO m_HubID = CFlylinkDBManager::getInstance()->get_dic_hub_id(m_HubURL); dcassert(m_HubID != 0); l_my_user->setHubID(m_HubID); // ƒл¤ сохранени¤ кол-ва мессаг по самому себе //l_hub_user->setHubID(m_HubID); // ƒл¤ бота-хаба не сохран¤ем пока #endif m_myOnlineUser = new OnlineUser(UserPtr(l_my_user), *this, 0); // [+] IRainman fix. m_hubOnlineUser = new OnlineUser(UserPtr(l_hub_user), *this, AdcCommand::HUB_SID); // [+] IRainman fix. // [-] IRainman. //m_hEventClientInitialized = CreateEvent(NULL, TRUE, FALSE, NULL);//[+]FlylinkDC string file, proto, query, fragment; Util::decodeUrl(getHubUrl(), proto, m_address, m_port, file, query, fragment); if (!query.empty()) { m_keyprint = Util::decodeQuery(query)["kp"]; #ifdef _DEBUG LogManager::getInstance()->message("keyprint = " + m_keyprint); #endif } #ifdef _DEBUG else { LogManager::getInstance()->message("hubURL = " + getHubUrl() + " query.empty()"); } #endif TimerManager::getInstance()->addListener(this); }
void Client::on(Connected) noexcept { updateActivity(); { #ifdef FLYLINKDC_USE_CS_CLIENT_SOCKET FastLock lock(csSock); // [+] brain-ripper #endif boost::system::error_code ec; m_ip = boost::asio::ip::address_v4::from_string(m_client_sock->getIp(), ec); dcassert(!ec); } if (m_client_sock->isSecure() && m_keyprint.compare(0, 7, "SHA256/", 7) == 0) { const auto kp = m_client_sock->getKeyprint(); if (!kp.empty()) { vector<uint8_t> kp2v(kp.size()); Encoder::fromBase32(m_keyprint.c_str() + 7, &kp2v[0], kp2v.size()); if (!std::equal(kp.begin(), kp.end(), kp2v.begin())) { state = STATE_DISCONNECTED; m_client_sock->removeListener(this); fire(ClientListener::Failed(), this, "Keyprint mismatch"); return; } } } #ifdef IRAINMAN_ENABLE_CON_STATUS_ON_FAV_HUBS FavoriteManager::getInstance()->changeConnectionStatus(getHubUrl(), ConnectionStatus::SUCCES); #endif fire(ClientListener::Connected(), this); state = STATE_PROTOCOL; }
void Client::reloadSettings(bool updateNick) { /// @todo update the nick in ADC hubs? string prevNick; if(!updateNick) prevNick = get(Nick); auto fav = FavoriteManager::getInstance()->getFavoriteHubEntry(getHubUrl()); *static_cast<HubSettings*>(this) = SettingsManager::getInstance()->getHubSettings(); bool isAdcHub = AirUtil::isAdcHub(hubUrl); if(fav) { FavoriteManager::getInstance()->mergeHubSettings(fav, *this); if(!fav->getPassword().empty()) setPassword(fav->getPassword()); setStealth(!isAdcHub ? fav->getStealth() : false); setFavNoPM(fav->getFavNoPM()); favToken = fav->getToken(); } else { setStealth(false); setFavNoPM(false); setPassword(Util::emptyString); } searchQueue.minInterval = get(HubSettings::SearchInterval) * 1000; //convert from seconds if (updateNick) checkNick(get(Nick)); else get(Nick) = prevNick; }
void MessageManager::saveUsers() { SimpleXML xml; xml.addTag("Ignored"); xml.stepIn(); xml.addTag("Users"); xml.stepIn(); //TODO: cache this information? { RLock l(Ignorecs); for (const auto& u : ignoredUsers) { xml.addTag("User"); xml.addChildAttrib("CID", u->getCID().toBase32()); auto ou = ClientManager::getInstance()->findOnlineUser(u->getCID(), ""); if (ou) { xml.addChildAttrib("Nick", ou->getIdentity().getNick()); xml.addChildAttrib("Hub", ou->getHubUrl()); xml.addChildAttrib("LastSeen", GET_TIME()); } else { auto ofu = ClientManager::getInstance()->getOfflineUser(u->getCID()); xml.addChildAttrib("Nick", ofu ? ofu->getNick() : ""); xml.addChildAttrib("Hub", ofu ? ofu->getUrl() : ""); xml.addChildAttrib("LastSeen", ofu ? ofu->getLastSeen() : GET_TIME()); } } } xml.stepOut(); xml.stepOut(); SettingsManager::saveSettingFile(xml, CONFIG_DIR, CONFIG_NAME); }
Client::~Client() throw() { dcassert(!sock); // In case we were deleted before we Failed FavoriteManager::getInstance()->removeUserCommand(getHubUrl()); TimerManager::getInstance()->removeListener(this); updateCounts(true); }
Client::~Client() { dcassert(!m_client_sock); if (m_client_sock) { LogManager::getInstance()->message("[Error] Client::~Client() sock == nullptr"); } FavoriteManager::getInstance()->removeUserCommand(getHubUrl()); dcassert(FavoriteManager::getInstance()->countUserCommand(getHubUrl()) == 0); // In case we were deleted before we Failed // [-] TimerManager::getInstance()->removeListener(this); [-] IRainman fix: please see shutdown(). updateCounts(true); //[+]FlylinkDC // [-] IRainman. //if (m_hEventClientInitialized) // CloseHandle(m_hEventClientInitialized); //[~]FlylinkDC }
void Client::disconnect(bool graceLess) { state = STATE_DISCONNECTED;//[!] IRainman fix FavoriteManager::getInstance()->removeUserCommand(getHubUrl()); #ifdef FLYLINKDC_USE_CS_CLIENT_SOCKET FastLock lock(csSock); // [+] brain-ripper #endif if (m_client_sock) m_client_sock->disconnect(graceLess); }
void Client::reloadSettings(bool updateNick) { const FavoriteHubEntry* hub = FavoriteManager::getInstance()->getFavoriteHubEntry(getHubUrl()); string ClientId; if (::strncmp(getHubUrl().c_str(),"adc://", 6) == 0 || ::strncmp(getHubUrl().c_str(),"adcs://", 6) == 0) ClientId = fullADCVersionString; else ClientId = fullVersionString; if(hub) { if(updateNick) { setCurrentNick(checkNick(hub->getNick(true))); } if(!hub->getUserDescription().empty()) { setCurrentDescription(hub->getUserDescription()); } else { setCurrentDescription(SETTING(DESCRIPTION)); } if(!hub->getPassword().empty()) setPassword(hub->getPassword()); if (hub->getOverrideId() && strlen(hub->getClientId().c_str()) > 1) ClientId = hub->getClientId(); if (!hub->getExternalIP().empty()) externalIP = hub->getExternalIP(); if (!hub->getEncoding().empty()){ setEncoding(hub->getEncoding()); } if (hub->getUseInternetIP() && !SETTING(INTERNETIP).empty()){ externalIP = SETTING(INTERNETIP); } } else { if(updateNick) { setCurrentNick(checkNick(SETTING(NICK))); } setCurrentDescription(SETTING(DESCRIPTION)); } setClientId(ClientId); }
bool Client::saveFavorite() { FavoriteHubEntryPtr e = new FavoriteHubEntry(); e->setServer(getHubUrl()); e->setName(getHubName()); e->setDescription(getHubDescription()); e->setAutoConnect(true); if (!defpassword.empty()) { e->setPassword(defpassword); } return FavoriteManager::getInstance()->addFavoriteHub(e); }
void Client::on(Failed, const string& aLine) noexcept { // although failed consider initialized state = STATE_DISCONNECTED;//[!] IRainman fix FavoriteManager* l_fm = FavoriteManager::getInstance(); l_fm->removeUserCommand(getHubUrl()); { #ifdef FLYLINKDC_USE_CS_CLIENT_SOCKET FastLock lock(csSock); // [+] brain-ripper #endif if (m_client_sock) m_client_sock->removeListener(this); } // [-] IRainman. //SetEvent(m_hEventClientInitialized); updateActivity(); #ifdef IRAINMAN_ENABLE_CON_STATUS_ON_FAV_HUBS l_fm->changeConnectionStatus(getHubUrl(), ConnectionStatus::CONNECTION_FAILURE); #endif fire(ClientListener::Failed(), this, aLine); }
void Client::onChatMessage(const ChatMessagePtr& aMessage) noexcept { if (MessageManager::getInstance()->isIgnoredOrFiltered(aMessage, this, false)) return; if (get(HubSettings::LogMainChat)) { ParamMap params; params["message"] = aMessage->format(); getHubIdentity().getParams(params, "hub", false); params["hubURL"] = getHubUrl(); getMyIdentity().getParams(params, "my", true); LOG(LogManager::CHAT, params); } cache.addMessage(aMessage); fire(ClientListener::ChatMessage(), this, aMessage); }
void Client::statusMessage(const string& aMessage, LogMessage::Severity aSeverity, int aFlag) noexcept { auto message = make_shared<LogMessage>(aMessage, aSeverity); if (aFlag != ClientListener::FLAG_IS_SPAM) { cache.addMessage(message); if (SETTING(LOG_STATUS_MESSAGES)) { ParamMap params; getHubIdentity().getParams(params, "hub", false); params["hubURL"] = getHubUrl(); getMyIdentity().getParams(params, "my", true); params["message"] = aMessage; LOG(LogManager::STATUS, params); } } fire(ClientListener::StatusMessage(), this, message, aFlag); }
void Client::on(Failed, const string& aLine) noexcept { clearUsers(); if(stateNormal()) FavoriteManager::getInstance()->removeUserCommand(hubUrl); //Better ways to transfer the text in here?... string aError = aLine; if (secure && SETTING(ALLOW_UNTRUSTED_HUBS) && sock && !sock->isKeyprintMatch()) { aError += ", type /allow to proceed with untrusted connection"; iskeypError = true; } setConnectState(STATE_DISCONNECTED); statusMessage(aError, LogMessage::SEV_WARNING); //Error? sock->removeListener(this); fire(ClientListener::Failed(), getHubUrl(), aError); }
void Client::shutdown(ClientPtr& aClient, bool aRedirect) { FavoriteManager::getInstance()->removeUserCommand(getHubUrl()); TimerManager::getInstance()->removeListener(this); if (!aRedirect) { fire(ClientListener::Disconnecting(), this); } if(sock) { BufferedSocket::putSocket(sock, [=] { // Ensure that the pointer won't be deleted too early state = STATE_DISCONNECTED; if (!aRedirect) { cache.clear(); } aClient->clearUsers(); updateCounts(true); }); } }
void Client::reloadSettings(bool updateNick) { FavoriteHubEntry* hub = FavoriteManager::getInstance()->getFavoriteHubEntry(getHubUrl()); if(hub) { if(updateNick) { setCurrentNick(checkNick(hub->getNick(true))); } if(!hub->getUserDescription().empty()) { setCurrentDescription(hub->getUserDescription()); } else { setCurrentDescription(SETTING(DESCRIPTION)); } if(!hub->getPassword().empty()) setPassword(hub->getPassword()); } else { if(updateNick) { setCurrentNick(checkNick(SETTING(NICK))); } setCurrentDescription(SETTING(DESCRIPTION)); } }
void Client::messageYouHaweRightOperatorOnThisHub() { AutoArray<char> buf(512); snprintf(buf.data(), 512, CSTRING(AT_HUB_YOU_HAVE_RIGHT_OPERATOR), getHubUrl().c_str()); LogManager::getInstance()->message(buf.data()); }
void Client::on(BufferedSocketListener::Connecting) noexcept { statusMessage(STRING(CONNECTING_TO) + " " + getHubUrl() + " ...", LogMessage::SEV_INFO); fire(ClientListener::Connecting(), this); }
// [+] IRainman fix. bool Client::allowPrivateMessagefromUser(const ChatMessage& message) { if (isMe(message.m_replyTo)) { if (UserManager::expectPasswordFromUser(message.m_to->getUser()) #ifdef IRAINMAN_ENABLE_AUTO_BAN || UploadManager::getInstance()->isBanReply(message.m_to->getUser()) // !SMT!-S #endif ) { return false; } else { return true; } } else if (message.thirdPerson && BOOLSETTING(NSL_IGNORE_ME)) { return false; } else if (UserManager::isInIgnoreList(message.m_replyTo->getIdentity().getNick())) // !SMT!-S { return false; } else if (BOOLSETTING(SUPPRESS_PMS)) { #ifdef IRAINMAN_ENABLE_AUTO_BAN if (UploadManager::getInstance()->isBanReply(message.m_replyTo->getUser())) // !SMT!-S { return false; } else #endif if (FavoriteManager::getInstance()->isNoFavUserOrUserIgnorePrivate(message.m_replyTo->getUser())) { if (BOOLSETTING(LOG_IF_SUPPRESS_PMS)) { LocalArray<char, 200> l_buf; snprintf(l_buf.data(), l_buf.size(), CSTRING(LOG_IF_SUPPRESS_PMS), message.m_replyTo->getIdentity().getNick().c_str(), getHubName().c_str(), getHubUrl().c_str()); LogManager::getInstance()->message(l_buf.data()); } return false; } else { return true; } } else if (message.m_replyTo->getIdentity().isHub()) { if (BOOLSETTING(IGNORE_HUB_PMS) && !isInOperatorList(message.m_replyTo->getIdentity().getNick())) { fire(ClientListener::StatusMessage(), this, STRING(IGNORED_HUB_BOT_PM) + ": " + message.m_text); return false; } else if (FavoriteManager::getInstance()->hasIgnorePM(message.m_replyTo->getUser())) { return false; } else { return true; } } else if (message.m_replyTo->getIdentity().isBot()) { if (BOOLSETTING(IGNORE_BOT_PMS) && !isInOperatorList(message.m_replyTo->getIdentity().getNick())) { fire(ClientListener::StatusMessage(), this, STRING(IGNORED_HUB_BOT_PM) + ": " + message.m_text); return false; } else if (FavoriteManager::getInstance()->hasIgnorePM(message.m_replyTo->getUser())) { return false; } else { return true; } } else if (BOOLSETTING(PROTECT_PRIVATE) && !FavoriteManager::getInstance()->hasFreePM(message.m_replyTo->getUser())) // !SMT!-PSW { switch (UserManager::checkPrivateMessagePassword(message)) { case UserManager::FREE: { return true; } case UserManager::WAITING: { return false; } case UserManager::FIRST: { StringMap params; params["pm_pass"] = SETTING(PM_PASSWORD); privateMessage(message.m_replyTo, Util::formatParams(SETTING(PM_PASSWORD_HINT), params, false), false); if (BOOLSETTING(PROTECT_PRIVATE_SAY)) { fire(ClientListener::StatusMessage(), this, STRING(REJECTED_PRIVATE_MESSAGE_FROM) + ": " + message.m_replyTo->getIdentity().getNick()); } return false; } case UserManager::CHECKED: { privateMessage(message.m_replyTo, SETTING(PM_PASSWORD_OK_HINT), true); // TODO needs? // const tstring passwordOKMessage = _T('<') + message.m_replyTo->getUser()->getLastNickT() + _T("> ") + TSTRING(PRIVATE_CHAT_PASSWORD_OK_STARTED); // PrivateFrame::gotMessage(from, to, replyTo, passwordOKMessage, getHubHint(), myPM, pm.thirdPerson); // !SMT!-S return true; } default: // Only for compiler. { dcassert(0); return false; } } } else { if (FavoriteManager::getInstance()->hasIgnorePM(message.m_replyTo->getUser()) #ifdef IRAINMAN_ENABLE_AUTO_BAN || UploadManager::getInstance()->isBanReply(message.m_replyTo->getUser()) // !SMT!-S #endif ) { return false; } else { return true; } } }
const FavoriteHubEntry* Client::reloadSettings(bool updateNick) { #ifdef IRAINMAN_ENABLE_SLOTS_AND_LIMIT_IN_DESCRIPTION string speedDescription; #endif // [!] FlylinkDC mimicry function const FavoriteHubEntry* hub = FavoriteManager::getInstance()->getFavoriteHubEntry(getHubUrl()); if (hub && hub->getOverrideId()) // mimicry tag { m_clientName = hub->getClientName(); m_clientVersion = hub->getClientVersion(); } #ifdef IRAINMAN_ENABLE_STEALTH_MODE else if (hub && hub->getStealth()) // stealth DC++ { m_clientName = "++"; m_clientVersion = DCVERSIONSTRING; } #endif else // FlylinkDC native { #ifdef IRAINMAN_ENABLE_SLOTS_AND_LIMIT_IN_DESCRIPTION if (BOOLSETTING(ADD_TO_DESCRIPTION)) { if (BOOLSETTING(ADD_DESCRIPTION_SLOTS)) speedDescription += '[' + Util::toString(UploadManager::getInstance()->getFreeSlots()) + ']'; if (BOOLSETTING(ADD_DESCRIPTION_LIMIT) && BOOLSETTING(THROTTLE_ENABLE) && ThrottleManager::getInstance()->getUploadLimitInKBytes() != 0) speedDescription += "[L:" + Util::toString(ThrottleManager::getInstance()->getUploadLimitInKBytes()) + "KB]"; } #endif m_clientName = APPNAME; m_clientVersion = A_SHORT_VERSIONSTRING; if (CompatibilityManager::isWine()) { m_clientVersion += "-wine"; } } // [~] FlylinkDC mimicry function if (hub) { if (updateNick) { string l_nick = hub->getNick(true); checkNick(l_nick); setCurrentNick(l_nick); } if (!hub->getUserDescription().empty()) { setCurrentDescription( #ifdef IRAINMAN_ENABLE_SLOTS_AND_LIMIT_IN_DESCRIPTION speedDescription + #endif hub->getUserDescription()); } else { setCurrentDescription( #ifdef IRAINMAN_ENABLE_SLOTS_AND_LIMIT_IN_DESCRIPTION speedDescription + #endif SETTING(DESCRIPTION)); } if (!hub->getEmail().empty()) { setCurrentEmail(hub->getEmail()); } else { setCurrentEmail(SETTING(EMAIL)); } if (!hub->getPassword().empty()) { setPassword(hub->getPassword()); } #ifdef IRAINMAN_ENABLE_STEALTH_MODE setStealth(hub->getStealth()); #endif //[+]FlylinkDC #ifdef IRAINMAN_INCLUDE_HIDE_SHARE_MOD setHideShare(hub->getHideShare()); #endif setFavIp(hub->getIP()); if (!hub->getEncoding().empty()) { setEncoding(hub->getEncoding()); } if (hub->getSearchInterval() < 2) // [!]FlylinkDC changed 10 to 2 { setSearchInterval(SETTING(MINIMUM_SEARCH_INTERVAL) * 1000); } else { setSearchInterval(hub->getSearchInterval() * 1000); } // [+] IRainman fix. m_opChat = hub->getOpChat(); m_exclChecks = hub->getExclChecks(); // [~] IRainman fix. } else { if (updateNick) { string l_nick = SETTING(NICK); checkNick(l_nick); setCurrentNick(l_nick); } setCurrentDescription( #ifdef IRAINMAN_ENABLE_SLOTS_AND_LIMIT_IN_DESCRIPTION speedDescription + #endif SETTING(DESCRIPTION)); setCurrentEmail(SETTING(EMAIL)); #ifdef IRAINMAN_ENABLE_STEALTH_MODE setStealth(false); #endif #ifdef IRAINMAN_INCLUDE_HIDE_SHARE_MOD setHideShare(false); #endif setFavIp(Util::emptyString); setSearchInterval(SETTING(MINIMUM_SEARCH_INTERVAL) * 1000); // [+] IRainman fix. m_opChat.clear(); m_exclChecks = false; // [~] IRainman fix. } /* [-] IRainman mimicry function // !SMT!-S for (string::size_type i = 0; i < ClientId.length(); i++) if (ClientId[i] == '<' || ClientId[i] == '>' || ClientId[i] == ',' || ClientId[i] == '$' || ClientId[i] == '|') { ClientId = ClientId.substr(0, i); break; } */ // [~] IRainman mimicry function return hub; }
void Client::on(Failed, const string& aLine) throw() { state = STATE_DISCONNECTED; FavoriteManager::getInstance()->removeUserCommand(getHubUrl()); sock->removeListener(this); fire(ClientListener::Failed(), this, aLine); }