mirror of
https://gitlab.com/niansa/asbots.git
synced 2025-03-06 20:48:25 +01:00
Code that makes gcc crash... commited for bug reporting
This commit is contained in:
parent
14163753e5
commit
8773d0b886
6 changed files with 171 additions and 7 deletions
|
@ -11,6 +11,7 @@ add_executable(asbots
|
|||
utility.cpp
|
||||
serviceBase.cpp
|
||||
services/nickserv.cpp
|
||||
services/chanserv.cpp
|
||||
configParser.cpp
|
||||
)
|
||||
|
||||
|
|
16
instance.hpp
16
instance.hpp
|
@ -31,6 +31,7 @@
|
|||
#include <fmt/format.h>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <sstream>
|
||||
#include <optional>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
@ -66,6 +67,14 @@ struct ModeSet {
|
|||
std::string str;
|
||||
std::vector<std::tuple<char, std::string>> params;
|
||||
|
||||
std::string fullStr() const {
|
||||
std::ostringstream o;
|
||||
o << str;
|
||||
for (const auto& [mode, param] : params) {
|
||||
o << ' ' << param;
|
||||
}
|
||||
return o.str();
|
||||
}
|
||||
template<bool channelModes>
|
||||
void parse(std::string_view str, NetworkInfo& netInfo);
|
||||
};
|
||||
|
@ -96,6 +105,13 @@ struct Channel {
|
|||
.text = std::string(topic)
|
||||
};
|
||||
}
|
||||
Event get_tmode(const ModeSet& modes, const UUID& user) const {
|
||||
return {
|
||||
.sender = user,
|
||||
.name = "TMODE",
|
||||
.raw_args = fmt::format("{} {} {}", time(nullptr), name, modes.fullStr())
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
struct User {
|
||||
|
|
101
services/chanserv.cpp
Normal file
101
services/chanserv.cpp
Normal file
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* 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
|
||||
};
|
||||
co_await mark_ready(user);
|
||||
|
||||
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] (u_User& sender, std::vector<std::string_view> args) -> async::result<void> {
|
||||
// Get channel
|
||||
u_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;
|
||||
}
|
||||
// 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(sender->nick), 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}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
async::result<void> ChanServ::initializeChannel(u_Channel *channel, const ChannelReg& channelReg) {
|
||||
// We need to loop twice because co_await'ing inside a loop through a non-local dynamically-sized container is DANGEROUS
|
||||
std::vector<u_User*> to_mark_as_admin;
|
||||
for (const auto member : channel->get()->members) {
|
||||
if (member->get()->loginName.value_or("") == channelReg.owner) {
|
||||
to_mark_as_admin.push_back(member);
|
||||
}
|
||||
}
|
||||
for (const auto member : to_mark_as_admin) {
|
||||
co_await i->send_event(channel->get()->get_tmode({"o", {std::tuple<char, std::string>{'o', member->get()->uid.str()}}}, member->get()->uid));
|
||||
}
|
||||
}
|
45
services/chanserv.hpp
Normal file
45
services/chanserv.hpp
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
#ifndef _TEST_HPP
|
||||
#define _TEST_HPP
|
||||
#include "../instance.hpp"
|
||||
#include "../serviceBase.hpp"
|
||||
|
||||
#include <async/result.hpp>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include "sqlite_orm.h"
|
||||
|
||||
|
||||
|
||||
struct ChannelReg {
|
||||
int id = -1;
|
||||
std::string name, owner;
|
||||
};
|
||||
|
||||
using Storage = sqlite_orm::internal::storage_t<sqlite_orm::internal::table_t<ChannelReg, sqlite_orm::internal::column_t<ChannelReg, int, const int& (ChannelReg::*)() const, void (ChannelReg::*)(int), sqlite_orm::constraints::autoincrement_t, sqlite_orm::constraints::primary_key_t<> >, sqlite_orm::internal::column_t<ChannelReg, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >& (ChannelReg::*)() const, void (ChannelReg::*)(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)>, sqlite_orm::internal::column_t<ChannelReg, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >& (ChannelReg::*)() const, void (ChannelReg::*)(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)> > >;
|
||||
|
||||
class ChanServ : public ServiceBase {
|
||||
std::unique_ptr<Storage> storage;
|
||||
User user;
|
||||
|
||||
virtual async::result<void> intitialize() override;
|
||||
|
||||
async::result<void> initializeChannel(u_Channel *channel, const ChannelReg& channelReg);
|
||||
};
|
||||
#endif
|
|
@ -19,6 +19,7 @@
|
|||
#include "../instance.hpp"
|
||||
|
||||
#include <async/result.hpp>
|
||||
#include <fmt/format.h>
|
||||
#include <cryptopp/hex.h>
|
||||
#include <cryptopp/sha.h>
|
||||
#include <cryptopp/pwdbased.h>
|
||||
|
@ -27,6 +28,8 @@
|
|||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
using fmt::operator""_format;
|
||||
|
||||
|
||||
|
||||
async::result<void> NickServ::intitialize() {
|
||||
|
@ -70,7 +73,7 @@ async::result<void> NickServ::intitialize() {
|
|||
// Get account from storage
|
||||
auto accounts_found = storage->get_all<Account>(where(c(&Account::name) == std::string(accountName)));
|
||||
if (accounts_found.empty()) {
|
||||
co_await i->send_event(user.get_notice("Error: '"+std::string(accountName)+"' is not registered!", sender->uid));
|
||||
co_await i->send_event(user.get_notice("Error: {} is not registered!"_format(accountName), sender->uid));
|
||||
co_return;
|
||||
}
|
||||
auto& account = accounts_found[0];
|
||||
|
@ -96,11 +99,11 @@ async::result<void> NickServ::intitialize() {
|
|||
co_await i->send_event(user.get_notice("Error: Passwords may not contain spaces!", sender->uid));
|
||||
co_return;
|
||||
}
|
||||
// Check that user does not exist already
|
||||
// Check that account does not exist already
|
||||
{
|
||||
auto accounts_found = storage->get_all<Account>(where(c(&Account::name) == sender->nick));
|
||||
if (!accounts_found.empty()) {
|
||||
co_await i->send_event(user.get_notice("Error: This nick has already been registered!", sender->uid));
|
||||
co_await i->send_event(user.get_notice("Error: {} has already been registered!"_format(sender->nick), sender->uid));
|
||||
co_return;
|
||||
}
|
||||
}
|
||||
|
@ -111,7 +114,7 @@ async::result<void> NickServ::intitialize() {
|
|||
.password_hash = pwdHash(args[0])
|
||||
});
|
||||
// Report success
|
||||
co_await i->send_event(user.get_notice("Your nickname has been registered!", sender->uid));
|
||||
co_await i->send_event(user.get_notice("{} has been registered!"_format(sender->nick), sender->uid));
|
||||
}, "<password> <email>", 2, false}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -20,11 +20,10 @@
|
|||
#include "../instance.hpp"
|
||||
#include "../serviceBase.hpp"
|
||||
|
||||
#include "sqlite_orm.h"
|
||||
|
||||
#include <async/result.hpp>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include "sqlite_orm.h"
|
||||
|
||||
|
||||
|
||||
|
@ -37,7 +36,6 @@ using Storage = sqlite_orm::internal::storage_t<sqlite_orm::internal::table_t<Ac
|
|||
|
||||
class NickServ : public ServiceBase {
|
||||
std::unique_ptr<Storage> storage;
|
||||
|
||||
User user;
|
||||
|
||||
virtual async::result<void> intitialize() override;
|
||||
|
|
Loading…
Add table
Reference in a new issue