Giter Site home page Giter Site logo

cee-studio / orca Goto Github PK

View Code? Open in Web Editor NEW
352.0 9.0 30.0 37.71 MB

C Multi-REST API library for Discord, Slack, Reddit, etc.

Home Page: https://cee-studio.github.io/orca/

License: MIT License

Shell 0.04% Makefile 0.34% C 99.62%
c curl discord slack reddit websockets github bot discord-bot discord-api

orca's People

Contributors

azbantium avatar bchiu3 avatar furmissile avatar julienraynal avatar kralverde avatar lcsmuller avatar mateuskater avatar mlite avatar papaulogamerofc avatar straight-into-the-wall avatar tarbomb avatar thechosenprometheanking avatar thepedroo avatar yattaro 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

orca's Issues

Add a coding guide line

@LucasMull your coding style is very good. can you please make a guide line for future contributors?

proposition to create json_printf() to circumvent the need of escaped commas

We should create a new function json_printf(), that reads a string formatted in the likes of json_scanf() and write a json formatted string to a buffer as result. This will ensure readability when creating our own json strings, and consistency with the already existing json_scanf(). Here is an example:

char buf[256];
json_printf(buf, sizeof(buf)-1, "[t][ta]%d, [k]%s", 4, "Hello There");

The expected string generated from this format is expected to be:

{
    "t" : {
        "ta" : 4
    },
    "k" : "Hello There"
}

[json-scanf] support the size of json string/object that is unknown at compile time.

The current json-scanf design is based on the assumption we know the size of all json objects and json strings. But there are situations that we don't know the length of an object or a string. We need a specifier that can tell json-scanf to allocate memory dynamically at runtime. I propose a new decorator ? for "%s" and "%S".

%?s and %?S will tell json-scanf to allocate memory large enough to store the matched string/object at runtime.

usage example:

char * sptr = NULL;
json_scanf(str, len, "%?s", &sptr);  // the last parameter needs to be char **. 

It's the responsibility of callers to free the memory pointed by sptr;

A tester bot

The bot will read data or generate data randomly and send messages to a channel at a either predefined interval or random interval.

add a new json path specifier for array

For json array of the following form,

"abc": [  "a", "b", "c", 1, 2, 3 ]

It's better we can extract any elements from it with json_scanf. In order to do this, we need a new path specifier to index the array's elements.
Here is one proposal for the path specifier:

json_scanf(str, "%d[abc][3]" ,&i); // get 1 and assign it to i. 

Invalid Discord Gateway opcode (code: 7)

I got this error after I started a second bot with the same token:

[discord-websockets.c:132] _ws_on_text_cb()
    ERROR:    Invalid Discord Gateway opcode (code: 7)
Aborted

the first bot was killed by this error, the second one is still running.

echo-bot existed with a memory error

  Memory access error: writing to the outside of a memory block; abort!
  # Writing 1 bytes to 0xa3aab70 will clobber other memory blocks.
  # 
  # The memory-block-to-be-written (start:0xa3aab50, size:32 bytes) is allocated at
  #    file:/home/nwang/workspace/orca/discord-public-user.c::18, 24
  #    file:/home/nwang/workspace/orca/discord-api.c::322, 23
  #    file:/home/nwang/workspace/orca/discord-websockets.c::83, 5
  #    file:/home/nwang/workspace/orca/discord-websockets.c::152, 7
  #    file:/home/nwang/workspace/orca/curl-websocket.c::587, 17
  #    file:/home/nwang/workspace/orca/curl-websocket.c::795, 5
  #    file:/home/nwang/workspace/orca/curl-websocket.c::814, 23
  #    file:/home/nwang/workspace/packages/tiny-curl-7.72.0/lib/sendf.c::582, 15
  # 
  #  0xa3aab50           0xa3aab6f
  #  +--------------------------+
  #  |memory-block-to-be-written|......
  #  +--------------------------+
  #                              ^~~~~~~~~~
  #        the write starts at 0xa3aab70 that is right after the memory block end.
  # 
  # Stack trace (most recent call first) of the write.
  # [0]  file:/home/nwang/workspace/orca/jscon-common.c::40, 13
  # [1]  file:/home/nwang/workspace/orca/json-scanf.c::184, 13
  # [2]  file:/home/nwang/workspace/orca/json-scanf.c::503, 17
  # [3]  file:/home/nwang/workspace/orca/discord-api.c::358, 3
  # [4]  file:/home/nwang/workspace/orca/discord-api.c::326, 3
  # [5]  file:/home/nwang/workspace/orca/discord-websockets.c::83, 5
  # [6]  file:/home/nwang/workspace/orca/discord-websockets.c::152, 7
  # [7]  file:/home/nwang/workspace/orca/curl-websocket.c::587, 17
  # [8]  file:/home/nwang/workspace/orca/curl-websocket.c::795, 5
  # [9]  file:/home/nwang/workspace/orca/curl-websocket.c::814, 23
  # [10]  file:/home/nwang/workspace/packages/tiny-curl-7.72.0/lib/sendf.c::582, 15
  # [11]  file:/home/nwang/workspace/packages/tiny-curl-7.72.0/lib/sendf.c::666, 10
  # [12]  file:/home/nwang/workspace/packages/tiny-curl-7.72.0/lib/transfer.c::894, 26
  # [13]  file:/home/nwang/workspace/packages/tiny-curl-7.72.0/lib/transfer.c::1254, 14
  # [14]  file:/home/nwang/workspace/packages/tiny-curl-7.72.0/lib/multi.c::2152, 16
  # [15]  file:/home/nwang/workspace/packages/tiny-curl-7.72.0/lib/multi.c::2422, 14
  # [16]  file:/home/nwang/workspace/orca/discord-websockets.c::292, 13
  # [17]  file:/home/nwang/workspace/orca/discord-websockets.c::315, 3
  # [18]  file:/home/nwang/workspace/orca/discord-public.c::59, 3
  # [19]  file:/home/nwang/workspace/orca/echo-bot.c::38, 3
  # [20]  [libc-start-main]

json_scanf2: the max number of nested paths and the max key length

I propose to set up the above to max numbers:

  1. the max number of nested path : 8
  2. the max number of key length: 128

This function is designed to de-serialize data from rest API. I expect most JSON data from rest API will not exceed the two limits. But the two limits will simplify the memory management and reduce the number of malloc/free.
Let me what do you think?
I can make a change.

discord-common.h

This file lists all very important size information. This is really great. It must take a lot of time to find these limits. I tried to search them on discord, but I could not find them. I was wondering if you can point out the link for me?

echo-bot aborted after a bot joined the test server.

[discord-websockets.c:255] ws_on_text_cb()
        ON_TEXT:
                {"t":"MESSAGE_CREATE","s":67,"op":0,"d":{"type":7,"tts":false,"timestamp":"2021-01-15T16:58:32.678000+00:00","pinned":false,"mentions":[],"mention_roles":[],"mention_everyone":false,"member":{"roles":["799683956206993459"],"premium_since":null,"pending":false,"nick":null,"mute":false,"joined_at":"2021-01-15T16:58:32.598293+00:00","is_pending":false,"hoisted_role":null,"deaf":false},"id":"799683956664172544","flags":0,"embeds":[],"edited_timestamp":null,"content":"","channel_id":"796672077309673497","author":{"username":"bot-bob","public_flags":0,"id":"796671542879846431","discriminator":"5481","bot":true,"avatar":null},"attachments":[],"guild_id":"796672077309673492"}}
        OP:             GATEWAY_DISPATCH
        EVENT_NAME:     MESSAGE_CREATE
        SEQ_NUMBER:     67
        EVENT_DATA:     {"type":7,"tts":false,"timestamp":"2021-01-15T16:58:32.678000+00:00","pinned":false,"mentions":[],"mention_roles":[],"mention_everyone":false,"member":{"roles":["799683956206993459"],"premium_since":null,"pending":false,"nick":null,"mute":false,"joined_at":"2021-01-15T16:58:32.598293+00:00","is_pending":false,"hoisted_role":null,"deaf":false},"id":"799683956664172544","flags":0,"embeds":[],"edited_timestamp":null,"content":"","channel_id":"796672077309673497","author":{"username":"bot-bob","public_flags":0,"id":"796671542879846431","discriminator":"5481","bot":true,"avatar":null},"attachments":[],"guild_id":"796672077309673492"}
[discord-api.c:379] Discord_api_load_user()
        User loaded with API response
[discord-api.c:379] Discord_api_load_user()
        User loaded with API response
[discord-api.c:321] Discord_api_load_message()
        Message loaded with API response
[discord-api.c:236] perform_request()
        Request URL: https://discord.com/api/channels/796672077309673497/messages
[discord-api.c:265] perform_request()
        ERROR:  Unknown HTTP response code 400
Aborted

add a new path specifier for indexing json array.

For json array of the following form,

"abc": [  "a", "b", "c", 1, 2, 3 ]

It's better we can extract any elements from it with json_scanf. In order to do this, we need a new path specifier to index the array's elements.
Here is one proposal for the path specifier:

json_scanf(str, "%d[abc][3]" ,&i); // get 1 and assign it to i. 

oob read

 Memory access error: reading from the outside of a memory block; abort!
  # Reading 4 bytes from 0xffbc85fc will read undefined values.
  # 
  # The memory-block-to-be-read (start:0xffbc85dc, size:32 bytes) is allocated at
  #    cmg.in.stensal.discord_send_message
  # 
  #  0xffbc85dc           0xffbc85fb
  #  +--------------------------+
  #  | memory-block-to-be-read  |......
  #  +--------------------------+
  #                              ^~~~~~~~~~
  #        the read starts at 0xffbc85fc that is right after the memory block end.
  # 
  # Stack trace (most recent call first) of the read.
  # [0]  file:/musl-1.1.10/src/stdio/vfprintf.c::134, 19
  # [1]  file:/musl-1.1.10/src/stdio/vfprintf.c::534, 16
  # [2]  file:/musl-1.1.10/src/stdio/vfprintf.c::678, 8
  # [3]  file:/musl-1.1.10/src/stdio/vsnprintf.c::37, 6
  # [4]  file:/musl-1.1.10/src/stdio/vsprintf.c::6, 9
  # [5]  file:/workspace/orca/discord-api.c::400, 3
  # [6]  file:/workspace/orca/discord-public-message.c::83, 3
  # [7]  file:/workspace/orca/echo-bot.c::28, 5
  # [8]  file:/workspace/orca/discord-websockets.c::171, 5
  # [9]  file:/workspace/orca/discord-websockets.c::305, 7
  # [10]  file:/workspace/orca/curl-websocket.c::587, 17
  # [11]  file:/workspace/orca/curl-websocket.c::795, 5
  # [12]  file:/workspace/orca/curl-websocket.c::814, 23
  # [13]  file:/workspace/packages/tiny-curl-7.72.0/lib/sendf.c::582, 15
  # [14]  file:/workspace/packages/tiny-curl-7.72.0/lib/sendf.c::666, 10
  # [15]  file:/workspace/packages/tiny-curl-7.72.0/lib/transfer.c::894, 26
  # [16]  file:/workspace/packages/tiny-curl-7.72.0/lib/transfer.c::1254, 14
  # [17]  file:/workspace/packages/tiny-curl-7.72.0/lib/multi.c::2152, 16
  # [18]  file:/workspace/packages/tiny-curl-7.72.0/lib/multi.c::2422, 14
  # [19]  file:/workspace/orca/discord-websockets.c::460, 13
  # [20]  file:/workspace/orca/discord-websockets.c::487, 5
  # [21]  file:/workspace/orca/discord-public.c::102, 3
  # [22]  file:/workspace/orca/echo-bot.c::80, 3
  # [23]  [libc-start-main]
  https://cee.studio/explanation

CURLM_OK == mcode

echo-bot ran 203m40.358s before exiting with the following error.

[discord-websockets.c:159] on_reconnect()
        Attempting to reconnect to Discord WebSockets ...
[discord-websockets.c:390] ws_main_loop()
        ERROR:  Assert Failed:  Error
        Expected:       CURLM_OK == mcode
Aborted

Whats the optimal format for an array of objects?

Sometimes the API will deliver a JSON containing an array of some object (guild, user, channel, ...). What would be the optimal way to represent an array of objects? I've thought of three options:

  1. Create a new struct format for each object, containing its array format and an attribute for size:
typedef struct discord_lguild_s {
    discord_guild_t *guilds;
    size_t size;
} discord_lguild_t;

typedef struct discord_luser_s {
    discord_guild_t *users;
    size_t size;
} discord_luser_t;

Unfortunately, this means we would need to double the amount of structs.

  1. We create a new struct for lists, like the first one, but with an extra field for type of list:
typedef struct discord_list_s {
    enum list_type type;
    void *objs;
    size_t size;
} discord_list_t;
  1. We don’t create new structs. Instead we simply NULL terminate each array of objects as such
int main() 
{
    discord_guild_t *guilds;
    discord_get_guilds(client, &guilds);

    for (int i=0; guilds[i] != NULL; ++i) { 
        printf(“Guild Name: %s\n”, guilds[i].name);
    }
}

Discord WebSocket requesting client reconnect

[discord-websockets.c:103] _ws_on_close_cb()
CLOSE=1001 46 bytes 'Discord WebSocket requesting client reconnect.'
* Operation timed out after 6517351 milliseconds with 7102 bytes received
* SSL: EOF without close notify

out-of-bound write

I typed 'yo bot' to trigger this out-of-bound access.

OP:             GATEWAY_DISPATCH
        EVENT_NAME:     MESSAGE_CREATE
        SEQ_NUMBER:     6
        EVENT_DATA:     {"type":0,"tts":false,"timestamp":"2021-01-11T17:05:55.039000+00:00","referenced_message":null,"pinned":false,"nonce":"798236060843769856","mentions":[],"mention_roles":[],"mention_everyone":false,"member":{"roles":["701251877039243364","703021940784234507","722639588543299677"],"mute":false,"joined_at":"2019-04-02T17:45:27.768000+00:00","hoisted_role":"701251877039243364","deaf":false},"id":"798236260597497896","flags":0,"embeds":[],"edited_timestamp":null,"content":"yo bot","channel_id":"562694099887587340","author":{"username":"garth","public_flags":0,"id":"562693705505701889","discriminator":"8223","avatar":"e09a27bc13f2c21ebeb2f6124c3c3f92"},"attachments":[],"guild_id":"562694099887587338"}

  Memory access error: writing to the outside of a memory block; abort!
  # Writing 1 bytes to 0xa4a97e4 will clobber other memory blocks.
  # 
  # The memory-block-to-be-written (start:0xa4a97e0, size:4 bytes) is allocated at
  #    file:/home/nwang/workspace/orca/discord-public-user.c::21, 29
  #    file:/home/nwang/workspace/orca/discord-api.c::330, 23
  #    file:/home/nwang/workspace/orca/discord-websockets.c::84, 5
  #    file:/home/nwang/workspace/orca/discord-websockets.c::172, 7
  #    file:/home/nwang/workspace/orca/curl-websocket.c::587, 17
  #    file:/home/nwang/workspace/orca/curl-websocket.c::795, 5
  #    file:/home/nwang/workspace/orca/curl-websocket.c::814, 23
  #    file:/home/nwang/workspace/packages/tiny-curl-7.72.0/lib/sendf.c::582, 15
  # 
  #  0xa4a97e0           0xa4a97e3
  #  +--------------------------+
  #  |memory-block-to-be-written|......
  #  +--------------------------+
  #                              ^~~~~~~~~~
  #        the write starts at 0xa4a97e4 that is right after the memory block end.
  # 
  # Stack trace (most recent call first) of the write.
  # [0]  file:/home/nwang/workspace/orca/jscon-common.c::40, 13
  # [1]  file:/home/nwang/workspace/orca/json-scanf.c::183, 13
  # [2]  file:/home/nwang/workspace/orca/json-scanf.c::502, 17
  # [3]  file:/home/nwang/workspace/orca/discord-api.c::366, 3
  # [4]  file:/home/nwang/workspace/orca/discord-api.c::334, 3
  # [5]  file:/home/nwang/workspace/orca/discord-websockets.c::84, 5
  # [6]  file:/home/nwang/workspace/orca/discord-websockets.c::172, 7
  # [7]  file:/home/nwang/workspace/orca/curl-websocket.c::587, 17
  # [8]  file:/home/nwang/workspace/orca/curl-websocket.c::795, 5
  # [9]  file:/home/nwang/workspace/orca/curl-websocket.c::814, 23
  # [10]  file:/home/nwang/workspace/packages/tiny-curl-7.72.0/lib/sendf.c::582, 15
  # [11]  file:/home/nwang/workspace/packages/tiny-curl-7.72.0/lib/sendf.c::666, 10
  # [12]  file:/home/nwang/workspace/packages/tiny-curl-7.72.0/lib/transfer.c::894, 26
  # [13]  file:/home/nwang/workspace/packages/tiny-curl-7.72.0/lib/transfer.c::1254, 14
  # [14]  file:/home/nwang/workspace/packages/tiny-curl-7.72.0/lib/multi.c::2152, 16
  # [15]  file:/home/nwang/workspace/packages/tiny-curl-7.72.0/lib/multi.c::2422, 14
  # [16]  file:/home/nwang/workspace/orca/discord-websockets.c::320, 13
  # [17]  file:/home/nwang/workspace/orca/discord-websockets.c::343, 3
  # [18]  file:/home/nwang/workspace/orca/discord-public.c::59, 3
  # [19]  file:/home/nwang/workspace/orca/echo-bot.c::38, 3
  # [20]  [libc-start-main]
  https://cee.studio/explanation

Improve the error message

One user used an invalid token, and got the following message.

[discord-api.c:268] perform_request()
    ERROR:    Unknown HTTP response code 401
Aborted (core dumped)

He didn't know how to fix the problem by reading this error. Is it possible to improve the error message to "Unauthorized request, the probably cause: invalid bot token"?

[discord-api.c:268] perform_request()
    ERROR:    401 Unauthorized, probably cause: invalid bot token
Aborted (core dumped)

bot exited with 1011

We need to understand where the 1011 code comes from.

my bot aborted with this

[discord-websockets.c:108] on_reconnect()
        Attempting to reconnect to Discord WebSockets ...
        RESUME PAYLOAD:
        {"op":6,"d":{"token":"xxxx","session_id":"118667356330c2287b8865b8704b7fc3","seq":55}}
[discord-websockets.c:138] ws_on_close_cb()
        CLOSE=1011 0 bytes ''
* Operation timed out after 4930526 milliseconds with 58426 bytes received
* SSL: EOF without close notify

from ws RFC

1011

      1011 indicates that a server is terminating the connection because
      it encountered an unexpected condition that prevented it from
      fulfilling the request.

from cloudflare

Error 1011: Access Denied (Hotlinking Denied)
Common cause

A request is made for a resource that uses Cloudflare hotlink protection.
Resolution

Notify the website owner of the blocking. If you cannot determine how to contact the website owner, lookup contact information for the domain via the Whois database.  Hotlink Protection is managed via the Cloudflare Scrape Shield app.

Unimplemented method: MESSAGE_DELETE

echo-bot exited with this after I deleted a message.

	EVENT_DATA:	{"id":"797910163448791091","channel_id":"562694099887587340","guild_id":"562694099887587338"}
[discord-websockets.c:91] _discord_on_dispatch()
	ERROR:	Unimplemented GATEWAY_DISPATCH event: MESSAGE_DELETE

make self a part of client

void on_message(discord_t *client, discord_message_t *message)
{
  discord_user_t *self = discord_user_init();
  assert(NULL != self);

  discord_get_client_user(client, &self);

Can we only call discord_get_client_user once after client is initialized?
This will certainly reduce the number of redundant calls, it might improve the reliability.

New HTTP code: 500

discord-websockets.c:276] ws_on_text_cb()
        ON_TEXT:
                {"t":"MESSAGE_CREATE","s":3,"op":0,"d":{"type":0,"tts":false,"timestamp":"2021-01-19T00:11:25.027000+00:00","referenced_message":null,"pinned":false,"nonce":"800879800469159936","mentions":[],"mention_roles":[],"mention_everyone":false,"member":{"roles":["798978236901621760","799770797681934356"],"premium_since":null,"pending":false,"nick":null,"mute":false,"joined_at":"2021-01-07T09:30:24.689000+00:00","is_pending":false,"hoisted_role":"798978236901621760","deaf":false},"id":"800880056188534816","flags":0,"embeds":[],"edited_timestamp":null,"content":"j","channel_id":"796910034058870804","author":{"username":"garth","public_flags":0,"id":"562693705505701889","discriminator":"8223","avatar":"e09a27bc13f2c21ebeb2f6124c3c3f92"},"attachments":[],"guild_id":"796672077309673492"}}
        OP:             GATEWAY_DISPATCH
        EVENT_NAME:     MESSAGE_CREATE
        SEQ_NUMBER:     3
        EVENT_DATA:     {"type":0,"tts":false,"timestamp":"2021-01-19T00:11:25.027000+00:00","referenced_message":null,"pinned":false,"nonce":"800879800469159936","mentions":[],"mention_roles":[],"mention_everyone":false,"member":{"roles":["798978236901621760","799770797681934356"],"premium_since":null,"pending":false,"nick":null,"mute":false,"joined_at":"2021-01-07T09:30:24.689000+00:00","is_pending":false,"hoisted_role":"798978236901621760","deaf":false},"id":"800880056188534816","flags":0,"embeds":[],"edited_timestamp":null,"content":"j","channel_id":"796910034058870804","author":{"username":"garth","public_flags":0,"id":"562693705505701889","discriminator":"8223","avatar":"e09a27bc13f2c21ebeb2f6124c3c3f92"},"attachments":[],"guild_id":"796672077309673492"}
        User object loaded with API response
        User object loaded with API response
        Message object loaded with API response
[discord-api.c:263] perform_request()
        Request URL: https://discord.com/api/channels/796910034058870804/messages
[discord-api.c:30] http_code_print()
        ERROR:  Invalid HTTP response code (code: 500)

New function to initialize the client simply by passing the config file as parameter

We have the option of doing this currently:

  static struct bot_settings settings;

  bot_settings_init(&settings, "bot.config");

  discord_global_init();

  discord_t *client = discord_init(settings.discord.token);
  assert(NULL != client);

  if (settings.logging.dump_json.enable)
    discord_dump_json(client, settings.logging.dump_json.filename);
  if (settings.logging.dump_curl.enable)
    discord_dump_curl(client, settings.logging.dump_curl.filename);

Instead we could achieve the same with:

discord_t *client = discord_fast_init("bot.config");

Then it will automatically detect the fields set by bot.config and set them accordingly.

dump http response bodies into unique tmp files

We need to understand what are sent to us by discord and be able to reapply these data to our de-serialization functions and business logic. For each response body, we generate a unique file name, and write the body to the file.

ERROR: Assert Failed: Couldn't send resume payload

[discord-websockets.c:110] on_reconnect()
        Attempting to reconnect to Discord WebSockets ...
        RESUME PAYLOAD:
        {"op":6,"d":{"token":"xxx","session_id":"5c7b7db9cc0f468a9284e9a66b533aa0","seq":97}}
cannot send data to closed WebSocket connection 0xa43fbd0[discord-websockets.c:334] try_resume()
        ERROR:  Assert Failed:  Couldn't send resume payload
        Expected:       true == ret
Aborted

echo-bot exited with assert error

[discord-api.c:378] Discord_api_load_user()
        User loaded with API response
[discord-api.c:378] Discord_api_load_user()
        User loaded with API response
[discord-api.c:320] Discord_api_load_message()
        Message loaded with API response

[discord-api.c:226] perform_request()
        ERROR:  Assert Failed:  Error
        Expected:       CURLE_OK == ecode
Aborted

real    501m42.289s
user    2m7.136s
sys     0m1.476s

safer alternative for discord-api.c:399-400

Less safe version

  char url_route[MAX_URL_LEN];
  vsprintf(url_route, endpoint, args);

Safer version

  char url_route[MAX_URL_LEN];
  int ret = vsnprintf(url_route, sizeof(url_route), endpoint, args);
  ASSERT_P(ret < sizeof(url_route), "out-of-bounds write of url_route");

Improve the readability of discord-public-user.c

If Discord_api_load_user is moved to discord-public-user.c, The relation between discord_user_t and the corresponding json string will become clear.

This applies to other Discord_api_load_xxx functions.

Remove the build of shared lib and dynamic linking

Dynamic lib and dynamic linking are good for the situations to avoid re-linking the executions for minor changes in the libraries. But it also increase the complexity of deployment (all shared libraries need to be deployed to the correct paths). By linking everything statically, we can avoid the deployment complexity.
@LucasMull If you don't have objections, I will change the Makefile to remove the steps to build a shared lib.

echo-bot.c:23-24

 if (true == message->author->bot)
    return;

can be simplified as

 if (message->author->bot)
    return;

to improve readability.

How to handle invalid session?

[discord-websockets.c:278] ws_on_text_cb()
    ON_TEXT:
        {"t":null,"s":null,"op":9,"d":false}
    OP:        GATEWAY_INVALID_SESSION
    EVENT_NAME:    NULL
    SEQ_NUMBER:    38
    EVENT_DATA:    false
[discord-websockets.c:225] on_reconnect()
    Attempting to reconnect to WebSockets

It seems the discord server thought the bot client is dead and invalid a session. How should we handle this error? It seems a simple reconnect won't work.

* SSL: EOF without close notify

the bot stopped with this message. It might be a reliability problem of bearssl. We should use openssl, mbedtls or wolfssl which is more stable.

set longer timeouts for curl

This a special request for my builds that are compiled with stensal-c. Because my code are slower than normal, I was wondering if it's possible to expose the timeout options to the bot.config so we can set to longer values.

echo-bot segfaults after a MESSAGE_DELETE event is detected.

Only happens when compiled with stensal-c. May be related with #71, but I'm not sure yet.
Here is the stack trace:

[discord-websockets.c:276] ws_on_text_cb()
        ON_TEXT:
                {"t":"MESSAGE_DELETE","s":8,"op":0,"d":{"id":"799981057918369812","channel_id":"796910034058870804","guild_id":"796672077309673492"}}
        OP:             GATEWAY_DISPATCH
        EVENT_NAME:     MESSAGE_DELETE
        SEQ_NUMBER:     8
        EVENT_DATA:     {"id":"799981057918369812","channel_id":"796910034058870804","guild_id":"796672077309673492"}
[discord-public-user.c:54] Discord_public_load_user()
        User loaded with API response

  Memory access error: dereferencing an uninitialized pointer; abort!
  # Reading 1 bytes from a random address (0xff9deebc).
  # 
  # Stack trace (most recent call first) of the read.
  # [0]  file:/home/lucasmull/Trabalho/orca/./jsmn.h::275, 3
  # [1]  file:/home/lucasmull/Trabalho/orca/json-scanf.c::513, 17
  # [2]  file:/home/lucasmull/Trabalho/orca/discord-public-user.c::26, 3
  # [3]  file:/home/lucasmull/Trabalho/orca/discord-public-message.c::91, 3
  # [4]  file:/home/lucasmull/Trabalho/orca/discord-websockets.c::204, 5
  # [5]  file:/home/lucasmull/Trabalho/orca/discord-websockets.c::309, 7
  # [6]  file:/home/lucasmull/Trabalho/orca/curl-websocket.c::587, 17
  # [7]  file:/home/lucasmull/Trabalho/orca/curl-websocket.c::795, 5
  # [8]  file:/home/lucasmull/Trabalho/orca/curl-websocket.c::814, 23
  # [9]  file:/home/sbuilder/worker/acore_workdir/build/packages/curl-7.72.0/lib/sendf.c::582, 15
  # [10]  file:/home/sbuilder/worker/acore_workdir/build/packages/curl-7.72.0/lib/sendf.c::666, 10
  # [11]  file:/home/sbuilder/worker/acore_workdir/build/packages/curl-7.72.0/lib/transfer.c::894, 26
  # [12]  file:/home/sbuilder/worker/acore_workdir/build/packages/curl-7.72.0/lib/transfer.c::1254, 14
  # [13]  file:/home/sbuilder/worker/acore_workdir/build/packages/curl-7.72.0/lib/multi.c::2150, 16
  # [14]  file:/home/sbuilder/worker/acore_workdir/build/packages/curl-7.72.0/lib/multi.c::2420, 14
  # [15]  file:/home/lucasmull/Trabalho/orca/discord-websockets.c::464, 13
  # [16]  file:/home/lucasmull/Trabalho/orca/discord-websockets.c::491, 5
  # [17]  file:/home/lucasmull/Trabalho/orca/discord-public.c::102, 3
  # [18]  file:/home/lucasmull/Trabalho/orca/echo-bot.c::80, 3
  # [19]  [libc-start-main]
  https://cee.studio/explanation
Segmentation fault (core dumped)

how jscon_scanf handle null?

given this example

str = {   "key1": null }


jscon_scanf(str, "%s[key1]", s);

printf ("%s\n", s); // what will this print out? 

Allocate api objects dynamically or statically?

Should we allocate API objects statically? I'm not a fan of using triple pointers as a function parameter for fetching an array of objects.

Instead of:

discord_guild_t *guild = discord_guild_init();
discord_user_t *user = discord_user_init();
discord_channel_t *channel = discord_channel_init();

we do

discord_guild_t guild = {0}
discord_user_t user = {0}
discord_channel_t channel = {0}

But for

discord_t *client = discord_init(token);

it remains the same

dereferencing a null pointer

I built it from the latest code.

[discord-websockets.c:99] on_reconnect()
        Attempting to reconnect to Discord WebSockets ...

  Memory access error: dereferencing a null pointer; abort!
  # Reading 4 bytes from address 0x0.
  # 
  # Stack trace (most recent call first) of the read.
  # [0]  file:/home/nwang/workspace/orca/json-scanf.c::349, 9
  # [1]  file:/home/nwang/workspace/orca/json-scanf.c::417, 17
  # [2]  file:/home/nwang/workspace/orca/json-scanf.c::463, 5
  # [3]  file:/home/nwang/workspace/orca/discord-websockets.c::106, 3
  # [4]  file:/home/nwang/workspace/orca/discord-websockets.c::175, 7
  # [5]  file:/home/nwang/workspace/orca/curl-websocket.c::587, 17
  # [6]  file:/home/nwang/workspace/orca/curl-websocket.c::795, 5
  # [7]  file:/home/nwang/workspace/orca/curl-websocket.c::814, 23
  # [8]  file:/home/nwang/workspace/packages/tiny-curl-7.72.0/lib/sendf.c::582, 15
  # [9]  file:/home/nwang/workspace/packages/tiny-curl-7.72.0/lib/sendf.c::666, 10
  # [10]  file:/home/nwang/workspace/packages/tiny-curl-7.72.0/lib/transfer.c::894, 26
  # [11]  file:/home/nwang/workspace/packages/tiny-curl-7.72.0/lib/transfer.c::1254, 14
  # [12]  file:/home/nwang/workspace/packages/tiny-curl-7.72.0/lib/multi.c::2152, 16
  # [13]  file:/home/nwang/workspace/packages/tiny-curl-7.72.0/lib/multi.c::2422, 14
  # [14]  file:/home/nwang/workspace/orca/discord-websockets.c::320, 13
  # [15]  file:/home/nwang/workspace/orca/discord-websockets.c::343, 3
  # [16]  file:/home/nwang/workspace/orca/discord-public.c::59, 3
  # [17]  file:/home/nwang/workspace/orca/echo-bot.c::38, 3
  # [18]  [libc-start-main]
  https://cee.studio/explanation
Segmentation fault

Unknown GATEWAY_DISPATCH event.

I pulled out the latest change, and got this error.

[discord-websockets.c:83] _discord_on_dispatch()
        ERROR:  Unknown GATEWAY_DISPATCH event: MESSAGE_CREATE
Aborted

port over your API roadmap

You made excellent documentation about the API roadmap. Don't waste it, please port them over as a separated page and linked to README.md

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.