Fix remote folder so that directory structure is exactly like in real steam.
parent
68b8e0241a
commit
9a9c3e1a4b
|
@ -19,6 +19,10 @@
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
|
struct File_Data {
|
||||||
|
std::string name;
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef NO_DISK_WRITES
|
#ifdef NO_DISK_WRITES
|
||||||
std::string Local_Storage::get_program_path()
|
std::string Local_Storage::get_program_path()
|
||||||
{
|
{
|
||||||
|
@ -159,36 +163,10 @@ static void create_directory(std::string strPath)
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
static int count_files_directory(std::string path)
|
static std::vector<struct File_Data> get_filenames(std::string strPath)
|
||||||
{
|
|
||||||
path = path.append("*");
|
|
||||||
int counter = 0;
|
|
||||||
WIN32_FIND_DATAA ffd;
|
|
||||||
HANDLE hFind = INVALID_HANDLE_VALUE;
|
|
||||||
|
|
||||||
// Start iterating over the files in the path directory.
|
|
||||||
hFind = ::FindFirstFileA (path.c_str(), &ffd);
|
|
||||||
if (hFind != INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
do // Managed to locate and create an handle to that folder.
|
|
||||||
{
|
|
||||||
if (strcmp(".", ffd.cFileName) == 0) continue;
|
|
||||||
if (strcmp("..", ffd.cFileName) == 0) continue;
|
|
||||||
counter++;
|
|
||||||
} while (::FindNextFileA(hFind, &ffd) == TRUE);
|
|
||||||
::FindClose(hFind);
|
|
||||||
} else {
|
|
||||||
//printf("Failed to find path: %s", path.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
return counter;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static bool get_filename_at_index(std::string strPath, char *filename, int index)
|
|
||||||
{
|
{
|
||||||
|
std::vector<struct File_Data> output;
|
||||||
strPath = strPath.append("\\*");
|
strPath = strPath.append("\\*");
|
||||||
int counter = 0;
|
|
||||||
WIN32_FIND_DATAA ffd;
|
WIN32_FIND_DATAA ffd;
|
||||||
HANDLE hFind = INVALID_HANDLE_VALUE;
|
HANDLE hFind = INVALID_HANDLE_VALUE;
|
||||||
|
|
||||||
|
@ -200,43 +178,53 @@ static bool get_filename_at_index(std::string strPath, char *filename, int index
|
||||||
{
|
{
|
||||||
if (strcmp(".", ffd.cFileName) == 0) continue;
|
if (strcmp(".", ffd.cFileName) == 0) continue;
|
||||||
if (strcmp("..", ffd.cFileName) == 0) continue;
|
if (strcmp("..", ffd.cFileName) == 0) continue;
|
||||||
|
struct File_Data f_data;
|
||||||
|
f_data.name = ffd.cFileName;
|
||||||
|
output.push_back(f_data);
|
||||||
|
} while (::FindNextFileA(hFind, &ffd) == TRUE);
|
||||||
|
::FindClose(hFind);
|
||||||
|
} else {
|
||||||
|
//printf("Failed to find path: %s", strPath.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
if (counter == index) {
|
return output;
|
||||||
memcpy(filename, ffd.cFileName, MAX_PATH);
|
}
|
||||||
::FindClose(hFind);
|
|
||||||
return true;
|
static std::vector<struct File_Data> get_filenames_recursive(std::string base_path)
|
||||||
|
{
|
||||||
|
std::vector<struct File_Data> output;
|
||||||
|
std::string strPath = base_path;
|
||||||
|
strPath = strPath.append("\\*");
|
||||||
|
WIN32_FIND_DATAA ffd;
|
||||||
|
HANDLE hFind = INVALID_HANDLE_VALUE;
|
||||||
|
|
||||||
|
// Start iterating over the files in the path directory.
|
||||||
|
hFind = ::FindFirstFileA (strPath.c_str(), &ffd);
|
||||||
|
if (hFind != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
do // Managed to locate and create an handle to that folder.
|
||||||
|
{
|
||||||
|
if (strcmp(".", ffd.cFileName) == 0) continue;
|
||||||
|
if (strcmp("..", ffd.cFileName) == 0) continue;
|
||||||
|
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
|
||||||
|
// Construct new path from our base path
|
||||||
|
std::string dir_name = ffd.cFileName;
|
||||||
|
|
||||||
|
std::string path = base_path;
|
||||||
|
path += "\\";
|
||||||
|
path += dir_name;
|
||||||
|
|
||||||
|
std::vector<struct File_Data> lower = get_filenames_recursive(path);
|
||||||
|
std::transform(lower.begin(), lower.end(), std::back_inserter(output), [dir_name](File_Data f) {f.name = dir_name + "\\" + f.name; return f;});
|
||||||
|
} else {
|
||||||
|
File_Data f;
|
||||||
|
f.name = ffd.cFileName;
|
||||||
|
output.push_back(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
counter++;
|
|
||||||
} while (::FindNextFileA(hFind, &ffd) == TRUE);
|
} while (::FindNextFileA(hFind, &ffd) == TRUE);
|
||||||
::FindClose(hFind);
|
::FindClose(hFind);
|
||||||
} else {
|
} else {
|
||||||
printf("Failed to find path: %s", strPath.c_str());
|
//printf("Failed to find path: %s", strPath.c_str());
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::vector<std::string> get_filenames(std::string strPath)
|
|
||||||
{
|
|
||||||
std::vector<std::string> output;
|
|
||||||
strPath = strPath.append("\\*");
|
|
||||||
WIN32_FIND_DATAA ffd;
|
|
||||||
HANDLE hFind = INVALID_HANDLE_VALUE;
|
|
||||||
|
|
||||||
// Start iterating over the files in the path directory.
|
|
||||||
hFind = ::FindFirstFileA (strPath.c_str(), &ffd);
|
|
||||||
if (hFind != INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
do // Managed to locate and create an handle to that folder.
|
|
||||||
{
|
|
||||||
if (strcmp(".", ffd.cFileName) == 0) continue;
|
|
||||||
if (strcmp("..", ffd.cFileName) == 0) continue;
|
|
||||||
output.push_back(ffd.cFileName);
|
|
||||||
} while (::FindNextFileA(hFind, &ffd) == TRUE);
|
|
||||||
::FindClose(hFind);
|
|
||||||
} else {
|
|
||||||
printf("Failed to find path: %s", strPath.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
|
@ -313,66 +301,21 @@ static void create_directory(std::string strPath)
|
||||||
mkdir_p(strPath.c_str(), 0777);
|
mkdir_p(strPath.c_str(), 0777);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int count_files_directory(std::string strPath)
|
static std::vector<struct File_Data> get_filenames(std::string strPath)
|
||||||
{
|
|
||||||
DIR *dp;
|
|
||||||
int i = 0;
|
|
||||||
struct dirent *ep;
|
|
||||||
dp = opendir (strPath.c_str());
|
|
||||||
|
|
||||||
if (dp != NULL)
|
|
||||||
{
|
|
||||||
while ((ep = readdir (dp)))
|
|
||||||
i++;
|
|
||||||
|
|
||||||
(void) closedir (dp);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i < 2) i = 2;
|
|
||||||
return i - 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
//filename should be 256 big
|
|
||||||
static bool get_filename_at_index(std::string strPath, char *filename, int index)
|
|
||||||
{
|
{
|
||||||
DIR *dp;
|
DIR *dp;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
struct dirent *ep;
|
struct dirent *ep;
|
||||||
|
std::vector<struct File_Data> output;
|
||||||
dp = opendir (strPath.c_str());
|
dp = opendir (strPath.c_str());
|
||||||
|
|
||||||
if (dp != NULL)
|
if (dp != NULL)
|
||||||
{
|
{
|
||||||
while ((ep = readdir (dp))) {
|
while ((ep = readdir (dp))) {
|
||||||
if (memcmp(ep->d_name, ".", 2) != 0 && memcmp(ep->d_name, "..", 3) != 0) {
|
if (memcmp(ep->d_name, ".", 2) != 0 && memcmp(ep->d_name, "..", 3) != 0) {
|
||||||
if (i == (index)) {
|
struct File_Data f_data;
|
||||||
memcpy(filename, ep->d_name, 256);
|
f_data.name = ep->d_name;
|
||||||
(void) closedir (dp);
|
output.push_back(f_data);
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
(void) closedir (dp);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::vector<std::string> get_filenames(std::string strPath)
|
|
||||||
{
|
|
||||||
DIR *dp;
|
|
||||||
int i = 0;
|
|
||||||
struct dirent *ep;
|
|
||||||
std::vector<std::string> output;
|
|
||||||
dp = opendir (strPath.c_str());
|
|
||||||
|
|
||||||
if (dp != NULL)
|
|
||||||
{
|
|
||||||
while ((ep = readdir (dp))) {
|
|
||||||
if (memcmp(ep->d_name, ".", 2) != 0 && memcmp(ep->d_name, "..", 3) != 0) {
|
|
||||||
output.push_back(ep->d_name);
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -383,6 +326,45 @@ static std::vector<std::string> get_filenames(std::string strPath)
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::vector<struct File_Data> get_filenames_recursive(std::string base_path)
|
||||||
|
{
|
||||||
|
std::vector<struct File_Data> output;
|
||||||
|
std::string path;
|
||||||
|
struct dirent *dp;
|
||||||
|
DIR *dir = opendir(base_path.c_str());
|
||||||
|
|
||||||
|
// Unable to open directory stream
|
||||||
|
if (!dir)
|
||||||
|
return output;
|
||||||
|
|
||||||
|
while ((dp = readdir(dir)) != NULL)
|
||||||
|
{
|
||||||
|
if (strcmp(dp->d_name, ".") != 0 && strcmp(dp->d_name, "..") != 0)
|
||||||
|
{
|
||||||
|
if (dp->d_type == DT_REG) {
|
||||||
|
File_Data f;
|
||||||
|
f.name = dp->d_name;
|
||||||
|
output.push_back(f);
|
||||||
|
} else if (dp->d_type == DT_DIR) {
|
||||||
|
// Construct new path from our base path
|
||||||
|
std::string dir_name = dp->d_name;
|
||||||
|
|
||||||
|
path = base_path;
|
||||||
|
path += "/";
|
||||||
|
path += dir_name;
|
||||||
|
|
||||||
|
std::vector<struct File_Data> lower = get_filenames_recursive(path);
|
||||||
|
std::transform(lower.begin(), lower.end(), std::back_inserter(output), [dir_name](File_Data f) {f.name = dir_name + "/" + f.name; return f;});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir(dir);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::string Local_Storage::get_program_path()
|
std::string Local_Storage::get_program_path()
|
||||||
|
@ -441,9 +423,14 @@ static std::string sanitize_file_name(std::string name)
|
||||||
{
|
{
|
||||||
//I'm not sure all of these are necessary but just to be sure
|
//I'm not sure all of these are necessary but just to be sure
|
||||||
if (name[0] == '.' && name.size() > 2 && (name[1] == '\\' || name[1] == '/')) name.erase(0, 2);
|
if (name[0] == '.' && name.size() > 2 && (name[1] == '\\' || name[1] == '/')) name.erase(0, 2);
|
||||||
name = replace_with(name, PATH_SEPARATOR, ".SLASH.");
|
|
||||||
name = replace_with(name, "\\", ".SLASH.");
|
#if defined(STEAM_WIN32)
|
||||||
name = replace_with(name, "/", ".SLASH.");
|
name = replace_with(name, "/", PATH_SEPARATOR);
|
||||||
|
#else
|
||||||
|
//On linux does using "\\" in a remote storage file name create a directory?
|
||||||
|
//I didn't test but I'm going to say yes
|
||||||
|
name = replace_with(name, "\\", PATH_SEPARATOR);
|
||||||
|
#endif
|
||||||
name = replace_with(name, "|", ".V_SLASH.");
|
name = replace_with(name, "|", ".V_SLASH.");
|
||||||
name = replace_with(name, ":", ".COLON.");
|
name = replace_with(name, ":", ".COLON.");
|
||||||
name = replace_with(name, "*", ".ASTERISK.");
|
name = replace_with(name, "*", ".ASTERISK.");
|
||||||
|
@ -489,15 +476,23 @@ int Local_Storage::store_file_data(std::string folder, std::string file, char *d
|
||||||
}
|
}
|
||||||
|
|
||||||
file = sanitize_file_name(file);
|
file = sanitize_file_name(file);
|
||||||
|
std::string::size_type pos = file.rfind(PATH_SEPARATOR);
|
||||||
|
|
||||||
create_directory(folder);
|
std::string file_folder;
|
||||||
|
if (pos == 0 || pos == std::string::npos) {
|
||||||
|
file_folder = "";
|
||||||
|
} else {
|
||||||
|
file_folder = file.substr(0,pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
create_directory(folder + file_folder);
|
||||||
std::ofstream myfile;
|
std::ofstream myfile;
|
||||||
myfile.open(folder + file, std::ios::binary | std::ios::out);
|
myfile.open(folder + file, std::ios::binary | std::ios::out);
|
||||||
if (!myfile.is_open()) return -1;
|
if (!myfile.is_open()) return -1;
|
||||||
myfile.write(data, length);
|
myfile.write(data, length);
|
||||||
int pos = myfile.tellp();
|
int position = myfile.tellp();
|
||||||
myfile.close();
|
myfile.close();
|
||||||
return pos;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Local_Storage::get_path(std::string folder)
|
std::string Local_Storage::get_path(std::string folder)
|
||||||
|
@ -518,7 +513,10 @@ std::vector<std::string> Local_Storage::get_filenames_path(std::string path)
|
||||||
path.append(PATH_SEPARATOR);
|
path.append(PATH_SEPARATOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
return get_filenames(path);
|
std::vector<struct File_Data> filenames = get_filenames(path);
|
||||||
|
std::vector<std::string> output;
|
||||||
|
std::transform(filenames.begin(), filenames.end(), std::back_inserter(output), [](struct File_Data d) { return d.name;});
|
||||||
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Local_Storage::store_data(std::string folder, std::string file, char *data, unsigned int length)
|
int Local_Storage::store_data(std::string folder, std::string file, char *data, unsigned int length)
|
||||||
|
@ -574,7 +572,7 @@ int Local_Storage::count_files(std::string folder)
|
||||||
folder.append(PATH_SEPARATOR);
|
folder.append(PATH_SEPARATOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
return count_files_directory(save_directory + appid + folder);
|
return get_filenames_recursive(save_directory + appid + folder).size();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Local_Storage::file_exists(std::string folder, std::string file)
|
bool Local_Storage::file_exists(std::string folder, std::string file)
|
||||||
|
@ -632,32 +630,31 @@ bool Local_Storage::iterate_file(std::string folder, int index, char *output_fil
|
||||||
folder.append(PATH_SEPARATOR);
|
folder.append(PATH_SEPARATOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
char temp[1024] = {};
|
std::vector<struct File_Data> files = get_filenames_recursive(save_directory + appid + folder);
|
||||||
if (get_filename_at_index(save_directory + appid + folder, temp, index)) {
|
if (index < 0 || index >= files.size()) return false;
|
||||||
std::string name = desanitize_file_name(temp);
|
|
||||||
if (output_size) *output_size = file_size(folder, name);
|
|
||||||
strcpy(output_filename, name.c_str());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
std::string name = desanitize_file_name(files[index].name);
|
||||||
|
if (output_size) *output_size = file_size(folder, name);
|
||||||
|
#if defined(STEAM_WIN32)
|
||||||
|
name = replace_with(name, PATH_SEPARATOR, "/");
|
||||||
|
#endif
|
||||||
|
strcpy(output_filename, name.c_str());
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Local_Storage::update_save_filenames(std::string folder)
|
bool Local_Storage::update_save_filenames(std::string folder)
|
||||||
{
|
{
|
||||||
int num_files = count_files(folder);
|
std::vector<struct File_Data> files = get_filenames_recursive(save_directory + appid + folder);
|
||||||
std::vector<std::string> files;
|
|
||||||
for (int i = 0; i < num_files; ++i) {
|
|
||||||
char out_folder[1024];
|
|
||||||
if (get_filename_at_index(save_directory + appid + folder, out_folder, i)) {
|
|
||||||
files.push_back(out_folder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto &path : files) {
|
for (auto &f : files) {
|
||||||
|
std::string path = f.name;
|
||||||
PRINT_DEBUG("Local_Storage:: remote file %s\n", path.c_str());
|
PRINT_DEBUG("Local_Storage:: remote file %s\n", path.c_str());
|
||||||
std::string to = sanitize_file_name(desanitize_file_name(path));
|
std::string to = sanitize_file_name(desanitize_file_name(path));
|
||||||
if (path != to) {
|
if (path != to && !file_exists(folder, to)) {
|
||||||
|
//create the folder
|
||||||
|
store_data(folder, to, (char *)"", 0);
|
||||||
|
file_delete(folder, to);
|
||||||
|
|
||||||
std::string from = (save_directory + appid + folder + PATH_SEPARATOR + path);
|
std::string from = (save_directory + appid + folder + PATH_SEPARATOR + path);
|
||||||
to = (save_directory + appid + folder + PATH_SEPARATOR + to);
|
to = (save_directory + appid + folder + PATH_SEPARATOR + to);
|
||||||
PRINT_DEBUG("Local_Storage::update_save_filenames renaming %s to %s\n", from.c_str(), to.c_str());
|
PRINT_DEBUG("Local_Storage::update_save_filenames renaming %s to %s\n", from.c_str(), to.c_str());
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
#define SETTINGS_STORAGE_FOLDER "settings"
|
#define SETTINGS_STORAGE_FOLDER "settings"
|
||||||
#define REMOTE_STORAGE_FOLDER "remote"
|
#define REMOTE_STORAGE_FOLDER "remote"
|
||||||
#define STATS_STORAGE_FOLDER "stats"
|
#define STATS_STORAGE_FOLDER "stats"
|
||||||
#define USER_DATA_FOLDER "userdata"
|
#define USER_DATA_FOLDER "local"
|
||||||
|
|
||||||
#define GAME_SETTINGS_FOLDER "steam_settings"
|
#define GAME_SETTINGS_FOLDER "steam_settings"
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue