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:
ITotalJustice
2025-04-22 23:15:16 +01:00
parent 21f6f4b74d
commit e2a1c8b5e3
14 changed files with 48 additions and 27 deletions

View File

@@ -2,3 +2,4 @@
path=/retroarch/cores/fbneo_libretro_libnx.nro
supported_extensions=zip|7z|cue|ccd
database=FBNeo - Arcade Games
use_base_name=true

View File

@@ -2,3 +2,4 @@
path=/retroarch/cores/mame2000_libretro_libnx.nro
supported_extensions=zip|7z
database=MAME 2000
use_base_name=true

View File

@@ -2,3 +2,4 @@
path=/retroarch/cores/mame2003_libretro_libnx.nro
supported_extensions=zip
database=MAME 2003
use_base_name=true

View File

@@ -2,3 +2,4 @@
path=/retroarch/cores/mame2003_plus_libretro_libnx.nro
supported_extensions=zip
database=MAME 2003-Plus
use_base_name=true

View File

@@ -2,3 +2,4 @@
path=/retroarch/cores/xrick_libretro_libnx.nro
supported_extensions=zip
database=Rick Dangerous
use_base_name=true

View File

@@ -64,7 +64,7 @@ public:
static void SetTheme(s64 theme_index);
static auto GetThemeIndex() -> s64;
static auto GetDefaultImage(int* w = nullptr, int* h = nullptr) -> int;
static auto GetDefaultImage() -> int;
// returns argv[0]
static auto GetExePath() -> fs::FsPath;
@@ -185,7 +185,6 @@ public:
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_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_patch{INI_SECTION, "skip_patch", false};
option::OptionBool m_skip_addon{INI_SECTION, "skip_addon", false};

View File

@@ -89,6 +89,7 @@ struct FileAssocEntry {
std::string name{}; // ini name
std::vector<std::string> ext{}; // list of ext
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 {
for (const auto& assoc_ext : ext) {

View File

@@ -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 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

View File

@@ -79,11 +79,6 @@ struct Config {
// installs tickets 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.
bool skip_base{};
bool skip_patch{};

View File

@@ -544,7 +544,7 @@ auto App::GetThemeIndex() -> s64 {
return g_app->m_theme_index;
}
auto App::GetDefaultImage(int* w, int* h) -> int {
auto App::GetDefaultImage() -> int {
return g_app->m_default_image;
}
@@ -1392,8 +1392,33 @@ App::App(const char* argv0) {
}
}
// soon (tm)
// ui::bubble::Init();
struct EventDay {
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>());
log_write("finished app constructor\n");

View File

@@ -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 (db_indexs.empty()) {
log_write("using nro image\n");
@@ -812,8 +812,7 @@ void Menu::InstallForwarder() {
return false;
}
log_write("got nro data\n");
std::string file_name = GetEntry().GetInternalName();
std::string extension = GetEntry().GetInternalExtension();
auto file_name = assoc.use_base_name ? GetEntry().GetName() : GetEntry().GetInternalName();
if (auto pos = file_name.find_last_of('.'); pos != std::string::npos) {
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 = file_name;
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));
}));
@@ -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;
}, &assoc, full_path);

View File

@@ -391,10 +391,6 @@ MainMenu::MainMenu() {
App::GetApp()->m_ticket_only.Set(enable);
}, "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){
App::GetApp()->m_skip_base.Set(enable);
}, "Enabled"_i18n, "Disabled"_i18n));

View File

@@ -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: 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;
R_TRY(GetTicketData(ticket, &data));
if (data.title_key_type == es::TicketTitleKeyType_Common) {
// todo: verify common signature
} else if (data.title_key_type == es::TicketTitleKeyType_Personalized && convert_personalised) {
} else if (data.title_key_type == es::TicketTitleKeyType_Personalized) {
}

View File

@@ -797,7 +797,6 @@ Result Yati::Setup() {
config.allow_downgrade = App::GetApp()->m_allow_downgrade.Get();
config.skip_if_already_installed = App::GetApp()->m_skip_if_already_installed.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_patch = App::GetApp()->m_skip_patch.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
// for the gamecard...
// 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) {
s32 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;
}
} 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");
} else {
log_write("patching ticket\n");
if (config.patch_ticket) {
R_TRY(es::PatchTicket(ticket.ticket, keys, false));
}
R_TRY(es::PatchTicket(ticket.ticket, keys));
log_write("installing ticket\n");
R_TRY(es::ImportTicket(std::addressof(es), ticket.ticket.data(), ticket.ticket.size(), ticket.cert.data(), ticket.cert.size()));
ticket.required = false;