mirror of
https://forgejo.xatacraft.ru/Sunshine/mkxp-sunshine.git
synced 2026-08-19 13:29:54 +00:00
Fix steamshim on OS X and Windows
This commit is contained in:
parent
546f29f42e
commit
6f3d70e6e4
3 changed files with 65 additions and 20 deletions
|
|
@ -65,12 +65,11 @@ static void closePipe(PipeType fd)
|
||||||
CloseHandle(fd);
|
CloseHandle(fd);
|
||||||
} /* closePipe */
|
} /* closePipe */
|
||||||
|
|
||||||
static char *getEnvVar(const char *key, char *buf, const size_t _buflen)
|
static char *getEnvVar(const char *key, char *buf, const size_t buflen)
|
||||||
{
|
{
|
||||||
const DWORD buflen = (DWORD) _buflen;
|
|
||||||
const DWORD rc = GetEnvironmentVariableA(key, buf, buflen);
|
const DWORD rc = GetEnvironmentVariableA(key, buf, buflen);
|
||||||
/* rc doesn't count null char, hence "<". */
|
/* rc doesn't count null char, hence "<". */
|
||||||
return ((rc > 0) && (rc < buflen)) ? NULL : buf;
|
return ((rc > 0) && (rc < buflen)) ? buf : NULL;
|
||||||
} /* getEnvVar */
|
} /* getEnvVar */
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
@ -157,21 +156,14 @@ static inline int writeBye(void)
|
||||||
static int initPipes(void)
|
static int initPipes(void)
|
||||||
{
|
{
|
||||||
char buf[64];
|
char buf[64];
|
||||||
unsigned long long val;
|
|
||||||
|
|
||||||
if (!getEnvVar("STEAMSHIM_READHANDLE", buf, sizeof (buf)))
|
if (!getEnvVar("STEAMSHIM_READHANDLE", buf, sizeof (buf)))
|
||||||
return 0;
|
return 0;
|
||||||
else if ((val = strtoull(buf, 0, 10)) == 0)
|
GPipeRead = (PipeType) strtoull(buf, 0, 10);
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
GPipeRead = (PipeType) val;
|
|
||||||
|
|
||||||
if (!getEnvVar("STEAMSHIM_WRITEHANDLE", buf, sizeof (buf)))
|
if (!getEnvVar("STEAMSHIM_WRITEHANDLE", buf, sizeof (buf)))
|
||||||
return 0;
|
return 0;
|
||||||
else if ((val = strtoull(buf, 0, 10)) == 0)
|
GPipeWrite = (PipeType) strtoull(buf, 0, 10);
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
GPipeWrite = (PipeType) val;
|
|
||||||
|
|
||||||
return ((GPipeRead != NULLPIPE) && (GPipeWrite != NULLPIPE));
|
return ((GPipeRead != NULLPIPE) && (GPipeWrite != NULLPIPE));
|
||||||
} /* initPipes */
|
} /* initPipes */
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ GAME_LAUNCH_NAME ?= oneshot
|
||||||
CXX ?= clang++
|
CXX ?= clang++
|
||||||
WINDRES ?= windres
|
WINDRES ?= windres
|
||||||
HOST ?= linux64
|
HOST ?= linux64
|
||||||
FLAGS := -I$(STEAMWORKS)/public -DGAME_LAUNCH_NAME=\"$(GAME_LAUNCH_NAME)\"
|
FLAGS := -I$(STEAMWORKS)/public -DGAME_LAUNCH_NAME=\"$(GAME_LAUNCH_NAME)\" -Wall
|
||||||
|
|
||||||
ifeq ($(HOST),w32)
|
ifeq ($(HOST),w32)
|
||||||
FLAGS += -L$(STEAMWORKS)/redistributable_bin -mwindows
|
FLAGS += -L$(STEAMWORKS)/redistributable_bin -mwindows
|
||||||
|
|
|
||||||
|
|
@ -9,18 +9,21 @@
|
||||||
typedef PROCESS_INFORMATION ProcessType;
|
typedef PROCESS_INFORMATION ProcessType;
|
||||||
typedef HANDLE PipeType;
|
typedef HANDLE PipeType;
|
||||||
#define NULLPIPE NULL
|
#define NULLPIPE NULL
|
||||||
|
#define LLUFMT "%I64u"
|
||||||
#else
|
#else
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <fcntl.h>
|
||||||
typedef pid_t ProcessType;
|
typedef pid_t ProcessType;
|
||||||
typedef int PipeType;
|
typedef int PipeType;
|
||||||
#define NULLPIPE -1
|
#define NULLPIPE -1
|
||||||
|
#define LLUFMT "%llu"
|
||||||
#endif
|
#endif
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "steam/steam_api.h"
|
#include "steam/steam_api.h"
|
||||||
|
|
||||||
|
|
@ -99,11 +102,57 @@ static bool setEnvVar(const char *key, const char *val)
|
||||||
return (SetEnvironmentVariableA(key, val) != 0);
|
return (SetEnvironmentVariableA(key, val) != 0);
|
||||||
} // setEnvVar
|
} // setEnvVar
|
||||||
|
|
||||||
|
static LPWSTR genCommandLine()
|
||||||
|
{
|
||||||
|
// Construct a command line with the appropriate filename
|
||||||
|
LPWSTR cmdline = GetCommandLineW();
|
||||||
|
|
||||||
|
// Find the index of the first argument after 0
|
||||||
|
int iFirstArg = -1;
|
||||||
|
bool quote = false;
|
||||||
|
bool whitespace = false;
|
||||||
|
for (int i = 0; cmdline[i]; ++i)
|
||||||
|
{
|
||||||
|
if (cmdline[i] == '"' && (i == 0 || cmdline[i-1] != '\\'))
|
||||||
|
{
|
||||||
|
quote = !quote;
|
||||||
|
whitespace = false;
|
||||||
|
}
|
||||||
|
else if (!quote && (cmdline[i] == ' ' || cmdline[i] == '\t'))
|
||||||
|
{
|
||||||
|
whitespace = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (whitespace)
|
||||||
|
{
|
||||||
|
iFirstArg = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
whitespace = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If it doesn't exist, that must mean there are no arguments,
|
||||||
|
// so just return GAME_LAUNCH_NAME
|
||||||
|
if (iFirstArg == -1)
|
||||||
|
return _wcsdup(TEXT("\".\\" GAME_LAUNCH_NAME ".exe\""));
|
||||||
|
|
||||||
|
// Create the new string
|
||||||
|
// (`".\.exe" ` == +9
|
||||||
|
LPWSTR newcmdline = (LPWSTR)malloc(sizeof(TEXT(GAME_LAUNCH_NAME))
|
||||||
|
+ sizeof(WCHAR) * (wcslen(cmdline) - iFirstArg + 9));
|
||||||
|
wsprintf(newcmdline, TEXT("\".\\" GAME_LAUNCH_NAME ".exe\" %s"), cmdline + iFirstArg);
|
||||||
|
return newcmdline;
|
||||||
|
}
|
||||||
|
|
||||||
static bool launchChild(ProcessType *pid)
|
static bool launchChild(ProcessType *pid)
|
||||||
{
|
{
|
||||||
return (CreateProcessW(TEXT(".\\") TEXT(GAME_LAUNCH_NAME) TEXT(".exe"),
|
STARTUPINFOW si;
|
||||||
GetCommandLineW(), NULL, NULL, TRUE, 0, NULL,
|
memset(&si, 0, sizeof(si));
|
||||||
NULL, NULL, pid) != 0);
|
return CreateProcessW(TEXT(".\\" GAME_LAUNCH_NAME ".exe"),
|
||||||
|
genCommandLine(), NULL, NULL, TRUE, 0, NULL,
|
||||||
|
NULL, &si, pid);
|
||||||
} // launchChild
|
} // launchChild
|
||||||
|
|
||||||
static int closeProcess(ProcessType *pid)
|
static int closeProcess(ProcessType *pid)
|
||||||
|
|
@ -153,6 +202,8 @@ static bool createPipes(PipeType *pPipeParentRead, PipeType *pPipeParentWrite,
|
||||||
int fds[2];
|
int fds[2];
|
||||||
if (pipe(fds) == -1)
|
if (pipe(fds) == -1)
|
||||||
return 0;
|
return 0;
|
||||||
|
fcntl(fds[0], F_SETFL, 0);
|
||||||
|
fcntl(fds[1], F_SETFL, 0);
|
||||||
*pPipeParentRead = fds[0];
|
*pPipeParentRead = fds[0];
|
||||||
*pPipeChildWrite = fds[1];
|
*pPipeChildWrite = fds[1];
|
||||||
|
|
||||||
|
|
@ -163,6 +214,8 @@ static bool createPipes(PipeType *pPipeParentRead, PipeType *pPipeParentWrite,
|
||||||
return 0;
|
return 0;
|
||||||
} // if
|
} // if
|
||||||
|
|
||||||
|
fcntl(fds[0], F_SETFL, 0);
|
||||||
|
fcntl(fds[1], F_SETFL, 0);
|
||||||
*pPipeChildRead = fds[0];
|
*pPipeChildRead = fds[0];
|
||||||
*pPipeParentWrite = fds[1];
|
*pPipeParentWrite = fds[1];
|
||||||
|
|
||||||
|
|
@ -337,7 +390,7 @@ static bool writeAchievementGet(PipeType fd, const char *name, const int status,
|
||||||
{
|
{
|
||||||
uint8 buf[256];
|
uint8 buf[256];
|
||||||
uint8 *ptr = buf+1;
|
uint8 *ptr = buf+1;
|
||||||
dbgpipe("Parent sending SHIMEVENT_GETACHIEVEMENT('%s', status %d, time %llu).\n", name, status, (unsigned long long) time);
|
dbgpipe("Parent sending SHIMEVENT_GETACHIEVEMENT('%s', status %d, time " LLUFMT ").\n", name, status, (unsigned long long) time);
|
||||||
*(ptr++) = (uint8) SHIMEVENT_GETACHIEVEMENT;
|
*(ptr++) = (uint8) SHIMEVENT_GETACHIEVEMENT;
|
||||||
*(ptr++) = (uint8) status;
|
*(ptr++) = (uint8) status;
|
||||||
memcpy(ptr, &time, sizeof (time));
|
memcpy(ptr, &time, sizeof (time));
|
||||||
|
|
@ -601,11 +654,11 @@ static void processCommands(PipeType pipeParentRead, PipeType pipeParentWrite)
|
||||||
static bool setEnvironmentVars(PipeType pipeChildRead, PipeType pipeChildWrite)
|
static bool setEnvironmentVars(PipeType pipeChildRead, PipeType pipeChildWrite)
|
||||||
{
|
{
|
||||||
char buf[64];
|
char buf[64];
|
||||||
snprintf(buf, sizeof (buf), "%llu", (unsigned long long) pipeChildRead);
|
snprintf(buf, sizeof (buf), LLUFMT, (unsigned long long) pipeChildRead);
|
||||||
if (!setEnvVar("STEAMSHIM_READHANDLE", buf))
|
if (!setEnvVar("STEAMSHIM_READHANDLE", buf))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
snprintf(buf, sizeof (buf), "%llu", (unsigned long long) pipeChildWrite);
|
snprintf(buf, sizeof (buf), LLUFMT, (unsigned long long) pipeChildWrite);
|
||||||
if (!setEnvVar("STEAMSHIM_WRITEHANDLE", buf))
|
if (!setEnvVar("STEAMSHIM_WRITEHANDLE", buf))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue