diff --git a/construct/console.cc b/construct/console.cc index d3b8f2f1a..bde7223fb 100644 --- a/construct/console.cc +++ b/construct/console.cc @@ -76,7 +76,7 @@ console_init() console_cancel(); console_active = true; console_ctx = &ctx::cur(); - console_module = new ircd::module{"console"}; + console_module = new ircd::module{"s_console"}; } void diff --git a/ircd/m/m.cc b/ircd/m/m.cc index c2e7f096e..b0dedd758 100644 --- a/ircd/m/m.cc +++ b/ircd/m/m.cc @@ -111,10 +111,9 @@ ircd::m::init::modules() { const string_view prefixes[] { - "m_", "client_", "key_", "federation_", "media_" + "s_", "m_", "client_", "key_", "federation_", "media_" }; - m::modules.emplace("conf"s, "conf"s); for(const auto &name : mods::available()) if(startswith_any(name, std::begin(prefixes), std::end(prefixes))) m::modules.emplace(name, name); @@ -213,13 +212,6 @@ ircd::m::init::bootstrap() { "topic", "The daemon's den." } }); - create(control, me.user_id); - join(control, me.user_id); - send(control, me.user_id, "m.room.name", "", - { - { "name", "Control Room" } - }); - send(user::users, me.user_id, "m.room.name", "", { { "name", "Users" } @@ -232,9 +224,6 @@ ircd::m::init::bootstrap() }); _keys.bootstrap(); - - notice(control, me.user_id, "Welcome to the control room."); - notice(control, me.user_id, "I am the daemon. You can talk to me in this room by highlighting me."); } bool diff --git a/modules/Makefile.am b/modules/Makefile.am index 25e784a75..f2dbc715f 100644 --- a/modules/Makefile.am +++ b/modules/Makefile.am @@ -37,21 +37,34 @@ AM_LDFLAGS += \ ############################################################################### # -# (TBD) equipment +# Server modules +# + +s_moduledir = @moduledir@ + +s_console_la_SOURCES = s_console.cc +s_conf_la_SOURCES = s_conf.cc +s_control_la_SOURCES = s_control.cc + +s_module_LTLIBRARIES = \ + s_console.la \ + s_conf.la \ + s_control.la \ + ### + +############################################################################### +# +# Messages / protocol # -# This puts the source in vm/ but the installed -# library is vm_X.so in the main modules dir. m_moduledir = @moduledir@ -console_la_SOURCES = console.cc -conf_la_SOURCES = conf.cc m_noop_la_SOURCES = m_noop.cc +m_presence_la_SOURCES = m_presence.cc m_module_LTLIBRARIES = \ - console.la \ - conf.la \ m_noop.la \ + m_presence.la \ ### ############################################################################### diff --git a/modules/s_conf.cc b/modules/s_conf.cc new file mode 100644 index 000000000..0ed6b8eb4 --- /dev/null +++ b/modules/s_conf.cc @@ -0,0 +1,121 @@ +// Matrix Construct +// +// Copyright (C) Matrix Construct Developers, Authors & Contributors +// Copyright (C) 2016-2018 Jason Volk +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice is present in all copies. The +// full license for this software is available in the LICENSE file. + +using namespace ircd; + +mapi::header +IRCD_MODULE +{ + "Configuration module" +}; + +const ircd::m::room::id::buf +conf_room_id +{ + "conf", ircd::my_host() +}; + +m::room +conf_room +{ + conf_room_id +}; + +static void +update_conf(const m::event &event) +noexcept +{ + const auto &content + { + at<"content"_>(event) + }; + + const auto &key + { + at<"state_key"_>(event) + }; + + const string_view &value + { + unquote(content.at("value")) + }; + + ircd::conf::set(key, value); +} + +const m::hook +update_conf_hook +{ + update_conf, + { + { "_site", "vm notify" }, + { "room_id", "!conf" }, + { "type", "ircd.conf.item" }, + } +}; + +static void +init_conf_items(const m::event &) +{ + +} + +const m::hook +init_conf_items_hook +{ + init_conf_items, + { + { "_site", "vm notify" }, + { "room_id", "!ircd" }, + { "type", "m.room.member" }, + { "membership", "join" }, + { "state_key", "@ircd" }, + } +}; + +static void +create_conf_item(const string_view &key, + const conf::item<> &item) +{ + thread_local char vbuf[4_KiB]; + const string_view &val + { + item.get(vbuf) + }; + + send(conf_room, m::me.user_id, "ircd.conf.item", key, + { + { "value", val } + }); +} + +static void +create_conf_room(const m::event &) +{ + m::create(conf_room_id, m::me.user_id); + + for(const auto &p : conf::items) + { + const auto &key{p.first}; + const auto &item{p.second}; assert(item); + create_conf_item(key, *item); + } +} + +const m::hook +create_conf_room_hook +{ + create_conf_room, + { + { "_site", "vm notify" }, + { "room_id", "!ircd" }, + { "type", "m.room.create" }, + } +}; diff --git a/modules/console.cc b/modules/s_console.cc similarity index 97% rename from modules/console.cc rename to modules/s_console.cc index 0c2dbb34b..5304f9d74 100644 --- a/modules/console.cc +++ b/modules/s_console.cc @@ -283,6 +283,7 @@ console_cmd__mod_reload(const string_view &line) // static bool console_cmd__db_list(const string_view &line); +static bool console_cmd__db_prop(const string_view &line); bool console_cmd__db(const string_view &line) @@ -294,12 +295,31 @@ console_cmd__db(const string_view &line) switch(hash(token(line, " ", 0))) { + case hash("prop"): + return console_cmd__db_prop(args); + default: case hash("list"): return console_cmd__db_list(args); } } +bool +console_cmd__db_prop(const string_view &line) +{ + const auto dbname + { + token(line, ' ', 0) + }; + + const auto property + { + token(line, ' ', 1) + }; + + return true; +} + bool console_cmd__db_list(const string_view &line) { @@ -976,7 +996,11 @@ console_cmd__exec_file(const string_view &line) id && m::sigil(id) == m::id::USER? id : string_view{} }; - struct m::vm::eval::opts opts; + m::vm::opts opts; + opts.non_conform.set(m::event::conforms::MISSING_PREV_STATE); + opts.non_conform.set(m::event::conforms::MISSING_MEMBERSHIP); + opts.prev_check_exists = false; + opts.notify = false; m::vm::eval eval { opts @@ -1157,6 +1181,11 @@ console_cmd__room__members(const string_view &line) token(line, ' ', 0) }; + const string_view membership + { + token_count(line, ' ') > 1? token(line, ' ', 1) : string_view{} + }; + const m::room room { room_id @@ -1167,10 +1196,15 @@ console_cmd__room__members(const string_view &line) room }; - members.for_each([](const m::event &event) + const auto closure{[](const m::event &event) { out << pretty_oneline(event) << std::endl; - }); + }}; + + if(membership) + members.for_each(membership, closure); + else + members.for_each(closure); return true; } @@ -1210,9 +1244,14 @@ console_cmd__room__state(const string_view &line) token(line, ' ', 0) }; + const auto &event_id + { + token(line, ' ', 1, {}) + }; + const m::room room { - room_id + room_id, event_id }; const m::room::state state diff --git a/modules/conf.cc b/modules/s_control.cc similarity index 55% rename from modules/conf.cc rename to modules/s_control.cc index ea214ab2e..06e2b8b7d 100644 --- a/modules/conf.cc +++ b/modules/s_control.cc @@ -17,15 +17,21 @@ IRCD_MODULE }; const ircd::m::room::id::buf -conf_room_id +control_room_id { - "conf", ircd::my_host() + "!control", ircd::my_host() }; -m::room -conf_room +const m::room +control_room { - conf_room_id + control_room_id +}; + +const ircd::m::room::id::buf +conf_room_id +{ + "!conf", ircd::my_host() }; static void @@ -34,25 +40,23 @@ _conf_set(const m::event &event, const string_view &val) try { - conf::set(key, val); - const auto event_id { - send(conf_room, at<"sender"_>(event), key, + send(conf_room_id, at<"sender"_>(event), "ircd.conf.item", key, { { "value", val } }) }; char kvbuf[768]; - notice(m::control, fmt::sprintf + notice(control_room, fmt::sprintf { kvbuf, "[%s] %s = %s", string_view{event_id}, key, val }); } catch(const std::exception &e) { - notice(m::control, e.what()); + notice(control_room, e.what()); } static void @@ -60,21 +64,25 @@ _conf_get(const m::event &event, const string_view &key) try { - char vbuf[256]; - const auto value + const m::room conf_room{conf_room_id}; + conf_room.get("ircd.conf.item", key, [&key] + (const m::event &event) { - conf::get(key, vbuf) - }; + const auto &value + { + unquote(at<"content"_>(event).at("value")) + }; - char kvbuf[512]; - notice(m::control, fmt::sprintf - { - kvbuf, "%s = %s", key, value + char kvbuf[256]; + notice(control_room, fmt::sprintf + { + kvbuf, "%s = %s", key, value + }); }); } catch(const std::exception &e) { - notice(m::control, e.what()); + notice(control_room, e.what()); } static void @@ -90,31 +98,21 @@ try << "
"; ss << ""; - msghtml(m::control, m::me.user_id, ss.str()); + msghtml(control_room, m::me.user_id, ss.str()); } catch(const std::exception &e) { - notice(m::control, e.what()); + notice(control_room, e.what()); } static void -_update_conf(const m::event &event) -noexcept +_cmd__conf(const m::event &event, + const string_view &line) { - const auto &content - { - at<"content"_>(event) - }; - - const string_view &body - { - unquote(content.at("body")) - }; - string_view tokens[4]; const size_t count { - ircd::tokens(body, ' ', tokens) + ircd::tokens(line, ' ', tokens) }; const auto &cmd{tokens[0]}; @@ -127,14 +125,55 @@ noexcept if(cmd == "get" && count >= 2) return _conf_get(event, key); - if(cmd == "conf") + if(cmd == "list") return _conf_list(event); } -const m::hook -_update_conf_hook +static void +_cmd__die(const m::event &event, + const string_view &line) { - _update_conf, + ircd::post([] + { + ircd::quit(); + }); + + ctx::yield(); +} + +static void +command_control(const m::event &event) +noexcept +{ + const auto &content + { + at<"content"_>(event) + }; + + const string_view &body + { + unquote(content.at("body")) + }; + + const string_view &cmd + { + token(body, ' ', 0, {}) + }; + + switch(hash(cmd)) + { + case hash("conf"): + return _cmd__conf(event, tokens_after(body, ' ', 0)); + + case hash("die"): + return _cmd__die(event, tokens_after(body, ' ', 0)); + } +} + +const m::hook +command_control_hook +{ + command_control, { { "_site", "vm notify" }, { "room_id", "!control" }, @@ -146,16 +185,27 @@ _update_conf_hook } }; -const m::hook -_create_conf_hook +static void +create_control_room(const m::event &) { + create(control_room_id, m::me.user_id); + join(control_room, m::me.user_id); + send(control_room, m::me.user_id, "m.room.name", "", + { + { "name", "Control Room" } + }); + + notice(control_room, m::me.user_id, "Welcome to the control room."); + notice(control_room, m::me.user_id, "I am the daemon. You can talk to me in this room by highlighting me."); +} + +const m::hook +create_control_hook +{ + create_control_room, { { "_site", "vm notify" }, { "room_id", "!ircd" }, { "type", "m.room.create" }, - }, - [](const m::event &) - { - m::create(conf_room_id, m::me.user_id); } };