From da015427f35fb249e5b94f8d9b35474ec53be47b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anton=20Luka=20=C5=A0ijanec?= Date: Sun, 26 Sep 2021 22:27:42 +0200 Subject: grem spat, ni testirano --- src/h.c | 57 +++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 20 deletions(-) (limited to 'src/h.c') diff --git a/src/h.c b/src/h.c index 7ace971..81d7179 100644 --- a/src/h.c +++ b/src/h.c @@ -16,6 +16,7 @@ #define DC_LWS_MAX_FD 64 /* max file descriptors LWS will have open. if unset, LWS acquires all unused */ #define DC_LWS_MAX_HEADER_LENGTH 64 /* _MAX_HEADER_LENGTH*_HEADERS_LENGTH is allocated for every reque */ #define DC_WS_PING_FORMAT "{\"op\":1,\"d\":%lld}" +#define DC_ID2TIME(x) ((x >> 22 /* this gives us ms since 2015 */)/1000 + 1420070400 /* UNIX 2015 */) #ifdef DC_UI_GTK #define DC_IF_UI_GTK(...) __VA_ARGS__ #else @@ -71,12 +72,11 @@ enum dc_ws_packet { /* op numbers of websocket packets or json objects in other DC_PING = 1, DC_STRPKTOFF = 100, /* here follow string types (t) */ DC_NONE = DC_STRPKTOFF + 0, /* unknown packet or packet type not yet defermined */ - DC_MESSAGE_CREATE = DC_STRPKTOFF + 0, + DC_MESSAGE_CREATE = DC_STRPKTOFF + 1, }; /* intents enum was removed - intents're for bots, clients have capabilities - are not understood */ char * dc_ws_packet[] = { "", - "MESSAGE_CREATE", - "" + "MESSAGE_CREATE" }; enum dc_message_type { /* other types exist, but are not implemented/understood, same values as server */ DC_MESSAGE = 0, @@ -136,14 +136,19 @@ struct dc_api_io { /* output struct does NOT contain void * data (user pointer) struct dc_lws_pass * pass; unsigned long long int id; }; -#define DC_API_IO_MEMB_GC(m, t) if (m && m->status & DC_IN_PROGRESS) { \ - t##_free(m, DC_UNSET); \ - m = NULL; } \ +#define DC_API_IO_MEMB_GC(m, t) do { \ + if (m && m->status & DC_IN_PROGRESS) { \ + t##_free(m, DC_UNSET); \ + m = NULL; \ + } \ if (m && m->status & DC_EXPLICIT_NULL) { \ m->status &= ~DC_EXPLICIT_NULL; \ m = NULL; \ - } -#define DC_API_IO_GC(s) do { /* this is called if: json_cb will start parsing another before callback, */ \ + } \ + } while (0) +#define DC_API_IO_GC(s) do { /* this is called if: */ \ + if (s.message) \ + DC_API_IO_MEMB_GC(s.message->reply, dc_message); \ DC_API_IO_MEMB_GC(s.message, dc_message); /* WS connection closed, meaning json_cb */ \ DC_API_IO_MEMB_GC(s.channel, dc_channel); /* will never be called again */ \ DC_API_IO_MEMB_GC(s.guild, dc_guild); \ @@ -220,8 +225,8 @@ enum dc_json_paths { /* lws reduces the following char array to uint8_t, so we c DC_JSON_MEMBER_ID, DC_JSON_MEMBER_DISCRIMINATOR, DC_JSON_MEMBER_ROLE, /* id, array */ - DC_JSON_MESSAGE, - DC_JSON_MESSAGE_ATTACHMENTS, + DC_JSON_MESSAGE, /* also check if pass->packet == DC_MESSAGE_CREATE */ + DC_JSON_MESSAGE_ATTACHMENTS, /* not implemented yet */ DC_JSON_MESSAGE_ID, DC_JSON_MESSAGE_TYPE, DC_JSON_MESSAGE_CHANNEL, /* id */ @@ -230,8 +235,8 @@ enum dc_json_paths { /* lws reduces the following char array to uint8_t, so we c DC_JSON_MESSAGE_AUTHOR_USERNAME, DC_JSON_MESSAGE_AUTHOR_DISCRIMINATOR, DC_JSON_MESSAGE_AUTHOR_ID, - DC_JSON_MESSAGE_REFERENCE, /* id */ - DC_JSON_MESSAGE_MENTION_CHANNEL, /* TODO: implement role and user mentions fetching */ + DC_JSON_MESSAGE_REFERENCE, /* id, not implemented, only DC_JSON_MESSAGE_REFOBJ is used */ + DC_JSON_MESSAGE_MENTION_CHANNEL, DC_JSON_MESSAGE_MENTION_CHANNEL_ID, DC_JSON_MESSAGE_MENTION_CHANNEL_GUILD, /* id */ DC_JSON_MESSAGE_MENTION_CHANNEL_NAME, @@ -241,6 +246,7 @@ enum dc_json_paths { /* lws reduces the following char array to uint8_t, so we c DC_JSON_MESSAGE_MENTION_USER_ROLE, DC_JSON_MESSAGE_MENTION_USER_ID, DC_JSON_MESSAGE_MENTION_USER_DISCRIMINATOR, + DC_JSON_MESSAGE_MENTION_ROLE, /* id, array */ DC_JSON_MESSAGE_REFOBJ, /* server only sends reference object one level deep */ DC_JSON_MESSAGE_REFOBJ_ATTACHMENTS, DC_JSON_MESSAGE_REFOBJ_ID, @@ -263,6 +269,7 @@ enum dc_json_paths { /* lws reduces the following char array to uint8_t, so we c DC_JSON_MESSAGE_REFOBJ_MENTION_USER_ROLE, DC_JSON_MESSAGE_REFOBJ_MENTION_USER_ID, DC_JSON_MESSAGE_REFOBJ_MENTION_USER_DISCRIMINATOR, + DC_JSON_MESSAGE_REFOBJ_MENTION_ROLE, /* id */ DC_JSON_PATHS_LENGTH /* we have 256 max length, because that's what library supports */ }; char * dc_json_paths[] = { /* array of paths we are interested in */ @@ -327,11 +334,12 @@ char * dc_json_paths[] = { /* array of paths we are interested in */ "d.mention_channels[].type", "d.mentions[]", "d.mentions[].username", - "d.mentions[].member.roles[]", + "d.mentions[].member.roles", "d.mentions[].id", "d.mentions[].discriminator", + "d.mentions[].mention_roles", "d.referenced_message", - "d.referenced_message.attachments[]", + "d.referenced_message.attachments", "d.referenced_message.id", "d.referenced_message.type", "d.referenced_message.channel_id", @@ -340,7 +348,7 @@ char * dc_json_paths[] = { /* array of paths we are interested in */ "d.referenced_message.author.username", "d.referenced_message.author.discriminator", "d.referenced_message.author.id", - "d.referenced_message.member.roles[]", + "d.referenced_message.member.roles", "d.referenced_message.message_reference", /* this is ID */ "d.referenced_message.mention_channels[]", "d.referenced_message.mention_channels[].id", @@ -349,9 +357,10 @@ char * dc_json_paths[] = { /* array of paths we are interested in */ "d.referenced_message.mention_channels[].type", "d.referenced_message.mentions[]", "d.referenced_message.mentions[].username", - "d.referenced_message.mentions[].member.roles[]", + "d.referenced_message.mentions[].member.roles", "d.referenced_message.mentions[].id", "d.referenced_message.mentions[].discriminator", + "d.referenced_message.mention_roles" }; struct dc_lws_pass { /* struct that is allocated for in dc_lws_cb unique per connection in void * us */ DC_STRUCT_PREFIX @@ -505,14 +514,14 @@ void dc_channel_free (struct dc_channel * s, enum dc_status t) { struct dc_message { DC_STRUCT_PREFIX char * message; /* yesfree */ - char * attachment; /* yesfree - this is a HTTP URL. it would be nice to request file and store to ~/.cache/discord.c/ and only then use (RENDER IMAGE) from disk */ struct dc_channel * channel; /* nofree */ struct dc_user * user; /* nofree */ - time_t time; + time_t time; /* obtained with DC_ID2TIME, edited timestamp is in ISO string format¬ implemt */ unsigned long long int id; struct dc_message * next; /* next message (linked list of all messages of dc_channel) */ struct dc_message * reply; /* nofree - this message replies to another message or NULL */ enum dc_status status; + enum dc_message_type type; DC_ISASQ(user); /* yesfree pointer array only - mentions */ DC_ISASQ(role); /* yesfree pointer array only - mentions */ DC_ISASQ(channel); /* yesfree pointer array only - mentions */ @@ -528,10 +537,9 @@ void dc_message_free (struct dc_message * s, enum dc_status t) { if (!s) return; free(s->message); - free(s->attachment); free(s->users); free(s->roles); - free(s->channel); + free(s->channels); if (!(t & DC_REPLACE)) free(s); } @@ -715,6 +723,7 @@ void dc_program_free (struct dc_program * s, enum dc_status t) { } void dc_api_stack (struct dc_api_io); #define DC_FIND_X(x) struct dc_##x * dc_find_##x(struct dc_##x ** p, size_t l, unsigned long long int id) { \ + assert(id); \ for (size_t i = 0; i < l; i++) \ if (p[i]->id == id) { \ /* fprintf(stderr, "id %llu was found!\n", id); */ /* too much */ \ @@ -735,6 +744,7 @@ void dc_api_stack (struct dc_api_io); } /* untested, not sure if works!!! */ #define DC_ADD_X(x) struct dc_##x * dc_add_##x (struct dc_##x *** p, size_t * so, size_t * l, struct dc_##x * u, enum dc_status s) { \ struct dc_##x * us; \ + assert(u); \ if ((us = dc_find_##x(*p, *l, u->id))) { \ /* fprintf(stderr, "debug: %s found already existing member\n", __func__); */ \ if (us == u) \ @@ -782,6 +792,8 @@ DC_FIND_LL_X(channel) DC_GEN_X(guild, GUILD) DC_GEN_X(role, ROLE) DC_FIND_LL_X(role) +DC_GEN_X(message, MESSAGE) +DC_FIND_LL_X(message) #define DC_ISAE(a) &(a), &(a##_sizeof), &(a##_length) /* ISA Expand */ #define DC_ISAN NULL, NULL, NULL /* ISA NULL */ #define DC_TRANSFER_CHANNEL(n, o) do { /* n is going to DC_REPLACE o, transfer important data */ \ @@ -810,3 +822,8 @@ void dc_transfer_role (struct dc_role * n, struct dc_role * o) { o->users_length = 0; } } +void dc_transfer_message (struct dc_message * n, struct dc_message * o) { + n->next = o->next; + if (!n->reply) + n->reply = o->reply; +} -- cgit v1.2.3