aboutsummaryrefslogtreecommitdiff
path: root/src/main.cpp
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2018-05-01 13:27:52 +0200
committerdec05eba <dec05eba@protonmail.com>2018-05-01 13:28:29 +0200
commit431c1dcded16649c10331b9dc4e57f20067cea0b (patch)
tree3f5327ca81f76ad7c77f36a930d56401a4ec458e /src/main.cpp
parent9e576f9fbcbcc4603689b0b1215cf3d526bd9616 (diff)
Add 'add user', 'join channel'. Improve scrolling. Added locks
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp251
1 files changed, 202 insertions, 49 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 364b2a9..7245b6e 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -47,6 +47,19 @@ odhtdb::DatabaseNode createDatabaseNodeFromJoinKey(const string &joinKey)
return result;
}
+void channelAddStoredMessage(Channel *channel, odhtdb::DatabaseStorageObject *nodeStorageObject)
+{
+ User *user = channel->getUserByPublicKey(nodeStorageObject->creatorPublicKey);
+ if(!user)
+ {
+ fprintf(stderr, "Missing user? %s\n", nodeStorageObject->creatorPublicKey.toString().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);
+}
+
void channelAddStoredMessages(Channel *channel, const odhtdb::DatabaseStorageObjectList *nodeStorage)
{
printf("Load %u messages in channel %s\n", nodeStorage->objects.size(), channel->getName().c_str());
@@ -54,14 +67,7 @@ void channelAddStoredMessages(Channel *channel, const odhtdb::DatabaseStorageObj
{
if(nodeStorageAddedObject->decryptedObject.operation == odhtdb::DatabaseOperation::ADD_DATA)
{
- User *user = channel->getUserByPublicKey(nodeStorageAddedObject->creatorPublicKey);
- if(!user)
- {
- fprintf(stderr, "Missing user? %s\n", nodeStorageAddedObject->creatorPublicKey.toString().c_str());
- continue;
- }
- string msg((const char*)nodeStorageAddedObject->decryptedObject.data.data, nodeStorageAddedObject->decryptedObject.data.size);
- channel->addLocalMessage(msg, user, ntp::NtpTimestamp::fromCombined(nodeStorageAddedObject->createdTimestamp).seconds);
+ channelAddStoredMessage(channel, nodeStorageAddedObject);
}
}
}
@@ -75,27 +81,16 @@ int main(int argc, char **argv)
boost::filesystem::current_path(parentPath); // Ensures loading of resources works no matter which path we run this executable from
*/
+ const int FRAMERATE_FOCUSED = 200;
+ const int FRAMERATE_NOT_FOCUSED = 30;
+
XInitThreads();
sf::RenderWindow window(sf::VideoMode(1920, 1080), "dchat");
window.setVerticalSyncEnabled(false);
- window.setFramerateLimit(60);
+ window.setFramerateLimit(FRAMERATE_FOCUSED);
odhtdb::Database database("bootstrap.ring.cx", 4222, Cache::getDchatDir());
- database.setOnCreateNodeCallback([](const odhtdb::DatabaseCreateNodeRequest &request)
- {
-
- });
-
- database.setOnAddNodeCallback([](const odhtdb::DatabaseAddNodeRequest &request)
- {
-
- });
-
- database.setOnAddUserCallback([](const odhtdb::DatabaseAddUserRequest &request)
- {
-
- });
//Video video(500, 500, "https://www.youtube.com/watch?v=bs0-EX9mJmg");
Cache cache;
@@ -108,10 +103,89 @@ int main(int argc, char **argv)
odhtdb::Signature::KeyPair *currentUserKeyPair = nullptr;
vector<odhtdb::NodeLocalUser> localNodeUsers;
+ vector<odhtdb::DatabaseNode> waitingToJoinChannels;
string currentUserName;
string currentUserPassword;
+ recursive_mutex channelMessageMutex;
+
+ database.setOnCreateNodeCallback([&waitingToJoinChannels, &database, &channels, &channelMessageMutex](const odhtdb::DatabaseCreateNodeRequest &request)
+ {
+ lock_guard<recursive_mutex> lock(channelMessageMutex);
+ for(vector<odhtdb::DatabaseNode>::iterator it = waitingToJoinChannels.begin(); it != waitingToJoinChannels.end(); ++it)
+ {
+ if(*request.nodeHash == *it->getRequestHash())
+ {
+ User *localUser = new OfflineUser("You");
+ Channel *channel = new Channel(request.name, *it, localUser, &database);
+ ChannelSidePanel::addChannel(channel);
+ channels.push_back(channel);
+ Channel::setCurrent(channel);
+
+ User *nodeCreatorUser = new OnlineUser(request.creatorUser);
+ channel->addUserLocally(nodeCreatorUser);
+
+ waitingToJoinChannels.erase(it);
+ return;
+ }
+ }
+ });
+
+ database.setOnAddNodeCallback([&channels, &channelMessageMutex](const odhtdb::DatabaseAddNodeRequest &request)
+ {
+ lock_guard<recursive_mutex> lock(channelMessageMutex);
+ for(Channel *channel : channels)
+ {
+ if(*request.nodeHash == *channel->getId())
+ {
+ 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);
+ return;
+ }
+ }
+ });
+
+ database.setOnAddUserCallback([&currentUserKeyPair, &channels, &channelMessageMutex](const odhtdb::DatabaseAddUserRequest &request)
+ {
+ lock_guard<recursive_mutex> lock(channelMessageMutex);
+ if(currentUserKeyPair && request.userToAdd->getPublicKey() == currentUserKeyPair->getPublicKey())
+ {
+ printf("You were added to channel %s by %s\n", request.nodeHash->toString().c_str(), request.creatorUser->getName().c_str());
+ return;
+ }
+
+ for(Channel *channel : channels)
+ {
+ if(*request.nodeHash == *channel->getId())
+ {
+ User *userToAdd = channel->getUserByPublicKey(request.userToAdd->getPublicKey());
+ if(userToAdd && currentUserKeyPair && request.userToAdd->getPublicKey() == currentUserKeyPair->getPublicKey() && channel->getLocalUser()->type != User::Type::ONLINE)
+ {
+ channel->replaceLocalUser(new OnlineUser(request.userToAdd));
+ return;
+ }
+
+ if(userToAdd)
+ {
+ fprintf(stderr, "User %s already exists in channel\n", request.userToAdd->getPublicKey().toString().c_str());
+ return;
+ }
+
+ User *newRemoteUser = new OnlineUser(request.userToAdd);
+ channel->addUserLocally(newRemoteUser);
+ return;
+ }
+ }
+ });
- Command::add("login", [&currentUserKeyPair, &currentUserName, &currentUserPassword, &localNodeUsers, &database, &channels](const vector<string> &args)
+ // Login to account
+ Command::add("login", [&currentUserKeyPair, &currentUserName, &currentUserPassword, &localNodeUsers, &database, &channels, &channelMessageMutex](const vector<string> &args)
{
if(args.size() != 2)
{
@@ -131,6 +205,7 @@ int main(int argc, char **argv)
}
channels.clear();
+ lock_guard<recursive_mutex> lock(channelMessageMutex);
for(auto localNodeUser : localNodeUsers)
{
auto nodeStorage = database.getStorage().getStorage(localNodeUser.nodeHash);
@@ -149,7 +224,7 @@ int main(int argc, char **argv)
if(nodeUserIt.second != localNodeUser.localUser)
{
User *newRemoteUser = new OnlineUser(nodeUserIt.second);
- channel->addUser(newRemoteUser);
+ channel->addUserLocally(newRemoteUser);
}
}
@@ -173,8 +248,10 @@ int main(int argc, char **argv)
}
});
- Command::add("register", [&currentUserKeyPair, &currentUserName, &currentUserPassword, &localNodeUsers, &database](const vector<string> &args)
+ // Register account
+ Command::add("register", [&currentUserKeyPair, &currentUserName, &currentUserPassword, &localNodeUsers, &database, &channelMessageMutex](const vector<string> &args)
{
+ lock_guard<recursive_mutex> lock(channelMessageMutex);
if(args.size() != 2)
{
fprintf(stderr, "Expected 2 arguments for command register (username and password), got %u argument(s)\n", args.size());
@@ -206,8 +283,10 @@ int main(int argc, char **argv)
currentUserPassword = args[1];
});
- Command::add("cc", [&currentUserKeyPair, &currentUserName, &database, &channels](const vector<string> &args)
+ // Create channel
+ Command::add("cc", [&currentUserKeyPair, &currentUserName, &database, &channels, &channelMessageMutex](const vector<string> &args)
{
+ lock_guard<recursive_mutex> lock(channelMessageMutex);
if(args.size() != 1)
{
fprintf(stderr, "Expected 1 argument for command cc (channel name), got %u argument(s)\n", args.size());
@@ -232,8 +311,53 @@ int main(int argc, char **argv)
Channel::setCurrent(channel);
});
- Command::add("jc", [&currentUserKeyPair, &database, &localNodeUsers](const vector<string> &args)
+ // Add user
+ Command::add("au", [&offlineChannel, &channelMessageMutex](const vector<string> &args)
{
+ lock_guard<recursive_mutex> lock(channelMessageMutex);
+ if(args.size() != 2)
+ {
+ fprintf(stderr, "Expected 2 arguments for command au (user id, group id), got %u argument(s)\n", args.size());
+ return;
+ }
+
+ if(args[0].size() != odhtdb::PUBLIC_KEY_NUM_BYTES * 2)
+ {
+ fprintf(stderr, "User id is wrong size. Expected to be %u characters, was %u character(s)\n", odhtdb::PUBLIC_KEY_NUM_BYTES * 2, args[0].size());
+ return;
+ }
+
+ if(args[1].size() != odhtdb::GROUP_ID_LENGTH * 2)
+ {
+ fprintf(stderr, "Group id is wrong size. Expected to be %u characters, was %u character(s)\n", odhtdb::GROUP_ID_LENGTH * 2, args[1].size());
+ return;
+ }
+
+ Channel *currentChannel = Channel::getCurrent();
+ if(currentChannel == &offlineChannel)
+ {
+ Channel::getCurrent()->addLocalMessage("You need to be in a channel to add user to the channel", Channel::getCurrent()->getSystemUser());
+ return;
+ }
+
+ auto userIdRaw = odhtdb::hex2bin(args[0].c_str(), args[0].size());
+ odhtdb::Signature::PublicKey userPublicKey(userIdRaw.data(), userIdRaw.size());
+
+ auto groupIdRaw = odhtdb::hex2bin(args[1].c_str(), args[1].size());
+ bool userAddResult = currentChannel->addUser(userPublicKey, groupIdRaw);
+ if(userAddResult)
+ {
+ printf("Added user to your channel!\n");
+ }
+ else
+ {
+ fprintf(stderr, "Failed to add user to your channel!\n");
+ }
+ });
+
+ Command::add("jc", [&currentUserKeyPair, &database, &localNodeUsers, &channelMessageMutex](const vector<string> &args)
+ {
+ lock_guard<recursive_mutex> lock(channelMessageMutex);
if(args.size() != 1)
{
fprintf(stderr, "Expected 1 argument for command jc (channel join key), got %u argument(s)\n", args.size());
@@ -261,28 +385,15 @@ int main(int argc, char **argv)
return;
}
}
-#if 0
- User *newLocalUser = new OnlineUser(localNodeUser.localUser);
- odhtdb::DatabaseNode databaseNode(nodeDecryptionKeyResult.second, make_shared<odhtdb::Hash>(localNodeUser.nodeHash));
- Channel *channel = new Channel(nodeStorage->nodeName, databaseNode, newLocalUser, &database);
-
- auto nodeUserMapByPublicKey = database.getStorage().getNodeUsers(localNodeUser.nodeHash);
- for(auto nodeUserIt : *nodeUserMapByPublicKey)
- {
- if(nodeUserIt.second != localNodeUser.localUser)
- {
- User *newRemoteUser = new OnlineUser(nodeUserIt.second);
- channel->addUser(newRemoteUser);
- }
- }
- ChannelSidePanel::addChannel(channel);
- channels.push_back(channel);
- Channel::setCurrent(channel);
- channelAddStoredMessages(channel, nodeStorage);
-#endif
+ database.seed(databaseNode);
+ // TODO: Add the channel to join to a pending join list in a file and remove from it when we have joined the channel.
+ // The reason for doing that is so if we crash or lose internet connection before we have got `create node` request from remote peers,
+ // then we need to start seeding again when we login. Once we have `create node` request, then it's added to local cache and when you login,
+ // it will be used to seed the channel.
});
+ // Scale UI
Command::add("scale", [](const vector<string> &args)
{
if(args.size() != 1)
@@ -296,9 +407,31 @@ int main(int argc, char **argv)
printf("UI scaling set to %f\n", scaling);
});
+ // Get username and id (public key)
+ Command::add("whoami", [&currentUserKeyPair, &currentUserName](const vector<string> &args)
+ {
+ if(!currentUserKeyPair)
+ {
+ Channel::getCurrent()->addLocalMessage("You are not logged in", Channel::getCurrent()->getSystemUser());
+ return;
+ }
+
+ string response = "Username: ";
+ response += currentUserName;
+ response += ", id: ";
+ response += currentUserKeyPair->getPublicKey().toString();
+ printf("%s\n", response.c_str());
+ Channel::getCurrent()->addLocalMessage(response, Channel::getCurrent()->getSystemUser());
+ });
+
sf::Event event;
while (window.isOpen())
{
+ channelMessageMutex.lock();
+ Channel *currentChannel = Channel::getCurrent();
+ bool waitingToJoin = currentChannel != &offlineChannel && currentChannel->getLocalUser()->type != User::Type::ONLINE;
+ channelMessageMutex.unlock();
+
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
@@ -316,14 +449,34 @@ int main(int argc, char **argv)
sf::View view(viewRect);
window.setView(view);
}
- Channel::getCurrent()->processEvent(event);
+ else if(event.type == sf::Event::GainedFocus)
+ window.setFramerateLimit(FRAMERATE_FOCUSED);
+ else if(event.type == sf::Event::LostFocus)
+ window.setFramerateLimit(FRAMERATE_NOT_FOCUSED);
+ currentChannel->processEvent(event);
}
window.clear(ColorScheme::getBackgroundColor());
ChannelSidePanel::draw(window);
- Channel::getCurrent()->draw(window, cache);
+ currentChannel->draw(window, cache);
UsersSidePanel::draw(window);
ChannelTopPanel::draw(window);
+
+ if(waitingToJoin)
+ {
+ auto windowSize = window.getSize();
+
+ sf::RectangleShape shadeRect(sf::Vector2f(windowSize.x, windowSize.y));
+ shadeRect.setFillColor(sf::Color(0, 0, 0, 200));
+ window.draw(shadeRect);
+
+ const sf::Font *FONT = ResourceCache::getFont("fonts/Roboto-Regular.ttf");
+ const float FONT_SIZE = 30 * Settings::getScaling();
+ sf::Text text("Wait until you are added to the channel", *FONT, FONT_SIZE);
+ text.setPosition(floor((float)windowSize.x * 0.5f - text.getLocalBounds().width * 0.5f), floor((float)windowSize.y * 0.5f - FONT->getLineSpacing(FONT_SIZE) * 0.5f));
+ window.draw(text);
+ }
+
//video.draw(window);
window.display();
}