00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "server.h"
00031 #include "sv_rma.h"
00032 #include "../shared/parse.h"
00033
00034 serverInstanceStatic_t svs;
00035 serverInstanceGame_t sv;
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
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
00079 sv_maxclients->flags |= CVAR_LATCH;
00080
00081
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
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
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
00120 Com_SetServerState(ss_restart);
00121
00122
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
00135 SV_SetConfigString(CS_NAME, levelstring);
00136 SV_SetConfigString(CS_LIGHTMAP, day);
00137
00138 Q_strncpyz(sv.name, levelstring, sizeof(sv.name));
00139
00140
00141 sv_mapname = Cvar_FullSet("sv_mapname", sv.name, CVAR_SERVERINFO | CVAR_NOSET);
00142
00143
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
00152 cl = NULL;
00153 while ((cl = SV_GetNextClient(cl)) != NULL) {
00154
00155 if (cl->state >= cs_spawning)
00156 SV_SetClientState(cl, cs_connected);
00157 }
00158
00159
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
00185 SV_SetConfigString(CS_MAPTITLE, "Base attack");
00186 SV_SetConfigString(CS_NAME, ".baseattack");
00187 }
00188
00189
00190 Mem_Free(randomMap);
00191 randomMap = NULL;
00192
00193
00194 SV_ClearWorld();
00195
00196
00197 for (i = 1; i <= sv.mapData.numInline; i++)
00198 sv.models[i] = CM_InlineModel(&sv.mapTiles, va("*%i", i));
00199
00200
00201 Com_SetServerState(ss_loading);
00202
00203 SDL_mutexP(svs.serverMutex);
00204
00205 svs.ge->SpawnEntities(sv.name, SV_GetConfigStringInteger(CS_LIGHTMAP), sv.mapData.mapEntityString);
00206 SDL_mutexV(svs.serverMutex);
00207
00208
00209 Com_SetServerState(ss_game);
00210
00211 Com_Printf("-------------------------------------\n");
00212
00213 Cbuf_CopyToDefer();
00214 }