Gracefully fail if savegame fails to save, detect all load errors

This commit is contained in:
Stefanos Kornilios Mitsis Poiitidis
2025-03-15 14:01:30 +02:00
committed by Stefanos Kornilios Mitsis Poiitidis
parent 346c6cbdf3
commit d7af07d549
4 changed files with 125 additions and 50 deletions

View File

@@ -74,6 +74,10 @@ uint32 TimeToStayFadedBeforeFadeOut = 1750;
do {\ do {\
size = C_PcSave::PcClassLoadRoutine(file, work_buff); \ size = C_PcSave::PcClassLoadRoutine(file, work_buff); \
if (!size) {\ if (!size) {\
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_LOAD_READ; \
if (!CloseFile(file)) { \
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_LOAD_CLOSE; \
} \
return false; \ return false; \
} \ } \
buf = work_buff;\ buf = work_buff;\
@@ -95,8 +99,12 @@ do {\
MakeSpaceForSizeInBufferPointer(presize, buf, postsize);\ MakeSpaceForSizeInBufferPointer(presize, buf, postsize);\
save_func(buf, &size);\ save_func(buf, &size);\
CopySizeAndPreparePointer(presize, buf, postsize, reserved, size);\ CopySizeAndPreparePointer(presize, buf, postsize, reserved, size);\
if (!PcSaveHelper.PcClassSaveRoutine(file, work_buff, buf - work_buff))\ if (!PcSaveHelper.PcClassSaveRoutine(file, work_buff, buf - work_buff)) { \
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_SAVE_WRITE; \
if (!CloseFile(file)) \
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_SAVE_CLOSE; \
return false;\ return false;\
} \
totalSize += buf - work_buff;\ totalSize += buf - work_buff;\
} while (0) } while (0)
@@ -195,8 +203,12 @@ GenericSave(int file)
postsize = buf; postsize = buf;
CTheScripts::SaveAllScripts(buf, &size); CTheScripts::SaveAllScripts(buf, &size);
CopySizeAndPreparePointer(presize, buf, postsize, reserved, size); CopySizeAndPreparePointer(presize, buf, postsize, reserved, size);
if (!PcSaveHelper.PcClassSaveRoutine(file, work_buff, buf - work_buff)) if (!PcSaveHelper.PcClassSaveRoutine(file, work_buff, buf - work_buff)) {
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_SAVE_WRITE;
if (!CloseFile(file))
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_SAVE_CLOSE;
return false; return false;
}
totalSize = buf - work_buff; totalSize = buf - work_buff;
@@ -232,15 +244,19 @@ GenericSave(int file)
if (size > sizeof(work_buff)) if (size > sizeof(work_buff))
size = sizeof(work_buff); size = sizeof(work_buff);
if (size > 4) { if (size > 4) {
if (!PcSaveHelper.PcClassSaveRoutine(file, work_buff, size)) if (!PcSaveHelper.PcClassSaveRoutine(file, work_buff, size)) {
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_SAVE_WRITE;
if (!CloseFile(file))
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_SAVE_CLOSE;
return false; return false;
}
totalSize += size; totalSize += size;
} }
} }
// Write checksum and close // Write checksum and close
CFileMgr::Write(file, (const char *) &CheckSum, sizeof(CheckSum)); bool err = CFileMgr::Write(file, (const char *) &CheckSum, sizeof(CheckSum)) != sizeof(CheckSum);
if (CFileMgr::GetErrorReadWrite(file)) { if (err || CFileMgr::GetErrorReadWrite(file)) {
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_SAVE_WRITE; PcSaveHelper.nErrorCode = SAVESTATUS_ERR_SAVE_WRITE;
if (!CloseFile(file)) if (!CloseFile(file))
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_SAVE_CLOSE; PcSaveHelper.nErrorCode = SAVESTATUS_ERR_SAVE_CLOSE;
@@ -269,9 +285,17 @@ GenericLoad()
CDate dummy; // unused CDate dummy; // unused
CPad::ResetCheats(); CPad::ResetCheats();
file = CFileMgr::OpenFile(LoadFileName, "rb"); file = CFileMgr::OpenFile(LoadFileName, "rb");
assert(file != 0); if (file == 0) {
return false;
}
size = C_PcSave::PcClassLoadRoutine(file, work_buff); size = C_PcSave::PcClassLoadRoutine(file, work_buff);
assert(size != 0); if (!size) {
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_LOAD_READ;
if (!CloseFile(file)) {
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_LOAD_CLOSE;
}
return false;
}
buf = (work_buff + 0x40); buf = (work_buff + 0x40);
ReadDataFromBufferPointer(buf, saveSize); ReadDataFromBufferPointer(buf, saveSize);
#ifdef MISSION_REPLAY // a hack to keep compatibility but get new data from save #ifdef MISSION_REPLAY // a hack to keep compatibility but get new data from save
@@ -563,10 +587,9 @@ RestoreForStartLoad()
} }
uint32_t size = C_PcSave::PcClassLoadRoutine(file, work_buff); uint32_t size = C_PcSave::PcClassLoadRoutine(file, work_buff);
assert(size != 0);
uint8 *buf = work_buff; uint8 *buf = work_buff;
if (CFileMgr::GetErrorReadWrite(file)) { if (size == 0 || CFileMgr::GetErrorReadWrite(file)) {
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_LOAD_READ; PcSaveHelper.nErrorCode = SAVESTATUS_ERR_LOAD_READ;
if (!CloseFile(file)) if (!CloseFile(file))
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_LOAD_CLOSE; PcSaveHelper.nErrorCode = SAVESTATUS_ERR_LOAD_CLOSE;

View File

@@ -61,8 +61,10 @@ C_PcSave::SaveSlot(int32 slot)
#endif #endif
DoGameSpecificStuffBeforeSave(); DoGameSpecificStuffBeforeSave();
if (GenericSave(file)) { if (GenericSave(file)) {
if (!!CFileMgr::CloseFile(file)) if (!!CFileMgr::CloseFile(file)) {
nErrorCode = SAVESTATUS_ERR_SAVE_CLOSE; nErrorCode = SAVESTATUS_ERR_SAVE_CLOSE;
return false;
}
return true; return true;
} }
@@ -74,23 +76,26 @@ C_PcSave::SaveSlot(int32 slot)
uint32_t C_PcSave::PcClassLoadRoutine(int32 file, uint8 *data) { uint32_t C_PcSave::PcClassLoadRoutine(int32 file, uint8 *data) {
uint32 size; uint32 size;
CFileMgr::Read(file, (char*)&size, sizeof(size)); bool err = CFileMgr::Read(file, (char*)&size, sizeof(size)) != sizeof(size);
if (err) {
return 0;
}
assert(data == work_buff); assert(data == work_buff);
if (!(size & 0x80000000)) { if (!(size & 0x80000000)) {
assert(align4bytes(size) == size); assert(align4bytes(size) == size);
CFileMgr::Read(file, (char*)data, align4bytes(size)); err = CFileMgr::Read(file, (char*)data, align4bytes(size)) != align4bytes(size);
if (CFileMgr::GetErrorReadWrite(file)) { if (err || CFileMgr::GetErrorReadWrite(file)) {
return 0; return 0;
} }
return size; return size;
} else { } else {
size &= ~0x80000000; size &= ~0x80000000;
uint8* compressed = (uint8*)malloc(size); uint8* compressed = (uint8*)malloc(size);
CFileMgr::Read(file, (const char*)compressed, size); err = CFileMgr::Read(file, (const char*)compressed, size) != size;
if (CFileMgr::GetErrorReadWrite(file)) { if (err || CFileMgr::GetErrorReadWrite(file)) {
free(compressed); free(compressed);
return 0; return 0;
} }
@@ -120,26 +125,36 @@ C_PcSave::PcClassSaveRoutine(int32 file, uint8 *data, uint32 size)
if (crv == LZO_E_OK) { if (crv == LZO_E_OK) {
uint32_t compressed_size32 = compressed_size | 0x80000000; uint32_t compressed_size32 = compressed_size | 0x80000000;
CFileMgr::Write(file, (const char*)&compressed_size32, sizeof(compressed_size32)); bool err = CFileMgr::Write(file, (const char*)&compressed_size32, sizeof(compressed_size32)) != sizeof(compressed_size32);
if (CFileMgr::GetErrorReadWrite(file)) { if (err || CFileMgr::GetErrorReadWrite(file)) {
free(compressed); free(compressed);
nErrorCode = SAVESTATUS_ERR_SAVE_WRITE; nErrorCode = SAVESTATUS_ERR_SAVE_WRITE;
strncpy(SaveFileNameJustSaved, ValidSaveName, sizeof(ValidSaveName) - 1); strncpy(SaveFileNameJustSaved, ValidSaveName, sizeof(ValidSaveName) - 1);
return false; return false;
} }
CFileMgr::Write(file, (const char*)compressed, compressed_size); err = CFileMgr::Write(file, (const char*)compressed, compressed_size) != compressed_size;
free(compressed); free(compressed);
} else if (crv == LZO_E_NOT_COMPRESSIBLE) { if (err || CFileMgr::GetErrorReadWrite(file)) {
free(compressed); nErrorCode = SAVESTATUS_ERR_SAVE_WRITE;
uint32_t compressed_size32 = size; strncpy(SaveFileNameJustSaved, ValidSaveName, sizeof(ValidSaveName) - 1);
CFileMgr::Write(file, (const char*)&compressed_size32, sizeof(compressed_size32)); return false;
if (CFileMgr::GetErrorReadWrite(file)) { }
} else if (crv == LZO_E_NOT_COMPRESSIBLE) {
free(compressed);
uint32_t compressed_size32 = size;
bool err = CFileMgr::Write(file, (const char*)&compressed_size32, sizeof(compressed_size32)) != sizeof(compressed_size32);
if (err || CFileMgr::GetErrorReadWrite(file)) {
nErrorCode = SAVESTATUS_ERR_SAVE_WRITE;
strncpy(SaveFileNameJustSaved, ValidSaveName, sizeof(ValidSaveName) - 1);
return false;
}
err = CFileMgr::Write(file, (const char*)data, align4bytes(size)) != align4bytes(size);
if (err || CFileMgr::GetErrorReadWrite(file)) {
nErrorCode = SAVESTATUS_ERR_SAVE_WRITE; nErrorCode = SAVESTATUS_ERR_SAVE_WRITE;
strncpy(SaveFileNameJustSaved, ValidSaveName, sizeof(ValidSaveName) - 1); strncpy(SaveFileNameJustSaved, ValidSaveName, sizeof(ValidSaveName) - 1);
return false; return false;
} }
CFileMgr::Write(file, (const char*)data, align4bytes(size));
} else { } else {
free(compressed); free(compressed);
return false; return false;

View File

@@ -98,6 +98,10 @@ PopulateRadioStationPositionList()
do {\ do {\
size = C_PcSave::PcClassLoadRoutine(file, work_buff); \ size = C_PcSave::PcClassLoadRoutine(file, work_buff); \
if (!size) {\ if (!size) {\
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_LOAD_READ; \
if (!CloseFile(file)) { \
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_LOAD_CLOSE; \
} \
return false; \ return false; \
} \ } \
buf = work_buff;\ buf = work_buff;\
@@ -121,8 +125,12 @@ do {\
save_func(buf, &size);\ save_func(buf, &size);\
debug(msg"== %i \n", size);\ debug(msg"== %i \n", size);\
CopySizeAndPreparePointer(presize, buf, postsize, reserved, size);\ CopySizeAndPreparePointer(presize, buf, postsize, reserved, size);\
if (!PcSaveHelper.PcClassSaveRoutine(file, work_buff, buf - work_buff))\ if (!PcSaveHelper.PcClassSaveRoutine(file, work_buff, buf - work_buff)) { \
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_SAVE_WRITE; \
if (!CloseFile(file)) \
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_SAVE_CLOSE; \
return false;\ return false;\
} \
totalSize += buf - work_buff;\ totalSize += buf - work_buff;\
} while (0) } while (0)
@@ -223,8 +231,12 @@ GenericSave(int file)
CTheScripts::SaveAllScripts(buf, &size); CTheScripts::SaveAllScripts(buf, &size);
debug("ScriptSize== %i \n", size); debug("ScriptSize== %i \n", size);
CopySizeAndPreparePointer(presize, buf, postsize, reserved, size); CopySizeAndPreparePointer(presize, buf, postsize, reserved, size);
if (!PcSaveHelper.PcClassSaveRoutine(file, work_buff, buf - work_buff)) if (!PcSaveHelper.PcClassSaveRoutine(file, work_buff, buf - work_buff)) {
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_SAVE_WRITE;
if (!CloseFile(file))
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_SAVE_CLOSE;
return false; return false;
}
totalSize = buf - work_buff; totalSize = buf - work_buff;
@@ -263,15 +275,19 @@ GenericSave(int file)
if (size > sizeof(work_buff)) if (size > sizeof(work_buff))
size = sizeof(work_buff); size = sizeof(work_buff);
if (size > 4) { if (size > 4) {
if (!PcSaveHelper.PcClassSaveRoutine(file, work_buff, size)) if (!PcSaveHelper.PcClassSaveRoutine(file, work_buff, size)) {
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_SAVE_WRITE;
if (!CloseFile(file))
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_SAVE_CLOSE;
return false; return false;
}
totalSize += size; totalSize += size;
} }
} }
// Write checksum and close // Write checksum and close
CFileMgr::Write(file, (const char *) &CheckSum, sizeof(CheckSum)); bool err = CFileMgr::Write(file, (const char *) &CheckSum, sizeof(CheckSum)) != sizeof(CheckSum);
if (CFileMgr::GetErrorReadWrite(file)) { if (err || CFileMgr::GetErrorReadWrite(file)) {
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_SAVE_WRITE; PcSaveHelper.nErrorCode = SAVESTATUS_ERR_SAVE_WRITE;
if (!CloseFile(file)) if (!CloseFile(file))
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_SAVE_CLOSE; PcSaveHelper.nErrorCode = SAVESTATUS_ERR_SAVE_CLOSE;
@@ -302,9 +318,17 @@ GenericLoad()
CPad::ResetCheats(); CPad::ResetCheats();
file = CFileMgr::OpenFile(LoadFileName, "rb"); file = CFileMgr::OpenFile(LoadFileName, "rb");
assert(file != 0); if (file == 0) {
return false;
}
size = C_PcSave::PcClassLoadRoutine(file, work_buff); size = C_PcSave::PcClassLoadRoutine(file, work_buff);
assert(size != 0); if (!size) {
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_LOAD_READ;
if (!CloseFile(file)) {
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_LOAD_CLOSE;
}
return false;
}
buf = (work_buff + 0x40); buf = (work_buff + 0x40);
ReadDataFromBufferPointer(buf, saveSize); ReadDataFromBufferPointer(buf, saveSize);
@@ -615,10 +639,9 @@ RestoreForStartLoad()
} }
uint32_t size = C_PcSave::PcClassLoadRoutine(file, work_buff); uint32_t size = C_PcSave::PcClassLoadRoutine(file, work_buff);
assert(size != 0);
uint8 *buf = work_buff; uint8 *buf = work_buff;
if (CFileMgr::GetErrorReadWrite(file)) { if (size == 0 || CFileMgr::GetErrorReadWrite(file)) {
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_LOAD_READ; PcSaveHelper.nErrorCode = SAVESTATUS_ERR_LOAD_READ;
if (!CloseFile(file)) if (!CloseFile(file))
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_LOAD_CLOSE; PcSaveHelper.nErrorCode = SAVESTATUS_ERR_LOAD_CLOSE;

View File

@@ -60,15 +60,17 @@ C_PcSave::SaveSlot(int32 slot)
#endif #endif
DoGameSpecificStuffBeforeSave(); DoGameSpecificStuffBeforeSave();
if (GenericSave(file)) { if (GenericSave(file)) {
if (!!CFileMgr::CloseFile(file)) if (!!CFileMgr::CloseFile(file)) {
nErrorCode = SAVESTATUS_ERR_SAVE_CLOSE; nErrorCode = SAVESTATUS_ERR_SAVE_CLOSE;
return 2;
}
return 0; return 0;
} }
return 2; return 2;
} }
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_SAVE_CREATE; PcSaveHelper.nErrorCode = SAVESTATUS_ERR_SAVE_CREATE;
return false; return 2;
} }
bool bool
@@ -82,26 +84,36 @@ C_PcSave::PcClassSaveRoutine(int32 file, uint8 *data, uint32 size)
if (crv == LZO_E_OK) { if (crv == LZO_E_OK) {
uint32_t compressed_size32 = compressed_size | 0x80000000; uint32_t compressed_size32 = compressed_size | 0x80000000;
CFileMgr::Write(file, (const char*)&compressed_size32, sizeof(compressed_size32)); bool err = CFileMgr::Write(file, (const char*)&compressed_size32, sizeof(compressed_size32)) != sizeof(compressed_size32);
if (CFileMgr::GetErrorReadWrite(file)) { if (err || CFileMgr::GetErrorReadWrite(file)) {
free(compressed); free(compressed);
nErrorCode = SAVESTATUS_ERR_SAVE_WRITE; nErrorCode = SAVESTATUS_ERR_SAVE_WRITE;
strncpy(SaveFileNameJustSaved, ValidSaveName, sizeof(ValidSaveName) - 1); strncpy(SaveFileNameJustSaved, ValidSaveName, sizeof(ValidSaveName) - 1);
return false; return false;
} }
CFileMgr::Write(file, (const char*)compressed, compressed_size); err = CFileMgr::Write(file, (const char*)compressed, compressed_size) != compressed_size;
free(compressed); free(compressed);
} else if (crv == LZO_E_NOT_COMPRESSIBLE) { if (err || CFileMgr::GetErrorReadWrite(file)) {
free(compressed); nErrorCode = SAVESTATUS_ERR_SAVE_WRITE;
uint32_t compressed_size32 = size; strncpy(SaveFileNameJustSaved, ValidSaveName, sizeof(ValidSaveName) - 1);
CFileMgr::Write(file, (const char*)&compressed_size32, sizeof(compressed_size32)); return false;
if (CFileMgr::GetErrorReadWrite(file)) { }
} else if (crv == LZO_E_NOT_COMPRESSIBLE) {
free(compressed);
uint32_t compressed_size32 = size;
bool err = CFileMgr::Write(file, (const char*)&compressed_size32, sizeof(compressed_size32)) != sizeof(compressed_size32);
if (err || CFileMgr::GetErrorReadWrite(file)) {
nErrorCode = SAVESTATUS_ERR_SAVE_WRITE;
strncpy(SaveFileNameJustSaved, ValidSaveName, sizeof(ValidSaveName) - 1);
return false;
}
err = CFileMgr::Write(file, (const char*)data, align4bytes(size)) != align4bytes(size);
if (err || CFileMgr::GetErrorReadWrite(file)) {
nErrorCode = SAVESTATUS_ERR_SAVE_WRITE; nErrorCode = SAVESTATUS_ERR_SAVE_WRITE;
strncpy(SaveFileNameJustSaved, ValidSaveName, sizeof(ValidSaveName) - 1); strncpy(SaveFileNameJustSaved, ValidSaveName, sizeof(ValidSaveName) - 1);
return false; return false;
} }
CFileMgr::Write(file, (const char*)data, align4bytes(size));
} else { } else {
free(compressed); free(compressed);
return false; return false;
@@ -125,23 +137,25 @@ C_PcSave::PcClassSaveRoutine(int32 file, uint8 *data, uint32 size)
uint32_t C_PcSave::PcClassLoadRoutine(int32 file, uint8 *data) { uint32_t C_PcSave::PcClassLoadRoutine(int32 file, uint8 *data) {
uint32 size; uint32 size;
CFileMgr::Read(file, (char*)&size, sizeof(size)); bool err = CFileMgr::Read(file, (char*)&size, sizeof(size)) != sizeof(size);
if (err) {
return 0;
}
assert(data == work_buff); assert(data == work_buff);
if (!(size & 0x80000000)) { if (!(size & 0x80000000)) {
assert(align4bytes(size) == size); assert(align4bytes(size) == size);
CFileMgr::Read(file, (char*)data, align4bytes(size)); err = CFileMgr::Read(file, (char*)data, align4bytes(size)) != align4bytes(size);
if (CFileMgr::GetErrorReadWrite(file)) { if (err || CFileMgr::GetErrorReadWrite(file)) {
return 0; return 0;
} }
return size; return size;
} else { } else {
size &= ~0x80000000; size &= ~0x80000000;
uint8* compressed = (uint8*)malloc(size); uint8* compressed = (uint8*)malloc(size);
CFileMgr::Read(file, (const char*)compressed, size); err = CFileMgr::Read(file, (const char*)compressed, size) != size;
if (CFileMgr::GetErrorReadWrite(file)) { if (err || CFileMgr::GetErrorReadWrite(file)) {
free(compressed); free(compressed);
return 0; return 0;
} }