mirror of
https://gitlab.com/niansa/asbots.git
synced 2025-03-06 20:48:25 +01:00
First signs of NickServ arriving soon! lol
This commit is contained in:
parent
3bb85ee277
commit
def0dc6715
13 changed files with 143 additions and 183 deletions
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
[submodule "sqlite_orm"]
|
||||
path = sqlite_orm
|
||||
url = https://github.com/fnc12/sqlite_orm
|
|
@ -10,14 +10,17 @@ add_executable(asbots
|
|||
instance.cpp
|
||||
utility.cpp
|
||||
serviceBase.cpp
|
||||
services/test.cpp
|
||||
services/nickserv.cpp
|
||||
configParser.cpp
|
||||
)
|
||||
|
||||
target_include_directories(asbots PRIVATE sqlite_orm/include/sqlite_orm)
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(libasync-uv REQUIRED IMPORTED_TARGET libasync-uv)
|
||||
pkg_check_modules(fmt REQUIRED IMPORTED_TARGET fmt)
|
||||
pkg_check_modules(sqlite3 REQUIRED IMPORTED_TARGET sqlite3)
|
||||
|
||||
target_link_libraries(asbots PRIVATE PkgConfig::libasync-uv PkgConfig::fmt)
|
||||
target_link_libraries(asbots PRIVATE PkgConfig::libasync-uv PkgConfig::fmt PkgConfig::sqlite3)
|
||||
|
||||
configure_file(config.inil config.inil COPYONLY)
|
||||
|
|
|
@ -103,7 +103,7 @@ struct User {
|
|||
std::string nick;
|
||||
size_t hops = 1;
|
||||
ModeSet umode;
|
||||
std::string ident;
|
||||
std::string ident = "~";
|
||||
std::optional<std::string> vhost;
|
||||
std::optional<std::string> ip;
|
||||
std::string realhost;
|
||||
|
|
4
main.cpp
4
main.cpp
|
@ -18,7 +18,7 @@
|
|||
#include "config.hpp"
|
||||
#include "instance.hpp"
|
||||
|
||||
#include "services/test.hpp"
|
||||
#include "services/nickserv.hpp"
|
||||
|
||||
#include <uvpp.hpp>
|
||||
#include <async/result.hpp>
|
||||
|
@ -33,7 +33,7 @@ int main() {
|
|||
loop_service service;
|
||||
|
||||
Instance instance(service, parseConfig("config.inil"));
|
||||
instance.services.push_back(std::make_unique<TestService>());
|
||||
instance.services.push_back(std::make_unique<NickServ>());
|
||||
|
||||
async::detach(instance.run());
|
||||
async::run_forever(rq.run_token(), loop_service_wrapper{service});
|
||||
|
|
|
@ -19,10 +19,13 @@
|
|||
#include "instance.hpp"
|
||||
|
||||
#include <async/result.hpp>
|
||||
#include <fmt/format.h>
|
||||
#include <string>
|
||||
#include <optional>
|
||||
#include <stdexcept>
|
||||
|
||||
using fmt::operator""_format;
|
||||
|
||||
|
||||
|
||||
async::result<void> ServiceBase::mark_ready(const User& user) {
|
||||
|
@ -46,3 +49,21 @@ std::optional<std::string_view> ServiceBase::getConfig(const std::string& sectio
|
|||
// Return final result
|
||||
return {k_res->second};
|
||||
}
|
||||
|
||||
async::result<void> ServiceBase::on_direct_privmsg(std::string_view msg, u_User& author) {
|
||||
auto split = Utility::strSplit(msg, ' ');
|
||||
User user = {.server = i->config.server.uid, .uid = uuid};
|
||||
|
||||
auto res = commands.find(Utility::lowers(split[0]));
|
||||
if (res == commands.end()) {
|
||||
co_await i->send_event(user.get_notice("Error: Command not found", author->uid));
|
||||
} else {
|
||||
split.erase(split.begin());
|
||||
auto& [fnc, usage, minArgs] = res->second;
|
||||
if (split.size() < minArgs) {
|
||||
co_await i->send_event(user.get_notice("Error: Usage: {}"_format(usage), author->uid));
|
||||
} else {
|
||||
co_await fnc(author, split);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@ class Instance;
|
|||
#include <async/result.hpp>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
|
||||
|
||||
|
@ -36,10 +38,11 @@ public:
|
|||
UUID uuid;
|
||||
Instance *i;
|
||||
bool ready = false;
|
||||
std::unordered_map<std::string_view, std::tuple<std::function<async::result<void> (u_User& sender, const std::vector<std::string_view>& args)>, std::string_view, size_t>> commands;
|
||||
|
||||
virtual async::result<void> intitialize() = 0;
|
||||
virtual async::result<void> on_event(const Event& event) = 0;
|
||||
virtual async::result<void> on_direct_privmsg(std::string_view msg, u_User& author) = 0;
|
||||
virtual async::result<void> on_direct_privmsg(std::string_view msg, u_User& author);
|
||||
|
||||
async::result<void> mark_ready(const User& user);
|
||||
std::optional<std::string_view> getConfig(const std::string& section, const std::string& key);
|
||||
|
|
60
services/nickserv.cpp
Normal file
60
services/nickserv.cpp
Normal file
|
@ -0,0 +1,60 @@
|
|||
#include "nickserv.hpp"
|
||||
#include "../instance.hpp"
|
||||
|
||||
#include <async/result.hpp>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
|
||||
|
||||
async::result<void> NickServ::intitialize() {
|
||||
co_await i->netInfo.wait_ready();
|
||||
user = {
|
||||
.server = i->config.server.uid,
|
||||
.nick = std::string(getConfig("NickServ", "nickname").value_or("NickServ")),
|
||||
.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("NickServ", "database").value_or("nickserv.sqlite")),
|
||||
make_table("users",
|
||||
make_column("id", &Account::id, autoincrement(), primary_key()),
|
||||
make_column("name", &Account::name),
|
||||
make_column("password_hash", &Account::password_hash))
|
||||
));
|
||||
storage->sync_schema();
|
||||
|
||||
commands = {
|
||||
{"test", {[this] (u_User& sender, std::vector<std::string_view> args) -> async::result<void> {
|
||||
co_await i->send_event(user.get_notice("Hello world! Works", sender->uid));
|
||||
}, "", 0}
|
||||
},
|
||||
{"identify", {[this] (u_User& sender, const std::vector<std::string_view>& args) -> async::result<void> {
|
||||
// Get user from storage
|
||||
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: Your nick is not registered!", sender->uid));
|
||||
co_return;
|
||||
}
|
||||
auto& account = accounts_found[0];
|
||||
// Check password
|
||||
if (account.password_hash != args[0]) {
|
||||
co_await i->send_event(user.get_notice("Error: Invalid password!", sender->uid));
|
||||
co_return;
|
||||
}
|
||||
// Login
|
||||
co_await i->send_event(sender->get_encap_su(account.name));
|
||||
}, "<password>", 1}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
async::result<void> NickServ::on_event(const Event& event) {
|
||||
co_return;
|
||||
}
|
46
services/nickserv.hpp
Normal file
46
services/nickserv.hpp
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* 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 "sqlite_orm.h"
|
||||
|
||||
#include <async/result.hpp>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
|
||||
|
||||
struct Account {
|
||||
size_t id;
|
||||
std::string name, password_hash;
|
||||
};
|
||||
|
||||
using Storage = sqlite_orm::internal::storage_t<sqlite_orm::internal::table_t<Account, sqlite_orm::internal::column_t<Account, long unsigned int, const long unsigned int& (Account::*)() const, void (Account::*)(long unsigned int), sqlite_orm::constraints::autoincrement_t, sqlite_orm::constraints::primary_key_t<> >, sqlite_orm::internal::column_t<Account, 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> >& (Account::*)() const, void (Account::*)(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)>, sqlite_orm::internal::column_t<Account, 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> >& (Account::*)() const, void (Account::*)(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)> > >;
|
||||
|
||||
class NickServ : public ServiceBase {
|
||||
std::unique_ptr<Storage> storage;
|
||||
|
||||
User user;
|
||||
|
||||
virtual async::result<void> intitialize() override;
|
||||
virtual async::result<void> on_event(const Event& event) override;
|
||||
};
|
||||
#endif
|
|
@ -1,28 +0,0 @@
|
|||
#include "test.hpp"
|
||||
|
||||
#include <async/result.hpp>
|
||||
|
||||
|
||||
|
||||
async::result<void> TestService::intitialize() {
|
||||
user = {
|
||||
.server = i->config.get().server.uid,
|
||||
.nick = "services",
|
||||
.ident = "services",
|
||||
.host = "services.",
|
||||
.realhost = "127.0.0.1",
|
||||
.uid = uuid,
|
||||
.realname = "LOL"
|
||||
};
|
||||
co_await mark_ready(user);
|
||||
co_await i->send_event(user.get_join("#lol"));
|
||||
co_await i->send_event(user.get_privmsg("Test... Hello world!", "#lol"));
|
||||
}
|
||||
|
||||
async::result<void> TestService::on_event(const Event& event) {
|
||||
co_return;
|
||||
}
|
||||
|
||||
async::result<void> TestService::on_direct_privmsg(std::string_view msg, u_User& author) {
|
||||
co_await i->send_event(user.get_privmsg("I received a message: "+std::string(msg), "#lol"));
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* 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>
|
||||
|
||||
|
||||
|
||||
class TestService : public ServiceBase {
|
||||
User user;
|
||||
|
||||
virtual async::result<void> intitialize() override;
|
||||
virtual async::result<void> on_event(const Event& event) override;
|
||||
virtual async::result<void> on_direct_privmsg(std::string_view msg, u_User& author) override;
|
||||
};
|
||||
#endif
|
|
@ -1,81 +0,0 @@
|
|||
/*
|
||||
* 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 "test.hpp"
|
||||
#include "../utility.hpp"
|
||||
|
||||
#include <async/result.hpp>
|
||||
#include <fmt/format.h>
|
||||
|
||||
using fmt::operator""_format;
|
||||
|
||||
|
||||
|
||||
async::result<void> TestService::intitialize() {
|
||||
co_await i->netInfo.wait_ready();
|
||||
user = {
|
||||
.server = i->config.server.uid,
|
||||
.nick = "services",
|
||||
.ident = "services",
|
||||
.realhost = "services.",
|
||||
.uid = uuid,
|
||||
.realname = i->netInfo.name,
|
||||
.loginName = "serviceD"
|
||||
};
|
||||
Channel serviceChannel = {
|
||||
.server = i->config.server.uid,
|
||||
.name = std::string(getConfig("testservice", "channel").value_or("#services"))
|
||||
};
|
||||
co_await mark_ready(user);
|
||||
co_await i->send_event(serviceChannel.get_sjoin(user.uid));
|
||||
//co_await i->send_event(serviceChannel.get_topic("IRC Service channel", user.uid));
|
||||
co_await i->send_event(user.get_notice("Test... Hello world!", serviceChannel.name));
|
||||
}
|
||||
|
||||
async::result<void> TestService::on_event(const Event& event) {
|
||||
co_return;
|
||||
}
|
||||
|
||||
async::result<void> TestService::on_direct_privmsg(std::string_view msg, u_User &author) {
|
||||
auto cmd = Utility::strSplit(msg, ' ', 1);
|
||||
|
||||
auto command = Utility::lowers(cmd[0]);
|
||||
|
||||
Event response = user.get_notice("You need to log in as NetOP first", author->uid);
|
||||
if (cmd.size() == 2 && !cmd[1].empty()) {
|
||||
if (command == "login") {
|
||||
co_await i->send_event(author->get_encap_su(cmd[1]));
|
||||
response = user.get_notice("Logged in!", author->uid);
|
||||
} else if (command == "send") {
|
||||
if (author->loginName.value_or("") == "NetOP") {
|
||||
Event event;
|
||||
try {
|
||||
event.parse(cmd[1]);
|
||||
co_await i->send_event(event);
|
||||
response = user.get_notice("Sent.", author->uid);
|
||||
} catch (std::exception&e) {
|
||||
response = user.get_notice(e.what(), author->uid);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
response = user.get_notice("Unknown command", author->uid);
|
||||
}
|
||||
} else {
|
||||
response = user.get_notice("Insufficient arguments?", author->uid);
|
||||
}
|
||||
co_await i->send_event(response);
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* 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>
|
||||
|
||||
|
||||
|
||||
class TestService : public ServiceBase {
|
||||
User user;
|
||||
|
||||
virtual async::result<void> intitialize() override;
|
||||
virtual async::result<void> on_event(const Event& event) override;
|
||||
virtual async::result<void> on_direct_privmsg(std::string_view msg, u_User& author) override;
|
||||
};
|
||||
#endif
|
1
sqlite_orm
Submodule
1
sqlite_orm
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 1ee0a8653fe57ed4d4f69b5a65839b1861c41d32
|
Loading…
Add table
Reference in a new issue