bool TwitchGroupChat::OnLoad(const CString& sArgsi, CString& sMessage) { PutIRC("CAP REQ :twitch.tv/commands"); PutIRC("CAP REQ :twitch.tv/tags"); return true; }
void CIRCNetwork::JoinChans(set<CChan*>& sChans) { CString sKeys, sJoin; bool bHaveKey = false; size_t uiJoinLength = strlen("JOIN "); while (!sChans.empty()) { set<CChan*>::iterator it = sChans.begin(); const CString& sName = (*it)->GetName(); const CString& sKey = (*it)->GetKey(); size_t len = sName.length() + sKey.length(); len += 2; // two comma if (!sKeys.empty() && uiJoinLength + len >= 512) break; if (!sJoin.empty()) { sJoin += ","; sKeys += ","; } uiJoinLength += len; sJoin += sName; if (!sKey.empty()) { sKeys += sKey; bHaveKey = true; } sChans.erase(it); } if (bHaveKey) PutIRC("JOIN " + sJoin + " " + sKeys); else PutIRC("JOIN " + sJoin); }
void OverrideCommand(const CString& sLine) { m_bTemporaryAcceptMotd = true; const CString sServer = sLine.Token(1); if (sServer.empty()) { PutIRC("motd"); } else { PutIRC("motd " + sServer); } }
void Authenticate(const CString& sLine) { if (m_Mechanisms.GetCurrent().Equals("PLAIN") && sLine.Equals("+")) { CString sAuthLine = GetNV("username") + '\0' + GetNV("username") + '\0' + GetNV("password"); sAuthLine.Base64Encode(); PutIRC("AUTHENTICATE " + sAuthLine); } else { /* Send blank authenticate for other mechanisms (like EXTERNAL). */ PutIRC("AUTHENTICATE +"); } }
virtual EModRet OnUserCTCP(CString& sTarget, CString& sMessage) { if (sMessage.Equals("DCC ", false, 4)) { CString sType = sMessage.Token(1); CString sFile = sMessage.Token(2); unsigned long uLongIP = sMessage.Token(3).ToULong(); unsigned short uPort = sMessage.Token(4).ToUShort(); unsigned long uFileSize = sMessage.Token(5).ToULong(); CString sIP = GetLocalDCCIP(); if (!UseClientIP()) { uLongIP = CUtils::GetLongIP(m_pClient->GetRemoteIP()); } if (sType.Equals("CHAT")) { unsigned short uBNCPort = CDCCBounce::DCCRequest(sTarget, uLongIP, uPort, "", true, this, ""); if (uBNCPort) { PutIRC("PRIVMSG " + sTarget + " :\001DCC CHAT chat " + CString(CUtils::GetLongIP(sIP)) + " " + CString(uBNCPort) + "\001"); } } else if (sType.Equals("SEND")) { // DCC SEND readme.txt 403120438 5550 1104 unsigned short uBNCPort = CDCCBounce::DCCRequest(sTarget, uLongIP, uPort, sFile, false, this, ""); if (uBNCPort) { PutIRC("PRIVMSG " + sTarget + " :\001DCC SEND " + sFile + " " + CString(CUtils::GetLongIP(sIP)) + " " + CString(uBNCPort) + " " + CString(uFileSize) + "\001"); } } else if (sType.Equals("RESUME")) { // PRIVMSG user :DCC RESUME "znc.o" 58810 151552 unsigned short uResumePort = sMessage.Token(3).ToUShort(); set<CSocket*>::const_iterator it; for (it = BeginSockets(); it != EndSockets(); ++it) { CDCCBounce* pSock = (CDCCBounce*) *it; if (pSock->GetLocalPort() == uResumePort) { PutIRC("PRIVMSG " + sTarget + " :\001DCC " + sType + " " + sFile + " " + CString(pSock->GetUserPort()) + " " + sMessage.Token(4) + "\001"); } } } else if (sType.Equals("ACCEPT")) { // Need to lookup the connection by port, filter the port, and forward to the user set<CSocket*>::const_iterator it; for (it = BeginSockets(); it != EndSockets(); ++it) { CDCCBounce* pSock = (CDCCBounce*) *it; if (pSock->GetUserPort() == sMessage.Token(3).ToUShort()) { PutIRC("PRIVMSG " + sTarget + " :\001DCC " + sType + " " + sFile + " " + CString(pSock->GetLocalPort()) + " " + sMessage.Token(4) + "\001"); } } } return HALTCORE; } return CONTINUE; }
void CIRCSock::Quit(const CString& sQuitMsg) { if (!m_bAuthed) { Close(CLT_NOW); return; } if (!sQuitMsg.empty()) { PutIRC("QUIT :" + sQuitMsg); } else { PutIRC("QUIT :" + m_pNetwork->ExpandString(m_pNetwork->GetUser()->GetQuitMsg())); } Close(CLT_AFTERWRITE); }
virtual EModRet OnIRCRegistration(CString& sPass, CString& sNick, CString& sIdent, CString& sRealName) { CString fake = GetFake(m_pUser->GetUserName()); PutIRC("WEBIRC " + m_pPass + " ZNC " + CleanHostname(m_pUser->GetCleanUserName()) + CGIIRC_HOSTNAME_SUFFIX + " " + fake); sIdent = m_pUser->GetCleanUserName(); return CONTINUE; }
EModRet OnUserNotice(CString& sTarget, CString& sMessage) override { sTarget.TrimPrefix(NickPrefix()); if (sMessage.TrimPrefix("``")) { return CONTINUE; } MCString::iterator it = FindNV(sTarget.AsLower()); if (it != EndNV()) { CChan* pChan = GetNetwork()->FindChan(sTarget); CString sNickMask = GetNetwork()->GetIRCNick().GetNickMask(); if (pChan) { if (!pChan->AutoClearChanBuffer()) pChan->AddBuffer(":" + NickPrefix() + _NAMEDFMT(sNickMask) + " NOTICE " + _NAMEDFMT(sTarget) + " :{text}", sMessage); GetUser()->PutUser(":" + NickPrefix() + sNickMask + " NOTICE " + sTarget + " :" + sMessage, NULL, GetClient()); } CString sMsg = MakeIvec() + sMessage; sMsg.Encrypt(it->second); sMsg.Base64Encode(); sMsg = "+OK *" + sMsg; PutIRC("NOTICE " + sTarget + " :" + sMsg); return HALTCORE; } return CONTINUE; }
void SetBack() { RemTimer("simple_away"); if (m_bWeSetAway) { PutIRC("AWAY"); m_bWeSetAway = false; } }
virtual void OnModCommand( const CString& sCommand ) { CString sCmdName = sCommand.Token(0).AsLower(); if(sCmdName == "set") { CString sPass = sCommand.Token(1, true) + " "; m_sAuth = sPass; PutModule("Auth set"); } else if(sCmdName == "auth") { if (m_sAuth.empty()) PutModule("No auth set"); else { PutIRC("PRIVMSG [email protected] :auth " + m_sAuth); PutModule("Authing!"); } } else if(sCmdName == "show") { if (m_sAuth.empty()) PutModule("No auth set"); else PutModule("Current user and password: "******"save") { SetNV("Auth", m_sAuth); PutModule("Saved!"); } else { PutModule("Commands: set <user password>, show, save"); } }
void Cloak() { if (m_bCloaked) return; PutModule("Cloak: Trying to cloak your hostname, setting +x..."); PutIRC("MODE " + GetUser()->GetIRCSock()->GetNick() + " +x"); }
void SendRequest() { requestQueue::iterator it; if (m_pDoing || m_pReplies) return; if (m_vsPending.empty()) return; it = m_vsPending.begin(); if (it->second.empty()) { m_vsPending.erase(it); SendRequest(); return; } // When we are called from the timer, we need to remove it. // We can't delete it (segfault on return), thus we // just stop it. The main loop will delete it. CTimer* pTimer = FindTimer("RouteTimeout"); if (pTimer) { pTimer->Stop(); UnlinkTimer(pTimer); } AddTimer( new CRouteTimeout(this, 60, 1, "RouteTimeout", "Recover from missing / wrong server replies")); m_pDoing = it->first; m_pReplies = it->second[0].reply; m_sLastRequest = it->second[0].sLine; PutIRC(it->second[0].sLine); it->second.erase(it->second.begin()); }
void Authenticate(const CString& sLine) { if (m_Mechanisms.GetCurrent().Equals("PLAIN") && sLine.Equals("+")) { CString sAuthLine = GetNV("username") + '\0' + GetNV("username") + '\0' + GetNV("password"); sAuthLine.Base64Encode(); PutIRC("AUTHENTICATE " + sAuthLine); #ifdef HAVE_SASL_MECHANISM } else if (m_Mechanisms.GetCurrent().Equals("DH-BLOWFISH")) { AuthenticateBlowfish(sLine); } else if (m_Mechanisms.GetCurrent().Equals("DH-AES")) { AuthenticateAES(sLine); #endif } else { /* Send blank authenticate for other mechanisms (like EXTERNAL). */ PutIRC("AUTHENTICATE +"); } }
virtual void RunJob() { if (!m_pUser->GetIRCSock()) return; for (MCString::iterator it = BeginNV(); it != EndNV(); ++it) { CChan *pChan = m_pUser->FindChan(it->first); if (!pChan) { pChan = new CChan(it->first, m_pUser, true); if (!it->second.empty()) pChan->SetKey(it->second); if (!m_pUser->AddChan(pChan)) { /* AddChan() deleted that channel */ PutModule("Could not join [" + it->first + "] (# prefix missing?)"); continue; } } if (!pChan->IsOn()) { PutModule("Joining [" + pChan->GetName() + "]"); PutIRC("JOIN " + pChan->GetName() + (pChan->GetKey().empty() ? "" : " " + pChan->GetKey())); } } }
void HandleMessage(CNick& Nick, const CString& sMessage) { CString sNickServName = (!GetNV("NickServName").empty()) ? GetNV("NickServName") : "NickServ"; if (!GetNV("Password").empty() && Nick.NickEquals(sNickServName) && (sMessage.find("msg") != CString::npos || sMessage.find("authenticate") != CString::npos || sMessage.find("choose a different nickname") != CString::npos || sMessage.find("please choose a different nick") != CString::npos || sMessage.find("If this is your nick, identify yourself with") != CString::npos || sMessage.find("If this is your nick, type") != CString::npos || sMessage.find("This is a registered nickname, please identify") != CString::npos || sMessage.StripControls_n().find( "type /NickServ IDENTIFY password") != CString::npos || sMessage.StripControls_n().find( "type /msg NickServ IDENTIFY password") != CString::npos) && sMessage.AsUpper().find("IDENTIFY") != CString::npos && sMessage.find("help") == CString::npos) { MCString msValues; msValues["password"] = GetNV("Password"); PutIRC(CString::NamedFormat(GetNV("IdentifyCmd"), msValues)); } }
virtual EModRet OnUserMsg(CString& sTarget, CString& sMessage) { sTarget.TrimLeft(NickPrefix()); if (sMessage.Left(2) == "``") { sMessage.LeftChomp(2); return CONTINUE; } MCString::iterator it = FindNV(sTarget.AsLower()); if (it != EndNV()) { CChan* pChan = m_pNetwork->FindChan(sTarget); if (pChan) { if (!pChan->AutoClearChanBuffer()) pChan->AddBuffer(":" + NickPrefix() + _NAMEDFMT(m_pNetwork->GetIRCNick().GetNickMask()) + " PRIVMSG " + _NAMEDFMT(sTarget) + " :{text}", sMessage); m_pUser->PutUser(":" + NickPrefix() + m_pNetwork->GetIRCNick().GetNickMask() + " PRIVMSG " + sTarget + " :" + sMessage, NULL, m_pClient); } CString sMsg = MakeIvec() + sMessage; sMsg.Encrypt(it->second); sMsg.Base64Encode(); sMsg = "+OK *" + sMsg; PutIRC("PRIVMSG " + sTarget + " :" + sMsg); return HALTCORE; } return CONTINUE; }
virtual EModRet OnRaw(CString &sLine) { if (sLine.Token(0).Equals("AUTHENTICATE")) { Authenticate(sLine.Token(1, true)); } else if (sLine.Token(1).Equals("903")) { /* SASL success! */ m_pNetwork->GetIRCSock()->ResumeCap(); m_bAuthenticated = true; DEBUG("sasl: Authenticated with mechanism [" << m_Mechanisms.GetCurrent() << "]"); } else if (sLine.Token(1).Equals("904") || sLine.Token(1).Equals("905")) { DEBUG("sasl: Mechanism [" << m_Mechanisms.GetCurrent() << "] failed."); PutModule(m_Mechanisms.GetCurrent() + " mechanism failed."); if (m_Mechanisms.HasNext()) { m_Mechanisms.IncrementIndex(); PutIRC("AUTHENTICATE " + m_Mechanisms.GetCurrent()); } else { CheckRequireAuth(); m_pNetwork->GetIRCSock()->ResumeCap(); } } else if (sLine.Token(1).Equals("906")) { /* CAP wasn't paused? */ DEBUG("sasl: Reached 906."); CheckRequireAuth(); } else if (sLine.Token(1).Equals("907")) { m_bAuthenticated = true; m_pNetwork->GetIRCSock()->ResumeCap(); DEBUG("sasl: Received 907 -- We are already registered"); } else { return CONTINUE; } return HALT; }
virtual void OnClientDisconnect() { if (!m_pUser->GetAllClients().empty()) return; for (VCString::iterator it = m_vPerform.begin(); it != m_vPerform.end(); it++) { PutIRC(GetUser()->ExpandString(*it)); } }
virtual EModRet OnUserRaw(CString& sLine) { CString sCmd = sLine.Token(0); if (sCmd.Equals("AWAY")) { if (m_pClient->IsAway()) { m_pClient->SetAway(false); m_pClient->PutClient(":irc.znc.in 305 " + m_pClient->GetNick() + " :You are no longer marked as being away"); if (m_pNetwork) { const vector<CChan*>& vChans = m_pNetwork->GetChans(); vector<CChan*>::const_iterator it; for (it = vChans.begin(); it != vChans.end(); ++it) { // Skip channels which are detached or we don't use keepbuffer if (!(*it)->IsDetached() && (*it)->AutoClearChanBuffer()) { (*it)->ClearBuffer(); } } m_pNetwork->ClearQueryBuffer(); if (GetAutoAway() && m_pNetwork->IsIRCAway()) { PutIRC("AWAY"); } } } else { m_pClient->SetAway(true); m_pClient->PutClient(":irc.znc.in 306 " + m_pClient->GetNick() + " :You have been marked as being away"); if (GetAutoAway() && m_pNetwork && !m_pNetwork->IsIRCAway() && !m_pNetwork->IsUserOnline()) { // Use the supplied reason if there was one CString sAwayReason = sLine.Token(1, true).TrimPrefix_n(); if (sAwayReason.empty()) { sAwayReason = GetAwayReason(); } PutIRC("AWAY :" + sAwayReason); } } return HALTCORE; } return CONTINUE; }
void Handle(const CString& sNick) { if (m_Messaged.HasItem(sNick)) return; if (m_pUser->IsUserAttached()) return; m_Messaged.AddItem(sNick); PutIRC("PRIVMSG " + sNick + " :" + GetReply()); }
void HandleMessage(CNick& Nick, const CString& sMessage) { if (!m_sAuth.empty() && Nick.GetNick().CaseCmp("Q") == 0 && Nick.GetHost().CaseCmp("CServe.quakenet.org") == 0 && sMessage.find("AUTH") != CString::npos && sMessage.find("authenticate") != CString::npos) { PutIRC("PRIVMSG [email protected] :auth " + m_sAuth); } }
void CIRCNetwork::JoinChans() { bool bHaveKey = false; size_t joinLength = 4; // join CString sChannels, sKeys; for (vector<CChan*>::iterator it = m_vChans.begin(); it != m_vChans.end(); ++it) { CChan *pChan = *it; if (pChan->IsOn() || pChan->IsDisabled() || !JoinChan(pChan)) { continue; } size_t length = pChan->GetName().length() + pChan->GetKey().length() + 2; // +2 for either space or commas if ((joinLength + length) >= 510) { // Sent what we got, and cleanup PutIRC("JOIN " + sChannels + (bHaveKey ? (" " + sKeys) : "")); sChannels = ""; sKeys = ""; joinLength = 4; // join bHaveKey = false; } if (!sChannels.empty()) { sChannels += ","; sKeys += ","; } if (!pChan->GetKey().empty()) { bHaveKey = true; sKeys += pChan->GetKey(); } sChannels += pChan->GetName(); joinLength += length; } if (!sChannels.empty()) { PutIRC("JOIN " + sChannels + (bHaveKey ? (" " + sKeys) : "")); } }
void HandleMessage(CNick& Nick, const CString& sMessage) { if (!m_sPass.empty() && Nick.GetNick().Equals("NickServ") && (sMessage.find("msg") != CString::npos || sMessage.find("authenticate") != CString::npos) && sMessage.AsUpper().find("IDENTIFY") != CString::npos && sMessage.find("help") == CString::npos) { PutIRC("PRIVMSG NickServ :IDENTIFY " + m_sPass); } }
virtual void OnKick(const CNick& OpNick, const CString& sKickedNick, CChan& pChan, const CString& sMessage) { if (m_pUser->GetCurNick().Equals(sKickedNick)) { if (!delay) { PutIRC("JOIN " + pChan.GetName() + " " + pChan.GetKey()); pChan.Enable(); return; } AddTimer(new CRejoinJob(this, delay, 1, "Rejoin " + pChan.GetName(), "Rejoin channel after a delay")); } }
virtual EModRet OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage) { if (sMessage == "!ping") { PutIRC("PRIVMSG " + Channel.GetName() + " :PONG?"); } sMessage = "x " + sMessage + " x"; PutModule(sMessage); return CONTINUE; }
void SetAway(bool bTimer = true) { if (bTimer) { RemTimer("simple_away"); AddTimer(new CSimpleAwayJob(this, m_iAwayWait, 1, "simple_away", "Sets you away after detach")); } else { if (!m_bClientSetAway) { PutIRC("AWAY :" + ExpandReason()); m_bWeSetAway = true; } } }
bool ChallengeRespond(const CNick& Nick, const CString& sChallenge) { // Validate before responding - don't blindly trust everyone bool bValid = false; bool bMatchedHost = false; CAutoOpUser* pUser = NULL; for (map<CString, CAutoOpUser*>::iterator it = m_msUsers.begin(); it != m_msUsers.end(); it++) { pUser = it->second; // First verify that the guy who challenged us matches a user's host if (pUser->HostMatches(Nick.GetHostMask())) { const vector<CChan*>& Chans = m_pUser->GetChans(); bMatchedHost = true; // Also verify that they are opped in at least one of the user's chans for (size_t a = 0; a < Chans.size(); a++) { const CChan& Chan = *Chans[a]; CNick* pNick = Chan.FindNick(Nick.GetNick()); if (pNick) { if (pNick->HasPerm(CChan::Op) && pUser->ChannelMatches(Chan.GetName())) { bValid = true; break; } } } if (bValid) { break; } } } if (!bValid) { if (bMatchedHost) { PutModule("[" + Nick.GetHostMask() + "] sent us a challenge but they are not opped in any defined channels."); } else { PutModule("[" + Nick.GetHostMask() + "] sent us a challenge but they do not match a defined user."); } return false; } if (sChallenge.length() != AUTOOP_CHALLENGE_LENGTH) { PutModule("WARNING! [" + Nick.GetHostMask() + "] sent an invalid challenge."); return false; } CString sResponse = pUser->GetUserKey() + "::" + sChallenge; PutIRC("NOTICE " + Nick.GetNick() + " :!ZNCAO RESPONSE " + sResponse.MD5()); return false; }
virtual void OnJoin(const CNick& Nick, CChan& Channel) { // If we have ops in this chan if (Channel.HasPerm(CChan::Op) || Channel.HasPerm(CChan::HalfOp)) { for (map<CString, CAutoVoiceUser*>::iterator it = m_msUsers.begin(); it != m_msUsers.end(); ++it) { // and the nick who joined is a valid user if (it->second->HostMatches(Nick.GetHostMask()) && it->second->ChannelMatches(Channel.GetName())) { PutIRC("MODE " + Channel.GetName() + " +v " + Nick.GetNick()); break; } } } }
void OnClientDisconnect() { if(!m_pUser->IsUserAttached()) { const vector<CChan*>& vChans = m_pUser->GetChans(); while(!vChans.empty()) { CChan *pChan = *(vChans.begin()); CString sChan = pChan->GetName(); m_pUser->DelChan(sChan); PutIRC("PART " + sChan); } } }
~CRouteRepliesMod() override { requestQueue::iterator it; while (!m_vsPending.empty()) { it = m_vsPending.begin(); while (!it->second.empty()) { PutIRC(it->second[0].sLine); it->second.erase(it->second.begin()); } m_vsPending.erase(it); } }