toolTip.append(QString("Server: %1").arg(currentServer()));
toolTip.append(QString("Users: %1").arg(nickCount()));
+ if(_network) {
+ toolTip.append(QString("Lag: %1 msecs").arg(_network->latency()));
+ }
+
return QString("<p> %1 </p>").arg(toolTip.join("<br />"));
}
_networkId(networkid),
_identity(0),
_myNick(QString()),
+ _latency(0),
_networkName(QString("<not initialized>")),
_currentServer(QString()),
_connected(false),
emit myNickSet(nickname);
}
+void Network::setLatency(int latency) {
+ if(_latency == latency)
+ return;
+ _latency = latency;
+ emit latencySet(latency);
+}
+
void Network::setIdentity(IdentityId id) {
_identity = id;
emit identitySet(id);
Q_PROPERTY(QString networkName READ networkName WRITE setNetworkName STORED false)
Q_PROPERTY(QString currentServer READ currentServer WRITE setCurrentServer STORED false)
Q_PROPERTY(QString myNick READ myNick WRITE setMyNick STORED false)
+ Q_PROPERTY(int latency READ latency WRITE setLatency STORED false)
Q_PROPERTY(QByteArray codecForServer READ codecForServer WRITE setCodecForServer STORED false)
Q_PROPERTY(QByteArray codecForEncoding READ codecForEncoding WRITE setCodecForEncoding STORED false)
Q_PROPERTY(QByteArray codecForDecoding READ codecForDecoding WRITE setCodecForDecoding STORED false)
inline const QString &networkName() const { return _networkName; }
inline const QString ¤tServer() const { return _currentServer; }
inline const QString &myNick() const { return _myNick; }
+ inline const int latency() const { return _latency; }
inline IrcUser *me() const { return ircUser(myNick()); }
inline IdentityId identity() const { return _identity; }
QStringList nicks() const;
//void setConnectionState(Network::ConnectionState state);
void setConnectionState(int state);
void setMyNick(const QString &mynick);
+ void setLatency(int latency);
void setIdentity(IdentityId);
void setServerList(const QVariantList &serverList);
void connectionStateSet(int);
void connectionError(const QString &errorMsg);
void myNickSet(const QString &mynick);
+ void latencySet(int latency);
void identitySet(IdentityId);
void serverListSet(QVariantList serverList);
IdentityId _identity;
QString _myNick;
+ int _latency;
QString _networkName;
QString _currentServer;
bool _connected;
QHash<QIODevice *, peerInfo>::iterator peerIterEnd = _peers.end();
while(peerIter != peerIterEnd) {
if(peerIter->sentHeartBeats > 0) {
- updateLag(peerIter.key(), (float)_heartBeatTimer.interval());
+ updateLag(peerIter.key(), _heartBeatTimer.interval());
}
if(peerIter->sentHeartBeats > 1) {
QAbstractSocket *socket = qobject_cast<QAbstractSocket *>(peerIter.key());
}
QTime sendTime = params[0].value<QTime>();
- updateLag(dev, (float)sendTime.msecsTo(QTime::currentTime()) / 2);
+ updateLag(dev, sendTime.msecsTo(QTime::currentTime()) / 2);
}
-void SignalProxy::updateLag(QIODevice *dev, float lag) {
+void SignalProxy::updateLag(QIODevice *dev, int lag) {
Q_ASSERT(_peers.contains(dev));
_peers[dev].lag = lag;
if(proxyMode() == Client) {
void connected();
void disconnected();
void objectInitialized(SyncableObject *);
- void lagUpdated(float lag);
+ void lagUpdated(int lag);
private:
void init();
QVariantMap initData(SyncableObject *obj) const;
void setInitData(SyncableObject *obj, const QVariantMap &properties);
- void updateLag(QIODevice *dev, float lag);
+ void updateLag(QIODevice *dev, int lag);
public:
void dumpSyncMap(SyncableObject *object);
quint32 byteCount;
bool usesCompression;
int sentHeartBeats;
- float lag;
+ int lag;
peerInfo() : byteCount(0), usesCompression(false), sentHeartBeats(0) {}
};
//QHash<QIODevice*, peerInfo> _peerByteCount;
putCmd("PONG", params);
}
+void IrcServerHandler::handlePong(const QString &prefix, const QList<QByteArray> ¶ms) {
+ Q_UNUSED(prefix);
+ // the server is supposed to send back what we passed as param. and we send a timestamp
+ // but using quote and whatnought one can send arbitrary pings, so we have to do some sanity checks
+ if(params.count() < 2)
+ return;
+
+ QString timestamp = serverDecode(params[1]);
+ QTime sendTime = QTime::fromString(timestamp, "hh:mm:ss.zzz");
+ if(!sendTime.isValid()) {
+ emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", "PONG " + serverDecode(params).join(" "), prefix);
+ return;
+ }
+
+ network()->setLatency(sendTime.msecsTo(QTime::currentTime()) / 2);
+}
+
void IrcServerHandler::handlePrivmsg(const QString &prefix, const QList<QByteArray> ¶ms) {
if(!checkParamCount("IrcServerHandler::handlePrivmsg()", params, 1))
return;
void handleNotice(const QString &prefix, const QList<QByteArray> ¶ms);
void handlePart(const QString &prefix, const QList<QByteArray> ¶ms);
void handlePing(const QString &prefix, const QList<QByteArray> ¶ms);
+ void handlePong(const QString &prefix, const QList<QByteArray> ¶ms);
void handlePrivmsg(const QString &prefix, const QList<QByteArray> ¶ms);
void handleQuit(const QString &prefix, const QList<QByteArray> ¶ms);
void handleTopic(const QString &prefix, const QList<QByteArray> ¶ms);
_autoReconnectTimer.setSingleShot(true);
_socketCloseTimer.setSingleShot(true);
connect(&_socketCloseTimer, SIGNAL(timeout()), this, SLOT(socketCloseTimeout()));
-
+
+ _pingTimer.setInterval(60000);
+ connect(&_pingTimer, SIGNAL(timeout()), this, SLOT(sendPing()));
+
_autoWhoTimer.setInterval(_autoWhoDelay * 1000);
_autoWhoCycleTimer.setInterval(_autoWhoInterval * 1000);
network()->setConnected(true);
emit connected(networkId());
+ _pingTimer.start();
+
if(_autoWhoEnabled) {
_autoWhoCycleTimer.start();
_autoWhoTimer.start();
putRawLine(msg);
}
+void NetworkConnection::sendPing() {
+ userInputHandler()->handlePing(BufferInfo(), QString());
+}
+
void NetworkConnection::sendAutoWho() {
while(!_autoWhoQueue.isEmpty()) {
QString chan = _autoWhoQueue.takeFirst();
void sendPerform();
void autoReconnectSettingsChanged();
void doAutoReconnect();
+ void sendPing();
void sendAutoWho();
void startAutoWhoCycle();
void nickChanged(const QString &newNick, const QString &oldNick); // this signal is inteded to rename query buffers in the storage backend
bool _previousConnectionAttemptFailed;
int _lastUsedServerlistIndex;
+ QTimer _pingTimer;
+
bool _autoWhoEnabled;
QStringList _autoWhoQueue;
QHash<QString, int> _autoWhoInProgress;
emit putCmd("PART", params);
}
+void UserInputHandler::handlePing(const BufferInfo &bufferInfo, const QString &msg) {
+ Q_UNUSED(bufferInfo)
+
+ QString param = msg;
+ if(param.isEmpty())
+ param = QTime::currentTime().toString("hh:mm:ss.zzz");
+
+ putCmd("PING", serverEncode(param));
+}
+
// TODO: implement queries
void UserInputHandler::handleQuery(const BufferInfo &bufferInfo, const QString &msg) {
Q_UNUSED(bufferInfo)
void handleOper(const BufferInfo &bufferInfo, const QString &text);
void handleOp(const BufferInfo &bufferInfo, const QString &text);
void handlePart(const BufferInfo &bufferInfo, const QString &text);
+ void handlePing(const BufferInfo &bufferInfo, const QString &text);
void handleQuery(const BufferInfo &bufferInfo, const QString &text);
void handleQuit(const BufferInfo &bufferInfo, const QString &text);
void handleQuote(const BufferInfo &bufferInfo, const QString &text);
// Core Lag:
updateLagIndicator(0);
statusBar()->addPermanentWidget(coreLagLabel);
- connect(Client::signalProxy(), SIGNAL(lagUpdated(float)), this, SLOT(updateLagIndicator(float)));
+ connect(Client::signalProxy(), SIGNAL(lagUpdated(int)), this, SLOT(updateLagIndicator(int)));
// SSL indicator
connect(Client::instance(), SIGNAL(securedConnection()), this, SLOT(securedConnection()));
if(accountId > 0) s.setValue(QString("MainWinState-%1").arg(accountId) , saveState(accountId));
}
-void MainWin::updateLagIndicator(float lag) {
+void MainWin::updateLagIndicator(int lag) {
coreLagLabel->setText(QString("Core Lag: %1 msec").arg(lag));
}
protected slots:
void connectedToCore();
void setConnectedState();
- void updateLagIndicator(float lag);
+ void updateLagIndicator(int lag);
void securedConnection();
void disconnectedFromCore();
void setDisconnectedState();