Try to fix up package downloads, and dp-compat downloads too.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@6199 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2022-03-01 02:51:55 +00:00
parent d9b4bc1a77
commit c2633078ff
9 changed files with 163 additions and 106 deletions

View File

@ -4538,7 +4538,29 @@ void CL_DownloadSize_f(void)
dl = CL_DownloadFailed(rname, NULL, DLFAIL_REDIRECTED);
Con_DPrintf("Download of \"%s\" redirected to \"%s\".\n", rname, redirection);
CL_CheckOrEnqueDownloadFile(redirection, NULL, dl->flags);
if (!strncmp(redirection, "package/", 8))
{ //redirected to a package, make sure we cache it in the proper place.
char pkn[MAX_QPATH], pkh[32];
char localname[MAX_QPATH];
char *spn = cl.serverpacknames, *sph = cl.serverpackhashes;
*pkh = 0;
while(spn && sph)
{
spn=COM_ParseOut(spn, pkn, sizeof(pkn));
sph=COM_ParseOut(sph, pkh, sizeof(pkh));
if (!spn || !sph)
break;
if (!strcmp(pkn, redirection+8))
break;
*pkh = 0;
}
if (*pkh)
if (FS_GenCachedPakName(redirection+8, pkh, localname, sizeof(localname)))
CL_CheckOrEnqueDownloadFile(redirection+8, localname, DLLF_NONGAME);
}
else
CL_CheckOrEnqueDownloadFile(redirection, NULL, dl->flags);
}
else
{

View File

@ -2885,7 +2885,11 @@ static void CLDP_ParseDownloadData(void)
if (dl->file)
{
if (start > dl->completedbytes)
; //this protocol cannot deal with gaps. we might as well wait until its repeated later.
{ //this protocol cannot deal with gaps. we might as well wait until its repeated later.
//don't ack values ahead of what we completed, we won't get good results if we do that. servers are dumb.
start = dl->completedbytes;
size = 0;
}
else if (start+size < dl->completedbytes)
; //already completed this data
else
@ -2897,7 +2901,7 @@ static void CLDP_ParseDownloadData(void)
dl->ratebytes += size-offset; //for download rate calcs
}
dl->percent = (start+size) / (float)dl->size * 100;
dl->percent = (dl->completedbytes) / (float)dl->size * 100;
}
//we need to ack in order.
@ -2992,15 +2996,16 @@ static void CLDP_ParseDownloadBegin(char *s)
chunk = sizeof(buffer);
VFS_WRITE(dl->file, buffer, chunk);
}
VFS_SEEK(dl->file, 0);
}
static void CLDP_ParseDownloadFinished(char *s)
{
qdownload_t *dl = cls.download;
unsigned short runningcrc = 0;
unsigned int runningcrc = 0;
const hashfunc_t *hfunc = &hash_crc16;
char buffer[8192];
int size, pos, chunk;
qofs_t size, pos, chunk;
if (!dl || !dl->file)
return;
@ -3011,16 +3016,15 @@ static void CLDP_ParseDownloadFinished(char *s)
dl->file = FS_OpenVFS (dl->tempname+dl->prefixbytes, "rb", dl->fsroot);
if (dl->file)
{
char *hashctx = alloca(hfunc->digestsize);
void *hashctx = alloca(hfunc->contextsize);
size = dl->size;
hfunc->init(&hashctx);
for (pos = 0, chunk = 1; chunk; pos += chunk)
hfunc->init(hashctx);
for (pos = 0; pos < size; pos += chunk)
{
chunk = size - pos;
if (chunk > sizeof(buffer))
chunk = sizeof(buffer);
VFS_READ(dl->file, buffer, chunk);
hfunc->process(&hashctx, buffer, chunk);
chunk = min(sizeof(buffer), size - pos);
if (chunk != VFS_READ(dl->file, buffer, chunk))
break;
hfunc->process(hashctx, buffer, chunk);
}
VFS_CLOSE (dl->file);
dl->file = NULL;
@ -3034,7 +3038,6 @@ static void CLDP_ParseDownloadFinished(char *s)
return;
}
Cmd_TokenizeString(s, false, false);
if (size != atoi(Cmd_Argv(1)))
{
Con_Printf("Download failed: wrong file size\n");
@ -6916,7 +6919,7 @@ static void CL_ParsePrecache(void)
{
model_t *model;
CL_CheckOrEnqueDownloadFile(s, s, DLLF_ALLOWWEB);
model = Mod_ForName(Mod_FixName(s, cl.model_name[1]), (i == 1)?MLV_ERROR:MLV_WARN);
model = Mod_ForName(Mod_FixName(s, cl.model_name[1]), (i == 1&&!cl.sendprespawn)?MLV_ERROR:MLV_WARN);
// if (!model)
// Con_Printf("svc_precache: Mod_ForName(\"%s\") failed\n", s);
cl.model_precache[i] = model;

View File

@ -901,6 +901,13 @@ static cvar_t *Cvar_SetCore (cvar_t *var, const char *value, qboolean force)
latch = "variable %s is a cheat variable - latched\n";
#endif
if ((var->flags & CVAR_WARNONCHANGE) && cl_warncmd.ival)
{
if (var->defaultstr && strcmp(var->defaultstr, value)) //warn if its different from the default
if (!var->enginevalue || strcmp(var->enginevalue, value)) //unless it matches the ENGINE's default, in which case its probably still okay.
Con_Printf (CON_WARNING"WARNING: %s has been set to \"%s\". This is NOT recommended!\n", var->name, value);
}
if (latch)
{
if (cl_warncmd.value)

View File

@ -140,6 +140,7 @@ typedef struct cvar_group_s
#define CVAR_WATCHED (1<<22) //report any attempts to change this cvar.
#define CVAR_VIDEOLATCH (1<<23)
#define CVAR_WARNONCHANGE (1<<24) //print a warning when changed to a value other than its default.
#define CVAR_LASTFLAG CVAR_VIDEOLATCH

View File

@ -979,9 +979,17 @@ COM_Path_f
*/
static void COM_PathLine(searchpath_t *s)
{
Con_Printf(U8("%s")" %s%s%s%s%s%s%s\n", s->logicalpath,
char *col = "";
if (s->flags&SPF_ISDIR)
col = S_COLOR_GREEN;
else if (s->flags&SPF_COPYPROTECTED)
col = S_COLOR_BLUE;
else
col = S_COLOR_CYAN;
Con_Printf(" %s" U8("%s")" %s%s%s%s%s%s%s%s\n", col, s->logicalpath,
(s->flags & SPF_REFERENCED)?"^[(ref)\\tip\\Referenced\\desc\\Package will auto-download to clients^]":"",
(s->flags & SPF_TEMPORARY)?"^[(temp)\\tip\\Temporary\\desc\\Flushed on map change^]":"",
(s->flags & SPF_SERVER)?"^[(srv)\\tip\\Server-Specified\\desc\\Loaded to match the server, closed on disconnect^]":"",
(s->flags & SPF_COPYPROTECTED)?"^[(c)\\tip\\Copyrighted\\desc\\Copy-Protected and is not downloadable^]":"",
(s->flags & SPF_EXPLICIT)?"^[(e)\\tip\\Explicit\\desc\\Loaded explicitly by the gamedir^]":"",
(s->flags & SPF_UNTRUSTED)?"^[(u)\\tip\\Untrusted\\desc\\Configs and scripts will not be given access to passwords^]":"",
@ -1011,8 +1019,6 @@ static void COM_Path_f (void)
return;
}
Con_TPrintf ("Current search path:\n");
if (com_purepaths || fs_puremode)
{
Con_Printf ("Pure paths:\n");
@ -1020,21 +1026,53 @@ static void COM_Path_f (void)
{
COM_PathLine(s);
}
Con_Printf ("----------\n");
if (fs_puremode == 2)
Con_Printf ("Inactive paths:\n");
else
Con_Printf ("Impure paths:\n");
}
else
Con_TPrintf ("Current search path:\n");
for (s=com_searchpaths ; s ; s=s->next)
{
if (s == com_base_searchpaths)
Con_Printf ("----------\n");
Con_Printf (" ----------\n");
COM_PathLine(s);
}
if (fs_purenames && fs_purecrcs)
{
char crctok[64];
char nametok[MAX_QPATH];
int crc;
char *pc = fs_purecrcs;
char *pn = fs_purenames;
for (;;)
{
pc = COM_ParseOut(pc, crctok, sizeof(crctok));
pn = COM_ParseOut(pn, nametok, sizeof(nametok));
if (!pc || !pn)
break;
crc = strtoul(crctok, NULL, 0);
for (s=com_searchpaths ; s ; s=s->next)
{
if (s && s->crc_check == crc)
break;
}
if (!s)
{
COM_DefaultExtension(nametok, ".pk3", sizeof(nametok));
Con_Printf(CON_WARNING "MISSING: " U8("%s")" (%x)\n", nametok, crc);
}
}
}
}
@ -3549,9 +3587,9 @@ static searchpath_t *FS_AddPathHandle(searchpath_t **oldpaths, const char *purep
//temp packages also do not nest
if (!(flags & SPF_TEMPORARY))
FS_AddDataFiles(oldpaths, purepath, logicalpath, search, flags&(SPF_COPYPROTECTED|SPF_UNTRUSTED|SPF_TEMPORARY|SPF_PRIVATE|SPF_QSHACK), loadstuff);
FS_AddDataFiles(oldpaths, purepath, logicalpath, search, flags&(SPF_COPYPROTECTED|SPF_UNTRUSTED|SPF_TEMPORARY|SPF_SERVER|SPF_PRIVATE|SPF_QSHACK), loadstuff);
if (flags & SPF_TEMPORARY)
if (flags & (SPF_TEMPORARY|SPF_SERVER))
{
//add at end. pureness will reorder if needed.
link = &com_searchpaths;
@ -3658,7 +3696,7 @@ static searchpath_t *FS_AddSingleGameDirectory (searchpath_t **oldpaths, const c
if (!handle)
handle = VFSOS_OpenPath(NULL, NULL, dir, dir, "");
return FS_AddPathHandle(oldpaths, puredir, dir, handle, "", flags|keptflags, loadstuff);
return FS_AddPathHandle(oldpaths, puredir, dir, handle, "", flags|keptflags|SPF_ISDIR, loadstuff);
}
static void FS_AddGameDirectory (searchpath_t **oldpaths, const char *puredir, unsigned int loadstuff, unsigned int flags)
{
@ -3922,7 +3960,7 @@ void COM_Gamedir (const char *dir, const struct gamepacks *packagespaths)
/*quake requires a few settings for compatibility*/
#define QRPCOMPAT "set cl_cursor_scale 0.2\nset cl_cursor_bias_x 7.5\nset cl_cursor_bias_y 0.8\n"
#define QUAKESPASMSUCKS "set mod_h2holey_bugged 1\n"
#define QUAKEOVERRIDES "set v_gammainverted 1\nset con_stayhidden 0\nset allow_download_pakcontents 1\nset allow_download_refpackages 0\nset r_meshpitch -1\nr_sprite_backfacing 1\nset sv_bigcoords \"\"\nmap_autoopenportals 1\n" "sv_port "STRINGIFY(PORT_QWSERVER)" "STRINGIFY(PORT_NQSERVER)"\n" ZFIXHACK EZQUAKECOMPETITIVE QUAKESPASMSUCKS
#define QUAKEOVERRIDES "set v_gammainverted 1\nset con_stayhidden 0\nset allow_download_pakcontents 2\nset allow_download_refpackages 0\nset r_meshpitch -1\nr_sprite_backfacing 1\nset sv_bigcoords \"\"\nmap_autoopenportals 1\n" "sv_port "STRINGIFY(PORT_QWSERVER)" "STRINGIFY(PORT_NQSERVER)"\n" ZFIXHACK EZQUAKECOMPETITIVE QUAKESPASMSUCKS
#define QCFG "//schemes quake qw\n" QUAKEOVERRIDES "set com_parseutf8 0\n" QRPCOMPAT
#define KEXCFG "//schemes quake_r2\n" QUAKEOVERRIDES "set com_parseutf8 1\nset campaign 0\nset net_enable_dtls 1\nset sv_mintic 0.016666667\nset sv_maxtic $sv_mintic\nset cl_netfps 60\n"
/*NetQuake reconfiguration, to make certain people feel more at home...*/
@ -4804,7 +4842,7 @@ static void FS_ReloadPackFilesFlags(unsigned int reloadflags)
handle = FS_GetOldPath(&oldpaths, local, &keptflags);
if (handle)
{
sp = FS_AddPathHandle(&oldpaths, pname, local, handle, "", SPF_COPYPROTECTED|SPF_UNTRUSTED|SPF_TEMPORARY|keptflags, (unsigned int)-1);
sp = FS_AddPathHandle(&oldpaths, pname, local, handle, "", SPF_COPYPROTECTED|SPF_UNTRUSTED|SPF_SERVER|keptflags, (unsigned int)-1);
if (!sp)
continue; //some kind of error...
if (sp->handle->GeneratePureCRC)
@ -4842,7 +4880,7 @@ static void FS_ReloadPackFilesFlags(unsigned int reloadflags)
handle = searchpathformats[i].OpenNew (vfs, NULL, local, local, "");
if (!handle)
break;
sp = FS_AddPathHandle(&oldpaths, pname, local, handle, "", SPF_COPYPROTECTED|SPF_UNTRUSTED|SPF_TEMPORARY, (unsigned int)-1);
sp = FS_AddPathHandle(&oldpaths, pname, local, handle, "", SPF_COPYPROTECTED|SPF_UNTRUSTED|SPF_SERVER, (unsigned int)-1);
if (sp->handle->GeneratePureCRC)
{
sp->crc_check = sp->handle->GeneratePureCRC(sp->handle, fs_pureseed, 0);

View File

@ -105,15 +105,17 @@ struct modlist_s
};
struct modlist_s *Mods_GetMod(size_t diridx);
#define SPF_REFERENCED 1 //something has been loaded from this path. should filter out client references...
#define SPF_COPYPROTECTED 2 //downloads are not allowed fom here.
#define SPF_TEMPORARY 4 //a map-specific path, purged at map change.
#define SPF_EXPLICIT 8 //a root gamedir (bumps depth on gamedir depth checks).
#define SPF_UNTRUSTED 16 //has been downloaded from somewhere. configs inside it should never be execed with local access rights.
#define SPF_PRIVATE 32 //private to the client. ie: the fte dir. name is not networked.
#define SPF_WRITABLE 64 //safe to write here. lots of weird rules etc.
#define SPF_BASEPATH 128 //part of the basegames, and not the mod gamedir(s).
#define SPF_QSHACK 256 //part of the basegames, and not the mod gamedir(s).
#define SPF_REFERENCED 1 //something has been loaded from this path. should filter out client references...
#define SPF_COPYPROTECTED 2 //downloads are not allowed fom here.
#define SPF_TEMPORARY 4 //a map-specific path, purged at map change.
#define SPF_EXPLICIT 8 //a root gamedir (bumps depth on gamedir depth checks).
#define SPF_UNTRUSTED 16 //has been downloaded from somewhere. configs inside it should never be execed with local access rights.
#define SPF_PRIVATE 32 //private to the client. ie: the fte dir. name is not networked.
#define SPF_WRITABLE 64 //safe to write here. lots of weird rules etc.
#define SPF_BASEPATH 128 //part of the basegames, and not the mod gamedir(s).
#define SPF_QSHACK 256 //a bit of a hack, allows scanning for $rootdir/quakespasm.pak
#define SPF_SERVER 512 //a package that was loaded to match the server's packages
#define SPF_ISDIR 1024 //is an actual directory (not itself a package).
qboolean FS_LoadPackageFromFile(vfsfile_t *vfs, char *pname, char *localname, int *crc, unsigned int flags);
#ifdef AVAIL_XZDEC

View File

@ -2244,7 +2244,7 @@ static void SV_Status_f (void)
#define C_RATE COLUMN(4, "rate", Con_Printf("%4i ", cl->frameunion.frames?(int)(1/cl->netchan.frame_rate):0))
#define C_PING COLUMN(5, "ping", Con_Printf("%4i ", (int)SV_CalcPing (cl, false)))
#define C_DROP COLUMN(6, "drop", Con_Printf("%4.1f ", 100.0*cl->netchan.drop_count / cl->netchan.incoming_sequence))
#define C_DLP COLUMN(7, "dl ", if (!cl->download)Con_Printf(" ");else Con_Printf("%3g ", (cl->downloadcount*100.0)/cl->downloadsize))
#define C_DLP COLUMN(7, "dl ", if (!cl->download)Con_Printf(" ");else Con_Printf("%3.0f ", (cl->downloadcount*100.0)/cl->downloadsize))
#define C_DLS COLUMN(8, "dls", if (!cl->download)Con_Printf(" ");else Con_Printf("%3u ", (unsigned int)(cl->downloadsize/1024)))
#define C_PROT COLUMN(9, "prot ", Con_Printf("%-6.6s", p))
#define C_ADDRESS2 COLUMN(10, "address ", Con_Printf("%s", s))
@ -3336,9 +3336,6 @@ void SV_InitOperatorCommands (void)
Cmd_AddCommand("sv_meminfo", SV_MemInfo_f);
// Cmd_AddCommand ("reallyevilhack", SV_ReallyEvilHack_f);
if (isDedicated)
cl_warncmd.value = 1;
}
#endif

View File

@ -90,17 +90,17 @@ cvar_t allow_download_sounds = CVARD("allow_download_sounds", "1", "0 blocks do
cvar_t allow_download_particles = CVARD("allow_download_particles", "1", "0 blocks downloading of any file in the particles/ directory");
cvar_t allow_download_demos = CVARD("allow_download_demos", "1", "0 blocks downloading of any file in the demos/ directory");
cvar_t allow_download_maps = CVARD("allow_download_maps", "1", "0 blocks downloading of any file in the maps/ directory");
cvar_t allow_download_logs = CVARD("allow_download_logs", "0", "1 permits downloading files with the extension .log\n"CON_ERROR"THIS IS DANGEROUS AS IT POTENTIALLY ALLOWS PEOPLE TO SEE PASSWORDS OR OTHER PRIVATE INFORMATION.\nNote that it can be switch on/off via rcon.");
cvar_t allow_download_anymap = CVARD("allow_download_pakmaps", "0", "If 1, permits downloading of maps from within packages. This is normally disabled in order to prevent copyrighted content from being downloaded.");
cvar_t allow_download_pakcontents = CVARD("allow_download_pakcontents", "0", "controls whether clients connected to this server are allowed to download files from within packages.\nDoes NOT implicitly allow downloading bsps, set allow_download_pakmaps to enable that.\nWhile treating each file contained within packages is often undesirable, this is often needed for compatibility with legacy clients (despite it potentially allowing copyright violations).");
cvar_t allow_download_root = CVARD("allow_download_root", "0", "If set, enables downloading from the root of the gamedir (not the basedir). This setting has a lower priority than extension-based checks.");
cvar_t allow_download_logs = CVARFD("allow_download_logs", "0", CVAR_WARNONCHANGE, "1 permits downloading files with the extension .log\n"CON_ERROR"THIS IS DANGEROUS AS IT POTENTIALLY ALLOWS PEOPLE TO SEE PASSWORDS OR OTHER PRIVATE INFORMATION.\nNote that it can be switch on/off via rcon.");
cvar_t allow_download_anymap = CVARFD("allow_download_pakmaps", "0", CVAR_WARNONCHANGE, "0: clients may not download map files within the server's packages.\n1: clients may download such files so long as the package is not deemed copyrighted, for compat with old clients that do not support package downloads.\n2: client may download such files regardless of copyright state (WARNING! Should never be used!).");
cvar_t allow_download_pakcontents = CVARFD("allow_download_pakcontents", "0", CVAR_WARNONCHANGE, "0: clients may not download non-map files within the server's packages.\n1: clients may download such files so long as the package is not deemed copyrighted, for compat with old clients that do not support package downloads.\n2: client may download such files regardless of copyright state (WARNING! ONLY for consistency with vanilla QuakeWorld!).");
cvar_t allow_download_root = CVARFD("allow_download_root", "0", CVAR_WARNONCHANGE, "If set, enables downloading from the root of the gamedir (not the basedir). This setting has a lower priority than extension-based checks.");
cvar_t allow_download_textures = CVARD("allow_download_textures", "1", "0 blocks downloading of any file in the textures/ directory");
cvar_t allow_download_packages = CVARD("allow_download_packages", "1", "if 1, permits downloading files (from root directory or elsewhere) with known package extensions (eg: pak+pk3). Packages with a name starting 'pak' are covered by allow_download_copyrighted as well.");
cvar_t allow_download_refpackages = CVARD("allow_download_refpackages", "1", "If set to 1, packages that contain files needed during spawn functions will be become 'referenced' and automatically downloaded to clients.\nThis cvar should probably not be set if you have large packages that provide replacement pickup models on public servers.\nThe path command will show a '(ref)' tag next to packages which clients will automatically attempt to download.");
cvar_t allow_download_wads = CVARD("allow_download_wads", "1", "0 blocks downloading of any file in the wads/ directory, or is in the root directory with the extension .wad");
cvar_t allow_download_configs = CVARD("allow_download_configs", "0", "1 allows downloading of config files, either with the extension .cfg or in the subdir configs/.\n"CON_ERROR"THIS IS DANGEROUS AS IT CAN ALLOW PEOPLE TO READ YOUR RCON PASSWORD ETC.");
cvar_t allow_download_configs = CVARFD("allow_download_configs", "0", CVAR_WARNONCHANGE, "1 allows downloading of config files, either with the extension .cfg or in the subdir configs/.\n"CON_ERROR"THIS IS DANGEROUS AS IT CAN ALLOW PEOPLE TO READ YOUR RCON PASSWORD ETC.");
cvar_t allow_download_locs = CVARD("allow_download_locs", "1", "0 blocks downloading of any file in the locs/ directory");
cvar_t allow_download_copyrighted = CVARD("allow_download_copyrighted", "0", "0 blocks download of packages that are considered copyrighted. Specifically, this means packages with a leading 'pak' prefix on the filename.\nIf you take your copyrights seriously, you should also set allow_download_pakmaps 0 and allow_download_pakcontents 0.");
cvar_t allow_download_copyrighted = CVARFD("allow_download_copyrighted", "0", CVAR_WARNONCHANGE, "0 blocks download of packages that are considered copyrighted. Specifically, this means packages with a leading 'pak' prefix on the filename.\nIf you take your copyrights seriously, you should also set allow_download_pakmaps 0 and allow_download_pakcontents 0.");
cvar_t allow_download_other = CVARD("allow_download_other", "0", "0 blocks downloading of any file that was not covered by any of the directory download blocks.");
extern cvar_t sv_allow_splitscreen;
@ -6210,7 +6210,9 @@ void SV_ExecInitialConfigs(char *defaultexec)
Cbuf_AddText(va("sv_gamedir \"%s\"\n", FS_GetGamedir(true)), RESTRICT_LOCAL);
Cbuf_AddText("cl_warncmd 0\n", RESTRICT_LOCAL);
Cbuf_AddText(defaultexec, RESTRICT_LOCAL);
Cbuf_AddText("cl_warncmd 1\n", RESTRICT_LOCAL);
Cbuf_AddText("\n", RESTRICT_LOCAL);
//make sure +set args override fmf/engine defaults (redundant when there's no map/etc command in configs)
COM_ParsePlusSets(true);

View File

@ -737,9 +737,6 @@ void SVNQ_New_f (void)
if (!*csprogsname && *InfoBuf_ValueForKey(&svs.info, "*csprogs"))
csprogsname = "csprogs.dat";
MSG_WriteByte (&host_client->netchan.message, svc_stufftext);
MSG_WriteString (&host_client->netchan.message, "cl_serverextension_download 1\n");
f = *csprogsname?COM_LoadTempFile(csprogsname, 0, &sz):NULL;
if (f)
{
@ -759,12 +756,6 @@ void SVNQ_New_f (void)
// MSG_WriteString (&host_client->netchan.message, "csqc_progcrc \"\"\n");
}
}
else if (allow_download.value && (protext1||protext2))
{ //technically this is a DP extension, but is separate from actual protocols and shouldn't harm anything.
//it is annoying to have prints about unknown commands however, hence the above pext checks (which are unfortunate).
MSG_WriteByte (&host_client->netchan.message, svc_stufftext);
MSG_WriteString (&host_client->netchan.message, "cl_serverextension_download 1\n");
}
if (sv.state == ss_cinematic)
{
@ -825,6 +816,13 @@ void SVNQ_New_f (void)
MSG_WriteByte (&host_client->netchan.message, 0);
}
if (allow_download.value && (protext1||protext2||ISDPCLIENT(host_client)))
{ //technically this is a DP extension, but is separate from actual protocols and shouldn't harm anything.
//it is annoying to have prints about unknown commands however, hence the above pext checks (which are unfortunate).
MSG_WriteByte (&host_client->netchan.message, svc_stufftext);
MSG_WriteString (&host_client->netchan.message, "cl_serverextension_download 1\n");
}
if (host_client->qex)
{ //FIXME: these may change mid-map.
extern cvar_t sv_friction, sv_stopspeed, sv_maxvelocity, sv_accelerate, sv_gravity;
@ -2515,17 +2513,7 @@ void SV_DarkPlacesDownloadAck(client_t *cl)
if (!cl->download)
return;
if (start != cl->downloadacked)
{
//packetloss
VFS_SEEK(cl->download, cl->downloadacked);
}
else if (size != 0)
{
cl->downloadacked += size; //successful packet
cl->downloadcount = cl->downloadacked;
}
else
if (start == cl->downloadsize && !size)
{
char *s;
const hashfunc_t *hfunc = &hash_crc16;
@ -2539,7 +2527,8 @@ void SV_DarkPlacesDownloadAck(client_t *cl)
csize = sizeof(chunk);
if (pos + csize > host_client->downloadsize)
csize = host_client->downloadsize - pos;
VFS_READ(host_client->download, chunk, csize);
if (csize != VFS_READ(host_client->download, chunk, csize))
break;
hfunc->process(hctx, chunk, csize);
pos += csize;
}
@ -2553,6 +2542,14 @@ void SV_DarkPlacesDownloadAck(client_t *cl)
host_client->download = NULL;
host_client->downloadsize = 0;
}
else if (start != cl->downloadacked || !size)
{
//packetloss
VFS_SEEK(cl->download, cl->downloadacked);
cl->downloadcount = cl->downloadacked;
}
else
cl->downloadacked = start+size; //successful packet
}
#endif
@ -3167,7 +3164,7 @@ qboolean SV_FindRemotePackage(const char *package, char *url, size_t urlsize)
//filter out the gamedir, so different gamedirs can have different sets of urls.
//(useful for eg pakN.pak, if it were not blocked elsewhere)
char *sep = strchr(package, '/');
if (!sep || sep-package>=strlen(line))
if (!sep || sep-package>=sizeof(line))
return false;
memcpy(line, package, sep-package+1);
line[sep-package+1] = 0;
@ -3340,8 +3337,8 @@ qboolean SV_AllowDownload (const char *name)
static int SV_LocateDownload(const char *name, flocation_t *loc, char **replacementname, qboolean redirectpaks)
{
extern cvar_t allow_download_anymap, allow_download_pakcontents;
qboolean protectedpak;
extern cvar_t allow_download_anymap, allow_download_pakcontents, allow_download_copyrighted, allow_download_packages;
qboolean copyprotected;
qboolean found;
static char tmpname[MAX_QPATH];
@ -3466,60 +3463,48 @@ static int SV_LocateDownload(const char *name, flocation_t *loc, char **replacem
if (found)
{
protectedpak = loc->search && (loc->search->flags & SPF_COPYPROTECTED);
// special check for maps, if it came from a pak file, don't allow download
if (protectedpak)
{
if (!allow_download_anymap.value && !Q_strncasecmp(name, "maps/", 5))
{
Sys_Printf ("%s denied download of %s - it is in a pak\n", host_client->name, name);
return DLERR_PERMISSIONS;
}
}
const char *pakname = FS_GetPackageDownloadFilename(loc);
qboolean ispak = loc->search && !(loc->search->flags & SPF_ISDIR);
copyprotected = loc->search && (loc->search->flags & SPF_COPYPROTECTED);
if (replacementname)
{
#if 1
const char *pakname = FS_GetPackageDownloadFilename(loc);
if (pakname && strchr(pakname, '/'))
{ //if we're able to redirect it then do so.
if (ispak && pakname && strchr(pakname, '/'))
{
extern cvar_t allow_download_packages,allow_download_copyrighted; //non authoritive, but should normally match.
if (allow_download_packages.ival && !(loc->search && (loc->search->flags&SPF_BASEPATH)))
if (allow_download_packages.ival && !(loc->search && (loc->search->flags&SPF_TEMPORARY)))
{
if (allow_download_copyrighted.ival || !protectedpak)
{
if (allow_download_copyrighted.ival || !copyprotected)
{ //this path is non authoritive, but we shouldn't be pushing people to download files they're not going to be allowed to download.
Q_snprintfz(tmpname, sizeof(tmpname), "package/%s", pakname);
*replacementname = tmpname;
return DLERR_REDIRECTPACK; //redirect
}
}
}
#else
char *pakname = FS_WhichPackForLocation(loc, false);
if (pakname && SV_AllowDownload(pakname))
{
//return loc of the pak instead.
if (FS_FLocateFile(name, FSLF_IFFOUND, loc))
{
//its inside a pak file, return the name of this file instead
*replacementname = pakname;
return DLERR_REDIRECTPACK; //redirect
}
else
Con_Printf("Failed to read %s\n", pakname);
}
#endif
}
if (protectedpak)
{ //if its in a pak file, don't allow downloads if we don't allow the contents of paks to be sent.
if (!allow_download_pakcontents.value)
if (ispak)
{
int pakcontents = (!Q_strncasecmp(name, "maps/", 5)?allow_download_anymap.ival:allow_download_pakcontents.ival);
if (pakcontents == 2)
{ //qw-like allow-and-ignore-copyrights, skip the following cases...
}
else if (copyprotected)
{
Sys_Printf ("%s denied download of %s - it is in a copyrighted pak\n", host_client->name, name);
return DLERR_PERMISSIONS;
}
else if (!pakcontents)
{ //block it if its entirely disabllowed
Sys_Printf ("%s denied download of %s - it is in a pak\n", host_client->name, name);
return DLERR_PERMISSIONS;
}
}
else if (copyprotected)
{ //not really sure how we can get here, but oh well.
Sys_Printf ("%s denied download of %s - it is copyrighted\n", host_client->name, name);
return DLERR_PERMISSIONS;
}
if (replacementname && *replacementname)
return DLERR_REDIRECTPACK;