Q3 server works a bit better now.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@1265 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2005-08-30 00:13:56 +00:00
parent 02ba159623
commit a81732a8e0
1 changed files with 129 additions and 50 deletions

View File

@ -31,6 +31,8 @@ q3entityState_t *q3_baselines;
#define SENTITY_FOR_GENTITY(ge) (SENTITY_FOR_NUM(NUM_FOR_GENTITY(ge))) #define SENTITY_FOR_GENTITY(ge) (SENTITY_FOR_NUM(NUM_FOR_GENTITY(ge)))
#define GENTITY_FOR_SENTITY(se) (GENTITY_FOR_NUM(NUM_FOR_SENTITY(se))) #define GENTITY_FOR_SENTITY(se) (GENTITY_FOR_NUM(NUM_FOR_SENTITY(se)))
static qboolean BoundsIntersect (vec3_t mins1, vec3_t maxs1, vec3_t mins2, vec3_t maxs2);
void SVQ3_CreateBaseline(void); void SVQ3_CreateBaseline(void);
char *mapentspointer; char *mapentspointer;
@ -285,8 +287,7 @@ int SVQ3_EntitiesInBoxNode(areanode_t *node, vec3_t mins, vec3_t maxs, int *list
q3serverEntity_t *sent; q3serverEntity_t *sent;
q3sharedEntity_t *gent; q3sharedEntity_t *gent;
int linkcount = 0, ln; int linkcount = 0;
float d1, d2;
//work out who they are first. //work out who they are first.
for (l = node->solid_edicts.next ; l != &node->solid_edicts ; l = next) for (l = node->solid_edicts.next ; l != &node->solid_edicts ; l = next)
@ -329,9 +330,10 @@ void SVQ3_Trace(q3trace_t *result, vec3_t start, vec3_t mins, vec3_t maxs, vec3_
int contactlist[128]; int contactlist[128];
trace_t tr; trace_t tr;
vec3_t mmins, mmaxs; vec3_t mmins, mmaxs;
int i, contactcount; int i;
q3entityShared_t *es; q3sharedEntity_t *es;
model_t *mod; model_t *mod;
int ourowner;
if (!mins) if (!mins)
mins = vec3_origin; mins = vec3_origin;
@ -365,17 +367,48 @@ void SVQ3_Trace(q3trace_t *result, vec3_t start, vec3_t mins, vec3_t maxs, vec3_
} }
} }
if ( entnum != ENTITYNUM_WORLD )
{
ourowner = GENTITY_FOR_NUM(entnum)->r.ownerNum;
if (ourowner == ENTITYNUM_WORLD)
ourowner = -1;
}
else
ourowner = -1;
for (i = SVQ3_EntitiesInBox(mmins, mmaxs, contactlist, sizeof(contactlist)/sizeof(contactlist[0]))-1; i >= 0; i--) for (i = SVQ3_EntitiesInBox(mmins, mmaxs, contactlist, sizeof(contactlist)/sizeof(contactlist[0]))-1; i >= 0; i--)
{ {
if (contactlist[i] == entnum) if (contactlist[i] == entnum)
continue; //don't collide with self. continue; //don't collide with self.
es = GENTITY_FOR_NUM(contactlist[i]); es = GENTITY_FOR_NUM(contactlist[i]);
if (es->bmodel) if (!(es->r.contents & contentmask))
mod = Mod_ForName(va("*%i", es->s.modelindex), true); continue;
if (entnum != ENTITYNUM_WORLD)
{
// if (contactlist[i] == entnum)
// continue; // don't clip against the pass entity
// if (es->r.ownerNum == entnum)
// continue; // don't clip against own missiles
// if (es->r.ownerNum == ourowner)
// continue; // don't clip against other missiles from our owner
}
if (es->r.bmodel)
{
mod = Mod_ForName(va("*%i", es->s.modelindex), false);
if (mod->needload)
continue;
tr = CM_TransformedBoxTrace(mod, start, end, mins, maxs, 0xffffffff, es->r.currentOrigin, vec3_origin);
}
else else
mod = CM_TempBoxModel(es->mins, es->maxs); {
tr = CM_TransformedBoxTrace(mod, start, mins, mmins, mmaxs, contentmask, es->currentOrigin, es->currentAngles); mod = CM_TempBoxModel(es->r.mins, es->r.maxs);
tr = CM_TransformedBoxTrace(mod, start, end, mins, maxs, 0xffffffff, es->r.currentOrigin, es->r.currentAngles);
// mod->funcs.Trace(mod, 0, 0, start, end, mins, maxs, &tr);
}
if (tr.fraction < result->fraction) if (tr.fraction < result->fraction)
{ {
result->allsolid = tr.allsolid; result->allsolid = tr.allsolid;
@ -384,7 +417,7 @@ void SVQ3_Trace(q3trace_t *result, vec3_t start, vec3_t mins, vec3_t maxs, vec3_
result->entityNum = contactlist[i]; result->entityNum = contactlist[i];
result->fraction = tr.fraction; result->fraction = tr.fraction;
result->plane = tr.plane; result->plane = tr.plane;
result->startsolid = tr.startsolid; result->startsolid |= tr.startsolid;
// if (tr.surface) // if (tr.surface)
// result->surfaceFlags = tr.surface->flags; // result->surfaceFlags = tr.surface->flags;
// else // else
@ -393,20 +426,24 @@ void SVQ3_Trace(q3trace_t *result, vec3_t start, vec3_t mins, vec3_t maxs, vec3_
} }
} }
int SVQ3_Contact(vec3_t mins, vec3_t maxs, q3entityShared_t *ent) int SVQ3_Contact(vec3_t mins, vec3_t maxs, q3sharedEntity_t *ent)
{ {
/* model_t *mod; model_t *mod;
vec3_t org;
trace_t tr; trace_t tr;
VectorSubtract(maxs, mins, org); if (!ent->s.modelindex || ent->r.bmodel)
VectorMA(mins, 0.5, org, org); mod = CM_TempBoxModel(ent->r.mins, ent->r.maxs);
mod = Mod_ForName(va("*%i", ent->s.modelindex), false); else
mod->funcs.Trace(mod, 0, 0, org, org, mins, maxs, &tr); mod = Mod_ForName(va("*%i", ent->s.modelindex), false);
if (tr.startsolid)*/ if (mod->needload || !mod->funcs.Trace)
return false;
mod->funcs.Trace(mod, 0, 0, vec3_origin, vec3_origin, mins, maxs, &tr);
if (tr.startsolid)
return true; return true;
// return false; return false;
} }
void SVQ3_SetBrushModel(q3sharedEntity_t *ent, char *modelname) void SVQ3_SetBrushModel(q3sharedEntity_t *ent, char *modelname)
@ -473,7 +510,7 @@ void SVQ3_SendServerCommand(client_t *cl, char *str)
} }
cl->num_server_commands++; cl->num_server_commands++;
Q_strncpyz(cl->server_commands[cl->num_server_commands], str, sizeof(cl->server_commands[0])); Q_strncpyz(cl->server_commands[cl->num_server_commands & TEXTCMD_MASK], str, sizeof(cl->server_commands[0]));
} }
void SVQ3_SetConfigString(int num, char *string) void SVQ3_SetConfigString(int num, char *string)
@ -581,6 +618,48 @@ long Q3G_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
Q_strncpyz(VM_POINTER(arg[1]), Cmd_Argv(VM_LONG(arg[0])), VM_LONG(arg[2])); Q_strncpyz(VM_POINTER(arg[1]), Cmd_Argv(VM_LONG(arg[0])), VM_LONG(arg[2]));
break; break;
case G_FS_FOPEN_FILE: //fopen
if ((int)arg[1] + 4 >= mask || VM_POINTER(arg[1]) < offset)
break; //out of bounds.
VM_LONG(ret) = VMUI_fopen(VM_POINTER(arg[0]), VM_POINTER(arg[1]), VM_LONG(arg[2]), 0);
break;
case G_FS_READ: //fread
if ((int)arg[0] + VM_LONG(arg[1]) >= mask || VM_POINTER(arg[0]) < offset)
break; //out of bounds.
VMUI_FRead(VM_POINTER(arg[0]), VM_LONG(arg[1]), VM_LONG(arg[2]), 0);
break;
case G_FS_WRITE: //fwrite
break;
case G_FS_FCLOSE_FILE: //fclose
VMUI_fclose(VM_LONG(arg[0]), 0);
break;
/* case G_FS_GETFILELIST: //fs listing
if ((int)arg[2] + arg[3] >= mask || VM_POINTER(arg[2]) < offset)
break; //out of bounds.
{
vmsearch_t vms;
vms.initialbuffer = vms.buffer = VM_POINTER(arg[2]);
vms.skip = strlen(VM_POINTER(arg[0]))+1;
vms.bufferleft = arg[3];
vms.found=0;
if (*(char *)VM_POINTER(arg[0]) == '$')
{
extern char com_basedir[];
vms.skip=0;
Sys_EnumerateFiles(com_basedir, "*", VMEnumMods, &vms);
}
else if (*(char *)VM_POINTER(arg[1]) == '.' || *(char *)VM_POINTER(arg[1]) == '/')
COM_EnumerateFiles(va("%s/*%s", VM_POINTER(arg[0]), VM_POINTER(arg[1])), VMEnum, &vms);
else
COM_EnumerateFiles(va("%s/*.%s", VM_POINTER(arg[0]), VM_POINTER(arg[1])), VMEnum, &vms);
VM_LONG(ret) = vms.found;
}
break;*/
case G_LOCATE_GAME_DATA: // ( gentity_t *gEnts, int numGEntities, int sizeofGEntity_t, 15 case G_LOCATE_GAME_DATA: // ( gentity_t *gEnts, int numGEntities, int sizeofGEntity_t, 15
// playerState_t *clients, int sizeofGameClient ); // playerState_t *clients, int sizeofGameClient );
@ -597,6 +676,8 @@ long Q3G_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
break; break;
case G_SEND_SERVER_COMMAND: // ( int clientNum, const char *fmt, ... ); 17 case G_SEND_SERVER_COMMAND: // ( int clientNum, const char *fmt, ... ); 17
Con_DPrintf("Game dispatching %s\n", VM_POINTER(arg[1]));
if (VM_LONG(arg[0]) == -1) if (VM_LONG(arg[0]) == -1)
{ //broadcast { //broadcast
SVQ3_SendServerCommand(NULL, VM_POINTER(arg[1])); SVQ3_SendServerCommand(NULL, VM_POINTER(arg[1]));
@ -653,7 +734,7 @@ long Q3G_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
return SVQ3_EntitiesInBox(VM_POINTER(arg[0]), VM_POINTER(arg[1]), VM_POINTER(arg[2]), VM_LONG(arg[3])); return SVQ3_EntitiesInBox(VM_POINTER(arg[0]), VM_POINTER(arg[1]), VM_POINTER(arg[2]), VM_LONG(arg[3]));
break; break;
case G_POINT_CONTENTS: case G_POINT_CONTENTS:
return sv.worldmodel->funcs.PointContents(sv.worldmodel, VM_POINTER(arg[0])); return CM_PointContents(sv.worldmodel, VM_POINTER(arg[0]));
break; break;
case G_SET_BRUSH_MODEL: //ent, name case G_SET_BRUSH_MODEL: //ent, name
VALIDATEPOINTER(arg[0], sizeof(q3sharedEntity_t)); VALIDATEPOINTER(arg[0], sizeof(q3sharedEntity_t));
@ -667,7 +748,7 @@ long Q3G_SystemCallsEx(void *offset, unsigned int mask, int fn, const long *arg)
mapentspointer = COM_ParseOut(mapentspointer, VM_POINTER(arg[0]), arg[1]); mapentspointer = COM_ParseOut(mapentspointer, VM_POINTER(arg[0]), arg[1]);
return !!mapentspointer; return !!mapentspointer;
case G_REAL_TIME: // 42 case G_REAL_TIME: // 41
Con_Printf("builtin %i is not implemented\n", fn); Con_Printf("builtin %i is not implemented\n", fn);
return 0; return 0;
case G_SNAPVECTOR: case G_SNAPVECTOR:
@ -767,20 +848,13 @@ void SVQ3_ShutdownGame(void)
qboolean SVQ3_InitGame(void) qboolean SVQ3_InitGame(void)
{ {
int i; char buffer[8192];
if (sv.worldmodel->fromgame == fg_quake) if (sv.worldmodel->fromgame == fg_quake)
return false; //always fail on q1bsp return false; //always fail on q1bsp
//clear out the configstrings
for (i = 0; i < MAX_CONFIGSTRINGS; i++) SVQ3_ShutdownGame();
{
if (svq3_configstrings[i])
{
Z_Free(svq3_configstrings[i]);
svq3_configstrings[i] = NULL;
}
}
q3gamevm = VM_Create(NULL, "vm/qagame", Q3G_SystemCalls, Q3G_SystemCallsEx); q3gamevm = VM_Create(NULL, "vm/qagame", Q3G_SystemCalls, Q3G_SystemCallsEx);
@ -791,9 +865,12 @@ qboolean SVQ3_InitGame(void)
q3_sentities = Z_Malloc(sizeof(q3serverEntity_t)*MAX_GENTITIES); q3_sentities = Z_Malloc(sizeof(q3serverEntity_t)*MAX_GENTITIES);
svq3_configstrings[0] = Z_Malloc(strlen(svs.info)+1 + 9+strlen(sv.name)+16); strcpy(buffer, svs.info);
strcpy(svq3_configstrings[0], svs.info); Info_SetValueForKey(buffer, "map", "", sizeof(buffer));
Info_SetValueForKey(svq3_configstrings[0], "mapname", sv.name, MAX_SERVERINFO_STRING); Info_SetValueForKey(buffer, "maxclients", "", sizeof(buffer));
Info_SetValueForKey(buffer, "mapname", sv.name, sizeof(buffer));
Info_SetValueForKey(buffer, "sv_maxclients", "32", sizeof(buffer));
SVQ3_SetConfigString(0, buffer);
svq3_configstrings[1] = Z_Malloc(32); svq3_configstrings[1] = Z_Malloc(32);
Info_SetValueForKey(svq3_configstrings[1], "sv_serverid", va("%i", svs.spawncount), MAX_SERVERINFO_STRING); Info_SetValueForKey(svq3_configstrings[1], "sv_serverid", va("%i", svs.spawncount), MAX_SERVERINFO_STRING);
@ -814,7 +891,7 @@ qboolean SVQ3_InitGame(void)
void SVQ3_RunFrame(void) void SVQ3_RunFrame(void)
{ {
VM_Call(q3gamevm, GAME_RUN_FRAME, sv.framenum*100); VM_Call(q3gamevm, GAME_RUN_FRAME, (int)(sv.time*1000));
} }
void SVQ3_ClientCommand(client_t *cl) void SVQ3_ClientCommand(client_t *cl)
@ -952,6 +1029,7 @@ void SVQ3_WriteSnapshotToClient(client_t *client, sizebuf_t *msg)
// not fully in game yet // not fully in game yet
delta = 0; delta = 0;
oldsnap = NULL; oldsnap = NULL;
return;
} }
else if(client->delta_sequence < 0) else if(client->delta_sequence < 0)
{ {
@ -988,7 +1066,7 @@ void SVQ3_WriteSnapshotToClient(client_t *client, sizebuf_t *msg)
// write snapshot header // write snapshot header
MSG_WriteBits(msg, svcq3_snapshot, 8); MSG_WriteBits(msg, svcq3_snapshot, 8);
MSG_WriteBits(msg, sv.framenum*100, 32); MSG_WriteBits(msg, (int)(sv.time*1000), 32);
MSG_WriteBits(msg, delta, 8); // what we are delta'ing from MSG_WriteBits(msg, delta, 8); // what we are delta'ing from
// write snapFlags // write snapFlags
@ -1004,7 +1082,6 @@ void SVQ3_WriteSnapshotToClient(client_t *client, sizebuf_t *msg)
// delta encode the entities // delta encode the entities
SVQ3_EmitPacketEntities(client, oldsnap, snap, msg); SVQ3_EmitPacketEntities(client, oldsnap, snap, msg);
// MSG_WriteBits( msg, ENTITYNUM_NONE, GENTITYNUM_BITS );
// while( msg.cursize < sv_padPackets->integer ) { // FIXME? // while( msg.cursize < sv_padPackets->integer ) { // FIXME?
// for( i=0 ; i<sv_padPackets->integer ; i++ ) // for( i=0 ; i<sv_padPackets->integer ; i++ )
@ -1164,7 +1241,7 @@ void SVQ3_BuildClientSnapshot( client_t *client )
org[2] += ps->viewheight; org[2] += ps->viewheight;
clientarea = CM_PointLeafnum(sv.worldmodel, org); clientarea = CM_PointLeafnum(sv.worldmodel, org);
bitvector = sv.worldmodel->funcs.LeafPVS(sv.worldmodel, sv.worldmodel->funcs.LeafnumForPoint(sv.worldmodel, org), clientarea); bitvector = sv.worldmodel->funcs.LeafPVS(sv.worldmodel, sv.worldmodel->funcs.LeafnumForPoint(sv.worldmodel, org), NULL);
clientarea = CM_LeafArea(sv.worldmodel, clientarea); clientarea = CM_LeafArea(sv.worldmodel, clientarea);
/* /*
if( client->areanum != clientarea ) { if( client->areanum != clientarea ) {
@ -1260,12 +1337,12 @@ void SVQ3_BuildClientSnapshot( client_t *client )
} }
/*
for (i = 0; i < snap->areabytes;i++) for (i = 0; i < snap->areabytes;i++)
{ //fix areabits, q2->q3 style.. { //fix areabits, q2->q3 style..
snap->areabits[i]^=255; snap->areabits[i]^=255;
} }
*/
} }
@ -1524,7 +1601,6 @@ void SVQ3_ParseUsercmd(client_t *client, qboolean delta)
from = &nullcmd; from = &nullcmd;
for(i=0, to=commands; i<cmdCount; i++, to++) for(i=0, to=commands; i<cmdCount; i++, to++)
{ {
memcpy(to, from, sizeof(*to));
MSG_Q3_ReadDeltaUsercmd(key, from, to); MSG_Q3_ReadDeltaUsercmd(key, from, to);
from = to; from = to;
} }
@ -1541,8 +1617,8 @@ void SVQ3_ParseUsercmd(client_t *client, qboolean delta)
// run G_ClientThink() on each usercmd // run G_ClientThink() on each usercmd
for(i=0,to=commands; i<cmdCount; i++, to++) for(i=0,to=commands; i<cmdCount; i++, to++)
{ {
if(to->servertime <= client->lastcmd.servertime ) // if(to->servertime <= client->lastcmd.servertime )
continue; // continue;
memcpy( &client->lastcmd, to, sizeof(client->lastcmd)); memcpy( &client->lastcmd, to, sizeof(client->lastcmd));
SVQ3_ClientThink(client); SVQ3_ClientThink(client);
@ -1554,15 +1630,19 @@ void SVQ3_ParseUsercmd(client_t *client, qboolean delta)
} }
void SVQ3_UpdateUserinfo_f(void) void SVQ3_UpdateUserinfo_f(client_t *cl)
{ {
Q_strncpyz( host_client->userinfo, Cmd_Argv(1), sizeof(host_client->userinfo) ); Q_strncpyz( cl->userinfo, Cmd_Argv(1), sizeof(cl->userinfo) );
SV_ExtractFromUserinfo (host_client); SV_ExtractFromUserinfo (cl);
VM_Call(q3gamevm, GAME_CLIENT_USERINFO_CHANGED, host_client-svs.clients); VM_Call(q3gamevm, GAME_CLIENT_USERINFO_CHANGED, cl-svs.clients);
} }
void SVQ3_Drop_f(client_t *cl)
{
SV_DropClient(cl);
}
typedef struct ucmd_s { typedef struct ucmd_s {
char *name; char *name;
@ -1571,7 +1651,7 @@ typedef struct ucmd_s {
static const ucmd_t ucmds[] = { static const ucmd_t ucmds[] = {
{ "userinfo", SVQ3_UpdateUserinfo_f}, { "userinfo", SVQ3_UpdateUserinfo_f},
{ "disconnect", NULL},//SV_Disconnect_f }, { "disconnect", SVQ3_Drop_f},//SV_Disconnect_f },
// TODO // TODO
{ "cp", NULL }, { "cp", NULL },
@ -1640,7 +1720,7 @@ void SVQ3_ParseClientCommand(client_t *client)
void SVQ3_ParseClientMessage(client_t *client) void SVQ3_ParseClientMessage(client_t *client)
{ {
int serverid; //sorta like the level number. int serverid; //sorta like the level number.
int c, last; int c;
host_client = client; host_client = client;
@ -1697,7 +1777,6 @@ void SVQ3_ParseClientMessage(client_t *client)
return; return;
} }
last = c;
c = MSG_ReadBits(8); c = MSG_ReadBits(8);
if (c == clcq3_eom) if (c == clcq3_eom)
{ {