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 {\
size = C_PcSave::PcClassLoadRoutine(file, work_buff); \
if (!size) {\
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_LOAD_READ; \
if (!CloseFile(file)) { \
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_LOAD_CLOSE; \
} \
return false; \
} \
buf = work_buff;\
@@ -95,8 +99,12 @@ do {\
MakeSpaceForSizeInBufferPointer(presize, buf, postsize);\
save_func(buf, &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;\
} \
totalSize += buf - work_buff;\
} while (0)
@@ -195,8 +203,12 @@ GenericSave(int file)
postsize = buf;
CTheScripts::SaveAllScripts(buf, &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;
}
totalSize = buf - work_buff;
@@ -232,15 +244,19 @@ GenericSave(int file)
if (size > sizeof(work_buff))
size = sizeof(work_buff);
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;
}
totalSize += size;
}
}
// Write checksum and close
CFileMgr::Write(file, (const char *) &CheckSum, sizeof(CheckSum));
if (CFileMgr::GetErrorReadWrite(file)) {
bool err = CFileMgr::Write(file, (const char *) &CheckSum, sizeof(CheckSum)) != sizeof(CheckSum);
if (err || CFileMgr::GetErrorReadWrite(file)) {
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_SAVE_WRITE;
if (!CloseFile(file))
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_SAVE_CLOSE;
@@ -269,9 +285,17 @@ GenericLoad()
CDate dummy; // unused
CPad::ResetCheats();
file = CFileMgr::OpenFile(LoadFileName, "rb");
assert(file != 0);
if (file == 0) {
return false;
}
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);
ReadDataFromBufferPointer(buf, saveSize);
#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);
assert(size != 0);
uint8 *buf = work_buff;
if (CFileMgr::GetErrorReadWrite(file)) {
if (size == 0 || CFileMgr::GetErrorReadWrite(file)) {
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_LOAD_READ;
if (!CloseFile(file))
PcSaveHelper.nErrorCode = SAVESTATUS_ERR_LOAD_CLOSE;

View File

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

View File

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

View File

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