From e403cebc657a42e048878694ecc396b254e7ab75 Mon Sep 17 00:00:00 2001 From: Spoike Date: Tue, 7 Apr 2009 01:26:47 +0000 Subject: [PATCH] Should be more robust with first-run config execs now. Multiple download sources can be specified (eg for mod+map). Takes the form "providedfile:urltodownload providedfile:urltodownload". This comes via the browser so relative urls = woot. The old single-url-only path is no longer supported. This is an incompatible change, but we're still young. The unpacking process is still the same, and still only paks/pk3s are extracted. Note that the providedfile is relative to the base dir rather than the game dir. You can specify potential alternate gamedirs. The QTV file is not mandatory, you can use map="blah" join="blah" stream="0@blah", so long as you set the mime type as: type="application/x-fteplugin". src="someqtvfile" still works, of course (and doesn't mandate the type= field, although that should probably be specified to make life easier on configuring servers to use the correct mime types). The splash image can be set with: splash="myurlhere". Note that only jpg and png files are supported. This comes via the browser so relative urls = woot. Game property can take multiple game dirs now, too. First argument is the basic game. If its one of the special ones then FTE is meant to hunt down your prior install for that. If its not recognised then its added as the only game directory. Additional ones are added after (eg: "id1 fortress" adds just id1+fortress while "q1 fortress" adds id1+qw+fte+fortress). Use appropriately. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@3160 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/client/cl_main.c | 44 +++++---- engine/client/client.h | 1 + engine/client/sys_npqtv.c | 186 ++++++++++++++++++++++++++++---------- engine/common/fs.c | 17 +++- engine/ftequake/npplug.rc | 2 +- 5 files changed, 185 insertions(+), 65 deletions(-) diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index ae5c79041..a2d455d2a 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -164,6 +164,7 @@ cvar_t ruleset_allow_sensative_texture_replacements = SCVAR("ruleset_allow_sensa cvar_t ruleset_allow_localvolume = SCVAR("ruleset_allow_localvolume", "1"); extern cvar_t cl_hightrack; +extern cvar_t vid_renderer; char cl_screengroup[] = "Screen options"; char cl_controlgroup[] = "client operation options"; @@ -3486,10 +3487,11 @@ Host_Init */ void Host_Init (quakeparms_t *parms) { +#ifndef NPQTV int i; int qrc, hrc, def; +#endif - extern cvar_t vid_renderer; COM_InitArgv (parms->argc, parms->argv); if (setjmp (host_abort) ) @@ -3572,6 +3574,23 @@ void Host_Init (quakeparms_t *parms) // Con_Printf ("Exe: "__TIME__" "__DATE__"\n"); Con_TPrintf (TL_HEAPSIZE, parms->memsize/ (1024*1024.0)); + Hunk_AllocName (0, "-HOST_HUNKLEVEL-"); + host_hunklevel = Hunk_LowMark (); + + R_SetRenderer(-1);//set the renderer stuff to unset... + + host_initialized = true; + +#ifdef NPQTV +} + +void Host_FinishInit(void) +{ + int i; + int qrc, hrc, def; +#endif + + Cbuf_AddText ("cl_warncmd 0\n", RESTRICT_LOCAL); Cbuf_AddText ("+mlook\n", RESTRICT_LOCAL); //fixme: this is bulky, only exec one of these. @@ -3597,12 +3616,7 @@ void Host_Init (quakeparms_t *parms) Cbuf_AddText ("exec fte.cfg\n", RESTRICT_LOCAL); Cbuf_AddText ("cl_warncmd 1\n", RESTRICT_LOCAL); //and then it's allowed to start moaning. - Hunk_AllocName (0, "-HOST_HUNKLEVEL-"); - host_hunklevel = Hunk_LowMark (); - R_SetRenderer(-1);//set the renderer stuff to unset... - - host_initialized = true; Cbuf_Execute (); //if the server initialisation causes a problem, give it a place to abort to @@ -3645,7 +3659,6 @@ void Host_Init (quakeparms_t *parms) Cvar_ApplyLatches(CVAR_RENDERERLATCH); -#ifndef NPQTV //-1 means 'never set' if (qrenderer == -1 && *vid_renderer.string) { @@ -3661,7 +3674,6 @@ void Host_Init (quakeparms_t *parms) if (qrenderer == QR_NONE) Con_Printf("Use the setrenderer command to use a gui\n"); -#endif #ifdef VM_UI UI_Init(); @@ -3707,14 +3719,14 @@ Con_TPrintf (TL_NL); if (!*cls.servername) { - #ifndef CLIENTONLY - if (!sv.state) - { - if (qrenderer > QR_NONE) - M_ToggleMenu_f(); - //Con_ForceActiveNow(); - } - #endif +#ifndef CLIENTONLY + if (!sv.state) +#endif + { + if (qrenderer > QR_NONE) + M_ToggleMenu_f(); + //Con_ForceActiveNow(); + } } } diff --git a/engine/client/client.h b/engine/client/client.h index 576204d69..9161ff214 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -814,6 +814,7 @@ typedef struct QTVCT_CONNECT, QTVCT_JOIN, QTVCT_OBSERVE, + QTVCT_MAP } connectiontype; enum { diff --git a/engine/client/sys_npqtv.c b/engine/client/sys_npqtv.c index d03a6f923..88b3b9e52 100644 --- a/engine/client/sys_npqtv.c +++ b/engine/client/sys_npqtv.c @@ -161,8 +161,9 @@ struct context WNDPROC oldproc; #endif - char datadownload[MAX_PATH]; - char gamename[MAX_QPATH]; + char *datadownload; + char *gamename; + char *password; char *onstart; char *onend; char *ondemoend; @@ -277,12 +278,6 @@ void UnpackAndExtractPakFiles_Complete(struct context *ctx, vfsfile_t *file, con zipfilefuncs.ClosePath(zip); Cmd_ExecuteString("fs_restart", RESTRICT_LOCAL); - - //this code is to stop them from constantly downloading if that zip didn't contain one for some reason - if (!FS_FLocateFile("default.cfg", FSLFRT_IFFOUND, NULL)) - { - FS_WriteFile("default.cfg", "", 0, FS_GAMEONLY); - } } } struct pipetype UnpackAndExtractPakFiles = @@ -455,37 +450,26 @@ LRESULT CALLBACK MyPluginWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPar if (sys_parentwindow != ctx->window.window) { - if (!sys_parentwindow) + if (qrenderer == -1) { - switch(ctx->qtvf.connectiontype) + //urgh, its not started up yet + sys_parentwindow = ctx->window.window; + + Host_FinishInit(); + } + else + { + sys_parentwindow = ctx->window.window; + if (sys_parentwindow) { - default: - break; - case QTVCT_STREAM: - Cmd_ExecuteString(va("qtvplay %s", ctx->qtvf.server), RESTRICT_LOCAL); - break; - case QTVCT_CONNECT: - Cmd_ExecuteString(va("connect %s", ctx->qtvf.server), RESTRICT_LOCAL); - break; - case QTVCT_JOIN: - Cmd_ExecuteString(va("join %s", ctx->qtvf.server), RESTRICT_LOCAL); - break; - case QTVCT_OBSERVE: - Cmd_ExecuteString(va("observe %s", ctx->qtvf.server), RESTRICT_LOCAL); - break; + sys_parentwidth = ctx->window.width; + sys_parentheight = ctx->window.height; + Cmd_ExecuteString("vid_restart", RESTRICT_LOCAL); } } - sys_parentwindow = ctx->window.window; - if (sys_parentwindow) - { - sys_parentwidth = ctx->window.width; - sys_parentheight = ctx->window.height; - Cmd_ExecuteString("vid_restart", RESTRICT_LOCAL); - } - } - else + else if (sys_parentwindow) { NPQTV_Sys_MainLoop(); if (!host_initialized) @@ -505,6 +489,7 @@ LRESULT CALLBACK MyPluginWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPar case WM_PAINT: if (activecontext == ctx && !ctx->contextrunning && ctx->window.window) { + char *s; int argc; char *argv[16]; sys_parentwindow = NULL; @@ -515,33 +500,92 @@ LRESULT CALLBACK MyPluginWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPar activecontext = ctx; - if (!*ctx->gamename || !strcmp(ctx->gamename, "q1") || !strcmp(ctx->gamename, "qw") || !strcmp(ctx->gamename, "quake") || !strcmp(ctx->gamename, "id1")) + switch(ctx->qtvf.connectiontype) + { + default: + break; + case QTVCT_STREAM: + argv[argc++] = "+qtvplay"; + argv[argc++] = ctx->qtvf.server; + break; + case QTVCT_CONNECT: + argv[argc++] = "+connect"; + argv[argc++] = ctx->qtvf.server; + break; + case QTVCT_JOIN: + argv[argc++] = "+join"; + argv[argc++] = ctx->qtvf.server; + break; + case QTVCT_OBSERVE: + argv[argc++] = "+observe"; + argv[argc++] = ctx->qtvf.server; + break; + case QTVCT_MAP: + argv[argc++] = "+map"; + argv[argc++] = ctx->qtvf.server; + break; + } + + if (ctx->password) + { + argv[argc++] = "+password"; + argv[argc++] = ctx->password; + } + + //figure out the game dirs (first token is the base game) + s = ctx->gamename; + s = COM_ParseOut(s, com_token, sizeof(com_token)); + if (!*com_token || !strcmp(com_token, "q1") || !strcmp(com_token, "qw") || !strcmp(com_token, "quake")) argv[argc++] = "-quake"; - else if (!strcmp(ctx->gamename, "q2") || !strcmp(ctx->gamename, "quake2")) + else if (!strcmp(com_token, "q2") || !strcmp(com_token, "quake2")) argv[argc++] = "-q2"; - else if (!strcmp(ctx->gamename, "q3") || !strcmp(ctx->gamename, "quake3")) + else if (!strcmp(com_token, "q3") || !strcmp(com_token, "quake3")) argv[argc++] = "-q3"; - else if (!strcmp(ctx->gamename, "hl") || !strcmp(ctx->gamename, "halflife")) + else if (!strcmp(com_token, "hl") || !strcmp(com_token, "halflife")) argv[argc++] = "-halflife"; - else if (!strcmp(ctx->gamename, "h2") || !strcmp(ctx->gamename, "hexen2")) + else if (!strcmp(com_token, "h2") || !strcmp(com_token, "hexen2")) argv[argc++] = "-hexen2"; - else if (!strcmp(ctx->gamename, "nex") || !strcmp(ctx->gamename, "nexuiz")) + else if (!strcmp(com_token, "nex") || !strcmp(com_token, "nexuiz")) argv[argc++] = "-nexuiz"; else { argv[argc++] = "-basegame"; - argv[argc++] = ctx->gamename; + argv[argc++] = strdup(com_token); //FIXME: this will leak + } + //later options are additions to that + while ((s = COM_ParseOut(s, com_token, sizeof(com_token)))) + { + argv[argc++] = "-addbasegame"; + argv[argc++] = strdup(com_token); //FIXME: this will leak } sys_parentwidth = ctx->window.width; sys_parentheight = ctx->window.height; ctx->contextrunning = NPQTV_Sys_Startup(argc, argv); - if (*ctx->datadownload) + //now that the file system is started up, check to make sure its complete + if (ctx->datadownload) { - if (!FS_FLocateFile("default.cfg", FSLFRT_IFFOUND, NULL) && !FS_FLocateFile("gfx.wad", FSLFRT_IFFOUND, NULL)) + char *s = ctx->datadownload; + char *c; + vfsfile_t *f; + while ((s = COM_ParseOut(s, com_token, sizeof(com_token)))) { - browserfuncs->geturlnotify(ctx->nppinstance, ctx->datadownload, NULL, &UnpackAndExtractPakFiles); + //FIXME: do we want to add some sort of file size indicator? + c = strchr(com_token, ':'); + if (!c) + continue; + *c++ = 0; + f = FS_OpenVFS(com_token, "rb", FS_ROOT); + if (f) + { + Con_Printf("Already have %s\n", com_token); + VFS_CLOSE(f); + continue; + } + + Con_Printf("Attempting to download %s\n", c); + browserfuncs->geturlnotify(ctx->nppinstance, c, NULL, &UnpackAndExtractPakFiles); ctx->waitingfordatafiles++; } } @@ -657,14 +701,14 @@ NPError NP_LOADDS NPP_New(NPMIMEType pluginType, NPP instance, instance->pdata = ctx; ctx->nppinstance = instance; - Q_strncpyz(ctx->gamename, "q1", sizeof(ctx->gamename)); + ctx->gamename = strdup("q1"); //parse out the properties for (i = 0; i < argc; i++) { if (!stricmp(argn[i], "dataDownload")) { - Q_strncpyz(ctx->datadownload, argv[i], sizeof(ctx->datadownload)); + ctx->datadownload = strdup(argv[i]); } else if (!stricmp(argn[i], "game")) { @@ -672,16 +716,23 @@ NPError NP_LOADDS NPP_New(NPMIMEType pluginType, NPP instance, if (!strstr(argn[i], "/")) if (!strstr(argn[i], "\\")) if (!strstr(argn[i], ":")) - Q_strncpyz(ctx->gamename, argv[i], sizeof(ctx->gamename)); + { + free(ctx->gamename); + ctx->gamename = strdup(argv[i]); + } } else if (!stricmp(argn[i], "connType")) { + if (ctx->qtvf.connectiontype) + continue; if (!stricmp(argn[i], "join")) ctx->qtvf.connectiontype = QTVCT_JOIN; else if (!stricmp(argn[i], "qtv")) ctx->qtvf.connectiontype = QTVCT_STREAM; else if (!stricmp(argn[i], "connect")) ctx->qtvf.connectiontype = QTVCT_CONNECT; + else if (!stricmp(argn[i], "map")) + ctx->qtvf.connectiontype = QTVCT_MAP; else if (!stricmp(argn[i], "join")) ctx->qtvf.connectiontype = QTVCT_JOIN; else if (!stricmp(argn[i], "observe")) @@ -690,7 +741,43 @@ NPError NP_LOADDS NPP_New(NPMIMEType pluginType, NPP instance, ctx->qtvf.connectiontype = QTVCT_NONE; } else if (!stricmp(argn[i], "server") || !stricmp(argn[i], "stream")) + { + if (*ctx->qtvf.server) + continue; Q_strncpyz(ctx->qtvf.server, argv[i], sizeof(ctx->qtvf.server)); + } + else if (!stricmp(argn[i], "map")) + { + if (ctx->qtvf.connectiontype) + continue; + ctx->qtvf.connectiontype = QTVCT_MAP; + Q_strncpyz(ctx->qtvf.server, argv[i], sizeof(ctx->qtvf.server)); + } + else if (!stricmp(argn[i], "stream")) + { + if (ctx->qtvf.connectiontype) + continue; + ctx->qtvf.connectiontype = QTVCT_STREAM; + Q_strncpyz(ctx->qtvf.server, argv[i], sizeof(ctx->qtvf.server)); + } + else if (!stricmp(argn[i], "join")) + { + if (ctx->qtvf.connectiontype) + continue; + ctx->qtvf.connectiontype = QTVCT_JOIN; + Q_strncpyz(ctx->qtvf.server, argv[i], sizeof(ctx->qtvf.server)); + } + else if (!stricmp(argn[i], "observe")) + { + if (ctx->qtvf.connectiontype) + continue; + ctx->qtvf.connectiontype = QTVCT_OBSERVE; + Q_strncpyz(ctx->qtvf.server, argv[i], sizeof(ctx->qtvf.server)); + } + else if (!stricmp(argn[i], "password")) + { + ctx->password = strdup(argv[i]); + } else if (!stricmp(argn[i], "splash")) { Q_strncpyz(ctx->qtvf.splashscreen, argv[i], sizeof(ctx->qtvf.splashscreen)); @@ -748,6 +835,13 @@ NPError NP_LOADDS NPP_Destroy(NPP instance, NPSavedData** save) } #endif + //actually these ifs are not required, just the frees + if (ctx->gamename) + free(ctx->gamename); + if (ctx->password) + free(ctx->password); + if (ctx->datadownload) + free(ctx->datadownload); if (ctx->splashdata) free(ctx->splashdata); diff --git a/engine/common/fs.c b/engine/common/fs.c index b0eb58ec6..ec7e13841 100644 --- a/engine/common/fs.c +++ b/engine/common/fs.c @@ -2256,7 +2256,6 @@ void COM_InitFilesystem (void) #ifdef _WIN32 { //win32 sucks. HMODULE shfolder = LoadLibrary("shfolder.dll"); - HMODULE advapi32; DWORD winver = (DWORD)LOBYTE(LOWORD(GetVersion())); if (shfolder) @@ -2282,7 +2281,7 @@ void COM_InitFilesystem (void) #ifdef NPQTV if (!*com_homedir) - Q_snprintfz(com_homedir, sizeof(com_homedir), "/%s/", ev, FULLENGINENAME); + Q_snprintfz(com_homedir, sizeof(com_homedir), "/%s/", FULLENGINENAME); //as a browser plugin, always use their home directory usehome = true; #else @@ -2290,6 +2289,7 @@ void COM_InitFilesystem (void) usehome = true; // always use home directory by default, as Vista+ mimics this behavior anyway else if (winver >= 0x5) // Windows 2000/XP/2003 { + HMODULE advapi32; advapi32 = LoadLibrary("advapi32.dll"); if (advapi32) @@ -2388,6 +2388,19 @@ void COM_InitFilesystem (void) } } + + i = COM_CheckParm ("-addbasegame"); + do //use multiple -addbasegames (this is so the basic dirs don't die) + { + FS_AddGameDirectory (com_argv[i+1], va("%s%s", com_quakedir, com_argv[i+1]), ~0); + if (*com_homedir) + FS_AddGameDirectory (com_argv[i+1], va("%s%s", com_homedir, com_argv[i+1]), ~0); + + i = COM_CheckNextParm ("-addbasegame", i); + } + while (i && i < com_argc-1); + + // any set gamedirs will be freed up to here com_base_searchpaths = com_searchpaths; diff --git a/engine/ftequake/npplug.rc b/engine/ftequake/npplug.rc index b1077aad7..2419e5582 100644 --- a/engine/ftequake/npplug.rc +++ b/engine/ftequake/npplug.rc @@ -52,7 +52,7 @@ BEGIN VALUE "InternalName", "npqtv\0" VALUE "LegalCopyright", "Copyright © 2009\0" VALUE "LegalTrademarks", "\0" - VALUE "MIMEType", "text/x-quaketvident|application/x-multiviewdemo\0" + VALUE "MIMEType", "text/x-quaketvident|application/x-multiviewdemo|application/x-fteplugin\0" VALUE "OriginalFilename", "npqtv.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "QTV Viewer\0"