Minor code revisions in preparation for cache system on 20.0+

This commit is contained in:
J-D-K 2025-05-28 18:33:58 -04:00
parent 291d2fd82f
commit c094030c52
19 changed files with 1599 additions and 959 deletions

136
.clang-format Normal file
View File

@ -0,0 +1,136 @@
---
Language: Cpp
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveMacros: false
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Right
AlignOperands: true
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: false
AllowAllConstructorInitializersOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: false
BinPackParameters: false
BraceWrapping:
AfterCaseLabel: true
AfterClass: true
AfterControlStatement: true
AfterEnum: true
AfterFunction: true
AfterNamespace: true
AfterObjCDeclaration: true
AfterStruct: true
AfterUnion: true
AfterExternBlock: true
BeforeCatch: true
BeforeElse: true
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 120
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DeriveLineEnding: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
SortPriority: 0
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
SortPriority: 0
- Regex: '.*'
Priority: 1
SortPriority: 0
IncludeIsMainRegex: '(Test)?$'
IncludeIsMainSourceRegex: ''
IndentAccessModifiers: true
IndentCaseLabels: true
IndentGotoLabels: true
IndentPPDirectives: None
IndentWidth: 4
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 2
NamespaceIndentation: All
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 1000
PointerAlignment: Right
ReflowComments: false
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInConditionalStatement: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false
Standard: Latest
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 4
UseCRLF: false
UseTab: Never
...

9
.clang-tidy Normal file
View File

@ -0,0 +1,9 @@
---
Checks: 'clang-analyzer-*,cppcoreguidelines-*,modernize-*,bugprone-*,performance-*,readability-*,readability-non-const-parameter,misc-const-correctness,misc-use-anonymous-namespace,google-explicit-constructor,-modernize-use-trailing-return-type,-bugprone-exception-escape,-cppcoreguidelines-pro-bounds-constant-array-index,-cppcoreguidelines-avoid-magic-numbers,-bugprone-easily-swappable-parameters,-cppcoreguidelines-non-private-member-variables-in-classes'
WarningsAsErrors: ''
HeaderFilterRegex: ''
CheckOptions:
- key: readability-magic-numbers.IgnoredFloatingPointValues
value: '0.0;1.0;100.0;'
- key: readability-magic-numbers.IgnoredIntegerValues
value: '0;1;2;3;4;5;6;7;8;9;'

11
.gitattributes vendored Normal file
View File

@ -0,0 +1,11 @@
# Set the default behavior for all files.
* text=auto eol=lf
# Normalized and converts to native line endings on checkout.
*.c text
*.cc text
*.cxx
*.cpp text
*.h text
*.hxx text
*.hpp text

1
.gitignore vendored
View File

@ -2,6 +2,7 @@ build/
.vscode/
*.cbp
*.layout
.editorconfig
.idea/
cmake-build-debug/

View File

@ -1,8 +1,9 @@
#pragma once
#include <cstdint>
#include <string>
#include <vector>
#include <unordered_map>
#include <vector>
namespace cfg
{
@ -17,18 +18,18 @@ namespace cfg
void loadConfig();
void saveConfig();
bool isBlacklisted(const uint64_t& tid);
bool isBlacklisted(uint64_t tid);
void addTitleToBlacklist(void *a);
void removeTitleFromBlacklist(const uint64_t& tid);
void removeTitleFromBlacklist(uint64_t tid);
bool isFavorite(const uint64_t& tid);
void addTitleToFavorites(const uint64_t& tid);
bool isFavorite(uint64_t tid);
void addTitleToFavorites(uint64_t tid);
bool isDefined(const uint64_t& tid);
void pathDefAdd(const uint64_t& tid, const std::string& newPath);
std::string getPathDefinition(const uint64_t& tid);
bool isDefined(uint64_t tid);
void pathDefAdd(uint64_t tid, const std::string &newPath);
std::string getPathDefinition(uint64_t tid);
void addPathToFilter(const uint64_t& tid, const std::string& _p);
void addPathToFilter(uint64_t tid, const std::string &_p);
extern std::unordered_map<std::string, bool> config;
extern std::vector<uint64_t> blacklist;
@ -36,4 +37,4 @@ namespace cfg
extern uint8_t sortType;
extern std::string driveClientID, driveClientSecret, driveRefreshToken;
extern std::string webdavOrigin, webdavBasePath, webdavUser, webdavPassword;
}
} // namespace cfg

View File

@ -1,15 +1,15 @@
#pragma once
#include <switch.h>
#include <vector>
#include <string>
#include <unordered_map>
#include <vector>
#include "gfx.h"
#define BLD_MON 11
#define BLD_DAY 5
#define BLD_YEAR 2024
#define BLD_MON 5
#define BLD_DAY 28
#define BLD_YEAR 2025
namespace data
{
@ -25,8 +25,13 @@ namespace data
// Global stuff for all titles/saves
typedef struct
{
NacpStruct nacp;
std::string title, safeTitle, author;//Shortcuts sorta.
/// @brief Control data.
NsApplicationControlData data;
/// @brief Saves whether or not the title has valid control data.
bool hasControlData = false;
std::string title, safeTitle, author;
SDL_Texture *icon = NULL;
bool fav;
} titleInfo;
@ -45,28 +50,51 @@ namespace data
{
public:
user() = default;
user(const AccountUid& _id, const std::string& _backupName, const std::string& _safeBackupName);
user(const AccountUid& _id, const std::string& _backupName, const std::string& _safeBackupName, SDL_Texture *img);
user(AccountUid _id, const std::string &_backupName, const std::string &_safeBackupName);
user(AccountUid _id, const std::string &_backupName, const std::string &_safeBackupName, SDL_Texture *img);
// Sets ID
void setUID(const AccountUid& _id);
void setUID(AccountUid _id);
// Assigns icon
void assignIcon(SDL_Texture *_icn) { userIcon = _icn; }
void assignIcon(SDL_Texture *_icn)
{
userIcon = _icn;
}
// Returns user ID
AccountUid getUID() const { return userID; }
u128 getUID128() const { return uID128; }
AccountUid getUID() const
{
return userID;
}
u128 getUID128() const
{
return uID128;
}
// Returns username
std::string getUsername() const { return username; }
std::string getUsernameSafe() const { return userSafe; }
std::string getUsername() const
{
return username;
}
std::string getUsernameSafe() const
{
return userSafe;
}
SDL_Texture *getUserIcon(){ return userIcon; }
void delIcon(){ SDL_DestroyTexture(userIcon); }
SDL_Texture *getUserIcon()
{
return userIcon;
}
void delIcon()
{
SDL_DestroyTexture(userIcon);
}
std::vector<data::userTitleInfo> titleInfo;
void addUserTitleInfo(const uint64_t& _tid, const FsSaveDataInfo *_saveInfo, const PdmPlayStatistics *_stats);
void addUserTitleInfo(const uint64_t &_tid,
const FsSaveDataInfo *_saveInfo,
const PdmPlayStatistics *_stats);
private:
AccountUid userID;
@ -100,4 +128,4 @@ namespace data
int getTitleIndexInUser(const data::user &u, const uint64_t &tid);
extern SetLanguage sysLang;
}
} // namespace data

View File

@ -1,14 +1,14 @@
#pragma once
#include <minizip/zip.h>
#include <minizip/unzip.h>
#include <minizip/zip.h>
#include "fs/fstype.h"
#include "fs/file.h"
#include "fs/dir.h"
#include "fs/zip.h"
#include "fs/file.h"
#include "fs/fsfile.h"
#include "fs/fstype.h"
#include "fs/remote.h"
#include "fs/zip.h"
#include "ui/miscui.h"
#define BUFF_SIZE 0x4000
@ -17,18 +17,28 @@
namespace fs
{
copyArgs *copyArgsCreate(const std::string& src, const std::string& dst, const std::string& dev, zipFile z, unzFile unz, bool _cleanup, bool _trimZipPath, uint8_t _trimPlaces);
copyArgs *copyArgsCreate(const std::string &src,
const std::string &dst,
const std::string &dev,
zipFile z,
unzFile unz,
bool _cleanup,
bool _trimZipPath,
uint8_t _trimPlaces);
void copyArgsDestroy(copyArgs *c);
void init();
bool mountSave(const FsSaveDataInfo &_m);
inline bool unmountSave() { return fsdevUnmountDevice("sv") == 0; }
inline bool unmountSave()
{
return fsdevUnmountDevice("sv") == 0;
}
bool commitToDevice(const std::string &dev);
std::string getWorkDir();
void setWorkDir(const std::string &_w);
//Loads paths to filter from backup/deletion
void loadPathFilters(const uint64_t& tid);
void loadPathFilters(uint64_t tid);
bool pathIsFiltered(const std::string &_path);
void freePathFilters();
@ -52,4 +62,4 @@ namespace fs
void logOpen();
void logWrite(const char *fmt, ...);
}
} // namespace fs

View File

@ -1,7 +1,8 @@
#pragma once
#include <string>
#include "type.h"
#include <string>
#include <vector>
namespace fs
{
@ -22,10 +23,19 @@ namespace fs
{
public:
dirItem(const std::string &pathTo, const std::string &sItem);
std::string getItm() const { return itm; }
std::string getItm() const
{
return itm;
}
std::string getName() const;
std::string getExt() const;
bool isDir() const { return dir; }
bool isDir() const
{
return dir;
}
private:
std::string itm;
@ -41,14 +51,33 @@ namespace fs
void reassign(const std::string &_path);
void rescan();
std::string getItem(int index) const { return item[index].getItm(); }
std::string getItemExt(int index) const { return item[index].getExt(); }
bool isDir(int index) const { return item[index].isDir(); }
unsigned getCount() const { return item.size(); }
fs::dirItem *getDirItemAt(unsigned int _ind) { return &item[_ind]; }
std::string getItem(int index) const
{
return item[index].getItm();
}
std::string getItemExt(int index) const
{
return item[index].getExt();
}
bool isDir(int index) const
{
return item[index].isDir();
}
unsigned getCount() const
{
return item.size();
}
fs::dirItem *getDirItemAt(unsigned int _ind)
{
return &item[_ind];
}
private:
std::string path;
std::vector<dirItem> item;
};
}
} // namespace fs

View File

@ -4,7 +4,7 @@ namespace ui
{
void fmInit();
void fmExit();
void fmPrep(const FsSaveDataType& _type, const std::string& _dev, const std::string& _baseSDMC, bool _commit);
void fmPrep(FsSaveDataType _type, const std::string &_dev, const std::string &_baseSDMC, bool _commit);
void fmUpdate();
void fmDraw(SDL_Texture *target);
}
} // namespace ui

View File

@ -1,10 +1,10 @@
#pragma once
#include <vector>
#include <SDL2/SDL.h>
#include <vector>
#include "type.h"
#include "gfx.h"
#include "type.h"
#define POP_FRAME_DEFAULT 130
@ -52,14 +52,21 @@ namespace ui
{
public:
menu() = default;
menu(const int& _x, const int& _y, const int& _rW, const int& _fS, const int& _mL);
menu(int _x, int _y, int _rW, int _fS, int _mL);
void editParam(int _param, int newVal);
//Gets executed when menu changes at all
void setOnChangeFunc(funcPtr func) { onChange = func; }
void setOnChangeFunc(funcPtr func)
{
onChange = func;
}
//executed when .update() is called.
void setCallback(funcPtr _callback, void *args) { callback = _callback; callbackArgs = args; }
void setCallback(funcPtr _callback, void *args)
{
callback = _callback;
callbackArgs = args;
}
//Adds option.
int addOpt(SDL_Texture *_icn, const std::string &add);
@ -68,7 +75,10 @@ namespace ui
void optAddButtonEvent(unsigned _ind, HidNpadButton _button, funcPtr _func, void *args);
//Changes opt text
void editOpt(int ind, SDL_Texture *_icn, const std::string &ch);
size_t getOptCount() { return opt.size(); }
size_t getOptCount()
{
return opt.size();
}
int getOptPos(const std::string &txt);
//Clears menu stuff
@ -78,10 +88,16 @@ namespace ui
void update();
//Returns selected option
int getSelected() { return selected; }
int getSelected()
{
return selected;
}
//Returns menu option count
int getCount() { return opt.size(); }
int getCount()
{
return opt.size();
}
//Draws the menu at x and y. rectWidth is the width of the rectangle drawn under the selected
void draw(SDL_Texture *target, const SDL_Color *textClr, bool drawText);
@ -90,11 +106,17 @@ namespace ui
void reset();
//Resets selected + start
void resetSel() { selected = 0; }
void resetSel()
{
selected = 0;
}
//Enables control/disables drawing select box
void setActive(bool _set);
bool getActive() { return isActive; }
bool getActive()
{
return isActive;
}
private:
//drawing x and y + rectangle width/height. Height is calc'd with font size
@ -118,12 +140,15 @@ namespace ui
public:
//Constructor. _max is the maximum value
progBar() = default;
progBar(const uint64_t& _max) { max = _max; }
progBar(uint64_t _max) : max(_max) {};
void setMax(const uint64_t& _max) { max = _max; };
void setMax(uint64_t _max)
{
max = _max;
}
//Updates progress
void update(const uint64_t& _prog);
void update(uint64_t _prog);
//Draws with text at top
void draw(const std::string &text);
@ -150,16 +175,22 @@ namespace ui
void draw();
private:
std::vector<popMessage> popQueue;//All graphics need to be on main thread. Directly adding will cause text issues
std::vector<popMessage>
popQueue; //All graphics need to be on main thread. Directly adding will cause text issues
std::vector<popMessage> message;
};
//General use
ui::confirmArgs *confirmArgsCreate(bool _hold, funcPtr _confFunc, funcPtr _cancelFunc, void *_funcArgs, const char *fmt, ...);
ui::confirmArgs *confirmArgsCreate(bool _hold,
funcPtr _confFunc,
funcPtr _cancelFunc,
void *_funcArgs,
const char *fmt,
...);
void confirm(void *a);
void showMessage(const char *fmt, ...);
bool confirmTransfer(const std::string &f, const std::string &t);
bool confirmDelete(const std::string &p);
void drawBoundBox(SDL_Texture *target, int x, int y, int w, int h, uint8_t clrSh);
void drawTextbox(SDL_Texture *target, int x, int y, int w, int h);
}
} // namespace ui

View File

@ -1,9 +1,9 @@
#pragma once
#include "data.h"
#include "ui.h"
#include "file.h"
#include "gfx.h"
#include "ui.h"
namespace util
{
@ -78,19 +78,24 @@ namespace util
size_t getTotalPlacesInPath(const std::string &_path);
void trimPath(std::string &_path, uint8_t _places);
inline bool isASCII(const uint32_t& t)
inline bool isASCII(uint32_t t)
{
return t > 30 && t < 127;
}
std::string safeString(const std::string &s);
std::string getStringInput(SwkbdType _type, const std::string& def, const std::string& head, size_t maxLength, unsigned dictCnt, const std::string dictWords[]);
std::string getStringInput(SwkbdType _type,
const std::string &def,
const std::string &head,
size_t maxLength,
unsigned dictCnt,
const std::string dictWords[]);
std::string getExtensionFromString(const std::string &get);
std::string getFilenameFromPath(const std::string &get);
std::string generateAbbrev(const uint64_t& tid);
std::string generateAbbrev(uint64_t tid);
//removes char from C++ string
void stripChar(char _c, std::string &_s);
@ -116,35 +121,33 @@ namespace util
return ret;
}
inline std::string getIDStr(const uint64_t& _id)
inline std::string getIDStr(uint64_t _id)
{
char tmp[18];
sprintf(tmp, "%016lX", _id);
return std::string(tmp);
}
inline std::string getIDStrLower(const uint64_t& _id)
inline std::string getIDStrLower(uint64_t _id)
{
char tmp[18];
sprintf(tmp, "%08X", (uint32_t)_id);
return std::string(tmp);
}
inline std::string generatePathByTID(const uint64_t& tid)
inline std::string generatePathByTID(uint64_t tid)
{
return fs::getWorkDir() + data::getTitleSafeNameByTID(tid) + "/";
}
std::string getSizeString(const uint64_t& _size);
std::string getSizeString(uint64_t _size);
inline void createTitleDirectoryByTID(const uint64_t& tid)
inline void createTitleDirectoryByTID(uint64_t tid)
{
std::string makePath = fs::getWorkDir() + data::getTitleSafeNameByTID(tid);
mkdir(makePath.c_str(), 777);
}
Result accountDeleteUser(AccountUid *uid);
void sysBoost();
void sysNormal();
@ -155,4 +158,4 @@ namespace util
}
void checkForUpdate(void *a);
}
} // namespace util

View File

@ -1,14 +1,14 @@
#include <switch.h>
#include <string>
#include <unordered_map>
#include <json-c/json.h>
#include <string>
#include <switch.h>
#include <unordered_map>
#include "cfg.h"
#include "data.h"
#include "file.h"
#include "type.h"
#include "ui.h"
#include "util.h"
#include "type.h"
std::unordered_map<std::string, bool> cfg::config;
std::vector<uint64_t> cfg::blacklist;
@ -19,21 +19,38 @@ std::string cfg::driveClientID, cfg::driveClientSecret, cfg::driveRefreshToken;
std::string cfg::webdavOrigin, cfg::webdavBasePath, cfg::webdavUser, cfg::webdavPassword;
const char *cfgPath = "sdmc:/config/JKSV/JKSV.cfg", *titleDefPath = "sdmc:/config/JKSV/titleDefs.txt", *workDirLegacy = "sdmc:/switch/jksv_dir.txt";
static std::unordered_map<std::string, unsigned> cfgStrings =
{
{"workDir", 0}, {"includeDeviceSaves", 1}, {"autoBackup", 2}, {"overclock", 3}, {"holdToDelete", 4}, {"holdToRestore", 5},
{"holdToOverwrite", 6}, {"forceMount", 7}, {"accountSystemSaves", 8}, {"allowSystemSaveWrite", 9}, {"directFSCommands", 10},
{"exportToZIP", 11}, {"languageOverride", 12}, {"enableTrashBin", 13}, {"titleSortType", 14}, {"animationScale", 15},
{"favorite", 16}, {"blacklist", 17}, {"autoName", 18}, {"driveRefreshToken", 19},
const char *cfgPath = "sdmc:/config/JKSV/JKSV.cfg", *titleDefPath = "sdmc:/config/JKSV/titleDefs.txt",
*workDirLegacy = "sdmc:/switch/jksv_dir.txt";
static std::unordered_map<std::string, unsigned> cfgStrings = {
{"workDir", 0},
{"includeDeviceSaves", 1},
{"autoBackup", 2},
{"overclock", 3},
{"holdToDelete", 4},
{"holdToRestore", 5},
{"holdToOverwrite", 6},
{"forceMount", 7},
{"accountSystemSaves", 8},
{"allowSystemSaveWrite", 9},
{"directFSCommands", 10},
{"exportToZIP", 11},
{"languageOverride", 12},
{"enableTrashBin", 13},
{"titleSortType", 14},
{"animationScale", 15},
{"favorite", 16},
{"blacklist", 17},
{"autoName", 18},
{"driveRefreshToken", 19},
};
const std::string _true_ = "true", _false_ = "false";
bool cfg::isBlacklisted(const uint64_t& tid)
bool cfg::isBlacklisted(uint64_t tid)
{
for (uint64_t &bid : cfg::blacklist)
if(tid == bid) return true;
if (tid == bid)
return true;
return false;
}
@ -48,14 +65,15 @@ void cfg::addTitleToBlacklist(void *a)
for (data::user &u : data::users)
{
for (unsigned i = 0; i < u.titleInfo.size(); i++)
if(u.titleInfo[i].tid == tid) u.titleInfo.erase(u.titleInfo.begin() + i);
if (u.titleInfo[i].tid == tid)
u.titleInfo.erase(u.titleInfo.begin() + i);
}
ui::ttlRefresh();
cfg::saveConfig();
t->finished = true;
}
void cfg::removeTitleFromBlacklist(const uint64_t& tid)
void cfg::removeTitleFromBlacklist(uint64_t tid)
{
for (unsigned i = 0; i < cfg::blacklist.size(); i++)
{
@ -67,15 +85,16 @@ void cfg::removeTitleFromBlacklist(const uint64_t& tid)
cfg::saveConfig();
}
bool cfg::isFavorite(const uint64_t& tid)
bool cfg::isFavorite(uint64_t tid)
{
for (uint64_t &fid : cfg::favorites)
if(tid == fid) return true;
if (tid == fid)
return true;
return false;
}
static int getFavoriteIndex(const uint64_t& tid)
static int getFavoriteIndex(uint64_t tid)
{
for (unsigned i = 0; i < cfg::favorites.size(); i++)
{
@ -85,7 +104,7 @@ static int getFavoriteIndex(const uint64_t& tid)
return -1;
}
void cfg::addTitleToFavorites(const uint64_t& tid)
void cfg::addTitleToFavorites(uint64_t tid)
{
if (cfg::isFavorite(tid))
{
@ -100,15 +119,16 @@ void cfg::addTitleToFavorites(const uint64_t& tid)
cfg::saveConfig();
}
bool cfg::isDefined(const uint64_t& tid)
bool cfg::isDefined(uint64_t tid)
{
for (auto &def : pathDefs)
if(def.first == tid) return true;
if (def.first == tid)
return true;
return false;
}
void cfg::pathDefAdd(const uint64_t& tid, const std::string& newPath)
void cfg::pathDefAdd(uint64_t tid, const std::string &newPath)
{
data::titleInfo *t = data::getTitleInfoByTID(tid);
std::string oldSafe = t->safeTitle;
@ -122,18 +142,21 @@ void cfg::pathDefAdd(const uint64_t& tid, const std::string& newPath)
std::string newOutput = fs::getWorkDir() + tmp;
rename(oldOutput.c_str(), newOutput.c_str());
ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("popChangeOutputFolder", 0), oldSafe.c_str(), tmp.c_str());
ui::showPopMessage(POP_FRAME_DEFAULT,
ui::getUICString("popChangeOutputFolder", 0),
oldSafe.c_str(),
tmp.c_str());
}
else
ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("popChangeOutputError", 0), newPath.c_str());
}
std::string cfg::getPathDefinition(const uint64_t& tid)
std::string cfg::getPathDefinition(uint64_t tid)
{
return pathDefs[tid];
}
void cfg::addPathToFilter(const uint64_t& tid, const std::string& _p)
void cfg::addPathToFilter(uint64_t tid, const std::string &_p)
{
char outpath[128];
sprintf(outpath, "sdmc:/config/JKSV/0x%016lX_filter.txt", tid);
@ -319,8 +342,8 @@ static void loadDriveConfig()
{
if (json_object_object_get_ex(driveJSON, "installed", &installed))
{
if(json_object_object_get_ex(installed, "client_id", &clientID)
&& json_object_object_get_ex(installed, "client_secret", &clientSecret))
if (json_object_object_get_ex(installed, "client_id", &clientID) &&
json_object_object_get_ex(installed, "client_secret", &clientSecret))
{
cfg::driveClientID = json_object_get_string(clientID);
cfg::driveClientSecret = json_object_get_string(clientSecret);
@ -336,16 +359,20 @@ static void loadDriveConfig()
json_object *origin, *basepath, *username, *password;
if (webdavJSON)
{
if (json_object_object_get_ex(webdavJSON, "origin", &origin)) {
if (json_object_object_get_ex(webdavJSON, "origin", &origin))
{
cfg::webdavOrigin = json_object_get_string(origin);
}
if (json_object_object_get_ex(webdavJSON, "basepath", &basepath)) {
if (json_object_object_get_ex(webdavJSON, "basepath", &basepath))
{
cfg::webdavBasePath = json_object_get_string(basepath);
}
if (json_object_object_get_ex(webdavJSON, "username", &username)) {
if (json_object_object_get_ex(webdavJSON, "username", &username))
{
cfg::webdavUser = json_object_get_string(username);
}
if (json_object_object_get_ex(webdavJSON, "password", &password)) {
if (json_object_object_get_ex(webdavJSON, "password", &password))
{
cfg::webdavPassword = json_object_get_string(password);
}
json_object_put(webdavJSON);

View File

@ -1,31 +1,52 @@
#include <vector>
#include <unordered_map>
#include <string>
#include <cstring>
#include <algorithm>
#include <array>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <memory>
#include <string>
#include <string_view>
#include <switch.h>
#include <unordered_map>
#include <vector>
#include "cfg.h"
#include "data.h"
#include "file.h"
#include "util.h"
#include "type.h"
#include "cfg.h"
#include "util.h"
//FsSaveDataSpaceId_All doesn't work for SD
static const unsigned saveOrder [] = { 0, 1, 2, 3, 4, 100, 101 };
namespace
{
/// @brief This is the string used for when a publisher isn't found in the NACP.
constexpr std::string_view STRING_UNKOWN_AUTHOR = "Someone?";
/// @brief This array holds the order in which to scan save data space IDs since the all pseudo value from libnx doesn't seem to work.
constexpr std::array<FsSaveDataSpaceId, 7> ORDER_SAVE_DATA_SPACES = {FsSaveDataSpaceId_System,
FsSaveDataSpaceId_User,
FsSaveDataSpaceId_SdSystem,
FsSaveDataSpaceId_Temporary,
FsSaveDataSpaceId_SdUser,
FsSaveDataSpaceId_ProperSystem,
FsSaveDataSpaceId_SafeMode};
/// @brief This saves whether or not the System BCAT user was pushed.
bool s_systemBCATPushed = false;
/// @brief This saves whether or not the Temporary save user was pushed.
bool s_temporaryPushed = false;
} // namespace
/// @brief External variables I used to track selected user/title.
int selUser = 0, selData = 0;
//User vector
/// @brief This vector holds the user instances.
std::vector<data::user> data::users;
//System language
/// @brief System language. I don't know why this is here in data?
SetLanguage data::sysLang;
//For other save types
static bool sysBCATPushed = false, tempPushed = false;
/// @brief This is the map of titleInfo.
std::unordered_map<uint64_t, data::titleInfo> data::titles;
//Sorts titles by sortType
@ -34,7 +55,8 @@ static struct
bool operator()(const data::userTitleInfo &a, const data::userTitleInfo &b)
{
//Favorites override EVERYTHING
if(cfg::isFavorite(a.tid) != cfg::isFavorite(b.tid)) return cfg::isFavorite(a.tid);
if (cfg::isFavorite(a.tid) != cfg::isFavorite(b.tid))
return cfg::isFavorite(a.tid);
switch (cfg::sortType)
{
@ -70,18 +92,20 @@ static struct
} sortTitles;
//Returns -1 for new
static int getUserIndex(const AccountUid& id)
static int getUserIndex(AccountUid id)
{
u128 nId = util::accountUIDToU128(id);
for (unsigned i = 0; i < data::users.size(); i++)
if(data::users[i].getUID128() == nId) return i;
if (data::users[i].getUID128() == nId)
return i;
return -1;
}
static inline bool accountSystemSaveCheck(const FsSaveDataInfo &_inf)
{
if(_inf.save_data_type == FsSaveDataType_System && util::accountUIDToU128(_inf.uid) != 0 && !cfg::config["accSysSave"])
if (_inf.save_data_type == FsSaveDataType_System && util::accountUIDToU128(_inf.uid) != 0 &&
!cfg::config["accSysSave"])
return false;
return true;
@ -100,72 +124,140 @@ static bool testMount(const FsSaveDataInfo& _inf)
return ret;
}
static inline void addTitleToList(const uint64_t& tid)
/// @brief This version of the function uses the title/application ID to pull the data from the system.
/// @param titleID Title/Application ID of the title to add.
static void add_title_to_list(uint64_t titleID)
{
uint64_t outSize = 0;
NsApplicationControlData *ctrlData = new NsApplicationControlData;
NacpLanguageEntry *ent;
Result ctrlRes = nsGetApplicationControlData(NsApplicationControlSource_Storage, tid, ctrlData, sizeof(NsApplicationControlData), &outSize);
Result nacpRes = nacpGetLanguageEntry(&ctrlData->nacp, &ent);
size_t iconSize = outSize - sizeof(ctrlData->nacp);
// This is the output size of the control data.
uint64_t dataSize = 0;
// This is the size of the icon.
size_t iconSize = 0;
// Nacp language entry pointer.
NacpLanguageEntry *entry = nullptr;
if(R_SUCCEEDED(ctrlRes) && !(outSize < sizeof(ctrlData->nacp)) && R_SUCCEEDED(nacpRes) && iconSize > 0)
// Try to read the control data directly into the map.
Result nsError = nsGetApplicationControlData(NsApplicationControlSource_Storage,
titleID,
&data::titles[titleID].data,
sizeof(NsApplicationControlData),
&dataSize);
// At this point, regardless, the title should exist in the map. Using a reference from here on out.
data::titleInfo &info = data::titles[titleID];
// Calc icon size. Not sure this is really needed?
iconSize = dataSize - sizeof(NacpStruct);
// If that failed, run the backup routine and bail.
if (R_FAILED(nsError) || dataSize < sizeof(info.data.nacp) || iconSize <= 0 ||
R_FAILED(nacpGetLanguageEntry(&info.data.nacp, &entry)))
{
//Copy nacp
memcpy(&data::titles[tid].nacp, &ctrlData->nacp, sizeof(NacpStruct));
// Clear the NACP.
std::memset(&info.data.nacp, 0x00, sizeof(NacpStruct));
//Setup 'shortcuts' to strings
NacpLanguageEntry *ent;
nacpGetLanguageEntry(&data::titles[tid].nacp, &ent);
if(strlen(ent->name) == 0)
data::titles[tid].title = ctrlData->nacp.lang[SetLanguage_ENUS].name;
else
data::titles[tid].title = ent->name;
data::titles[tid].author = ent->author;
if(cfg::isDefined(tid))
data::titles[tid].safeTitle = cfg::getPathDefinition(tid);
else if((data::titles[tid].safeTitle = util::safeString(ent->name)) == "")
data::titles[tid].safeTitle = util::getIDStr(tid);
// Set the title and publisher.
info.title = util::getIDStr(titleID);
info.author = STRING_UNKOWN_AUTHOR;
if(cfg::isFavorite(tid))
data::titles[tid].fav = true;
data::titles[tid].icon = gfx::texMgr->textureLoadFromMem(IMG_FMT_JPG, ctrlData->icon, iconSize);
if(!data::titles[tid].icon)
data::titles[tid].icon = util::createIconGeneric(util::getIDStrLower(tid).c_str(), 32, true);
// Check if the title has a path defined in the config.
if (cfg::isDefined(titleID))
{
info.safeTitle = cfg::getPathDefinition(titleID);
}
else
{
memset(&data::titles[tid].nacp, 0, sizeof(NacpStruct));
data::titles[tid].title = util::getIDStr(tid);
data::titles[tid].author = "Someone?";
if(cfg::isDefined(tid))
data::titles[tid].safeTitle = cfg::getPathDefinition(tid);
info.safeTitle = util::getIDStr(titleID);
}
// Create the icon.
std::string idHex = util::getIDStrLower(titleID);
info.icon = util::createIconGeneric(idHex.c_str(), 32, true);
// Bail. Do not continue. We're done.
return;
}
else
data::titles[tid].safeTitle = util::getIDStr(tid);
data::titles[tid].icon = util::createIconGeneric(util::getIDStrLower(tid).c_str(), 32, true);
{
// Check to make sure the title isn't blank. If it is, use English.
if (std::char_traits<char>::length(entry->name) == 0)
{
info.title = info.data.nacp.lang[SetLanguage_ENUS].name;
}
delete ctrlData;
else
{
info.title = entry->name;
}
static inline bool titleIsLoaded(const uint64_t& tid)
// Check the same for author/publisher.
if (std::char_traits<char>::length(entry->author) == 0)
{
auto findTid = data::titles.find(tid);
return findTid == data::titles.end() ? false : true;
info.author = info.data.nacp.lang[SetLanguage_ENUS].author;
}
else
{
info.author = entry->author;
}
static void loadUserAccounts()
// Load the icon from the control data.
info.icon = gfx::texMgr->textureLoadFromMem(IMG_FMT_JPG, info.data.icon, iconSize);
// Make sure to save that the title has valid control data.
info.hasControlData = true;
}
// The following is universal whether the title has control data or not.
// Set the safe path title. Note: I hate the second else if statement, but screw it. Rewrite avoids this kind of stuff.
if (cfg::isDefined(titleID))
{
s32 total = 0;
AccountUid *uids = new AccountUid[8];
if(R_SUCCEEDED(accountListAllUsers(uids, 8, &total)))
info.safeTitle = cfg::getPathDefinition(titleID);
}
else if ((info.safeTitle = util::safeString(entry->name)) == "")
{
info.safeTitle = util::getIDStr(titleID);
}
// Favorite check.
if (cfg::isFavorite(titleID))
{
info.fav = true;
}
}
/// @brief Adds a title to the map using the application ID and cached control data.
/// @param titleID Application ID of the title.
/// @param data Reference to the data to use.
static void add_title_to_list(uint64_t titleID, NsApplicationControlData &data)
{
// Start by memcpy'ing the data over.
std::memcpy(&data::titles[titleID].data, &data, sizeof(NsApplicationControlData));
// Since this function is always being fed cached data, we're going to assume everything else is good.
}
static inline bool titleIsLoaded(uint64_t titleID)
{
return data::titles.find(titleID) != data::titles.end();
}
static void loadUserAccounts(void)
{
// Total accounts listed.
int total = 0;
// Switch has eight accounts max.
AccountUid accounts[8] = {0};
if (R_FAILED(accountListAllUsers(accounts, 8, &total)))
{
// Rewrite logs this.
return;
}
for (int i = 0; i < total; i++)
data::users.emplace_back(uids[i], "", "");
{
// Maybe to do: This looks stupid. Overload constructors?
data::users.emplace_back(accounts[i], "", "");
}
delete[] uids;
}
//This can load titles installed without having save data
@ -176,53 +268,93 @@ static void loadTitlesFromRecords()
while (R_SUCCEEDED(nsListApplicationRecord(&nsRecord, 1, recordOffset++, &entryCount)) && entryCount > 0)
{
if (!titleIsLoaded(nsRecord.application_id))
addTitleToList(nsRecord.application_id);
{
add_title_to_list(nsRecord.application_id);
}
}
}
static void importSVIs()
static void import_svi_files(void)
{
std::string sviDir = fs::getWorkDir() + "svi/";
fs::dirList sviList(sviDir);
if(sviList.getCount() > 0)
// This is the path used. JKSV master was written before fslib.
std::string sviPath = fs::getWorkDir() + "svi";
// Get the listing and check to make sure there was actually something in it.
fs::dirList sviList(sviPath);
if (sviList.getCount() <= 0)
{
for(unsigned i = 0; i < sviList.getCount(); i++)
{
uint64_t tid = 0;
NacpStruct *nacp = new NacpStruct;
NacpLanguageEntry *ent;
std::string sviPath = fs::getWorkDir() + "svi/" + sviList.getItem(i);
size_t iconSize = fs::fsize(sviPath) - (sizeof(uint64_t) + sizeof(NacpStruct));
uint8_t *iconBuffer = new uint8_t[iconSize];
FILE *sviIn = fopen(sviPath.c_str(), "rb");
fread(&tid, sizeof(uint64_t), 1, sviIn);
fread(nacp, sizeof(NacpStruct), 1, sviIn);
fread(iconBuffer, 1, iconSize, sviIn);
if(!titleIsLoaded(tid))
{
nacpGetLanguageEntry(nacp, &ent);
memcpy(&data::titles[tid].nacp, nacp, sizeof(NacpStruct));
data::titles[tid].title = ent->name;
data::titles[tid].author = ent->author;
if(cfg::isDefined(tid))
data::titles[tid].safeTitle = cfg::getPathDefinition(tid);
else if((data::titles[tid].safeTitle = util::safeString(ent->name)) == "")
data::titles[tid].safeTitle = util::getIDStr(tid);
if(cfg::isFavorite(tid))
data::titles[tid].fav = true;
if(!data::titles[tid].icon && iconSize > 0)
data::titles[tid].icon = gfx::texMgr->textureLoadFromMem(IMG_FMT_JPG, iconBuffer, iconSize);
else if(!data::titles[tid].icon && iconSize == 0)
data::titles[tid].icon = util::createIconGeneric(util::getIDStrLower(tid).c_str(), 32, true);
// Just return and don't do anything.
return;
}
delete nacp;
delete[] iconBuffer;
fclose(sviIn);
// Loop through the listing and load them all.
for (unsigned int i = 0; i < sviList.getCount(); i++)
{
// Full path to the file.
std::string fullPath = sviPath + "/" + sviList.getItem(i);
// Grab the size of the SVI before continuing.
size_t sviSize = fs::fsize(fullPath);
// Application ID
uint64_t applicationID = 0;
// Language entry.
NacpLanguageEntry *entry = nullptr;
// Icon size.
size_t iconSize = 0;
// Open the file and read the application ID.
std::FILE *sviFile = std::fopen(sviPath.c_str(), "rb");
std::fread(&applicationID, 1, sizeof(uint64_t), sviFile);
// If it already exists in the map, just continue.
if (titleIsLoaded(applicationID))
{
std::fclose(sviFile);
continue;
}
// Read the NACP data into the map directly.
std::fread(&data::titles[applicationID].data.nacp, 1, sizeof(NacpStruct), sviFile);
// Calculate the icon size and read that too. The ControlData has memory set aside for the icon anyway.
iconSize = fs::fsize(fullPath) - (sizeof(uint64_t) + sizeof(NacpStruct));
std::fread(&data::titles[applicationID].data.icon, 1, iconSize, sviFile);
// Think I should be safe to use a reference now?
data::titleInfo &info = data::titles[applicationID];
// Setup the title stuff.
if (R_FAILED(nacpGetLanguageEntry(&info.data.nacp, &entry)))
{
// Default to English.
info.title = info.data.nacp.lang[SetLanguage_ENUS].name;
info.author = info.data.nacp.lang[SetLanguage_ENUS].author;
}
else
{
info.title = entry->name;
info.author = entry->author;
}
// Safe path.
if (cfg::isDefined(applicationID))
{
info.safeTitle = cfg::getPathDefinition(applicationID);
}
else if ((info.safeTitle = util::safeString(info.title)).empty())
{
info.safeTitle = util::getIDStr(applicationID);
}
// Favorite
if (cfg::isFavorite(applicationID))
{
info.fav = true;
}
// Just going to assume this is good.
info.icon = gfx::texMgr->textureLoadFromMem(IMG_FMT_JPG, info.data.icon, iconSize);
}
}
@ -234,21 +366,25 @@ bool data::loadUsersTitles(bool clearUsers)
s64 total = 0;
loadTitlesFromRecords();
importSVIs();
import_svi_files();
//Clear titles
for (data::user &u : data::users)
{
u.titleInfo.clear();
}
if (clearUsers)
{
systemUserCount = 4;
for (data::user &u : data::users)
{
u.delIcon();
}
data::users.clear();
loadUserAccounts();
sysBCATPushed = false;
tempPushed = false;
s_systemBCATPushed = false;
s_temporaryPushed = false;
users.emplace_back(util::u128ToAccountUID(3), ui::getUIString("saveTypeMainMenu", 0), "Device");
users.emplace_back(util::u128ToAccountUID(2), ui::getUIString("saveTypeMainMenu", 1), "BCAT");
@ -258,7 +394,7 @@ bool data::loadUsersTitles(bool clearUsers)
for (unsigned i = 0; i < 7; i++)
{
if(R_FAILED(fsOpenSaveDataInfoReader(&it, (FsSaveDataSpaceId)saveOrder[i])))
if (R_FAILED(fsOpenSaveDataInfoReader(&it, ORDER_SAVE_DATA_SPACES.at(i))))
continue;
while (R_SUCCEEDED(fsSaveDataInfoReaderRead(&it, &info, 1, &total)) && total != 0)
@ -270,7 +406,9 @@ bool data::loadUsersTitles(bool clearUsers)
tid = info.application_id;
if (!titleIsLoaded(tid))
addTitleToList(tid);
{
add_title_to_list(tid);
}
//Don't bother with this stuff
if (cfg::isBlacklisted(tid) || !accountSystemSaveCheck(info) || !testMount(info))
@ -288,11 +426,13 @@ bool data::loadUsersTitles(bool clearUsers)
case FsSaveDataType_SystemBcat:
info.uid = util::u128ToAccountUID(4);
if(!sysBCATPushed)
if (!s_systemBCATPushed)
{
++systemUserCount;
sysBCATPushed = true;
users.emplace_back(util::u128ToAccountUID(4), ui::getUIString("saveTypeMainMenu", 4), "System BCAT");
s_systemBCATPushed = true;
users.emplace_back(util::u128ToAccountUID(4),
ui::getUIString("saveTypeMainMenu", 4),
"System BCAT");
}
break;
@ -302,11 +442,13 @@ bool data::loadUsersTitles(bool clearUsers)
case FsSaveDataType_Temporary:
info.uid = util::u128ToAccountUID(6);
if(!tempPushed)
if (!s_temporaryPushed)
{
++systemUserCount;
tempPushed = true;
users.emplace_back(util::u128ToAccountUID(6), ui::getUIString("saveTypeMainMenu", 5), "Temporary");
s_temporaryPushed = true;
users.emplace_back(util::u128ToAccountUID(6),
ui::getUIString("saveTypeMainMenu", 5),
"Temporary");
}
break;
}
@ -320,7 +462,10 @@ bool data::loadUsersTitles(bool clearUsers)
PdmPlayStatistics playStats;
if (info.save_data_type == FsSaveDataType_Account || info.save_data_type == FsSaveDataType_Device)
pdmqryQueryPlayStatisticsByApplicationIdAndUserAccountId(info.application_id, info.uid, false, &playStats);
pdmqryQueryPlayStatisticsByApplicationIdAndUserAccountId(info.application_id,
info.uid,
false,
&playStats);
else
memset(&playStats, 0, sizeof(PdmPlayStatistics));
users[u].addUserTitleInfo(tid, &info, &playStats);
@ -425,7 +570,7 @@ int data::getTitleIndexInUser(const data::user& u, const uint64_t& tid)
return -1;
}
data::user::user(const AccountUid& _id, const std::string& _backupName, const std::string& _safeBackupName)
data::user::user(AccountUid _id, const std::string &_backupName, const std::string &_safeBackupName)
{
userID = _id;
uID128 = util::accountUIDToU128(_id);
@ -462,14 +607,15 @@ data::user::user(const AccountUid& _id, const std::string& _backupName, const st
titles.reserve(64);
}
data::user::user(const AccountUid& _id, const std::string& _backupName, const std::string& _safeBackupName, SDL_Texture *img) : user(_id, _backupName, _safeBackupName)
data::user::user(AccountUid _id, const std::string &_backupName, const std::string &_safeBackupName, SDL_Texture *img)
: user(_id, _backupName, _safeBackupName)
{
delIcon();
userIcon = img;
titles.reserve(64);
}
void data::user::setUID(const AccountUid& _id)
void data::user::setUID(AccountUid _id)
{
userID = _id;
uID128 = util::accountUIDToU128(_id);
@ -484,7 +630,7 @@ void data::user::addUserTitleInfo(const uint64_t& tid, const FsSaveDataInfo *_sa
titleInfo.push_back(newInfo);
}
static const SDL_Color green = {0x00, 0xDD, 0x00, 0xFF};
static constexpr SDL_Color green = {0x00, 0xDD, 0x00, 0xFF};
void data::dispStats()
{

View File

@ -1,8 +1,8 @@
#include <switch.h>
#include <string>
#include <switch.h>
#include "fs.h"
#include "cfg.h"
#include "fs.h"
#include "util.h"
static std::string wd = "sdmc:/JKSV/";
@ -103,12 +103,18 @@ bool fs::commitToDevice(const std::string& dev)
return ret;
}
std::string fs::getWorkDir() { return wd; }
std::string fs::getWorkDir()
{
return wd;
}
void fs::setWorkDir(const std::string& _w) { wd = _w; }
void fs::setWorkDir(const std::string &_w)
{
wd = _w;
}
void fs::loadPathFilters(const uint64_t& tid)
void fs::loadPathFilters(uint64_t tid)
{
char path[256];
sprintf(path, "sdmc:/config/JKSV/0x%016lX_filter.txt", tid);
@ -147,7 +153,9 @@ void fs::createSaveData(FsSaveDataType _type, uint64_t _tid, AccountUid _uid, th
uint16_t cacheIndex = 0;
std::string indexStr;
if(_type == FsSaveDataType_Cache && !(indexStr = util::getStringInput(SwkbdType_NumPad, "0", ui::getUIString("swkbdSaveIndex", 0), 2, 0, NULL)).empty())
if (_type == FsSaveDataType_Cache &&
!(indexStr = util::getStringInput(SwkbdType_NumPad, "0", ui::getUIString("swkbdSaveIndex", 0), 2, 0, NULL))
.empty())
cacheIndex = strtoul(indexStr.c_str(), NULL, 10);
else if (_type == FsSaveDataType_Cache && indexStr.empty())
{
@ -168,41 +176,59 @@ void fs::createSaveData(FsSaveDataType _type, uint64_t _tid, AccountUid _uid, th
FsSaveDataCreationInfo crt;
memset(&crt, 0, sizeof(FsSaveDataCreationInfo));
int64_t saveSize = 0, journalSize = 0;
// Grab a pointer to the nacp of the title data.
NacpStruct *nacp = &tinfo->data.nacp;
switch (_type)
{
case FsSaveDataType_Account:
saveSize = tinfo->nacp.user_account_save_data_size;
journalSize = tinfo->nacp.user_account_save_data_journal_size;
{
saveSize = nacp->user_account_save_data_size;
journalSize = nacp->user_account_save_data_journal_size;
}
break;
case FsSaveDataType_Device:
saveSize = tinfo->nacp.device_save_data_size;
journalSize = tinfo->nacp.device_save_data_journal_size;
{
saveSize = nacp->device_save_data_size;
journalSize = nacp->device_save_data_journal_size;
}
break;
case FsSaveDataType_Bcat:
saveSize = tinfo->nacp.bcat_delivery_cache_storage_size;
journalSize = tinfo->nacp.bcat_delivery_cache_storage_size;
{
saveSize = nacp->bcat_delivery_cache_storage_size;
journalSize = nacp->bcat_delivery_cache_storage_size;
}
break;
case FsSaveDataType_Cache:
{
saveSize = 32 * 1024 * 1024;
if(tinfo->nacp.cache_storage_journal_size > tinfo->nacp.cache_storage_data_and_journal_size_max)
journalSize = tinfo->nacp.cache_storage_journal_size;
if (nacp->cache_storage_journal_size > nacp->cache_storage_data_and_journal_size_max)
{
journalSize = nacp->cache_storage_journal_size;
}
else
journalSize = tinfo->nacp.cache_storage_data_and_journal_size_max;
{
journalSize = nacp->cache_storage_data_and_journal_size_max;
}
}
break;
default:
{
if (t)
t->finished = true;
return;
}
break;
}
crt.save_data_size = saveSize;
crt.journal_size = journalSize;
crt.available_size = 0x4000;
crt.owner_id = _type == FsSaveDataType_Bcat ? 0x010000000000000C : tinfo->nacp.save_data_owner_id;
crt.owner_id = _type == FsSaveDataType_Bcat ? 0x010000000000000C : nacp->save_data_owner_id;
crt.flags = 0;
crt.save_data_space_id = FsSaveDataSpaceId_User;
@ -249,7 +275,8 @@ void fs::createSaveDataThreaded(FsSaveDataType _type, uint64_t _tid, AccountUid
bool fs::extendSaveData(const data::userTitleInfo *tinfo, uint64_t extSize, threadInfo *t)
{
if (t)
t->status->setStatus(ui::getUICString("threadStatusExtendingSaveData", 0), data::getTitleNameByTID(tinfo->tid).c_str());
t->status->setStatus(ui::getUICString("threadStatusExtendingSaveData", 0),
data::getTitleNameByTID(tinfo->tid).c_str());
uint64_t journal = fs::getJournalSizeMax(tinfo);
uint64_t saveID = tinfo->saveInfo.save_data_id;
@ -290,29 +317,47 @@ uint64_t fs::getJournalSize(const data::userTitleInfo *tinfo)
{
uint64_t ret = 0;
data::titleInfo *t = data::getTitleInfoByTID(tinfo->tid);
// NACP pointer.
NacpStruct *nacp = &t->data.nacp;
switch (tinfo->saveInfo.save_data_type)
{
case FsSaveDataType_Account:
ret = t->nacp.user_account_save_data_journal_size;
{
ret = nacp->user_account_save_data_journal_size;
}
break;
case FsSaveDataType_Device:
ret = t->nacp.device_save_data_journal_size;
{
ret = nacp->device_save_data_journal_size;
}
break;
case FsSaveDataType_Bcat:
ret = t->nacp.bcat_delivery_cache_storage_size;
{
ret = nacp->bcat_delivery_cache_storage_size;
}
break;
case FsSaveDataType_Cache:
if(t->nacp.cache_storage_journal_size > 0)
ret = t->nacp.cache_storage_journal_size;
{
if (nacp->cache_storage_journal_size > 0)
{
ret = nacp->cache_storage_journal_size;
}
else
ret = t->nacp.cache_storage_data_and_journal_size_max;
{
ret = nacp->cache_storage_data_and_journal_size_max;
}
}
break;
default:
{
ret = BUFF_SIZE;
}
break;
}
return ret;
@ -322,36 +367,50 @@ uint64_t fs::getJournalSizeMax(const data::userTitleInfo *tinfo)
{
uint64_t ret = 0;
data::titleInfo *extend = data::getTitleInfoByTID(tinfo->tid);
// NACP pointer
NacpStruct *nacp = &extend->data.nacp;
switch (tinfo->saveInfo.save_data_type)
{
case FsSaveDataType_Account:
if(extend->nacp.user_account_save_data_journal_size_max > extend->nacp.user_account_save_data_journal_size)
ret = extend->nacp.user_account_save_data_journal_size_max;
{
if (nacp->user_account_save_data_journal_size_max > nacp->user_account_save_data_journal_size)
ret = nacp->user_account_save_data_journal_size_max;
else
ret = extend->nacp.user_account_save_data_journal_size;
ret = nacp->user_account_save_data_journal_size;
}
break;
case FsSaveDataType_Bcat:
ret = extend->nacp.bcat_delivery_cache_storage_size;
{
ret = nacp->bcat_delivery_cache_storage_size;
}
break;
case FsSaveDataType_Cache:
if(extend->nacp.cache_storage_data_and_journal_size_max > extend->nacp.cache_storage_journal_size)
ret = extend->nacp.cache_storage_data_and_journal_size_max;
{
if (nacp->cache_storage_data_and_journal_size_max > nacp->cache_storage_journal_size)
ret = nacp->cache_storage_data_and_journal_size_max;
else
ret = extend->nacp.cache_storage_journal_size;
ret = nacp->cache_storage_journal_size;
}
break;
case FsSaveDataType_Device:
if(extend->nacp.device_save_data_journal_size_max > extend->nacp.device_save_data_journal_size)
ret = extend->nacp.device_save_data_journal_size_max;
{
if (nacp->device_save_data_journal_size_max > nacp->device_save_data_journal_size)
ret = nacp->device_save_data_journal_size_max;
else
ret = extend->nacp.device_save_data_journal_size;
ret = nacp->device_save_data_journal_size;
}
break;
default:
{
//will just fail
ret = 0;
}
break;
}
return ret;
@ -395,9 +454,7 @@ void fs::createNewBackup(void *a)
out = u->getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_HOYSTE);
else
{
const std::string dict[] =
{
util::getDateTime(util::DATE_FMT_YMD),
const std::string dict[] = {util::getDateTime(util::DATE_FMT_YMD),
util::getDateTime(util::DATE_FMT_YDM),
util::getDateTime(util::DATE_FMT_HOYSTE),
util::getDateTime(util::DATE_FMT_JHK),
@ -405,8 +462,7 @@ void fs::createNewBackup(void *a)
u->getUsernameSafe(),
t->safeTitle,
util::generateAbbrev(d->tid),
".zip"
};
".zip"};
std::string defaultText = u->getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD);
out = util::getStringInput(SwkbdType_QWERTY, defaultText, ui::getUIString("swkbdEnterName", 0), 64, 9, dict);
out = util::safeString(out);
@ -423,7 +479,6 @@ void fs::createNewBackup(void *a)
zipFile zip = zipOpen64(path.c_str(), 0);
fs::copyDirToZipThreaded("sv:/", zip, false, 0);
}
else
{
@ -468,13 +523,15 @@ void fs::restoreBackup(void *a)
bool saveHasFiles = fs::dirNotEmpty("sv:/");
if (cfg::config["autoBack"] && cfg::config["zip"] && saveHasFiles)
{
std::string autoZip = util::generatePathByTID(utinfo->tid) + "/AUTO " + u->getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD) + ".zip";
std::string autoZip = util::generatePathByTID(utinfo->tid) + "/AUTO " + u->getUsernameSafe() + " - " +
util::getDateTime(util::DATE_FMT_YMD) + ".zip";
zipFile zip = zipOpen64(autoZip.c_str(), 0);
fs::copyDirToZipThreaded("sv:/", zip, false, 0);
}
else if (cfg::config["autoBack"] && saveHasFiles)
{
std::string autoFolder = util::generatePathByTID(utinfo->tid) + "/AUTO - " + u->getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD) + "/";
std::string autoFolder = util::generatePathByTID(utinfo->tid) + "/AUTO - " + u->getUsernameSafe() + " - " +
util::getDateTime(util::DATE_FMT_YMD) + "/";
fs::mkDir(autoFolder.substr(0, autoFolder.length() - 1));
fs::copyDirToDirThreaded("sv:/", autoFolder);
}
@ -591,7 +648,8 @@ void fs::dumpAllUserSaves(void *a)
if (saveMounted && fs::dirNotEmpty("sv:/") && cfg::config["zip"])
{
fs::loadPathFilters(u->titleInfo[i].tid);
std::string dst = util::generatePathByTID(u->titleInfo[i].tid) + u->getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD) + ".zip";
std::string dst = util::generatePathByTID(u->titleInfo[i].tid) + u->getUsernameSafe() + " - " +
util::getDateTime(util::DATE_FMT_YMD) + ".zip";
zipFile zip = zipOpen64(dst.c_str(), 0);
fs::copyDirToZip("sv:/", zip, false, 0, t);
zipClose(zip, NULL);
@ -600,7 +658,8 @@ void fs::dumpAllUserSaves(void *a)
else if (saveMounted && fs::dirNotEmpty("sv:/"))
{
fs::loadPathFilters(u->titleInfo[i].tid);
std::string dst = util::generatePathByTID(u->titleInfo[i].tid) + u->getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD) + "/";
std::string dst = util::generatePathByTID(u->titleInfo[i].tid) + u->getUsernameSafe() + " - " +
util::getDateTime(util::DATE_FMT_YMD) + "/";
fs::mkDir(dst.substr(0, dst.length() - 1));
fs::copyDirToDir("sv:/", dst, t);
fs::freePathFilters();
@ -627,7 +686,8 @@ void fs::dumpAllUsersAllSaves(void *a)
if (saveMounted && fs::dirNotEmpty("sv:/") && cfg::config["zip"])
{
fs::loadPathFilters(u->titleInfo[i].tid);
std::string dst = util::generatePathByTID(u->titleInfo[i].tid) + u->getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD) + ".zip";
std::string dst = util::generatePathByTID(u->titleInfo[i].tid) + u->getUsernameSafe() + " - " +
util::getDateTime(util::DATE_FMT_YMD) + ".zip";
zipFile zip = zipOpen64(dst.c_str(), 0);
fs::copyDirToZip("sv:/", zip, false, 0, t);
zipClose(zip, NULL);
@ -636,7 +696,8 @@ void fs::dumpAllUsersAllSaves(void *a)
else if (saveMounted && fs::dirNotEmpty("sv:/"))
{
fs::loadPathFilters(u->titleInfo[i].tid);
std::string dst = util::generatePathByTID(u->titleInfo[i].tid) + u->getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD) + "/";
std::string dst = util::generatePathByTID(u->titleInfo[i].tid) + u->getUsernameSafe() + " - " +
util::getDateTime(util::DATE_FMT_YMD) + "/";
fs::mkDir(dst.substr(0, dst.length() - 1));
fs::copyDirToDir("sv:/", dst, t);
fs::freePathFilters();
@ -667,4 +728,3 @@ void fs::logWrite(const char *fmt, ...)
fsfwrite(tmp, 1, strlen(tmp), debLog);
fsfclose(debLog);
}

View File

@ -1,11 +1,11 @@
#include <string>
#include "ui.h"
#include "file.h"
#include "util.h"
#include "fm.h"
#include "cfg.h"
#include "file.h"
#include "fm.h"
#include "type.h"
#include "ui.h"
#include "util.h"
//This is going to be a mess but the old one was too.
//It gets more complicated because of system saves and committing.
@ -252,7 +252,13 @@ static void _copyMenuCopy(void *a)
if (ma == devArgs || (ma == sdmcArgs && (type != FsSaveDataType_System || cfg::config["sysSaveWrite"])))
{
ui::confirmArgs *send = ui::confirmArgsCreate(false, _copyMenuCopy_t, NULL, ma, ui::getUICString("confirmCopy", 0), srcPath.c_str(), dstPath.c_str());
ui::confirmArgs *send = ui::confirmArgsCreate(false,
_copyMenuCopy_t,
NULL,
ma,
ui::getUICString("confirmCopy", 0),
srcPath.c_str(),
dstPath.c_str());
ui::confirm(send);
}
}
@ -324,9 +330,15 @@ static void _copyMenuDelete(void *a)
else if (sel > 1)
itmPath = *ma->path + d->getItem(sel - 2);
if(ma == sdmcArgs || (ma == devArgs && (sel == 0 || sel > 1) && (type != FsSaveDataType_System || cfg::config["sysSaveWrite"])))
if (ma == sdmcArgs ||
(ma == devArgs && (sel == 0 || sel > 1) && (type != FsSaveDataType_System || cfg::config["sysSaveWrite"])))
{
ui::confirmArgs *send = ui::confirmArgsCreate(cfg::config["holdDel"], _copyMenuDelete_t, NULL, a, ui::getUICString("confirmDelete", 0), itmPath.c_str());
ui::confirmArgs *send = ui::confirmArgsCreate(cfg::config["holdDel"],
_copyMenuDelete_t,
NULL,
a,
ui::getUICString("confirmDelete", 0),
itmPath.c_str());
ui::confirm(send);
}
}
@ -340,7 +352,8 @@ static void _copyMenuRename(void *a)
int sel = m->getSelected();
if (sel > 1)
{
std::string getNewName = util::getStringInput(SwkbdType_QWERTY, d->getItem(sel - 2), ui::getUIString("swkbdRename", 0), 64, 0, NULL);
std::string getNewName =
util::getStringInput(SwkbdType_QWERTY, d->getItem(sel - 2), ui::getUIString("swkbdRename", 0), 64, 0, NULL);
if (!getNewName.empty())
{
std::string prevPath = *ma->path + d->getItem(sel - 2);
@ -358,7 +371,12 @@ static void _copyMenuRename(void *a)
static void _copyMenuMkDir(void *a)
{
menuFuncArgs *ma = (menuFuncArgs *)a;
std::string getNewFolder = util::getStringInput(SwkbdType_QWERTY, ui::getUIString("fileModeMenuMkDir", 0), ui::getUIString("swkbdMkDir", 0), 64, 0, NULL);
std::string getNewFolder = util::getStringInput(SwkbdType_QWERTY,
ui::getUIString("fileModeMenuMkDir", 0),
ui::getUIString("swkbdMkDir", 0),
64,
0,
NULL);
if (!getNewFolder.empty())
{
std::string createPath = *ma->path + getNewFolder;
@ -379,7 +397,11 @@ static void _copyMenuGetShowDirProps_t(void *a)
uint64_t totalSize = 0;
t->status->setStatus(ui::getUICString("threadStatusGetDirProps", 0));
fs::getDirProps(*p, dirCount, fileCount, totalSize);
ui::showMessage(ui::getUICString("fileModeFolderProperties", 0), p->c_str(), dirCount, fileCount, util::getSizeString(totalSize).c_str());
ui::showMessage(ui::getUICString("fileModeFolderProperties", 0),
p->c_str(),
dirCount,
fileCount,
util::getSizeString(totalSize).c_str());
delete p;
t->finished = true;
}
@ -514,7 +536,7 @@ void ui::fmExit()
delete sdmcArgs;
}
void ui::fmPrep(const FsSaveDataType& _type, const std::string& _dev, const std::string& _baseSDMC, bool _commit)
void ui::fmPrep(FsSaveDataType _type, const std::string &_dev, const std::string &_baseSDMC, bool _commit)
{
type = _type;
dev = _dev;

View File

@ -1,13 +1,13 @@
#include <cstring>
#include <cstdarg>
#include <cmath>
#include <cstdarg>
#include <cstring>
#include <switch.h>
#include "gfx.h"
#include "ui.h"
#include "miscui.h"
#include "util.h"
#include "type.h"
#include "ui.h"
#include "util.h"
static const SDL_Color divLight = {0x6D, 0x6D, 0x6D, 0xFF};
static const SDL_Color divDark = {0xCC, 0xCC, 0xCC, 0xFF};
@ -19,7 +19,7 @@ static const SDL_Color fillBar = {0x00, 0xDD, 0x00, 0xFF};
static const SDL_Color menuColorLight = {0x32, 0x50, 0xF0, 0xFF};
static const SDL_Color menuColorDark = {0x00, 0xFF, 0xC5, 0xFF};
ui::menu::menu(const int& _x, const int& _y, const int& _rW, const int& _fS, const int& _mL)
ui::menu::menu(int _x, int _y, int _rW, int _fS, int _mL)
{
x = _x;
mY = _y;
@ -50,14 +50,22 @@ void ui::menu::editParam(int _param, int newVal)
case MENU_RECT_WIDTH:
rW = newVal;
SDL_DestroyTexture(optTex);
optTex = SDL_CreateTexture(gfx::render, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STATIC | SDL_TEXTUREACCESS_TARGET, rW, rH);
optTex = SDL_CreateTexture(gfx::render,
SDL_PIXELFORMAT_RGBA8888,
SDL_TEXTUREACCESS_STATIC | SDL_TEXTUREACCESS_TARGET,
rW,
rH);
SDL_SetTextureBlendMode(optTex, SDL_BLENDMODE_BLEND);
break;
case MENU_RECT_HEIGHT:
rH = newVal;
SDL_DestroyTexture(optTex);
optTex = SDL_CreateTexture(gfx::render, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STATIC | SDL_TEXTUREACCESS_TARGET, rW, rH);
optTex = SDL_CreateTexture(gfx::render,
SDL_PIXELFORMAT_RGBA8888,
SDL_TEXTUREACCESS_STATIC | SDL_TEXTUREACCESS_TARGET,
rW,
rH);
SDL_SetTextureBlendMode(optTex, SDL_BLENDMODE_BLEND);
break;
@ -235,7 +243,12 @@ void ui::menu::draw(SDL_Texture *target, const SDL_Color *textClr, bool drawText
if (isActive)
ui::drawBoundBox(target, x, y + (i * rH), rW, rH, clrSh);
gfx::drawRect(target, ui::thmID == ColorSetId_Light ? &menuColorLight : &menuColorDark, x + 10, ((y + (rH / 2 - fSize / 2)) + (i * rH)) - 2, 4, fSize + 4);
gfx::drawRect(target,
ui::thmID == ColorSetId_Light ? &menuColorLight : &menuColorDark,
x + 10,
((y + (rH / 2 - fSize / 2)) + (i * rH)) - 2,
4,
fSize + 4);
static int dX = 0;
if (hover && opt[i].txtWidth > rW - 24)
@ -247,13 +260,28 @@ void ui::menu::draw(SDL_Texture *target, const SDL_Color *textClr, bool drawText
hover = false;
}
gfx::drawTextf(optTex, fSize, dX, ((rH - 8) / 2) - fSize / 2, ui::thmID == ColorSetId_Light ? &menuColorLight : &menuColorDark, opt[i].txt.c_str());
gfx::drawTextf(optTex, fSize, dX + opt[i].txtWidth + spcWidth, ((rH - 8) / 2) - fSize / 2, ui::thmID == ColorSetId_Light ? &menuColorLight : &menuColorDark, opt[i].txt.c_str());
gfx::drawTextf(optTex,
fSize,
dX,
((rH - 8) / 2) - fSize / 2,
ui::thmID == ColorSetId_Light ? &menuColorLight : &menuColorDark,
opt[i].txt.c_str());
gfx::drawTextf(optTex,
fSize,
dX + opt[i].txtWidth + spcWidth,
((rH - 8) / 2) - fSize / 2,
ui::thmID == ColorSetId_Light ? &menuColorLight : &menuColorDark,
opt[i].txt.c_str());
}
else
{
dX = 0;
gfx::drawTextf(optTex, fSize, 0, ((rH - 8) / 2) - fSize / 2, ui::thmID == ColorSetId_Light ? &menuColorLight : &menuColorDark, opt[i].txt.c_str());
gfx::drawTextf(optTex,
fSize,
0,
((rH - 8) / 2) - fSize / 2,
ui::thmID == ColorSetId_Light ? &menuColorLight : &menuColorDark,
opt[i].txt.c_str());
}
gfx::texDraw(target, optTex, x + 20, (y + 4 + (i * rH)));
}
@ -267,7 +295,12 @@ void ui::menu::draw(SDL_Texture *target, const SDL_Color *textClr, bool drawText
if (isActive)
ui::drawBoundBox(target, x, y + (i * rH), rW, rH, clrSh);
gfx::drawRect(target, ui::thmID == ColorSetId_Light ? &menuColorLight : &menuColorDark, x + 10, ((y + (rH / 2 - fSize / 2)) + (i * rH)) - 2, 4, fSize + 4);
gfx::drawRect(target,
ui::thmID == ColorSetId_Light ? &menuColorLight : &menuColorDark,
x + 10,
((y + (rH / 2 - fSize / 2)) + (i * rH)) - 2,
4,
fSize + 4);
gfx::texDrawStretch(optTex, opt[i].icn, 0, ((rH - 8) / 2) - fSize / 2, dW, dH);
gfx::texDraw(target, optTex, x + 20, (y + 4 + (i * rH)));
}
@ -304,7 +337,7 @@ void ui::menu::setActive(bool _set)
isActive = _set;
}
void ui::progBar::update(const uint64_t& _prog)
void ui::progBar::update(uint64_t _prog)
{
prog = _prog;
@ -377,7 +410,12 @@ void ui::popMessageMngr::draw()
}
}
ui::confirmArgs *ui::confirmArgsCreate(bool _hold, funcPtr _confFunc, funcPtr _cancelFunc, void *_funcArgs, const char *fmt, ...)
ui::confirmArgs *ui::confirmArgsCreate(bool _hold,
funcPtr _confFunc,
funcPtr _cancelFunc,
void *_funcArgs,
const char *fmt,
...)
{
char tmp[1024];
va_list args;

View File

@ -1,10 +1,10 @@
#include <vector>
#include "ui.h"
#include "ttl.h"
#include "file.h"
#include "util.h"
#include "cfg.h"
#include "file.h"
#include "ttl.h"
#include "ui.h"
#include "util.h"
static int ttlHelpX = 0;
static std::vector<ui::titleview *> ttlViews;
@ -109,7 +109,12 @@ static void ttlOptsShowInfoPanel(void *)
static void ttlOptsBlacklistTitle(void *a)
{
std::string title = data::getTitleNameByTID(data::getCurrentUserTitleInfo()->tid);
ui::confirmArgs *conf = ui::confirmArgsCreate(false, cfg::addTitleToBlacklist, NULL, NULL, ui::getUICString("confirmBlacklist", 0), title.c_str());
ui::confirmArgs *conf = ui::confirmArgsCreate(false,
cfg::addTitleToBlacklist,
NULL,
NULL,
ui::getUICString("confirmBlacklist", 0),
title.c_str());
ui::confirm(conf);
}
@ -117,7 +122,8 @@ static void ttlOptsDefinePath(void *a)
{
uint64_t tid = data::getCurrentUserTitleInfo()->tid;
std::string safeTitle = data::getTitleInfoByTID(tid)->safeTitle;
std::string newSafeTitle = util::getStringInput(SwkbdType_QWERTY, safeTitle, ui::getUICString("swkbdNewSafeTitle", 0), 0x200, 0, NULL);
std::string newSafeTitle =
util::getStringInput(SwkbdType_QWERTY, safeTitle, ui::getUICString("swkbdNewSafeTitle", 0), 0x200, 0, NULL);
if (!newSafeTitle.empty())
cfg::pathDefAdd(tid, newSafeTitle);
}
@ -163,7 +169,12 @@ static void ttlOptsDeleteAllBackups(void *a)
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
std::string currentTitle = data::getTitleNameByTID(d->tid);
ui::confirmArgs *send = ui::confirmArgsCreate(cfg::config["holdDel"], ttlOptsDeleteAllBackups_t, NULL, NULL, ui::getUICString("confirmDeleteBackupsTitle", 0), currentTitle.c_str());
ui::confirmArgs *send = ui::confirmArgsCreate(cfg::config["holdDel"],
ttlOptsDeleteAllBackups_t,
NULL,
NULL,
ui::getUICString("confirmDeleteBackupsTitle", 0),
currentTitle.c_str());
ui::confirm(send);
}
@ -188,7 +199,12 @@ static void ttlOptsResetSaveData(void *a)
if (d->saveInfo.save_data_type != FsSaveDataType_System)
{
std::string title = data::getTitleNameByTID(d->tid);
ui::confirmArgs *conf = ui::confirmArgsCreate(cfg::config["holdDel"], ttlOptsResetSaveData_t, NULL, NULL, ui::getUICString("confirmResetSaveData", 0), title.c_str());
ui::confirmArgs *conf = ui::confirmArgsCreate(cfg::config["holdDel"],
ttlOptsResetSaveData_t,
NULL,
NULL,
ui::getUICString("confirmResetSaveData", 0),
title.c_str());
ui::confirm(conf);
}
}
@ -202,7 +218,8 @@ static void ttlOptsDeleteSaveData_t(void *a)
std::string title = data::getTitleNameByTID(d->tid);
t->status->setStatus(ui::getUICString("threadStatusDeletingSaveData", 0), title.c_str());
if(R_SUCCEEDED(fsDeleteSaveDataFileSystemBySaveDataSpaceId((FsSaveDataSpaceId)d->saveInfo.save_data_space_id, d->saveInfo.save_data_id)))
if (R_SUCCEEDED(fsDeleteSaveDataFileSystemBySaveDataSpaceId((FsSaveDataSpaceId)d->saveInfo.save_data_space_id,
d->saveInfo.save_data_id)))
{
data::loadUsersTitles(false);
if (u->titleInfo.size() == 0)
@ -226,7 +243,12 @@ static void ttlOptsDeleteSaveData(void *a)
if (d->saveInfo.save_data_type != FsSaveDataType_System)
{
std::string title = data::getTitleNameByTID(d->tid);
ui::confirmArgs *conf = ui::confirmArgsCreate(cfg::config["holdDel"], ttlOptsDeleteSaveData_t, NULL, NULL, ui::getUICString("confirmDeleteSaveData", 0), title.c_str());
ui::confirmArgs *conf = ui::confirmArgsCreate(cfg::config["holdDel"],
ttlOptsDeleteSaveData_t,
NULL,
NULL,
ui::getUICString("confirmDeleteSaveData", 0),
title.c_str());
ui::confirm(conf);
}
}
@ -236,7 +258,8 @@ static void ttlOptsExtendSaveData(void *a)
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
if (d->saveInfo.save_data_type != FsSaveDataType_System)
{
std::string expSizeStr = util::getStringInput(SwkbdType_NumPad, "", ui::getUICString("swkbdExpandSize", 0), 4, 0, NULL);
std::string expSizeStr =
util::getStringInput(SwkbdType_NumPad, "", ui::getUICString("swkbdExpandSize", 0), 4, 0, NULL);
uint64_t extMB = strtoul(expSizeStr.c_str(), NULL, 10) * 0x100000;
fs::extendSaveDataThreaded(d, extMB);
}
@ -244,27 +267,36 @@ static void ttlOptsExtendSaveData(void *a)
static void ttlOptsExportSVI(void *a)
{
data::userTitleInfo *ut = data::getCurrentUserTitleInfo();
data::titleInfo *t = data::getTitleInfoByTID(ut->tid);
std::string out = fs::getWorkDir() + "svi/";
fs::mkDir(out.substr(0, out.length() - 1));
out += util::getIDStr(ut->tid) + ".svi";
FILE *svi = fopen(out.c_str(), "wb");
if(svi)
{
//Grab icon
NsApplicationControlData *ctrlData = new NsApplicationControlData;
uint64_t ctrlSize = 0;
nsGetApplicationControlData(NsApplicationControlSource_Storage, ut->tid, ctrlData, sizeof(NsApplicationControlData), &ctrlSize);
size_t jpegSize = ctrlSize - sizeof(ctrlData->nacp);
// Grab the current user title info.
data::userTitleInfo *userInfo = data::getCurrentUserTitleInfo();
fwrite(&ut->tid, sizeof(uint64_t), 1, svi);
fwrite(&t->nacp, sizeof(NacpStruct), 1, svi);
fwrite(ctrlData->icon, 1, jpegSize, svi);
fclose(svi);
delete ctrlData;
ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("popSVIExported", 0));
// Use that to grab the corresponding title info.
data::titleInfo *info = data::getTitleInfoByTID(userInfo->tid);
// Ensure the svi directory exists.
std::string sviPath = fs::getWorkDir() + "svi/";
fs::mkDir(sviPath.substr(0, sviPath.length() - 1));
// Append the application ID and extension.
sviPath += util::getIDStr(userInfo->tid) + ".svi";
// Try to open the file for writing.
std::FILE *sviFile = std::fopen(sviPath.data(), "wb");
if (!sviFile)
{
return;
}
// Write the application ID
std::fwrite(&userInfo->tid, 1, sizeof(uint64_t), sviFile);
// Control data.
std::fwrite(&info->data, 1, sizeof(NacpStruct), sviFile);
// Close the file.
std::fclose(sviFile);
// Toast.
ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("popSVIExported", 0));
}
static void infoPanelDraw(void *a)
@ -292,7 +324,13 @@ static void infoPanelDraw(void *a)
drawY += 40;
gfx::drawRect(panel, &ui::rectSh, 10, drawY, rectWidth, 38);
gfx::drawTextf(panel, 18, 20, drawY + 10, &ui::txtCont, ui::getUICString("infoStatus", 1), d->saveInfo.save_data_id);
gfx::drawTextf(panel,
18,
20,
drawY + 10,
&ui::txtCont,
ui::getUICString("infoStatus", 1),
d->saveInfo.save_data_id);
drawY += 40;
uint32_t hours, mins;
@ -303,23 +341,47 @@ static void infoPanelDraw(void *a)
drawY += 40;
gfx::drawRect(panel, &ui::rectSh, 10, drawY, rectWidth, 38);
gfx::drawTextf(panel, 18, 20, drawY + 10, &ui::txtCont, ui::getUICString("infoStatus", 3), d->playStats.total_launches);
gfx::drawTextf(panel,
18,
20,
drawY + 10,
&ui::txtCont,
ui::getUICString("infoStatus", 3),
d->playStats.total_launches);
drawY += 40;
gfx::drawRect(panel, &ui::rectLt, 10, drawY, rectWidth, 38);
gfx::drawTextf(panel, 18, 20, drawY + 10, &ui::txtCont, ui::getUICString("infoStatus", 5), ui::getUICString("saveDataTypeText", d->saveInfo.save_data_type));
gfx::drawTextf(panel,
18,
20,
drawY + 10,
&ui::txtCont,
ui::getUICString("infoStatus", 5),
ui::getUICString("saveDataTypeText", d->saveInfo.save_data_type));
drawY += 40;
uint8_t saveType = d->saveInfo.save_data_type;
if (saveType == FsSaveDataType_Cache)
{
gfx::drawRect(panel, &ui::rectSh, 10, drawY, rectWidth, 38);
gfx::drawTextf(panel, 18, 20, drawY + 10, &ui::txtCont, ui::getUICString("infoStatus", 6), d->saveInfo.save_data_index);
gfx::drawTextf(panel,
18,
20,
drawY + 10,
&ui::txtCont,
ui::getUICString("infoStatus", 6),
d->saveInfo.save_data_index);
drawY += 40;
}
gfx::drawRect(panel, saveType == FsSaveDataType_Cache ? &ui::rectLt : &ui::rectSh, 10, drawY, rectWidth, 38);
gfx::drawTextf(panel, 18, 20, drawY + 10, &ui::txtCont, ui::getUICString("infoStatus", 7), data::getCurrentUser()->getUsername().c_str());
gfx::drawTextf(panel,
18,
20,
drawY + 10,
&ui::txtCont,
ui::getUICString("infoStatus", 7),
data::getCurrentUser()->getUsername().c_str());
}
static void infoPanelCallback(void *a)

View File

@ -1,16 +1,16 @@
#include <string>
#include <vector>
#include <algorithm>
#include <string>
#include <switch.h>
#include <vector>
#include "file.h"
#include "data.h"
#include "file.h"
#include "type.h"
#include "ui.h"
#include "util.h"
#include "type.h"
#include "usr.h"
#include "ttl.h"
#include "usr.h"
static const char *settText = ui::getUICString("mainMenuSettings", 0), *extText = ui::getUICString("mainMenuExtras", 0);
@ -168,9 +168,11 @@ static void usrOptDeleteAllUserSaves_t(void *a)
for (data::userTitleInfo &tinf : u->titleInfo)
{
if(tinf.saveInfo.save_data_type != FsSaveDataType_System && (tinf.saveInfo.save_data_type != FsSaveDataType_Device || curUserIndex == devUser))
if (tinf.saveInfo.save_data_type != FsSaveDataType_System &&
(tinf.saveInfo.save_data_type != FsSaveDataType_Device || curUserIndex == devUser))
{
t->status->setStatus(ui::getUICString("threadStatusDeletingSaveData", 0), data::getTitleNameByTID(tinf.tid).c_str());
t->status->setStatus(ui::getUICString("threadStatusDeletingSaveData", 0),
data::getTitleNameByTID(tinf.tid).c_str());
fsDeleteSaveDataFileSystemBySaveDataSpaceId(FsSaveDataSpaceId_User, tinf.saveInfo.save_data_id);
}
}
@ -182,7 +184,12 @@ static void usrOptDeleteAllUserSaves_t(void *a)
static void usrOptDeleteAllUserSaves(void *a)
{
data::user *u = data::getCurrentUser();
ui::confirmArgs *conf = ui::confirmArgsCreate(true, usrOptDeleteAllUserSaves_t, NULL, NULL, ui::getUICString("saveDataDeleteAllUser", 0), u->getUsername().c_str());
ui::confirmArgs *conf = ui::confirmArgsCreate(true,
usrOptDeleteAllUserSaves_t,
NULL,
NULL,
ui::getUICString("saveDataDeleteAllUser", 0),
u->getUsername().c_str());
ui::confirm(conf);
}
@ -284,7 +291,12 @@ static void usrOptCreateAllSaves_t(void *a)
static void usrOptCreateAllSaves(void *a)
{
data::user *u = data::getCurrentUser();
ui::confirmArgs *conf = ui::confirmArgsCreate(true, usrOptCreateAllSaves_t, NULL, NULL, ui::getUICString("confirmCreateAllSaveData", 0), u->getUsername().c_str());
ui::confirmArgs *conf = ui::confirmArgsCreate(true,
usrOptCreateAllSaves_t,
NULL,
NULL,
ui::getUICString("confirmCreateAllSaveData", 0),
u->getUsername().c_str());
ui::confirm(conf);
}
@ -304,7 +316,7 @@ static void initSaveCreateMenus()
//Group into vectors to match
for (auto &t : data::titles)
{
NacpStruct *nacp = &t.second.nacp;
NacpStruct *nacp = &t.second.data.nacp;
if (nacp->user_account_save_data_size > 0)
accSids.push_back(t.first);
@ -315,7 +327,8 @@ static void initSaveCreateMenus()
if (nacp->bcat_delivery_cache_storage_size > 0)
bcatSids.push_back(t.first);
if(nacp->cache_storage_size > 0 || nacp->cache_storage_journal_size > 0 || nacp->cache_storage_data_and_journal_size_max > 0)
if (nacp->cache_storage_size > 0 || nacp->cache_storage_journal_size > 0 ||
nacp->cache_storage_data_and_journal_size_max > 0)
cacheSids.push_back(t.first);
}

View File

@ -1,17 +1,17 @@
#include <string>
#include <cstdio>
#include <ctime>
#include <sys/stat.h>
#include <json-c/json.h>
#include <string>
#include <sys/stat.h>
#include "file.h"
#include "data.h"
#include "gfx.h"
#include "util.h"
#include "ui.h"
#include "curlfuncs.h"
#include "type.h"
#include "cfg.h"
#include "curlfuncs.h"
#include "data.h"
#include "file.h"
#include "gfx.h"
#include "type.h"
#include "ui.h"
#include "util.h"
static const uint32_t verboten[] = {L',', L'/', L'\\', L'<', L'>', L':', L'"', L'|', L'?', L'*', L'', L'©', L'®'};
@ -95,11 +95,25 @@ std::string util::getDateTime(int fmt)
switch (fmt)
{
case DATE_FMT_YMD:
sprintf(ret, "%04d.%02d.%02d @ %02d.%02d.%02d", Time->tm_year + 1900, Time->tm_mon + 1, Time->tm_mday, Time->tm_hour, Time->tm_min, Time->tm_sec);
sprintf(ret,
"%04d.%02d.%02d @ %02d.%02d.%02d",
Time->tm_year + 1900,
Time->tm_mon + 1,
Time->tm_mday,
Time->tm_hour,
Time->tm_min,
Time->tm_sec);
break;
case DATE_FMT_YDM:
sprintf(ret, "%04d.%02d.%02d @ %02d.%02d.%02d", Time->tm_year + 1900, Time->tm_mday, Time->tm_mon + 1, Time->tm_hour, Time->tm_min, Time->tm_sec);
sprintf(ret,
"%04d.%02d.%02d @ %02d.%02d.%02d",
Time->tm_year + 1900,
Time->tm_mday,
Time->tm_mon + 1,
Time->tm_hour,
Time->tm_min,
Time->tm_sec);
break;
case DATE_FMT_HOYSTE:
@ -107,7 +121,13 @@ std::string util::getDateTime(int fmt)
break;
case DATE_FMT_JHK:
sprintf(ret, "%04d%02d%02d_%02d%02d", Time->tm_year + 1900, Time->tm_mon + 1, Time->tm_mday, Time->tm_hour, Time->tm_min);
sprintf(ret,
"%04d%02d%02d_%02d%02d",
Time->tm_year + 1900,
Time->tm_mon + 1,
Time->tm_mday,
Time->tm_hour,
Time->tm_min);
break;
case DATE_FMT_ASC:
@ -191,7 +211,12 @@ static inline std::string getTimeString(const uint32_t& _h, const uint32_t& _m)
return std::string(tmp);
}
std::string util::getStringInput(SwkbdType _type, const std::string& def, const std::string& head, size_t maxLength, unsigned dictCnt, const std::string dictWords[])
std::string util::getStringInput(SwkbdType _type,
const std::string &def,
const std::string &head,
size_t maxLength,
unsigned dictCnt,
const std::string dictWords[])
{
SwkbdConfig swkbd;
swkbdCreate(&swkbd, dictCnt);
@ -240,7 +265,7 @@ std::string util::getFilenameFromPath(const std::string& get)
return "";
}
std::string util::generateAbbrev(const uint64_t& tid)
std::string util::generateAbbrev(uint64_t tid)
{
data::titleInfo *tmp = data::getTitleInfoByTID(tid);
size_t titleLength = tmp->safeTitle.length();
@ -349,7 +374,6 @@ void util::sysNormal()
clkrstCloseSession(&gpu);
clkrstCloseSession(&ram);
clkrstExit();
}
void util::checkForUpdate(void *a)
@ -394,7 +418,7 @@ void util::checkForUpdate(void *a)
t->finished = true;
}
std::string util::getSizeString(const uint64_t& _size)
std::string util::getSizeString(uint64_t _size)
{
char sizeStr[32];
if (_size >= 0x40000000)
@ -407,14 +431,3 @@ std::string util::getSizeString(const uint64_t& _size)
sprintf(sizeStr, "%lu Bytes", _size);
return std::string(sizeStr);
}
Result util::accountDeleteUser(AccountUid *uid)
{
Service *account = accountGetServiceSession();
struct
{
AccountUid uid;
} in = {*uid};
return serviceDispatchIn(account, 203, in);
}