feat: extend SaveMigration
This commit is contained in:
1 parent
966c022003
commit
e4208f3a97
1 file changed
+77
@@ -628,3 +628,80 @@ MigrationPlan SaveMigrator::planFor(SaveVersion from, SaveVersion to) {
|
||||
return plan;
|
||||
}
|
||||
|
||||
bool SaveMigrator::applyStep(const ByteBuffer& in, const MigrationStep& step,
|
||||
MigrationResult& result, ByteBuffer& out) const {
|
||||
SaveContainer container;
|
||||
if (!readSaveContainer(in.data(), in.size(), container)) {
|
||||
result.failure = "container is not readable at " + std::string(saveVersionName(step.from));
|
||||
return false;
|
||||
}
|
||||
if (container.version != step.from) {
|
||||
result.failure = "expected " + std::string(saveVersionName(step.from)) + " but found " +
|
||||
saveVersionName(container.version);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (SaveChunkRecord& record : container.chunks) {
|
||||
if (step.to == SaveVersion::V2) {
|
||||
std::vector<Block> palette;
|
||||
std::vector<uint32_t> indices;
|
||||
buildPalette(record.blocks, palette, indices);
|
||||
result.paletteEntriesCreated += palette.size();
|
||||
} else if (step.to == SaveVersion::V3) {
|
||||
record.light = defaultChunkLight(record.blocks, skyLightForNewPlanes);
|
||||
result.lightCellsInitialized += record.light.size();
|
||||
} else {
|
||||
record.meta = metadataDefaults;
|
||||
++result.metadataRecordsCreated;
|
||||
}
|
||||
}
|
||||
|
||||
container.version = step.to;
|
||||
container.compressPayloads = compressMigratedPayloads && step.to == currentSaveVersion;
|
||||
out = writeSaveContainer(container);
|
||||
return true;
|
||||
}
|
||||
|
||||
MigrationResult SaveMigrator::migrate(const uint8_t* data, std::size_t size,
|
||||
SaveVersion target) const {
|
||||
MigrationResult result;
|
||||
result.to = target;
|
||||
|
||||
SaveVersion from = currentSaveVersion;
|
||||
if (!peekVersion(data, size, from)) {
|
||||
result.failure = "save header is unreadable: bad magic, short buffer or unknown version";
|
||||
return result;
|
||||
}
|
||||
result.from = from;
|
||||
|
||||
MigrationPlan plan = planFor(from, target);
|
||||
if (!plan.possible) {
|
||||
result.failure = plan.refusal;
|
||||
return result;
|
||||
}
|
||||
|
||||
SaveContainer source;
|
||||
if (!readSaveContainer(data, size, source)) {
|
||||
result.failure = "save body is unreadable at " + std::string(saveVersionName(from));
|
||||
return result;
|
||||
}
|
||||
result.chunksMigrated = source.chunks.size();
|
||||
|
||||
ByteBuffer current(data, data + size);
|
||||
for (const MigrationStep& step : plan.steps) {
|
||||
ByteBuffer next;
|
||||
if (!applyStep(current, step, result, next)) return result;
|
||||
current = std::move(next);
|
||||
result.applied.push_back(step);
|
||||
}
|
||||
|
||||
result.output = std::move(current);
|
||||
result.ok = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
MigrationResult SaveMigrator::migrateToCurrent(const ByteBuffer& buffer) const {
|
||||
return migrate(buffer.data(), buffer.size(), currentSaveVersion);
|
||||
}
|
||||
|
||||
} // namespace vf
|
||||
Reference in new issue
Block a user