From d78369fee0f8962bef62f7759bb778cb22b58e32 Mon Sep 17 00:00:00 2001 From: psychon Date: Fri, 16 Nov 2007 22:37:27 +0000 Subject: [PATCH] Main part is: Add disconnect and connect to *status Other stuff included here: - Always send the quit message when disconnecting from IRC - Partly rewrite CConnectUserTimer::RunJob() for some de-uglification git-svn-id: https://znc.svn.sourceforge.net/svnroot/znc/trunk@874 726aef4b-f618-498e-8847-2d620e286838 --- Client.cpp | 22 +++++++++++++++++++--- IRCSock.cpp | 15 ++++++++++----- IRCSock.h | 1 + User.cpp | 23 +++++++++++++++++++---- User.h | 4 ++++ znc.cpp | 18 ++++++++++-------- 6 files changed, 63 insertions(+), 20 deletions(-) diff --git a/Client.cpp b/Client.cpp index 0f285362..9d1afad2 100644 --- a/Client.cpp +++ b/Client.cpp @@ -783,13 +783,27 @@ void CClient::UserCommand(const CString& sLine) { usleep(100000); // Sleep for 10ms to attempt to allow the previous Broadcast() to go through to all users throw CException(CException::EX_Shutdown); - } else if (sCommand.CaseCmp("JUMP") == 0) { + } else if (sCommand.CaseCmp("JUMP") == 0 || + sCommand.CaseCmp("CONNECT") == 0) { if (m_pUser) { if (m_pIRCSock) { - m_pIRCSock->Close(); + m_pIRCSock->Quit(); PutStatus("Jumping to the next server in the list..."); - return; + } else { + PutStatus("Connecting..."); } + + m_pUser->SetIRCConnectEnabled(true); + m_pUser->CheckIRCConnect(); + return; + } + } else if (sCommand.CaseCmp("DISCONNECT") == 0) { + if (m_pUser) { + if (m_pIRCSock) + m_pIRCSock->Quit(); + m_pUser->SetIRCConnectEnabled(false); + PutStatus("Disconnected from IRC. Use 'connect' to reconnect."); + return; } } else if (sCommand.CaseCmp("ENABLECHAN") == 0) { CString sChan = sLine.Token(1, true); @@ -1449,6 +1463,8 @@ void CClient::HelpUser() { Table.AddRow(); Table.SetCell("Command", "SetBuffer"); Table.SetCell("Arguments", "<#chan> [linecount]"); Table.SetCell("Description", "Set the buffer count for a channel"); Table.AddRow(); Table.SetCell("Command", "SetVHost"); Table.SetCell("Arguments", "");Table.SetCell("Description", "Set the VHost for this connection"); Table.AddRow(); Table.SetCell("Command", "Jump"); Table.SetCell("Arguments", ""); Table.SetCell("Description", "Jump to the next server in the list"); + Table.AddRow(); Table.SetCell("Command", "Disconnect"); Table.SetCell("Arguments", ""); Table.SetCell("Description", "Disconnect from IRC"); + Table.AddRow(); Table.SetCell("Command", "Connect"); Table.SetCell("Arguments", ""); Table.SetCell("Description", "Reconnect to IRC"); Table.AddRow(); Table.SetCell("Command", "Send"); Table.SetCell("Arguments", " "); Table.SetCell("Description", "Send a shell file to a nick on IRC"); Table.AddRow(); Table.SetCell("Command", "Get"); Table.SetCell("Arguments", ""); Table.SetCell("Description", "Send a shell file to yourself"); diff --git a/IRCSock.cpp b/IRCSock.cpp index 8a6970ba..e0139914 100644 --- a/IRCSock.cpp +++ b/IRCSock.cpp @@ -55,12 +55,17 @@ CIRCSock::~CIRCSock() { CZNC::Get().ReleaseISpoof(); } - PutIRC("QUIT :" + m_pUser->GetQuitMsg()); + Quit(); m_msChans.clear(); GetUser()->AddBytesRead(GetBytesRead()); GetUser()->AddBytesWritten(GetBytesWritten()); } +void CIRCSock::Quit() { + PutIRC("QUIT :" + m_pUser->GetQuitMsg()); + Close(CLT_AFTERWRITE); +} + void CIRCSock::ReadLine(const CString& sData) { CString sLine = sData; @@ -195,14 +200,14 @@ void CIRCSock::ReadLine(const CString& sData) { } else { char cLetter = 0; if (sBadNick.empty()) { - Close(); + Quit(); return; } cLetter = sBadNick.Right(1)[0]; if (cLetter == 'z') { - Close(); + Quit(); return; } @@ -897,8 +902,8 @@ void CIRCSock::Disconnected() { MODULECALL(OnIRCDisconnected(), m_pUser, NULL, ); DEBUG_ONLY(cout << GetSockName() << " == Disconnected()" << endl); - if (!m_pUser->IsBeingDeleted()) { - m_pUser->PutStatus("Disconnected from IRC. Reconnecting..."); + if (!m_pUser->IsBeingDeleted() && m_pUser->GetIRCConnectEnabled()) { + m_pUser->PutStatus("Disconnected from IRC. Reconnecting..."); } m_pUser->ClearRawBuffer(); m_pUser->ClearMotdBuffer(); diff --git a/IRCSock.h b/IRCSock.h index c30c8084..19e00491 100644 --- a/IRCSock.h +++ b/IRCSock.h @@ -51,6 +51,7 @@ public: void PutIRC(const CString& sLine); void ParseISupport(const CString& sLine); void ResetChans(); + void Quit(); // Setters void SetPass(const CString& s) { m_sPass = s; } diff --git a/User.cpp b/User.cpp index 2b743b94..d0c70c0b 100644 --- a/User.cpp +++ b/User.cpp @@ -50,6 +50,7 @@ CUser::CUser(const CString& sUserName) { m_sTimestampFormat = "[%H:%M:%S]"; m_bAppendTimestamp = false; m_bPrependTimestamp = true; + m_bIRCConnectEnabled = true; m_pKeepNickTimer = new CKeepNickTimer(this); m_pJoinTimer = new CJoinTimer(this); m_pMiscTimer = new CMiscTimer(this); @@ -232,6 +233,11 @@ void CUser::UserConnected(CClient* pClient) { while (m_QueryBuffer.GetNextLine(GetIRCNick().GetNick(), sBufLine)) { pClient->PutClient(sBufLine); } + + // Tell them why they won't connect + if (!GetIRCConnectEnabled()) + PutStatus("You are currently disconnected from IRC. " + "Use 'connect' to reconnect."); } void CUser::UserDisconnected(CClient* pClient) { @@ -357,7 +363,7 @@ bool CUser::Clone(const CUser& User, CString& sErrorRet) { if (pSock) { PutStatus("Jumping servers because this server is no longer in the list"); - pSock->Close(); + pSock->Quit(); } } } @@ -674,7 +680,7 @@ bool CUser::DelServer(const CString& sName) { } if (pIRCSock) { - pIRCSock->Close(); + pIRCSock->Quit(); PutStatus("Your current server was removed, jumping..."); } } else if (m_uServerIdx >= m_vServers.size()) { @@ -737,6 +743,8 @@ bool CUser::AddServer(const CString& sName, unsigned short uPort, const CString& CServer* pServer = new CServer(sName, uPort, sPass, bSSL, bIPV6); m_vServers.push_back(pServer); + CheckIRCConnect(); + return true; } @@ -993,6 +1001,13 @@ void CUser::SetBufferCount(unsigned int u) { m_uBufferCount = u; } void CUser::SetKeepBuffer(bool b) { m_bKeepBuffer = b; } void CUser::SetAutoCycle(bool b) { m_bAutoCycle = b; } +void CUser::CheckIRCConnect() +{ + // Do we want to connect? + if (m_bIRCConnectEnabled && GetIRCSock() == NULL) + CZNC::Get().EnableConnectUser(); +} + void CUser::SetIRCNick(const CNick& n) { m_IRCNick = n; @@ -1034,12 +1049,12 @@ bool CUser::IsPassHashed() const { return m_bPassHashed; } bool CUser::ConnectPaused() { if (!m_uConnectTime) { m_uConnectTime = time(NULL); - return false; + return !m_bIRCConnectEnabled; } if (time(NULL) - m_uConnectTime >= 5) { m_uConnectTime = time(NULL); - return false; + return !m_bIRCConnectEnabled; } return true; diff --git a/User.h b/User.h index ef440dc3..7bcf2235 100644 --- a/User.h +++ b/User.h @@ -98,6 +98,7 @@ public: bool IsIRCConnected() { return m_bIRCConnected; } void IRCConnected(CIRCSock* pIRCSock); void IRCDisconnected(); + void CheckIRCConnect(); CString ExpandString(const CString& sStr) const; CString& ExpandString(const CString& sStr, CString& sRet) const; @@ -145,6 +146,7 @@ public: void SetTimestampPrepend(bool b) { m_bPrependTimestamp = b; } void SetTimezoneOffset(float b) { m_fTimezoneOffset = b; } void SetJoinTries(unsigned int i) { m_uMaxJoinTries = i; } + void SetIRCConnectEnabled(bool b) { m_bIRCConnectEnabled = b; } // !Setters // Getters @@ -164,6 +166,7 @@ public: const CString& GetTimestampFormat() const; bool GetTimestampAppend() const; bool GetTimestampPrepend() const; + bool GetIRCConnectEnabled() const { return m_bIRCConnectEnabled; } const CString& GetChanPrefixes() const { return m_sChanPrefixes; } bool IsChan(const CString& sChan) const { return (sChan.size() && GetChanPrefixes().find(sChan[0]) != CString::npos); } @@ -237,6 +240,7 @@ protected: bool m_bBeingDeleted; bool m_bAppendTimestamp; bool m_bPrependTimestamp; + bool m_bIRCConnectEnabled; CKeepNickTimer* m_pKeepNickTimer; CJoinTimer* m_pJoinTimer; diff --git a/znc.cpp b/znc.cpp index 1b54d265..56ca3697 100644 --- a/znc.cpp +++ b/znc.cpp @@ -1347,15 +1347,15 @@ public: protected: virtual void RunJob() { - CUser *pStartedUser; + unsigned int uiUserCount; map::const_iterator end; - bool bUserWithoutIRC = false; + bool bUsersLeft = false; - pStartedUser = m_itUserIter->second; + uiUserCount = CZNC::Get().GetUserMap().size(); end = CZNC::Get().GetUserMap().end(); // Try to connect each user, if this doesnt work, abort - do { + for (unsigned int i = 0; i < uiUserCount; i++) { if (m_itUserIter == end) { m_itUserIter = CZNC::Get().GetUserMap().begin(); } @@ -1364,14 +1364,16 @@ protected: m_itUserIter++; - if (pUser->GetIRCSock() == NULL) - bUserWithoutIRC = true; + // Is this user disconnected and does he want to connect? + if (pUser->GetIRCSock() == NULL && pUser->GetIRCConnectEnabled()) + bUsersLeft = true; if (CZNC::Get().ConnectUser(pUser)) + // Wait until next time timer fires return; - } while (pStartedUser != m_itUserIter->second); + } - if (bUserWithoutIRC == false) + if (bUsersLeft == false) CZNC::Get().DisableConnectUser(); }