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
This commit is contained in:
Spoike 2009-04-07 01:26:47 +00:00
parent f2688e7866
commit e403cebc65
5 changed files with 185 additions and 65 deletions

View File

@ -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();
}
}
}

View File

@ -814,6 +814,7 @@ typedef struct
QTVCT_CONNECT,
QTVCT_JOIN,
QTVCT_OBSERVE,
QTVCT_MAP
} connectiontype;
enum
{

View File

@ -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);

View File

@ -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;

View File

@ -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"