try to be more strict/paranoid with cvars.

load q2 game dlls from the binarydir in preference to gamedir (allows such dlls to be distributed with the engine).
add small emscripten msvc project so I can build the web port a little more conveniently.
require mouse releases to have had a corresponding mouse press while in the menu. this solves issues with mouse clicks triggering the load menu while dead and instantlyish loading one, and alt-tab issues too.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4755 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2014-09-20 04:11:39 +00:00
parent 489e88feb4
commit b29c68ef92
21 changed files with 376 additions and 88 deletions

View file

@ -3569,7 +3569,10 @@ static void QCBUILTIN PF_cvar (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
cv = Cvar_Get(str, def, 0, "QC variables");
Con_Printf("^3Creating cvar %s\n", str);
}
G_FLOAT(OFS_RETURN) = cv->value;
if (cv->flags & CVAR_NOUNSAFEEXPAND)
G_FLOAT(OFS_RETURN) = 0;
else
G_FLOAT(OFS_RETURN) = cv->value;
}
}
@ -5111,9 +5114,11 @@ logfrag (killer, killee)
*/
void QCBUILTIN PF_logfrag (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
extern cvar_t fraglog_details;
edict_t *ent1, *ent2;
int e1, e2;
char *s;
char s[2048];
int slen;
sizebuf_t *sz;
ent1 = G_EDICT(prinst, OFS_PARM0);
@ -5132,11 +5137,51 @@ void QCBUILTIN PF_logfrag (pubprogfuncs_t *prinst, struct globalvars_s *pr_globa
svs.clients[e2].deaths += 1;
#endif
s = va("\\%s\\%s\\\n",svs.clients[e1].name, svs.clients[e2].name);
if (!fraglog_details.ival)
return; //not logging any details
else if (fraglog_details.ival == 7)
{ //compat with mvdsv.
time_t t = time (NULL);
struct tm *tm = gmtime(&t);
Q_snprintfz(s, sizeof(s)-2, "\\frag\\");
}
else if (fraglog_details.ival == 1)
strcpy(s, "\\");//vanilla compat
else //specify what info is actually in there
Q_snprintfz(s, sizeof(s)-2, "\\\\%u\\", fraglog_details.ival);
slen = strlen(s);
if (fraglog_details.ival & 1)
{
Q_snprintfz(s+slen, sizeof(s)-2-slen, "%s\\%s\\", svs.clients[e1].name, svs.clients[e2].name);
slen += strlen(s+slen);
}
if (fraglog_details.ival & 2)
{
Q_snprintfz(s+slen, sizeof(s)-2-slen, "%s\\%s\\", svs.clients[e1].team, svs.clients[e2].team);
slen += strlen(s+slen);
}
if (fraglog_details.ival & 4)
{
time_t t = time (NULL);
struct tm *tm = gmtime(&t);
Q_snprintfz(s+slen, sizeof(s)-2-slen, "%d-%d-%d %d:%d:%d\\", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
slen += strlen(s+slen);
}
if (fraglog_details.ival & 8)
{
Q_snprintfz(s+slen, sizeof(s)-2-slen, "%g\\", ent1->v->weapon);
slen += strlen(s+slen);
}
if (fraglog_details.ival & 16)
{
Q_snprintfz(s+slen, sizeof(s)-2-slen, "%s\\%s\\", svs.clients[e1].guid, svs.clients[e2].guid);
slen += strlen(s+slen);
}
s[slen++] = '\n';
//print it to the fraglog buffer for masters/etc to query
sz = &svs.log[svs.logsequence&(FRAGLOG_BUFFERS-1)];
if (sz->cursize && sz->cursize+strlen(s)+1 >= sz->maxsize)
if (sz->cursize && sz->cursize+slen+1 >= sz->maxsize)
{
// swap buffers and bump sequence
svs.logtime = realtime;
@ -5145,7 +5190,7 @@ void QCBUILTIN PF_logfrag (pubprogfuncs_t *prinst, struct globalvars_s *pr_globa
sz->cursize = 0;
Con_TPrintf ("beginning fraglog sequence %i\n", svs.logsequence);
}
SZ_Print (sz, s);
SZ_Write(sz, s, slen);
//print it to our local fraglog file.
if (sv_fraglogfile)

View file

@ -93,6 +93,7 @@ cvar_t sv_limittics = CVARD("sv_limittics","3", "The maximum number of ticks tha
cvar_t sv_nailhack = CVARD("sv_nailhack","0", "If set to 1, disables the nail entity networking optimisation. This hack was popularised by qizmo which recommends it for better compression. Also allows clients to interplate nail positions and add trails.");
cvar_t sv_nopvs = CVARD("sv_nopvs", "0", "Set to 1 to ignore pvs on the server. This can make wallhacks more dangerous, so should only be used for debugging.");
cvar_t fraglog_public = CVARD("fraglog_public", "1", "Enables support for connectionless fraglog requests");
cvar_t fraglog_details = CVARD("fraglog_details", "1", "Bitmask\n1: killer+killee names.\n2: killer+killee teams\n4:timestamp.\n8:killer weapon\n16:killer+killee guid.\nFor compatibility, use 1(vanilla) or 7(mvdsv).");
cvar_t timeout = SCVAR("timeout","65"); // seconds without any message
cvar_t zombietime = SCVAR("zombietime", "2"); // seconds to sink messages
@ -1307,10 +1308,12 @@ void SVC_Log (void)
unsigned int seq;
char data[MAX_DATAGRAM+64];
char adr[MAX_ADR_SIZE];
char *av;
if (Cmd_Argc() == 2)
av = Cmd_Argv(1);
if (*av)
{
seq = strtoul(Cmd_Argv(1), NULL, 0);
seq = strtoul(av, NULL, 0);
//seq is the last one that the client already has
if (seq < svs.logsequence-(FRAGLOG_BUFFERS-1))
@ -1338,7 +1341,12 @@ void SVC_Log (void)
Con_DPrintf ("sending log %i to %s\n", seq, NET_AdrToString(adr, sizeof(adr), &net_from));
Q_snprintfz(data, sizeof(data), "stdlog %i\n%s", seq, (char *)svs.log_buf[seq&(FRAGLOG_BUFFERS-1)]);
//cookie support, to avoid spoofing
av = Cmd_Argv(2);
if (*av)
Q_snprintfz(data, sizeof(data), "stdlog %i %s\n%s", seq, av, (char *)svs.log_buf[seq&(FRAGLOG_BUFFERS-1)]);
else
Q_snprintfz(data, sizeof(data), "stdlog %i\n%s", seq, (char *)svs.log_buf[seq&(FRAGLOG_BUFFERS-1)]);
NET_SendPacket (NS_SERVER, strlen(data)+1, data, &net_from);
}
@ -5098,11 +5106,6 @@ void SV_InitNet (void)
// NET_StringToAdr ("192.246.40.70:27000", &idmaster_adr);
}
void SV_IgnoreCommand_f(void)
{
}
/*
====================
SV_Init
@ -5239,8 +5242,10 @@ void SV_Init (quakeparms_t *parms)
}
if (sv.state == ss_dead && COM_FCheckExists("maps/start.bsp"))
Cmd_ExecuteString ("map start", RESTRICT_LOCAL); //regular q1
#ifdef HEXEN2
if (sv.state == ss_dead && COM_FCheckExists("maps/demo1.bsp"))
Cmd_ExecuteString ("map demo1", RESTRICT_LOCAL); //regular h2 sp
#endif
#ifdef Q2SERVER
if (sv.state == ss_dead && COM_FCheckExists("maps/base1.bsp"))
Cmd_ExecuteString ("map base1", RESTRICT_LOCAL); //regular q2 sp

View file

@ -28,10 +28,13 @@ void *SVQ2_GetGameAPI (void *parms)
};
char name[MAX_OSPATH];
char searchpath[MAX_OSPATH];
char syspath[MAX_OSPATH];
char gamepath[MAX_OSPATH];
void *iterator;
int o;
const char *gamename[] = {
"",
"",
#ifdef _DEBUG
"debug/game" ARCH_CPU_POSTFIX ARCH_DL_POSTFIX,
#endif
@ -42,21 +45,37 @@ void *SVQ2_GetGameAPI (void *parms)
"game" ARCH_DL_POSTFIX,
NULL
};
void *ret;
#ifdef _DEBUG
Con_DPrintf("Searching for %s\n", gamename[1]);
Con_DPrintf("Searching for %s\n", gamename[3]);
#else
Con_DPrintf("Searching for %s\n", gamename[0]);
Con_DPrintf("Searching for %s\n", gamename[2]);
#endif
iterator = NULL;
while(COM_IteratePaths(&iterator, searchpath, sizeof(searchpath)))
while(COM_IteratePaths(&iterator, syspath, sizeof(syspath), gamepath, sizeof(gamepath)))
{
for (o = 0; gamename[o]; o++)
{
snprintf(name, sizeof(name), "%s%s", searchpath, gamename[o]);
if (o == 0)
{ //nice and specific
if (!host_parms.binarydir)
continue;
Q_snprintfz(name, sizeof(name), "%sq2game"ARCH_CPU_POSTFIX"_%s"ARCH_DL_POSTFIX, host_parms.binarydir, gamepath);
}
else if (o == 1)
{ //because some people don't like knowing what cpu arch they're compiling for
if (!host_parms.binarydir)
continue;
Q_snprintfz(name, sizeof(name), "%slibgame_%s"ARCH_DL_POSTFIX, host_parms.binarydir, gamepath);
}
else
{
if (com_nogamedirnativecode.ival)
continue;
Q_snprintfz(name, sizeof(name), "%s%s", syspath, gamename[o]);
}
q2gamedll = Sys_LoadLibrary(name, funcs);
if (q2gamedll)

View file

@ -123,14 +123,74 @@ hull_t *World_HullForBox (vec3_t mins, vec3_t maxs)
model_t mod_capsule;
qboolean World_BoxTrace(struct model_s *model, int hulloverride, int frame, vec3_t axis[3], vec3_t p1, vec3_t p2, vec3_t mins, vec3_t maxs, unsigned int against, struct trace_s *trace)
{
//bbox vs bbox (NYI)
hull_t *hull = &box_hull;
//bbox vs bbox
//capsule vs bbox (NYI)
return false;
memset (trace, 0, sizeof(trace_t));
trace->fraction = 1;
trace->allsolid = true;
VectorCopy (p2, trace->endpos);
return Q1BSP_RecursiveHullCheck (hull, hull->firstclipnode, 0, 1, p1, p2, trace);
}
qboolean World_CapsuleTrace(struct model_s *model, int hulloverride, int frame, vec3_t axis[3], vec3_t p1, vec3_t p2, vec3_t mins, vec3_t maxs, qboolean capsule, unsigned int against, struct trace_s *trace)
{
//bbox vs capsule (NYI)
//capsule vs capsule (NYI)
memset (trace, 0, sizeof(trace_t));
trace->fraction = 1;
trace->allsolid = false;
VectorCopy(p2, trace->endpos);
if (capsule)
{ //capsule vs capsule.
//no orientation support on either (ignore axis)
float sr = ((model->maxs[0]-model->mins[0]) + (model->maxs[1]-model->mins[1]))/4.0;
float sh = (model->maxs[2]-model->mins[2]) - sr*2;
float mr = ((maxs[0]-mins[0]) + (maxs[1]-mins[1]))/4.0;
float mh = (maxs[2]-mins[2]) - mr*2;
vec3_t sup = {0, 0, 1};
vec3_t dir, sright;
vec4_t nearestplane;
float d1, d2;
vec3_t nearestpoint;
float neardist;
//expand the static capsule's height+radius by the mover's height+radius, so that its point+capsule instead
sr += mr;
sh += mh;
VectorSubtract(p1, p2, dir);
d2=VectorNormalize(dir);
CrossProduct(sup, dir, sright);
VectorNormalize(sright);
CrossProduct(sup, sright, nearestplane);
VectorNormalize(nearestplane);
nearestplane[3] = DotProduct(vec3_origin, nearestplane); //capsule is at 0 0 0
d1 = DotProduct(nearestplane, p1) - nearestplane[3];
d2 = DotProduct(nearestplane, p2) - nearestplane[3];
d2 = -d1 /(d1+d2);
VectorInterpolate(p1, d2, p2, nearestpoint);
neardist = VectorLength(nearestpoint);
if (neardist < sr)
{
float x, y, oz, nz;
//sqrt(h*h-(x*x+y*y))=z
//change the hypotenuse from the messed up value to the actual radius
//and update z to match the changed h
x = DotProduct(sup, nearestpoint) - 0;
y = DotProduct(sright, nearestpoint) - 0;
oz = DotProduct(nearestplane, nearestpoint) - nearestplane[3];
nz = sqrt(sr*sr - (x*x+y*y));
VectorMA(nearestpoint, nz-oz, dir, trace->endpos);
trace->fraction = 0;
}
}
return false;
}
model_t *World_CapsuleForBox(vec3_t mins, vec3_t maxs)
@ -1020,9 +1080,9 @@ static trace_t World_ClipMoveToEntity (world_t *w, wedict_t *ent, vec3_t eorg, v
model = NULL;
VectorSubtract (ent->v->mins, maxs, boxmins);
VectorSubtract (ent->v->maxs, mins, boxmaxs);
if (ent->xv->geomtype == GEOMTYPE_CAPSULE && !hitmodel)
model = World_CapsuleForBox(boxmins, boxmaxs);
else
// if (ent->xv->geomtype == GEOMTYPE_CAPSULE && !hitmodel)
// model = World_CapsuleForBox(boxmins, boxmaxs);
// else
World_HullForBox(boxmins, boxmaxs);
}