From dc3a9abff3f01d4c93c4a8cf335b0e69f6f7d18c Mon Sep 17 00:00:00 2001 From: Asciimov Date: Thu, 29 Oct 2026 18:35:11 +0700 Subject: [PATCH] fix: give the v5 address library map its own name Every format used the mapping name COMMONLIB_IDDB_OFFSETS_, and FMemoryMap opens an existing mapping of that name before mapping its own file. v2 loaders keep sorted id/offset pairs there, while v5 maps the raw file and reads a u32 array after the header. If a plugin whose loader got a v2 table created the mapping first, every v5 plugin read that pair table as offsets: half of the valid ids came back as 0 ("Failed to find offset") and the other half as wrong addresses. In the other order the v2 plugin could not map its table. Use COMMONLIB_IDDB_OFFSETS_V5_ for v5, and fail with a clear message if the mapped header does not match the file. --- src/REL/IDDB.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/REL/IDDB.cpp b/src/REL/IDDB.cpp index a02c5f1..6e3f88c 100644 --- a/src/REL/IDDB.cpp +++ b/src/REL/IDDB.cpp @@ -278,12 +278,22 @@ namespace REL m_name, modVersion.string(), header.game_version().string()); } - const auto mapName = std::format("COMMONLIB_IDDB_OFFSETS_{}", modVersion.string("_")); + // v0/v2 loaders store id/offset pairs under COMMONLIB_IDDB_OFFSETS_*, so the raw v5 file needs its own name + const auto mapName = std::format("COMMONLIB_IDDB_OFFSETS_V5_{}", modVersion.string("_")); if (!m_mmap.create(false, m_path, mapName)) REX::FAIL(L"Failed to create Address Library MemoryMap!\nError: {}\nPath: {}", REX::W32::GetLastError(), m_path.wstring()); validate_file(); + static_assert(sizeof(HEADER_V5) == 0x60); + if (std::memcmp(m_mmap.data(), std::addressof(header), sizeof(HEADER_V5)) != 0) + REX::FAIL( + "{}\n\n" + "Address Library MemoryMap {} does not match {}!\n" + "Another plugin created it with a different layout.\n" + "Game Version: {}", + m_name, mapName, m_path.filename().string(), modVersion.string()); + m_v5 = { reinterpret_cast(m_mmap.data() + sizeof(HEADER_V5)), header.offset_count() }; } catch (const std::system_error&) {