add support for finding daybreak in non-standard paths (#62)
This commit is contained in:
@@ -76,4 +76,10 @@ auto nro_add_arg_file(std::string arg) -> std::string;
|
|||||||
// strips sdmc:
|
// strips sdmc:
|
||||||
auto nro_normalise_path(const std::string& p) -> std::string;
|
auto nro_normalise_path(const std::string& p) -> std::string;
|
||||||
|
|
||||||
|
// helpers to find nro entry, will be made methods soon once i convert vector into a struct.
|
||||||
|
auto nro_find(std::span<const NroEntry> array, std::string_view name, std::string_view author, const fs::FsPath& path) -> std::optional<NroEntry>;
|
||||||
|
auto nro_find_name(std::span<const NroEntry> array, std::string_view name) -> std::optional<NroEntry>;
|
||||||
|
auto nro_find_author(std::span<const NroEntry> array, std::string_view author) -> std::optional<NroEntry>;
|
||||||
|
auto nro_find_path(std::span<const NroEntry> array, const fs::FsPath& path) -> std::optional<NroEntry>;
|
||||||
|
|
||||||
} // namespace sphaira
|
} // namespace sphaira
|
||||||
|
|||||||
@@ -203,6 +203,7 @@ private:
|
|||||||
void OnDeleteCallback();
|
void OnDeleteCallback();
|
||||||
void OnPasteCallback();
|
void OnPasteCallback();
|
||||||
void OnRenameCallback();
|
void OnRenameCallback();
|
||||||
|
auto CheckIfUpdateFolder() -> Result;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr inline const char* INI_SECTION = "filebrowser";
|
static constexpr inline const char* INI_SECTION = "filebrowser";
|
||||||
@@ -215,6 +216,8 @@ private:
|
|||||||
std::vector<u32> m_entries_index_search; // files found via search
|
std::vector<u32> m_entries_index_search; // files found via search
|
||||||
std::span<u32> m_entries_current;
|
std::span<u32> m_entries_current;
|
||||||
|
|
||||||
|
std::optional<fs::FsPath> m_daybreak_path;
|
||||||
|
|
||||||
// search options
|
// search options
|
||||||
// show files [X]
|
// show files [X]
|
||||||
// show folders [X]
|
// show folders [X]
|
||||||
|
|||||||
@@ -309,4 +309,37 @@ auto nro_normalise_path(const std::string& p) -> std::string {
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto nro_find(std::span<const NroEntry> array, std::string_view name, std::string_view author, const fs::FsPath& path) -> std::optional<NroEntry> {
|
||||||
|
const auto it = std::find_if(array.cbegin(), array.cend(), [name, author, path](auto& e){
|
||||||
|
if (!name.empty() && !author.empty() && !path.empty()) {
|
||||||
|
return e.GetName() == name && e.GetAuthor() == author && e.path == path;
|
||||||
|
} else if (!name.empty()) {
|
||||||
|
return e.GetName() == name;
|
||||||
|
} else if (!author.empty()) {
|
||||||
|
return e.GetAuthor() == author;
|
||||||
|
} else if (!path.empty()) {
|
||||||
|
return e.path == path;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (it == array.cend()) {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *it;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto nro_find_name(std::span<const NroEntry> array, std::string_view name) -> std::optional<NroEntry> {
|
||||||
|
return nro_find(array, name, {}, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
auto nro_find_author(std::span<const NroEntry> array, std::string_view author) -> std::optional<NroEntry> {
|
||||||
|
return nro_find(array, {}, author, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
auto nro_find_path(std::span<const NroEntry> array, const fs::FsPath& path) -> std::optional<NroEntry> {
|
||||||
|
return nro_find(array, {}, {}, path);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace sphaira
|
} // namespace sphaira
|
||||||
|
|||||||
@@ -248,36 +248,6 @@ auto GetRomIcon(ProgressBox* pbox, std::string filename, std::string extension,
|
|||||||
return nro_get_icon(nro.path, nro.icon_size, nro.icon_offset);
|
return nro_get_icon(nro.path, nro.icon_size, nro.icon_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns 0 if true
|
|
||||||
auto CheckIfUpdateFolder(const fs::FsPath& path, std::span<FileEntry> entries) -> Result {
|
|
||||||
fs::FsNativeSd fs;
|
|
||||||
R_TRY(fs.GetFsOpenResult());
|
|
||||||
|
|
||||||
// check that we have daybreak installed
|
|
||||||
R_UNLESS(fs.FileExists(DAYBREAK_PATH), FsError_FileNotFound);
|
|
||||||
|
|
||||||
FsDir d;
|
|
||||||
R_TRY(fs.OpenDirectory(path, FsDirOpenMode_ReadDirs, &d));
|
|
||||||
ON_SCOPE_EXIT(fs.DirClose(&d));
|
|
||||||
|
|
||||||
s64 count;
|
|
||||||
R_TRY(fs.DirGetEntryCount(&d, &count));
|
|
||||||
|
|
||||||
// check that we are at the bottom level
|
|
||||||
R_UNLESS(count == 0, 0x1);
|
|
||||||
// check that we have enough ncas and not too many
|
|
||||||
R_UNLESS(entries.size() > 150 && entries.size() < 300, 0x1);
|
|
||||||
|
|
||||||
// check that all entries end in .nca
|
|
||||||
const auto nca_ext = std::string_view{".nca"};
|
|
||||||
for (auto& e : entries) {
|
|
||||||
const auto ext = std::strrchr(e.name, '.');
|
|
||||||
R_UNLESS(ext && ext == nca_ext, 0x1);
|
|
||||||
}
|
|
||||||
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto get_collection(fs::FsNative& fs, const fs::FsPath& path, const fs::FsPath& parent_name, FsDirCollection& out, bool inc_file, bool inc_dir, bool inc_size) -> Result {
|
auto get_collection(fs::FsNative& fs, const fs::FsPath& path, const fs::FsPath& parent_name, FsDirCollection& out, bool inc_file, bool inc_dir, bool inc_size) -> Result {
|
||||||
out.path = path;
|
out.path = path;
|
||||||
out.parent_name = parent_name;
|
out.parent_name = parent_name;
|
||||||
@@ -376,12 +346,12 @@ Menu::Menu(const std::vector<NroEntry>& nro_entries) : MenuBase{"FileBrowser"_i1
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_is_update_folder) {
|
if (m_is_update_folder && m_daybreak_path.has_value()) {
|
||||||
App::Push(std::make_shared<OptionBox>("Open with DayBreak?"_i18n, "No"_i18n, "Yes"_i18n, 1, [this](auto op_index){
|
App::Push(std::make_shared<OptionBox>("Open with DayBreak?"_i18n, "No"_i18n, "Yes"_i18n, 1, [this](auto op_index){
|
||||||
if (op_index && *op_index) {
|
if (op_index && *op_index) {
|
||||||
// daybreak uses native fs so do not use nro_add_arg_file
|
// daybreak uses native fs so do not use nro_add_arg_file
|
||||||
// otherwise it'll fail to open the folder...
|
// otherwise it'll fail to open the folder...
|
||||||
nro_launch(DAYBREAK_PATH, nro_add_arg(m_path));
|
nro_launch(m_daybreak_path.value(), nro_add_arg(m_path));
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
return;
|
return;
|
||||||
@@ -956,7 +926,7 @@ auto Menu::Scan(const fs::FsPath& new_path, bool is_walk_up) -> Result {
|
|||||||
Sort();
|
Sort();
|
||||||
|
|
||||||
// quick check to see if this is an update folder
|
// quick check to see if this is an update folder
|
||||||
m_is_update_folder = R_SUCCEEDED(CheckIfUpdateFolder(new_path, m_entries));
|
m_is_update_folder = R_SUCCEEDED(CheckIfUpdateFolder());
|
||||||
|
|
||||||
SetIndex(0);
|
SetIndex(0);
|
||||||
|
|
||||||
@@ -1462,6 +1432,53 @@ void Menu::OnRenameCallback() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto Menu::CheckIfUpdateFolder() -> Result {
|
||||||
|
// check if we have already tried to find daybreak
|
||||||
|
if (m_daybreak_path.has_value() && m_daybreak_path.value().empty()) {
|
||||||
|
return FsError_FileNotFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
fs::FsNativeSd fs;
|
||||||
|
R_TRY(fs.GetFsOpenResult());
|
||||||
|
|
||||||
|
// check that we have daybreak installed
|
||||||
|
if (!m_daybreak_path.has_value()) {
|
||||||
|
auto daybreak_path = DAYBREAK_PATH;
|
||||||
|
if (!fs.FileExists(DAYBREAK_PATH)) {
|
||||||
|
if (auto e = nro_find(m_nro_entries, "Daybreak", "Atmosphere-NX", {}); e.has_value()) {
|
||||||
|
daybreak_path = e.value().path;
|
||||||
|
} else {
|
||||||
|
log_write("failed to find daybreak\n");
|
||||||
|
m_daybreak_path = "";
|
||||||
|
return FsError_FileNotFound;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_daybreak_path = daybreak_path;
|
||||||
|
log_write("found daybreak in: %s\n", m_daybreak_path.value().s);
|
||||||
|
}
|
||||||
|
|
||||||
|
FsDir d;
|
||||||
|
R_TRY(fs.OpenDirectory(m_path, FsDirOpenMode_ReadDirs, &d));
|
||||||
|
ON_SCOPE_EXIT(fs.DirClose(&d));
|
||||||
|
|
||||||
|
s64 count;
|
||||||
|
R_TRY(fs.DirGetEntryCount(&d, &count));
|
||||||
|
|
||||||
|
// check that we are at the bottom level
|
||||||
|
R_UNLESS(count == 0, 0x1);
|
||||||
|
// check that we have enough ncas and not too many
|
||||||
|
R_UNLESS(m_entries.size() > 150 && m_entries.size() < 300, 0x1);
|
||||||
|
|
||||||
|
// check that all entries end in .nca
|
||||||
|
const auto nca_ext = std::string_view{".nca"};
|
||||||
|
for (auto& e : m_entries) {
|
||||||
|
const auto ext = std::strrchr(e.name, '.');
|
||||||
|
R_UNLESS(ext && ext == nca_ext, 0x1);
|
||||||
|
}
|
||||||
|
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace sphaira::ui::menu::filebrowser
|
} // namespace sphaira::ui::menu::filebrowser
|
||||||
|
|
||||||
// options
|
// options
|
||||||
|
|||||||
Reference in New Issue
Block a user