Skip to content

Commit

Permalink
Changed mod binary and mod symbol files to use fixed paths, removed t…
Browse files Browse the repository at this point in the history
…hem from the manifest
  • Loading branch information
Mr-Wiseguy committed Sep 3, 2024
1 parent 09f5759 commit 3718758
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 108 deletions.
12 changes: 3 additions & 9 deletions librecomp/include/librecomp/mods.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ namespace recomp {
InvalidVersionString,
InvalidMinimumRecompVersionString,
MissingManifestField,
InnerFileDoesNotExist,
DuplicateMod,
WrongGame
};
Expand All @@ -54,8 +53,9 @@ namespace recomp {
Good,
InvalidGame,
MinimumRecompVersionNotMet,
FailedToLoadSyms,
FailedToLoadBinary,
HasSymsButNoBinary,
HasBinaryButNoSyms,
FailedToParseSyms,
FailedToLoadNativeCode,
FailedToLoadNativeLibrary,
FailedToFindNativeExport,
Expand Down Expand Up @@ -129,13 +129,7 @@ namespace recomp {
Version minimum_recomp_version;
Version version;

// These are all relative to the base path for loose mods or inside the zip for zipped mods.
std::string binary_path;
std::string binary_syms_path;
std::string rom_patch_path;
std::string rom_patch_syms_path;
std::vector<NativeLibraryManifest> native_libraries;

std::unique_ptr<ModFileHandle> file_handle;
};

Expand Down
100 changes: 10 additions & 90 deletions librecomp/src/mod_manifest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,33 +135,21 @@ enum class ManifestField {
Id,
Version,
MinimumRecompVersion,
BinaryPath,
BinarySymsPath,
RomPatchPath,
RomPatchSymsPath,
NativeLibraryPaths,
NativeLibraries,
};

const std::string game_mod_id_key = "game_id";
const std::string mod_id_key = "id";
const std::string version_key = "version";
const std::string minimum_recomp_version_key = "minimum_recomp_version";
const std::string binary_path_key = "binary";
const std::string binary_syms_path_key = "binary_syms";
const std::string rom_patch_path_key = "rom_patch";
const std::string rom_patch_syms_path_key = "rom_patch_syms";
const std::string native_library_paths_key = "native_libraries";
const std::string native_libraries_key = "native_libraries";

std::unordered_map<std::string, ManifestField> field_map {
{ game_mod_id_key, ManifestField::GameModId },
{ mod_id_key, ManifestField::Id },
{ version_key, ManifestField::Version },
{ minimum_recomp_version_key, ManifestField::MinimumRecompVersion },
{ binary_path_key, ManifestField::BinaryPath },
{ binary_syms_path_key, ManifestField::BinarySymsPath },
{ rom_patch_path_key, ManifestField::RomPatchPath },
{ rom_patch_syms_path_key, ManifestField::RomPatchSymsPath },
{ native_library_paths_key, ManifestField::NativeLibraryPaths },
{ native_libraries_key, ManifestField::NativeLibraries },
};

template <typename T1, typename T2>
Expand Down Expand Up @@ -263,31 +251,7 @@ recomp::mods::ModOpenError parse_manifest(recomp::mods::ModManifest& ret, const
ret.minimum_recomp_version.suffix.clear();
}
break;
case ManifestField::BinaryPath:
if (!get_to<json::string_t>(val, ret.binary_path)) {
error_param = key;
return recomp::mods::ModOpenError::IncorrectManifestFieldType;
}
break;
case ManifestField::BinarySymsPath:
if (!get_to<json::string_t>(val, ret.binary_syms_path)) {
error_param = key;
return recomp::mods::ModOpenError::IncorrectManifestFieldType;
}
break;
case ManifestField::RomPatchPath:
if (!get_to<json::string_t>(val, ret.rom_patch_path)) {
error_param = key;
return recomp::mods::ModOpenError::IncorrectManifestFieldType;
}
break;
case ManifestField::RomPatchSymsPath:
if (!get_to<json::string_t>(val, ret.rom_patch_syms_path)) {
error_param = key;
return recomp::mods::ModOpenError::IncorrectManifestFieldType;
}
break;
case ManifestField::NativeLibraryPaths:
case ManifestField::NativeLibraries:
{
if (!val.is_object()) {
error_param = key;
Expand All @@ -310,18 +274,6 @@ recomp::mods::ModOpenError parse_manifest(recomp::mods::ModManifest& ret, const
return recomp::mods::ModOpenError::Good;
}

recomp::mods::ModOpenError validate_file_exists(const recomp::mods::ModManifest& manifest, const std::string& filepath, std::string& error_param) {
// No file provided, so nothing to check for.
if (filepath.empty()) {
return recomp::mods::ModOpenError::Good;
}
if (!manifest.file_handle->file_exists(filepath)) {
error_param = filepath;
return recomp::mods::ModOpenError::InnerFileDoesNotExist;
}
return recomp::mods::ModOpenError::Good;
}

recomp::mods::ModOpenError validate_manifest(const recomp::mods::ModManifest& manifest, std::string& error_param) {
using namespace recomp::mods;

Expand All @@ -343,38 +295,6 @@ recomp::mods::ModOpenError validate_manifest(const recomp::mods::ModManifest& ma
return ModOpenError::MissingManifestField;
}

// If either a binary file or binary symbol file is provided, the other must be as well.
if (manifest.binary_path.empty() != manifest.binary_syms_path.empty()) {
if (manifest.binary_path.empty()) {
error_param = binary_path_key;
}
else {
error_param = binary_syms_path_key;
}
return ModOpenError::MissingManifestField;
}

// If a ROM patch symbol file is provided, a ROM patch file must be as well.
if (!manifest.rom_patch_syms_path.empty() && manifest.rom_patch_path.empty()) {
error_param = rom_patch_path_key;
return ModOpenError::MissingManifestField;
}

// Validate that provided files exist.
ModOpenError validate_error;
if ((validate_error = validate_file_exists(manifest, manifest.binary_path, error_param)) != ModOpenError::Good) {
return validate_error;
}
if ((validate_error = validate_file_exists(manifest, manifest.binary_syms_path, error_param)) != ModOpenError::Good) {
return validate_error;
}
if ((validate_error = validate_file_exists(manifest, manifest.rom_patch_path, error_param)) != ModOpenError::Good) {
return validate_error;
}
if ((validate_error = validate_file_exists(manifest, manifest.rom_patch_syms_path, error_param)) != ModOpenError::Good) {
return validate_error;
}

return ModOpenError::Good;
}

Expand Down Expand Up @@ -485,8 +405,6 @@ std::string recomp::mods::error_to_string(ModOpenError error) {
return "Invalid minimum recomp version string in manifest.json";
case ModOpenError::MissingManifestField:
return "Missing required field in manifest";
case ModOpenError::InnerFileDoesNotExist:
return "File inside mod does not exist";
case ModOpenError::DuplicateMod:
return "Duplicate mod found";
case ModOpenError::WrongGame:
Expand All @@ -503,10 +421,12 @@ std::string recomp::mods::error_to_string(ModLoadError error) {
return "Invalid game";
case ModLoadError::MinimumRecompVersionNotMet:
return "Mod requires a newer version of this project";
case ModLoadError::FailedToLoadSyms:
return "Failed to load mod symbol file";
case ModLoadError::FailedToLoadBinary:
return "Failed to load mod binary file";
case ModLoadError::HasSymsButNoBinary:
return "Mod has a symbol file but no binary file";
case ModLoadError::HasBinaryButNoSyms:
return "Mod has a binary file but no symbol file";
case ModLoadError::FailedToParseSyms:
return "Failed to parse mod symbol file";
case ModLoadError::FailedToLoadNativeCode:
return "Failed to load mod code DLL";
case ModLoadError::FailedToLoadNativeLibrary:
Expand Down
23 changes: 14 additions & 9 deletions librecomp/src/mods.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ void protect(void* target_func, uint64_t old_flags) {
# error "Mods not implemented yet on this platform"
#endif

namespace modpaths {
const std::string binary_path = "mod_binary.bin";
const std::string binary_syms_path = "mod_syms.bin";
};

recomp::mods::ModLoadError recomp::mods::validate_api_version(uint32_t api_version, std::string& error_param) {
switch (api_version) {
case 1:
Expand Down Expand Up @@ -323,26 +328,26 @@ recomp::mods::ModLoadError recomp::mods::ModContext::load_mod(uint8_t* rdram, co

// Load the mod symbol data from the file provided in the manifest.
bool binary_syms_exists = false;
std::vector<char> syms_data = handle.manifest.file_handle->read_file(handle.manifest.binary_syms_path, binary_syms_exists);

if (!binary_syms_exists) {
return recomp::mods::ModLoadError::FailedToLoadSyms;
}
std::vector<char> syms_data = handle.manifest.file_handle->read_file(modpaths::binary_syms_path, binary_syms_exists);

// Load the binary data from the file provided in the manifest.
bool binary_exists = false;
std::vector<char> binary_data = handle.manifest.file_handle->read_file(handle.manifest.binary_path, binary_exists);
std::vector<char> binary_data = handle.manifest.file_handle->read_file(modpaths::binary_path, binary_exists);

if (binary_syms_exists && !binary_exists) {
return recomp::mods::ModLoadError::HasSymsButNoBinary;
}

if (!binary_exists) {
return recomp::mods::ModLoadError::FailedToLoadBinary;
if (binary_exists && !binary_syms_exists) {
return recomp::mods::ModLoadError::HasBinaryButNoSyms;
}

std::span<uint8_t> binary_span {reinterpret_cast<uint8_t*>(binary_data.data()), binary_data.size() };

// Parse the symbol file into the recompiler context.
N64Recomp::ModSymbolsError symbol_load_error = N64Recomp::parse_mod_symbols(syms_data, binary_span, section_vrom_map, *handle.recompiler_context);
if (symbol_load_error != N64Recomp::ModSymbolsError::Good) {
return ModLoadError::FailedToLoadSyms;
return ModLoadError::FailedToParseSyms;
}

handle.section_load_addresses.resize(handle.recompiler_context->sections.size());
Expand Down

0 comments on commit 3718758

Please sign in to comment.