(C++) IrcBot
February 24, 2017 · View on GitHub
(C++) IrcBot



IrcBot is a class for an IRC bot. Its default name is 'lambda'.
Technical facts
./CppIrcBot/CppIrcBot.pri
INCLUDEPATH += \ ../../Classes/CppIrcBot SOURCES += \ ../../Classes/CppIrcBot/ircbot.cpp HEADERS += \ ../../Classes/CppIrcBot/ircbot.h OTHER_FILES += \ ../../Classes/CppIrcBot/Licence.txt
./CppIrcBot/ircbot.h
//Inspired by Quxbot, developed by Viderizer and Tyler Allen #include <fstream> #include <functional> #include <string> #include <vector> struct IrcBot { IrcBot( const std::string& bot_name, const std::string& channel_name, const int port, const std::string& server_name, const std::function<const std::vector<std::string>(const std::string& input)>& respond_function); private: const std::string ReadLine() const; void Send(const std::string& text); mutable std::fstream m_log_file; int m_socket_index; };
./CppIrcBot/ircbot.cpp
//Inspired by Quxbot, developed by Viderizer and Tyler Allen #include <ircbot.h> #include <fstream> #include <stdexcept> #include <netdb.h> #include <boost/lexical_cast.hpp> IrcBot::IrcBot( const std::string& bot_name, const std::string& channel_name, const int port, const std::string& server_name, const std::function<const std::vector<std::string>(const std::string& input)>& respond_function) : m_log_file("log_lambdabot.txt"), m_socket_index{-1} { const std::string port_str = boost::lexical_cast<std::string>(port); addrinfo hints; memset(&hints, 0, sizeof(hints)); // make sure the struct is empty hints.ai_family = AF_UNSPEC; // don't care IPv4 or IPv6 hints.ai_socktype = SOCK_STREAM; // TCP stream sockets addrinfo *servinfo = 0; if (const int res = getaddrinfo(const_cast<char*>(server_name.c_str()), const_cast<char*>(port_str.c_str()), &hints, &servinfo)) { const std::string s = std::string("getaddrinfo: ") + std::string(gai_strerror(res)); throw std::runtime_error(s); } m_socket_index = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol); if (m_socket_index == -1) { std::perror("client: socket"); const std::string s = "client: socket"; throw std::runtime_error(s); } if (connect(m_socket_index, servinfo->ai_addr, servinfo->ai_addrlen) == -1) { close(m_socket_index); std::perror("client: connect"); const std::string s = "client: connect"; throw std::runtime_error(s); } freeaddrinfo(servinfo); for (int count = 0; ; ++count) { std::cout << count << std::endl; switch (count) { case 2: //Note: must be 2 on e.g. irc.freenode.net { const std::string nickname_str = "NICK " + bot_name; Send(nickname_str); const std::string user_str = "USER " + bot_name + " tolmoon tolsun :" + bot_name; Send(user_str); } break; case 3: //Note: must be 3 on e.g. irc.freenode.net { const std::string joinmsg = "JOIN " + channel_name; Send(joinmsg); break; } default: break; } //Read text from IRC const std::string line { ReadLine() }; if (line.find("PING") != std::string::npos) { const std::string msg = std::string("PONG"); Send(msg); continue; } if (1 == 2 && line.find("266") != std::string::npos) { const std::string joinmsg = "JOIN " + channel_name; Send(joinmsg); continue; } if (1 == 1 && line.find("Found your hostname") != std::string::npos) { const std::string connect_str = "/connect " + server_name + "/6697 -ssl"; Send(connect_str); continue; } if (1==2) { const std::string nickname_str = "NICK " + bot_name; Send(nickname_str); const std::string user_str = "USER " + bot_name + " tolmoon tolsun :" + bot_name; Send(user_str); } const std::vector<std::string> response = respond_function(line); for (const std::string& s: response) { const std::string msg = std::string("PRIVMSG ") + channel_name + std::string(" :") + s; Send(msg.c_str()); } if (line.empty() == true) { m_log_file << "CONNECTION CLOSED" << std::endl; std::clog << "CONNECTION CLOSED" << std::endl; break; } } close(m_socket_index); } const std::string IrcBot::ReadLine() const { const int max_data_size = 1024; char buf[max_data_size]; std::cout << "Start reading line" << std::endl; const int numbytes = recv(m_socket_index, buf, max_data_size-1, 0); buf[numbytes] = '\0'; const std::string line{buf}; m_log_file << "Received: '" << line << "\'\n"; std::clog << "Received: '" << line << "\'" << std::endl; return line; } void IrcBot::Send(const std::string& s) { const std::string t = s + "\r\n"; m_log_file << "Sent: '" << s << '\'' << std::endl; std::clog << "Sent: '" << s << '\'' << std::endl; send(m_socket_index,t.c_str(),t.size(),0); }