sv_init.c

Go to the documentation of this file.
00001 
00006 /*
00007 All original material Copyright (C) 2002-2010 UFO: Alien Invasion.
00008 
00009 Original file from Quake 2 v3.21: quake2-2.31/server/sv_init.c
00010 
00011 Copyright (C) 1997-2001 Id Software, Inc.
00012 
00013 This program is free software; you can redistribute it and/or
00014 modify it under the terms of the GNU General Public License
00015 as published by the Free Software Foundation; either version 2
00016 of the License, or (at your option) any later version.
00017 
00018 This program is distributed in the hope that it will be useful,
00019 but WITHOUT ANY WARRANTY; without even the implied warranty of
00020 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00021 
00022 See the GNU General Public License for more details.
00023 
00024 You should have received a copy of the GNU General Public License
00025 along with this program; if not, write to the Free Software
00026 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00027 
00028 */
00029 
00030 #include "server.h"
00031 #include "sv_rma.h"
00032 #include "../shared/parse.h"
00033 
00034 serverInstanceStatic_t svs;         /* persistant server info */
00035 serverInstanceGame_t sv;                    /* local server */
00036 
00042 static const char* SV_GetMapTitle (const mapInfo_t *map, const char* const mapname)
00043 {
00044     assert(mapname);
00045 
00046     if (mapname[0] == '+') {
00047         const mAssembly_t *mAsm = &map->mAssembly[map->mAsm];
00048         if (mAsm && mAsm->title[0]) {
00049             /* return the assembly title itself - must be translated client side */
00050             if (mAsm->title[0] == '_')
00051                 return mAsm->title + 1;
00052             else {
00053                 Com_Printf("The assembly title '%s' is not marked as translatable\n", mAsm->title);
00054                 return mAsm->title;
00055             }
00056         }
00057     }
00058     return mapname;
00059 }
00060 
00064 static void SV_DiscoveryCallback (struct datagram_socket *s, const char *buf, int len, struct sockaddr *from)
00065 {
00066     const char match[] = "discover";
00067     if (len == sizeof(match) && memcmp(buf, match, len) == 0) {
00068         const char msg[] = "discovered";
00069         NET_DatagramSend(s, msg, sizeof(msg), from);
00070     }
00071 }
00072 
00076 static void SV_InitGame (void)
00077 {
00078     /* allow next change after map change or restart */
00079     sv_maxclients->flags |= CVAR_LATCH;
00080 
00081     /* get any latched variable changes (sv_maxclients, etc) */
00082     Cvar_UpdateLatchedVars();
00083 
00084     svs.clients = Mem_PoolAlloc(sizeof(client_t) * sv_maxclients->integer, sv_genericPool, 0);
00085     svs.serverMutex = SDL_CreateMutex();
00086 
00087     /* init network stuff */
00088     if (sv_maxclients->integer > 1) {
00089         svs.initialized = SV_Start(NULL, port->string, &SV_ReadPacket);
00090         svs.netDatagramSocket = NET_DatagramSocketNew(NULL, Cvar_Get("port", DOUBLEQUOTE(PORT_SERVER), CVAR_NOSET, NULL)->string, &SV_DiscoveryCallback);
00091     } else
00092         svs.initialized = SV_Start(NULL, NULL, &SV_ReadPacket);
00093 
00094     SV_Heartbeat_f();
00095 
00096     /* init game */
00097     SV_InitGameProgs();
00098 
00099     if (sv_maxclients->integer != 1 && (sv_dedicated->integer || sv_public->integer))
00100         SV_SetMaster_f();
00101 }
00102 
00110 void SV_Map (qboolean day, const char *levelstring, const char *assembly)
00111 {
00112     int i;
00113     unsigned checksum = 0;
00114     char * map = SV_GetConfigString(CS_TILES);
00115     char * pos = SV_GetConfigString(CS_POSITIONS);
00116     mapInfo_t *randomMap = NULL;
00117     client_t *cl;
00118 
00119     /* any partially connected client will be restarted */
00120     Com_SetServerState(ss_restart);
00121 
00122     /* the game is just starting */
00123     SV_InitGame();
00124 
00125     if (!svs.initialized) {
00126         Com_Printf("Could not spawn the server\n");
00127         return;
00128     }
00129 
00130     assert(levelstring[0] != '\0');
00131 
00132     Com_DPrintf(DEBUG_SERVER, "SpawnServer: %s\n", levelstring);
00133 
00134     /* save name for levels that don't set message */
00135     SV_SetConfigString(CS_NAME, levelstring);
00136     SV_SetConfigString(CS_LIGHTMAP, day);
00137 
00138     Q_strncpyz(sv.name, levelstring, sizeof(sv.name));
00139 
00140     /* set serverinfo variable */
00141     sv_mapname = Cvar_FullSet("sv_mapname", sv.name, CVAR_SERVERINFO | CVAR_NOSET);
00142 
00143     /* notify the client in case of a listening server */
00144     SCR_BeginLoadingPlaque();
00145 
00146     if (assembly)
00147         Q_strncpyz(sv.assembly, assembly, sizeof(sv.assembly));
00148     else
00149         sv.assembly[0] = '\0';
00150 
00151     /* leave slots at start for clients only */
00152     cl = NULL;
00153     while ((cl = SV_GetNextClient(cl)) != NULL) {
00154         /* needs to reconnect */
00155         if (cl->state >= cs_spawning)
00156             SV_SetClientState(cl, cs_connected);
00157     }
00158 
00159     /* assemble and load the map */
00160     if (levelstring[0] == '+') {
00161         randomMap = SV_AssembleMap(levelstring + 1, assembly, map, pos);
00162         if (!randomMap) {
00163             Com_Printf("Could not load assembly for map '%s'\n", levelstring);
00164             return;
00165         }
00166     } else {
00167         SV_SetConfigString(CS_TILES, levelstring);
00168         SV_SetConfigString(CS_POSITIONS, assembly ? assembly : "");
00169     }
00170 
00171     CM_LoadMap(map, day, pos, &sv.mapData, &sv.mapTiles);
00172 
00173     Com_Printf("checksum for the map '%s': %u\n", levelstring, sv.mapData.mapChecksum);
00174     SV_SetConfigString(CS_MAPCHECKSUM, sv.mapData.mapChecksum);
00175 
00176     checksum = Com_GetScriptChecksum();
00177 
00178     Com_Printf("ufo script checksum %u\n", checksum);
00179     SV_SetConfigString(CS_UFOCHECKSUM, checksum);
00180     SV_SetConfigString(CS_OBJECTAMOUNT, csi.numODs);
00181     SV_SetConfigString(CS_VERSION, UFO_VERSION);
00182     SV_SetConfigString(CS_MAPTITLE, SV_GetMapTitle(randomMap, levelstring));
00183     if (!strncmp(SV_GetConfigString(CS_MAPTITLE), "b/", 2)) {
00184         /* For base attack, CS_MAPTITLE contains too many chars */
00185         SV_SetConfigString(CS_MAPTITLE, "Base attack");
00186         SV_SetConfigString(CS_NAME, ".baseattack");
00187     }
00188 
00189     /* clear random-map assembly data */
00190     Mem_Free(randomMap);
00191     randomMap = NULL;
00192 
00193     /* clear physics interaction links */
00194     SV_ClearWorld();
00195 
00196     /* fix this! */
00197     for (i = 1; i <= sv.mapData.numInline; i++)
00198         sv.models[i] = CM_InlineModel(&sv.mapTiles, va("*%i", i));
00199 
00200     /* precache and static commands can be issued during map initialization */
00201     Com_SetServerState(ss_loading);
00202 
00203     SDL_mutexP(svs.serverMutex);
00204     /* load and spawn all other entities */
00205     svs.ge->SpawnEntities(sv.name, SV_GetConfigStringInteger(CS_LIGHTMAP), sv.mapData.mapEntityString);
00206     SDL_mutexV(svs.serverMutex);
00207 
00208     /* all precaches are complete */
00209     Com_SetServerState(ss_game);
00210 
00211     Com_Printf("-------------------------------------\n");
00212 
00213     Cbuf_CopyToDefer();
00214 }

Generated by  doxygen 1.6.2