summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRoman Smrž <roman.smrz@seznam.cz>2023-05-23 22:11:42 +0200
committerRoman Smrž <roman.smrz@seznam.cz>2023-05-23 22:32:01 +0200
commit15ad6ae7bd64d8d7319d75dbbb0827addd22fef2 (patch)
treec5f7ac828f4c1d5f51c461ad332b83e570ce3b26 /src
parentfce349f8f1c53d3e205a8d86b79784fdfd2b7b7a (diff)
Message sending to identity or contact
Diffstat (limited to 'src')
-rw-r--r--src/main.cpp50
-rw-r--r--src/message.cpp30
-rw-r--r--src/network.cpp14
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));