minilauncher-for-slippi/gg.c

213 lines
7.4 KiB
C

#include <cjson/cJSON.h>
#include "gg.h"
#include "http.h"
// Static
#include "static/tourney_query.json.h"
Evas_Object* tab_gg = NULL;
static Evas_Object* tab_gg_sidebar;
static Evas_Object* tab_gg_content;
extern char* start_gg_api;
//extern char* start_gg_token;
static int player_id;
#define UserTourneysQuery
static void
_gg_sidebar_cb(void *_data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Evas_Object** data = _data;
//update_tab(*data);
}
static void
_gg_set_token(Ecore_Con_Url* ec_url, char* token)
{
Eina_Strbuf* sesh = eina_strbuf_new();
eina_strbuf_append_printf(sesh, "gg_session=%s;", token);
//Eina_Strbuf* bearer = eina_strbuf_new();
//eina_strbuf_append_printf(bearer, "Bearer %s", start_gg_token);
ecore_con_url_additional_header_add(ec_url, "Cookie", eina_strbuf_string_get(sesh));
ecore_con_url_additional_header_add(ec_url, "x-web-source", "gg-web-gql-client, gg-web-rest");
//ecore_con_url_additional_header_add(ec_url, "Authorization", eina_strbuf_string_get(bearer));
free(eina_strbuf_release(sesh));
//free(eina_strbuf_release(bearer));
}
static Eina_Bool
_gg_tourneys_result(struct memory_chunk* dd, void *deta EINA_UNUSED, int type EINA_UNUSED, void *event_info)
{
Ecore_Con_Event_Url_Complete* ev = event_info;
cJSON* json = cJSON_Parse(dd->data);
if (!json)
{
fprintf(stderr, "Something happened.\n");
return EINA_FALSE;
}
cJSON* data = cJSON_GetObjectItemCaseSensitive(json->child, "data");
cJSON* user = cJSON_GetObjectItemCaseSensitive(data, "user");
cJSON* player = cJSON_GetObjectItemCaseSensitive(user, "player");
cJSON* events = cJSON_GetObjectItemCaseSensitive(player, "events");
cJSON* nodes = cJSON_GetObjectItemCaseSensitive(events, "nodes");
//int i = 0;
//for (cJSON* c = nodes->child; c->next != NULL; (++i, c = c->next))
cJSON* c;
cJSON_ArrayForEach(c, nodes)
{
cJSON* entity = cJSON_GetObjectItemCaseSensitive(c, "entity");
printf("name: %s\n", cJSON_GetObjectItemCaseSensitive(entity, "name")->valuestring);
}
return EINA_TRUE;
}
static Eina_Bool
_gg_scrape_result(struct memory_chunk* dd, void *data EINA_UNUSED, int type EINA_UNUSED, void *event_info)
{
#define magiccode "script id=\"__NEXT_DATA__\" type=\"application/json\">"
char* start_json = strstr(dd->data, magiccode);
if (!start_json)
{
fprintf(stderr, "Something happened with start_json.\n");
return EINA_FALSE; // Some error
}
start_json += sizeof(magiccode) - 1;
char* end_json = strstr(start_json, "</script><script>");
if (!end_json)
{
fprintf(stderr, "Something happened with end_json.\n");
return EINA_FALSE;
}
*end_json = '\0';
#undef magiccode
// Data required is scraped now!
cJSON* json = cJSON_Parse(start_json);
if (!json)
{
fprintf(stderr, "Something happened.\n");
return EINA_FALSE;
}
cJSON* props = cJSON_GetObjectItemCaseSensitive(json, "props");
cJSON* pageProps = cJSON_GetObjectItemCaseSensitive(props, "pageProps");
cJSON* currentUserFetchSpec = cJSON_GetObjectItemCaseSensitive(
pageProps, "currentUserFetchSpec");
cJSON* entities = cJSON_GetObjectItemCaseSensitive(currentUserFetchSpec, "entities");
cJSON* users = cJSON_GetObjectItemCaseSensitive(entities, "users");
cJSON* jplayer_id = cJSON_GetObjectItemCaseSensitive(users, "id");
if (jplayer_id)
player_id = jplayer_id->valueint;
else
{
printf("Token expired. Create a new one.\n");
return EINA_FALSE;
}
free(dd);
// Now attempt another request
// RANT: There are two endpoints. api.start.gg/gql/alpha is the official, and it SUCKS
Ecore_Con_Url* ec_url = ecore_con_url_custom_new("https://www.start.gg/api/-/gql", "POST");
ecore_con_url_data_set(ec_url, memory_chunk_alloc(_gg_tourneys_result));
ecore_con_url_verbose_set(ec_url, EINA_TRUE);
//ecore_event_handler_add(ECORE_CON_EVENT_URL_DATA, memory_chunk_data, NULL);
//ecore_event_handler_add(ECORE_CON_EVENT_URL_COMPLETE, memory_chunk_result, NULL);
ecore_con_url_additional_header_add(ec_url, "User-Agent", ":^)'); DROP TABLE users; --");
_gg_set_token(ec_url, (char*)data);
// Fill info
Eina_Strbuf* req = eina_strbuf_new();
eina_strbuf_append_printf(req, data_tourney_query, player_id);
// Need to remove real newlines
eina_strbuf_replace_all(req, "\n", "\\n");
// Need to remove the newline at the end or it's not valid.
ecore_con_url_post(ec_url, eina_strbuf_string_get(req), eina_strbuf_length_get(req)-2, "application/json, application/json");
free(eina_strbuf_release(req));
return EINA_FALSE;
#if 0
int i = 0;
for (cJSON* c = tournament->child; c->next != NULL; (++i, c = c->next))
{
printf("name: %s\n", cJSON_GetObjectItemCaseSensitive(c, "name")->valuestring);
}
#endif
}
static void
_gg_scrape_homepage(char* token)
{
if (!ecore_con_url_pipeline_get())
ecore_con_url_pipeline_set(EINA_TRUE);
Ecore_Con_Url* ec_url = ecore_con_url_custom_new("https://www.start.gg/", "GET");
ecore_con_url_data_set(ec_url, memory_chunk_alloc(_gg_scrape_result));
ecore_event_handler_add(ECORE_CON_EVENT_URL_DATA, memory_chunk_data, NULL);
ecore_event_handler_add(ECORE_CON_EVENT_URL_COMPLETE, memory_chunk_result, token);
ecore_con_url_additional_header_add(ec_url, "User-Agent", ":^)'); DROP TABLE users; --");
_gg_set_token(ec_url, token);
ecore_con_url_get(ec_url);
}
Evas_Object*
gg_create_view(Evas_Object* parent)
{
Evas_Object* tb_it;
tab_gg = elm_box_add(parent);
elm_box_horizontal_set(tab_gg, EINA_TRUE);
evas_object_size_hint_weight_set(tab_gg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(tab_gg, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_show(tab_gg);
tab_gg_sidebar = elm_toolbar_add(tab_gg);
elm_toolbar_horizontal_set(tab_gg_sidebar, EINA_FALSE);
//elm_object_style_set(tab_gg_sidebar, "item_vertical");
elm_toolbar_homogeneous_set(tab_gg_sidebar, EINA_TRUE);
elm_toolbar_shrink_mode_set(tab_gg_sidebar, ELM_TOOLBAR_SHRINK_MENU);
evas_object_size_hint_weight_set(tab_gg_sidebar, 0.0, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(tab_gg_sidebar, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_box_pack_end(tab_gg, tab_gg_sidebar);
tb_it = elm_toolbar_item_append(tab_gg_sidebar, "home", NULL, _gg_sidebar_cb, NULL);
elm_toolbar_item_priority_set(tb_it, 100);
tb_it = elm_toolbar_item_append(tab_gg_sidebar, "mail-unread", NULL, _gg_sidebar_cb, NULL);
elm_toolbar_item_priority_set(tb_it, 100);
//-----
elm_toolbar_item_separator_set(
elm_toolbar_item_append(tab_gg_sidebar, NULL, NULL, NULL, NULL), EINA_TRUE);
_gg_scrape_homepage(start_gg_api);
//-----
#if 0
elm_toolbar_item_separator_set(
elm_toolbar_item_append(tab_gg_sidebar, NULL, NULL, NULL, NULL), EINA_TRUE);
tb_it = elm_toolbar_item_append(tab_gg_sidebar, "view-list-compact", "", _gg_sidebar_cb, NULL);
elm_toolbar_item_priority_set(tb_it, 100);
#endif
Evas_Object* tab_gg_scr = elm_scroller_add(tab_gg);
evas_object_size_hint_weight_set(tab_gg_scr, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(tab_gg_scr, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_box_pack_end(tab_gg, tab_gg_scr);
evas_object_show(tab_gg_scr);
tab_gg_content = elm_box_add(tab_gg_scr);
evas_object_size_hint_weight_set(tab_gg_content, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(tab_gg_content, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_show(tab_gg_content);
elm_object_content_set(tab_gg_scr, tab_gg_content);
evas_object_show(tab_gg_content);
evas_object_show(tab_gg_scr);
evas_object_show(tab_gg_sidebar);
evas_object_show(tab_gg);
return tab_gg;
}