CoreNetwork::~CoreNetwork()
{
- if (connectionState() != Disconnected && connectionState() != Network::Reconnecting)
- disconnectFromIrc(false); // clean up, but this does not count as requested disconnect!
+ // Request a proper disconnect, but don't count as user-requested disconnect
+ if (socketConnected()) {
+ // Only try if the socket's fully connected (not initializing or disconnecting).
+ // Force an immediate disconnect, jumping the command queue. Ensures the proper QUIT is
+ // shown even if other messages are queued.
+ disconnectFromIrc(false, QString(), false, true);
+ // Process the putCmd events that trigger the quit. Without this, shutting down the core
+ // results in abrubtly closing the socket rather than sending the QUIT as expected.
+ QCoreApplication::processEvents();
+ // Wait briefly for each network to disconnect. Sometimes it takes a little while to send.
+ if (!forceDisconnect()) {
+ qWarning() << "Timed out quitting network" << networkName() <<
+ "(user ID " << userId() << ")";
+ }
+ }
disconnect(&socket, 0, this, 0); // this keeps the socket from triggering events during clean up
delete _userInputHandler;
}
+bool CoreNetwork::forceDisconnect(int msecs)
+{
+ if (socket.state() == QAbstractSocket::UnconnectedState) {
+ // Socket already disconnected.
+ return true;
+ }
+ // Request a socket-level disconnect if not already happened
+ socket.disconnectFromHost();
+ // Return the result of waiting for disconnect; true if successful, otherwise false
+ return socket.waitForDisconnected(msecs);
+}
+
+
QString CoreNetwork::channelDecode(const QString &bufferName, const QByteArray &string) const
{
if (!bufferName.isEmpty()) {
void CoreNetwork::beginCapNegotiation()
{
// Don't begin negotiation if no capabilities are queued to request
- if (!capNegotiationInProgress())
+ if (!capNegotiationInProgress()) {
+ // If the server doesn't have any capabilities, but supports CAP LS, continue on with the
+ // normal connection.
+ displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("No capabilities available"));
+ endCapNegotiation();
return;
+ }
_capNegotiationActive = true;
displayMsg(Message::Server, BufferInfo::StatusBuffer, "",
_capNegotiationActive = false;
}
- // If nick registration is already complete, CAP END is not required
- if (!_capInitialNegotiationEnded) {
- putRawLine(serverEncode(QString("CAP END")));
- _capInitialNegotiationEnded = true;
- }
+ endCapNegotiation();
+ }
+}
+
+void CoreNetwork::endCapNegotiation()
+{
+ // If nick registration is already complete, CAP END is not required
+ if (!_capInitialNegotiationEnded) {
+ putRawLine(serverEncode(QString("CAP END")));
+ _capInitialNegotiationEnded = true;
}
}