UFO: Alien Invasion
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
sv_game.cpp
Go to the documentation of this file.
1 
6 /*
7 All original material Copyright (C) 2002-2020 UFO: Alien Invasion.
8 
9 Original file from Quake 2 v3.21: quake2-2.31/server/sv_game.c
10 Copyright (C) 1997-2001 Id Software, Inc.
11 
12 This program is free software; you can redistribute it and/or
13 modify it under the terms of the GNU General Public License
14 as published by the Free Software Foundation; either version 2
15 of the License, or (at your option) any later version.
16 
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20 
21 See the GNU General Public License for more details.
22 
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 */
27 
28 #include "server.h"
29 #include "sv_log.h"
30 #include "../common/grid.h"
31 #include "../common/routing.h"
32 #include "../ports/system.h"
33 #include "../shared/thread.h"
34 #include "../shared/scopedmutex.h"
35 
39 static void SV_dprintf (const char* fmt, ...)
40 {
41  va_list ap;
42 
43  va_start(ap, fmt);
44  SV_LogAdd(fmt, ap);
45  va_end(ap);
46 }
47 
52 static void SV_PlayerPrintf (const SrvPlayer* player, int level, const char* fmt, va_list ap)
53 {
54  if (level == PRINT_NONE)
55  return;
56 
57  if (player) {
58  char msg[1024];
59  Q_vsnprintf(msg, sizeof(msg), fmt, ap);
60  client_t* cl = SV_GetClient(player->getNum());
61  SV_ClientPrintf(cl, level, "%s", msg);
62  } else
63  SV_LogAdd(fmt, ap);
64 }
65 
69 static float SV_GetVisibility (const pos3_t position)
70 {
71  return CM_GetVisibility(&sv->mapTiles, position);
72 }
73 
74 static void SV_error (const char* fmt, ...) __attribute__((noreturn));
79 static void SV_error (const char* fmt, ...)
80 {
81  char msg[1024];
82  va_list argptr;
83 
84  va_start(argptr, fmt);
85  Q_vsnprintf(msg, sizeof(msg), fmt, argptr);
86  va_end(argptr);
87 
88  Com_Error(ERR_DROP, "Game Error: %s", msg);
89 }
90 
99 static unsigned int SV_FindIndex (const char* name, int start, int max, bool create)
100 {
101  int i;
102 
103  if (!name || !name[0])
104  return 0;
105 
106  for (i = 1; i < max && SV_GetConfigString(start + i)[0] != '\0'; i++) {
107  const char* configString = SV_GetConfigString(start + i);
108  if (Q_streq(configString, name))
109  return i;
110  }
111 
112  if (!create)
113  return 0;
114 
115  if (i == max)
116  SV_error("*Index: overflow '%s' start: %i, max: %i", name, start, max);
117 
118  SV_SetConfigString(start + i, name);
119 
120  if (Com_ServerState() != ss_loading) { /* send the update to everyone */
121  dbuffer msg(4 + strlen(name));
123  NET_WriteShort(&msg, start + i);
124  NET_WriteString(&msg, name);
125  SV_Multicast(~0, msg);
126  }
127 
128  return i;
129 }
130 
131 static unsigned int SV_ModelIndex (const char* name)
132 {
133  return SV_FindIndex(name, CS_MODELS, MAX_MODELS, true);
134 }
135 
140 static void SV_SetModel (edict_t* ent, const char* name)
141 {
142  if (!name)
143  SV_error("SV_SetModel: nullptr");
144 
145  ent->modelindex = SV_ModelIndex(name);
146 
147  /* if it is an inline model, get the size information for it */
148  if (name[0] == '*') {
149  const cBspModel_t* mod = CM_InlineModel(&sv->mapTiles, name);
150  /* Copy model mins and maxs to entity */
151  ent->entBox.set(mod->cbmBox);
152  /* This is to help the entity collision code out */
153  /* Copy entity origin and angles to model*/
155  }
156 }
157 
161 static void SV_Configstring (int index, const char* fmt, ...)
162 {
163  char val[MAX_TOKEN_CHARS * MAX_TILESTRINGS];
164  va_list argptr;
165 
166  if (!Com_CheckConfigStringIndex(index))
167  SV_error("configstring: bad index %i", index);
168 
169  va_start(argptr, fmt);
170  Q_vsnprintf(val, sizeof(val), fmt, argptr);
171  va_end(argptr);
172 
173  SV_SetConfigString(index, val);
174 
175  if (Com_ServerState() != ss_loading) { /* send the update to everyone */
176  dbuffer msg(4 + strlen(val));
178  NET_WriteShort(&msg, index);
179  NET_WriteString(&msg, val);
180 
181  /* send to all clients */
182  SV_Multicast(~0, msg);
183  }
184 }
185 
186 static void SV_WriteChar (char c)
187 {
189 }
190 
191 static void SV_WriteByte (byte c)
192 {
194 }
195 
196 static void SV_WriteShort (int c)
197 {
199 }
200 
201 static void SV_WriteLong (int c)
202 {
204 }
205 
206 static void SV_WriteString (const char* s)
207 {
209 }
210 
211 static void SV_WritePos (const vec3_t pos)
212 {
214 }
215 
216 static void SV_WriteGPos (const pos3_t pos)
217 {
219 }
220 
221 static void SV_WriteDir (const vec3_t dir)
222 {
224 }
225 
226 static void SV_WriteAngle (float f)
227 {
229 }
230 
231 static void SV_WriteFormat (const char* format, ...)
232 {
233  va_list ap;
234  va_start(ap, format);
235  NET_vWriteFormat(sv->pendingEvent.buf, format, ap);
236  va_end(ap);
237 }
238 
239 static int SV_ReadChar (void)
240 {
241  return NET_ReadChar(sv->messageBuffer);
242 }
243 
244 static int SV_ReadByte (void)
245 {
246  return NET_ReadByte(sv->messageBuffer);
247 }
248 
249 static int SV_ReadShort (void)
250 {
251  return NET_ReadShort(sv->messageBuffer);
252 }
253 
254 static int SV_ReadLong (void)
255 {
256  return NET_ReadLong(sv->messageBuffer);
257 }
258 
259 static int SV_ReadString (char* str, size_t length)
260 {
261  return NET_ReadString(sv->messageBuffer, str, length);
262 }
263 
264 static void SV_ReadPos (vec3_t pos)
265 {
267 }
268 
269 static void SV_ReadGPos (pos3_t pos)
270 {
272 }
273 
274 static void SV_ReadDir (vec3_t vector)
275 {
276  NET_ReadDir(sv->messageBuffer, vector);
277 }
278 
279 static float SV_ReadAngle (void)
280 {
281  return NET_ReadAngle(sv->messageBuffer);
282 }
283 
284 static void SV_ReadData (void* buffer, int size)
285 {
286  NET_ReadData(sv->messageBuffer, buffer, size);
287 }
288 
292 static void SV_ReadFormat (const char* format, ...)
293 {
294  va_list ap;
295 
296  assert(format);
297  if (!*format) /* PA_NULL */
298  return;
299 
300  va_start(ap, format);
301  NET_vReadFormat(sv->messageBuffer, format, ap);
302  va_end(ap);
303 }
304 
308 static void SV_AbortEvents (void)
309 {
311 
312  if (!p->pending)
313  return;
314 
315  p->pending = false;
316  delete p->buf;
317  p->buf = nullptr;
318 }
319 
320 static void SV_SendQueuedEvents (void)
321 {
322  for (int i = 0; i < sv->eventQueuePos; i++) {
323  pending_event_t& entry = sv->eventQueue[i];
324  NET_WriteByte(entry.buf, EV_NULL);
325  SV_Multicast(entry.playerMask, *entry.buf);
326  delete entry.buf;
327  }
328  sv->eventQueuePos = 0;
329 }
330 
334 static void SV_EndEvents (void)
335 {
337 
338  if (!p->pending) {
340  return;
341  }
342 
344  SV_Multicast(p->playerMask, *p->buf);
345  p->pending = false;
346  delete p->buf;
347  p->buf = nullptr;
348 
350 }
351 
352 typedef struct {
353  const char* name;
354 } eventNames_t;
355 
356 #define M(x) { #x }
357 static const eventNames_t eventNames[] = {
358  M(EV_NULL),
359  M(EV_RESET),
360  M(EV_START),
361  M(EV_ENDROUND),
363 
364  M(EV_RESULTS),
365  M(EV_CENTERVIEW),
366  M(EV_MOVECAMERA),
367 
368  M(EV_ENT_APPEAR),
369  M(EV_ENT_PERISH),
370  M(EV_ENT_DESTROY),
372  M(EV_ADD_EDICT),
373 
375  M(EV_ACTOR_ADD),
376  M(EV_ACTOR_TURN),
377  M(EV_ACTOR_MOVE),
383 
385  M(EV_ACTOR_SHOOT),
387  M(EV_ACTOR_THROW),
389 
390  M(EV_ACTOR_DIE),
392  M(EV_ACTOR_STATS),
395  M(EV_ACTOR_WOUND),
396 
397  M(EV_INV_ADD),
398  M(EV_INV_DEL),
399  M(EV_INV_AMMO),
400  M(EV_INV_RELOAD),
402 
405 
408 
409  M(EV_SOUND),
410 
411  M(EV_DOOR_OPEN),
412  M(EV_DOOR_CLOSE),
415 
417 };
418 #undef M
419 CASSERT(lengthof(eventNames) == EV_NUM_EVENTS);
420 
427 static void SV_AddEvent (unsigned int mask, int eType, int entnum)
428 {
430  const int rawType = eType &~ EVENT_INSTANTLY;
431 
432  if (rawType >= EV_NUM_EVENTS || rawType < 0)
433  Com_Error(ERR_DROP, "SV_AddEvent: invalid event %i", rawType);
434 
435  const char* eventName = eventNames[rawType].name;
436  Com_DPrintf(DEBUG_EVENTSYS, "Event type: %s (%i - %i) (mask %s) (entnum: %i)\n", eventName,
437  rawType, eType, Com_UnsignedIntToBinary(mask), entnum);
438 
439  /* finish the last event */
440  if (p->pending)
441  SV_EndEvents();
442  else
444 
445  /* start the new event */
446  p->pending = true;
447  p->playerMask = mask;
448  p->type = eType;
449  p->entnum = entnum;
450  p->buf = new dbuffer();
451 
452  /* write header */
454  NET_WriteByte(p->buf, eType);
455  if (entnum != -1)
456  NET_WriteShort(p->buf, entnum);
457 }
458 
465 static void SV_QueueEvent (unsigned int mask, int eType, int entnum)
466 {
468  Com_Error(ERR_DROP, "overflow in SV_QueueEvent");
469 
470  const int rawType = eType &~ EVENT_INSTANTLY;
471 
472  if (rawType >= EV_NUM_EVENTS || rawType < 0)
473  Com_Error(ERR_DROP, "SV_QueueEvent: invalid event %i", rawType);
474 
475  const char* eventName = eventNames[rawType].name;
476  Com_DPrintf(DEBUG_EVENTSYS, "Queued event type: %s (%i - %i) (mask %s) (entnum: %i)\n", eventName,
477  rawType, eType, Com_UnsignedIntToBinary(mask), entnum);
478 
480 
481  /* start the new event */
482  p.pending = false;
483  p.playerMask = mask;
484  p.type = eType;
485  p.entnum = entnum;
486  p.buf = new dbuffer();
487  /* write header */
489  NET_WriteByte(p.buf, eType);
490  if (p.entnum != -1)
491  NET_WriteShort(p.buf, p.entnum);
492 }
493 
494 static void SV_QueueWriteByte (byte c)
495 {
497 }
498 
499 static void SV_QueueWriteString (const char* s)
500 {
502 }
503 
504 static void SV_QueueWritePos (const vec3_t pos)
505 {
507 }
508 
509 static void SV_QueueWriteShort (int c)
510 {
512 }
513 
517 static int SV_GetEvent (void)
518 {
519  const pending_event_t* p = &sv->pendingEvent;
520  if (!p->pending)
521  return -1;
522 
523  return p->type;
524 }
525 
526 static edict_t* SV_GetEventEdict (void)
527 {
528  const pending_event_t* p = &sv->pendingEvent;
529  if (!p->pending)
530  return nullptr;
531 
532  if (p->entnum == -1)
533  return nullptr;
534 
535  const sv_edict_t& e = sv->edicts[p->entnum];
536  return e.ent;
537 }
538 
542 static void* SV_TagAlloc (int size, int tagNum, const char* file, int line)
543 {
544  if (tagNum < 0)
545  tagNum *= -1;
546 
547  return _Mem_Alloc(size, true, sv->gameSysPool, tagNum, file, line);
548 }
549 
550 static void SV_MemFree (void* ptr, const char* file, int line)
551 {
552  _Mem_Free(ptr, file, line);
553 }
554 
558 static void SV_FreeTags (int tagNum, const char* file, int line)
559 {
560  if (tagNum < 0)
561  tagNum *= -1;
562 
563  _Mem_FreeTag(sv->gameSysPool, tagNum, file, line);
564 }
565 
566 static bool SV_TestLine (const vec3_t start, const vec3_t stop, const int levelmask)
567 {
568  return TR_TestLine(&sv->mapTiles, start, stop, levelmask);
569 }
570 
571 static bool SV_TestLineWithEnt (const vec3_t start, const vec3_t stop, const int levelmask, const char** entlist)
572 {
573  /* do the line test */
574  const bool hit = CM_EntTestLine(&sv->mapTiles, Line(start, stop), levelmask, entlist);
575  return hit;
576 }
577 
578 static pos_t SV_GridFall (const int actorSize, const pos3_t pos)
579 {
580  return Grid_Fall(sv->mapData.routing, actorSize, pos);
581 }
582 
583 static void SV_RecalcRouting (const char* name, const GridBox& box, const char** list)
584 {
585  Grid_RecalcRouting(&sv->mapTiles, sv->mapData.routing, name, box, list);
586 }
587 
588 static void SV_GridPosToVec (const int actorSize, const pos3_t pos, vec3_t vec)
589 {
590  Grid_PosToVec(sv->mapData.routing, actorSize, pos, vec);
591 }
592 
593 static bool SV_GridIsOnMap (const vec3_t vec)
594 {
595  return sv->mapData.mapBox.contains(vec);
596 }
597 
598 static void SV_GridCalcPathing (actorSizeEnum_t actorSize, pathing_t* path, const pos3_t from, int distance, forbiddenList_t* forbiddenList)
599 {
600  Grid_CalcPathing(sv->mapData.routing, actorSize, path, from, distance, forbiddenList);
601 }
602 
603 static bool SV_GridFindPath (actorSizeEnum_t actorSize, pathing_t* path, const pos3_t from, const pos3_t targetPos, byte crouchingState, int maxTUs, forbiddenList_t* forbiddenList)
604 {
605  return Grid_FindPath(sv->mapData.routing, actorSize, path, from, targetPos, crouchingState, maxTUs, forbiddenList);
606 }
607 
608 static bool SV_CanActorStandHere (const int actorSize, const pos3_t pos)
609 {
610  return RT_CanActorStandHere(sv->mapData.routing, actorSize, pos);
611 }
612 
613 static void SV_SetInlineModelOrientation (const char* name, const vec3_t origin, const vec3_t angles)
614 {
615  CM_SetInlineModelOrientation(&sv->mapTiles, name, origin, angles);
616 }
617 
618 static void SV_GetInlineModelAABB (const char* name, AABB& aabb)
619 {
620  CM_GetInlineModelAABB(&sv->mapTiles, name, aabb);
621 }
622 
623 static void SV_UnloadGame (void)
624 {
625 #ifndef HARD_LINKED_GAME
626  if (svs.gameLibrary) {
627  Com_Printf("Unload the game library\n");
628  SDL_UnloadObject(svs.gameLibrary);
629  }
630 #endif
631 }
632 
633 #ifndef HARD_LINKED_GAME
634 static bool SV_LoadGame (const char* path)
635 {
636  char name[MAX_OSPATH];
637 
638  Com_sprintf(name, sizeof(name), "%s/game_" CPUSTRING ".%s", path, SO_EXT);
639  svs.gameLibrary = SDL_LoadObject(name);
640  if (!svs.gameLibrary) {
641  Com_sprintf(name, sizeof(name), "%s/game.%s", path, SO_EXT);
642  svs.gameLibrary = SDL_LoadObject(name);
643  }
644 
645  if (svs.gameLibrary) {
646  Com_Printf("found at '%s'\n", path);
647  return true;
648  } else {
649  Com_Printf("not found at '%s'\n", path);
650  Com_DPrintf(DEBUG_SYSTEM, "%s\n", SDL_GetError());
651  return false;
652  }
653 }
654 #endif
655 
660 {
661 #ifndef HARD_LINKED_GAME
662  typedef game_export_t* (*game_api_t) (game_import_t*);
663  game_api_t GetGameAPI;
664  const char* path;
665 
666  if (svs.gameLibrary)
667  Com_Error(ERR_FATAL, "SV_GetGameAPI without SV_UnloadGame");
668 
669  Com_Printf("------- Loading game.%s -------\n", SO_EXT);
670 
671 #ifdef PKGLIBDIR
673 #endif
674 
675  /* now run through the search paths */
676  path = nullptr;
677  while (!svs.gameLibrary) {
678  path = FS_NextPath(path);
679  if (!path)
680  /* couldn't find one anywhere */
681  return nullptr;
682  else if (SV_LoadGame(path))
683  break;
684  }
685 
686  GetGameAPI = (game_api_t)(uintptr_t)SDL_LoadFunction(svs.gameLibrary, "GetGameAPI");
687  if (!GetGameAPI) {
688  SV_UnloadGame();
689  return nullptr;
690  }
691 #endif
692 
693  return GetGameAPI(parms);
694 }
695 
696 static char const* const gameSysPoolName = "Server: Game system";
697 
704 {
705  uint32_t size;
706 
707  if (!svs.ge)
708  return;
709 
711 
712  if (svs.gameThread) {
713  SDL_CondSignal(svs.gameFrameCond);
714  SDL_WaitThread(svs.gameThread, nullptr);
715  SDL_DestroyCond(svs.gameFrameCond);
716  svs.gameFrameCond = nullptr;
717  svs.gameThread = nullptr;
718  }
719 
720  svs.ge->Shutdown();
721 
722  size = Mem_PoolSize(sv->gameSysPool);
723  if (size > 0) {
724  Com_Printf("WARNING: Game memory leak (%u bytes)\n", size);
725  Cmd_ExecuteString("mem_stats %s", gameSysPoolName);
726  }
727 
729  sv->gameSysPool = nullptr;
730 
731  SV_UnloadGame();
732 
733  svs.ge = nullptr;
734 }
735 
742 {
743  do {
744  const ScopedMutex scopedMutex(svs.serverMutex);
745  SDL_CondWait(svs.gameFrameCond, svs.serverMutex);
746  SV_RunGameFrame();
747  } while (!sv->endgame);
748 
749  return 0;
750 }
751 
758 void SV_RunGameFrame (void)
759 {
760  sv->endgame = svs.ge->RunFrame();
761  if (sv->state == ss_game_shutdown)
762  sv->endgame = true;
763 }
764 
769 void SV_InitGameProgs (void)
770 {
771  game_import_t import;
772 
773  /* unload anything we have now */
774  /*SV_ShutdownGameProgs();*/
775 
776  /* load a new game dll */
777  import.BroadcastPrintf = SV_BroadcastPrintf;
778  import.DPrintf = SV_dprintf;
779  import.PlayerPrintf = SV_PlayerPrintf;
780  import.Error = SV_error;
781 
782  import.Trace = SV_Trace;
783  import.LinkEdict = SV_LinkEdict;
784  import.UnlinkEdict = SV_UnlinkEdict;
785 
786  import.TestLine = SV_TestLine;
787  import.TestLineWithEnt = SV_TestLineWithEnt;
788  import.GrenadeTarget = Com_GrenadeTarget;
789 
790  import.GridCalcPathing = SV_GridCalcPathing;
791  import.GridFindPath = SV_GridFindPath;
792  import.MoveStore = Grid_MoveStore;
793  import.MoveLength = Grid_MoveLength;
794  import.MoveNext = Grid_MoveNext;
795  import.GetTUsForDirection = Grid_GetTUsForDirection;
796  import.GridFall = SV_GridFall;
797  import.GridPosToVec = SV_GridPosToVec;
798  import.isOnMap = SV_GridIsOnMap;
799  import.GridRecalcRouting = SV_RecalcRouting;
800  import.CanActorStandHere = SV_CanActorStandHere;
801  import.GridShouldUseAutostand = Grid_ShouldUseAutostand;
802 
803  import.GetVisibility = SV_GetVisibility;
804 
805  import.ModelIndex = SV_ModelIndex;
806 
807  import.SetInlineModelOrientation = SV_SetInlineModelOrientation;
808  import.GetInlineModelAABB = SV_GetInlineModelAABB;
809 
810  import.SetModel = SV_SetModel;
811 
812  import.ConfigString = SV_Configstring;
813 
814  import.PointContents = SV_PointContents;
815  import.GetFootstepSound = SV_GetFootstepSound;
816  import.GetBounceFraction = SV_GetBounceFraction;
817  import.LoadModelAABB = SV_LoadModelAABB;
818 
819  import.FS_Gamedir = FS_Gamedir;
820  import.FS_LoadFile = FS_LoadFile;
821  import.FS_FreeFile = FS_FreeFile;
822  import.Sys_Fopen = Sys_Fopen;
823 
824  import.WriteChar = SV_WriteChar;
825  import.WriteByte = SV_WriteByte;
826  import.WriteShort = SV_WriteShort;
827  import.WriteLong = SV_WriteLong;
828  import.WriteString = SV_WriteString;
829  import.WritePos = SV_WritePos;
830  import.WriteGPos = SV_WriteGPos;
831  import.WriteDir = SV_WriteDir;
832  import.WriteAngle = SV_WriteAngle;
833  import.WriteFormat = SV_WriteFormat;
834 
835  import.AbortEvents = SV_AbortEvents;
836  import.EndEvents = SV_EndEvents;
837  import.AddEvent = SV_AddEvent;
838  import.GetEvent = SV_GetEvent;
839  import.GetEventEdict = SV_GetEventEdict;
840 
841  import.QueueEvent = SV_QueueEvent;
842  import.QueueWriteByte = SV_QueueWriteByte;
843  import.QueueWritePos = SV_QueueWritePos;
844  import.QueueWriteString = SV_QueueWriteString;
845  import.QueueWriteShort = SV_QueueWriteShort;
846 
847  import.ReadChar = SV_ReadChar;
848  import.ReadByte = SV_ReadByte;
849  import.ReadShort = SV_ReadShort;
850  import.ReadLong = SV_ReadLong;
851  import.ReadString = SV_ReadString;
852  import.ReadPos = SV_ReadPos;
853  import.ReadGPos = SV_ReadGPos;
854  import.ReadDir = SV_ReadDir;
855  import.ReadAngle = SV_ReadAngle;
856  import.ReadData = SV_ReadData;
857  import.ReadFormat = SV_ReadFormat;
858 
859  import.GetConstInt = Com_GetConstInt;
860  import.GetConstIntFromNamespace = Com_GetConstIntFromNamespace;
861  import.GetConstVariable = Com_GetConstVariable;
862  import.RegisterConstInt = Com_RegisterConstInt;
863  import.UnregisterConstVariable = Com_UnregisterConstVariable;
864 
865  import.GetCharacterValues = Com_GetCharacterValues;
866 
867  import.TagMalloc = SV_TagAlloc;
868  import.TagFree = SV_MemFree;
869  import.FreeTags = SV_FreeTags;
870 
871  import.Cvar_Get = Cvar_Get;
872  import.Cvar_Set = Cvar_Set;
873  import.Cvar_String = Cvar_GetString;
874 
875  import.Cmd_Argc = Cmd_Argc;
876  import.Cmd_Argv = Cmd_Argv;
877  import.Cmd_Args = Cmd_Args;
878  import.AddCommandString = Cbuf_AddText;
879 
880  import.seed = Sys_Milliseconds();
881  import.csi = &csi;
882 
883  Com_Printf("setting game random seed to %i\n", import.seed);
884 
885  svs.ge = SV_GetGameAPI(&import);
886 
887  if (!svs.ge)
888  Com_Error(ERR_DROP, "failed to load game library");
890  Com_Error(ERR_DROP, "game is version %i, not %i", svs.ge->apiversion, GAME_API_VERSION);
891 
892  sv->gameSysPool = Mem_CreatePool(gameSysPoolName);
893 
894  svs.ge->Init();
895 
896  if (sv_threads->integer) {
897  svs.gameFrameCond = SDL_CreateCond();
899  }
900 }
static int SV_ReadLong(void)
Definition: sv_game.cpp:254
bool Grid_ShouldUseAutostand(const pathing_t *path, const pos3_t toPos)
Checks if a crouched actor could save TUs by standing up, walking and crouching again.
Definition: grid.cpp:818
const char * Cmd_Argv(int arg)
Returns a given argument.
Definition: cmd.cpp:516
pending_event_t eventQueue[64]
Definition: server.h:121
void NET_ReadPos(dbuffer *buf, vec3_t pos)
Definition: netpack.cpp:364
void NET_ReadGPos(dbuffer *buf, pos3_t pos)
Definition: netpack.cpp:376
edict_t * ent
Definition: server.h:43
static void SV_WritePos(const vec3_t pos)
Definition: sv_game.cpp:211
#define M(x)
Definition: sv_game.cpp:356
void void void SV_BroadcastPrintf(int level, const char *fmt,...) __attribute__((format(__printf__
static void SV_QueueWriteShort(int c)
Definition: sv_game.cpp:509
int Q_vsnprintf(char *str, size_t size, const char *format, va_list ap)
Safe (null terminating) vsnprintf implementation.
Definition: shared.cpp:535
bool Com_UnregisterConstVariable(const char *name)
Removes a registered constant from the script mapping hash table.
Definition: scripts.cpp:147
static bool SV_TestLine(const vec3_t start, const vec3_t stop, const int levelmask)
Definition: sv_game.cpp:566
int Grid_GetTUsForDirection(const int dir, bool crouched)
Returns the amounts of TUs that are needed to perform one step into the given direction.
Definition: grid.cpp:766
bool Com_GetConstIntFromNamespace(const char *space, const char *variable, int *value)
Searches whether a given value was registered as a string to int mapping.
Definition: scripts.cpp:103
#define DEBUG_EVENTSYS
Definition: defines.h:64
int Grid_MoveNext(const pathing_t *path, const pos3_t toPos, byte crouchingState)
Get the direction to use to move to a position (used to reconstruct the path)
Definition: grid.cpp:719
char * SV_GetConfigString(int index)
Definition: sv_main.cpp:77
static void SV_ReadFormat(const char *format,...)
Definition: sv_game.cpp:292
static void SV_Configstring(int index, const char *fmt,...)
Definition: sv_game.cpp:161
#define GAME_API_VERSION
Definition: game.h:35
SDL_mutex * serverMutex
Definition: server.h:86
#define CPUSTRING
Definition: common.h:109
vec3_t origin
Definition: srvedict.h:42
void NET_ReadDir(dbuffer *buf, vec3_t dir)
Definition: netpack.cpp:400
static void SV_error(const char *fmt,...) __attribute__((noreturn))
Abort the server with a game error.
Definition: sv_game.cpp:79
static void SV_ReadGPos(pos3_t pos)
Definition: sv_game.cpp:269
static void SV_WriteGPos(const pos3_t pos)
Definition: sv_game.cpp:216
int NET_ReadChar(dbuffer *buf)
Definition: netpack.cpp:221
void * _Mem_Alloc(size_t size, bool zeroFill, memPool_t *pool, const int tagNum, const char *fileName, const int fileLine)
Definition: game.h:45
pos_t Grid_Fall(const Routing &routing, const actorSizeEnum_t actorSize, const pos3_t pos)
Calculated the new height level when something falls down from a certain position.
Definition: grid.cpp:783
voidpf uLong int origin
Definition: ioapi.h:45
csi_t csi
Definition: common.cpp:39
bool Com_sprintf(char *dest, size_t size, const char *fmt,...)
copies formatted string with buffer-size checking
Definition: shared.cpp:494
int32_t actorSizeEnum_t
Definition: ufotypes.h:77
#define MAX_TILESTRINGS
Definition: q_shared.h:298
static void SV_dprintf(const char *fmt,...)
Debug print to server console.
Definition: sv_game.cpp:39
static void SV_PlayerPrintf(const SrvPlayer *player, int level, const char *fmt, va_list ap)
Print to a single client.
Definition: sv_game.cpp:52
Definition: aabb.h:42
void Grid_CalcPathing(const Routing &routing, const actorSizeEnum_t actorSize, pathing_t *path, const pos3_t from, int maxTUs, forbiddenList_t *fb_list)
Recalculate the pathing table for the given actor(-position)
Definition: grid.cpp:497
#define PRINT_NONE
Definition: defines.h:105
static int SV_ReadString(char *str, size_t length)
Definition: sv_game.cpp:259
void Cbuf_AddText(const char *format,...)
Adds command text at the end of the buffer.
Definition: cmd.cpp:126
static void SV_GetInlineModelAABB(const char *name, AABB &aabb)
Definition: sv_game.cpp:618
void SV_ShutdownGameProgs(void)
Called when either the entire server is being killed, or it is changing to a different game directory...
Definition: sv_game.cpp:703
void NET_WriteString(dbuffer *buf, const char *str)
Definition: netpack.cpp:59
void NET_WriteChar(dbuffer *buf, char c)
Definition: netpack.cpp:33
static const eventNames_t eventNames[]
Definition: sv_game.cpp:357
static void SV_GridPosToVec(const int actorSize, const pos3_t pos, vec3_t vec)
Definition: sv_game.cpp:588
#define DEBUG_SYSTEM
Definition: defines.h:57
void NET_WritePos(dbuffer *buf, const vec3_t pos)
Definition: netpack.cpp:96
static void SV_WriteChar(char c)
Definition: sv_game.cpp:186
int FS_LoadFile(const char *path, byte **buffer)
Filenames are relative to the quake search path.
Definition: files.cpp:384
static void SV_WriteString(const char *s)
Definition: sv_game.cpp:206
void SV_UnlinkEdict(edict_t *ent)
call before removing an entity, and before trying to move one, so it doesn't clip against itself ...
Definition: sv_world.cpp:97
int NET_ReadLong(dbuffer *buf)
Definition: netpack.cpp:282
void set(const AABB &other)
Copies the values from the given aabb.
Definition: aabb.h:60
#define MAX_OSPATH
Definition: filesys.h:44
void Com_Printf(const char *const fmt,...)
Definition: common.cpp:386
SDL_Thread * Com_CreateThread(int(*fn)(void *), const char *name, void *data=nullptr)
Definition: thread.h:5
static unsigned int SV_FindIndex(const char *name, int start, int max, bool create)
Search the index in the config strings relative to a given start.
Definition: sv_game.cpp:99
void Grid_RecalcRouting(mapTiles_t *mapTiles, Routing &routing, const char *name, const GridBox &box, const char **list)
This function recalculates the routing surrounding the entity name.
Definition: grid.cpp:922
void NET_vReadFormat(dbuffer *buf, const char *format, va_list ap)
Reads from a buffer according to format; version without syntactic sugar for variable arguments...
Definition: netpack.cpp:415
void Com_SetServerState(int state)
Definition: common.cpp:547
bool SV_LoadModelAABB(const char *model, int frame, AABB &aabb)
Load the bounding box for the model on the serverside for pathfinding and clipping.
Definition: sv_world.cpp:543
#define __attribute__(x)
Definition: cxx.h:37
void SV_LinkEdict(edict_t *ent)
Needs to be called any time an entity changes origin, mins, maxs, or solid. Automatically unlinks if ...
Definition: sv_world.cpp:131
int integer
Definition: cvar.h:81
#define ERR_FATAL
Definition: common.h:210
void SV_InitGameProgs(void)
Init the game subsystem for a new map.
Definition: sv_game.cpp:769
#define PKGLIBDIR
Definition: config_android.h:8
void Com_GetCharacterValues(const char *teamDefition, character_t *chr)
Assign character values, 3D models and names to a character.
Definition: scripts.cpp:2430
void Com_Error(int code, const char *fmt,...)
Definition: common.cpp:417
dbuffer * buf
Definition: server.h:73
const char * name
Definition: sv_game.cpp:353
client_t * SV_GetClient(int index)
Definition: sv_main.cpp:174
vec3_t angles
Definition: srvedict.h:43
pos_t Grid_MoveLength(const pathing_t *path, const pos3_t to, byte crouchingState, bool stored)
Return the needed TUs to walk to a given position.
Definition: grid.cpp:698
void Cmd_ExecuteString(const char *text,...)
A complete command line has been parsed, so try to execute it.
Definition: cmd.cpp:1007
void SV_Multicast(int mask, const dbuffer &msg)
Sends the contents of msg to a subset of the clients, then frees msg.
Definition: sv_send.cpp:126
const char * FS_Gamedir(void)
Called to find where to write a file (savegames, etc)
Definition: files.cpp:68
serverInstanceGame_t * sv
Definition: sv_init.cpp:36
pending_event_t pendingEvent
Definition: server.h:120
#define SV_SetConfigString(index, value)
Definition: server.h:188
functions exported by the game subsystem
Definition: game.h:317
CASSERT(lengthof(eventNames)==EV_NUM_EVENTS)
#define CS_MODELS
Definition: q_shared.h:327
static int SV_ReadChar(void)
Definition: sv_game.cpp:239
void _Mem_Free(void *ptr, const char *fileName, const int fileLine)
Definition: mem.cpp:204
functions provided by the main engine
Definition: game.h:173
void NET_vWriteFormat(dbuffer *buf, const char *format, va_list ap)
Writes to buffer according to format; version without syntactic sugar for variable arguments...
Definition: netpack.cpp:149
#define ERR_DROP
Definition: common.h:211
void SV_RunGameFrame(void)
Calls the G_RunFrame function from game api let everything in the world think and move...
Definition: sv_game.cpp:758
cvar_t * sv_threads
Definition: sv_main.cpp:48
cvar_t * Cvar_Get(const char *var_name, const char *var_value, int flags, const char *desc)
Init or return a cvar.
Definition: cvar.cpp:342
int NET_ReadString(dbuffer *buf, char *string, size_t length)
Definition: netpack.cpp:302
GLsizei size
Definition: r_gl.h:152
game lib logging handling
static unsigned int SV_ModelIndex(const char *name)
Definition: sv_game.cpp:131
QGL_EXTERN GLuint GLsizei GLsizei * length
Definition: r_gl.h:110
bool contains(const vec3_t point) const
Definition: aabb.h:200
bool pending
Definition: server.h:68
float CM_GetVisibility(const mapTiles_t *mapTiles, const pos3_t position)
Checks how well a position is visible.
Definition: bsp.cpp:991
static float SV_ReadAngle(void)
Definition: sv_game.cpp:279
static void SV_QueueWritePos(const vec3_t pos)
Definition: sv_game.cpp:504
static void SV_FreeTags(int tagNum, const char *file, int line)
Makes sure the game DLL does not use client, or signed tags.
Definition: sv_game.cpp:558
int Cmd_Argc(void)
Return the number of arguments of the current command. "command parameter" will result in a argc of 2...
Definition: cmd.cpp:505
static bool SV_GridFindPath(actorSizeEnum_t actorSize, pathing_t *path, const pos3_t from, const pos3_t targetPos, byte crouchingState, int maxTUs, forbiddenList_t *forbiddenList)
Definition: sv_game.cpp:603
void NET_WriteLong(dbuffer *buf, int c)
Definition: netpack.cpp:52
Main server include file.
float Com_GrenadeTarget(const vec3_t from, const vec3_t at, float speed, bool launched, bool rolled, vec3_t v0)
Calculates parabola-type shot.
Definition: common.cpp:231
int NET_ReadShort(dbuffer *buf)
Definition: netpack.cpp:242
static forbiddenList_t forbiddenList
A list of locations that cannot be moved to.
Definition: cl_actor.cpp:602
clientBattleScape_t cl
#define Mem_CreatePool(name)
Definition: mem.h:32
#define EVENT_INSTANTLY
Definition: q_shared.h:73
#define Mem_DeletePool(pool)
Definition: mem.h:33
static void SV_SetModel(edict_t *ent, const char *name)
Definition: sv_game.cpp:140
mapData_t mapData
Definition: server.h:124
server_state_t state
Definition: server.h:107
static void SV_UnloadGame(void)
Definition: sv_game.cpp:623
void CM_GetInlineModelAABB(mapTiles_t *mapTiles, const char *name, AABB &aabb)
This function calculates a model's aabb in world coordinates.
Definition: bsp.cpp:979
bool CM_EntTestLine(mapTiles_t *mapTiles, const Line &traceLine, const int levelmask, const char **entlist)
Checks traces against the world and all inline models.
Definition: cmodel.cpp:184
static void SV_WriteAngle(float f)
Definition: sv_game.cpp:226
#define MAX_TOKEN_CHARS
Definition: defines.h:372
Definition: line.h:31
void Com_DPrintf(int level, const char *fmt,...)
A Com_Printf that only shows up if the "developer" cvar is set.
Definition: common.cpp:398
Definition: grid.h:83
bool Grid_FindPath(const Routing &routing, const actorSizeEnum_t actorSize, pathing_t *path, const pos3_t from, const pos3_t targetPos, byte crouchingState, int maxTUs, forbiddenList_t *forbiddenList)
Tries to find a path from the given actor(-position) to a given target position.
Definition: grid.cpp:590
pos_t pos3_t[3]
Definition: ufotypes.h:58
int SV_PointContents(const vec3_t p)
Returns the content flags for a given point.
Definition: sv_world.cpp:395
static void SV_AbortEvents(void)
Definition: sv_game.cpp:308
AABB cbmBox
Definition: typedefs.h:27
void Com_RegisterConstInt(const char *name, int value)
Register mappings between script strings and enum values for values of the type V_INT.
Definition: scripts.cpp:198
int getNum(void) const
Definition: game.h:58
static void SV_WriteFormat(const char *format,...)
Definition: sv_game.cpp:231
QGL_EXTERN GLuint index
Definition: r_gl.h:110
AABB entBox
Definition: srvedict.h:48
bool Com_CheckConfigStringIndex(int index)
Definition: common.cpp:860
cBspModel_t * CM_InlineModel(const mapTiles_t *mapTiles, const char *name)
Searches all inline models and return the cBspModel_t pointer for the given modelnumber or -name...
Definition: bsp.cpp:929
static bool SV_GridIsOnMap(const vec3_t vec)
Definition: sv_game.cpp:593
QGL_EXTERN GLfloat f
Definition: r_gl.h:114
#define MAX_MODELS
Definition: defines.h:100
static void SV_EndEvents(void)
Definition: sv_game.cpp:334
const char * Com_UnsignedIntToBinary(uint32_t x)
Definition: common.cpp:1021
const char * Com_GetConstVariable(const char *space, int value)
Searches the mapping variable for a given integer value and a namespace.
Definition: scripts.cpp:122
void Grid_MoveStore(pathing_t *path)
Caches the calculated move.
Definition: grid.cpp:683
static void SV_WriteByte(byte c)
Definition: sv_game.cpp:191
void NET_ReadData(dbuffer *buf, void *data, int len)
Definition: netpack.cpp:394
void NET_WriteAngle(dbuffer *buf, float f)
Definition: netpack.cpp:110
mapTiles_t mapTiles
Definition: server.h:126
static char const *const gameSysPoolName
Definition: sv_game.cpp:696
int SV_RunGameFrameThread(void *data)
Thread for the game frame function.
Definition: sv_game.cpp:741
static bool SV_TestLineWithEnt(const vec3_t start, const vec3_t stop, const int levelmask, const char **entlist)
Definition: sv_game.cpp:571
static void SV_WriteLong(int c)
Definition: sv_game.cpp:201
float NET_ReadAngle(dbuffer *buf)
Definition: netpack.cpp:383
QGL_EXTERN GLint i
Definition: r_gl.h:113
float SV_GetBounceFraction(const char *texture)
Different terrain types might have different bounce fraction.
Definition: sv_world.cpp:462
int apiversion
Definition: game.h:318
QGL_EXTERN GLuint GLsizei GLsizei GLint GLenum GLchar * name
Definition: r_gl.h:110
void NET_WriteByte(dbuffer *buf, byte c)
Definition: netpack.cpp:39
sv_edict_t edicts[MAX_EDICTS]
Definition: server.h:130
static void SV_ReadDir(vec3_t vector)
Definition: sv_game.cpp:274
static void SV_RecalcRouting(const char *name, const GridBox &box, const char **list)
Definition: sv_game.cpp:583
static void SV_QueueWriteString(const char *s)
Definition: sv_game.cpp:499
bool TR_TestLine(mapTiles_t *mapTiles, const vec3_t start, const vec3_t end, const int levelmask)
Checks traces against the world.
Definition: tracing.cpp:310
cBspModel_t * CM_SetInlineModelOrientation(mapTiles_t *mapTiles, const char *name, const vec3_t origin, const vec3_t angles)
This function updates a model's orientation.
Definition: bsp.cpp:963
static bool SV_CanActorStandHere(const int actorSize, const pos3_t pos)
Definition: sv_game.cpp:608
static void SV_QueueWriteByte(byte c)
Definition: sv_game.cpp:494
static void SV_ReadData(void *buffer, int size)
Definition: sv_game.cpp:284
vec_t vec3_t[3]
Definition: ufotypes.h:39
const char * SV_GetFootstepSound(const char *texture)
Query the footstep sound for the given surface texture.
Definition: sv_world.cpp:451
static void SV_ReadPos(vec3_t pos)
Definition: sv_game.cpp:264
void void SV_ClientPrintf(client_t *cl, int level, const char *fmt,...) __attribute__((format(__printf__
FILE * Sys_Fopen(const char *filename, const char *mode)
Definition: unix_files.cpp:240
static int SV_ReadByte(void)
Definition: sv_game.cpp:244
static float SV_GetVisibility(const pos3_t position)
Glue function to get the visibility from a given position.
Definition: sv_game.cpp:69
trace_t SV_Trace(const Line &traceLine, const AABB &box, const edict_t *passedict, int contentmask)
Moves the given mins/maxs volume through the world from start to end.
Definition: sv_world.cpp:417
game_export_t * GetGameAPI(game_import_t *import)
Returns a pointer to the structure with all entry points and global variables.
Definition: g_main.cpp:384
static void SV_GridCalcPathing(actorSizeEnum_t actorSize, pathing_t *path, const pos3_t from, int distance, forbiddenList_t *forbiddenList)
Definition: sv_game.cpp:598
dbuffer * messageBuffer
Definition: server.h:119
AABB mapBox
Definition: typedefs.h:351
static void SV_AddEvent(unsigned int mask, int eType, int entnum)
Definition: sv_game.cpp:427
void SV_LogAdd(const char *format, va_list ap)
Async version to add a log entry for the game lib.
Definition: sv_log.cpp:60
#define lengthof(x)
Definition: shared.h:105
GLsizei const GLvoid * data
Definition: r_gl.h:152
static game_export_t * SV_GetGameAPI(game_import_t *parms)
Loads the game shared library and calls the api init function.
Definition: sv_game.cpp:659
cvar_t * Cvar_Set(const char *varName, const char *value,...)
Sets a cvar value.
Definition: cvar.cpp:615
const char * Cvar_GetString(const char *varName)
Returns the value of cvar as string.
Definition: cvar.cpp:210
#define Q_streq(a, b)
Definition: shared.h:136
static pos_t SV_GridFall(const int actorSize, const pos3_t pos)
Definition: sv_game.cpp:578
static bool SV_LoadGame(const char *path)
Definition: sv_game.cpp:634
A list of locations that cannot be moved to.
Definition: grid.h:35
void NET_WriteGPos(dbuffer *buf, const pos3_t pos)
Definition: netpack.cpp:103
static int SV_GetEvent(void)
Definition: sv_game.cpp:517
void NET_WriteDir(dbuffer *buf, const vec3_t dir)
Definition: netpack.cpp:124
void _Mem_FreeTag(memPool_t *pool, const int tagNum, const char *fileName, const int fileLine)
Free memory blocks assigned to a specified tag within a pool.
Definition: mem.cpp:241
static int SV_ReadShort(void)
Definition: sv_game.cpp:249
void Grid_PosToVec(const Routing &routing, const actorSizeEnum_t actorSize, const pos3_t pos, vec3_t vec)
Converts a grid position to world coordinates.
Definition: grid.cpp:832
int modelindex
Definition: srvedict.h:54
static void SV_SetInlineModelOrientation(const char *name, const vec3_t origin, const vec3_t angles)
Definition: sv_game.cpp:613
static void * SV_TagAlloc(int size, int tagNum, const char *file, int line)
Makes sure the game DLL does not use client, or signed tags.
Definition: sv_game.cpp:542
Routing routing
Definition: typedefs.h:341
uint8_t byte
Definition: ufotypes.h:34
bool RT_CanActorStandHere(const Routing &routing, const int actorSize, const pos3_t pos)
Check if an actor can stand(up) in the cell given by pos.
Definition: routing.cpp:237
static void SV_WriteShort(int c)
Definition: sv_game.cpp:196
int Com_ServerState(void)
Check whether we are the server or have a singleplayer tactical mission.
Definition: common.cpp:538
serverInstanceStatic_t svs
Definition: sv_init.cpp:35
static void SV_MemFree(void *ptr, const char *file, int line)
Definition: sv_game.cpp:550
SDL_Thread * gameThread
Definition: server.h:88
static void SV_SendQueuedEvents(void)
Definition: sv_game.cpp:320
static void SV_QueueEvent(unsigned int mask, int eType, int entnum)
Definition: sv_game.cpp:465
void NET_WriteShort(dbuffer *buf, int c)
Definition: netpack.cpp:45
int NET_ReadByte(dbuffer *buf)
Reads a byte from the netchannel.
Definition: netpack.cpp:234
memPool_t * gameSysPool
Definition: server.h:134
const char * Cmd_Args(void)
Returns a single string containing argv(1) to argv(argc()-1)
Definition: cmd.cpp:526
bool Com_GetConstInt(const char *name, int *value)
Searches whether a given value was registered as a string to int mapping.
Definition: scripts.cpp:74
void format(__printf__, 1, 2)))
byte pos_t
Definition: ufotypes.h:57
level_locals_t level
Definition: g_main.cpp:38
static void SV_WriteDir(const vec3_t dir)
Definition: sv_game.cpp:221
SDL_cond * gameFrameCond
Definition: server.h:87
void FS_FreeFile(void *buffer)
Definition: files.cpp:411
static edict_t * SV_GetEventEdict(void)
Definition: sv_game.cpp:526
int Sys_Milliseconds(void)
Definition: unix_shared.cpp:41
#define Mem_PoolSize(pool)
Definition: mem.h:51
const char * FS_NextPath(const char *prevpath)
Allows enumerating all of the directories in the search path.
Definition: files.cpp:614
game_export_t * ge
Definition: server.h:92
int playerMask
Definition: server.h:70