Skip to content

Commit

Permalink
Add Support for PlayStation Mobile games in "Refresh Livearea" (#557)
Browse files Browse the repository at this point in the history
* Add Suppot for PlayStation Mobile games in "Refresh Livearea"

* Add support for PlayStation Mobile games to "Refresh Livearea"

(and my credits ofc-)

* Switched to vitasdk provied structs

* Add files via upload
  • Loading branch information
LiEnby authored and TheOfficialFloW committed Jan 15, 2020
1 parent 8c10171 commit ee7060c
Show file tree
Hide file tree
Showing 3 changed files with 178 additions and 32 deletions.
45 changes: 45 additions & 0 deletions package_installer.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,51 @@ static int unloadScePaf() {
return sceSysmoduleUnloadModuleInternalWithArg(SCE_SYSMODULE_INTERNAL_PAF, 0, NULL, &buf);
}

int promotePsm(const char *path, const char *titleid)
{

ScePromoterUtilityImportParams promoteArgs;
memset(&promoteArgs,0x00,sizeof(ScePromoterUtilityImportParams));

strncpy(promoteArgs.path,path,0x7F);
strncpy(promoteArgs.titleid,titleid,0xB);

promoteArgs.type = SCE_PKG_TYPE_PSM;
promoteArgs.attribute = 0x1;

int res;

res = loadScePaf();
if (res < 0)
return res;

res = sceSysmoduleLoadModuleInternal(SCE_SYSMODULE_INTERNAL_PROMOTER_UTIL);
if (res < 0)
return res;

res = scePromoterUtilityInit();
if (res < 0)
return res;

res = scePromoterUtilityPromoteImport(&promoteArgs);
if (res < 0)
return res;

res = scePromoterUtilityExit();
if (res < 0)
return res;

res = sceSysmoduleUnloadModuleInternal(SCE_SYSMODULE_INTERNAL_PROMOTER_UTIL);
if (res < 0)
return res;

res = unloadScePaf();
if (res < 0)
return res;

return res;
}

int promoteApp(const char *path) {
int res;

Expand Down
1 change: 1 addition & 0 deletions package_installer.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ typedef struct {
} InstallArguments;

int promoteApp(const char *path);
int promotePsm(const char *path, const char *titleid);
int deleteApp(const char *titleid);
int checkAppExist(const char *titleid);

Expand Down
164 changes: 132 additions & 32 deletions refresh.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
Copyright (C) 2015-2018, TheFloW
Copyright (C) 2017, VitaSmith
Copyright (C) 2018, TheRadziu
Copyright (C) 2020, SilicaAndPina
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -36,7 +37,7 @@
#define APP_TEMP "ux0:temp/app"
#define DLC_TEMP "ux0:temp/addcont"
#define PATCH_TEMP "ux0:temp/patch"
#define PSM_TEMP "ux0:temp/psm"
#define PSM_TEMP "ux0:temp/game"
#define THEME_TEMP "ux0:temp/theme"

#define MAX_DLC_PER_TITLE 1024
Expand All @@ -55,60 +56,98 @@ int isCustomHomebrew(const char* path)
return 1;
}



int refreshNeeded(const char *app_path, const char* content_type)
{
char sfo_path[MAX_PATH_LENGTH];
char appmeta_path[MAX_PATH_LENGTH];
char appmeta_param[MAX_PATH_LENGTH];
char sfo_path[MAX_PATH_LENGTH];
int mounted_appmeta;

// Read param.sfo
snprintf(sfo_path, MAX_PATH_LENGTH, "%s/sce_sys/param.sfo", app_path);
void *sfo_buffer = NULL;
int sfo_size = allocateReadFile(sfo_path, &sfo_buffer);
if (sfo_size < 0)
return sfo_size;

// Get title and content ids
char titleid[12], contentid[50], appver[8];
getSfoString(sfo_buffer, "TITLE_ID", titleid, sizeof(titleid));
getSfoString(sfo_buffer, "CONTENT_ID", contentid, sizeof(contentid));
getSfoString(sfo_buffer, "APP_VER", appver, sizeof(appver));

// Free sfo buffer
free(sfo_buffer);

if(strcmp(content_type,"psm") == 0)
{
char contentid_path[MAX_PATH_LENGTH];
void *cidFile = NULL;

//Initalize buffers
memset(titleid,0,12);
memset(contentid,0,50);
memset(appver,0,8);

snprintf(contentid_path, MAX_PATH_LENGTH, "%s/RW/System/content_id", app_path);

// Get content id
int contentid_size = allocateReadFile(contentid_path, &cidFile);
if(contentid_size < 0)
return contentid_size;

// Get title id from content id
strncpy(titleid,cidFile+7,9);
strncpy(contentid,cidFile,49);


free(cidFile);

int isExist = checkAppExist(titleid);
}
else
{
// Read param.sfo
snprintf(sfo_path, MAX_PATH_LENGTH, "%s/sce_sys/param.sfo", app_path);

void *sfo_buffer = NULL;
int sfo_size = allocateReadFile(sfo_path, &sfo_buffer);
if (sfo_size < 0)
return sfo_size;

// Get title and content ids

getSfoString(sfo_buffer, "TITLE_ID", titleid, sizeof(titleid));
getSfoString(sfo_buffer, "CONTENT_ID", contentid, sizeof(contentid));
getSfoString(sfo_buffer, "APP_VER", appver, sizeof(appver));

// Free sfo buffer
free(sfo_buffer);
}


// Check if app or dlc exists
if (((strcmp(content_type, "app") == 0)||(strcmp(content_type, "dlc") == 0))&&(checkAppExist(titleid))) {
if (((strcmp(content_type, "app") == 0)||(strcmp(content_type, "dlc") == 0)||(strcmp(content_type,"psm") == 0))&&(checkAppExist(titleid))) {
char rif_name[48];

char rif_path[MAX_PATH_LENGTH];

uint64_t aid;
sceRegMgrGetKeyBin("/CONFIG/NP", "account_id", &aid, sizeof(uint64_t));

// Check if bounded rif file exits
_sceNpDrmGetRifName(rif_name, 0, aid);
if (strcmp(content_type, "app") == 0)
snprintf(sfo_path, MAX_PATH_LENGTH, "ux0:license/app/%s/%s", titleid, rif_name);
snprintf(rif_path, MAX_PATH_LENGTH, "ux0:license/app/%s/%s", titleid, rif_name);
else if (strcmp(content_type, "dlc") == 0)
snprintf(sfo_path, MAX_PATH_LENGTH, "ux0:license/addcont/%s/%s/%s", titleid, &contentid[20], rif_name);
if (checkFileExist(sfo_path))
snprintf(rif_path, MAX_PATH_LENGTH, "ux0:license/addcont/%s/%s/%s", titleid, &contentid[20], rif_name);
if (checkFileExist(rif_path))
return 0;

// Check if fixed rif file exits
_sceNpDrmGetFixedRifName(rif_name, 0, 0);
if (strcmp(content_type, "app") == 0)
snprintf(sfo_path, MAX_PATH_LENGTH, "ux0:license/app/%s/%s", titleid, rif_name);
snprintf(rif_path, MAX_PATH_LENGTH, "ux0:license/app/%s/%s", titleid, rif_name);
else if (strcmp(content_type, "dlc") == 0)
snprintf(sfo_path, MAX_PATH_LENGTH, "ux0:license/addcont/%s/%s/%s", titleid, &contentid[20], rif_name);
if (checkFileExist(sfo_path))
snprintf(rif_path, MAX_PATH_LENGTH, "ux0:license/addcont/%s/%s/%s", titleid, &contentid[20], rif_name);
if (checkFileExist(rif_path))
return 0;
}

if(strcmp(content_type,"psm") == 0)
return 0;
}

// Check if patch for installed app exists
else if (strcmp(content_type, "patch") == 0) {
if (!checkAppExist(titleid))
return 0;
if (checkFileExist(sfo_path)) {
void *sfo_buffer = NULL;
snprintf(appmeta_path, MAX_PATH_LENGTH, "ux0:appmeta/%s", titleid);
pfsUmount();
if(pfsMount(appmeta_path)<0)
Expand Down Expand Up @@ -326,6 +365,57 @@ void patch_callback(void* data, const char* dir, const char* subdir)
}
}

void psm_callback(void* data, const char* dir, const char* subdir)
{
refresh_data_t *refresh_data = (refresh_data_t*)data;
char path[MAX_PATH_LENGTH];

if (strcasecmp(subdir, vitashell_titleid) == 0)
return;

if (refresh_data->refresh_pass) {
snprintf(path, MAX_PATH_LENGTH, "%s/%s", dir, subdir);
if (refreshNeeded(path, "psm")) {
char contentid_path[MAX_PATH_LENGTH];
snprintf(contentid_path, MAX_PATH_LENGTH, "%s/RW/System/content_id", path);

char titleid[12];
void *cidFile = NULL;

// Initalize Bufer
memset(titleid,0,12);

// Get content id
allocateReadFile(contentid_path, &cidFile);

// Get title id from content id
strncpy(titleid,cidFile+7,9);

//free buffers
free(cidFile);


// Get promote path
char promote_path[MAX_PATH_LENGTH];
snprintf(promote_path,MAX_PATH_LENGTH,"%s/%s",PSM_TEMP,titleid);

// Move the directory to temp for installation
removePath(promote_path, NULL);
sceIoRename(path, promote_path);

// Finally call promote
if (promotePsm(PSM_TEMP,titleid) == 0)
refresh_data->refreshed++;
else
// Restore folder on error
sceIoRename(promote_path, path);
}
SetProgress(++refresh_data->processed, refresh_data->count);
} else {
refresh_data->count++;
}
}

int refresh_thread(SceSize args, void *argp)
{
SceUID thid = -1;
Expand All @@ -350,13 +440,18 @@ int refresh_thread(SceSize args, void *argp)
if (parse_dir_with_callback(SCE_S_IFDIR, "ux0:patch", patch_callback, &refresh_data) < 0)
goto EXIT;

// Get the psm count
if (parse_dir_with_callback(SCE_S_IFDIR, "ux0:psm", psm_callback, &refresh_data) < 0)
goto EXIT;

// Update thread
thid = createStartUpdateThread(refresh_data.count, 0);

// Make sure we have the temp directories we need
sceIoMkdir("ux0:temp", 0006);
sceIoMkdir("ux0:temp/addcont", 0006);
sceIoMkdir("ux0:temp/patch", 0006);
sceIoMkdir(DLC_TEMP, 0006);
sceIoMkdir(PATCH_TEMP, 0006);
sceIoMkdir(PSM_TEMP, 0006);
refresh_data.refresh_pass = 1;

// Refresh apps
Expand All @@ -371,8 +466,13 @@ int refresh_thread(SceSize args, void *argp)
if (parse_dir_with_callback(SCE_S_IFDIR, "ux0:patch", patch_callback, &refresh_data) < 0)
goto EXIT;

sceIoRmdir("ux0:temp/addcont");
sceIoRmdir("ux0:temp/patch");
// Refresh psm
if (parse_dir_with_callback(SCE_S_IFDIR, "ux0:psm", psm_callback, &refresh_data) < 0)
goto EXIT;

sceIoRmdir(DLC_TEMP);
sceIoRmdir(PATCH_TEMP);
sceIoRmdir(PSM_TEMP);

// Set progress to 100%
sceMsgDialogProgressBarSetValue(SCE_MSG_DIALOG_PROGRESSBAR_TARGET_BAR_DEFAULT, 100);
Expand Down

0 comments on commit ee7060c

Please sign in to comment.