mirror of
https://github.com/joel16/NX-Shell.git
synced 2024-11-26 21:20:27 +00:00
115 lines
4.1 KiB
C++
115 lines
4.1 KiB
C++
#include <cstdio>
|
|
#include <cstring>
|
|
#include <jansson.h>
|
|
|
|
#include "config.hpp"
|
|
#include "fs.hpp"
|
|
#include "log.hpp"
|
|
|
|
#define CONFIG_VERSION 5
|
|
|
|
config_t cfg;
|
|
|
|
namespace Config {
|
|
static const char *config_path = "/switch/NX-Shell/config.json";
|
|
static const char *config_file = "{\n\t\"config_version\": %d,\n\t\"language\": %d,\n\t\"dev_options\": %d,\n\t\"image_filename\": %d,\n\t\"multi_lang\": %d\n}";
|
|
static int config_version_holder = 0;
|
|
static const int buf_size = 128;
|
|
|
|
int Save(config_t &config) {
|
|
Result ret = 0;
|
|
char *buf = new char[buf_size];
|
|
u64 len = std::snprintf(buf, buf_size, config_file, CONFIG_VERSION, config.lang, config.dev_options, config.image_filename, config.multi_lang);
|
|
|
|
// Delete and re-create the file, we don't care about the return value here.
|
|
fsFsDeleteFile(std::addressof(devices[FileSystemSDMC]), config_path);
|
|
fsFsCreateFile(std::addressof(devices[FileSystemSDMC]), config_path, len, 0);
|
|
|
|
FsFile file;
|
|
if (R_FAILED(ret = fsFsOpenFile(std::addressof(devices[FileSystemSDMC]), config_path, FsOpenMode_Write, std::addressof(file)))) {
|
|
Log::Error("Config::Save fsFsOpenFile(%s) failed: 0x%x\n", config_path, ret);
|
|
delete[] buf;
|
|
return ret;
|
|
}
|
|
|
|
if (R_FAILED(ret = fsFileWrite(std::addressof(file), 0, buf, len, FsWriteOption_Flush))) {
|
|
Log::Error("Config::Save fsFileWrite(%s) failed: 0x%x\n", config_path, ret);
|
|
delete[] buf;
|
|
fsFileClose(std::addressof(file));
|
|
return ret;
|
|
}
|
|
|
|
fsFileClose(std::addressof(file));
|
|
delete[] buf;
|
|
return 0;
|
|
}
|
|
|
|
int Load(void) {
|
|
Result ret = 0;
|
|
|
|
if (!FS::DirExists("/switch/"))
|
|
fsFsCreateDirectory(std::addressof(devices[FileSystemSDMC]), "/switch");
|
|
if (!FS::DirExists("/switch/NX-Shell/"))
|
|
fsFsCreateDirectory(std::addressof(devices[FileSystemSDMC]), "/switch/NX-Shell");
|
|
|
|
if (!FS::FileExists(config_path)) {
|
|
cfg = {};
|
|
return Config::Save(cfg);
|
|
}
|
|
|
|
FsFile file;
|
|
if (R_FAILED(ret = fsFsOpenFile(std::addressof(devices[FileSystemSDMC]), config_path, FsOpenMode_Read, std::addressof(file))))
|
|
return ret;
|
|
|
|
s64 size = 0;
|
|
if (R_FAILED(ret = fsFileGetSize(std::addressof(file), std::addressof(size)))) {
|
|
fsFileClose(std::addressof(file));
|
|
return ret;
|
|
}
|
|
|
|
char *buf = new char[size + 1];
|
|
if (R_FAILED(ret = fsFileRead(std::addressof(file), 0, buf, static_cast<u64>(size) + 1, FsReadOption_None, nullptr))) {
|
|
delete[] buf;
|
|
fsFileClose(std::addressof(file));
|
|
return ret;
|
|
}
|
|
|
|
fsFileClose(std::addressof(file));
|
|
|
|
json_t *root;
|
|
json_error_t error;
|
|
root = json_loads(buf, 0, std::addressof(error));
|
|
delete[] buf;
|
|
|
|
if (!root) {
|
|
std::printf("error: on line %d: %s\n", error.line, error.text);
|
|
return -1;
|
|
}
|
|
|
|
json_t *config_ver = json_object_get(root, "config_version");
|
|
config_version_holder = json_integer_value(config_ver);
|
|
|
|
// Delete config file if config file is updated. This will rarely happen.
|
|
if (config_version_holder < CONFIG_VERSION) {
|
|
fsFsDeleteFile(std::addressof(devices[FileSystemSDMC]), config_path);
|
|
cfg = {};
|
|
return Config::Save(cfg);
|
|
}
|
|
|
|
json_t *language = json_object_get(root, "language");
|
|
cfg.lang = json_integer_value(language);
|
|
|
|
json_t *dev_options = json_object_get(root, "dev_options");
|
|
cfg.dev_options = json_integer_value(dev_options);
|
|
|
|
json_t *image_filename = json_object_get(root, "image_filename");
|
|
cfg.image_filename = json_integer_value(image_filename);
|
|
|
|
json_t *multi_lang = json_object_get(root, "multi_lang");
|
|
cfg.multi_lang = json_integer_value(multi_lang);
|
|
|
|
json_decref(root);
|
|
return 0;
|
|
}
|
|
}
|