handle incoming messages through MESSAGE_CREATE

This commit is contained in:
Florian Stinglmayr 2019-07-11 20:06:51 +02:00
parent 6d7c7e641f
commit f742f29fcc
5 changed files with 77 additions and 18 deletions

View File

@ -21,7 +21,7 @@ typedef enum {
/* A direct message channel for 1:1 communication /* A direct message channel for 1:1 communication
*/ */
CHANNEL_TYPE_DM_TEXT, CHANNEL_TYPE_DM,
/* A guild voice channel /* A guild voice channel
*/ */
@ -53,6 +53,7 @@ dc_channel_t dc_channel_from_json(json_t *j);
char const *dc_channel_id(dc_channel_t c); char const *dc_channel_id(dc_channel_t c);
dc_channel_type_t dc_channel_type(dc_channel_t c); dc_channel_type_t dc_channel_type(dc_channel_t c);
bool dc_channel_is_dm(dc_channel_t c);
void dc_channel_set_type(dc_channel_t c, dc_channel_type_t t); void dc_channel_set_type(dc_channel_t c, dc_channel_type_t t);
size_t dc_channel_recipients(dc_channel_t c); size_t dc_channel_recipients(dc_channel_t c);

View File

@ -10,7 +10,9 @@ typedef struct dc_event_ *dc_event_t;
typedef enum { typedef enum {
DC_EVENT_TYPE_UNKNOWN = 0, DC_EVENT_TYPE_UNKNOWN = 0,
DC_EVENT_TYPE_READY, DC_EVENT_TYPE_READY,
DC_EVENT_TYPE_MESSAGE_CREATE,
/* ^^^^^^ Make sure events are up there ^^^^^^^ */
DC_EVENT_TYPE_LAST, DC_EVENT_TYPE_LAST,
} dc_event_type_t; } dc_event_type_t;

View File

@ -44,6 +44,7 @@ struct dc_channel_
*/ */
char *application_id; char *application_id;
GHashTable *messages_byid;
GPtrArray *messages; GPtrArray *messages;
}; };
@ -69,6 +70,11 @@ static void dc_channel_free(dc_channel_t c)
c->messages = NULL; c->messages = NULL;
} }
if (c->messages_byid != NULL) {
g_hash_table_unref(c->messages_byid);
c->messages_byid = NULL;
}
free(c); free(c);
} }
@ -87,6 +93,11 @@ dc_channel_t dc_channel_new(void)
(GDestroyNotify)dc_unref (GDestroyNotify)dc_unref
); );
c->messages_byid = g_hash_table_new_full(
g_str_hash, g_str_equal,
free, dc_unref
);
return dc_ref(c); return dc_ref(c);
} }
@ -237,6 +248,14 @@ dc_channel_type_t dc_channel_type(dc_channel_t c)
return c->type; return c->type;
} }
bool dc_channel_is_dm(dc_channel_t c)
{
return_if_true(c == NULL, false);
return (c->type == CHANNEL_TYPE_GROUP_DM ||
c->type == CHANNEL_TYPE_DM
);
}
void dc_channel_set_type(dc_channel_t c, dc_channel_type_t t) void dc_channel_set_type(dc_channel_t c, dc_channel_type_t t)
{ {
return_if_true(c == NULL,); return_if_true(c == NULL,);
@ -292,6 +311,12 @@ void dc_channel_add_messages(dc_channel_t c, dc_message_t *m, size_t s)
size_t i = 0; size_t i = 0;
for (i = 0; i < s; i++) { for (i = 0; i < s; i++) {
char const *id = dc_message_id(m[i]);
if (g_hash_table_contains(c->messages_byid, id)) {
continue;
}
g_hash_table_insert(c->messages_byid, strdup(id), dc_ref(m[i]));
g_ptr_array_add(c->messages, dc_ref(m[i])); g_ptr_array_add(c->messages, dc_ref(m[i]));
} }

View File

@ -60,15 +60,15 @@ json_t *dc_event_payload(dc_event_t e)
dc_event_type_t dc_event_type_code(dc_event_t e) dc_event_type_t dc_event_type_code(dc_event_t e)
{ {
static char const *types[] = { static char const *types[DC_EVENT_TYPE_LAST] = {
"UNKNOWN", [DC_EVENT_TYPE_UNKNOWN] = "UNKNOWN",
"READY", [DC_EVENT_TYPE_READY] = "READY",
NULL [DC_EVENT_TYPE_MESSAGE_CREATE] = "MESSAGE_CREATE",
}; };
int i = 0; int i = 0;
for (i = 0; types[i] != NULL; i++) { for (i = 0; i < DC_EVENT_TYPE_LAST; i++) {
if (strcmp(types[i], e->type) == 0) { if (strcmp(types[i], e->type) == 0) {
return (dc_event_type_t)i; return (dc_event_type_t)i;
} }

View File

@ -18,10 +18,12 @@ struct dc_session_
*/ */
typedef void (*dc_session_handler_t)(dc_session_t s, dc_event_t e); typedef void (*dc_session_handler_t)(dc_session_t s, dc_event_t e);
static void dc_session_handle_ready(dc_session_t s, dc_event_t e); static void dc_session_handle_ready(dc_session_t s, dc_event_t e);
static void dc_session_handle_message_create(dc_session_t s, dc_event_t e);
static dc_session_handler_t handlers[DC_EVENT_TYPE_LAST] = { static dc_session_handler_t handlers[DC_EVENT_TYPE_LAST] = {
[DC_EVENT_TYPE_UNKNOWN] = NULL, [DC_EVENT_TYPE_UNKNOWN] = NULL,
[DC_EVENT_TYPE_READY] = dc_session_handle_ready, [DC_EVENT_TYPE_READY] = dc_session_handle_ready,
[DC_EVENT_TYPE_MESSAGE_CREATE] = dc_session_handle_message_create,
}; };
static void dc_session_free(dc_session_t s) static void dc_session_free(dc_session_t s)
@ -46,6 +48,28 @@ static void dc_session_free(dc_session_t s)
free(s); free(s);
} }
static void dc_session_handle_message_create(dc_session_t s, dc_event_t e)
{
dc_message_t m = NULL;
json_t *r = dc_event_payload(e);
char const *id = NULL;
m = dc_message_from_json(r);
goto_if_true(m == NULL, cleanup);
id = dc_message_channel_id(m);
goto_if_true(m == NULL, cleanup);
if (g_hash_table_contains(s->channels, id)) {
dc_channel_t c = g_hash_table_lookup(s->channels, id);
dc_channel_add_messages(c, &m, 1);
}
cleanup:
dc_unref(m);
}
static void dc_session_handle_ready(dc_session_t s, dc_event_t e) static void dc_session_handle_ready(dc_session_t s, dc_event_t e)
{ {
json_t *r = dc_event_payload(e); json_t *r = dc_event_payload(e);
@ -276,21 +300,28 @@ dc_channel_t dc_session_make_channel(dc_session_t s, dc_account_t *r,
/* check if we have the channel already with those recipients /* check if we have the channel already with those recipients
*/ */
c = dc_session_channel_recipients(s, r, n); c = dc_session_channel_recipients(s, r, n);
return_if_true(c != NULL, c);
/* no? create new one if (c == NULL) {
*/ /* no? create new one
if (!dc_api_create_channel(s->api, s->login, r, n, &c)) { */
return NULL; if (!dc_api_create_channel(s->api, s->login, r, n, &c)) {
return NULL;
}
return_if_true(c == NULL, NULL);
dc_session_add_channel(s, c);
/* unref once to match the proper ref count after
* dc_session_add_channel()
* BUG: if dc_session_add_channel() fails this is bad
*/
dc_unref(c);
} }
return_if_true(c == NULL, NULL); if (dc_channel_messages(c) <= 0 && dc_channel_is_dm(c)) {
dc_session_add_channel(s, c); /* fetch some messages for it
*/
/* unref once to match the proper ref count after dc_session_add_channel() dc_api_get_messages(s->api, s->login, c);
* BUG: if dc_session_add_channel() fails this is bad }
*/
dc_unref(c);
return c; return c;
} }