mirror of
https://github.com/ChronosX88/Influence-cjdns.git
synced 2024-11-23 15:42:18 +00:00
commit
cdb17e08bd
7
.gitignore
vendored
7
.gitignore
vendored
@ -1,5 +1,4 @@
|
|||||||
|
.project
|
||||||
*.user
|
*.user
|
||||||
|
*.autosave
|
||||||
/.project
|
*.o
|
||||||
|
|
||||||
*.autosave
|
|
||||||
|
@ -1,22 +1,13 @@
|
|||||||
# Общая документация мессенджера Influence
|
# Общая документация мессенджера Influence
|
||||||
|
|
||||||
## Структура мессенджера
|
|
||||||
|
|
||||||
Связь между узлами - точка-точка
|
|
||||||
|
|
||||||
GUI - API ==== API - GUI
|
|
||||||
|
|
||||||
GUI - примитивная программа под Linux/Windows/Android, которая умеет отображать сообщения и вызывать функции ядра (API).
|
|
||||||
API - ядро мессенджера. Достаточно подключить *main.hpp*, чтобы вызывать функции ядра. Такая структура позволяет писать какие угодно клиенты.
|
|
||||||
|
|
||||||
## Протокол обмена
|
## Протокол обмена
|
||||||
|
|
||||||
Обмен сообщениями ведётся по UDP протоколу в формате JSON.
|
Обмен сообщениями ведётся по UDP протоколу в формате JSON.
|
||||||
При любой успешной отправке данных обновляем поле last_connect у контакта.
|
При любой успешной отправке данных обновляем поле last_connect у контакта. (not implemented)
|
||||||
Если пришло сообщение от контакта, которого нет в адресной книге - то оно отбрасывается.
|
Если пришло сообщение от контакта, которого нет в адресной книге - то оно отбрасывается.
|
||||||
Исключения - запрос handshake.
|
Исключения - запрос handshake.
|
||||||
|
|
||||||
### Добавление в друзья
|
### Добавление в друзья (not implemented)
|
||||||
|
|
||||||
Используется, чтобы установить связь с контактом. Тот кто хочет добавиться в друзья - отправляет такой запрос:
|
Используется, чтобы установить связь с контактом. Тот кто хочет добавиться в друзья - отправляет такой запрос:
|
||||||
|
|
||||||
@ -32,8 +23,7 @@ API - ядро мессенджера. Достаточно подключить
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"action":"handshakeSuccess",
|
"action":"handshakeSuccess",
|
||||||
"peerID":"*IPv6*",
|
"peerID":"*IPv6*"
|
||||||
"status": true
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -72,7 +62,7 @@ API - ядро мессенджера. Достаточно подключить
|
|||||||
Если нет ответа, то сохраняем сообщение у себя в истории, чтобы потом переотправить.
|
Если нет ответа, то сохраняем сообщение у себя в истории, чтобы потом переотправить.
|
||||||
`status == true` - доставлено.
|
`status == true` - доставлено.
|
||||||
|
|
||||||
### Пинг - проверка онлайна
|
### Пинг - проверка онлайна (not implemented)
|
||||||
|
|
||||||
Если прошло время last_connect > 1 минуты, от отправляем запрос
|
Если прошло время last_connect > 1 минуты, от отправляем запрос
|
||||||
|
|
||||||
@ -113,7 +103,7 @@ API - ядро мессенджера. Достаточно подключить
|
|||||||
|
|
||||||
В ответ приходит массив с `true` или `false`. Если `true` - сообщение успешно отправлено, `false` - сообщение недоставлено.
|
В ответ приходит массив с `true` или `false`. Если `true` - сообщение успешно отправлено, `false` - сообщение недоставлено.
|
||||||
|
|
||||||
### Отправление сообщения для другого абонента (это нужно чтобы отправлять тем, кто в offline)
|
### Отправление сообщения для другого абонента (это нужно чтобы отправлять тем, кто в offline) (not implemented)
|
||||||
|
|
||||||
Если человек, которому мы отправляем сообщение offline - то, во-первых, оно сохраняется у себя на сервере, для последующей отправки.
|
Если человек, которому мы отправляем сообщение offline - то, во-первых, оно сохраняется у себя на сервере, для последующей отправки.
|
||||||
Во-вторых, можно попросить какого-то друга его переотправить. Для этого выбираем случайно несколько друзей из списка контактов, у которых `can_resend == 1` и отправляем им запрос.
|
Во-вторых, можно попросить какого-то друга его переотправить. Для этого выбираем случайно несколько друзей из списка контактов, у которых `can_resend == 1` и отправляем им запрос.
|
||||||
|
@ -27,12 +27,15 @@ SOURCES += \
|
|||||||
main.cpp \
|
main.cpp \
|
||||||
mainwindow.cpp \
|
mainwindow.cpp \
|
||||||
kernel/network.cpp \
|
kernel/network.cpp \
|
||||||
kernel/handler.cpp
|
kernel/handler.cpp \
|
||||||
|
chatwindow.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
kernel/network.hpp \
|
kernel/network.hpp \
|
||||||
mainwindow.h \
|
mainwindow.h \
|
||||||
kernel/handler.hpp
|
kernel/handler.hpp \
|
||||||
|
chatwindow.hpp
|
||||||
|
|
||||||
FORMS += \
|
FORMS += \
|
||||||
mainwindow.ui
|
mainwindow.ui \
|
||||||
|
chatwindow.ui
|
||||||
|
70
src/chatwindow.cpp
Normal file
70
src/chatwindow.cpp
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
#include "chatwindow.hpp"
|
||||||
|
#include "ui_chatwindow.h"
|
||||||
|
|
||||||
|
ChatWindow::ChatWindow(QString pID, QString cUUID, Handler *h, Network *n, QWidget *parent) :
|
||||||
|
QWidget(parent),
|
||||||
|
ui(new Ui::ChatWindow)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
this->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
chatID = cUUID;
|
||||||
|
peerID = pID;
|
||||||
|
handler = h;
|
||||||
|
network = n;
|
||||||
|
ui->peerIDLabel->setText(ui->peerIDLabel->text() + pID);
|
||||||
|
ui->chatIDLabel->setText(ui->chatIDLabel->text() + cUUID);
|
||||||
|
connect(ui->sendMsgButton, &QAbstractButton::clicked, this, &ChatWindow::sendMsgButtonClicked);
|
||||||
|
}
|
||||||
|
ChatWindow::~ChatWindow()
|
||||||
|
{
|
||||||
|
leftFromChat();
|
||||||
|
emit deleteChat(chatID);
|
||||||
|
delete ui;
|
||||||
|
this->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatWindow::sendMessage(QString msgText)
|
||||||
|
{
|
||||||
|
QJsonObject jSend;
|
||||||
|
jSend["action"] = "msgSend";
|
||||||
|
jSend["peerID"] = *network->myIPv6;
|
||||||
|
jSend["chatID"] = chatID;
|
||||||
|
jSend["msgText"] = msgText;
|
||||||
|
network->sendDatagram(jSend, peerID);
|
||||||
|
QDateTime date(QDateTime::currentDateTime());
|
||||||
|
ui->chatEdit->append("<i>[" + date.toString() + "]</i> " + tr("<b>You</b>: ") + msgText);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatWindow::sendMsgButtonClicked()
|
||||||
|
{
|
||||||
|
QString msg = ui->msgEdit->text();
|
||||||
|
sendMessage(msg);
|
||||||
|
ui->msgEdit->setText("");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatWindow::displayMsg(QString msgText)
|
||||||
|
{
|
||||||
|
QDateTime date(QDateTime::currentDateTime());
|
||||||
|
ui->chatEdit->append("<i>[" + date.toString() + "]</i> " + "<b>" + peerID + "</b>" + ": " + msgText);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatWindow::leftFromChat()
|
||||||
|
{
|
||||||
|
QJsonObject json;
|
||||||
|
json["action"] = "leftChat";
|
||||||
|
json["peerID"] = *network->myIPv6;
|
||||||
|
json["chatID"] = chatID;
|
||||||
|
network->sendDatagram(json, peerID);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatWindow::peerReceiverLeftFromChat()
|
||||||
|
{
|
||||||
|
QString msg;
|
||||||
|
msg += tr("Peer ");
|
||||||
|
msg += peerID;
|
||||||
|
msg += tr(" left from this chat.");
|
||||||
|
QMessageBox::warning(this, tr("Peer receiver left from chat!"), msg, QMessageBox::Ok);
|
||||||
|
ui->chatEdit->append("<b>" + peerID + "</b>" + tr(" left from this chat."));
|
||||||
|
ui->msgEdit->setEnabled(false);
|
||||||
|
ui->sendMsgButton->setEnabled(false);
|
||||||
|
}
|
33
src/chatwindow.hpp
Normal file
33
src/chatwindow.hpp
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include "kernel/handler.hpp"
|
||||||
|
#include "kernel/network.hpp"
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class ChatWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ChatWindow : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit ChatWindow(QString pID, QString cUUID, Handler *h, Network *n, QWidget *parent = 0);
|
||||||
|
~ChatWindow();
|
||||||
|
QString chatID;
|
||||||
|
QString peerID;
|
||||||
|
Handler *handler;
|
||||||
|
Network *network;
|
||||||
|
void displayMsg(QString msgText);
|
||||||
|
void peerReceiverLeftFromChat();
|
||||||
|
private:
|
||||||
|
Ui::ChatWindow *ui;
|
||||||
|
void sendMessage(QString msgText);
|
||||||
|
void leftFromChat();
|
||||||
|
signals:
|
||||||
|
void deleteChat(QString cID);
|
||||||
|
private slots:
|
||||||
|
void sendMsgButtonClicked();
|
||||||
|
};
|
78
src/chatwindow.ui
Normal file
78
src/chatwindow.ui
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>ChatWindow</class>
|
||||||
|
<widget class="QWidget" name="ChatWindow">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>807</width>
|
||||||
|
<height>519</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="3" column="0" colspan="2">
|
||||||
|
<widget class="QLineEdit" name="msgEdit"/>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="peerIDLabel">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>697</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Contact PeerID: </string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="2">
|
||||||
|
<widget class="QPushButton" name="sendMsgButton">
|
||||||
|
<property name="locale">
|
||||||
|
<locale language="English" country="UnitedStates"/>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Send</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0" colspan="3">
|
||||||
|
<widget class="QTextEdit" name="chatEdit">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="chatIDLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>ChatID: </string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>msgEdit</sender>
|
||||||
|
<signal>returnPressed()</signal>
|
||||||
|
<receiver>sendMsgButton</receiver>
|
||||||
|
<slot>click()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>360</x>
|
||||||
|
<y>497</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>757</x>
|
||||||
|
<y>497</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
@ -2,24 +2,101 @@
|
|||||||
|
|
||||||
Handler::Handler()
|
Handler::Handler()
|
||||||
{
|
{
|
||||||
|
using namespace std::placeholders;
|
||||||
|
|
||||||
|
handlers = {
|
||||||
|
{"checkPeer", std::bind(&Handler::checkPeer, this, _1)},
|
||||||
|
{"checkPeerSuccess", std::bind(&Handler::checkPeerSuccessMethod, this, _1)},
|
||||||
|
{"createChat", std::bind(&Handler::createChatMethod, this, _1)},
|
||||||
|
{"createChatSuccess", std::bind(&Handler::createChatSuccessMethod, this, _1)},
|
||||||
|
{"createChatFailed", std::bind(&Handler::createChatFailedMethod, this, _1)},
|
||||||
|
{"msgSend", std::bind(&Handler::msgReceiveMethod, this, _1)},
|
||||||
|
{"leftChat", std::bind(&Handler::peerReceiverLeftFromChatMethod, this, _1)}
|
||||||
|
};
|
||||||
|
peerReceiver = new QString();
|
||||||
network = new Network();
|
network = new Network();
|
||||||
connect(network, &Network::json_received, this, &Handler::handle);
|
connect(network, &Network::jsonReceived, this, &Handler::handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Handler::handle(QJsonObject jsonReceived)
|
void Handler::handle(QJsonObject jsonReceived)
|
||||||
|
{
|
||||||
|
QString action = jsonReceived["action"].toString();
|
||||||
|
*peerReceiver = jsonReceived["peerID"].toString();
|
||||||
|
handlers[action](jsonReceived);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Handler::checkPeer(QJsonObject jsonReceived)
|
||||||
{
|
{
|
||||||
QJsonObject jsonSend;
|
QJsonObject jsonSend;
|
||||||
if(jsonReceived["action"] == "createSession" && !jsonReceived.contains("status"))
|
jsonSend["peerID"] = *network->myIPv6;
|
||||||
|
jsonSend["action"] = "checkPeerSuccess";
|
||||||
|
network->sendDatagram(jsonSend, *peerReceiver);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Handler::checkPeerSuccessMethod(QJsonObject jsonReceived)
|
||||||
|
{
|
||||||
|
emit checkPeerSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
Handler::~Handler()
|
||||||
|
{
|
||||||
|
delete peerReceiver;
|
||||||
|
delete network;
|
||||||
|
//delete handlers;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Handler::createChatMethod(QJsonObject jsonReceived)
|
||||||
|
{
|
||||||
|
QWidget *parent = 0;
|
||||||
|
QString msgTitle;
|
||||||
|
QString msg;
|
||||||
|
msgTitle += "Create chat";
|
||||||
|
msg += tr("Peer ");
|
||||||
|
msg += *peerReceiver;
|
||||||
|
msg += tr(" want to create chat with you.\n");
|
||||||
|
msg += tr("Do you want to create chat?");
|
||||||
|
int ret = QMessageBox::warning(parent, msgTitle, msg, QMessageBox::Yes | QMessageBox::No);
|
||||||
|
if(ret == QMessageBox::Yes)
|
||||||
{
|
{
|
||||||
jsonSend["peerID"] = my_ipv6;
|
QJsonObject jsonSend;
|
||||||
jsonSend["action"] = "createSession";
|
jsonSend["peerID"] = *network->myIPv6;
|
||||||
jsonSend["status"] = true;
|
jsonSend["action"] = "createChatSuccess";
|
||||||
QString peerReceiver = jsonReceived["peerID"].toString();
|
jsonSend["chatID"] = jsonReceived["chatUUID"].toString();
|
||||||
network->sendDatagram(jsonSend, peerReceiver);
|
network->sendDatagram(jsonSend, *peerReceiver);
|
||||||
|
emit createChatSuccess(jsonReceived["peerID"].toString(), jsonReceived["chatUUID"].toString());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
emit createSessionSuccess();
|
QJsonObject jsonSend;
|
||||||
|
jsonSend["peerID"] = *network->myIPv6;
|
||||||
|
jsonSend["action"] = "createChatFailed";
|
||||||
|
network->sendDatagram(jsonSend, *peerReceiver);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Handler::createChatFailedMethod(QJsonObject jsonReceived)
|
||||||
|
{
|
||||||
|
QString msg;
|
||||||
|
msg += tr("Peer ");
|
||||||
|
msg += *peerReceiver;
|
||||||
|
msg += tr(" refused to create a chat with you");
|
||||||
|
QWidget *parent = 0;
|
||||||
|
QMessageBox::critical(parent, tr("Create chat failed!"), msg, QMessageBox::Ok);
|
||||||
|
emit createChatFailed();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Handler::createChatSuccessMethod(QJsonObject jsonReceived)
|
||||||
|
{
|
||||||
|
emit createChatSuccess(jsonReceived["peerID"].toString(), jsonReceived["chatID"].toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Handler::msgReceiveMethod(QJsonObject jsonReceived)
|
||||||
|
{
|
||||||
|
emit msgReceived(jsonReceived["peerID"].toString(), jsonReceived["chatID"].toString(), jsonReceived["msgText"].toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Handler::peerReceiverLeftFromChatMethod(QJsonObject jsonReceived)
|
||||||
|
{
|
||||||
|
emit peerReceiverLeftFromChat(jsonReceived["peerID"].toString(), jsonReceived["chatID"].toString());
|
||||||
|
}
|
||||||
|
@ -2,21 +2,32 @@
|
|||||||
|
|
||||||
#include "network.hpp"
|
#include "network.hpp"
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
|
#include <QMessageBox>
|
||||||
|
|
||||||
class Handler : public QObject
|
class Handler : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
const QString my_ipv6 = Network::local_ipv6();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Handler();
|
Handler();
|
||||||
signals:
|
~Handler();
|
||||||
void createSessionSuccess();
|
QString *peerReceiver;
|
||||||
private:
|
private:
|
||||||
Network *network;
|
Network *network;
|
||||||
|
void checkPeer(QJsonObject jsonReceived);
|
||||||
|
std::map<QString, std::function<void(QJsonObject)>> handlers;
|
||||||
|
void checkPeerSuccessMethod(QJsonObject jsonReceived);
|
||||||
|
void createChatMethod(QJsonObject jsonReceived);
|
||||||
|
void createChatSuccessMethod(QJsonObject jsonReceived);
|
||||||
|
void createChatFailedMethod(QJsonObject jsonReceived);
|
||||||
|
void msgReceiveMethod(QJsonObject jsonReceived);
|
||||||
|
void peerReceiverLeftFromChatMethod(QJsonObject jsonReceived);
|
||||||
|
signals:
|
||||||
|
void checkPeerSuccess();
|
||||||
|
void createChatSuccess(QString peerID, QString chatID);
|
||||||
|
void createChatFailed();
|
||||||
|
void msgReceived(QString peerID, QString chatID, QString msgText);
|
||||||
|
void peerReceiverLeftFromChat(QString peerID, QString chatID);
|
||||||
private slots:
|
private slots:
|
||||||
void handle(QJsonObject jsonReceived);
|
void handle(QJsonObject jsonReceived);
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "network.hpp"
|
#include "network.hpp"
|
||||||
|
|
||||||
Network::Network(bool is_server)
|
Network::Network(bool is_server)
|
||||||
{
|
{
|
||||||
udpSocket = new QUdpSocket(this);
|
udpSocket = new QUdpSocket(this);
|
||||||
@ -7,6 +8,7 @@ Network::Network(bool is_server)
|
|||||||
udpSocket->bind(QHostAddress::AnyIPv6, 6552);
|
udpSocket->bind(QHostAddress::AnyIPv6, 6552);
|
||||||
connect(udpSocket, SIGNAL(readyRead()), this, SLOT(processTheDatagram()));
|
connect(udpSocket, SIGNAL(readyRead()), this, SLOT(processTheDatagram()));
|
||||||
}
|
}
|
||||||
|
myIPv6 = new QString(localIPv6());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Network::sendDatagram(QJsonObject j, QString s)
|
void Network::sendDatagram(QJsonObject j, QString s)
|
||||||
@ -23,21 +25,35 @@ void Network::processTheDatagram()
|
|||||||
{
|
{
|
||||||
QByteArray baDatagram;
|
QByteArray baDatagram;
|
||||||
do {
|
do {
|
||||||
baDatagram.resize(udpSocket->pendingDatagramSize ()) ;
|
baDatagram.resize(udpSocket->pendingDatagramSize()) ;
|
||||||
udpSocket->readDatagram (baDatagram.data(), baDatagram.size()) ;
|
udpSocket->readDatagram (baDatagram.data(), baDatagram.size()) ;
|
||||||
} while (udpSocket->hasPendingDatagrams()) ;
|
} while (udpSocket->hasPendingDatagrams()) ;
|
||||||
|
|
||||||
QJsonDocument jbuff = QJsonDocument::fromJson(baDatagram);
|
QJsonDocument jbuff = QJsonDocument::fromJson(baDatagram);
|
||||||
QJsonObject j = QJsonObject(jbuff.object());
|
QJsonObject j = QJsonObject(jbuff.object());
|
||||||
emit json_received(j);
|
emit jsonReceived(j);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Network::local_ipv6()
|
QString Network::localIPv6()
|
||||||
{
|
{
|
||||||
QHostAddress address;
|
QHostAddress address;
|
||||||
|
QString addressString;
|
||||||
foreach (address, QNetworkInterface::allAddresses()) {
|
foreach (address, QNetworkInterface::allAddresses()) {
|
||||||
if (address.protocol() == QAbstractSocket::IPv6Protocol && address != QHostAddress(QHostAddress::LocalHost))
|
if (address.protocol() == QAbstractSocket::IPv6Protocol && address != QHostAddress(QHostAddress::LocalHostIPv6) && (address.toString()).contains("fc"))
|
||||||
break;
|
{
|
||||||
|
addressString = address.toString();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
addressString = "null";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return(address.toString());
|
return(addressString);
|
||||||
|
}
|
||||||
|
|
||||||
|
Network::~Network()
|
||||||
|
{
|
||||||
|
delete udpSocket;
|
||||||
|
delete myIPv6;
|
||||||
}
|
}
|
||||||
|
@ -9,15 +9,18 @@ class Network : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
private:
|
|
||||||
QUdpSocket* udpSocket;
|
|
||||||
public:
|
public:
|
||||||
Network(bool is_server = true);
|
Network(bool is_server = true);
|
||||||
static QString local_ipv6();
|
~Network();
|
||||||
|
static QString localIPv6();
|
||||||
|
const QString *myIPv6;
|
||||||
|
private:
|
||||||
|
QUdpSocket* udpSocket;
|
||||||
public slots:
|
public slots:
|
||||||
void sendDatagram(QJsonObject j, QString s);
|
void sendDatagram(QJsonObject j, QString s);
|
||||||
signals:
|
signals:
|
||||||
void json_received(QJsonObject &jsonReceived);
|
void jsonReceived(QJsonObject &jsonReceived);
|
||||||
private slots:
|
private slots:
|
||||||
void processTheDatagram();
|
void processTheDatagram();
|
||||||
};
|
};
|
||||||
|
@ -5,6 +5,10 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
QApplication a(argc, argv);
|
QApplication a(argc, argv);
|
||||||
MainWindow w;
|
MainWindow w;
|
||||||
|
if(w.doQuit())
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
w.show();
|
w.show();
|
||||||
|
|
||||||
return a.exec();
|
return a.exec();
|
||||||
|
@ -5,47 +5,140 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||||||
QMainWindow(parent),
|
QMainWindow(parent),
|
||||||
ui(new Ui::MainWindow)
|
ui(new Ui::MainWindow)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
|
||||||
network = new Network(false);
|
network = new Network(false);
|
||||||
|
if(*network->myIPv6 == "null")
|
||||||
|
{
|
||||||
|
QMessageBox::critical(parent, tr("Cjdns is not running!"), tr("Cjdns is not running, so the application will be closed."));
|
||||||
|
mDoQuit = true;
|
||||||
|
}
|
||||||
|
ui->setupUi(this);
|
||||||
handler = new Handler();
|
handler = new Handler();
|
||||||
connect(handler, &Handler::createSessionSuccess, this, &MainWindow::peerReceiverConnected);
|
timer = new QTimer();
|
||||||
|
connect(timer, SIGNAL(timeout()), this, SLOT(slotTimerAlarm()));
|
||||||
|
connect(handler, &Handler::checkPeerSuccess, this, &MainWindow::peerReceiverAvailable);
|
||||||
|
connect(handler, &Handler::createChatSuccess, this, &MainWindow::createChat);
|
||||||
|
connect(handler, &Handler::createChatFailed, this, &MainWindow::createChatFailedMethod);
|
||||||
|
connect(handler, &Handler::msgReceived, this, &MainWindow::msgReceivedMethod);
|
||||||
|
connect(handler, &Handler::peerReceiverLeftFromChat, this, &MainWindow::peerReceiverLeftFromChatMethod);
|
||||||
|
ui->myIP->setText(*network->myIPv6);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWindow::~MainWindow()
|
MainWindow::~MainWindow()
|
||||||
{
|
{
|
||||||
delete ui;
|
delete ui;
|
||||||
|
delete network;
|
||||||
|
delete handler;
|
||||||
|
delete timer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::on_connectToPeer_clicked()
|
void MainWindow::on_connectToPeer_clicked()
|
||||||
{
|
{
|
||||||
|
setButtonToWaiting();
|
||||||
QJsonObject j;
|
QJsonObject j;
|
||||||
j["peerID"] = my_ipv6;
|
j["peerID"] = *network->myIPv6;
|
||||||
j["action"] = "createSession";
|
j["action"] = "checkPeer";
|
||||||
QString s = ui->peerID->text();
|
QString s = ui->peerID->text();
|
||||||
network->sendDatagram(j, s);
|
network->sendDatagram(j, s);
|
||||||
timer = new QTimer();
|
|
||||||
connect(timer, SIGNAL(timeout()), this, SLOT(slotTimerAlarm()));
|
|
||||||
timer->start(10000);
|
timer->start(10000);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::slotTimerAlarm()
|
void MainWindow::slotTimerAlarm()
|
||||||
{
|
{
|
||||||
if(receive)
|
if(receive == true)
|
||||||
{
|
{
|
||||||
timer->stop();
|
timer->stop();
|
||||||
receive = false;
|
receive = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int ret = QMessageBox::critical(this,QObject::tr("Error"),tr("Timeout Error"));
|
QMessageBox::critical(this, tr("Error"), tr("Timeout Error\n\nPerhaps you have not started the cjdns daemon, you entered the wrong IP, the peer is off, or the peer did not start the messenger."));
|
||||||
timer->stop();
|
timer->stop();
|
||||||
delete timer;
|
setButtonToConnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::peerReceiverConnected()
|
void MainWindow::peerReceiverAvailable()
|
||||||
{
|
{
|
||||||
receive = true;
|
receive = true;
|
||||||
int ret = QMessageBox::information(this,QObject::tr("Info"),tr("Peer Available!"));
|
int ret = QMessageBox::information(this, tr("Peer Available!"),
|
||||||
|
tr("Peer Available!\nDo you want to create chat?"), QMessageBox::Yes | QMessageBox::No);
|
||||||
|
if(ret == QMessageBox::Yes)
|
||||||
|
{
|
||||||
|
createChatSendDatagram(*handler->peerReceiver);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setButtonToConnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::setButtonToWaiting() // Function, which sets button "connectToPeer" in status "Waiting..."
|
||||||
|
{
|
||||||
|
ui->connectToPeer->setEnabled(false);
|
||||||
|
ui->connectToPeer->setText(tr("Waiting..."));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::setButtonToConnect() // Function, which sets button "connectToPeer" in status "Connect"
|
||||||
|
{
|
||||||
|
ui->connectToPeer->setEnabled(true);
|
||||||
|
ui->connectToPeer->setText(tr("Connect"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::createChatSendDatagram(QString peerReceiver)
|
||||||
|
{
|
||||||
|
QUuid chatID = QUuid::createUuid();
|
||||||
|
QJsonObject jSend;
|
||||||
|
jSend["action"] = "createChat";
|
||||||
|
jSend["peerID"] = *network->myIPv6;
|
||||||
|
jSend["chatUUID"] = chatID.toString();
|
||||||
|
network->sendDatagram(jSend, peerReceiver);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::createChat(QString peerID, QString chatID)
|
||||||
|
{
|
||||||
|
pChatWindows.push_back(new ChatWindow(peerID, chatID, handler, network));
|
||||||
|
connect(pChatWindows.back(), &ChatWindow::deleteChat, this, &MainWindow::deleteChatMethod);
|
||||||
|
pChatWindows.back()->show();
|
||||||
|
setButtonToConnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::createChatFailedMethod()
|
||||||
|
{
|
||||||
|
setButtonToConnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::deleteChatMethod(QString cID)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < pChatWindows.size(); i++)
|
||||||
|
{
|
||||||
|
if(pChatWindows.at(i)->chatID == cID)
|
||||||
|
{
|
||||||
|
pChatWindows.remove(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::msgReceivedMethod(QString peerID, QString chatID, QString msgText)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < pChatWindows.size(); i++)
|
||||||
|
{
|
||||||
|
if(pChatWindows.at(i)->peerID == peerID && pChatWindows.at(i)->chatID == chatID)
|
||||||
|
{
|
||||||
|
pChatWindows.at(i)->displayMsg(msgText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::peerReceiverLeftFromChatMethod(QString peerID, QString chatID)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < pChatWindows.size(); i++)
|
||||||
|
{
|
||||||
|
if(pChatWindows.at(i)->peerID == peerID && pChatWindows.at(i)->chatID == chatID)
|
||||||
|
{
|
||||||
|
pChatWindows.at(i)->peerReceiverLeftFromChat();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,12 @@
|
|||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include "kernel/network.hpp"
|
#include "kernel/network.hpp"
|
||||||
#include "kernel/handler.hpp"
|
#include "kernel/handler.hpp"
|
||||||
|
#include "chatwindow.hpp"
|
||||||
|
#include <QUuid>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
@ -19,18 +22,26 @@ class MainWindow : public QMainWindow
|
|||||||
public:
|
public:
|
||||||
explicit MainWindow(QWidget *parent = 0);
|
explicit MainWindow(QWidget *parent = 0);
|
||||||
~MainWindow();
|
~MainWindow();
|
||||||
|
QVector<ChatWindow*> pChatWindows;
|
||||||
|
void setButtonToWaiting();
|
||||||
|
void setButtonToConnect();
|
||||||
|
inline bool doQuit() const { return mDoQuit; }
|
||||||
public slots:
|
public slots:
|
||||||
void peerReceiverConnected();
|
void peerReceiverAvailable();
|
||||||
private slots:
|
private slots:
|
||||||
void on_connectToPeer_clicked();
|
void on_connectToPeer_clicked();
|
||||||
void slotTimerAlarm();
|
void slotTimerAlarm();
|
||||||
|
void createChatFailedMethod();
|
||||||
|
void createChat(QString peerID, QString chatID);
|
||||||
|
void deleteChatMethod(QString cID);
|
||||||
|
void msgReceivedMethod(QString peerID, QString chatID, QString msgText);
|
||||||
|
void peerReceiverLeftFromChatMethod(QString peerID, QString chatID);
|
||||||
private:
|
private:
|
||||||
|
void createChatSendDatagram(QString peerReceiver);
|
||||||
Ui::MainWindow *ui;
|
Ui::MainWindow *ui;
|
||||||
QTimer *timer;
|
QTimer *timer;
|
||||||
Network *network;
|
Network *network;
|
||||||
Handler *handler;
|
Handler *handler;
|
||||||
|
bool receive = false;
|
||||||
bool receive;
|
bool mDoQuit = false;
|
||||||
const QString my_ipv6 = Network::local_ipv6();
|
|
||||||
};
|
};
|
||||||
|
@ -29,18 +29,38 @@
|
|||||||
<string>Influence</string>
|
<string>Influence</string>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="centralWidget">
|
<widget class="QWidget" name="centralWidget">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<item>
|
<item row="1" column="0" colspan="4">
|
||||||
<widget class="QLineEdit" name="peerID">
|
<widget class="QLineEdit" name="peerID">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item row="0" column="0">
|
||||||
<widget class="QPushButton" name="connectToPeer">
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="locale">
|
||||||
|
<locale language="English" country="UnitedStates"/>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Подключиться</string>
|
<string>My IPv6:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="4">
|
||||||
|
<widget class="QPushButton" name="connectToPeer">
|
||||||
|
<property name="locale">
|
||||||
|
<locale language="English" country="UnitedStates"/>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Connect</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1" colspan="2">
|
||||||
|
<widget class="QLineEdit" name="myIP">
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -49,5 +69,22 @@
|
|||||||
</widget>
|
</widget>
|
||||||
<layoutdefault spacing="6" margin="11"/>
|
<layoutdefault spacing="6" margin="11"/>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>peerID</sender>
|
||||||
|
<signal>returnPressed()</signal>
|
||||||
|
<receiver>connectToPeer</receiver>
|
||||||
|
<slot>click()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>122</x>
|
||||||
|
<y>90</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>281</x>
|
||||||
|
<y>90</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
</ui>
|
</ui>
|
||||||
|
3
src/make.sh
Executable file
3
src/make.sh
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
rm -f Influence
|
||||||
|
qmake
|
||||||
|
make
|
Loading…
Reference in New Issue
Block a user