diff options
| author | 2015-08-05 03:16:17 +0200 | |
|---|---|---|
| committer | 2015-08-05 03:16:17 +0200 | |
| commit | e3de2f90169961969caa8d041a1db60bee29e5fc (patch) | |
| tree | f7e35ee526aed7a76a99e3b36b4a60ed27f91718 | |
| parent | Fix cache in appveyor (diff) | |
| download | KVIrc-e3de2f90169961969caa8d041a1db60bee29e5fc.tar.gz KVIrc-e3de2f90169961969caa8d041a1db60bee29e5fc.tar.bz2 KVIrc-e3de2f90169961969caa8d041a1db60bee29e5fc.zip | |
Rework automatic channel join process a bit. Fixes #1500
| -rw-r--r-- | src/kvilib/irc/KviIrcServerReconnectInfo.cpp | 5 | ||||
| -rw-r--r-- | src/kvilib/irc/KviIrcServerReconnectInfo.h | 8 | ||||
| -rw-r--r-- | src/kvirc/kernel/KviIrcConnection.cpp | 141 | ||||
| -rw-r--r-- | src/kvirc/kernel/KviIrcConnection.h | 20 | ||||
| -rw-r--r-- | src/kvirc/kernel/KviIrcConnectionServerInfo.cpp | 6 | ||||
| -rw-r--r-- | src/kvirc/kernel/KviIrcConnectionServerInfo.h | 1 | ||||
| -rw-r--r-- | src/kvirc/kernel/KviIrcContext.cpp | 44 |
7 files changed, 131 insertions, 94 deletions
diff --git a/src/kvilib/irc/KviIrcServerReconnectInfo.cpp b/src/kvilib/irc/KviIrcServerReconnectInfo.cpp index 4f2e11bdb..9edffe0ca 100644 --- a/src/kvilib/irc/KviIrcServerReconnectInfo.cpp +++ b/src/kvilib/irc/KviIrcServerReconnectInfo.cpp @@ -38,7 +38,8 @@ KviIrcServerReconnectInfo::KviIrcServerReconnectInfo(const KviIrcServerReconnect m_szNick = info.m_szNick; m_szPass = info.m_szPass; m_szAwayReason = info.m_szAwayReason; - m_szJoinChannels = info.m_szJoinChannels; - m_szOpenQueryes = info.m_szOpenQueryes; + //m_szJoinChannels = info.m_szJoinChannels; + m_lJoinChannels = info.m_lJoinChannels; + m_lOpenQueries = info.m_lOpenQueries; m_bIsAway = info.m_bIsAway; } diff --git a/src/kvilib/irc/KviIrcServerReconnectInfo.h b/src/kvilib/irc/KviIrcServerReconnectInfo.h index 901583402..20e690f79 100644 --- a/src/kvilib/irc/KviIrcServerReconnectInfo.h +++ b/src/kvilib/irc/KviIrcServerReconnectInfo.h @@ -37,6 +37,8 @@ #include <QString> #include <QStringList> +#include <QList> +#include <QPair> /** * \class KviIrcServerReconnectInfo @@ -66,9 +68,11 @@ public: QString m_szNick; QString m_szPass; QString m_szAwayReason; - QString m_szJoinChannels; - QStringList m_szOpenQueryes; + QStringList m_lOpenQueries; bool m_bIsAway; + + // The list of channels to join (first = channel name, second = password) + QList< QPair< QString,QString > > m_lJoinChannels; }; #endif //_KVI_IRCSERVER_INFO_H_ diff --git a/src/kvirc/kernel/KviIrcConnection.cpp b/src/kvirc/kernel/KviIrcConnection.cpp index 7f24f9b4d..fdd31b362 100644 --- a/src/kvirc/kernel/KviIrcConnection.cpp +++ b/src/kvirc/kernel/KviIrcConnection.cpp @@ -74,6 +74,7 @@ #include <QTimer> #include <QTextCodec> +#include <QtGlobal> extern KVIRC_API KviIrcServerDataBase * g_pServerDataBase; extern KVIRC_API KviProxyDataBase * g_pProxyDataBase; @@ -1702,6 +1703,83 @@ bool KviIrcConnection::changeUserMode(char cMode, bool bSet) return true; } +void KviIrcConnection::gatherChannelAndPasswordPairs(QList< QPair< QString,QString > > &lChannelsAndPasses) +{ + for(KviChannelWindow * c = m_pChannelList->first();c;c = m_pChannelList->next()) + lChannelsAndPasses.append( + QPair<QString,QString>( + c->windowName(), + c->hasChannelMode('k') ? c->channelModeParam('k') : QString() + ) + ); +} + +void KviIrcConnection::gatherQueryNames(QStringList &lQueryNames) +{ + for(KviQueryWindow * q = m_pQueryList->first(); q; q = m_pQueryList->next()) + lQueryNames.append(q->target()); +} + +void KviIrcConnection::joinChannels(const QList< QPair< QString,QString > > &lChannelsAndPasses) +{ + if(lChannelsAndPasses.count() < 1) + return; + + // Sort the list so the channels with passwords come first + QList< QPair< QString,QString> > lSorted; + + QPair<QString,QString> oChanAndPass; + Q_FOREACH(oChanAndPass,lChannelsAndPasses) + { + if(oChanAndPass.second.isEmpty()) + lSorted.append(oChanAndPass); + else + lSorted.prepend(oChanAndPass); + } + + // We send the channel list in chunks to avoid overflowing the 510 character limit on the message. + QString szChans,szPasses; + QString szCommand; + + while(lSorted.count() > 0) + { + QPair<QString,QString> oChanAndPass = lSorted.takeFirst(); + + if(!szChans.isEmpty()) + szChans.append(','); + szChans.append(oChanAndPass.first); + + if(!oChanAndPass.second.isEmpty()) + { + if(!szPasses.isEmpty()) + szPasses.append(','); + szPasses.append(oChanAndPass.second); + } + + // empirical limit + if((szChans.length() + szPasses.length()) > 450) + { + szCommand = szChans; + if(!szPasses.isEmpty()) + { + szCommand.append(" "); + szCommand.append(szPasses); + } + sendFmtData("JOIN %s",encodeText(szCommand).data()); + szChans = QString(); + szPasses = QString(); + } + } + + szCommand = szChans; + if(!szPasses.isEmpty()) + { + szCommand.append(" "); + szCommand.append(szPasses); + } + sendFmtData("JOIN %s",encodeText(szCommand).data()); +} + void KviIrcConnection::loginComplete(const QString & szNickName) { if(context()->state() == KviIrcContext::Connected) @@ -1807,16 +1885,16 @@ void KviIrcConnection::loginComplete(const QString & szNickName) if(target()->server()->reconnectInfo()) { - if(!target()->server()->reconnectInfo()->m_szJoinChannels.isEmpty()) + if(!target()->server()->reconnectInfo()->m_lJoinChannels.isEmpty()) { bJoinStdChannels=false; - sendFmtData("JOIN %s",encodeText(target()->server()->reconnectInfo()->m_szJoinChannels).data()); + joinChannels(target()->server()->reconnectInfo()->m_lJoinChannels); } KviQueryWindow * pQuery; - for(QStringList::Iterator it = target()->server()->reconnectInfo()->m_szOpenQueryes.begin(); - it != target()->server()->reconnectInfo()->m_szOpenQueryes.end();it++) + for(QStringList::Iterator it = target()->server()->reconnectInfo()->m_lOpenQueries.begin(); + it != target()->server()->reconnectInfo()->m_lOpenQueries.end();it++) { QString szNick = *it; pQuery = findQuery(szNick); @@ -1844,6 +1922,8 @@ void KviIrcConnection::loginComplete(const QString & szNickName) if(bJoinStdChannels) { + QList< QPair< QString,QString > > lChansAndPass; + if(target()->network()->autoJoinChannelList()) { if(_OUTPUT_VERBOSE) @@ -1856,23 +1936,9 @@ void KviIrcConnection::loginComplete(const QString & szNickName) szCurChan = (*it).section(':',0,0); if(szCurChan.isEmpty()) continue; - if(szCurPass.isEmpty()) - { - if(!szChannels.isEmpty()) - szChannels.append(","); - if(!(szCurChan[0]=='#' || szCurChan[0]=='&' || szCurChan[0]=='!' || szCurChan[0]=='+')) - szCurChan.prepend('#'); - szChannels.append(szCurChan); - } else { - if(!szProtectedChannels.isEmpty()) - szProtectedChannels.append(","); - if(!(szCurChan[0]=='#' || szCurChan[0]=='&' || szCurChan[0]=='!' || szCurChan[0]=='+')) - szCurChan.prepend('#'); - szProtectedChannels.append(szCurChan); - if(!szPasswords.isEmpty()) - szPasswords.append(","); - szPasswords.append(szCurPass); - } + if(!m_pServerInfo->isSupportedChannelType(szCurChan[0])) + szCurChan.prepend('#'); + lChansAndPass.append(QPair<QString,QString>(szCurChan,szCurPass)); } } @@ -1888,38 +1954,13 @@ void KviIrcConnection::loginComplete(const QString & szNickName) szCurChan = (*it).section(':',0,0); if(szCurChan.isEmpty()) continue; - if(szCurPass.isEmpty()) - { - if(!szChannels.isEmpty()) - szChannels.append(","); - if(!(szCurChan[0]=='#' || szCurChan[0]=='&' || szCurChan[0]=='!' || szCurChan[0]=='+')) - szCurChan.prepend('#'); - szChannels.append(szCurChan); - } else { - if(!szProtectedChannels.isEmpty()) - szProtectedChannels.append(","); - if(!(szCurChan[0]=='#' || szCurChan[0]=='&' || szCurChan[0]=='!' || szCurChan[0]=='+')) - szCurChan.prepend('#'); - szProtectedChannels.append(szCurChan); - if(!szPasswords.isEmpty()) - szPasswords.append(","); - szPasswords.append(szCurPass); - } + if(!m_pServerInfo->isSupportedChannelType(szCurChan[0])) + szCurChan.prepend('#'); + lChansAndPass.append(QPair<QString,QString>(szCurChan,szCurPass)); } } - QString szCommand; - if( (!szChannels.isEmpty()) || (!szProtectedChannels.isEmpty()) ) - { - szCommand.append(szProtectedChannels); - if(!szProtectedChannels.isEmpty() && !szChannels.isEmpty()) - szCommand.append(','); - szCommand.append(szChannels); - szCommand.append(" "); - szCommand.append(szPasswords); - - sendFmtData("JOIN %s",encodeText(szCommand).data()); - } + joinChannels(lChansAndPass); } // minimize after connect if(KVI_OPTION_BOOL(KviOption_boolMinimizeConsoleAfterConnect)) diff --git a/src/kvirc/kernel/KviIrcConnection.h b/src/kvirc/kernel/KviIrcConnection.h index fbde1fdbf..f473dd61a 100644 --- a/src/kvirc/kernel/KviIrcConnection.h +++ b/src/kvirc/kernel/KviIrcConnection.h @@ -37,6 +37,9 @@ #include <QObject> #include <QByteArray> +#include <QStringList> +#include <QList> +#include <QPair> class QTimer; class QTextCodec; @@ -753,6 +756,23 @@ protected: void loginToIrcServer(); /** + * Joins a list of channels. + * The first element of the pair is the channel name, the second element of the pair is the eventual password. + * May send multiple JOIN messages. + */ + void joinChannels(const QList< QPair< QString,QString > > &lChannelsAndPasses); + + /** + * Gather the list of currently joined channels with the relative passwords. + */ + void gatherChannelAndPasswordPairs(QList< QPair< QString,QString > > &lChannelsAndPasses); + + /** + * Gather the list of currently open query names. + */ + void gatherQueryNames(QStringList &lQueryNames); + + /** * Picks the next login nickname to be tried. If bForceDefaultIfPrimaryNicknamesEmpty is true then the algorithm * will return a default nickname in case the primary setting in the options is empty. If bForceDefaultIfPrimaryNicknamesEmpty * is false then the algorithm will try the alternative nicknames instead, then try some random options and finally diff --git a/src/kvirc/kernel/KviIrcConnectionServerInfo.cpp b/src/kvirc/kernel/KviIrcConnectionServerInfo.cpp index a699d8e32..abd222d5f 100644 --- a/src/kvirc/kernel/KviIrcConnectionServerInfo.cpp +++ b/src/kvirc/kernel/KviIrcConnectionServerInfo.cpp @@ -58,6 +58,12 @@ KviIrcConnectionServerInfo::~KviIrcConnectionServerInfo() KviMemory::free(m_pModePrefixTable); } +bool KviIrcConnectionServerInfo::isSupportedChannelType(QChar c) +{ + return m_szSupportedChannelTypes.contains(c); +} + + void KviIrcConnectionServerInfo::addSupportedCaps(const QString &szCapList) { m_bSupportsCap = true; diff --git a/src/kvirc/kernel/KviIrcConnectionServerInfo.h b/src/kvirc/kernel/KviIrcConnectionServerInfo.h index 397a6d6d6..1867a31e3 100644 --- a/src/kvirc/kernel/KviIrcConnectionServerInfo.h +++ b/src/kvirc/kernel/KviIrcConnectionServerInfo.h @@ -240,6 +240,7 @@ public: const QString & getChannelModeDescription(char mode) { return m_pServInfo->getChannelModeDescription(mode); }; const QString & getUserModeDescription(QChar mode) { return m_pServInfo->getUserModeDescription(mode); }; + bool isSupportedChannelType(QChar c); bool isSupportedModePrefix(QChar c); bool isSupportedModeFlag(QChar c); QChar modePrefixChar(kvi_u32_t flag); diff --git a/src/kvirc/kernel/KviIrcContext.cpp b/src/kvirc/kernel/KviIrcContext.cpp index 7f25d4379..9a69577b4 100644 --- a/src/kvirc/kernel/KviIrcContext.cpp +++ b/src/kvirc/kernel/KviIrcContext.cpp @@ -738,48 +738,10 @@ void KviIrcContext::connectionTerminated() if(KVI_OPTION_BOOL(KviOption_boolAutoReconnectOnUnexpectedDisconnect)) { if(KVI_OPTION_BOOL(KviOption_boolRejoinChannelsAfterReconnect)) - { - // FIXME: THIS SHOULD BE A KviIrcConnection FUNCTION - KviChannelWindow * c; - QString szChannels, szProtectedChannels, szPasswords, szCurPass, szCurChan; - // first only chans without key, in groups of 4 - for(c = connection()->channelList()->first(); c; c = connection()->channelList()->next()) - { - szCurPass = c->hasChannelMode('k') ? c->channelModeParam('k') : ""; - szCurChan = c->windowName(); - if(szCurPass.isEmpty()) - { - if(!szChannels.isEmpty()) - szChannels.append(","); - szChannels.append(szCurChan); - } else { - if(!szProtectedChannels.isEmpty()) - szProtectedChannels.append(","); - szProtectedChannels.append(szCurChan); - if(!szPasswords.isEmpty()) - szPasswords.append(","); - szPasswords.append(szCurPass); - } - } - if((!szChannels.isEmpty()) || (!szProtectedChannels.isEmpty())) - { - info.m_szJoinChannels.append(szProtectedChannels); - if(!szProtectedChannels.isEmpty() && !szChannels.isEmpty()) - info.m_szJoinChannels.append(','); - info.m_szJoinChannels.append(szChannels); - info.m_szJoinChannels.append(" "); - info.m_szJoinChannels.append(szPasswords); - } - } - + connection()->gatherChannelAndPasswordPairs(info.m_lJoinChannels); if(KVI_OPTION_BOOL(KviOption_boolReopenQueriesAfterReconnect)) - { - for(KviQueryWindow * q = connection()->queryList()->first(); q; q = connection()->queryList()->next()) - { - info.m_szOpenQueryes.append(q->target()); - } - } + connection()->gatherQueryNames(info.m_lOpenQueries); } if(KVI_OPTION_BOOL(KviOption_boolKeepChannelsOpenOnUnexpectedDisconnect) || KVI_OPTION_BOOL(KviOption_boolKeepChannelsOpenOnDisconnect)) @@ -816,6 +778,7 @@ void KviIrcContext::connectionTerminated() //m_uConnectAttemptCount = 1; if(!_OUTPUT_MUTE) m_pConsole->output(KVI_OUT_CONNECTION,__tr2qs("The connection terminated unexpectedly. Trying to reconnect...")); + KviAsynchronousConnectionData * d = new KviAsynchronousConnectionData(); d->szServerId = oldServer.id(); d->szServer = oldServer.hostName(); @@ -827,6 +790,7 @@ void KviIrcContext::connectionTerminated() d->szPass = oldServer.password(); d->szInitUMode = oldServer.initUMode(); d->m_pReconnectInfo = new KviIrcServerReconnectInfo(info); + setAsynchronousConnectionData(d); beginAsynchronousConnect(1000 * KVI_OPTION_UINT(KviOption_uintAutoReconnectDelay)); |
