void ent_remove( gedict_t * t ) { if ( !t || t == world ) DebugTrap( "BUG BUG BUG remove world\n" ); if ( NUM_FOR_EDICT( t ) <= MAX_CLIENTS ) // debug G_Error ("remove client"); trap_remove( NUM_FOR_EDICT( t ) ); }
void SetTeamName( gedict_t * p ) { if ( p->isBot ) { if( p->team_no >0 && p->team_no <=4) trap_SetBotUserInfo(NUM_FOR_EDICT( p ),"team",team_names[p->team_no-1 ]); else trap_SetBotUserInfo(NUM_FOR_EDICT( p ),"team",""); }else stuffcmd( p, "team %s\n", GetTeamName( p->team_no ) ); }
void Bot_CL_KeyMove( ) { int forwardmove = 0, sidemove = 0, upmove = 0; int buttons = 0; buttons = ( ( self->s.v.button0 ) ? 1 : 0 ) + ( ( self->s.v.button2 ) ? 2 : 0 ); sidemove += self->maxstrafespeed * CL_KeyState( KEY_MOVERIGHT ); sidemove -= self->maxstrafespeed * CL_KeyState( KEY_MOVELEFT ); upmove += 200 * CL_KeyState( KEY_MOVEUP ); upmove -= 200 * CL_KeyState( KEY_MOVEDOWN ); forwardmove += self->maxfbspeed * CL_KeyState( KEY_MOVEFORWARD ); forwardmove -= self->maxfbspeed * CL_KeyState( KEY_MOVEBACK ); if ( self->s.v.v_angle[0] > 80 ) self->s.v.v_angle[0] = 80; else { if ( self->s.v.v_angle[0] < -70 ) self->s.v.v_angle[0] = -70; } //self->s.v.v_angle[2] = 0; self->s.v.v_angle[1] = anglemod( self->s.v.v_angle[1] ); trap_SetBotCMD( NUM_FOR_EDICT( self ), bot_frametime * 1000, PASSVEC3(self->s.v.v_angle), forwardmove, sidemove, upmove, buttons, self->s.v.impulse ); }
static void PF_putsaytime (progs_t *pr) { edict_t *client_ent; int e_num, tmp; client_ent = P_EDICT (pr, 0); e_num = NUM_FOR_EDICT (pr, client_ent); if (e_num <= MAX_CLIENTS && e_num >= 1) { tmp = svs.clients[e_num - 1].whensaidhead - fp_messages + 1; if (tmp < 0) tmp = 10 + tmp; if (svs.clients[e_num - 1].whensaid[tmp] && (realtime - svs.clients[e_num - 1].whensaid[tmp] < fp_persecond)) { svs.clients[e_num - 1].lockedtill = realtime + fp_secondsdead; return; } svs.clients[e_num - 1].whensaidhead++; if (svs.clients[e_num - 1].whensaidhead > 9) svs.clients[e_num - 1].whensaidhead = 0; svs.clients[e_num - 1].whensaid[svs.clients[e_num - 1].whensaidhead] = realtime; } }
int SV_PointContents(const CVec3 &p) { guard(SV_PointContents); // get base contents from world unsigned contents = CM_PointContents(p, 0); contents |= CM_PointModelContents(p); edict_t *list[MAX_EDICTS]; int num = SV_AreaEdicts(p, p, ARRAY_ARG(list), AREA_SOLID); for (int i = 0; i < num; i++) { edict_t *edict = list[i]; entityHull_t &ent = ents[NUM_FOR_EDICT(edict)]; if (ent.model) contents |= CM_TransformedPointContents(p, ent.model->headnode, edict->s.origin, ent.axis); else contents |= CM_TransformedPointContents(p, CM_HeadnodeForBox(ent.bounds), edict->s.origin, nullVec3); } return contents; unguard; }
/* * PF_GameCmd * * Sends the server command to clients. * If ent is NULL the command will be sent to all connected clients */ static void PF_GameCmd( edict_t *ent, const char *cmd ) { int i; client_t *client; if( !cmd || !cmd[0] ) return; if( !ent ) { for( i = 0, client = svs.clients; i < sv_maxclients->integer; i++, client++ ) { if( client->state < CS_SPAWNED ) continue; SV_AddGameCommand( client, cmd ); } } else { i = NUM_FOR_EDICT( ent ); if( i < 1 || i > sv_maxclients->integer ) return; client = svs.clients + ( i - 1 ); if( client->state < CS_SPAWNED ) return; SV_AddGameCommand( client, cmd ); } }
// 2000-05-02 NVS SVC by Maddes void PF_NVS_InitSVCMsg(void) { edict_t *ent; int entnum; client_t *client; client = NULL; ent = G_EDICT(OFS_PARM3); entnum = NUM_FOR_EDICT(ent); if (entnum == 0) // world means all clients { client = NULL; } else if (entnum < 1 || entnum > svs.maxclients) { PR_RunError ("PF_NVS_InitSVCMsg: entity not a client"); } else { client = &svs.clients[entnum-1]; } NVS_InitSVCMsg(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1), G_FLOAT(OFS_PARM2), client); }
/* ================ SV_SendServerinfo Sends the first message from the server to a connected client. This will be sent on the initial connection and upon each server load. ================ */ void SV_SendServerinfo (client_t *client) { char **s; char* message = Sys_BigStackAlloc(2048, "SV_SendServerinfo"); if (svs.maxclients > 1) { MSG_WriteByte(&client->message, svc_print); snprintf(message, sizeof(message), "\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n" "\n \01\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\03"); MSG_WriteString(&client->message, message); MSG_WriteByte(&client->message, svc_print); snprintf(message, sizeof(message), "\02\n \04ProQuake Server Version %4.2f\06" "\n \07\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\10\11", VERSION_PROQUAKE); MSG_WriteString(&client->message, message); } MSG_WriteByte (&client->message, svc_serverinfo); MSG_WriteLong (&client->message, PROTOCOL_NETQUAKE); MSG_WriteByte (&client->message, svs.maxclients); if (!coop.value && deathmatch.value) MSG_WriteByte (&client->message, GAME_DEATHMATCH); else MSG_WriteByte (&client->message, GAME_COOP); sprintf (message, pr_strings+sv.edicts->v.message); MSG_WriteString (&client->message,message); for (s = sv.model_precache+1 ; *s ; s++) MSG_WriteString (&client->message, *s); MSG_WriteByte (&client->message, 0); for (s = sv.sound_precache+1 ; *s ; s++) MSG_WriteString (&client->message, *s); MSG_WriteByte (&client->message, 0); // send music MSG_WriteByte (&client->message, svc_cdtrack); MSG_WriteByte (&client->message, sv.edicts->v.sounds); MSG_WriteByte (&client->message, sv.edicts->v.sounds); // set view MSG_WriteByte (&client->message, svc_setview); MSG_WriteShort (&client->message, NUM_FOR_EDICT(client->edict)); if (!pq_fullpitch.value && client->netconnection->proquake_connection != MOD_QSMACK) { // Ch0wW: Re-add it MSG_WriteByte(&client->message, svc_stufftext); MSG_WriteString(&client->message, "pq_fullpitch 0; cl_fullpitch 0\n"); } MSG_WriteByte (&client->message, svc_signonnum); MSG_WriteByte (&client->message, 1); client->sendsignon = true; client->spawned = false; // need prespawn, spawn, etc Sys_BigStackFree(2048, "SV_SendServerinfo"); }
// 2000-04-30 NVS HANDSHAKE SRV<->CL/QC<->CL by Maddes void Host_NVS_Request_f (void) { float value; if (cmd_source == src_command) // this a client remote only command { Con_Printf("%s is not valid from the console\n", Cmd_Argv(0)); return; } if (Cmd_Argc() < 2) // not enough arguments { SV_ClientPrintf("%s: not enough arguments\n", Cmd_Argv(0)); SV_ClientPrintf("Syntax: %s <version>\n", Cmd_Argv(0)); return; } Con_DPrintf("Server received NVS client version %s from client %i\n", Cmd_Argv(1), NUM_FOR_EDICT(host_client->edict)); // 2001-12-24 Keeping full backwards compatibility by Maddes start if (sv_compatibility->value) // do not reply, like the original Quake executable { return; } // 2001-12-24 Keeping full backwards compatibility by Maddes end // get and check value value = Q_atof(Cmd_Argv(1)); if (value < 0) { SV_ClientPrintf ("Only positive NVS versions are accepted.\n"); return; } // determine and store client NVS versions host_client->nvs_cmax = value; host_client->nvs_cclc = (value < MAX_NVS_VERSION) ? value : MAX_NVS_VERSION; host_client->nvs_csvc = (value < nvs_current_ssvc->value) ? value : nvs_current_ssvc->value; // check client against required version if (NVS_RejectClient()) { return; } // tell client the NVS versions, only when necessary or when client changes during a running game // NECESSARY (GOOD) HACK: This is a special case were not the client's SVC is of importance if (host_client->nvs_cclc || nvs_current_ssvc->value || host_client->spawned) { MSG_WriteByte (&host_client->message, svc_extra_version); MSG_WriteByte (&host_client->message, VERSION_NVS); MSG_WriteFloat (&host_client->message, nvs_current_ssvc->value); MSG_WriteFloat (&host_client->message, host_client->nvs_csvc); MSG_WriteFloat (&host_client->message, host_client->nvs_cclc); Con_DPrintf("Server sends NVS versions SSVC %1.2f CSVC %1.2f CCLC %1.2f to client %i\n", nvs_current_ssvc->value, host_client->nvs_csvc, host_client->nvs_cclc, NUM_FOR_EDICT(host_client->edict)); } }
void AddLinksToPmove ( areanode_t *node ) { link_t *l, *next; edict_t *check; int pl; int i; physent_t *pe; pl = EDICT_TO_PROG(sv_player); // touch linked edicts for (l = node->solid_edicts.next ; l != &node->solid_edicts ; l = next) { next = l->next; check = EDICT_FROM_AREA(l); if (check->v.owner == pl) continue; // player's own missile if (check->v.solid == SOLID_BSP || check->v.solid == SOLID_BBOX || check->v.solid == SOLID_SLIDEBOX) { if (check == sv_player) continue; for (i=0 ; i<3 ; i++) if (check->v.absmin[i] > pmove_maxs[i] || check->v.absmax[i] < pmove_mins[i]) break; if (i != 3) continue; if (pmove.numphysent == MAX_PHYSENTS) return; pe = &pmove.physents[pmove.numphysent]; pmove.numphysent++; VectorCopy (check->v.origin, pe->origin); pe->info = NUM_FOR_EDICT(check); if (check->v.solid == SOLID_BSP) pe->model = sv.models[(int)(check->v.modelindex)]; else { pe->model = NULL; VectorCopy (check->v.mins, pe->mins); VectorCopy (check->v.maxs, pe->maxs); } } } // recurse down both sides if (node->axis == -1) return; if ( pmove_maxs[node->axis] > node->dist ) AddLinksToPmove ( node->children[0] ); if ( pmove_mins[node->axis] < node->dist ) AddLinksToPmove ( node->children[1] ); }
/* ================ SV_SendServerInfo Sends the first message from the server to a connected client. This will be sent on the initial connection and upon each server load. ================ */ void SV_SendServerInfo (client_t *client) { char **s; char message[2048]; int i; //johnfitz MSG_WriteByte (&client->message, svc_print); sprintf (message, "%c\nfxQuake %4.2f SERVER (%i CRC)\n", 2, (float)VERSION, pr_crc); MSG_WriteString (&client->message,message); MSG_WriteByte (&client->message, svc_serverinfo); MSG_WriteLong (&client->message, sv.protocol); // use sv.protocol instead of PROTOCOL_NETQUAKE if (sv.protocol == PROTOCOL_RMQ) { // mh - now send protocol flags so that the client knows the protocol features to expect MSG_WriteLong (&client->message, sv.protocolflags); } MSG_WriteByte (&client->message, svs.maxclients); if (!coop.value && deathmatch.value) MSG_WriteByte (&client->message, GAME_DEATHMATCH); else MSG_WriteByte (&client->message, GAME_COOP); sprintf (message, "%s", pr_strings+sv.edicts->v.message); MSG_WriteString (&client->message,message); //johnfitz -- only send the first 256 model and sound precaches if protocol is 15 for (i=0,s = sv.model_precache+1 ; *s ; s++,i++) if (sv.protocol != PROTOCOL_NETQUAKE || i < 256) // MAX_MODELS for PROTOCOL_NETQUAKE MSG_WriteString (&client->message, *s); MSG_WriteByte (&client->message, 0); for (i=0,s = sv.sound_precache+1 ; *s ; s++,i++) if (sv.protocol != PROTOCOL_NETQUAKE || i < 256) // MAX_SOUNDS for PROTOCOL_NETQUAKE MSG_WriteString (&client->message, *s); MSG_WriteByte (&client->message, 0); //johnfitz // send music MSG_WriteByte (&client->message, svc_cdtrack); MSG_WriteByte (&client->message, sv.edicts->v.sounds); MSG_WriteByte (&client->message, sv.edicts->v.sounds); // set view MSG_WriteByte (&client->message, svc_setview); MSG_WriteShort (&client->message, NUM_FOR_EDICT(client->edict)); MSG_WriteByte (&client->message, svc_signonnum); MSG_WriteByte (&client->message, 1); client->sendsignon = true; client->spawned = false; // need prespawn, spawn, etc }
sizebuf_t *Game_MessageOne(ServerEntity_t *seMessage) { int iEntity; iEntity = NUM_FOR_EDICT(seMessage); if (iEntity < 1 || iEntity > svs.maxclients) Con_Error("Attempted to send message to a non-client! (%i) (%s)", iEntity, seMessage->v.cClassname); return &svs.clients[iEntity - 1].message; }
/* ============= SV_BuildClientFrame Decides which entities are going to be visible to the client, and copies off the playerstat and areabits. ============= */ void SV_BuildClientFrame( sv_client_t *cl ) { edict_t *ent; edict_t *clent; edict_t *viewent; // may be NULL client_frame_t *frame; entity_state_t *state; sv_ents_t frame_ents; int i; clent = cl->edict; viewent = cl->pViewEntity; sv.net_framenum++; // this is the frame we are creating frame = &cl->frames[sv.framenum & SV_UPDATE_MASK]; frame->senttime = svs.realtime; // save it for ping calc later // clear everything in this snapshot frame_ents.num_entities = c_fullsend = 0; Mem_Set( frame->areabits, 0, sizeof( frame->areabits )); if( !clent->pvServerData->client ) return; // not in game yet // grab the current player index frame->index = NUM_FOR_EDICT( clent ); // add all the entities directly visible to the eye, which // may include portal entities that merge other viewpoints SV_AddEntitiesToPacket( viewent, clent, frame, &frame_ents, false ); // if there were portals visible, there may be out of order entities // in the list which will need to be resorted for the delta compression // to work correctly. This also catches the error condition // of an entity being included twice. qsort( frame_ents.entities, frame_ents.num_entities, sizeof( frame_ents.entities[0] ), SV_EntityNumbers ); // copy the entity states out frame->num_entities = 0; frame->first_entity = svs.next_client_entities; for( i = 0; i < frame_ents.num_entities; i++ ) { ent = EDICT_NUM( frame_ents.entities[i] ); // add it to the circular client_entities array state = &svs.client_entities[svs.next_client_entities % svs.num_client_entities]; *state = ent->pvServerData->s; svs.next_client_entities++; // this should never hit, map should always be restarted first in SV_Frame if( svs.next_client_entities >= 0x7FFFFFFE ) Host_Error( "svs.next_client_entities wrapped (sv.time limit is out)\n" ); frame->num_entities++; } }
/* ================ SV_SendServerinfo Sends the first message from the server to a connected client. This will be sent on the initial connection and upon each server load. ================ */ void SV_SendServerinfo (client_t *client) { char **s; // >>> FIX: For Nintendo Wii using devkitPPC / libogc // Allocating in big stack. Stack in this device is pretty small: //char message[2048]; char* message = Sys_BigStackAlloc(2048, "SV_SendServerinfo"); // <<< FIX MSG_WriteByte (&client->message, svc_print); sprintf (message, "%c\nVERSION %4.2f SERVER (%i CRC)", 2, VERSION, pr_crc); MSG_WriteString (&client->message,message); MSG_WriteByte (&client->message, svc_serverinfo); MSG_WriteLong (&client->message, PROTOCOL_VERSION); MSG_WriteByte (&client->message, svs.maxclients); if (!coop.value && deathmatch.value) MSG_WriteByte (&client->message, GAME_DEATHMATCH); else MSG_WriteByte (&client->message, GAME_COOP); sprintf (message, pr_strings+sv.edicts->v.message); MSG_WriteString (&client->message,message); for (s = sv.model_precache+1 ; *s ; s++) MSG_WriteString (&client->message, *s); MSG_WriteByte (&client->message, 0); for (s = sv.sound_precache+1 ; *s ; s++) MSG_WriteString (&client->message, *s); MSG_WriteByte (&client->message, 0); // send music MSG_WriteByte (&client->message, svc_cdtrack); MSG_WriteByte (&client->message, sv.edicts->v.sounds); MSG_WriteByte (&client->message, sv.edicts->v.sounds); // set view MSG_WriteByte (&client->message, svc_setview); MSG_WriteShort (&client->message, NUM_FOR_EDICT(client->edict)); MSG_WriteByte (&client->message, svc_signonnum); MSG_WriteByte (&client->message, 1); client->sendsignon = true; client->spawned = false; // need prespawn, spawn, etc // >>> FIX: For Nintendo Wii using devkitPPC / libogc // Deallocating from previous fix: Sys_BigStackFree(2048, "SV_SendServerinfo"); // <<< FIX }
/* * SVC_FakeConnect * (Not a real out of band command) * A connection request that came from the game module */ int SVC_FakeConnect( char *fakeUserinfo, char *fakeSocketType, const char *fakeIP ) { int i; char userinfo[MAX_INFO_STRING]; client_t *cl, *newcl; netadr_t address; Com_DPrintf( "SVC_FakeConnect ()\n" ); if( !fakeUserinfo ) fakeUserinfo = ""; if( !fakeIP ) fakeIP = "127.0.0.1"; if( !fakeSocketType ) fakeIP = "loopback"; Q_strncpyz( userinfo, fakeUserinfo, sizeof( userinfo ) ); // force the IP key/value pair so the game can filter based on ip if( !Info_SetValueForKey( userinfo, "socket", fakeSocketType ) ) return -1; if( !Info_SetValueForKey( userinfo, "ip", fakeIP ) ) return -1; // find a client slot newcl = NULL; for( i = 0, cl = svs.clients; i < sv_maxclients->integer; i++, cl++ ) { if( cl->state == CS_FREE ) { newcl = cl; break; } } if( !newcl ) { Com_DPrintf( "Rejected a connection.\n" ); return -1; } NET_InitAddress( &address, NA_NOTRANSMIT ); // get the game a chance to reject this connection or modify the userinfo if( !SV_ClientConnect( NULL, &address, newcl, userinfo, -1, -1, qtrue, qfalse, 0, 0 ) ) { Com_DPrintf( "Game rejected a connection.\n" ); return -1; } // directly call the game begin function newcl->state = CS_SPAWNED; ge->ClientBegin( newcl->edict ); return NUM_FOR_EDICT( newcl->edict ); }
/* ================== SV_StartSound Each entity can have eight independant sound sources, like voice, weapon, feet, etc. Channel 0 is an auto-allocate channel, the others override anything allready running on that entity/channel pair. An attenuation of 0 will play full volume everywhere in the level. Larger attenuations will drop off. (max 4 attenuation) ================== */ void SV_StartSound (edict_t *entity, int channel, char *sample, int volume, float attenuation) { int sound_num; int field_mask; int i; int ent; if (volume < 0 || volume > 255) Sys_Error ("SV_StartSound: volume = %i", volume); if (attenuation < 0 || attenuation > 4) Sys_Error ("SV_StartSound: attenuation = %f", attenuation); if (channel < 0 || channel > 7) Sys_Error ("SV_StartSound: channel = %i", channel); if (sv.datagram.cursize > MAX_DATAGRAM-16) return; // find precache number for sound for (sound_num=1 ; sound_num<MAX_SOUNDS && sv.sound_precache[sound_num] ; sound_num++) if (!strcmp(sample, sv.sound_precache[sound_num])) break; if ( sound_num == MAX_SOUNDS || !sv.sound_precache[sound_num] ) { Con_Printf ("SV_StartSound: %s not precacheed\n", sample); return; } ent = NUM_FOR_EDICT(entity); channel = (ent<<3) | channel; field_mask = 0; if (volume != DEFAULT_SOUND_PACKET_VOLUME) field_mask |= SND_VOLUME; if (attenuation != DEFAULT_SOUND_PACKET_ATTENUATION) field_mask |= SND_ATTENUATION; // directed messages go only to the entity the are targeted on MSG_WriteByte (&sv.datagram, svc_sound); MSG_WriteByte (&sv.datagram, field_mask); if (field_mask & SND_VOLUME) MSG_WriteByte (&sv.datagram, volume); if (field_mask & SND_ATTENUATION) MSG_WriteByte (&sv.datagram, attenuation*64); MSG_WriteShort (&sv.datagram, channel); MSG_WriteByte (&sv.datagram, sound_num); for (i=0 ; i<3 ; i++) MSG_WriteCoord (&sv.datagram, entity->v.origin[i]+0.5*(entity->v.mins[i]+entity->v.maxs[i])); }
/* ================ SV_SendServerinfo Sends the first message from the server to a connected client. This will be sent on the initial connection and upon each server load. ================ */ void SV_SendServerinfo(client_t *client) { char **s; char message[2048]; MSG_WriteByte(&client->message, svc_print); sprintf(message, "%c\nVERSION %4.2f SERVER (%i CRC)", 2, VERSION, pr_crc); MSG_WriteString(&client->message,message); MSG_WriteByte(&client->message, svc_serverinfo); MSG_WriteLong(&client->message, PROTOCOL_VERSION); MSG_WriteByte(&client->message, svs.maxclients); if (!coop.value && deathmatch.value) { MSG_WriteByte(&client->message, GAME_DEATHMATCH); } else { MSG_WriteByte(&client->message, GAME_COOP); } sprintf(message, pr_strings+sv.edicts->v.message); MSG_WriteString(&client->message,message); for (s = sv.model_precache+1 ; *s ; s++) { MSG_WriteString(&client->message, *s); } MSG_WriteByte(&client->message, 0); for (s = sv.sound_precache+1 ; *s ; s++) { MSG_WriteString(&client->message, *s); } MSG_WriteByte(&client->message, 0); // send music MSG_WriteByte(&client->message, svc_cdtrack); MSG_WriteByte(&client->message, sv.edicts->v.sounds); MSG_WriteByte(&client->message, sv.edicts->v.sounds); // set view MSG_WriteByte(&client->message, svc_setview); MSG_WriteShort(&client->message, NUM_FOR_EDICT(client->edict)); MSG_WriteByte(&client->message, svc_signonnum); MSG_WriteByte(&client->message, 1); client->sendsignon = true; client->spawned = false; // need prespawn, spawn, etc }
gedict_t *nextent( gedict_t * ent ) { int entn; if ( !ent ) G_Error( "find: NULL start\n" ); entn = trap_nextent( NUM_FOR_EDICT( ent ) ); if ( entn ) return &g_edicts[entn]; else return NULL; }
void CenterPrint( gedict_t * pl, const char *fmt, ... ) { va_list argptr; char text[16000]; va_start( argptr, fmt ); _vsnprintf( text, sizeof(text), fmt, argptr ); va_end( argptr ); trap_CenterPrint( NUM_FOR_EDICT( pl ), text ); pl->StatusRefreshTime = g_globalvars.time + 1.5; }
void botDisconnect( gedict_t * te ) { gedict_t *oself; if ( !te->isBot ) { G_bprint( 2, "WARNING!!! Trying to disconnect non bot client\n" ); return; } oself = self; self = te; trap_RemoveBot( NUM_FOR_EDICT( te ) ); self = oself; }
/* For debugging */ void Edict_Print(ServerEntity_t *eEntity) { #if 0 int l; ddef_t *d; int *v,i,j,type; char *name; for (i=1 ; i<progs->numfielddefs ; i++) { d = &pr_fielddefs[i]; name = pr_strings + d->s_name; if(name[strlen(name)-2] == '_') continue; // skip _x, _y, _z vars v = (int *)((char *)&ed->v + d->ofs*4); // if the value is still all 0, skip the field type = d->type & ~DEF_SAVEGLOBAL; for (j=0 ; j<type_size[type] ; j++) if (v[j]) break; if (j == type_size[type]) continue; Con_Printf("%s",name); //johnfitz -- was Con_Printf l = Q_strlen(name); while (l++ < 15) Con_Printf(" "); //johnfitz -- was Con_Printf Con_Printf("%s\n",PR_ValueString((EntityType_t)d->type,(eval_t *)v)); //johnfitz -- was Con_Printf } #else int i; if(eEntity->free) { Con_Printf("Entity is free!\n"); return; } Con_Printf("\nEDICT %i:\n",NUM_FOR_EDICT(eEntity)); for (i = 1; i < sizeof(ServerEntity_t); i++) { } #endif }
/* ================ SV_SendServerinfo Sends the first message from the server to a connected client. This will be sent on the initial connection and upon each server load. ================ */ void SV_SendServerinfo (client_t *client) { const char **s; char message[2048]; int i; //johnfitz MSG_WriteByte (&client->message, svc_print); sprintf (message, "%c\nFITZQUAKE %1.2f SERVER (%i CRC)\n", 2, FITZQUAKE_VERSION, pr_crc); //johnfitz -- include fitzquake version MSG_WriteString (&client->message,message); MSG_WriteByte (&client->message, svc_serverinfo); MSG_WriteLong (&client->message, sv.protocol); //johnfitz -- sv.protocol instead of PROTOCOL_VERSION MSG_WriteByte (&client->message, svs.maxclients); if (!coop.value && deathmatch.value) MSG_WriteByte (&client->message, GAME_DEATHMATCH); else MSG_WriteByte (&client->message, GAME_COOP); MSG_WriteString (&client->message, PR_GetString(sv.edicts->v.message)); //johnfitz -- only send the first 256 model and sound precaches if protocol is 15 for (i=0,s = sv.model_precache+1 ; *s; s++,i++) if (sv.protocol != PROTOCOL_NETQUAKE || i < 256) MSG_WriteString (&client->message, *s); MSG_WriteByte (&client->message, 0); for (i=0,s = sv.sound_precache+1 ; *s ; s++,i++) if (sv.protocol != PROTOCOL_NETQUAKE || i < 256) MSG_WriteString (&client->message, *s); MSG_WriteByte (&client->message, 0); //johnfitz // send music MSG_WriteByte (&client->message, svc_cdtrack); MSG_WriteByte (&client->message, sv.edicts->v.sounds); MSG_WriteByte (&client->message, sv.edicts->v.sounds); // set view MSG_WriteByte (&client->message, svc_setview); MSG_WriteShort (&client->message, NUM_FOR_EDICT(client->edict)); MSG_WriteByte (&client->message, svc_signonnum); MSG_WriteByte (&client->message, 1); client->sendsignon = true; client->spawned = false; // need prespawn, spawn, etc }
/* PF_getuid float(entity client) getuid */ static void PF_getuid (progs_t *pr) { edict_t *client_ent; int e_num; float retval = 0; client_ent = P_EDICT (pr, 0); e_num = NUM_FOR_EDICT (pr, client_ent); if (e_num <= MAX_CLIENTS && e_num >= 1) retval = (float) svs.clients[e_num - 1].userid; R_FLOAT (pr) = retval; }
/* ============ PR_ValueString Returns a string describing *data in a type specific manner ============= */ char *PR_ValueString (etype_t type, eval_t *val) { static char line[256]; ddef_t *def; dfunction_t *f; int type_t = (int)type; type_t &= ~DEF_SAVEGLOBAL; type = (etype_t)type_t; switch (type) { case ev_string: sprintf (line, "%s", pr_strings + val->string); break; case ev_entity: sprintf (line, "entity %i", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)) ); break; case ev_function: f = pr_functions + val->function; sprintf (line, "%s()", pr_strings + f->s_name); break; case ev_field: def = ED_FieldAtOfs ( val->_int ); sprintf (line, ".%s", pr_strings + def->s_name); break; case ev_void: sprintf (line, "void"); break; case ev_float: sprintf (line, "%5.1f", val->_float); break; case ev_vector: sprintf (line, "'%5.1f %5.1f %5.1f'", val->vector[0], val->vector[1], val->vector[2]); break; case ev_pointer: sprintf (line, "pointer"); break; default: sprintf (line, "bad type %i", type); break; } return line; }
/* ================ SV_CheckAllEnts ================ */ void SV_CheckAllEnts( void ) { edict_t *e; int i; if( !sv_check_errors->integer || sv.state != ss_active ) return; // check edicts errors for( i = svgame.globals->maxClients + 1; i < svgame.numEntities; i++ ) { e = EDICT_NUM( i ); // DEBUG: check 'gamestate' for using by mods if( e->v.gamestate != 0 ) { MsgDev( D_INFO, "Entity %s[%i] uses gamestate %i\n", SV_ClassName( e ), NUM_FOR_EDICT( e ), e->v.gamestate ); } if( e->free && e->pvPrivateData != NULL ) { MsgDev( D_ERROR, "Freed entity %s (%i) has private data.\n", SV_ClassName( e ), i ); continue; } if( !SV_IsValidEdict( e )) continue; if( !e->v.pContainingEntity || e->v.pContainingEntity != e ) { MsgDev( D_ERROR, "Entity %s (%i) has invalid container, fixed.\n", SV_ClassName( e ), i ); e->v.pContainingEntity = e; continue; } if( !e->pvPrivateData || !Mem_IsAllocatedExt( svgame.mempool, e->pvPrivateData )) { MsgDev( D_ERROR, "Entity %s (%i) trashed private data.\n", SV_ClassName( e ), i ); e->pvPrivateData = NULL; continue; } SV_CheckVelocity( e ); } }
/* * PF_DropClient */ static void PF_DropClient( edict_t *ent, int type, const char *message ) { int p; client_t *drop; if( !ent ) return; p = NUM_FOR_EDICT( ent ); if( p < 1 || p > sv_maxclients->integer ) return; drop = svs.clients + ( p-1 ); if( message ) SV_DropClient( drop, type, "%s", message ); else SV_DropClient( drop, type, NULL ); }
/** * This function is used to cycle thro all avaliable clients * (this is just a recoded PF_nextent) */ edict_t *Nextent(edict_t *edict) { int e; edict_t *ent; e = NUM_FOR_EDICT(edict); // Get the edictnum while (true) { // Loop until we get a return e++; // Increase e with 1 if (e == sv.num_edicts) // If gone through all edict's return sv.edicts; // then return ent = EDICT_NUM(e); // Get the edict from the new edictnum if (!ent->free) // If it exists return ent; // then return it } }
/* ============= ED_Print For debugging ============= */ void ED_Print (edict_t *ed) { ddef_t *d; int *v; int i, j, l; const char *name; int type; if (ed->free) { Con_Printf ("FREE\n"); return; } Con_SafePrintf("\nEDICT %i:\n", NUM_FOR_EDICT(ed)); //johnfitz -- was Con_Printf for (i = 1; i < progs->numfielddefs; i++) { d = &pr_fielddefs[i]; name = PR_GetString(d->s_name); l = strlen (name); if (l > 1 && name[l - 2] == '_') continue; // skip _x, _y, _z vars v = (int *)((char *)&ed->v + d->ofs*4); // if the value is still all 0, skip the field type = d->type & ~DEF_SAVEGLOBAL; for (j = 0; j < type_size[type]; j++) { if (v[j]) break; } if (j == type_size[type]) continue; Con_SafePrintf ("%s", name); //johnfitz -- was Con_Printf while (l++ < 15) Con_SafePrintf (" "); //johnfitz -- was Con_Printf Con_SafePrintf ("%s\n", PR_ValueString(d->type, (eval_t *)v)); //johnfitz -- was Con_Printf } }
/* ============= ED_Print For debugging ============= */ void ED_Print (edict_t *ed) { int l; ddef_t *d; int *v; int i, j; char *name; int type; if (ed->free) { Con_Printf ("FREE\n"); return; } Con_Printf("\nEDICT %i:\n", NUM_FOR_EDICT(ed)); for (i=1 ; i<progs->numfielddefs ; i++) { d = &pr_fielddefs[i]; name = pr_strings + d->s_name; if (name[strlen(name)-2] == '_') continue; // skip _x, _y, _z vars v = (int *)((char *)&ed->v + d->ofs*4); // if the value is still all 0, skip the field type = d->type & ~DEF_SAVEGLOBAL; for (j=0 ; j<type_size[type] ; j++) if (v[j]) break; if (j == type_size[type]) continue; Con_Printf ("%s",name); l = strlen (name); while (l++ < 15) Con_Printf (" "); Con_Printf ("%s\n", PR_ValueString((etype_t)d->type, (eval_t *)v)); } }
static void PF_mutedtime (progs_t *pr) { edict_t *client_ent; int e_num; float retval = 0; client_ent = P_EDICT (pr, 0); e_num = NUM_FOR_EDICT (pr, client_ent); if (e_num <= MAX_CLIENTS && e_num > 0) { if (realtime >= svs.clients[e_num - 1].lockedtill) retval = (float) 0; else retval = (float) svs.clients[e_num - 1].lockedtill - realtime; } R_FLOAT (pr) = retval; }