initial commit
This commit is contained in:
commit
a57ababfec
28
SparrowBot.pro
Normal file
28
SparrowBot.pro
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#-------------------------------------------------
|
||||||
|
#
|
||||||
|
# Project created by QtCreator 2015-05-13T11:07:00
|
||||||
|
#
|
||||||
|
#-------------------------------------------------
|
||||||
|
|
||||||
|
QT += core gui network widgets
|
||||||
|
|
||||||
|
TARGET = SparrowBot
|
||||||
|
TEMPLATE = app
|
||||||
|
CONFIG += c++11
|
||||||
|
|
||||||
|
SOURCES += main.cpp\
|
||||||
|
mainwindow.cpp \
|
||||||
|
sparrowbot.cpp \
|
||||||
|
socketirc.cpp \
|
||||||
|
message.cpp \
|
||||||
|
user.cpp \
|
||||||
|
prompt.cpp
|
||||||
|
|
||||||
|
HEADERS += mainwindow.h \
|
||||||
|
sparrowbot.h \
|
||||||
|
socketirc.h \
|
||||||
|
message.h \
|
||||||
|
user.h \
|
||||||
|
prompt.h
|
||||||
|
|
||||||
|
FORMS += mainwindow.ui
|
45
main.cpp
Normal file
45
main.cpp
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#include "mainwindow.h"
|
||||||
|
#include "socketirc.h"
|
||||||
|
#include "sparrowbot.h"
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
// set up the socket
|
||||||
|
SocketIRC sock;
|
||||||
|
sock.setServer("irc.freenode.net");
|
||||||
|
sock.setPort(6667);
|
||||||
|
|
||||||
|
// set up the bot
|
||||||
|
SparrowBot* bot = new SparrowBot("SparrowBot", "#epicsparrow");
|
||||||
|
QObject::connect(&sock, SIGNAL(receivedMsg(QString)), bot, SLOT(receiveMsg(QString)));
|
||||||
|
QObject::connect(bot, SIGNAL(sendMsg(QString)), &sock, SLOT(sendMsg(QString)));
|
||||||
|
QObject::connect(bot, SIGNAL(changeSocketStatus(int)), &sock, SLOT(setConnected(int)));
|
||||||
|
|
||||||
|
// set up Qt
|
||||||
|
QApplication a(argc, argv);
|
||||||
|
bool nogui = a.arguments().contains("-nogui");
|
||||||
|
MainWindow w;
|
||||||
|
|
||||||
|
// set up UI
|
||||||
|
if(!nogui)
|
||||||
|
{
|
||||||
|
// bind signals to slots
|
||||||
|
QObject::connect(&sock, SIGNAL(receivedMsg(QString)), w.getConsole(), SLOT(append(QString)));
|
||||||
|
QObject::connect(&sock, SIGNAL(stateChanged(int)), w.getLed(), SLOT(setValue(int)));
|
||||||
|
QObject::connect(&sock, SIGNAL(stateChanged(int)), w.getSwitch(), SLOT(setValue(int)));
|
||||||
|
|
||||||
|
QObject::connect(w.getPrompt(), SIGNAL(sendMsg(QString)), &sock, SLOT(sendMsg(QString)));
|
||||||
|
QObject::connect(w.getPrompt(), SIGNAL(returnPressed()), w.getPrompt(), SLOT(confirmationPerformed()));
|
||||||
|
|
||||||
|
QObject::connect(w.getSwitch(), SIGNAL(valueChanged(int)), bot, SLOT(forceStatus(int)));
|
||||||
|
|
||||||
|
// show window
|
||||||
|
w.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
// run event loop on the main thread
|
||||||
|
if(nogui)
|
||||||
|
bot->forceStatus(1);
|
||||||
|
return a.exec();
|
||||||
|
}
|
34
mainwindow.cpp
Normal file
34
mainwindow.cpp
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#include "mainwindow.h"
|
||||||
|
#include "ui_mainwindow.h"
|
||||||
|
|
||||||
|
MainWindow::MainWindow(QWidget *parent) :
|
||||||
|
QMainWindow(parent),
|
||||||
|
ui(new Ui::MainWindow)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
QTextBrowser* MainWindow::getConsole()
|
||||||
|
{
|
||||||
|
return this->ui->monitoringConsole;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSlider* MainWindow::getSwitch()
|
||||||
|
{
|
||||||
|
return this->ui->connectSwitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
QProgressBar* MainWindow::getLed()
|
||||||
|
{
|
||||||
|
return this->ui->statusLed;
|
||||||
|
}
|
||||||
|
|
||||||
|
Prompt* MainWindow::getPrompt()
|
||||||
|
{
|
||||||
|
return this->ui->prompt;
|
||||||
|
}
|
||||||
|
|
||||||
|
MainWindow::~MainWindow()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
30
mainwindow.h
Normal file
30
mainwindow.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#ifndef MAINWINDOW_H
|
||||||
|
#define MAINWINDOW_H
|
||||||
|
|
||||||
|
#include "prompt.h"
|
||||||
|
#include <QMainWindow>
|
||||||
|
#include <QTextBrowser>
|
||||||
|
#include <QSlider>
|
||||||
|
#include <QProgressBar>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class MainWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
class MainWindow : public QMainWindow
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit MainWindow(QWidget *parent = 0);
|
||||||
|
~MainWindow();
|
||||||
|
|
||||||
|
QTextBrowser* getConsole();
|
||||||
|
QSlider* getSwitch();
|
||||||
|
QProgressBar* getLed();
|
||||||
|
Prompt* getPrompt();
|
||||||
|
private:
|
||||||
|
Ui::MainWindow *ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MAINWINDOW_H
|
66
mainwindow.ui
Normal file
66
mainwindow.ui
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>MainWindow</class>
|
||||||
|
<widget class="QMainWindow" name="MainWindow">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>374</width>
|
||||||
|
<height>404</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>MainWindow</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="centralWidget">
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QSlider" name="connectSwitch">
|
||||||
|
<property name="maximum">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="pageStep">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QProgressBar" name="statusLed">
|
||||||
|
<property name="maximum">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="textVisible">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="invertedAppearance">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0" colspan="2">
|
||||||
|
<widget class="QTextBrowser" name="monitoringConsole"/>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0" colspan="2">
|
||||||
|
<widget class="Prompt" name="prompt"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
<layoutdefault spacing="6" margin="11"/>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>Prompt</class>
|
||||||
|
<extends>QLineEdit</extends>
|
||||||
|
<header>prompt.h</header>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
40
message.cpp
Normal file
40
message.cpp
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#include "message.h"
|
||||||
|
|
||||||
|
#include <QStringList>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
Message::Message(QString str)
|
||||||
|
{
|
||||||
|
if(str.startsWith("PING"))
|
||||||
|
{
|
||||||
|
command = "PING";
|
||||||
|
target = "PING";
|
||||||
|
src = str.right(str.size()-(str.indexOf(':')+1));
|
||||||
|
args = str;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// remove the first char, which is ':'
|
||||||
|
str = str.remove(0, 1);
|
||||||
|
// locate the mid ':' separator
|
||||||
|
int mid = str.indexOf(':');
|
||||||
|
// the arguments are after the separator
|
||||||
|
args = str.right(str.size()-(mid+1));
|
||||||
|
// the interesting infos before the separator are separated by spaces
|
||||||
|
QStringList list = str.split(' ');
|
||||||
|
// source of the message
|
||||||
|
src = list.takeFirst();
|
||||||
|
// command issued by the source
|
||||||
|
command = list.takeFirst();
|
||||||
|
// target of the command
|
||||||
|
target = list.takeFirst();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Message::~Message()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
18
message.h
Normal file
18
message.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#ifndef MESSAGE_H
|
||||||
|
#define MESSAGE_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
class Message
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QString src;
|
||||||
|
QString command;
|
||||||
|
QString target;
|
||||||
|
QString args;
|
||||||
|
Message(QString str);
|
||||||
|
~Message();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MESSAGE_H
|
8
prompt.cpp
Normal file
8
prompt.cpp
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#include "prompt.h"
|
||||||
|
|
||||||
|
void Prompt::confirmationPerformed()
|
||||||
|
{
|
||||||
|
QString str = text();
|
||||||
|
clear();
|
||||||
|
emit sendMsg(str.append("\r\n"));
|
||||||
|
}
|
19
prompt.h
Normal file
19
prompt.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#ifndef PROMPT_H
|
||||||
|
#define PROMPT_H
|
||||||
|
|
||||||
|
#include <QLineEdit>
|
||||||
|
|
||||||
|
class Prompt : public QLineEdit
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
Prompt(QWidget*& w) : QLineEdit(w) {}
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void confirmationPerformed();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void sendMsg(QString);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PROMPT_H
|
61
socketirc.cpp
Normal file
61
socketirc.cpp
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#include "socketirc.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
SocketIRC::SocketIRC() : server("irc.freenode.net"), port(6667), isConnected(false)
|
||||||
|
{
|
||||||
|
connect(&sock, SIGNAL(readyRead()), this, SLOT(readMsg()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocketIRC::setServer(std::string server_)
|
||||||
|
{
|
||||||
|
server = server_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocketIRC::setPort(int port_)
|
||||||
|
{
|
||||||
|
port = port_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocketIRC::sendMsg(QString msg)
|
||||||
|
{
|
||||||
|
if(isConnected)
|
||||||
|
{
|
||||||
|
sock.write(msg.toStdString().c_str());
|
||||||
|
sock.flush();
|
||||||
|
std::cout << msg.toStdString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocketIRC::setConnected(int c)
|
||||||
|
{
|
||||||
|
if(c != isConnected)
|
||||||
|
{
|
||||||
|
if(isConnected)
|
||||||
|
{
|
||||||
|
sock.close();
|
||||||
|
isConnected = false;
|
||||||
|
emit stateChanged(isConnected);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sock.connectToHost(QString(server.c_str()), quint16(port));
|
||||||
|
if(sock.waitForConnected(5000))
|
||||||
|
isConnected = true;
|
||||||
|
else
|
||||||
|
std::cerr << "failed to connect : " << sock.errorString().toStdString() << std::endl;
|
||||||
|
emit stateChanged(isConnected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocketIRC::readMsg()
|
||||||
|
{
|
||||||
|
char buffer[512];
|
||||||
|
while(sock.canReadLine())
|
||||||
|
{
|
||||||
|
int numbytes = sock.readLine(buffer, 512);
|
||||||
|
buffer[numbytes - 2] = '\0';
|
||||||
|
std::cout << buffer << std::endl;
|
||||||
|
emit receivedMsg(QString(buffer));
|
||||||
|
}
|
||||||
|
}
|
37
socketirc.h
Normal file
37
socketirc.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#ifndef SOCKETIRC_H
|
||||||
|
#define SOCKETIRC_H
|
||||||
|
|
||||||
|
#include <QTcpSocket>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QThread>
|
||||||
|
|
||||||
|
class SocketIRC : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
SocketIRC();
|
||||||
|
void setServer(std::string server_);
|
||||||
|
void setPort(int port_);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::string server;
|
||||||
|
int port;
|
||||||
|
QTcpSocket sock;
|
||||||
|
bool isConnected;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void readMsg();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void sendMsg(QString msg);
|
||||||
|
void setConnected(int c);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void receivedMsg(QString msg);
|
||||||
|
void stateChanged(int newState);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SOCKETIRC_H
|
95
sparrowbot.cpp
Normal file
95
sparrowbot.cpp
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
#include "sparrowbot.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
void SparrowBot::receiveMsg(QString msg)
|
||||||
|
{
|
||||||
|
string str;
|
||||||
|
if(msg.contains("PING"))
|
||||||
|
{
|
||||||
|
str = "PONG\r\n";
|
||||||
|
emit sendMsg(QString(str.c_str()));
|
||||||
|
}
|
||||||
|
switch(status)
|
||||||
|
{
|
||||||
|
case OFFLINE :
|
||||||
|
status = ONLINE;
|
||||||
|
sendRawMessage("NICK " + nick + "\r\nUSER " + nick + " 0 * " + nick + "\r\n");
|
||||||
|
break;
|
||||||
|
case ONLINE :
|
||||||
|
status = ON_CHAN;
|
||||||
|
sendRawMessage("JOIN #" + chan + "\r\n");
|
||||||
|
break;
|
||||||
|
case ON_CHAN :
|
||||||
|
handleMessage(Message(msg));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SparrowBot::forceStatus(int newStatus)
|
||||||
|
{
|
||||||
|
emit changeSocketStatus(newStatus);
|
||||||
|
if(newStatus)
|
||||||
|
{
|
||||||
|
//status = ONLINE;
|
||||||
|
//sendRawMessage("NICK " + nick + "\r\nUSER " + nick + " 0 * " + nick + "\r\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
status = OFFLINE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SparrowBot::handleMessage(Message msg)
|
||||||
|
{
|
||||||
|
//char* str = msg.args.toStdString().c_str();
|
||||||
|
if(msg.command.compare(QString("PRIVMSG"), Qt::CaseInsensitive) == 0)
|
||||||
|
{
|
||||||
|
// message
|
||||||
|
|
||||||
|
|
||||||
|
if(msg.args.compare("!destroy") == 0)
|
||||||
|
{
|
||||||
|
sendRawMessage("QUIT :i'll be back\r\n");
|
||||||
|
status = OFFLINE;
|
||||||
|
emit changeSocketStatus(false);
|
||||||
|
}
|
||||||
|
if(msg.args.compare("!list") == 0)
|
||||||
|
{
|
||||||
|
string str = "Online users : ";
|
||||||
|
for(User u : users)
|
||||||
|
str += u.getNick().toStdString() + " ";
|
||||||
|
say(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(msg.command.compare(QString("353"), Qt::CaseInsensitive) == 0)
|
||||||
|
{
|
||||||
|
// names
|
||||||
|
QStringList names = msg.args.split(' ');
|
||||||
|
for(QString s : names)
|
||||||
|
{
|
||||||
|
User u = User(s);
|
||||||
|
users.push_back(u);
|
||||||
|
sendRawMessage("WHOIS "+u.getNick().toStdString()+"\r\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SparrowBot::say(string str)
|
||||||
|
{
|
||||||
|
sendRawMessage("PRIVMSG #" + chan + " :" + str + "\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void SparrowBot::action(string str)
|
||||||
|
{
|
||||||
|
sendRawMessage("PRIVMSG #" + chan + " :ACTION " + str + "\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void SparrowBot::sendRawMessage(string str)
|
||||||
|
{
|
||||||
|
emit sendMsg(QString(str.c_str()));
|
||||||
|
}
|
39
sparrowbot.h
Normal file
39
sparrowbot.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#ifndef SPARROWBOT_H
|
||||||
|
#define SPARROWBOT_H
|
||||||
|
|
||||||
|
#include "user.h"
|
||||||
|
#include "message.h"
|
||||||
|
#include <QObject>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class SparrowBot : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
enum{OFFLINE, ONLINE, ON_CHAN};
|
||||||
|
|
||||||
|
std::string nick;
|
||||||
|
std::string chan;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
std::vector<User> users;
|
||||||
|
public:
|
||||||
|
SparrowBot() : nick("SparrowBot"), chan("epicsparrow"), status(OFFLINE) {}
|
||||||
|
SparrowBot(std::string nick_, std::string chan_) : nick(nick_), chan(chan_), status(OFFLINE) {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void handleMessage(Message msg);
|
||||||
|
void say(std::string str);
|
||||||
|
void action(std::string str);
|
||||||
|
void sendRawMessage(std::string str);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void receiveMsg(QString msg);
|
||||||
|
void forceStatus(int newStatus);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void sendMsg(QString msg);
|
||||||
|
void changeSocketStatus(int newStatus);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SPARROWBOT_H
|
15
user.cpp
Normal file
15
user.cpp
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#include "user.h"
|
||||||
|
|
||||||
|
User::User(QString str)
|
||||||
|
{
|
||||||
|
isOp = (str.at(0) == '@');
|
||||||
|
if(isOp)
|
||||||
|
str = str.remove(0, 1);
|
||||||
|
nick = str;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString User::getNick()
|
||||||
|
{
|
||||||
|
return nick;
|
||||||
|
}
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user