forked from Areteic/dsfix
-
Notifications
You must be signed in to change notification settings - Fork 1
/
SaveManager.cpp
122 lines (122 loc) · 4.55 KB
/
SaveManager.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include "SaveManager.h"
#include <algorithm>
#include "Settings.h"
#define QUOTE(str) #str
#define EXPAND_AND_QUOTE(str) QUOTE(str)
#define TIMESTAMP_LENGTH 12
#define TIMESTAMP_LENGTH_STR EXPAND_AND_QUOTE(TIMESTAMP_LENGTH)
SaveManager SaveManager::instance;
void SaveManager::init() {
if(Settings::get().getEnableBackups()) {
CHAR documents[MAX_PATH];
HRESULT hr = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, documents);
char buffer[MAX_PATH];
sprintf_s(buffer, "%s%s", documents, "\\NBGI\\DarkSouls\\*");
//find user save folder
WIN32_FIND_DATA userSaveFolderData;
HANDLE searchHandle = FindFirstFile(buffer, &userSaveFolderData);
bool found = false;
if(searchHandle != INVALID_HANDLE_VALUE) {
do {
std::string fn = userSaveFolderData.cFileName;
bool dir = !!(userSaveFolderData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
bool saveFile = fn.substr(fn.find_last_of(".") + 1) == "sl2";
//newer versions don't contain an additional folder under NBGI\\DarkSouls
if (fn.size() > 2 && (dir || saveFile)) {
if (dir)
sprintf_s(buffer, "%s%s%s", documents, "\\NBGI\\DarkSouls\\", userSaveFolderData.cFileName);
else
sprintf_s(buffer, "%s%s", documents, "\\NBGI\\DarkSouls");
userSaveFolder = string(buffer);
SDLOG(0, "SaveManager: user save folder is %s\n", userSaveFolder.c_str());
found = true;
break;
}
} while(FindNextFile(searchHandle, &userSaveFolderData));
}
if(!found) {
SDLOG(0, "SaveManager: could not determine user save folder\n");
return;
}
removeOldBackups();
}
}
void SaveManager::tick() {
if(Settings::get().getEnableBackups()) {
time_t curTime = time(NULL);
if(curTime - getLastBackupTime() > Settings::get().getBackupInterval()) {
backup(curTime);
lastBackupTime = curTime;
}
}
}
time_t SaveManager::getLastBackupTime() {
if(lastBackupTime == 0) {
vector<string> backupFiles = getSaveFiles(".bak");
if(!backupFiles.empty()) {
string fn = getFileNameFromPath(backupFiles.front());
sscanf_s(fn.c_str(), "%lu", &lastBackupTime);
}
}
SDLOG(3, "SaveManager: last backup time %ld\n", lastBackupTime);
return lastBackupTime;
}
vector<string> SaveManager::getSaveFiles(const char* ending /*= ".sl2"*/) {
SDLOG(2, "SaveManager: searching for files ending on %s\n", ending);
vector<string> ret;
//find saved files
if(userSaveFolder.length() > 0) {
char buffer[MAX_PATH];
sprintf_s(buffer, "%s\\*%s", userSaveFolder.c_str(), ending);
WIN32_FIND_DATA saveFileData;
HANDLE searchHandle = FindFirstFile(buffer, &saveFileData);
if(searchHandle != INVALID_HANDLE_VALUE) {
do {
char buff2[MAX_PATH];
sprintf_s(buff2, "%s\\%s", userSaveFolder.c_str(), saveFileData.cFileName);
ret.push_back(string(buff2));
} while(FindNextFile(searchHandle, &saveFileData));
}
std::sort(ret.begin(), ret.end());
std::reverse(ret.begin(), ret.end());
for(size_t i=0; i<ret.size(); ++i) {
SDLOG(4, "SaveManager: found existing file %s\n", ret[i].c_str());
}
}
return ret;
}
void SaveManager::backup(const time_t curTime) {
SDLOG(1, "SaveManager: Backing up save files\n");
char buffer[MAX_PATH];
vector<string> saveFiles = getSaveFiles();
for(size_t i=0; i<saveFiles.size(); ++i) {
string fn = getFileNameFromPath(saveFiles[i]);
sprintf_s(buffer, "%s\\%0" TIMESTAMP_LENGTH_STR "lu_", userSaveFolder.c_str(), static_cast<unsigned long>(curTime));
string newPath = string(buffer) + fn + ".bak";
if(CopyFile(saveFiles[i].c_str(), newPath.c_str(), false) == 0) {
SDLOG(0, "ERROR: SaveManager failed to back up file! (Copying %s to %s)\n", saveFiles[i].c_str(), buffer);
} else {
SDLOG(1, "SaveManager: Backed up %s\n", fn.c_str());
}
}
removeOldBackups();
}
void SaveManager::removeOldBackups() {
vector<string> backupFiles = getSaveFiles(".bak");
if(Settings::get().getMaxBackups() < backupFiles.size()) {
SDLOG(1, "SaveManager: Removing %u old backups\n", backupFiles.size() - Settings::get().getMaxBackups());
for(size_t i=Settings::get().getMaxBackups(); i<backupFiles.size(); ++i) {
DeleteFile(backupFiles[i].c_str());
}
}
}
string SaveManager::getFileNameFromPath(const string& path) {
size_t pos = path.rfind('\\');
if(pos != path.npos) {
pos += 1;
return path.substr(pos);
} else {
SDLOG(0, "ERROR: SaveManager could not extract file name from path %s\n", path.c_str());
}
return path;
}