------------------------------------------------------------------------
r4207 | acceptthis | 2013-02-16 23:16:07 +0000 (Sat, 16 Feb 2013) | 2 lines update np plugin to do autoupdates properly. Stop people from being able to save the game while dead (in single player, at least). ------------------------------------------------------------------------ git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4205 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
165a9006c7
commit
3717f655a3
4 changed files with 316 additions and 18 deletions
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
static void UnpackAndExtractPakFiles_Complete(struct dl_download *dl);
|
static void UnpackAndExtractPakFiles_Complete(struct dl_download *dl);
|
||||||
static void pscript_property_splash_sets(struct context *ctx, const char *val);
|
static void pscript_property_splash_sets(struct context *ctx, const char *val);
|
||||||
|
void *globalmutex;
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
# ifdef _WIN64
|
# ifdef _WIN64
|
||||||
|
@ -254,11 +254,19 @@ dblbreak:
|
||||||
|
|
||||||
if (addrfamily)
|
if (addrfamily)
|
||||||
*addrfamily = ((struct sockaddr*)sadr)->sa_family;
|
*addrfamily = ((struct sockaddr*)sadr)->sa_family;
|
||||||
if (addrsize)
|
|
||||||
|
if (((struct sockaddr*)sadr)->sa_family == AF_INET)
|
||||||
{
|
{
|
||||||
if (((struct sockaddr*)sadr)->sa_family == AF_INET)
|
if (!((struct sockaddr_in *)sadr)->sin_port)
|
||||||
|
((struct sockaddr_in *)sadr)->sin_port = htons(defaultport);
|
||||||
|
if (addrsize)
|
||||||
*addrsize = sizeof(struct sockaddr_in);
|
*addrsize = sizeof(struct sockaddr_in);
|
||||||
else
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!((struct sockaddr_in6 *)sadr)->sin6_port)
|
||||||
|
((struct sockaddr_in6 *)sadr)->sin6_port = htons(defaultport);
|
||||||
|
if (addrsize)
|
||||||
*addrsize = sizeof(struct sockaddr_in6);
|
*addrsize = sizeof(struct sockaddr_in6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -443,6 +451,187 @@ vfsfile_t *VFSPIPE_Open(void)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(OFFICIAL_RELEASE)
|
||||||
|
#define BUILDTYPE "rel"
|
||||||
|
#else
|
||||||
|
#define BUILDTYPE "test"
|
||||||
|
#define UPDATE_URL "http://triptohell.info/moodles/"
|
||||||
|
#define UPDATE_URL_VERSION UPDATE_URL "version.txt"
|
||||||
|
#ifdef _WIN64
|
||||||
|
#define UPDATE_URL_BUILD UPDATE_URL "win64/fte" EXETYPE ".exe"
|
||||||
|
#else
|
||||||
|
#define UPDATE_URL_BUILD UPDATE_URL "win32/fte" EXETYPE ".exe"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//#if defined(GLQUAKE) && defined(D3DQUAKE)
|
||||||
|
// #define EXETYPE "qw"
|
||||||
|
//#elif defined(GLQUAKE)
|
||||||
|
// #ifdef MINIMAL
|
||||||
|
// #define EXETYPE "minglqw"
|
||||||
|
// #else
|
||||||
|
#define EXETYPE "glqw"
|
||||||
|
// #endif
|
||||||
|
//#elif defined(D3DQUAKE)
|
||||||
|
// #define EXETYPE "d3dqw"
|
||||||
|
//#elif defined(SWQUAKE)
|
||||||
|
// #define EXETYPE "swqw"
|
||||||
|
//#else //erm...
|
||||||
|
// #define EXETYPE "qw"
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
|
||||||
|
qboolean MyRegGetStringValue(HKEY base, char *keyname, char *valuename, void *data, int datalen)
|
||||||
|
{
|
||||||
|
qboolean result = false;
|
||||||
|
DWORD resultlen = datalen - 1;
|
||||||
|
HKEY subkey;
|
||||||
|
DWORD type = REG_NONE;
|
||||||
|
if (RegOpenKeyEx(base, keyname, 0, KEY_READ, &subkey) == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
result = ERROR_SUCCESS == RegQueryValueEx(subkey, valuename, NULL, &type, data, &datalen);
|
||||||
|
RegCloseKey (subkey);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == REG_SZ || type == REG_EXPAND_SZ)
|
||||||
|
((char*)data)[datalen] = 0;
|
||||||
|
else
|
||||||
|
((char*)data)[0] = 0;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyRegSetValue(HKEY base, char *keyname, char *valuename, int type, void *data, int datalen)
|
||||||
|
{
|
||||||
|
HKEY subkey;
|
||||||
|
if (RegCreateKeyEx(base, keyname, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &subkey, NULL) == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
RegSetValueEx(subkey, valuename, 0, type, data, datalen);
|
||||||
|
RegCloseKey (subkey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void MyRegDeleteKeyValue(HKEY base, char *keyname, char *valuename)
|
||||||
|
{
|
||||||
|
HKEY subkey;
|
||||||
|
if (RegOpenKeyEx(base, keyname, 0, KEY_WRITE, &subkey) == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
RegDeleteValue(subkey, valuename);
|
||||||
|
RegCloseKey (subkey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qboolean Update_GetHomeDirectory(char *homedir, int homedirsize)
|
||||||
|
{
|
||||||
|
HMODULE shfolder = LoadLibrary("shfolder.dll");
|
||||||
|
|
||||||
|
if (shfolder)
|
||||||
|
{
|
||||||
|
HRESULT (WINAPI *dSHGetFolderPath) (HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPTSTR pszPath);
|
||||||
|
dSHGetFolderPath = (void *)GetProcAddress(shfolder, "SHGetFolderPathA");
|
||||||
|
if (dSHGetFolderPath)
|
||||||
|
{
|
||||||
|
char folder[MAX_PATH];
|
||||||
|
// 0x5 == CSIDL_PERSONAL
|
||||||
|
if (dSHGetFolderPath(NULL, 0x5, NULL, 0, folder) == S_OK)
|
||||||
|
{
|
||||||
|
Q_snprintfz(homedir, homedirsize, "%s/My Games/%s/", folder, FULLENGINENAME);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// FreeLibrary(shfolder);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "fs.h"
|
||||||
|
struct dl_download *enginedownloadactive;
|
||||||
|
void Update_Version_Updated(struct dl_download *dl)
|
||||||
|
{
|
||||||
|
//happens in a thread, avoid va
|
||||||
|
if (dl->file)
|
||||||
|
{
|
||||||
|
if (dl->status == DL_FINISHED)
|
||||||
|
{
|
||||||
|
char buf[8192];
|
||||||
|
unsigned int size = 0, chunk, fullsize;
|
||||||
|
char pendingname[MAX_OSPATH];
|
||||||
|
FILE *pending;
|
||||||
|
Update_GetHomeDirectory(pendingname, sizeof(pendingname));
|
||||||
|
Q_strncatz(pendingname, DISTRIBUTION BUILDTYPE EXETYPE".tmp", sizeof(pendingname));
|
||||||
|
fullsize = VFS_GETLEN(dl->file);
|
||||||
|
pending = fopen(pendingname, "wb");
|
||||||
|
if (pending)
|
||||||
|
{
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
chunk = VFS_READ(dl->file, buf, sizeof(buf));
|
||||||
|
if (!chunk)
|
||||||
|
break;
|
||||||
|
size += fwrite(buf, 1, chunk, pending);
|
||||||
|
}
|
||||||
|
fclose(pending);
|
||||||
|
if (fullsize == size)
|
||||||
|
{
|
||||||
|
MyRegSetValue(HKEY_CURRENT_USER, "Software\\"FULLENGINENAME, "pending" BUILDTYPE EXETYPE, REG_SZ, pendingname, strlen(pendingname)+1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dl->status = DL_FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
VFS_CLOSE(dl->file);
|
||||||
|
dl->file = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
qboolean Plug_GetDownloadedName(char *updatedpath, int updatedpathlen)
|
||||||
|
{
|
||||||
|
char pendingpath[MAX_OSPATH];
|
||||||
|
char temppath[MAX_OSPATH];
|
||||||
|
|
||||||
|
Sys_LockMutex(globalmutex);
|
||||||
|
|
||||||
|
if (!enginedownloadactive || (enginedownloadactive->status == DL_FINISHED || enginedownloadactive->status == DL_FAILED))
|
||||||
|
{
|
||||||
|
if (enginedownloadactive)
|
||||||
|
DL_Close(enginedownloadactive);
|
||||||
|
enginedownloadactive = NULL;
|
||||||
|
|
||||||
|
/*if there's some downloaded binary which isn't running yet, kill the old active one and update it*/
|
||||||
|
MyRegGetStringValue(HKEY_CURRENT_USER, "Software\\"FULLENGINENAME, "pending" BUILDTYPE EXETYPE, pendingpath, sizeof(pendingpath));
|
||||||
|
if (*pendingpath)
|
||||||
|
{
|
||||||
|
MyRegDeleteKeyValue(HKEY_CURRENT_USER, "Software\\"FULLENGINENAME, "pending" BUILDTYPE EXETYPE);
|
||||||
|
Update_GetHomeDirectory(temppath, sizeof(temppath));
|
||||||
|
CreateDirectory(temppath, NULL);
|
||||||
|
Q_strncatz(temppath, "cur" BUILDTYPE EXETYPE".exe", sizeof(temppath));
|
||||||
|
DeleteFile(temppath);
|
||||||
|
if (MoveFile(pendingpath, temppath))
|
||||||
|
MyRegSetValue(HKEY_CURRENT_USER, "Software\\"FULLENGINENAME, BUILDTYPE EXETYPE, REG_SZ, temppath, strlen(temppath)+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*grab the binary to run from the registry*/
|
||||||
|
MyRegGetStringValue(HKEY_CURRENT_USER, "Software\\"FULLENGINENAME, BUILDTYPE EXETYPE, updatedpath, updatedpathlen);
|
||||||
|
if (!*updatedpath)
|
||||||
|
{
|
||||||
|
/*ooer, its not set, try and download one. updates are handled by the client itself.*/
|
||||||
|
enginedownloadactive = DL_Create(UPDATE_URL_BUILD);
|
||||||
|
if (enginedownloadactive)
|
||||||
|
{
|
||||||
|
enginedownloadactive->user_ctx = NULL;
|
||||||
|
DL_CreateThread(enginedownloadactive, VFSPIPE_Open(), Update_Version_Updated);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Sys_UnlockMutex(globalmutex);
|
||||||
|
|
||||||
|
return !!*updatedpath;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -564,7 +753,7 @@ char *cleanarg(char *arg)
|
||||||
return strdup("\"\"");
|
return strdup("\"\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Plug_GetBinaryName(char *exe, int exelen,
|
qboolean Plug_GetBinaryName(char *exe, int exelen,
|
||||||
char *basedir, int basedirlen)
|
char *basedir, int basedirlen)
|
||||||
{
|
{
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
|
@ -572,6 +761,10 @@ void Plug_GetBinaryName(char *exe, int exelen,
|
||||||
char value[1024];
|
char value[1024];
|
||||||
FILE *f;
|
FILE *f;
|
||||||
Q_snprintfz(buffer, sizeof(buffer), "%s%s", binarypath, "npfte.txt");
|
Q_snprintfz(buffer, sizeof(buffer), "%s%s", binarypath, "npfte.txt");
|
||||||
|
|
||||||
|
*exe = 0;
|
||||||
|
*basedir = 0;
|
||||||
|
|
||||||
f = fopen(buffer, "rt");
|
f = fopen(buffer, "rt");
|
||||||
if (f)
|
if (f)
|
||||||
{
|
{
|
||||||
|
@ -581,7 +774,7 @@ void Plug_GetBinaryName(char *exe, int exelen,
|
||||||
*value = 0;
|
*value = 0;
|
||||||
COM_ParseOut(COM_ParseOut(buffer, cmd, sizeof(cmd)), value, sizeof(value));
|
COM_ParseOut(COM_ParseOut(buffer, cmd, sizeof(cmd)), value, sizeof(value));
|
||||||
if (!strcmp(cmd, "relexe"))
|
if (!strcmp(cmd, "relexe"))
|
||||||
Q_snprintfz(buffer, sizeof(buffer), "%s%s", binarypath, value);
|
Q_snprintfz(exe, exelen, "%s%s", binarypath, value);
|
||||||
else if (!strcmp(cmd, "absexe"))
|
else if (!strcmp(cmd, "absexe"))
|
||||||
Q_strncpyz(exe, value, exelen);
|
Q_strncpyz(exe, value, exelen);
|
||||||
else if (!strcmp(cmd, "basedir"))
|
else if (!strcmp(cmd, "basedir"))
|
||||||
|
@ -589,6 +782,10 @@ void Plug_GetBinaryName(char *exe, int exelen,
|
||||||
}
|
}
|
||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!*exe)
|
||||||
|
return Plug_GetDownloadedName(exe, exelen);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Plug_GenCommandline(struct context *ctx, char **argv, int maxargs)
|
int Plug_GenCommandline(struct context *ctx, char **argv, int maxargs)
|
||||||
|
@ -598,15 +795,24 @@ int Plug_GenCommandline(struct context *ctx, char **argv, int maxargs)
|
||||||
char tok[256];
|
char tok[256];
|
||||||
char exe[1024];
|
char exe[1024];
|
||||||
char basedir[1024];
|
char basedir[1024];
|
||||||
|
qboolean autoupdate;
|
||||||
|
|
||||||
Q_snprintfz(exe, sizeof(exe), "%s%s", binarypath, "fteqw");
|
Q_snprintfz(exe, sizeof(exe), "%s%s", binarypath, "fteqw");
|
||||||
*basedir = 0;
|
*basedir = 0;
|
||||||
|
|
||||||
Plug_GetBinaryName(exe, sizeof(exe), basedir, sizeof(basedir));
|
autoupdate = Plug_GetBinaryName(exe, sizeof(exe), basedir, sizeof(basedir));
|
||||||
|
|
||||||
|
if (!*exe)
|
||||||
|
return 0; //error
|
||||||
|
|
||||||
argv[0] = strdup(exe);
|
argv[0] = strdup(exe);
|
||||||
argc = 1;
|
argc = 1;
|
||||||
|
|
||||||
|
if (autoupdate)
|
||||||
|
{
|
||||||
|
ADDRARG("-autoupdate");
|
||||||
|
}
|
||||||
|
|
||||||
ADDRARG("-plugin");
|
ADDRARG("-plugin");
|
||||||
|
|
||||||
if (*basedir)
|
if (*basedir)
|
||||||
|
@ -682,6 +888,8 @@ qboolean Plug_GenCommandlineString(struct context *ctx, char *cmdline, int cmdli
|
||||||
char *argv[64];
|
char *argv[64];
|
||||||
int argc, i;
|
int argc, i;
|
||||||
argc = Plug_GenCommandline(ctx, argv, 64);
|
argc = Plug_GenCommandline(ctx, argv, 64);
|
||||||
|
if (!argc)
|
||||||
|
return false;
|
||||||
for (i = 0; i < argc; i++)
|
for (i = 0; i < argc; i++)
|
||||||
{
|
{
|
||||||
//add quotes for any arguments with spaces
|
//add quotes for any arguments with spaces
|
||||||
|
@ -712,14 +920,14 @@ void Plug_ExecuteCommand(struct context *ctx, char *message, ...)
|
||||||
WriteFile(ctx->pipetoengine, finalmessage, strlen(finalmessage), &written, NULL);
|
WriteFile(ctx->pipetoengine, finalmessage, strlen(finalmessage), &written, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Plug_CreatePluginProcess(struct context *ctx)
|
qboolean Plug_CreatePluginProcess(struct context *ctx)
|
||||||
{
|
{
|
||||||
char cmdline[8192];
|
char cmdline[8192];
|
||||||
PROCESS_INFORMATION childinfo;
|
PROCESS_INFORMATION childinfo;
|
||||||
STARTUPINFO startinfo;
|
STARTUPINFO startinfo;
|
||||||
SECURITY_ATTRIBUTES pipesec = {sizeof(pipesec), NULL, TRUE};
|
SECURITY_ATTRIBUTES pipesec = {sizeof(pipesec), NULL, TRUE};
|
||||||
if (!Plug_GenCommandlineString(ctx, cmdline, sizeof(cmdline)))
|
if (!Plug_GenCommandlineString(ctx, cmdline, sizeof(cmdline)))
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
memset(&startinfo, 0, sizeof(startinfo));
|
memset(&startinfo, 0, sizeof(startinfo));
|
||||||
startinfo.cb = sizeof(startinfo);
|
startinfo.cb = sizeof(startinfo);
|
||||||
|
@ -742,6 +950,8 @@ void Plug_CreatePluginProcess(struct context *ctx)
|
||||||
//these ends of the pipes were inherited by now, so we can discard them in the caller.
|
//these ends of the pipes were inherited by now, so we can discard them in the caller.
|
||||||
CloseHandle(startinfo.hStdOutput);
|
CloseHandle(startinfo.hStdOutput);
|
||||||
CloseHandle(startinfo.hStdInput);
|
CloseHandle(startinfo.hStdInput);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Plug_PluginThread(void *ctxptr)
|
int Plug_PluginThread(void *ctxptr)
|
||||||
|
@ -820,11 +1030,80 @@ int Plug_PluginThread(void *ctxptr)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Plug_CreatePluginProcess(ctx);
|
if (!Plug_CreatePluginProcess(ctx))
|
||||||
|
{
|
||||||
|
if (!enginedownloadactive)
|
||||||
|
{
|
||||||
|
strcpy(ctx->pub.statusmessage, "Unable to determine engine to run. Plugin is not correctly installed.");
|
||||||
|
if (ctx->bfuncs.StatusChanged)
|
||||||
|
ctx->bfuncs.StatusChanged(ctx->hostinstance);
|
||||||
|
ctx->pub.running = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int os = -1;
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
Sys_LockMutex(globalmutex);
|
||||||
|
if (!enginedownloadactive)
|
||||||
|
{
|
||||||
|
Sys_UnlockMutex(globalmutex);
|
||||||
|
if (!Plug_CreatePluginProcess(ctx))
|
||||||
|
ctx->pub.running = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (os != enginedownloadactive->status)
|
||||||
|
{
|
||||||
|
os = enginedownloadactive->status;
|
||||||
|
switch(os)
|
||||||
|
{
|
||||||
|
case DL_PENDING:
|
||||||
|
strcpy(ctx->pub.statusmessage, "Download pending.");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DL_FAILED:
|
||||||
|
strcpy(ctx->pub.statusmessage, "Engine download failed. Try later, or fix internet connection.");
|
||||||
|
os = -2; //stop trying.
|
||||||
|
ctx->pub.running = false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DL_RESOLVING:
|
||||||
|
strcpy(ctx->pub.statusmessage, "Download pending. Resolving hostname.");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DL_QUERY:
|
||||||
|
strcpy(ctx->pub.statusmessage, "Download pending. Reqeusting file.");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DL_ACTIVE:
|
||||||
|
Q_snprintfz(ctx->pub.statusmessage, sizeof(ctx->pub.statusmessage), "Download pending. At %u of %u.", enginedownloadactive->completed, enginedownloadactive->totalsize);
|
||||||
|
os = -1; //keep refreshing
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DL_FINISHED:
|
||||||
|
strcpy(ctx->pub.statusmessage, "Download completed!");
|
||||||
|
DL_Close(enginedownloadactive);
|
||||||
|
enginedownloadactive = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Sys_UnlockMutex(globalmutex);
|
||||||
|
if (ctx->bfuncs.StatusChanged)
|
||||||
|
ctx->bfuncs.StatusChanged(ctx->hostinstance);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Sys_UnlockMutex(globalmutex);
|
||||||
|
if (os == -2)
|
||||||
|
break;
|
||||||
|
Sleep(1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ctx->bfuncs.StatusChanged)
|
if (ctx->bfuncs.StatusChanged)
|
||||||
ctx->bfuncs.StatusChanged(ctx->hostinstance);
|
ctx->bfuncs.StatusChanged(ctx->hostinstance);
|
||||||
|
|
||||||
|
if (ctx->pub.running)
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
DWORD avail;
|
DWORD avail;
|
||||||
|
@ -837,6 +1116,7 @@ int Plug_PluginThread(void *ctxptr)
|
||||||
if (!ReadFile(ctx->pipefromengine, buffer + bufoffs, avail, &avail, NULL) || !avail)
|
if (!ReadFile(ctx->pipefromengine, buffer + bufoffs, avail, &avail, NULL) || !avail)
|
||||||
{
|
{
|
||||||
//broken pipe, client died.
|
//broken pipe, client died.
|
||||||
|
*ctx->pub.statusmessage = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
bufoffs += avail;
|
bufoffs += avail;
|
||||||
|
@ -887,13 +1167,12 @@ int Plug_PluginThread(void *ctxptr)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctx->pub.running = false;
|
|
||||||
*ctx->pub.statusmessage = 0;
|
|
||||||
if (ctx->bfuncs.StatusChanged)
|
if (ctx->bfuncs.StatusChanged)
|
||||||
ctx->bfuncs.StatusChanged(ctx->hostinstance);
|
ctx->bfuncs.StatusChanged(ctx->hostinstance);
|
||||||
|
|
||||||
if (ctx == activecontext)
|
if (ctx == activecontext)
|
||||||
activecontext = NULL;
|
activecontext = NULL;
|
||||||
|
ctx->pub.running = false;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1652,6 +1931,8 @@ static const struct plugfuncs exportedplugfuncs_1 =
|
||||||
|
|
||||||
const struct plugfuncs *Plug_GetFuncs(int ver)
|
const struct plugfuncs *Plug_GetFuncs(int ver)
|
||||||
{
|
{
|
||||||
|
if (!globalmutex)
|
||||||
|
globalmutex = Sys_CreateMutex();
|
||||||
if (ver == 1)
|
if (ver == 1)
|
||||||
return &exportedplugfuncs_1;
|
return &exportedplugfuncs_1;
|
||||||
else
|
else
|
||||||
|
|
|
@ -2024,7 +2024,7 @@ qboolean MyRegGetStringValue(HKEY base, char *keyname, char *valuename, void *da
|
||||||
DWORD resultlen = datalen - 1;
|
DWORD resultlen = datalen - 1;
|
||||||
HKEY subkey;
|
HKEY subkey;
|
||||||
DWORD type = REG_NONE;
|
DWORD type = REG_NONE;
|
||||||
if (RegOpenKeyEx(base, keyname, 0, KEY_WRITE, &subkey) == ERROR_SUCCESS)
|
if (RegOpenKeyEx(base, keyname, 0, KEY_READ, &subkey) == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
result = ERROR_SUCCESS == RegQueryValueEx(subkey, valuename, NULL, &type, data, &datalen);
|
result = ERROR_SUCCESS == RegQueryValueEx(subkey, valuename, NULL, &type, data, &datalen);
|
||||||
RegCloseKey (subkey);
|
RegCloseKey (subkey);
|
||||||
|
@ -2167,18 +2167,25 @@ qboolean Sys_CheckUpdated(void)
|
||||||
return false;
|
return false;
|
||||||
else if (!COM_CheckParm("-autoupdate") && !COM_CheckParm("--autoupdate"))
|
else if (!COM_CheckParm("-autoupdate") && !COM_CheckParm("--autoupdate"))
|
||||||
return false;
|
return false;
|
||||||
|
else if (COM_CheckParm("-plugin"))
|
||||||
|
{
|
||||||
|
//download, but don't invoke. the caller is expected to start us up properly (once installed).
|
||||||
|
}
|
||||||
else if (!ffe)
|
else if (!ffe)
|
||||||
{
|
{
|
||||||
|
//if we're not from the frontend, we should run the updated build instead
|
||||||
char frontendpath[MAX_OSPATH];
|
char frontendpath[MAX_OSPATH];
|
||||||
char pendingpath[MAX_OSPATH];
|
char pendingpath[MAX_OSPATH];
|
||||||
char updatedpath[MAX_QPATH];
|
char updatedpath[MAX_OSPATH];
|
||||||
|
|
||||||
MyRegGetStringValue(HKEY_CURRENT_USER, "Software\\"FULLENGINENAME, "pending" BUILDTYPE EXETYPE, pendingpath, sizeof(pendingpath));
|
MyRegGetStringValue(HKEY_CURRENT_USER, "Software\\"FULLENGINENAME, "pending" BUILDTYPE EXETYPE, pendingpath, sizeof(pendingpath));
|
||||||
if (*pendingpath)
|
if (*pendingpath)
|
||||||
{
|
{
|
||||||
MyRegDeleteKeyValue(HKEY_CURRENT_USER, "Software\\"FULLENGINENAME, "pending" BUILDTYPE EXETYPE);
|
MyRegDeleteKeyValue(HKEY_CURRENT_USER, "Software\\"FULLENGINENAME, "pending" BUILDTYPE EXETYPE);
|
||||||
Update_GetHomeDirectory(updatedpath, sizeof(updatedpath));
|
Update_GetHomeDirectory(updatedpath, sizeof(updatedpath));
|
||||||
|
CreateDirectory(updatedpath, NULL);
|
||||||
Q_strncatz(updatedpath, "cur" BUILDTYPE EXETYPE".exe", sizeof(updatedpath));
|
Q_strncatz(updatedpath, "cur" BUILDTYPE EXETYPE".exe", sizeof(updatedpath));
|
||||||
|
DeleteFile(updatedpath);
|
||||||
if (MoveFile(pendingpath, updatedpath))
|
if (MoveFile(pendingpath, updatedpath))
|
||||||
MyRegSetValue(HKEY_CURRENT_USER, "Software\\"FULLENGINENAME, BUILDTYPE EXETYPE, REG_SZ, updatedpath, strlen(updatedpath)+1);
|
MyRegSetValue(HKEY_CURRENT_USER, "Software\\"FULLENGINENAME, BUILDTYPE EXETYPE, REG_SZ, updatedpath, strlen(updatedpath)+1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,8 +28,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1,0,0,3
|
FILEVERSION 1,0,2,0
|
||||||
PRODUCTVERSION 1,0,0,3
|
PRODUCTVERSION 1,0,2,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -48,7 +48,7 @@ BEGIN
|
||||||
VALUE "CompanyName", "Forethought Entertainment\0"
|
VALUE "CompanyName", "Forethought Entertainment\0"
|
||||||
VALUE "FileDescription", "Quake in a browser\0"
|
VALUE "FileDescription", "Quake in a browser\0"
|
||||||
VALUE "FileExtents", "qtv|mvd\0"
|
VALUE "FileExtents", "qtv|mvd\0"
|
||||||
VALUE "FileVersion", "1, 0, 0, 3\0"
|
VALUE "FileVersion", "1, 0, 2, 0\0"
|
||||||
VALUE "InternalName", "npfte\0"
|
VALUE "InternalName", "npfte\0"
|
||||||
VALUE "LegalCopyright", "Copyright © 2010\0"
|
VALUE "LegalCopyright", "Copyright © 2010\0"
|
||||||
VALUE "LegalTrademarks", "\0"
|
VALUE "LegalTrademarks", "\0"
|
||||||
|
@ -56,7 +56,7 @@ BEGIN
|
||||||
VALUE "OriginalFilename", "npfte.dll\0"
|
VALUE "OriginalFilename", "npfte.dll\0"
|
||||||
VALUE "PrivateBuild", "\0"
|
VALUE "PrivateBuild", "\0"
|
||||||
VALUE "ProductName", "FTE Browser Plugin\0"
|
VALUE "ProductName", "FTE Browser Plugin\0"
|
||||||
VALUE "ProductVersion", "1, 0, 0, 3\0"
|
VALUE "ProductVersion", "1, 0, 2, 0\0"
|
||||||
VALUE "SpecialBuild", "\0"
|
VALUE "SpecialBuild", "\0"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
|
|
|
@ -989,6 +989,16 @@ void SV_Savegame (char *savename)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sv.allocated_client_slots == 1 && svs.gametype == GT_PROGS)
|
||||||
|
{
|
||||||
|
if (svs.clients->state > cs_connected && svs.clients[0].edict->v->health <= 0)
|
||||||
|
{
|
||||||
|
Con_Printf("Refusing to save while dead.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//FIXME: we should probably block saving during intermission too.
|
||||||
|
|
||||||
/*catch invalid names*/
|
/*catch invalid names*/
|
||||||
if (!*savename || strstr(savename, ".."))
|
if (!*savename || strstr(savename, ".."))
|
||||||
savename = "quicksav";
|
savename = "quicksav";
|
||||||
|
|
Loading…
Reference in a new issue