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
|
utility.cpp
|
||||||
serviceBase.cpp
|
serviceBase.cpp
|
||||||
services/nickserv.cpp
|
services/nickserv.cpp
|
||||||
|
services/chanserv.cpp
|
||||||
configParser.cpp
|
configParser.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
16
instance.hpp
16
instance.hpp
|
@ -31,6 +31,7 @@
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
#include <sstream>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -66,6 +67,14 @@ struct ModeSet {
|
||||||
std::string str;
|
std::string str;
|
||||||
std::vector<std::tuple<char, std::string>> params;
|
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>
|
template<bool channelModes>
|
||||||
void parse(std::string_view str, NetworkInfo& netInfo);
|
void parse(std::string_view str, NetworkInfo& netInfo);
|
||||||
};
|
};
|
||||||
|
@ -96,6 +105,13 @@ struct Channel {
|
||||||
.text = std::string(topic)
|
.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 {
|
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 "../instance.hpp"
|
||||||
|
|
||||||
#include <async/result.hpp>
|
#include <async/result.hpp>
|
||||||
|
#include <fmt/format.h>
|
||||||
#include <cryptopp/hex.h>
|
#include <cryptopp/hex.h>
|
||||||
#include <cryptopp/sha.h>
|
#include <cryptopp/sha.h>
|
||||||
#include <cryptopp/pwdbased.h>
|
#include <cryptopp/pwdbased.h>
|
||||||
|
@ -27,6 +28,8 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
using fmt::operator""_format;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async::result<void> NickServ::intitialize() {
|
async::result<void> NickServ::intitialize() {
|
||||||
|
@ -70,7 +73,7 @@ async::result<void> NickServ::intitialize() {
|
||||||
// Get account from storage
|
// Get account from storage
|
||||||
auto accounts_found = storage->get_all<Account>(where(c(&Account::name) == std::string(accountName)));
|
auto accounts_found = storage->get_all<Account>(where(c(&Account::name) == std::string(accountName)));
|
||||||
if (accounts_found.empty()) {
|
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;
|
co_return;
|
||||||
}
|
}
|
||||||
auto& account = accounts_found[0];
|
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_await i->send_event(user.get_notice("Error: Passwords may not contain spaces!", sender->uid));
|
||||||
co_return;
|
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));
|
auto accounts_found = storage->get_all<Account>(where(c(&Account::name) == sender->nick));
|
||||||
if (!accounts_found.empty()) {
|
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;
|
co_return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,7 +114,7 @@ async::result<void> NickServ::intitialize() {
|
||||||
.password_hash = pwdHash(args[0])
|
.password_hash = pwdHash(args[0])
|
||||||
});
|
});
|
||||||
// Report success
|
// 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}
|
}, "<password> <email>", 2, false}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -20,11 +20,10 @@
|
||||||
#include "../instance.hpp"
|
#include "../instance.hpp"
|
||||||
#include "../serviceBase.hpp"
|
#include "../serviceBase.hpp"
|
||||||
|
|
||||||
#include "sqlite_orm.h"
|
|
||||||
|
|
||||||
#include <async/result.hpp>
|
#include <async/result.hpp>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#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 {
|
class NickServ : public ServiceBase {
|
||||||
std::unique_ptr<Storage> storage;
|
std::unique_ptr<Storage> storage;
|
||||||
|
|
||||||
User user;
|
User user;
|
||||||
|
|
||||||
virtual async::result<void> intitialize() override;
|
virtual async::result<void> intitialize() override;
|
||||||
|
|
Loading…
Add table
Reference in a new issue