Skip to content

Commit

Permalink
xmb trophy lock/unlock
Browse files Browse the repository at this point in the history
  • Loading branch information
bucanero committed Dec 20, 2024
1 parent 33eb916 commit d0d0179
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 11 deletions.
5 changes: 4 additions & 1 deletion include/saves.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ enum cmd_code_enum
CMD_CODE_NULL,

// Trophy commands
CMD_RESIGN_TROPHY,
CMD_UPDATE_TROPHY,
CMD_EXP_TROPHY_USB,
CMD_COPY_TROPHIES_USB,
CMD_COPY_ALL_TROPHIES_USB,
Expand Down Expand Up @@ -315,6 +315,9 @@ int orbis_SaveMount(const save_entry_t *save, uint32_t mode, char* mountPath);
int orbis_SaveDelete(const save_entry_t *save);
int orbis_UpdateSaveParams(const save_entry_t* save, const char* title, const char* subtitle, const char* details, uint32_t up);

int trophy_lock(const save_entry_t* game, int trp_id, int type);
int trophy_unlock(const save_entry_t* game, int trp_id, int type);

int vmc_export_psv(const char* save, const char* out_path);
int vmc_export_psu(const char* path, const char* output);
int vmc_import_psv(const char *input);
Expand Down
46 changes: 46 additions & 0 deletions source/exec_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,47 @@ static void exportFingerprint(const save_entry_t* save, int silent)
fclose(fp);
}

static void toggleTrophy(const save_entry_t* entry)
{
int ret = 1;
uint32_t trophy_id;
code_entry_t* code;
list_node_t* node;

init_loading_screen("Applying changes...");

for (node = list_head(entry->codes); (code = list_get(node)); node = list_next(node))
{
if (!code->activated || (code->type != PATCH_TROP_UNLOCK && code->type != PATCH_TROP_LOCK))
continue;

trophy_id = *(uint32_t*)(code->file);
LOG("Active code: [%d] '%s'", trophy_id, code->name+2);

if (code->type == PATCH_TROP_UNLOCK)
{
ret &= trophy_unlock(entry, trophy_id, code->name[0]);
code->type = PATCH_TROP_LOCK;
code->name[1] = ' ';
}
else
{
ret &= trophy_lock(entry, trophy_id, code->name[0]);
code->type = PATCH_TROP_UNLOCK;
code->name[1] = CHAR_TAG_LOCKED;
}

code->activated = 0;
}

stop_loading_screen();

if(ret)
show_message("Trophies successfully updated!");
else
show_message("Error! Couldn't update trophies");
}

static void exportTrophiesZip(const char* exp_path)
{
char* export_file;
Expand Down Expand Up @@ -1393,6 +1434,11 @@ void execCodeCommand(code_entry_t* code, const char* codecmd)
code->activated = 0;
break;

case CMD_UPDATE_TROPHY:
toggleTrophy(selected_entry);
code->activated = 0;
break;

case CMD_ZIP_TROPHY_USB:
exportTrophiesZip(codecmd[1] ? EXPORT_PATH_USB1 : EXPORT_PATH_USB0);
code->activated = 0;
Expand Down
4 changes: 2 additions & 2 deletions source/menu_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ static void SetMenu(int id)
if(strncmp(APOLLO_SANDBOX_PATH, vmc1_saves.path, 16) == 0)
{
*strrchr(vmc1_saves.path, '/') = 0;
orbis_SaveUmount(strrchr(vmc1_saves.path, '/'));
orbis_SaveUmount(strrchr(vmc1_saves.path, '/')+1);
}
}
break;
Expand All @@ -140,7 +140,7 @@ static void SetMenu(int id)
if(strncmp(APOLLO_SANDBOX_PATH, vmc2_saves.path, 16) == 0)
{
*strrchr(vmc2_saves.path, '/') = 0;
orbis_SaveUmount(strrchr(vmc2_saves.path, '/'));
orbis_SaveUmount(strrchr(vmc2_saves.path, '/')+1);
}

stop_loading_screen();
Expand Down
111 changes: 103 additions & 8 deletions source/saves.c
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,101 @@ int appdb_rebuild(const char* db_path, uint32_t userid)
return 1;
}

static const char* trophy_type_field(int type)
{
switch (type)
{
case CHAR_TRP_PLATINUM:
return "unlocked_platinum_num";

case CHAR_TRP_GOLD:
return "unlocked_gold_num";

case CHAR_TRP_SILVER:
return "unlocked_silver_num";

case CHAR_TRP_BRONZE:
return "unlocked_bronze_num";

default:
return NULL;
}
}

int trophy_unlock(const save_entry_t* game, int trp_id, int type)
{
char dbpath[256];
sqlite3 *db;
const char *field = trophy_type_field(type);

if (!field)
return 0;

snprintf(dbpath, sizeof(dbpath), TROPHY_DB_PATH, apollo_config.user_id);
if ((db = open_sqlite_db(dbpath)) == NULL)
return 0;

char* query = sqlite3_mprintf("UPDATE tbl_trophy_flag SET (visible, unlocked, time_unlocked, time_unlocked_uc) ="
"(1, 1, strftime('%%Y-%%m-%%dT%%H:%%M:%%S.00Z', CURRENT_TIMESTAMP), strftime('%%Y-%%m-%%dT%%H:%%M:%%S.00Z', CURRENT_TIMESTAMP))"
"WHERE (title_id = %d AND trophyid = %d);\n"
"UPDATE tbl_trophy_title SET (progress, unlocked_trophy_num, %s) ="
"(((unlocked_trophy_num+1)*100)/trophy_num, unlocked_trophy_num+1, %s+1) WHERE (id=%d);",
game->blocks, trp_id,
field, field, game->blocks);

if (sqlite3_exec(db, query, NULL, NULL, NULL) != SQLITE_OK)
{
LOG("Error updating '%s': %s", game->title_id, sqlite3_errmsg(db));
sqlite3_free(query);
sqlite3_close(db);
return 0;
}

LOG("Saving database to %s", dbpath);
sqlite3_memvfs_dump(db, NULL, dbpath);
sqlite3_free(query);
sqlite3_close(db);

return 1;
}

int trophy_lock(const save_entry_t* game, int trp_id, int type)
{
char dbpath[256];
sqlite3 *db;
const char *field = trophy_type_field(type);

if (!field)
return 0;

snprintf(dbpath, sizeof(dbpath), TROPHY_DB_PATH, apollo_config.user_id);
if ((db = open_sqlite_db(dbpath)) == NULL)
return 0;

char* query = sqlite3_mprintf("UPDATE tbl_trophy_flag SET (visible, unlocked, time_unlocked, time_unlocked_uc) ="
"((~(hidden&1))&(hidden|1), 0, '0001-01-01T00:00:00.00Z', '0001-01-01T00:00:00.00Z') "
"WHERE (title_id = %d AND trophyid = %d);\n"
"UPDATE tbl_trophy_title SET (progress, unlocked_trophy_num, %s) ="
"(((unlocked_trophy_num-1)*100)/trophy_num, unlocked_trophy_num-1, %s-1) WHERE (id=%d);",
game->blocks, trp_id,
field, field, game->blocks);

if (sqlite3_exec(db, query, NULL, NULL, NULL) != SQLITE_OK)
{
LOG("Error updating '%s': %s", game->title_id, sqlite3_errmsg(db));
sqlite3_free(query);
sqlite3_close(db);
return 0;
}

LOG("Saving database to %s", dbpath);
sqlite3_memvfs_dump(db, NULL, dbpath);
sqlite3_free(query);
sqlite3_close(db);

return 1;
}

int orbis_SaveDelete(const save_entry_t *save)
{
OrbisSaveDataDelete del;
Expand Down Expand Up @@ -934,7 +1029,7 @@ int ReadCodes(save_entry_t * save)

int ReadTrophies(save_entry_t * game)
{
int trop_count = 0;
int trop_id = 0;
code_entry_t * trophy;
char query[256];
char mount[ORBIS_SAVE_DATA_DIRNAME_DATA_MAXSIZE];
Expand All @@ -956,8 +1051,8 @@ int ReadTrophies(save_entry_t * game)
tmp = game->path;
asprintf(&game->path, APOLLO_SANDBOX_PATH, mount);

// trophy = _createCmdCode(PATCH_COMMAND, CHAR_ICON_SIGN " Apply Changes & Resign Trophy Set", CMD_RESIGN_TROPHY);
// list_append(game->codes, trophy);
trophy = _createCmdCode(PATCH_COMMAND, CHAR_ICON_SIGN " Apply Changes to Trophy Set", CMD_UPDATE_TROPHY);
list_append(game->codes, trophy);

trophy = _createCmdCode(PATCH_COMMAND, CHAR_ICON_COPY " Backup Trophy files to USB", CMD_CODE_NULL);
trophy->file = strdup(game->path);
Expand Down Expand Up @@ -993,7 +1088,7 @@ int ReadTrophies(save_entry_t * game)
trophy = _createCmdCode(PATCH_NULL, "----- " UTF8_CHAR_STAR " Trophies " UTF8_CHAR_STAR " -----", CMD_CODE_NULL);
list_append(game->codes, trophy);

snprintf(query, sizeof(query), "SELECT title_id, trophy_title_id, title, description, grade, unlocked, id FROM tbl_trophy_flag WHERE title_id = %d", game->blocks);
snprintf(query, sizeof(query), "SELECT trophyid, trophy_title_id, title, description, grade, unlocked FROM tbl_trophy_flag WHERE title_id = %d", game->blocks);

if (sqlite3_prepare_v2(db, query, -1, &res, NULL) != SQLITE_OK)
{
Expand Down Expand Up @@ -1031,9 +1126,9 @@ int ReadTrophies(save_entry_t * game)
break;
}

trop_count = sqlite3_column_int(res, 6);
trophy->file = malloc(sizeof(trop_count));
memcpy(trophy->file, &trop_count, sizeof(trop_count));
trop_id = sqlite3_column_int(res, 0);
trophy->file = malloc(sizeof(trop_id));
memcpy(trophy->file, &trop_id, sizeof(trop_id));

if (!sqlite3_column_int(res, 5))
trophy->name[1] = CHAR_TAG_LOCKED;
Expand All @@ -1044,7 +1139,7 @@ int ReadTrophies(save_entry_t * game)
else
trophy->type = (sqlite3_column_int(res, 5) ? PATCH_TROP_LOCK : PATCH_TROP_UNLOCK);

LOG("Trophy=%d [%d] '%s' (%s)", trop_count, trophy->type, trophy->name, trophy->codes);
LOG("Trophy=%d [%d] '%s' (%s)", trop_id, trophy->type, trophy->name+2, trophy->codes);
list_append(game->codes, trophy);
}

Expand Down

0 comments on commit d0d0179

Please sign in to comment.