From c1a80e5ba895d38ccee1037e51e6099a473ca2b1 Mon Sep 17 00:00:00 2001 From: Spoike Date: Tue, 12 Mar 2013 23:24:15 +0000 Subject: [PATCH] ------------------------------------------------------------------------ r4256 | acceptthis | 2013-03-12 21:07:07 +0000 (Tue, 12 Mar 2013) | 5 lines Don't mess up/crash when the snap command is used (in multiple ways). Misc NQ+csqc compat tweaks/hacks/fixes. Added pointsound. Don't rely upon fragmentation support with downloads. its a bad idea. Fixed up the text editor to be able to debug properly again. ------------------------------------------------------------------------ git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4252 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/client/cl_ents.c | 6 +- engine/client/cl_input.c | 2 + engine/client/cl_main.c | 52 ++++++---- engine/client/cl_parse.c | 12 +-- engine/client/cl_screen.c | 13 ++- engine/client/pr_csqc.c | 93 +++++++++++++---- engine/client/pr_menu.c | 2 + engine/client/sys_win.c | 159 ++++++++++++++++++++---------- engine/client/textedit.c | 26 +++-- engine/common/cmd.c | 2 +- engine/common/net_wins.c | 11 ++- engine/common/pr_common.h | 2 +- engine/common/world.h | 2 +- engine/dotnet2005/ftequake.sln | 4 - engine/dotnet2005/ftequake.vcproj | 10 +- engine/gl/gl_backend.c | 3 + engine/gl/gl_heightmap.c | 5 +- engine/gl/gl_model.c | 2 +- engine/gl/gl_rmisc.c | 1 + engine/gl/gl_shader.c | 2 +- engine/qclib/initlib.c | 2 +- engine/server/pr_cmds.c | 36 +++++-- engine/server/pr_q1qvm.c | 10 +- engine/server/server.h | 2 +- engine/server/sv_ents.c | 5 +- engine/server/sv_main.c | 29 +++--- engine/server/sv_phys.c | 6 +- engine/server/sv_send.c | 22 +++-- engine/server/sv_sys_win.c | 7 ++ engine/server/sv_user.c | 26 +++-- engine/server/world.c | 9 +- 31 files changed, 383 insertions(+), 180 deletions(-) diff --git a/engine/client/cl_ents.c b/engine/client/cl_ents.c index 73472493c..631ed69df 100644 --- a/engine/client/cl_ents.c +++ b/engine/client/cl_ents.c @@ -3413,11 +3413,11 @@ void CL_LinkPacketEntities (void) } else if (modelflags & MFH2_FIREBALL) { - rad = 120 - (rand() % 20); + rad = 120 - (r_lightflicker.value?(rand() % 20):10); } else if (modelflags & MFH2_ACIDBALL) { - rad = 120 - (rand() % 20); + rad = 120 - (r_lightflicker.value?(rand() % 20):10); dclr[0] = 0.1; dclr[1] = 0.2; } @@ -3427,7 +3427,7 @@ void CL_LinkPacketEntities (void) dclr[0] = -dclr[0]; dclr[0] = -dclr[1]; dclr[0] = -dclr[2]; - rad = 120 - (rand() % 20); + rad = 120 - (r_lightflicker.value?(rand() % 20):10); } if (rad) diff --git a/engine/client/cl_input.c b/engine/client/cl_input.c index a1eb5606d..0a6df7462 100644 --- a/engine/client/cl_input.c +++ b/engine/client/cl_input.c @@ -915,6 +915,8 @@ void CL_UpdatePrydonCursor(usercmd_t *from, float cursor_screen[2], vec3_t curso TraceLineN(cursor_start, cursor_end, cursor_impact, cursor_impact_normal); + *entnum = 0; + // P_RunParticleEffect(cursor_impact, vec3_origin, 15, 16); } diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index e72560168..e6828a1e2 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -140,7 +140,7 @@ cvar_t cl_gunangley = SCVAR("cl_gunangley", "0"); cvar_t cl_gunanglez = SCVAR("cl_gunanglez", "0"); cvar_t cl_download_csprogs = CVARFD("cl_download_csprogs", "1", CVAR_NOTFROMSERVER, "Download updated client gamecode if available."); -cvar_t cl_download_redirection = CVARFD("cl_download_redirection", "2", CVAR_NOTFROMSERVER, "Follow download redirection to download packages instead of individual files. 2 allows redirection only to named packages files."); +cvar_t cl_download_redirection = CVARFD("cl_download_redirection", "2", CVAR_NOTFROMSERVER, "Follow download redirection to download packages instead of individual files. 2 allows redirection only to named packages files. Also allows the server to send nearly arbitary download commands."); cvar_t cl_download_mapsrc = CVARD("cl_download_mapsrc", "", "Specifies an http location prefix for map downloads. EG: \"http://bigfoot.morphos-team.net/misc/quakemaps/\""); cvar_t cl_download_packages = CVARFD("cl_download_packages", "1", CVAR_NOTFROMSERVER, "0=Do not download packages simply because the server is using them. 1=Download and load packages as needed (does not affect games which do not use this package). 2=Do download and install permanently (use with caution!)"); cvar_t requiredownloads = CVARFD("requiredownloads","1", CVAR_ARCHIVE, "0=join the game before downloads have even finished (might be laggy). 1=wait for all downloads to complete before joining."); @@ -2841,6 +2841,27 @@ void CL_ReadPackets (void) //============================================================================= +qboolean CL_AllowArbitaryDownload(char *localfile) +{ + qboolean allow; + //never allow certain (native code) arbitary downloads. + if (!strnicmp(localfile, "game", 4) || !stricmp(localfile, "progs.dat") || !stricmp(localfile, "menu.dat") || !stricmp(localfile, "csprogs.dat") || !stricmp(localfile, "qwprogs.dat") || strstr(localfile, "..") || strstr(localfile, ":") || strstr(localfile, "//") || strstr(localfile, ".qvm") || strstr(localfile, ".dll") || strstr(localfile, ".so")) + { //yes, I know the user can use a different progs from the one that is specified. If you leave it blank there will be no problem. (server isn't allowed to stuff progs cvar) + Con_Printf("Ignoring arbitary download to \"%s\" due to possible security risk\n", localfile); + return false; + } + allow = cl_download_redirection.ival; + if (allow == 2) + { + char *ext = COM_FileExtension(localfile); + if (!strcmp(ext, "pak") || !strcmp(ext, "pk3") || !strcmp(ext, "pk4")) + allow = true; + else + allow = false; + } + return !!allow; +} + /* ===================== CL_Download_f @@ -2888,11 +2909,8 @@ void CL_Download_f (void) if (Cmd_IsInsecure()) //mark server specified downloads. { - if (!strnicmp(url, "game", 4) || !stricmp(url, "progs.dat") || !stricmp(url, "menu.dat") || !stricmp(url, "csprogs.dat") || !stricmp(url, "qwprogs.dat") || strstr(url, "..") || strstr(url, ".qvm") || strstr(url, ".dll") || strstr(url, ".so")) - { //yes, I know the user can use a different progs from the one that is specified. If you leave it blank there will be no problem. (server isn't allowed to stuff progs cvar) - Con_Printf("Ignoring stuffed download of \"%s\" due to possible security risk\n", url); + if (!CL_AllowArbitaryDownload(url)) return; - } CL_CheckOrEnqueDownloadFile(url, url, DLLF_REQUIRED|DLLF_VERBOSE); return; @@ -2933,23 +2951,15 @@ void CL_DownloadSize_f(void) int allow = cl_download_redirection.ival; redirection = Cmd_Argv(3); - dl = CL_DownloadFailed(rname, false); + if (!CL_AllowArbitaryDownload(redirection)) + { + Con_Printf("Ignoring redirection of %s to %s\n", rname, redirection); + return; + } - if (allow == 2) - { - char *ext = COM_FileExtension(redirection); - if (!strcmp(ext, "pak") || !strcmp(ext, "pk3") || !strcmp(ext, "pk4")) - allow = true; - else - allow = false; - } - if (allow) - { - Con_DPrintf("Download of \"%s\" redirected to \"%s\".\n", rname, redirection); - CL_CheckOrEnqueDownloadFile(redirection, NULL, dl->flags); - } - else - Con_Printf("Download of \"%s\" redirected to \"%s\". Prevented by cl_download_redirection.\n", rname, redirection); + dl = CL_DownloadFailed(rname, false); + Con_DPrintf("Download of \"%s\" redirected to \"%s\".\n", rname, redirection); + CL_CheckOrEnqueDownloadFile(redirection, NULL, dl->flags); } else { diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index 6ea2c9cf2..24c607cc3 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -1018,7 +1018,7 @@ int CL_LoadModels(int stage, qboolean dontactuallyload) pmove.numphysent = 0; -#ifdef PEXT_CSQC +/*#ifdef PEXT_CSQC if (atstage()) { extern cvar_t cl_nocsqc; @@ -1045,7 +1045,7 @@ int CL_LoadModels(int stage, qboolean dontactuallyload) } endstage(); } -#endif +#endif*/ #ifdef HLCLIENT if (atstage()) @@ -2867,7 +2867,7 @@ void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caution. return; } strcpy (cl.model_name[nummodels], str); - if (*str != '*') //not inline models! + if (*str != '*' && strcmp(str, "null")) //not inline models! CL_CheckOrEnqueDownloadFile(str, NULL, ((nummodels==1)?DLLF_REQUIRED:0)); Mod_TouchModel (str); } @@ -2885,9 +2885,7 @@ void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caution. } strcpy (cl.sound_name[numsounds], str); - if (*str != '*') //not inline models! - CL_CheckOrEnqueDownloadFile(va("sound/%s", str), NULL, 0); - + Sound_CheckDownload(str); S_TouchSound (str); } @@ -6185,6 +6183,8 @@ void CLNQ_ParseServerMessage (void) CLDP_ParseDownloadBegin(s); else if (!strncmp(s, "\ncl_downloadfinished ", 17)) CLDP_ParseDownloadFinished(s); + else if (!strcmp(s, "\nstopdownload\n")) + CL_DownloadFailed(cls.downloadremotename, true); else if (!strncmp(s, "csqc_progname ", 14)) COM_ParseOut(s+14, cl_dp_csqc_progsname, sizeof(cl_dp_csqc_progsname)); else if (!strncmp(s, "csqc_progsize ", 14)) diff --git a/engine/client/cl_screen.c b/engine/client/cl_screen.c index 144a0fa8d..a24076010 100644 --- a/engine/client/cl_screen.c +++ b/engine/client/cl_screen.c @@ -2058,6 +2058,13 @@ void SCR_DrawCharToSnap (int num, qbyte *dest, int width) int drawline; int x; + if (!draw_chars) + { + draw_chars = W_GetLumpName("conchars"); + if (!draw_chars) + return; + } + row = num>>4; col = num&15; source = draw_chars + (row<<10) + (col<<3); @@ -2102,7 +2109,6 @@ qboolean SCR_RSShot (void) int x, y; unsigned char *src, *dest; - char pcxname[80]; unsigned char *newbuf; int w, h; int dx, dy, dex, dey, nx; @@ -2128,7 +2134,6 @@ qboolean SCR_RSShot (void) Con_Printf("Remote screen shot requested.\n"); - // // save the pcx file // @@ -2195,12 +2200,10 @@ qboolean SCR_RSShot (void) Q_strncpyz(st, name.string, sizeof(st)); SCR_DrawStringToSnap (st, newbuf, w - strlen(st)*8, h - 21, w); - WritePCXfile (pcxname, newbuf, w, h, w, host_basepal, true); + WritePCXfile ("snap.pcx", newbuf, w, h, w, host_basepal, true); BZ_Free(newbuf); - Con_Printf ("Wrote %s\n", pcxname); - return true; } diff --git a/engine/client/pr_csqc.c b/engine/client/pr_csqc.c index fc26abc80..2ae2aea0e 100644 --- a/engine/client/pr_csqc.c +++ b/engine/client/pr_csqc.c @@ -211,7 +211,7 @@ static void CSQC_ChangeLocalPlayer(int lplayernum) csqcg.view_angles[1] = cl.playerview[csqc_lplayernum].viewangles[1]; csqcg.view_angles[2] = cl.playerview[csqc_lplayernum].viewangles[2]; } - if (dpcompat_corruptglobals.ival) + if (dpcompat_corruptglobals.ival || csqc_isdarkplaces) { if (csqcg.pmove_org) { @@ -266,7 +266,10 @@ static void CSQC_FindGlobals(void) csqc_world.g.drawfontscale = (float*)PR_FindGlobal(csqcprogs, "drawfontscale", 0, NULL); if (!csqc_world.g.physics_mode) + { + csphysicsmode = csqc_isdarkplaces?1:0; csqc_world.g.physics_mode = &csphysicsmode; + } if (csqcg.maxclients) *csqcg.maxclients = cl.allocated_client_slots; @@ -936,17 +939,17 @@ static void QCBUILTIN PF_R_AddEntityMask(pubprogfuncs_t *prinst, struct globalva if (ent->isfree) continue; + if (ent->xv->predraw) + { + *csqcg.self = EDICT_TO_PROG(prinst, (void*)ent); + PR_ExecuteProgram(prinst, ent->xv->predraw); + + if (ent->isfree || (int)ent->xv->renderflags & CSQCRF_NOAUTOADD) + continue; //bummer... + } + if ((int)ent->xv->drawmask & mask) { - if (ent->xv->predraw) - { - *csqcg.self = EDICT_TO_PROG(prinst, (void*)ent); - PR_ExecuteProgram(prinst, ent->xv->predraw); - - if (ent->isfree || (int)ent->xv->renderflags & CSQCRF_NOAUTOADD) - continue; //bummer... - } - if (CopyCSQCEdictToEntity(ent, &rent)) { CLQ1_AddShadow(&rent); @@ -978,10 +981,13 @@ static int csqc_poly_flags; // #306 void(string texturename) R_BeginPolygon (EXT_CSQC_???) void QCBUILTIN PF_R_PolygonBegin(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { - csqc_poly_shader = R_RegisterSkin(PR_GetStringOfs(prinst, OFS_PARM0), NULL); + csqc_poly_flags = (prinst->callargc > 1)?G_FLOAT(OFS_PARM1):0; + if (csqc_poly_flags & 4) + csqc_poly_shader = R_RegisterPic(PR_GetStringOfs(prinst, OFS_PARM0)); + else + csqc_poly_shader = R_RegisterSkin(PR_GetStringOfs(prinst, OFS_PARM0), NULL); csqc_poly_startvert = cl_numstrisvert; csqc_poly_startidx = cl_numstrisidx; - csqc_poly_flags = (prinst->callargc > 1)?G_FLOAT(OFS_PARM1):0; } // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex (EXT_CSQC_???) @@ -1050,6 +1056,7 @@ void QCBUILTIN PF_R_PolygonEnd(pubprogfuncs_t *prinst, struct globalvars_s *pr_g if (csqc_poly_flags & 4) { mesh_t mesh; + int i; memset(&mesh, 0, sizeof(mesh)); mesh.colors4f_array = cl_strisvertc + csqc_poly_startvert; @@ -2273,6 +2280,16 @@ static void QCBUILTIN PF_cs_runplayerphysics (pubprogfuncs_t *prinst, struct glo static void QCBUILTIN PF_cs_getentitytoken (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { + if (prinst->callargc) + { + char *s = PR_GetStringOfs(prinst, OFS_PARM0); + if (*s == 0) + s = cl.worldmodel?cl.worldmodel->entities:NULL; + csqcmapentitydata = s; + G_INT(OFS_RETURN) = 0; + return; + } + if (!csqcmapentitydata) { //nothing more to parse @@ -4581,6 +4598,8 @@ static struct { {"loadfromdata", PF_loadfromdata, 529}, {"loadfromfile", PF_loadfromfile, 530}, + {"soundlength", PF_soundlength, 534}, + {"callfunction", PF_callfunction, 605}, {"writetofile", PF_writetofile, 606}, {"isfunction", PF_isfunction, 607}, @@ -4749,18 +4768,20 @@ void CSQC_Event_Think(world_t *w, wedict_t *s) PR_ExecuteProgram (w->progs, s->v->think); } -void CSQC_Event_Sound (wedict_t *wentity, int channel, char *sample, int volume, float attenuation, int pitchadj) +void CSQC_Event_Sound (float *origin, wedict_t *wentity, int channel, char *sample, int volume, float attenuation, int pitchadj) { int i; - vec3_t origin; - if (wentity->v->solid == SOLID_BSP) + vec3_t originbuf; + if (!origin) { - for (i=0 ; i<3 ; i++) - origin[i] = wentity->v->origin[i]+0.5*(wentity->v->mins[i]+wentity->v->maxs[i]); - } - else - { - VectorCopy (wentity->v->origin, origin); + if (wentity->v->solid == SOLID_BSP) + { + origin = originbuf; + for (i=0 ; i<3 ; i++) + origin[i] = wentity->v->origin[i]+0.5*(wentity->v->mins[i]+wentity->v->maxs[i]); + } + else + origin = wentity->v->origin; } S_StartSound(NUM_FOR_EDICT(csqcprogs, (edict_t*)wentity), channel, S_PrecacheSound(sample), origin, volume, attenuation, 0, pitchadj); @@ -5368,6 +5389,34 @@ void CSQC_Breakpoint_f(void) } +static void CSQC_Poke_f(void) +{ + if (!csqc_singlecheats) + Con_Printf("%s is a cheat command\n", Cmd_Argv(0)); + else if (csqcprogs) + Con_Printf("Result: %s\n", csqcprogs->EvaluateDebugString(csqcprogs, Cmd_Args())); + else + Con_Printf("csqc not running\n"); +} +void CSQC_WatchPoint_f(void) +{ + char *variable = Cmd_Argv(1); + if (!*variable) + variable = NULL; + + if (!csqc_singlecheats) + Con_Printf("%s is a cheat command\n", Cmd_Argv(0)); + else if (!csqcprogs) + { + Con_Printf("csqc not running\n"); + return; + } + if (csqcprogs->SetWatchPoint(csqcprogs, variable)) + Con_Printf("Watchpoint set\n"); + else + Con_Printf("Watchpoint cleared\n"); +} + static void CSQC_GameCommand_f(void); void CSQC_RegisterCvarsAndThings(void) { @@ -5375,6 +5424,8 @@ void CSQC_RegisterCvarsAndThings(void) Cmd_AddCommand ("extensionlist_csqc", PR_CSExtensionList_f); Cmd_AddCommandD("cl_cmd", CSQC_GameCommand_f, "Calls the csqc's GameCommand function"); Cmd_AddCommand("breakpoint_csqc", CSQC_Breakpoint_f); + Cmd_AddCommand ("watchpoint_csqc", CSQC_WatchPoint_f); + Cmd_AddCommandD("poke_csqc", CSQC_Poke_f, "Allows you to inspect/debug "); Cvar_Register(&pr_csqc_formenus, CSQCPROGSGROUP); Cvar_Register(&pr_csqc_memsize, CSQCPROGSGROUP); diff --git a/engine/client/pr_menu.c b/engine/client/pr_menu.c index d471a686c..f1673869b 100644 --- a/engine/client/pr_menu.c +++ b/engine/client/pr_menu.c @@ -1397,6 +1397,8 @@ static struct { {"buf_cvarlist", PF_buf_cvarlist, 517}, {"cvar_description", PF_cvar_description, 518}, //gap + {"soundlength", PF_soundlength, 534}, + //gap {"setkeydest", PF_cl_setkeydest, 601}, {"getkeydest", PF_cl_getkeydest, 602}, {"setmousetarget", PF_cl_setmousetarget, 603}, diff --git a/engine/client/sys_win.c b/engine/client/sys_win.c index fb1501446..5c48e0bf1 100644 --- a/engine/client/sys_win.c +++ b/engine/client/sys_win.c @@ -42,7 +42,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifdef _DEBUG #if _MSC_VER >= 1300 -//#define CATCHCRASH +#define CATCHCRASH #endif #endif @@ -750,70 +750,127 @@ qboolean Sys_Rename (char *oldfname, char *newfname) return !rename(oldfname, newfname); } -int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *, int, void *), void *parm) +static int Sys_EnumerateFiles2 (const char *match, int matchstart, int neststart, int (*func)(const char *, int, void *), void *parm) { HANDLE r; WIN32_FIND_DATA fd; - char apath[MAX_OSPATH]; - char apath2[MAX_OSPATH]; - char file[MAX_OSPATH]; - char *s; - int go; - if (!gpath) - return 0; -// strcpy(apath, match); - Q_snprintfz(apath, sizeof(apath), "%s/%s", gpath, match); - for (s = apath+strlen(apath)-1; s> apath; s--) + int nest = neststart; //neststart refers to just after a / + qboolean go; + qboolean wild = false; + + while(match[nest] && match[nest] != '/') { - if (*s == '/') - break; + if (match[nest] == '?' || match[nest] == '*') + wild = true; + nest++; } - *s = '\0'; - - //this is what we ask windows for. - Q_snprintfz(file, sizeof(file), "%s/*.*", apath); - - //we need to make apath contain the path in match but not gpath - Q_strncpyz(apath2, match, sizeof(apath)); - match = s+1; - for (s = apath2+strlen(apath2)-1; s> apath2; s--) + if (match[nest] == '/') { - if (*s == '/') - break; - } - *s = '\0'; - if (s != apath2) - strcat(apath2, "/"); + char submatch[MAX_OSPATH]; + char tmproot[MAX_OSPATH]; + char file[MAX_OSPATH]; - r = FindFirstFile(file, &fd); - if (r==(HANDLE)-1) - return 1; - go = true; - do - { - if (*fd.cFileName == '.'); //don't ever find files with a name starting with '.' - else if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) //is a directory + if (!wild) + return Sys_EnumerateFiles2(match, matchstart, nest+1, func, parm); + + if (nest-neststart+1> MAX_OSPATH) + return 1; + memcpy(submatch, match+neststart, nest - neststart); + submatch[nest - neststart] = 0; + nest++; + + if (neststart+4 > MAX_OSPATH) + return 1; + memcpy(tmproot, match, neststart); + strcpy(tmproot+neststart, "*.*"); + + r = FindFirstFile(tmproot, &fd); + strcpy(tmproot+neststart, ""); + if (r==(HANDLE)-1) + return 1; + go = true; + do { - if (wildcmp(match, fd.cFileName)) + if (*fd.cFileName == '.'); //don't ever find files with a name starting with '.' + else if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) //is a directory { - Q_snprintfz(file, sizeof(file), "%s%s/", apath2, fd.cFileName); - go = func(file, fd.nFileSizeLow, parm); + if (wildcmp(submatch, fd.cFileName)) + { + int newnest; + if (strlen(tmproot) + strlen(fd.cFileName) + strlen(match+nest) + 2 < MAX_OSPATH) + { + Q_snprintfz(file, sizeof(file), "%s%s/", tmproot, fd.cFileName); + newnest = strlen(file); + strcpy(file+newnest, match+nest); + go = Sys_EnumerateFiles2(file, matchstart, newnest, func, parm); + } + } } - } - else - { - if (wildcmp(match, fd.cFileName)) - { - Q_snprintfz(file, sizeof(file), "%s%s", apath2, fd.cFileName); - go = func(file, fd.nFileSizeLow, parm); - } - } + } while(FindNextFile(r, &fd) && go); + FindClose(r); + } + else + { + const char *submatch = match + neststart; + char tmproot[MAX_OSPATH]; + char file[MAX_OSPATH]; + + if (neststart+4 > MAX_OSPATH) + return 1; + memcpy(tmproot, match, neststart); + strcpy(tmproot+neststart, "*.*"); + + r = FindFirstFile(tmproot, &fd); + strcpy(tmproot+neststart, ""); + if (r==(HANDLE)-1) + return 1; + go = true; + do + { + if (*fd.cFileName == '.'); //don't ever find files with a name starting with '.' + else if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) //is a directory + { + if (wildcmp(submatch, fd.cFileName)) + { + if (strlen(tmproot+matchstart) + strlen(fd.cFileName) + 2 < MAX_OSPATH) + { + Q_snprintfz(file, sizeof(file), "%s%s/", tmproot+matchstart, fd.cFileName); + go = func(file, fd.nFileSizeLow, parm); + } + } + } + else + { + if (wildcmp(submatch, fd.cFileName)) + { + if (strlen(tmproot+matchstart) + strlen(fd.cFileName) + 1 < MAX_OSPATH) + { + Q_snprintfz(file, sizeof(file), "%s%s", tmproot+matchstart, fd.cFileName); + go = func(file, fd.nFileSizeLow, parm); + } + } + } + } while(FindNextFile(r, &fd) && go); + FindClose(r); } - while(FindNextFile(r, &fd) && go); - FindClose(r); return go; } +int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *, int, void *), void *parm) +{ + char fullmatch[MAX_OSPATH]; + int start; + if (strlen(gpath) + strlen(match) + 2 > MAX_OSPATH) + return 1; + + strcpy(fullmatch, gpath); + start = strlen(fullmatch); + if (start && fullmatch[start-1] != '/') + fullmatch[start++] = '/'; + fullmatch[start] = 0; + strcat(fullmatch, match); + return Sys_EnumerateFiles2(fullmatch, start, start, func, parm); +} /* =============================================================================== diff --git a/engine/client/textedit.c b/engine/client/textedit.c index c765c9dc1..3efbf8914 100644 --- a/engine/client/textedit.c +++ b/engine/client/textedit.c @@ -296,7 +296,8 @@ static void EditorOpenFile(char *name, qboolean readonly) int len, flen, pos=0; vfsfile_t *F; fileblock_t *b; - + char *prname; + pubprogfuncs_t *epf = editprogfuncs; CloseEditor(); strcpy(OpenEditorFile, name); @@ -315,6 +316,12 @@ static void EditorOpenFile(char *name, qboolean readonly) } i=1; + prname = OpenEditorFile; + if (!strncmp(prname, "src/", 4)) + prname += 4; + if (!strncmp(prname, "source/", 7)) + prname += 7; + flen = VFS_GETLEN(F); while(pos < flen) @@ -349,9 +356,9 @@ static void EditorOpenFile(char *name, qboolean readonly) firstblock->datalength = len; memcpy(firstblock->data, line, len); - if (editprogfuncs) + if (epf) { - if (editprogfuncs->ToggleBreak(editprogfuncs, OpenEditorFile, i, 3)) + if (epf->ToggleBreak(epf, prname, i, 3)) { firstblock->flags |= FB_BREAK; } @@ -360,7 +367,7 @@ static void EditorOpenFile(char *name, qboolean readonly) { if (svprogfuncs) { - if (svprogfuncs->ToggleBreak(svprogfuncs, OpenEditorFile, i, 3)) + if (svprogfuncs->ToggleBreak(svprogfuncs, prname, i, 3)) { firstblock->flags |= FB_BREAK; } @@ -389,6 +396,7 @@ static void EditorOpenFile(char *name, qboolean readonly) editor_oldkeydest = key_dest; key_dest = key_editor; editoractive = true; + editprogfuncs = epf; } extern qboolean keydown[K_MAX]; @@ -634,9 +642,15 @@ void Editor_Key(int key, int unicode) case K_F9: /*set breakpoint*/ { int f = 0; + char *fname = OpenEditorFile; + if (!strncmp(fname, "src/", 4)) + fname += 4; + if (!strncmp(fname, "source/", 7)) + fname += 7; + if (editprogfuncs) { - if (editprogfuncs->ToggleBreak(editprogfuncs, OpenEditorFile, cursorlinenum, 2)) + if (editprogfuncs->ToggleBreak(editprogfuncs, fname, cursorlinenum, 2)) f |= 1; else f |= 2; @@ -644,7 +658,7 @@ void Editor_Key(int key, int unicode) #ifndef CLIENTONLY else if (svprogfuncs) { - if (svprogfuncs->ToggleBreak(svprogfuncs, OpenEditorFile, cursorlinenum, 2)) + if (svprogfuncs->ToggleBreak(svprogfuncs, fname, cursorlinenum, 2)) f |= 1; else f |= 2; diff --git a/engine/common/cmd.c b/engine/common/cmd.c index 9f950936b..07a9e2376 100644 --- a/engine/common/cmd.c +++ b/engine/common/cmd.c @@ -1868,7 +1868,7 @@ void Cmd_ForwardToServer_f (void) return; } - if (Q_strcasecmp(Cmd_Argv(1), "snap") == 0) + if (Q_strcasecmp(Cmd_Argv(1), "snap") == 0 && cls.protocol == CP_QUAKEWORLD) { if (SCR_RSShot()) return; diff --git a/engine/common/net_wins.c b/engine/common/net_wins.c index 915629aab..854dd7e12 100644 --- a/engine/common/net_wins.c +++ b/engine/common/net_wins.c @@ -90,7 +90,7 @@ static qboolean allowconnects = false; #define MAX_LOOPBACK 8 typedef struct { - qbyte data[MAX_UDP_PACKET]; + qbyte data[MAX_OVERALLMSGLEN]; int datalen; } loopmsg_t; @@ -1466,12 +1466,15 @@ void NET_SendLoopPacket (netsrc_t sock, int length, void *data, netadr_t to) loop = &loopbacks[sock^1]; + if (length > sizeof(loop->msgs[i].data)) + { + Con_Printf("NET_SendLoopPacket: Loopback buffer is too small"); + return; + } + i = loop->send & (MAX_LOOPBACK-1); loop->send++; - if (length > sizeof(loop->msgs[i].data)) - Sys_Error("NET_SendLoopPacket: Loopback buffer is too small"); - memcpy (loop->msgs[i].data, data, length); loop->msgs[i].datalen = length; } diff --git a/engine/common/pr_common.h b/engine/common/pr_common.h index b7f503d32..3e7226a48 100644 --- a/engine/common/pr_common.h +++ b/engine/common/pr_common.h @@ -51,7 +51,6 @@ struct wedict_s #define PF_gecko_resize PF_Fixme #define PF_gecko_get_texture_extent PF_Fixme -#define PF_pointsound PF_Fixme #define PF_gecko_mousemove PF_Fixme #define PF_WritePicture PF_Fixme #define PF_ReadPicture PF_Fixme @@ -385,6 +384,7 @@ void QCBUILTIN PF_memfree (pubprogfuncs_t *prinst, struct globalvars_s *pr_globa void QCBUILTIN PF_memcpy (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_memset (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_soundlength (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_calltimeofday (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_whichpack (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); diff --git a/engine/common/world.h b/engine/common/world.h index ce64b191e..66ff1f3a5 100644 --- a/engine/common/world.h +++ b/engine/common/world.h @@ -150,7 +150,7 @@ struct world_s { void (*Event_Touch)(struct world_s *w, wedict_t *s, wedict_t *o); void (*Event_Think)(struct world_s *w, wedict_t *s); - void (*Event_Sound) (wedict_t *entity, int channel, char *sample, int volume, float attenuation, int pitchadj); + void (*Event_Sound) (float *origin, wedict_t *entity, int channel, char *sample, int volume, float attenuation, int pitchadj); qboolean (*Event_ContentsTransition) (struct world_s *w, wedict_t *ent, int oldwatertype, int newwatertype); model_t *(*Get_CModel)(struct world_s *w, int modelindex); void (*Get_FrameState)(struct world_s *w, wedict_t *s, framestate_t *fstate); diff --git a/engine/dotnet2005/ftequake.sln b/engine/dotnet2005/ftequake.sln index 26e3ffb26..d6803575b 100644 --- a/engine/dotnet2005/ftequake.sln +++ b/engine/dotnet2005/ftequake.sln @@ -318,7 +318,6 @@ Global {873CCE24-3549-49D4-A4B4-653F91B1532A}.D3DRelease|Win32.ActiveCfg = Release|Win32 {873CCE24-3549-49D4-A4B4-653F91B1532A}.D3DRelease|x64.ActiveCfg = Release|Win32 {873CCE24-3549-49D4-A4B4-653F91B1532A}.Debug Dedicated Server|Win32.ActiveCfg = Debug|Win32 - {873CCE24-3549-49D4-A4B4-653F91B1532A}.Debug Dedicated Server|Win32.Build.0 = Debug|Win32 {873CCE24-3549-49D4-A4B4-653F91B1532A}.Debug Dedicated Server|x64.ActiveCfg = Debug|Win32 {873CCE24-3549-49D4-A4B4-653F91B1532A}.Debug|Win32.ActiveCfg = Debug|Win32 {873CCE24-3549-49D4-A4B4-653F91B1532A}.Debug|Win32.Build.0 = Debug|Win32 @@ -350,7 +349,6 @@ Global {4877586B-E85B-4DF8-BCCE-59D31514D240}.D3DRelease|Win32.Build.0 = Release|Win32 {4877586B-E85B-4DF8-BCCE-59D31514D240}.D3DRelease|x64.ActiveCfg = Release|Win32 {4877586B-E85B-4DF8-BCCE-59D31514D240}.Debug Dedicated Server|Win32.ActiveCfg = Debug|Win32 - {4877586B-E85B-4DF8-BCCE-59D31514D240}.Debug Dedicated Server|Win32.Build.0 = Debug|Win32 {4877586B-E85B-4DF8-BCCE-59D31514D240}.Debug Dedicated Server|x64.ActiveCfg = Debug|Win32 {4877586B-E85B-4DF8-BCCE-59D31514D240}.Debug|Win32.ActiveCfg = Debug|Win32 {4877586B-E85B-4DF8-BCCE-59D31514D240}.Debug|Win32.Build.0 = Debug|Win32 @@ -382,7 +380,6 @@ Global {32B12987-DF8C-4E40-B07C-B18586A4CA65}.D3DRelease|Win32.Build.0 = Release|Win32 {32B12987-DF8C-4E40-B07C-B18586A4CA65}.D3DRelease|x64.ActiveCfg = Release|Win32 {32B12987-DF8C-4E40-B07C-B18586A4CA65}.Debug Dedicated Server|Win32.ActiveCfg = Debug|Win32 - {32B12987-DF8C-4E40-B07C-B18586A4CA65}.Debug Dedicated Server|Win32.Build.0 = Debug|Win32 {32B12987-DF8C-4E40-B07C-B18586A4CA65}.Debug Dedicated Server|x64.ActiveCfg = Debug|Win32 {32B12987-DF8C-4E40-B07C-B18586A4CA65}.Debug|Win32.ActiveCfg = Debug|Win32 {32B12987-DF8C-4E40-B07C-B18586A4CA65}.Debug|Win32.Build.0 = Debug|Win32 @@ -415,7 +412,6 @@ Global {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.D3DRelease|Win32.Build.0 = Release|Win32 {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.D3DRelease|x64.ActiveCfg = Release|Win32 {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.Debug Dedicated Server|Win32.ActiveCfg = Debug|Win32 - {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.Debug Dedicated Server|Win32.Build.0 = Debug|Win32 {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.Debug Dedicated Server|x64.ActiveCfg = Debug|Win32 {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.Debug|Win32.ActiveCfg = Debug|Win32 {4735677B-6D5A-4BE6-A945-CB32DEADBEEF}.Debug|Win32.Build.0 = Debug|Win32 diff --git a/engine/dotnet2005/ftequake.vcproj b/engine/dotnet2005/ftequake.vcproj index 8e6ad9589..65ad61eb0 100644 --- a/engine/dotnet2005/ftequake.vcproj +++ b/engine/dotnet2005/ftequake.vcproj @@ -1302,7 +1302,7 @@ + + + name); - if (*mod->name != '*') + if (*mod->name != '*' && strcmp(mod->name, "null")) Con_Printf(CON_ERROR "Unable to load or replace %s\n", mod->name); mod->type = mod_dummy; mod->mins[0] = -16; diff --git a/engine/gl/gl_rmisc.c b/engine/gl/gl_rmisc.c index 46f5cc49a..9b31edf17 100644 --- a/engine/gl/gl_rmisc.c +++ b/engine/gl/gl_rmisc.c @@ -496,6 +496,7 @@ void GLR_NewMap (void) VectorInverse(r_worldentity.axis[1]); r_worldentity.model = cl.worldmodel; Vector4Set(r_worldentity.shaderRGBAf, 1, 1, 1, 1); + VectorSet(r_worldentity.light_avg, 1, 1, 1); COM_StripExtension(COM_SkipPath(cl.worldmodel->name), namebuf, sizeof(namebuf)); diff --git a/engine/gl/gl_shader.c b/engine/gl/gl_shader.c index e567d1c15..a4d2bfb2b 100644 --- a/engine/gl/gl_shader.c +++ b/engine/gl/gl_shader.c @@ -584,7 +584,7 @@ qboolean Shader_ParseSkySides (char *shadername, char *texturename, texid_t *ima for (ss = 0; ss < sizeof(skyname_suffix)/sizeof(skyname_suffix[0]); ss++) { Com_sprintf ( path, sizeof(path), skyname_pattern[sp], texturename, skyname_suffix[ss][i] ); - images[i] = R_LoadHiResTexture ( path, NULL, IF_NOALPHA); + images[i] = R_LoadHiResTexture ( path, NULL, IF_NOALPHA|IF_CLAMP); if (TEXVALID(images[i])) break; } diff --git a/engine/qclib/initlib.c b/engine/qclib/initlib.c index a62cf28a4..062b3e77b 100644 --- a/engine/qclib/initlib.c +++ b/engine/qclib/initlib.c @@ -473,7 +473,7 @@ void PDECL PR_Configure (pubprogfuncs_t *ppf, size_t addressable_size, int max_p #ifdef _WIN64 addressable_size = 0x80000000; //use of virtual address space rather than physical memory means we can just go crazy and use the max of 2gb. #else - addressable_size = 8*1024*1024; + addressable_size = 32*1024*1024; #endif } if (addressable_size > 0x80000000) diff --git a/engine/server/pr_cmds.c b/engine/server/pr_cmds.c index 00fd50118..1ff54b8de 100644 --- a/engine/server/pr_cmds.c +++ b/engine/server/pr_cmds.c @@ -3005,7 +3005,27 @@ static void QCBUILTIN PF_sound (pubprogfuncs_t *prinst, struct globalvars_s *pr_ channel |= 256; //shift the reliable flag to 256 instead. - SVQ1_StartSound ((wedict_t*)entity, channel, sample, volume, attenuation, pitchadj); + SVQ1_StartSound (NULL, (wedict_t*)entity, channel, sample, volume, attenuation, pitchadj); +} + +static void QCBUILTIN PF_pointsound(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) +{ + char *sample; + float *origin; + float volume; + float attenuation; + float pitchpct; + + origin = G_VECTOR(OFS_PARM0); + sample = PR_GetStringOfs(prinst, OFS_PARM1); + volume = G_FLOAT(OFS_PARM2); + attenuation = G_FLOAT(OFS_PARM3); + if (prinst->callargc >= 5) + pitchpct = G_FLOAT(OFS_PARM4); + else + pitchpct = 0; + + SVQ1_StartSound (origin, sv.world.edicts, 0, sample, volume, attenuation, pitchpct); } //an evil one from telejano. @@ -7378,7 +7398,7 @@ static void QCBUILTIN PF_h2StopSound(pubprogfuncs_t *prinst, struct globalvars_s entity = G_EDICT(prinst, OFS_PARM0); channel = G_FLOAT(OFS_PARM1); - SVQ1_StartSound ((wedict_t*)entity, channel, "", 1, 0, 0); + SVQ1_StartSound (NULL, (wedict_t*)entity, channel, "", 1, 0, 0); } static void QCBUILTIN PF_h2updatesoundpos(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) @@ -9414,7 +9434,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs {"registercommand", PF_Fixme, 0, 0, 0, 352, "void(string cmdname)"},//(EXT_CSQC) {"wasfreed", PF_WasFreed,0, 0, 0, 353, "float(entity ent)"},//(EXT_CSQC) (should be availabe on server too) {"serverkey", PF_Fixme, 0, 0, 0, 354, "string(string key)"},// - {"getentitytoken", PF_Fixme, 0, 0, 0, 355, "string()"},//; + {"getentitytoken", PF_Fixme, 0, 0, 0, 355, "string(optional string resetstring)"},//; {"findfont", PF_Fixme, 0, 0, 0, 356, "float(string s)"},//; {"loadfont", PF_Fixme, 0, 0, 0, 357, "float(string fontname, string fontmaps, string sizes, float slot, optional float fix_scale, optional float fix_voffset)"}, {"sendevent", PF_Fixme, 0, 0, 0, 359, "void(string evname, string evargs, ...)"},// (EXT_CSQC_1) @@ -9441,10 +9461,10 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs {"adddecal", PF_Fixme, 0, 0, 0, 375, "void(string shadername, vector origin, vector up, vector side, vector rgb, float alpha)"}, //END EXT_CSQC - {"memalloc", PF_memalloc, 0, 0, 0, 384, "void*(int size)"}, - {"memfree", PF_memfree, 0, 0, 0, 385, "void(void *ptr)"}, - {"memcpy", PF_memcpy, 0, 0, 0, 386, "void(void *dst, void *src, int size)"}, - {"memset", PF_memset, 0, 0, 0, 387, "void(void *dst, int val, int size)"}, + {"memalloc", PF_memalloc, 0, 0, 0, 384, "__variant*(int size)"}, + {"memfree", PF_memfree, 0, 0, 0, 385, "void(__variant *ptr)"}, + {"memcpy", PF_memcpy, 0, 0, 0, 386, "void(__variant *dst, __variant *src, int size)"}, + {"memset", PF_memset, 0, 0, 0, 387, "void(__variant *dst, int val, int size)"}, //end fte extras @@ -9646,7 +9666,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs //restart dp extras // {"log", PF_Fixme, 0, 0, 0, 532, "float(string mname)", true}, // {"getsoundtime", VM_getsoundtime, 0, 0, 0, 533, "float(entity e, float channel)" STUB}, -// {"soundlength", VM_soundlength, 0, 0, 0, 534, "float(string sample)" STUB}, + {"soundlength", PF_Ignore, 0, 0, 0, 534, "float(string sample)" STUB}, // {"buf_loadfile", PF_Fixme, 0, 0, 0, 535, "float(string filename, float bufhandle)"}, // {"buf_writefile", PF_Fixme, 0, 0, 0, 536, "float(float filehandle, float bufhandle, float startpos, float numstrings)"}, // {"bufstr_find", PF_Fixme, 0, 0, 0, 537, "float(float bufhandle, string match, float matchrule, float startpos)"}, diff --git a/engine/server/pr_q1qvm.c b/engine/server/pr_q1qvm.c index e515f1671..0dc7c645f 100755 --- a/engine/server/pr_q1qvm.c +++ b/engine/server/pr_q1qvm.c @@ -31,6 +31,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define VMFSID_Q1QVM 57235 //a cookie +void PR_SV_FillWorldGlobals(world_t *w); + #if GAME_API_VERSION >= 13 #define WASTED_EDICT_T_SIZE (VM_NonNative(q1qvm)?sizeof(int):sizeof(void*)) //in version 13, the actual edict_t struct is gone, and there's a pointer to it in its place (which we don't need, but it changes size based on vm/native). @@ -639,7 +641,7 @@ static qintptr_t syscallhandle (void *offset, quintptr_t mask, qintptr_t fn, con case G_SOUND: // ( int edn, int channel, char *samp, float vol, float att ) - SVQ1_StartSound ((wedict_t*)Q1QVMPF_EdictNum(svprogfuncs, VM_LONG(arg[0])), VM_LONG(arg[1]), VM_POINTER(arg[2]), VM_FLOAT(arg[3])*255, VM_FLOAT(arg[4]), 0); + SVQ1_StartSound (NULL, (wedict_t*)Q1QVMPF_EdictNum(svprogfuncs, VM_LONG(arg[0])), VM_LONG(arg[1]), VM_POINTER(arg[2]), VM_FLOAT(arg[3])*255, VM_FLOAT(arg[4]), 0); break; case G_TRACELINE: @@ -1321,8 +1323,6 @@ void Q1QVM_Event_Think(world_t *w, wedict_t *s) pr_global_struct->self = EDICT_TO_PROG(w->progs, s); pr_global_struct->other = EDICT_TO_PROG(w->progs, w->edicts); VM_Call(q1qvm, GAME_EDICT_THINK); - - PR_ExecuteProgram (w->progs, s->v->think); } qboolean Q1QVM_Event_ContentsTransition(world_t *w, wedict_t *ent, int oldwatertype, int newwatertype) @@ -1334,6 +1334,7 @@ qboolean PR_LoadQ1QVM(void) { static float writable; static float dimensionsend; + static float physics_mode = 2; int i; gameDataN_t *gd, gdm; gameData32_t *gd32; @@ -1473,6 +1474,7 @@ qboolean PR_LoadQ1QVM(void) pr_global_ptrs->trace_surfaceflags = &writable; pr_global_ptrs->trace_endcontents = &writable; pr_global_ptrs->dimension_send = &dimensionsend; + pr_global_ptrs->physics_mode = &physics_mode; dimensionsend = 255; for (i = 0; i < 16; i++) @@ -1487,6 +1489,8 @@ qboolean PR_LoadQ1QVM(void) if ((unsigned)gd->global->mapname && (unsigned)gd->global->mapname+MAPNAME_LEN < VM_MemoryMask(q1qvm)) Q_strncpyz((char*)VM_MemoryBase(q1qvm) + gd->global->mapname, sv.mapname, MAPNAME_LEN); + + PR_SV_FillWorldGlobals(&sv.world); return true; } diff --git a/engine/server/server.h b/engine/server/server.h index a872b02b1..e7dbd18bd 100644 --- a/engine/server/server.h +++ b/engine/server/server.h @@ -1038,7 +1038,7 @@ void VARGS SV_Multicast (vec3_t origin, multicast_t to); void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int with, int without); void SV_StartSound (int ent, vec3_t origin, int seenmask, int channel, char *sample, int volume, float attenuation, int pitchadj); -void SVQ1_StartSound (wedict_t *entity, int channel, char *sample, int volume, float attenuation, int pitchadj); +void SVQ1_StartSound (float *origin, wedict_t *entity, int channel, char *sample, int volume, float attenuation, int pitchadj); void SV_PrintToClient(client_t *cl, int level, char *string); void SV_StuffcmdToClient(client_t *cl, char *string); void VARGS SV_ClientPrintf (client_t *cl, int level, char *fmt, ...) LIKEPRINTF(3); diff --git a/engine/server/sv_ents.c b/engine/server/sv_ents.c index 79af918fe..b299eb46e 100644 --- a/engine/server/sv_ents.c +++ b/engine/server/sv_ents.c @@ -3037,6 +3037,7 @@ void SV_Snapshot_BuildQ1(client_t *client, packet_entities_t *pack, qbyte *pvs, #endif globalvars_t *pr_globals = PR_globals(svprogfuncs, PR_CURRENT); int pvsflags; + int limit; if (client->spectator) trackent = EDICT_NUM(svprogfuncs, client->spec_track); @@ -3097,7 +3098,9 @@ void SV_Snapshot_BuildQ1(client_t *client, packet_entities_t *pack, qbyte *pvs, else e = 1; - for ( ; emax_net_ents, sv.world.num_edicts); + + for ( ; efteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS) { - if (client->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS) - { - //you need to reconnect for this to update, of course. so make sure its not *too* low... - client->max_net_ents = bound(512, pr_maxedicts.ival, MAX_EDICTS); - client->maxmodels = MAX_MODELS; //protocol limited to 14 bits. - } - else - { - client->max_net_ents = 512; - if (client->fteprotocolextensions & PEXT_ENTITYDBL) - client->max_net_ents += 512; - if (client->fteprotocolextensions & PEXT_ENTITYDBL2) - client->max_net_ents += 1024; - } - + //you need to reconnect for this to update, of course. so make sure its not *too* low... + client->max_net_ents = bound(512, pr_maxedicts.ival, MAX_EDICTS); + client->maxmodels = MAX_MODELS; //protocol limited to 14 bits. + } + else if (ISQWCLIENT(client)) //readd? + { + client->max_net_ents = 512; + if (client->fteprotocolextensions & PEXT_ENTITYDBL) + client->max_net_ents += 512; + if (client->fteprotocolextensions & PEXT_ENTITYDBL2) + client->max_net_ents += 1024; + if (client->fteprotocolextensions & PEXT_MODELDBL) client->maxmodels = MAX_MODELS; } diff --git a/engine/server/sv_phys.c b/engine/server/sv_phys.c index 4d281a1e9..fffa43171 100644 --- a/engine/server/sv_phys.c +++ b/engine/server/sv_phys.c @@ -1043,7 +1043,7 @@ static void WPhys_CheckWaterTransition (world_t *w, wedict_t *ent) { if (ent->v->watertype == Q1CONTENTS_EMPTY && *sv_sound_watersplash.string) { // just crossed into water - w->Event_Sound(ent, 0, sv_sound_watersplash.string, 255, 1, 0); + w->Event_Sound(NULL, ent, 0, sv_sound_watersplash.string, 255, 1, 0); } ent->v->watertype = cont; ent->v->waterlevel = 1; @@ -1052,7 +1052,7 @@ static void WPhys_CheckWaterTransition (world_t *w, wedict_t *ent) { if (ent->v->watertype != Q1CONTENTS_EMPTY && *sv_sound_watersplash.string) { // just crossed into open - w->Event_Sound(ent, 0, sv_sound_watersplash.string, 255, 1, 0); + w->Event_Sound(NULL, ent, 0, sv_sound_watersplash.string, 255, 1, 0); } ent->v->watertype = Q1CONTENTS_EMPTY; ent->v->waterlevel = cont; @@ -1235,7 +1235,7 @@ static void WPhys_Physics_Step (world_t *w, wedict_t *ent) { if (hitsound && *sv_sound_land.string) { - w->Event_Sound(ent, 0, sv_sound_land.string, 255, 1, 0); + w->Event_Sound(NULL, ent, 0, sv_sound_land.string, 255, 1, 0); } } } diff --git a/engine/server/sv_send.c b/engine/server/sv_send.c index d02097752..2b292f384 100644 --- a/engine/server/sv_send.c +++ b/engine/server/sv_send.c @@ -1029,19 +1029,23 @@ void SV_StartSound (int ent, vec3_t origin, int seenmask, int channel, char *sam SV_MulticastProtExt(origin, reliable ? MULTICAST_ALL_R : MULTICAST_ALL, seenmask, requiredextensions, 0); } -void SVQ1_StartSound (wedict_t *wentity, int channel, char *sample, int volume, float attenuation, int pitchadj) +void SVQ1_StartSound (float *origin, wedict_t *wentity, int channel, char *sample, int volume, float attenuation, int pitchadj) { edict_t *entity = (edict_t*)wentity; int i; - vec3_t origin; - if (entity->v->solid == SOLID_BSP) + vec3_t originbuf; + if (!origin) { - for (i=0 ; i<3 ; i++) - origin[i] = entity->v->origin[i]+0.5*(entity->v->mins[i]+entity->v->maxs[i]); - } - else - { - VectorCopy (entity->v->origin, origin); + origin = originbuf; + if (entity->v->solid == SOLID_BSP) + { + for (i=0 ; i<3 ; i++) + origin[i] = entity->v->origin[i]+0.5*(entity->v->mins[i]+entity->v->maxs[i]); + } + else + { + VectorCopy (entity->v->origin, origin); + } } SV_StartSound(NUM_FOR_EDICT(svprogfuncs, entity), origin, entity->xv->dimension_seen, channel, sample, volume, attenuation, pitchadj); diff --git a/engine/server/sv_sys_win.c b/engine/server/sv_sys_win.c index 1ecda763e..2cc655102 100644 --- a/engine/server/sv_sys_win.c +++ b/engine/server/sv_sys_win.c @@ -94,7 +94,14 @@ DWORD CrashExceptionHandler (DWORD exceptionCode, LPEXCEPTION_POINTERS exception if (fnMiniDumpWriteDump) { if (MessageBox(NULL, "KABOOM! We crashed!\nBlame the monkey in the corner.\nI hope you saved your work.\nWould you like to take a dump now?", DISTRIBUTION " Sucks", MB_ICONSTOP|MB_YESNO) != IDYES) + { + if (pIsDebuggerPresent ()) + { + //its possible someone attached a debugger while we were showing that message + return EXCEPTION_CONTINUE_SEARCH; + } return EXCEPTION_EXECUTE_HANDLER; + } /*take a dump*/ GetTempPath (sizeof(dumpPath)-16, dumpPath); diff --git a/engine/server/sv_user.c b/engine/server/sv_user.c index c96c365e0..ce13364ca 100644 --- a/engine/server/sv_user.c +++ b/engine/server/sv_user.c @@ -473,7 +473,8 @@ void SVNQ_New_f (void) MSG_WriteByte (&host_client->netchan.message, svc_stufftext); MSG_WriteString (&host_client->netchan.message, va("csqc_progcrc %i\n", QCRC_Block(f, com_filesize))); - host_client->csqcactive = true; + MSG_WriteByte (&host_client->netchan.message, svc_stufftext); + MSG_WriteString (&host_client->netchan.message, "cmd enablecsqc\n"); } } @@ -1978,9 +1979,9 @@ void SV_NextChunkedDownload(unsigned int chunknum, int ezpercent, int ezfilenum) host_client->downloadcount = chunknum*CHUNKSIZE; } - if (host_client->datagram.cursize + CHUNKSIZE+5+50 > host_client->datagram.maxsize) + if ((host_client->datagram.cursize + CHUNKSIZE+5+50 > host_client->datagram.maxsize) || (host_client->datagram.cursize + CHUNKSIZE+5 > 1400)) { - //would overflow the packet. + //would overflow the packet, or result in (ethernet) fragmentation and high packet loss. msg = &msg_oob; if (!ezfilenum) @@ -2158,7 +2159,7 @@ void SV_NextUpload (void) { SV_ClientTPrintf(host_client, PRINT_HIGH, STL_UPLOADDENIED); ClientReliableWrite_Begin (host_client, svc_stufftext, 8); - ClientReliableWrite_String (host_client, "stopul"); + ClientReliableWrite_String (host_client, "stopul\n"); // suck out rest of packet size = MSG_ReadShort (); MSG_ReadByte (); @@ -2171,12 +2172,13 @@ void SV_NextUpload (void) if (!host_client->upload) { + FS_CreatePath(host_client->uploadfn, FS_GAMEONLY); host_client->upload = FS_OpenVFS(host_client->uploadfn, "wb", FS_GAMEONLY); if (!host_client->upload) { Sys_Printf("Can't create %s\n", host_client->uploadfn); ClientReliableWrite_Begin (host_client, svc_stufftext, 8); - ClientReliableWrite_String (host_client, "stopul"); + ClientReliableWrite_String (host_client, "stopul\n"); *host_client->uploadfn = 0; return; } @@ -2211,6 +2213,7 @@ void SV_NextUpload (void) OutofBandPrintf(host_client->snap_from, "%s upload completed.\nTo download, enter:\ndownload %s\n", host_client->uploadfn, p); } + *host_client->uploadfn = 0; //don't let it get overwritten again } } @@ -2521,8 +2524,10 @@ qboolean SV_AllowDownload (const char *name) if (!allow_download_packages.ival) return false; /*do not permit 'id1/pak1.pak' or 'baseq3/pak0.pk3' or any similarly named packages. such packages would violate copyright, and must be obtained through other means (like buying the damn game)*/ - if (FS_GetPackageDownloadable(name+8)) - return !!allow_download_packages.ival; + if (!allow_download_copyrighted.ival && !FS_GetPackageDownloadable(name+8)) + return false; + + return true; } return false; } @@ -3682,7 +3687,8 @@ void SV_NoSnap_f(void) { SV_LogPlayer(host_client, "refused snap"); - if (*host_client->uploadfn) { + if (*host_client->uploadfn) + { *host_client->uploadfn = 0; SV_BroadcastTPrintf (PRINT_HIGH, STL_SNAPREFUSED, host_client->name); } @@ -4836,6 +4842,10 @@ ucmd_t ucmds[] = {"notarget", Cmd_Notarget_f}, {"setpos", Cmd_SetPos_f}, +#ifdef NQPROT + {"name", SVNQ_NQInfo_f}, +#endif + #ifdef VOICECHAT {"voicetarg", SV_Voice_Target_f}, {"vignore", SV_Voice_Ignore_f}, /*ignore/mute specific player*/ diff --git a/engine/server/world.c b/engine/server/world.c index 5a51711a2..f1d847794 100644 --- a/engine/server/world.c +++ b/engine/server/world.c @@ -1023,15 +1023,20 @@ static trace_t World_ClipMoveToEntity (world_t *w, wedict_t *ent, vec3_t eorg, v { model = w->Get_CModel(w, mdlidx); if (!model || (model->type != mod_brush && model->type != mod_heightmap)) - Host_Error("SOLID_BSP with non bsp model (classname: %s)", PR_GetString(w->progs, ent->v->classname)); + { +// Host_Error("SOLID_BSP with non bsp model (classname: %s)", PR_GetString(w->progs, ent->v->classname)); + model = NULL; + } } else + model = NULL; + + if (!model); { vec3_t boxmins, boxmaxs; VectorSubtract (ent->v->mins, maxs, boxmins); VectorSubtract (ent->v->maxs, mins, boxmaxs); World_HullForBox(boxmins, boxmaxs); - model = NULL; } // trace a line through the apropriate clipping hull