parse READY event to get information for session
This commit is contained in:
parent
d10f0b1f32
commit
b6cffac1d9
@ -46,7 +46,9 @@ dc_account_t dc_account_new2(char const *email, char const *pass);
|
||||
dc_account_t dc_account_from_fullname(char const *fullid);
|
||||
|
||||
dc_account_t dc_account_from_json(json_t *j);
|
||||
dc_account_t dc_account_from_relationship(json_t *j);
|
||||
json_t *dc_account_to_json(dc_account_t a);
|
||||
bool dc_account_load(dc_account_t a, json_t *j);
|
||||
|
||||
void dc_account_set_email(dc_account_t a, char const *email);
|
||||
char const *dc_account_email(dc_account_t a);
|
||||
@ -76,6 +78,7 @@ bool dc_account_equal(dc_account_t a, dc_account_t b);
|
||||
/* relationships
|
||||
*/
|
||||
void dc_account_set_friends(dc_account_t a, dc_account_t *ptr, size_t len);
|
||||
void dc_account_add_friend(dc_account_t a, dc_account_t friend);
|
||||
dc_account_t dc_account_nthfriend(dc_account_t a, size_t i);
|
||||
size_t dc_account_friends_size(dc_account_t a);
|
||||
dc_account_t dc_account_findfriend(dc_account_t a, char const *fullname);
|
||||
|
@ -56,6 +56,7 @@ dc_channel_type_t dc_channel_type(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);
|
||||
void dc_channel_addrecipient(dc_channel_t c, dc_account_t a);
|
||||
dc_account_t dc_channel_nthrecipient(dc_channel_t c, size_t i);
|
||||
|
||||
size_t dc_channel_messages(dc_channel_t c);
|
||||
|
@ -7,6 +7,13 @@
|
||||
struct dc_event_;
|
||||
typedef struct dc_event_ *dc_event_t;
|
||||
|
||||
typedef enum {
|
||||
DC_EVENT_TYPE_UNKNOWN = 0,
|
||||
DC_EVENT_TYPE_READY,
|
||||
|
||||
DC_EVENT_TYPE_LAST,
|
||||
} dc_event_type_t;
|
||||
|
||||
dc_event_t dc_event_new(char const *type, json_t *payload);
|
||||
|
||||
/**
|
||||
@ -22,4 +29,9 @@ char const *dc_event_type(dc_event_t e);
|
||||
*/
|
||||
json_t *dc_event_payload(dc_event_t e);
|
||||
|
||||
/**
|
||||
* Returns an integer code representing the given type string.
|
||||
*/
|
||||
dc_event_type_t dc_event_type_code(dc_event_t e);
|
||||
|
||||
#endif
|
||||
|
@ -52,6 +52,19 @@ bool dc_session_has_token(dc_session_t s);
|
||||
*/
|
||||
dc_account_t dc_session_me(dc_session_t s);
|
||||
|
||||
/**
|
||||
* access to the internal account cache
|
||||
*/
|
||||
void dc_session_add_account(dc_session_t s, dc_account_t u);
|
||||
|
||||
/**
|
||||
* access to the internal channel cache
|
||||
*/
|
||||
void dc_session_add_channel(dc_session_t s, dc_channel_t u);
|
||||
|
||||
/**
|
||||
* comparision functions for sorting, and finding
|
||||
*/
|
||||
bool dc_session_equal_me(dc_session_t s, dc_account_t a);
|
||||
bool dc_session_equal_me_fullname(dc_session_t s, char const *a);
|
||||
|
||||
|
@ -116,24 +116,43 @@ dc_account_t dc_account_from_fullname(char const *fullid)
|
||||
return acc;
|
||||
}
|
||||
|
||||
dc_account_t dc_account_from_json(json_t *j)
|
||||
bool dc_account_load(dc_account_t user, json_t *j)
|
||||
{
|
||||
json_t *val = NULL;
|
||||
|
||||
return_if_true(!json_is_object(j), false);
|
||||
|
||||
val = json_object_get(j, "id");
|
||||
return_if_true(val == NULL || !json_is_string(val), false);
|
||||
dc_account_set_id(user, json_string_value(val));
|
||||
|
||||
val = json_object_get(j, "username");
|
||||
return_if_true(val == NULL || !json_is_string(val), false);
|
||||
dc_account_set_username(user, json_string_value(val));
|
||||
|
||||
val = json_object_get(j, "discriminator");
|
||||
return_if_true(val == NULL || !json_is_string(val), false);
|
||||
dc_account_set_discriminator(user, json_string_value(val));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
dc_account_t dc_account_from_relationship(json_t *j)
|
||||
{
|
||||
dc_account_t user = dc_account_new();
|
||||
json_t *val = NULL;
|
||||
|
||||
goto_if_true(!json_is_object(j), error);
|
||||
val = json_object_get(j, "user");
|
||||
goto_if_true(val == NULL || !json_is_object(val), error);
|
||||
|
||||
val = json_object_get(j, "username");
|
||||
goto_if_true(val == NULL || !json_is_string(val), error);
|
||||
dc_account_set_username(user, json_string_value(val));
|
||||
if (!dc_account_load(user, val)) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
val = json_object_get(j, "discriminator");
|
||||
goto_if_true(val == NULL || !json_is_string(val), error);
|
||||
dc_account_set_discriminator(user, json_string_value(val));
|
||||
|
||||
val = json_object_get(j, "id");
|
||||
goto_if_true(val == NULL || !json_is_string(val), error);
|
||||
dc_account_set_id(user, json_string_value(val));
|
||||
val = json_object_get(j, "type");
|
||||
if (val != NULL && json_is_integer(val)) {
|
||||
dc_account_set_friend_state(user, json_integer_value(val));
|
||||
}
|
||||
|
||||
return user;
|
||||
|
||||
@ -143,6 +162,18 @@ error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dc_account_t dc_account_from_json(json_t *j)
|
||||
{
|
||||
dc_account_t user = dc_account_new();
|
||||
|
||||
if (!dc_account_load(user, j)) {
|
||||
dc_unref(user);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
json_t *dc_account_to_json(dc_account_t a)
|
||||
{
|
||||
json_t *j = NULL;
|
||||
@ -315,6 +346,12 @@ dc_account_t dc_account_findfriend(dc_account_t a, char const *fullname)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void dc_account_add_friend(dc_account_t a, dc_account_t friend)
|
||||
{
|
||||
return_if_true(a == NULL || friend == NULL,);
|
||||
g_ptr_array_add(a->friends, dc_ref(friend));
|
||||
}
|
||||
|
||||
dc_account_t dc_account_nthfriend(dc_account_t a, size_t i)
|
||||
{
|
||||
return_if_true(a == NULL || a->friends == NULL, NULL);
|
||||
|
@ -256,6 +256,12 @@ dc_account_t dc_channel_nthrecipient(dc_channel_t c, size_t i)
|
||||
return g_ptr_array_index(c->recipients, i);
|
||||
}
|
||||
|
||||
void dc_channel_addrecipient(dc_channel_t c, dc_account_t a)
|
||||
{
|
||||
return_if_true(c == NULL || a == NULL,);
|
||||
g_ptr_array_add(c->recipients, dc_ref(a));
|
||||
}
|
||||
|
||||
size_t dc_channel_messages(dc_channel_t c)
|
||||
{
|
||||
return_if_true(c == NULL || c->messages == NULL, 0);
|
||||
|
@ -57,3 +57,22 @@ json_t *dc_event_payload(dc_event_t e)
|
||||
return_if_true(e == NULL, NULL);
|
||||
return e->payload;
|
||||
}
|
||||
|
||||
dc_event_type_t dc_event_type_code(dc_event_t e)
|
||||
{
|
||||
static char const *types[] = {
|
||||
"UNKNOWN",
|
||||
"READY",
|
||||
NULL
|
||||
};
|
||||
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; types[i] != NULL; i++) {
|
||||
if (strcmp(types[i], e->type) == 0) {
|
||||
return (dc_event_type_t)i;
|
||||
}
|
||||
}
|
||||
|
||||
return DC_EVENT_TYPE_UNKNOWN;
|
||||
}
|
||||
|
@ -309,10 +309,6 @@ static void dc_gateway_process_read(dc_gateway_t gw)
|
||||
do {
|
||||
ret = curl_easy_recv(gw->easy, buf, sizeof(buf), &outlen);
|
||||
if (ret == CURLE_OK && outlen > 0) {
|
||||
FILE *f = fopen("output.txt", "a+");
|
||||
fwrite(buf, outlen, sizeof(char), f);
|
||||
fputc('\n', f);
|
||||
fclose(f);
|
||||
g_byte_array_append(gw->buffer, (uint8_t const*)buf, outlen);
|
||||
}
|
||||
} while (ret == CURLE_OK && outlen > 0);
|
||||
|
@ -9,12 +9,35 @@ struct dc_session_
|
||||
dc_api_t api;
|
||||
dc_account_t login;
|
||||
dc_gateway_t gateway;
|
||||
|
||||
GHashTable *accounts;
|
||||
GHashTable *channels;
|
||||
};
|
||||
|
||||
/* event handlers
|
||||
*/
|
||||
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 dc_session_handler_t handlers[DC_EVENT_TYPE_LAST] = {
|
||||
[DC_EVENT_TYPE_UNKNOWN] = NULL,
|
||||
[DC_EVENT_TYPE_READY] = dc_session_handle_ready,
|
||||
};
|
||||
|
||||
static void dc_session_free(dc_session_t s)
|
||||
{
|
||||
return_if_true(s == NULL,);
|
||||
|
||||
if (s->accounts != NULL) {
|
||||
g_hash_table_unref(s->accounts);
|
||||
s->accounts = NULL;
|
||||
}
|
||||
|
||||
if (s->channels != NULL) {
|
||||
g_hash_table_unref(s->channels);
|
||||
s->channels = NULL;
|
||||
}
|
||||
|
||||
dc_session_logout(s);
|
||||
|
||||
dc_unref(s->api);
|
||||
@ -23,14 +46,68 @@ static void dc_session_free(dc_session_t s)
|
||||
free(s);
|
||||
}
|
||||
|
||||
static void dc_session_handle_ready(dc_session_t s, dc_event_t e)
|
||||
{
|
||||
json_t *r = dc_event_payload(e);
|
||||
json_t *user = NULL;
|
||||
json_t *relationships = NULL;
|
||||
size_t idx = 0;
|
||||
json_t *c = NULL;
|
||||
json_t *channels = NULL;
|
||||
|
||||
/* retrieve user information about ourselves, including snowflake,
|
||||
* discriminator, and other things
|
||||
*/
|
||||
user = json_object_get(r, "user");
|
||||
if (user != NULL && json_is_object(user)) {
|
||||
dc_account_load(s->login, user);
|
||||
dc_session_add_account(s, s->login);
|
||||
}
|
||||
|
||||
/* load relationships, aka friends
|
||||
*/
|
||||
relationships = json_object_get(r, "relationships");
|
||||
if (relationships != NULL && json_is_array(relationships)) {
|
||||
json_array_foreach(relationships, idx, c) {
|
||||
dc_account_t u = dc_account_from_relationship(user);
|
||||
|
||||
if (u == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
dc_account_add_friend(s->login, u);
|
||||
dc_session_add_account(s, u);
|
||||
}
|
||||
}
|
||||
|
||||
/* load channels
|
||||
*/
|
||||
channels = json_object_get(r, "private_channels");
|
||||
if (channels != NULL && json_is_array(channels)) {
|
||||
json_array_foreach(channels, idx, c) {
|
||||
dc_channel_t chan = dc_channel_from_json(c);
|
||||
if (chan == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
dc_session_add_channel(s, chan);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void dc_session_handler(dc_gateway_t gw, dc_event_t e, void *p)
|
||||
{
|
||||
dc_session_t s = (dc_session_t)p;
|
||||
dc_session_handler_t h = handlers[dc_event_type_code(e)];
|
||||
|
||||
if (h != NULL) {
|
||||
h(s, e);
|
||||
}
|
||||
|
||||
char *str = NULL;
|
||||
str = json_dumps(dc_event_payload(e), 0);
|
||||
FILE *f = fopen("events.txt", "a+");
|
||||
fprintf(f, "%p: %s: %s\n", s, dc_event_type(e), str);
|
||||
fprintf(f, "%s: %s\n", dc_event_type(e), str);
|
||||
free(str);
|
||||
fclose(f);
|
||||
}
|
||||
@ -44,17 +121,29 @@ dc_session_t dc_session_new(dc_loop_t loop)
|
||||
|
||||
s->ref.cleanup = (dc_cleanup_t)dc_session_free;
|
||||
|
||||
s->accounts = g_hash_table_new_full(g_str_hash, g_str_equal,
|
||||
free, dc_unref
|
||||
);
|
||||
goto_if_true(s->accounts == NULL, error);
|
||||
|
||||
s->channels = g_hash_table_new_full(g_str_hash, g_str_equal,
|
||||
free, dc_unref
|
||||
);
|
||||
goto_if_true(s->channels == NULL, error);
|
||||
|
||||
s->loop = dc_ref(loop);
|
||||
|
||||
s->api = dc_api_new();
|
||||
if (s->api == NULL) {
|
||||
dc_session_free(s);
|
||||
return NULL;
|
||||
}
|
||||
goto_if_true(s->api == NULL, error);
|
||||
|
||||
dc_loop_add_api(s->loop, s->api);
|
||||
|
||||
return dc_ref(s);
|
||||
|
||||
error:
|
||||
|
||||
dc_session_free(s);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool dc_session_logout(dc_session_t s)
|
||||
@ -133,3 +222,29 @@ bool dc_session_equal_me_fullname(dc_session_t s, char const *a)
|
||||
return_if_true(s == NULL || s->login == NULL || a == NULL, false);
|
||||
return (strcmp(dc_account_fullname(s->login), a) == 0);
|
||||
}
|
||||
|
||||
void dc_session_add_account(dc_session_t s, dc_account_t u)
|
||||
{
|
||||
return_if_true(s == NULL || u == NULL,);
|
||||
return_if_true(dc_account_id(u) == NULL,);
|
||||
|
||||
char const *id = dc_account_id(u);
|
||||
|
||||
if (!g_hash_table_contains(s->accounts, id)) {
|
||||
g_hash_table_insert(s->accounts, strdup(id), dc_ref(u));
|
||||
}
|
||||
}
|
||||
|
||||
void dc_session_add_channel(dc_session_t s, dc_channel_t u)
|
||||
{
|
||||
return_if_true(s == NULL || u == NULL,);
|
||||
return_if_true(dc_channel_id(u) == NULL,);
|
||||
|
||||
char const *id = dc_channel_id(u);
|
||||
|
||||
if (!g_hash_table_contains(s->channels, id)) {
|
||||
g_hash_table_insert(s->channels, strdup(id), dc_ref(u));
|
||||
/* TODO: dedup for saving storage
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ dc_gateway_parseframe(uint8_t const *data, size_t datalen,
|
||||
goto_if_true(datalen <= idx, cleanup);
|
||||
memcpy(&len, data+idx, sizeof(len));
|
||||
|
||||
data_len = len;
|
||||
data_len = GUINT16_TO_BE(len);
|
||||
idx += sizeof(len);
|
||||
} else if (l == 127) {
|
||||
/* read an uint16_t from the data
|
||||
@ -113,7 +113,7 @@ dc_gateway_parseframe(uint8_t const *data, size_t datalen,
|
||||
goto_if_true(datalen <= idx, cleanup);
|
||||
memcpy(&len, data+idx, sizeof(len));
|
||||
|
||||
data_len = len;
|
||||
data_len = GUINT64_TO_BE(len);
|
||||
idx += sizeof(len);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user