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

📄 sv_main.pas

📁 雷神之锤2(Quake2)Delphi源码
💻 PAS
📖 第 1 页 / 共 3 页
字号:
{----------------------------------------------------------------------------}
{                                                                            }
{ File(s): sv_main.c                                                         }
{                                                                            }
{ Initial conversion by : George Melekos (inet_crow@hotmail.com)             }
{ Initial conversion on : 13-Feb-2002                                        }
{                                                                            }
{ This File contains part of convertion of Quake2 source to ObjectPascal.    }
{ More information about this project can be found at:                       }
{ http://www.sulaco.co.za/quake2/                                            }
{                                                                            }
{ Copyright (C) 1997-2001 Id Software, Inc.                                  }
{                                                                            }
{ This program is free software; you can redistribute it and/or              }
{ modify it under the terms of the GNU General Public License                }
{ as published by the Free Software Foundation; either version 2             }
{ of the License, or (at your option) any later version.                     }
{                                                                            }
{ This program is distributed in the hope that it will be useful,            }
{ but WITHOUT ANY WARRANTY; without even the implied warranty of             }
{ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                       }
{                                                                            }
{ See the GNU General Public License for more details.                       }
{                                                                            }
{----------------------------------------------------------------------------}
{ Updated on :                                                               }
{ Updated by :                                                               }
{                                                                            }
{----------------------------------------------------------------------------}
{ * Still dependent (to compile correctly) on:                               }
{----------------------------------------------------------------------------}
{ * TODO:                                                                    }
{----------------------------------------------------------------------------}
// 25.07.2002 Juha: Proof-readed this unit

  // address of group servers
  // current client
  // seconds without any message
  // seconds to sink messages after disconnect
  // password for remote server commands
  // don't reload level state when reentering
  // FIXME: rename sv_maxclients
  // should heartbeats be sent
  // minimum seconds between connect messages

unit Sv_main;

interface


uses
  Windows,
  SysUtils,
  Common,
  q_shared,
  Server,
  ref;

var
  master_adr: array[0..MAX_MASTERS-1] of netadr_t;	// address of group servers

  sv_client: client_p;			// current client


  sv_paused,
  sv_timedemo,

  sv_enforcetime,

  timeout,				// seconds without any message
  zombietime,			// seconds to sink messages after disconnect

  rcon_password,			// password for remote server commands

  allow_download,
  allow_download_players,
  allow_download_models,
  allow_download_sounds,
  allow_download_maps,

  sv_airaccelerate,

  sv_noreload,			// don't reload level state when reentering

  maxclients,			// FIXME: rename sv_maxclients
  sv_showclamp,

  hostname,
  public_server,			// should heartbeats be sent

  sv_reconnect_limit: cvar_p;	// minimum seconds between connect messages


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

(*
=====================
SV_DropClient

Called when the player is totally leaving the server, either willingly
or unwillingly.  This is NOT called if the entire server is quiting
or crashing.
=====================
*)

procedure SV_DropClient (drop : client_p);
  // add the disconnect

(*
==============================================================================

CONNECTIONLESS COMMANDS

==============================================================================
*)

(*
===============
SV_StatusString

Builds the string that is sent as heartbeats and status replies
===============
*)

function SV_StatusString : PChar;

(*
================
SVC_Status

Responds with all the info that qplug or qspy can see
================
*)

procedure SVC_Status;

(*
================
SVC_Ack

================
*)

procedure SVC_Ack;

(*
================
SVC_Info

Responds with short info for broadcast scans
The second parameter should be the current protocol version number.
================
*)

procedure SVC_Info;

(*
================
SVC_Ping

Just responds with an acknowledgement
================
*)

procedure SVC_Ping;

(*
=================
SVC_GetChallenge

Returns a challenge number that can be used
in a subsequent client_connect command.
We do this to prevent denial of service attacks that
flood the server with invalid connection IPs.  With a
challenge, they must give a valid IP address.
=================
*)

procedure SVC_GetChallenge;

(*
==================
SVC_DirectConnect

A connection request that did not come from the master
==================
*)

procedure SVC_DirectConnect;

function Rcon_Validate : Integer;

(*
===============
SVC_RemoteCommand

A client issued an rcon command.
Shift down the remaining args
Redirect all printfs
===============
*)

procedure SVC_RemoteCommand;

(*
=================
SV_ConnectionlessPacket

A connectionless packet has four leading $ff
characters to distinguish it from a game channel.
Clients that are in the game can still send
connectionless packets.
=================
*)

procedure SV_ConnectionlessPacket;
  //============================================================================

(*
===================
SV_CalcPings

Updates the cl^.ping variables
===================
*)

procedure SV_CalcPings;

(*
===================
SV_GiveMsec

Every few frames, gives all clients an allotment of milliseconds
for their command moves.  If they exceed it, assume cheating.
===================
*)

procedure SV_GiveMsec;

(*
=================
SV_ReadPackets
=================
*)

procedure SV_ReadPackets;

(*
==================
SV_CheckTimeouts

If a packet has not been received from a client for timeout^.value
seconds, drop the conneciton.  Server frames are used instead of
realtime to aprocedure dropping the local client while debugging.

When a client is normally dropped, the client_t goes into a zombie state
for a few seconds to make sure any final reliable message gets resent
if necessary
==================
*)

procedure SV_CheckTimeouts;

(*
================
SV_PrepWorldFrame

This has to be done before the world logic, because
player processing happens outside RunWorldFrame
================
*)

procedure SV_PrepWorldFrame;

(*
=================
SV_RunGameFrame
=================
*)

procedure SV_RunGameFrame;

(*
==================
SV_Frame

==================
*)

procedure SV_Frame (msec : Integer);
  //============================================================================

(*
================
Master_Heartbeat

Send a message to the master every few minutes to
let it know we are alive, and log information
================
*)

const
  HEARTBEAT_SECONDS = 300;

procedure Master_Heartbeat;

(*
=================
Master_Shutdown

Informs all masters that this server is going down
=================
*)

procedure Master_Shutdown;
  //============================================================================

(*
=================
SV_UserinfoChanged

Pull specific info from a newly changed userinfo string
into a more C freindly form.
=================
*)

procedure SV_UserinfoChanged (cl : client_p);
  //============================================================================

(*
===============
SV_Init

Only called at quake2.exe startup, not for each game
===============
*)

procedure SV_Init;

(*
==================
SV_FinalMessage

Used by SV_Shutdown to send a final message to all
connected clients before the server goes down.  The messages are sent immediately,
not just stuck on the outgoing message list, because the server is going
to totally exit after returning from this function.
==================
*)

procedure SV_FinalMessage (message_ : PChar; reconnect : qboolean);

(*
================
SV_Shutdown

Called when each game quits,
before Sys_Quit or Sys_Error
================
*)

procedure SV_Shutdown (finalmsg : PChar; reconnect : qboolean);

implementation

uses
  CVar,
  CPas,
  Cmd,
  Files,
  net_wins,
  net_chan,
  g_local,
  q_shwin,
  sv_ccmds,
  sv_send,
  sv_ents,
  sv_init,
  sv_user,
  sv_game;


(*
=====================
SV_DropClient

Called when the player is totally leaving the server, either willingly
or unwillingly.  This is NOT called if the entire server is quiting
or crashing.
=====================
*)
procedure SV_DropClient (drop: client_p);
begin
	// add the disconnect
	MSG_WriteByte (drop.netchan.message, Integer(svc_disconnect));

	if (drop^.state = cs_spawned) then begin
		// call the prog function for removing a client
		// this will remove the body, among other things
		ge^.ClientDisconnect (drop^.edict);
	end;

	if (drop^.download <> nil) then begin
		FS_FreeFile (drop^.download);
		drop^.download := nil;
	end;

	drop^.state := cs_zombie;		// become free in a few seconds
	drop^.name[0] := #0;
end;



(*
==============================================================================

CONNECTIONLESS COMMANDS

==============================================================================
*)

(*
===============
SV_StatusString

Builds the string that is sent as heartbeats and status replies
===============
*)
var
  status: array[0..MAX_MSGLEN - 16-1] of char;

function SV_StatusString (): pchar;
var
	player: array[0..1024-1] of char;
	i: integer;
	cl: client_p;
	statusLength: integer;
	playerLength: integer;
begin
	strcpy (status, Cvar_Serverinfo_());
	strcat (status, #10);
	statusLength := strlen(status);

	for i := 0 to Round(maxclients^.value)-1 do begin
		cl := @svs.clients^[i];
		if (cl^.state = cs_connected) or (cl^.state = cs_spawned) then begin
			Com_sprintf (player, sizeof(player), '%i %i "%s"'#10,
				[cl^.edict^.client^.ps.stats[STAT_FRAGS], cl^.ping, cl^.name]);
			playerLength := strlen(player);
			if (statusLength + playerLength >= sizeof(status)) then
				break;		// can't hold any more
			strcpy (status + statusLength, player);
			statusLength := statusLength + playerLength;
		end;
	end;

⌨️ 快捷键说明

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