Understanding the CoD4 Unleashed Server architecture and core components
The CoD4 Unleashed Server is built on a modified Quake 3 engine architecture, with several subsystems working together to provide game server functionality.
The server maintains two primary state structures:
typedef struct { serverState_t state; int timeResidual; int frameusec; qboolean restarting; int serverId; int checksumFeed; unsigned short configstringIndex[MAX_CONFIGSTRINGS]; svEntity_t svEntities[MAX_GENTITIES]; sharedEntity_t* gentities; int gentitySize; int num_entities; playerState_t* gameClients; int gameClientSize; int bpsWindow[MAX_BPS_WINDOW]; int bpsWindowSteps; int bpsTotalBytes; int bpsMaxBytes; char gametype[MAX_QPATH];} server_t;
The server_t structure (located at 0x13e78d00 in memory) contains per-map state that gets reset on map changes.
Persistent data across map changes is stored in serverStatic_t:
typedef struct { entityUnknownStr_t entUnknown1[512]; archivedEntity_t archivedEntities[16384]; qboolean initialized; int time; int snapFlagServerBit; client_t clients[MAX_CLIENTS]; int numSnapshotEntities; int numSnapshotClients; int nextSnapshotEntities; int nextSnapshotClients; entityState_t snapshotEntities[0x2A000]; clientState_ts snapshotClients[0x20000]; int nextHeartbeatTime; challenge2_t challenges[MAX_CHALLENGES]; int redirectAddress[5]; int authorizeAddress[5]; char netProfilingBuf[1504]; banlist_t banlist[16]; vec3_t mapCenter;} serverStatic_t;
The serverStatic_t structure (at 0x8c51780) persists across map changes and stores client connections, snapshots, and authentication data.
Each connected client progresses through several states:
typedef enum { CS_FREE, // can be reused for a new connection CS_ZOMBIE, // client disconnected, don't reuse yet CS_CONNECTED, // assigned to client_t, no gamestate yet CS_PRIMED, // gamestate sent, awaiting usercmd CS_ACTIVE // client fully in game} clientState_t;
The server maintains consistent timing through frame accumulation:
// Frame timing is calculated based on sv_fpsframeusec = 1000000 / sv_fps->integer;timeResidual += usec;while (timeResidual >= frameusec) { timeResidual -= frameusec; // Process server frame}
The server maintains svEntity_t structures for tracking entity state:
typedef struct svEntity_s { struct svEntity_s* nextEntityInWorldSector; entityState_t baseline; // For delta compression int numClusters; int clusternums[MAX_ENT_CLUSTERS]; int lastCluster; int areanum, areanum2; int snapshotCounter; // Prevent double adding} svEntity_t;
The server supports up to MAX_GENTITIES (2048) entities simultaneously. Entity numbers 0-63 are reserved for clients.
Each client stores up to PACKET_BACKUP (32) frames:
typedef struct { playerState_t ps; int num_entities; int num_clients; int first_entity; int first_client; unsigned int messageSent; unsigned int messageAcked; int messageSize;} clientSnapshot_t;