00001 #include "Common/Ini.h"
00002 #include "Common/Error.h"
00003 #include "Common/Console.h"
00004 #include "Common/Command.h"
00005 #include "Common/Time.h"
00006 #include "Game/ServerWorld.h"
00007 #include "Game/ServerPlayer.h"
00008 #include "Game/ClientInfos.h"
00009 #include "Game/Entity.h"
00010 #include "Server/GameServer.h"
00011 #include "Server/Client.h"
00012
00013 #include "Game/ServerGameManager.h"
00014
00015
00016 KServerGameManager::KServerGameManager( KUDPSocket* pSocket, KList<KClient*>* pClientList, KVERSION GameVersion )
00017 : KGameManager( pSocket, GameVersion )
00018 {
00019 m_pClientList = pClientList;
00020 m_LastFrameTime = 0;
00021 m_NextObjectHandle = 1;
00022 m_NextPlayerHandle = 1;
00023 m_FrameRate = 30;
00024 m_Frame = 0;
00025 m_State = KGSS_NOTHING;
00026
00027 g_pGame->GetpCommand()->RegisterCommand( "fakeman", CommandFakeMan, "Create a fake man", this );
00028 g_pGame->GetpCommand()->RegisterCommand( "framerate", CommandFrameRate, "Set game frame rate", this );
00029 }
00030
00031
00032 KServerGameManager::~KServerGameManager()
00033 {
00034 g_pGame->GetpCommand()->UnregisterCommand( "fakeman" );
00035 g_pGame->GetpCommand()->UnregisterCommand( "framerate" );
00036 }
00037
00038
00039 bool KServerGameManager::Init()
00040 {
00041 if( !KGameManager::Init() )
00042 return false;
00043
00044 m_FrameRate = (u32)g_pGame->GetpIniFile()->ReadInt( "GAME", "FrameRate", 30 );
00045 g_Console << "Game framerate : " << m_FrameRate << KENDL;
00046
00047 return true;
00048 }
00049
00050
00051 bool KServerGameManager::End()
00052 {
00053 if( !KGameManager::End() )
00054 return false;
00055
00056 return true;
00057 }
00058
00059
00060 bool KServerGameManager::Manage()
00061 {
00062 if( !KGameManager::Manage() )
00063 return false;
00064
00065 switch( m_State )
00066 {
00067 case KGSS_PLAYING:
00068
00069 if( (g_Time.GetTime() - m_LastFrameTime) > (1000 / m_FrameRate) )
00070 {
00071
00072 NotifyFrame();
00073
00074 m_LastFrameTime = g_Time.GetTime();
00075 }
00076 break;
00077 }
00078
00079 return true;
00080 }
00081
00082
00083 bool KServerGameManager::MoveFrame()
00084 {
00085 if( !KGameManager::MoveFrame() )
00086 return false;
00087
00088 if( GetpServerWorld() )
00089 GetpServerWorld()->MoveFrame( GetLastFrameTime(), GetCurrentFrameTime() );
00090
00091 return true;
00092 }
00093
00094
00095 void KServerGameManager::OnConnect( KClient* pClient )
00096 {
00097 KClientInfos* pClientInfos = new KClientInfos();
00098
00099 pClient->SetpData( pClientInfos );
00100 }
00101
00102
00103 KServerPlayer* KServerGameManager::GetpPlayerByClient( KClient* pClient )
00104 {
00105 KServerPlayer* pPlayer;
00106
00107 for( pPlayer = GetpFirstServerPlayer(); pPlayer; pPlayer = GetpNextServerPlayer( pPlayer ) )
00108 if( pPlayer->GetpClient() == pClient )
00109 return pPlayer;
00110
00111 return NULL;
00112 }
00113
00114
00115 void KServerGameManager::OnDisconnect( KClient* pClient )
00116 {
00117 KServerPlayer* pPlayer;
00118 KClient* pNotifyClient;
00119 KNetMsg Msg;
00120
00121 DoGoodBye( pClient );
00122
00123
00124 for( pPlayer = GetpFirstServerPlayer(); pPlayer; pPlayer = GetpNextServerPlayer( pPlayer ) )
00125 {
00126 if( pPlayer->GetpClient() == pClient )
00127 {
00128
00129 Msg = CreateMsg( KGMT_DELETEPLAYER ) << pPlayer->GetHandle();
00130
00131 for( pNotifyClient = GetClientList()->GetFirst(); pNotifyClient; pNotifyClient = GetClientList()->GetNext( pNotifyClient ) )
00132 {
00133
00134 if( pClient == pNotifyClient )
00135 continue;
00136
00137 Send( pNotifyClient, Msg );
00138 }
00139
00140 if( GetpServerWorld() )
00141 {
00142
00143 K3DObject* pObject;
00144 for( pObject = GetpServerWorld()->GetpFirstObject(); pObject; pObject = GetpServerWorld()->GetpNextObject( pObject ) )
00145 {
00146 if( pObject->GethPlayer() == pPlayer->GetHandle() )
00147 {
00148 Msg = CreateMsg( KGMT_DELETEOBJECT ) << pObject->GetHandle();
00149
00150 for( pNotifyClient = GetClientList()->GetFirst(); pNotifyClient; pNotifyClient = GetClientList()->GetNext( pNotifyClient ) )
00151 {
00152
00153 if( pClient == pNotifyClient )
00154 continue;
00155
00156 Send( pNotifyClient, Msg );
00157 }
00158
00159 GetpServerWorld()->RemovepObject( pObject );
00160 delete pObject;
00161 }
00162 }
00163 }
00164
00165
00166 RemovepPlayer( pPlayer );
00167 Deletep( pPlayer );
00168 break;
00169 }
00170 }
00171
00172 KClientInfos* pClientInfos = (KClientInfos*)pClient->GetpData();
00173 if( pClientInfos )
00174 {
00175 Deletep( pClientInfos );
00176 pClient->SetpData( NULL );
00177 }
00178 }
00179
00180
00181 void KServerGameManager::OnMessage( KClient* pClient, KGAMEMSGTYPE MsgType, KNetMsg& Msg )
00182 {
00183 KServerPlayer* pPlayer = (KServerPlayer*)GetpPlayerByClient( pClient );
00184
00185 switch( MsgType )
00186 {
00187
00188
00189
00190 case KGMT_GAMEVERSION:
00191 {
00192 KVERSION ClientVersion;
00193
00194 Msg >> ClientVersion;
00195
00196 g_Console << "Client version : " << KVERSION_GETMAJOR( ClientVersion ) << "." << KVERSION_GETMINOR( ClientVersion ) << KENDL;
00197
00198 KNetMsg& Msg2 = CreateMsg( KGMT_GAMEVERSION ) << m_GameVersion ;
00199 bool bChecked;
00200
00201 if( KVERSION_GETMAJOR( ClientVersion ) < KVERSION_GETMAJOR( m_GameVersion ) )
00202 {
00203
00204 bChecked = false;
00205 }
00206 else
00207 {
00208
00209 bChecked = true;
00210 }
00211
00212 Msg2 << bChecked;
00213 Send( pClient, Msg2 );
00214
00215 if( !bChecked )
00216 {
00217
00218 pClient->GetSocket()->Disconnect();
00219 return;
00220 }
00221 }
00222 return;
00223
00224
00225
00226
00227 case KGMT_CREATEPLAYER:
00228 {
00229 KStr sName;
00230 Msg.ReadString( sName );
00231 OnCreatePlayer( pClient, sName );
00232 }
00233 return;
00234
00235 case KGMT_DELETEPLAYER:
00236 OnDeletePlayer( pClient );
00237 return;
00238
00239 case KGMT_PLAYERNAME:
00240 {
00241 KStr sName;
00242 Msg.ReadString( sName );
00243 OnChangeName( pPlayer, sName );
00244 }
00245 return;
00246
00247
00248
00249
00250 case KGMT_GETGAMEINFOS:
00251 OnGetGameInfos( pClient );
00252 return;
00253
00254
00255
00256
00257 case KGMT_SETCLIENTSTATE:
00258 OnSetClientState( pClient, Msg );
00259 return;
00260
00261 case KGMT_OBJECTPOS:
00262 {
00263 KHANDLE Handle;
00264 KVector Pos, Rot;
00265
00266 Msg >> Handle >> Pos >> Rot;
00267
00268 if( !SetPosAndNotityObject( Handle, Pos, Rot ) )
00269 KError::Warning( NULL, "KServerGameManager::OnMessage(...) : Cannot SetPosAndNotityObject" );
00270
00271 return;
00272 }
00273
00274
00275
00276
00277
00278
00279
00280 case KGMT_GETWORLD:
00281 OnGetWorld( pPlayer );
00282 return;
00283
00284
00285
00286 case KGMT_CHAT:
00287 {
00288 KStr pText;
00289 KStr pText2;
00290 KServerPlayer* pPlayer;
00291
00292 Msg.ReadString( pText );
00293
00294 pPlayer = GetpPlayerByClient( pClient );
00295 if( !pPlayer )
00296 {
00297 KError::Warning( NULL, "KServerGameManager::OnMessage(...) : This client [%] has no player", pClient->GetpName() );
00298 return;
00299 }
00300
00301 pText2 = pPlayer->GetsName();
00302 pText2 += "> ";
00303 pText2 += pText;
00304 NotifyChat( pClient, pText2.GetpString() );
00305 g_Console << (char*)pText2 << KENDL;
00306 return;
00307 }
00308 }
00309
00310 KGameManager::OnMessage( MsgType, Msg );
00311 }
00312
00313
00314 K3DObject* KServerGameManager::CreateAndNotityObject( KHANDLE hPlayer, KGAMEOBJECTTYPE Type, KVector& Pos, KVector& Rot )
00315 {
00316 K3DObject* pObject = CreateObject( Type );
00317
00318 if( !pObject )
00319 return NULL;
00320
00321 u32 Handle;
00322
00323 Handle = m_NextObjectHandle++;
00324 pObject->SetType( Type );
00325 pObject->SetHandle( Handle );
00326 pObject->SethPlayer( hPlayer );
00327 pObject->Translate( Pos.x, Pos.y, Pos.z );
00328 pObject->SetRot( Rot );
00329
00330
00331 KNetMsg Msg = CreateMsg( KGMT_CREATEOBJECT ) << Type;
00332 *pObject >> Msg;
00333
00334 KClient* pClient;
00335 for( pClient = GetClientList()->GetFirst(); pClient; pClient = GetClientList()->GetNext( pClient ) )
00336 {
00337 pClient->GetSocket()->SendMessage( Msg );
00338 }
00339
00340 return pObject;
00341 }
00342
00343
00344 bool KServerGameManager::SetPosAndNotityObject( KHANDLE Handle, KVector& Pos, KVector& Rot )
00345 {
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357 if( !SetObjectPos( Handle, Pos, Rot ) )
00358 return false;
00359
00360 return true;
00361 }
00362
00363
00364
00365
00366 bool KServerGameManager::CreateAndNotityAllObjects( KServerPlayer* pPlayer )
00367 {
00368 KASSERT( pPlayer );
00369
00370 K3DObject* pObject;
00371 KNetMsg Msg;
00372
00373 for( pObject = GetpServerWorld()->GetpFirstObject(); pObject; pObject = GetpServerWorld()->GetpNextObject( pObject ) )
00374 {
00375
00376 Msg = CreateMsg( KGMT_CREATEOBJECT ) << pObject->GetType();
00377 *pObject >> Msg;
00378 Send( pPlayer->GetpClient(), Msg );
00379
00380
00381
00382 }
00383
00384 return true;
00385 }
00386
00387
00388
00389
00390 bool KServerGameManager::NotityObject( KServerPlayer* pPlayer, K3DObject* pObject )
00391 {
00392 KASSERT( pPlayer );
00393 KASSERT( pObject );
00394
00395 KNetMsg Msg;
00396
00397
00398 Msg = CreateMsg( KGMT_NOTIFYOBJECT ) << pObject->GetHandle();
00399 *pObject >> Msg;
00400 Send( pPlayer->GetpClient(), Msg );
00401
00402 return true;
00403 }
00404
00405
00406
00407
00408 bool KServerGameManager::NotityObjectAllPlayers( K3DObject* pObject )
00409 {
00410 KASSERT( pObject );
00411 KServerPlayer* pPlayer;
00412
00413
00414 for( pPlayer = GetpFirstServerPlayer(); pPlayer; pPlayer = GetpNextServerPlayer( pPlayer ) )
00415 {
00416 NotityObject( pPlayer, pObject );
00417 }
00418
00419 return true;
00420 }
00421
00422
00423 bool KServerGameManager::OnCreatePlayer( KClient* pClient, KStr& sName )
00424 {
00425 KServerPlayer* pPlayer;
00426 KNetMsg Msg;
00427
00428
00429 for( pPlayer = GetpFirstServerPlayer(); pPlayer; pPlayer = GetpNextServerPlayer( pPlayer ) )
00430 {
00431 if( pPlayer->GetpClient() == pClient )
00432 {
00433 KError::Warning( NULL, "KServerGameManager::CreatePlayer(...) : Player already created [%s:%i]", pClient->GetAddress().GetpAddress(), pClient->GetAddress().GetPort() );
00434 return false;
00435 }
00436 }
00437
00438
00439 pPlayer = (KServerPlayer*)CreatePlayer();
00440 pPlayer->SetpClient( pClient );
00441 pPlayer->SetHandle( m_NextPlayerHandle++ );
00442 pPlayer->SetsName( sName );
00443 AddpPlayer( pPlayer );
00444
00445
00446 if( !NotifyCreateAllPlayers( pClient ) )
00447 return false;
00448
00449
00450 KClient* pNotifyClient;
00451 for( pNotifyClient = GetClientList()->GetFirst(); pNotifyClient; pNotifyClient = GetClientList()->GetNext( pNotifyClient ) )
00452 {
00453 if( pNotifyClient == pClient )
00454 continue;
00455
00456 if( !NotifyCreatePlayer( pNotifyClient, pPlayer ) )
00457 return false;
00458 }
00459
00460
00461 Msg = CreateMsg( KGMT_ASSIGNPLAYER ) << pPlayer->GetHandle();
00462 Send( pClient, Msg );
00463
00464 return true;
00465 }
00466
00467
00468 bool KServerGameManager::OnDeletePlayer( KClient* pClient )
00469 {
00470 KServerPlayer* pPlayer;
00471
00472
00473 for( pPlayer = GetpFirstServerPlayer(); pPlayer; pPlayer = GetpNextServerPlayer( pPlayer ) )
00474 {
00475 if( pPlayer->GetpClient() == pClient )
00476 {
00477 RemovepPlayer( pPlayer );
00478 Deletep( pPlayer );
00479 return true;
00480 }
00481 }
00482
00483 KError::Warning( NULL, "KServerGameManager::DeletePlayer(...) : Unknown client [%s:%i]", pClient->GetAddress().GetpAddress, pClient->GetAddress().GetPort() );
00484 return false;
00485 }
00486
00487
00488 void KServerGameManager::OnChangeName( KServerPlayer* pPlayer, KStr& sName )
00489 {
00490
00491 pPlayer->SetsName( sName );
00492
00493
00494 KServerPlayer* pServerPlayer;
00495 KNetMsg Msg = CreateMsg( KGMT_PLAYERNAME ) << pPlayer->GetHandle();
00496 Msg.WriteString( sName );
00497
00498 for( pServerPlayer = GetpFirstServerPlayer(); pServerPlayer; pServerPlayer = GetpNextServerPlayer( pServerPlayer ) )
00499 {
00500
00501 Send( pServerPlayer->GetpClient(), Msg );
00502 }
00503 }
00504
00505
00506
00507
00508 bool KServerGameManager::NotifyCreatePlayer( KClient* pClient, KServerPlayer* pPlayer )
00509 {
00510 KNetMsg Msg;
00511
00512 Msg = CreateMsg( KGMT_CREATEPLAYER );
00513 *pPlayer >> Msg;
00514 if( !Send( pClient, Msg ) )
00515 return false;
00516
00517 return true;
00518 }
00519
00520
00521
00522
00523 bool KServerGameManager::NotifyCreateAllPlayers( KClient* pClient )
00524 {
00525 KServerPlayer* pPlayer;
00526 KNetMsg Msg;
00527
00528
00529 Msg = CreateMsg( KGMT_FLUSHPLAYERS );
00530 Send( pClient, Msg );
00531
00532
00533 for( pPlayer = GetpFirstServerPlayer(); pPlayer; pPlayer = GetpNextServerPlayer( pPlayer ) )
00534 {
00535 if( !NotifyCreatePlayer( pClient, pPlayer ) )
00536 return false;
00537 }
00538
00539 return true;
00540 }
00541
00542
00543
00544
00545 bool KServerGameManager::NotifyPlayer( KClient* pClient, KServerPlayer* pPlayer )
00546 {
00547 KNetMsg Msg;
00548
00549 Msg = CreateMsg( KGMT_NOTIFYPLAYER );
00550 *pPlayer >> Msg;
00551 if( !Send( pClient, Msg ) )
00552 return false;
00553
00554 return true;
00555 }
00556
00557
00558
00559
00560 bool KServerGameManager::NotifyAllPlayers( KClient* pClient )
00561 {
00562 KServerPlayer* pPlayer;
00563 KNetMsg Msg;
00564
00565
00566 for( pPlayer = GetpFirstServerPlayer(); pPlayer; pPlayer = GetpNextServerPlayer( pPlayer ) )
00567 {
00568 if( !NotifyPlayer( pClient, pPlayer ) )
00569 return false;
00570 }
00571
00572 return true;
00573 }
00574
00575
00576 bool KServerGameManager::NotifyChat( KClient* pClient, char* pText )
00577 {
00578 KNetMsg Msg = CreateMsg( KGMT_CHAT );
00579
00580
00581 KClient* pNotifyClient;
00582 for( pNotifyClient = GetClientList()->GetFirst(); pNotifyClient; pNotifyClient = GetClientList()->GetNext( pNotifyClient ) )
00583 {
00584 if( pNotifyClient == pClient )
00585 continue;
00586
00587 Msg.WriteString( KStr( pText ) );
00588 Send( pNotifyClient, Msg );
00589 }
00590
00591 return true;
00592 }
00593
00594
00595 bool KServerGameManager::SendChatText( KClient* pClient, char* pText )
00596 {
00597 char pText2[1024];
00598
00599 sprintf( pText2, "Server> %s", pText );
00600
00601 KNetMsg Msg = CreateMsg( KGMT_CHAT );
00602 Msg.WriteString( KStr( pText2 ) );
00603 Send( pClient, Msg );
00604
00605 return true;
00606 }
00607
00608
00609 bool KServerGameManager::OnGetGameInfos( KClient* pClient )
00610 {
00611 KNetMsg Msg = CreateMsg( KGMT_GAMEINFOS );
00612 *m_pGameInfos >> Msg;
00613 Send( pClient, Msg );
00614
00615 return true;
00616 }
00617
00618
00619 bool KServerGameManager::OnSetClientState( KClient* pClient, KNetMsg& Msg )
00620 {
00621 KGAMECLIENTSTATE ClientState;
00622
00623 g_Console << "[" << pClient->GetAddress().GetpAddress() << ":" << pClient->GetpName() << "] ";
00624
00625 Msg >> ClientState;
00626
00627 ((KClientInfos*)pClient->GetpData())->SetClientState( ClientState );
00628
00629 switch( ClientState )
00630 {
00631 case KGCS_NOTHING: g_Console << "KGCS_NOTHING" << KENDL; break;
00632 case KGCS_CREATEPLAYER: g_Console << "KGCS_CREATEPLAYER" << KENDL; break;
00633 case KGCS_WAITINGFORGAMEINFOS: g_Console << "KGCS_WAITINGFORGAMEINFOS" << KENDL; break;
00634 case KGCS_LOADING: g_Console << "KGCS_LOADING" << KENDL; break;
00635 case KGCS_WAITINGTOSTART:
00636 g_Console << "KGCS_WAITINGTOSTART" << KENDL;
00637 if( m_State == m_State )
00638 {
00639 KNetMsg Msg2 = CreateMsg( KGMT_START );
00640 Send( pClient, Msg2 );
00641
00642 DoWelcome( pClient );
00643 }
00644 break;
00645 case KGCS_PLAYING: g_Console << "KGCS_PLAYING" << KENDL; break;
00646 }
00647
00648 return true;
00649 }
00650
00651
00652 bool KServerGameManager::Send( KClient* pClient, KNetMsg& Msg )
00653 {
00654 return pClient->GetSocket()->SendMessage( Msg );
00655 }
00656
00657
00658 bool KServerGameManager::SendAll( KNetMsg& Msg )
00659 {
00660 KServerPlayer* pPlayer;
00661
00662
00663 for( pPlayer = GetpFirstServerPlayer(); pPlayer; pPlayer = GetpNextServerPlayer( pPlayer ) )
00664 pPlayer->GetpClient()->GetSocket()->SendMessage( Msg );
00665
00666 return true;
00667 }
00668
00669
00670 void KServerGameManager::CommandFakeMan( KStr Argument, void* pContext )
00671 {
00672 KServerGameManager* pThis = (KServerGameManager*)pContext;
00673 KGEInfoPlayerStart* pInfo = (KGEInfoPlayerStart*)pThis->GetpServerWorld()->GetRandomGameEntity( KGET_INFO_PLAYER_START );
00674 if( pInfo )
00675 {
00676
00677 g_Console << "CommandFakeMan TODO!!!!!!" << KENDL;
00678
00679 }
00680 else
00681 {
00682 g_Console << "Fake man creation failed : no spawn point found!" << KENDL;
00683 }
00684 }
00685
00686
00687 void KServerGameManager::CommandFrameRate( KStr Argument, void* pContext )
00688 {
00689 KServerGameManager* pThis = (KServerGameManager*)pContext;
00690
00691 pThis->m_FrameRate = atoi( Argument );
00692 if( pThis->m_FrameRate < 1 )
00693 pThis->m_FrameRate = 1;
00694 g_Console << "FrameRate set to : " << pThis->m_FrameRate << " fps"<< KENDL;
00695 }
00696
00697
00698 void KServerGameManager::NotifyFrame()
00699 {
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724 m_Frame ++;
00725 }
00726
00727
00728 void KServerGameManager::DoWelcome( KClient* pClient )
00729 {
00730 }
00731
00732
00733 void KServerGameManager::DoGoodBye( KClient* pClient )
00734 {
00735 }
00736
00737
00738 void KServerGameManager::OnGetWorld( KServerPlayer* pPlayer )
00739 {
00740
00741 CreateAndNotityAllObjects( pPlayer );
00742 }
00743
00744
00745 bool KServerGameManager::StartGame( KGameInfos* pGameInfos )
00746 {
00747 m_pGameInfos = pGameInfos;
00748 m_State = KGSS_LOADING;
00749
00750
00751
00752
00753 KNetMsg Msg = CreateMsg( KGMT_GAMEINFOS );
00754 *m_pGameInfos >> Msg;
00755 SendAll( Msg );
00756
00757
00758
00759
00760 KASSERT( !m_pWorld );
00761 m_pWorld = AllocWorld();
00762 if( !GetpServerWorld()->Init() )
00763 return false;
00764
00765
00766
00767
00768 if( !GetpServerWorld()->LoadMap( m_pGameInfos->GetsMapName() ) )
00769 return false;
00770
00771 m_State = KGSS_PLAYING;
00772
00773 return true;
00774 }
00775
00776
00777 bool KServerGameManager::EndGame()
00778 {
00779 m_State = KGSS_NOTHING;
00780 m_pGameInfos = NULL;
00781
00782
00783
00784
00785 if( GetpServerWorld() )
00786 {
00787 if( !GetpServerWorld()->UnloadMap() )
00788 return false;
00789
00790 GetpServerWorld()->End();
00791 }
00792
00793
00794
00795
00796 if( m_pWorld )
00797 Deletep( m_pWorld );
00798
00799
00800
00801
00802 KServerPlayer* pPlayer;
00803
00804 for( pPlayer = GetpFirstServerPlayer(); pPlayer; pPlayer = GetpNextServerPlayer( pPlayer ) )
00805 pPlayer->Flush();
00806
00807 return true;
00808 }