mirror of
https://github.com/mkxp-z/mkxp-z.git
synced 2025-08-07 07:25:49 +02:00
correct steamshim_parent.cpp
(It still crashes when built on Windows 8.1)
This commit is contained in:
parent
8b10b72d2a
commit
e2a7313b80
2 changed files with 518 additions and 556 deletions
|
@ -176,6 +176,7 @@ if steamworks == true
|
||||||
include_directories: (steamworks_path + '/public'),
|
include_directories: (steamworks_path + '/public'),
|
||||||
cpp_args: shim_args,
|
cpp_args: shim_args,
|
||||||
link_args: la.split(),
|
link_args: la.split(),
|
||||||
|
gui_app: (get_option('console') == false),
|
||||||
install: (host_system != 'windows'))
|
install: (host_system != 'windows'))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,20 @@
|
||||||
#ifndef GAME_LAUNCH_NAME
|
|
||||||
#define GAME_LAUNCH_NAME "oneshot"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define WIN32_LEAN_AND_MEAN 1
|
#define WIN32_LEAN_AND_MEAN 1
|
||||||
#define UNICODE
|
#define UNICODE
|
||||||
|
#include <cstdio>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
typedef PROCESS_INFORMATION ProcessType;
|
typedef PROCESS_INFORMATION ProcessType;
|
||||||
typedef HANDLE PipeType;
|
typedef HANDLE PipeType;
|
||||||
#define NULLPIPE NULL
|
#define NULLPIPE NULL
|
||||||
#define LLUFMT "%I64u"
|
#define LLUFMT "%I64u"
|
||||||
#else
|
#else
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <signal.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <signal.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
|
||||||
typedef pid_t ProcessType;
|
typedef pid_t ProcessType;
|
||||||
typedef int PipeType;
|
typedef int PipeType;
|
||||||
#define NULLPIPE -1
|
#define NULLPIPE -1
|
||||||
|
@ -30,9 +27,7 @@ typedef int PipeType;
|
||||||
#ifdef STEAMSHIM_DEBUG
|
#ifdef STEAMSHIM_DEBUG
|
||||||
#define dbgpipe printf
|
#define dbgpipe printf
|
||||||
#else
|
#else
|
||||||
static inline void dbgpipe(const char *fmt, ...) {
|
static inline void dbgpipe(const char *fmt, ...) { (void)fmt; }
|
||||||
(void)fmt;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* platform-specific mainline calls this. */
|
/* platform-specific mainline calls this. */
|
||||||
|
@ -50,42 +45,37 @@ static bool launchChild(ProcessType *pid);
|
||||||
static int closeProcess(ProcessType *pid);
|
static int closeProcess(ProcessType *pid);
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
static void fail(const char *err)
|
static void fail(const char *err) {
|
||||||
{
|
|
||||||
MessageBoxA(NULL, err, "ERROR", MB_ICONERROR | MB_OK);
|
MessageBoxA(NULL, err, "ERROR", MB_ICONERROR | MB_OK);
|
||||||
ExitProcess(1);
|
ExitProcess(1);
|
||||||
} // fail
|
} // fail
|
||||||
|
|
||||||
static bool writePipe(PipeType fd, const void *buf, const unsigned int _len)
|
static bool writePipe(PipeType fd, const void *buf, const unsigned int _len) {
|
||||||
{
|
const DWORD len = (DWORD)_len;
|
||||||
const DWORD len = (DWORD) _len;
|
|
||||||
DWORD bw = 0;
|
DWORD bw = 0;
|
||||||
return ((WriteFile(fd, buf, len, &bw, NULL) != 0) && (bw == len));
|
return ((WriteFile(fd, buf, len, &bw, NULL) != 0) && (bw == len));
|
||||||
} // writePipe
|
} // writePipe
|
||||||
|
|
||||||
static int readPipe(PipeType fd, void *buf, const unsigned int _len)
|
static int readPipe(PipeType fd, void *buf, const unsigned int _len) {
|
||||||
{
|
const DWORD len = (DWORD)_len;
|
||||||
const DWORD len = (DWORD) _len;
|
|
||||||
DWORD br = 0;
|
DWORD br = 0;
|
||||||
return ReadFile(fd, buf, len, &br, NULL) ? (int) br : -1;
|
return ReadFile(fd, buf, len, &br, NULL) ? (int)br : -1;
|
||||||
} // readPipe
|
} // readPipe
|
||||||
|
|
||||||
static bool createPipes(PipeType *pPipeParentRead, PipeType *pPipeParentWrite,
|
static bool createPipes(PipeType *pPipeParentRead, PipeType *pPipeParentWrite,
|
||||||
PipeType *pPipeChildRead, PipeType *pPipeChildWrite)
|
PipeType *pPipeChildRead, PipeType *pPipeChildWrite) {
|
||||||
{
|
|
||||||
SECURITY_ATTRIBUTES pipeAttr;
|
SECURITY_ATTRIBUTES pipeAttr;
|
||||||
|
|
||||||
pipeAttr.nLength = sizeof (pipeAttr);
|
pipeAttr.nLength = sizeof(pipeAttr);
|
||||||
pipeAttr.lpSecurityDescriptor = NULL;
|
pipeAttr.lpSecurityDescriptor = NULL;
|
||||||
pipeAttr.bInheritHandle = TRUE;
|
pipeAttr.bInheritHandle = TRUE;
|
||||||
if (!CreatePipe(pPipeParentRead, pPipeChildWrite, &pipeAttr, 0))
|
if (!CreatePipe(pPipeParentRead, pPipeChildWrite, &pipeAttr, 0))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
pipeAttr.nLength = sizeof (pipeAttr);
|
pipeAttr.nLength = sizeof(pipeAttr);
|
||||||
pipeAttr.lpSecurityDescriptor = NULL;
|
pipeAttr.lpSecurityDescriptor = NULL;
|
||||||
pipeAttr.bInheritHandle = TRUE;
|
pipeAttr.bInheritHandle = TRUE;
|
||||||
if (!CreatePipe(pPipeChildRead, pPipeParentWrite, &pipeAttr, 0))
|
if (!CreatePipe(pPipeChildRead, pPipeParentWrite, &pipeAttr, 0)) {
|
||||||
{
|
|
||||||
CloseHandle(*pPipeParentRead);
|
CloseHandle(*pPipeParentRead);
|
||||||
CloseHandle(*pPipeChildWrite);
|
CloseHandle(*pPipeChildWrite);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -94,18 +84,13 @@ static bool createPipes(PipeType *pPipeParentRead, PipeType *pPipeParentWrite,
|
||||||
return 1;
|
return 1;
|
||||||
} // createPipes
|
} // createPipes
|
||||||
|
|
||||||
static void closePipe(PipeType fd)
|
static void closePipe(PipeType fd) { CloseHandle(fd); } // closePipe
|
||||||
{
|
|
||||||
CloseHandle(fd);
|
|
||||||
} // closePipe
|
|
||||||
|
|
||||||
static bool setEnvVar(const char *key, const char *val)
|
static bool setEnvVar(const char *key, const char *val) {
|
||||||
{
|
|
||||||
return (SetEnvironmentVariableA(key, val) != 0);
|
return (SetEnvironmentVariableA(key, val) != 0);
|
||||||
} // setEnvVar
|
} // setEnvVar
|
||||||
|
|
||||||
static LPWSTR genCommandLine()
|
static LPWSTR genCommandLine() {
|
||||||
{
|
|
||||||
// Construct a command line with the appropriate filename
|
// Construct a command line with the appropriate filename
|
||||||
LPWSTR cmdline = GetCommandLineW();
|
LPWSTR cmdline = GetCommandLineW();
|
||||||
|
|
||||||
|
@ -113,21 +98,14 @@ static LPWSTR genCommandLine()
|
||||||
int iFirstArg = -1;
|
int iFirstArg = -1;
|
||||||
bool quote = false;
|
bool quote = false;
|
||||||
bool whitespace = false;
|
bool whitespace = false;
|
||||||
for (int i = 0; cmdline[i]; ++i)
|
for (int i = 0; cmdline[i]; ++i) {
|
||||||
{
|
if (cmdline[i] == '"' && (i == 0 || cmdline[i - 1] != '\\')) {
|
||||||
if (cmdline[i] == '"' && (i == 0 || cmdline[i-1] != '\\'))
|
|
||||||
{
|
|
||||||
quote = !quote;
|
quote = !quote;
|
||||||
whitespace = false;
|
whitespace = false;
|
||||||
}
|
} else if (!quote && (cmdline[i] == ' ' || cmdline[i] == '\t')) {
|
||||||
else if (!quote && (cmdline[i] == ' ' || cmdline[i] == '\t'))
|
|
||||||
{
|
|
||||||
whitespace = true;
|
whitespace = true;
|
||||||
}
|
} else {
|
||||||
else
|
if (whitespace) {
|
||||||
{
|
|
||||||
if (whitespace)
|
|
||||||
{
|
|
||||||
iFirstArg = i;
|
iFirstArg = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -142,65 +120,60 @@ static LPWSTR genCommandLine()
|
||||||
|
|
||||||
// Create the new string
|
// Create the new string
|
||||||
// (`".\.exe" ` == +9
|
// (`".\.exe" ` == +9
|
||||||
LPWSTR newcmdline = (LPWSTR)malloc(sizeof(TEXT(GAME_LAUNCH_NAME))
|
LPWSTR newcmdline =
|
||||||
+ sizeof(WCHAR) * (wcslen(cmdline) - iFirstArg + 9));
|
(LPWSTR)malloc(sizeof(TEXT(GAME_LAUNCH_NAME)) +
|
||||||
wsprintf(newcmdline, TEXT("\".\\" GAME_LAUNCH_NAME ".exe\" %s"), cmdline + iFirstArg);
|
sizeof(WCHAR) * (wcslen(cmdline) - iFirstArg + 9));
|
||||||
|
wsprintf(newcmdline, TEXT("\".\\" GAME_LAUNCH_NAME ".exe\" %s"),
|
||||||
|
cmdline + iFirstArg);
|
||||||
return newcmdline;
|
return newcmdline;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool launchChild(ProcessType *pid)
|
static bool launchChild(ProcessType *pid) {
|
||||||
{
|
|
||||||
STARTUPINFOW si;
|
STARTUPINFOW si;
|
||||||
memset(&si, 0, sizeof(si));
|
memset(&si, 0, sizeof(si));
|
||||||
return CreateProcessW(TEXT(".\\" GAME_LAUNCH_NAME ".exe"),
|
return CreateProcessW(TEXT(".\\" GAME_LAUNCH_NAME ".exe"), genCommandLine(),
|
||||||
genCommandLine(), NULL, NULL, TRUE, 0, NULL,
|
NULL, NULL, TRUE, 0, NULL, NULL, &si, pid);
|
||||||
NULL, &si, pid);
|
|
||||||
} // launchChild
|
} // launchChild
|
||||||
|
|
||||||
static int closeProcess(ProcessType *pid)
|
static int closeProcess(ProcessType *pid) {
|
||||||
{
|
|
||||||
CloseHandle(pid->hProcess);
|
CloseHandle(pid->hProcess);
|
||||||
CloseHandle(pid->hThread);
|
CloseHandle(pid->hThread);
|
||||||
return 0;
|
return 0;
|
||||||
} // closeProcess
|
} // closeProcess
|
||||||
|
|
||||||
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
||||||
LPSTR lpCmdLine, int nCmdShow)
|
LPSTR lpCmdLine, int nCmdShow) {
|
||||||
{
|
|
||||||
mainline();
|
mainline();
|
||||||
ExitProcess(0);
|
ExitProcess(0);
|
||||||
return 0; // just in case.
|
return 0; // just in case.
|
||||||
} // WinMain
|
} // WinMain
|
||||||
|
|
||||||
|
|
||||||
#else // everyone else that isn't Windows.
|
#else // everyone else that isn't Windows.
|
||||||
|
|
||||||
static void fail(const char *err)
|
static void fail(const char *err) {
|
||||||
{
|
|
||||||
// !!! FIXME: zenity or something.
|
// !!! FIXME: zenity or something.
|
||||||
fprintf(stderr, "%s\n", err);
|
fprintf(stderr, "%s\n", err);
|
||||||
_exit(1);
|
_exit(1);
|
||||||
} // fail
|
} // fail
|
||||||
|
|
||||||
static bool writePipe(PipeType fd, const void *buf, const unsigned int _len)
|
static bool writePipe(PipeType fd, const void *buf, const unsigned int _len) {
|
||||||
{
|
const ssize_t len = (ssize_t)_len;
|
||||||
const ssize_t len = (ssize_t) _len;
|
|
||||||
ssize_t bw;
|
ssize_t bw;
|
||||||
while (((bw = write(fd, buf, len)) == -1) && (errno == EINTR)) { /*spin*/ }
|
while (((bw = write(fd, buf, len)) == -1) && (errno == EINTR)) { /*spin*/
|
||||||
|
}
|
||||||
return (bw == len);
|
return (bw == len);
|
||||||
} // writePipe
|
} // writePipe
|
||||||
|
|
||||||
static int readPipe(PipeType fd, void *buf, const unsigned int _len)
|
static int readPipe(PipeType fd, void *buf, const unsigned int _len) {
|
||||||
{
|
const ssize_t len = (ssize_t)_len;
|
||||||
const ssize_t len = (ssize_t) _len;
|
|
||||||
ssize_t br;
|
ssize_t br;
|
||||||
while (((br = read(fd, buf, len)) == -1) && (errno == EINTR)) { /*spin*/ }
|
while (((br = read(fd, buf, len)) == -1) && (errno == EINTR)) { /*spin*/
|
||||||
return (int) br;
|
}
|
||||||
|
return (int)br;
|
||||||
} // readPipe
|
} // readPipe
|
||||||
|
|
||||||
static bool createPipes(PipeType *pPipeParentRead, PipeType *pPipeParentWrite,
|
static bool createPipes(PipeType *pPipeParentRead, PipeType *pPipeParentWrite,
|
||||||
PipeType *pPipeChildRead, PipeType *pPipeChildWrite)
|
PipeType *pPipeChildRead, PipeType *pPipeChildWrite) {
|
||||||
{
|
|
||||||
int fds[2];
|
int fds[2];
|
||||||
if (pipe(fds) == -1)
|
if (pipe(fds) == -1)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -209,8 +182,7 @@ static bool createPipes(PipeType *pPipeParentRead, PipeType *pPipeParentWrite,
|
||||||
*pPipeParentRead = fds[0];
|
*pPipeParentRead = fds[0];
|
||||||
*pPipeChildWrite = fds[1];
|
*pPipeChildWrite = fds[1];
|
||||||
|
|
||||||
if (pipe(fds) == -1)
|
if (pipe(fds) == -1) {
|
||||||
{
|
|
||||||
close(*pPipeParentRead);
|
close(*pPipeParentRead);
|
||||||
close(*pPipeChildWrite);
|
close(*pPipeChildWrite);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -224,21 +196,16 @@ static bool createPipes(PipeType *pPipeParentRead, PipeType *pPipeParentWrite,
|
||||||
return 1;
|
return 1;
|
||||||
} // createPipes
|
} // createPipes
|
||||||
|
|
||||||
static void closePipe(PipeType fd)
|
static void closePipe(PipeType fd) { close(fd); } // closePipe
|
||||||
{
|
|
||||||
close(fd);
|
|
||||||
} // closePipe
|
|
||||||
|
|
||||||
static bool setEnvVar(const char *key, const char *val)
|
static bool setEnvVar(const char *key, const char *val) {
|
||||||
{
|
|
||||||
return (setenv(key, val, 1) != -1);
|
return (setenv(key, val, 1) != -1);
|
||||||
} // setEnvVar
|
} // setEnvVar
|
||||||
|
|
||||||
static int GArgc = 0;
|
static int GArgc = 0;
|
||||||
static char **GArgv = NULL;
|
static char **GArgv = NULL;
|
||||||
|
|
||||||
static bool launchChild(ProcessType *pid)
|
static bool launchChild(ProcessType *pid) {
|
||||||
{
|
|
||||||
*pid = fork();
|
*pid = fork();
|
||||||
if (*pid == -1) // failed
|
if (*pid == -1) // failed
|
||||||
return false;
|
return false;
|
||||||
|
@ -260,17 +227,16 @@ static bool launchChild(ProcessType *pid)
|
||||||
_exit(1);
|
_exit(1);
|
||||||
} // launchChild
|
} // launchChild
|
||||||
|
|
||||||
static int closeProcess(ProcessType *pid)
|
static int closeProcess(ProcessType *pid) {
|
||||||
{
|
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
while ((waitpid(*pid, &rc, 0) == -1) && (errno == EINTR)) { /*spin*/ }
|
while ((waitpid(*pid, &rc, 0) == -1) && (errno == EINTR)) { /*spin*/
|
||||||
|
}
|
||||||
if (!WIFEXITED(rc))
|
if (!WIFEXITED(rc))
|
||||||
return 1; // oh well.
|
return 1; // oh well.
|
||||||
return WEXITSTATUS(rc);
|
return WEXITSTATUS(rc);
|
||||||
} // closeProcess
|
} // closeProcess
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv) {
|
||||||
{
|
|
||||||
signal(SIGPIPE, SIG_IGN);
|
signal(SIGPIPE, SIG_IGN);
|
||||||
GArgc = argc;
|
GArgc = argc;
|
||||||
GArgv = argv;
|
GArgv = argv;
|
||||||
|
@ -279,7 +245,6 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// THE ACTUAL PROGRAM.
|
// THE ACTUAL PROGRAM.
|
||||||
|
|
||||||
class SteamBridge;
|
class SteamBridge;
|
||||||
|
@ -293,19 +258,19 @@ static AppId_t GAppID = 0;
|
||||||
static uint64 GUserID = 0;
|
static uint64 GUserID = 0;
|
||||||
static SteamBridge *GSteamBridge = NULL;
|
static SteamBridge *GSteamBridge = NULL;
|
||||||
|
|
||||||
class SteamBridge
|
class SteamBridge {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
SteamBridge(PipeType _fd);
|
SteamBridge(PipeType _fd);
|
||||||
STEAM_CALLBACK(SteamBridge, OnUserStatsReceived, UserStatsReceived_t, m_CallbackUserStatsReceived);
|
STEAM_CALLBACK(SteamBridge, OnUserStatsReceived, UserStatsReceived_t,
|
||||||
STEAM_CALLBACK(SteamBridge, OnUserStatsStored, UserStatsStored_t, m_CallbackUserStatsStored);
|
m_CallbackUserStatsReceived);
|
||||||
|
STEAM_CALLBACK(SteamBridge, OnUserStatsStored, UserStatsStored_t,
|
||||||
|
m_CallbackUserStatsStored);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PipeType fd;
|
PipeType fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum ShimCmd
|
typedef enum ShimCmd {
|
||||||
{
|
|
||||||
SHIMCMD_BYE,
|
SHIMCMD_BYE,
|
||||||
SHIMCMD_PUMP,
|
SHIMCMD_PUMP,
|
||||||
SHIMCMD_REQUESTSTATS,
|
SHIMCMD_REQUESTSTATS,
|
||||||
|
@ -321,8 +286,7 @@ typedef enum ShimCmd
|
||||||
SHIMCMD_GETCURRENTGAMELANGUAGE,
|
SHIMCMD_GETCURRENTGAMELANGUAGE,
|
||||||
} ShimCmd;
|
} ShimCmd;
|
||||||
|
|
||||||
typedef enum ShimEvent
|
typedef enum ShimEvent {
|
||||||
{
|
|
||||||
SHIMEVENT_BYE,
|
SHIMEVENT_BYE,
|
||||||
SHIMEVENT_STATSRECEIVED,
|
SHIMEVENT_STATSRECEIVED,
|
||||||
SHIMEVENT_STATSSTORED,
|
SHIMEVENT_STATSSTORED,
|
||||||
|
@ -337,158 +301,158 @@ typedef enum ShimEvent
|
||||||
SHIMEVENT_GETCURRENTGAMELANGUAGE,
|
SHIMEVENT_GETCURRENTGAMELANGUAGE,
|
||||||
} ShimEvent;
|
} ShimEvent;
|
||||||
|
|
||||||
static bool write1ByteCmd(PipeType fd, const uint8 b1)
|
static bool write1ByteCmd(PipeType fd, const uint8 b1) {
|
||||||
{
|
const uint8 buf[] = {1, b1};
|
||||||
const uint8 buf[] = { 1, b1 };
|
return writePipe(fd, buf, sizeof(buf));
|
||||||
return writePipe(fd, buf, sizeof (buf));
|
|
||||||
} // write1ByteCmd
|
} // write1ByteCmd
|
||||||
|
|
||||||
static bool write2ByteCmd(PipeType fd, const uint8 b1, const uint8 b2)
|
static bool write2ByteCmd(PipeType fd, const uint8 b1, const uint8 b2) {
|
||||||
{
|
const uint8 buf[] = {2, b1, b2};
|
||||||
const uint8 buf[] = { 2, b1, b2 };
|
return writePipe(fd, buf, sizeof(buf));
|
||||||
return writePipe(fd, buf, sizeof (buf));
|
|
||||||
} // write2ByteCmd
|
} // write2ByteCmd
|
||||||
|
|
||||||
static bool write3ByteCmd(PipeType fd, const uint8 b1, const uint8 b2, const uint8 b3)
|
static bool write3ByteCmd(PipeType fd, const uint8 b1, const uint8 b2,
|
||||||
{
|
const uint8 b3) {
|
||||||
const uint8 buf[] = { 3, b1, b2, b3 };
|
const uint8 buf[] = {3, b1, b2, b3};
|
||||||
return writePipe(fd, buf, sizeof (buf));
|
return writePipe(fd, buf, sizeof(buf));
|
||||||
} // write3ByteCmd
|
} // write3ByteCmd
|
||||||
|
|
||||||
static bool writeString(PipeType fd, ShimEvent event, const char *str)
|
static bool writeString(PipeType fd, ShimEvent event, const char *str) {
|
||||||
{
|
|
||||||
uint8 buf[256];
|
uint8 buf[256];
|
||||||
buf[0] = strlen(str) + 2;
|
buf[0] = strlen(str) + 2;
|
||||||
buf[1] = (uint8) event;
|
buf[1] = (uint8)event;
|
||||||
strcpy((char *) buf + 2, str);
|
strcpy((char *)buf + 2, str);
|
||||||
return writePipe(fd, buf, buf[0] + 1);
|
return writePipe(fd, buf, buf[0] + 1);
|
||||||
} // writeString
|
} // writeString
|
||||||
|
|
||||||
static inline bool writeBye(PipeType fd)
|
static inline bool writeBye(PipeType fd) {
|
||||||
{
|
|
||||||
dbgpipe("Parent sending SHIMEVENT_BYE().\n");
|
dbgpipe("Parent sending SHIMEVENT_BYE().\n");
|
||||||
return write1ByteCmd(fd, SHIMEVENT_BYE);
|
return write1ByteCmd(fd, SHIMEVENT_BYE);
|
||||||
} // writeBye
|
} // writeBye
|
||||||
|
|
||||||
static inline bool writeStatsReceived(PipeType fd, const bool okay)
|
static inline bool writeStatsReceived(PipeType fd, const bool okay) {
|
||||||
{
|
|
||||||
dbgpipe("Parent sending SHIMEVENT_STATSRECEIVED(%sokay).\n", okay ? "" : "!");
|
dbgpipe("Parent sending SHIMEVENT_STATSRECEIVED(%sokay).\n", okay ? "" : "!");
|
||||||
return write2ByteCmd(fd, SHIMEVENT_STATSRECEIVED, okay ? 1 : 0);
|
return write2ByteCmd(fd, SHIMEVENT_STATSRECEIVED, okay ? 1 : 0);
|
||||||
} // writeStatsReceived
|
} // writeStatsReceived
|
||||||
|
|
||||||
static inline bool writeStatsStored(PipeType fd, const bool okay)
|
static inline bool writeStatsStored(PipeType fd, const bool okay) {
|
||||||
{
|
|
||||||
dbgpipe("Parent sending SHIMEVENT_STATSSTORED(%sokay).\n", okay ? "" : "!");
|
dbgpipe("Parent sending SHIMEVENT_STATSSTORED(%sokay).\n", okay ? "" : "!");
|
||||||
return write2ByteCmd(fd, SHIMEVENT_STATSSTORED, okay ? 1 : 0);
|
return write2ByteCmd(fd, SHIMEVENT_STATSSTORED, okay ? 1 : 0);
|
||||||
} // writeStatsStored
|
} // writeStatsStored
|
||||||
|
|
||||||
static bool writeAchievementSet(PipeType fd, const char *name, const bool enable, const bool okay)
|
static bool writeAchievementSet(PipeType fd, const char *name,
|
||||||
{
|
const bool enable, const bool okay) {
|
||||||
uint8 buf[256];
|
uint8 buf[256];
|
||||||
uint8 *ptr = buf+1;
|
uint8 *ptr = buf + 1;
|
||||||
dbgpipe("Parent sending SHIMEVENT_SETACHIEVEMENT('%s', %senable, %sokay).\n", name, enable ? "" : "!", okay ? "" : "!");
|
dbgpipe("Parent sending SHIMEVENT_SETACHIEVEMENT('%s', %senable, %sokay).\n",
|
||||||
*(ptr++) = (uint8) SHIMEVENT_SETACHIEVEMENT;
|
name, enable ? "" : "!", okay ? "" : "!");
|
||||||
|
*(ptr++) = (uint8)SHIMEVENT_SETACHIEVEMENT;
|
||||||
*(ptr++) = enable ? 1 : 0;
|
*(ptr++) = enable ? 1 : 0;
|
||||||
*(ptr++) = okay ? 1 : 0;
|
*(ptr++) = okay ? 1 : 0;
|
||||||
strcpy((char *) ptr, name);
|
strcpy((char *)ptr, name);
|
||||||
ptr += strlen(name) + 1;
|
ptr += strlen(name) + 1;
|
||||||
buf[0] = (uint8) ((ptr-1) - buf);
|
buf[0] = (uint8)((ptr - 1) - buf);
|
||||||
return writePipe(fd, buf, buf[0] + 1);
|
return writePipe(fd, buf, buf[0] + 1);
|
||||||
} // writeAchievementSet
|
} // writeAchievementSet
|
||||||
|
|
||||||
static bool writeAchievementGet(PipeType fd, const char *name, const int status, const uint64 time)
|
static bool writeAchievementGet(PipeType fd, const char *name, const int status,
|
||||||
{
|
const uint64 time) {
|
||||||
uint8 buf[256];
|
uint8 buf[256];
|
||||||
uint8 *ptr = buf+1;
|
uint8 *ptr = buf + 1;
|
||||||
dbgpipe("Parent sending SHIMEVENT_GETACHIEVEMENT('%s', status %d, time " LLUFMT ").\n", name, status, (unsigned long long) time);
|
dbgpipe(
|
||||||
*(ptr++) = (uint8) SHIMEVENT_GETACHIEVEMENT;
|
"Parent sending SHIMEVENT_GETACHIEVEMENT('%s', status %d, time " LLUFMT
|
||||||
*(ptr++) = (uint8) status;
|
").\n",
|
||||||
memcpy(ptr, &time, sizeof (time));
|
name, status, (unsigned long long)time);
|
||||||
ptr += sizeof (time);
|
*(ptr++) = (uint8)SHIMEVENT_GETACHIEVEMENT;
|
||||||
strcpy((char *) ptr, name);
|
*(ptr++) = (uint8)status;
|
||||||
|
memcpy(ptr, &time, sizeof(time));
|
||||||
|
ptr += sizeof(time);
|
||||||
|
strcpy((char *)ptr, name);
|
||||||
ptr += strlen(name) + 1;
|
ptr += strlen(name) + 1;
|
||||||
buf[0] = (uint8) ((ptr-1) - buf);
|
buf[0] = (uint8)((ptr - 1) - buf);
|
||||||
return writePipe(fd, buf, buf[0] + 1);
|
return writePipe(fd, buf, buf[0] + 1);
|
||||||
} // writeAchievementGet
|
} // writeAchievementGet
|
||||||
|
|
||||||
static inline bool writeResetStats(PipeType fd, const bool alsoAch, const bool okay)
|
static inline bool writeResetStats(PipeType fd, const bool alsoAch,
|
||||||
{
|
const bool okay) {
|
||||||
dbgpipe("Parent sending SHIMEVENT_RESETSTATS(%salsoAchievements, %sokay).\n", alsoAch ? "" : "!", okay ? "" : "!");
|
dbgpipe("Parent sending SHIMEVENT_RESETSTATS(%salsoAchievements, %sokay).\n",
|
||||||
|
alsoAch ? "" : "!", okay ? "" : "!");
|
||||||
return write3ByteCmd(fd, SHIMEVENT_RESETSTATS, alsoAch ? 1 : 0, okay ? 1 : 0);
|
return write3ByteCmd(fd, SHIMEVENT_RESETSTATS, alsoAch ? 1 : 0, okay ? 1 : 0);
|
||||||
} // writeResetStats
|
} // writeResetStats
|
||||||
|
|
||||||
static bool writeStatThing(PipeType fd, const ShimEvent ev, const char *name, const void *val, const size_t vallen, const bool okay)
|
static bool writeStatThing(PipeType fd, const ShimEvent ev, const char *name,
|
||||||
{
|
const void *val, const size_t vallen,
|
||||||
|
const bool okay) {
|
||||||
uint8 buf[256];
|
uint8 buf[256];
|
||||||
uint8 *ptr = buf+1;
|
uint8 *ptr = buf + 1;
|
||||||
*(ptr++) = (uint8) ev;
|
*(ptr++) = (uint8)ev;
|
||||||
*(ptr++) = okay ? 1 : 0;
|
*(ptr++) = okay ? 1 : 0;
|
||||||
memcpy(ptr, val, vallen);
|
memcpy(ptr, val, vallen);
|
||||||
ptr += vallen;
|
ptr += vallen;
|
||||||
strcpy((char *) ptr, name);
|
strcpy((char *)ptr, name);
|
||||||
ptr += strlen(name) + 1;
|
ptr += strlen(name) + 1;
|
||||||
buf[0] = (uint8) ((ptr-1) - buf);
|
buf[0] = (uint8)((ptr - 1) - buf);
|
||||||
return writePipe(fd, buf, buf[0] + 1);
|
return writePipe(fd, buf, buf[0] + 1);
|
||||||
} // writeStatThing
|
} // writeStatThing
|
||||||
|
|
||||||
static inline bool writeSetStatI(PipeType fd, const char *name, const int32 val, const bool okay)
|
static inline bool writeSetStatI(PipeType fd, const char *name, const int32 val,
|
||||||
{
|
const bool okay) {
|
||||||
dbgpipe("Parent sending SHIMEVENT_SETSTATI('%s', val %d, %sokay).\n", name, (int) val, okay ? "" : "!");
|
dbgpipe("Parent sending SHIMEVENT_SETSTATI('%s', val %d, %sokay).\n", name,
|
||||||
return writeStatThing(fd, SHIMEVENT_SETSTATI, name, &val, sizeof (val), okay);
|
(int)val, okay ? "" : "!");
|
||||||
|
return writeStatThing(fd, SHIMEVENT_SETSTATI, name, &val, sizeof(val), okay);
|
||||||
} // writeSetStatI
|
} // writeSetStatI
|
||||||
|
|
||||||
static inline bool writeSetStatF(PipeType fd, const char *name, const float val, const bool okay)
|
static inline bool writeSetStatF(PipeType fd, const char *name, const float val,
|
||||||
{
|
const bool okay) {
|
||||||
dbgpipe("Parent sending SHIMEVENT_SETSTATF('%s', val %f, %sokay).\n", name, val, okay ? "" : "!");
|
dbgpipe("Parent sending SHIMEVENT_SETSTATF('%s', val %f, %sokay).\n", name,
|
||||||
return writeStatThing(fd, SHIMEVENT_SETSTATF, name, &val, sizeof (val), okay);
|
val, okay ? "" : "!");
|
||||||
|
return writeStatThing(fd, SHIMEVENT_SETSTATF, name, &val, sizeof(val), okay);
|
||||||
} // writeSetStatF
|
} // writeSetStatF
|
||||||
|
|
||||||
static inline bool writeGetStatI(PipeType fd, const char *name, const int32 val, const bool okay)
|
static inline bool writeGetStatI(PipeType fd, const char *name, const int32 val,
|
||||||
{
|
const bool okay) {
|
||||||
dbgpipe("Parent sending SHIMEVENT_GETSTATI('%s', val %d, %sokay).\n", name, (int) val, okay ? "" : "!");
|
dbgpipe("Parent sending SHIMEVENT_GETSTATI('%s', val %d, %sokay).\n", name,
|
||||||
return writeStatThing(fd, SHIMEVENT_GETSTATI, name, &val, sizeof (val), okay);
|
(int)val, okay ? "" : "!");
|
||||||
|
return writeStatThing(fd, SHIMEVENT_GETSTATI, name, &val, sizeof(val), okay);
|
||||||
} // writeGetStatI
|
} // writeGetStatI
|
||||||
|
|
||||||
static inline bool writeGetStatF(PipeType fd, const char *name, const float val, const bool okay)
|
static inline bool writeGetStatF(PipeType fd, const char *name, const float val,
|
||||||
{
|
const bool okay) {
|
||||||
dbgpipe("Parent sending SHIMEVENT_GETSTATF('%s', val %f, %sokay).\n", name, val, okay ? "" : "!");
|
dbgpipe("Parent sending SHIMEVENT_GETSTATF('%s', val %f, %sokay).\n", name,
|
||||||
return writeStatThing(fd, SHIMEVENT_GETSTATF, name, &val, sizeof (val), okay);
|
val, okay ? "" : "!");
|
||||||
|
return writeStatThing(fd, SHIMEVENT_GETSTATF, name, &val, sizeof(val), okay);
|
||||||
} // writeGetStatF
|
} // writeGetStatF
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SteamBridge::SteamBridge(PipeType _fd)
|
SteamBridge::SteamBridge(PipeType _fd)
|
||||||
: m_CallbackUserStatsReceived( this, &SteamBridge::OnUserStatsReceived )
|
: m_CallbackUserStatsReceived(this, &SteamBridge::OnUserStatsReceived),
|
||||||
, m_CallbackUserStatsStored( this, &SteamBridge::OnUserStatsStored )
|
m_CallbackUserStatsStored(this, &SteamBridge::OnUserStatsStored),
|
||||||
, fd(_fd)
|
fd(_fd) {} // SteamBridge::SteamBridge
|
||||||
{
|
|
||||||
} // SteamBridge::SteamBridge
|
|
||||||
|
|
||||||
void SteamBridge::OnUserStatsReceived(UserStatsReceived_t *pCallback)
|
void SteamBridge::OnUserStatsReceived(UserStatsReceived_t *pCallback) {
|
||||||
{
|
if (GAppID != pCallback->m_nGameID)
|
||||||
if (GAppID != pCallback->m_nGameID) return;
|
return;
|
||||||
if (GUserID != pCallback->m_steamIDUser.ConvertToUint64()) return;
|
if (GUserID != pCallback->m_steamIDUser.ConvertToUint64())
|
||||||
|
return;
|
||||||
writeStatsReceived(fd, pCallback->m_eResult == k_EResultOK);
|
writeStatsReceived(fd, pCallback->m_eResult == k_EResultOK);
|
||||||
} // SteamBridge::OnUserStatsReceived
|
} // SteamBridge::OnUserStatsReceived
|
||||||
|
|
||||||
void SteamBridge::OnUserStatsStored(UserStatsStored_t *pCallback)
|
void SteamBridge::OnUserStatsStored(UserStatsStored_t *pCallback) {
|
||||||
{
|
if (GAppID != pCallback->m_nGameID)
|
||||||
if (GAppID != pCallback->m_nGameID) return;
|
return;
|
||||||
writeStatsStored(fd, pCallback->m_eResult == k_EResultOK);
|
writeStatsStored(fd, pCallback->m_eResult == k_EResultOK);
|
||||||
} // SteamBridge::OnUserStatsStored
|
} // SteamBridge::OnUserStatsStored
|
||||||
|
|
||||||
|
static bool processCommand(const uint8 *buf, unsigned int buflen, PipeType fd) {
|
||||||
static bool processCommand(const uint8 *buf, unsigned int buflen, PipeType fd)
|
|
||||||
{
|
|
||||||
if (buflen == 0)
|
if (buflen == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
const ShimCmd cmd = (ShimCmd) *(buf++);
|
const ShimCmd cmd = (ShimCmd) * (buf++);
|
||||||
buflen--;
|
buflen--;
|
||||||
|
|
||||||
#if STEAMSHIM_DEBUG
|
#if STEAMSHIM_DEBUG
|
||||||
if (false) {}
|
if (false) {
|
||||||
#define PRINTGOTCMD(x) else if (cmd == x) printf("Parent got " #x ".\n")
|
}
|
||||||
|
#define PRINTGOTCMD(x) else if (cmd == x) printf("Parent got " #x ".\n")
|
||||||
PRINTGOTCMD(SHIMCMD_BYE);
|
PRINTGOTCMD(SHIMCMD_BYE);
|
||||||
PRINTGOTCMD(SHIMCMD_PUMP);
|
PRINTGOTCMD(SHIMCMD_PUMP);
|
||||||
PRINTGOTCMD(SHIMCMD_REQUESTSTATS);
|
PRINTGOTCMD(SHIMCMD_REQUESTSTATS);
|
||||||
|
@ -502,12 +466,11 @@ static bool processCommand(const uint8 *buf, unsigned int buflen, PipeType fd)
|
||||||
PRINTGOTCMD(SHIMCMD_GETSTATF);
|
PRINTGOTCMD(SHIMCMD_GETSTATF);
|
||||||
PRINTGOTCMD(SHIMCMD_GETPERSONANAME);
|
PRINTGOTCMD(SHIMCMD_GETPERSONANAME);
|
||||||
PRINTGOTCMD(SHIMCMD_GETCURRENTGAMELANGUAGE);
|
PRINTGOTCMD(SHIMCMD_GETCURRENTGAMELANGUAGE);
|
||||||
#undef PRINTGOTCMD
|
#undef PRINTGOTCMD
|
||||||
else printf("Parent got unknown shimcmd %d.\n", (int) cmd);
|
else printf("Parent got unknown shimcmd %d.\n", (int)cmd);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch (cmd)
|
switch (cmd) {
|
||||||
{
|
|
||||||
case SHIMCMD_PUMP:
|
case SHIMCMD_PUMP:
|
||||||
SteamAPI_RunCallbacks();
|
SteamAPI_RunCallbacks();
|
||||||
break;
|
break;
|
||||||
|
@ -529,10 +492,10 @@ static bool processCommand(const uint8 *buf, unsigned int buflen, PipeType fd)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SHIMCMD_SETACHIEVEMENT:
|
case SHIMCMD_SETACHIEVEMENT:
|
||||||
if (buflen >= 2)
|
if (buflen >= 2) {
|
||||||
{
|
|
||||||
const bool enable = (*(buf++) != 0);
|
const bool enable = (*(buf++) != 0);
|
||||||
const char *name = (const char *) buf; // !!! FIXME: buffer overflow possible.
|
const char *name =
|
||||||
|
(const char *)buf; // !!! FIXME: buffer overflow possible.
|
||||||
if (!GSteamStats)
|
if (!GSteamStats)
|
||||||
writeAchievementSet(fd, name, enable, false);
|
writeAchievementSet(fd, name, enable, false);
|
||||||
else if (enable && !GSteamStats->SetAchievement(name))
|
else if (enable && !GSteamStats->SetAchievement(name))
|
||||||
|
@ -545,12 +508,13 @@ static bool processCommand(const uint8 *buf, unsigned int buflen, PipeType fd)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SHIMCMD_GETACHIEVEMENT:
|
case SHIMCMD_GETACHIEVEMENT:
|
||||||
if (buflen)
|
if (buflen) {
|
||||||
{
|
const char *name =
|
||||||
const char *name = (const char *) buf; // !!! FIXME: buffer overflow possible.
|
(const char *)buf; // !!! FIXME: buffer overflow possible.
|
||||||
bool ach = false;
|
bool ach = false;
|
||||||
uint32 t = 0;
|
uint32 t = 0;
|
||||||
if ((GSteamStats) && (GSteamStats->GetAchievementAndUnlockTime(name, &ach, &t)))
|
if ((GSteamStats) &&
|
||||||
|
(GSteamStats->GetAchievementAndUnlockTime(name, &ach, &t)))
|
||||||
writeAchievementGet(fd, name, ach ? 1 : 0, t);
|
writeAchievementGet(fd, name, ach ? 1 : 0, t);
|
||||||
else
|
else
|
||||||
writeAchievementGet(fd, name, 2, 0);
|
writeAchievementGet(fd, name, 2, 0);
|
||||||
|
@ -558,27 +522,28 @@ static bool processCommand(const uint8 *buf, unsigned int buflen, PipeType fd)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SHIMCMD_RESETSTATS:
|
case SHIMCMD_RESETSTATS:
|
||||||
if (buflen)
|
if (buflen) {
|
||||||
{
|
|
||||||
const bool alsoAch = (*(buf++) != 0);
|
const bool alsoAch = (*(buf++) != 0);
|
||||||
writeResetStats(fd, alsoAch, (GSteamStats) && (GSteamStats->ResetAllStats(alsoAch)));
|
writeResetStats(fd, alsoAch,
|
||||||
|
(GSteamStats) && (GSteamStats->ResetAllStats(alsoAch)));
|
||||||
} // if
|
} // if
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SHIMCMD_SETSTATI:
|
case SHIMCMD_SETSTATI:
|
||||||
if (buflen >= 5)
|
if (buflen >= 5) {
|
||||||
{
|
const int32 val = *((int32 *)buf);
|
||||||
const int32 val = *((int32 *) buf);
|
buf += sizeof(int32);
|
||||||
buf += sizeof (int32);
|
const char *name =
|
||||||
const char *name = (const char *) buf; // !!! FIXME: buffer overflow possible.
|
(const char *)buf; // !!! FIXME: buffer overflow possible.
|
||||||
writeSetStatI(fd, name, val, (GSteamStats) && (GSteamStats->SetStat(name, val)));
|
writeSetStatI(fd, name, val,
|
||||||
|
(GSteamStats) && (GSteamStats->SetStat(name, val)));
|
||||||
} // if
|
} // if
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SHIMCMD_GETSTATI:
|
case SHIMCMD_GETSTATI:
|
||||||
if (buflen)
|
if (buflen) {
|
||||||
{
|
const char *name =
|
||||||
const char *name = (const char *) buf; // !!! FIXME: buffer overflow possible.
|
(const char *)buf; // !!! FIXME: buffer overflow possible.
|
||||||
int32 val = 0;
|
int32 val = 0;
|
||||||
if ((GSteamStats) && (GSteamStats->GetStat(name, &val)))
|
if ((GSteamStats) && (GSteamStats->GetStat(name, &val)))
|
||||||
writeGetStatI(fd, name, val, true);
|
writeGetStatI(fd, name, val, true);
|
||||||
|
@ -588,19 +553,20 @@ static bool processCommand(const uint8 *buf, unsigned int buflen, PipeType fd)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SHIMCMD_SETSTATF:
|
case SHIMCMD_SETSTATF:
|
||||||
if (buflen >= 5)
|
if (buflen >= 5) {
|
||||||
{
|
const float val = *((float *)buf);
|
||||||
const float val = *((float *) buf);
|
buf += sizeof(float);
|
||||||
buf += sizeof (float);
|
const char *name =
|
||||||
const char *name = (const char *) buf; // !!! FIXME: buffer overflow possible.
|
(const char *)buf; // !!! FIXME: buffer overflow possible.
|
||||||
writeSetStatF(fd, name, val, (GSteamStats) && (GSteamStats->SetStat(name, val)));
|
writeSetStatF(fd, name, val,
|
||||||
|
(GSteamStats) && (GSteamStats->SetStat(name, val)));
|
||||||
} // if
|
} // if
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SHIMCMD_GETSTATF:
|
case SHIMCMD_GETSTATF:
|
||||||
if (buflen)
|
if (buflen) {
|
||||||
{
|
const char *name =
|
||||||
const char *name = (const char *) buf; // !!! FIXME: buffer overflow possible.
|
(const char *)buf; // !!! FIXME: buffer overflow possible.
|
||||||
float val = 0;
|
float val = 0;
|
||||||
if ((GSteamStats) && (GSteamStats->GetStat(name, &val)))
|
if ((GSteamStats) && (GSteamStats->GetStat(name, &val)))
|
||||||
writeGetStatF(fd, name, val, true);
|
writeGetStatF(fd, name, val, true);
|
||||||
|
@ -616,42 +582,37 @@ static bool processCommand(const uint8 *buf, unsigned int buflen, PipeType fd)
|
||||||
|
|
||||||
case SHIMCMD_GETCURRENTGAMELANGUAGE:
|
case SHIMCMD_GETCURRENTGAMELANGUAGE:
|
||||||
dbgpipe("Parent sending SHIMEVENT_GETCURRENTGAMELANGUAGE.\n");
|
dbgpipe("Parent sending SHIMEVENT_GETCURRENTGAMELANGUAGE.\n");
|
||||||
writeString(fd, SHIMEVENT_GETCURRENTGAMELANGUAGE, GSteamApps->GetCurrentGameLanguage());
|
writeString(fd, SHIMEVENT_GETCURRENTGAMELANGUAGE,
|
||||||
|
GSteamApps->GetCurrentGameLanguage());
|
||||||
break;
|
break;
|
||||||
} // switch
|
} // switch
|
||||||
|
|
||||||
return true; // keep going.
|
return true; // keep going.
|
||||||
} // processCommand
|
} // processCommand
|
||||||
|
|
||||||
static void processCommands(PipeType pipeParentRead, PipeType pipeParentWrite)
|
static void processCommands(PipeType pipeParentRead, PipeType pipeParentWrite) {
|
||||||
{
|
|
||||||
bool quit = false;
|
bool quit = false;
|
||||||
uint8 buf[256];
|
uint8 buf[256];
|
||||||
int br;
|
int br;
|
||||||
|
|
||||||
// this read blocks.
|
// this read blocks.
|
||||||
while (!quit && ((br = readPipe(pipeParentRead, buf, sizeof (buf))) > 0))
|
while (!quit && ((br = readPipe(pipeParentRead, buf, sizeof(buf))) > 0)) {
|
||||||
{
|
while (br > 0) {
|
||||||
while (br > 0)
|
const int cmdlen = (int)buf[0];
|
||||||
{
|
if ((br - 1) >= cmdlen) {
|
||||||
const int cmdlen = (int) buf[0];
|
if (!processCommand(buf + 1, cmdlen, pipeParentWrite)) {
|
||||||
if ((br-1) >= cmdlen)
|
|
||||||
{
|
|
||||||
if (!processCommand(buf+1, cmdlen, pipeParentWrite))
|
|
||||||
{
|
|
||||||
quit = true;
|
quit = true;
|
||||||
break;
|
break;
|
||||||
} // if
|
} // if
|
||||||
|
|
||||||
br -= cmdlen + 1;
|
br -= cmdlen + 1;
|
||||||
if (br > 0)
|
if (br > 0)
|
||||||
memmove(buf, buf+cmdlen+1, br);
|
memmove(buf, buf + cmdlen + 1, br);
|
||||||
} // if
|
} // if
|
||||||
else // get more data.
|
else // get more data.
|
||||||
{
|
{
|
||||||
const int morebr = readPipe(pipeParentRead, buf+br, sizeof (buf) - br);
|
const int morebr = readPipe(pipeParentRead, buf + br, sizeof(buf) - br);
|
||||||
if (morebr <= 0)
|
if (morebr <= 0) {
|
||||||
{
|
|
||||||
quit = true; // uhoh.
|
quit = true; // uhoh.
|
||||||
break;
|
break;
|
||||||
} // if
|
} // if
|
||||||
|
@ -661,31 +622,26 @@ static void processCommands(PipeType pipeParentRead, PipeType pipeParentWrite)
|
||||||
} // while
|
} // while
|
||||||
} // processCommands
|
} // processCommands
|
||||||
|
|
||||||
static bool setEnvironmentVars(PipeType pipeChildRead, PipeType pipeChildWrite)
|
static bool setEnvironmentVars(PipeType pipeChildRead,
|
||||||
{
|
PipeType pipeChildWrite) {
|
||||||
char buf[64];
|
char buf[64];
|
||||||
snprintf(buf, sizeof (buf), LLUFMT, (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), LLUFMT, (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;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} // setEnvironmentVars
|
} // setEnvironmentVars
|
||||||
|
|
||||||
static bool initSteamworks(PipeType fd)
|
static int initSteamworks(PipeType fd) {
|
||||||
{
|
|
||||||
#ifndef STEAM_APPID
|
|
||||||
// this can fail for many reasons:
|
// this can fail for many reasons:
|
||||||
// - you forgot a steam_appid.txt in the current working directory.
|
// - you forgot a steam_appid.txt in the current working directory.
|
||||||
// - you don't have Steam running
|
// - you don't have Steam running
|
||||||
// - you don't own the game listed in steam_appid.txt
|
// - you don't own the game listed in steam_appid.txt
|
||||||
if (!SteamAPI_Init())
|
if (!SteamAPI_Init())
|
||||||
#else
|
|
||||||
if (SteamAPI_RestartAppIfNecessary(STEAM_APPID))
|
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
GSteamStats = SteamUserStats();
|
GSteamStats = SteamUserStats();
|
||||||
|
@ -701,18 +657,22 @@ static bool initSteamworks(PipeType fd)
|
||||||
return 1;
|
return 1;
|
||||||
} // initSteamworks
|
} // initSteamworks
|
||||||
|
|
||||||
static void deinitSteamworks(void)
|
static void deinitSteamworks(void) {
|
||||||
{
|
|
||||||
SteamAPI_Shutdown();
|
SteamAPI_Shutdown();
|
||||||
delete GSteamBridge;
|
delete GSteamBridge;
|
||||||
GSteamBridge = NULL;
|
GSteamBridge = NULL;
|
||||||
GSteamStats = NULL;
|
GSteamStats = NULL;
|
||||||
GSteamUtils= NULL;
|
GSteamUtils = NULL;
|
||||||
GSteamUser = NULL;
|
GSteamUser = NULL;
|
||||||
} // deinitSteamworks
|
} // deinitSteamworks
|
||||||
|
|
||||||
static int mainline(void)
|
static int mainline(void) {
|
||||||
{
|
|
||||||
|
#ifdef STEAM_APPID
|
||||||
|
if (SteamAPI_RestartAppIfNecessary(STEAM_APPID))
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
PipeType pipeParentRead = NULLPIPE;
|
PipeType pipeParentRead = NULLPIPE;
|
||||||
PipeType pipeParentWrite = NULLPIPE;
|
PipeType pipeParentWrite = NULLPIPE;
|
||||||
PipeType pipeChildRead = NULLPIPE;
|
PipeType pipeChildRead = NULLPIPE;
|
||||||
|
@ -721,7 +681,8 @@ static int mainline(void)
|
||||||
|
|
||||||
dbgpipe("Parent starting mainline.\n");
|
dbgpipe("Parent starting mainline.\n");
|
||||||
|
|
||||||
if (!createPipes(&pipeParentRead, &pipeParentWrite, &pipeChildRead, &pipeChildWrite))
|
if (!createPipes(&pipeParentRead, &pipeParentWrite, &pipeChildRead,
|
||||||
|
&pipeChildWrite))
|
||||||
fail("Failed to create application pipes");
|
fail("Failed to create application pipes");
|
||||||
else if (!initSteamworks(pipeParentWrite))
|
else if (!initSteamworks(pipeParentWrite))
|
||||||
fail("Failed to initialize Steamworks");
|
fail("Failed to initialize Steamworks");
|
||||||
|
|
Loading…
Add table
Reference in a new issue