⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 host.c

📁 quake1 dos源代码最新版本
💻 C
📖 第 1 页 / 共 3 页
字号:

/*
=================
SV_BroadcastPrintf

Sends text to all active clients
=================
*/
void SV_BroadcastPrintf (char *fmt, ...)
{
	va_list		argptr;
	char		string[1024];
	int			i;

	va_start (argptr,fmt);
	vsprintf (string, fmt,argptr);
	va_end (argptr);

	for (i=0 ; i<svs.maxclients ; i++)
		if (svs.clients[i].active && svs.clients[i].spawned)
		{
			MSG_WriteByte (&svs.clients[i].message, svc_print);
			MSG_WriteString (&svs.clients[i].message, string);
		}
}

/*
=================
Host_ClientCommands

Send text over to the client to be executed
=================
*/
void Host_ClientCommands (char *fmt, ...)
{
	va_list		argptr;
	char		string[1024];

	va_start (argptr,fmt);
	vsprintf (string, fmt,argptr);
	va_end (argptr);

	MSG_WriteByte (&host_client->message, svc_stufftext);
	MSG_WriteString (&host_client->message, string);
}

/*
=====================
SV_DropClient

Called when the player is getting totally kicked off the host
if (crash = true), don't bother sending signofs
=====================
*/
void SV_DropClient (qboolean crash)
{
	int		saveSelf;
	int		i;
	client_t *client;

	if (!crash)
	{
		// send any final messages (don't check for errors)
		if (NET_CanSendMessage (host_client->netconnection))
		{
			MSG_WriteByte (&host_client->message, svc_disconnect);
			NET_SendMessage (host_client->netconnection, &host_client->message);
		}

		if (host_client->edict && host_client->spawned)
		{
		// call the prog function for removing a client
		// this will set the body to a dead frame, among other things
			saveSelf = pr_global_struct->self;
			pr_global_struct->self = EDICT_TO_PROG(host_client->edict);
			PR_ExecuteProgram (pr_global_struct->ClientDisconnect);
			pr_global_struct->self = saveSelf;
		}

		Sys_Printf ("Client %s removed\n",host_client->name);
	}

// break the net connection
	NET_Close (host_client->netconnection);
	host_client->netconnection = NULL;

// free the client (the body stays around)
	host_client->active = false;
	host_client->name[0] = 0;
	host_client->old_frags = -999999;
	net_activeconnections--;

// send notification to all clients
	for (i=0, client = svs.clients ; i<svs.maxclients ; i++, client++)
	{
		if (!client->active)
			continue;
		MSG_WriteByte (&client->message, svc_updatename);
		MSG_WriteByte (&client->message, host_client - svs.clients);
		MSG_WriteString (&client->message, "");
		MSG_WriteByte (&client->message, svc_updatefrags);
		MSG_WriteByte (&client->message, host_client - svs.clients);
		MSG_WriteShort (&client->message, 0);
		MSG_WriteByte (&client->message, svc_updatecolors);
		MSG_WriteByte (&client->message, host_client - svs.clients);
		MSG_WriteByte (&client->message, 0);
	}
}

/*
==================
Host_ShutdownServer

This only happens at the end of a game, not between levels
==================
*/
void Host_ShutdownServer(qboolean crash)
{
	int		i;
	int		count;
	sizebuf_t	buf;
	char		message[4];
	double	start;

	if (!sv.active)
		return;

	sv.active = false;

// stop all client sounds immediately
	if (cls.state == ca_connected)
		CL_Disconnect ();

// flush any pending messages - like the score!!!
	start = Sys_FloatTime();
	do
	{
		count = 0;
		for (i=0, host_client = svs.clients ; i<svs.maxclients ; i++, host_client++)
		{
			if (host_client->active && host_client->message.cursize)
			{
				if (NET_CanSendMessage (host_client->netconnection))
				{
					NET_SendMessage(host_client->netconnection, &host_client->message);
					SZ_Clear (&host_client->message);
				}
				else
				{
					NET_GetMessage(host_client->netconnection);
					count++;
				}
			}
		}
		if ((Sys_FloatTime() - start) > 3.0)
			break;
	}
	while (count);

// make sure all the clients know we're disconnecting
	buf.data = message;
	buf.maxsize = 4;
	buf.cursize = 0;
	MSG_WriteByte(&buf, svc_disconnect);
	count = NET_SendToAll(&buf, 5);
	if (count)
		Con_Printf("Host_ShutdownServer: NET_SendToAll failed for %u clients\n", count);

	for (i=0, host_client = svs.clients ; i<svs.maxclients ; i++, host_client++)
		if (host_client->active)
			SV_DropClient(crash);

//
// clear structures
//
	memset (&sv, 0, sizeof(sv));
	memset (svs.clients, 0, svs.maxclientslimit*sizeof(client_t));
}


/*
================
Host_ClearMemory

This clears all the memory used by both the client and server, but does
not reinitialize anything.
================
*/
void Host_ClearMemory (void)
{
	Con_DPrintf ("Clearing memory\n");
	D_FlushCaches ();
	Mod_ClearAll ();
	if (host_hunklevel)
		Hunk_FreeToLowMark (host_hunklevel);

	cls.signon = 0;
	memset (&sv, 0, sizeof(sv));
	memset (&cl, 0, sizeof(cl));
}


//============================================================================


/*
===================
Host_FilterTime

Returns false if the time is too short to run a frame
===================
*/
qboolean Host_FilterTime (float time)
{
	realtime += time;

// 2001-12-16 MAX_FPS cvar by MrG  start
//	if (!cls.timedemo && realtime - oldrealtime < 1.0/72.0)
	if (max_fps->value < 10) Cvar_Set(max_fps, "72");
	if (!cls.timedemo && realtime - oldrealtime < 1.0/max_fps->value)
// 2001-12-16 MAX_FPS cvar by MrG  end
		return false;		// framerate is too high

// 2001-10-20 TIMESCALE extension by Tomaz/Maddes  start
//	host_frametime = realtime - oldrealtime;
	host_cpu_frametime = realtime - oldrealtime;
	host_org_frametime = host_cpu_frametime;
// 2001-10-20 TIMESCALE extension by Tomaz/Maddes  end
	oldrealtime = realtime;

	if (host_framerate->value > 0)
// 2001-10-20 TIMESCALE extension by Tomaz/Maddes  start
	{
//		host_frametime = host_framerate->value;
		host_org_frametime = host_framerate->value;
	}
// 2001-10-20 TIMESCALE extension by Tomaz/Maddes  end
	else
	{	// don't allow really long or short frames
// 2001-10-20 TIMESCALE extension by Tomaz/Maddes  start
/*
		if (host_frametime > 0.1)
			host_frametime = 0.1;
		if (host_frametime < 0.001)
			host_frametime = 0.001;
*/
		if (host_org_frametime > 0.1)
			host_org_frametime = 0.1;
		if (host_org_frametime < 0.001)
			host_org_frametime = 0.001;
// 2001-10-20 TIMESCALE extension by Tomaz/Maddes  end
	}

	host_frametime = host_org_frametime * host_timescale->value;	// 2001-10-20 TIMESCALE extension by Tomaz/Maddes

	return true;
}


/*
===================
Host_GetConsoleCommands

Add them exactly as if they had been typed at the console
===================
*/
void Host_GetConsoleCommands (void)
{
	char	*cmd;

	while (1)
	{
		cmd = Sys_ConsoleInput ();
		if (!cmd)
			break;
		Cbuf_AddText (cmd);
	}
}


/*
==================
Host_ServerFrame

==================
*/
#ifdef FPS_20

void _Host_ServerFrame (void)
{
// run the world state
	pr_global_struct->frametime = host_frametime;
// 2001-10-20 TIMESCALE extension by Tomaz/Maddes  start
	if (pr_global_cpu_frametime)
	{
		G_FLOAT(pr_global_cpu_frametime->ofs) = host_cpu_frametime;
	}

	if (pr_global_org_frametime)
	{
		G_FLOAT(pr_global_org_frametime->ofs) = host_org_frametime;
	}
// 2001-10-20 TIMESCALE extension by Tomaz/Maddes  end

// read client messages
	SV_RunClients ();

// move things around and think
// always pause in single player if in console or menus
	if (!sv.paused && (svs.maxclients > 1 || key_dest == key_game) )
		SV_Physics ();
}

void Host_ServerFrame (void)
{
	float	save_host_frametime;
	float	temp_host_frametime;
	int	i;		// 2000-05-02 NVS SVC by Maddes

// run the world state
	pr_global_struct->frametime = host_frametime;
// 2001-10-20 TIMESCALE extension by Tomaz/Maddes  start
	if (pr_global_cpu_frametime)
	{
		G_FLOAT(pr_global_cpu_frametime->ofs) = host_cpu_frametime;
	}

	if (pr_global_org_frametime)
	{
		G_FLOAT(pr_global_org_frametime->ofs) = host_org_frametime;
	}
// 2001-10-20 TIMESCALE extension by Tomaz/Maddes  end

// set the time and clear the general datagram
	SV_ClearDatagram ();
// 2000-05-02 NVS SVC by Maddes  start
	// clear existing clients
	for (i=0 ; i<svs.maxclients ; i++)
	{
		if (svs.clients[i].active)
		{
			SZ_Clear (&svs.clients[i].datagram);
		}
	}
// 2000-05-02 NVS SVC by Maddes  end

// check for new clients
	SV_CheckForNewClients ();

	temp_host_frametime = save_host_frametime = host_frametime;
	while(temp_host_frametime > (1.0/72.0))
	{
		if (temp_host_frametime > 0.05)
			host_frametime = 0.05;
		else
			host_frametime = temp_host_frametime;
		temp_host_frametime -= host_frametime;
		_Host_ServerFrame ();
	}
	host_frametime = save_host_frametime;

// send all messages to the clients
	SV_SendClientMessages ();
}

#else

void Host_ServerFrame (void)
{
	int	i;		// 2000-05-02 NVS SVC by Maddes

// run the world state
	pr_global_struct->frametime = host_frametime;
// 2001-10-20 TIMESCALE extension by Tomaz/Maddes  start
	if (pr_global_cpu_frametime)
	{
		G_FLOAT(pr_global_cpu_frametime->ofs) = host_cpu_frametime;
	}

	if (pr_global_org_frametime)
	{
		G_FLOAT(pr_global_org_frametime->ofs) = host_org_frametime;
	}
// 2001-10-20 TIMESCALE extension by Tomaz/Maddes  end

// set the time and clear the general datagram
	SV_ClearDatagram ();
// 2000-05-02 NVS SVC by Maddes  start
	// clear existing clients
	for (i=0 ; i<svs.maxclients ; i++)
	{
		if (svs.clients[i].active)
		{
			SZ_Clear (&svs.clients[i].datagram);
		}
	}
// 2000-05-02 NVS SVC by Maddes  end

// check for new clients
	SV_CheckForNewClients ();

// read client messages
	SV_RunClients ();

// move things around and think
// always pause in single player if in console or menus
	if (!sv.paused && (svs.maxclients > 1 || key_dest == key_game) )
		SV_Physics ();

// send all messages to the clients
	SV_SendClientMessages ();
}

#endif


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -