00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <Windows.h>
00016 #include <Assert.h>
00017 #include <Time.h>
00018
00019 #include "Server.h"
00020
00021 LARGE_INTEGER g_Freq, g_OldTick, g_CurTick;
00022
00023 #define NUM_AVG 10
00024 static float AvgTime[NUM_AVG];
00025 static int32 CurAvg;
00026
00027 static void SubLarge(LARGE_INTEGER *start, LARGE_INTEGER *end, LARGE_INTEGER *delta)
00028 {
00029 _asm {
00030 mov ebx,dword ptr [start]
00031 mov esi,dword ptr [end]
00032
00033 mov eax,dword ptr [esi+0]
00034 sub eax,dword ptr [ebx+0]
00035
00036 mov edx,dword ptr [esi+4]
00037 sbb edx,dword ptr [ebx+4]
00038
00039 mov ebx,dword ptr [delta]
00040 mov dword ptr [ebx+0],eax
00041 mov dword ptr [ebx+4],edx
00042 }
00043 }
00044
00045 #define BEGIN_TIMER() QueryPerformanceCounter(&g_OldTick)
00046
00047 #define END_TIMER(g) \
00048 { \
00049 LARGE_INTEGER DeltaTick; \
00050 float ElapsedTime, Total; \
00051 int32 i; \
00052 \
00053 QueryPerformanceCounter(&g_CurTick); \
00054 SubLarge(&g_OldTick, &g_CurTick, &DeltaTick); \
00055 \
00056 if (DeltaTick.LowPart > 0) \
00057 ElapsedTime = 1.0f / (((float)g_Freq.LowPart / (float)DeltaTick.LowPart)); \
00058 else \
00059 ElapsedTime = 0.001f; \
00060 \
00061 AvgTime[CurAvg] = ElapsedTime; \
00062 CurAvg++; \
00063 CurAvg %= NUM_AVG; \
00064 \
00065 for (Total = 0.0f, i=0; i< NUM_AVG; i++) \
00066 Total += AvgTime[i]; \
00067 \
00068 Total *= (1.0f/ NUM_AVG); \
00069 \
00070 geEngine_Printf(GameMgr_GetEngine(g), 1, 70, "Timer ms: %2.3f/%2.3f", ElapsedTime, Total); \
00071 }
00072 extern geBoolean ShowStats;
00073 static ServerBotCount = 0;
00074
00075 void GenVS_Error(const char *Msg, ...);
00076 static geBoolean Server_ManageBots(Server_Server *Server);
00077
00078 #ifdef _DEBUG
00079 uint32 SERVER_GPLAYER_TO_INDEX(Server_Server *Server, GPlayer *Player)
00080 {
00081 uint32 Index;
00082
00083 assert(Server);
00084 assert(Player);
00085
00086 assert(Player >= Server->SvPlayers);
00087
00088 Index = (Player - Server->SvPlayers);
00089
00090 assert(Index < NETMGR_MAX_PLAYERS);
00091
00092 return Index;
00093 }
00094 #else
00095 #define SERVER_GPLAYER_TO_INDEX(s, p) ((p) - (s)->SvPlayers)
00096 #endif
00097
00098
00099
00100
00101 static geBoolean SendAllClientsMessage(Server_Server *Server, Buffer_Data *Buffer, geBoolean G);
00102
00103 static geBoolean ReadClientMessages(Server_Server *Server, float Time);
00104 static void FillBufferWithPlayerData(Server_Server *Server, Buffer_Data *Buffer, GPlayer *Player, uint16 SendFlags);
00105 static geBoolean SendPlayersToClients(Server_Server *Server);
00106 static void ControlPlayer(Server_Server *Server, GPlayer *Player, float Time);
00107 static geBoolean ControlPlayers(Server_Server *Server, float Time);
00108 static geBoolean Server_IsClientBot(Server_Server *Server, GenVSI_CHandle ClientHandle);
00109
00110 static void ForceServerPlayerOnLocalClient(Server_Server *Server, GPlayer *Player);
00111
00112 static void Server_SetupGenVSI(Server_Server *Server);
00113 static geBoolean Server_ManageBots(Server_Server *Server);
00114
00115
00116
00117
00118 static void Server_SetPlayerDefaults(GPlayer *Player)
00119 {
00120 memset(Player, 0, sizeof(GPlayer));
00121
00122 Player->OldViewFlags = Player->ViewFlags = VIEW_TYPE_NONE;
00123 Player->OldViewIndex = Player->ViewIndex = VIEW_INDEX_NONE;
00124 Player->OldControlIndex = Player->ControlIndex = CONTROL_INDEX_NONE;
00125 Player->OldTriggerIndex = Player->TriggerIndex = TRIGGER_INDEX_NONE;
00126 Player->OldScale = Player->Scale = 1.0f;
00127 Player->OldMotionIndex = Player->MotionIndex = MOTION_INDEX_NONE;
00128
00129 Player->PingTime = -1.0f;
00130
00131 }
00132
00133
00134
00135
00136 Server_Server *Server_Create(GameMgr *GMgr, NetMgr *NMgr, Client_Client *Client, const char *LevelHack)
00137 {
00138 int32 i;
00139 Server_Server *NewServer;
00140
00141 NewServer = GE_RAM_ALLOCATE_STRUCT(Server_Server);
00142
00143 assert(NewServer != NULL);
00144
00145 if (!NewServer)
00146 return NULL;
00147
00148 memset(NewServer, 0, sizeof(Server_Server));
00149
00150
00151 NewServer->GMgr = GMgr;
00152 NewServer->NMgr = NMgr;
00153 NewServer->Client = Client;
00154
00155 Server_SetupGenVSI(NewServer);
00156
00157 if (!Server_NewWorldDefaults(NewServer))
00158 {
00159 geRam_Free(NewServer);
00160 return NULL;
00161 }
00162
00163 for (i=0; i< NETMGR_MAX_PLAYERS; i++)
00164 Server_SetPlayerDefaults(&NewServer->SvPlayers[i]);
00165
00166
00167 NewServer->NumClassSpawns = 0;
00168 ServerBotCount = 0;
00169
00170
00171 Server_Main(&NewServer->GenVSI, LevelHack);
00172 Console_Printf(GameMgr_GetConsole(NewServer->GMgr), "Server_Create: Game_Main initialized\n");
00173 Console_Printf(GameMgr_GetConsole(NewServer->GMgr), "Server_Create: Num Main Spawned Players: %i\n", NewServer->NumTotalPlayers);
00174
00175 Console_Printf(GameMgr_GetConsole(NewServer->GMgr), "Server_Create: Server created...\n");
00176
00177 return NewServer;
00178 }
00179
00180
00181
00182
00183 void Server_Destroy(Server_Server *Server)
00184 {
00185 Buffer_Data Buffer;
00186 char Data[128];
00187 geBoolean Ret;
00188
00189 assert(Server);
00190
00191 Ret = Server_FreeWorldData(Server);
00192
00193 assert(Ret == GE_TRUE);
00194
00195
00196 Buffer_Set(&Buffer, Data, 128);
00197 Buffer_FillByte(&Buffer, NETMGR_MSG_SHUTDOWN);
00198
00199 SendAllClientsMessage(Server, &Buffer, GE_TRUE);
00200
00201 geRam_Free(Server);
00202 }
00203
00204
00205
00206
00207 static geBoolean FillBufferWithClientInfo(Server_Server *Server, Buffer_Data *Buffer)
00208 {
00209 int32 i;
00210 Server_Client *Client;
00211
00212 Client = Server->Clients;
00213
00214 for (i=0; i< NETMGR_MAX_CLIENTS; i++, Client++)
00215 {
00216 if (!Client->Active)
00217 continue;
00218
00219 Buffer_FillByte(Buffer, NETMGR_MSG_CLIENT_ACTIVE);
00220 Buffer_FillByte(Buffer, (char)i);
00221 Buffer_FillByte(Buffer, 1);
00222
00223 Buffer_FillByte(Buffer, NETMGR_MSG_CLIENT_NAME);
00224 Buffer_FillByte(Buffer, (char)i);
00225 Buffer_FillString(Buffer, Client->Name);
00226
00227 Buffer_FillByte(Buffer, NETMGR_MSG_CLIENT_SCORE);
00228 Buffer_FillByte(Buffer, (char)i);
00229 Buffer_FillSLong(Buffer, Client->Score);
00230
00231 Buffer_FillByte(Buffer, NETMGR_MSG_CLIENT_HEALTH);
00232 Buffer_FillByte(Buffer, (char)i);
00233 Buffer_FillSLong(Buffer, Client->Health);
00234 }
00235
00236 return GE_TRUE;
00237 }
00238
00239
00240
00241
00242
00243 static geBoolean SendClientPlayerData(Server_Server *Server, Server_Client *Client)
00244 {
00245 int32 i;
00246 Buffer_Data Buffer;
00247 char Data[20000];
00248 GPlayer *Player;
00249
00250 Buffer_Set(&Buffer, Data, 20000);
00251
00252 Buffer_FillByte(&Buffer, NETMGR_MSG_TIME);
00253 Buffer_FillFloat(&Buffer, GameMgr_GetTime(Server->GMgr));
00254 Buffer_FillFloat(&Buffer, Client->Ping);
00255
00256 Player = Server->SvPlayers;
00257
00258 for (i=0; i< NETMGR_MAX_PLAYERS; i++, Player++)
00259 {
00260 if (!Player->Active)
00261 continue;
00262
00263 Buffer_FillByte(&Buffer, NETMGR_MSG_NEW_WORLD_PLAYER_DATA);
00264
00265 FillBufferWithPlayerData(Server, &Buffer, Player, 0xffff);
00266 }
00267
00268 if (!NetMgr_SendClientMessage(Server->NMgr, Client->NetID, &Buffer, GE_TRUE))
00269 GenVS_Error("SendClientPlayerData: NetMgr_SendClientMessage failed.\n");
00270
00271 return GE_TRUE;
00272 }
00273
00274
00275
00276
00277 geBoolean Server_ChangeClientState(Server_Server *Server, Server_Client *Client, NetMgr_NetState NetState)
00278 {
00279 Buffer_Data Buffer;
00280 char Data[128];
00281
00282 assert(Server);
00283 assert(Client);
00284
00285 Buffer_Set(&Buffer, Data, 128);
00286
00287 Buffer_FillByte(&Buffer, NETMGR_MSG_NET_STATE_CHANGE);
00288 Buffer_FillSLong(&Buffer, NetState);
00289
00290 if (!NetMgr_SendClientMessage(Server->NMgr, Client->NetID, &Buffer, GE_TRUE))
00291 GenVS_Error("Server_ChangeClientState: NetMgr_SendClientMessage failed.\n");
00292
00293 Client->NetState = NetState;
00294 Client->NetStateConfirmed[NetState] = GE_FALSE;
00295
00296 return GE_TRUE;
00297 }
00298
00299
00300
00301
00302
00303 geBoolean Server_SetupClientWithCurrentWorld(Server_Server *Server, Server_Client *Client)
00304 {
00305 geWorld *World;
00306
00307 World = GameMgr_GetWorld(Server->GMgr);
00308
00309 assert(World != NULL);
00310
00311
00312 if (!Server_ChangeClientState(Server, Client, NetState_WorldChange))
00313 GenVS_Error("Server_SetupClientWithCurrentWorld: Server_ChangeClientState failed.\n");
00314
00315 if (!Server_SendClientCurrentWorldData(Server, Client))
00316 GenVS_Error("Server_SetupClientWithCurrentWorld: Server_SendClientCurrentWorldData failed.\n");
00317
00318 if (!SendClientPlayerData(Server, Client))
00319 GenVS_Error("Server_SetupClientWithCurrentWorld: SendClientPlayerData failed.\n");
00320
00321 if (!Server_ChangeClientState(Server, Client, NetState_WorldActive))
00322 GenVS_Error("Server_SetupClientWithCurrentWorld: Server_ChangeClientState failed.\n");
00323
00324 return GE_TRUE;
00325 }
00326
00327
00328
00329
00330
00331
00332 geBoolean Server_SetupAllClientsWithCurrentWorld(Server_Server *Server)
00333 {
00334 int32 i;
00335
00336
00337 for (i=0; i< NETMGR_MAX_CLIENTS; i++)
00338 {
00339 Server_Client *Client;
00340
00341 Client = &Server->Clients[i];
00342
00343 if (!Client->Active)
00344 continue;
00345
00346 if (!Server_SetupClientWithCurrentWorld(Server, Client))
00347 {
00348 Server_ClientDisconnect(Server, Client->NetID, Client->Name);
00349 }
00350 }
00351
00352 return GE_TRUE;
00353 }
00354
00355
00356
00357
00358 geBoolean Server_SendClientStartupData(Server_Server *Server, Server_Client *Client)
00359 {
00360
00361 uint8 Data[20000];
00362 Buffer_Data Buffer;
00363 int32 ClientIndex;
00364 geWorld *World;
00365
00366 assert(Client->Player);
00367
00368 ClientIndex = Client - Server->Clients;
00369 assert(ClientIndex >=0 && ClientIndex < NETMGR_MAX_CLIENTS);
00370
00371
00372 Buffer_Set(&Buffer, Data, 20000);
00373
00374 Buffer_FillByte(&Buffer, NETMGR_MSG_CLIENT_INDEX);
00375 Buffer_FillByte(&Buffer, (uint8)ClientIndex);
00376
00377 if (!NetMgr_SendClientMessage(Server->NMgr, Client->NetID, &Buffer, GE_TRUE))
00378 GenVS_Error("Server_SendClientStartupData: NetMgr_SendClientMessage failed.\n");
00379
00380 Buffer_Set(&Buffer, Data, 20000);
00381
00382 if (!FillBufferWithClientInfo(Server, &Buffer))
00383 GenVS_Error("Server_SendClientStartupData: FillBufferWithClientInfo failed.\n");
00384
00385
00386 if (!SendAllClientsMessage(Server, &Buffer, GE_TRUE))
00387 GenVS_Error("Server_SendClientStartupData: SendAllClientsMessage failed.\n");
00388
00389 World = GameMgr_GetWorld(Server->GMgr);
00390
00391 if (World)
00392 {
00393 if (!Server_SetupClientWithCurrentWorld(Server, Client))
00394 GenVS_Error("Server_SendClientStartupData: Server_SetupClientWithCurrentWorld failed.\n");
00395 }
00396
00397 return GE_TRUE;
00398 }
00399
00400
00401
00402 static geBoolean SendAllClientsMessage(Server_Server *Server, Buffer_Data *Buffer, geBoolean G)
00403 {
00404 int32 i;
00405
00406
00407 for (i=0; i< NETMGR_MAX_CLIENTS; i++)
00408 {
00409 Server_Client *Client;
00410
00411 Client = &Server->Clients[i];
00412
00413 if (!Client->Active)
00414 continue;
00415
00416 if (Server_IsClientBot(Server,i))
00417 continue;
00418
00419 if (!NetMgr_SendClientMessage(Server->NMgr, Client->NetID, Buffer, G))
00420 {
00421 Server_ClientDisconnect(Server, Client->NetID, Client->Name);
00422
00423 }
00424 }
00425
00426 return GE_TRUE;
00427 }
00428
00429
00430
00431
00432
00433
00434 geBoolean Server_SendClientCurrentWorldData(Server_Server *Server, Server_Client *Client)
00435 {
00436 int32 i;
00437 Buffer_Data Buffer;
00438 char Data[20000];
00439
00440 assert(GameMgr_GetWorld(Server->GMgr));
00441 assert(Client->Active == GE_TRUE);
00442
00443
00444 Buffer_Set(&Buffer, Data, 20000);
00445 Buffer_FillByte(&Buffer, NETMGR_MSG_SET_WORLD);
00446 Buffer_FillString(&Buffer, Server->WorldName);
00447
00448 if (!NetMgr_SendClientMessage(Server->NMgr, Client->NetID, &Buffer, GE_TRUE))
00449 GenVS_Error("Server_SendClientCurrentWorldData: NetMgr_SendClientMessage failed 1.\n");
00450
00451
00452 Buffer_Set(&Buffer, Data, 20000);
00453 for (i=0; i< GAMEMGR_MAX_ACTOR_INDEX; i++)
00454 {
00455 GameMgr_ActorIndex *ActorIndex;
00456
00457 ActorIndex = GameMgr_GetActorIndex(Server->GMgr, i);
00458
00459 if (!ActorIndex->Active)
00460 continue;
00461
00462 Buffer_FillByte(&Buffer, NETMGR_MSG_ACTOR_INDEX);
00463 Buffer_FillSLong(&Buffer, i);
00464 Buffer_FillString(&Buffer, ActorIndex->FileName);
00465 }
00466
00467 if (!NetMgr_SendClientMessage(Server->NMgr, Client->NetID, &Buffer, GE_TRUE))
00468 GenVS_Error("Server_SendClientCurrentWorldData: NetMgr_SendClientMessage failed 2.\n");
00469
00470
00471 Buffer_Set(&Buffer, Data, 20000);
00472 for (i=0; i< GAMEMGR_MAX_MOTION_INDEX; i++)
00473 {
00474 GameMgr_MotionIndexDef *MotionIndex;
00475
00476 MotionIndex = GameMgr_GetMotionIndexDef(Server->GMgr, i);
00477
00478
00479 if (!MotionIndex->Active)
00480 continue;
00481
00482 Buffer_FillByte(&Buffer, NETMGR_MSG_MOTION_INDEX);
00483 Buffer_FillSLong(&Buffer, i);
00484 Buffer_FillString(&Buffer, MotionIndex->MotionName);
00485 }
00486
00487 if (!NetMgr_SendClientMessage(Server->NMgr, Client->NetID, &Buffer, GE_TRUE))
00488 GenVS_Error("Server_SendClientCurrentWorldData: NetMgr_SendClientMessage failed 3.\n");
00489
00490
00491 Buffer_Set(&Buffer, Data, 20000);
00492 for (i=0; i< GAMEMGR_MAX_BONE_INDEX; i++)
00493 {
00494 GameMgr_BoneIndex *BoneIndex;
00495
00496 BoneIndex = GameMgr_GetBoneIndex(Server->GMgr, i);
00497
00498
00499 if (!BoneIndex->Active)
00500 continue;
00501
00502 Buffer_FillByte(&Buffer, NETMGR_MSG_BONE_INDEX);
00503 Buffer_FillSLong(&Buffer, i);
00504 Buffer_FillString(&Buffer, BoneIndex->BoneName);
00505 }
00506
00507 if (!NetMgr_SendClientMessage(Server->NMgr, Client->NetID, &Buffer, GE_TRUE))
00508 GenVS_Error("Server_SendClientCurrentWorldData: NetMgr_SendClientMessage failed 4.\n");
00509
00510
00511 Buffer_Set(&Buffer, Data, 20000);
00512 for (i=0; i< GAMEMGR_MAX_TEXTURE_INDEX; i++)
00513 {
00514 GameMgr_TextureIndex *TextureIndex;
00515
00516 TextureIndex = GameMgr_GetTextureIndex(Server->GMgr, i);
00517
00518
00519 if (!TextureIndex->Active)
00520 continue;
00521
00522 Buffer_FillByte(&Buffer, NETMGR_MSG_TEXTURE_INDEX);
00523 Buffer_FillSLong(&Buffer, i);
00524 Buffer_FillString(&Buffer, TextureIndex->FileName);
00525 Buffer_FillString(&Buffer, TextureIndex->AFileName);
00526 }
00527
00528 if (!NetMgr_SendClientMessage(Server->NMgr, Client->NetID, &Buffer, GE_TRUE))
00529 GenVS_Error("Server_SendClientCurrentWorldData: NetMgr_SendClientMessage failed 5.\n");
00530
00531
00532 Buffer_Set(&Buffer, Data, 20000);
00533 for (i=0; i< GAMEMGR_MAX_SOUND_INDEX; i++)
00534 {
00535 GameMgr_SoundIndex *SoundIndex;
00536
00537 SoundIndex = GameMgr_GetSoundIndex(Server->GMgr, i);
00538
00539
00540 if (!SoundIndex->Active)
00541 continue;
00542
00543 Buffer_FillByte(&Buffer, NETMGR_MSG_SOUND_INDEX);
00544 Buffer_FillSLong(&Buffer, i);
00545 Buffer_FillString(&Buffer, SoundIndex->FileName);
00546 }
00547
00548 if (!NetMgr_SendClientMessage(Server->NMgr, Client->NetID, &Buffer, GE_TRUE))
00549 GenVS_Error("Server_SendClientCurrentWorldData: NetMgr_SendClientMessage failed 6.\n");
00550
00551
00552 {
00553 int32 PlayerIndex;
00554
00555 assert(Client->Player);
00556
00557 PlayerIndex = (int32)SERVER_GPLAYER_TO_INDEX(Server, Client->Player);
00558
00559 Buffer_Set(&Buffer, Data, 10000);
00560 Buffer_FillByte(&Buffer, NETMGR_MSG_CLIENT_PLAYER_INDEX);
00561 Buffer_FillSLong(&Buffer, PlayerIndex);
00562
00563 if (!NetMgr_SendClientMessage(Server->NMgr, Client->NetID, &Buffer, GE_TRUE))
00564 GenVS_Error("Server_SendClientCurrentWorldData: NetMgr_SendClientMessage failed 7.\n");
00565 }
00566
00567 return GE_TRUE;
00568 }
00569
00570
00571
00572
00573 void Server_ValidateClient(Server_Server *Server, Server_Client *Client)
00574 {
00575 GPlayer *Player;
00576 geWorld *World;
00577
00578 assert(Server);
00579 assert(Client);
00580 assert(Client->Active);
00581
00582 assert(Client->Player == NULL);
00583
00584
00585
00586
00587
00588 Player = Server_CreatePlayer(Server, Client->Name);
00589
00590 if (!Player)
00591 GenVS_Error("Server_ClientConnect: No more players available for client.");
00592
00593
00594 Client->Player = Player;
00595 Player->ClientHandle = (GenVSI_CHandle)(Client - Server->Clients);
00596
00597 World = GameMgr_GetWorld(Server->GMgr);
00598
00599
00600 if (!Client->Spawned && World)
00601 {
00602 int32 PlayerIndex;
00603 Buffer_Data Buffer;
00604 char Data[1024];
00605
00606 if (Server_IsClientBot(Server,Player->ClientHandle))
00607 {
00608 if (!Game_SpawnBot(&Server->GenVSI, World, Player, Player->ClassData))
00609 GenVS_Error("Server_ValidateClient: Game_SpawnBot failed...");
00610 }
00611 else
00612 {
00613 if (!Game_SpawnClient(&Server->GenVSI, World, Player, Player->ClassData))
00614 GenVS_Error("Server_ValidateClient: Game_SpawnClient failed...");
00615 }
00616
00617 if (!Client->Active)
00618 return;
00619
00620 Client->Spawned = GE_TRUE;
00621
00622
00623 if (!Player->DFunc)
00624 Player->DFunc = Game_DestroyClient;
00625
00626 PlayerIndex = (int32)SERVER_GPLAYER_TO_INDEX(Server, Client->Player);
00627
00628 Buffer_Set(&Buffer, Data, 1024);
00629
00630 Buffer_FillByte(&Buffer, NETMGR_MSG_CLIENT_PLAYER_INDEX);
00631 Buffer_FillSLong(&Buffer, PlayerIndex);
00632
00633 if (!NetMgr_SendClientMessage(Server->NMgr, Client->NetID, &Buffer, GE_TRUE))
00634 {
00635 Server_ClientDisconnect(Server, Client->NetID, Client->Name);
00636 }
00637
00638 ForceServerPlayerOnLocalClient(Server, Client->Player);
00639 }
00640 }
00641
00642
00643
00644
00645 geBoolean Server_ClientConnect(Server_Server *Server, const geCSNetMgr_NetClient *Client)
00646 {
00647 int32 i;
00648 Buffer_Data Buffer;
00649 char Data[128];
00650 Server_Client *SClient;
00651
00652 SClient = Server->Clients;
00653
00654 for (i=0; i< NETMGR_MAX_CLIENTS; i++, SClient++)
00655 {
00656 if (!SClient->Active)
00657 break;
00658 }
00659
00660 if (i >= NETMGR_MAX_CLIENTS)
00661 return FALSE;
00662
00663 memset(SClient, 0, sizeof(Server_Client));
00664
00665 strcpy(SClient->Name, Client->Name);
00666 SClient->NetID = Client->Id;
00667
00668 SClient->Active = GE_TRUE;
00669
00670
00671 Buffer_Set(&Buffer, Data, 128);
00672 Buffer_FillByte(&Buffer, NETMGR_MSG_VERSION);
00673 Buffer_FillLong(&Buffer, NETMGR_VERSION_MAJOR);
00674 Buffer_FillLong(&Buffer, NETMGR_VERSION_MINOR);
00675
00676 if (!NetMgr_SendClientMessage(Server->NMgr, SClient->NetID, &Buffer, GE_TRUE))
00677 {
00678 Server_ClientDisconnect(Server, SClient->NetID, SClient->Name);
00679 return GE_TRUE;
00680 }
00681
00682
00683 Server_ChangeClientState(Server, SClient, NetState_Connecting);
00684
00685
00686 Server_ValidateClient(Server, SClient);
00687
00688 if (!SClient->Active)
00689 return GE_TRUE;
00690
00691
00692 if (!Server_SendClientStartupData(Server, SClient))
00693 {
00694 Server_ClientDisconnect(Server, SClient->NetID, SClient->Name);
00695
00696 GenVS_Error("Server_ClientConnect: Server_SendClientStartupData failed.\n");
00697 return GE_FALSE;
00698 }
00699
00700 Console_Printf(GameMgr_GetConsole(Server->GMgr), " Client connected: %s, %i...\n", Client->Name, Client->Id);
00701
00702 return GE_TRUE;
00703 }
00704
00705
00706
00707
00708
00709 Server_Client *Server_BotConnect(Server_Server *Server, const char *BotName)
00710 {
00711 int32 i;
00712 Server_Client *SClient;
00713
00714 SClient = Server->Clients;
00715
00716 for (i=0; i< NETMGR_MAX_CLIENTS; i++, SClient++)
00717 {
00718 if (!SClient->Active)
00719 break;
00720 }
00721
00722 if (i >= NETMGR_MAX_CLIENTS)
00723 return NULL;
00724
00725 memset(SClient, 0, sizeof(Server_Client));
00726
00727 strcpy(SClient->Name, BotName);
00728 SClient->NetID = NETMGR_SPECIAL_BOT_NETID;
00729
00730 SClient->Active = GE_TRUE;
00731
00732
00733 Server_ValidateClient(Server, SClient);
00734
00735 if (!SClient->Active)
00736 return SClient;
00737
00738
00739 if (!Server_SendClientStartupData(Server, SClient))
00740 {
00741 Server_ClientDisconnect(Server, SClient->NetID, SClient->Name);
00742 return NULL;
00743 }
00744
00745 Console_Printf(GameMgr_GetConsole(Server->GMgr), "(Server) Client connected: %s, %i...\n", "Bot", NETMGR_SPECIAL_BOT_NETID);
00746
00747 return SClient;
00748 }
00749
00750
00751
00752
00753
00754 geBoolean Server_ClientDisconnect(Server_Server *Server, geCSNetMgr_NetID Id, const char *Name)
00755 {
00756 int32 i;
00757 Server_Client *SClient;
00758
00759 assert(Server);
00760 assert(Name);
00761
00762 for (i=0; i< NETMGR_MAX_CLIENTS; i++)
00763 {
00764 SClient = &Server->Clients[i];
00765
00766 if (!SClient->Active)
00767 continue;
00768
00769 if (SClient->NetID == Id)
00770 {
00771 Buffer_Data Buffer;
00772 char Data[512];
00773
00774 if (SClient->Player)
00775 Server_DestroyPlayer(Server, SClient->Player);
00776
00777 SClient->Player = NULL;
00778 SClient->Active = GE_FALSE;
00779
00780
00781 Buffer_Set(&Buffer, Data, 512);
00782
00783 Buffer_FillByte(&Buffer, NETMGR_MSG_CLIENT_ACTIVE);
00784 Buffer_FillByte(&Buffer, (char)i);
00785 Buffer_FillByte(&Buffer, 0);
00786
00787 SendAllClientsMessage(Server, &Buffer, GE_TRUE);
00788
00789 Console_Printf(GameMgr_GetConsole(Server->GMgr), "[SERVER] Client disconnected: %s, %i...\n", Name, Id);
00790 return GE_TRUE;
00791 }
00792 }
00793
00794 Console_Printf(GameMgr_GetConsole(Server->GMgr), "[SERVER] Client not found for disconnect: %s, %i...\n", Name, Id);
00795
00796 return GE_FALSE;
00797 }
00798
00799
00800
00801
00802 geBoolean Server_ClientDisconnectByHandle(Server_Server *Server, GenVSI_CHandle ClientHandle)
00803 {
00804 Server_Client *SClient;
00805 Buffer_Data Buffer;
00806 char Data[512];
00807
00808 assert(Server);
00809
00810 SClient = &Server->Clients[ClientHandle];
00811
00812 assert(SClient);
00813
00814 if (SClient->Player)
00815 Server_DestroyPlayer(Server, SClient->Player);
00816
00817 SClient->Player = NULL;
00818 SClient->Active = GE_FALSE;
00819
00820
00821 Buffer_Set(&Buffer, Data, 512);
00822
00823 Buffer_FillByte(&Buffer, NETMGR_MSG_CLIENT_ACTIVE);
00824 Buffer_FillByte(&Buffer, (char)ClientHandle);
00825 Buffer_FillByte(&Buffer, 0);
00826
00827 SendAllClientsMessage(Server, &Buffer, GE_TRUE);
00828
00829 return GE_TRUE;
00830 }
00831
00832
00833
00834
00835
00836 GPlayer *Server_CreatePlayer(Server_Server *Server, const char *ClassName)
00837 {
00838 int32 i, Start, End;
00839
00840 assert(strlen(ClassName) < MAX_CLASS_NAME_STRING);
00841
00842 Start = 0;
00843 End = NETMGR_MAX_PLAYERS;
00844
00845 for (i=Start; i< End; i++)
00846 {
00847 if (!Server->SvPlayers[i].Active)
00848 break;
00849 }
00850
00851 if (i >= End)
00852 {
00853 GenVS_Error("Failed to add player!!!\n");
00854
00855 Console_Printf(GameMgr_GetConsole(Server->GMgr), "Server_CreatePlayer2: Max players exceeded...\n");
00856 return NULL;
00857 }
00858
00859 assert(Server->NumTotalPlayers >= 0);
00860
00861 Server->NumTotalPlayers++;
00862
00863 assert(Server->NumTotalPlayers <= End);
00864
00865 memset(&Server->SvPlayers[i], 0, sizeof(GPlayer));
00866
00867 Server->SvPlayers[i].Active = GE_TRUE;
00868
00869 Server->SvPlayers[i].OldViewFlags = VIEW_TYPE_NONE | VIEW_TYPE_LOCAL;
00870 Server->SvPlayers[i].ViewFlags = VIEW_TYPE_NONE | VIEW_TYPE_LOCAL;
00871 Server->SvPlayers[i].OldViewIndex = 0xffff;
00872 Server->SvPlayers[i].ViewIndex = 0xffff;
00873 Server->SvPlayers[i].ControlIndex = 0xffff;
00874 Server->SvPlayers[i].TriggerIndex = 0xffff;
00875 strcpy(Server->SvPlayers[i].ClassName, ClassName);
00876 Server->SvPlayers[i].ClientHandle = CLIENT_NULL_HANDLE;
00877
00878 return &Server->SvPlayers[i];
00879 }
00880
00881
00882
00883
00884 void Callback_CallDestroy(Server_Server *Server, GPlayer *Player)
00885 {
00886 if (Player->DFunc)
00887 Player->DFunc(&Server->GenVSI, Player, Player->ClassData);
00888
00889 Player->DFunc = NULL;
00890 }
00891
00892
00893
00894
00895 void Server_DestroyPlayer(Server_Server *Server, GPlayer *Player)
00896 {
00897 assert(Server);
00898 assert(Player);
00899
00900 assert(Player->Active);
00901
00902 assert(Server->NumTotalPlayers <= NETMGR_MAX_PLAYERS);
00903
00904 Callback_CallDestroy(Server, Player);
00905
00906 Server->NumTotalPlayers--;
00907
00908 assert(Server->NumTotalPlayers >= 0);
00909
00910 memset(Player, 0, sizeof(GPlayer));
00911 }
00912
00913
00914
00915
00916
00917 geBoolean Server_FreeWorldData(Server_Server *Server)
00918 {
00919 GPlayer *Player;
00920 int32 i;
00921
00922 assert(Server);
00923
00924
00925 if (Server->ShutdownWorldCB1)
00926 {
00927 if (!Server->ShutdownWorldCB1(&Server->GenVSI))
00928 GenVS_Error("Server_FreeWorldData: ShutdownWorldCB1 failed.\n");
00929 }
00930
00931
00932 for (Player = Server->SvPlayers, i=0; i< NETMGR_MAX_PLAYERS; i++, Player++)
00933 {
00934 if (Player->DFunc)
00935 Player->DFunc(&Server->GenVSI, Player, Player->ClassData);
00936
00937 Player->DFunc = NULL;
00938 }
00939
00940 return GE_TRUE;
00941 }
00942
00943
00944
00945
00946 geBoolean Server_NewWorldDefaults(Server_Server *Server)
00947 {
00948 int32 i;
00949 GPlayer *Player;
00950 Server_Client *Client;
00951
00952 assert(Server);
00953
00954
00955 for (Player = Server->SvPlayers, i=0; i< NETMGR_MAX_PLAYERS; i++, Player++)
00956 {
00957 assert(Player->DFunc == NULL);
00958 Server_SetPlayerDefaults(Player);
00959 }
00960
00961
00962 Server->NumTotalPlayers = 0;;
00963
00964
00965 for (Client = Server->Clients, i=0; i< NETMGR_MAX_CLIENTS; i++, Client++)
00966 {
00967
00968 Client->Player = NULL;
00969 Client->NextUpdate = 0.0f;
00970 Client->OldMoveTime = 0.0f;
00971 Client->MoveTime = 0.0f;
00972 Client->Spawned = GE_FALSE;
00973 }
00974
00975 return GE_TRUE;
00976 }
00977
00978
00979
00980
00981
00982
00983 geBoolean Server_SpawnWorld(Server_Server *Server)
00984 {
00985 int32 i;
00986 geWorld *World;
00987 Server_CSpawn *CSpawn;
00988 GPlayer *Player;
00989 void *ClassData;
00990 geEntity_EntitySet *ClassSet;
00991 geEntity *Entity;
00992
00993 assert(Server);
00994
00995 World = GameMgr_GetWorld(Server->GMgr);
00996 assert(World);
00997
00998 if (!Server->NumClassSpawns)
00999 {
01000 GenVS_Error("Server_SpawnWorld: No Class Spawns in Game code.\n");
01001 }
01002
01003
01004 for (i=0; i < Server->NumClassSpawns; i++)
01005 {
01006 CSpawn = &Server->ClassSpawns[i];
01007
01008
01009 ClassSet = geWorld_GetEntitySet(World, CSpawn->Name);
01010
01011
01012 if (!ClassSet)
01013 continue;
01014
01015 Entity = NULL;
01016
01017 while (1)
01018 {
01019 #define MAX_NAME 200
01020 char EntityName[MAX_NAME];
01021
01022 Entity = geEntity_EntitySetGetNextEntity(ClassSet, Entity);
01023 if (!Entity)
01024 break;
01025
01026 geEntity_GetName(Entity, EntityName, MAX_NAME-1);
01027 EntityName[MAX_NAME-1]=0;
01028
01029 ClassData = geEntity_GetUserData(Entity);
01030
01031
01032 Player = Server_CreatePlayer(Server, CSpawn->Name);
01033
01034 Player->Mode = MODE_Authoritive;
01035 Player->ClassData = ClassData;
01036 Player->DFunc = CSpawn->DFunc;
01037
01038 assert(CSpawn->Func);
01039
01040
01041 CSpawn->Func(&Server->GenVSI, Player, ClassData, EntityName);
01042
01043 }
01044
01045 }
01046
01047
01048 for (i=0; i< NETMGR_MAX_CLIENTS; i++)
01049 {
01050 Server_Client *Client;
01051
01052
01053 Client = &Server->Clients[i];
01054
01055 if (!Client->Active)
01056 continue;
01057
01058
01059 Server_ValidateClient(Server, Client);
01060 }
01061
01062
01063
01064
01065
01066 return GE_TRUE;
01067 }
01068
01069 extern geVFile *MainFS;
01070
01071
01072
01073
01074 geBoolean Server_SetupWorld(Server_Server *Server)
01075 {
01076 geWorld *World;
01077 GameMgr *GMgr;
01078
01079 assert(Server);
01080 assert(Server->NewWorldCB);
01081
01082 GMgr = Server->GMgr;
01083 World = GameMgr_GetWorld(GMgr);
01084
01085 assert(GMgr);
01086 assert(World);
01087 assert(MainFS);
01088
01089
01090 if (!Server->NewWorldCB(&Server->GenVSI, Server->WorldName, MainFS))
01091 GenVS_Error("Server_SetupWorld: NewWorldCB failed.\n");
01092
01093
01094 if (!Server_SpawnWorld(Server))
01095 GenVS_Error("Server_SetWorld: Failed to spawn world.\n");
01096
01097
01098 if (!Server_SetupAllClientsWithCurrentWorld(Server))
01099 GenVS_Error("Server_SetWorld: Failed send all clients world data.\n");
01100
01101
01102 return GE_TRUE;
01103 }
01104
01105
01106
01107
01108 geBoolean Server_Frame(Server_Server *Server, GameMgr *GMgr, float Time)
01109 {
01110 assert(Server != NULL);
01111 assert(GMgr);
01112
01113 Server->GMgr = GMgr;
01114
01115
01116 Server->Client->NetTime = GameMgr_GetTime(Server->GMgr);
01117
01118 if (Server->ChangeWorldRequest)
01119 {
01120 Server->ChangeWorldRequest = GE_FALSE;
01121
01122 if (!Server_FreeWorldData(Server))
01123 GenVS_Error("Server_Frame: Server_FreeWorldData failed.\n");
01124
01125
01126 if (!Server_NewWorldDefaults(Server))
01127 GenVS_Error("Server_Frame: Server_NewWorldDefaults failed.\n");
01128
01129
01130 if (Server->Client)
01131 Client_NewWorldDefaults(Server->Client);
01132
01133 if (!GameMgr_SetWorld(GMgr, Server->WorldName))
01134 GenVS_Error("Server_Frame: GameMgr_SetWorld failed.\n");
01135
01136 if (!Server_SetupWorld(Server))
01137 GenVS_Error("Server_Frame: Server_SetupWorld failed.\n");
01138
01139
01140 Server->ShutdownWorldCB1 = Server->ShutdownWorldCB2;
01141 Server->ShutdownWorldCB2 = NULL;
01142
01143
01144 }
01145
01146 if (!GameMgr_GetWorld(GMgr))
01147 return GE_TRUE;
01148
01149
01150
01151 if (!ReadClientMessages(Server, Time))
01152 GenVS_Error("Server_Frame: ReadClientMessages failed.\n");
01153
01154 if (!ControlPlayers(Server, Time))
01155 GenVS_Error("Server_Frame: ControlPlayers failed.\n");
01156
01157 Server_ManageBots(Server);
01158
01159
01160 if (!SendPlayersToClients(Server))
01161 GenVS_Error("Server_Frame: SendPlayersToClients failed.\n");
01162
01163
01164
01165 {
01166 Server_Client *Client;
01167 int32 i, t;
01168
01169 Client = Server->Clients;
01170
01171 t = 0;
01172
01173 for (i = 0; i< NETMGR_MAX_CLIENTS; i++, Client++)
01174 {
01175 int32 k;
01176
01177 if (!Client->Active)
01178 continue;
01179
01180 t++;
01181
01182 Client->Ping = 0.0f;
01183
01184 for (k=0; k< 10; k++)
01185 Client->Ping += Client->Pings[k];
01186
01187 Client->Ping *= (1.0f/10.0f);
01188
01189 if (ShowStats)
01190 geEngine_Printf(GameMgr_GetEngine(Server->GMgr), 2, 140+t*15, "Client: %s, Ping: %2.2f", Client->Name, Client->Ping*1000.0f);
01191 }
01192 }
01193
01194 #if 0 // FIXME: put in Server_RenderFrame!!!
01195 {
01196 geEngine *Engine;
01197
01198 Engine = GameMgr_GetEngine(Server->GMgr);
01199
01200 geEngine_Printf(Engine, 2, 15*2 , "SpawnTime : %3i", Server->NetStats.NumSpawnTime);
01201 geEngine_Printf(Engine, 2, 15*3 , "ViewFlags : %3i", Server->NetStats.NumViewFlags);
01202 geEngine_Printf(Engine, 2, 15*4 , "ViewIndex : %3i", Server->NetStats.NumViewIndex);
01203 geEngine_Printf(Engine, 2, 15*5 , "MotionIndex : %3i", Server->NetStats.NumMotionIndex);
01204 geEngine_Printf(Engine, 2, 15*6 , "FxFlags : %3i", Server->NetStats.NumFxFlags);
01205 geEngine_Printf(Engine, 2, 15*7 , "Pos : %3i", Server->NetStats.NumPos);
01206 geEngine_Printf(Engine, 2, 15*8 , "Angles : %3i", Server->NetStats.NumAngles);
01207 geEngine_Printf(Engine, 2, 15*9 , "FrameTime : %3i", Server->NetStats.NumFrameTime);
01208 geEngine_Printf(Engine, 2, 15*10, "Scale : %3i", Server->NetStats.NumScale);
01209 geEngine_Printf(Engine, 2, 15*11, "Velocity : %3i", Server->NetStats.NumVelocity);
01210 geEngine_Printf(Engine, 2, 15*12, "State : %3i", Server->NetStats.NumState);
01211 geEngine_Printf(Engine, 2, 15*13, "ControlIndex: %3i", Server->NetStats.NumControlIndex);
01212 geEngine_Printf(Engine, 2, 15*14, "TriggerIndex: %3i", Server->NetStats.NumTriggerIndex);
01213 geEngine_Printf(Engine, 2, 15*15, "MinsMaxs : %3i", Server->NetStats.NumMinsMaxs);
01214 geEngine_Printf(Engine, 2, 15*16, "BytesToSend : %3i", Server->NetStats.NumBytesToSend);
01215 }
01216 #endif
01217
01218 return GE_TRUE;
01219 }
01220
01221
01222
01223
01224 static Server_Client *FindClient(Server_Server *Server, geCSNetMgr_NetID ClientID)
01225 {
01226 int32 i;
01227 Server_Client *Client;
01228
01229 Client = Server->Clients;
01230
01231 for (i=0; i< NETMGR_MAX_CLIENTS; i++, Client++)
01232 {
01233 if (!Client->Active)
01234 continue;
01235
01236 if (Client->NetID == ClientID)
01237 return Client;
01238 }
01239
01240 return NULL;
01241 }
01242
01243
01244
01245
01246 static void ParseClientMove(Server_Server *Server, Buffer_Data *Buffer, Server_Client *Client, float Time)
01247 {
01248 float DeltaTime, MoveTime, NetTime;
01249 geVec3d Origin = {0.0f, 0.0f, 0.0f};
01250
01251 Buffer_GetFloat(Buffer, &MoveTime);
01252 Buffer_GetFloat(Buffer, &NetTime);
01253 Buffer_GetFloat(Buffer, &Client->ForwardSpeed);
01254 Buffer_GetFloat(Buffer, &Client->Angles.X);
01255 Buffer_GetFloat(Buffer, &Client->Angles.Y);
01256 Buffer_GetShort(Buffer, &Client->ButtonBits);
01257
01258 if (NetTime >= 0)
01259 {
01260 float Ping;
01261
01262 Ping = GameMgr_GetTime(Server->GMgr) - NetTime;
01263
01264 if (Ping >= 0)
01265 {
01266 Client->Pings[Client->NumPings%10] = Ping;
01267 Client->NumPings++;
01268 }
01269 }
01270
01271 if (Client->ButtonBits & HOST_BUTTON_FIRE)
01272 Buffer_GetShort(Buffer, &Client->CurrentWeapon);
01273
01274 #ifdef CALC_ERROR
01275 Buffer_GetAngle(Buffer, &Client->Pos);
01276 #endif
01277
01278 if (!GameMgr_GetWorld(Server->GMgr))
01279 return;
01280
01281 Client->OldMoveTime = Client->MoveTime;
01282 Client->MoveTime = MoveTime;
01283
01284 if (MoveTime <= Client->OldMoveTime)
01285 return;
01286
01287
01288
01289 DeltaTime = Client->MoveTime - Client->OldMoveTime;
01290
01291 if (DeltaTime <= 0.0f)
01292 return;
01293
01294 if (DeltaTime > 0.1f)
01295 DeltaTime = 0.1f;
01296 else if (DeltaTime < 0.001f)
01297 DeltaTime = 0.001f;
01298
01299 #ifdef CALC_ERROR
01300 if (!geVec3d_Compare(&Client->Pos, &Origin, 0.1f))
01301 {
01302 geVec3d Vect;
01303
01304 geVec3d_Subtract(&Client->Player->XForm.Translation, &Client->Pos, &Vect);
01305
01306 if (geVec3d_Length(&Vect) > 1.0f)
01307 {
01308 Client->Player->OldPos.X = 0.0f;
01309 geEngine_Printf(Server->Host->Engine, 10, 100, "Client prediction error.");
01310 }
01311 }
01312 #endif
01313
01314 if (Client->Player)
01315 {
01316 Client->Player->SpawnTime = Client->MoveTime;
01317 Client->Player->PingTime = Client->Ping;
01318
01319
01320 ControlPlayer(Server, Client->Player, DeltaTime);
01321
01322 ForceServerPlayerOnLocalClient(Server, Client->Player);
01323 }
01324 else
01325 GenVS_Error("ParseClientMove: No player for client!!!");
01326 }
01327
01328
01329
01330
01331 static geBoolean ParseClientMessage(Server_Server *Server, geCSNetMgr_NetID ClientID, Buffer_Data *Buffer, float Time)
01332 {
01333 uint8 Type;
01334 Server_Client *Client;
01335
01336 Client = FindClient(Server, ClientID);
01337
01338 if (!Client)
01339 {
01340
01341 Console_Printf(GameMgr_GetConsole(Server->GMgr), "ParseClientMessage: FindClient failed.\n");
01342 return GE_TRUE;
01343 }
01344
01345 if (!Client->Player)
01346 return GE_TRUE;
01347
01348 Buffer->Pos = 0;
01349
01350
01351 while (Buffer->Pos < Buffer->Size)
01352 {
01353
01354
01355 Buffer_GetByte(Buffer, &Type);
01356
01357 switch(Type)
01358 {
01359 case NETMGR_MSG_CLIENT_MOVE:
01360 {
01361 ParseClientMove(Server, Buffer, Client, Time);
01362 break;
01363 }
01364
01365 case NETMGR_MSG_CLIENT_CONFIRM:
01366 {
01367 NetMgr_NetState NetState;
01368
01369 Buffer_GetSLong(Buffer, &NetState);
01370
01371
01372
01373
01374 Client->NetStateConfirmed[NetState] = GE_TRUE;
01375
01376 break;
01377 }
01378
01379 default:
01380 {
01381 GenVS_Error("Server_ParseClientMessage: Invalid msg type.\n");
01382 }
01383 }
01384 }
01385
01386 return GE_TRUE;
01387 }
01388
01389
01390
01391
01392 static geBoolean ReadClientMessages(Server_Server *Server, float Time)
01393 {
01394 Buffer_Data Buffer;
01395 geCSNetMgr_NetID ClientId;
01396 geCSNetMgr_NetMsgType MsgType;
01397 geCSNetMgr_NetClient *pGEClient;
01398
01399 while (1)
01400 {
01401 if (!NetMgr_ReceiveClientMessage(Server->NMgr, &MsgType, &ClientId, &Buffer))
01402 GenVS_Error("ReadClientMessages: NetMgr_ReceiveClientMessage failed.\n");
01403
01404 if (MsgType == NET_MSG_NONE)
01405 break;
01406
01407 assert(Buffer.Size > 0);
01408
01409 switch(MsgType)
01410 {
01411 case NET_MSG_CREATE_CLIENT:
01412 {
01413 pGEClient = (geCSNetMgr_NetClient*)Buffer.Data;
01414
01415 if (!Server_ClientConnect(Server, pGEClient))
01416 GenVS_Error("Could not add client...\n");
01417
01418 break;
01419 }
01420
01421 case NET_MSG_DESTROY_CLIENT:
01422 {
01423
01424 pGEClient = (geCSNetMgr_NetClient*)Buffer.Data;
01425
01426 Server_ClientDisconnect(Server, pGEClient->Id, pGEClient->Name);
01427 break;
01428 }
01429
01430 case NET_MSG_USER:
01431 {
01432 if (!ParseClientMessage(Server, ClientId, &Buffer, Time))
01433 GenVS_Error("ReadClientMessages: ParseClientMessage failed.\n");
01434 break;
01435 }
01436
01437 case NET_MSG_HOST:
01438 {
01439 break;
01440 }
01441
01442 case NET_MSG_SESSIONLOST:
01443 {
01444 GenVS_Error("ReadClientMessages: Session was lost.\n");
01445 }
01446
01447 default:
01448
01449 break;
01450 }
01451 }
01452
01453 return GE_TRUE;
01454 }
01455
01456 #define ANGLE_EPSILON 0.0001f
01457 #define POS_EPSILON 0.0001f
01458 #define VELOCITY_EPSILON 0.0001f
01459 #define MIN_MAX_EPSILON 0.001f
01460
01461
01462
01463
01464 static uint16 GetPlayerSendFlags(Server_Server *Server, GPlayer *Player)
01465 {
01466 uint16 SendFlags;
01467
01468 assert(Server);
01469 assert(Player);
01470
01471
01472 geXForm3d_GetEulerAngles(&Player->XForm, &Player->Angles);
01473 Player->Pos = Player->XForm.Translation;
01474
01475 SendFlags = 0;
01476
01477 if (Player->SpawnTime != Player->OldSpawnTime)
01478 {
01479 SendFlags |= NETMGR_SEND_SPAWN_TIME;
01480 Player->OldSpawnTime = Player->SpawnTime;
01481 Server->NetStats.NumSpawnTime++;
01482 }
01483
01484 if (Player->ViewFlags != Player->OldViewFlags)
01485 {
01486 SendFlags |= NETMGR_SEND_VIEW_FLAGS;
01487 Player->OldViewFlags = Player->ViewFlags;
01488 Server->NetStats.NumViewFlags++;
01489 }
01490
01491 if (Player->ViewIndex != Player->OldViewIndex)
01492 {
01493 SendFlags |= NETMGR_SEND_VIEW_INDEX;
01494 Player->OldViewIndex = Player->ViewIndex;
01495 Server->NetStats.NumViewIndex++;
01496 }
01497
01498 if (Player->MotionIndex != Player->OldMotionIndex)
01499 {
01500 SendFlags |= NETMGR_SEND_MOTION_INDEX;
01501 Player->OldMotionIndex = Player->MotionIndex;
01502 Server->NetStats.NumMotionIndex++;
01503 }
01504
01505 if (Player->FxFlags != Player->OldFxFlags)
01506 {
01507 SendFlags |= NETMGR_SEND_FX_FLAGS;
01508 Player->OldFxFlags = Player->FxFlags;
01509 Server->NetStats.NumFxFlags++;
01510 }
01511
01512 if (!geVec3d_Compare(&Player->OldPos, &Player->Pos, POS_EPSILON))
01513 {
01514 SendFlags |= NETMGR_SEND_POS;
01515 Player->OldPos = Player->Pos;
01516 Server->NetStats.NumPos++;
01517 }
01518
01519 if (!geVec3d_Compare(&Player->OldAngles, &Player->Angles, ANGLE_EPSILON))
01520 {
01521 SendFlags |= NETMGR_SEND_ANGLES;
01522 Player->OldAngles = Player->Angles;
01523 Server->NetStats.NumAngles++;
01524 }
01525
01526 if (Player->OldFrameTime != Player->FrameTime)
01527 {
01528 SendFlags |= NETMGR_SEND_FRAME_TIME;
01529 Player->OldFrameTime = Player->FrameTime;
01530 Server->NetStats.NumFrameTime++;
01531 }
01532
01533 if (Player->Scale != Player->OldScale)
01534 {
01535 SendFlags |= NETMGR_SEND_SCALE;
01536 Player->OldScale = Player->Scale;
01537 Server->NetStats.NumScale++;
01538 }
01539
01540 if (!geVec3d_Compare(&Player->OldVelocity, &Player->Velocity, VELOCITY_EPSILON))
01541 {
01542 SendFlags |= NETMGR_SEND_VELOCITY;
01543 Player->OldVelocity = Player->Velocity;
01544 Server->NetStats.NumVelocity++;
01545 }
01546
01547 if (Player->OldState != Player->State)
01548 {
01549 SendFlags |= NETMGR_SEND_STATE;
01550 Player->OldState = Player->State;
01551 Server->NetStats.NumState++;
01552 }
01553
01554 if (Player->OldControlIndex != Player->ControlIndex)
01555 {
01556 Player->OldControlIndex = Player->ControlIndex;
01557 SendFlags |= NETMGR_SEND_CONTROL_INDEX;
01558 Server->NetStats.NumControlIndex++;
01559 }
01560
01561 if (Player->OldTriggerIndex != Player->TriggerIndex)
01562 {
01563 SendFlags |= NETMGR_SEND_TRIGGER_INDEX;
01564 Player->OldTriggerIndex = Player->TriggerIndex;
01565 Server->NetStats.NumTriggerIndex++;
01566 }
01567
01568 if (!geVec3d_Compare(&Player->OldMins, &Player->Mins, MIN_MAX_EPSILON) || !geVec3d_Compare(&Player->OldMaxs, &Player->Maxs, MIN_MAX_EPSILON))
01569 {
01570 SendFlags |= NETMGR_SEND_MINS_MAXS;
01571 Player->OldMins = Player->Mins;
01572 Player->OldMaxs = Player->Maxs;
01573 Server->NetStats.NumMinsMaxs++;
01574 }
01575
01576 return SendFlags;
01577 }
01578
01579
01580
01581
01582 static void FillBufferWithPlayerData(Server_Server *Server, Buffer_Data *Buffer, GPlayer *Player, uint16 SendFlags)
01583 {
01584 uint16 Index;
01585
01586 assert(Server);
01587 assert(Buffer);
01588 assert(Player);
01589
01590 Index = (uint16)SERVER_GPLAYER_TO_INDEX(Server, Player);
01591
01592 assert(Index < (65535>>1));
01593
01594
01595
01596 if (SendFlags)
01597 Index |= (1<<15);
01598
01599 Buffer_FillShort(Buffer, Index);
01600
01601 if (!SendFlags)
01602 return;
01603
01604
01605 Buffer_FillShort(Buffer, SendFlags);
01606
01607
01608 geXForm3d_GetEulerAngles(&Player->XForm, &Player->Angles);
01609 Player->Pos = Player->XForm.Translation;
01610
01611
01612 if (SendFlags & NETMGR_SEND_SPAWN_TIME)
01613 Buffer_FillFloat(Buffer, Player->SpawnTime);
01614
01615 if (SendFlags & NETMGR_SEND_VIEW_FLAGS)
01616 Buffer_FillShort(Buffer, Player->ViewFlags);
01617
01618 if (SendFlags & NETMGR_SEND_VIEW_INDEX)
01619 Buffer_FillShort(Buffer, Player->ViewIndex);
01620
01621 if (SendFlags & NETMGR_SEND_MOTION_INDEX)
01622 Buffer_FillByte(Buffer, Player->MotionIndex);
01623
01624 if (SendFlags & NETMGR_SEND_FX_FLAGS)
01625 Buffer_FillShort(Buffer, Player->FxFlags);
01626
01627 if (SendFlags & NETMGR_SEND_POS)
01628
01629 Buffer_FillPos(Buffer, Player->Pos);
01630
01631 if (SendFlags & NETMGR_SEND_ANGLES)
01632 Buffer_FillAngle(Buffer, Player->Angles);
01633
01634 if (SendFlags & NETMGR_SEND_FRAME_TIME)
01635
01636 Buffer_FillFloat2(Buffer, Player->FrameTime, 60.0f);
01637
01638 if (SendFlags & NETMGR_SEND_SCALE)
01639
01640 Buffer_FillFloat2(Buffer, Player->Scale, 100.0f);
01641
01642 if (SendFlags & NETMGR_SEND_VELOCITY)
01643 Buffer_FillAngle(Buffer, Player->Velocity);
01644
01645 if (SendFlags & NETMGR_SEND_STATE)
01646 {
01647 assert(Player->State >= 0 && Player->State <= 255);
01648
01649 Buffer_FillByte(Buffer, (uint8)Player->State);
01650 }
01651
01652 if (SendFlags & NETMGR_SEND_CONTROL_INDEX)
01653 Buffer_FillShort(Buffer, Player->ControlIndex);
01654
01655 if (SendFlags & NETMGR_SEND_TRIGGER_INDEX)
01656 Buffer_FillShort(Buffer, Player->TriggerIndex);
01657
01658 if (SendFlags & NETMGR_SEND_MINS_MAXS)
01659 {
01660 Buffer_FillPos(Buffer, Player->Mins);
01661 Buffer_FillPos(Buffer, Player->Maxs);
01662 }
01663
01664 #if 0
01665
01666 if (Player->ViewFlags & VIEW_TYPE_HACK)
01667 {
01668 GPlayer_XFormData *pXFormData;
01669 int32 i;
01670
01671 assert(Player->NumXFormData <= 255 && Player->NumXFormData < GPLAYER_MAX_XFORM_DATA);
01672
01673 Buffer_FillByte(Buffer, (uint8)Player->NumXFormData);
01674
01675 pXFormData = Player->XFormData;
01676
01677 for (i=0; i<Player->NumXFormData; i++, pXFormData++)
01678 {
01679 geVec3d EulerAngles;
01680
01681 geXForm3d_GetEulerAngles(&pXFormData->XForm, &EulerAngles);
01682 Buffer_FillAngle(Buffer, EulerAngles);
01683 Buffer_FillPos(Buffer, pXFormData->XForm.Translation);
01684 Buffer_FillByte(Buffer, pXFormData->BoneIndex);
01685 }
01686
01687 }
01688
01689
01690 if (Player->ViewFlags & VIEW_TYPE_HACK)
01691 {
01692 GPlayer_MotionData *pMotionData;
01693 int32 i;
01694
01695 assert(Player->NumMotionData <= 255 && Player->NumMotionData < GPLAYER_MAX_MOTION_DATA);
01696
01697 Buffer_FillByte(Buffer, (uint8)Player->NumMotionData);
01698
01699 pMotionData = Player->MotionData;
01700
01701 for (i=0; i<Player->NumMotionData; i++, pMotionData++)
01702 {
01703 Buffer_FillFloat(Buffer, pMotionData->MotionTime);
01704
01705 Buffer_FillByte(Buffer, pMotionData->MotionIndex);
01706 }
01707 }
01708
01709 #endif
01710
01711 }
01712
01713
01714
01715
01716
01717
01718
01719 static void SetupClientPlayerSendFlags(Server_Server *Server)
01720 {
01721 GPlayer *Player;
01722 int32 i;
01723
01724 Player = Server->SvPlayers;
01725
01726 for (i=0; i< NETMGR_MAX_PLAYERS; i++, Player++)
01727 {
01728 uint16 SendFlags;
01729 int32 k;
01730 Server_Client *Client;
01731
01732 if (!Player->Active)
01733 continue;
01734
01735 if (Player->ViewFlags & VIEW_TYPE_LOCAL)
01736 continue;
01737
01738 if (!Player->Control)
01739 continue;
01740
01741 SendFlags = GetPlayerSendFlags(Server, Player);
01742
01743 Client = Server->Clients;
01744
01745
01746 for (k=0; k< NETMGR_MAX_CLIENTS; k++, Client++)
01747 {
01748 if (!Client->Active)
01749 continue;
01750
01751 Client->SendFlags[i] |= SendFlags;
01752 }
01753 }
01754 }
01755
01756 #if 1
01757 static int32 NumData;
01758 #endif
01759
01760
01761
01762
01763 static geBoolean SendPlayersToClients(Server_Server *Server)
01764 {
01765
01766 #if 1 // Optimized for internet gameplay (can use on LAN just fine too)
01767 int32 i;
01768 uint8 Data[20000];
01769 Buffer_Data Buffer;
01770 Server_Client *Client;
01771 geWorld *World;
01772
01773 World = GameMgr_GetWorld(Server->GMgr);
01774
01775 if (!World)
01776 return GE_TRUE;
01777
01778 SetupClientPlayerSendFlags(Server);
01779
01780 Client = Server->Clients;
01781
01782
01783 for (i=0; i< NETMGR_MAX_CLIENTS; i++, Client++)
01784 {
01785 GPlayer *Player;
01786 int32 k;
01787 geVec3d Pos1[5];
01788 geVec3d Pos2;
01789 geVec3d In;
01790 int32 Leaf1[5], Leaf2;
01791 float NextUpdate, Ping, GTime;
01792
01793 if (!Client->Active)
01794 continue;
01795
01796
01797 if (!(Client->NetState == NetState_WorldActive && Client->NetStateConfirmed[NetState_WorldActive]))
01798 continue;
01799
01800
01801 GTime = GameMgr_GetTime(Server->GMgr);
01802
01803 if (GTime < Client->NextUpdate)
01804 continue;
01805
01806
01807 Buffer_Set(&Buffer, Data, 20000);
01808
01809
01810 Buffer_FillByte(&Buffer, NETMGR_MSG_TIME);
01811 Buffer_FillFloat(&Buffer, GTime);
01812 Buffer_FillFloat(&Buffer, Client->Ping);
01813
01814 Player = Server->SvPlayers;
01815
01816
01817 Pos1[0] = Client->Player->VPos;
01818 Pos1[1] = Client->Player->VPos;
01819
01820 Pos1[1].Y += 120.0f;
01821
01822 geXForm3d_GetIn(&Client->Player->XForm, &In);
01823 geVec3d_AddScaled(&Pos1[1], &In, 450.0f, &Pos1[1]);
01824
01825 geWorld_GetLeaf(World, &Pos1[0], &Leaf1[0]);
01826 geWorld_GetLeaf(World, &Pos1[1], &Leaf1[1]);
01827
01828 for (k=0; k< NETMGR_MAX_PLAYERS; k++, Player++)
01829 {
01830 GE_Collision Collision;
01831
01832 if (!Player->Active)
01833 continue;
01834
01835 if (Player->ViewFlags & VIEW_TYPE_LOCAL)
01836 continue;
01837
01838 if (!Player->Control)
01839 continue;
01840
01841 Pos2 = Player->VPos;
01842
01843 geWorld_GetLeaf(World, &Pos2, &Leaf2);
01844
01845 #if 1
01846
01847
01848 if (Player != Client->Player)
01849 {
01850 if (!geWorld_LeafMightSeeLeaf(World, Leaf2, Leaf1[0], 0))
01851 if (!geWorld_LeafMightSeeLeaf(World, Leaf2, Leaf1[1], 0))
01852 {
01853
01854
01855 if (i == 0)
01856 {
01857 Buffer_FillByte(&Buffer, NETMGR_MSG_PLAYER_DATA);
01858 FillBufferWithPlayerData(Server, &Buffer, Player, 0);
01859 }
01860 else
01861 Client->SendFlags[k] = 0xffff;
01862
01863 continue;
01864 }
01865
01866
01867
01868 if (Player->ClientHandle == -1)
01869 if (!Player->Model)
01870 if (geWorld_Collision(World, NULL, NULL, &Pos1[0], &Pos2, GE_CONTENTS_CANNOT_OCCUPY, GE_COLLIDE_MODELS | GE_COLLIDE_NO_SUB_MODELS, 0, NULL, NULL, &Collision))
01871 if (geWorld_Collision(World, NULL, NULL, &Pos1[1], &Pos2, GE_CONTENTS_CANNOT_OCCUPY, GE_COLLIDE_MODELS | GE_COLLIDE_NO_SUB_MODELS, 0, NULL, NULL, &Collision))
01872 {
01873
01874 if (i==0)
01875 {
01876 Buffer_FillByte(&Buffer, NETMGR_MSG_PLAYER_DATA);
01877 FillBufferWithPlayerData(Server, &Buffer, Player, 0);
01878 }
01879 else
01880 Client->SendFlags[k] = 0xffff;
01881
01882 continue;
01883 }
01884 }
01885 #endif
01886
01887
01888
01889
01890 Buffer_FillByte(&Buffer, NETMGR_MSG_PLAYER_DATA);
01891 FillBufferWithPlayerData(Server, &Buffer, Player, Client->SendFlags[k]);
01892 Client->SendFlags[k] = 0;
01893 }
01894
01895 Ping = Client->Ping * 1000.0f;
01896
01897
01898 if (Ping < 100.0f)
01899 NextUpdate = Client->Ping*0.1f;
01900 else if (Ping < 300.0f)
01901 NextUpdate = Client->Ping*0.15f;
01902
01903 else if (Ping < 700.0f)
01904 NextUpdate = Client->Ping*0.2f;
01905 else if (Ping < 1000.0f)
01906 NextUpdate = Client->Ping*0.25f;
01907 else if (Ping < 2500.0f)
01908 NextUpdate = Client->Ping*0.3f;
01909 else
01910 NextUpdate = 1.0f;
01911
01912
01913 Client->NextUpdate = GTime + NextUpdate;
01914
01915 Server->NetStats.NumBytesToSend += Buffer.Pos;
01916
01917 #if 0
01918 if (i != 0)
01919 {
01920 geEngine_Printf(GameMgr_GetEngine(Server->GMgr), 3, 65, "Sending client data: %i", NumData);
01921 NumData += Buffer.Pos;
01922 }
01923 #endif
01924
01925
01926 if (!NetMgr_SendClientMessage(Server->NMgr, Client->NetID, &Buffer, FALSE))
01927 Server_ClientDisconnect(Server, Client->NetID, Client->Name);
01928 }
01929 #else
01930 int32 i;
01931 uint8 Data[20000];
01932 Buffer_Data Buffer;
01933 GPlayer *Player;
01934 uint16 SendFlags;
01935
01936 Buffer_Set(&Buffer, Data, 20000);
01937
01938 Buffer_FillByte(&Buffer, NETMGR_MSG_TIME);
01939 Buffer_FillFloat(&Buffer, Host->Time);
01940 Buffer_FillFloat(&Buffer, 0.0f);
01941
01942
01943 for (i=0; i< NETMGR_MAX_PLAYERS; i++)
01944 {
01945 Player = &Server->SvPlayers[i];
01946
01947
01948 if (!Player->Active)
01949 continue;
01950
01951 if (Player->ViewFlags & VIEW_TYPE_LOCAL)
01952 continue;
01953
01954 if (!Player->Control)
01955 continue;
01956
01957 assert(i >=0 && i <= 65535);
01958
01959
01960 Buffer_FillByte(&Buffer, NETMGR_MSG_PLAYER_DATA);
01961
01962 SendFlags = GetPlayerSendFlags(Server, Player);
01963
01964
01965 FillBufferWithPlayerData(Server, &Buffer, Player, SendFlags);
01966 }
01967
01968
01969 for (i=0; i< NETMGR_MAX_CLIENTS; i++)
01970 {
01971 if (!Server->Clients[i].Active)
01972 continue;
01973
01974 if (!NetMgr_SendClientMessage(Server->NMgr, Server->Clients[i].NetID, &Buffer, FALSE))
01975 GenVS_Error("SendPlayersToClients: NetMgr_SendClientMessage failed.\n");
01976
01977 Server->NetStats.NumBytesToSend += Buffer.Pos;
01978 }
01979
01980 #endif
01981 return GE_TRUE;
01982 }
01983
01984
01985
01986 static void DrawFace(geWorld *World, const geVec3d **Verts)
01987 {
01988 GE_LVertex LVerts[4];
01989 int i;
01990
01991 for (i = 0; i < 4; i++)
01992 {
01993 LVerts[i].r = 40.0f;
01994 LVerts[i].g = 40.0f;
01995 LVerts[i].b = 80.0f + 20.0f * (geFloat)i;
01996 LVerts[i].a = 128.0f;
01997 LVerts[i].X = Verts[i]->X;
01998 LVerts[i].Y = Verts[i]->Y;
01999 LVerts[i].Z = Verts[i]->Z;
02000 }
02001
02002 geWorld_AddPolyOnce(World, &LVerts[0], 4, NULL, GE_GOURAUD_POLY, GE_RENDER_DO_NOT_OCCLUDE_OTHERS, 1.0f);
02003 }
02004
02005 void DrawBoundBox(geWorld *World, const geVec3d *Pos, const geVec3d *Min, const geVec3d *Max)
02006 {
02007 geFloat dx;
02008 geFloat dy;
02009 geFloat dz;
02010 static geVec3d Verts[8];
02011 static geVec3d * Faces[6][4] =
02012 {
02013 { &Verts[0], &Verts[1], &Verts[2], &Verts[3] },
02014 { &Verts[4], &Verts[5], &Verts[6], &Verts[7] },
02015 { &Verts[3], &Verts[2], &Verts[6], &Verts[7] },
02016 { &Verts[1], &Verts[0], &Verts[4], &Verts[5] },
02017 { &Verts[0], &Verts[3], &Verts[7], &Verts[4] },
02018 { &Verts[2], &Verts[1], &Verts[5], &Verts[6] },
02019 };
02020 int i;
02021
02022 for (i = 0; i < 8; i++)
02023 geVec3d_Add(Pos, Min, &Verts[i]);
02024
02025 dx = Max->X - Min->X;
02026 dy = Max->Y - Min->Y;
02027 dz = Max->Z - Min->Z;
02028
02029 Verts[0].Y += dy;
02030 Verts[3].Y += dy;
02031 Verts[3].X += dx;
02032 Verts[7].X += dx;
02033
02034 Verts[1].Y += dy;
02035 Verts[1].Z += dz;
02036 Verts[5].Z += dz;
02037 Verts[6].Z += dz;
02038 Verts[6].X += dx;
02039
02040 Verts[2].X += dx;
02041 Verts[2].Y += dy;
02042 Verts[2].Z += dz;
02043
02044 for (i = 0; i < 6; i++)
02045 DrawFace(World, &Faces[i][0]);
02046 }
02047
02048
02049
02050
02051
02052 static void ForceServerPlayerOnLocalClient(Server_Server *Server, GPlayer *Player)
02053 {
02054 GPlayer *ClientPlayer;
02055 int32 PlayerIndex;
02056 Buffer_Data Buffer;
02057 uint8 Data[1024];
02058
02059 assert(Server);
02060 assert(Server->Client);
02061 assert(Player);
02062
02063 if (!GameMgr_GetWorld(Server->GMgr))
02064 return;
02065
02066 if (!Player->Active)
02067 return;
02068
02069 PlayerIndex = (int32)SERVER_GPLAYER_TO_INDEX(Server, Player);
02070
02071 assert(PlayerIndex >= 0 && PlayerIndex < NETMGR_MAX_PLAYERS);
02072
02073
02074
02075 ClientPlayer = &Server->Client->Players[PlayerIndex];
02076
02077 Buffer_Set(&Buffer, Data, 1024);
02078
02079
02080 FillBufferWithPlayerData(Server, &Buffer, Player, 0xffff);
02081
02082
02083 Buffer.Pos = 0;
02084
02085 Client_ParsePlayerData(Server->Client, &Buffer, GE_FALSE);
02086
02087
02088 ClientPlayer->Pos = Player->Pos;
02089 ClientPlayer->Angles = Player->Angles;
02090
02091
02092 Client_UpdateSinglePlayer(Server->Client, ClientPlayer, 1.0f, GameMgr_GetTime(Server->GMgr), GE_FALSE);
02093
02094 }
02095
02096
02097
02098
02099
02100 static void ControlPlayer(Server_Server *Server, GPlayer *Player, float Time)
02101 {
02102 assert (Player->Control);
02103
02104 if (!Player->Control)
02105 return;
02106
02107
02108
02109
02110 if (!Player->Control(&Server->GenVSI, Player, Time))
02111 GenVS_Error("[SERVER] ControlPlayer: Failed.");
02112
02113 geXForm3d_GetEulerAngles(&Player->XForm, &Player->Angles);
02114 Player->Pos = Player->XForm.Translation;
02115
02116
02117
02118 }
02119
02120
02121
02122
02123 static geBoolean ControlPlayers(Server_Server *Server, float Time)
02124 {
02125 GPlayer *Player;
02126 int32 i;
02127
02128 for (i=0; i< NETMGR_MAX_PLAYERS; i++)
02129 {
02130 Player = &Server->SvPlayers[i];
02131
02132 if (!Player->Active)
02133 continue;
02134
02135 if (!Player->Control)
02136 continue;
02137
02138 if (Player->ClientHandle != CLIENT_NULL_HANDLE && !Server_IsClientBot(Server, Player->ClientHandle))
02139 {
02140
02141 geXForm3d_GetEulerAngles(&Player->XForm, &Player->Angles);
02142 Player->Pos = Player->XForm.Translation;
02143
02144
02145 ForceServerPlayerOnLocalClient(Server, Player);
02146
02147 continue;
02148 }
02149
02150
02151
02152
02153 if (Player->PingTime > 0)
02154 {
02155 float Val;
02156
02157 Val = Player->PingTime * (1.0f/20.0f);
02158
02159
02160
02161 while (Player->PingTime > 0.0f && Player->Active)
02162 {
02163 ControlPlayer(Server, Player, Val);
02164
02165 Player->PingTime -= Val;
02166 }
02167
02168
02169 Player->PingTime = -1.0f;
02170 }
02171 else
02172 ControlPlayer(Server, Player, Time);
02173
02174
02175 ForceServerPlayerOnLocalClient(Server, Player);
02176 }
02177
02178 return GE_TRUE;
02179 }
02180
02181
02182
02183
02184 static int32 Server_CountBots(Server_Server *Server)
02185 {
02186 GPlayer *Player;
02187 int32 i, Count;
02188
02189 for (i=Count=0; i< NETMGR_MAX_PLAYERS; i++)
02190 {
02191 Player = &Server->SvPlayers[i];
02192
02193 if (!Player->Active)
02194 continue;
02195
02196 if (!Player->Control)
02197 continue;
02198
02199 if (Player->ClientHandle != CLIENT_NULL_HANDLE && Server_IsClientBot(Server, Player->ClientHandle))
02200 {
02201 Count++;
02202 }
02203 }
02204
02205 return Count;
02206 }
02207
02208
02209
02210
02211 static GenVSI_CHandle Server_GetBotByName(Server_Server *Server, char *Name)
02212 {
02213 GPlayer *Player;
02214 int32 i, Count;
02215 Server_Client *SClient;
02216
02217 for (i=Count=0; i< NETMGR_MAX_PLAYERS; i++)
02218 {
02219 Player = &Server->SvPlayers[i];
02220
02221 if (!Player->Active)
02222 continue;
02223
02224 if (!Player->Control)
02225 continue;
02226
02227 if (Player->ClientHandle != CLIENT_NULL_HANDLE && Server_IsClientBot(Server, Player->ClientHandle))
02228 {
02229 SClient = &Server->Clients[Player->ClientHandle];
02230
02231 if (strcmp(SClient->Name, Name) == 0)
02232 return (Player->ClientHandle);
02233 }
02234 }
02235
02236 return CLIENT_NULL_HANDLE;
02237 }
02238
02239
02240
02241
02242
02243 static geBoolean Server_ManageBots(Server_Server *Server)
02244 {
02245 int cnt;
02246 int i;
02247 extern int32 MenuBotCount;
02248 Server_Client *SClient;
02249 int32 Index;
02250
02251 static int32 RandomSet = -1;
02252
02253 static char *BotNames[4][4] = {
02254 {"Masque", "Velvet", "M&M", "Mellow"},
02255 {"Red Death", "Royal", "Yellow Streak", "Green Machine"},
02256 {"Anger", "Envy", "Melancholy", "Chicken"},
02257 {"Scarlet", "Violet", "Azure", "Chartreuse"},
02258 };
02259
02260 static GE_RGBA BotLight[4][4] = {
02261 {
02262 {255.0f, 050.0f, 050.0f, 0.0f},
02263 {255.0f, 050.0f, 255.0f, 0.0f},
02264 {000.0f, 255.0f, 000.0f, 0.0f},
02265 {255.0f, 229.0f, 094.0f, 0.0f},
02266 },
02267 {
02268 {255.0f, 050.0f, 050.0f, 0.0f},
02269 {000.0f, 050.0f, 255.0f, 0.0f},
02270 {255.0f, 229.0f, 094.0f, 0.0f},
02271 {000.0f, 255.0f, 000.0f, 0.0f},
02272 },
02273 {
02274 {255.0f, 050.0f, 050.0f, 0.0f},
02275 {000.0f, 255.0f, 000.0f, 0.0f},
02276 {000.0f, 050.0f, 255.0f, 0.0f},
02277 {255.0f, 229.0f, 094.0f, 0.0f},
02278 },
02279 {
02280 {255.0f, 050.0f, 050.0f, 0.0f},
02281 {255.0f, 050.0f, 255.0f, 0.0f},
02282 {000.0f, 050.0f, 255.0f, 0.0f},
02283 {176.0f, 232.0f, 082.0f, 0.0f},
02284 },
02285 };
02286
02287
02288 if (RandomSet == -1)
02289 {
02290 srand((unsigned)time(NULL));
02291 RandomSet = rand() % 4;
02292
02293 }
02294
02295 if (ServerBotCount == MenuBotCount)
02296 return GE_TRUE;
02297
02298 cnt = Server_CountBots(Server);
02299
02300 if (cnt < MenuBotCount)
02301 {
02302 for (i = cnt; i < MenuBotCount; i++)
02303 {
02304 if (!(SClient = Server_BotConnect(Server, BotNames[RandomSet][i])))
02305 {
02306 GenVS_Error("Server_ManageBots: Could not add BOT client in single player mode...\n");
02307 }
02308 else
02309 {
02310 if (!SClient->Active)
02311 continue;
02312
02313 Index = SClient->Player - Server->SvPlayers;
02314
02315 if (Server->Client->Players[Index].Actor)
02316 {
02317 geVec3d Normal = {0.0f, 1.0f, 0.0f};
02318
02319 geActor_SetLightingOptions( Server->Client->Players[Index].Actor,
02320 GE_TRUE, &Normal,
02321 BotLight[RandomSet][i].r,
02322 BotLight[RandomSet][i].g,
02323 BotLight[RandomSet][i].b,
02324 1.0f, 1.0f, 1.0f,
02325 GE_TRUE, 3, NULL, GE_FALSE);
02326 }
02327 }
02328
02329 ServerBotCount++;
02330 }
02331 }
02332 else
02333 if (cnt > MenuBotCount)
02334 {
02335 GenVSI_CHandle ClientHandle;
02336 for (i = cnt-1; i >= MenuBotCount; i--)
02337 {
02338 if ((ClientHandle = Server_GetBotByName(Server, BotNames[RandomSet][i])) != CLIENT_NULL_HANDLE)
02339 Server_ClientDisconnectByHandle(Server, ClientHandle);
02340 ServerBotCount--;
02341 }
02342 }
02343
02344 return GE_TRUE;
02345 }
02346
02347
02348
02349
02350
02351
02352
02353
02354
02355
02356 static void Server_SetClassSpawn(void *UData, const char *ClassName, GenVSI_SpawnFunc *Func, GenVSI_DestroyFunc *DFunc)
02357 {
02358 int32 i;
02359 Server_Server *Server;
02360
02361 assert(ClassName);
02362 assert(strlen(ClassName) < MAX_CLASS_NAME_STRING);
02363 assert(Func);
02364
02365 Server = (Server_Server*)UData;
02366
02367 for (i=0; i< Server->NumClassSpawns; i++)
02368 {
02369 if (!strcmp(Server->ClassSpawns[i].Name, ClassName))
02370 return;
02371 }
02372
02373 if (i >= MAX_SERVER_CLASS_SPAWNS)
02374 {
02375 GenVS_Error("Server_SetClassSpawn: No more slots left.\n");
02376 }
02377
02378 strcpy(Server->ClassSpawns[i].Name, ClassName);
02379 Server->ClassSpawns[i].Func = Func;
02380 Server->ClassSpawns[i].DFunc = DFunc;
02381
02382 Server->NumClassSpawns++;
02383 }
02384
02385
02386
02387
02388 static void Server_SetWorldRequest(Server_Server *Server, GenVSI_NewWorldCB *NewWorldCB, GenVSI_ShutdownWorldCB *ShutdownWorldCB, const char *Name)
02389 {
02390 assert(Server);
02391 assert(NewWorldCB);
02392 assert(Name);
02393
02394 strcpy(Server->WorldName, Name);
02395 Server->ChangeWorldRequest = GE_TRUE;
02396
02397 Server->NewWorldCB = NewWorldCB;
02398
02399
02400
02401 Server->ShutdownWorldCB2 = ShutdownWorldCB;
02402 }
02403
02404
02405
02406
02407 static void Server_ActorIndex(Server_Server *Server, uint16 Index, const char *GFXPath, const char *ActorName)
02408 {
02409 assert(Server);
02410 assert(GFXPath);
02411 assert(ActorName);
02412 assert(strlen(GFXPath) < GAMEMGR_MAX_GFX_PATH);
02413 assert(strlen(ActorName) < GAMEMGR_MAX_ACTOR_NAME);
02414 assert(Index < GAMEMGR_MAX_ACTOR_INDEX);
02415
02416 if (!GameMgr_SetActorIndex(Server->GMgr, Index, ActorName))
02417 {
02418
02419
02420
02421 GenVS_Error("Server_ActorIndex: GameMgr_SetActorIndex failed...");
02422 }
02423 }
02424
02425
02426
02427
02428 static void Server_MotionIndex(Server_Server *Server, uint16 MotionIndex, const char *MotionName)
02429 {
02430 assert(Server);
02431
02432 if (!GameMgr_SetMotionIndexDef(Server->GMgr, MotionIndex, MotionName))
02433 GenVS_Error("Server_MotionIndex: Could not set motion: %s.\n", MotionName);
02434 }
02435
02436
02437
02438
02439 static void Server_BoneIndex(Server_Server *Server, uint16 BoneIndex, const char *BoneName)
02440 {
02441 assert(Server);
02442
02443 if (!GameMgr_SetBoneIndex(Server->GMgr, BoneIndex, BoneName))
02444 GenVS_Error("Server_BoneIndex: Could not set Bone Index: %s.\n", BoneName);
02445 }
02446
02447
02448
02449
02450 static void Server_TextureIndex(Server_Server *Server, uint16 Index, const char *FileName, const char *AFileName)
02451 {
02452 assert(Server);
02453 assert(FileName);
02454 assert(strlen(FileName) < GAMEMGR_MAX_FILENAME);
02455
02456 if (!GameMgr_SetTextureIndex(Server->GMgr, Index, FileName, AFileName))
02457 {
02458 GenVS_Error("Server_TextureIndex: GameMgr_SetTextureIndex failed...");
02459 }
02460 }
02461
02462
02463
02464
02465 static void Server_SoundIndex(Server_Server *Server, uint16 Index, const char *FileName)
02466 {
02467 assert(Server);
02468 assert(FileName);
02469
02470 if (!GameMgr_SetSoundIndex(Server->GMgr, Index, FileName))
02471 {
02472 GenVS_Error("Server_SoundIndex: GameMgr_SetSoundIndex failed...");
02473 }
02474 }
02475
02476
02477
02478
02479 static void Server_PlaySound(Server_Server *Server, uint16 SoundIndex, const geVec3d *Pos)
02480 {
02481 int32 i;
02482 uint8 Data[1000];
02483 Buffer_Data Buffer;
02484 Server_Client *Client;
02485
02486 Buffer_Set(&Buffer, Data, 1000);
02487
02488
02489 Buffer_FillByte(&Buffer, NETMGR_MSG_PLAY_SOUND_INDEX);
02490 Buffer_FillShort(&Buffer, (uint16)SoundIndex);
02491 Buffer_FillPos(&Buffer, *Pos);
02492
02493 Client = Server->Clients;
02494
02495
02496 for (i=0; i< NETMGR_MAX_CLIENTS; i++, Client++)
02497 {
02498 if (!Client->Active)
02499 continue;
02500
02501 if (!NetMgr_SendClientMessage(Server->NMgr, Client->NetID, &Buffer, FALSE))
02502 {
02503 Server_ClientDisconnect(Server, Client->NetID, Client->Name);
02504
02505 }
02506 }
02507 }
02508
02509
02510
02511
02512 static void Server_SpawnFx(Server_Server *Server, uint8 Type, const geVec3d *Pos, uint8 Sound)
02513 {
02514 Buffer_Data Buffer;
02515 char Data[128];
02516
02517 assert(Server);
02518
02519 Buffer_Set(&Buffer, Data, 128);
02520 Buffer_FillByte(&Buffer, NETMGR_MSG_SPAWN_FX);
02521 Buffer_FillPos(&Buffer, *Pos);
02522 Buffer_FillByte(&Buffer, Type);
02523 Buffer_FillByte(&Buffer, Sound);
02524
02525 if (!SendAllClientsMessage(Server, &Buffer, GE_FALSE))
02526 GenVS_Error("Server_SpawnFx: Could not send mesages to clients.\n");
02527 }
02528
02529
02530
02531
02532 static void Server_SetClientScore(Server_Server *Server, GenVSI_CHandle ClientHandle, int32 Score)
02533 {
02534 Buffer_Data Buffer;
02535 char Data[128];
02536 Server_Client *Client;
02537
02538 assert(Server);
02539
02540 assert(ClientHandle >= 0 && ClientHandle <= 255);
02541
02542 Client = &Server->Clients[ClientHandle];
02543
02544 if (!Client->Active)
02545 {
02546 Console_Printf(GameMgr_GetConsole(Server->GMgr), "Server_SetClientScore: Client not active!\n");
02547 return;
02548 }
02549
02550 Client->Score = Score;
02551
02552 Buffer_Set(&Buffer, Data, 128);
02553 Buffer_FillByte(&Buffer, NETMGR_MSG_CLIENT_SCORE);
02554 Buffer_FillByte(&Buffer, (uint8)ClientHandle);
02555 Buffer_FillSLong(&Buffer, Client->Score);
02556
02557 if (!SendAllClientsMessage(Server, &Buffer, GE_TRUE))
02558 GenVS_Error("Server_SetClientScore: Could not send message.\n");
02559 }
02560
02561
02562
02563
02564 static geBoolean Server_IsClientBot(Server_Server *Server, GenVSI_CHandle ClientHandle)
02565 {
02566 Server_Client *Client;
02567
02568 assert(Server);
02569
02570 if (ClientHandle < 0 || ClientHandle > NETMGR_MAX_CLIENTS)
02571 return GE_FALSE;
02572
02573 Client = &Server->Clients[ClientHandle];
02574
02575 assert(Client->Active);
02576
02577 if (Client->NetID == NETMGR_SPECIAL_BOT_NETID)
02578 return GE_TRUE;
02579
02580 return GE_FALSE;
02581 }
02582
02583
02584
02585
02586 static void Server_SetClientHealth(Server_Server *Server, GenVSI_CHandle ClientHandle, int32 Health)
02587 {
02588 Buffer_Data Buffer;
02589 char Data[128];
02590 Server_Client *Client;
02591
02592 assert(Server);
02593
02594 assert(ClientHandle >= 0 && ClientHandle <= 255);
02595
02596 Client = &Server->Clients[ClientHandle];
02597
02598 if (!Client->Active)
02599 {
02600 Console_Printf(GameMgr_GetConsole(Server->GMgr), "Server_SetClientScore: Client not active!\n");
02601 return;
02602 }
02603
02604 Client->Health = Health;
02605
02606 Buffer_Set(&Buffer, Data, 128);
02607 Buffer_FillByte(&Buffer, NETMGR_MSG_CLIENT_HEALTH);
02608 Buffer_FillByte(&Buffer, (uint8)ClientHandle);
02609 Buffer_FillSLong(&Buffer, Client->Health);
02610
02611 if (!NetMgr_SendClientMessage(Server->NMgr, Client->NetID, &Buffer, GE_TRUE))
02612 {
02613 Server_ClientDisconnect(Server, Client->NetID, Client->Name);
02614
02615 }
02616 }
02617
02618
02619
02620
02621 static void Server_SetClientWeapon(Server_Server *Server, GenVSI_CHandle ClientHandle, int32 Weapon)
02622 {
02623 Buffer_Data Buffer;
02624 char Data[512];
02625 Server_Client *Client;
02626
02627 assert(Server);
02628
02629 assert(ClientHandle >= 0 && ClientHandle <= 255);
02630 assert(Weapon >= 0 && Weapon <= 255);
02631
02632 Client = &Server->Clients[ClientHandle];
02633
02634 if (!Client->Active)
02635 GenVS_Error("Server_SetClientWeapon: Client not active!\n");
02636
02637 Client->CurrentWeapon = (uint16)Weapon;
02638
02639 Buffer_Set(&Buffer, Data, 512);
02640 Buffer_FillByte(&Buffer, NETMGR_MSG_CLIENT_WEAPON);
02641 Buffer_FillByte(&Buffer, (uint8)ClientHandle);
02642 Buffer_FillShort(&Buffer, (uint16)Client->CurrentWeapon);
02643
02644 if (!NetMgr_SendClientMessage(Server->NMgr, Client->NetID, &Buffer, GE_FALSE))
02645 {
02646 Server_ClientDisconnect(Server, Client->NetID, Client->Name);
02647
02648 }
02649 }
02650
02651
02652
02653
02654 static void Server_SetClientInventory(Server_Server *Server, GenVSI_CHandle ClientHandle, int32 Slot, uint16 Amount, geBoolean HasItem)
02655 {
02656 Buffer_Data Buffer;
02657 char Data[128];
02658 uint16 SendVal;
02659 Server_Client *Client;
02660
02661 assert(Server);
02662 assert(ClientHandle >= 0 && ClientHandle < NETMGR_MAX_CLIENTS);
02663
02664 Client = &Server->Clients[ClientHandle];
02665
02666 if (!Client->Active)
02667 GenVS_Error("Server_SetClientInventory: Client not active.");
02668
02669 assert(Slot < MAX_PLAYER_ITEMS && Slot < 256);
02670
02671 Client->Inventory[Slot] = Amount;
02672 Client->InventoryHas[Slot] = HasItem;
02673
02674 SendVal = Client->Inventory[Slot];
02675
02676 if (Client->InventoryHas[Slot])
02677 SendVal |= (1<<15);
02678
02679 assert(ClientHandle <= 255);
02680
02681 Buffer_Set(&Buffer, Data, 128);
02682 Buffer_FillByte(&Buffer, NETMGR_MSG_CLIENT_INVENTORY);
02683 Buffer_FillByte(&Buffer, (uint8)ClientHandle);
02684 Buffer_FillByte(&Buffer, (uint8)Slot);
02685 Buffer_FillShort(&Buffer, SendVal);
02686
02687 if (!NetMgr_SendClientMessage(Server->NMgr, Client->NetID, &Buffer, GE_TRUE))
02688 {
02689 Server_ClientDisconnect(Server, Client->NetID, Client->Name);
02690
02691 }
02692 }
02693
02694
02695
02696
02697 static GenVSI_CMove *Server_GetClientMove(Server_Server *Server, GenVSI_CHandle ClientHandle)
02698 {
02699 Server_Client *Client;
02700
02701 assert(Server);
02702
02703 Client = &Server->Clients[ClientHandle];
02704
02705 Client->Move.MoveTime = Client->MoveTime;
02706 Client->Move.ForwardSpeed = Client->ForwardSpeed;
02707 Client->Move.Angles = Client->Angles;
02708 Client->Move.ButtonBits = Client->ButtonBits;
02709 Client->Move.Pos = Client->Pos;
02710 Client->Move.Weapon = Client->CurrentWeapon;
02711
02712 return &Client->Move;
02713 }
02714
02715
02716
02717
02718 static uint16 Server_ModelToViewIndex(Server_Server *Server, geWorld_Model *Model)
02719 {
02720 int32 i, NumModels;
02721
02722 assert(Server);
02723 assert(GameMgr_GetWorld(Server->GMgr));
02724
02725 NumModels = GameMgr_GetNumModels(Server->GMgr);
02726
02727 for (i=0; i< NumModels; i++)
02728 {
02729 if (Model == GameMgr_GetModel(Server->GMgr, i))
02730 break;
02731 }
02732
02733 if (i >= NumModels)
02734 {
02735 GenVS_Error("Server_ModelToViewIndex: Model not in world...");
02736 }
02737
02738 return (uint16)i;
02739 }
02740
02741
02742
02743
02744 static void Server_RegisterPlayerModel(Server_Server *Server, GPlayer *Player, geWorld_Model *Model)
02745 {
02746 assert(Server);
02747 assert(Player);
02748 assert(Model);
02749
02750
02751 geWorld_ModelSetUserData(Model, (void*)Player);
02752 Player->Model = Model;
02753 }
02754
02755
02756
02757
02758 static GPlayer *Server_GetNextPlayer(Server_Server *Server, GPlayer *Start, const char *ClassName)
02759 {
02760 GPlayer *RealStart, *End;
02761
02762 RealStart = &Server->SvPlayers[0];
02763 End = &Server->SvPlayers[NETMGR_MAX_PLAYERS-1];
02764
02765 if (Start == End)
02766 return NULL;
02767
02768 if (!Start)
02769 Start = Server->SvPlayers;
02770 else
02771 Start++;
02772
02773 assert(Start >= RealStart && Start <= End);
02774
02775 if (Start < RealStart || Start > End)
02776 {
02777 Console_Printf(GameMgr_GetConsole(Server->GMgr), "[SERVER] Server_GetNextPlayer: Bad start.\n");
02778 return NULL;
02779 }
02780
02781 for ( ; Start < End; Start++)
02782 {
02783 if (!Start->Active)
02784 continue;
02785
02786 if (!ClassName)
02787 return Start;
02788
02789 if (!strcmp(Start->ClassName, ClassName))
02790 return Start;
02791 }
02792
02793 return NULL;
02794 }
02795
02796
02797
02798
02799 static GPlayer *Server_GetNextPlayerInRadius(void *Server, GPlayer *Player, GPlayer *Start, const char *ClassName, float Radius)
02800 {
02801 while (1)
02802 {
02803 geVec3d Vect;
02804
02805 Start = Server_GetNextPlayer(Server, Start, ClassName);
02806
02807 if (!Start)
02808 return NULL;
02809
02810
02811 geVec3d_Subtract(&Start->XForm.Translation, &Player->XForm.Translation, &Vect);
02812
02813 if (geVec3d_Length(&Vect) <= Radius)
02814 return Start;
02815 }
02816
02817 return NULL;
02818 }
02819
02820
02821
02822
02823 static void Server_SetViewPlayer(Server_Server *Server, GenVSI_CHandle ClientHandle, GPlayer *Player)
02824 {
02825 int32 i;
02826 uint8 Data[1000];
02827 Buffer_Data Buffer;
02828 Server_Client *Client;
02829
02830 assert(Server);
02831 assert(ClientHandle >= 0 && ClientHandle <= NETMGR_MAX_CLIENTS);
02832 assert(Player);
02833
02834 Client = &Server->Clients[ClientHandle];
02835
02836 assert(Client->Active);
02837
02838 Buffer.Data = Data;
02839 Buffer.Size = 1000;
02840 Buffer.Pos = 0;
02841
02842
02843 i = (int32)SERVER_GPLAYER_TO_INDEX(Server, Player);
02844
02845 Buffer_FillByte(&Buffer, NETMGR_MSG_VIEW_PLAYER);
02846 Buffer_FillShort(&Buffer, (uint16)i);
02847
02848 Console_Printf(GameMgr_GetConsole(Server->GMgr), "View Player sent: %i\n", i);
02849
02850 if (!NetMgr_SendClientMessage(Server->NMgr, Client->NetID, &Buffer, GE_TRUE))
02851 {
02852 Server_ClientDisconnect(Server, Client->NetID, Client->Name);
02853
02854 }
02855 }
02856
02857
02858
02859
02860 static geBoolean Server_MovePlayerModel(Server_Server *Server, GPlayer *Player, const geXForm3d *DestXForm)
02861 {
02862 geBoolean CanMove;
02863 int32 i;
02864 geWorld *World;
02865
02866 assert(Server);
02867
02868 World = GameMgr_GetWorld(Server->GMgr);
02869 assert(World);
02870
02871 CanMove = GE_TRUE;
02872
02873 for (i=0; i< NETMGR_MAX_PLAYERS; i++)
02874 {
02875 geVec3d Mins, Maxs, Pos, Out;
02876 GPlayer *Target;
02877
02878 Target = &Server->SvPlayers[i];
02879
02880 if (!Target->Active)
02881 continue;
02882
02883 if (Target->ViewFlags & VIEW_TYPE_MODEL)
02884 continue;
02885
02886
02887 if (!(Target->ViewFlags & VIEW_TYPE_COLLIDEMODEL))
02888 continue;
02889
02890 Mins = Target->Mins;
02891 Maxs = Target->Maxs;
02892
02893 Pos = Target->XForm.Translation;
02894
02895
02896 if (!geWorld_TestModelMove(World, Player->Model, DestXForm, &Mins, &Maxs, &Pos, &Out))
02897 {
02898 CanMove = GE_FALSE;
02899
02900
02901 if (Player->Blocked)
02902 {
02903 Player->Blocked(&Server->GenVSI, Player, Target);
02904 }
02905
02906 }
02907 else
02908 {
02909 Target->XForm.Translation = Out;
02910 }
02911 }
02912
02913 if (CanMove)
02914 {
02915 if (World)
02916 geWorld_SetModelXForm(World, Player->Model, DestXForm);
02917 else
02918 Console_Printf(GameMgr_GetConsole(Server->GMgr), "Server_MovePlayerModel: No world!\n");
02919 }
02920
02921 return CanMove;
02922 }
02923
02924
02925
02926
02927 static void Server_GetPlayerTimeExtents(Server_Server *Server, GPlayer *Player, uint16 MotionIndex, float *Start, float *End)
02928 {
02929 geMotion *Motion;
02930 int32 Index;
02931 GameMgr_MotionIndexDef *pMotionIndex;
02932
02933 assert(Server);
02934 assert(Player);
02935 assert(Start && End);
02936 assert(GameMgr_GetWorld(Server->GMgr));
02937
02938 Index = SERVER_GPLAYER_TO_INDEX(Server, Player);
02939
02940 if (!Server->Client->Players[Index].ActorDef)
02941 {
02942 *Start = 0.0f;
02943 *End = 0.0f;
02944 return;
02945 }
02946
02947 pMotionIndex = GameMgr_GetMotionIndexDef(Server->GMgr, MotionIndex);
02948
02949 Motion = geActor_GetMotionByName(Server->Client->Players[Index].ActorDef, pMotionIndex->MotionName);
02950
02951 if (!Motion)
02952 GenVS_Error("Server_GetPlayerTimeExtents: Motion not found in actor: %s", pMotionIndex->MotionName);
02953
02954 if (!geMotion_GetTimeExtents(Motion, Start, End))
02955 GenVS_Error("Server_GetPlayerTimeExtents: geMotion_GetTimeExtents failed...\n");
02956 }
02957
02958 #define CLIENT_TO_SERVER_PLAYER(s, p) (s->SvPlayers + (int32)(p - s->Client->Players))
02959
02960
02961
02962
02963 static GPlayer *Server_ActorToPlayer(Server_Server *Server, geActor *Actor)
02964 {
02965
02966 GPlayer *CPlayer;
02967 GPlayer *SPlayer;
02968
02969
02970 CPlayer = (GPlayer*)geActor_GetUserData(Actor);
02971
02972 if (!CPlayer)
02973 return NULL;
02974
02975 SPlayer = CLIENT_TO_SERVER_PLAYER(Server, CPlayer);
02976
02977 return SPlayer;
02978 }
02979
02980
02981
02982
02983 static geWorld *Server_GetWorld(Server_Server *Server)
02984 {
02985 return GameMgr_GetWorld(Server->GMgr);
02986 }
02987
02988
02989
02990
02991 static void Server_ConsolePrintf(Server_Server *Server, const char *Str, ...)
02992 {
02993 va_list ArgPtr;
02994
02995 assert(Server);
02996 assert(Str);
02997
02998 va_start (ArgPtr, Str);
02999 Console_Printf(GameMgr_GetConsole(Server->GMgr), Str, ArgPtr);
03000 va_end (ArgPtr);
03001 }
03002
03003
03004
03005
03006 static void Server_ConsoleHeaderPrintf(Server_Server *Server, int32 ClientHandle, geBoolean AllClients, const char *Str, ...)
03007 {
03008 Buffer_Data Buffer;
03009 char Data[1024];
03010 Server_Client *Client;
03011 assert(ClientHandle != CLIENT_NULL_HANDLE);
03012
03013 assert(Server);
03014 assert(Str);
03015
03016
03017 Buffer_Set(&Buffer, Data, 1024);
03018
03019
03020 Buffer_FillByte(&Buffer, NETMGR_MSG_HEADER_PRINTF);
03021 Buffer_FillString(&Buffer, (char*)Str);
03022
03023 Client = &Server->Clients[ClientHandle];
03024
03025 assert(Client->Active);
03026
03027 if (AllClients)
03028 {
03029 SendAllClientsMessage(Server, &Buffer, GE_TRUE);
03030 }
03031 else if (Client->Active)
03032 {
03033 if (!NetMgr_SendClientMessage(Server->NMgr, Client->NetID, &Buffer, GE_TRUE))
03034 {
03035
03036
03037 Server_ClientDisconnect(Server, Client->NetID, Client->Name);
03038 }
03039 }
03040
03041 }
03042
03043
03044
03045
03046 static float Server_GetTime(Server_Server *Server)
03047 {
03048 assert(Server);
03049
03050 return GameMgr_GetTime(Server->GMgr);
03051 }
03052
03053
03054
03055
03056
03057 static void *Server_GetPlayerClientData(Server_Server *Server, GenVSI_CHandle ClientHandle)
03058 {
03059 assert(Server);
03060 assert(ClientHandle >=0 && ClientHandle <= 255);
03061
03062 return &Server->Clients[ClientHandle];
03063 }
03064
03065
03066
03067
03068 static void Server_Error(Server_Server *Server, const char *ErrorStr, ...)
03069 {
03070 va_list ArgPtr;
03071
03072 assert(Server);
03073 assert(ErrorStr);
03074
03075 va_start (ArgPtr, ErrorStr);
03076 GenVS_Error(ErrorStr, ArgPtr);
03077 va_end (ArgPtr);
03078 }
03079
03080
03081
03082
03083 static void Server_ProcIndex(Server_Server *Server, uint16 Index, void *Proc)
03084 {
03085 assert(Server);
03086 assert(Index >= 0 && Index < 65535);
03087 assert(Index >= 0 && Index < SERVER_MAX_PROC_INDEX);
03088
03089 Server->ProcIndex[Index] = Proc;
03090 }
03091
03092
03093
03094
03095
03096 static void Server_SetupGenVSI(Server_Server *Server)
03097 {
03098 GenVSI *VSI;
03099
03100 VSI = &Server->GenVSI;
03101
03102
03103 memset(VSI, 0, sizeof(GenVSI));
03104
03105
03106 VSI->Mode = MODE_Server;
03107
03108
03109 VSI->UData = Server;
03110
03111
03112
03113
03114 VSI->SetClassSpawn = Server_SetClassSpawn;
03115 VSI->SetWorld = Server_SetWorldRequest;
03116 VSI->ActorIndex = Server_ActorIndex;
03117 VSI->MotionIndex = Server_MotionIndex;
03118 VSI->BoneIndex = Server_BoneIndex;
03119 VSI->TextureIndex = Server_TextureIndex;
03120 VSI->SoundIndex = Server_SoundIndex;
03121
03122
03123 VSI->PlaySound = Server_PlaySound;
03124 VSI->SpawnFx = Server_SpawnFx;
03125
03126
03127 VSI->GetPlayerClientData = Server_GetPlayerClientData;
03128 VSI->SetClientScore = Server_SetClientScore;
03129 VSI->SetClientHealth = Server_SetClientHealth;
03130 VSI->SetClientWeapon = Server_SetClientWeapon;
03131 VSI->SetClientInventory = Server_SetClientInventory;
03132 VSI->GetClientMove = Server_GetClientMove;
03133 #pragma message ("Bot - Server.c")
03134 VSI->IsClientBot = Server_IsClientBot;
03135 VSI->ClientDisconnect = Server_ClientDisconnectByHandle;
03136
03137
03138 VSI->ModelToViewIndex = Server_ModelToViewIndex;
03139 VSI->RegisterPlayerModel = Server_RegisterPlayerModel;
03140 VSI->GetNextPlayer = Server_GetNextPlayer;
03141 VSI->GetNextPlayerInRadius = Server_GetNextPlayerInRadius;
03142 VSI->SetViewPlayer = Server_SetViewPlayer;
03143 VSI->MovePlayerModel = Server_MovePlayerModel;
03144 VSI->GetPlayerTimeExtents = Server_GetPlayerTimeExtents;
03145 VSI->ActorToPlayer = Server_ActorToPlayer;
03146 VSI->GetWorld = Server_GetWorld;
03147 VSI->ConsolePrintf = Server_ConsolePrintf;
03148 VSI->ConsoleHeaderPrintf = Server_ConsoleHeaderPrintf;
03149 VSI->GetTime = Server_GetTime;
03150
03151 VSI->SpawnPlayer = Server_CreatePlayer;
03152 VSI->DestroyPlayer = Server_DestroyPlayer;
03153
03154 VSI->ProcIndex = Server_ProcIndex;
03155 }