initial commit

This commit is contained in:
unknown 2015-05-21 15:26:18 +02:00
commit a57ababfec
15 changed files with 551 additions and 0 deletions

28
SparrowBot.pro Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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;
}

16
user.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef USER_H
#define USER_H
#include <QString>
class User
{
QString nick;
bool isOp;
public:
User(QString str);
QString getNick();
};
#endif // USER_H