Home | History | Annotate | Download | only in server
      1 /*
      2 Copyright (C) 1996-1997 Id Software, Inc.
      3 
      4 This program is free software; you can redistribute it and/or
      5 modify it under the terms of the GNU General Public License
      6 as published by the Free Software Foundation; either version 2
      7 of the License, or (at your option) any later version.
      8 
      9 This program is distributed in the hope that it will be useful,
     10 but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     12 
     13 See the GNU General Public License for more details.
     14 
     15 You should have received a copy of the GNU General Public License
     16 along with this program; if not, write to the Free Software
     17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     18 
     19 */
     20 
     21 #include "qwsvdef.h"
     22 
     23 server_static_t	svs;				// persistant server info
     24 server_t		sv;					// local server
     25 
     26 char	localmodels[MAX_MODELS][5];	// inline model names for precache
     27 
     28 char localinfo[MAX_LOCALINFO_STRING+1]; // local game info
     29 
     30 /*
     31 ================
     32 SV_ModelIndex
     33 
     34 ================
     35 */
     36 int SV_ModelIndex (char *name)
     37 {
     38 	int		i;
     39 
     40 	if (!name || !name[0])
     41 		return 0;
     42 
     43 	for (i=0 ; i<MAX_MODELS && sv.model_precache[i] ; i++)
     44 		if (!strcmp(sv.model_precache[i], name))
     45 			return i;
     46 	if (i==MAX_MODELS || !sv.model_precache[i])
     47 		SV_Error ("SV_ModelIndex: model %s not precached", name);
     48 	return i;
     49 }
     50 
     51 /*
     52 ================
     53 SV_FlushSignon
     54 
     55 Moves to the next signon buffer if needed
     56 ================
     57 */
     58 void SV_FlushSignon (void)
     59 {
     60 	if (sv.signon.cursize < sv.signon.maxsize - 512)
     61 		return;
     62 
     63 	if (sv.num_signon_buffers == MAX_SIGNON_BUFFERS-1)
     64 		SV_Error ("sv.num_signon_buffers == MAX_SIGNON_BUFFERS-1");
     65 
     66 	sv.signon_buffer_size[sv.num_signon_buffers-1] = sv.signon.cursize;
     67 	sv.signon.data = sv.signon_buffers[sv.num_signon_buffers];
     68 	sv.num_signon_buffers++;
     69 	sv.signon.cursize = 0;
     70 }
     71 
     72 /*
     73 ================
     74 SV_CreateBaseline
     75 
     76 Entity baselines are used to compress the update messages
     77 to the clients -- only the fields that differ from the
     78 baseline will be transmitted
     79 ================
     80 */
     81 void SV_CreateBaseline (void)
     82 {
     83 	int			i;
     84 	edict_t			*svent;
     85 	int				entnum;
     86 
     87 	for (entnum = 0; entnum < sv.num_edicts ; entnum++)
     88 	{
     89 		svent = EDICT_NUM(entnum);
     90 		if (svent->free)
     91 			continue;
     92 		// create baselines for all player slots,
     93 		// and any other edict that has a visible model
     94 		if (entnum > MAX_CLIENTS && !svent->v.modelindex)
     95 			continue;
     96 
     97 	//
     98 	// create entity baseline
     99 	//
    100 		VectorCopy (svent->v.origin, svent->baseline.origin);
    101 		VectorCopy (svent->v.angles, svent->baseline.angles);
    102 		svent->baseline.frame = svent->v.frame;
    103 		svent->baseline.skinnum = svent->v.skin;
    104 		if (entnum > 0 && entnum <= MAX_CLIENTS)
    105 		{
    106 			svent->baseline.colormap = entnum;
    107 			svent->baseline.modelindex = SV_ModelIndex("progs/player.mdl");
    108 		}
    109 		else
    110 		{
    111 			svent->baseline.colormap = 0;
    112 			svent->baseline.modelindex =
    113 				SV_ModelIndex(PR_GetString(svent->v.model));
    114 		}
    115 
    116 		//
    117 		// flush the signon message out to a seperate buffer if
    118 		// nearly full
    119 		//
    120 		SV_FlushSignon ();
    121 
    122 		//
    123 		// add to the message
    124 		//
    125 		MSG_WriteByte (&sv.signon,svc_spawnbaseline);
    126 		MSG_WriteShort (&sv.signon,entnum);
    127 
    128 		MSG_WriteByte (&sv.signon, svent->baseline.modelindex);
    129 		MSG_WriteByte (&sv.signon, svent->baseline.frame);
    130 		MSG_WriteByte (&sv.signon, svent->baseline.colormap);
    131 		MSG_WriteByte (&sv.signon, svent->baseline.skinnum);
    132 		for (i=0 ; i<3 ; i++)
    133 		{
    134 			MSG_WriteCoord(&sv.signon, svent->baseline.origin[i]);
    135 			MSG_WriteAngle(&sv.signon, svent->baseline.angles[i]);
    136 		}
    137 	}
    138 }
    139 
    140 
    141 /*
    142 ================
    143 SV_SaveSpawnparms
    144 
    145 Grabs the current state of the progs serverinfo flags
    146 and each client for saving across the
    147 transition to another level
    148 ================
    149 */
    150 void SV_SaveSpawnparms (void)
    151 {
    152 	int		i, j;
    153 
    154 	if (!sv.state)
    155 		return;		// no progs loaded yet
    156 
    157 	// serverflags is the only game related thing maintained
    158 	svs.serverflags = pr_global_struct->serverflags;
    159 
    160 	for (i=0, host_client = svs.clients ; i<MAX_CLIENTS ; i++, host_client++)
    161 	{
    162 		if (host_client->state != cs_spawned)
    163 			continue;
    164 
    165 		// needs to reconnect
    166 		host_client->state = cs_connected;
    167 
    168 		// call the progs to get default spawn parms for the new client
    169 		pr_global_struct->self = EDICT_TO_PROG(host_client->edict);
    170 		PR_ExecuteProgram (pr_global_struct->SetChangeParms);
    171 		for (j=0 ; j<NUM_SPAWN_PARMS ; j++)
    172 			host_client->spawn_parms[j] = (&pr_global_struct->parm1)[j];
    173 	}
    174 }
    175 
    176 /*
    177 ================
    178 SV_CalcPHS
    179 
    180 Expands the PVS and calculates the PHS
    181 (Potentially Hearable Set)
    182 ================
    183 */
    184 void SV_CalcPHS (void)
    185 {
    186 	int		rowbytes, rowwords;
    187 	int		i, j, k, l, index, num;
    188 	int		bitbyte;
    189 	unsigned	*dest, *src;
    190 	byte	*scan;
    191 	int		count, vcount;
    192 
    193 	Con_Printf ("Building PHS...\n");
    194 
    195 	num = sv.worldmodel->numleafs;
    196 	rowwords = (num+31)>>5;
    197 	rowbytes = rowwords*4;
    198 
    199 	sv.pvs = Hunk_Alloc (rowbytes*num);
    200 	scan = sv.pvs;
    201 	vcount = 0;
    202 	for (i=0 ; i<num ; i++, scan+=rowbytes)
    203 	{
    204 		memcpy (scan, Mod_LeafPVS(sv.worldmodel->leafs+i, sv.worldmodel),
    205 			rowbytes);
    206 		if (i == 0)
    207 			continue;
    208 		for (j=0 ; j<num ; j++)
    209 		{
    210 			if ( scan[j>>3] & (1<<(j&7)) )
    211 			{
    212 				vcount++;
    213 			}
    214 		}
    215 	}
    216 
    217 
    218 	sv.phs = Hunk_Alloc (rowbytes*num);
    219 	count = 0;
    220 	scan = sv.pvs;
    221 	dest = (unsigned *)sv.phs;
    222 	for (i=0 ; i<num ; i++, dest += rowwords, scan += rowbytes)
    223 	{
    224 		memcpy (dest, scan, rowbytes);
    225 		for (j=0 ; j<rowbytes ; j++)
    226 		{
    227 			bitbyte = scan[j];
    228 			if (!bitbyte)
    229 				continue;
    230 			for (k=0 ; k<8 ; k++)
    231 			{
    232 				if (! (bitbyte & (1<<k)) )
    233 					continue;
    234 				// or this pvs row into the phs
    235 				// +1 because pvs is 1 based
    236 				index = ((j<<3)+k+1);
    237 				if (index >= num)
    238 					continue;
    239 				src = (unsigned *)sv.pvs + index*rowwords;
    240 				for (l=0 ; l<rowwords ; l++)
    241 					dest[l] |= src[l];
    242 			}
    243 		}
    244 
    245 		if (i == 0)
    246 			continue;
    247 		for (j=0 ; j<num ; j++)
    248 			if ( ((byte *)dest)[j>>3] & (1<<(j&7)) )
    249 				count++;
    250 	}
    251 
    252 	Con_Printf ("Average leafs visible / hearable / total: %i / %i / %i\n"
    253 		, vcount/num, count/num, num);
    254 }
    255 
    256 unsigned SV_CheckModel(char *mdl)
    257 {
    258 	byte	stackbuf[1024];		// avoid dirtying the cache heap
    259 	byte *buf;
    260 	unsigned short crc;
    261 //	int len;
    262 
    263 	buf = (byte *)COM_LoadStackFile (mdl, stackbuf, sizeof(stackbuf));
    264 	crc = CRC_Block(buf, com_filesize);
    265 //	for (len = com_filesize; len; len--, buf++)
    266 //		CRC_ProcessByte(&crc, *buf);
    267 
    268 	return crc;
    269 }
    270 
    271 /*
    272 ================
    273 SV_SpawnServer
    274 
    275 Change the server to a new map, taking all connected
    276 clients along with it.
    277 
    278 This is only called from the SV_Map_f() function.
    279 ================
    280 */
    281 void SV_SpawnServer (char *server)
    282 {
    283 	edict_t		*ent;
    284 	int			i;
    285 
    286 	Con_DPrintf ("SpawnServer: %s\n",server);
    287 
    288 	SV_SaveSpawnparms ();
    289 
    290 	svs.spawncount++;		// any partially connected client will be
    291 							// restarted
    292 
    293 	sv.state = ss_dead;
    294 
    295 	Mod_ClearAll ();
    296 	Hunk_FreeToLowMark (host_hunklevel);
    297 
    298 	// wipe the entire per-level structure
    299 	memset (&sv, 0, sizeof(sv));
    300 
    301 	sv.datagram.maxsize = sizeof(sv.datagram_buf);
    302 	sv.datagram.data = sv.datagram_buf;
    303 	sv.datagram.allowoverflow = true;
    304 
    305 	sv.reliable_datagram.maxsize = sizeof(sv.reliable_datagram_buf);
    306 	sv.reliable_datagram.data = sv.reliable_datagram_buf;
    307 
    308 	sv.multicast.maxsize = sizeof(sv.multicast_buf);
    309 	sv.multicast.data = sv.multicast_buf;
    310 
    311 	sv.master.maxsize = sizeof(sv.master_buf);
    312 	sv.master.data = sv.master_buf;
    313 
    314 	sv.signon.maxsize = sizeof(sv.signon_buffers[0]);
    315 	sv.signon.data = sv.signon_buffers[0];
    316 	sv.num_signon_buffers = 1;
    317 
    318 	strcpy (sv.name, server);
    319 
    320 	// load progs to get entity field count
    321 	// which determines how big each edict is
    322 	PR_LoadProgs ();
    323 
    324 	// allocate edicts
    325 	sv.edicts = Hunk_AllocName (MAX_EDICTS*pr_edict_size, "edicts");
    326 
    327 	// leave slots at start for clients only
    328 	sv.num_edicts = MAX_CLIENTS+1;
    329 	for (i=0 ; i<MAX_CLIENTS ; i++)
    330 	{
    331 		ent = EDICT_NUM(i+1);
    332 		svs.clients[i].edict = ent;
    333 //ZOID - make sure we update frags right
    334 		svs.clients[i].old_frags = 0;
    335 	}
    336 
    337 	sv.time = 1.0;
    338 
    339 	strcpy (sv.name, server);
    340 	sprintf (sv.modelname,"maps/%s.bsp", server);
    341 	sv.worldmodel = Mod_ForName (sv.modelname, true);
    342 	SV_CalcPHS ();
    343 
    344 	//
    345 	// clear physics interaction links
    346 	//
    347 	SV_ClearWorld ();
    348 
    349 	sv.sound_precache[0] = pr_strings;
    350 
    351 	sv.model_precache[0] = pr_strings;
    352 	sv.model_precache[1] = sv.modelname;
    353 	sv.models[1] = sv.worldmodel;
    354 	for (i=1 ; i<sv.worldmodel->numsubmodels ; i++)
    355 	{
    356 		sv.model_precache[1+i] = localmodels[i];
    357 		sv.models[i+1] = Mod_ForName (localmodels[i], false);
    358 	}
    359 
    360 	//check player/eyes models for hacks
    361 	sv.model_player_checksum = SV_CheckModel("progs/player.mdl");
    362 	sv.eyes_player_checksum = SV_CheckModel("progs/eyes.mdl");
    363 
    364 	//
    365 	// spawn the rest of the entities on the map
    366 	//
    367 
    368 	// precache and static commands can be issued during
    369 	// map initialization
    370 	sv.state = ss_loading;
    371 
    372 	ent = EDICT_NUM(0);
    373 	ent->free = false;
    374 	ent->v.model = PR_SetString(sv.worldmodel->name);
    375 	ent->v.modelindex = 1;		// world model
    376 	ent->v.solid = SOLID_BSP;
    377 	ent->v.movetype = MOVETYPE_PUSH;
    378 
    379 	pr_global_struct->mapname = PR_SetString(sv.name);
    380 	// serverflags are for cross level information (sigils)
    381 	pr_global_struct->serverflags = svs.serverflags;
    382 
    383 	// run the frame start qc function to let progs check cvars
    384 	SV_ProgStartFrame ();
    385 
    386 	// load and spawn all other entities
    387 	ED_LoadFromFile (sv.worldmodel->entities);
    388 
    389 	// look up some model indexes for specialized message compression
    390 	SV_FindModelNumbers ();
    391 
    392 	// all spawning is completed, any further precache statements
    393 	// or prog writes to the signon message are errors
    394 	sv.state = ss_active;
    395 
    396 	// run two frames to allow everything to settle
    397 	host_frametime = 0.1;
    398 	SV_Physics ();
    399 	SV_Physics ();
    400 
    401 	// save movement vars
    402 	SV_SetMoveVars();
    403 
    404 	// create a baseline for more efficient communications
    405 	SV_CreateBaseline ();
    406 	sv.signon_buffer_size[sv.num_signon_buffers-1] = sv.signon.cursize;
    407 
    408 	Info_SetValueForKey (svs.info, "map", sv.name, MAX_SERVERINFO_STRING);
    409 	Con_DPrintf ("Server spawned.\n");
    410 }
    411 
    412