Giter Site home page Giter Site logo

brainboxdotcc / dpp Goto Github PK

View Code? Open in Web Editor NEW
943.0 23.0 144.0 37.31 MB

C++ Discord API Bot Library - D++ is Lightweight and scalable for small and huge bots!

Home Page: https://dpp.dev/

License: Apache License 2.0

C++ 97.90% CMake 1.05% CSS 0.02% C 0.03% Dockerfile 0.01% PHP 0.98%
cpp discord discord-bot library linux ssl websocket json api api-client

dpp's Introduction

DPP

An incredibly lightweight C++ Discord library


Discord Downloads Codacy Badge OpenSSF Best Practices D++ CI OpenSSF Scorecard AUR version vcpkg version Homebrew version Contributor Covenant


D++ is a lightweight and efficient library for Discord written in modern C++, covering as much of the API specification as possible with an incredibly small memory footprint even when caching large amounts of data.

Library Features

  • Support for Discord API v10
  • Really small memory footprint
  • Efficient caching system for guilds, channels, guild members, roles, users
  • Sharding and clustering (Many shards, one process: specify the number of shards, or let the library decide)
  • Highly optimised ETF (Erlang Term Format) support for very fast websocket throughput
  • Slash Commands/Interactions support
  • Voice support (sending and receiving audio)
  • The entire Discord API is available for use in the library
  • Stable Windows support
  • Ready-made compiled packages for Windows, Raspberry Pi (ARM64/ARM7/ARMv6), Debian x86/x64, and RPM based distributions
  • Highly scalable for large amounts of guilds and users

Want to help? Drop me a line or send a PR.

This library is in use on TriviaBot and Sporks bot and many other bots!

๐Ÿ“š Documentation

The documentation is constantly evolving and improving, generated from the code comments and markdown examples using Doxygen.

Example

This is a simple ping-pong example using slash commands.

#include <dpp/dpp.h>
#include <cstdlib>

int main() {
	dpp::cluster bot(std::getenv("BOT_TOKEN"));

	bot.on_slashcommand([](auto event) {
		if (event.command.get_command_name() == "ping") {
			event.reply("Pong!");
		}
	});

	bot.on_ready([&bot](auto event) {
		if (dpp::run_once<struct register_bot_commands>()) {
			bot.global_command_create(
				dpp::slashcommand("ping", "Ping pong!", bot.me.id)
			);
		}
	});

	bot.start(dpp::st_wait);
	return 0;
}

You can find more examples in our example page.

๐Ÿ’ป Supported Systems

Linux

The library runs ideally on Linux.

Mac OS X, FreeBSD, and OpenBSD

The library is well-functional and stable on Mac OS X, FreeBSD, and OpenBSD too!

Raspberry Pi

For running your bot on a Raspberry Pi, we offer a prebuilt .deb package for ARM64, ARM6, and ARM7 so that you do not have to wait for it to compile.

Windows

Windows is well-supported with ready-made compiled DLL and LIB files, please check out our Windows Bot Template repository. The Windows Bot repository can be cloned and integrated immediately into any Visual Studio 2019 and 2022 project in a matter of minutes.

Other OS

The library should work fine on other operating systems as well, and if you run a D++ bot on something not listed here, please let us know!

๐Ÿ”ฐ Getting Started

Installation

D++ can be easily installed using various package managers. Please refer to our documentation for installation tutorials based on your preferred package manager.

Building from Source

If you prefer to build the library from source, detailed instructions are available here.

FAQ

For frequently asked questions and their answers, please visit our FAQ page.

Nightly Builds

If you prefer to use Nightly Builds (This is only if you know what you are doing!) then you can use either our master nightly builds or our dev nightly builds.

๐Ÿค Contributing

Contributions, issues and feature requests are welcome. After cloning and setting up the project locally, you can just submit a PR to this repo and it will be deployed once it's accepted.

Please read the D++ Code Style Guide for more information on how we format pull requests.

๐Ÿ’ฌ Get in touch

If you have various suggestions, questions or want to discuss things with our community, Join our discord server! Make a humorous reference to brains in your nickname to get access to a secret brain cult channel! :)

Discord

๐Ÿ’• Show your support

We love people's support in growing and improving. Be sure to leave a โญ๏ธ if you like the project and also be sure to contribute, if you're interested!

๐Ÿ“‚ Dependencies

Build requirements

  • cmake (version 3.13+)
  • A supported C++ compiler from the list below

Supported compilers

  • g++ (version 8 or higher)
  • clang (version 6 or higher)
  • AppleClang (12.0 or higher)
  • Microsoft Visual Studio 2019 or 2022 (16.x/17.x)
  • clang-cl (version 15 or higher)

Other compilers may work (either newer versions of those listed above, or different compilers entirely) but have not been tested by us.

External Dependencies (You must install these)

  • OpenSSL (whichever -dev package comes with your OS)
  • zlib (whichever -dev package comes with your OS)

Optional Dependencies

For voice support you require both of:

Included Dependencies (Packaged with the library)

dpp's People

Contributors

aa1999 avatar axyte avatar braindigitalis avatar bricklou avatar commandserver avatar d-nery avatar daggersoath avatar dependabot[bot] avatar djoetzi avatar es183923 avatar harshfeudal avatar henonicks avatar janasunrise avatar jaskowicz1 avatar kar8uncle avatar linker-123 avatar lohkdesgds avatar mishura4 avatar mobergmann avatar neko-life avatar nexadn avatar realtimechris avatar rept1d avatar rgnter avatar ruslan-ilesik avatar sirobby avatar veryholycheeeese avatar webtax-gh avatar wizard7377 avatar wykerd avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dpp's Issues

Channel edit dont work

Describe the bug
When i try to edit a channel or thread, nothing happends.

To Reproduce
I used this code to edit a channel:

// some code over here...
bot.channel_get(788499352297406487, [&bot, &log](const dpp::confirmation_callback_t &confirmationCallback) {
                if (!confirmationCallback.is_error()) {
                    dpp::channel channel = std::get<dpp::channel>(confirmationCallback.value);

                    channel.rate_limit_per_user = 300;

                    log->info("{}", channel.build_json());

                    bot.channel_edit(channel, [&bot, &log](const dpp::confirmation_callback_t &confirmationCallback) {
                        if (confirmationCallback.is_error()) {
                            log->error("{}",confirmationCallback.http_info.body);
                            log->error("{}", confirmationCallback.get_error().message);
                        }
                    });
                }
            });
// some code after this...

The code snippet prints out this:

2021-11-07 15:03:18.934 [I] [th#11787] : {"guild_id":"788499352297406484","name":"allgemein","nsfw":false,"parent_id":788499352297406485,"position":12,"rate_limit_per_user":300,"topic":"","type":0}
2021-11-07 15:03:20.234 [E] [th#11787] : {"code": 50035, "errors": {"_errors": [{"code": "DICT_TYPE_CONVERT", "message": "Only dictionaries may be used in a DictType"}]}, "message": "Invalid Form Body"}
2021-11-07 15:03:20.234 [E] [th#11787] : Invalid Form Body

Expected behavior
The slowmode of the channel set to 300 seconds.

System Details:

  • Linux (Ubuntu 21.10)
  • Editor: CLion
  • Discord Client used for testing: desktop
  • DPP version: 9.0.11

Cluster cannot be closed gracefully.

Describe the bug
Destroying dpp::cluster blocks "indefinitely" (quotes explained bellow).

To Reproduce
Steps to reproduce the behavior:

  1. std::unique_ptr< dpp::cluster > c = std::make_unique< dpp::cluster >("token...");
  2. c->start(true);
  3. Later on: c.reset();

Expected behavior
Expecting code c.reset(); to return so execution can continue.

System Details:

  • OS: [e.g. Windows 10 x64]
  • Discord Client used for testing [mobile, desktop, web]

Additional context
The dpp::cluster destructor gets stuck. From the looks of it it seems to happen in the dpp::request_queue actually. in_thread->join(); waits indefinitely. Probably because while (!terminating) { is never reached again after the initial entry.

while (recv(notifier, &n is also blocking if no data is received (why the quotes). So you need to receive data to enter the loop in case you want to move the !terminating check inside the inner loop as an alternative. Thus, preventing the thread from actually terminating.

messages_get throws an error / breaks the execution when set the limit higher than 100

Describe the bug
messages_get breaks the execution when set the limit of messages higher than 100!

To Reproduce

try {
            bot.messages_get(845266528676468976, 0, 0, 0, 101, [](const dpp::confirmation_callback_t &event) {
                if (!event.is_error()) {
                    auto mm = get<dpp::message_map>(event.value);
                    cout << "success; amount of messages: " << mm.size() << endl;
                } else {
                    cout << "error: " << event.http_info.body << endl;
                }
            });
        } catch (const std::exception &e) {
            cout << "exception: "  << e.what() << endl;
        }

Expected behavior
it calls multiple api requests to get more than 100 messages

System Details:

  • DPP 9.0.17

Add a size option for dpp::user::get_avatar_url()

Is your feature request related to a problem? Please describe.
For example, if you want to add a user's avatar to an embed as a thumbnail, you usually have the problem that the image is too small.

Describe the solution you'd like
You can make avatars bigger by adding a ?size=1024 string after the url.
Example without resize: https://cdn.discordapp.com/avatars/788468151200514088/5a9782e9f4f77c5ef60f97cb1206370a.png?
Example with resize: https://cdn.discordapp.com/avatars/788468151200514088/5a9782e9f4f77c5ef60f97cb1206370a.png?size=1024
As you can see the avatar is much bigger.
My suggestion would be to add a size option in get_avatar_url() -> get_avatar_url(uint32_t size).
This feature does exist in discord.js.

Describe alternatives you've considered
You could also make a separate dpp::utils function for it.

user edit does not work

Describe the bug
When i try to edit a user, nothing happends.

To Reproduce
I used this code to edit a user:

		bot->guild_get_member(GUILD_ID, this->discord_id, [&](const dpp::confirmation_callback_t event) {
			if (event.is_error())
			{
				printf("error %s!\n", event.get_error().message.c_str());
			}

			auto member = (const dpp::guild_member&)(event.value);
			member.set_nickname(this->username);
			bot->guild_edit_member(member, [&](const dpp::confirmation_callback_t& t) {
				if (t.is_error()) {
					printf("Error message %s!\n", t.get_error().message.c_str());
					printf("Error body %s!\n", t.http_info.body.c_str());
				}
			});

		});

Expected behavior
the username nickname to change

System Details:
DPP 9.0.18

Error Message
Error message -> Invalid Form Body!
Error body -> {"code": 50035, "errors": {"communication_disabled_until": {"_errors": [{"code": "INVALID_COMMUNICATION_DISABLED_TIMESTAMP", "message": "Invalid communication disabled timestamp"}]}}, "message": "Invalid Form Body"}!

role_edit() fails with "Invalid Form Body"

Describe the bug
When attempting to use cluster::role_edit() to change a role we throw an error in the callback.

{"code": 50035, "errors": {"_errors": [{"code": "DICT_TYPE_CONVERT", "message": "Only dictionaries may be used in a DictType"}]}, "message": "Invalid Form Body"}

To Reproduce

  1. Call role_edit() while passing in a modified or unmodified role.
  2. Check the error results.

Here is code that I am using to reproduce the bug:

bot.role_edit(role_to_edit.set_name("test"), [](const dpp::confirmation_callback_t& role) {
    if (role.is_error()) {
        std::cout << "error: " << role.get_error().message << std::endl;
        std::cout << "error: " << role.http_info.body << std::endl;
    }
    auto t = get<dpp::role>(role.value);
    std::cout << t.name << std::endl;
});

Expected behavior
I would expect the role name to be updated however instead we just simply error out.

System Details:

  • OS: macOS 12.2 and RaspberryPI latest 64bit
  • Discord Desktop PTB macOS

Build gets stuck at %5 (cluster.cpp.o)

Describe the bug
Running make -j1 on a RPI Zero gets stuck at 5%

To Reproduce
Steps to reproduce the behavior:

  1. cd build
  2. cmake ..
  3. make -j1

Expected behavior
Building without getting stuck

System Details:
RPI Zero, Raspberry Pi OS
g++ 8.3.0

Replace MinGW with mingw-64

MinGW refers to both MinGW 32 and 64
(64 being the newer one)
If I remember correctly we've only gotten mingw-64 working.

Helper for mentions

Describe the solution you'd like
In discordpy you can get the mention string of a channel, member or role.
It would be nice if you can add this too.
Just a member or a getter that gives the mention of the member, channel or role.

i know i can create a mention easily by do something like "<@" + std::to_string(member.id) + ">".
but having a member that makes this for you would make this even easier.

dpp.dev search box overlaps hamburger menu on mobile

Describe the bug

The documentation seems to be not pretty responsive on some resolutions.

  • At a resolution of 600 to 1050, the position of the menu glitches.
  • The whole page is scrollable for a half centimeter or so. Which technically doesn't matters but sometimes it'll be a bit annoying when i scroll in the docs. etc., that the whole page moves a bit up or down

Expected behavior

At a small resolution, i think the menu should be in the top right corner?...

Screenshots

Weird menu position on small size:
2021-10-13_20-53

Useless scrollability
2021-10-13_20-55

Really weird menu position on middle sizes (i removed the top property in the debugger, as you can see right, so that it's visible)
2021-10-13_20-52

System Details:

  • Linux Ubuntu 21.04
  • Browser: Firefox 93.0 (Tested also on Google Chrome 93.0.4577.63)

Additional context
nope

400 bad request when trying to ban a member

Describe the bug
400 bad request error when trying to ban a guild member.

To Reproduce
Steps to reproduce the behavior:

  1. bot.guild_ban_add(guild_id, user_id, 0, "reason doesn't matter", <callback>)
  2. In the callback log the error message

Expected behavior
A successful request.

Screenshots
None

System Details:

  • Arch Linux
  • Discord Client used for testing web

Additional context
None

is_communication_disabled method sometimes not working

Describe the bug
is_communication_disabled in dpp::member returns false when the member is in timeout!

To Reproduce
Steps to reproduce the behavior:

It happens when i set communication_disabled_until to +1 hour.
But only with short timeouts. For example I've tried it with a user that i gave a 600 days timeout and this worked fine.

Expected behavior
returns true when the user really is in timeout.

System Details:
my timezone is UTC +1. maybe this is usefull?!

Additional context
I've added some debugging to the current code:

bool guild_member::is_communication_disabled() const {
    std::cout << "internal communication_disabled_until: " << std::to_string(communication_disabled_until) << " current timestamp: " << time(nullptr) << std::endl;
    return communication_disabled_until > time(nullptr);
}

I called the method on a user that have a one hour timeout, and it returns false.
the code above printed

internal communication_disabled_until: 1641250800 current timestamp: 1641335917

I think its because discord uses ISO8601 timestamp and not the normal unix timestamp.
https://discord.com/developers/docs/resources/guild#guild-member-object-guild-member-structure

Are events invoked in other threads?

If I bind a callback to an event (on_message_update for example). Is the callback guaranteed to be called in the same thread that created the cluster? I guess it doesn't since you start the cluster (true argument) and it has no way of getting back to the main thread. There's no control over the internal loop. Or way of integrating into parent loop (like having an update() method called periodically). I feel like this should be made a bit more obvious in case someone uses the library and deals with code that is not thread safe.

Because if I want to process that event in the main thread with a queue or something like that. I will receive a message_update_t argument in the event. But the problem now becomes: Who manages the lifetime of that message_update_t instance? So now I'm confronted with a few questions:

Do I block the thread that invoked the event and wait until it is handled in main thread? Seems weird.

Do I just queue the argument value and return? Then process it in main thread. But then who owns the message* updated; pointer? How do I tell the library that I'm still using that?

There are a bunch of raw pointers passed throughout the library and no way to get involved in their lifetime. No reference counting or something like that. And for something that deals with multiple threads seems weird.

Do I create deep copies of everything? Like keeping my own separate kind of cache?

I noticed in another issue that you said most discord bots are dedicated processes and not embedded in something else. That may be the case for some but not for most.

How would you approach this situation? How would you synchronize events and deal with the lifetime of objects that the library yields?

Thank you.

EDIT:

Upon further reading, I noticed that some of the objects that I was interested in their lifetime inherit from dpp::managed class.

Which are then down-casted to a dpp::managed pointer and stored inside various (static/global) containers in the cache.cpp unit. And then deleted by garbage_collection() which I guess is then called periodically from some other thread.

But in the garbage_collection() function I notice this line delete g->first; in which g->first is the dpp::managed pointer that was down-casted from whatever inherited that class. Which seems fine until you notice that dpp::managed does not have a virtual destructor.

Basically, delete does not know about the derived class destructor and only invokes the destructor of the dpp::managed class (which has nothing to cleanup). Doesn't this classify as a memory leak? (link)

Regarding the initial question. I guess I could modify the dpp::managed class to include a reference counter and the garbage_collection() function to take that into consideration before trying to delete the instance. Requirements to maintain this modification would be minimal since is just 2-3 lines of code.

EDIT2: But then dpp::message doesn't inherit from dpp::managed class. So I'm back to where I started. I guess I have to look further into this.

slowmode in threads

Is your feature request related to a problem? Please describe.
I want to be able to set the slowmode in threads.

Describe the solution you'd like
to have an argument in channel_edit for example or even better an argument directly in the thread_create method.

Additional context
I'm sure that this feature could help many people because spam prevention is important especially for big servers.

Error build slashcommand json with sub-commands and options

Describe the bug
Trying to use sub-commands with options in slash commands causes the build_json method to behave unexpectedly, replicating the sub-command in it's options, causing nested type: 1 options, which is not supported by discord.

To Reproduce
Example program:

int main() {
    dpp::slashcommand command;

    command.set_name("cmd name")
        .set_description("cmd desc")
        .set_application_id(1234567)
        .add_option(dpp::command_option(dpp::co_sub_command, "sub1", "sub1 desc")
                        .add_option(dpp::command_option(dpp::co_string, "option 1", "sub1 option1 desc")
                                        .add_choice(dpp::command_option_choice("choice1", std::string("choice1")))
                                        .add_choice(dpp::command_option_choice("choice2", std::string("choice2"))))
                        .add_option(dpp::command_option(dpp::co_integer, "option 2", "sub1 option2 desc")))
        .add_option(dpp::command_option(dpp::co_sub_command, "sub2", "sub2 desc"));

    std::string json_dump = command.build_json(false);

    std::cout << json::parse(json_dump).dump(4) << std::endl;
}

Generated output:

{
    "description": "cmd desc",
    "name": "cmd name",
    "options": [
        {
            "description": "sub1 desc",
            "name": "sub1",
            "options": [
                {
                    "description": "sub1 desc",
                    "name": "sub1",
                    "options": [],
                    "required": false,
                    "type": 1
                },
                {
                    "description": "sub1 desc",
                    "name": "sub1",
                    "options": [
                        {
                            "description": "sub1 desc",
                            "name": "sub1",
                            "options": [],
                            "required": false,
                            "type": 1
                        }
                    ],
                    "required": false,
                    "type": 1
                }
            ],
            "required": false,
            "type": 1
        },
        {
            "description": "sub2 desc",
            "name": "sub2",
            "required": false,
            "type": 1
        }
    ]
}

Expected behavior
This is the expected output:

{
    "description": "cmd desc",
    "name": "cmd name",
    "options": [
        {
            "description": "sub1 desc",
            "name": "sub1",
            "options": [
                {
                    "choices": [
                        {
                            "name": "choice1",
                            "value": "choice1"
                        },
                        {
                            "name": "choice2",
                            "value": "choice2"
                        }
                    ],
                    "description": "sub1 option1 desc",
                    "name": "option 1",
                    "required": false,
                    "type": 3
                },
                {
                    "description": "sub1 option2 desc",
                    "name": "option 2",
                    "required": false,
                    "type": 4
                }
            ],
            "required": false,
            "type": 1
        },
        {
            "description": "sub2 desc",
            "name": "sub2",
            "required": false,
            "type": 1
        }
    ]
}

System Details:

  • OS: Linux 4.19.128-microsoft-standard (Pengwin on WSL2)
  • Discord Client used for testing: desktop

Additional context
There is propably a reference issue in the slashcommand::build_json method while looping, I will open a PR that uses json lib arbitrary type conversion to try to solve this.

multiple attachments

Is your feature request related to a problem? Please describe.
multiple attachments on a message are missing.

for example currently there's only message.set_file_content. So i'm only able to attach one file ig

guild_command_create does not edit the slashcommand permissions

Describe the bug
the permissions of slash commands aren't working when using guild_command_create.

i found out that guild_command_edit_permissions inside the cluster::guild_command_create method always throw and error:

{"message": "Unknown application command", "code": 10063}

I found out that this happens because the given slash command needs an id but doesn't have one.

So #209 isn't fully fixed.

To Reproduce
Steps to reproduce the behavior:

add a lambda in guild_command_create like so:

void cluster::guild_command_create(const slashcommand &s, snowflake guild_id, command_completion_event_t callback) {
	this->post_rest(API_PATH "/applications", std::to_string(s.application_id ? s.application_id : me.id), "guilds/" + std::to_string(guild_id) + "/commands", m_post, s.build_json(false), [s, this, guild_id, callback] (json &j, const http_request_completion_t& http) mutable {
		if (callback) {
			callback(confirmation_callback_t("slashcommand", slashcommand().fill_from_json(&j), http));
		}

		if (http.status < 300 && s.permissions.size()) {
			guild_command_edit_permissions(s, guild_id, [](const confirmation_callback_t & e) {
				if (e.is_error()) {
					std::cout << e.http_info.body << std::endl;
				} else {
					std::cout << "success" << std::endl;
				}
			});
		}
	});
}

Expected behavior
the guild_command_edit_permissions method works

spdlog example wont work

Describe the bug
The spdlog-example dont work as expected. I've tried to use the code from the example but i got a bunch of errors.

To Reproduce
Steps to reproduce the behavior:

  1. Make a new projekt and follow the instruction in https://dpp.dev/buildcmake.html
    • Created the same file structure and cloned dpp and spdlog in the libs folder
    • copy & paste the CmakeLists.txt
  2. copy & paste the main.cpp from here
  3. compiling

Expected behavior
No compile erros and the bot running.

Screenshots
If applicable, add screenshots to help explain your problem.

System Details:

  • OS: Linux Fedora 29
  • IDE: CLion 2021.2.2
  • g++ version (GCC) 8.3.1 20190223 (Red Hat 8.3.1-2)
  • GNU Make 4.2.1

fix
It'll fix that for me when i include the dpp stuff after the spdlog like this:

#include <spdlog/spdlog.h>
#include <spdlog/async.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/sinks/rotating_file_sink.h>
#include <iomanip>
#include <dpp/dpp.h>
#include <dpp/fmt/format.h>

And i also added add_subdirectory(libs/spdlog) in the CMakeLists.txt.

context menu rework

Is your feature request related to a problem? Please describe.
rework the context menu events. The issue is that now its a bit complicate to handle these events and get access to the actual message or user you've right-clicked on. I must do like event.command.resolved.users.begin()->second to get the user i've right-clicked on. That's too complicated i think.

Describe the solution you'd like
having a dedicated event for this like on_context_menu and get an easy access to the message or user i've right-clicked on, without having to play with the resolved.

Additional context
The example here: https://dpp.dev/context-menu.html

Any chance of a pre-compiled 32-bit version for Windows?

My intended application to use D++ in, is currently built for 32-bit.

I followed the build instructions in the Documentation and it defaults to x64 debug. My attempts at switching to 32-bit architecture haven't worked thus far, and using CMake-Gui to generate a solution (which deviates from the recommended build procedure) appears to cause some unresolved external symbol issues. Perhaps because the packaged libraries are all x64?

Tons of errors in ws2def.h and Winsock2.h

Describe the bug
When I include <dpp/dpp.h> and try to build the project, I get a bunch of errors, "expected an identifier" and more from ws2def.h and Winsock2.h

To Reproduce
Steps to reproduce the behavior:

  1. Include <dpp/dpp.h>

Expected behavior
The #include should work properly and not give any errors

Screenshots
image

System Details:

  • OS: [Windows 10 x64 20H2]
  • Visual Studio 2022

Additional context
I'm not even using dpp.h, just including it gives a bunch of errors.

I've tried re-ordering the #includes in the culprit (dpp/discordvoiceclient.h) but that didn't help. I've also tried adding #pragma comment(lib,"ws2_32") but that didn't work either.

guild_get_members

Describe the bug
guild_get_members is not working properly.
when casting to guild_member_map size is always 1 and contains incorrect info.

Once called
To Reproduce

bot->on_ready([&](const dpp::ready_t& event) {
	p.guild_get_members(GUILD_ID, 50, 0, [](const dpp::confirmation_callback_t& event) {
		printf("Get member = %s\n", event.http_info.body.c_str()); // print correctly every user
		auto members = (dpp::guild_member_map&)(event.value); // work fine
		printf("Members size = %i\n", members.size()); // return 1
	});
})

Expected behavior
to the vector to contains every user?

System Details:

  • OS: [e.g. iOS8.1]
  • Latest version (v9.0.18)

Additional context

Temporary fix ?

https://github.com/brainboxdotcc/DPP/blob/master/src/dpp/cluster/guild_member.cpp#L74

from guild_members[snowflake_not_null(&curr_member, "id")] = guild_member().fill_from_json(&curr_member, guild_id, user_id);
to -> guild_members[guild_members.size() + 1] = guild_member().fill_from_json(&curr_member, guild_id, user_id);

after checking json, ["id"] only exist in ["user"]

member not populated correctly

Describe the bug
in the event (on_interaction_create)

-> event.command.member is not being populated correctly
it only have nick, and roles. which is a problem.

the event.raw_event got all informations tho

To Reproduce
Create an interaction,
add the on_interaction_event

add this line to print member info
printf("info = %s\n", (event.command.member.build_json()).c_str());

Expected behavior
member to be populated correctly

System Details:
v9.0.18

banner-url helpers

Is your feature request related to a problem? Please describe.
support for banner-urls on users and guilds.

Describe the solution you'd like
guild only have has_banner. It would be cool to have something like get_banner_url in it. Same as guild_member and/or user (Edit: also Channel banners).

Linker error with libopus

When compiling the library itself, all files compile correctly, then, when Linking CXX shared library libdpp.so, I get the following error :

/usr/bin/ld: /usr/local/lib/libopus.a(decode_indices.c.o): warning: relocation against `silk_NLSF_EXT_iCDF' in read-only section `.text'
/usr/bin/ld: /usr/local/lib/libopus.a(celt_encoder.c.o): relocation R_X86_64_PC32 against symbol `tf_select_table' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: bad value
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/dpp.dir/build.make:1943: libdpp.so] Error 1
make[1]: *** [CMakeFiles/Makefile2:85: CMakeFiles/dpp.dir/all] Error 2
make: *** [Makefile:156: all] Error 2

I tried using cmake -D CMAKE_CXX_FLAGS=-fPIC .. on an empty build directory, but it didn't change a thing.
I checked, libopus was compiled with -fPIC. I don't understand.

I followed the build instructions in the docs :

git clone --recursive [email protected]:/brainboxdotcc/DPP
cd DPP
mkdir build
cd build
cmake .. //Also tried with -D CMAKE_CXX_FLAGS=-fPIC
make -j4 //I only have 4 cores on my CPU

Cmake does find libopus & libsodium correctly - here is the output of cmake .. on the empty build directory.

-- The CXX compiler identification is GNU 11.1.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found sodium: /usr/lib/libsodium.so (found version "1.0.18") 
-- Found Opus: /usr/local/include  
-- Sodium 1.0.18
-- Detected libsodium and libopus. VOICE support will be enabled
-- Looking for C++ include pthread.h
-- Looking for C++ include pthread.h - found
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed
-- Check if compiler accepts -pthread
-- Check if compiler accepts -pthread - yes
-- Found Threads: TRUE  
-- Found ZLIB: /usr/lib/libz.so (found version "1.2.11") 
-- Found OpenSSL: /usr/lib/libcrypto.so (found version "1.1.1l")  
-- Building git version. Be aware git versions may be unstable!
-- Configuring done
-- Generating done
-- Build files have been written to: /[...]/DPP/build

I'm on Archlinux x86_64 5.15.4-arch1-1.
I have libopus and libsodium installed, and all packages are on their latest version (as of writing this) :

  • g++ 11.1.0
  • ld 2.36.1
  • cmake 3.22.0
  • lib32-opus 1.3.1-1 (installed from pacman - multilib)
  • libsodium 1.0.18-2 (installed from pacman - extra)
  • DPP commit b85115b

I'm sure the error is on my side, but I cannot tell what I'm doing wrong.

Edit: just tried with commit 8ab0ca5 with no luck.

Bad handling of optional parameters in slash commands by the unified command handler

When getting a parameter from an interaction event, if it isn't found, a reference to a default-constructed static variant is returned.
When being default-constructed, a variant holds a default-constructed instance of the first alternative.
This results in there being no clear indication whether the command was provided, since the variant just holds an empty string.

I suggest to prepend std::monostate to the alternatives of command_value, as to have a clear state for optional commands.

Directly related to this, the check to see if the parameter was optional in the routing for slash commands in the unified command handler checks for the variant being valueless by exception, even though that isn't the state if the parameter wasn't provided.

Though that is kinda caught by the exception handling around the following type switch, though this breaks when the type of the optional parameter is a string and is also hacky.

The proposed suggestion would also fix those issues.

Also, the integer branch of the type switch is missing a break :)

missing heartbeat handling?

Describe the bug
Instead of sending a heartbeat to the discord servers every ~40 seconds the connection is shutdown with code 1000 every minute (and immediately reconnected). After the connection is closed unexpectedly (eg. TCP error) the disconnect seems to be unhandled.

To Reproduce
I noticed the disconnect issue after I suspended my computer. After wakeup the bot was naturally disconnected from discord servers but the library never noticed or fixed this. All logs (even trace) stay empty.

Expected behavior

  • According to Discord documentation: first heartbeat after a random duration <= heartbeat_interval, subsequently one haertbeat every heartbeat_interval milliseconds.
  • Automatic resume, on failure reconnect if the connection is closed without a terminating message by discord servers.

System Details:

CMakeLists doesn't export `include/` include directory

Describe the bug
This library doesn't export its include/ path to other projects who may want to use it, meaning using a pure CMake build we can't include any of the dpp headers without manually including the dpp include directory. This doesn't follow modern CMake best practices.

To Reproduce
Make a simple project:

.
โ”œโ”€โ”€ CMakeLists.txt
โ”œโ”€โ”€ deps
โ”‚ย ย  โ””โ”€โ”€ dpp
โ””โ”€โ”€ src
    โ””โ”€โ”€ main.cpp

CMakeLists:

cmake_minimum_required(VERSION 3.0)
project(cppbot VERSION "0.0.1")

set(CMAKE_CXX_STANDARD 17)

add_subdirectory(deps/dpp)

add_executable(cppbot)

target_sources(cppbot PRIVATE
  src/main.cpp
)

target_link_libraries(cppbot PRIVATE
  dpp
)

And just include the dpp.h header in main.cpp:

#include <dpp/dpp.h>

int main() {
  dpp::cluster bot("zob");

  return 0;
}

Expected behavior
This program should compile as dpp should export its include/ directory, which is then included in cppbot when dpp is added as a target library.

Screenshots
image

System Details:

  • Linux + Arch
  • CMake 3.22.1
  • gcc 11.1

Receive Combined audio from users

JDA can receive combined audio, it is very convenient. We need the same feature.
Anyone who uses audio receive has to implement this feature by himself unfortunately.

Just combine all users' audio packets

Incorrect documentation on `dpp::interaction::usr`

Describe the bug
The comment on dpp::interaction::usr says that it's "only in DMs", but in reality dpp::interaction::member is empty on normal guild channel interactions (as far as I tested) and *::usr has the correct data instead.

The documentation should probably reflect that usr is not just for DMs. The interaction structure in discord's documentation also names user, but I'm unsure this is relevant.

To Reproduce
Steps to reproduce the behavior:

  1. Add
bot.on_interaction_create([&bot](const dpp::interaction_create_t& event) {
        if (event.command.type == dpp::it_application_command) {
            bot.log(dpp::ll_info, event.command.usr.username);
        }
}

... to a bot with existing / commands.
2. Invoke any slash command in a guild's channel (not in DMs)
3. You will see it incorrectly print the username successfully.

Expected behavior
I would expect it to not work due to this documentation comment: https://github.com/brainboxdotcc/DPP/blob/master/include/dpp/slashcommand.h#L353

on_guild_update

From what i have tested, the on_guild_update is only triggered once per server after a server is edited, if you try to edit it after once, the event isnt triggered, as seen in the photo, once you restart the bot it can be triggered again

image

Expected output there would be a new log in console with the server name being POGGERS

DM me brain if you dont know what i mean

slash command permissions broken

Describe the bug
I can create slash commands, but the permissions then wont work.

When i created a slash command and attached a permission role, the command will add successfully, no errors occurs in the lambda, but the actual permissions dont work, everyone can still use the command.

When i changed my dpp version to 9.0.5 it worked fine.
The issue is in the json that gets send to discord.

Comparing the json that gets send:

With DPP 9.0.16, (not working):

{
   "application_id":"910926270102143076",
   "default_permission":false,
   "description":"Schalte einen User stumm",
   "name":"mute",
   "options":[
      {
         "autocomplete":false,
         "description":"Der User der gestummt werden soll",
         "name":"user",
         "required":true,
         "type":6
      },
      {
         "autocomplete":false,
         "description":"Lรคnge der Stummschaltung (1d, 4h, 15m, 35s)",
         "name":"duration",
         "required":true,
         "type":3
      },
      {
         "autocomplete":false,
         "description":"Grund der Stummschaltung",
         "name":"reason",
         "required":true,
         "type":3
      }
   ],
   "permissions":[
      {
         "id":"897881982128754699",
         "permission":true,
         "type":1
      }
   ],
   "type":1
}

And DPP 9.0.5:

{
   "application_id":"910926270102143076",
   "default_permission":false,
   "description":"Schalte einen User stumm",
   "name":"mute",
   "options":[
      {
         "description":"Der User der gestummt werden soll",
         "name":"user",
         "required":true,
         "type":6
      },
      {
         "description":"Lรคnge der Stummschaltung (1d, 4h, 15m, 35s)",
         "name":"duration",
         "required":true,
         "type":3
      },
      {
         "description":"Grund der Stummschaltung",
         "name":"reason",
         "required":true,
         "type":3
      }
   ],
   "permissions":[
      {
         "id":"897881982128754699",
         "permission":true,
         "type":1
      }
   ]
}

It looks like the autocomplete tag breaks the permissions.

@Lohkdesgds said the issue is more a discord bug itself but i thought making an issue here could help people having the same issue :)

To Reproduce
Create some slashcommand with permissions like:

auto p = dpp::command_permission();
	p.id = 897881982128754699;
	p.type = dpp::cpt_role;
	p.permission = true;

dpp::slashcommand slash;
slash.set_name("manage")
    .set_application_id(bot.me.id)
    .add_option(dpp::command_option(dpp::co_string, "foobar", "blabla", true))
    .disable_default_permissions()
    .add_permission(p);

bot.guild_command_create(slash, /*guild_id*/);

Expected behavior
Only users with a specific role can execute the slash command

System Details:
DPP version 9.0.16

Additional context
Big thanks to @Lohkdesgds who helped me finding the problem.

timestamp setter on embed objects

Is your feature request related to a problem? Please describe.
I was wondering that there's no setter for the timestamp of an embed.
All other properties of a embedded message already have a setter, so why not also on the timestamp as well?
I personally prefer setters as they tell me of what type the argument must be.

Describe the solution you'd like
A setter

Describe alternatives you've considered
The alternative is to just do nothing and leave everything as it is. lul

CMake issue with Threads on linux

It seems like whenever you try to compile the library on Ubuntu 20.04+ with CMake 3.16.0 the Threads part fails with:
undefined reference to pthread_create

I already looked up the issue on google but everything always leads to issues with the way stuff is linked.

The error log:

gmake[1]: Entering directory '/home/marie/Documents/Projects/DPP/build/CMakeFiles/CMakeTmp'
Building CXX object CMakeFiles/cmTC_68755.dir/src.cxx.o
/usr/bin/c++    -DCMAKE_HAVE_LIBC_PTHREAD   -o CMakeFiles/cmTC_68755.dir/src.cxx.o -c /home/marie/Documents/Projects/DPP/build/CMakeFiles/CMakeTmp/src.cxx
Linking CXX executable cmTC_68755
/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_68755.dir/link.txt --verbose=1
/usr/bin/c++   -DCMAKE_HAVE_LIBC_PTHREAD    CMakeFiles/cmTC_68755.dir/src.cxx.o  -o cmTC_68755 
/usr/bin/ld: CMakeFiles/cmTC_68755.dir/src.cxx.o: in function `main':
src.cxx:(.text+0x46): undefined reference to `pthread_create'
/usr/bin/ld: src.cxx:(.text+0x52): undefined reference to `pthread_detach'
/usr/bin/ld: src.cxx:(.text+0x63): undefined reference to `pthread_join'
collect2: error: ld returned 1 exit status
gmake[1]: *** [CMakeFiles/cmTC_68755.dir/build.make:87: cmTC_68755] Error 1
gmake[1]: Leaving directory '/home/marie/Documents/Projects/DPP/build/CMakeFiles/CMakeTmp'
gmake: *** [Makefile:121: cmTC_68755/fast] Error 2


Source file was:
#include <pthread.h>

void* test_func(void* data)
{
  return data;
}

int main(void)
{
  pthread_t thread;
  pthread_create(&thread, NULL, test_func, NULL);
  pthread_detach(thread);
  pthread_join(thread, NULL);
  pthread_atfork(NULL, NULL, NULL);
  pthread_exit(NULL);

  return 0;
}

undefined reference when trying to compile bot

So after the last issue I have tried to compile a example program from the docs but for unknown reasons it only spits out undefined reference errors while vscode shows me that dpp is indeed found in the default include directories for c++
image

Support for building without vendored dependencies

Is your feature request related to a problem? Please describe.
Currently, DPP ships with three dependencies directly integrated into the source tree.
While this is very comfortable for users and developers, it is a nightmare for package maintainers, trying to integrate the software properly into their system and (in the process) removing vendored dependencies.

I managed to remove nlohmann JSON as a vendored dependency with a bunch of sed and rm, but creating this patch was already painful.

From the point of properly documenting all required licenses and being able to install patched versions of dependencies without having to depend on the downstream library to bump a new release, it is desirable for package maintainers to have the libary only use system-installed dependencies and no vendored ones.

Describe the solution you'd like
Preferably, removing all vendored dependencies.
But since I see valid reasons for vendoring dependencies which aren't commonly available in distributions, it's probably better to move the vendored dependencies to a separate subdirectory and providing a CMake option to disable the inclusion of vendored dependencies.

Describe alternatives you've considered
The alternative is the status quo, but I've explained why I'd like to see the change.

Additional context

user discriminator zero disappears

Describe the bug
In discord, i have a discriminator of 0098.
due its an uint16_t in dpp, the zeros disappear :(

To Reproduce

cout << "Member discriminator: " << user.discriminator << endl;

printing my discriminator:

98

bot.reply() Unknown Channel

When calling the reply function in dpp::cluster the callback contains an error with the message "Unknown Channel" and doesn't send the reply. there is nothing in error_info.

To Reproduce

void Roles(const dpp::message_create_t &event)
{
    bot.roles_get(event.msg.guild_id, [&](const dpp::confirmation_callback_t &confm)
    {
        if (confm.is_error())
        {
            std::string err = confm.get_error().message;
            std::cout << "get_roles: " << err << std::endl;
            throw err;
        }

        dpp::role_map allRoles = std::get<dpp::role_map>(confm.value);

        std::string roleText = "\\";

        for (auto it = allRoles.begin(); it != allRoles.end(); it++)
            roleText = it->second.name + "\n" + roleText;

        event.reply(roleText, 0, [&](const dpp::confirmation_callback_t &rply)
        {
            if (rply.is_error())
            {
                dpp::error_info err = rply.get_error();
                std::cout << "reply: " << err.message << std::endl;

                std::vector<dpp::error_detail> detail = err.errors;

                for (auto it = detail.begin(); it != detail.end(); it++)
                    std::cout << &it->code << ": " << &it->field << ": " << &it->object << ": " << &it->reason << std::endl;

                throw err.message;
            }
        });

        std::cout << roleText << std::endl;
    });
}

System Details:

  • OS: Arch Linux (5.16.8-arch1-1)

Additional context
Other similar functions that call reply() do work, for example:

void Repeat(const dpp::message_create_t &event)
{
    std::string input = sliceString(event.msg.content, sizeof("!repeat"));

    event.reply("```" + input + "```");
}

Darkmode for Note in documentation

Describe the bug
Noteblock in darkmode in the documentation has white text color and light yellow as background so its unreadable.
Found this here https://dpp.dev/commandhandler.html

To Reproduce
Steps to reproduce the behavior:
Turn on darkmode

Expected behavior
The text to be in dark (black or so...)

Screenshots
grafik

System Details:

  • OS: Linux Ubuntu
  • Firefox latest version on desktop

Additional context

stage_instance_get does not return a stage instance

Describe the bug
when calling dpp::cluster::stage_instance_get, it throws

terminate called after throwing an instance of 'std::bad_variant_access'
  what():  std::get: wrong index for variant

when i get the stage instance in the callback.
Same with stage_instance_create and stage_instance_edit.

Expected behavior
having the stage instance in it.

System Details:

  • DPP 9.0.18

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.