aboutsummaryrefslogtreecommitdiff
path: root/include/dchat/Room.hpp
blob: 5dd0e3ffc5fb71b75bc82686224be21a5996895c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#pragma once

#include "utils.hpp"
#include "types.hpp"
#include "StringView.hpp"
#include "User.hpp"
#include <string>
#include <memory>
#include <vector>
#include <functional>
#include <mutex>
#include <odhtdb/Database.hpp>

namespace dchat
{
    struct RoomMessage
    {
        odhtdb::Hash id;
        std::shared_ptr<User> creator;
        uint32_t timestampSeconds;
        std::string text;
    };

    class Rooms;

    class Room
    {
        DISABLE_COPY(Room)
    public:
        Room(Rooms *rooms, std::shared_ptr<odhtdb::Hash> id);
        std::shared_ptr<User> addUser(const odhtdb::Signature::PublicKey &userPublicKey, const odhtdb::DataView groupId);
        // Returns null if user doesn't exist in room
        std::shared_ptr<User> getUserByPublicKey(const odhtdb::Signature::PublicKey &userPublicKey);
        void publishMessage(const std::string &msg);

        Rooms *rooms;
        std::shared_ptr<odhtdb::Hash> id;
        std::shared_ptr<odhtdb::OwnedByteArray> encryptionKey;
        std::string name;
        odhtdb::Signature::MapPublicKey<std::shared_ptr<User>> userByPublicKey;
        std::vector<RoomMessage> messages;
        std::shared_ptr<User> localUser;
        // Used for local users
        odhtdb::Signature::MapPublicKey<std::shared_ptr<odhtdb::Signature::KeyPair>> publicKeyToKeyPairMap;
        void *userdata;
    };

    struct RoomAddMessageRequest
    {
        std::shared_ptr<Room> room;
        bool loadedFromCache;
        RoomMessage message;
    };

    struct UserChangeNicknameRequest
    {
        std::shared_ptr<Room> room;
        std::shared_ptr<User> user;
        uint32_t timestampSeconds;
        bool loadedFromCache;
        std::string newNickname;
    };

    struct RoomChangeNameRequest
    {
        std::shared_ptr<Room> room;
        std::shared_ptr<User> user;
        uint32_t timestampSeconds;
        bool loadedFromCache;
        std::string newName;
    };

    // if connection failed then @rooms is null and errMsg contains the error
    using ConnectBoostrapNodeCallbackFunc = std::function<void(std::shared_ptr<Rooms> rooms, const char *errMsg)>;
    using CreateRoomCallbackFunc = std::function<void(std::shared_ptr<Room> room)>;
    using RoomAddUserCallbackFunc = std::function<void(std::shared_ptr<Room> room, std::shared_ptr<User> user)>;
    using RoomAddMessageCallbackFunc = std::function<void(const RoomAddMessageRequest &request)>;
    using UserChangeNicknameCallbackFunc = std::function<void(const UserChangeNicknameRequest &request)>;
    using ChangeRoomNameCallbackFunc = std::function<void(const RoomChangeNameRequest &request)>;
    struct RoomCallbackFuncs
    {
        ConnectBoostrapNodeCallbackFunc connectCallbackFunc;
        CreateRoomCallbackFunc createRoomCallbackFunc;
        RoomAddUserCallbackFunc addUserCallbackFunc;
        RoomAddMessageCallbackFunc addMessageCallbackFunc;
        UserChangeNicknameCallbackFunc userChangeNicknameCallbackFunc;
        ChangeRoomNameCallbackFunc changeRoomNameCallbackFunc;
    };

    class Rooms
    {
        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
        void createRoom(const std::string &name);

        std::shared_ptr<odhtdb::Database> 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<std::shared_ptr<Room>> roomById;
        RoomCallbackFuncs callbackFuncs;
        bool loggedIn;
        odhtdb::MapHash<std::shared_ptr<odhtdb::Signature::KeyPair>> roomLocalUser;
        odhtdb::MapHash<std::shared_ptr<odhtdb::OwnedByteArray>> roomEncryptionKey;

        std::string currentUsername;
        std::string currentUserPassword;
        std::recursive_mutex roomModifyMutex;
    };
}