๐ I live in Pittsburgh, Pennsylvania, US
๐ฉโ๐ป I love working with code.
๐ฝ Backend programming is my jam.
Discord C++ library for interfacing with the API. Join our server: https://discord.gg/w7Y3Bb8
Home Page: https://discord.gg/w7Y3Bb8
License: MIT License
json object construction should occur in the shard manager, not the core. The core function should simply be a convenience function.
Around
and before
are ignored, they work as after
aegis.cpp/include/aegis/impl/channel.cpp
Lines 193 to 207 in d680afd
I just included the include directory in my project settings, however I get this error along with not recognizing "spdlog" as a namespace. Any help would be appreciated.
bot could write its own invite link at startup
Due to the async design, a MESSAGE_CREATE
can be processed prior to a GUILD_CREATE
creating the scenario of a message being handled that has no channel in the cache which leads to the message being rejected.
aegis.cpp/include/aegis/impl/core.cpp
Line 1202 in 176c67b
Solution is to perform a create_channel()
to create a semi-empty channel so the message can still be handled. This would be best accomplished with some sort of flag in the channel object itself to identify whether or not the channel is in this empty state or has been populated by a GUILD_CREATE
or CHANNEL_CREATE
.
Some of the visible Aegis API is either redundant or not necessary to be exposed.
both asio and websocket++ need updating but it is no small task.
chriskohlhoff/asio@cbe1c5e
along with a few attempts suggest a re-imagining of how the lib schedules tasks.
aegis.cpp/include/aegis/gateway/objects/impl/message.cpp
Lines 138 to 147 in d77feda
HP@Windobe MINGW64 ~/Documents/C++ Discord Bot/aegis.cpp/build (master)
$ cmake ..
-- CMake version: 3.17.3
-- Selecting Windows SDK version 10.0.18362.0 to target Windows 10.0.19041.
-- Could NOT find PkgConfig (missing: PKG_CONFIG_EXECUTABLE)
CMake Warning at cmake/FindAsio.cmake:10 (message):
Using git-module path for Asio
Call Stack (most recent call first):
CMakeLists.txt:34 (find_package)
-- Could NOT find PkgConfig (missing: PKG_CONFIG_EXECUTABLE)
CMake Warning at cmake/FindJSON.cmake:10 (message):
Using git-module path for JSON
Call Stack (most recent call first):
CMakeLists.txt:35 (find_package)
-- Could NOT find PkgConfig (missing: PKG_CONFIG_EXECUTABLE)
CMake Warning at cmake/FindSpdlog.cmake:10 (message):
Using git-module path for Spdlog
Call Stack (most recent call first):
CMakeLists.txt:36 (find_package)
-- Could NOT find PkgConfig (missing: PKG_CONFIG_EXECUTABLE)
CMake Warning at cmake/FindWebsocketpp.cmake:10 (message):
Using git-module path for Websocketpp
Call Stack (most recent call first):
CMakeLists.txt:37 (find_package)
CMake Error at C:/Program Files/CMake/share/cmake-3.17/Modules/FindPackageHandleStandardArgs.cmake:164 (message):
Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the
system variable OPENSSL_ROOT_DIR (missing: OPENSSL_CRYPTO_LIBRARY
OPENSSL_INCLUDE_DIR) (Required is at least version "1.0.1")
Call Stack (most recent call first):
C:/Program Files/CMake/share/cmake-3.17/Modules/FindPackageHandleStandardArgs.cmake:445 (_FPHSA_FAILURE_MESSAGE)
C:/Program Files/CMake/share/cmake-3.17/Modules/FindOpenSSL.cmake:459 (find_package_handle_standard_args)
CMakeLists.txt:38 (find_package)
-- Configuring incomplete, errors occurred!
See also "C:/Users/HP/Documents/C++ Discord Bot/aegis.cpp/build/CMakeFiles/CMakeOutput.log".
See also "C:/Users/HP/Documents/C++ Discord Bot/aegis.cpp/build/CMakeFiles/CMakeError.log".
Just a HTTP 401 error causes abnormal process shutdown from the library.
I don't understand the whole design yet, but I assume that it is a little bit too rough.
aegis.cpp/include/aegis/impl/core.cpp
Lines 655 to 660 in 391457c
Do you have difficulties in restoring the state, for example?
44e4c45
When i run cmake i get the error:
CMake Error at cmake/FindSpdlog.cmake:16 (message): Cannot get SPDLOG_VERSION from common.h. Call Stack (most recent call first): CMakeLists.txt:36 (find_package)
i installed spdlog and the other dependencies.
CMake option BUILD_SHARED_LIBS=off causes build errors.
In file included from /home/yappy/aegis.cpp/include/aegis/config.hpp:13,
from /home/yappy/aegis.cpp/include/aegis/channel.hpp:12,
from /home/yappy/aegis.cpp/include/aegis/impl/channel.cpp:10:
/home/yappy/aegis.cpp/include/aegis/fwd.hpp:12:10: fatal error: nlohmann/json_fwd.hpp: No such file or directory
#include <nlohmann/json_fwd.hpp>
^~~~~~~~~~~~~~~~~~~~~~~
In file included from /home/yappy/aegis.cpp/include/aegis/config.hpp:13,
from /home/yappy/aegis.cpp/include/aegis/impl/core.cpp:10:
/home/yappy/aegis.cpp/include/aegis/fwd.hpp:12:10: fatal error: nlohmann/json_fwd.hpp: No such file or directory
#include <nlohmann/json_fwd.hpp>
^~~~~~~~~~~~~~~~~~~~~~~
...
This patch will fix this but I don't know whether it is the best way.
fix_static_lib.patch.txt
Response for invalid token is not processed correctly giving vague json parse error.
When using aegis with a custom logger (tested with spdlog::sinks::basic_file_sink_mt
, spdlog::sinks::basic_file_sink_st
, spdlog::sinks::null_sink_mt
and spdlog::sinks::stdout_color_sink_mt
) running into a rate limit (e.g. by spamming messages to a channel using a while (true) {/*...*/}
construct), the executable gets terminated with SIGSEGV
.
An excerpt from my main()
without all the #include
directives and command line parsing.
auto log_file_sink =
std::make_shared<spdlog::sinks::basic_file_sink_mt>(logfile_path); // logfile_path is a std::string, same problem when using any other mentioned sink
auto logger =
std::make_shared<spdlog::logger>("my_cool_logger_name", log_file_sink);
logger->flush_on(spdlog::level::info); // removing this line doesn't mitigate the issue
if (log_verbose) // log_verbose is a bool and (in my tests) always true
logger->set_level(spdlog::level::debug); // same results when using spdlog::level::trace or spdlog::level::info
logger->debug("creating aegis::core");
// token is a std::string
aegis::core core(aegis::create_bot_t{}.token(token).logger(logger)); // remove .logger(logger) and everything works fine!
core.run();
while (true)
{
core.channel_create(TEST_CHANNEL_ID)->create_message("spam").get();
}
The program runs fine for some time, spamming the given channel with messages until the rate limit kicks in.
After that, the programm terminates immediately, leaving (at least to me) no reasonable output:
[2021-05-09 16:48:59.280] [my_cool_logger_name] [debug] creating aegis::core
[2021-05-09 16:48:59.281] [my_cool_logger_name] [info] Creating websocket
[2021-05-09 16:48:59.550] [my_cool_logger_name] [info] Shard count: 1
[2021-05-09 16:48:59.550] [my_cool_logger_name] [info] Starting shard manager with 1 shards
[2021-05-09 16:48:59.550] [my_cool_logger_name] [info] Starting bot with 1 shards
[2021-05-09 16:48:59.550] [my_cool_logger_name] [info] Websocket[s] connecting
[2021-05-09 16:48:59.650] [my_cool_logger_name] [debug] Shards to connect : 1
[2021-05-09 16:48:59.650] [my_cool_logger_name] [debug] Shard#0: connecting
[2021-05-09 16:48:59.782] [my_cool_logger_name] [debug] message::populate_self() user not found - created
[2021-05-09 16:49:01.152] [my_cool_logger_name] [debug] Shard#0: connection established
[2021-05-09 16:49:02.085] [my_cool_logger_name] [info] Shard#0 READY Processed
(same output with spdlog::level::debug
and spdlog::level::trace
)
gdb gives me the following:
GNU gdb (Gentoo 10.1 vanilla) 10.1
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-pc-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://bugs.gentoo.org/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./src/(my test executable)...
(gdb) r
Starting program: (my test executable) -l output.log -v -t (my token)
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
[New Thread 0x7ffff7585640 (LWP 122985)]
[New Thread 0x7ffff6d84640 (LWP 122986)]
[New Thread 0x7ffff6583640 (LWP 122987)]
[New Thread 0x7ffff5d82640 (LWP 122988)]
[New Thread 0x7ffff5555640 (LWP 122989)]
Thread 3 "(my bot name)" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff6d84640 (LWP 122986)]
0x00005555555b8bb7 in aegis::ratelimit::bucket::perform(aegis::rest::request_params) ()
(gdb) bt
#0 0x00005555555b8bb7 in aegis::ratelimit::bucket::perform(aegis::rest::request_params) ()
#1 0x00005555555ce781 in asio::detail::executor_op<asio::detail::work_dispatcher<aegis::core::async<aegis::ratelimit::ratelimit_mgr::post_task<aegis::gateway::objects::message, void>(aegis::rest::request_params)::{lambda()#1}, aegis::gateway::objects::message, void>(aegis::ratelimit::ratelimit_mgr::post_task<aegis::gateway::objects::message, void>(aegis::rest::request_params)::{lambda()#1})::{lambda()#1}>, std::allocator<void>, asio::detail::scheduler_operation>::do_complete(void*, asio::detail::scheduler_operation*, std::error_code const&, unsigned long) ()
#2 0x00005555555ff62f in asio::detail::scheduler::run(std::error_code&) ()
#3 0x0000555555601cda in asio::io_context::run() ()
#4 0x00005555555d5f8e in aegis::core::_thread_track(aegis::thread_state*) ()
#5 0x00007ffff79c9ef0 in ?? () from /usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/libstdc++.so.6
#6 0x00007ffff7e63f5e in start_thread () from /lib64/libpthread.so.0
#7 0x00007ffff781c1ef in clone () from /lib64/libc.so.6
sometimes, this is the function where the SEGV is received:
0x00005555555b8297 in void spdlog::logger::log_<fmt::v7::basic_string_view<char>, int>(spdlog::source_loc, spdlog::level::level_enum, fmt::v7::basic_string_view<char> const&, int const&) ()
Refrain from using custom loggers or running into rate limits (good luck with that^^) for now.
From the following excerpt I had the assumption that aegis might be implicitly depending on the logger being named aegis
:
aegis.cpp/include/aegis/impl/core.cpp
Lines 137 to 140 in 6ac47e7
aegis.cpp/include/aegis/ratelimit/bucket.hpp
Line 108 in 6ac47e7
spdlog::get
)
However, without having searched the rest of the codebase, I assume that spdlog::get
will be called elsewhere as well. Furthermore, giving the custom logger the name aegis
like in the aegis codebase (see below) doesn't resolve the problem.
aegis.cpp/include/aegis/impl/core.cpp
Line 79 in 6ac47e7
Another explanation might be that the file logger is too slow for the rate limit manager and somehow causes the rate limit manager to access memory which (possibly from another thread) has been deallocated by the time the memory is accessed.
Lastly, it still might be possible that the rate limit manager is the only one accessing the logger using spdlog::get()
which I'd find a bit odd. But then, doing the registration of the logger wrong in a way that spdlog::get()
returns an invalid pointer (possibly nullptr
) could explain the symptoms. But it doesn't explain the debugger sometimes telling me that SEGV is received during an internal spdlog function call (for which I assume the logger object must have been accessed correctly).
https://github.com/zeroxs/aegis.cpp/blob/master/include/aegis/impl/core.cpp#L559
Error during construction should not be self-caught
I cloned the repository with its dependencies, and built the lib:
git clone --recursive [email protected]:zeroxs/aegis.cpp
cd aegis.cpp
mkdir build
cd build
cmake ..
make
sudo make install
No error until here.
Then I created a little project, with a single main.cpp
file, containing the template code given in the Readme - in which I took care to replace "TOKEN" with my bot's token, obviously.
When compiling it with
g++ -o bot src/main.cpp -Wall -Wextra -Werror
I get an error:
/usr/local/include/aegis/fwd.hpp:12:10: fatal error: nlohmann/json_fwd.hpp: No such file or directory
I'm investigating on this, looking for some lib I wouldn't have installed on my PC.
Hi there,
I'm the author of a websocket C++ library (with also http support) which has been used by other libraries already to talk to discord (you can see which ones at the bottom of the landing page). If you want to give it a try it is here -> https://github.com/machinezone/IXWebSocket
I am very biased because I wrote it ... but one thing I like about it is that it has few dependencies (zlib + a tls backend) ; it does not depend on boost so people usually find it easy to integrate in their project, and it is not too low level and uses C++11 threads etc... with callbacks.
Ciao and good luck with your library !
(this really would belong more to a 'discussion', but using a github issue instead)
aegis::guild::member_has_role function always returns false for the bot, except right after the roles are changed on server side. For other users it only returns true for the role @everyone and false for everything else. This has worked in the past. Here is my code:
void showRoles(aegis::gateway::objects::message m) {
unordered_map<aegis::snowflake, aegis::gateway::objects::role> roles = m.get_guild().get_roles();
for (pair<aegis::snowflake, aegis::gateway::objects::role> role : roles) {
cout << role.second.name << endl;
unordered_map<aegis::snowflake, aegis::user*> members = m.get_guild().get_members();
for (pair<aegis::snowflake, aegis::user*> member : members) {
cout << member.second->get_full_name() << ": ";
if (m.get_guild().member_has_role(member.second->get_id(), role.second.id) == true)
cout << "True" << endl;
else
cout << "False" << endl;
}
cout << endl;
}
}
Pretty much everything listed as needing documentation needs to be added. As time goes on I fill it out slowly.
The code in guild.cpp for create_guild_ban incorrectly PUTs the reason and delete_message_days parameters to Discord as URL parameters. This causes an HTTP 400 Bad Request
response, as the Discord docs specify that that these parameters should be sent as a JSON object, seen here.
I noticed this issue when the ban command for my bot failed, and resolved the issue by changing the code for the create_guild_ban method to the following:
AEGIS_DECL aegis::future<rest::rest_reply> guild::create_guild_ban(snowflake user_id, int8_t delete_message_days, const std::string & reason)
{
#if !defined(AEGIS_DISABLE_ALL_CACHE)
if (!perms().can_ban())
return aegis::make_exception_future(error::no_permission);
#endif
std::shared_lock<shared_mutex> l(_m);
json obj = { { "delete_message_days", delete_message_days }, { "reason", reason } };
return _bot->get_ratelimit().post_task({ fmt::format("/guilds/{}/bans/{}", guild_id, user_id), rest::Put, obj.dump()});
}
this issue started today it was working fine yesterday it compiles links as normal when I run it this is what I get:
2020-06-30 17:27:49.990 [I] [th#9460] : Creating websocket
2020-06-30 17:27:50.900 [I] [th#9460] : Shard count: 1
2020-06-30 17:27:50.901 [I] [th#9460] : Starting shard manager with 1 shards
2020-06-30 17:27:50.901 [I] [th#9460] : Starting bot with 1 shards
2020-06-30 17:27:50.901 [I] [th#9460] : Websocket[s] connecting
2020-06-30 17:27:51.003 [D] [th#7716] : Shards to connect : 1
2020-06-30 17:27:51.003 [D] [th#7716] : Shard#0: connecting
2020-06-30 17:27:51.693 [D] [th#15508] : Shard#0: connection established
2020-06-30 17:27:52.663 [D] [th#15508] : Shard#0: disconnected. lastheartbeat(1659) lastwsevent(969) lastheartbeatack(96
9) ms ago
2020-06-30 17:27:57.801 [D] [th#15764] : Shards to connect : 1
2020-06-30 17:27:57.802 [D] [th#15764] : Shard#0: connecting
2020-06-30 17:27:58.444 [D] [th#15508] : Shard#0: connection established
2020-06-30 17:27:59.351 [D] [th#15508] : Shard#0: disconnected. lastheartbeat(1549) lastwsevent(906) lastheartbeatack(90
6) ms ago
Can you try to add it in vcpkg packages?
CMake JSON and OPENSSL variable corrections
void guild::_load(const json & obj, shards::shard * _shard) noexcept
This function is noexcept, but throws.
Also, in one of the catch clauses:
spdlog::get("aegis")->error("Shard#{} : Error processing guild[{}] {}", _shard->get_id(), g_id, (std::string)e.what());
The cast to std::string
feels redundant, on top of oncurring an unnecessary construction.
Consider allowing users to use Boost.Asio instead of standalone asio (It should pretty much be a drop-in replacement, at least for versions of Boost.Asio up to 1.73 (1.74 has some namespace changes that require aliases). This is what websocketpp
does, which is one of your dependency. The most egregious change is asio::system_error
, since it doesn't exist in Boost.Asio: boost::system::error_code
is the counterpart. In turn, because websocketpp uses std::error_code
, there are calls that will no longer compile (because they used asio::system_error
), and need to be manually fixed.
There are missing includes in some places (I'm not using PCH headers, maybe that's why you're not seeing those). Unfortunately, since all my edits are currently unstaged, I can't provide a diff. If you wish me to, I can try to generate one, but I heavily hacked away at config.hpp
(removing the polyfills for std::optional, among other things), so I'll have to filter some changes out.
// shard_mgr.cpp
_shard->_connection = websocket_o.get_connection(gateway_url, ecs);
_shard->_strand = _shard->_connection->get_strand();
if (ecs)
throw ecs;
Should probably become this?
_shard->_connection = websocket_o.get_connection(gateway_url, ecs);
if (ecs)
throw ecs;
_shard->_strand = _shard->_connection->get_strand();
On MSVC, i'm getting duplicate function bodies across multiple types, namely permissions
's to_json
and from_json
. This was deeply confusing and I just moved the implementation back into permissions.hpp
. Not a clean solution, but I'm not sure why this happens.
Cheers
Are there any examples for sharded bots?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.