-
Notifications
You must be signed in to change notification settings - Fork 59
/
SaveManager.cpp
136 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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#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(), 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;
}