#include "../include/Channel.hpp" #include #include #include #include #include using namespace std; namespace dchat { static Channel *currentChannel; Channel::Channel(const string &_name, const odhtdb::DatabaseNode &_databaseNodeInfo, User *_localUser, odhtdb::Database *_database) : database(_database), databaseNodeInfo(_databaseNodeInfo), name(_name), messageBoard(sf::Vector2u(1.0f, 1.0f)), localUser(_localUser ? _localUser : new OfflineUser("You")) { addUserLocally(localUser); { Message *message = new Message(&systemUser, u8"[emoji](https://discordemoji.com/assets/emoji/PepeDab.gif) deaf [emoji](https://discordemoji.com/assets/emoji/COGGERS.gif)"); messageBoard.addMessage(message); } { Message *message = new Message(&systemUser, u8"[emoji](https://discordemoji.com/assets/emoji/PepeDab.gif)[emoji](https://discordemoji.com/assets/emoji/COGGERS.gif)"); messageBoard.addMessage(message); } { Message *message = new Message(&systemUser, u8"pepedab https://discordemoji.com/assets/emoji/PepeDab.gif coggers https://discordemoji.com/assets/emoji/COGGERS.gif"); messageBoard.addMessage(message); } if(database) database->seed(databaseNodeInfo); } Channel::~Channel() { if(database) database->stopSeeding(*databaseNodeInfo.getRequestHash()); for(User *user : users) { delete user; } } User* Channel::getLocalUser() { return localUser; } SystemUser* Channel::getSystemUser() { return &systemUser; } MessageBoard& Channel::getMessageBoard() { return messageBoard; } const string& Channel::getName() const { return name; } const vector Channel::getUsers() const { return users; } OnlineUser* Channel::getUserByPublicKey(const odhtdb::Signature::PublicKey &publicKey) { auto userIt = publicKeyOnlineUsersMap.find(publicKey); if(userIt != publicKeyOnlineUsersMap.end()) return userIt->second; return nullptr; } const odhtdb::DatabaseNode& Channel::getNodeInfo() const { return databaseNodeInfo; } void Channel::addLocalMessage(const std::string &msg, User *owner, u64 timestampSeconds) { assert(owner); messageBoard.addMessage(new Message(owner, msg, timestampSeconds)); } void Channel::addMessage(const std::string &msg) { if(database && localUser->type == User::Type::ONLINE) { auto localOnlineUser = static_cast(localUser); assert(localOnlineUser->databaseUser->getType() == odhtdb::User::Type::LOCAL); sibs::SafeSerializer serializer; serializer.add(ChannelDataType::MESSAGE); serializer.add((const u8*)msg.data(), msg.size()); database->addData(databaseNodeInfo, static_cast(localOnlineUser->databaseUser), odhtdb::DataView(serializer.getBuffer().data(), serializer.getBuffer().size())); database->commit(); } else addLocalMessage(msg, localUser, 0); } void Channel::addUserLocally(User *user) { users.push_back(user); if(user->type == User::Type::ONLINE) { auto onlineUser = static_cast(user); publicKeyOnlineUsersMap[onlineUser->databaseUser->getPublicKey()] = onlineUser; } } bool Channel::addUser(const odhtdb::Signature::PublicKey &userId, const string &groupId) { assert(database); if(!database || localUser->type != User::Type::ONLINE) return false; if(groupId.size() != odhtdb::GROUP_ID_LENGTH) { fprintf(stderr, "Group id is wrong size. Expected to be %u bytes, was %u byte(s)\n", odhtdb::GROUP_ID_LENGTH, groupId.size()); return false; } auto localOnlineUser = static_cast(localUser); assert(localOnlineUser->databaseUser->getType() == odhtdb::User::Type::LOCAL); uint8_t groupIdRaw[odhtdb::GROUP_ID_LENGTH]; memcpy(groupIdRaw, groupId.data(), groupId.size()); auto groupToAddUserTo = database->getStorage().getGroupById(*databaseNodeInfo.getRequestHash(), groupIdRaw); if(!groupToAddUserTo) { fprintf(stderr, "Group with id %s does not exist in channel %s\n", odhtdb::bin2hex(groupId.c_str(), groupId.size()).c_str(), databaseNodeInfo.getRequestHash()->toString().c_str()); return false; } database->addUser(databaseNodeInfo, static_cast(localOnlineUser->databaseUser), "noname", userId, groupToAddUserTo); return true; } void Channel::replaceLocalUser(User *newLocalUser) { for(vector::iterator it = users.begin(); it != users.end(); ++it) { if(*it == localUser) { users.erase(it); delete localUser; break; } } localUser = newLocalUser; addUserLocally(newLocalUser); } void Channel::changeNick(const std::string &newNick) { if(database && localUser->type == User::Type::ONLINE) { auto localOnlineUser = static_cast(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(localOnlineUser->databaseUser), odhtdb::DataView(serializer.getBuffer().data(), serializer.getBuffer().size())); database->commit(); } } void Channel::processEvent(const sf::Event &event) { chatbar.processEvent(event, this); messageBoard.processEvent(event); } void Channel::draw(sf::RenderWindow &window, Cache &cache) { messageBoard.draw(window, cache); chatbar.draw(window); } void Channel::setCurrent(Channel *channel) { currentChannel = channel; } Channel* Channel::getCurrent() { return currentChannel; } }