aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/kvirc/CMakeLists.txt2
-rw-r--r--src/kvirc/kernel/kvi_ircconnection.cpp4
-rw-r--r--src/kvirc/kernel/kvi_ircconnection.h9
-rw-r--r--src/kvirc/kernel/kvi_ircconnectionrequestqueue.cpp152
-rw-r--r--src/kvirc/kernel/kvi_ircconnectionrequestqueue.h62
-rw-r--r--src/kvirc/kernel/kvi_irccontext.cpp3
-rw-r--r--src/kvirc/kernel/kvi_options.cpp1
-rw-r--r--src/kvirc/kernel/kvi_options.h3
-rw-r--r--src/kvirc/sparser/kvi_sp_literal.cpp47
-rw-r--r--src/modules/options/optw_channel.cpp6
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)));