/* * 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 . */ #include "chanserv.hpp" #include "../instance.hpp" #include #include #include #include #include #include using fmt::operator""_format; async::result 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("+o {}"_format(user.uid.str()), i->netInfo); using namespace sqlite_orm; storage = std::make_unique(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 args) -> async::result { // 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(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); }, "", 1, true} }, }; co_await mark_ready(user); } async::result 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("+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)); }