Make IRCSock network aware

This commit is contained in:
Kyle Fuller
2011-08-24 14:30:54 +01:00
parent ef2b2cf601
commit da6c601e57
2 changed files with 144 additions and 143 deletions
+140 -140
View File
@@ -10,20 +10,21 @@
#include "Chan.h"
#include "Client.h"
#include "User.h"
#include "IRCNetwork.h"
#include "znc.h"
// These are used in OnGeneralCTCP()
const time_t CIRCSock::m_uCTCPFloodTime = 5;
const unsigned int CIRCSock::m_uCTCPFloodCount = 5;
CIRCSock::CIRCSock(CUser* pUser) : CZNCSock() {
m_pUser = pUser;
CIRCSock::CIRCSock(CIRCNetwork* pNetwork) : CZNCSock() {
m_pNetwork = pNetwork;
m_bAuthed = false;
m_bNamesx = false;
m_bUHNames = false;
EnableReadLine();
m_Nick.SetIdent(pUser->GetIdent());
m_Nick.SetHost(pUser->GetBindHost());
m_Nick.SetIdent(m_pNetwork->GetUser()->GetIdent());
m_Nick.SetHost(m_pNetwork->GetUser()->GetBindHost());
m_uMaxNickLen = 9;
m_uCapPaused = 0;
@@ -42,7 +43,7 @@ CIRCSock::CIRCSock(CUser* pUser) : CZNCSock() {
m_mueChanModes['i'] = NoArg;
m_mueChanModes['n'] = NoArg;
pUser->SetIRCSocket(this);
pNetwork->SetIRCSocket(this);
// RFC says a line can have 512 chars max, but we don't care ;)
SetMaxBufferThreshold(1024);
@@ -50,15 +51,15 @@ CIRCSock::CIRCSock(CUser* pUser) : CZNCSock() {
CIRCSock::~CIRCSock() {
if (!m_bAuthed) {
MODULECALL(OnIRCConnectionError(this), m_pUser, NULL, NOTHING);
MODULECALL(OnIRCConnectionError(this), m_pNetwork->GetUser(), m_pNetwork, NULL, NOTHING);
}
const vector<CChan*>& vChans = m_pUser->GetChans();
const vector<CChan*>& vChans = m_pNetwork->GetChans();
for (unsigned int a = 0; a < vChans.size(); a++) {
vChans[a]->Reset();
}
m_pUser->IRCDisconnected();
m_pNetwork->IRCDisconnected();
for (map<CString, CChan*>::iterator a = m_msChans.begin(); a != m_msChans.end(); ++a) {
delete a->second;
@@ -66,8 +67,8 @@ CIRCSock::~CIRCSock() {
Quit();
m_msChans.clear();
GetUser()->AddBytesRead(GetBytesRead());
GetUser()->AddBytesWritten(GetBytesWritten());
m_pNetwork->GetUser()->AddBytesRead(GetBytesRead());
m_pNetwork->GetUser()->AddBytesWritten(GetBytesWritten());
}
void CIRCSock::Quit(const CString& sQuitMsg) {
@@ -78,7 +79,7 @@ void CIRCSock::Quit(const CString& sQuitMsg) {
if (!sQuitMsg.empty()) {
PutIRC("QUIT :" + sQuitMsg);
} else {
PutIRC("QUIT :" + m_pUser->ExpandString(m_pUser->GetQuitMsg()));
PutIRC("QUIT :" + m_pNetwork->GetUser()->ExpandString(m_pNetwork->GetUser()->GetQuitMsg()));
}
Close(CLT_AFTERWRITE);
}
@@ -88,9 +89,9 @@ void CIRCSock::ReadLine(const CString& sData) {
sLine.TrimRight("\n\r");
DEBUG("(" << m_pUser->GetUserName() << ") IRC -> ZNC [" << sLine << "]");
DEBUG("(" << m_pNetwork->GetUser()->GetUserName() << "/" << m_pNetwork->GetName() << ") IRC -> ZNC [" << sLine << "]");
MODULECALL(OnRaw(sLine), m_pUser, NULL, return);
MODULECALL(OnRaw(sLine), m_pNetwork->GetUser(), m_pNetwork, NULL, return);
if (sLine.Equals("PING ", false, 5)) {
// Generate a reply and don't forward this to any user,
@@ -108,7 +109,7 @@ void CIRCSock::ReadLine(const CString& sData) {
sError.LeftChomp();
}
m_pUser->PutStatus("Error from Server [" + sError + "]");
m_pNetwork->PutStatus("Error from Server [" + sError + "]");
return;
}
@@ -124,19 +125,19 @@ void CIRCSock::ReadLine(const CString& sData) {
case 1: { // :irc.server.com 001 nick :Welcome to the Internet Relay Network nick
if (m_bAuthed && sServer == "irc.znc.in") {
// m_bAuthed == true => we already received another 001 => we might be in a traffic loop
m_pUser->PutStatus("ZNC seems to be connected to itself, disconnecting...");
m_pNetwork->PutStatus("ZNC seems to be connected to itself, disconnecting...");
Quit();
return;
}
m_pUser->SetIRCServer(sServer);
m_pNetwork->SetIRCServer(sServer);
SetTimeout(540, TMO_READ); // Now that we are connected, let nature take its course
PutIRC("WHO " + sNick);
m_bAuthed = true;
m_pUser->PutStatus("Connected!");
m_pNetwork->PutStatus("Connected!");
vector<CClient*>& vClients = m_pUser->GetClients();
vector<CClient*>& vClients = m_pNetwork->GetClients();
for (unsigned int a = 0; a < vClients.size(); a++) {
CClient* pClient = vClients[a];
@@ -150,16 +151,16 @@ void CIRCSock::ReadLine(const CString& sData) {
SetNick(sNick);
MODULECALL(OnIRCConnected(), m_pUser, NULL, NOTHING);
MODULECALL(OnIRCConnected(), m_pNetwork->GetUser(), m_pNetwork, NULL, NOTHING);
m_pUser->ClearRawBuffer();
m_pUser->AddRawBuffer(":" + sServer + " " + sCmd + " ", " " + sRest);
m_pNetwork->ClearRawBuffer();
m_pNetwork->AddRawBuffer(":" + sServer + " " + sCmd + " ", " " + sRest);
break;
}
case 5:
ParseISupport(sRest);
m_pUser->UpdateExactRawBuffer(":" + sServer + " " + sCmd + " ", " " + sRest);
m_pNetwork->UpdateExactRawBuffer(":" + sServer + " " + sCmd + " ", " " + sRest);
break;
case 2:
case 3:
@@ -171,17 +172,17 @@ void CIRCSock::ReadLine(const CString& sData) {
case 255: // client count
case 265: // local users
case 266: // global users
m_pUser->UpdateRawBuffer(":" + sServer + " " + sCmd + " ", " " + sRest);
m_pNetwork->UpdateRawBuffer(":" + sServer + " " + sCmd + " ", " " + sRest);
break;
case 305:
m_pUser->SetIRCAway(false);
m_pNetwork->SetIRCAway(false);
break;
case 306:
m_pUser->SetIRCAway(true);
m_pNetwork->SetIRCAway(true);
break;
case 324: { // MODE
sRest.Trim();
CChan* pChan = m_pUser->FindChan(sRest.Token(0));
CChan* pChan = m_pNetwork->FindChan(sRest.Token(0));
if (pChan) {
pChan->SetModes(sRest.Token(1, true));
@@ -190,7 +191,7 @@ void CIRCSock::ReadLine(const CString& sData) {
break;
case 329: {
sRest.Trim();
CChan* pChan = m_pUser->FindChan(sRest.Token(0));
CChan* pChan = m_pNetwork->FindChan(sRest.Token(0));
if (pChan) {
unsigned long ulDate = sLine.Token(4).ToULong();
@@ -200,7 +201,7 @@ void CIRCSock::ReadLine(const CString& sData) {
break;
case 331: {
// :irc.server.com 331 yournick #chan :No topic is set.
CChan* pChan = m_pUser->FindChan(sLine.Token(3));
CChan* pChan = m_pNetwork->FindChan(sLine.Token(3));
if (pChan) {
pChan->SetTopic("");
@@ -210,7 +211,7 @@ void CIRCSock::ReadLine(const CString& sData) {
}
case 332: {
// :irc.server.com 332 yournick #chan :This is a topic
CChan* pChan = m_pUser->FindChan(sLine.Token(3));
CChan* pChan = m_pNetwork->FindChan(sLine.Token(3));
if (pChan) {
CString sTopic = sLine.Token(4, true);
@@ -222,7 +223,7 @@ void CIRCSock::ReadLine(const CString& sData) {
}
case 333: {
// :irc.server.com 333 yournick #chan setternick 1112320796
CChan* pChan = m_pUser->FindChan(sLine.Token(3));
CChan* pChan = m_pNetwork->FindChan(sLine.Token(3));
if (pChan) {
sNick = sLine.Token(4);
@@ -248,10 +249,10 @@ void CIRCSock::ReadLine(const CString& sData) {
m_Nick.SetHost(sHost);
}
m_pUser->SetIRCNick(m_Nick);
m_pUser->SetIRCServer(sServer);
m_pNetwork->SetIRCNick(m_Nick);
m_pNetwork->SetIRCServer(sServer);
const vector<CChan*>& vChans = m_pUser->GetChans();
const vector<CChan*>& vChans = m_pNetwork->GetChans();
for (unsigned int a = 0; a < vChans.size(); a++) {
vChans[a]->OnWho(sNick, sIdent, sHost);
@@ -262,7 +263,7 @@ void CIRCSock::ReadLine(const CString& sData) {
case 353: { // NAMES
sRest.Trim();
// Todo: allow for non @+= server msgs
CChan* pChan = m_pUser->FindChan(sRest.Token(1));
CChan* pChan = m_pNetwork->FindChan(sRest.Token(1));
// If we don't know that channel, some client might have
// requested a /names for it and we really should forward this.
if (pChan) {
@@ -280,10 +281,10 @@ void CIRCSock::ReadLine(const CString& sData) {
return;
}
case 366: { // end of names list
m_pUser->PutUser(sLine); // First send them the raw
m_pNetwork->PutUser(sLine); // First send them the raw
// :irc.server.com 366 nick #chan :End of /NAMES list.
CChan* pChan = m_pUser->FindChan(sRest.Token(0));
CChan* pChan = m_pNetwork->FindChan(sRest.Token(0));
if (pChan) {
if (pChan->IsOn()) {
@@ -292,7 +293,7 @@ void CIRCSock::ReadLine(const CString& sData) {
CString sModes = pChan->GetDefaultModes();
if (sModes.empty()) {
sModes = m_pUser->GetDefaultChanModes();
sModes = m_pNetwork->GetUser()->GetDefaultChanModes();
}
if (!sModes.empty()) {
@@ -306,16 +307,16 @@ void CIRCSock::ReadLine(const CString& sData) {
}
case 375: // begin motd
case 422: // MOTD File is missing
m_pUser->ClearMotdBuffer();
m_pNetwork->ClearMotdBuffer();
case 372: // motd
case 376: // end motd
m_pUser->AddMotdBuffer(":" + sServer + " " + sCmd + " ", " " + sRest);
m_pNetwork->AddMotdBuffer(":" + sServer + " " + sCmd + " ", " " + sRest);
break;
case 437:
// :irc.server.net 437 * badnick :Nick/channel is temporarily unavailable
// :irc.server.net 437 mynick badnick :Nick/channel is temporarily unavailable
// :irc.server.net 437 mynick badnick :Cannot change nickname while banned on channel
if (m_pUser->IsChan(sRest.Token(0)) || sNick != "*")
if (m_pNetwork->IsChan(sRest.Token(0)) || sNick != "*")
break;
case 432: // :irc.server.com 432 * nick :Erroneous Nickname: Illegal characters
case 433: {
@@ -337,14 +338,14 @@ void CIRCSock::ReadLine(const CString& sData) {
// :mccaffrey.freenode.net 470 mynick #electronics ##electronics :Forwarding to another channel
// freenode style numeric
CChan* pChan = m_pUser->FindChan(sRest.Token(0));
CChan* pChan = m_pNetwork->FindChan(sRest.Token(0));
if (!pChan) {
// unreal style numeric
pChan = m_pUser->FindChan(sRest.Token(1));
pChan = m_pNetwork->FindChan(sRest.Token(1));
}
if (pChan) {
pChan->Disable();
m_pUser->PutStatus("Channel [" + pChan->GetName() + "] is linked to "
m_pNetwork->PutStatus("Channel [" + pChan->GetName() + "] is linked to "
"another channel and was thus disabled.");
}
break;
@@ -364,7 +365,7 @@ void CIRCSock::ReadLine(const CString& sData) {
}
vector<CChan*> vFoundChans;
const vector<CChan*>& vChans = m_pUser->GetChans();
const vector<CChan*>& vChans = m_pNetwork->GetChans();
for (unsigned int a = 0; a < vChans.size(); a++) {
CChan* pChan = vChans[a];
@@ -385,7 +386,7 @@ void CIRCSock::ReadLine(const CString& sData) {
SetNick(sNewNick);
}
MODULECALL(OnNick(Nick, sNewNick, vFoundChans), m_pUser, NULL, NOTHING);
MODULECALL(OnNick(Nick, sNewNick, vFoundChans), m_pNetwork->GetUser(), m_pNetwork, NULL, NOTHING);
if (!bIsVisible) {
return;
@@ -401,7 +402,7 @@ void CIRCSock::ReadLine(const CString& sData) {
// :nick!ident@host.com QUIT :message
if (Nick.GetNick().Equals(GetNick())) {
m_pUser->PutStatus("You quit [" + sMessage + "]");
m_pNetwork->PutStatus("You quit [" + sMessage + "]");
// We don't call module hooks and we don't
// forward this quit to clients (Some clients
// disconnect if they receive such a QUIT)
@@ -409,7 +410,7 @@ void CIRCSock::ReadLine(const CString& sData) {
}
vector<CChan*> vFoundChans;
const vector<CChan*>& vChans = m_pUser->GetChans();
const vector<CChan*>& vChans = m_pNetwork->GetChans();
for (unsigned int a = 0; a < vChans.size(); a++) {
CChan* pChan = vChans[a];
@@ -423,7 +424,7 @@ void CIRCSock::ReadLine(const CString& sData) {
}
}
MODULECALL(OnQuit(Nick, sMessage, vFoundChans), m_pUser, NULL, NOTHING);
MODULECALL(OnQuit(Nick, sMessage, vFoundChans), m_pNetwork->GetUser(), m_pNetwork, NULL, NOTHING);
if (!bIsVisible) {
return;
@@ -438,20 +439,20 @@ void CIRCSock::ReadLine(const CString& sData) {
// Todo: use nick compare function
if (Nick.GetNick().Equals(GetNick())) {
m_pUser->AddChan(sChan, false);
pChan = m_pUser->FindChan(sChan);
m_pNetwork->AddChan(sChan, false);
pChan = m_pNetwork->FindChan(sChan);
if (pChan) {
pChan->ResetJoinTries();
pChan->Enable();
pChan->SetIsOn(true);
}
} else {
pChan = m_pUser->FindChan(sChan);
pChan = m_pNetwork->FindChan(sChan);
}
if (pChan) {
pChan->AddNick(Nick.GetNickMask());
MODULECALL(OnJoin(Nick.GetNickMask(), *pChan), m_pUser, NULL, NOTHING);
MODULECALL(OnJoin(Nick.GetNickMask(), *pChan), m_pNetwork->GetUser(), m_pNetwork, NULL, NOTHING);
if (pChan->IsDetached()) {
return;
@@ -464,11 +465,11 @@ void CIRCSock::ReadLine(const CString& sData) {
}
CString sMsg = sRest.Token(1, true).TrimPrefix_n(":");
CChan* pChan = m_pUser->FindChan(sChan);
CChan* pChan = m_pNetwork->FindChan(sChan);
bool bDetached = false;
if (pChan) {
pChan->RemNick(Nick.GetNick());
MODULECALL(OnPart(Nick.GetNickMask(), *pChan, sMsg), m_pUser, NULL, NOTHING);
MODULECALL(OnPart(Nick.GetNickMask(), *pChan, sMsg), m_pNetwork->GetUser(), m_pNetwork, NULL, NOTHING);
if (pChan->IsDetached())
bDetached = true;
@@ -476,12 +477,12 @@ void CIRCSock::ReadLine(const CString& sData) {
// Todo: use nick compare function
if (Nick.GetNick().Equals(GetNick())) {
m_pUser->DelChan(sChan);
m_pNetwork->DelChan(sChan);
}
/*
* We use this boolean because
* m_pUser->DelChan() will delete this channel
* m_pNetwork->DelChan() will delete this channel
* and thus we would dereference an
* already-freed pointer!
*/
@@ -494,7 +495,7 @@ void CIRCSock::ReadLine(const CString& sData) {
if (sModes.Left(1) == ":")
sModes = sModes.substr(1);
CChan* pChan = m_pUser->FindChan(sTarget);
CChan* pChan = m_pNetwork->FindChan(sTarget);
if (pChan) {
pChan->ModeChange(sModes, &Nick);
@@ -505,7 +506,7 @@ void CIRCSock::ReadLine(const CString& sData) {
CString sModeArg = sModes.Token(0);
bool bAdd = true;
/* no module call defined (yet?)
MODULECALL(OnRawUserMode(*pOpNick, *this, sModeArg, sArgs), m_pUser, NULL, );
MODULECALL(OnRawUserMode(*pOpNick, *this, sModeArg, sArgs), m_pNetwork->GetUser(), NULL, );
*/
for (unsigned int a = 0; a < sModeArg.size(); a++) {
const unsigned char& uMode = sModeArg[a];
@@ -530,10 +531,10 @@ void CIRCSock::ReadLine(const CString& sData) {
CString sMsg = sRest.Token(2, true);
sMsg.LeftChomp();
CChan* pChan = m_pUser->FindChan(sChan);
CChan* pChan = m_pNetwork->FindChan(sChan);
if (pChan) {
MODULECALL(OnKick(Nick, sKickedNick, *pChan, sMsg), m_pUser, NULL, NOTHING);
MODULECALL(OnKick(Nick, sKickedNick, *pChan, sMsg), m_pNetwork->GetUser(), m_pNetwork, NULL, NOTHING);
// do not remove the nick till after the OnKick call, so modules
// can do Chan.FindNick or something to get more info.
pChan->RemNick(sKickedNick);
@@ -565,7 +566,7 @@ void CIRCSock::ReadLine(const CString& sData) {
}
}
m_pUser->PutUser(":" + Nick.GetNickMask() + " NOTICE " + sTarget + " :\001" + sMsg + "\001");
m_pNetwork->PutUser(":" + Nick.GetNickMask() + " NOTICE " + sTarget + " :\001" + sMsg + "\001");
return;
} else {
if (sTarget.Equals(GetNick())) {
@@ -579,22 +580,22 @@ void CIRCSock::ReadLine(const CString& sData) {
}
}
if (Nick.GetNick().Equals(m_pUser->GetIRCServer())) {
m_pUser->PutUser(":" + Nick.GetNick() + " NOTICE " + sTarget + " :" + sMsg);
if (Nick.GetNick().Equals(m_pNetwork->GetIRCServer())) {
m_pNetwork->PutUser(":" + Nick.GetNick() + " NOTICE " + sTarget + " :" + sMsg);
} else {
m_pUser->PutUser(":" + Nick.GetNickMask() + " NOTICE " + sTarget + " :" + sMsg);
m_pNetwork->PutUser(":" + Nick.GetNickMask() + " NOTICE " + sTarget + " :" + sMsg);
}
return;
} else if (sCmd.Equals("TOPIC")) {
// :nick!ident@host.com TOPIC #chan :This is a topic
CChan* pChan = m_pUser->FindChan(sLine.Token(2));
CChan* pChan = m_pNetwork->FindChan(sLine.Token(2));
if (pChan) {
CString sTopic = sLine.Token(3, true);
sTopic.LeftChomp();
MODULECALL(OnTopic(Nick, *pChan, sTopic), m_pUser, NULL, return)
MODULECALL(OnTopic(Nick, *pChan, sTopic), m_pNetwork->GetUser(), m_pNetwork, NULL, return)
pChan->SetTopicOwner(Nick.GetNick());
pChan->SetTopicDate((unsigned long) time(NULL));
@@ -629,7 +630,7 @@ void CIRCSock::ReadLine(const CString& sData) {
}
}
m_pUser->PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + sTarget + " :\001" + sMsg + "\001");
m_pNetwork->PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + sTarget + " :\001" + sMsg + "\001");
return;
} else {
if (sTarget.Equals(GetNick())) {
@@ -642,7 +643,7 @@ void CIRCSock::ReadLine(const CString& sData) {
}
}
m_pUser->PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + sTarget + " :" + sMsg);
m_pNetwork->PutUser(":" + Nick.GetNickMask() + " PRIVMSG " + sTarget + " :" + sMsg);
return;
}
} else if (sCmd.Equals("WALLOPS")) {
@@ -653,8 +654,8 @@ void CIRCSock::ReadLine(const CString& sData) {
sMsg.LeftChomp();
}
if (!m_pUser->IsUserAttached()) {
m_pUser->AddQueryBuffer(":" + Nick.GetNickMask() + " WALLOPS ", ":" + m_pUser->AddTimestamp(sMsg), false);
if (!m_pNetwork->IsUserAttached()) {
m_pNetwork->AddQueryBuffer(":" + Nick.GetNickMask() + " WALLOPS ", ":" + m_pNetwork->GetUser()->AddTimestamp(sMsg), false);
}
} else if (sCmd.Equals("CAP")) {
// CAPs are supported only before authorization.
@@ -694,7 +695,7 @@ void CIRCSock::ReadLine(const CString& sData) {
}
} else if (sSubCmd == "ACK") {
sArgs.Trim();
MODULECALL(OnServerCapResult(sArgs, true), m_pUser, NULL, NOTHING);
MODULECALL(OnServerCapResult(sArgs, true), m_pNetwork->GetUser(), m_pNetwork, NULL, NOTHING);
if ("multi-prefix" == sArgs) {
m_bNamesx = true;
} else if ("userhost-in-names" == sArgs) {
@@ -705,7 +706,7 @@ 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();
MODULECALL(OnServerCapResult(sArgs, false), m_pUser, NULL, NOTHING);
MODULECALL(OnServerCapResult(sArgs, false), m_pNetwork->GetUser(), m_pNetwork, NULL, NOTHING);
}
SendNextCap();
@@ -715,7 +716,7 @@ void CIRCSock::ReadLine(const CString& sData) {
}
}
m_pUser->PutUser(sLine);
m_pNetwork->PutUser(sLine);
}
void CIRCSock::SendNextCap() {
@@ -741,25 +742,25 @@ void CIRCSock::ResumeCap() {
}
bool CIRCSock::OnServerCapAvailable(const CString& sCap) {
MODULECALL(OnServerCapAvailable(sCap), m_pUser, NULL, return true);
MODULECALL(OnServerCapAvailable(sCap), m_pNetwork->GetUser(), m_pNetwork, NULL, return true);
return false;
}
bool CIRCSock::OnCTCPReply(CNick& Nick, CString& sMessage) {
MODULECALL(OnCTCPReply(Nick, sMessage), m_pUser, NULL, return true);
MODULECALL(OnCTCPReply(Nick, sMessage), m_pNetwork->GetUser(), m_pNetwork, NULL, return true);
return false;
}
bool CIRCSock::OnPrivCTCP(CNick& Nick, CString& sMessage) {
MODULECALL(OnPrivCTCP(Nick, sMessage), m_pUser, NULL, return true);
MODULECALL(OnPrivCTCP(Nick, sMessage), m_pNetwork->GetUser(), m_pNetwork, NULL, return true);
if (sMessage.TrimPrefix("ACTION ")) {
MODULECALL(OnPrivAction(Nick, sMessage), m_pUser, NULL, return true);
MODULECALL(OnPrivAction(Nick, sMessage), m_pNetwork->GetUser(), m_pNetwork, NULL, return true);
if (!m_pUser->IsUserAttached()) {
if (!m_pNetwork->IsUserAttached()) {
// If the user is detached, add to the buffer
m_pUser->AddQueryBuffer(":" + Nick.GetNickMask() + " PRIVMSG ", " :\001ACTION " + m_pUser->AddTimestamp(sMessage) + "\001");
m_pNetwork->AddQueryBuffer(":" + Nick.GetNickMask() + " PRIVMSG ", " :\001ACTION " + m_pNetwork->GetUser()->AddTimestamp(sMessage) + "\001");
}
sMessage = "ACTION " + sMessage;
@@ -770,18 +771,18 @@ bool CIRCSock::OnPrivCTCP(CNick& Nick, CString& sMessage) {
}
bool CIRCSock::OnGeneralCTCP(CNick& Nick, CString& sMessage) {
const MCString& mssCTCPReplies = m_pUser->GetCTCPReplies();
const MCString& mssCTCPReplies = m_pNetwork->GetUser()->GetCTCPReplies();
CString sQuery = sMessage.Token(0).AsUpper();
MCString::const_iterator it = mssCTCPReplies.find(sQuery);
bool bHaveReply = false;
CString sReply;
if (it != mssCTCPReplies.end()) {
sReply = m_pUser->ExpandString(it->second);
sReply = m_pNetwork->GetUser()->ExpandString(it->second);
bHaveReply = true;
}
if (!bHaveReply && !m_pUser->IsUserAttached()) {
if (!bHaveReply && !m_pNetwork->IsUserAttached()) {
if (sQuery == "VERSION") {
sReply = CZNC::GetTag();
} else if (sQuery == "PING") {
@@ -810,37 +811,37 @@ bool CIRCSock::OnGeneralCTCP(CNick& Nick, CString& sMessage) {
}
bool CIRCSock::OnPrivNotice(CNick& Nick, CString& sMessage) {
MODULECALL(OnPrivNotice(Nick, sMessage), m_pUser, NULL, return true);
MODULECALL(OnPrivNotice(Nick, sMessage), m_pNetwork->GetUser(), m_pNetwork, NULL, return true);
if (!m_pUser->IsUserAttached()) {
if (!m_pNetwork->IsUserAttached()) {
// If the user is detached, add to the buffer
m_pUser->AddQueryBuffer(":" + Nick.GetNickMask() + " NOTICE ", " :" + m_pUser->AddTimestamp(sMessage));
m_pNetwork->AddQueryBuffer(":" + Nick.GetNickMask() + " NOTICE ", " :" + m_pNetwork->GetUser()->AddTimestamp(sMessage));
}
return false;
}
bool CIRCSock::OnPrivMsg(CNick& Nick, CString& sMessage) {
MODULECALL(OnPrivMsg(Nick, sMessage), m_pUser, NULL, return true);
MODULECALL(OnPrivMsg(Nick, sMessage), m_pNetwork->GetUser(), m_pNetwork, NULL, return true);
if (!m_pUser->IsUserAttached()) {
if (!m_pNetwork->IsUserAttached()) {
// If the user is detached, add to the buffer
m_pUser->AddQueryBuffer(":" + Nick.GetNickMask() + " PRIVMSG ", " :" + m_pUser->AddTimestamp(sMessage));
m_pNetwork->AddQueryBuffer(":" + Nick.GetNickMask() + " PRIVMSG ", " :" + m_pNetwork->GetUser()->AddTimestamp(sMessage));
}
return false;
}
bool CIRCSock::OnChanCTCP(CNick& Nick, const CString& sChan, CString& sMessage) {
CChan* pChan = m_pUser->FindChan(sChan);
CChan* pChan = m_pNetwork->FindChan(sChan);
if (pChan) {
MODULECALL(OnChanCTCP(Nick, *pChan, sMessage), m_pUser, NULL, return true);
MODULECALL(OnChanCTCP(Nick, *pChan, sMessage), m_pNetwork->GetUser(), m_pNetwork, NULL, return true);
// Record a /me
if (sMessage.TrimPrefix("ACTION ")) {
MODULECALL(OnChanAction(Nick, *pChan, sMessage), m_pUser, NULL, return true);
if (pChan->KeepBuffer() || !m_pUser->IsUserAttached() || pChan->IsDetached()) {
pChan->AddBuffer(":" + Nick.GetNickMask() + " PRIVMSG " + sChan + " :\001ACTION " + m_pUser->AddTimestamp(sMessage) + "\001");
MODULECALL(OnChanAction(Nick, *pChan, sMessage), m_pNetwork->GetUser(), m_pNetwork, NULL, return true);
if (pChan->KeepBuffer() || !m_pNetwork->IsUserAttached() || pChan->IsDetached()) {
pChan->AddBuffer(":" + Nick.GetNickMask() + " PRIVMSG " + sChan + " :\001ACTION " + m_pNetwork->GetUser()->AddTimestamp(sMessage) + "\001");
}
sMessage = "ACTION " + sMessage;
}
@@ -853,12 +854,12 @@ bool CIRCSock::OnChanCTCP(CNick& Nick, const CString& sChan, CString& sMessage)
}
bool CIRCSock::OnChanNotice(CNick& Nick, const CString& sChan, CString& sMessage) {
CChan* pChan = m_pUser->FindChan(sChan);
CChan* pChan = m_pNetwork->FindChan(sChan);
if (pChan) {
MODULECALL(OnChanNotice(Nick, *pChan, sMessage), m_pUser, NULL, return true);
MODULECALL(OnChanNotice(Nick, *pChan, sMessage), m_pNetwork->GetUser(), m_pNetwork, NULL, return true);
if (pChan->KeepBuffer() || !m_pUser->IsUserAttached() || pChan->IsDetached()) {
pChan->AddBuffer(":" + Nick.GetNickMask() + " NOTICE " + sChan + " :" + m_pUser->AddTimestamp(sMessage));
if (pChan->KeepBuffer() || !m_pNetwork->IsUserAttached() || pChan->IsDetached()) {
pChan->AddBuffer(":" + Nick.GetNickMask() + " NOTICE " + sChan + " :" + m_pNetwork->GetUser()->AddTimestamp(sMessage));
}
}
@@ -866,12 +867,12 @@ bool CIRCSock::OnChanNotice(CNick& Nick, const CString& sChan, CString& sMessage
}
bool CIRCSock::OnChanMsg(CNick& Nick, const CString& sChan, CString& sMessage) {
CChan* pChan = m_pUser->FindChan(sChan);
CChan* pChan = m_pNetwork->FindChan(sChan);
if (pChan) {
MODULECALL(OnChanMsg(Nick, *pChan, sMessage), m_pUser, NULL, return true);
MODULECALL(OnChanMsg(Nick, *pChan, sMessage), m_pNetwork->GetUser(), m_pNetwork, NULL, return true);
if (pChan->KeepBuffer() || !m_pUser->IsUserAttached() || pChan->IsDetached()) {
pChan->AddBuffer(":" + Nick.GetNickMask() + " PRIVMSG " + sChan + " :" + m_pUser->AddTimestamp(sMessage));
if (pChan->KeepBuffer() || !m_pNetwork->IsUserAttached() || pChan->IsDetached()) {
pChan->AddBuffer(":" + Nick.GetNickMask() + " PRIVMSG " + sChan + " :" + m_pNetwork->GetUser()->AddTimestamp(sMessage));
}
}
@@ -879,24 +880,24 @@ bool CIRCSock::OnChanMsg(CNick& Nick, const CString& sChan, CString& sMessage) {
}
void CIRCSock::PutIRC(const CString& sLine) {
DEBUG("(" << m_pUser->GetUserName() << ") ZNC -> IRC [" << sLine << "]");
DEBUG("(" << m_pNetwork->GetUser()->GetUserName() << "/" << m_pNetwork->GetName() << ") ZNC -> IRC [" << sLine << "]");
Write(sLine + "\r\n");
}
void CIRCSock::SetNick(const CString& sNick) {
m_Nick.SetNick(sNick);
m_pUser->SetIRCNick(m_Nick);
m_pNetwork->SetIRCNick(m_Nick);
}
void CIRCSock::Connected() {
DEBUG(GetSockName() << " == Connected()");
CString sPass = m_sPass;
CString sNick = m_pUser->GetNick();
CString sIdent = m_pUser->GetIdent();
CString sRealName = m_pUser->GetRealName();
CString sNick = m_pNetwork->GetUser()->GetNick();
CString sIdent = m_pNetwork->GetUser()->GetIdent();
CString sRealName = m_pNetwork->GetUser()->GetRealName();
MODULECALL(OnIRCRegistration(sPass, sNick, sIdent, sRealName), m_pUser, NULL, return);
MODULECALL(OnIRCRegistration(sPass, sNick, sIdent, sRealName), m_pNetwork->GetUser(), m_pNetwork, NULL, return);
PutIRC("CAP LS");
@@ -912,15 +913,15 @@ void CIRCSock::Connected() {
}
void CIRCSock::Disconnected() {
MODULECALL(OnIRCDisconnected(), m_pUser, NULL, NOTHING);
MODULECALL(OnIRCDisconnected(), m_pNetwork->GetUser(), m_pNetwork, NULL, NOTHING);
DEBUG(GetSockName() << " == Disconnected()");
if (!m_pUser->IsBeingDeleted() && m_pUser->GetIRCConnectEnabled() &&
m_pUser->GetServers().size() != 0) {
m_pUser->PutStatus("Disconnected from IRC. Reconnecting...");
if (!m_pNetwork->GetUser()->IsBeingDeleted() && m_pNetwork->GetUser()->GetIRCConnectEnabled() &&
m_pNetwork->GetServers().size() != 0) {
m_pNetwork->PutStatus("Disconnected from IRC. Reconnecting...");
}
m_pUser->ClearRawBuffer();
m_pUser->ClearMotdBuffer();
m_pNetwork->ClearRawBuffer();
m_pNetwork->ClearMotdBuffer();
ResetChans();
@@ -932,7 +933,7 @@ void CIRCSock::Disconnected() {
sUserMode += *it;
}
if (!sUserMode.empty()) {
m_pUser->PutUser(":" + m_pUser->GetIRCNick().GetNickMask() + " MODE " + m_pUser->GetIRCNick().GetNick() + " :-" + sUserMode);
m_pNetwork->PutUser(":" + m_pNetwork->GetIRCNick().GetNickMask() + " MODE " + m_pNetwork->GetIRCNick().GetNick() + " :-" + sUserMode);
}
// also clear the user modes in our space:
@@ -958,16 +959,15 @@ void CIRCSock::SockError(int iErrno) {
DEBUG(GetSockName() << " == SockError(" << iErrno << " "
<< sError << ")");
if (!m_pUser->IsBeingDeleted()) {
if (GetConState() != CST_OK)
m_pUser->PutStatus("Cannot connect to IRC (" +
sError + "). Retrying...");
else
m_pUser->PutStatus("Disconnected from IRC (" +
sError + "). Reconnecting...");
if (!m_pNetwork->GetUser()->IsBeingDeleted()) {
if (GetConState() != CST_OK) {
m_pNetwork->PutStatus("Cannot connect to IRC (" + sError + "). Retrying...");
} else {
m_pNetwork->PutStatus("Disconnected from IRC (" + sError + "). Reconnecting...");
}
}
m_pUser->ClearRawBuffer();
m_pUser->ClearMotdBuffer();
m_pNetwork->ClearRawBuffer();
m_pNetwork->ClearMotdBuffer();
ResetChans();
m_scUserModes.clear();
@@ -975,11 +975,11 @@ void CIRCSock::SockError(int iErrno) {
void CIRCSock::Timeout() {
DEBUG(GetSockName() << " == Timeout()");
if (!m_pUser->IsBeingDeleted()) {
m_pUser->PutStatus("IRC connection timed out. Reconnecting...");
if (!m_pNetwork->GetUser()->IsBeingDeleted()) {
m_pNetwork->PutStatus("IRC connection timed out. Reconnecting...");
}
m_pUser->ClearRawBuffer();
m_pUser->ClearMotdBuffer();
m_pNetwork->ClearRawBuffer();
m_pNetwork->ClearMotdBuffer();
ResetChans();
m_scUserModes.empty();
@@ -987,16 +987,16 @@ void CIRCSock::Timeout() {
void CIRCSock::ConnectionRefused() {
DEBUG(GetSockName() << " == ConnectionRefused()");
if (!m_pUser->IsBeingDeleted()) {
m_pUser->PutStatus("Connection Refused. Reconnecting...");
if (!m_pNetwork->GetUser()->IsBeingDeleted()) {
m_pNetwork->PutStatus("Connection Refused. Reconnecting...");
}
m_pUser->ClearRawBuffer();
m_pUser->ClearMotdBuffer();
m_pNetwork->ClearRawBuffer();
m_pNetwork->ClearMotdBuffer();
}
void CIRCSock::ReachedMaxBuffer() {
DEBUG(GetSockName() << " == ReachedMaxBuffer()");
m_pUser->PutStatus("Received a too long line from the IRC server!");
m_pNetwork->PutStatus("Received a too long line from the IRC server!");
Quit();
}
@@ -1020,7 +1020,7 @@ void CIRCSock::ParseISupport(const CString& sLine) {
m_sPermModes = sPermModes;
}
} else if (sName.Equals("CHANTYPES")) {
m_pUser->SetChanPrefixes(sValue);
m_pNetwork->SetChanPrefixes(sValue);
} else if (sName.Equals("NICKLEN")) {
unsigned int uMax = sValue.ToUInt();
@@ -1054,7 +1054,7 @@ void CIRCSock::ParseISupport(const CString& sLine) {
}
void CIRCSock::ForwardRaw353(const CString& sLine) const {
vector<CClient*>& vClients = m_pUser->GetClients();
vector<CClient*>& vClients = m_pNetwork->GetClients();
vector<CClient*>::iterator it;
for (it = vClients.begin(); it != vClients.end(); ++it) {
@@ -1069,7 +1069,7 @@ void CIRCSock::ForwardRaw353(const CString& sLine, CClient* pClient) const {
if ((!m_bNamesx || pClient->HasNamesx()) && (!m_bUHNames || pClient->HasUHNames())) {
// Client and server have both the same UHNames and Namesx stuff enabled
m_pUser->PutUser(sLine, pClient);
m_pNetwork->PutUser(sLine, pClient);
} else {
// Get everything except the actual user list
CString sTmp = sLine.Token(0, false, " :") + " :";
@@ -1102,7 +1102,7 @@ void CIRCSock::ForwardRaw353(const CString& sLine, CClient* pClient) const {
}
// Strip away the spaces we inserted at the end
sTmp.TrimRight(" ");
m_pUser->PutUser(sTmp, pClient);
m_pNetwork->PutUser(sTmp, pClient);
}
}
@@ -1117,8 +1117,8 @@ void CIRCSock::SendAltNick(const CString& sBadNick) {
unsigned int uMax = m_uMaxNickLen;
const CString& sConfNick = m_pUser->GetNick();
const CString& sAltNick = m_pUser->GetAltNick();
const CString& sConfNick = m_pNetwork->GetUser()->GetNick();
const CString& sAltNick = m_pNetwork->GetUser()->GetAltNick();
CString sNewNick;
if (sLastNick.Equals(sConfNick)) {
@@ -1138,7 +1138,7 @@ void CIRCSock::SendAltNick(const CString& sBadNick) {
} else {
char cLetter = 0;
if (sBadNick.empty()) {
m_pUser->PutUser("No free nick available");
m_pNetwork->PutUser("No free nick available");
Quit();
return;
}
@@ -1146,7 +1146,7 @@ void CIRCSock::SendAltNick(const CString& sBadNick) {
cLetter = sBadNick.Right(1)[0];
if (cLetter == 'z') {
m_pUser->PutUser("No free nick found");
m_pNetwork->PutUser("No free nick found");
Quit();
return;
}