diff options
author | Roman Smrž <roman.smrz@seznam.cz> | 2023-05-23 22:11:42 +0200 |
---|---|---|
committer | Roman Smrž <roman.smrz@seznam.cz> | 2023-05-23 22:32:01 +0200 |
commit | 15ad6ae7bd64d8d7319d75dbbb0827addd22fef2 (patch) | |
tree | c5f7ac828f4c1d5f51c461ad332b83e570ce3b26 /src | |
parent | fce349f8f1c53d3e205a8d86b79784fdfd2b7b7a (diff) |
Message sending to identity or contact
Diffstat (limited to 'src')
-rw-r--r-- | src/main.cpp | 50 | ||||
-rw-r--r-- | src/message.cpp | 30 | ||||
-rw-r--r-- | src/network.cpp | 14 |
3 files changed, 69 insertions, 25 deletions
diff --git a/src/main.cpp b/src/main.cpp index f33bcc4..cc02b55 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -104,6 +104,22 @@ TestPeer & getPeer(const Peer & peer) throw invalid_argument("peer not found"); } +Contact getContact(const string & id) +{ + auto cmp = [](const Contact & x, const Contact & y) { + return x.data() < y.data(); + }; + for (const auto & c : h->behavior().lens<SharedState>().lens<Set<Contact>>().get().view(cmp)) { + if (string(c.leastRoot()) == id) { + return c; + } + } + + ostringstream ss; + ss << "contact '" << id << "' not found"; + throw invalid_argument(ss.str().c_str()); +} + struct Command { string name; @@ -505,22 +521,16 @@ void contactSetName(const vector<string> & args) auto id = args.at(0); auto name = args.at(1); - auto cmp = [](const Contact & x, const Contact & y) { - return x.data() < y.data(); - }; - for (const auto & c : h->behavior().lens<SharedState>().lens<Set<Contact>>().get().view(cmp)) { - if (string(c.leastRoot()) == id) { - auto nh = h->update([&] (const Stored<LocalState> & loc) { - auto st = loc.ref().storage(); - auto cc = c.customName(st, name); - auto contacts = loc->shared<Set<Contact>>(); - return st.store(loc->shared<Set<Contact>>(contacts.add(st, cc))); - }); - if (nh) - *h = *nh; - break; - } - } + auto c = getContact(id); + auto nh = h->update([&] (const Stored<LocalState> & loc) { + auto st = loc.ref().storage(); + auto cc = c.customName(st, name); + auto contacts = loc->shared<Set<Contact>>(); + return st.store(loc->shared<Set<Contact>>(contacts.add(st, cc))); + }); + if (nh) + *h = *nh; + printLine("contact-set-name-done"); } @@ -531,6 +541,13 @@ void dmSendPeer(const vector<string> & args) args.at(1)); } +void dmSendContact(const vector<string> & args) +{ + server->svc<DirectMessageService>().send( + getContact(args.at(0)), + args.at(1)); +} + vector<Command> commands = { { "store", store }, { "stored-generation", storedGeneration }, @@ -556,6 +573,7 @@ vector<Command> commands = { { "contact-list", contactList }, { "contact-set-name", contactSetName }, { "dm-send-peer", dmSendPeer }, + { "dm-send-contact", dmSendContact }, }; } diff --git a/src/message.cpp b/src/message.cpp index dd4f9d5..ff8e05b 100644 --- a/src/message.cpp +++ b/src/message.cpp @@ -1,5 +1,6 @@ #include "message.h" +#include <erebos/contact.h> #include <erebos/network.h> using namespace erebos; @@ -246,26 +247,37 @@ DirectMessageThread DirectMessageService::thread(const Identity & peer) return DirectMessageThread::Priv::getThreadLocked(peer.finalOwner()); } -DirectMessage DirectMessageService::send(const Peer & peer, const string & text) +DirectMessage DirectMessageService::send(const Identity & to, const string & text) { - auto pid = peer.identity(); - if (!pid) - throw std::runtime_error("Peer without known identity"); - auto powner = pid->finalOwner(); - scoped_lock lock(threadLock); auto msg = server.localHead().ref().storage().store(DirectMessageData { - .prev = DirectMessageThread::Priv::getThreadLocked(powner).p->head, + .prev = DirectMessageThread::Priv::getThreadLocked(to).p->head, .from = server.identity().finalOwner(), .time = ZonedTime::now(), .text = text, }); - DirectMessageThread::Priv::updateThreadLocked(powner, { msg }); - peer.send(myUUID, msg.ref()); + DirectMessageThread::Priv::updateThreadLocked(to, { msg }); + + if (auto peer = server.peer(to)) + peer->send(myUUID, msg.ref()); return DirectMessage(new DirectMessage::Priv { .data = msg, }); } + +DirectMessage DirectMessageService::send(const Contact & to, const string & text) +{ + if (auto id = to.identity()) + return send(*id, text); + throw std::runtime_error("contact without erebos identity"); +} + +DirectMessage DirectMessageService::send(const Peer & to, const string & text) +{ + if (auto id = to.identity()) + return send(id->finalOwner(), text); + throw std::runtime_error("peer without known identity"); +} diff --git a/src/network.cpp b/src/network.cpp index 1eb33d0..929908a 100644 --- a/src/network.cpp +++ b/src/network.cpp @@ -73,6 +73,20 @@ PeerList & Server::peerList() const return p->plist; } +optional<Peer> Server::peer(const Identity & identity) const +{ + scoped_lock lock(p->dataMutex); + + for (auto & peer : p->peers) { + const auto & pid = peer->identity; + if (holds_alternative<Identity>(pid)) + if (std::get<Identity>(pid).finalOwner().sameAs(identity)) + return peer->lpeer; + } + + return nullopt; +} + void Server::addPeer(const string & node) const { return addPeer(node, to_string(Priv::discoveryPort)); |