|
|
@ -28,7 +28,6 @@ |
|
|
|
#include "src/model/groupinvite.h" |
|
|
|
#include "src/model/groupinvite.h" |
|
|
|
#include "src/nexus.h" |
|
|
|
#include "src/nexus.h" |
|
|
|
#include "src/persistence/profile.h" |
|
|
|
#include "src/persistence/profile.h" |
|
|
|
#include "src/widget/gui.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <QCoreApplication> |
|
|
|
#include <QCoreApplication> |
|
|
|
#include <QRegularExpression> |
|
|
|
#include <QRegularExpression> |
|
|
@ -40,94 +39,89 @@ |
|
|
|
#include <ctime> |
|
|
|
#include <ctime> |
|
|
|
|
|
|
|
|
|
|
|
const QString Core::TOX_EXT = ".tox"; |
|
|
|
const QString Core::TOX_EXT = ".tox"; |
|
|
|
QThread* Core::coreThread{nullptr}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define MAX_GROUP_MESSAGE_LEN 1024 |
|
|
|
#define MAX_GROUP_MESSAGE_LEN 1024 |
|
|
|
|
|
|
|
|
|
|
|
Core::Core(QThread* CoreThread, Profile& profile, const ICoreSettings* const settings) |
|
|
|
Core::Core(QThread* coreThread) |
|
|
|
: tox(nullptr) |
|
|
|
: tox(nullptr) |
|
|
|
, av(nullptr) |
|
|
|
, av(nullptr) |
|
|
|
, profile(profile) |
|
|
|
, coreThread{coreThread} |
|
|
|
, ready(false) |
|
|
|
|
|
|
|
, s{settings} |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
coreThread = CoreThread; |
|
|
|
toxTimer.setSingleShot(true); |
|
|
|
toxTimer = new QTimer(this); |
|
|
|
connect(&this->toxTimer, &QTimer::timeout, this, &Core::process); |
|
|
|
toxTimer->setSingleShot(true); |
|
|
|
|
|
|
|
connect(toxTimer, &QTimer::timeout, this, &Core::process); |
|
|
|
|
|
|
|
s->connectTo_dhtServerListChanged([=](const QList<DhtServer>& servers){ |
|
|
|
|
|
|
|
process(); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Core::deadifyTox() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (av) { |
|
|
|
|
|
|
|
delete av; |
|
|
|
|
|
|
|
av = nullptr; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (tox) { |
|
|
|
|
|
|
|
tox_kill(tox); |
|
|
|
|
|
|
|
tox = nullptr; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Core::~Core() |
|
|
|
Core::~Core() |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (coreThread->isRunning()) { |
|
|
|
if (QThread::currentThread() == coreThread) { |
|
|
|
if (QThread::currentThread() == coreThread) { |
|
|
|
killTimers(); |
|
|
|
killTimers(false); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
// ensure the timer is stopped, even if not called from this thread
|
|
|
|
QMetaObject::invokeMethod(this, "killTimers", Qt::BlockingQueuedConnection, |
|
|
|
QMetaObject::invokeMethod(this, "killTimers", Qt::BlockingQueuedConnection); |
|
|
|
Q_ARG(bool, false)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
coreThread->exit(0); |
|
|
|
coreThread->exit(0); |
|
|
|
if (QThread::currentThread() != coreThread) { |
|
|
|
|
|
|
|
while (coreThread->isRunning()) { |
|
|
|
|
|
|
|
qApp->processEvents(); |
|
|
|
|
|
|
|
coreThread->wait(500); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
deadifyTox(); |
|
|
|
delete av; |
|
|
|
|
|
|
|
tox_kill(tox); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @brief Returns the global widget's Core instance |
|
|
|
* @brief Registers all toxcore callbacks |
|
|
|
|
|
|
|
* @param tox Tox instance to register the callbacks on |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
Core* Core::getInstance() |
|
|
|
void Core::registerCallbacks(Tox * tox) { |
|
|
|
{ |
|
|
|
tox_callback_friend_request(tox, onFriendRequest); |
|
|
|
return Nexus::getCore(); |
|
|
|
tox_callback_friend_message(tox, onFriendMessage); |
|
|
|
} |
|
|
|
tox_callback_friend_name(tox, onFriendNameChange); |
|
|
|
|
|
|
|
tox_callback_friend_typing(tox, onFriendTypingChange); |
|
|
|
const CoreAV* Core::getAv() const |
|
|
|
tox_callback_friend_status_message(tox, onStatusMessageChanged); |
|
|
|
{ |
|
|
|
tox_callback_friend_status(tox, onUserStatusChanged); |
|
|
|
return av; |
|
|
|
tox_callback_friend_connection_status(tox, onConnectionStatusChanged); |
|
|
|
} |
|
|
|
tox_callback_friend_read_receipt(tox, onReadReceiptCallback); |
|
|
|
|
|
|
|
tox_callback_conference_invite(tox, onGroupInvite); |
|
|
|
CoreAV* Core::getAv() |
|
|
|
tox_callback_conference_message(tox, onGroupMessage); |
|
|
|
{ |
|
|
|
#if TOX_VERSION_IS_API_COMPATIBLE(0, 2, 0) |
|
|
|
return av; |
|
|
|
tox_callback_conference_peer_list_changed(tox, onGroupPeerListChange); |
|
|
|
|
|
|
|
tox_callback_conference_peer_name(tox, onGroupPeerNameChange); |
|
|
|
|
|
|
|
#else |
|
|
|
|
|
|
|
tox_callback_conference_namelist_change(tox, onGroupNamelistChange); |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
tox_callback_conference_title(tox, onGroupTitleChange); |
|
|
|
|
|
|
|
tox_callback_file_chunk_request(tox, CoreFile::onFileDataCallback); |
|
|
|
|
|
|
|
tox_callback_file_recv(tox, CoreFile::onFileReceiveCallback); |
|
|
|
|
|
|
|
tox_callback_file_recv_chunk(tox, CoreFile::onFileRecvChunkCallback); |
|
|
|
|
|
|
|
tox_callback_file_recv_control(tox, CoreFile::onFileControlCallback); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @brief Creates Tox instance from previously saved data |
|
|
|
* @brief Factory method for the Core object |
|
|
|
* @param savedata Previously saved Tox data - null, if new profile was created |
|
|
|
* @param savedata empty if new profile or saved data else |
|
|
|
|
|
|
|
* @param settings Settings specific to Core |
|
|
|
|
|
|
|
* @return nullptr or a Core object ready to start |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
void Core::makeTox(QByteArray savedata) |
|
|
|
ToxCorePtr Core::makeToxCore(const QByteArray &savedata, const ICoreSettings * const settings) |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto toxOptions = ToxOptions::makeToxOptions(savedata, s); |
|
|
|
QThread* thread = new QThread(); |
|
|
|
|
|
|
|
if (thread == nullptr) { |
|
|
|
|
|
|
|
qCritical() << "could not allocate Core thread"; |
|
|
|
|
|
|
|
return {}; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
thread->setObjectName("qTox Core"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto toxOptions = ToxOptions::makeToxOptions(savedata, settings); |
|
|
|
if (toxOptions == nullptr) { |
|
|
|
if (toxOptions == nullptr) { |
|
|
|
qCritical() << "could not allocate Tox Options data structure"; |
|
|
|
qCritical() << "could not allocate Tox Options data structure"; |
|
|
|
emit failedToStart(); |
|
|
|
return {}; |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ToxCorePtr core(new Core(thread)); |
|
|
|
|
|
|
|
if(core == nullptr) { |
|
|
|
|
|
|
|
return {}; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
TOX_ERR_NEW tox_err; |
|
|
|
TOX_ERR_NEW tox_err; |
|
|
|
tox = tox_new(*toxOptions, &tox_err); |
|
|
|
core->tox = tox_new(*toxOptions, &tox_err); |
|
|
|
|
|
|
|
|
|
|
|
switch (tox_err) { |
|
|
|
switch (tox_err) { |
|
|
|
case TOX_ERR_NEW_OK: |
|
|
|
case TOX_ERR_NEW_OK: |
|
|
@ -135,13 +129,12 @@ void Core::makeTox(QByteArray savedata) |
|
|
|
|
|
|
|
|
|
|
|
case TOX_ERR_NEW_LOAD_BAD_FORMAT: |
|
|
|
case TOX_ERR_NEW_LOAD_BAD_FORMAT: |
|
|
|
qCritical() << "failed to parse Tox save data"; |
|
|
|
qCritical() << "failed to parse Tox save data"; |
|
|
|
emit failedToStart(); |
|
|
|
return {}; |
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case TOX_ERR_NEW_PORT_ALLOC: |
|
|
|
case TOX_ERR_NEW_PORT_ALLOC: |
|
|
|
if (s->getEnableIPv6()) { |
|
|
|
if (toxOptions->getIPv6Enabled()) { |
|
|
|
tox_options_set_ipv6_enabled(*toxOptions, false); |
|
|
|
toxOptions->setIPv6Enabled(false); |
|
|
|
tox = tox_new(*toxOptions, &tox_err); |
|
|
|
core->tox = tox_new(*toxOptions, &tox_err); |
|
|
|
if (tox_err == TOX_ERR_NEW_OK) { |
|
|
|
if (tox_err == TOX_ERR_NEW_OK) { |
|
|
|
qWarning() << "Core failed to start with IPv6, falling back to IPv4. LAN discovery " |
|
|
|
qWarning() << "Core failed to start with IPv6, falling back to IPv4. LAN discovery " |
|
|
|
"may not work properly."; |
|
|
|
"may not work properly."; |
|
|
@ -150,80 +143,72 @@ void Core::makeTox(QByteArray savedata) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
qCritical() << "can't to bind the port"; |
|
|
|
qCritical() << "can't to bind the port"; |
|
|
|
emit failedToStart(); |
|
|
|
return {}; |
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case TOX_ERR_NEW_PROXY_BAD_HOST: |
|
|
|
case TOX_ERR_NEW_PROXY_BAD_HOST: |
|
|
|
case TOX_ERR_NEW_PROXY_BAD_PORT: |
|
|
|
case TOX_ERR_NEW_PROXY_BAD_PORT: |
|
|
|
case TOX_ERR_NEW_PROXY_BAD_TYPE: |
|
|
|
case TOX_ERR_NEW_PROXY_BAD_TYPE: |
|
|
|
qCritical() << "bad proxy, error code:" << tox_err; |
|
|
|
qCritical() << "bad proxy, error code:" << tox_err; |
|
|
|
emit badProxy(); |
|
|
|
//emit badProxy();
|
|
|
|
return; |
|
|
|
return {}; |
|
|
|
|
|
|
|
|
|
|
|
case TOX_ERR_NEW_PROXY_NOT_FOUND: |
|
|
|
case TOX_ERR_NEW_PROXY_NOT_FOUND: |
|
|
|
qCritical() << "proxy not found"; |
|
|
|
qCritical() << "proxy not found"; |
|
|
|
emit badProxy(); |
|
|
|
//emit badProxy();
|
|
|
|
return; |
|
|
|
return {}; |
|
|
|
|
|
|
|
|
|
|
|
case TOX_ERR_NEW_LOAD_ENCRYPTED: |
|
|
|
case TOX_ERR_NEW_LOAD_ENCRYPTED: |
|
|
|
qCritical() << "attempted to load encrypted Tox save data"; |
|
|
|
qCritical() << "attempted to load encrypted Tox save data"; |
|
|
|
emit failedToStart(); |
|
|
|
//emit failedToStart();
|
|
|
|
return; |
|
|
|
return {}; |
|
|
|
|
|
|
|
|
|
|
|
case TOX_ERR_NEW_MALLOC: |
|
|
|
case TOX_ERR_NEW_MALLOC: |
|
|
|
qCritical() << "memory allocation failed"; |
|
|
|
qCritical() << "memory allocation failed"; |
|
|
|
emit failedToStart(); |
|
|
|
//emit failedToStart();
|
|
|
|
return; |
|
|
|
return {}; |
|
|
|
|
|
|
|
|
|
|
|
case TOX_ERR_NEW_NULL: |
|
|
|
case TOX_ERR_NEW_NULL: |
|
|
|
qCritical() << "a parameter was null"; |
|
|
|
qCritical() << "a parameter was null"; |
|
|
|
emit failedToStart(); |
|
|
|
//emit failedToStart();
|
|
|
|
return; |
|
|
|
return {}; |
|
|
|
|
|
|
|
|
|
|
|
default: |
|
|
|
default: |
|
|
|
qCritical() << "Tox core failed to start, unknown error code:" << tox_err; |
|
|
|
qCritical() << "Tox core failed to start, unknown error code:" << tox_err; |
|
|
|
emit failedToStart(); |
|
|
|
//emit failedToStart();
|
|
|
|
return; |
|
|
|
return {}; |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* @brief Initializes the core, must be called before anything else |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
void Core::start(const QByteArray& savedata) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
bool isNewProfile = profile.isNewProfile(); |
|
|
|
|
|
|
|
if (isNewProfile) { |
|
|
|
|
|
|
|
qDebug() << "Creating a new profile"; |
|
|
|
|
|
|
|
makeTox(QByteArray()); |
|
|
|
|
|
|
|
setStatusMessage(tr("Toxing on qTox")); |
|
|
|
|
|
|
|
setUsername(profile.getName()); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
qDebug() << "Loading user profile"; |
|
|
|
|
|
|
|
if (savedata.isEmpty()) { |
|
|
|
|
|
|
|
emit failedToStart(); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
makeTox(savedata); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
qsrand(time(nullptr)); |
|
|
|
qsrand(time(nullptr)); // TODO(sudden6): needed?
|
|
|
|
if (!tox) { |
|
|
|
// tox should be valid by now
|
|
|
|
ready = true; |
|
|
|
assert(core->tox != nullptr); |
|
|
|
GUI::setEnabled(true); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// toxcore is successfully created, create toxav
|
|
|
|
// toxcore is successfully created, create toxav
|
|
|
|
av = new CoreAV(tox); |
|
|
|
core->av = new CoreAV(core->tox); |
|
|
|
if (!av->getToxAv()) { |
|
|
|
if (!core->av || !core->av->getToxAv()) { |
|
|
|
qCritical() << "Toxav failed to start"; |
|
|
|
qCritical() << "Toxav failed to start"; |
|
|
|
emit failedToStart(); |
|
|
|
//emit failedToStart();
|
|
|
|
deadifyTox(); |
|
|
|
//deadifyTox();
|
|
|
|
return; |
|
|
|
return {}; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
registerCallbacks(core->tox); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// connect the thread with the Core
|
|
|
|
|
|
|
|
connect(thread, &QThread::started, core.get(), &Core::onStarted); |
|
|
|
|
|
|
|
core->moveToThread(thread); |
|
|
|
|
|
|
|
// since this is allocated in the constructor move it to the other thread too
|
|
|
|
|
|
|
|
core->toxTimer.moveToThread(thread); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// when leaving this function 'core' should be ready for it's start() action or
|
|
|
|
|
|
|
|
// a nullptr
|
|
|
|
|
|
|
|
return core; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Core::onStarted() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// TODO(sudden6): this assert should hold?
|
|
|
|
|
|
|
|
//assert(QThread::currentThread() == coreThread);
|
|
|
|
|
|
|
|
// One time initialization stuff
|
|
|
|
// set GUI with user and statusmsg
|
|
|
|
// set GUI with user and statusmsg
|
|
|
|
QString name = getUsername(); |
|
|
|
QString name = getUsername(); |
|
|
|
if (!name.isEmpty()) { |
|
|
|
if (!name.isEmpty()) { |
|
|
@ -243,41 +228,38 @@ void Core::start(const QByteArray& savedata) |
|
|
|
|
|
|
|
|
|
|
|
loadFriends(); |
|
|
|
loadFriends(); |
|
|
|
|
|
|
|
|
|
|
|
tox_callback_friend_request(tox, onFriendRequest); |
|
|
|
process(); // starts its own timer
|
|
|
|
tox_callback_friend_message(tox, onFriendMessage); |
|
|
|
av->start(); |
|
|
|
tox_callback_friend_name(tox, onFriendNameChange); |
|
|
|
emit avReady(); |
|
|
|
tox_callback_friend_typing(tox, onFriendTypingChange); |
|
|
|
} |
|
|
|
tox_callback_friend_status_message(tox, onStatusMessageChanged); |
|
|
|
|
|
|
|
tox_callback_friend_status(tox, onUserStatusChanged); |
|
|
|
|
|
|
|
tox_callback_friend_connection_status(tox, onConnectionStatusChanged); |
|
|
|
|
|
|
|
tox_callback_friend_read_receipt(tox, onReadReceiptCallback); |
|
|
|
|
|
|
|
tox_callback_conference_invite(tox, onGroupInvite); |
|
|
|
|
|
|
|
tox_callback_conference_message(tox, onGroupMessage); |
|
|
|
|
|
|
|
#if TOX_VERSION_IS_API_COMPATIBLE(0, 2, 0) |
|
|
|
|
|
|
|
tox_callback_conference_peer_list_changed(tox, onGroupPeerListChange); |
|
|
|
|
|
|
|
tox_callback_conference_peer_name(tox, onGroupPeerNameChange); |
|
|
|
|
|
|
|
#else |
|
|
|
|
|
|
|
tox_callback_conference_namelist_change(tox, onGroupNamelistChange); |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
tox_callback_conference_title(tox, onGroupTitleChange); |
|
|
|
|
|
|
|
tox_callback_file_chunk_request(tox, CoreFile::onFileDataCallback); |
|
|
|
|
|
|
|
tox_callback_file_recv(tox, CoreFile::onFileReceiveCallback); |
|
|
|
|
|
|
|
tox_callback_file_recv_chunk(tox, CoreFile::onFileRecvChunkCallback); |
|
|
|
|
|
|
|
tox_callback_file_recv_control(tox, CoreFile::onFileControlCallback); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ready = true; |
|
|
|
/**
|
|
|
|
|
|
|
|
* @brief Starts toxcore and it's event loop, must be run from the Core thread |
|
|
|
|
|
|
|
* @return true on success, false otherwise |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
bool Core::start() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
coreThread->start(); |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (isNewProfile) { |
|
|
|
|
|
|
|
profile.saveToxSave(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (isReady()) { |
|
|
|
/**
|
|
|
|
GUI::setEnabled(true); |
|
|
|
* @brief Returns the global widget's Core instance |
|
|
|
} |
|
|
|
*/ |
|
|
|
|
|
|
|
Core* Core::getInstance() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return Nexus::getCore(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
process(); // starts its own timer
|
|
|
|
const CoreAV* Core::getAv() const |
|
|
|
av->start(); |
|
|
|
{ |
|
|
|
emit avReady(); |
|
|
|
return av; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CoreAV* Core::getAv() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return av; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* Using the now commented out statements in checkConnection(), I watched how
|
|
|
|
/* Using the now commented out statements in checkConnection(), I watched how
|
|
|
@ -294,19 +276,21 @@ void Core::start(const QByteArray& savedata) |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
void Core::process() |
|
|
|
void Core::process() |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
assert(QThread::currentThread() == coreThread); |
|
|
|
if (!isReady()) { |
|
|
|
if (!isReady()) { |
|
|
|
av->stop(); |
|
|
|
av->stop(); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static int tolerance = CORE_DISCONNECT_TOLERANCE; |
|
|
|
static int tolerance = CORE_DISCONNECT_TOLERANCE; |
|
|
|
tox_iterate(tox, getInstance()); |
|
|
|
tox_iterate(tox, this); |
|
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG |
|
|
|
#ifdef DEBUG |
|
|
|
// we want to see the debug messages immediately
|
|
|
|
// we want to see the debug messages immediately
|
|
|
|
fflush(stdout); |
|
|
|
fflush(stdout); |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO(sudden6): recheck if this is still necessary
|
|
|
|
if (checkConnection()) { |
|
|
|
if (checkConnection()) { |
|
|
|
tolerance = CORE_DISCONNECT_TOLERANCE; |
|
|
|
tolerance = CORE_DISCONNECT_TOLERANCE; |
|
|
|
} else if (!(--tolerance)) { |
|
|
|
} else if (!(--tolerance)) { |
|
|
@ -315,7 +299,7 @@ void Core::process() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
unsigned sleeptime = qMin(tox_iteration_interval(tox), CoreFile::corefileIterationInterval()); |
|
|
|
unsigned sleeptime = qMin(tox_iteration_interval(tox), CoreFile::corefileIterationInterval()); |
|
|
|
toxTimer->start(sleeptime); |
|
|
|
toxTimer.start(sleeptime); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool Core::checkConnection() |
|
|
|
bool Core::checkConnection() |
|
|
@ -339,7 +323,8 @@ bool Core::checkConnection() |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
void Core::bootstrapDht() |
|
|
|
void Core::bootstrapDht() |
|
|
|
{ |
|
|
|
{ |
|
|
|
QList<DhtServer> dhtServerList = s->getDhtServerList(); |
|
|
|
// TODO(sudden6): fix bootstrapping
|
|
|
|
|
|
|
|
QList<DhtServer> dhtServerList{};// = s->getDhtServerList();
|
|
|
|
int listSize = dhtServerList.size(); |
|
|
|
int listSize = dhtServerList.size(); |
|
|
|
if (!listSize) { |
|
|
|
if (!listSize) { |
|
|
|
qWarning() << "no bootstrap list?!?"; |
|
|
|
qWarning() << "no bootstrap list?!?"; |
|
|
@ -540,7 +525,8 @@ void Core::acceptFriendRequest(const ToxPk& friendPk) |
|
|
|
if (friendId == std::numeric_limits<uint32_t>::max()) { |
|
|
|
if (friendId == std::numeric_limits<uint32_t>::max()) { |
|
|
|
emit failedToAddFriend(friendPk); |
|
|
|
emit failedToAddFriend(friendPk); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
profile.saveToxSave(); |
|
|
|
// TODO(sudden6): emit save request
|
|
|
|
|
|
|
|
//profile.saveToxSave();
|
|
|
|
emit friendAdded(friendId, friendPk); |
|
|
|
emit friendAdded(friendId, friendPk); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -579,7 +565,8 @@ void Core::requestFriendship(const ToxId& friendId, const QString& message) |
|
|
|
QString errorMessage = getFriendRequestErrorMessage(friendId, message); |
|
|
|
QString errorMessage = getFriendRequestErrorMessage(friendId, message); |
|
|
|
if (!errorMessage.isNull()) { |
|
|
|
if (!errorMessage.isNull()) { |
|
|
|
emit failedToAddFriend(friendPk, errorMessage); |
|
|
|
emit failedToAddFriend(friendPk, errorMessage); |
|
|
|
profile.saveToxSave(); |
|
|
|
// TODO(sudden6): emit save request
|
|
|
|
|
|
|
|
// profile.saveToxSave();
|
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -595,7 +582,8 @@ void Core::requestFriendship(const ToxId& friendId, const QString& message) |
|
|
|
emit requestSent(friendPk, message); |
|
|
|
emit requestSent(friendPk, message); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
profile.saveToxSave(); |
|
|
|
// TODO(sudden6): emit save request
|
|
|
|
|
|
|
|
// profile.saveToxSave();
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int Core::sendMessage(uint32_t friendId, const QString& message) |
|
|
|
int Core::sendMessage(uint32_t friendId, const QString& message) |
|
|
@ -757,8 +745,8 @@ void Core::removeFriend(uint32_t friendId, bool fake) |
|
|
|
emit failedToRemoveFriend(friendId); |
|
|
|
emit failedToRemoveFriend(friendId); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// TODO(sudden6): emit save request
|
|
|
|
profile.saveToxSave(); |
|
|
|
// profile.saveToxSave();
|
|
|
|
emit friendRemoved(friendId); |
|
|
|
emit friendRemoved(friendId); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -817,9 +805,8 @@ void Core::setUsername(const QString& username) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
emit usernameSet(username); |
|
|
|
emit usernameSet(username); |
|
|
|
if (ready) { |
|
|
|
|
|
|
|
profile.saveToxSave(); |
|
|
|
// TODO(sudden6): request saving
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -900,9 +887,7 @@ void Core::setStatusMessage(const QString& message) |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (ready) { |
|
|
|
// TODO(sudden6): request saving
|
|
|
|
profile.saveToxSave(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
emit statusMessageSet(message); |
|
|
|
emit statusMessageSet(message); |
|
|
|
} |
|
|
|
} |
|
|
@ -929,7 +914,8 @@ void Core::setStatus(Status status) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
tox_self_set_status(tox, userstatus); |
|
|
|
tox_self_set_status(tox, userstatus); |
|
|
|
profile.saveToxSave(); |
|
|
|
// TODO(sudden6): emit save request
|
|
|
|
|
|
|
|
// profile.saveToxSave();
|
|
|
|
emit statusSet(status); |
|
|
|
emit statusSet(status); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -1369,7 +1355,7 @@ QString Core::getPeerName(const ToxPk& id) const |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
bool Core::isReady() const |
|
|
|
bool Core::isReady() const |
|
|
|
{ |
|
|
|
{ |
|
|
|
return av && av->getToxAv() && tox && ready; |
|
|
|
return av && av->getToxAv() && tox; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -1383,32 +1369,13 @@ void Core::setNospam(uint32_t nospam) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @brief Returns the unencrypted tox save data |
|
|
|
* @brief Stops the AV thread and the timer here |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
void Core::killTimers(bool onlyStop) |
|
|
|
void Core::killTimers() |
|
|
|
{ |
|
|
|
{ |
|
|
|
assert(QThread::currentThread() == coreThread); |
|
|
|
assert(QThread::currentThread() == coreThread); |
|
|
|
if (av) { |
|
|
|
if (av) { |
|
|
|
av->stop(); |
|
|
|
av->stop(); |
|
|
|
} |
|
|
|
} |
|
|
|
toxTimer->stop(); |
|
|
|
toxTimer.stop(); |
|
|
|
if (!onlyStop) { |
|
|
|
|
|
|
|
delete toxTimer; |
|
|
|
|
|
|
|
toxTimer = nullptr; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* @brief Reinitialized the core. |
|
|
|
|
|
|
|
* @warning Must be called from the Core thread, with the GUI thread ready to process events. |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
void Core::reset() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
assert(QThread::currentThread() == coreThread); |
|
|
|
|
|
|
|
QByteArray toxsave = getToxSaveData(); |
|
|
|
|
|
|
|
ready = false; |
|
|
|
|
|
|
|
killTimers(true); |
|
|
|
|
|
|
|
deadifyTox(); |
|
|
|
|
|
|
|
GUI::clearContacts(); |
|
|
|
|
|
|
|
start(toxsave); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|