1
0
Fork 0
mirror of https://gitlab.com/niansa/asbots.git synced 2025-03-06 20:48:25 +01:00
asbots/services/chanserv.cpp

106 lines
4.6 KiB
C++

/*
* asbots
* Copyright (C) 2021 niansa
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "chanserv.hpp"
#include "../instance.hpp"
#include <async/result.hpp>
#include <fmt/format.h>
#include <string>
#include <string_view>
#include <vector>
#include <memory>
using fmt::operator""_format;
async::result<void> ChanServ::intitialize() {
co_await i->netInfo.wait_ready();
user = {
.server = i->config.server.uid,
.nick = std::string(getConfig("ChanServ", "nickname").value_or("ChanServ")),
.realhost = i->config.server.name,
.uid = uuid,
.realname = i->netInfo.name
};
opMe.parse<true>("+o {}"_format(user.uid.str()), i->netInfo);
using namespace sqlite_orm;
storage = std::make_unique<Storage>(make_storage(
std::string(getConfig("ChanServ", "database").value_or("chanserv.sqlite")),
make_table("users",
make_column("id", &ChannelReg::id, autoincrement(), primary_key()),
make_column("name", &ChannelReg::name),
make_column("owner", &ChannelReg::owner))
));
storage->sync_schema();
commands = {
{"register", {[this] (User *sender, std::vector<std::string_view> args) -> async::result<void> {
// Get channel
Channel *channel;
{
auto res = i->cache.find_channel_by_name(args[0]);
if (res == i->cache.channels.end()) {
co_await i->send_event(user.get_notice("Error: {} does not exist!"_format(args[0]), sender->uid));
co_return;
}
channel = res->get();
}
// Check if user is operator in the channel
// TODO
// Check that account does not exist already
{
auto channelregs_found = storage->get_all<ChannelReg>(where(c(&ChannelReg::name) == std::string(args[0])));
if (!channelregs_found.empty()) {
co_await i->send_event(user.get_notice("Error: {} has already been registered!"_format(args[0]), sender->uid));
co_return;
}
}
// Append it to database
ChannelReg reg = {
.name = std::string(args[0]),
.owner = sender->nick
};
storage->insert(reg);
// Report success
co_await i->send_event(user.get_notice("{} has been registered!"_format(args[0]), sender->uid));
// Initialize channel
co_await initializeChannel(channel, reg);
}, "<channel>", 1, true}
},
};
co_await mark_ready(user);
}
async::result<void> ChanServ::initializeChannel(Channel *channel, const ChannelReg& channelReg) {
// Get all owners nicks mode +o
ModeSet initialModes;
for (const auto& member : channel->members) {
if (member->loginName.has_value() && member->loginName.value() == channelReg.owner) {
initialModes.parse<true>("+o {}"_format(member->uid.str()), i->netInfo);
}
}
// Join the channel
auto je = channel->get_sjoin(user.uid, i->config.server.uid); // Needs to be done seperately to avoid some... super weird... crash
co_await i->send_event(je);
// Grant owners nicks OP
co_await i->send_event(channel->get_tmode(initialModes, user.uid));
}