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_fullname(char const *fullid);
|
||||||
|
|
||||||
dc_account_t dc_account_from_json(json_t *j);
|
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);
|
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);
|
void dc_account_set_email(dc_account_t a, char const *email);
|
||||||
char const *dc_account_email(dc_account_t a);
|
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
|
/* relationships
|
||||||
*/
|
*/
|
||||||
void dc_account_set_friends(dc_account_t a, dc_account_t *ptr, size_t len);
|
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);
|
dc_account_t dc_account_nthfriend(dc_account_t a, size_t i);
|
||||||
size_t dc_account_friends_size(dc_account_t a);
|
size_t dc_account_friends_size(dc_account_t a);
|
||||||
dc_account_t dc_account_findfriend(dc_account_t a, char const *fullname);
|
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);
|
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);
|
||||||
|
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);
|
dc_account_t dc_channel_nthrecipient(dc_channel_t c, size_t i);
|
||||||
|
|
||||||
size_t dc_channel_messages(dc_channel_t c);
|
size_t dc_channel_messages(dc_channel_t c);
|
||||||
|
@ -7,6 +7,13 @@
|
|||||||
struct dc_event_;
|
struct dc_event_;
|
||||||
typedef struct dc_event_ *dc_event_t;
|
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);
|
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);
|
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
|
#endif
|
||||||
|
@ -52,6 +52,19 @@ bool dc_session_has_token(dc_session_t s);
|
|||||||
*/
|
*/
|
||||||
dc_account_t dc_session_me(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(dc_session_t s, dc_account_t a);
|
||||||
bool dc_session_equal_me_fullname(dc_session_t s, char const *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;
|
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();
|
dc_account_t user = dc_account_new();
|
||||||
json_t *val = NULL;
|
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");
|
if (!dc_account_load(user, val)) {
|
||||||
goto_if_true(val == NULL || !json_is_string(val), error);
|
goto error;
|
||||||
dc_account_set_username(user, json_string_value(val));
|
}
|
||||||
|
|
||||||
val = json_object_get(j, "discriminator");
|
val = json_object_get(j, "type");
|
||||||
goto_if_true(val == NULL || !json_is_string(val), error);
|
if (val != NULL && json_is_integer(val)) {
|
||||||
dc_account_set_discriminator(user, json_string_value(val));
|
dc_account_set_friend_state(user, json_integer_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));
|
|
||||||
|
|
||||||
return user;
|
return user;
|
||||||
|
|
||||||
@ -143,6 +162,18 @@ error:
|
|||||||
return NULL;
|
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 *dc_account_to_json(dc_account_t a)
|
||||||
{
|
{
|
||||||
json_t *j = NULL;
|
json_t *j = NULL;
|
||||||
@ -315,6 +346,12 @@ dc_account_t dc_account_findfriend(dc_account_t a, char const *fullname)
|
|||||||
return NULL;
|
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)
|
dc_account_t dc_account_nthfriend(dc_account_t a, size_t i)
|
||||||
{
|
{
|
||||||
return_if_true(a == NULL || a->friends == NULL, NULL);
|
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);
|
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)
|
size_t dc_channel_messages(dc_channel_t c)
|
||||||
{
|
{
|
||||||
return_if_true(c == NULL || c->messages == NULL, 0);
|
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_if_true(e == NULL, NULL);
|
||||||
return e->payload;
|
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 {
|
do {
|
||||||
ret = curl_easy_recv(gw->easy, buf, sizeof(buf), &outlen);
|
ret = curl_easy_recv(gw->easy, buf, sizeof(buf), &outlen);
|
||||||
if (ret == CURLE_OK && outlen > 0) {
|
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);
|
g_byte_array_append(gw->buffer, (uint8_t const*)buf, outlen);
|
||||||
}
|
}
|
||||||
} while (ret == CURLE_OK && outlen > 0);
|
} while (ret == CURLE_OK && outlen > 0);
|
||||||
|
@ -9,12 +9,35 @@ struct dc_session_
|
|||||||
dc_api_t api;
|
dc_api_t api;
|
||||||
dc_account_t login;
|
dc_account_t login;
|
||||||
dc_gateway_t gateway;
|
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)
|
static void dc_session_free(dc_session_t s)
|
||||||
{
|
{
|
||||||
return_if_true(s == NULL,);
|
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_session_logout(s);
|
||||||
|
|
||||||
dc_unref(s->api);
|
dc_unref(s->api);
|
||||||
@ -23,14 +46,68 @@ static void dc_session_free(dc_session_t s)
|
|||||||
free(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)
|
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_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;
|
char *str = NULL;
|
||||||
str = json_dumps(dc_event_payload(e), 0);
|
str = json_dumps(dc_event_payload(e), 0);
|
||||||
FILE *f = fopen("events.txt", "a+");
|
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);
|
free(str);
|
||||||
fclose(f);
|
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->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->loop = dc_ref(loop);
|
||||||
|
|
||||||
s->api = dc_api_new();
|
s->api = dc_api_new();
|
||||||
if (s->api == NULL) {
|
goto_if_true(s->api == NULL, error);
|
||||||
dc_session_free(s);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
dc_loop_add_api(s->loop, s->api);
|
dc_loop_add_api(s->loop, s->api);
|
||||||
|
|
||||||
return dc_ref(s);
|
return dc_ref(s);
|
||||||
|
|
||||||
|
error:
|
||||||
|
|
||||||
|
dc_session_free(s);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dc_session_logout(dc_session_t s)
|
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_if_true(s == NULL || s->login == NULL || a == NULL, false);
|
||||||
return (strcmp(dc_account_fullname(s->login), a) == 0);
|
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);
|
goto_if_true(datalen <= idx, cleanup);
|
||||||
memcpy(&len, data+idx, sizeof(len));
|
memcpy(&len, data+idx, sizeof(len));
|
||||||
|
|
||||||
data_len = len;
|
data_len = GUINT16_TO_BE(len);
|
||||||
idx += sizeof(len);
|
idx += sizeof(len);
|
||||||
} else if (l == 127) {
|
} else if (l == 127) {
|
||||||
/* read an uint16_t from the data
|
/* 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);
|
goto_if_true(datalen <= idx, cleanup);
|
||||||
memcpy(&len, data+idx, sizeof(len));
|
memcpy(&len, data+idx, sizeof(len));
|
||||||
|
|
||||||
data_len = len;
|
data_len = GUINT64_TO_BE(len);
|
||||||
idx += sizeof(len);
|
idx += sizeof(len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user