MCPcopy Create free account
hub / github.com/OpenRCT2/OpenRCT2 / SaveObject

Method SaveObject

src/openrct2/object/ObjectRepository.cpp:474–528  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

472 };
473
474 static void SaveObject(
475 std::string_view path, const RCTObjectEntry* entry, const void* data, size_t dataSize, bool fixChecksum = true)
476 {
477 if (fixChecksum)
478 {
479 uint32_t realChecksum = ObjectCalculateChecksum(entry, data, dataSize);
480 if (realChecksum != entry->checksum)
481 {
482 char objectName[9];
483 ObjectEntryGetNameFixed(objectName, sizeof(objectName), entry);
484 LOG_VERBOSE("[%s] Incorrect checksum, adding salt bytes...", objectName);
485
486 // Calculate the value of extra bytes that can be appended to the data so that the
487 // data is then valid for the object's checksum
488 const auto extraBytes = calculateExtraBytesToFixChecksum(realChecksum, entry->checksum);
489
490 // Create new data blob with appended bytes
491 std::vector<uint8_t> newData;
492 newData.reserve(dataSize + extraBytes.size());
493
494 const auto dataSpan = std::span(static_cast<const uint8_t*>(data), dataSize);
495 newData.insert(newData.end(), dataSpan.begin(), dataSpan.end());
496 newData.insert(newData.end(), extraBytes.begin(), extraBytes.end());
497
498 uint32_t newRealChecksum = ObjectCalculateChecksum(entry, newData.data(), newData.size());
499 if (newRealChecksum != entry->checksum)
500 {
501 Console::Error::WriteLine("CalculateExtraBytesToFixChecksum failed to fix checksum.");
502
503 // Save old data form
504 SaveObject(path, entry, data, dataSize, false);
505 }
506 else
507 {
508 // Save new data form
509 SaveObject(path, entry, newData.data(), newData.size(), false);
510 }
511 return;
512 }
513 }
514
515 // Encode data
516 ObjectType objectType = entry->GetType();
517 ChunkHeader chunkHeader;
518 chunkHeader.encoding = kLegacyObjectEntryGroupEncoding[EnumValue(objectType)];
519 chunkHeader.length = static_cast<uint32_t>(dataSize);
520 const auto encodedDataBuffer = std::make_unique_for_overwrite<uint8_t[]>(0x600000);
521 const size_t encodedDataSize = WriteChunkBuffer(
522 encodedDataBuffer.get(), reinterpret_cast<const uint8_t*>(data), chunkHeader);
523
524 // Save to file
525 auto fs = FileStream(std::string(path), FileMode::write);
526 fs.Write(entry, sizeof(RCTObjectEntry));
527 fs.Write(encodedDataBuffer.get(), encodedDataSize);
528 }
529
530 static std::array<uint8_t, 11> calculateExtraBytesToFixChecksum(
531 const int32_t currentChecksum, const int32_t targetChecksum)

Callers

nothing calls this directly

Calls 13

ObjectCalculateChecksumFunction · 0.85
ObjectEntryGetNameFixedFunction · 0.85
WriteLineFunction · 0.85
EnumValueFunction · 0.85
WriteChunkBufferFunction · 0.85
FileStreamClass · 0.85
endMethod · 0.65
getMethod · 0.65
sizeMethod · 0.45
beginMethod · 0.45
dataMethod · 0.45
GetTypeMethod · 0.45

Tested by

no test coverage detected