QString Conference::seen(const QString&n, bool ext) { Nick* nick=myNicks.byName(n); // int cnt=0; if (nick) { return QString("\"%1\" is already in room (Joined %2 ago)").arg(n) .arg(secsToString(nick->joined().secsTo(QDateTime::currentDateTime()))); } QSqlQuery query=DataStorage::instance() ->prepareQuery("SELECT jid FROM conference_nicks WHERE conference_id=? AND nick=? ORDER BY lastaction DESC LIMIT 1"); query.addBindValue(myId); query.addBindValue(n); if (query.exec() && query.next()) { int jid=query.value(0).toInt(); query.prepare("SELECT online, nick, lastaction, joined, jid FROM conference_nicks WHERE " "conference_id=? AND jid=? ORDER BY lastaction DESC LIMIT 1"); query.addBindValue(myId); query.addBindValue(jid); if (query.exec() && query.next()) { bool online=query.value(0).toBool(); QString newNick=query.value(1).toString(); QDateTime lastAction=query.value(2).toDateTime(); QDateTime joinedTime=query.value(3).toDateTime(); int jidId = query.value(4).toInt(); if (online) return QString("%1 is here with nick \"%2\" (Joined %3 ago)").arg(n).arg(newNick) .arg(secsToString(joinedTime.secsTo(QDateTime::currentDateTime()))); QString secs=secsToString(lastAction.secsTo(QDateTime::currentDateTime())); QString token("was here"); QString reason; QString version; if (jidId > 0) { // Query for some stat information; JidStat *stat = JidStat::queryReadOnly(jidId); if (stat) { JidStat::StatAction act = stat->lastAction(); delete stat; stat = NULL; switch (act.type) { case ActionKick: token = "was kicked"; break; case ActionBan: token = "was banned"; break; } reason = act.reason; if (!act.verName.isEmpty()) { version = act.verName; if (!act.verVersion.isEmpty()) version+=" " + act.verVersion; if (!act.verOs.isEmpty() && ext) version+=" // " + act.verOs; } } } QString reply; if (newNick == n) reply = QString("%1 %2 %3 ago").arg(n, token, secs); else reply = QString("%1 %2 %3 ago with nick \"%4\"").arg(n, token, secs, newNick); if (!reason.isEmpty()) reply += QString(" (%1)").arg(reason); if (!version.isEmpty()) reply += QString(", Client: %1").arg(version); return reply; } } return QString("I never see \"%1\" here").arg(n); }
void UserInformation::update(const MumbleProto::UserStats &msg) { bRequested = false; bool showcon = false; ClientUser *cu = ClientUser::get(uiSession); if (cu) setWindowTitle(cu->qsName); if (msg.certificates_size() > 0) { showcon = true; qlCerts.clear(); for (int i=0;i<msg.certificates_size(); ++i) { const std::string &s = msg.certificates(i); QList<QSslCertificate> certs = QSslCertificate::fromData(QByteArray(s.data(), s.length()), QSsl::Der); qlCerts <<certs; } if (! qlCerts.isEmpty()) { qpbCertificate->setEnabled(true); const QSslCertificate &cert = qlCerts.last(); const QMultiMap<QSsl::AlternateNameEntryType, QString> &alts = cert.alternateSubjectNames(); if (alts.contains(QSsl::EmailEntry)) qlCertificate->setText(QStringList(alts.values(QSsl::EmailEntry)).join(tr(", "))); else qlCertificate->setText(decode_utf8_qssl_string(cert.subjectInfo(QSslCertificate::CommonName))); if (msg.strong_certificate()) { QFont f = qfCertificateFont; f.setBold(true); qlCertificate->setFont(f); } else { qlCertificate->setFont(qfCertificateFont); } } else { qpbCertificate->setEnabled(false); qlCertificate->setText(QString()); } } if (msg.has_address()) { showcon = true; HostAddress ha(msg.address()); qlAddress->setText(ha.toString()); } if (msg.has_version()) { showcon = true; const MumbleProto::Version &mpv = msg.version(); qlVersion->setText(tr("%1 (%2)").arg(MumbleVersion::toString(mpv.version())).arg(u8(mpv.release()))); qlOS->setText(tr("%1 (%2)").arg(u8(mpv.os())).arg(u8(mpv.os_version()))); } if (msg.celt_versions_size() > 0) { QStringList qsl; for (int i=0;i<msg.celt_versions_size(); ++i) { int v = msg.celt_versions(i); CELTCodec *cc = g.qmCodecs.value(v); if (cc) qsl << cc->version(); else qsl << QString::number(v, 16); } qlCELT->setText(qsl.join(tr(", "))); } if (msg.has_opus()) { qlOpus->setText(msg.opus() ? tr("Supported") : tr("Not Supported")); } if (showcon) qgbConnection->setVisible(true); qlTCPCount->setText(QString::number(msg.tcp_packets())); qlUDPCount->setText(QString::number(msg.udp_packets())); qlTCPAvg->setText(QString::number(msg.tcp_ping_avg(), 'f', 2)); qlUDPAvg->setText(QString::number(msg.udp_ping_avg(), 'f', 2)); qlTCPVar->setText(QString::number(msg.tcp_ping_var() > 0.0f ? sqrtf(msg.tcp_ping_var()) : 0.0f, 'f', 2)); qlUDPVar->setText(QString::number(msg.udp_ping_var() > 0.0f ? sqrtf(msg.udp_ping_var()) : 0.0f, 'f', 2)); if (msg.has_from_client() && msg.has_from_server()) { qgbUDP->setVisible(true); const MumbleProto::UserStats_Stats &from = msg.from_client(); qlFromGood->setText(QString::number(from.good())); qlFromLate->setText(QString::number(from.late())); qlFromLost->setText(QString::number(from.lost())); qlFromResync->setText(QString::number(from.resync())); const MumbleProto::UserStats_Stats &to = msg.from_server(); qlToGood->setText(QString::number(to.good())); qlToLate->setText(QString::number(to.late())); qlToLost->setText(QString::number(to.lost())); qlToResync->setText(QString::number(to.resync())); quint32 allFromPackets = from.good() + from.late() + from.lost(); qlFromLatePercent->setText(QString::number(allFromPackets > 0 ? from.late() * 100.0f / allFromPackets : 0.f, 'f', 2)); qlFromLostPercent->setText(QString::number(allFromPackets > 0 ? from.lost() * 100.0f / allFromPackets : 0.f, 'f', 2)); quint32 allToPackets = to.good() + to.late() + to.lost(); qlToLatePercent->setText(QString::number(allToPackets > 0 ? to.late() * 100.0f / allToPackets : 0.f, 'f', 2)); qlToLostPercent->setText(QString::number(allToPackets > 0 ? to.lost() * 100.0f / allToPackets : 0.f, 'f', 2)); } else { qgbUDP->setVisible(false); } if (msg.has_onlinesecs()) { if (msg.has_idlesecs()) qlTime->setText(tr("%1 online (%2 idle)").arg(secsToString(msg.onlinesecs()), secsToString(msg.idlesecs()))); else qlTime->setText(tr("%1 online").arg(secsToString(msg.onlinesecs()))); } if (msg.has_bandwidth()) { qlBandwidth->setVisible(true); qliBandwidth->setVisible(true); qlBandwidth->setText(tr("%1 kbit/s").arg(msg.bandwidth() / 125.0f, 0, 'f', 1)); } else { qlBandwidth->setVisible(false); qliBandwidth->setVisible(false); qlBandwidth->setText(QString()); } }
void ClientInfoDialog::updateText() { QString itemMask = "%1 %2<br>"; QString html = QString("<b>%1</b> (%2)<br><br>").arg(HTML_ESCAPE(FContactName)).arg(HTML_ESCAPE(FContactJid.uFull())); //Software Info if ((FInfoTypes & IClientInfo::SoftwareVersion)>0) { html += "<b>" + tr("Software Version") + "</b><br>"; if (FClientInfo->hasSoftwareInfo(FContactJid)) { html += itemMask.arg(tr("Name:")).arg(HTML_ESCAPE(FClientInfo->softwareName(FContactJid))); if (!FClientInfo->softwareVersion(FContactJid).isEmpty()) html += itemMask.arg(tr("Version:")).arg(HTML_ESCAPE(FClientInfo->softwareVersion(FContactJid))); if (!FClientInfo->softwareOs(FContactJid).isEmpty()) html += itemMask.arg(tr("OS:")).arg(HTML_ESCAPE(FClientInfo->softwareOs(FContactJid))); } else if (FClientInfo->softwareStatus(FContactJid) == IClientInfo::SoftwareError) { html += itemMask.arg(tr("Error:")).arg(FClientInfo->softwareName(FContactJid)); } else { html += tr("Waiting response...") + "<br>"; } html += "<br>"; } //Last Activity if ((FInfoTypes & IClientInfo::LastActivity)>0) { if (!FContactJid.hasNode()) html += "<b>" + tr("Service Uptime") + "</b>"; else if (!FContactJid.hasResource()) html += "<b>" + tr("Last Activity") + "</b>"; else html += "<b>" + tr("Idle Time") + "</b>"; html += "<br>"; if (FClientInfo->hasLastActivity(FContactJid)) { if (!FContactJid.hasNode()) { html += itemMask.arg(tr("Uptime:")).arg(secsToString(FClientInfo->lastActivityTime(FContactJid).secsTo(QDateTime::currentDateTime()))); } else if (!FContactJid.hasResource()) { html += itemMask.arg(tr("Inactive:")).arg(secsToString(FClientInfo->lastActivityTime(FContactJid).secsTo(QDateTime::currentDateTime()))); if (!FClientInfo->lastActivityText(FContactJid).isEmpty()) html += itemMask.arg(tr("Status:")).arg(HTML_ESCAPE(FClientInfo->lastActivityText(FContactJid))); } else { html += itemMask.arg(tr("Idle:")).arg(secsToString(FClientInfo->lastActivityTime(FContactJid).secsTo(QDateTime::currentDateTime()))); } } else if (!FClientInfo->lastActivityText(FContactJid).isEmpty()) { html += itemMask.arg(tr("Error:")).arg(FClientInfo->lastActivityText(FContactJid)); } else { html += tr("Waiting response...") + "<br>"; } html += "<br>"; } //Entity Time if ((FInfoTypes & IClientInfo::EntityTime)>0) { html += "<b>" + tr("Entity Time") + "</b><br>"; if (FClientInfo->hasEntityTime(FContactJid)) { html += itemMask.arg(tr("Time:")).arg(FClientInfo->entityTime(FContactJid).time().toString()); html += itemMask.arg(tr("Delta:")).arg(secsToString(FClientInfo->entityTimeDelta(FContactJid))); html += itemMask.arg(tr("Ping, msec:")).arg(FClientInfo->entityTimePing(FContactJid)); } else if (FClientInfo->entityTimePing(FContactJid) < -1) { html += tr("Waiting response...") + "<br>"; } else { html += tr("Not available") + "<br>"; } html += "<br>"; } ui.tedText->setHtml(html); this->adjustSize(); }
bool UserPlugin::onIq(gloox::Stanza* s) { QString xmlns=QString::fromStdString(s->xmlns()); AsyncRequest* req=bot()->asyncRequests()->byStanza(s); if (s->subtype()==gloox::StanzaIqGet) { if (s->subtype()!=gloox::StanzaIqResult && xmlns=="jabber:iq:version") { //We should send our version sendVersion(s); return true; } if (xmlns=="http://jabber.org/protocol/disco#items") { //Disco items request. Report error; gloox::Stanza *st=gloox::Stanza::createIqStanza(s->from(), s->findAttribute("id"), gloox::StanzaIqError, xmlns.toStdString()); bot()->client()->send(st); } if (s->subtype() != gloox::StanzaIqResult && xmlns=="jabber:iq:time" ) { //We should send our time (XEP-0090) sendTime(s); return true; } if (req) bot()->asyncRequests()->removeAll(req); return true; } if (!req) return false; if (req->plugin()!=this) return false; gloox::Tag* query=s->findChild("query", "xmlns", xmlns.toStdString()); if (!query) { reply(req->stanza(), "Error"); bot()->asyncRequests()->removeAll(req); delete req; return true; } if (xmlns=="jabber:iq:time") { QString msg, time; QString src = bot()->JIDtoNick(QString::fromStdString(s->from().full())); gloox::Tag *display = query->findChild("display"); if(display) { assert(display); time = QString::fromStdString(display->cdata()); } if( time.isEmpty() ) { gloox::Tag *tz = query->findChild("tz"); if(tz) { assert(tz); time = QString::fromStdString(tz->cdata()); } } if( time.isEmpty() ) { gloox::Tag *utc = query->findChild("utc"); if(utc) { assert(utc); QString time = utcToString( QString::fromStdString(utc->cdata()).trimmed(), "ddd, dd MMM yyyy HH:mm:ss"); msg=QString("at %1 there is %2 +0000") .arg(QString::fromStdString(s->from().full())) .arg(time); } } else { if ( msg.isEmpty() && src.isEmpty() ) msg=QString("It's %1 on your watch").arg(time); else if( msg.isEmpty() ) msg=QString("It's %1 on %2's watch").arg(time).arg(src); if( time.isEmpty() ) msg="responce with no data."; } if( s->subtype()==gloox::StanzaIqResult && s->error() == gloox::StanzaErrorUndefined ) reply( req->stanza(), msg ); else if( s->error() == gloox::StanzaErrorRemoteServerNotFound ) reply( req->stanza(), "Recipient is not in the conference room" ); else if( s->error() == gloox::StanzaErrorFeatureNotImplemented ) reply( req->stanza(), "Feature Not Implemented" ); else reply( req->stanza(), "Unable to get time" ); } if (xmlns=="jabber:iq:version") { if (req->name()=="PING") { QString msg; QString src=bot()->JIDtoNick(QString::fromStdString(s->from().full())); double delay=(double)req->time().time().msecsTo(QTime::currentTime()); delay/=1000.0; if (s->subtype()==gloox::StanzaIqResult) msg=QString("Pong from %1 after %2 secs.").arg(src).arg(delay); else msg=QString("Pong from %1's server after %2 secs.").arg(src).arg(delay); reply(req->stanza(), msg); } else if (s->subtype()==gloox::StanzaIqResult) { QString name; QString version; QString os; gloox::Tag* t; t=query->findChild("name"); if (t) name=QString::fromStdString(t->cdata()); t=query->findChild("version"); if (t) version=QString::fromStdString(t->cdata()); t=query->findChild("os"); if (t) os=QString::fromStdString(t->cdata()); QString res=name; if (!version.isEmpty()) res+=QString(" %1").arg(version); if (!os.isEmpty()) res+=QString(" // %1").arg(os); QString src=bot()->JIDtoNick(QString::fromStdString(s->from().full())); if (!src.isEmpty()) src+=" uses "; src+=res; reply(req->stanza(), src); } else { //TODO: Error handling reply(req->stanza(), "Unable to get version"); } } if (xmlns=="http://jabber.org/protocol/disco#items") { if (s->subtype()==gloox::StanzaIqError) reply(req->stanza(), "Unable to query"); else { QList<gloox::Tag*> lst= QList<gloox::Tag*>::fromStdList(query->children()); QStringList strings; bool safeJid=req->name().indexOf('@')<0; int noval=0; for (int i=0; i<lst.count(); i++) { QString name= QString::fromStdString(lst[i]->findAttribute("name")); QString jid= QString::fromStdString(lst[i]->findAttribute("jid")); if (name.isEmpty()) name=jid; if (name.isEmpty()) continue; QString cnt=getValue(name, "^.*\\(([^\\)]+)\\)$"); if (cnt.isEmpty()) { cnt="0"; noval++; } else name=getValue(name,"^(.*)\\([^\\)]+\\)$").trimmed(); bool ok=true; cnt.toInt(&ok); if (!ok) cnt="0"; cnt=cnt.rightJustified(8, '0', true); if (name!=jid && safeJid) name+=QString(" [%1]").arg(jid); strings.append(QString("%1 %2").arg(cnt).arg(name)); } strings.sort(); QStringList replyList; bool haveValues; if (lst.count()) { double perc=((double)noval)/((double)(lst.count())); haveValues=perc<0.2; } int idx=strings.count()-1; for (int i=0; i<strings.count(); i++) { int curIdx=haveValues ? idx : i; int value=strings[curIdx].section(' ',0,0).toInt(); QString name=strings[curIdx].section(' ', 1); idx--; QString item=QString("%1) %2").arg(i+1).arg(name); if (haveValues) item+=QString(": %1").arg(value); replyList.append(item); if (replyList.count()>=100) { replyList.append("..."); break; } } reply(req->stanza(), "Disco items:\n"+replyList.join("\n")); } } if (xmlns=="http://jabber.org/protocol/stats") { // Got statistic to display? if (s->subtype()==gloox::StanzaIqError) reply(req->stanza(), "Unable to query"); else { std::list<gloox::Tag*> childList=query->children(); QStringList statItemList; bool haveValues=true; for (std::list<gloox::Tag*>::iterator it=childList.begin(); it!=childList.end(); ++it) { gloox::Tag* child=*it; if (child->name()!="stat") continue; QString item=QString::fromStdString(child->findAttribute("name")); QString value=QString::fromStdString(child->findAttribute("value")); if (!value.isEmpty()) { item+=QString(": %1").arg(value); QString units=QString::fromStdString(child->findAttribute("units")); if (!units.isEmpty()) item+=QString(" %1").arg(units); } else { gloox::Tag* err=child->findChild("error"); if (err) { value=QString::fromStdString(err->cdata()); if (value.isEmpty()) value=QString::fromStdString(err->xml()); item+=QString(": %1").arg(value); } } if (value.isEmpty()) haveValues=false; statItemList.append(item); } if (req->name()=="STAT" && !haveValues) { // Resubmit query with values information std::string id=bot()->client()->getID(); gloox::Stanza *st2=gloox::Stanza::createIqStanza(s->from(), id, gloox::StanzaIqGet, xmlns.toStdString()); gloox::Tag* query2=st2->findChild("query", "xmlns", xmlns.toStdString()); assert(query2); for (QStringList::iterator it=statItemList.begin(); it!=statItemList.end(); ++it) { QString statItem=*it; query2->addChild(new gloox::Tag("stat","name",statItem.toStdString())); } st2->finalize(); gloox::Stanza *sf=new gloox::Stanza(req->stanza()); sf->addAttribute("id", id); AsyncRequest *req=new AsyncRequest(-1, this, sf, 3600); req->setName("STAT2"); bot()->asyncRequests()->append(req); bot()->client()->send(st2); } else { reply(req->stanza(), QString("Statistic:\n%1").arg(statItemList.join("\n"))); } } } if (xmlns=="jabber:iq:last") { QString value=QString::fromStdString(query->findAttribute("seconds")); bool ok=true; int res=value.toInt(&ok); if (ok==false || value.isEmpty()) reply(req->stanza(),"Unable to query"); else reply(req->stanza(), secsToString(res)); } bot()->asyncRequests()->removeAll(req); delete req; return true; }
QString AListItem::toString() const { QString flags; flags+=isInvert() ? "!" : " "; switch (matcherType()) { case AListItem::MatcherUnknown: flags+="? "; break; case AListItem::MatcherNick: flags+="N "; break; case AListItem::MatcherJid: flags+="J "; break; case AListItem::MatcherBody: flags+="B "; break; case AListItem::MatcherBodySize: flags+="Bs "; break; case AListItem::MatcherResource: flags+="R "; break; case AListItem::MatcherVersion: flags+="V "; break; case AListItem::MatcherVersionName: flags+="Vn"; break; case AListItem::MatcherVersionClient: flags+="Vn"; break; case AListItem::MatcherVersionOs: flags+="Vo"; break; case AListItem::MatcherVCardPhotoSize: flags+="Ps"; break; case AListItem::MatcherAge: flags+="Ag"; break; case AListItem::MatcherRole: flags+="ro"; break; }; switch (testType()) { case AListItem::TestUnknown: flags+="?"; break; case AListItem::TestExact: flags+=" "; break; case AListItem::TestRegExp: flags+="E"; break; case AListItem::TestSubstring: flags+="S"; break; case AListItem::TestGreater: flags+=">"; break; case AListItem::TestLesser: flags+="<"; break; } QString line=QString("%1 %2").arg(flags).arg(value()); if (expire().isValid()) { int delta=QDateTime::currentDateTime().secsTo(expire()); if (delta>0) line+=QString(" [%1]").arg(secsToString(delta)); else line+=QString(" [EXPIRED]"); } if (!reason().isEmpty()) line+=" // "+reason(); if (child_) line+="\n && "+child_->toString(); return line; }