And now starting the actual game works when in directories with characters like 敨

also completely untested so I hope I didn't break non-windows..
This commit is contained in:
UnknownShadow200 2019-08-15 21:37:46 +10:00
parent c3f9110778
commit ce715a4001
3 changed files with 95 additions and 89 deletions

View File

@ -565,17 +565,11 @@ bool Launcher_StartGame(const String* user, const String* mppass, const String*
Options_Save();
}
#ifndef CC_BUILD_ANDROID
String_InitArray(path, pathBuffer);
res = Process_GetExePath(&path);
if (res) { Logger_Warn(res, "getting .exe path"); return false; }
#endif
String_InitArray(args, argsBuffer);
String_AppendString(&args, user);
if (mppass->length) String_Format3(&args, " %s %s %s", mppass, ip, port);
res = Process_Start(&path, &args);
res = Process_StartGame(&args);
if (res) { Logger_Warn(res, "starting game"); return false; }
#ifdef CC_BUILD_ANDROID

View File

@ -349,7 +349,7 @@ uint64_t Stopwatch_Measure(void) {
*#########################################################################################################################*/
#if defined CC_BUILD_WIN
bool Directory_Exists(const String* path) {
TCHAR str[300];
TCHAR str[NATIVE_STR_LEN];
DWORD attribs;
Platform_ConvertString(str, path);
@ -358,7 +358,7 @@ bool Directory_Exists(const String* path) {
}
ReturnCode Directory_Create(const String* path) {
TCHAR str[300];
TCHAR str[NATIVE_STR_LEN];
BOOL success;
Platform_ConvertString(str, path);
@ -367,7 +367,7 @@ ReturnCode Directory_Create(const String* path) {
}
bool File_Exists(const String* path) {
TCHAR str[300];
TCHAR str[NATIVE_STR_LEN];
DWORD attribs;
Platform_ConvertString(str, path);
@ -377,7 +377,7 @@ bool File_Exists(const String* path) {
ReturnCode Directory_Enum(const String* dirPath, void* obj, Directory_EnumCallback callback) {
String path; char pathBuffer[MAX_PATH + 10];
TCHAR str[300];
TCHAR str[NATIVE_STR_LEN];
WIN32_FIND_DATA entry;
HANDLE find;
ReturnCode res;
@ -455,7 +455,7 @@ ReturnCode File_SetModifiedTime(const String* path, TimeMS time) {
ReturnCode File_MarkExecutable(const String* path) { return 0; }
static ReturnCode File_Do(FileHandle* file, const String* path, DWORD access, DWORD createMode) {
TCHAR str[300];
TCHAR str[NATIVE_STR_LEN];
Platform_ConvertString(str, path);
*file = CreateFile(str, access, FILE_SHARE_READ, NULL, createMode, 0, NULL);
return *file != INVALID_HANDLE_VALUE ? 0 : GetLastError();
@ -504,14 +504,14 @@ ReturnCode File_Length(FileHandle file, uint32_t* len) {
}
#elif defined CC_BUILD_POSIX
bool Directory_Exists(const String* path) {
char str[600];
char str[NATIVE_STR_LEN];
struct stat sb;
Platform_ConvertString(str, path);
return stat(str, &sb) == 0 && S_ISDIR(sb.st_mode);
}
ReturnCode Directory_Create(const String* path) {
char str[600];
char str[NATIVE_STR_LEN];
Platform_ConvertString(str, path);
/* read/write/search permissions for owner and group, and with read/search permissions for others. */
/* TODO: Is the default mode in all cases */
@ -519,7 +519,7 @@ ReturnCode Directory_Create(const String* path) {
}
bool File_Exists(const String* path) {
char str[600];
char str[NATIVE_STR_LEN];
struct stat sb;
Platform_ConvertString(str, path);
return stat(str, &sb) == 0 && S_ISREG(sb.st_mode);
@ -527,7 +527,7 @@ bool File_Exists(const String* path) {
ReturnCode Directory_Enum(const String* dirPath, void* obj, Directory_EnumCallback callback) {
String path; char pathBuffer[FILENAME_SIZE];
char str[600];
char str[NATIVE_STR_LEN];
DIR* dirPtr;
struct dirent* entry;
char* src;
@ -570,7 +570,7 @@ ReturnCode Directory_Enum(const String* dirPath, void* obj, Directory_EnumCallba
}
ReturnCode File_GetModifiedTime(const String* path, TimeMS* time) {
char str[600];
char str[NATIVE_STR_LEN];
struct stat sb;
Platform_ConvertString(str, path);
if (stat(str, &sb) == -1) return errno;
@ -580,7 +580,7 @@ ReturnCode File_GetModifiedTime(const String* path, TimeMS* time) {
}
ReturnCode File_SetModifiedTime(const String* path, TimeMS time) {
char str[600];
char str[NATIVE_STR_LEN];
struct utimbuf times = { 0 };
times.modtime = (time - UNIX_EPOCH) / 1000;
@ -589,7 +589,7 @@ ReturnCode File_SetModifiedTime(const String* path, TimeMS time) {
}
ReturnCode File_MarkExecutable(const String* path) {
char str[600];
char str[NATIVE_STR_LEN];
struct stat st;
Platform_ConvertString(str, path);
@ -599,7 +599,7 @@ ReturnCode File_MarkExecutable(const String* path) {
}
static ReturnCode File_Do(FileHandle* file, const String* path, int mode) {
char str[600];
char str[NATIVE_STR_LEN];
Platform_ConvertString(str, path);
*file = open(str, mode, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
return *file == -1 ? errno : 0;
@ -1542,22 +1542,29 @@ static ReturnCode Process_RawStart(const TCHAR* path, TCHAR* args) {
return 0;
}
ReturnCode Process_Start(const String* path, const String* args) {
String file, argv; char argvBuffer[300];
TCHAR str[300], raw[300];
static ReturnCode Process_RawGetExePath(TCHAR* path, int* len) {
*len = GetModuleFileName(NULL, path, NATIVE_STR_LEN);
return *len ? 0 : GetLastError();
}
ReturnCode Process_StartGame(const String* args) {
String argv; char argvBuffer[NATIVE_STR_LEN];
TCHAR raw[NATIVE_STR_LEN], path[NATIVE_STR_LEN + 1];
int len;
ReturnCode res = Process_RawGetExePath(path, &len);
if (res) return res;
path[len] = '\0';
file = *path; Utils_UNSAFE_GetFilename(&file);
String_InitArray(argv, argvBuffer);
String_Format2(&argv, "\"%s\" %s", &file, args);
Platform_ConvertString(str, path);
String_Format1(&argv, "ClassiCube.exe %s", args);
Platform_ConvertString(raw, &argv);
return Process_RawStart(str, raw);
return Process_RawStart(path, raw);
}
void Process_Exit(ReturnCode code) { ExitProcess(code); }
ReturnCode Process_StartOpen(const String* args) {
TCHAR str[300];
TCHAR str[NATIVE_STR_LEN];
HINSTANCE instance;
Platform_ConvertString(str, args);
instance = ShellExecute(NULL, NULL, str, NULL, NULL, SW_SHOWNORMAL);
@ -1566,32 +1573,27 @@ ReturnCode Process_StartOpen(const String* args) {
ReturnCode Process_StartShell(void) {
static const String args = String_FromConst("cmd.exe /C start cmd /C " UPDATE_FILENAME);
TCHAR str[300];
TCHAR str[NATIVE_STR_LEN];
/* args must be modifiable, otherwise access violation */
Platform_ConvertString(str, &args);
return Process_RawStart(NULL, str);
}
static ReturnCode Process_GetRawExePath(TCHAR* path, int* len) {
*len = GetModuleFileName(NULL, path, NATIVE_STR_LEN);
return *len ? 0 : GetLastError();
}
ReturnCode Process_GetExePath(String* path) {
TCHAR raw[NATIVE_STR_LEN];
int len;
ReturnCode res = Process_GetRawExePath(raw, &len);
ReturnCode res = Process_RawGetExePath(raw, &len);
if (res) return res;
Platform_DecodeString(path, raw, len);
return 0;
}
#elif defined CC_BUILD_WEB
ReturnCode Process_Start(const String* path, const String* args) { return ERR_NOT_SUPPORTED; }
ReturnCode Process_StartGame(const String* args) { return ERR_NOT_SUPPORTED; }
void Process_Exit(ReturnCode code) { exit(code); }
ReturnCode Process_StartOpen(const String* args) {
char str[600];
char str[NATIVE_STR_LEN];
Platform_ConvertString(str, args);
EM_ASM_({ window.open(UTF8ToString($0)); }, str);
return 0;
@ -1603,7 +1605,7 @@ ReturnCode Process_GetExePath(String* path) { return ERR_NOT_SUPPORTED; }
static char gameArgsBuffer[512];
static String gameArgs = String_FromArray(gameArgsBuffer);
ReturnCode Process_Start(const String* path, const String* args) {
ReturnCode Process_StartGame(const String* args) {
String_Copy(&gameArgs, args);
return 0; /* TODO: Is there a clean way of handling an error */
}
@ -1617,32 +1619,13 @@ ReturnCode Process_StartOpen(const String* args) {
ReturnCode Process_StartShell(void) { return ERR_NOT_SUPPORTED; }
ReturnCode Process_GetExePath(String* path) { return ERR_NOT_SUPPORTED; }
#elif defined CC_BUILD_POSIX
ReturnCode Process_Start(const String* path, const String* args) {
char str[600], raw[600];
pid_t pid;
int i, j;
Platform_ConvertString(str, path);
Platform_ConvertString(raw, args);
pid = fork();
static ReturnCode Process_RawStart(const char* path, const char** argv) {
pid_t pid = fork();
if (pid == -1) return errno;
if (pid == 0) {
/* Executed in child process */
char* argv[15];
argv[0] = str; argv[1] = raw;
/* need to null-terminate multiple arguments */
for (i = 0, j = 2; raw[i] && i < Array_Elems(raw); i++) {
if (raw[i] != ' ') continue;
/* null terminate previous argument */
raw[i] = '\0';
argv[j++] = &raw[i + 1];
}
argv[j] = NULL;
execvp(str, argv);
execvp(path, argv);
_exit(127); /* "command not found" */
} else {
/* Executed in parent process */
@ -1651,13 +1634,46 @@ ReturnCode Process_Start(const String* path, const String* args) {
}
}
static ReturnCode Process_RawStartOpen(const char* path, const String* url) {
char raw[NATIVE_STR_LEN];
const char* args[3];
Platform_ConvertString(raw, url);
args[0] = path; args[1] = raw; args[2] = NULL;
return Process_RawStart(path, args);
}
static ReturnCode Process_RawGetExePath(char* path, int* len);
ReturnCode Process_StartGame(const String* args) {
char path[NATIVE_STR_LEN], raw[NATIVE_STR_LEN];
int i, j, len = 0;
char* argv[15];
ReturnCode res = Process_RawGetExePath(path, &len);
if (res) return res;
path[len] = '\0';
Platform_ConvertString(raw, args);
argv[0] = path; argv[1] = raw;
/* need to null-terminate multiple arguments */
for (i = 0, j = 2; raw[i] && i < Array_Elems(raw); i++) {
if (raw[i] != ' ') continue;
/* null terminate previous argument */
raw[i] = '\0';
argv[j++] = &raw[i + 1];
}
argv[j] = NULL;
return Process_RawStart(path, argv);
}
void Process_Exit(ReturnCode code) { exit(code); }
static ReturnCode Process_GetRawExePath(char* path, int* len);
ReturnCode Process_GetExePath(String* path) {
char str[NATIVE_STR_LEN];
int len = 0;
ReturnCode res = Process_GetRawExePath(str, &len);
ReturnCode res = Process_RawGetExePath(str, &len);
if (res) return res;
Platform_DecodeString(path, str, len);
@ -1667,45 +1683,41 @@ ReturnCode Process_GetExePath(String* path) {
/* Opening browser and starting shell is not really standardised */
#if defined CC_BUILD_OSX
ReturnCode Process_StartOpen(const String* args) {
static const String path = String_FromConst("/usr/bin/open");
return Process_Start(&path, args);
return Process_RawStartOpen("/usr/bin/open", args);
}
ReturnCode Process_StartShell(void) {
static const String path = String_FromConst("/usr/bin/open");
static const String args = String_FromConst("-a Terminal ./update.sh");
return Process_Start(&path, &args);
static const char* args[5] = { "/usr/bin/open", "-a", "Terminal", "./update.sh", NULL };
return Process_RawStart("/usr/bin/open", args);
}
#elif defined CC_BUILD_UNIX
ReturnCode Process_StartOpen(const String* args) {
/* TODO: Can this be used on original Solaris, or is it just an OpenIndiana thing */
static const String path = String_FromConst("xdg-open");
return Process_Start(&path, args);
return Process_RawStartOpen("xdg-open", args);
}
ReturnCode Process_StartShell(void) {
/* There isn't a standardised way to "run command in user's preferred terminal" */
/* xterm is pretty much universally available though */
static const String path = String_FromConst("xterm");
static const String args = String_FromConst("-e ./update.sh");
return Process_Start(&path, &args);
static const char* args[4] = { "xterm", "-e", "./update.sh", NULL };
return Process_RawStart("xterm", args);
}
#endif
/* Retrieving exe path is completely OS dependant */
#if defined CC_BUILD_OSX
static ReturnCode Process_GetRawExePath(char* path, int* len) {
static ReturnCode Process_RawGetExePath(char* path, int* len) {
Mem_Set(path, '\0', NATIVE_STR_LEN);
uint32_t size = 600;
if (_NSGetExecutablePath(str, &size)) return ERR_INVALID_ARGUMENT;
if (_NSGetExecutablePath(path, &size)) return ERR_INVALID_ARGUMENT;
*len = String_CalcLen(path, NATIVE_STR_LEN);
return 0;
}
#elif defined CC_BUILD_LINUX
static ReturnCode Process_GetRawExePath(char* path, int* len) {
static ReturnCode Process_RawGetExePath(char* path, int* len) {
*len = readlink("/proc/self/exe", path, NATIVE_STR_LEN);
return *len == -1 ? errno : 0;
}
#elif defined CC_BUILD_FREEBSD
static ReturnCode Process_GetRawExePath(char* path, int* len) {
static ReturnCode Process_RawGetExePath(char* path, int* len) {
static int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
size_t size = NATIVE_STR_LEN;
@ -1714,9 +1726,9 @@ static ReturnCode Process_GetRawExePath(char* path, int* len) {
return 0;
}
#elif defined CC_BUILD_OPENBSD
static ReturnCode Process_GetRawExePath(char* path, int* len) {
static ReturnCode Process_RawGetExePath(char* path, int* len) {
static int mib[4] = { CTL_KERN, KERN_PROC_ARGS, 0, KERN_PROC_ARGV };
char tmp[600];
char tmp[NATIVE_STR_LEN];
size_t size;
char* argv[100];
char* str;
@ -1740,7 +1752,7 @@ static ReturnCode Process_GetRawExePath(char* path, int* len) {
return 0;
}
#elif defined CC_BUILD_NETBSD
static ReturnCode Process_GetRawExePath(char* path, int* len) {
static ReturnCode Process_RawGetExePath(char* path, int* len) {
static int mib[4] = { CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME };
size_t size = NATIVE_STR_LEN;
@ -1749,7 +1761,7 @@ static ReturnCode Process_GetRawExePath(char* path, int* len) {
return 0;
}
#elif defined CC_BUILD_SOLARIS
static ReturnCode Process_GetRawExePath(char* path, int* len) {
static ReturnCode Process_RawGetExePath(char* path, int* len) {
*len = readlink("/proc/self/path/a.out", path, NATIVE_STR_LEN);
return *len == -1 ? errno : 0;
}
@ -1761,7 +1773,7 @@ static ReturnCode Process_GetRawExePath(char* path, int* len) {
*#########################################################################################################################*/
#if defined CC_BUILD_WIN
ReturnCode DynamicLib_Load(const String* path, void** lib) {
TCHAR str[300];
TCHAR str[NATIVE_STR_LEN];
Platform_ConvertString(str, path);
*lib = LoadLibrary(str);
return *lib ? 0 : GetLastError();
@ -1781,7 +1793,7 @@ ReturnCode DynamicLib_Get(void* lib, const char* name, void** symbol) { return E
bool DynamicLib_DescribeError(ReturnCode res, String* dst) { return false; }
#elif defined CC_BUILD_POSIX
ReturnCode DynamicLib_Load(const String* path, void** lib) {
char str[600];
char str[NATIVE_STR_LEN];
Platform_ConvertString(str, path);
*lib = dlopen(str, RTLD_NOW);
return *lib == NULL;
@ -1880,7 +1892,7 @@ void Platform_Free(void) {
ReturnCode Platform_SetDefaultCurrentDirectory(void) {
TCHAR path[NATIVE_STR_LEN + 1];
int i, len;
ReturnCode res = Process_GetRawExePath(path, &len);
ReturnCode res = Process_RawGetExePath(path, &len);
if (res) return res;
/* Get rid of filename at end of directory */
@ -1958,7 +1970,7 @@ ReturnCode Platform_Decrypt(const void* data, int len, uint8_t** dec, int* decLe
}
bool Platform_DescribeError(ReturnCode res, String* dst) {
TCHAR chars[600];
TCHAR chars[NATIVE_STR_LEN];
res = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, res, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), chars, 600, NULL);
if (!res) return false;
@ -2030,7 +2042,7 @@ ReturnCode Platform_Decrypt(const void* data, int len, uint8_t** dec, int* decLe
ReturnCode Platform_SetDefaultCurrentDirectory(void) {
char path[NATIVE_STR_LEN];
int i, len = 0;
ReturnCode res = Process_GetRawExePath(path, &len);
ReturnCode res = Process_RawGetExePath(path, &len);
if (res) return res;
/* get rid of filename at end of directory */
@ -2044,7 +2056,7 @@ ReturnCode Platform_SetDefaultCurrentDirectory(void) {
#endif
bool Platform_DescribeError(ReturnCode res, String* dst) {
char chars[600];
char chars[NATIVE_STR_LEN];
int len;
len = strerror_r(res, chars, 600);

View File

@ -61,8 +61,8 @@ ReturnCode Platform_Decrypt(const void* data, int len, uint8_t** dec, int* decLe
describe exists (e.g. DynamicLib_DescribeError), that should be preferred. */
bool Platform_DescribeError(ReturnCode res, String* dst);
/* Starts the given program with the given arguments. */
CC_API ReturnCode Process_Start(const String* path, const String* args);
/* Starts the game with the given arguments. */
CC_API ReturnCode Process_StartGame(const String* args);
/* Terminates the process with the given return code. */
CC_API void Process_Exit(ReturnCode code);
/* Starts the platform-specific program to open the given url or filename. */