Skip to content

Commit

Permalink
More cloud cleanups
Browse files Browse the repository at this point in the history
  • Loading branch information
OFFTKP committed Dec 22, 2023
1 parent c47eadd commit dea0091
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 53 deletions.
89 changes: 57 additions & 32 deletions src/cloud.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ extern "C" {
}
#endif

bool pending_login = false;
bool pending_logout = false;

struct file_metadata_t
{
std::string id;
Expand Down Expand Up @@ -99,7 +102,7 @@ struct cloud_drive_t
}
};

void google_cloud_drive_init(cloud_drive_t*, std::function<void(cloud_drive_t*)>);
void google_cloud_drive_init(cloud_drive_t*);

#define GOOGLE_CLIENT_ID "617320710875-o9ev86s5ad18bmmgb98p0dkbqlfufekr.apps.googleusercontent.com"
#define GOOGLE_CLIENT_ID_WEB "617320710875-dakb2f10lgnnn3a97bgva18l83221pc3.apps.googleusercontent.com"
Expand Down Expand Up @@ -277,13 +280,12 @@ extern "C" void em_oath_sign_in_callback(cloud_drive_t* drive, const char* refre
sb_save_file_data(refresh_path.c_str(), (uint8_t*)drive->refresh_token.c_str(),
drive->refresh_token.size() + 1);
em_flush_fs();
google_cloud_drive_init(drive, drive->ready_callback);
google_cloud_drive_init(drive);
}
else
{
printf("[cloud] refresh token or access token is null\n");
drive->ready_callback(nullptr);
delete drive;
}
}
#endif
Expand Down Expand Up @@ -717,27 +719,28 @@ bool google_check_username_exists(cloud_drive_t* drive)
return false;
}

void google_get_user_data(cloud_drive_t* drive, std::function<void(cloud_drive_t*)> callback)
void google_get_user_data(cloud_drive_t* drive)
{
bool avatar_exists = google_check_avatar_exists(drive);
bool username_exists = google_check_username_exists(drive);
if (avatar_exists && username_exists)
{
callback(drive);
drive->ready_callback(drive);
return;
}

drive->inc();
https_request(http_request_e::GET, "https://www.googleapis.com/drive/v3/about?fields=user", "",
{{"Authorization", "Bearer " + drive->access_token}},
[drive, avatar_exists, callback](const std::vector<uint8_t>& data) {
[drive, avatar_exists](const std::vector<uint8_t>& data) {
std::string path = drive->save_directory + "cloud_username.txt";
nlohmann::json json = nlohmann::json::parse(data);
if (json.find("error") != json.end())
{
std::string error = json["error"]["message"];
printf("[cloud] failed to get username: %s\n", error.c_str());
drive->dec();
drive->ready_callback(nullptr);
return;
}

Expand All @@ -749,18 +752,19 @@ void google_get_user_data(cloud_drive_t* drive, std::function<void(cloud_drive_t
drive->inc();
std::string url = json["user"]["photoLink"];
https_request(http_request_e::GET, url, "", {},
[drive, callback](const std::vector<uint8_t>& data) {
[drive](const std::vector<uint8_t>& data) {
sb_save_file_data(
(drive->save_directory + "profile_picture").c_str(),
data.data(), data.size());
em_flush_fs();
google_check_avatar_exists(drive);
callback(drive);
drive->dec();
drive->ready_callback(drive);
});
} else {
printf("[cloud] failed to get username: no user in response\n");
drive->dec();
drive->ready_callback(nullptr);
return;
}
drive->dec();
Expand All @@ -770,17 +774,14 @@ void google_get_user_data(cloud_drive_t* drive, std::function<void(cloud_drive_t
void google_cloud_drive_mkdir(cloud_drive_t* drive, const std::string& name, const std::string& parent, std::function<void(cloud_drive_t*)> callback)
{
google_cloud_drive_upload(drive, name, parent, "application/vnd.google-apps.folder", NULL,
0, [callback](cloud_drive_t* drive) {
google_cloud_drive_get_files(
drive, [callback](cloud_drive_t* drive) {
google_get_user_data(drive, callback);
});
});
0, [callback](cloud_drive_t* drive) {
callback(drive);
});
}

void google_cloud_drive_init(cloud_drive_t* drive, std::function<void(cloud_drive_t*)> callback)
void google_cloud_drive_init(cloud_drive_t* drive)
{
google_cloud_drive_get_files(drive, [callback](cloud_drive_t* drive) {
google_cloud_drive_get_files(drive, [](cloud_drive_t* drive) {
bool folders_exist;
bool skyemu_folder_exists;
bool save_states_folder_exists;
Expand All @@ -794,18 +795,18 @@ void google_cloud_drive_init(cloud_drive_t* drive, std::function<void(cloud_driv

if (!folders_exist)
{
google_cloud_drive_mkdir(drive, "SkyEmu", "", [callback](cloud_drive_t* drive) {
google_cloud_drive_mkdir(drive, "save_states", "SkyEmu", [callback](cloud_drive_t* drive) {
google_cloud_drive_mkdir(drive, "SkyEmu", "", [](cloud_drive_t* drive) {
google_cloud_drive_mkdir(drive, "save_states", "SkyEmu", [](cloud_drive_t* drive) {
google_cloud_drive_get_files(
drive, [callback](cloud_drive_t* drive) {
google_get_user_data(drive, callback);
drive, [](cloud_drive_t* drive) {
google_get_user_data(drive);
});
});
});
}
else
{
google_get_user_data(drive, callback);
google_get_user_data(drive);
}
});
}
Expand Down Expand Up @@ -893,7 +894,7 @@ void cloud_drive_authenticate(cloud_drive_t* drive)
std::string error_description = json["error_description"];
printf("[cloud] got response with error while authenticating: %s: %s\n",
error.c_str(), error_description.c_str());
delete drive;
drive->ready_callback(nullptr);
return;
}

Expand All @@ -904,7 +905,7 @@ void cloud_drive_authenticate(cloud_drive_t* drive)
sb_save_file_data(refresh_path.c_str(), (uint8_t*)drive->refresh_token.c_str(),
drive->refresh_token.size() + 1);
em_flush_fs();
google_cloud_drive_init(drive, drive->ready_callback);
google_cloud_drive_init(drive);
});

#ifdef SE_PLATFORM_ANDROID
Expand All @@ -919,13 +920,13 @@ void cloud_drive_authenticate(cloud_drive_t* drive)
{
std::string error = req.get_param_value("error");
printf("[cloud] while authenticating got error: %s\n", error.c_str());
delete drive;
drive->ready_callback(nullptr);
}
else
{
printf(
"[cloud] while authenticating got response that contains neither code nor error\n");
delete drive;
drive->ready_callback(nullptr);
}
});
// TODO: disallow http_server from listening to port 5000
Expand All @@ -935,12 +936,24 @@ void cloud_drive_authenticate(cloud_drive_t* drive)

void cloud_drive_create(void (*ready_callback)(cloud_drive_t*))
{
pending_login = true;
cloud_drive_t* drive = new cloud_drive_t;
std::function<void(cloud_drive_t*)> fcallback = [ready_callback, drive](cloud_drive_t* called_drive) {
pending_login = false;
ready_callback(called_drive);

// If this callback is called with a nullptr that means something went wrong
// during authentication and the drive object we created should be deleted
if (called_drive == nullptr)
{
delete drive;
}
};
#ifndef EMSCRIPTEN
std::thread create_thread([ready_callback] {
std::thread create_thread([drive, fcallback] {
#endif
cloud_drive_t* drive = new cloud_drive_t;
drive->save_directory = se_get_pref_path();
drive->ready_callback = ready_callback;
drive->ready_callback = fcallback;

std::string refresh_path = drive->save_directory + "refresh_token.txt";
if (sb_file_exists(refresh_path.c_str()))
Expand All @@ -950,22 +963,22 @@ void cloud_drive_create(void (*ready_callback)(cloud_drive_t*))
if (refresh_token_data == NULL)
{
printf("[cloud] failed to load refresh token\n");
ready_callback(nullptr);
drive->ready_callback(nullptr);
return;
}
drive->refresh_token = std::string((char*)refresh_token_data, refresh_token_size - 1);
free(refresh_token_data);

google_use_refresh_token(drive, [ready_callback, refresh_path](cloud_drive_t* drive) {
google_use_refresh_token(drive, [refresh_path](cloud_drive_t* drive) {
if (drive->access_token.empty())
{
printf("[cloud] failed to use refresh token\n");
::remove(refresh_path.c_str());
ready_callback(nullptr);
drive->ready_callback(nullptr);
}
else
{
google_cloud_drive_init(drive, ready_callback);
google_cloud_drive_init(drive);
}
});
return;
Expand All @@ -979,6 +992,7 @@ void cloud_drive_create(void (*ready_callback)(cloud_drive_t*))

void cloud_drive_logout(cloud_drive_t* drive, void (*callback)())
{
pending_logout = true;
std::function<void()> fcallback = callback;
drive->scheduled_deletion = true; // no more requests
#ifndef EMSCRIPTEN
Expand All @@ -993,6 +1007,7 @@ void cloud_drive_logout(cloud_drive_t* drive, void (*callback)())
[drive, fcallback](const std::vector<uint8_t>& data) {
delete drive;
fcallback();
pending_logout = false;
});

em_flush_fs();
Expand Down Expand Up @@ -1128,4 +1143,14 @@ void cloud_drive_cleanup()
uint64_t cloud_drive_hash(const char* input, size_t input_size)
{
return XXH64(input, input_size, 0);
}

bool cloud_drive_pending_login()
{
return pending_login;
}

bool cloud_drive_pending_logout()
{
return pending_logout;
}
4 changes: 4 additions & 0 deletions src/cloud.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>

typedef struct cloud_drive_t cloud_drive_t;

Expand Down Expand Up @@ -39,5 +40,8 @@ cloud_user_info_t cloud_drive_get_user_info(cloud_drive_t* cloud_drive);
void cloud_drive_init();
void cloud_drive_cleanup();

bool cloud_drive_pending_login();
bool cloud_drive_pending_logout();

uint64_t cloud_drive_hash(const char* input, size_t input_size);
#endif
28 changes: 7 additions & 21 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -496,11 +496,6 @@ typedef struct{
}se_emu_id;
typedef struct{
cloud_drive_t* drive;
bool awaiting_login;
bool awaiting_login_swap;
bool awaiting_logout;
bool awaiting_logout_swap;
char username[128];
se_save_state_t save_states[SE_NUM_SAVE_STATES];
mutex_t save_states_mutex[SE_NUM_SAVE_STATES];
bool save_states_busy[SE_NUM_SAVE_STATES];
Expand Down Expand Up @@ -2819,10 +2814,6 @@ void se_logged_out_cloud_callback(){
cloud_state.drive = NULL;
memset(cloud_state.save_states, 0, sizeof(cloud_state.save_states));
memset(cloud_state.save_states_busy_swap, 0, sizeof(cloud_state.save_states_busy_swap));
cloud_state.awaiting_login = false;
cloud_state.awaiting_logout = false;
cloud_state.awaiting_login_swap = false;
cloud_state.awaiting_logout_swap = false;
}
void se_write_png_cloud(void* context, void* data, int size){
char file[SB_FILE_PATH_SIZE];
Expand Down Expand Up @@ -2851,7 +2842,6 @@ void se_restore_state_slot_cloud(size_t slot){
static void se_drive_ready_callback(cloud_drive_t* drive){
cloud_state.drive = drive;
if(drive){
cloud_state.awaiting_login_swap = false;
cloud_state.user_info = cloud_drive_get_user_info(drive);

// If there's a game, check if there's any save states to download
Expand All @@ -2860,11 +2850,9 @@ static void se_drive_ready_callback(cloud_drive_t* drive){
}
}else{
printf("Something went wrong during cloud login\n");
cloud_state.awaiting_login_swap = false;
}
}
void se_login_cloud(){
cloud_state.awaiting_login_swap = true;
cloud_drive_create(se_drive_ready_callback);
}
static void se_sync_cloud_save_states_callback(){
Expand Down Expand Up @@ -2909,7 +2897,7 @@ void se_drive_login(bool clicked, int x, int y, int w, int h){
};
});
}
if(cloud_state.awaiting_login) return;
if(cloud_drive_pending_login()) return;
EM_ASM_INT({
var input = document.getElementById('driveLogin');
input.style.left = $0 +'px';
Expand Down Expand Up @@ -5741,10 +5729,11 @@ void se_draw_menu_panel(){
}
se_section(ICON_FK_CLOUD " Google Drive");
if (!cloud_state.drive){
if (cloud_state.awaiting_login) se_push_disabled();
bool pending_login = cloud_drive_pending_login();
if (pending_login) se_push_disabled();
bool clicked = false;
if (se_button(ICON_FK_SIGN_IN " Login",(ImVec2){0,0})){clicked=true;}
if (cloud_state.awaiting_login) se_pop_disabled();
if (pending_login) se_pop_disabled();
if(igIsItemVisible()){
ImVec2 min, max;
igGetItemRectMin(&min);
Expand All @@ -5754,7 +5743,6 @@ void se_draw_menu_panel(){
max.y+=style->FramePadding.y;
se_drive_login(clicked, min.x, min.y, max.x-min.x, max.y-min.y);
}
cloud_state.awaiting_login = cloud_state.awaiting_login_swap;
} else {
ImVec2 avatar_frame_sz = (ImVec2){64+style->FramePadding.x*2,64+style->FramePadding.y*2};
ImVec2 screen_p;
Expand All @@ -5781,13 +5769,12 @@ void se_draw_menu_panel(){
char logged_in[256];
snprintf(logged_in,256,se_localize_and_cache("Logged in as %s"),cloud_state.user_info.name);
se_text(logged_in);
if (cloud_state.awaiting_logout) se_push_disabled();
bool pending_logout = cloud_drive_pending_logout();
if (pending_logout) se_push_disabled();
if (se_button(ICON_FK_SIGN_OUT " Logout",(ImVec2){0,0})){
cloud_state.awaiting_logout_swap = true;
cloud_drive_logout(cloud_state.drive,se_logged_out_cloud_callback);
}
if (cloud_state.awaiting_logout) se_pop_disabled();
cloud_state.awaiting_logout = cloud_state.awaiting_logout_swap;
if (pending_logout) se_pop_disabled();
igEndGroup();
}

Expand Down Expand Up @@ -7098,7 +7085,6 @@ void se_load_settings(){
char refresh_token_path[SB_FILE_PATH_SIZE];
snprintf(refresh_token_path,SB_FILE_PATH_SIZE,"%srefresh_token.txt",se_get_pref_path());
if(sb_file_exists(refresh_token_path)){
cloud_state.awaiting_login_swap = true;
cloud_drive_create(se_drive_ready_callback);
}
}
Expand Down

0 comments on commit dea0091

Please sign in to comment.