1
/* Copyright (C) 2005-2011, Thorvald Natvig <thorvald@natvig.com>
5
Redistribution and use in source and binary forms, with or without
6
modification, are permitted provided that the following conditions
9
- Redistributions of source code must retain the above copyright notice,
10
this list of conditions and the following disclaimer.
11
- Redistributions in binary form must reproduce the above copyright notice,
12
this list of conditions and the following disclaimer in the documentation
13
and/or other materials provided with the distribution.
14
- Neither the name of the Mumble Developers nor the names of its
15
contributors may be used to endorse or promote products derived from this
16
software without specific prior written permission.
18
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
22
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
#include "mumble_pch.hpp"
33
#include "UserInformation.h"
38
#include "ServerHandler.h"
41
static QString decode_utf8_qssl_string(const QString &input) {
43
return QUrl::fromPercentEncoding(i.replace(QLatin1String("\\x"), QLatin1String("%")).toLatin1());
46
UserInformation::UserInformation(const MumbleProto::UserStats &msg, QWidget *p) : QDialog(p) {
49
uiSession = msg.session();
51
qtTimer = new QTimer(this);
52
connect(qtTimer, SIGNAL(timeout()), this, SLOT(tick()));
55
qgbConnection->setVisible(false);
57
qlOpus->setText(tr("Not Reported"));
62
qfCertificateFont = qlCertificate->font();
65
unsigned int UserInformation::session() const {
69
void UserInformation::tick() {
75
g.sh->requestUserStats(uiSession, true);
78
void UserInformation::on_qpbCertificate_clicked() {
79
ViewCert *vc = new ViewCert(qlCerts, this);
80
vc->setWindowModality(Qt::WindowModal);
81
vc->setAttribute(Qt::WA_DeleteOnClose, true);
85
QString UserInformation::secsToString(unsigned int secs) {
88
int weeks = secs / (60 * 60 * 24 * 7);
89
secs = secs % (60 * 60 * 24 * 7);
90
int days = secs / (60 * 60 * 24);
91
secs = secs % (60 * 60 * 24);
92
int hours = secs / (60 * 60);
93
secs = secs % (60 * 60);
94
int minutes = secs / 60;
95
int seconds = secs % 60;
98
qsl << tr("%1w").arg(weeks);
100
qsl << tr("%1d").arg(days);
102
qsl << tr("%1h").arg(hours);
103
if (minutes || hours)
104
qsl << tr("%1m").arg(minutes);
105
qsl << tr("%1s").arg(seconds);
107
return qsl.join(QLatin1String(" "));
110
void UserInformation::update(const MumbleProto::UserStats &msg) {
113
bool showcon = false;
115
ClientUser *cu = ClientUser::get(uiSession);
117
setWindowTitle(cu->qsName);
119
if (msg.certificates_size() > 0) {
122
for (int i=0;i<msg.certificates_size(); ++i) {
123
const std::string &s = msg.certificates(i);
124
QList<QSslCertificate> certs = QSslCertificate::fromData(QByteArray(s.data(), s.length()), QSsl::Der);
127
if (! qlCerts.isEmpty()) {
128
qpbCertificate->setEnabled(true);
130
const QSslCertificate &cert = qlCerts.last();
131
const QMultiMap<QSsl::AlternateNameEntryType, QString> &alts = cert.alternateSubjectNames();
133
if (alts.contains(QSsl::EmailEntry))
134
qlCertificate->setText(QStringList(alts.values(QSsl::EmailEntry)).join(tr(", ")));
136
qlCertificate->setText(decode_utf8_qssl_string(cert.subjectInfo(QSslCertificate::CommonName)));
138
if (msg.strong_certificate()) {
139
QFont f = qfCertificateFont;
141
qlCertificate->setFont(f);
143
qlCertificate->setFont(qfCertificateFont);
146
qpbCertificate->setEnabled(false);
147
qlCertificate->setText(QString());
150
if (msg.has_address()) {
152
HostAddress ha(msg.address());
153
qlAddress->setText(ha.toString());
155
if (msg.has_version()) {
158
const MumbleProto::Version &mpv = msg.version();
160
qlVersion->setText(tr("%1 (%2)").arg(MumbleVersion::toString(mpv.version())).arg(u8(mpv.release())));
161
qlOS->setText(tr("%1 (%2)").arg(u8(mpv.os())).arg(u8(mpv.os_version())));
163
if (msg.celt_versions_size() > 0) {
165
for (int i=0;i<msg.celt_versions_size(); ++i) {
166
int v = msg.celt_versions(i);
167
CELTCodec *cc = g.qmCodecs.value(v);
169
qsl << cc->version();
171
qsl << QString::number(v, 16);
173
qlCELT->setText(qsl.join(tr(", ")));
175
if (msg.has_opus()) {
176
qlOpus->setText(msg.opus() ? tr("Supported") : tr("Not Supported"));
179
qgbConnection->setVisible(true);
181
qlTCPCount->setText(QString::number(msg.tcp_packets()));
182
qlUDPCount->setText(QString::number(msg.udp_packets()));
184
qlTCPAvg->setText(QString::number(msg.tcp_ping_avg(), 'f', 2));
185
qlUDPAvg->setText(QString::number(msg.udp_ping_avg(), 'f', 2));
187
qlTCPVar->setText(QString::number(msg.tcp_ping_var() > 0.0f ? sqrtf(msg.tcp_ping_var()) : 0.0f, 'f', 2));
188
qlUDPVar->setText(QString::number(msg.udp_ping_var() > 0.0f ? sqrtf(msg.udp_ping_var()) : 0.0f, 'f', 2));
190
if (msg.has_from_client() && msg.has_from_server()) {
191
qgbUDP->setVisible(true);
192
const MumbleProto::UserStats_Stats &from = msg.from_client();
193
qlFromGood->setText(QString::number(from.good()));
194
qlFromLate->setText(QString::number(from.late()));
195
qlFromLost->setText(QString::number(from.lost()));
196
qlFromResync->setText(QString::number(from.resync()));
198
const MumbleProto::UserStats_Stats &to = msg.from_server();
199
qlToGood->setText(QString::number(to.good()));
200
qlToLate->setText(QString::number(to.late()));
201
qlToLost->setText(QString::number(to.lost()));
202
qlToResync->setText(QString::number(to.resync()));
204
quint32 allFromPackets = from.good() + from.late() + from.lost();
205
qlFromLatePercent->setText(QString::number(allFromPackets > 0 ? from.late() * 100.0f / allFromPackets : 0.f, 'f', 2));
206
qlFromLostPercent->setText(QString::number(allFromPackets > 0 ? from.lost() * 100.0f / allFromPackets : 0.f, 'f', 2));
208
quint32 allToPackets = to.good() + to.late() + to.lost();
209
qlToLatePercent->setText(QString::number(allToPackets > 0 ? to.late() * 100.0f / allToPackets : 0.f, 'f', 2));
210
qlToLostPercent->setText(QString::number(allToPackets > 0 ? to.lost() * 100.0f / allToPackets : 0.f, 'f', 2));
212
qgbUDP->setVisible(false);
215
if (msg.has_onlinesecs()) {
216
if (msg.has_idlesecs())
217
qlTime->setText(tr("%1 online (%2 idle)").arg(secsToString(msg.onlinesecs()), secsToString(msg.idlesecs())));
219
qlTime->setText(tr("%1 online").arg(secsToString(msg.onlinesecs())));
221
if (msg.has_bandwidth()) {
222
qlBandwidth->setVisible(true);
223
qliBandwidth->setVisible(true);
224
qlBandwidth->setText(tr("%1 kbit/s").arg(msg.bandwidth() / 125.0f, 0, 'f', 1));
226
qlBandwidth->setVisible(false);
227
qliBandwidth->setVisible(false);
228
qlBandwidth->setText(QString());