Split FS/Threaded funcs, make restore check for empties before wiping, start working on extras (Only delete update works now)

This commit is contained in:
J-D-K 2021-07-28 22:23:08 -04:00
parent e445181e0c
commit 1e3e01a810
16 changed files with 560 additions and 439 deletions

View File

@ -9,9 +9,12 @@
#include <minizip/unzip.h>
#include "fsfile.h"
#include "fsthrd.h"
#include "data.h"
#include "miscui.h"
#define BUFF_SIZE 0xC0000
namespace fs
{
void init();
@ -20,6 +23,7 @@ namespace fs
//Mounts usr's save data for open. Returns false it fails
bool mountSave(const FsSaveDataInfo& _m);
inline bool unmountSave() { return fsdevUnmountDevice("sv") == 0; }
bool commitToDevice(const std::string& dev);
void copyFile(const std::string& from, const std::string& to);
void copyFileCommit(const std::string& from, const std::string& to, const std::string& dev);
@ -36,6 +40,10 @@ namespace fs
//Copies unzfile to 'to'
void copyZipToDir(unzFile unz, const std::string& to, const std::string& dev);
bool dirNotEmpty(const std::string& _dir);
bool zipNotEmpty(unzFile unzip);
void mkdirRec(const std::string& _p);
//deletes file
void delfile(const std::string& path);
//Recursively deletes 'path'
@ -127,12 +135,30 @@ namespace fs
bool opened = false;
};
//Structs to send data to threads
typedef struct
{
ui::menu *m;
fs::dirList *d;
} backupArgs;
typedef struct
{
std::string to, from, dev;
zipFile z;
unzFile unz;
bool cleanup = false;
uint64_t offset = 0, fileSize = 0;
ui::progBar *prog;
threadStatus *thrdStatus;
Mutex arglck = 0;
void argLock() { mutexLock(&arglck); }
void argUnlock() { mutexUnlock(&arglck); }
} copyArgs;
copyArgs *copyArgsCreate(const std::string& from, const std::string& to, const std::string& dev, zipFile z, unzFile unz, bool _cleanup);
void copyArgsDestroy(copyArgs *c);
//Take a pointer to backupArgs^
void createNewBackup(void *a);
void overwriteBackup(void *a);

14
inc/fsthrd.h Normal file
View File

@ -0,0 +1,14 @@
#pragma once
/*Threaded functions for copying files.
file.cpp has wrapper functions for these.
No need to call directly.*/
namespace fs
{
void _fileDrawFunc(void *a);
void copyfile_t(void *a);
void copyFileCommit_t(void *a);
void copyDirToZip_t(void *a);
void copyZipToDir_t(void *a);
void closeZip_t(void *a);
}

View File

@ -13,6 +13,7 @@
#include "ui/usr.h"
#include "ui/ttl.h"
#include "ui/sett.h"
#include "ui/ext.h"
#include "ui/fm.h"
#include "ui/ttlview.h"
#include "ui/thrdProc.h"

10
inc/ui/ext.h Normal file
View File

@ -0,0 +1,10 @@
#pragma once
namespace ui
{
extern ui::menu *extMenu;
void extInit();
void extExit();
void extUpdate();
void extDraw(SDL_Texture *target);
}

View File

@ -16,7 +16,7 @@ namespace ui
//Strings for extras menu
extern std::string exMenuStr[11];
//Strings for options menu
extern std::string optMenuStr[16];
extern std::string optMenuStr[17];
//Strings for the holding thing
extern std::string holdingText[3];
//Strings for sort type

View File

@ -93,6 +93,6 @@ namespace util
Result accountDeleteUser(AccountUid *uid);
void setCPU(uint32_t hz);
void checkForUpdate();
void checkForUpdate(void *a);
}
#endif // UTIL_H

View File

@ -3,11 +3,8 @@
#include <cstring>
#include <vector>
#include <switch.h>
#include <dirent.h>
#include <unistd.h>
#include <cstdarg>
#include <minizip/zip.h>
#include <minizip/unzip.h>
#include <sys/stat.h>
#include "file.h"
@ -16,8 +13,6 @@
#include "gfx.h"
#include "data.h"
#define BUFF_SIZE 0xC0000
static std::string wd;
static std::vector<std::string> pathFilter;
@ -26,21 +21,7 @@ static FSFILE *debLog;
static FsFileSystem sv;
typedef struct
{
std::string to, from, dev;
zipFile z;
unzFile unz;
bool cleanup = false;
uint64_t offset = 0, fileSize = 0;
ui::progBar *prog;
threadStatus *thrdStatus;
Mutex arglck = 0;
void argLock() { mutexLock(&arglck); }
void argUnlock() { mutexUnlock(&arglck); }
} copyArgs;
static copyArgs *copyArgsCreate(const std::string& from, const std::string& to, const std::string& dev, zipFile z, unzFile unz, bool _cleanup)
fs::copyArgs *fs::copyArgsCreate(const std::string& from, const std::string& to, const std::string& dev, zipFile z, unzFile unz, bool _cleanup)
{
copyArgs *ret = new copyArgs;
ret->to = to;
@ -55,7 +36,7 @@ static copyArgs *copyArgsCreate(const std::string& from, const std::string& to,
return ret;
}
static void copyArgsDestroy(copyArgs *c)
void fs::copyArgsDestroy(copyArgs *c)
{
delete c->prog;
delete c;
@ -80,7 +61,7 @@ static struct
}
} sortDirList;
static void mkdirRec(const std::string& _p)
void fs::mkdirRec(const std::string& _p)
{
//skip first slash
size_t pos = _p.find('/', 0) + 1;
@ -91,7 +72,7 @@ static void mkdirRec(const std::string& _p)
}
}
static inline bool commitToDevice(const std::string& dev)
bool fs::commitToDevice(const std::string& dev)
{
bool ret = true;
Result res = fsdevCommitDevice(dev.c_str());
@ -104,34 +85,6 @@ static inline bool commitToDevice(const std::string& dev)
return ret;
}
static uint64_t getJournalSize(const data::titleInfo *t)
{
uint64_t journalSize = 0;
switch(data::curData.saveInfo.save_data_type)
{
case FsSaveDataType_Account:
journalSize = t->nacp.user_account_save_data_journal_size;
break;
case FsSaveDataType_Device:
journalSize = t->nacp.device_save_data_journal_size;
break;
case FsSaveDataType_Bcat:
journalSize = t->nacp.bcat_delivery_cache_storage_size;
break;
case FsSaveDataType_Cache:
journalSize = t->nacp.cache_storage_journal_size;
break;
default:
journalSize = BUFF_SIZE;
break;
}
return journalSize;
}
void fs::init()
{
if(fs::fileExists("sdmc:/switch/jksv_dir.txt"))
@ -365,81 +318,7 @@ int fs::dataFile::getNextValueInt()
return ret;
}
//Todo: Weird flickering?
static void _fileDrawFunc(void *a)
{
threadInfo *t = (threadInfo *)a;
if(!t->finished)
{
copyArgs *c = (copyArgs *)t->argPtr;
std::string tmp;
t->status->getStatus(tmp);
c->argLock();
c->prog->draw(tmp);
c->argUnlock();
}
}
static void copyfile_t(void *a)
{
threadInfo *t = (threadInfo *)a;
copyArgs *args = (copyArgs *)t->argPtr;
t->status->setStatus("Copying '" + args->from + "'...");
uint8_t *buff = new uint8_t[BUFF_SIZE];
if(data::config["directFsCmd"])
{
FSFILE *in = fsfopen(args->from.c_str(), FsOpenMode_Read);
FSFILE *out = fsfopen(args->to.c_str(), FsOpenMode_Write);
if(!in || !out)
{
fsfclose(in);
fsfclose(out);
t->finished = true;
return;
}
size_t readIn = 0;
while((readIn = fsfread(buff, 1, BUFF_SIZE, in)) > 0)
{
fsfwrite(buff, 1, readIn, out);
args->argLock();
args->offset = in->offset;
args->prog->update(args->offset);
args->argUnlock();
}
fsfclose(in);
fsfclose(out);
}
else
{
FILE *in = fopen(args->from.c_str(), "rb");
FILE *out = fopen(args->to.c_str(), "wb");
if(!in || !out)
{
fclose(in);
fclose(out);
t->finished = true;
return;
}
size_t readIn = 0;
while((readIn = fread(buff, 1, BUFF_SIZE, in)) > 0)
{
fwrite(buff, 1, readIn, out);
args->argLock();
args->offset = ftell(in);
args->prog->update(args->offset);
args->argUnlock();
}
fclose(in);
fclose(out);
}
delete[] buff;
copyArgsDestroy(args);
t->finished = true;
}
//Wrapper functions to use functions from `fsthrd.cpp`
void fs::copyFile(const std::string& from, const std::string& to)
{
copyArgs *send = copyArgsCreate(from, to, "", NULL, NULL, false);
@ -448,93 +327,6 @@ void fs::copyFile(const std::string& from, const std::string& to)
ui::newThread(copyfile_t, send, _fileDrawFunc);
}
void copyFileCommit_t(void *a)
{
threadInfo *t = (threadInfo *)a;
copyArgs *args = (copyArgs *)t->argPtr;
data::titleInfo *info = data::getTitleInfoByTID(data::curData.saveID);
t->status->setStatus("Copying '" + args->from + "'...");
uint64_t journalSize = getJournalSize(info), writeCount = 0;
uint8_t *buff = new uint8_t[BUFF_SIZE];
if(data::config["directFsCmd"])
{
FSFILE *in = fsfopen(args->from.c_str(), FsOpenMode_Read);
FSFILE *out = fsfopen(args->to.c_str(), FsOpenMode_Write);
if(!in || !out)
{
fsfclose(in);
fsfclose(out);
t->finished = true;
return;
}
size_t readIn = 0;
while((readIn = fsfread(buff, 1, BUFF_SIZE, in)) > 0)
{
fsfwrite(buff, 1, readIn, out);
writeCount += readIn;
if(writeCount >= (journalSize - 0x100000))
{
writeCount = 0;
fsfclose(out);
if(!commitToDevice(args->dev))
break;
out = fsfopen(args->to.c_str(), FsOpenMode_Write | FsOpenMode_Append);
}
args->argLock();
args->offset = out->offset;
args->prog->update(args->offset);
args->argUnlock();
}
fsfclose(in);
fsfclose(out);
}
else
{
FILE *in = fopen(args->from.c_str(), "rb");
FILE *out = fopen(args->to.c_str(), "wb");
if(!in || !out)
{
fclose(in);
fclose(out);
t->finished = true;
return;
}
size_t readIn = 0;
while((readIn = fread(buff, 1, BUFF_SIZE, in)) > 0)
{
fwrite(buff, 1, readIn, out);
writeCount += readIn;
if(writeCount >= (journalSize - 0x100000))
{
writeCount = 0;
fclose(out);
if(!commitToDevice(args->dev))
break;
out = fopen(args->to.c_str(), "ab");
}
args->argLock();
args->offset = ftell(out);
args->prog->update(args->offset);
args->argUnlock();
}
fclose(in);
fclose(out);
}
delete[] buff;
commitToDevice(args->dev.c_str());
copyArgsDestroy(args);
t->finished = true;
}
void fs::copyFileCommit(const std::string& from, const std::string& to, const std::string& dev)
{
copyArgs *send = copyArgsCreate(from, to, dev, NULL, NULL, false);
@ -569,88 +361,6 @@ void fs::copyDirToDir(const std::string& from, const std::string& to)
}
}
void closeZip_t(void *a)
{
threadInfo *t = (threadInfo *)a;
zipFile z = t->argPtr;
zipClose(z, NULL);
t->finished = true;
}
void copyDirToZip_t(void *a)
{
threadInfo *t = (threadInfo *)a;
copyArgs *args = (copyArgs *)t->argPtr;
t->status->setStatus("Opening " + args->from + "...");
fs::dirList *list = new fs::dirList(args->from);
unsigned listTotal = list->getCount();
for(unsigned i = 0; i < listTotal; i++)
{
std::string itm = list->getItem(i);
if(fs::pathIsFiltered(args->from + itm))
continue;
if(list->isDir(i))
{
std::string newFrom = args->from + itm + "/";
//Fake thread and new args to point to src thread stuff
//This wouldn't work spawning a new thread.
threadInfo *tmpThread = new threadInfo;
tmpThread->status = t->status;
copyArgs *tmpArgs = new copyArgs;
tmpArgs->from = newFrom;
tmpArgs->prog = args->prog;
tmpArgs->z = args->z;
tmpArgs->cleanup = false;
tmpThread->argPtr = tmpArgs;
copyDirToZip_t(tmpThread);
delete tmpArgs;
delete tmpThread;
}
else
{
zip_fileinfo inf = {0};
std::string filename = args->from + itm;
size_t devPos = filename.find_first_of('/') + 1;
t->status->setStatus("Adding '" + itm + "' to ZIP.");
int zOpenFile = zipOpenNewFileInZip64(args->z, filename.substr(devPos, filename.length()).c_str(), &inf, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION, 0);
if(zOpenFile == ZIP_OK)
{
std::string fullFrom = args->from + itm;
args->offset = 0;
args->fileSize = fs::fsize(fullFrom);
args->prog->setMax(args->fileSize);
args->prog->update(0);
FILE *cpy = fopen(fullFrom.c_str(), "rb");
size_t readIn = 0;
uint8_t *buff = new uint8_t[BUFF_SIZE];
while((readIn = fread(buff, 1, BUFF_SIZE, cpy)) > 0)
{
zipWriteInFileInZip(args->z, buff, readIn);
args->offset += readIn;
args->prog->update(args->offset);
}
delete[] buff;
fclose(cpy);
zipCloseFileInZip(args->z);
}
}
}
delete list;
if(args->cleanup)
{
if(data::config["ovrClk"])
util::setCPU(1224000000);
ui::newThread(closeZip_t, args->z, NULL);
delete args->prog;
delete args;
}
t->finished = true;
}
void fs::copyDirToZip(const std::string& from, zipFile to)
{
if(data::config["ovrClk"])
@ -662,97 +372,6 @@ void fs::copyDirToZip(const std::string& from, zipFile to)
ui::newThread(copyDirToZip_t, send, _fileDrawFunc);
}
void copyZipToDir_t(void *a)
{
threadInfo *t = (threadInfo *)a;
copyArgs *args = (copyArgs *)t->argPtr;
data::titleInfo *tinfo = data::getTitleInfoByTID(data::curData.saveID);
uint64_t journalSize = getJournalSize(tinfo), writeCount = 0;
char filename[FS_MAX_PATH];
uint8_t *buff = new uint8_t[BUFF_SIZE];
int readIn = 0;
unz_file_info64 info;
if(unzGoToFirstFile(args->unz) == UNZ_OK)
{
do
{
unzGetCurrentFileInfo64(args->unz, &info, filename, FS_MAX_PATH, NULL, 0, NULL, 0);
if(unzOpenCurrentFile(args->unz) == UNZ_OK)
{
t->status->setStatus("Copying '" + std::string(filename) + "'...");
std::string path = args->to + filename;
mkdirRec(path.substr(0, path.find_last_of('/') + 1));
args->fileSize = info.uncompressed_size;
args->offset = 0.0f;
args->prog->setMax(args->fileSize);
size_t done = 0;
if(data::config["directFsCmd"])
{
FSFILE *out = fsfopen(path.c_str(), FsOpenMode_Write);
while((readIn = unzReadCurrentFile(args->unz, buff, BUFF_SIZE)) > 0)
{
done += readIn;
writeCount += readIn;
args->offset += readIn;
args->prog->update(args->offset);
fsfwrite(buff, 1, readIn, out);
if(writeCount >= (journalSize - 0x100000))
{
writeCount = 0;
fsfclose(out);
if(!commitToDevice(args->dev.c_str()))
break;
out = fsfopen(path.c_str(), FsOpenMode_Write | FsOpenMode_Append);
}
}
fsfclose(out);
}
else
{
FILE *out = fopen(path.c_str(), "wb");
while((readIn = unzReadCurrentFile(args->unz, buff, BUFF_SIZE)) > 0)
{
done += readIn;
writeCount += readIn;
args->offset += readIn;
args->prog->update(args->offset);
fwrite(buff, 1, readIn, out);
if(writeCount >= (journalSize - 0x100000))
{
writeCount = 0;
fclose(out);
if(!commitToDevice(args->dev.c_str()))
break;
out = fopen(path.c_str(), "ab");
}
}
fclose(out);
}
unzCloseCurrentFile(args->unz);
commitToDevice(args->dev.c_str());
}
}
while(unzGoToNextFile(args->unz) != UNZ_END_OF_LIST_OF_FILE);
}
else
ui::showPopMessage(POP_FRAME_DEFAULT, "ZIP file is empty!");
if(args->cleanup)
{
unzClose(args->unz);
copyArgsDestroy(args);
if(data::config["ovrClk"])
util::setCPU(1224000000);
}
delete[] buff;
t->finished = true;
}
void fs::copyZipToDir(unzFile unz, const std::string& to, const std::string& dev)
{
if(data::config["ovrClk"])
@ -764,6 +383,17 @@ void fs::copyZipToDir(unzFile unz, const std::string& to, const std::string& dev
ui::newThread(copyZipToDir_t, send, _fileDrawFunc);
}
bool fs::dirNotEmpty(const std::string& _dir)
{
fs::dirList tmp(_dir);
return tmp.getCount() > 0;
}
bool fs::zipNotEmpty(unzFile unzip)
{
return unzGoToFirstFile(unzip) == UNZ_OK;
}
void fs::copyDirToDirCommit(const std::string& from, const std::string& to, const std::string& dev)
{
dirList list(from);
@ -1088,16 +718,26 @@ void fs::restoreBackup(void *a)
if(d->isDir(ind))
{
fs::wipeSave();
std::string fromPath = util::generatePathByTID(data::curData.saveID) + itemName + "/";
fs::copyDirToDirCommit(fromPath, "sv:/", "sv");
if(fs::dirNotEmpty(fromPath))
{
fs::wipeSave();
fs::copyDirToDirCommit(fromPath, "sv:/", "sv");
}
else
ui::showPopMessage(POP_FRAME_DEFAULT, "Folder is empty!");
}
else if(!d->isDir(ind) && d->getItemExt(ind) == "zip")
{
fs::wipeSave();
std::string path = util::generatePathByTID(data::curData.saveID) + itemName;
unzFile unz = unzOpen64(path.c_str());
fs::copyZipToDir(unz, "sv:/", "sv");
if(unz && fs::zipNotEmpty(unz))
{
fs::wipeSave();
fs::copyZipToDir(unz, "sv:/", "sv");
}
else
ui::showPopMessage(POP_FRAME_DEFAULT, "ZIP is empty!");
}
else
{

359
src/fsthrd.cpp Normal file
View File

@ -0,0 +1,359 @@
#include <switch.h>
#include "file.h"
#include "util.h"
static uint64_t getJournalSize(const data::titleInfo *t)
{
uint64_t journalSize = 0;
switch(data::curData.saveInfo.save_data_type)
{
case FsSaveDataType_Account:
journalSize = t->nacp.user_account_save_data_journal_size;
break;
case FsSaveDataType_Device:
journalSize = t->nacp.device_save_data_journal_size;
break;
case FsSaveDataType_Bcat:
journalSize = t->nacp.bcat_delivery_cache_storage_size;
break;
case FsSaveDataType_Cache:
journalSize = t->nacp.cache_storage_journal_size;
break;
default:
journalSize = BUFF_SIZE;
break;
}
return journalSize;
}
//Todo: Weird flickering?
void fs::_fileDrawFunc(void *a)
{
threadInfo *t = (threadInfo *)a;
if(!t->finished)
{
copyArgs *c = (copyArgs *)t->argPtr;
std::string tmp;
t->status->getStatus(tmp);
c->argLock();
c->prog->draw(tmp);
c->argUnlock();
}
}
void fs::copyfile_t(void *a)
{
threadInfo *t = (threadInfo *)a;
copyArgs *args = (copyArgs *)t->argPtr;
t->status->setStatus("Copying '" + args->from + "'...");
uint8_t *buff = new uint8_t[BUFF_SIZE];
if(data::config["directFsCmd"])
{
FSFILE *in = fsfopen(args->from.c_str(), FsOpenMode_Read);
FSFILE *out = fsfopen(args->to.c_str(), FsOpenMode_Write);
if(!in || !out)
{
fsfclose(in);
fsfclose(out);
t->finished = true;
return;
}
size_t readIn = 0;
while((readIn = fsfread(buff, 1, BUFF_SIZE, in)) > 0)
{
fsfwrite(buff, 1, readIn, out);
args->argLock();
args->offset = in->offset;
args->prog->update(args->offset);
args->argUnlock();
}
fsfclose(in);
fsfclose(out);
}
else
{
FILE *in = fopen(args->from.c_str(), "rb");
FILE *out = fopen(args->to.c_str(), "wb");
if(!in || !out)
{
fclose(in);
fclose(out);
t->finished = true;
return;
}
size_t readIn = 0;
while((readIn = fread(buff, 1, BUFF_SIZE, in)) > 0)
{
fwrite(buff, 1, readIn, out);
args->argLock();
args->offset = ftell(in);
args->prog->update(args->offset);
args->argUnlock();
}
fclose(in);
fclose(out);
}
delete[] buff;
copyArgsDestroy(args);
t->finished = true;
}
void fs::copyFileCommit_t(void *a)
{
threadInfo *t = (threadInfo *)a;
copyArgs *args = (copyArgs *)t->argPtr;
data::titleInfo *info = data::getTitleInfoByTID(data::curData.saveID);
t->status->setStatus("Copying '" + args->from + "'...");
uint64_t journalSize = getJournalSize(info), writeCount = 0;
uint8_t *buff = new uint8_t[BUFF_SIZE];
if(data::config["directFsCmd"])
{
FSFILE *in = fsfopen(args->from.c_str(), FsOpenMode_Read);
FSFILE *out = fsfopen(args->to.c_str(), FsOpenMode_Write);
if(!in || !out)
{
fsfclose(in);
fsfclose(out);
t->finished = true;
return;
}
size_t readIn = 0;
while((readIn = fsfread(buff, 1, BUFF_SIZE, in)) > 0)
{
fsfwrite(buff, 1, readIn, out);
writeCount += readIn;
if(writeCount >= (journalSize - 0x100000))
{
writeCount = 0;
fsfclose(out);
if(!commitToDevice(args->dev))
break;
out = fsfopen(args->to.c_str(), FsOpenMode_Write | FsOpenMode_Append);
}
args->argLock();
args->offset = out->offset;
args->prog->update(args->offset);
args->argUnlock();
}
fsfclose(in);
fsfclose(out);
}
else
{
FILE *in = fopen(args->from.c_str(), "rb");
FILE *out = fopen(args->to.c_str(), "wb");
if(!in || !out)
{
fclose(in);
fclose(out);
t->finished = true;
return;
}
size_t readIn = 0;
while((readIn = fread(buff, 1, BUFF_SIZE, in)) > 0)
{
fwrite(buff, 1, readIn, out);
writeCount += readIn;
if(writeCount >= (journalSize - 0x100000))
{
writeCount = 0;
fclose(out);
if(!commitToDevice(args->dev))
break;
out = fopen(args->to.c_str(), "ab");
}
args->argLock();
args->offset = ftell(out);
args->prog->update(args->offset);
args->argUnlock();
}
fclose(in);
fclose(out);
}
delete[] buff;
commitToDevice(args->dev.c_str());
copyArgsDestroy(args);
t->finished = true;
}
void fs::copyDirToZip_t(void *a)
{
threadInfo *t = (threadInfo *)a;
copyArgs *args = (copyArgs *)t->argPtr;
t->status->setStatus("Opening " + args->from + "...");
fs::dirList *list = new fs::dirList(args->from);
unsigned listTotal = list->getCount();
for(unsigned i = 0; i < listTotal; i++)
{
std::string itm = list->getItem(i);
if(fs::pathIsFiltered(args->from + itm))
continue;
if(list->isDir(i))
{
std::string newFrom = args->from + itm + "/";
//Fake thread and new args to point to src thread stuff
//This wouldn't work spawning a new thread.
threadInfo tmpThread;
tmpThread.status = t->status;
copyArgs tmpArgs;
tmpArgs.from = newFrom;
tmpArgs.prog = args->prog;
tmpArgs.z = args->z;
tmpArgs.cleanup = false;
tmpThread.argPtr = &tmpArgs;
copyDirToZip_t(&tmpThread);
}
else
{
zip_fileinfo inf = {0};
std::string filename = args->from + itm;
size_t devPos = filename.find_first_of('/') + 1;
t->status->setStatus("Adding '" + itm + "' to ZIP.");
int zOpenFile = zipOpenNewFileInZip64(args->z, filename.substr(devPos, filename.length()).c_str(), &inf, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION, 0);
if(zOpenFile == ZIP_OK)
{
std::string fullFrom = args->from + itm;
args->offset = 0;
args->fileSize = fs::fsize(fullFrom);
args->prog->setMax(args->fileSize);
args->prog->update(0);
FILE *cpy = fopen(fullFrom.c_str(), "rb");
size_t readIn = 0;
uint8_t *buff = new uint8_t[BUFF_SIZE];
while((readIn = fread(buff, 1, BUFF_SIZE, cpy)) > 0)
{
zipWriteInFileInZip(args->z, buff, readIn);
args->offset += readIn;
args->prog->update(args->offset);
}
delete[] buff;
fclose(cpy);
zipCloseFileInZip(args->z);
}
}
}
delete list;
if(args->cleanup)
{
if(data::config["ovrClk"])
util::setCPU(1224000000);
ui::newThread(closeZip_t, args->z, NULL);
delete args->prog;
delete args;
}
t->finished = true;
}
void fs::closeZip_t(void *a)
{
threadInfo *t = (threadInfo *)a;
zipFile z = t->argPtr;
zipClose(z, NULL);
t->finished = true;
}
void fs::copyZipToDir_t(void *a)
{
threadInfo *t = (threadInfo *)a;
copyArgs *args = (copyArgs *)t->argPtr;
data::titleInfo *tinfo = data::getTitleInfoByTID(data::curData.saveID);
uint64_t journalSize = getJournalSize(tinfo), writeCount = 0;
char filename[FS_MAX_PATH];
uint8_t *buff = new uint8_t[BUFF_SIZE];
int readIn = 0;
unz_file_info64 info;
do
{
unzGetCurrentFileInfo64(args->unz, &info, filename, FS_MAX_PATH, NULL, 0, NULL, 0);
if(unzOpenCurrentFile(args->unz) == UNZ_OK)
{
t->status->setStatus("Copying '" + std::string(filename) + "'...");
std::string path = args->to + filename;
mkdirRec(path.substr(0, path.find_last_of('/') + 1));
args->fileSize = info.uncompressed_size;
args->offset = 0.0f;
args->prog->setMax(args->fileSize);
size_t done = 0;
if(data::config["directFsCmd"])
{
FSFILE *out = fsfopen(path.c_str(), FsOpenMode_Write);
while((readIn = unzReadCurrentFile(args->unz, buff, BUFF_SIZE)) > 0)
{
done += readIn;
writeCount += readIn;
args->offset += readIn;
args->prog->update(args->offset);
fsfwrite(buff, 1, readIn, out);
if(writeCount >= (journalSize - 0x100000))
{
writeCount = 0;
fsfclose(out);
if(!commitToDevice(args->dev.c_str()))
break;
out = fsfopen(path.c_str(), FsOpenMode_Write | FsOpenMode_Append);
}
}
fsfclose(out);
}
else
{
FILE *out = fopen(path.c_str(), "wb");
while((readIn = unzReadCurrentFile(args->unz, buff, BUFF_SIZE)) > 0)
{
done += readIn;
writeCount += readIn;
args->offset += readIn;
args->prog->update(args->offset);
fwrite(buff, 1, readIn, out);
if(writeCount >= (journalSize - 0x100000))
{
writeCount = 0;
fclose(out);
if(!commitToDevice(args->dev.c_str()))
break;
out = fopen(path.c_str(), "ab");
}
}
fclose(out);
}
unzCloseCurrentFile(args->unz);
commitToDevice(args->dev.c_str());
}
}
while(unzGoToNextFile(args->unz) != UNZ_END_OF_LIST_OF_FILE);
if(args->cleanup)
{
unzClose(args->unz);
copyArgsDestroy(args);
if(data::config["ovrClk"])
util::setCPU(1224000000);
}
delete[] buff;
t->finished = true;
}

View File

@ -162,6 +162,7 @@ void ui::init()
ui::usrInit();
ui::ttlInit();
ui::settInit();
ui::extInit();
popMessages = new ui::popMessageMngr;
threadMngr = new ui::threadProcMngr;
@ -176,6 +177,7 @@ void ui::exit()
ui::usrExit();
ui::ttlExit();
ui::settExit();
ui::extExit();
delete popMessages;
delete threadMngr;
@ -241,7 +243,7 @@ void ui::drawUI()
if(ui::usrMenu->getSelected() == settPos || ui::mstate == OPT_MNU)
ui::settDraw(rightPanel);
else if(usrMenu->getSelected() == extPos || ui::mstate == EX_MNU)
gfx::drawTextf(rightPanel, 24, 32, 32, &ui::txtCont, "PLACE HOLDER");
ui::extDraw(rightPanel);
else
ui::ttlDraw(rightPanel);
@ -273,25 +275,19 @@ bool ui::runApp()
switch(ui::mstate)
{
case USR_SEL:
usrUpdate();
ui::usrUpdate();
break;
case TTL_SEL:
ttlUpdate();
ui::ttlUpdate();
break;
case OPT_MNU:
settUpdate();
ui::settUpdate();
break;
case EX_MNU:
/*extMenu.update();
if(down & HidNpadButton_B)
{
ui::changeState(USR_SEL);
mainMenu.setActive(true);
extMenu.setActive(false);
}*/
ui::extUpdate();
break;
}
}

64
src/ui/ext.cpp Normal file
View File

@ -0,0 +1,64 @@
#include <switch.h>
#include <SDL.h>
#include "ui.h"
#include "file.h"
ui::menu *ui::extMenu;
static void extMenuCallback(void *a)
{
switch(ui::padKeysDown())
{
case HidNpadButton_B:
ui::extMenu->setActive(false);
ui::usrMenu->setActive(true);
ui::changeState(USR_SEL);
break;
}
}
static void _delUpdate(void *a)
{
threadInfo *t = (threadInfo *)a;
t->status->setStatus("Deleting update from NAND...");
FsFileSystem sys;
fsOpenBisFileSystem(&sys, FsBisPartitionId_System, "");
fsdevMountDevice("sys", sys);
fs::delDir("sys:/Contents/placehld/");
fsdevUnmountDevice("sys");
t->finished = true;
}
static void extMenuOptRemoveUpdate(void *a)
{
ui::newThread(_delUpdate, NULL, NULL);
}
void ui::extInit()
{
ui::extMenu = new ui::menu;
ui::extMenu->setParams(32, 32, 1016, 24, 5);
ui::extMenu->setCallback(extMenuCallback, NULL);
ui::extMenu->setActive(false);
for(unsigned i = 0; i < 11; i++)
ui::extMenu->addOpt(NULL, ui::exMenuStr[i]);
//Del update
ui::extMenu->optAddButtonEvent(5, HidNpadButton_A, extMenuOptRemoveUpdate, NULL);
}
void ui::extExit()
{
delete ui::extMenu;
}
void ui::extUpdate()
{
ui::extMenu->update();
}
void ui::extDraw(SDL_Texture *target)
{
ui::extMenu->draw(target, &ui::txtCont, true);
}

View File

@ -230,7 +230,6 @@ void ui::menu::draw(SDL_Texture *target, const SDL_Color *textClr, bool drawText
gfx::texDrawStretch(target, opt[i].icn, x + 20, (y + (rH / 2 - fSize / 2)) + (i * rH), dW, dH);
}
}
}

View File

@ -4,6 +4,7 @@
#include "ui.h"
#include "file.h"
#include "sett.h"
#include "util.h"
ui::menu *ui::settMenu;
@ -50,65 +51,69 @@ static void toggleOpt(void *a)
break;
case 1:
toggleBool(data::config["incDev"]);
ui::newThread(util::checkForUpdate, NULL, NULL);
break;
case 2:
toggleBool(data::config["autoBack"]);
toggleBool(data::config["incDev"]);
break;
case 3:
toggleBool(data::config["ovrClk"]);
toggleBool(data::config["autoBack"]);
break;
case 4:
toggleBool(data::config["holdDel"]);
toggleBool(data::config["ovrClk"]);
break;
case 5:
toggleBool(data::config["holdRest"]);
toggleBool(data::config["holdDel"]);
break;
case 6:
toggleBool(data::config["holdOver"]);
toggleBool(data::config["holdRest"]);
break;
case 7:
toggleBool(data::config["forceMount"]);
toggleBool(data::config["holdOver"]);
break;
case 8:
toggleBool(data::config["accSysSave"]);
toggleBool(data::config["forceMount"]);
break;
case 9:
toggleBool(data::config["sysSaveWrite"]);
toggleBool(data::config["accSysSave"]);
break;
case 10:
toggleBool(data::config["directFsCmd"]);
toggleBool(data::config["sysSaveWrite"]);
break;
case 11:
toggleBool(data::config["zip"]);
toggleBool(data::config["directFsCmd"]);
break;
case 12:
toggleBool(data::config["langOverride"]);
toggleBool(data::config["zip"]);
break;
case 13:
toggleBool(data::config["trashBin"]);
toggleBool(data::config["langOverride"]);
break;
case 14:
toggleBool(data::config["trashBin"]);
break;
case 15:
if(++data::sortType > 2)
data::sortType = 0;
data::loadUsersTitles(false);
ui::refreshAllViews();
break;
case 15:
case 16:
ui::animScale += 0.5f;
if(ui::animScale > 8)
ui::animScale = 1;
@ -118,24 +123,24 @@ static void toggleOpt(void *a)
static void updateMenuText()
{
ui::settMenu->editOpt(1, NULL, ui::optMenuStr[1] + getBoolText(data::config["incDev"]));
ui::settMenu->editOpt(2, NULL, ui::optMenuStr[2] + getBoolText(data::config["autoBack"]));
ui::settMenu->editOpt(3, NULL, ui::optMenuStr[3] + getBoolText(data::config["ovrClk"]));
ui::settMenu->editOpt(4, NULL, ui::optMenuStr[4] + getBoolText(data::config["holdDel"]));
ui::settMenu->editOpt(5, NULL, ui::optMenuStr[5] + getBoolText(data::config["holdRest"]));
ui::settMenu->editOpt(6, NULL, ui::optMenuStr[6] + getBoolText(data::config["holdOver"]));
ui::settMenu->editOpt(7, NULL, ui::optMenuStr[7] + getBoolText(data::config["forceMount"]));
ui::settMenu->editOpt(8, NULL, ui::optMenuStr[8] + getBoolText(data::config["accSysSave"]));
ui::settMenu->editOpt(9, NULL, ui::optMenuStr[9] + getBoolText(data::config["sysSaveWrite"]));
ui::settMenu->editOpt(10, NULL, ui::optMenuStr[10] + getBoolText(data::config["directFsCmd"]));
ui::settMenu->editOpt(11, NULL, ui::optMenuStr[11] + getBoolText(data::config["zip"]));
ui::settMenu->editOpt(12, NULL, ui::optMenuStr[12] + getBoolText(data::config["langOverride"]));
ui::settMenu->editOpt(13, NULL, ui::optMenuStr[13] + getBoolText(data::config["trashBin"]));
ui::settMenu->editOpt(14, NULL, ui::optMenuStr[14] + ui::sortString[data::sortType]);
ui::settMenu->editOpt(2, NULL, ui::optMenuStr[2] + getBoolText(data::config["incDev"]));
ui::settMenu->editOpt(3, NULL, ui::optMenuStr[3] + getBoolText(data::config["autoBack"]));
ui::settMenu->editOpt(4, NULL, ui::optMenuStr[4] + getBoolText(data::config["ovrClk"]));
ui::settMenu->editOpt(5, NULL, ui::optMenuStr[5] + getBoolText(data::config["holdDel"]));
ui::settMenu->editOpt(6, NULL, ui::optMenuStr[6] + getBoolText(data::config["holdRest"]));
ui::settMenu->editOpt(7, NULL, ui::optMenuStr[7] + getBoolText(data::config["holdOver"]));
ui::settMenu->editOpt(8, NULL, ui::optMenuStr[8] + getBoolText(data::config["forceMount"]));
ui::settMenu->editOpt(9, NULL, ui::optMenuStr[9] + getBoolText(data::config["accSysSave"]));
ui::settMenu->editOpt(10, NULL, ui::optMenuStr[10] + getBoolText(data::config["sysSaveWrite"]));
ui::settMenu->editOpt(11, NULL, ui::optMenuStr[11] + getBoolText(data::config["directFsCmd"]));
ui::settMenu->editOpt(12, NULL, ui::optMenuStr[12] + getBoolText(data::config["zip"]));
ui::settMenu->editOpt(13, NULL, ui::optMenuStr[13] + getBoolText(data::config["langOverride"]));
ui::settMenu->editOpt(14, NULL, ui::optMenuStr[14] + getBoolText(data::config["trashBin"]));
ui::settMenu->editOpt(15, NULL, ui::optMenuStr[15] + ui::sortString[data::sortType]);
char tmp[16];
sprintf(tmp, "%.1f", ui::animScale);
ui::settMenu->editOpt(15, NULL, ui::optMenuStr[15] + std::string(tmp));
ui::settMenu->editOpt(16, NULL, ui::optMenuStr[16] + std::string(tmp));
}
void ui::settInit()
@ -147,7 +152,7 @@ void ui::settInit()
optHelpX = 1220 - gfx::getTextWidth(ui::optHelp.c_str(), 18);
for(unsigned i = 0; i < 16; i++)
for(unsigned i = 0; i < 17; i++)
{
ui::settMenu->addOpt(NULL, ui::optMenuStr[i]);
ui::settMenu->optAddButtonEvent(i, HidNpadButton_A, toggleOpt, NULL);

View File

@ -5,7 +5,7 @@
#include "file.h"
#include "util.h"
int ttlHelpX = 0, fldHelpWidth = 0;
static int ttlHelpX = 0, fldHelpWidth = 0;
static std::vector<ui::titleview *> ttlViews;
static ui::menu *ttlOpts, *fldMenu;
static ui::slideOutPanel *ttlOptsPanel, *infoPanel, *fldPanel;//There's no reason to have a separate folder section
@ -344,7 +344,7 @@ void ui::ttlInit()
ttlOpts->setActive(false);
fldMenu = new ui::menu;
fldMenu->setParams(10, 32, fldHelpWidth + 44, 20, 6);
fldMenu->setParams(10, 32, fldHelpWidth + 44, 20, 7);
fldMenu->setCallback(fldMenuCallback, NULL);
fldMenu->setActive(false);

View File

@ -41,7 +41,7 @@ std::string ui::errorConnecting = "Error Connecting!";
std::string ui::noUpdate = "No updates available!";
std::string ui::advMenuStr[6] = { "Copy to ", "Delete", "Rename", "Make Dir", "Properties", "Close" };
std::string ui::exMenuStr[11] = { "SD to SD Browser", "BIS: PRODINFOF", "BIS: SAFE", "BIS: SYSTEM", "BIS: USER", "Remove Update", "Terminate Process", "Mount System Save", "Rescan Titles", "Mount Process RomFS", "Backup JKSV Folder" };
std::string ui::optMenuStr[16] = { "Empty Trash Bin", "Include Device Saves: ", "AutoBackup: ", "Overclock: ", "Hold to Delete: ", "Hold to Restore: ", "Hold to Overwrite: ", "Force Mount: ", "Account Sys. Saves: ", "Write to Sys. Saves: ", "Direct FS Cmd: ", "Export to ZIP: ", "Language Override: ", "Enable Trash Bin: ", "Sort: ", "Animation Scale: "};
std::string ui::optMenuStr[17] = { "Empty Trash Bin", "Check for Update", "Include Device Saves: ", "AutoBackup: ", "Overclock: ", "Hold to Delete: ", "Hold to Restore: ", "Hold to Overwrite: ", "Force Mount: ", "Account Sys. Saves: ", "Write to Sys. Saves: ", "Direct FS Cmd: ", "Export to ZIP: ", "Language Override: ", "Enable Trash Bin: ", "Sort: ", "Animation Scale: "};
std::string ui::holdingText[3] = { "(Hold) ", "(Keep Holding) ", "(Almost there!) " };
std::string ui::sortString[3] = { "Alphabetical", "Time Played", "Last Played" };
std::string ui::usrOptString[2] = { "Create Save Data", "Delete All User Saves" };

View File

@ -53,6 +53,7 @@ static void toEXT(void *a)
{
ui::changeState(EX_MNU);
ui::usrMenu->setActive(false);
ui::extMenu->setActive(true);
}
static void usrOptCallback(void *a)
@ -331,7 +332,7 @@ void ui::usrInit()
ext = util::createIconGeneric("Extras", 40);
pos = usrMenu->addOpt(ext, "Extras");
usrMenu->optAddButtonEvent(pos, HidNpadButton_A, NULL, NULL);
usrMenu->optAddButtonEvent(pos, HidNpadButton_A, toEXT, NULL);
usrMenu->setOnChangeFunc(onMainChange);
usrMenu->editParam(MENU_RECT_WIDTH, 126);

View File

@ -10,6 +10,7 @@
#include "util.h"
#include "ui.h"
#include "curlfuncs.h"
#include "type.h"
static const char verboten[] = { ',', '/', '\\', '<', '>', ':', '"', '|', '?', '*', '', '©', '®'};
@ -343,12 +344,15 @@ void util::setCPU(uint32_t hz)
clkrstExit();
}
void util::checkForUpdate()
void util::checkForUpdate(void *a)
{
threadInfo *t = (threadInfo *)a;
t->status->setStatus("Checking for Updates...");
std::string gitJson = getJSONURL(NULL, "https://api.github.com/repos/J-D-K/JKSV/releases/latest");
if(gitJson.empty())
{
ui::showPopMessage(POP_FRAME_DEFAULT, ui::errorConnecting.c_str());
t->finished = true;
return;
}
@ -361,6 +365,7 @@ void util::checkForUpdate()
//This can throw false positives as is. need to fix sometime
if(year > BLD_YEAR || month > BLD_MON || month > BLD_DAY)
{
t->status->setStatus("Downloading Update...");
//dunno about NSP yet...
json_object *assets, *asset0, *dlUrl;
json_object_object_get_ex(jobj, "assets", &assets);
@ -378,6 +383,7 @@ void util::checkForUpdate()
ui::showPopMessage(POP_FRAME_DEFAULT, ui::noUpdate.c_str());
json_object_put(jobj);
t->finished = true;
}
Result util::accountDeleteUser(AccountUid *uid)