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
*/
CHANNEL_TYPE_DM_TEXT,
CHANNEL_TYPE_DM,
/* 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);
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);
size_t dc_channel_recipients(dc_channel_t c);

View File

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

View File

@ -44,6 +44,7 @@ struct dc_channel_
*/
char *application_id;
GHashTable *messages_byid;
GPtrArray *messages;
};
@ -69,6 +70,11 @@ static void dc_channel_free(dc_channel_t c)
c->messages = NULL;
}
if (c->messages_byid != NULL) {
g_hash_table_unref(c->messages_byid);
c->messages_byid = NULL;
}
free(c);
}
@ -87,6 +93,11 @@ dc_channel_t dc_channel_new(void)
(GDestroyNotify)dc_unref
);
c->messages_byid = g_hash_table_new_full(
g_str_hash, g_str_equal,
free, dc_unref
);
return dc_ref(c);
}
@ -237,6 +248,14 @@ dc_channel_type_t dc_channel_type(dc_channel_t c)
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)
{
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;
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]));
}

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)
{
static char const *types[] = {
"UNKNOWN",
"READY",
NULL
static char const *types[DC_EVENT_TYPE_LAST] = {
[DC_EVENT_TYPE_UNKNOWN] = "UNKNOWN",
[DC_EVENT_TYPE_READY] = "READY",
[DC_EVENT_TYPE_MESSAGE_CREATE] = "MESSAGE_CREATE",
};
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) {
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);
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] = {
[DC_EVENT_TYPE_UNKNOWN] = NULL,
[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)
@ -46,6 +48,28 @@ static void dc_session_free(dc_session_t 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)
{
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
*/
c = dc_session_channel_recipients(s, r, n);
return_if_true(c != NULL, c);
/* no? create new one
*/
if (!dc_api_create_channel(s->api, s->login, r, n, &c)) {
return NULL;
if (c == NULL) {
/* no? create new one
*/
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);
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);
if (dc_channel_messages(c) <= 0 && dc_channel_is_dm(c)) {
/* fetch some messages for it
*/
dc_api_get_messages(s->api, s->login, c);
}
return c;
}