aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2018-05-03 13:16:04 +0200
committerdec05eba <dec05eba@protonmail.com>2018-05-03 13:16:10 +0200
commitc2841e19c227f9c0f7cef3023e012c5c80f6def4 (patch)
treeb29328141537e54d5d53d1636c7d6c1b20ec72f9
parent9bb631f1e1861c63f38125fffb91081c98a1cfcc (diff)
Support different types of channel data. Add nickname change command
m---------depends/odhtdb0
-rw-r--r--include/Channel.hpp10
-rw-r--r--include/User.hpp1
-rw-r--r--src/Channel.cpp27
-rw-r--r--src/User.cpp3
-rw-r--r--src/main.cpp121
6 files changed, 137 insertions, 25 deletions
diff --git a/depends/odhtdb b/depends/odhtdb
-Subproject c01f92c1b7f3c257d71961a8dcdf37318aa3f52
+Subproject f3b18e0309ca2dbb997908583f1d44d13d9fc83
diff --git a/include/Channel.hpp b/include/Channel.hpp
index 535cce5..17128fd 100644
--- a/include/Channel.hpp
+++ b/include/Channel.hpp
@@ -4,6 +4,7 @@
#include "Chatbar.hpp"
#include "User.hpp"
#include "Channel.hpp"
+#include "types.hpp"
#include <vector>
#include <odhtdb/DatabaseNode.hpp>
#include <odhtdb/Signature.hpp>
@@ -16,6 +17,12 @@ namespace odhtdb
namespace dchat
{
+ enum class ChannelDataType : u8
+ {
+ MESSAGE,
+ NICKNAME_CHANGE
+ };
+
class Channel
{
public:
@@ -30,7 +37,7 @@ namespace dchat
const std::string& getName() const;
const std::vector<User*> getUsers() const;
- User* getUserByPublicKey(const odhtdb::Signature::PublicKey &publicKey);
+ OnlineUser* getUserByPublicKey(const odhtdb::Signature::PublicKey &publicKey);
const odhtdb::DatabaseNode& getNodeInfo() const;
// If timestamp is 0, then timestamp is not used
@@ -39,6 +46,7 @@ namespace dchat
void addUserLocally(User *user);
bool addUser(const odhtdb::Signature::PublicKey &userId, const std::string &groupId);
void replaceLocalUser(User *newLocalUser);
+ void changeNick(const std::string &newNick);
void processEvent(const sf::Event &event);
void draw(sf::RenderWindow &window, Cache &cache);
diff --git a/include/User.hpp b/include/User.hpp
index e9e334a..821be6f 100644
--- a/include/User.hpp
+++ b/include/User.hpp
@@ -32,6 +32,7 @@ namespace dchat
OnlineUser(const odhtdb::User *databaseUser);
virtual const std::string& getName() const override;
+ std::string name;
const odhtdb::User *databaseUser;
};
diff --git a/src/Channel.cpp b/src/Channel.cpp
index d89a23f..a76a2c6 100644
--- a/src/Channel.cpp
+++ b/src/Channel.cpp
@@ -3,6 +3,7 @@
#include <odhtdb/Database.hpp>
#include <odhtdb/bin2hex.hpp>
#include <cstring>
+#include <sibs/SafeSerializer.hpp>
using namespace std;
@@ -93,7 +94,7 @@ namespace dchat
return users;
}
- User* Channel::getUserByPublicKey(const odhtdb::Signature::PublicKey &publicKey)
+ OnlineUser* Channel::getUserByPublicKey(const odhtdb::Signature::PublicKey &publicKey)
{
auto userIt = publicKeyOnlineUsersMap.find(publicKey);
if(userIt != publicKeyOnlineUsersMap.end())
@@ -118,7 +119,12 @@ namespace dchat
{
auto localOnlineUser = static_cast<OnlineUser*>(localUser);
assert(localOnlineUser->databaseUser->getType() == odhtdb::User::Type::LOCAL);
- database->addData(databaseNodeInfo, static_cast<const odhtdb::LocalUser*>(localOnlineUser->databaseUser), odhtdb::DataView((void*)msg.data(), msg.size()));
+
+ sibs::SafeSerializer serializer;
+ serializer.add(ChannelDataType::MESSAGE);
+ serializer.add((const u8*)msg.data(), msg.size());
+
+ database->addData(databaseNodeInfo, static_cast<const odhtdb::LocalUser*>(localOnlineUser->databaseUser), odhtdb::DataView(serializer.getBuffer().data(), serializer.getBuffer().size()));
database->commit();
}
else
@@ -178,6 +184,23 @@ namespace dchat
addUserLocally(newLocalUser);
}
+ void Channel::changeNick(const std::string &newNick)
+ {
+ if(database && localUser->type == User::Type::ONLINE)
+ {
+ auto localOnlineUser = static_cast<OnlineUser*>(localUser);
+ assert(localOnlineUser->databaseUser->getType() == odhtdb::User::Type::LOCAL);
+
+ sibs::SafeSerializer serializer;
+ serializer.add(ChannelDataType::NICKNAME_CHANGE);
+ serializer.add((u8)newNick.size());
+ serializer.add((const u8*)newNick.data(), newNick.size());
+
+ database->addData(databaseNodeInfo, static_cast<const odhtdb::LocalUser*>(localOnlineUser->databaseUser), odhtdb::DataView(serializer.getBuffer().data(), serializer.getBuffer().size()));
+ database->commit();
+ }
+ }
+
void Channel::processEvent(const sf::Event &event)
{
chatbar.processEvent(event, this);
diff --git a/src/User.cpp b/src/User.cpp
index 2908fd4..16b3648 100644
--- a/src/User.cpp
+++ b/src/User.cpp
@@ -14,6 +14,7 @@ namespace dchat
OnlineUser::OnlineUser(const odhtdb::User *_databaseUser) :
User(Type::ONLINE),
+ name("randomUser69"),
databaseUser(_databaseUser)
{
assert(databaseUser);
@@ -21,7 +22,7 @@ namespace dchat
const std::string& OnlineUser::getName() const
{
- return databaseUser->getName();
+ return name;
}
OfflineUser::OfflineUser(const std::string &_name) :
diff --git a/src/main.cpp b/src/main.cpp
index 59b89a5..3804f6f 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -56,17 +56,67 @@ odhtdb::DatabaseNode createDatabaseNodeFromJoinKey(const string &joinKey)
return odhtdb::DatabaseNode(encryptionKey, nodeHash);
}
-void channelAddStoredMessage(Channel *channel, odhtdb::DatabaseStorageObject *nodeStorageObject)
+void channelChangeUserNickname(Channel *channel, const StringView data, const odhtdb::Signature::PublicKey &userPublicKey)
{
- User *user = channel->getUserByPublicKey(nodeStorageObject->creatorPublicKey);
+ auto user = channel->getUserByPublicKey(userPublicKey);
if(!user)
{
- fprintf(stderr, "Missing user? %s\n", nodeStorageObject->creatorPublicKey.toString().c_str());
+ fprintf(stderr, "Nickname change: user with public key %s not found in channel %s\n", userPublicKey.toString().c_str(), channel->getName().c_str());
return;
}
- string msg((const char*)nodeStorageObject->decryptedObject.data.data, nodeStorageObject->decryptedObject.data.size);
- channel->addLocalMessage(msg, user, ntp::NtpTimestamp::fromCombined(nodeStorageObject->createdTimestamp).seconds);
+ sibs::SafeDeserializer deserializer((const u8*)data.data, data.size);
+ u8 nameLength = deserializer.extract<u8>();
+ if(nameLength > 0)
+ {
+ user->name.resize(nameLength);
+ deserializer.extract((u8*)&user->name[0], nameLength);
+ }
+ // We dont care if there is more data to read (malicious packet), we already got all the data we need
+}
+
+void channelAddStoredMessage(Channel *channel, const odhtdb::Signature::PublicKey &creatorPublicKey, const StringView decryptedObject, u64 timestamp)
+{
+ User *user = channel->getUserByPublicKey(creatorPublicKey);
+ if(!user)
+ {
+ fprintf(stderr, "Missing user? %s\n", creatorPublicKey.toString().c_str());
+ return;
+ }
+
+ if(decryptedObject.size > 1)
+ {
+ auto channelDataType = (ChannelDataType)static_cast<const char*>(decryptedObject.data)[0];
+ StringView decryptedData((const char*)decryptedObject.data + 1, decryptedObject.size - 1);
+ switch(channelDataType)
+ {
+ case ChannelDataType::MESSAGE:
+ {
+ string msg(decryptedData.data, decryptedData.size);
+ channel->addLocalMessage(msg, user, ntp::NtpTimestamp::fromCombined(timestamp).seconds);
+ break;
+ }
+ case ChannelDataType::NICKNAME_CHANGE:
+ {
+ try
+ {
+ channelChangeUserNickname(channel, decryptedData, creatorPublicKey);
+ }
+ catch(sibs::DeserializeException &e)
+ {
+ fprintf(stderr, "Failed to deserialize nick change\n");
+ }
+ break;
+ }
+ default:
+ fprintf(stderr, "Got unexpected channel data type: %u\n", channelDataType);
+ break;
+ }
+ }
+ else
+ {
+ fprintf(stderr, "ADD_DATA packet too small, ignoring...\n");
+ }
}
void channelAddStoredMessages(Channel *channel, const odhtdb::DatabaseStorageObjectList *nodeStorage)
@@ -76,7 +126,8 @@ void channelAddStoredMessages(Channel *channel, const odhtdb::DatabaseStorageObj
{
if(nodeStorageAddedObject->decryptedObject.operation == odhtdb::DatabaseOperation::ADD_DATA)
{
- channelAddStoredMessage(channel, nodeStorageAddedObject);
+ StringView decryptedObject((const char*)nodeStorageAddedObject->decryptedObject.data.data, nodeStorageAddedObject->decryptedObject.data.size);
+ channelAddStoredMessage(channel, nodeStorageAddedObject->creatorPublicKey, decryptedObject, nodeStorageAddedObject->createdTimestamp);
}
}
}
@@ -149,15 +200,7 @@ int main(int argc, char **argv)
{
if(*request.nodeHash == *channel->getNodeInfo().getRequestHash())
{
- User *user = channel->getUserByPublicKey(request.creatorUser->getPublicKey());
- if(!user)
- {
- fprintf(stderr, "Missing user? %s\n", request.creatorUser->getPublicKey().toString().c_str());
- return;
- }
-
- string msg((const char*)request.decryptedData.data, request.decryptedData.size);
- channel->addLocalMessage(msg, user, ntp::NtpTimestamp::fromCombined(request.timestamp).seconds);
+ channelAddStoredMessage(channel, request.creatorUser->getPublicKey(), StringView((const char*)request.decryptedData.data, request.decryptedData.size), request.timestamp);
return;
}
}
@@ -427,9 +470,9 @@ int main(int argc, char **argv)
{
if(args.size() != 2)
{
- string errMsg = "Expected 2 arguments for command addbind, got %u argument(";
+ string errMsg = "Expected 2 arguments for command addbind, got ";
errMsg += to_string(args.size());
- errMsg += ")";
+ errMsg += " argument(s)";
Channel::getCurrent()->addLocalMessage(errMsg, Channel::getCurrent()->getSystemUser());
return;
}
@@ -456,9 +499,9 @@ int main(int argc, char **argv)
{
if(args.size() != 1)
{
- string errMsg = "Expected 1 argument for command removebind, got %u argument(";
+ string errMsg = "Expected 1 argument for command removebind, got ";
errMsg += to_string(args.size());
- errMsg += ")";
+ errMsg += " argument(s)";
Channel::getCurrent()->addLocalMessage(errMsg, Channel::getCurrent()->getSystemUser());
return;
}
@@ -485,9 +528,9 @@ int main(int argc, char **argv)
{
if(args.size() != 0)
{
- string errMsg = "Expected 0 arguments for command removebind, got %u argument(";
+ string errMsg = "Expected 0 arguments for command removebind, got ";
errMsg += to_string(args.size());
- errMsg += ")";
+ errMsg += " argument(s)";
Channel::getCurrent()->addLocalMessage(errMsg, Channel::getCurrent()->getSystemUser());
return;
}
@@ -521,6 +564,42 @@ int main(int argc, char **argv)
Channel::getCurrent()->addLocalMessage(response, Channel::getCurrent()->getSystemUser());
});
+ // Change nick of current user in current channel
+ Command::add("nick", [&currentUserKeyPair, &offlineChannel](const vector<string> &args)
+ {
+ if(args.size() != 1)
+ {
+ string errMsg = "Expected 1 argument for command nick, got ";
+ errMsg += to_string(args.size());
+ errMsg += " argument(s)";
+ Channel::getCurrent()->addLocalMessage(errMsg, Channel::getCurrent()->getSystemUser());
+ return;
+ }
+
+ if(!currentUserKeyPair)
+ {
+ Channel::getCurrent()->addLocalMessage("You need to be logged in to change your nickname", Channel::getCurrent()->getSystemUser());
+ return;
+ }
+
+ if(Channel::getCurrent() == &offlineChannel)
+ {
+ Channel::getCurrent()->addLocalMessage("You need to be in a channel to change your nickname", Channel::getCurrent()->getSystemUser());
+ return;
+ }
+
+ if(args[0].size() == 0 || args[0].size() > 255)
+ {
+ Channel::getCurrent()->addLocalMessage("Invalid nickname. Nickname has to be between 1 and 255 characters", Channel::getCurrent()->getSystemUser());
+ return;
+ }
+
+ Channel::getCurrent()->changeNick(args[0]);
+ string msg = "Your nickname was changed to ";
+ msg += args[0];
+ Channel::getCurrent()->addLocalMessage(msg, Channel::getCurrent()->getSystemUser());
+ });
+
// Get channel join key
Command::add("joinkey", [&currentUserKeyPair, &currentUserName, &offlineChannel](const vector<string> &args)
{