mirror of
https://github.com/Dingo-Shenanigans/ReSkate.git
synced 2026-10-27 15:07:09 +01:00
Mods: a chunk no list describes gets an owner hash and meta in the merged bundle, instead of an empty record the game reads through null
merge_chunk_metadata gave such a chunk a record with no fields. The game's reader (0x41af080) takes a record without "h64" as a "g" record and, with no "g" either, reads its guid through null (Skate.exe+0x15b2c34: computerK-Fingerboard adds its grip texture to a game deck bundle whose list has no record for it). The record is now an owner hash no resource has, with an empty meta, which the game passes over.
This commit is contained in:
1 parent
8e5fb74498
commit
788eb98352
2 files changed
+30
-1
No files matched your search
@@ -170,6 +170,17 @@ int main() {
|
||||
check(read_list(merge_chunk_metadata(lists, unknown, gameList, shipped)) ==
|
||||
std::vector<Record>{mesh, Record{}, textureA, other, textureB, mesh, Record{}},
|
||||
"a chunk no list describes gets a record that says nothing, and the others stay in step");
|
||||
// The game reads a record without "h64" as a "g" record, and one with neither through null.
|
||||
{
|
||||
const auto written = merge_chunk_metadata(lists, unknown, gameList, shipped);
|
||||
const std::span<const unsigned char> bytes(reinterpret_cast<const unsigned char*>(written.data()), written.size());
|
||||
const auto root = db::read(bytes, "chunk metadata", nullptr);
|
||||
check(std::ranges::all_of(root.children, [](const db::Node& row) {
|
||||
const auto* owner = row.field("h64");
|
||||
return owner && owner->payload().size() == 8 && row.field("meta");
|
||||
}),
|
||||
"every record has the owner hash and meta the game reads");
|
||||
}
|
||||
|
||||
// A bundle the game has no list for (it has no chunks there, or does not ship the bundle): every
|
||||
// chunk is a mod's, with the record of the copy it came in. Maps each add their loading screen
|
||||
|
||||
@@ -336,15 +336,33 @@ std::vector<std::byte> merge_chunk_metadata(std::span<const std::vector<std::byt
|
||||
for (std::size_t copy = 0; !shape && copy < read.size(); ++copy)
|
||||
if (read[copy]) shape = &*read[copy];
|
||||
if (!shape) return {}; // no copy has a list at all
|
||||
// A chunk no list describes still takes up its place, with a record that says nothing.
|
||||
// A chunk no list describes still takes up its place, with a record that says nothing: an owner
|
||||
// hash no resource has, and no meta. The game's reader (0x41af080) takes a record without "h64"
|
||||
// as a "g" record and, with no "g" either, reads its guid through null (Skate.exe+0x15b2c34: a
|
||||
// mod's grip texture added to a game deck bundle whose list has no record for it; 2026-10-25).
|
||||
native_db::Node blank;
|
||||
blank.type = 2;
|
||||
blank.terminated = true;
|
||||
for (std::size_t index = 0; index < records.size(); ++index)
|
||||
if (described[index]) {
|
||||
blank = records[index];
|
||||
blank.children.clear();
|
||||
break;
|
||||
}
|
||||
{
|
||||
native_db::Node owner;
|
||||
owner.type = 9;
|
||||
owner.named = true;
|
||||
owner.name = "h64";
|
||||
owner.owned.assign(8, 0);
|
||||
native_db::Node meta;
|
||||
meta.type = 2;
|
||||
meta.named = true;
|
||||
meta.name = "meta";
|
||||
meta.terminated = true;
|
||||
blank.children.push_back(std::move(owner));
|
||||
blank.children.push_back(std::move(meta));
|
||||
}
|
||||
for (std::size_t index = 0; index < records.size(); ++index)
|
||||
if (!described[index]) records[index] = blank;
|
||||
|
||||
|
||||
Reference in new issue
Block a user