summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Luka Šijanec <anton@sijanec.eu>2021-09-16 22:08:05 +0200
committerAnton Luka Šijanec <anton@sijanec.eu>2021-09-16 22:08:05 +0200
commit5945af1f1b0f92877dd7e2fc959d95fa92d976f4 (patch)
treeadff7b17c12b7046df311e9aaef293ce53cef9a1
parentsome bullshit i just saved (diff)
downloaddiscord.c-5945af1f1b0f92877dd7e2fc959d95fa92d976f4.tar
discord.c-5945af1f1b0f92877dd7e2fc959d95fa92d976f4.tar.gz
discord.c-5945af1f1b0f92877dd7e2fc959d95fa92d976f4.tar.bz2
discord.c-5945af1f1b0f92877dd7e2fc959d95fa92d976f4.tar.lz
discord.c-5945af1f1b0f92877dd7e2fc959d95fa92d976f4.tar.xz
discord.c-5945af1f1b0f92877dd7e2fc959d95fa92d976f4.tar.zst
discord.c-5945af1f1b0f92877dd7e2fc959d95fa92d976f4.zip
-rw-r--r--README.md6
-rw-r--r--src/api.c83
-rw-r--r--src/h.c9
-rw-r--r--src/lib.c5
4 files changed, 77 insertions, 26 deletions
diff --git a/README.md b/README.md
index b40f17d..975286d 100644
--- a/README.md
+++ b/README.md
@@ -77,12 +77,6 @@ completing this task would make `discord.c` the first and the only alternative c
it would be useful to have an android port, and luckily this is possible with little effort due to the GTK broadway backend that interfaces with a HTML renderer, WebView for example.
-### misc
-
-* synchronise guild\_positions with server (packet 0)
-* synchronise nicknames with server (packet 0 for frends)
-* parse, store, download, render avatars
-
<!--
## working features
diff --git a/src/api.c b/src/api.c
index d76393b..850ae30 100644
--- a/src/api.c
+++ b/src/api.c
@@ -23,8 +23,9 @@ void dc_api_stack (struct dc_api_io i) { /* stack output struct to be delivered
signed char dc_json_cb (struct lejp_ctx * ctx, char /* enum lejp_callbacks */ reason) {
enum dc_json_paths path = ctx->path_match-1; /* we assume that the order of incoming data is */
struct dc_lws_pass * pass = ctx->user; /* correct. op should come first, etc. */
+ struct dc_client * client = pass->api_io.client;
+ struct dc_program * program = pass->api_io.program;
char * cp;
- char buf[LEJP_MAX_PATH+1];
pass->json_reason = reason;
if (reason == LEJPCB_FAILED) {
DC_API_IO_GC(pass->api_io);
@@ -32,7 +33,7 @@ signed char dc_json_cb (struct lejp_ctx * ctx, char /* enum lejp_callbacks */ re
pass->parsing_status = NULL;
return '\0';
}
- fprintf(stderr, "JSON: %s reason: %d %.*s\n", ctx->path, reason, 40, pass->cp);
+ fprintf(stderr, "JSON: %s %s\n", ctx->path, ctx->buf);
if (ctx->path_match && reason & LEJP_FLAG_CB_IS_VALUE) {
switch (path) {
case DC_JSON_S: /* packet sequence number */
@@ -50,35 +51,79 @@ signed char dc_json_cb (struct lejp_ctx * ctx, char /* enum lejp_callbacks */ re
}
return '\0';
}
- if (pass->packet == DC_NONE) /* useless to do anything if we haven't received packet type */
+ if ((cp = startswith(ctx->path, dc_json_paths[DC_JSON_ME]))) {
+ if (!client->user) {
+ DC_MR(program->users); /* we don't need DC_IN_PROGRESS cause we have ref in cl */
+ program->users[program->users_length] = client->user = dc_user_init();
+ }
+ if (reason & LEJPCB_OBJECT_END) {
+ pass->api_io.type = DC_API_USER;
+ dc_api_stack(pass->api_io); /* inform api user */
+ }
+ if (reason & LEJP_FLAG_CB_IS_VALUE)
+ switch (cp[0]) { /* email is already set from login */
+ case 'u': /* sername */
+ free(client->user->username);
+ client->user->username = strdup(ctx->buf);
+ break;
+ case 'i': /* d */
+ client->user->id = strtoull(ctx->buf, NULL, 10);
+ break;
+ case 'd': /* iscriminator */
+ client->user->discriminator = atoi(ctx->buf);
+ break;
+ }
+ }
+ if ((cp == startswith(ctx->path, dc_json_paths[DC_JSON_FRIEND]))) {
+ if (!client->user) /* for the client user */
+ client->user = dc_user_init();
+ struct dc_user * user = client->user->next; /* client->user->next is 1. friend */
+ if (reason == LEJPCB_OBJECT_START) { /* DC_JSON_FRIEND may not be an object*/
+ if (!pass->api_io.user) /* for the newly found friend (-; */
+ pass->api_io.user = dc_user_init();
+ pass->api_io.user->status &= ~(DC_IN_PROGRESS); /* if we never get here again */
+ } else {
+ free(pass->api_io.user); /* just in case */
+ pass->api_io.user = NULL;
+ }
+ if (reason == LEJPCB_OBJECT_END) {
+ while (user->next)
+ user = user->next;
+ DC_MR(program->users);
+ program->users[program->users_length++] = user = user->next = pass->api_io.user;
+ pass->api_io.user->status &= ~(DC_IN_PROGRESS);
+ pass->api_io.type = DC_API_USER;
+ dc_api_stack(pass->api_io); /* inform api user */
+ }
+ if (reason & LEJP_FLAG_CB_IS_VALUE)
+ switch(cp[0]) {
+ case 'u': /* sername */
+ free(pass->api_io.user->username); /* yup, we don't trust serv */
+ pass->api_io.user->username = strdup(ctx->buf);
+ break;
+ case 'i': /* d */
+ pass->api_io.user->id = strtoll(ctx->buf, NULL, 10);
+ break;
+ case 'd': /* iscriminator */
+ pass->api_io.user->discriminator = atoi(ctx->buf);
+ break; /* yeah, we don't care about nicknames */
+ }
+ }
+ if (pass->packet == DC_NONE) /* useless to do anything BELOW if we haven't recvd packet type */
return '\0';
- if (reason == LEJPCB_COMPLETE) { /* gr8, fin, call back to api */
+ if (reason == LEJPCB_COMPLETE) { /* NOT USED FOR ANYTHING, REMOVE */
if (!pass->parsing_status) { /* some stuff is fully handled in switch (pass->pkt) */
pass->packet = DC_NONE;
return '\0';
}
*pass->parsing_status &= ~DC_IN_PROGRESS;
pass->api_io.status |= DC_FROM_LWS;
- // dc_api_io(pass->api_io); /* not implemented, still testing */
+ // dc_api_io(pass->api_io); /* WE'RE NOT DOING IT THIS WAY */
pass->api_io.status &= ~DC_FROM_LWS;
pass->parsing_status = NULL;
pass->packet = DC_NONE;
return '\0';
}
-#define DC_IF_NO_INIT(m) if (!pass->api_io.m) if ((pass->api_io.m = dc_##m##_init()) && (pass->api_io.m->path = strdup(ctx->path)) && (cp = strrchr(pass->api_io.m->path, '.'))) cp[0] = '\0';
-#define DC_IF_PATH_MATCHES(m) if (pass->api_io.m && pass->api_io.m->path && strcpy(buf, ctx->path) && (cp = strrchr(buf, '.')) && (cp[0] = '\0') && !strcmp(pass->api_io.m->path, buf))
- if (reason & LEJP_FLAG_CB_IS_VALUE) {
- if (strstr(ctx->path, ".username")) { /* checking properties of user objects */
- DC_IF_NO_INIT(user);
- pass->api_io.user->username = strdup(ctx->buf);
- } else if (strstr(ctx->path, ".discriminator")) {
- DC_IF_NO_INIT(user);
- pass->api_io.user->discriminator = atoi(ctx->buf);
- } else DC_IF_PATH_MATCHES(user) {
- if (strstr(ctx->path, ".id"))
- pass->api_io.user->discriminator = strtoull(ctx->buf, NULL, 10);
- } else if (strstr(ctx->path, ""))
- }
switch (pass->packet) { /* we fill in structs, set DC_INCOMPLETE and pass->parsing_status */
case DC_PING:
dc_handle_ping(pass->api_io, pass /* this is just so it's not NULL */);
diff --git a/src/h.c b/src/h.c
index 3e47408..4463f01 100644
--- a/src/h.c
+++ b/src/h.c
@@ -155,12 +155,18 @@ enum dc_json_paths { /* lws reduces the following char array to uint8_t, so we c
DC_JSON_OP, /* packet type */
DC_JSON_S, /* packet sequence number */
DC_JSON_PING, /* interval */
+ DC_JSON_ME, /* never useful in path parser, but startswith() checks if we're in object */
+ DC_JSON_FRIEND, /* never useful in path parser, but startswith() checks if we're in object */
+ DC_JSON_DM, /* never useful in path parser, but startswith() checks if we're in object */
DC_JSON_PATHS_LENGTH
};
char * dc_json_paths[] = { /* array of paths we are interested in */
"op",
"s",
- "d.heartbeat_interval"
+ "d.heartbeat_interval",
+ "d.user",
+ "d.relationships[].user",
+ "d.private_channels[]"
};
struct dc_lws_pass { /* struct that is allocated for in dc_lws_cb unique per connection in void * us */
DC_STRUCT_PREFIX
@@ -324,6 +330,7 @@ struct dc_user {
short int discriminator;
enum dc_status status;
char * path; /* yesfree, internal, so parser knows what object this user is from */
+ struct dc_user * next; /* nofree, next friend in ll of friends, first is client->user->next */
};
struct dc_user * dc_user_init () {
struct dc_user * s = calloc(1, sizeof(*s));
diff --git a/src/lib.c b/src/lib.c
index e8d54b2..07d339d 100644
--- a/src/lib.c
+++ b/src/lib.c
@@ -10,3 +10,8 @@ int smprintf (char ** str, const char * format, ...) { /* allocates automaticall
va_end(aq);
return len;
}
+char * startswith (char * testiranec, char * začetek) {
+ if (!strncmp(testiranec, začetek, strlen(začetek)))
+ return testiranec+strlen(začetek);
+ return NULL;
+}