mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-05-31 16:37:07 +02:00
[android] fix crash when loader for invalid file is found
Signed-off-by: lizzie <lizzie@eden-emu.dev>
This commit is contained in:
parent
9b18d0b111
commit
a5fdd79684
1 changed files with 61 additions and 97 deletions
|
|
@ -20,132 +20,96 @@ struct RomMetadata {
|
||||||
std::vector<u8> icon;
|
std::vector<u8> icon;
|
||||||
bool isHomebrew;
|
bool isHomebrew;
|
||||||
};
|
};
|
||||||
|
static ankerl::unordered_dense::map<std::string, RomMetadata> m_rom_metadata_cache;
|
||||||
|
|
||||||
ankerl::unordered_dense::map<std::string, RomMetadata> m_rom_metadata_cache;
|
static RomMetadata CacheRomMetadata(const std::string& path) {
|
||||||
|
auto& instance = EmulationSession::GetInstance();
|
||||||
|
const auto file = Core::GetGameFileFromPath(instance.System().GetFilesystem(), path);
|
||||||
|
if (auto loader = Loader::GetLoader(instance.System(), file, 0, 0); loader) {
|
||||||
|
RomMetadata entry;
|
||||||
|
loader->ReadTitle(entry.title);
|
||||||
|
loader->ReadProgramId(entry.programId);
|
||||||
|
loader->ReadIcon(entry.icon);
|
||||||
|
|
||||||
RomMetadata CacheRomMetadata(const std::string& path) {
|
const FileSys::PatchManager pm{
|
||||||
const auto file =
|
entry.programId,
|
||||||
Core::GetGameFileFromPath(EmulationSession::GetInstance().System().GetFilesystem(), path);
|
instance.System().GetFileSystemController(),
|
||||||
auto loader = Loader::GetLoader(EmulationSession::GetInstance().System(), file, 0, 0);
|
instance.System().GetContentProvider()
|
||||||
|
};
|
||||||
|
const auto control = pm.GetControlMetadata();
|
||||||
|
|
||||||
RomMetadata entry;
|
if (control.first != nullptr) {
|
||||||
loader->ReadTitle(entry.title);
|
entry.developer = control.first->GetDeveloperName();
|
||||||
loader->ReadProgramId(entry.programId);
|
entry.version = control.first->GetVersionString();
|
||||||
loader->ReadIcon(entry.icon);
|
|
||||||
|
|
||||||
const FileSys::PatchManager pm{
|
|
||||||
entry.programId, EmulationSession::GetInstance().System().GetFileSystemController(),
|
|
||||||
EmulationSession::GetInstance().System().GetContentProvider()};
|
|
||||||
const auto control = pm.GetControlMetadata();
|
|
||||||
|
|
||||||
if (control.first != nullptr) {
|
|
||||||
entry.developer = control.first->GetDeveloperName();
|
|
||||||
entry.version = control.first->GetVersionString();
|
|
||||||
} else {
|
|
||||||
FileSys::NACP nacp;
|
|
||||||
if (loader->ReadControlData(nacp) == Loader::ResultStatus::Success) {
|
|
||||||
entry.developer = nacp.GetDeveloperName();
|
|
||||||
} else {
|
} else {
|
||||||
entry.developer = "";
|
FileSys::NACP nacp{};
|
||||||
|
entry.developer = loader->ReadControlData(nacp) == Loader::ResultStatus::Success
|
||||||
|
? nacp.GetDeveloperName()
|
||||||
|
: "";
|
||||||
|
entry.version = "1.0.0";
|
||||||
}
|
}
|
||||||
|
if (loader->GetFileType() == Loader::FileType::NRO) {
|
||||||
entry.version = "1.0.0";
|
auto loader_nro = reinterpret_cast<Loader::AppLoader_NRO*>(loader.get());
|
||||||
|
entry.isHomebrew = loader_nro->IsHomebrew();
|
||||||
|
} else {
|
||||||
|
entry.isHomebrew = false;
|
||||||
|
}
|
||||||
|
m_rom_metadata_cache[path] = entry;
|
||||||
|
return entry;
|
||||||
}
|
}
|
||||||
|
return {};
|
||||||
if (loader->GetFileType() == Loader::FileType::NRO) {
|
|
||||||
auto loader_nro = reinterpret_cast<Loader::AppLoader_NRO*>(loader.get());
|
|
||||||
entry.isHomebrew = loader_nro->IsHomebrew();
|
|
||||||
} else {
|
|
||||||
entry.isHomebrew = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_rom_metadata_cache[path] = entry;
|
|
||||||
|
|
||||||
return entry;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RomMetadata GetRomMetadata(const std::string& path, bool reload = false) {
|
static RomMetadata GetRomMetadata(const std::string& path, bool reload = false) {
|
||||||
if (reload) {
|
if (reload)
|
||||||
return CacheRomMetadata(path);
|
return CacheRomMetadata(path);
|
||||||
}
|
if (auto it = m_rom_metadata_cache.find(path); it != m_rom_metadata_cache.end())
|
||||||
|
return it->second;
|
||||||
if (auto search = m_rom_metadata_cache.find(path); search != m_rom_metadata_cache.end()) {
|
|
||||||
return search->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CacheRomMetadata(path);
|
return CacheRomMetadata(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
jboolean Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getIsValid(JNIEnv* env, jobject obj,
|
jboolean Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getIsValid(JNIEnv* env, jobject obj, jstring jpath) {
|
||||||
jstring jpath) {
|
if (auto const file = EmulationSession::GetInstance().System().GetFilesystem()->OpenFile(Common::Android::GetJString(env, jpath), FileSys::OpenMode::Read); file) {
|
||||||
const auto file = EmulationSession::GetInstance().System().GetFilesystem()->OpenFile(
|
if (auto loader = Loader::GetLoader(EmulationSession::GetInstance().System(), file); loader) {
|
||||||
Common::Android::GetJString(env, jpath), FileSys::OpenMode::Read);
|
auto const file_type = loader->GetFileType();
|
||||||
if (!file) {
|
if (file_type == Loader::FileType::Unknown || file_type == Loader::FileType::Error)
|
||||||
return false;
|
return false;
|
||||||
|
if ((file_type == Loader::FileType::NSP || file_type == Loader::FileType::XCI) && !Loader::IsBootableGameContainer(file, file_type))
|
||||||
|
return false;
|
||||||
|
u64 program_id = 0;
|
||||||
|
return loader->ReadProgramId(program_id) == Loader::ResultStatus::Success;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
auto loader = Loader::GetLoader(EmulationSession::GetInstance().System(), file);
|
|
||||||
if (!loader) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto file_type = loader->GetFileType();
|
|
||||||
if (file_type == Loader::FileType::Unknown || file_type == Loader::FileType::Error) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((file_type == Loader::FileType::NSP || file_type == Loader::FileType::XCI) &&
|
|
||||||
!Loader::IsBootableGameContainer(file, file_type)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
u64 program_id = 0;
|
|
||||||
Loader::ResultStatus res = loader->ReadProgramId(program_id);
|
|
||||||
if (res != Loader::ResultStatus::Success) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
jstring Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getTitle(JNIEnv* env, jobject obj,
|
jstring Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getTitle(JNIEnv* env, jobject obj, jstring jpath) {
|
||||||
jstring jpath) {
|
return Common::Android::ToJString(env, GetRomMetadata(Common::Android::GetJString(env, jpath)).title);
|
||||||
return Common::Android::ToJString(
|
|
||||||
env, GetRomMetadata(Common::Android::GetJString(env, jpath)).title);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
jstring Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getProgramId(JNIEnv* env, jobject obj,
|
jstring Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getProgramId(JNIEnv* env, jobject obj, jstring jpath) {
|
||||||
jstring jpath) {
|
return Common::Android::ToJString(env, std::to_string(GetRomMetadata(Common::Android::GetJString(env, jpath)).programId));
|
||||||
return Common::Android::ToJString(
|
|
||||||
env, std::to_string(GetRomMetadata(Common::Android::GetJString(env, jpath)).programId));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
jstring Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getDeveloper(JNIEnv* env, jobject obj,
|
jstring Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getDeveloper(JNIEnv* env, jobject obj, jstring jpath) {
|
||||||
jstring jpath) {
|
return Common::Android::ToJString(env, GetRomMetadata(Common::Android::GetJString(env, jpath)).developer);
|
||||||
return Common::Android::ToJString(
|
|
||||||
env, GetRomMetadata(Common::Android::GetJString(env, jpath)).developer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
jstring Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getVersion(JNIEnv* env, jobject obj,
|
jstring Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getVersion(JNIEnv* env, jobject obj, jstring jpath, jboolean jreload) {
|
||||||
jstring jpath, jboolean jreload) {
|
return Common::Android::ToJString(env, GetRomMetadata(Common::Android::GetJString(env, jpath), jreload).version);
|
||||||
return Common::Android::ToJString(
|
|
||||||
env, GetRomMetadata(Common::Android::GetJString(env, jpath), jreload).version);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
jbyteArray Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getIcon(JNIEnv* env, jobject obj,
|
jbyteArray Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getIcon(JNIEnv* env, jobject obj, jstring jpath) {
|
||||||
jstring jpath) {
|
|
||||||
auto icon_data = GetRomMetadata(Common::Android::GetJString(env, jpath)).icon;
|
auto icon_data = GetRomMetadata(Common::Android::GetJString(env, jpath)).icon;
|
||||||
jbyteArray icon = env->NewByteArray(static_cast<jsize>(icon_data.size()));
|
jbyteArray icon = env->NewByteArray(jsize(icon_data.size()));
|
||||||
env->SetByteArrayRegion(icon, 0, env->GetArrayLength(icon),
|
env->SetByteArrayRegion(icon, 0, env->GetArrayLength(icon), reinterpret_cast<jbyte*>(icon_data.data()));
|
||||||
reinterpret_cast<jbyte*>(icon_data.data()));
|
|
||||||
return icon;
|
return icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
jboolean Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getIsHomebrew(JNIEnv* env, jobject obj,
|
jboolean Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getIsHomebrew(JNIEnv* env, jobject obj, jstring jpath) {
|
||||||
jstring jpath) {
|
return jboolean(GetRomMetadata(Common::Android::GetJString(env, jpath)).isHomebrew);
|
||||||
return static_cast<jboolean>(
|
|
||||||
GetRomMetadata(Common::Android::GetJString(env, jpath)).isHomebrew);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Java_org_yuzu_yuzu_1emu_utils_GameMetadata_resetMetadata(JNIEnv* env, jobject obj) {
|
void Java_org_yuzu_yuzu_1emu_utils_GameMetadata_resetMetadata(JNIEnv* env, jobject obj) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue