Code:
/* This is RicBot, written by John */
#pragma warning(disable: 4786)
#include <winsock2.h>
#pragma comment(lib,"WS2_32.lib")
#include <vector>
#include <string>
#include <sstream>
#include <iostream>
/////////////////////////////
//This isn't multithreaded yet, so the code below isn't
//needed but I have added it from an older program I made
//to save me time ;)
//#include <process.h>
//Using MSVC++
//For Win32 Release
//Project -> Settings -> C/C++ -> Code Generation
//Use-Runtime Library -> Multithreaded
//#pragma comment(lib, "libcmt.lib")
//For Win32 Debug
//Project -> Settings -> C/C++ -> Code Generation
//Use-Runtime Library -> Debug Multithreaded
//#pragma comment(lib, "libcmtd.lib")
///////////////////////////////
SOCKET IRC_socket; //Global
using namespace std;
//#define RicBot
#define AUTHENTICATION
//Function Prototypes
int CreateSock();
int ConnectIRCSock(int Port, string IP);
int SendIRC_func(string SendData_string);
int RecvIRC_func(string &RecvData_string);
int OnConnect(string BotNick, string IP);
int ReConnect(int Port, string IP, string BotNick);
int CheckForTimeout(int Port, string IP, string BotNick);
int CheckForPing(string RecvData_string);
int Get_Nick_Ident_Host(string RecvData_string);
int JoinChannel(string Channel);
int MessageChannel(string Message, string Channel);
string RandomNick(string BotNick);
struct IdentNickHostInfo {
string Nick;
string Ident;
string Host;
} AuthInfo;
int PingTime = 0, TimeElapsed = 0;
#ifdef RicBot
#pragma comment(linker,"/subsystem:windows")
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow){
#endif
#ifndef RicBot
#pragma comment(linker,"/subsystem:console")
int main(int argc, char* argv[]){
#endif
string SendData_string, RecvData_string;
int Port = 6667;
string IP = "";
string BotNick = "";
string Channel = "";
//Nick/Ident/Host for Auth
string AuthNick = "";
string AuthIdent = "";
string AuthHost = "";
string CMDprefix = "!";
//our commands
string VersionCMD = "version";
string Version = "RicBot";
string ReconnectCMD = "reconnect";
string KillCMD = "stop";
string RawCMD = "raw";
CreateSock();
ConnectIRCSock(Port, IP);
OnConnect(BotNick, IP);
PingTime = GetTickCount()/1000;
while(1){
CheckForTimeout(Port, IP, BotNick);
if(RecvIRC_func(RecvData_string) == -1){
Sleep(10000);
ReConnect(Port, IP, BotNick);
}
#ifndef RicBot
cout<<RecvData_string;
#endif
CheckForPing(RecvData_string);
if(RecvData_string[0] == ':'){
//--------------------------
string strData = "";
vector<string> SplitData;
int i=0;
while(RecvData_string[i] != '\r'){
if(RecvData_string[i] == ' '){
if(RecvData_string[i+1] != '\r'){
SplitData.push_back(strData);
strData = "";
i++;
}
}
strData = strData + RecvData_string[i];
i++;
}
SplitData.push_back(strData);
//--------------------------
//here our server commands go.
if(SplitData.size() >= 2){
//We can join a channel now.
if(SplitData[1] == "001"){
JoinChannel(Channel);
}
//nick is in use, so change it.
if(SplitData[1] == "433"){
//(BotNick=RandomNick(BotNick));
OnConnect(BotNick=RandomNick(BotNick), IP);
}
}
if(SplitData.size() >= 4){
if(SplitData[1] == "KICK" && SplitData[3] == BotNick){
Sleep(3000);
JoinChannel(Channel);
}
}
//gets the nick/ident/host of user sending message.
if(Get_Nick_Ident_Host(RecvData_string) == 0){
//here are our user commands
if(SplitData.size() >= 4){
//this line will remove the :
SplitData[3] = SplitData[3].substr(1);
//will check if our first character is our prefix
if(SplitData[3][0] == CMDprefix[0]){
//this will remove our prefix.
SplitData[3] = SplitData[3].substr(1);
//--------------------------
//commands without Auth go here
// if they have no arguments
if(SplitData.size() >= 4){
if(SplitData[3] == VersionCMD){
MessageChannel(Version, Channel);
}
}
//Here is our authentication check.
#ifdef AUTHENTICATION
if(AuthInfo.Nick == AuthNick){
if(AuthInfo.Ident == AuthIdent){
if(AuthInfo.Host == AuthHost){
#endif
//commands with Auth go here
//-----------------------
//if command has 0 arguments
if(SplitData.size() == 4){
if(SplitData[3] == ReconnectCMD){
string QUIT = "QUIT Reconnecting...\r";
SendIRC_func(QUIT);
ReConnect(Port, IP, BotNick);
}
if(SplitData[3] == KillCMD){
exit(0);
}
}
//--------------------------
//if command has 1 argument or more
if(SplitData.size() >= 5){
if(SplitData[3] == RawCMD){
int sizerawmessage = (int)SplitData.size() - 4;
ostringstream rawmessage;
for(int i = 0; i < sizerawmessage; i++){
rawmessage<<SplitData[i+4]<<" ";
}
rawmessage<<"\r";
SendIRC_func(rawmessage.str());
}
}
}
}
}
}
#ifdef AUTHENTICATION
}
}
}
#endif
RecvData_string = '\0';
}
return 0;
}
////////////////////////////////////////
int CreateSock(){
WSADATA wsaData;
int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
if ( iResult != NO_ERROR )
return -1;
return 0;
}
////////////////////////////////////////
int ConnectIRCSock(int Port, string host){
IRC_socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
if (IRC_socket == INVALID_SOCKET){
WSACleanup();
return -2;
}
sockaddr_in remotehost;
remotehost.sin_family = AF_INET;
remotehost.sin_addr.s_addr = inet_addr(host.c_str());
remotehost.sin_port = htons(Port);
if (connect(IRC_socket, (SOCKADDR*) &remotehost, sizeof(remotehost) ) == SOCKET_ERROR){
closesocket(IRC_socket);
WSACleanup();
return -1;
}
return 0;
}
////////////////////////////////////////
int SendIRC_func(string SendData_string){
if (send(IRC_socket, SendData_string.c_str(), (int)SendData_string.size(), 0 ) <= 0){
WSACleanup();
return -1;
}
PingTime = GetTickCount()/1000;
return 0;
}
////////////////////////////////////////
int RecvIRC_func(string &RecvData_string){
char TempBuffer[1025]; //extra char for null terminating character
int BytesRecv;
if ((BytesRecv = recv(IRC_socket, TempBuffer, 1024, 0 )) <= 0){
WSACleanup();
return -1;
}
TempBuffer[BytesRecv] = '\0';
RecvData_string = TempBuffer;
PingTime = GetTickCount()/1000;
return 0;
}
////////////////////////////////////////
int OnConnect(string BotNick, string IP){
ostringstream tempstr;
tempstr <<"Nick "<<BotNick<<'\n';
SendIRC_func(tempstr.str());
tempstr.str("");
tempstr<<"USER "<<BotNick<<" \"\" \""<< IP <<
"\" :"<<BotNick<<'\n';
SendIRC_func(tempstr.str());
return 0;
}
////////////////////////////////////////
int ReConnect(int Port, string IP, string BotNick){
closesocket(IRC_socket);
CreateSock();
ConnectIRCSock(Port, IP);
OnConnect(BotNick, IP);
return 0;
}
////////////////////////////////////////
int CheckForTimeout(int Port, string IP, string BotNick){
if(TimeElapsed < PingTime+150){
TimeElapsed = GetTickCount()/1000;
return -1;
}
Sleep(10000);
ReConnect(Port, IP, BotNick);
PingTime = GetTickCount()/1000;
return 0;
}
////////////////////////////////////////
int CheckForPing(string RecvData_string){
string ServerPing;
ostringstream SendPong;
int i = 0;
//////////////////////////////////////////////////////
/*if(RecvData_string[i] == 'P' && RecvData_string[i+1] == 'I' &&
RecvData_string[i+2] == 'N' && RecvData_string[i+3] == 'G' ){
i += 5;
while(RecvData_string[i] != '\r'){
ServerPing = ServerPing + RecvData_string[i];
i++;
}
ServerPing = ServerPing + '\0';
SendPong << "PONG " << ServerPing << '\n';
SendIRC_func(SendPong.str());
return -1;
}*/
if(RecvData_string[i] == 'P' && RecvData_string[i+1] == 'I' &&
RecvData_string[i+2] == 'N' && RecvData_string[i+3] == 'G' ){
RecvData_string[1] = 'O';
SendIRC_func(RecvData_string);
}
//////////////////////////////////////////////////////
while(i < (int)RecvData_string.size()){
if(RecvData_string[i] == '\r' && RecvData_string[i+1] == '\n' &&
RecvData_string[i+2] == 'P' && RecvData_string[i+3] == 'I' &&
RecvData_string[i+4] == 'N' && RecvData_string[i+5] == 'G'){
i += 7;
while(RecvData_string[i] != '\r'){
ServerPing = ServerPing + RecvData_string[i];
i++;
}
ServerPing = ServerPing + '\0';
SendPong << "PONG " << ServerPing << '\n';
SendIRC_func(SendPong.str());
return -2;
}
i++;
}
//////////////////////////////////////////////////////
return 0;
}
////////////////////////////////////////
int Get_Nick_Ident_Host(string RecvData_string){
int i = 1;
AuthInfo.Nick = "";
AuthInfo.Ident = "";
AuthInfo.Host = "";
////////////////////////////////////////////
while(RecvData_string[i] != '!'){
AuthInfo.Nick = AuthInfo.Nick + RecvData_string[i];
i++;
if(i == RecvData_string.size()){
return -1;
}
}
////////////////////////////////////////////
i++;
while(RecvData_string[i] != '@'){
AuthInfo.Ident = AuthInfo.Ident + RecvData_string[i];
i++;
if(i == RecvData_string.size()){
return -2;
}
}
////////////////////////////////////////////
i++;
while(RecvData_string[i] != ' '){
AuthInfo.Host = AuthInfo.Host + RecvData_string[i];
i++;
if(i == RecvData_string.size()){
return -3;
}
}
//cout<<"Nick is "<<AuthInfo.Nick<<endl;
//cout<<"Ident is "<<AuthInfo.Ident<<endl;
//cout<<"Host is "<<AuthInfo.Host<<endl;
return 0;
}
////////////////////////////////////////
int JoinChannel(string Channel){
ostringstream joinchan;
joinchan << "JOIN " << Channel << "\r";
SendIRC_func(joinchan.str());
return 0;
}
////////////////////////////////////////
int MessageChannel(string Message, string Channel){
ostringstream ChannelMessage;
ChannelMessage << "PRIVMSG "<<Channel<< " :" <<Message<<"\r";
SendIRC_func(ChannelMessage.str());
return 0;
}
////////////////////////////////////////
string RandomNick(string BotNick){
srand((unsigned)GetTickCount());
int randomNum = rand()%10000;
ostringstream Nick;
Nick << BotNick << randomNum;
return Nick.str();
}
(I didn't upload the code in a .cpp file because it doesn't keep the line breaks the way they are.)