214 lines
6 KiB
C++
214 lines
6 KiB
C++
/*
|
|
_________ __ __
|
|
/ _____// |_____________ _/ |______ ____ __ __ ______
|
|
\_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/
|
|
/ \| | | | \// __ \| | / __ \_/ /_/ > | /\___ |
|
|
/_______ /|__| |__| (____ /__| (____ /\___ /|____//____ >
|
|
\/ \/ \//_____/ \/
|
|
______________________ ______________________
|
|
T H E W A R B E G I N S
|
|
Stratagus - A free fantasy real time strategy game engine
|
|
|
|
stratagus-game-launcher.h - Stratagus Game Launcher
|
|
Copyright (C) 2015-2016 The Stratagus Developers
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef STRATAGUS_GAMEUTILS_H
|
|
#define STRATAGUS_GAMEUTILS_H
|
|
|
|
void error(const char* title, const char* text);
|
|
void mkdir_p(const char* path);
|
|
void copy_dir(const char* source_folder, const char* target_folder);
|
|
|
|
#if __APPLE__
|
|
#define USE_MAC
|
|
#endif
|
|
|
|
#if ( defined (_MSC_VER) || defined (_WIN32) || defined (_WIN64) ) && ! defined (WIN32)
|
|
#define WIN32 1
|
|
#endif
|
|
|
|
#ifndef _CRT_SECURE_NO_DEPRECATE
|
|
#define _CRT_SECURE_NO_DEPRECATE
|
|
#endif
|
|
#ifndef _CRT_SECURE_NO_WARNINGS
|
|
#define _CRT_SECURE_NO_WARNINGS
|
|
#endif
|
|
|
|
#ifdef WIN32
|
|
|
|
// set everything to winxp sp2 compatiblity
|
|
#define NTDDI_VERSION 0x05010200
|
|
#define _WIN32_WINNT 0x0501
|
|
#define WINVER 0x0501
|
|
|
|
#ifndef PATH_MAX
|
|
#define PATH_MAX MAX_PATH
|
|
#endif
|
|
#include <Shlwapi.h>
|
|
#include <Shlobj.h>
|
|
#pragma comment(lib, "comdlg32.lib")
|
|
#pragma comment(lib, "ole32.lib")
|
|
#pragma comment(lib, "Shlwapi.lib")
|
|
#include <direct.h>
|
|
#define mkdir(f, m) _mkdir(f)
|
|
// PathRemoveFileSpec on a drive (e.g. when extracting from CD) will leave the trailing \... remove that
|
|
#define parentdir(x) PathRemoveFileSpec(x); if (x[strlen(x) - 1] == '\\') x[strlen(x) - 1] = '\0'
|
|
#else
|
|
#if defined(USE_MAC)
|
|
#define parentdir(x) strcpy(x, dirname(x))
|
|
#else
|
|
#define parentdir(x) dirname(x)
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef WIN32
|
|
#include <windows.h>
|
|
#include <wincon.h>
|
|
#include <process.h>
|
|
#define QUOTE "\""
|
|
#else
|
|
#include <ftw.h>
|
|
#include <unistd.h>
|
|
#include <libgen.h>
|
|
#include <sys/wait.h>
|
|
#define QUOTE "'"
|
|
#endif
|
|
|
|
#include <errno.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
|
|
#include "stratagus-tinyfiledialogs.h"
|
|
|
|
#define BUFF_SIZE 4096
|
|
char dst_root[BUFF_SIZE];
|
|
char src_root[BUFF_SIZE];
|
|
|
|
void error(const char* title, const char* text) {
|
|
tinyfd_messageBox(title, text, "ok", "error", 1);
|
|
exit(-1);
|
|
}
|
|
|
|
void mkdir_p(const char* path) {
|
|
int error = 0;
|
|
printf("mkdir %s\n", path);
|
|
if (mkdir(path, 0777)) {
|
|
error = errno;
|
|
if (error == ENOENT) {
|
|
char *sep = strrchr((char*)path, '/');
|
|
if (sep == NULL) {
|
|
sep = strrchr((char*)path, SLASH[0]);
|
|
}
|
|
if (sep != NULL) {
|
|
*sep = '\0';
|
|
if (strlen(path) > 0) {
|
|
// will be null if the we reach the first /
|
|
mkdir_p(path);
|
|
}
|
|
*sep = '/';
|
|
mkdir(path, 0777);
|
|
}
|
|
} else if (error != EEXIST) {
|
|
if (mkdir(path, 0777)) {
|
|
printf("Error while trying to create '%s'\n", path);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifdef WIN32
|
|
#include <wchar.h>
|
|
#include <string>
|
|
void copy_dir(const char* source_folder, const char* target_folder)
|
|
{
|
|
// make the parentdir of the target folder
|
|
char* ptarget = _strdup(target_folder);
|
|
parentdir(ptarget);
|
|
mkdir_p(ptarget);
|
|
// convert source and target folder strings to windows wide strings
|
|
wchar_t *wsource_folder = new wchar_t[strlen(source_folder) + 1];
|
|
size_t convertedChars = 0;
|
|
mbstowcs_s(&convertedChars, wsource_folder, strlen(source_folder) + 1, source_folder, _TRUNCATE);
|
|
wchar_t *wtarget_folder = new wchar_t[strlen(target_folder) + 1];
|
|
mbstowcs_s(&convertedChars, wtarget_folder, strlen(target_folder) + 1, target_folder, _TRUNCATE);
|
|
WCHAR sf[MAX_PATH + 1];
|
|
WCHAR tf[MAX_PATH + 1];
|
|
wcscpy_s(sf, MAX_PATH, wsource_folder);
|
|
wcscpy_s(tf, MAX_PATH, wtarget_folder);
|
|
// ensure we have double-null terminated strings like Windows docs demand
|
|
sf[lstrlenW(sf) + 1] = 0;
|
|
tf[lstrlenW(tf) + 1] = 0;
|
|
// first delete the target_folder, if it exists
|
|
SHFILEOPSTRUCTW deleteS = { 0 };
|
|
deleteS.wFunc = FO_DELETE;
|
|
deleteS.pTo = tf;
|
|
deleteS.pFrom = tf;
|
|
deleteS.fFlags = FOF_SILENT | FOF_NOCONFIRMMKDIR | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_NO_UI;
|
|
SHFileOperationW(&deleteS);
|
|
// now copy the new folder in its place
|
|
SHFILEOPSTRUCTW s = { 0 };
|
|
s.wFunc = FO_COPY;
|
|
s.pTo = tf;
|
|
s.pFrom = sf;
|
|
s.fFlags = FOF_SILENT | FOF_NOCONFIRMMKDIR | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_NO_UI;
|
|
SHFileOperationW(&s);
|
|
}
|
|
#else
|
|
int copy_file(const char* src_path, const struct stat* sb, int typeflag) {
|
|
char dst_path[BUFF_SIZE];
|
|
printf("%s to %s\n", src_path, dst_root);
|
|
strcpy(dst_path, dst_root);
|
|
strcat(dst_path, src_path + strlen(src_root));
|
|
switch(typeflag) {
|
|
case FTW_D:
|
|
mkdir_p(dst_path);
|
|
break;
|
|
case FTW_F:
|
|
mkdir_p(parentdir(strdup(dst_path)));
|
|
FILE* in = fopen(src_path, "rb");
|
|
FILE* out = fopen(dst_path, "wb");
|
|
char buf[4096];
|
|
int c = 0;
|
|
if (!in) {
|
|
error("Extraction error", "Could not open source folder for reading.");
|
|
}
|
|
if (!out) {
|
|
error("Extraction error", "Could not open data folder for writing.");
|
|
}
|
|
while ((c = fread(buf, sizeof(char), 4096, in))) {
|
|
fwrite(buf, sizeof(char), c, out);
|
|
}
|
|
fclose(in);
|
|
fclose(out);
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void copy_dir(const char* src_path, const char* dst_path) {
|
|
printf("Copying %s to %s\n", src_path, dst_path);
|
|
mkdir_p(parentdir(strdup(dst_path)));
|
|
strcpy(dst_root, dst_path);
|
|
strcpy(src_root, src_path);
|
|
ftw(src_path, copy_file, 20);
|
|
}
|
|
#endif
|
|
|
|
#endif
|