mirror of
https://github.com/J-D-K/JKSV.git
synced 2026-03-21 17:24:37 -05:00
Minor code revisions in preparation for cache system on 20.0+
This commit is contained in:
parent
291d2fd82f
commit
c094030c52
136
.clang-format
Normal file
136
.clang-format
Normal 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
9
.clang-tidy
Normal 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
11
.gitattributes
vendored
Normal 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
1
.gitignore
vendored
|
|
@ -2,6 +2,7 @@ build/
|
|||
.vscode/
|
||||
*.cbp
|
||||
*.layout
|
||||
.editorconfig
|
||||
|
||||
.idea/
|
||||
cmake-build-debug/
|
||||
|
|
|
|||
21
inc/cfg.h
21
inc/cfg.h
|
|
@ -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
|
||||
|
|
|
|||
64
inc/data.h
64
inc/data.h
|
|
@ -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
|
||||
|
|
|
|||
26
inc/fs.h
26
inc/fs.h
|
|
@ -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
|
||||
|
|
|
|||
47
inc/fs/dir.h
47
inc/fs/dir.h
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
27
inc/util.h
27
inc/util.h
|
|
@ -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
|
||||
|
|
|
|||
89
src/cfg.cpp
89
src/cfg.cpp
|
|
@ -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);
|
||||
|
|
|
|||
384
src/data.cpp
384
src/data.cpp
|
|
@ -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()
|
||||
{
|
||||
|
|
|
|||
152
src/fs.cpp
152
src/fs.cpp
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
132
src/ui/ttl.cpp
132
src/ui/ttl.cpp
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
67
src/util.cpp
67
src/util.cpp
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user