fix yati not setting correct version, add support for using zip name when creating forwarder, remove some dead code.
fixes #126 fixes #127
This commit is contained in:
@@ -2,3 +2,4 @@
|
|||||||
path=/retroarch/cores/fbneo_libretro_libnx.nro
|
path=/retroarch/cores/fbneo_libretro_libnx.nro
|
||||||
supported_extensions=zip|7z|cue|ccd
|
supported_extensions=zip|7z|cue|ccd
|
||||||
database=FBNeo - Arcade Games
|
database=FBNeo - Arcade Games
|
||||||
|
use_base_name=true
|
||||||
|
|||||||
@@ -2,3 +2,4 @@
|
|||||||
path=/retroarch/cores/mame2000_libretro_libnx.nro
|
path=/retroarch/cores/mame2000_libretro_libnx.nro
|
||||||
supported_extensions=zip|7z
|
supported_extensions=zip|7z
|
||||||
database=MAME 2000
|
database=MAME 2000
|
||||||
|
use_base_name=true
|
||||||
|
|||||||
@@ -2,3 +2,4 @@
|
|||||||
path=/retroarch/cores/mame2003_libretro_libnx.nro
|
path=/retroarch/cores/mame2003_libretro_libnx.nro
|
||||||
supported_extensions=zip
|
supported_extensions=zip
|
||||||
database=MAME 2003
|
database=MAME 2003
|
||||||
|
use_base_name=true
|
||||||
|
|||||||
@@ -2,3 +2,4 @@
|
|||||||
path=/retroarch/cores/mame2003_plus_libretro_libnx.nro
|
path=/retroarch/cores/mame2003_plus_libretro_libnx.nro
|
||||||
supported_extensions=zip
|
supported_extensions=zip
|
||||||
database=MAME 2003-Plus
|
database=MAME 2003-Plus
|
||||||
|
use_base_name=true
|
||||||
|
|||||||
@@ -2,3 +2,4 @@
|
|||||||
path=/retroarch/cores/xrick_libretro_libnx.nro
|
path=/retroarch/cores/xrick_libretro_libnx.nro
|
||||||
supported_extensions=zip
|
supported_extensions=zip
|
||||||
database=Rick Dangerous
|
database=Rick Dangerous
|
||||||
|
use_base_name=true
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ public:
|
|||||||
static void SetTheme(s64 theme_index);
|
static void SetTheme(s64 theme_index);
|
||||||
static auto GetThemeIndex() -> s64;
|
static auto GetThemeIndex() -> s64;
|
||||||
|
|
||||||
static auto GetDefaultImage(int* w = nullptr, int* h = nullptr) -> int;
|
static auto GetDefaultImage() -> int;
|
||||||
|
|
||||||
// returns argv[0]
|
// returns argv[0]
|
||||||
static auto GetExePath() -> fs::FsPath;
|
static auto GetExePath() -> fs::FsPath;
|
||||||
@@ -185,7 +185,6 @@ public:
|
|||||||
option::OptionBool m_allow_downgrade{INI_SECTION, "allow_downgrade", false};
|
option::OptionBool m_allow_downgrade{INI_SECTION, "allow_downgrade", false};
|
||||||
option::OptionBool m_skip_if_already_installed{INI_SECTION, "skip_if_already_installed", true};
|
option::OptionBool m_skip_if_already_installed{INI_SECTION, "skip_if_already_installed", true};
|
||||||
option::OptionBool m_ticket_only{INI_SECTION, "ticket_only", false};
|
option::OptionBool m_ticket_only{INI_SECTION, "ticket_only", false};
|
||||||
option::OptionBool m_patch_ticket{INI_SECTION, "patch_ticket", true};
|
|
||||||
option::OptionBool m_skip_base{INI_SECTION, "skip_base", false};
|
option::OptionBool m_skip_base{INI_SECTION, "skip_base", false};
|
||||||
option::OptionBool m_skip_patch{INI_SECTION, "skip_patch", false};
|
option::OptionBool m_skip_patch{INI_SECTION, "skip_patch", false};
|
||||||
option::OptionBool m_skip_addon{INI_SECTION, "skip_addon", false};
|
option::OptionBool m_skip_addon{INI_SECTION, "skip_addon", false};
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ struct FileAssocEntry {
|
|||||||
std::string name{}; // ini name
|
std::string name{}; // ini name
|
||||||
std::vector<std::string> ext{}; // list of ext
|
std::vector<std::string> ext{}; // list of ext
|
||||||
std::vector<std::string> database{}; // list of systems
|
std::vector<std::string> database{}; // list of systems
|
||||||
|
bool use_base_name{}; // if set, uses base name (rom.zip) otherwise uses internal name (rom.gba)
|
||||||
|
|
||||||
auto IsExtension(std::string_view extension, std::string_view internal_extension) const -> bool {
|
auto IsExtension(std::string_view extension, std::string_view internal_extension) const -> bool {
|
||||||
for (const auto& assoc_ext : ext) {
|
for (const auto& assoc_ext : ext) {
|
||||||
|
|||||||
@@ -78,6 +78,6 @@ Result SetTicketData(std::span<u8> ticket, const es::TicketData* in);
|
|||||||
|
|
||||||
Result GetTitleKey(keys::KeyEntry& out, const TicketData& data, const keys::Keys& keys);
|
Result GetTitleKey(keys::KeyEntry& out, const TicketData& data, const keys::Keys& keys);
|
||||||
Result DecryptTitleKey(keys::KeyEntry& out, u8 key_gen, const keys::Keys& keys);
|
Result DecryptTitleKey(keys::KeyEntry& out, u8 key_gen, const keys::Keys& keys);
|
||||||
Result PatchTicket(std::span<u8> ticket, const keys::Keys& keys, bool convert_personalised);
|
Result PatchTicket(std::span<u8> ticket, const keys::Keys& keys);
|
||||||
|
|
||||||
} // namespace sphaira::es
|
} // namespace sphaira::es
|
||||||
|
|||||||
@@ -79,11 +79,6 @@ struct Config {
|
|||||||
// installs tickets only.
|
// installs tickets only.
|
||||||
bool ticket_only{};
|
bool ticket_only{};
|
||||||
|
|
||||||
// converts personalised tickets to common tickets, allows for offline play.
|
|
||||||
// this breaks ticket signature so es needs to be patched.
|
|
||||||
// modified common tickets are patched regardless of this setting.
|
|
||||||
bool patch_ticket{};
|
|
||||||
|
|
||||||
// flags to enable / disable install of specific types.
|
// flags to enable / disable install of specific types.
|
||||||
bool skip_base{};
|
bool skip_base{};
|
||||||
bool skip_patch{};
|
bool skip_patch{};
|
||||||
|
|||||||
@@ -544,7 +544,7 @@ auto App::GetThemeIndex() -> s64 {
|
|||||||
return g_app->m_theme_index;
|
return g_app->m_theme_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto App::GetDefaultImage(int* w, int* h) -> int {
|
auto App::GetDefaultImage() -> int {
|
||||||
return g_app->m_default_image;
|
return g_app->m_default_image;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1392,8 +1392,33 @@ App::App(const char* argv0) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// soon (tm)
|
struct EventDay {
|
||||||
// ui::bubble::Init();
|
u8 day;
|
||||||
|
u8 month;
|
||||||
|
};
|
||||||
|
|
||||||
|
static constexpr EventDay event_days[] = {
|
||||||
|
{ .day = 1, .month = 1 }, // New years
|
||||||
|
|
||||||
|
{ .day = 3, .month = 3 }, // March 3 (switch 1)
|
||||||
|
{ .day = 10, .month = 5 }, // June 10 (switch 2)
|
||||||
|
{ .day = 15, .month = 5 }, // June 15
|
||||||
|
|
||||||
|
{ .day = 25, .month = 12 }, // Christmas
|
||||||
|
{ .day = 26, .month = 12 },
|
||||||
|
{ .day = 27, .month = 12 },
|
||||||
|
{ .day = 28, .month = 12 },
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto time = std::time(nullptr);
|
||||||
|
const auto tm = std::localtime(&time);
|
||||||
|
|
||||||
|
for (auto e : event_days) {
|
||||||
|
if (e.day == tm->tm_mday && e.month == (tm->tm_mon + 1)) {
|
||||||
|
ui::bubble::Init();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
App::Push(std::make_shared<ui::menu::main::MainMenu>());
|
App::Push(std::make_shared<ui::menu::main::MainMenu>());
|
||||||
log_write("finished app constructor\n");
|
log_write("finished app constructor\n");
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ auto GetRomDatabaseFromPath(std::string_view path) -> RomDatabaseIndexs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
auto GetRomIcon(fs::FsNative* fs, ProgressBox* pbox, std::string filename, std::string extension, const RomDatabaseIndexs& db_indexs, const NroEntry& nro) {
|
auto GetRomIcon(fs::FsNative* fs, ProgressBox* pbox, std::string filename, const RomDatabaseIndexs& db_indexs, const NroEntry& nro) {
|
||||||
// if no db entries, use nro icon
|
// if no db entries, use nro icon
|
||||||
if (db_indexs.empty()) {
|
if (db_indexs.empty()) {
|
||||||
log_write("using nro image\n");
|
log_write("using nro image\n");
|
||||||
@@ -812,8 +812,7 @@ void Menu::InstallForwarder() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
log_write("got nro data\n");
|
log_write("got nro data\n");
|
||||||
std::string file_name = GetEntry().GetInternalName();
|
auto file_name = assoc.use_base_name ? GetEntry().GetName() : GetEntry().GetInternalName();
|
||||||
std::string extension = GetEntry().GetInternalExtension();
|
|
||||||
|
|
||||||
if (auto pos = file_name.find_last_of('.'); pos != std::string::npos) {
|
if (auto pos = file_name.find_last_of('.'); pos != std::string::npos) {
|
||||||
log_write("got filename\n");
|
log_write("got filename\n");
|
||||||
@@ -829,7 +828,7 @@ void Menu::InstallForwarder() {
|
|||||||
config.name = nro.nacp.lang[0].name + std::string{" | "} + file_name;
|
config.name = nro.nacp.lang[0].name + std::string{" | "} + file_name;
|
||||||
// config.name = file_name;
|
// config.name = file_name;
|
||||||
config.nacp = nro.nacp;
|
config.nacp = nro.nacp;
|
||||||
config.icon = GetRomIcon(m_fs.get(), pbox, file_name, extension, db_indexs, nro);
|
config.icon = GetRomIcon(m_fs.get(), pbox, file_name, db_indexs, nro);
|
||||||
|
|
||||||
return R_SUCCEEDED(App::Install(pbox, config));
|
return R_SUCCEEDED(App::Install(pbox, config));
|
||||||
}));
|
}));
|
||||||
@@ -1035,6 +1034,10 @@ void Menu::LoadAssocEntriesPath(const fs::FsPath& path) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (!strcmp(Key, "use_base_name")) {
|
||||||
|
if (!strcmp(Value, "true") || !strcmp(Value, "1")) {
|
||||||
|
assoc->use_base_name = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}, &assoc, full_path);
|
}, &assoc, full_path);
|
||||||
|
|||||||
@@ -391,10 +391,6 @@ MainMenu::MainMenu() {
|
|||||||
App::GetApp()->m_ticket_only.Set(enable);
|
App::GetApp()->m_ticket_only.Set(enable);
|
||||||
}, "Enabled"_i18n, "Disabled"_i18n));
|
}, "Enabled"_i18n, "Disabled"_i18n));
|
||||||
|
|
||||||
options->Add(std::make_shared<SidebarEntryBool>("Patch ticket"_i18n, App::GetApp()->m_patch_ticket.Get(), [this](bool& enable){
|
|
||||||
App::GetApp()->m_patch_ticket.Set(enable);
|
|
||||||
}, "Enabled"_i18n, "Disabled"_i18n));
|
|
||||||
|
|
||||||
options->Add(std::make_shared<SidebarEntryBool>("Skip base"_i18n, App::GetApp()->m_skip_base.Get(), [this](bool& enable){
|
options->Add(std::make_shared<SidebarEntryBool>("Skip base"_i18n, App::GetApp()->m_skip_base.Get(), [this](bool& enable){
|
||||||
App::GetApp()->m_skip_base.Set(enable);
|
App::GetApp()->m_skip_base.Set(enable);
|
||||||
}, "Enabled"_i18n, "Disabled"_i18n));
|
}, "Enabled"_i18n, "Disabled"_i18n));
|
||||||
|
|||||||
@@ -106,13 +106,13 @@ Result DecryptTitleKey(keys::KeyEntry& out, u8 key_gen, const keys::Keys& keys)
|
|||||||
|
|
||||||
// todo: i thought i already wrote the code for this??
|
// todo: i thought i already wrote the code for this??
|
||||||
// todo: patch the ticket.
|
// todo: patch the ticket.
|
||||||
Result PatchTicket(std::span<u8> ticket, const keys::Keys& keys, bool convert_personalised) {
|
Result PatchTicket(std::span<u8> ticket, const keys::Keys& keys) {
|
||||||
TicketData data;
|
TicketData data;
|
||||||
R_TRY(GetTicketData(ticket, &data));
|
R_TRY(GetTicketData(ticket, &data));
|
||||||
|
|
||||||
if (data.title_key_type == es::TicketTitleKeyType_Common) {
|
if (data.title_key_type == es::TicketTitleKeyType_Common) {
|
||||||
// todo: verify common signature
|
// todo: verify common signature
|
||||||
} else if (data.title_key_type == es::TicketTitleKeyType_Personalized && convert_personalised) {
|
} else if (data.title_key_type == es::TicketTitleKeyType_Personalized) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -797,7 +797,6 @@ Result Yati::Setup() {
|
|||||||
config.allow_downgrade = App::GetApp()->m_allow_downgrade.Get();
|
config.allow_downgrade = App::GetApp()->m_allow_downgrade.Get();
|
||||||
config.skip_if_already_installed = App::GetApp()->m_skip_if_already_installed.Get();
|
config.skip_if_already_installed = App::GetApp()->m_skip_if_already_installed.Get();
|
||||||
config.ticket_only = App::GetApp()->m_ticket_only.Get();
|
config.ticket_only = App::GetApp()->m_ticket_only.Get();
|
||||||
config.patch_ticket = App::GetApp()->m_patch_ticket.Get();
|
|
||||||
config.skip_base = App::GetApp()->m_skip_base.Get();
|
config.skip_base = App::GetApp()->m_skip_base.Get();
|
||||||
config.skip_patch = App::GetApp()->m_skip_patch.Get();
|
config.skip_patch = App::GetApp()->m_skip_patch.Get();
|
||||||
config.skip_addon = App::GetApp()->m_skip_addon.Get();
|
config.skip_addon = App::GetApp()->m_skip_addon.Get();
|
||||||
@@ -1078,7 +1077,7 @@ Result Yati::GetLatestVersion(const CnmtCollection& cnmt, u32& version_out, bool
|
|||||||
// TODO: fix this when gamecard is inserted as it will only return records
|
// TODO: fix this when gamecard is inserted as it will only return records
|
||||||
// for the gamecard...
|
// for the gamecard...
|
||||||
// may have to use ncm directly to get the keys, then parse that.
|
// may have to use ncm directly to get the keys, then parse that.
|
||||||
u32 latest_version_num = cnmt.key.version;
|
version_out = cnmt.key.version;
|
||||||
if (has_records) {
|
if (has_records) {
|
||||||
s32 meta_count{};
|
s32 meta_count{};
|
||||||
R_TRY(nsCountApplicationContentMeta(app_id, &meta_count));
|
R_TRY(nsCountApplicationContentMeta(app_id, &meta_count));
|
||||||
@@ -1105,7 +1104,7 @@ Result Yati::GetLatestVersion(const CnmtCollection& cnmt, u32& version_out, bool
|
|||||||
skip = true;
|
skip = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
latest_version_num = std::max(latest_version_num, record.key.version);
|
version_out = std::max(version_out, record.key.version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1142,9 +1141,7 @@ Result Yati::ImportTickets(std::span<TikCollection> tickets) {
|
|||||||
log_write("WARNING: skipping ticket install, but it's required!\n");
|
log_write("WARNING: skipping ticket install, but it's required!\n");
|
||||||
} else {
|
} else {
|
||||||
log_write("patching ticket\n");
|
log_write("patching ticket\n");
|
||||||
if (config.patch_ticket) {
|
R_TRY(es::PatchTicket(ticket.ticket, keys));
|
||||||
R_TRY(es::PatchTicket(ticket.ticket, keys, false));
|
|
||||||
}
|
|
||||||
log_write("installing ticket\n");
|
log_write("installing ticket\n");
|
||||||
R_TRY(es::ImportTicket(std::addressof(es), ticket.ticket.data(), ticket.ticket.size(), ticket.cert.data(), ticket.cert.size()));
|
R_TRY(es::ImportTicket(std::addressof(es), ticket.ticket.data(), ticket.ticket.size(), ticket.cert.data(), ticket.cert.size()));
|
||||||
ticket.required = false;
|
ticket.required = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user