#pragma once #include "utils.hpp" #include "types.hpp" #include "StringView.hpp" #include "User.hpp" #include #include #include #include #include #include namespace dchat { struct RoomMessage { odhtdb::Hash id; std::shared_ptr creator; uint32_t timestampSeconds; std::string text; }; class Rooms; class Room { DISABLE_COPY(Room) public: Room(Rooms *rooms, std::shared_ptr id); // Throws exception on failure if we are not allowed to add the user to the group void addUser(const odhtdb::Signature::PublicKey &userPublicKey, std::shared_ptr group); // Returns null if the user already exists in the room std::shared_ptr addUserLocally(const odhtdb::Signature::PublicKey &userPublicKey, std::shared_ptr group); // Returns null if the group already exists in the room std::shared_ptr addGroupLocally(const odhtdb::DataView groupId); // Returns null if user doesn't exist in room std::shared_ptr getUserByPublicKey(const odhtdb::Signature::PublicKey &userPublicKey); // Returns null if group doesn't exist in room std::shared_ptr getGroupById(const odhtdb::DataView groupId); void setLocalUser(std::shared_ptr user, std::shared_ptr keyPair); void setAvatarUrl(const std::string &url); void setNickname(const std::string &nickname); void publishMessage(const std::string &msg); Rooms *rooms; std::shared_ptr id; std::shared_ptr encryptionKey; std::string name; odhtdb::Signature::MapPublicKey> userByPublicKey; std::vector> groups; std::vector messages; std::shared_ptr localUser; // Used for local users odhtdb::Signature::MapPublicKey> publicKeyToKeyPairMap; std::string inviteKey; void *userdata; }; struct RoomAddMessageRequest { std::shared_ptr room; bool loadedFromCache; RoomMessage message; }; struct UserChangeNicknameRequest { std::shared_ptr room; std::shared_ptr user; uint32_t timestampSeconds; bool loadedFromCache; std::string newNickname; }; struct UserChangeAvatarRequest { std::shared_ptr room; std::shared_ptr user; uint32_t timestampSeconds; bool loadedFromCache; std::string url; }; struct RoomChangeNameRequest { std::shared_ptr room; std::shared_ptr user; uint32_t timestampSeconds; bool loadedFromCache; std::string newName; }; struct InviteUserRequest { std::shared_ptr room; odhtdb::Signature::PublicKey userPublicKey; std::string message; }; struct RoomAddUserRequest { std::shared_ptr room; std::shared_ptr user; std::shared_ptr addedByUser; uint32_t timestampSeconds; bool loadedFromCache; bool isLocalUser; }; // if connection failed then @rooms is null and errMsg contains the error using ConnectBoostrapNodeCallbackFunc = std::function rooms, const char *errMsg)>; using CreateRoomCallbackFunc = std::function room)>; using RoomAddUserCallbackFunc = std::function; using RoomAddMessageCallbackFunc = std::function; using UserChangeNicknameCallbackFunc = std::function; using UserChangeAvatarCallbackFunc = std::function; using ChangeRoomNameCallbackFunc = std::function; using ReceiveInviteUserCallbackFunc = std::function; struct RoomCallbackFuncs { ConnectBoostrapNodeCallbackFunc connectCallbackFunc; CreateRoomCallbackFunc createRoomCallbackFunc; RoomAddUserCallbackFunc addUserCallbackFunc; RoomAddMessageCallbackFunc addMessageCallbackFunc; UserChangeNicknameCallbackFunc userChangeNicknameCallbackFunc; UserChangeAvatarCallbackFunc userChangeAvatarCallbackFunc; ChangeRoomNameCallbackFunc changeRoomNameCallbackFunc; ReceiveInviteUserCallbackFunc receiveInviteUserCallbackFunc; }; class Rooms { friend Room; DISABLE_COPY(Rooms) public: // @callbackFuncs.connectCallbackFunc can't be null static void connect(const char *address, u16 port, RoomCallbackFuncs callbackFuncs); // Throws on failure void loginUser(const std::string &username, const std::string &password); // Throws on failure void registerUser(const std::string &username, const std::string &password); // Throws on failure std::shared_ptr createRoom(const std::string &name); void requestJoinRoom(const std::string &inviteKey, const std::string &message); std::shared_ptr database; private: Rooms(const char *address, u16 port, RoomCallbackFuncs callbackFuncs); void createNodeCallbackFunc(const odhtdb::DatabaseCreateNodeRequest &request); void addNodeCallbackFunc(const odhtdb::DatabaseAddNodeRequest &request); void addUserCallbackFunc(const odhtdb::DatabaseAddUserRequest &request); private: odhtdb::MapHash> roomById; RoomCallbackFuncs callbackFuncs; bool loggedIn; odhtdb::MapHash> roomLocalUser; odhtdb::MapHash> roomEncryptionKey; std::string currentUsername; std::string currentUserPassword; std::recursive_mutex roomModifyMutex; odhtdb::MapHash> waitingToJoinRoom; std::recursive_mutex waitingToJoinRoomMutex; }; }