2018-03-02 12:51:10 +01:00
|
|
|
// Matrix Construct
|
|
|
|
//
|
|
|
|
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
|
|
|
// Copyright (C) 2016-2018 Jason Volk <jason@zemos.net>
|
|
|
|
//
|
|
|
|
// 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
|
|
|
|
{
|
2018-03-17 07:48:05 +01:00
|
|
|
"Server Control"
|
2018-03-02 12:51:10 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
const ircd::m::room::id::buf
|
2018-03-05 11:44:03 +01:00
|
|
|
control_room_id
|
|
|
|
{
|
|
|
|
"!control", ircd::my_host()
|
|
|
|
};
|
|
|
|
|
|
|
|
const m::room
|
|
|
|
control_room
|
2018-03-02 12:51:10 +01:00
|
|
|
{
|
2018-03-05 11:44:03 +01:00
|
|
|
control_room_id
|
2018-03-02 12:51:10 +01:00
|
|
|
};
|
|
|
|
|
2018-03-05 11:44:03 +01:00
|
|
|
const ircd::m::room::id::buf
|
|
|
|
conf_room_id
|
2018-03-02 12:51:10 +01:00
|
|
|
{
|
2018-03-05 11:44:03 +01:00
|
|
|
"!conf", ircd::my_host()
|
2018-03-02 12:51:10 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
|
|
|
_conf_set(const m::event &event,
|
|
|
|
const string_view &key,
|
|
|
|
const string_view &val)
|
|
|
|
{
|
2018-03-22 22:43:18 +01:00
|
|
|
const auto &sender
|
|
|
|
{
|
|
|
|
at<"sender"_>(event)
|
|
|
|
};
|
|
|
|
|
|
|
|
using prototype = m::event::id::buf (const m::user::id &,
|
|
|
|
const string_view &key,
|
|
|
|
const string_view &val);
|
|
|
|
|
|
|
|
static import<prototype> set_conf_item
|
|
|
|
{
|
|
|
|
"s_conf", "set_conf_item"
|
|
|
|
};
|
|
|
|
|
2018-03-02 12:51:10 +01:00
|
|
|
const auto event_id
|
|
|
|
{
|
2018-03-22 22:43:18 +01:00
|
|
|
set_conf_item(sender, key, val)
|
2018-03-02 12:51:10 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
char kvbuf[768];
|
2018-03-05 11:44:03 +01:00
|
|
|
notice(control_room, fmt::sprintf
|
2018-03-02 12:51:10 +01:00
|
|
|
{
|
|
|
|
kvbuf, "[%s] %s = %s", string_view{event_id}, key, val
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_conf_get(const m::event &event,
|
|
|
|
const string_view &key)
|
|
|
|
{
|
2018-03-22 22:43:18 +01:00
|
|
|
using closure = std::function<void (const string_view &val)>;
|
|
|
|
using prototype = void (const string_view &key,
|
|
|
|
const closure &);
|
|
|
|
|
|
|
|
static import<prototype> get_conf_item
|
2018-03-02 12:51:10 +01:00
|
|
|
{
|
2018-03-22 22:43:18 +01:00
|
|
|
"s_conf", "get_conf_item"
|
|
|
|
};
|
2018-03-02 12:51:10 +01:00
|
|
|
|
2018-03-22 22:43:18 +01:00
|
|
|
get_conf_item(key, [&key]
|
|
|
|
(const string_view &value)
|
|
|
|
{
|
2018-03-05 11:44:03 +01:00
|
|
|
char kvbuf[256];
|
|
|
|
notice(control_room, fmt::sprintf
|
|
|
|
{
|
|
|
|
kvbuf, "%s = %s", key, value
|
|
|
|
});
|
2018-03-02 12:51:10 +01:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_conf_list(const m::event &event)
|
|
|
|
{
|
|
|
|
char val[512];
|
|
|
|
std::stringstream ss;
|
2018-03-22 23:16:40 +01:00
|
|
|
ss << "<table>";
|
2018-03-02 12:51:10 +01:00
|
|
|
for(const auto &p : conf::items)
|
2018-03-22 23:16:40 +01:00
|
|
|
ss << "<tr><td>" << std::setw(32) << std::right << p.first
|
|
|
|
<< "</td><td>" << p.second->get(val)
|
|
|
|
<< "</td></tr>";
|
|
|
|
ss << "</table>";
|
2018-03-02 12:51:10 +01:00
|
|
|
|
2018-03-05 11:44:03 +01:00
|
|
|
msghtml(control_room, m::me.user_id, ss.str());
|
2018-03-02 12:51:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2018-03-05 11:44:03 +01:00
|
|
|
_cmd__conf(const m::event &event,
|
|
|
|
const string_view &line)
|
2018-03-02 12:51:10 +01:00
|
|
|
{
|
|
|
|
string_view tokens[4];
|
|
|
|
const size_t count
|
|
|
|
{
|
2018-03-05 11:44:03 +01:00
|
|
|
ircd::tokens(line, ' ', tokens)
|
2018-03-02 12:51:10 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
const auto &cmd{tokens[0]};
|
|
|
|
const auto &key{tokens[1]};
|
|
|
|
const auto &val{tokens[3]};
|
|
|
|
|
|
|
|
if(cmd == "set" && count >= 4)
|
|
|
|
return _conf_set(event, key, val);
|
|
|
|
|
|
|
|
if(cmd == "get" && count >= 2)
|
|
|
|
return _conf_get(event, key);
|
|
|
|
|
2018-03-05 11:44:03 +01:00
|
|
|
if(cmd == "list")
|
2018-03-02 12:51:10 +01:00
|
|
|
return _conf_list(event);
|
|
|
|
}
|
|
|
|
|
2018-03-05 11:44:03 +01:00
|
|
|
static void
|
|
|
|
_cmd__die(const m::event &event,
|
|
|
|
const string_view &line)
|
|
|
|
{
|
|
|
|
ircd::post([]
|
|
|
|
{
|
|
|
|
ircd::quit();
|
|
|
|
});
|
|
|
|
|
|
|
|
ctx::yield();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
command_control(const m::event &event)
|
2018-03-26 03:12:17 +02:00
|
|
|
noexcept try
|
2018-03-05 11:44:03 +01:00
|
|
|
{
|
|
|
|
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));
|
|
|
|
}
|
2018-03-26 03:12:17 +02:00
|
|
|
|
|
|
|
const ircd::module console_module
|
|
|
|
{
|
|
|
|
"console"
|
|
|
|
};
|
|
|
|
|
2018-03-26 09:12:16 +02:00
|
|
|
using prototype = int (std::ostream &, const string_view &, const string_view &);
|
2018-03-26 08:23:30 +02:00
|
|
|
const mods::import<prototype> command
|
2018-03-26 03:12:17 +02:00
|
|
|
{
|
|
|
|
*console_module, "console_command"
|
|
|
|
};
|
|
|
|
|
2018-03-26 08:23:30 +02:00
|
|
|
const unique_buffer<mutable_buffer> buf{32_KiB};
|
|
|
|
std::ostringstream out;
|
|
|
|
pubsetbuf(out, buf);
|
2018-03-26 03:12:17 +02:00
|
|
|
|
2018-03-26 08:23:30 +02:00
|
|
|
out << "<pre>";
|
2018-03-26 09:33:26 +02:00
|
|
|
static const string_view opts{"html"};
|
|
|
|
command(out, body, opts);
|
2018-03-26 08:23:30 +02:00
|
|
|
out << "</pre>";
|
|
|
|
|
|
|
|
const auto str //TODO: X
|
|
|
|
{
|
|
|
|
replace(view(out, buf), '\n', "<br />")
|
|
|
|
};
|
|
|
|
|
|
|
|
const string_view alt //TODO: X
|
|
|
|
{
|
|
|
|
"no alt text"
|
|
|
|
};
|
|
|
|
|
|
|
|
msghtml(control_room, m::me.user_id, str, alt);
|
2018-03-26 03:12:17 +02:00
|
|
|
}
|
|
|
|
catch(const std::exception &e)
|
|
|
|
{
|
|
|
|
notice(control_room, e.what());
|
2018-03-05 11:44:03 +01:00
|
|
|
}
|
|
|
|
|
2018-03-02 12:51:10 +01:00
|
|
|
const m::hook
|
2018-03-05 11:44:03 +01:00
|
|
|
command_control_hook
|
2018-03-02 12:51:10 +01:00
|
|
|
{
|
2018-03-05 11:44:03 +01:00
|
|
|
command_control,
|
2018-03-02 12:51:10 +01:00
|
|
|
{
|
2018-03-16 21:27:25 +01:00
|
|
|
{ "_site", "vm.notify" },
|
2018-03-03 11:38:05 +01:00
|
|
|
{ "room_id", "!control" },
|
|
|
|
{ "type", "m.room.message" },
|
2018-03-03 08:17:14 +01:00
|
|
|
{ "content",
|
|
|
|
{
|
|
|
|
{ "msgtype", "m.text" }
|
|
|
|
}}
|
|
|
|
}
|
2018-03-02 12:51:10 +01:00
|
|
|
};
|
|
|
|
|
2018-03-05 11:44:03 +01:00
|
|
|
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.");
|
|
|
|
}
|
|
|
|
|
2018-03-02 12:51:10 +01:00
|
|
|
const m::hook
|
2018-03-05 11:44:03 +01:00
|
|
|
create_control_hook
|
2018-03-02 12:51:10 +01:00
|
|
|
{
|
2018-03-05 11:44:03 +01:00
|
|
|
create_control_room,
|
2018-03-02 12:51:10 +01:00
|
|
|
{
|
2018-03-16 21:27:25 +01:00
|
|
|
{ "_site", "vm.notify" },
|
2018-03-03 11:38:05 +01:00
|
|
|
{ "room_id", "!ircd" },
|
|
|
|
{ "type", "m.room.create" },
|
2018-03-03 08:17:14 +01:00
|
|
|
}
|
2018-03-02 12:51:10 +01:00
|
|
|
};
|