int OnlineUserUtils::compareUsers(const OnlineUserPtr& a, const OnlineUserPtr& b, int aPropertyName) noexcept { switch (aPropertyName) { case HubInfo::PROP_NICK: { bool a_isOp = a->getIdentity().isOp(), b_isOp = b->getIdentity().isOp(); if (a_isOp && !b_isOp) return -1; if (!a_isOp && b_isOp) return 1; if (SETTING(SORT_FAVUSERS_FIRST)) { bool a_isFav = a->getUser()->isFavorite(), b_isFav = b->getUser()->isFavorite(); if (a_isFav && !b_isFav) return -1; if (!a_isFav && b_isFav) return 1; } return Util::DefaultSort(a->getIdentity().getNick(), b->getIdentity().getNick()); } default: dcassert(0); } return 0; }
void UserManager::checkUser(const OnlineUserPtr& user) { if (BOOLSETTING(CHECK_NEW_USERS)) { if (!ClientManager::getInstance()->isMe(user)) { const Client& client = user->getClient(); if (!client.getExcludeCheck() && client.isOp() && (client.isActive() || user->getIdentity().isTcpActive())) { if (!BOOLSETTING(PROT_FAVS) || !FavoriteManager::getInstance()->isNoFavUserOrUserBanUpload(user->getUser())) // !SMT!-opt { if (!isInProtectedUserList(user->getIdentity().getNick())) { try { QueueManager::getInstance()->addList(HintedUser(user->getUser(), client.getHubUrl()), QueueItem::FLAG_USER_CHECK); } catch (const Exception& e) { LogManager::getInstance()->message(e.getError()); } } } } } } }
double OnlineUserUtils::getNumericInfo(const OnlineUserPtr& aUser, int aPropertyName) noexcept { switch (aPropertyName) { case PROP_SHARED: return Util::toDouble(aUser->getIdentity().getShareSize()); case PROP_UPLOAD_SPEED: return (double)aUser->getIdentity().getAdcConnectionSpeed(false); case PROP_DOWNLOAD_SPEED: return (double)aUser->getIdentity().getAdcConnectionSpeed(true); case PROP_FILES: return Util::toDouble(aUser->getIdentity().getSharedFiles()); case PROP_UPLOAD_SLOTS: return aUser->getIdentity().getSlots(); default: dcassert(0); return 0; } }
std::string OnlineUserUtils::getStringInfo(const OnlineUserPtr& aUser, int aPropertyName) noexcept { switch (aPropertyName) { case HubInfo::PROP_NICK: return aUser->getIdentity().getNick(); case HubInfo::PROP_DESCRIPTION: return aUser->getIdentity().getDescription(); case HubInfo::PROP_EMAIL: return aUser->getIdentity().getEmail(); case HubInfo::PROP_TAG: return aUser->getIdentity().getTag(); case HubInfo::PROP_HUB_URL: return aUser->getHubUrl(); case HubInfo::PROP_HUB_NAME: return aUser->getClient()->getHubName(); case HubInfo::PROP_IP4: return aUser->getIdentity().getIp4(); case HubInfo::PROP_IP6: return aUser->getIdentity().getIp6(); case HubInfo::PROP_CID: return aUser->getUser()->getCID().toBase32(); default: dcassert(0); return 0; } }
json OnlineUserUtils::serializeUser(const OnlineUserPtr& aUser, int aPropertyName) noexcept { switch (aPropertyName) { case HubInfo::PROP_IP4: return Serializer::serializeIp(aUser->getIdentity().getIp4()); case HubInfo::PROP_IP6: return Serializer::serializeIp(aUser->getIdentity().getIp6()); case HubInfo::PROP_FLAGS: return Serializer::getOnlineUserFlags(aUser); } return nullptr; }
void Serializer::appendOnlineUserFlags(const OnlineUserPtr& aUser, StringSet& flags_) noexcept { if (aUser->getIdentity().isAway()) { flags_.insert("away"); } if (aUser->getIdentity().isOp()) { flags_.insert("op"); } if (aUser->getIdentity().isBot() || aUser->getIdentity().isHub()) { flags_.insert("bot"); } if (aUser->isHidden()) { flags_.insert("hidden"); } if (aUser->supportsCCPM()) { flags_.insert("ccpm"); } auto cm = aUser->getIdentity().getConnectMode(); if (!aUser->getUser()->isNMDC() && (cm == Identity::MODE_NOCONNECT_PASSIVE || cm == Identity::MODE_NOCONNECT_IP || cm == Identity::MODE_UNDEFINED)) { flags_.insert("noconnect"); } else if (!aUser->getIdentity().isTcpActive(aUser->getClient())) { flags_.insert("passive"); } }
void ChatCtrl::runUserCommand(UserCommand& uc) { StringMap ucParams; if(!WinUtil::getUCParams(m_hWnd, uc, ucParams)) return; client->getMyIdentity().getParams(ucParams, "my", true); client->getHubIdentity().getParams(ucParams, "hub", false); const OnlineUserPtr ou = client->findUser(Text::fromT(selectedUser)); if(ou != NULL) { StringMap tmp = ucParams; ou->getIdentity().getParams(tmp, "user", true); client->escapeParams(tmp); client->sendUserCmd(uc, tmp); } }
LRESULT ChatCtrl::onOpenUserLog(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) { OnlineUserPtr ou = client->findUser(Text::fromT(selectedUser)); if(ou) { StringMap params; params["userNI"] = ou->getIdentity().getNick(); params["hubNI"] = client->getHubName(); params["myNI"] = client->getMyNick(); params["userCID"] = ou->getUser()->getCID().toBase32(); params["hubURL"] = client->getHubUrl(); tstring file = Text::toT(Util::validateFileName(SETTING(LOG_DIRECTORY) + Util::formatParams(SETTING(LOG_FILE_PRIVATE_CHAT), params, false))); if(Util::fileExists(Text::fromT(file))) { ShellExecute(NULL, NULL, file.c_str(), NULL, NULL, SW_SHOWNORMAL); } else { MessageBox(CTSTRING(NO_LOG_FOR_USER),CTSTRING(NO_LOG_FOR_USER), MB_OK ); } } return 0; }
LRESULT ChatCtrl::onReport(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) { const OnlineUserPtr ou = client->findUser(Text::fromT(selectedUser)); if(ou) { CHARFORMAT2 cf; memzero(&cf, sizeof(CHARFORMAT2)); cf.cbSize = sizeof(cf); cf.dwMask = CFM_BACKCOLOR | CFM_COLOR | CFM_BOLD; cf.crBackColor = SETTING(BACKGROUND_COLOR); cf.crTextColor = SETTING(ERROR_COLOR); AppendText(Identity(NULL, 0), Text::toT(client->getCurrentNick()), Text::toT("[" + Util::getShortTimeString() + "] "), Text::toT(WinUtil::getReport(ou->getIdentity(), m_hWnd)) + _T('\n'), cf, false); } return 0; }
void ChatCtrl::AppendText(const Identity& i, const tstring& sMyNick, const tstring& sTime, tstring sMsg, CHARFORMAT2& cf, bool bUseEmo/* = true*/) { SetRedraw(FALSE); SCROLLINFO si = { 0 }; POINT pt = { 0 }; si.cbSize = sizeof(si); si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS; GetScrollInfo(SB_VERT, &si); GetScrollPos(&pt); LONG lSelBegin = 0, lSelEnd = 0, lTextLimit = 0, lNewTextLen = 0; LONG lSelBeginSaved, lSelEndSaved; // Unify line endings tstring::size_type j = 0; while((j = sMsg.find(_T("\r"), j)) != tstring::npos) sMsg.erase(j, 1); GetSel(lSelBeginSaved, lSelEndSaved); lSelEnd = lSelBegin = GetTextLengthEx(GTL_NUMCHARS); bool isMyMessage = i.getUser() == ClientManager::getInstance()->getMe(); tstring sLine = sTime + sMsg; // Remove old chat if size exceeds lNewTextLen = sLine.size(); lTextLimit = GetLimitText(); if(lSelEnd + lNewTextLen > lTextLimit) { LONG lRemoveChars = 0; int multiplier = 1; if(lNewTextLen >= lTextLimit) { lRemoveChars = lSelEnd; magnets.clear(); } else { while(lRemoveChars < lNewTextLen) lRemoveChars = LineIndex(LineFromChar(multiplier++ * lTextLimit / 10)); } if(magnets.size()) { tstring buf; buf.resize(lRemoveChars); GetTextRange(0, lRemoveChars, &buf[0]); CHARFORMAT2 cfSel; cfSel.cbSize = sizeof(CHARFORMAT2); for(TStringMap::iterator i = magnets.begin(); i != magnets.end();) { tstring::size_type j = 0; while((j = buf.find(i->first, j)) != tstring::npos) { SetSel(j, j + i->first.size()); GetSelectionCharFormat(cfSel); if(cfSel.dwEffects & CFE_LINK) { magnets.erase(i++); break; } j += i->first.size(); } if(j == tstring::npos) { ++i; } } } // Update selection ranges lSelEnd = lSelBegin -= lRemoveChars; lSelEndSaved -= lRemoveChars; lSelBeginSaved -= lRemoveChars; // ...and the scroll position pt.y -= PosFromChar(lRemoveChars).y; SetSel(0, lRemoveChars); ReplaceSel(_T("")); } // Add to the end SetSel(lSelBegin, lSelEnd); setText(sLine); CHARFORMAT2 enc; enc.bCharSet = RUSSIAN_CHARSET; enc.dwMask = CFM_CHARSET; SetSel(0, sLine.length()); SetSelectionCharFormat(enc); // Format TimeStamp if(!sTime.empty()) { lSelEnd += sTime.size(); SetSel(lSelBegin, lSelEnd - 1); SetSelectionCharFormat(WinUtil::m_TextStyleTimestamp); PARAFORMAT2 pf; memzero(&pf, sizeof(PARAFORMAT2)); pf.dwMask = PFM_STARTINDENT; pf.dxStartIndent = 0; SetParaFormat(pf); } // Authors nick tstring sAuthor = Text::toT(i.getNick()); if(!sAuthor.empty()) { LONG iLen = (sMsg[0] == _T('*')) ? 1 : 0; LONG iAuthorLen = sAuthor.size() + 1; sMsg.erase(0, iAuthorLen + iLen); lSelBegin = lSelEnd; lSelEnd += iAuthorLen + iLen; if(isMyMessage) { SetSel(lSelBegin, lSelBegin + iLen + 1); SetSelectionCharFormat(WinUtil::m_ChatTextMyOwn); SetSel(lSelBegin + iLen + 1, lSelBegin + iLen + iAuthorLen); SetSelectionCharFormat(WinUtil::m_TextStyleMyNick); } else { bool isFavorite = FavoriteManager::getInstance()->isFavoriteUser(i.getUser()); if(BOOLSETTING(BOLD_AUTHOR_MESS) || isFavorite || i.isOp()) { SetSel(lSelBegin, lSelBegin + iLen + 1); SetSelectionCharFormat(cf); SetSel(lSelBegin + iLen + 1, lSelEnd); if(isFavorite){ SetSelectionCharFormat(WinUtil::m_TextStyleFavUsers); } else if(i.isOp()) { SetSelectionCharFormat(WinUtil::m_TextStyleOPs); } else { SetSelectionCharFormat(WinUtil::m_TextStyleBold); } } else { SetSel(lSelBegin, lSelEnd); SetSelectionCharFormat(cf); } } } else { bool thirdPerson = false; switch(sMsg[0]) { case _T('*'): if(sMsg[1] != _T(' ')) break; thirdPerson = true; case _T('<'): tstring::size_type iAuthorLen = sMsg.find(thirdPerson ? _T(' ') : _T('>'), thirdPerson ? 2 : 1); if(iAuthorLen != tstring::npos) { bool isOp = false, isFavorite = false; if(client != NULL) { tstring nick(sMsg.c_str() + 1); nick.erase(iAuthorLen - 1); const OnlineUserPtr ou = client->findUser(Text::fromT(nick)); if(ou != NULL) { isFavorite = FavoriteManager::getInstance()->isFavoriteUser(ou->getUser()); isOp = ou->getIdentity().isOp(); } } lSelBegin = lSelEnd; lSelEnd += iAuthorLen; sMsg.erase(0, iAuthorLen); if(BOOLSETTING(BOLD_AUTHOR_MESS) || isFavorite || isOp) { SetSel(lSelBegin, lSelBegin + 1); SetSelectionCharFormat(cf); SetSel(lSelBegin + 1, lSelEnd); if(isFavorite){ SetSelectionCharFormat(WinUtil::m_TextStyleFavUsers); } else if(isOp) { SetSelectionCharFormat(WinUtil::m_TextStyleOPs); } else { SetSelectionCharFormat(WinUtil::m_TextStyleBold); } } else { SetSel(lSelBegin, lSelEnd); SetSelectionCharFormat(cf); } } } } // Format the message part FormatChatLine(sMyNick, sMsg, cf, isMyMessage, sAuthor, lSelEnd, bUseEmo); SetSel(lSelBeginSaved, lSelEndSaved); if( isMyMessage || ((si.nPage == 0 || (size_t)si.nPos >= (size_t)si.nMax - si.nPage - 5) && (lSelBeginSaved == lSelEndSaved || !selectedUser.empty() || !selectedIP.empty() || !selectedURL.empty()))) { PostMessage(EM_SCROLL, SB_BOTTOM, 0); } else { SetScrollPos(&pt); } // Force window to redraw SetRedraw(TRUE); InvalidateRect(NULL); }
bool OnlineUser::NickSort::operator()(const OnlineUserPtr& left, const OnlineUserPtr& right) const { return compare(left->getIdentity().getNick(), right->getIdentity().getNick()) < 0; }