diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/kvirc/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/kvirc/kernel/kvi_ircconnection.cpp | 4 | ||||
| -rw-r--r-- | src/kvirc/kernel/kvi_ircconnection.h | 9 | ||||
| -rw-r--r-- | src/kvirc/kernel/kvi_ircconnectionrequestqueue.cpp | 152 | ||||
| -rw-r--r-- | src/kvirc/kernel/kvi_ircconnectionrequestqueue.h | 62 | ||||
| -rw-r--r-- | src/kvirc/kernel/kvi_irccontext.cpp | 3 | ||||
| -rw-r--r-- | src/kvirc/kernel/kvi_options.cpp | 1 | ||||
| -rw-r--r-- | src/kvirc/kernel/kvi_options.h | 3 | ||||
| -rw-r--r-- | src/kvirc/sparser/kvi_sp_literal.cpp | 47 | ||||
| -rw-r--r-- | src/modules/options/optw_channel.cpp | 6 |
10 files changed, 243 insertions, 46 deletions
diff --git a/src/kvirc/CMakeLists.txt b/src/kvirc/CMakeLists.txt index 37c8cb2b9..7a697f108 100644 --- a/src/kvirc/CMakeLists.txt +++ b/src/kvirc/CMakeLists.txt @@ -85,6 +85,7 @@ SET(kvirc_MOC_HDRS kernel/kvi_iconmanager.h kernel/kvi_ipc.h kernel/kvi_ircconnection.h + kernel/kvi_ircconnectionrequestqueue.h kernel/kvi_ircconnectiontargetresolver.h kernel/kvi_irccontext.h kernel/kvi_irclink.h @@ -291,6 +292,7 @@ SET(kvirc_SRCS kernel/kvi_ircconnectionantictcpflooddata.cpp kernel/kvi_ircconnectionasyncwhoisdata.cpp kernel/kvi_ircconnectionnetsplitdetectordata.cpp + kernel/kvi_ircconnectionrequestqueue.cpp kernel/kvi_ircconnectionserverinfo.cpp kernel/kvi_ircconnectionstatedata.cpp kernel/kvi_ircconnectionstatistics.cpp diff --git a/src/kvirc/kernel/kvi_ircconnection.cpp b/src/kvirc/kernel/kvi_ircconnection.cpp index 99e5990be..8ca8d138e 100644 --- a/src/kvirc/kernel/kvi_ircconnection.cpp +++ b/src/kvirc/kernel/kvi_ircconnection.cpp @@ -32,6 +32,7 @@ #include "kvi_ircconnectionantictcpflooddata.h" #include "kvi_ircconnectionnetsplitdetectordata.h" #include "kvi_ircconnectionasyncwhoisdata.h" +#include "kvi_ircconnectionrequestqueue.h" #include "kvi_ircconnectionstatistics.h" #include "kvi_irclink.h" #include "kvi_ircsocket.h" @@ -98,6 +99,7 @@ KviIrcConnection::KviIrcConnection(KviIrcContext * pContext,KviIrcConnectionTarg m_pLocalhostDns = 0; m_pLagMeter = 0; m_eState = Idle; + m_pRequestQueue = new KviRequestQueue(); setupSrvCodec(); setupTextCodec(); } @@ -151,6 +153,7 @@ KviIrcConnection::~KviIrcConnection() delete m_pAsyncWhoisData; delete m_pStatistics; delete m_pUserIdentity; + delete m_pRequestQueue; } void KviIrcConnection::setEncoding(const QString & szEncoding) @@ -510,6 +513,7 @@ void KviIrcConnection::registerChannel(KviChannel * c) void KviIrcConnection::unregisterChannel(KviChannel * c) { m_pChannelList->removeRef(c); + requestQueue()->dequeueChannel(c); emit(channelUnregistered(c)); emit(chanListChanged()); } diff --git a/src/kvirc/kernel/kvi_ircconnection.h b/src/kvirc/kernel/kvi_ircconnection.h index 317439a9a..f469bcdb0 100644 --- a/src/kvirc/kernel/kvi_ircconnection.h +++ b/src/kvirc/kernel/kvi_ircconnection.h @@ -62,6 +62,7 @@ class KviIrcConnectionAntiCtcpFloodData; class KviIrcConnectionNetsplitDetectorData; class KviIrcConnectionAsyncWhoisData; class KviIrcConnectionStatistics; +class KviRequestQueue; class KviLagMeter; class KviNotifyListManager; class KviDns; @@ -176,6 +177,8 @@ private: QTextCodec * m_pSrvCodec; // connection codec: never null QTextCodec * m_pTextCodec; // connection codec: never null + KviRequestQueue * m_pRequestQueue; // owned, never null + public: /** * \brief Returns a pointer to the owning console @@ -338,6 +341,12 @@ public: inline KviLagMeter * lagMeter(){ return m_pLagMeter; }; /** + * \brief Returns a pointer to the current KviRequestQueue. + * \return KviRequestQueue * + */ + inline KviRequestQueue * requestQueue(){ return m_pRequestQueue; }; + + /** * \brief Returns the list of the channels bound to the current connection. * * The pointer itself is never null (though the list may be empty). diff --git a/src/kvirc/kernel/kvi_ircconnectionrequestqueue.cpp b/src/kvirc/kernel/kvi_ircconnectionrequestqueue.cpp new file mode 100644 index 000000000..e78f19471 --- /dev/null +++ b/src/kvirc/kernel/kvi_ircconnectionrequestqueue.cpp @@ -0,0 +1,152 @@ +//============================================================================= +// +// File : kvi_ircconnectionrequestqueue.h +// Creation date : Tue 09 Feb 2010 10:24:32 by Fabio Bas +// +// This file is part of the KVIrc IRC client distribution +// Copyright (C) 2010 Fabio Bas <ctrlaltca at gmail dot com> +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "kvi_ircconnectionrequestqueue.h" + +#include "kvi_channel.h" +#include "kvi_options.h" +#include "kvi_lagmeter.h" +#include "kvi_ircconnectionstatedata.h" + +#include <QByteArray> + +KviRequestQueue::KviRequestQueue() +{ + curType=ModeRequest; + connect(&timer, SIGNAL(timeout()), this, SLOT(timerSlot())); +} + +KviRequestQueue::~KviRequestQueue() +{ + disconnect(&timer, SIGNAL(timeout()), this, SLOT(timerSlot())); +} + +void KviRequestQueue::enqueueChannel(KviChannel *pChan) +{ + if(!channels.contains(pChan)) + { + channels.enqueue(pChan); + if(!timer.isActive()) timer.start(KVI_OPTION_UINT(KviOption_uintOnJoinRequestsDelay)*1000); + } +} + +void KviRequestQueue::dequeueChannel(KviChannel *pChan) +{ + if(channels.contains(pChan)) + { + channels.removeOne(pChan); + if(channels.isEmpty()) + timer.stop(); + } +} + +void KviRequestQueue::clearAll() +{ + channels.clear(); + timer.stop(); + curType=ModeRequest; +} + +void KviRequestQueue::timerSlot() +{ + if(channels.isEmpty()) + { + timer.stop(); + } else { + KviChannel* chan = channels.head(); + QByteArray encodedChan = chan->connection()->encodeText(chan->target()).data(); + /* The following switch will let the execution flow pass-trought if any request type + * is currently disabled (or not available on the server). Channel's "MODE" request is + * the only mandatory request. + */ + switch(curType) + { + case BanERequest: + if(chan->connection()->serverInfo()->supportsModesIe() && + !KVI_OPTION_BOOL(KviOption_boolDisableBanExceptionListRequestOnJoin)) + { + if(!chan->connection()->sendFmtData("MODE %s e",encodedChan.data())) + clearAll(); // disconnected + else chan->setSentBanExceptionListRequest(); + curType=InviRequest; + break; + } + case InviRequest: + if(chan->connection()->serverInfo()->supportsModesIe() && + !KVI_OPTION_BOOL(KviOption_boolDisableInviteListRequestOnJoin)) + { + if(!chan->connection()->sendFmtData("MODE %s I",encodedChan.data())) + clearAll(); // disconnected + else chan->setSentInviteListRequest(); + curType=WhoRequest; + break; + } + case WhoRequest: + if(!KVI_OPTION_BOOL(KviOption_boolDisableWhoRequestOnJoin)) + { + chan->connection()->stateData()->setLastSentChannelWhoRequest(kvi_unixTime()); + if(chan->connection()->lagMeter()) + { + KviStr tmp; + tmp.sprintf("WHO %s",encodedChan.data()); + chan->connection()->lagMeter()->lagCheckRegister(tmp.ptr(),60); + } + if(!chan->connection()->sendFmtData("WHO %s",encodedChan.data())) + clearAll(); // disconnected + else chan->setSentWhoRequest(); + curType=BanRequest; + break; + } + case BanRequest: + if(!KVI_OPTION_BOOL(KviOption_boolDisableBanListRequestOnJoin)) + { + if(!chan->connection()->sendFmtData("MODE %s b",encodedChan.data())) + clearAll(); // disconnected + else chan->setSentBanListRequest(); + channels.dequeue(); + curType=ModeRequest; + break; + } + default: + //we're at the end of the list + channels.dequeue(); + if(channels.isEmpty()) + { + timer.stop(); + return; + } + chan = channels.head(); + encodedChan = chan->connection()->encodeText(chan->target()); + curType=ModeRequest; + case ModeRequest: + if(!chan->connection()->sendFmtData("MODE %s",encodedChan.data())) + { + clearAll(); // disconnected + break; + } + curType=BanERequest; + break; + } + } +}
\ No newline at end of file diff --git a/src/kvirc/kernel/kvi_ircconnectionrequestqueue.h b/src/kvirc/kernel/kvi_ircconnectionrequestqueue.h new file mode 100644 index 000000000..539c5d27e --- /dev/null +++ b/src/kvirc/kernel/kvi_ircconnectionrequestqueue.h @@ -0,0 +1,62 @@ +#ifndef _KVI_IRCCONNECTIONREQUESTQUEUE_H_ +#define _KVI_IRCCONNECTIONREQUESTQUEUE_H_ +//============================================================================= +// +// File : kvi_ircconnectionrequestqueue.h +// Creation date : Tue 09 Feb 2010 10:24:32 by Fabio Bas +// +// This file is part of the KVIrc IRC client distribution +// Copyright (C) 2010 Fabio Bas <ctrlaltca at gmail dot com> +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "kvi_settings.h" + +#include <QTimer> +#include <QQueue> + +class KviChannel; + +class KVIRC_API KviRequestQueue: public QObject +{ + Q_OBJECT +protected: + QQueue<KviChannel *> channels; + QTimer timer; + // MODE %s b MUST BE THE LAST AUTOMATIC CHANNEL QUERY + // so we get RPL_ENDOFBANLIST as the last reply + // and we know that the channel is in sync + enum requestTypes { + ModeRequest = 0, + BanERequest = 1, + InviRequest = 2, + WhoRequest = 3, + BanRequest = 4 + }; + requestTypes curType; +public: + KviRequestQueue(); + virtual ~KviRequestQueue(); +public: + void enqueueChannel(KviChannel *pChan); + void dequeueChannel(KviChannel *pChan); + void clearAll(); +private slots: + void timerSlot(); +}; + +#endif //!_KVI_IRCCONNECTIONREQUESTQUEUE_H_ diff --git a/src/kvirc/kernel/kvi_irccontext.cpp b/src/kvirc/kernel/kvi_irccontext.cpp index 407a95b09..b5c88c1d3 100644 --- a/src/kvirc/kernel/kvi_irccontext.cpp +++ b/src/kvirc/kernel/kvi_irccontext.cpp @@ -37,6 +37,7 @@ #include "kvi_asynchronousconnectiondata.h" #include "kvi_ircconnectionstatedata.h" #include "kvi_ircconnectionuserinfo.h" +#include "kvi_ircconnectionrequestqueue.h" #include "kvi_irctoolbar.h" #include "kvi_out.h" #include "kvi_ircserverdb.h" @@ -713,6 +714,8 @@ void KviIrcContext::connectionTerminated() pInfo->m_bIsAway = connection()->userInfo()->isAway(); pInfo->m_szAwayReason = connection()->userInfo()->awayReason(); + connection()->requestQueue()->clearAll(); + // we consider it unexpected when we haven't sent a QUIT message and we're connected // or alternatively when a simulation of such a termination is requested (this is used to keep the queries open etc..) bool bUnexpectedDisconnect = (!(connection()->stateData()->sentQuit())) && ((m_eState == KviIrcContext::Connected) || connection()->stateData()->simulateUnexpectedDisconnect()); diff --git a/src/kvirc/kernel/kvi_options.cpp b/src/kvirc/kernel/kvi_options.cpp index 8c55f9281..7b9b45274 100644 --- a/src/kvirc/kernel/kvi_options.cpp +++ b/src/kvirc/kernel/kvi_options.cpp @@ -651,6 +651,7 @@ KviUIntOption g_uintOptionsTable[KVI_NUM_UINT_OPTIONS]= UINT_OPTION("UserIrcViewOwnBackground",8,KviOption_sectFlagIrcView | KviOption_resetUpdateGui | KviOption_groupTheme), UINT_OPTION("NotifierPixmapAlign",0,KviOption_sectFlagNotifier | KviOption_groupTheme), UINT_OPTION("OutputDatetimeFormat",0,KviOption_sectFlagIrcView), + UINT_OPTION("OnJoinRequestsDelay",2,KviOption_sectFlagConnection), }; #define FONT_OPTION(_name,_face,_size,_flags) \ diff --git a/src/kvirc/kernel/kvi_options.h b/src/kvirc/kernel/kvi_options.h index 43bbd422d..8117d5499 100644 --- a/src/kvirc/kernel/kvi_options.h +++ b/src/kvirc/kernel/kvi_options.h @@ -588,7 +588,8 @@ DECLARE_OPTION_STRUCT(KviStringListOption,QStringList) #define KviOption_uintUserIrcViewOwnBackground 75 /* look & feel::ircview */ #define KviOption_uintNotifierPixmapAlign 76 #define KviOption_uintOutputDatetimeFormat 77 /* irc::verbosity */ -#define KVI_NUM_UINT_OPTIONS 78 +#define KviOption_uintOnJoinRequestsDelay 78 +#define KVI_NUM_UINT_OPTIONS 79 namespace KviIdentdOutputMode { enum Mode { diff --git a/src/kvirc/sparser/kvi_sp_literal.cpp b/src/kvirc/sparser/kvi_sp_literal.cpp index cfcd6726b..6f58fbe4b 100644 --- a/src/kvirc/sparser/kvi_sp_literal.cpp +++ b/src/kvirc/sparser/kvi_sp_literal.cpp @@ -51,6 +51,7 @@ #include "kvi_ircconnection.h" #include "kvi_ircconnectionuserinfo.h" #include "kvi_ircconnectiontarget.h" +#include "kvi_ircconnectionrequestqueue.h" #include "kvi_ircconnectionserverinfo.h" #include "kvi_ircconnectionstatedata.h" #include "kvi_ircconnectionnetsplitdetectordata.h" @@ -241,50 +242,8 @@ void KviServerParser::parseLiteralJoin(KviIrcMessage *msg) // message in KviIrcSocket. See the comment in KviIrcSocket::processData() for more info. // FIXME: #warning "IF VERBOSE SAY THAT WE'RE REQUESTING MODES & BAN LIST" (Synching channel) - - if(!msg->connection()->sendFmtData("MODE %s",encodedChan)) - return; // disconnected - - if(msg->connection()->serverInfo()->supportsModesIe()) - { - if(!KVI_OPTION_BOOL(KviOption_boolDisableBanExceptionListRequestOnJoin)) - { - if(!msg->connection()->sendFmtData("MODE %s e",encodedChan)) - return; // disconnected - chan->setSentBanExceptionListRequest(); - } - if(!KVI_OPTION_BOOL(KviOption_boolDisableInviteListRequestOnJoin)) - { - if(!msg->connection()->sendFmtData("MODE %s I",encodedChan)) - return; // disconnected - chan->setSentInviteListRequest(); - } - } - - // MODE %s b MUST BE THE LAST AUTOMATIC CHANNEL QUERY - // so we get RPL_ENDOFBANLIST as the last reply - // and we know that the channel is in sync - - if(!KVI_OPTION_BOOL(KviOption_boolDisableWhoRequestOnJoin)) - { - msg->connection()->stateData()->setLastSentChannelWhoRequest(kvi_unixTime()); - if(msg->connection()->lagMeter()) - { - KviStr tmp(KviStr::Format,"WHO %s",encodedChan); - msg->connection()->lagMeter()->lagCheckRegister(tmp.ptr(),60); - } - if(!msg->connection()->sendFmtData("WHO %s",encodedChan)) - return; // disconnected - chan->setSentWhoRequest(); - } - - if(!KVI_OPTION_BOOL(KviOption_boolDisableBanListRequestOnJoin)) - { - if(!msg->connection()->sendFmtData("MODE %s b",encodedChan)) - return; // disconnected - chan->setSentBanListRequest(); - } - + msg->connection()->requestQueue()->enqueueChannel(chan); + if(KVI_OPTION_BOOL(KviOption_boolPasteLastLogOnChannelJoin)) chan->pasteLastLog(); diff --git a/src/modules/options/optw_channel.cpp b/src/modules/options/optw_channel.cpp index 1c166f99b..cf2159d15 100644 --- a/src/modules/options/optw_channel.cpp +++ b/src/modules/options/optw_channel.cpp @@ -117,6 +117,10 @@ KviChannelAdvancedOptionsWidget::KviChannelAdvancedOptionsWidget(QWidget * pPare m_pBanTypeCombo->setCurrentIndex(KVI_OPTION_UINT(KviOption_uintDefaultBanType)); KviTalGroupBox * g = addGroupBox(0,2,4,2,Qt::Horizontal,__tr2qs_ctx("On Channel Join","options")); + KviUIntSelector *u = addUIntSelector(g,__tr2qs_ctx("Minimum delay between two requests:","options"),KviOption_uintOnJoinRequestsDelay,0,60,2); + u->setSuffix(__tr2qs_ctx(" sec","options")); + mergeTip(u,__tr2qs_ctx("<center>Minimum value: <b>0 secs</b><br>Maximum value: <b>60 secs</b></center>","options")); + addBoolSelector(g,__tr2qs_ctx("Do not send /WHO request","options"),KviOption_boolDisableWhoRequestOnJoin); addBoolSelector(g,__tr2qs_ctx("Do not request ban list","options"),KviOption_boolDisableBanListRequestOnJoin); addBoolSelector(g,__tr2qs_ctx("Do not request ban exception list","options"),KviOption_boolDisableBanExceptionListRequestOnJoin); @@ -127,7 +131,7 @@ KviChannelAdvancedOptionsWidget::KviChannelAdvancedOptionsWidget(QWidget * pPare b = addBoolSelector(g,__tr2qs_ctx("Paste last channel log","options"),KviOption_boolPasteLastLogOnChannelJoin); KviTalHBox * box = new KviTalHBox(g); - KviUIntSelector * u = addUIntSelector(box,__tr2qs_ctx("Paste up to:","options"),KviOption_uintLinesToPasteOnChannelJoin,0,50,10,KVI_OPTION_BOOL(KviOption_boolPasteLastLogOnChannelJoin)); + u = addUIntSelector(box,__tr2qs_ctx("Paste up to:","options"),KviOption_uintLinesToPasteOnChannelJoin,0,50,10,KVI_OPTION_BOOL(KviOption_boolPasteLastLogOnChannelJoin)); u->setSuffix(__tr2qs_ctx(" lines","options")); mergeTip(u,__tr2qs_ctx("<center>Minimum value: <b>0 lines</b><br>Maximum value: <b>50 lines</b></center>","options")); connect(b,SIGNAL(toggled(bool)),u,SLOT(setEnabled(bool))); |
