-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #55 from ArthanIRC/bot-client-lowlevel
feat: implement first low-level building bots for the Bot client
- Loading branch information
Showing
16 changed files
with
357 additions
and
93 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,6 +29,7 @@ objs | |
|
||
# Executables | ||
ircserv | ||
ircbot | ||
*.exe | ||
*.out | ||
*.app | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
#pragma once | ||
|
||
#include <exception> | ||
#include <string> | ||
|
||
#include "BotSocket.hpp" | ||
|
||
class Bot { | ||
private: | ||
BotSocket _socket; | ||
std::string _password; | ||
bool _running; | ||
bool _registered; | ||
|
||
Bot(); | ||
Bot(Bot const&); | ||
void operator=(Bot const&); | ||
|
||
void login(); | ||
|
||
public: | ||
~Bot(); | ||
|
||
void init(int ac, char** data); | ||
void run(); | ||
void stop(); | ||
|
||
static Bot& getInstance(); | ||
|
||
class InvalidNumberOfParametersException : public std::exception { | ||
virtual const char* what() const throw(); | ||
}; | ||
|
||
class InvalidPortException : public std::exception { | ||
virtual const char* what() const throw(); | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#pragma once | ||
|
||
#include <string> | ||
|
||
#include "Socket.hpp" | ||
|
||
class BotSocket : public Socket { | ||
private: | ||
struct addrinfo* _ai; | ||
bool _registered; | ||
bool _eof; | ||
std::string _rem; | ||
|
||
public: | ||
BotSocket(); | ||
~BotSocket(); | ||
|
||
void init(const char* ip, const char* port); | ||
void connect(); | ||
std::string receive(); | ||
void sendMessage(std::string message); | ||
void onPoll(uint32_t events); | ||
void setRegistered(); | ||
bool isRegistered(); | ||
bool isEof(); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
#include <cstdlib> | ||
|
||
#include "Bot.hpp" | ||
#include "Server.hpp" | ||
|
||
using std::string; | ||
|
||
static const string defaultPort = "6667"; | ||
|
||
Bot::Bot() {} | ||
|
||
Bot::~Bot() {} | ||
|
||
void Bot::init(int ac, char** data) { | ||
if (ac < 3 || ac > 4) | ||
throw Bot::InvalidNumberOfParametersException(); | ||
|
||
string port; | ||
if (ac == 3) | ||
port = defaultPort; | ||
else | ||
port = Server::parsePort(data[3]); | ||
|
||
this->_password = Server::parsePassword(data[2]); | ||
this->_running = true; | ||
this->_registered = false; | ||
this->_socket.init(data[1], port.c_str()); | ||
} | ||
|
||
void Bot::run() { | ||
this->_socket.connect(); | ||
|
||
while (_running) { | ||
if (!_registered) { | ||
login(); | ||
} | ||
string data = _socket.receive(); | ||
if (data.empty() && _socket.isEof()) | ||
break; | ||
if (data.empty()) | ||
continue; | ||
|
||
// TODO: parse data, create response and do things | ||
} | ||
} | ||
|
||
void Bot::login() {} | ||
|
||
void Bot::stop() { this->_running = false; } | ||
|
||
Bot& Bot::getInstance() { | ||
static Bot instance; | ||
return instance; | ||
} | ||
|
||
const char* Bot::InvalidNumberOfParametersException::what() const throw() { | ||
return "Error: Usage: ./ircbot <address> <password> [<port>]"; | ||
} | ||
|
||
const char* Bot::InvalidPortException::what() const throw() { | ||
return "Error: Port has to be between 1 and 65535"; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
#include <cstring> | ||
#include <netdb.h> | ||
|
||
#include "BotSocket.hpp" | ||
|
||
using std::string; | ||
|
||
BotSocket::BotSocket() : Socket(), _registered(false) {} | ||
|
||
BotSocket::~BotSocket() { freeaddrinfo(_ai); } | ||
|
||
void BotSocket::init(const char* ip, const char* port) { | ||
struct addrinfo hints, *ai; | ||
int rv; | ||
|
||
memset(&hints, 0, sizeof hints); | ||
hints.ai_family = AF_INET; | ||
hints.ai_socktype = SOCK_STREAM; | ||
|
||
if ((rv = getaddrinfo(ip, port, &hints, &ai)) != 0) | ||
throw Socket::AddrInfoException(); | ||
|
||
this->_fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); | ||
if (_fd < 0) { | ||
freeaddrinfo(ai); | ||
throw Socket::SocketCreationException(); | ||
} | ||
|
||
this->_ai = ai; | ||
} | ||
|
||
void BotSocket::connect() { | ||
if (::connect(_fd, _ai->ai_addr, _ai->ai_addrlen) == -1) | ||
throw Socket::ConnectException(); | ||
} | ||
|
||
void BotSocket::onPoll(uint32_t events) { (void)events; } | ||
|
||
bool BotSocket::isEof() { return this->_eof; } | ||
|
||
string BotSocket::receive() { | ||
char buf[MAX_LIMIT]; | ||
string data; | ||
ssize_t size; | ||
memset(buf, 0, MAX_LIMIT); | ||
|
||
if (!_rem.empty()) { | ||
data.append(_rem); | ||
_rem.clear(); | ||
} | ||
|
||
size = recv(_fd, buf, MAX_LIMIT, 0); | ||
data.append(buf); | ||
if (data.empty() || size == -1) { | ||
_eof = true; | ||
return ""; | ||
} | ||
|
||
size_t i = data.find("\n"); | ||
i = i == string::npos ? string::npos : i + 1; | ||
string line = data.substr(0, i); | ||
data = data.erase(0, i); | ||
if (!line.empty() && i == string::npos) { | ||
_rem = line; | ||
return ""; | ||
} | ||
if (!data.empty()) | ||
_rem = data; | ||
return line; | ||
} | ||
|
||
void BotSocket::sendMessage(string message) { | ||
if (send(_fd, message.c_str(), message.size(), MSG_NOSIGNAL) == -1) | ||
throw Socket::SendException(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
#include <csignal> | ||
#include <cstdlib> | ||
#include <iostream> | ||
|
||
#include "Bot.hpp" | ||
|
||
static void handle_signint(int signal) { | ||
(void)signal; | ||
Bot::getInstance().stop(); | ||
} | ||
|
||
static int register_sigaction(int signal, void (*handler)(int)) { | ||
struct sigaction action; | ||
sigset_t set; | ||
|
||
sigemptyset(&set); | ||
action.sa_handler = handler; | ||
action.sa_mask = set; | ||
action.sa_flags = 0; | ||
if (sigaction(signal, &action, NULL) == -1) { | ||
std::cerr << "Error: sigaction creation failed\n"; | ||
return -1; | ||
} | ||
return 0; | ||
} | ||
|
||
int main(int ac, char** av) { | ||
if (register_sigaction(SIGINT, &handle_signint) == -1 || | ||
register_sigaction(SIGQUIT, SIG_IGN) == -1) | ||
return EXIT_FAILURE; | ||
|
||
std::setlocale(LC_ALL, "en_US.UTF-8"); | ||
|
||
try { | ||
Bot::getInstance().init(ac, av); | ||
Bot::getInstance().run(); | ||
} catch (std::exception& e) { | ||
std::cerr << e.what() << "\n"; | ||
return EXIT_FAILURE; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,3 +4,4 @@ | |
-std=c++98 | ||
-Iinclude | ||
-Iinclude/Commands | ||
-Ibot/include |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.