Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

xmb trophy lock/unlock #197

Merged
merged 3 commits into from
Dec 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 grp_id, int type);
int trophy_unlock(const save_entry_t* game, int trp_id, int grp_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;
int *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 = (int*)(code->file);
LOG("Active code: [%d] '%s'", trophy_id[0], code->name+2);

if (code->type == PATCH_TROP_UNLOCK)
{
ret &= trophy_unlock(entry, trophy_id[0], trophy_id[1], code->name[0]);
code->type = PATCH_TROP_LOCK;
code->name[1] = ' ';
}
else
{
ret &= trophy_lock(entry, trophy_id[0], trophy_id[1], 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
119 changes: 110 additions & 9 deletions source/saves.c
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,107 @@ 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 grp_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);\n"
"UPDATE tbl_trophy_group SET (progress, unlocked_trophy_num, %s) ="
"(((unlocked_trophy_num+1)*100)/trophy_num, unlocked_trophy_num+1, %s+1) WHERE (title_id=%d AND groupid=%d);",
game->blocks, trp_id,
field, field, game->blocks,
field, field, game->blocks, grp_id);

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 grp_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);\n"
"UPDATE tbl_trophy_group SET (progress, unlocked_trophy_num, %s) ="
"(((unlocked_trophy_num-1)*100)/trophy_num, unlocked_trophy_num-1, %s-1) WHERE (title_id=%d AND groupid=%d);",
game->blocks, trp_id,
field, field, game->blocks,
field, field, game->blocks, grp_id);

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 +1035,7 @@ int ReadCodes(save_entry_t * save)

int ReadTrophies(save_entry_t * game)
{
int trop_count = 0;
int *trop_id;
code_entry_t * trophy;
char query[256];
char mount[ORBIS_SAVE_DATA_DIRNAME_DATA_MAXSIZE];
Expand All @@ -956,8 +1057,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 +1094,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, groupid, 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 All @@ -1006,7 +1107,7 @@ int ReadTrophies(save_entry_t * game)
{
snprintf(query, sizeof(query), " %s", sqlite3_column_text(res, 2));
trophy = _createCmdCode(PATCH_NULL, query, CMD_CODE_NULL);

trophy->file = malloc(sizeof(int)*2);
asprintf(&trophy->codes, "%s\n", sqlite3_column_text(res, 3));

switch (sqlite3_column_int(res, 4))
Expand All @@ -1031,9 +1132,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 = (int*)trophy->file;
trop_id[0] = sqlite3_column_int(res, 0);
trop_id[1] = sqlite3_column_int(res, 1);

if (!sqlite3_column_int(res, 5))
trophy->name[1] = CHAR_TAG_LOCKED;
Expand All @@ -1044,7 +1145,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[0], trophy->type, trophy->name+2, trophy->codes);
list_append(game->codes, trophy);
}

Expand Down