📄 server.pas
字号:
{----------------------------------------------------------------------------}
{ }
{ File(s): server.c }
{ Content: }
{ }
{ Initial conversion by : osamaao }
{ Initial conversion on : 12-Jan-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: }
{ none }
{----------------------------------------------------------------------------}
{ * TODO: }
{ none }
{----------------------------------------------------------------------------}
// 25.07.2002 Juha: Proof-readed this unit
// server.h
//define PARANOID // speed sapping error checking
unit server;
interface
uses
Common,
q_shared,
g_local,
qfiles;
const
MAX_MASTERS = 8; // max recipients for heartbeat packets
LATENCY_COUNTS = 16;
RATE_MESSAGES = 10;
// MAX_CHALLENGES is made large to prevent a denial
// of service attack that could cycle all of them
// out before legitimate users connected
MAX_CHALLENGES = 1024;
type
// Note: I've added the TParams type to be able to use open parameters.
//TParams = array of Variant;
redirect_t = (RD_NONE, RD_CLIENT, RD_PACKET);
redirect_p = ^redirect_t;
server_state_p = ^server_state_t;
server_state_t = (
ss_dead, // no map loaded
ss_loading, // spawning level edicts
ss_game, // actively running
ss_cinematic,
ss_demo,
ss_pic);
// some qc commands are only valid before the server has finished
// initializing (precache commands, static sounds / objects, etc)
server_p = ^server_t;
server_t = record
State : server_state_t; // precache commands are only valid during load
attractloop : qboolean; // running cinematics and demos for the local system only
loadgame : qboolean; // client begins should reuse existing entity
time : Cardinal; // always sv.framenum * 100 msec
framenum : Integer;
name : array[0..MAX_QPATH-1] of char; // map name, or cinematic name
models : array[0..MAX_MODELS-1] of cmodel_p;
configstrings : array[0..MAX_CONFIGSTRINGS-1, 0..MAX_QPATH-1] of char;
baselines : array[0..MAX_EDICTS-1] of entity_state_t;
// the multicast buffer is used to send a message to a set of clients
// it is only used to marshall data until SV_Multicast is called
multicast : Sizebuf_t;
multicast_buf : array[0..MAX_MSGLEN-1] of byte;
// demo server information
demofile :integer; //File handle
timedemo :qBoolean; // don't time sync
end;
client_state_t = (
cs_free, // can be reused for a new connection
cs_zombie, // client has been disconnected, but don't reuse
// connection for a couple seconds
cs_connected, // has been assigned to a client_t, but not in game yet
cs_spawned // client is fully in game
);
client_frame_p = ^client_frame_t;
client_frame_t = record
areaBytes : Integer;
areaBits : array[0..(MAX_MAP_AREAS div 8)-1] of byte; // portalarea visibility bits
ps : player_state_t;
num_entities: Integer;
first_entity: Integer; // into the circular sv_packet_entities[]
SentTime : Integer; // for ping calculations
end;
client_p = ^client_s;
client_s = record
state : client_state_t;
userinfo : array[0..MAX_INFO_STRING-1] of char; // name, etc
lastframe : Integer; // for delta compression
lastcmd : usercmd_t; // for filling in big drops
commandMsec: Integer; // every seconds this is reset, if user
// commands exhaust it, assume time cheating
frame_latency: array[0..LATENCY_COUNTS-1] of Integer;
ping : Integer;
message_size : array[0..RATE_MESSAGES-1] of Integer; // used to rate drop packets
rate : Integer;
surpressCount: Integer; // number of messages rate supressed
edict : edict_p; // EDICT_NUM(clientnum+1)
name : array[0..32-1] of char; // extracted from userinfo, high bits masked
messagelevel : Integer; // for filtering printed messages
// The datagram is written to by sound calls, prints, temp ents, etc.
// It can be harmlessly overflowed.
datagram : sizebuf_t;
datagram_buf : array[0..MAX_MSGLEN-1] of byte;
frames : array[0..UPDATE_BACKUP-1] of client_frame_t; // updates can be delta'd from here
download : PByte; // file being downloaded
downloadsize : Integer; // total bytes (can't use EOF because of paks)
downloadcount: Integer; // bytes sent
lastmessage : Integer; // sv.framenum when packet was last received
lastconnect : Integer;
challenge : Integer; // challenge of this user, randomly generated
netchan : netchan_t;
end;
client_t = client_s;
// a client can leave the server in one of four ways:
// dropping properly by quiting or disconnecting
// timing out if no valid messages are received for timeout.value seconds
// getting kicked off by the server operator
// a program error, like an overflowed reliable buffer
challenge_p = ^challenge_t;
challenge_t = record
Adr : NetAdr_t;
Challenge: Integer;
Time : Integer;
end;
TEntityStateArr = array [0..0] of entity_state_t;
PEntityStateArr = ^TEntityStateArr;
TClientArr = array [0..0] of client_t;
PClientArr = ^TClientArr;
server_static_p = ^server_static_t;
server_static_t = record
initialized : qboolean; // sv_init has completed
realtime : Integer; // always increasing, no clamping, etc
MapCmd : array [0..MAX_TOKEN_CHARS-1] of char; // ie: *intro.cin+base
spawncount : Integer; // incremented each server start
// used to check late spawns
Clients : PClientArr; // [maxclients->value];
Num_Client_Entities : Integer; // maxclients->value*UPDATE_BACKUP*MAX_PACKET_ENTITIES
Next_Client_Entities: Integer; // next client_entity to use
Client_Entities : PEntityStateArr; // [num_client_entities]
Last_HeartBeat : Integer;
challenges : array[0..MAX_CHALLENGES-1] of challenge_t; // to prevent invalid IPs from connecting
// serverrecord values
DemoFile :integer; // File handle
demo_multicast :SizeBuf_t;
demo_multicast_buf : array[0..MAX_MSGLEN-1] of byte;
end;
function NUM_FOR_EDICT(e: edict_p): Integer;
function EDICT_NUM(n: integer): edict_p;
const
SV_OUTPUTBUF_LENGTH = MAX_MSGLEN - 16;
implementation
uses
sv_game;
function EDICT_NUM(n: integer): edict_p;
begin
Result := Pointer(Cardinal(ge.Edicts) + ge.Edict_size * n);
end;
function NUM_FOR_EDICT(e: edict_p): Integer;
begin
Result := (Cardinal(e) - Cardinal(ge.Edicts)) div ge.Edict_size;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -