Rearrange CAP requests between ZNC and server in a way

that each next REQ is sent only after receiving ACK/NAK
of previous REQ. Also now you can call CIRCSock::PauseCap()
and CIRCSock::ResumeCap() if you need to pause CAP negotiation
and process of logging in for a while.

git-svn-id: https://znc.svn.sourceforge.net/svnroot/znc/trunk@2137 726aef4b-f618-498e-8847-2d620e286838
This commit is contained in:
darthgandalf
2010-09-13 17:00:50 +00:00
parent 1d6f11f71a
commit 633c225811
2 changed files with 37 additions and 10 deletions
+25 -10
View File
@@ -24,6 +24,7 @@ CIRCSock::CIRCSock(CUser* pUser) : CZNCSock() {
m_Nick.SetHost(pUser->GetBindHost());
m_uMaxNickLen = 9;
m_uCapPaused = 0;
m_sPerms = "*!@%+";
m_sPermModes = "qaohv";
m_mueChanModes['b'] = ListArg;
@@ -679,15 +680,11 @@ void CIRCSock::ReadLine(const CString& sData) {
for (it = vsTokens.begin(); it != vsTokens.end(); ++it) {
if (OnServerCapAvailable(*it) || *it == "multi-prefix" || *it == "userhost-in-names") {
// For real support of ack (~) modifier need also
// to queue these cap requests.
PutIRC("CAP REQ :" + *it);
m_ssPendingCaps.insert(*it);
}
}
} else if (sSubCmd == "ACK") {
sArgs.Trim();
m_ssPendingCaps.erase(sArgs);
MODULECALL(OnServerCapResult(sArgs, true), m_pUser, NULL, );
if ("multi-prefix" == sArgs) {
m_bNamesx = true;
@@ -699,14 +696,10 @@ void CIRCSock::ReadLine(const CString& sData) {
// This should work because there's no [known]
// capability with length of name more than 100 characters.
sArgs.Trim();
m_ssPendingCaps.erase(sArgs);
MODULECALL(OnServerCapResult(sArgs, false), m_pUser, NULL, );
}
if (m_ssPendingCaps.empty()) {
// We already got all needed ACK/NAK replies.
PutIRC("CAP END");
}
SendNextCap();
}
// Don't forward any CAP stuff to the client
return;
@@ -716,6 +709,28 @@ void CIRCSock::ReadLine(const CString& sData) {
m_pUser->PutUser(sLine);
}
void CIRCSock::SendNextCap() {
if (!m_uCapPaused) {
if (m_ssPendingCaps.empty()) {
// We already got all needed ACK/NAK replies.
PutIRC("CAP END");
} else {
CString sCap = *m_ssPendingCaps.begin();
m_ssPendingCaps.erase(m_ssPendingCaps.begin());
PutIRC("CAP REQ :" + sCap);
}
}
}
void CIRCSock::PauseCap() {
++m_uCapPaused;
}
void CIRCSock::ResumeCap() {
--m_uCapPaused;
SendNextCap();
}
bool CIRCSock::OnServerCapAvailable(const CString& sCap) {
MODULECALL(OnServerCapAvailable(sCap), m_pUser, NULL, return true);
return false;
+12
View File
@@ -55,6 +55,16 @@ public:
void ResetChans();
void Quit(const CString& sQuitMsg = "");
/** You can call this from CModule::OnServerCapResult to suspend
* sending other CAP requests and CAP END for a while. Each
* call to PauseCap should be balanced with a call to ResumeCap.
*/
void PauseCap();
/** If you used PauseCap, call this when CAP negotiation and logging in
* should be resumed again.
*/
void ResumeCap();
// Setters
void SetPass(const CString& s) { m_sPass = s; }
// !Setters
@@ -88,6 +98,7 @@ private:
void ParseISupport(const CString& sLine);
// This is called when we connect and the nick we want is already taken
void SendAltNick(const CString& sBadNick);
void SendNextCap();
protected:
bool m_bISpoofReleased;
bool m_bAuthed;
@@ -102,6 +113,7 @@ protected:
CString m_sPass;
map<CString, CChan*> m_msChans;
unsigned int m_uMaxNickLen;
unsigned int m_uCapPaused;
SCString m_ssAcceptedCaps;
SCString m_ssPendingCaps;
};