Skip to content
This repository has been archived by the owner on Feb 12, 2023. It is now read-only.

Commit

Permalink
feat(toxid): reduce passing Tox IDs around
Browse files Browse the repository at this point in the history
reasons:
- most of the time we don't even know the Tox ID but only the Public Key
- use well defined objects instead of strings that could be anything
  • Loading branch information
sudden6 committed Jan 3, 2017
1 parent 2f4e8dc commit e07d8d3
Show file tree
Hide file tree
Showing 39 changed files with 357 additions and 396 deletions.
151 changes: 61 additions & 90 deletions src/core/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -276,8 +276,8 @@ void Core::start()
if (!msg.isEmpty())
emit statusMessageSet(msg);

QString id = getSelfId().toString();
if (!id.isEmpty())
ToxId id = getSelfId();
if (id.isValid()) // TODO: probably useless check, comes basically directly from toxcore
emit idSet(id);

// TODO: This is a backwards compatibility check,
Expand Down Expand Up @@ -424,9 +424,10 @@ void Core::bootstrapDht()
+':'+QString().setNum(dhtServer.port)+" ("+dhtServer.name+')';

QByteArray address = dhtServer.address.toLatin1();
QByteArray pk = ToxId{dhtServer.userId}.getPublicKey();
// TODO: constucting the pk via ToxId is a workaround
ToxPk pk = ToxId{dhtServer.userId}.getPublicKey();

const uint8_t* pkPtr = reinterpret_cast<const uint8_t*>(pk.constData());
const uint8_t* pkPtr = reinterpret_cast<const uint8_t*>(pk.getBytes());

if (!tox_bootstrap(tox, address.constData(), dhtServer.port, pkPtr, nullptr))
{
Expand All @@ -446,7 +447,7 @@ void Core::bootstrapDht()
void Core::onFriendRequest(Tox*/* tox*/, const uint8_t* cFriendPk,
const uint8_t* cMessage, size_t cMessageSize, void* core)
{
QString friendPk = ToxId(cFriendPk, TOX_PUBLIC_KEY_SIZE).getPublicKeyString();
ToxPk friendPk(cFriendPk);
emit static_cast<Core*>(core)->friendRequestReceived(friendPk, CString::toString(cMessage, cMessageSize));
}

Expand Down Expand Up @@ -556,67 +557,81 @@ void Core::onReadReceiptCallback(Tox*, uint32_t friendId, uint32_t receipt, void
emit static_cast<Core*>(core)->receiptRecieved(friendId, receipt);
}

void Core::acceptFriendRequest(const QString& userId)
void Core::acceptFriendRequest(const ToxPk& friendPk)
{
uint32_t friendId = tox_friend_add_norequest(tox, ToxId(userId).getPublicKeyBytes(), nullptr);
// TODO: error handling
uint32_t friendId = tox_friend_add_norequest(tox, friendPk.getBytes(), nullptr);
if (friendId == std::numeric_limits<uint32_t>::max())
{
emit failedToAddFriend(userId);
emit failedToAddFriend(friendPk);
}
else
{
profile.saveToxSave();
emit friendAdded(friendId, userId);
emit friendAdded(friendId, friendPk);
emit friendshipChanged(friendId);
}
}

void Core::requestFriendship(const QString& friendAddress, const QString& message)
void Core::requestFriendship(const ToxId& friendAddress, const QString& message)
{
ToxId friendToxId(friendAddress);
const QString userId = friendAddress.mid(0, TOX_PUBLIC_KEY_SIZE * 2);
ToxPk friendPk = friendAddress.getPublicKey();

if (!friendToxId.isValid())
if (!friendAddress.isValid())
{
emit failedToAddFriend(userId,
emit failedToAddFriend(friendPk,
tr("Invalid Tox ID"));
}
else if (message.isEmpty())
{
emit failedToAddFriend(userId, tr("You need to write a message with your request"));
emit failedToAddFriend(friendPk,
tr("You need to write a message with your request"));
}
else if (message.size() > TOX_MAX_FRIEND_REQUEST_LENGTH)
{
emit failedToAddFriend(userId, tr("Your message is too long!"));
emit failedToAddFriend(friendPk,
tr("Your message is too long!"));
}
else if (hasFriendWithAddress(userId))
else if (hasFriendWithPublicKey(friendPk))
{
emit failedToAddFriend(userId, tr("Friend is already added"));
emit failedToAddFriend(friendPk,
tr("Friend is already added"));
}
else
{
CString cMessage(message);

uint32_t friendId = tox_friend_add(tox, ToxId(friendAddress).getBytes(),
uint32_t friendId = tox_friend_add(tox, friendAddress.getBytes(),
cMessage.data(), cMessage.size(), nullptr);
if (friendId == std::numeric_limits<uint32_t>::max())
{
qDebug() << "Failed to request friendship";
emit failedToAddFriend(userId);
emit failedToAddFriend(friendPk);
}
else
{
qDebug() << "Requested friendship of "<<friendId;
qDebug() << "Requested friendship of " << friendId;
// Update our friendAddresses
Settings::getInstance().updateFriendAddress(userId);
Settings::getInstance().updateFriendAddress(friendAddress.toString());

// TODO: start: this really shouldn't be in Core
QString inviteStr = tr("/me offers friendship.");
if (message.length())
inviteStr = tr("/me offers friendship, \"%1\"").arg(message);

Profile* profile = Nexus::getProfile();
if (profile->isHistoryEnabled())
profile->getHistory()->addNewMessage(userId, inviteStr, getSelfId().getPublicKeyString(), QDateTime::currentDateTime(), true, QString());
emit friendAdded(friendId, userId);
{
profile->getHistory()->addNewMessage(friendAddress.toString(),
inviteStr,
getSelfId().getPublicKey().toString(),
QDateTime::currentDateTime(),
true,
QString());
}
// TODO: end

emit friendAdded(friendId, friendAddress.getPublicKey());
emit friendshipChanged(friendId);
}
}
Expand Down Expand Up @@ -847,7 +862,7 @@ void Core::setAvatar(const QByteArray& data)
{
QPixmap pic;
pic.loadFromData(data);
profile.saveAvatar(data, getSelfId().getPublicKeyString());
profile.saveAvatar(data, getSelfId().getPublicKey().toString());
emit selfAvatarChanged(pic);
}
else
Expand Down Expand Up @@ -997,7 +1012,7 @@ void Core::loadFriends()
{
if (tox_friend_get_public_key(tox, ids[i], friendPk, nullptr))
{
emit friendAdded(ids[i], ToxId(friendPk, TOX_PUBLIC_KEY_SIZE).getPublicKeyString());
emit friendAdded(ids[i], ToxPk(friendPk));

const size_t nameSize = tox_friend_get_name_size(tox, ids[i], nullptr);
if (nameSize && nameSize != SIZE_MAX)
Expand Down Expand Up @@ -1108,18 +1123,18 @@ QString Core::getGroupPeerName(int groupId, int peerId) const
/**
* @brief Get the public key of a peer of a group
*/
ToxId Core::getGroupPeerToxId(int groupId, int peerId) const
ToxPk Core::getGroupPeerPk(int groupId, int peerId) const
{
uint8_t friendPk[TOX_PUBLIC_KEY_SIZE] = {0x00};
TOX_ERR_CONFERENCE_PEER_QUERY error;
bool success = tox_conference_peer_get_public_key(tox, groupId, peerId, friendPk, &error);
if (!parsePeerQueryError(error) || !success)
{
qWarning() << "getGroupPeerToxId: Unknown error";
return ToxId();
return ToxPk();
}

return ToxId(friendPk, TOX_PUBLIC_KEY_SIZE);
return ToxPk(friendPk);
}

/**
Expand Down Expand Up @@ -1324,83 +1339,36 @@ bool Core::isFriendOnline(uint32_t friendId) const
return connetion != TOX_CONNECTION_NONE;
}

/**
* @brief Checks if we have a friend by address
*/
bool Core::hasFriendWithAddress(const QString &addr) const
{
// Valid length check
if (addr.length() != (TOX_ADDRESS_SIZE * 2))
{
return false;
}

QString pubkey = addr.left(TOX_PUBLIC_KEY_SIZE * 2);
return hasFriendWithPublicKey(pubkey);
}

/**
* @brief Checks if we have a friend by public key
*/
bool Core::hasFriendWithPublicKey(const QString &pubkey) const
bool Core::hasFriendWithPublicKey(const ToxPk &publicKey) const
{
// Valid length check
if (pubkey.length() != (TOX_PUBLIC_KEY_SIZE * 2))
return false;

bool found = false;
const size_t friendCount = tox_self_get_friend_list_size(tox);
if (friendCount > 0)
// Validity check
if (publicKey.isEmpty())
{
uint32_t *ids = new uint32_t[friendCount];
tox_self_get_friend_list(tox, ids);
for (int32_t i = 0; i < static_cast<int32_t>(friendCount); ++i)
{
// getFriendAddress may return either id (public key) or address
QString addrOrId = getFriendAddress(ids[i]);

// Set true if found
if (addrOrId.toUpper().startsWith(pubkey.toUpper()))
{
found = true;
break;
}
}

delete[] ids;
return false;
}

return found;
}

/**
* @brief Get the full address if known, or public key of a friend
*/
QString Core::getFriendAddress(uint32_t friendNumber) const
{
QString id = getFriendPublicKey(friendNumber);
QString addr = Settings::getInstance().getFriendAddress(id);
if (addr.size() > id.size())
return addr;
// TODO: error handling
uint32_t friendId = tox_friend_by_public_key(tox, publicKey.getBytes(), nullptr);

return id;
return friendId != std::numeric_limits<uint32_t>::max();
}

/**
* @brief Get the public key part of the ToxID only
*/
QString Core::getFriendPublicKey(uint32_t friendNumber) const
ToxPk Core::getFriendPublicKey(uint32_t friendNumber) const
{
uint8_t rawid[TOX_PUBLIC_KEY_SIZE];
if (!tox_friend_get_public_key(tox, friendNumber, rawid, nullptr))
{
qWarning() << "getFriendPublicKey: Getting public key failed";
return QString();
return ToxPk();
}
QByteArray data((char*)rawid, TOX_PUBLIC_KEY_SIZE);
QString id = data.toHex().toUpper();

return id;
return ToxPk(rawid);
}

/**
Expand Down Expand Up @@ -1450,7 +1418,7 @@ QList<CString> Core::splitMessage(const QString &message, int maxLen)
return splittedMsgs;
}

QString Core::getPeerName(const ToxId& id) const
QString Core::getPeerName(const ToxPk& id) const
{
QString name;
uint32_t friendId = tox_friend_by_public_key(tox, id.getBytes(), nullptr);
Expand Down Expand Up @@ -1485,13 +1453,16 @@ bool Core::isReady() const
return av && av->getToxAv() && tox && ready;
}


/**
* @brief Sets the NoSpam value to prevent friend request spam
* @param nospam an arbitrary which becomes part of the Tox ID
*/
void Core::setNospam(uint32_t nospam)
{
uint8_t *nspm = reinterpret_cast<uint8_t*>(&nospam);
std::reverse(nspm, nspm + 4);
tox_self_set_nospam(tox, nospam);

emit idSet(getSelfId().toString());
emit idSet(getSelfId());
}

/**
Expand Down
22 changes: 10 additions & 12 deletions src/core/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,20 +58,18 @@ class Core : public QObject

static QByteArray getSaltFromFile(QString filename);

QString getPeerName(const ToxId& id) const;
QString getPeerName(const ToxPk& id) const;

QVector<uint32_t> getFriendList() const;
uint32_t getGroupNumberPeers(int groupId) const;
QString getGroupPeerName(int groupId, int peerId) const;
ToxId getGroupPeerToxId(int groupId, int peerId) const;
ToxPk getGroupPeerPk(int groupId, int peerId) const;
QList<QString> getGroupPeerNames(int groupId) const;
QString getFriendAddress(uint32_t friendNumber) const;
QString getFriendPublicKey(uint32_t friendNumber) const;
ToxPk getFriendPublicKey(uint32_t friendNumber) const;
QString getFriendUsername(uint32_t friendNumber) const;

bool isFriendOnline(uint32_t friendId) const;
bool hasFriendWithAddress(const QString &addr) const;
bool hasFriendWithPublicKey(const QString &pubkey) const;
bool hasFriendWithPublicKey(const ToxPk &publicKey) const;
uint32_t joinGroupchat(int32_t friendId, uint8_t type, const uint8_t* pubkey,uint16_t length) const;
void quitGroupChat(int groupId) const;

Expand Down Expand Up @@ -99,8 +97,8 @@ public slots:

QByteArray getToxSaveData();

void acceptFriendRequest(const QString& userId);
void requestFriendship(const QString& friendAddress, const QString& message);
void acceptFriendRequest(const ToxPk &friendPk);
void requestFriendship(const ToxId &friendAddress, const QString& message);
void groupInviteFriend(uint32_t friendId, int groupId);
int createGroup(uint8_t type = TOX_CONFERENCE_TYPE_AV);

Expand Down Expand Up @@ -133,10 +131,10 @@ public slots:
void connected();
void disconnected();

void friendRequestReceived(const QString& userId, const QString& message);
void friendRequestReceived(const ToxPk& friendPk, const QString& message);
void friendMessageReceived(uint32_t friendId, const QString& message, bool isAction);

void friendAdded(uint32_t friendId, const QString& userId);
void friendAdded(uint32_t friendId, const ToxPk& friendPk);
void friendshipChanged(uint32_t friendId);

void friendStatusChanged(uint32_t friendId, Status status);
Expand All @@ -160,7 +158,7 @@ public slots:
void usernameSet(const QString& username);
void statusMessageSet(const QString& message);
void statusSet(Status status);
void idSet(const QString& id);
void idSet(const ToxId& id);
void selfAvatarChanged(const QPixmap& pic);

void messageSentResult(uint32_t friendId, const QString& message, int messageId);
Expand All @@ -169,7 +167,7 @@ public slots:

void receiptRecieved(int friedId, int receipt);

void failedToAddFriend(const QString& userId, const QString& errorInfo = QString());
void failedToAddFriend(const ToxPk& friendPk, const QString& errorInfo = QString());
void failedToRemoveFriend(uint32_t friendId);
void failedToSetUsername(const QString& username);
void failedToSetStatusMessage(const QString& message);
Expand Down
7 changes: 4 additions & 3 deletions src/core/corefile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ unsigned CoreFile::corefileIterationInterval()
/*
Sleep at most 1000ms if we have no FT, 10 for user FTs
There is no real difference between 10ms sleep and 50ms sleep when it
comes to CPU usage – just keep the CPU usage low when there are no file
comes to CPU usage – just keep the CPU usage low when there are no file
transfers, and speed things up when there is an ongoing file transfer.
*/
constexpr unsigned fileInterval = 10,
Expand Down Expand Up @@ -311,7 +311,8 @@ void CoreFile::onFileReceiveCallback(Tox*, uint32_t friendId, uint32_t fileId,

if (kind == TOX_FILE_KIND_AVATAR)
{
QString friendAddr = core->getFriendPublicKey(friendId);
// TODO: port this to ToxPk
QString friendAddr = core->getFriendPublicKey(friendId).toString();
if (!filesize)
{
qDebug() << QString("Received empty avatar request %1:%2").arg(friendId).arg(fileId);
Expand Down Expand Up @@ -482,7 +483,7 @@ void CoreFile::onFileRecvChunkCallback(Tox *tox, uint32_t friendId,
if (!pic.isNull())
{
qDebug() << "Got"<<file->avatarData.size()<<"bytes of avatar data from" <<friendId;
core->profile.saveAvatar(file->avatarData, core->getFriendPublicKey(friendId));
core->profile.saveAvatar(file->avatarData, core->getFriendPublicKey(friendId).toString());
emit core->friendAvatarChanged(friendId, pic);
}
}
Expand Down
Loading

0 comments on commit e07d8d3

Please sign in to comment.