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