aboutsummaryrefslogtreecommitdiff
path: root/src/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp1075
1 files changed, 232 insertions, 843 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 15c02ea..1e2e6d9 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,29 +1,22 @@
-#include "../include/Channel.hpp"
-#include "../include/ChannelSidePanel.hpp"
+#include "../include/RoomSidePanel.hpp"
#include "../include/UsersSidePanel.hpp"
-#include "../include/ChannelTopPanel.hpp"
-#include "../include/Cache.hpp"
+#include "../include/RoomTopPanel.hpp"
#include "../include/ResourceCache.hpp"
#include "../include/Video.hpp"
#include "../include/Command.hpp"
#include "../include/Settings.hpp"
#include "../include/ColorScheme.hpp"
#include "../include/GlobalContextMenu.hpp"
-#include "../include/StringUtils.hpp"
#include "../include/ImagePreview.hpp"
-#include "../include/Rpc.hpp"
-#include <msgpack.hpp>
+#include "../include/Room.hpp"
+#include "../include/RoomContainer.hpp"
#include <sstream>
#include <string>
#include <SFML/Graphics.hpp>
#include <cstring>
#include <boost/filesystem.hpp>
-#include <odhtdb/Database.hpp>
-#include <odhtdb/Signature.hpp>
-#include <odhtdb/bin2hex.hpp>
-#include <odhtdb/hex2bin.hpp>
-#include <ntp/NtpClient.hpp>
-#include <sibs/SafeSerializer.hpp>
+#include <dchat/Room.hpp>
+#include <dchat/Process.hpp>
#include <X11/Xlib.h>
#include <math.h>
@@ -33,25 +26,6 @@ using namespace dchat;
static bool focused = true;
static bool windowFocused = true;
-static void channelChangeUserNickname(Channel *channel, const StringView data, const odhtdb::Signature::PublicKey &userPublicKey)
-{
- auto user = channel->getUserByPublicKey(userPublicKey);
- if(!user)
- {
- fprintf(stderr, "Nickname change: user with public key %s not found in channel %s\n", userPublicKey.toString().c_str(), channel->getName().c_str());
- return;
- }
-
- 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
-}
-
static bool looksLikeUrl(const string &str)
{
if(str.find('.') == string::npos)
@@ -62,152 +36,13 @@ static bool looksLikeUrl(const string &str)
if(str.size() >= 8 && strncmp(str.c_str(), "https://", 8) == 0)
return true;
-
- return false;
-}
-
-static void channelChangeUserAvatar(Channel *channel, const StringView data, const odhtdb::Signature::PublicKey &userPublicKey)
-{
- auto user = channel->getUserByPublicKey(userPublicKey);
- if(!user)
- {
- fprintf(stderr, "Avatar change: user with public key %s not found in channel %s\n", userPublicKey.toString().c_str(), channel->getName().c_str());
- return;
- }
-
- sibs::SafeDeserializer deserializer((const u8*)data.data, data.size);
- u16 avatarLength = deserializer.extract<u16>();
- if(avatarLength >= 10 && avatarLength <= 512)
- {
- string avatarUrl;
- avatarUrl.resize(avatarLength);
- deserializer.extract((u8*)&avatarUrl[0], avatarLength);
- if(looksLikeUrl(avatarUrl))
- {
- user->avatarUrl = move(avatarUrl);
- }
- }
- // We dont care if there is more data to read (malicious packet), we already got all the data we need
-}
-static void channelChangeChannelName(Channel *channel, const StringView data, const odhtdb::Signature::PublicKey &userPublicKey)
-{
- auto user = channel->getUserByPublicKey(userPublicKey);
- if(!user)
- {
- fprintf(stderr, "Channel change name: user with public key %s not found in channel %s\n", userPublicKey.toString().c_str(), channel->getName().c_str());
- return;
- }
-
- int userPermissionLevel = channel->getUserLowestPermissionLevel(user);
- if(userPermissionLevel != odhtdb::PERMISSION_LEVEL_ADMIN)
- {
- fprintf(stderr, "Channel change name: attempted by user %s who is not an admin (permission level: %d)\n", user->getName().c_str(), userPermissionLevel);
- return;
- }
+ if(str.size() >= 4 && strncmp(str.c_str(), "www.", 4) == 0)
+ return true;
- sibs::SafeDeserializer deserializer((const u8*)data.data, data.size);
- u16 channelNameLength = deserializer.extract<u16>();
- if(channelNameLength > 0 && channelNameLength <= 32)
- {
- string channelName;
- channelName.resize(channelNameLength);
- deserializer.extract((u8*)&channelName[0], channelNameLength);
- channel->setNameLocally(channelName);
- }
- // We dont care if there is more data to read (malicious packet), we already got all the data we need
+ return false;
}
-static void channelAddStoredMessage(Channel *channel, const odhtdb::Hash &requestHash, const odhtdb::Signature::PublicKey &creatorPublicKey, const StringView decryptedObject, u64 timestamp, bool loadedFromCache)
-{
- 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::ADD_MESSAGE:
- {
- string msg(decryptedData.data, decryptedData.size);
- Message *latestMessage = channel->getLatestMessage();
- auto timestampSeconds = ntp::NtpTimestamp::fromCombined(timestamp).seconds;
- channel->addLocalMessage(msg, user, timestampSeconds, requestHash);
- if(!loadedFromCache && !windowFocused && channel->getLocalUser()->isOnlineUser() && (!latestMessage || (latestMessage && timestampSeconds >= latestMessage->timestampSeconds)))
- {
- auto onlineLocalUser = static_cast<OnlineLocalUser*>(channel->getLocalUser());
- if(creatorPublicKey != onlineLocalUser->getPublicKey())
- {
- stringReplaceChar(msg, "'", "");
- stringReplaceChar(msg, "\\", "");
- string cmd = "notify-send dchat '";
- cmd += msg;
- cmd += "'";
- system(cmd.c_str());
- }
- }
- break;
- }
- case ChannelDataType::DELETE_MESSAGE:
- {
- sibs::SafeDeserializer deserializer((const u8*)decryptedData.data, decryptedData.size);
- odhtdb::Hash messageId;
- deserializer.extract((u8*)messageId.getData(), odhtdb::HASH_BYTE_SIZE);
- channel->deleteLocalMessage(messageId, creatorPublicKey);
- break;
- }
- case ChannelDataType::NICKNAME_CHANGE:
- {
- try
- {
- channelChangeUserNickname(channel, decryptedData, creatorPublicKey);
- }
- catch(sibs::DeserializeException &e)
- {
- fprintf(stderr, "Failed to deserialize nick change\n");
- }
- break;
- }
- case ChannelDataType::CHANGE_AVATAR:
- {
- try
- {
- channelChangeUserAvatar(channel, decryptedData, creatorPublicKey);
- }
- catch(sibs::DeserializeException &e)
- {
- fprintf(stderr, "Failed to deserialize avatar change\n");
- }
- break;
- }
- case ChannelDataType::CHANGE_CHANNEL_NAME:
- {
- try
- {
- channelChangeChannelName(channel, decryptedData, creatorPublicKey);
- }
- catch(sibs::DeserializeException &e)
- {
- fprintf(stderr, "Failed to deserialize channel name 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");
- }
-}
int main(int argc, char **argv)
{
@@ -230,139 +65,151 @@ int main(int argc, char **argv)
//Video video(500, 500, "https://www.youtube.com/watch?v=bs0-EX9mJmg");
- Cache cache;
- Cache::loadBindsFromFile();
-
- Channel offlineChannel("Offline");
- ChannelSidePanel::addChannel(&offlineChannel);
- Channel::setCurrent(&offlineChannel);
+ //Channel offlineChannel("Offline");
+ //ChannelSidePanel::addChannel(&offlineChannel);
+ //Channel::setCurrent(&offlineChannel);
- vector<Channel*> channels;
-
- vector<odhtdb::DatabaseNode> waitingToJoinChannels;
- odhtdb::MapHash<odhtdb::StoredNodeInfo> localNodeUsers;
- string currentUsername;
- string currentPassword;
recursive_mutex channelMessageMutex;
- bool waitingToJoin = false;
- bool loggedIn = false;
sf::Clock lastFocusedTimer;
-
- shared_ptr<odhtdb::Database> database = nullptr;
- odhtdb::DatabaseCallbackFuncs callbackFuncs;
- using LocalUserMessageCallback = function<void(const odhtdb::DatabaseAddNodeRequest &request)>;
- LocalUserMessageCallback onMessageByLocalUser = nullptr;
-
- callbackFuncs.createNodeCallbackFunc = [&waitingToJoinChannels, &database, &channels, &channelMessageMutex, &waitingToJoin, &localNodeUsers, &lastFocusedTimer](const odhtdb::DatabaseCreateNodeRequest &request)
+ const char *bootstrapNode = "31.208.244.169";
+
+ std::shared_ptr<Room> offlineRoom = nullptr;
+
+ auto addSystemMessage = [&lastFocusedTimer](const std::string &msg, bool plainText = true)
{
- lock_guard<recursive_mutex> lock(channelMessageMutex);
- printf("Create node callback func %s\n", request.nodeHash->toString().c_str());
-
- auto nodeUserData = localNodeUsers.find(*request.nodeHash);
- if(nodeUserData == localNodeUsers.end()) return;
-
- User *localUser;
- if(nodeUserData->second.userKeyPair->getPublicKey() == *request.creatorPublicKey)
- localUser = new OnlineLocalUser("NoName", *nodeUserData->second.userKeyPair);
- else
- localUser = new OfflineUser("You");
-
- shared_ptr<odhtdb::Hash> databaseNodeHash = make_shared<odhtdb::Hash>();
- memcpy(databaseNodeHash->getData(), request.nodeHash->getData(), odhtdb::HASH_BYTE_SIZE);
- odhtdb::DatabaseNode databaseNode(nodeUserData->second.nodeEncryptionKey, databaseNodeHash);
- Channel *channel = new Channel("NoChannelName", databaseNode, localUser, database);
- printf("database: %llu\n", database.get());
- ChannelSidePanel::addChannel(channel);
- channels.push_back(channel);
- Channel::setCurrent(channel);
- lastFocusedTimer.restart();
-
- if(localUser->type == User::Type::OFFLINE)
+ auto currentRoom = getCurrentRoom();
+ if(currentRoom && currentRoom->userdata)
{
- User *nodeCreatorUser = new OnlineRemoteUser("NoName", *request.creatorPublicKey);
- channel->addUserLocally(nodeCreatorUser);
- }
-
- for(vector<odhtdb::DatabaseNode>::iterator it = waitingToJoinChannels.begin(); it != waitingToJoinChannels.end(); ++it)
- {
- if(*request.nodeHash == *it->getRequestHash())
- {
- waitingToJoin = true;
- waitingToJoinChannels.erase(it);
- return;
- }
+ auto *roomContainer = static_cast<RoomContainer*>(currentRoom->userdata);
+ roomContainer->messageBoard.addSystemUserMessage(msg, plainText);
}
+ lastFocusedTimer.restart();
};
- callbackFuncs.addNodeCallbackFunc = [&channels, &channelMessageMutex, &lastFocusedTimer, &onMessageByLocalUser](const odhtdb::DatabaseAddNodeRequest &request)
+ RoomCallbackFuncs roomCallbackFuncs;
+ roomCallbackFuncs.connectCallbackFunc = [bootstrapNode, &channelMessageMutex, &offlineRoom, &lastFocusedTimer, &addSystemMessage](std::shared_ptr<Rooms> rooms, const char *errMsg)
{
lock_guard<recursive_mutex> lock(channelMessageMutex);
- //printf("Add node callback func %s\n", request.requestHash->toString().c_str());
- for(Channel *channel : channels)
- {
- if(*request.nodeHash == *channel->getNodeInfo().getRequestHash())
+ if(rooms)
+ {
+ std::string msg = "Connected to ";
+ msg += bootstrapNode;
+ msg += ":27130";
+ fprintf(stderr, "%s\n", msg.c_str());
+ setRooms(rooms);
+ auto emptyId = make_shared<odhtdb::Hash>();
+ offlineRoom = make_shared<Room>(rooms.get(), emptyId);
+ offlineRoom->name = "Offline";
+ auto *roomContainer = new RoomContainer(nullptr);
+ roomContainer->offlineRoom = true;
+ offlineRoom->userdata = roomContainer;
+ setCurrentRoom(offlineRoom);
+
+ string commandsMsg = "Available commands: ";
+ for(const auto &commandIt : Command::getCommands())
{
- channelAddStoredMessage(channel, *request.requestHash, *request.creatorPublicKey, StringView((const char*)request.decryptedData.data, request.decryptedData.size), request.timestamp, request.loadedFromCache);
- if(channel == Channel::getCurrent())
- lastFocusedTimer.restart();
-
- if(!request.loadedFromCache && *request.creatorPublicKey == static_cast<OnlineLocalUser*>(channel->getLocalUser())->getPublicKey())
- {
- if(onMessageByLocalUser)
- onMessageByLocalUser(request);
- }
- return;
+ commandsMsg += "\n/";
+ commandsMsg += commandIt.first;
}
+ addSystemMessage(commandsMsg);
+ }
+ else
+ {
+ std::string errMsgToShow = "Failed to connect to boostrap node, reason: ";
+ errMsgToShow += (errMsg ? errMsg : "unknown");
+ fprintf(stderr, "%s\n", errMsgToShow.c_str());
}
+ lastFocusedTimer.restart();
};
-
- callbackFuncs.addUserCallbackFunc = [&channels, &channelMessageMutex, &waitingToJoin, &localNodeUsers, &lastFocusedTimer](const odhtdb::DatabaseAddUserRequest &request)
+ roomCallbackFuncs.createRoomCallbackFunc = [&channelMessageMutex, &lastFocusedTimer](std::shared_ptr<Room> room)
+ {
+ lock_guard<recursive_mutex> lock(channelMessageMutex);
+ // TODO: Update side panel
+ //RoomSidePanel::addRoom(room);
+ room->userdata = new RoomContainer(room);
+ lastFocusedTimer.restart();
+ };
+ roomCallbackFuncs.addUserCallbackFunc = [&channelMessageMutex, &lastFocusedTimer](const RoomAddUserRequest &request)
+ {
+ lock_guard<recursive_mutex> lock(channelMessageMutex);
+ // TODO: Update users side panel
+ //chatWindow.addUser(request);
+ request.user->nickname = "Anonymous";
+ lastFocusedTimer.restart();
+ };
+ roomCallbackFuncs.addMessageCallbackFunc = [&channelMessageMutex, &lastFocusedTimer](const RoomAddMessageRequest &request)
{
lock_guard<recursive_mutex> lock(channelMessageMutex);
- printf("Add user callback. Channel to add user to: %s\n", request.nodeHash->toString().c_str());
- for(Channel *channel : channels)
+ assert(request.room->userdata);
+ auto *roomContainer = static_cast<RoomContainer*>(request.room->userdata);
+ Message *message = new Message(request.message, false);
+ roomContainer->messageBoard.addMessage(message);
+
+ // Show notification if the message is new and window is not focused and the message was sent not sent by us
+ if(!request.loadedFromCache && !windowFocused)
{
- printf("My channel: %s (%s)\n", channel->getNodeInfo().getRequestHash()->toString().c_str(), channel->getName().c_str());
- if(*request.nodeHash == *channel->getNodeInfo().getRequestHash())
+ // TODO: Should this be done?
+ #if 0
+ if(!request.prevMessage || request.message->timestampSeconds >= request.prevMessage->timestampSeconds)
{
- printf("Add user to one of my channels\n");
- auto nodeUserData = localNodeUsers.find(*request.nodeHash);
-
- User *userToAdd = channel->getUserByPublicKey(*request.userToAddPublicKey);
- if(userToAdd)
- {
- fprintf(stderr, "User %s already exists in channel\n", request.userToAddPublicKey->toString().c_str());
- return;
- }
-
- if(channel == Channel::getCurrent())
- lastFocusedTimer.restart();
-
- if(*request.userToAddPublicKey == nodeUserData->second.userKeyPair->getPublicKey())
- {
- printf("You were added to channel %s by %s\n", request.nodeHash->toString().c_str(), request.creatorPublicKey->toString().c_str());
- channel->replaceLocalUser(new OnlineLocalUser("NoName", *nodeUserData->second.userKeyPair));
- waitingToJoin = false;
- return;
- }
-
- User *newRemoteUser = new OnlineRemoteUser("NoName", *request.userToAddPublicKey);
- channel->addUserLocally(newRemoteUser);
- return;
+
+ }
+ #endif
+ if(request.room->localUser && request.room->localUser != request.message->creator)
+ {
+ string cmd = "notify-send dchat '";
+ cmd += escapeCommand(request.message->text);
+ cmd += "'";
+ system(cmd.c_str());
}
}
+
+ lastFocusedTimer.restart();
};
- database = odhtdb::Database::connect("127.0.0.1", 27130, Cache::getDchatDir(), callbackFuncs).get();
-
- auto addSystemMessage = [&lastFocusedTimer](const std::string &msg, bool plainText = true)
+ roomCallbackFuncs.userChangeNicknameCallbackFunc = [&channelMessageMutex, &lastFocusedTimer](const UserChangeNicknameRequest &request)
+ {
+ lock_guard<recursive_mutex> lock(channelMessageMutex);
+ // TODO: Update panels
+ //chatWindow.setUserNickname(request);
+ lastFocusedTimer.restart();
+ };
+ roomCallbackFuncs.userChangeAvatarCallbackFunc = [&channelMessageMutex, &lastFocusedTimer](const UserChangeAvatarRequest &request)
{
- Channel::getCurrent()->addSystemMessage(msg, plainText);
+ lock_guard<recursive_mutex> lock(channelMessageMutex);
+ // TODO: Update panels
+ //chatWindow.setUserAvatar(request);
lastFocusedTimer.restart();
};
+ roomCallbackFuncs.changeRoomNameCallbackFunc = [&channelMessageMutex, &lastFocusedTimer](const RoomChangeNameRequest &request)
+ {
+ lock_guard<recursive_mutex> lock(channelMessageMutex);
+ // TODO: Update panels
+ //chatWindow.changeRoomName(request);
+ lastFocusedTimer.restart();
+ };
+ roomCallbackFuncs.receiveInviteUserCallbackFunc = [&channelMessageMutex](const InviteUserRequest &request)
+ {
+ lock_guard<recursive_mutex> lock(channelMessageMutex);
+ // TODO: Add invite to a list which we can accept the user from
+ //chatWindow.addInviteRequest(request);
+ // For now automatically add user to the room
+ fprintf(stderr, "User invite request message: %s\n", request.message.c_str());
+ assert(!request.room->localUser->groups.empty());
+ // TODO: Add user to guest group. Right now we are adding the user to our group, which in this case is the admin group...
+ try
+ {
+ request.room->addUser(request.userPublicKey, request.room->localUser->groups[0]);
+ fprintf(stderr, "Successfully added user %s to our group\n", request.userPublicKey.toString().c_str());
+ }
+ catch(odhtdb::PermissionDeniedException &e)
+ {
+ fprintf(stderr, "Failed to add user %s to our group, reason: %s\n", request.userPublicKey.toString().c_str(), e.what());
+ }
+ };
// Login to account
- Command::add("login", [&localNodeUsers, &database, &channels, &loggedIn, &channelMessageMutex, &currentUsername, &currentPassword](const vector<string> &args)
+ Command::add("login", [&channelMessageMutex](const vector<string> &args)
{
lock_guard<recursive_mutex> lock(channelMessageMutex);
if(args.size() != 2)
@@ -370,37 +217,24 @@ int main(int argc, char **argv)
fprintf(stderr, "Expected 2 arguments for command login (username and password), got %u argument(s)\n", args.size());
return;
}
+
+ auto rooms = getRooms();
+ if(!rooms)
+ return;
try
{
- localNodeUsers = database->getStoredNodeUserInfoDecrypted(args[0], args[1]);
-
- ChannelSidePanel::removeAllChannels();
- for(Channel *channel : channels)
- {
- delete channel;
- }
- channels.clear();
-
- printf("Loading %u channel(s) for user\n", localNodeUsers.size());
- for(auto &localNodeUser : localNodeUsers)
- {
- database->loadNode(localNodeUser.first);
- }
-
+ rooms->loginUser(args[0], args[1]);
printf("Successfully logged into user %s\n", args[0].c_str());
- currentUsername = args[0];
- currentPassword = args[1];
- loggedIn = true;
}
catch(std::exception &e)
{
- fprintf(stderr, "Failed to login, reason: %s\n", e.what());
+ fprintf(stderr, "Failed to login to user %s, reason: %s\n", args[0].c_str(), e.what());
}
});
// Register account
- Command::add("register", [&localNodeUsers, &database, &channels, &loggedIn, &channelMessageMutex, &currentUsername, &currentPassword](const vector<string> &args)
+ Command::add("register", [&channelMessageMutex](const vector<string> &args)
{
lock_guard<recursive_mutex> lock(channelMessageMutex);
if(args.size() != 2)
@@ -408,36 +242,26 @@ int main(int argc, char **argv)
fprintf(stderr, "Expected 2 arguments for command register (username and password), got %u argument(s)\n", args.size());
return;
}
+
+ auto rooms = getRooms();
+ if(!rooms)
+ return;
try
{
- database->storeUserWithoutNodes(args[0], args[1]);
+ rooms->registerUser(args[0], args[1]);
+ printf("Successfully registered user %s\n", args[0].c_str());
}
catch(odhtdb::SqlExecException &e)
{
- fprintf(stderr, "User with name %s already exists in storage\n", args[0].c_str());
+ fprintf(stderr, "Failed to register user %s, reason: %s", args[0].c_str(), e.what());
return;
}
-
- printf("Registered user %s\n", args[0].c_str());
-
- ChannelSidePanel::removeAllChannels();
- for(Channel *channel : channels)
- {
- delete channel;
- }
- channels.clear();
- localNodeUsers.clear();
-
- printf("Successfully logged into user %s\n", args[0].c_str());
- currentUsername = args[0];
- currentPassword = args[1];
- loggedIn = true;
});
// TODO: Use database->addData to change channel name
// Create channel
- Command::add("cc", [&database, &channels, &channelMessageMutex, &loggedIn, &localNodeUsers, &currentUsername, &currentPassword, &lastFocusedTimer, addSystemMessage](const vector<string> &args)
+ Command::add("cc", [&channelMessageMutex, &lastFocusedTimer](const vector<string> &args)
{
lock_guard<recursive_mutex> lock(channelMessageMutex);
if(args.size() != 1)
@@ -445,218 +269,83 @@ int main(int argc, char **argv)
fprintf(stderr, "Expected 1 argument for command cc (channel name), got %u argument(s)\n", args.size());
return;
}
+
+ auto rooms = getRooms();
+ if(!rooms)
+ return;
- if(!loggedIn)
+ if(!rooms->isLoggedIn())
{
- fprintf(stderr, "You are not logged in. Please login before creating a channel\n");
+ fprintf(stderr, "You are not logged in. Please login before creating a room\n");
return;
}
- auto createResponse = database->create();
- printf("Created channel %s\n", createResponse->getRequestHash()->toString().c_str());
-
- User *newLocalUser = new OnlineLocalUser("NoName", *createResponse->getNodeAdminKeyPair());
- odhtdb::DatabaseNode databaseNode(createResponse->getNodeEncryptionKey(), createResponse->getRequestHash());
- Channel *channel = new Channel(args[0], databaseNode, newLocalUser, database);
- ChannelSidePanel::addChannel(channel);
- channels.push_back(channel);
- Channel::setCurrent(channel);
- channel->setName(args[0]);
- lastFocusedTimer.restart();
-
- localNodeUsers[*createResponse->getRequestHash()] = { createResponse->getNodeEncryptionKey(), createResponse->getNodeAdminKeyPair() };
- database->storeNodeInfoForUserEncrypted(databaseNode, currentUsername, currentPassword, *createResponse->getNodeAdminKeyPair());
- addSystemMessage("Channel created and stored in database");
+ try
+ {
+ rooms->createRoom(args[0]);
+ printf("Successfully created room %s\n", args[0].c_str());
+ lastFocusedTimer.restart();
+ }
+ catch(std::exception &e)
+ {
+ fprintf(stderr, "Failed to create room %s, reason: %s\n", args[0].c_str(), e.what());
+ }
});
- // Create invite key
- Command::add("invite", [&channelMessageMutex, &offlineChannel, &database, addSystemMessage](const vector<string> &args)
+ // Get invite key
+ Command::add("invitekey", [&channelMessageMutex, &addSystemMessage](const vector<string> &args)
{
lock_guard<recursive_mutex> lock(channelMessageMutex);
if(args.size() != 0)
{
- fprintf(stderr, "Expected 0 arguments for command invite, got %u argument(s)\n", args.size());
+ fprintf(stderr, "Expected 0 arguments for command invitekey, got %u argument(s)\n", args.size());
return;
}
- Channel *currentChannel = Channel::getCurrent();
- if(currentChannel == &offlineChannel)
+ auto currentRoom = getCurrentRoom();
+ if(!currentRoom || static_cast<RoomContainer*>(currentRoom->userdata)->offlineRoom || currentRoom->inviteKey.empty())
{
- addSystemMessage("You need to be in a channel to create an invite key");
+ fprintf(stderr, "You need to be in a room to get the invite key\n");
return;
}
-
- // TODO: Verify user has permission to add users before generating invite key, otherwise invite will fail and the users attempting to join will wait in futile
-
- auto channelNodeHash = currentChannel->getNodeInfo().getRequestHash();
- auto channelEncryptionKey = currentChannel->getNodeInfo().getNodeEncryptionKey();
- shared_ptr<odhtdb::OwnedByteArray> encryptionKey = make_shared<odhtdb::OwnedByteArray>(new u8[odhtdb::ENCRYPTION_KEY_BYTE_SIZE], odhtdb::ENCRYPTION_KEY_BYTE_SIZE);
- odhtdb::Encryption::generateKey((unsigned char*)encryptionKey->data);
-
- string inviteKey = odhtdb::bin2hex((const char*)channelNodeHash->getData(), channelNodeHash->getSize());
- inviteKey += '&';
- inviteKey += odhtdb::bin2hex((const char*)encryptionKey->data, odhtdb::ENCRYPTION_KEY_BYTE_SIZE);
-
- string msg = "You are now listening for users to join the channel using the key: ";
- msg += inviteKey;
-
+
+ std::string msg = "Invite key: ";
+ msg += currentRoom->inviteKey;
addSystemMessage(msg);
- printf("%s\n", msg.c_str());
-
- sibs::SafeSerializer keySerializer;
- keySerializer.add((const u8*)channelNodeHash->getData(), channelNodeHash->getSize());
- keySerializer.add((const u8*)encryptionKey->data, odhtdb::ENCRYPTION_KEY_BYTE_SIZE);
- odhtdb::InfoHash key = odhtdb::Database::getInfoHash(keySerializer.getBuffer().data(), keySerializer.getBuffer().size());
- database->receiveCustomMessage(key, [&channelMessageMutex, encryptionKey, channelEncryptionKey, currentChannel, database](const void *data, usize size)
- {
- // TODO: User can remove channel @currentChannel before we get here, meaning @currentChannel is deleted and would be invalid; causing the program to crash
- try
- {
- sibs::SafeDeserializer deserializer((const u8*)data, size);
- u8 userToAddPublicKeyRaw[odhtdb::PUBLIC_KEY_NUM_BYTES];
- deserializer.extract(userToAddPublicKeyRaw, odhtdb::PUBLIC_KEY_NUM_BYTES);
- odhtdb::Signature::PublicKey userToAddPublicKey((const char*)userToAddPublicKeyRaw, odhtdb::PUBLIC_KEY_NUM_BYTES);
- string unsignedEncryptedMsg = userToAddPublicKey.unsign(odhtdb::DataView((void*)deserializer.getBuffer(), deserializer.getSize()));
-
- sibs::SafeDeserializer encryptedDataDeserializer((const u8*)unsignedEncryptedMsg.data(), unsignedEncryptedMsg.size());
- u8 nonce[odhtdb::ENCRYPTION_NONCE_BYTE_SIZE];
- encryptedDataDeserializer.extract(nonce, odhtdb::ENCRYPTION_NONCE_BYTE_SIZE);
- odhtdb::Decryption decryptedMsg(odhtdb::DataView((void*)encryptedDataDeserializer.getBuffer(), encryptedDataDeserializer.getSize()),
- odhtdb::DataView(nonce, odhtdb::ENCRYPTION_NONCE_BYTE_SIZE),
- encryptionKey->getView());
-
- // TODO: Create GUI for accepting users into channel instead of accepting ALL users
- sibs::SafeSerializer encryptedDataSerializer;
- encryptedDataSerializer.add((const u8*)channelEncryptionKey->data, channelEncryptionKey->size);
- encryptedDataSerializer.add((const u8*)userToAddPublicKey.getData(), userToAddPublicKey.getSize());
- odhtdb::Encryption encryptedChannelKey(odhtdb::DataView((void*)encryptedDataSerializer.getBuffer().data(), encryptedDataSerializer.getBuffer().size()), encryptionKey->getView());
-
- sibs::SafeSerializer serializer;
- serializer.add((const u8*)encryptedChannelKey.getNonce().data, encryptedChannelKey.getNonce().size);
- serializer.add((const u8*)encryptedChannelKey.getCipherText().data, encryptedChannelKey.getCipherText().size);
- const auto &localUserPublicKey = static_cast<OnlineLocalUser*>(currentChannel->getLocalUser())->getPublicKey();
- auto localUserGroups = database->getUserGroups(*currentChannel->getNodeInfo().getRequestHash(), localUserPublicKey);
- if(localUserGroups.empty())
- {
- fprintf(stderr, "No group to add user to...\n");
- return sibs::SafeSerializer();
- }
- lock_guard<recursive_mutex> lock(channelMessageMutex);
- currentChannel->addUser(userToAddPublicKey, localUserGroups[0].getView());
- return serializer;
- }
- catch(std::exception &e)
- {
- fprintf(stderr, "Failed while parsing user data to add to channel, reason: %s\n", e.what());
- }
- return sibs::SafeSerializer();
- });
+ fprintf(stderr, "%s\n", msg.c_str());
});
// Join channel using invite key
- Command::add("jc", [&loggedIn, &database, &localNodeUsers, &channelMessageMutex, &waitingToJoin, &waitingToJoinChannels, &currentUsername, &currentPassword](const vector<string> &args)
+ Command::add("jc", [&channelMessageMutex](const vector<string> &args)
{
lock_guard<recursive_mutex> lock(channelMessageMutex);
- if(args.size() != 1)
+ if(args.size() != 2)
{
- fprintf(stderr, "Expected 1 argument for command jc (channel join key), got %u argument(s)\n", args.size());
+ fprintf(stderr, "Expected 2 arguments for command jc (channel join key and message), got %u argument(s)\n", args.size());
return;
}
- if(args[0].size() != 129)
- {
- fprintf(stderr, "Expected join key to be 129 characters, was %u character(s)\n", args[0].size());
+ auto rooms = getRooms();
+ if(!rooms)
return;
- }
- if(!loggedIn)
+ if(!rooms->isLoggedIn())
{
- fprintf(stderr, "You are not logged in. Please login before joining a channel\n");
+ fprintf(stderr, "You are not logged in. Please login before joining a room\n");
return;
}
-
- string nodeHashBinRaw = odhtdb::hex2bin(args[0].c_str(), 64);
- shared_ptr<odhtdb::Hash> nodeHash = make_shared<odhtdb::Hash>();
- memcpy(nodeHash->getData(), nodeHashBinRaw.data(), nodeHashBinRaw.size());
- auto nodeUserIt = localNodeUsers.find(*nodeHash);
- if(nodeUserIt != localNodeUsers.end())
+
+ try
{
- fprintf(stderr, "You have already joined the channel %s\n", args[0].c_str());
- return;
+ if(rooms->requestJoinRoom(args[0], args[1]))
+ fprintf(stderr, "No error while joining room. Waiting to be added...");
}
-
- string encryptionKeyBinRaw = odhtdb::hex2bin(args[0].c_str() + 65, 64);
- shared_ptr<odhtdb::OwnedByteArray> encryptionKey = make_shared<odhtdb::OwnedByteArray>(new u8[odhtdb::ENCRYPTION_KEY_BYTE_SIZE], odhtdb::ENCRYPTION_KEY_BYTE_SIZE);
- memcpy(encryptionKey->data, encryptionKeyBinRaw.data(), encryptionKeyBinRaw.size());
-
- shared_ptr<odhtdb::Signature::KeyPair> keyPair = make_shared<odhtdb::Signature::KeyPair>();
- sibs::SafeSerializer serializer;
- serializer.add((const u8*)keyPair->getPublicKey().getData(), keyPair->getPublicKey().getSize());
-
- const char *msg = "please let me join";
- odhtdb::Encryption encryptedJoinMsg(odhtdb::DataView((void*)msg, strlen(msg)), encryptionKey->getView());
- sibs::SafeSerializer encryptedDataSerializer;
- encryptedDataSerializer.add((const u8*)encryptedJoinMsg.getNonce().data, encryptedJoinMsg.getNonce().size);
- encryptedDataSerializer.add((const u8*)encryptedJoinMsg.getCipherText().data, encryptedJoinMsg.getCipherText().size);
- string signedEncryptedMsg = keyPair->getPrivateKey().sign(odhtdb::DataView(encryptedDataSerializer.getBuffer().data(), encryptedDataSerializer.getBuffer().size()));
- serializer.add((const u8*)signedEncryptedMsg.data(), signedEncryptedMsg.size());
-
- sibs::SafeSerializer keySerializer;
- keySerializer.add((const u8*)nodeHash->getData(), nodeHash->getSize());
- keySerializer.add((const u8*)encryptionKeyBinRaw.data(), odhtdb::ENCRYPTION_KEY_BYTE_SIZE);
- odhtdb::InfoHash key = odhtdb::Database::getInfoHash(keySerializer.getBuffer().data(), keySerializer.getBuffer().size());
- database->sendCustomMessage(key, serializer.getBuffer().data(), serializer.getBuffer().size(),
- [&database, nodeHash, encryptionKey, &waitingToJoinChannels, &channelMessageMutex, keyPair, &currentUsername, &currentPassword, &localNodeUsers]
- (bool gotResponse, const void *data, usize size)
+ catch(std::exception &e)
{
- if(!gotResponse)
- {
- printf("We didn't get a response from anybody in the channel. Is there nobody that can add us (nobody with the permission required to do so or no online users) or is the node hash invalid?\n");
- return false;
- }
-
- try
- {
- sibs::SafeDeserializer deserializer((const u8*)data, size);
- u8 nonce[odhtdb::ENCRYPTION_NONCE_BYTE_SIZE];
- deserializer.extract(nonce, odhtdb::ENCRYPTION_NONCE_BYTE_SIZE);
- odhtdb::Decryption decryptedMsg(odhtdb::DataView((void*)deserializer.getBuffer(), deserializer.getSize()),
- odhtdb::DataView(nonce, odhtdb::ENCRYPTION_NONCE_BYTE_SIZE),
- encryptionKey->getView());
- if(decryptedMsg.getDecryptedText().size != odhtdb::ENCRYPTION_KEY_BYTE_SIZE + odhtdb::PUBLIC_KEY_NUM_BYTES)
- {
- fprintf(stderr, "Invite response was of unexpected size, maybe it wasn't meant for us?\n");
- return true;
- }
-
- odhtdb::DataView channelEncryptionKeyRaw(decryptedMsg.getDecryptedText().data, odhtdb::ENCRYPTION_KEY_BYTE_SIZE);
- odhtdb::DataView invitedUserPublicKey((u8*)decryptedMsg.getDecryptedText().data + odhtdb::ENCRYPTION_KEY_BYTE_SIZE, odhtdb::PUBLIC_KEY_NUM_BYTES);
- if(memcmp(keyPair->getPublicKey().getData(), invitedUserPublicKey.data, odhtdb::PUBLIC_KEY_NUM_BYTES) != 0)
- {
- fprintf(stderr, "Invite response was not meant for us\n");
- return true;
- }
-
- shared_ptr<odhtdb::OwnedByteArray> channelEncryptionKey = make_shared<odhtdb::OwnedByteArray>(new u8[channelEncryptionKeyRaw.size], channelEncryptionKeyRaw.size);
- memcpy(channelEncryptionKey->data, channelEncryptionKeyRaw.data, channelEncryptionKeyRaw.size);
- odhtdb::DatabaseNode databaseNode(channelEncryptionKey, nodeHash);
- localNodeUsers[*nodeHash] = { channelEncryptionKey, keyPair };
- database->storeNodeInfoForUserEncrypted(databaseNode, currentUsername, currentPassword, *keyPair);
- printf("Got a response from a person in the channel, we might get added...\n");
- waitingToJoinChannels.push_back(databaseNode);
- lock_guard<recursive_mutex> lock(channelMessageMutex);
- database->seed(databaseNode, odhtdb::DatabaseFetchOrder::NEWEST_FIRST);
- return false;
- }
- catch(std::exception &e)
- {
- fprintf(stderr, "Failed while parsing join response for invite link, reason: %s\n", e.what());
- }
- return true;
- });
- waitingToJoin = true;
+ fprintf(stderr, "Failed to join room %s, reason: %s", args[0].c_str(), e.what());
+ }
});
-
+
// Scale UI
Command::add("scale", [](const vector<string> &args)
{
@@ -752,8 +441,8 @@ int main(int argc, char **argv)
addSystemMessage(msg, false);
});
- // Change nick of current user in current channel
- Command::add("nick", [&loggedIn, &offlineChannel, addSystemMessage](const vector<string> &args)
+ // Change nick of current user in current room
+ Command::add("nick", [addSystemMessage](const vector<string> &args)
{
if(args.size() != 1)
{
@@ -763,16 +452,11 @@ int main(int argc, char **argv)
addSystemMessage(errMsg);
return;
}
-
- if(!loggedIn)
- {
- addSystemMessage("You need to be logged in to change your nickname");
- return;
- }
-
- if(Channel::getCurrent() == &offlineChannel)
+
+ auto currentRoom = getCurrentRoom();
+ if(!currentRoom || static_cast<RoomContainer*>(currentRoom->userdata)->offlineRoom)
{
- addSystemMessage("You need to be in a channel to change your nickname");
+ fprintf(stderr, "You need to be in a room to change your name\n");
return;
}
@@ -782,14 +466,14 @@ int main(int argc, char **argv)
return;
}
- Channel::getCurrent()->changeNick(args[0]);
+ currentRoom->setUserNickname(args[0]);
string msg = "Your nickname was changed to ";
msg += args[0];
addSystemMessage(msg);
});
// Change avatar of current user in current channel
- Command::add("avatar", [&loggedIn, &offlineChannel, addSystemMessage](const vector<string> &args)
+ Command::add("avatar", [addSystemMessage](const vector<string> &args)
{
if(args.size() != 1)
{
@@ -800,15 +484,10 @@ int main(int argc, char **argv)
return;
}
- if(!loggedIn)
+ auto currentRoom = getCurrentRoom();
+ if(!currentRoom || static_cast<RoomContainer*>(currentRoom->userdata)->offlineRoom)
{
- addSystemMessage("You need to be logged in to change your avatar");
- return;
- }
-
- if(Channel::getCurrent() == &offlineChannel)
- {
- addSystemMessage("You need to be in a channel to change your avatar");
+ fprintf(stderr, "You need to be in a room to change your avatar\n");
return;
}
@@ -820,37 +499,31 @@ int main(int argc, char **argv)
if(looksLikeUrl(args[0]))
{
- Channel::getCurrent()->setAvatar(args[0]);
+ currentRoom->setAvatarUrl(args[0]);
addSystemMessage("Your avatar has been changed (Note: max avatar size is 1 Mb, if your avatar is larger then it will not be visible)");
}
else
{
- addSystemMessage("Avatar url needs to start with either http:// or https:// and include a dot");
+ addSystemMessage("Avatar url needs to start with either http://, https:// or www.");
}
});
- // Change name of the current channel
- Command::add("channelname", [&offlineChannel, addSystemMessage](const vector<string> &args)
+ // Change name of the current room
+ Command::add("roomname", [addSystemMessage](const vector<string> &args)
{
if(args.size() != 1)
{
- string errMsg = "Expected 1 argument for command channelname, got ";
+ string errMsg = "Expected 1 argument for command roomname, got ";
errMsg += to_string(args.size());
errMsg += " argument(s)";
addSystemMessage(errMsg);
return;
}
- Channel *currentChannel = Channel::getCurrent();
- if(currentChannel == &offlineChannel)
- {
- addSystemMessage("You need to be in a channel to change channel name");
- return;
- }
-
- if(!currentChannel->getLocalUser()->isOnlineUser())
+ auto currentRoom = getCurrentRoom();
+ if(!currentRoom || static_cast<RoomContainer*>(currentRoom->userdata)->offlineRoom)
{
- addSystemMessage("You need to be logged in to change channel name");
+ fprintf(stderr, "You can't change room name size you are not in a room\n");
return;
}
@@ -859,297 +532,26 @@ int main(int argc, char **argv)
addSystemMessage("Channel name has to be between 1 and 32 bytes long");
return;
}
-
- int localUserPermissionLevel = currentChannel->getUserLowestPermissionLevel(static_cast<OnlineLocalUser*>(currentChannel->getLocalUser()));
- if(localUserPermissionLevel != odhtdb::PERMISSION_LEVEL_ADMIN)
- {
- addSystemMessage("You need to be admin to change channel name");
- return;
- }
- currentChannel->setName(args[0]);
+ currentRoom->setName(args[0]);
string msg = "Channel name has been changed to ";
msg += args[0];
addSystemMessage(msg);
});
- Command::add("clearcache", [database](const vector<string> &args)
- {
- printf("Cleared cache (%d bytes)\n", database->clearCache());
- });
+ //Command::add("clearcache", [](const vector<string> &args)
+ //{
+ // printf("Cleared cache (%d bytes)\n", database->clearCache());
+ //});
- string commandsMsg = "Available commands: ";
- for(const auto &commandIt : Command::getCommands())
- {
- commandsMsg += "\n/";
- commandsMsg += commandIt.first;
- }
- addSystemMessage(commandsMsg);
-
- odhtdb::MapHash<u64> myDiscordIdsByChannel;
-
bool running = true;
- thread rpcThread([&running, &onMessageByLocalUser, &channels, &lastFocusedTimer, &myDiscordIdsByChannel]()
- {
- Rpc rpc(5555);
- mutex messageMutex;
- vector<msgpack::sbuffer> messagesToSend;
- onMessageByLocalUser = [&messagesToSend, &messageMutex](const odhtdb::DatabaseAddNodeRequest &request)
- {
- lock_guard<mutex> lock(messageMutex);
- auto channelDataType = (ChannelDataType)static_cast<const char*>(request.decryptedData.data)[0];
- usize size = request.decryptedData.size - 1;
- const char *data = (const char*)request.decryptedData.data + 1;
- const char *action = nullptr;
- if(channelDataType == ChannelDataType::ADD_MESSAGE)
- action = "addMessage";
-
- if(!action) return;
- vector<string> msg = { action, string(data, data + size), request.nodeHash->toString() };
- msgpack::sbuffer buffer;
- msgpack::pack(buffer, msg);
- messagesToSend.emplace_back(move(buffer));
- };
-
- while(running)
- {
- rpc.recv([&channels, &lastFocusedTimer, &myDiscordIdsByChannel](zmq::message_t *message)
- {
- try
- {
- msgpack::object_handle oh = msgpack::unpack((const char*)message->data(), message->size());
- auto deserialized = oh.get();
- vector<string> msg;
- deserialized.convert(msg);
- if(msg.size() < 2)
- {
- fprintf(stderr, "Rpc receive, data length expected to be at least 2, was %u\n", msg.size());
- return;
- }
- auto &action = msg[0];
-
- string dchatChannelIdRaw = odhtdb::hex2bin(msg[1].c_str(), msg[1].size());
- odhtdb::Hash dchatChannelId;
- memcpy(dchatChannelId.getData(), dchatChannelIdRaw.data(), dchatChannelIdRaw.size());
- Channel *bridgedChannel = nullptr;
- for(Channel *channel : channels)
- {
- if(*channel->getNodeInfo().getRequestHash() == dchatChannelId)
- {
- bridgedChannel = channel;
- break;
- }
- }
-
- if(!bridgedChannel)
- {
- fprintf(stderr, "Rcp addMessage, invalid dchat channel %s\n", msg[1].c_str());
- return;
- }
-
- if(bridgedChannel == Channel::getCurrent())
- lastFocusedTimer.restart();
+ Cache *cache = ResourceCache::getCache();
+ Rooms::connect(bootstrapNode, 27130, roomCallbackFuncs);
+ Chatbar::loadBindsFromFile();
- fprintf(stderr, "Received rpc, action: %s\n", action.c_str());
- if(action == "addMessage")
- {
- if((msg.size() - 2) % 4 != 0)
- {
- fprintf(stderr, "Rpc addMessage, request was malformed\n");
- return;
- }
-
- for(size_t i = 2; i < msg.size(); i += 4)
- {
- auto &content = msg[i];
- auto &discordUserId = msg[i + 1];
- u64 discordUserIdNumber = 0;
- auto &discordUserName = msg[i + 2];
- auto &messageTimestampMillisec = msg[i + 3];
- u64 messageTimestampSecondsNumber = 0;
-
- try
- {
- discordUserIdNumber = stoull(discordUserId);
- }
- catch(...)
- {
- fprintf(stderr, "Rpc receive, failed to convert discord id to uint64_t: %s\n", discordUserId.c_str());
- return;
- }
-
- try
- {
- messageTimestampSecondsNumber = stoull(messageTimestampMillisec) / 1000;
- }
- catch(...)
- {
- fprintf(stderr, "Rpc receive, failed to convert discord message timestamp to uint64_t: %s\n", messageTimestampMillisec.c_str());
- return;
- }
-
- auto myDiscordIdIt = myDiscordIdsByChannel.find(dchatChannelId);
- if(myDiscordIdIt != myDiscordIdsByChannel.end() && myDiscordIdIt->second == discordUserIdNumber)
- {
- auto &channelMessages = bridgedChannel->getMessageBoard().getMessages();
- Message *myLatestMessage = nullptr;
- for(auto it = channelMessages.rbegin(), end = channelMessages.rend(); it != end; ++it)
- {
- if((*it)->user == bridgedChannel->getLocalUser())
- {
- myLatestMessage = *it;
- break;
- }
- }
-
- if(myLatestMessage && (i64)messageTimestampSecondsNumber - (i64)myLatestMessage->timestampSeconds <= 3)
- {
- return;
- /*
- auto myMessageUtf8 = myLatestMessage->text.getString().toUtf8();
- odhtdb::Hash myMessageHash(myMessageUtf8.data(), myMessageUtf8.size());
- odhtdb::Hash myDiscordMessageHash(content.data(), content.size());
- if(myMessageHash == myDiscordMessageHash)
- return;
- */
- }
- }
-
- bridgedChannel->addLocalDiscordMessage(discordUserName, discordUserIdNumber, content, bridgedChannel->getLocalUser(), messageTimestampSecondsNumber, odhtdb::Hash(messageTimestampMillisec.c_str(), messageTimestampMillisec.size()));
- }
- }
- else if(action == "addUser")
- {
- if((msg.size() - 2) % 4 != 0)
- {
- fprintf(stderr, "Rpc addUser, request was malformed\n");
- return;
- }
-
- for(size_t i = 2; i < msg.size(); i += 4)
- {
- auto &discordUsername = msg[i];
- auto &discordUserId = msg[i + 1];
- auto &userStatus = msg[i + 2];
- auto &avatarURL = msg[i + 3];
-
- try
- {
- u64 discordUserIdNumber = stoull(discordUserId);
- bool online = (userStatus != "offline");
- printf("Rpc, adding user %s with status %s\n", discordUsername.c_str(), userStatus.c_str());
- DiscordServiceUser *discordUser = bridgedChannel->getDiscordService()->getUserById(discordUserIdNumber);
- if(discordUser)
- {
- discordUser->connected = online;
- }
- else
- {
- discordUser = new DiscordServiceUser(discordUsername, discordUserIdNumber, online);
- bridgedChannel->getDiscordService()->addUser(discordUser);
- }
- discordUser->avatarUrl = avatarURL;
- }
- catch(...)
- {
- fprintf(stderr, "Warning: Rpc receive, failed to convert discord id to uint64_t: %s\n", discordUserId.c_str());
- // Ignore for now.. should we really handle this error other than showing warning?
- }
- }
- }
- else if(action == "removeUser")
- {
- for(size_t i = 2; i < msg.size(); ++i)
- {
- auto &discordUserId = msg[i];
- try
- {
- u64 discordUserIdNumber = stoull(discordUserId);
- bridgedChannel->getDiscordService()->removeUser(discordUserIdNumber);
- }
- catch(...)
- {
- fprintf(stderr, "Warning: Rpc receive, failed to convert discord id to uint64_t: %s\n", discordUserId.c_str());
- // Ignore for now.. should we really handle this error other than showing warning?
- }
- }
- }
- else if(action == "statusChange")
- {
- if((msg.size() - 2) != 2)
- {
- fprintf(stderr, "Rpc statusChange, request was malformed\n");
- return;
- }
-
- auto &discordUserId = msg[2];
- auto &userStatus = msg[3];
-
- try
- {
- u64 discordUserIdNumber = stoull(discordUserId);
- DiscordServiceUser *discordUser = bridgedChannel->getDiscordService()->getUserById(discordUserIdNumber);
- if(discordUser)
- {
- discordUser->connected = (userStatus != "offline");
- printf("Rcp statusChange, changed user %s (%s) status to %s\n", discordUserId.c_str(), discordUser->getName().c_str(), userStatus.c_str());
- }
- }
- catch(...)
- {
- fprintf(stderr, "Warning: Rpc receive, failed to convert discord id to uint64_t: %s\n", discordUserId.c_str());
- // Ignore for now.. should we really handle this error other than showing warning?
- }
- }
- else if(action == "addMe")
- {
- if((msg.size() - 2) != 1)
- {
- fprintf(stderr, "Rpc addMe, request was malformed\n");
- return;
- }
-
- auto &myDiscordId = msg[2];
- try
- {
- u64 myDiscordIdNumber = stoull(myDiscordId);
- myDiscordIdsByChannel[dchatChannelId] = myDiscordIdNumber;
- }
- catch(...)
- {
- fprintf(stderr, "Warning: Rpc receive, failed to convert discord id to uint64_t: %s\n", myDiscordId.c_str());
- // Ignore for now.. should we really handle this error other than showing warning?
- }
- }
- else
- {
- fprintf(stderr, "Rcp received unknown action %s\n", action.c_str());
- }
- }
- catch(msgpack::type_error &e)
- {
- fprintf(stderr, "Failed to deserialize received rpc, error: %s\n", e.what());
- }
- });
- {
- lock_guard<mutex> lock(messageMutex);
- for(auto &messageToSend : messagesToSend)
- {
- fprintf(stderr, "Rpc, sending message\n");
- rpc.send(messageToSend.data(), messageToSend.size());
- }
- messagesToSend.clear();
- }
- this_thread::sleep_for(chrono::milliseconds(50));
- }
- });
-
- sf::Clock frameTimer;
-
while (running)
{
- frameTimer.restart();
- Channel *currentChannel = Channel::getCurrent();
+ std::shared_ptr<Room> currentRoom = getCurrentRoom();
sf::Event event;
while (window.pollEvent(event))
@@ -1195,17 +597,21 @@ int main(int argc, char **argv)
if(!ImagePreview::getPreviewContentPtr() && ImagePreview::getTimeSinceLastSeenMs() > 250)
{
+ lock_guard<recursive_mutex> lock(channelMessageMutex);
GlobalContextMenu::processEvent(event);
- currentChannel->processEvent(event, cache);
+ if(currentRoom && currentRoom->userdata) {
+ auto *roomContainer = static_cast<RoomContainer*>(currentRoom->userdata);
+ roomContainer->processEvent(event, cache);
+ }
}
lastFocusedTimer.restart();
}
- for(Channel *channel : channels)
- {
- channel->update();
- }
+ //for(Channel *channel : channels)
+ // {
+ // channel->update();
+ // }
if((!windowFocused || !focused) && lastFocusedTimer.getElapsedTime().asMilliseconds() > 5000)
{
@@ -1214,43 +620,26 @@ int main(int argc, char **argv)
}
window.clear(ColorScheme::getBackgroundColor());
- ChannelSidePanel::draw(window);
- currentChannel->draw(window, cache);
- UsersSidePanel::draw(window, cache);
- ChannelTopPanel::draw(window);
- GlobalContextMenu::draw(window);
- ImagePreview::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/Nunito-Regular.ttf");
- const float FONT_SIZE = (double)windowSize.x / 40.0;
- 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);
+ lock_guard<recursive_mutex> lock(channelMessageMutex);
+ RoomSidePanel::draw(window);
+ if(currentRoom && currentRoom->userdata) {
+ auto *roomContainer = static_cast<RoomContainer*>(currentRoom->userdata);
+ roomContainer->draw(window, cache);
+ }
+ UsersSidePanel::draw(window, cache);
+ RoomTopPanel::draw(window);
+ GlobalContextMenu::draw(window);
+ ImagePreview::draw(window);
}
//video.draw(window);
window.display();
}
-
- onMessageByLocalUser = nullptr;
- rpcThread.join();
-
- for(Channel *channel : channels)
- {
- delete channel;
- }
// We need to wait until our `ping` packet for disconnecting is sent to all channels
- printf("Shutting down...\n");
- this_thread::sleep_for(chrono::seconds(3));
+ //printf("Shutting down...\n");
+ //this_thread::sleep_for(chrono::seconds(3));
return 0;
}