diff --git a/plugins/plugin_bridge.cpp b/plugins/plugin_bridge.cpp index d661a93..8a7eb0b 100644 --- a/plugins/plugin_bridge.cpp +++ b/plugins/plugin_bridge.cpp @@ -28,14 +28,16 @@ SOLANA_PLUGIN_EXPORT uint32_t solana_plugin_start(struct SolanaAPI* solana_api) return 1; } - Contact3Registry* cr; + Contact3Registry* cr = nullptr; RegistryMessageModel* rmm = nullptr; ConfigModelI* conf = nullptr; + MessageCommandDispatcher* mcd = nullptr; { // make sure required types are loaded cr = RESOLVE_INSTANCE(Contact3Registry); rmm = RESOLVE_INSTANCE(RegistryMessageModel); conf = RESOLVE_INSTANCE(ConfigModelI); + mcd = RESOLVE_INSTANCE(MessageCommandDispatcher); if (cr == nullptr) { std::cerr << "PLUGIN Bridge missing Contact3Registry\n"; @@ -51,11 +53,13 @@ SOLANA_PLUGIN_EXPORT uint32_t solana_plugin_start(struct SolanaAPI* solana_api) std::cerr << "PLUGIN Bridge missing ConfigModelI\n"; return 2; } + + // missing mcd is no error } // static store, could be anywhere tho // construct with fetched dependencies - g_bridge = std::make_unique(*cr, *rmm, *conf); + g_bridge = std::make_unique(*cr, *rmm, *conf, mcd); // register types PROVIDE_INSTANCE(Bridge, "Bridge", g_bridge.get()); diff --git a/src/bridge.cpp b/src/bridge.cpp index 1342900..2a39218 100644 --- a/src/bridge.cpp +++ b/src/bridge.cpp @@ -4,14 +4,16 @@ #include #include #include +#include #include Bridge::Bridge( Contact3Registry& cr, RegistryMessageModel& rmm, - ConfigModelI& conf -) : _cr(cr), _rmm(rmm), _conf(conf) { + ConfigModelI& conf, + MessageCommandDispatcher* mcd +) : _cr(cr), _rmm(rmm), _conf(conf), _mcd(mcd) { _rmm.subscribe(this, enumType::message_construct); if (!_conf.has_bool("Bridge", "username_angle_brackets")) { @@ -40,6 +42,8 @@ Bridge::Bridge( } updateVGroups(); + + registerCommands(); } Bridge::~Bridge(void) { @@ -79,6 +83,101 @@ void Bridge::updateVGroups(void) { } } +void Bridge::registerCommands(void) { + if (_mcd == nullptr) { + return; + } + + _mcd->registerCommand( + "Bridge", "bridge", + "users", + [this](std::string_view params, Message3Handle m) -> bool { + const auto contact_from = m.get().c; + const auto contact_to = m.get().c; + + // TODO: if no vgroup name supplied + + Contact3Handle group_contact; + if (/*is public ?*/ _c_to_vg.count({_cr, contact_to})) { + // message was sent public in group + group_contact = {_cr, contact_to}; + } else if (_cr.all_of(contact_from)) { + // use parent of sender + group_contact = {_cr, _cr.get(contact_from).parent}; + } else if (false /* parent of contact_to ? */) { + } + + if (!_c_to_vg.count(group_contact)) { + // nope + _rmm.sendText( + contact_from, + "It appears you are not bridged or forgot to supply the vgroup name!" + ); + return true; + } + + assert(static_cast(group_contact)); + const auto& vg = _vgroups.at(_c_to_vg.at(group_contact)); + + _rmm.sendText( + contact_from, + "Contacts online in other bridged group(s) in vgroup '" + vg.vg_name + "'" + ); + for (const auto& vgc : vg.contacts) { + if (vgc.c == group_contact) { + // skip self + continue; + } + + if (vgc.c.all_of()) { + _rmm.sendText( + contact_from, + " online in '" + + (vgc.c.all_of() ? vgc.c.get().name : "") + + "' id:" + bin2hex(vgc.id) + ); + + // for each sub contact + for (const auto& sub_c : vgc.c.get().subs) { + if ( + const auto* sub_cs = _cr.try_get(sub_c); + sub_cs != nullptr && sub_cs->state == Contact::Components::ConnectionState::disconnected + ) { + // skip offline + continue; + } + + _rmm.sendText( + contact_from, + " '" + + (_cr.all_of(sub_c) ? _cr.get(sub_c).name : "") + + "'" + + (_cr.all_of(sub_c) ? " id:" + bin2hex(vgc.id) : "") + ); + } + + } else { // contact without parent + _rmm.sendText( + contact_from, + " online contact '" + + (vgc.c.all_of() ? vgc.c.get().name : "") + + "' id:" + bin2hex(vgc.id) + ); + } + } + return true; + }, + "List users connected in the other bridged group(s).", + MessageCommandDispatcher::Perms::EVERYONE // TODO: should proably be MODERATOR + ); + + std::cout << "Bridge: registered commands\n"; +} + +const Bridge::VirtualGroups* Bridge::findVGforContact(const Contact3Handle& c) { + return nullptr; +} + bool Bridge::onEvent(const Message::Events::MessageConstruct& e) { if (!e.e.valid()) { return false; // how diff --git a/src/bridge.hpp b/src/bridge.hpp index 1aeb054..c1b92a2 100644 --- a/src/bridge.hpp +++ b/src/bridge.hpp @@ -1,7 +1,7 @@ #pragma once -#include #include +#include #include #include @@ -10,11 +10,13 @@ // fwd struct ConfigModelI; +class MessageCommandDispatcher; class Bridge : public RegistryMessageModelEventI { Contact3Registry& _cr; RegistryMessageModel& _rmm; ConfigModelI& _conf; + MessageCommandDispatcher* _mcd; struct VirtualGroups { struct VContact { @@ -35,7 +37,8 @@ class Bridge : public RegistryMessageModelEventI { Bridge( Contact3Registry& cr, RegistryMessageModel& rmm, - ConfigModelI& conf + ConfigModelI& conf, + MessageCommandDispatcher* mcd = nullptr ); ~Bridge(void); @@ -43,6 +46,8 @@ class Bridge : public RegistryMessageModelEventI { private: void updateVGroups(void); + void registerCommands(void); + const VirtualGroups* findVGforContact(const Contact3Handle& c); protected: // mm bool onEvent(const Message::Events::MessageConstruct& e) override;