bool ScmdServer_Impl::HandleListClients( HCLIENT hClient, ILTMessage_Read& msg ) { float fPing = 0.0f; uint16 nClientID = 0; uint8 aClientIP[4]; uint16 nPort; std::string sPlayerHandle = ""; // Write out the message header. CAutoMessage cMsg; cMsg.Writeuint8( MID_SCMD ); cMsg.Writeuint8( kScmdCommandListClients ); cMsg.Writeuint8( kScmdCommandStatusOk ); // Iterate over all the clients and put their id, ping, ip and name in the message. HCLIENT hIterClient = g_pLTServer->GetNextClient( NULL ); while( hIterClient ) { nClientID = ( uint16 )g_pLTServer->GetClientID( hIterClient ); g_pLTServer->GetClientPing( hIterClient, fPing ); g_pLTServer->GetClientAddr( hIterClient, aClientIP, &nPort ); cMsg.Writeuint16(( uint16 )nClientID ); cMsg.Writeuint16(( uint16 )( fPing + 0.5f )); cMsg.Writeuint8( aClientIP[0] ); cMsg.Writeuint8( aClientIP[1] ); cMsg.Writeuint8( aClientIP[2] ); cMsg.Writeuint8( aClientIP[3] ); // Get the player for this client. If there is none, // then we can't determine the name. CPlayerObj* pPlayerObj = ( CPlayerObj* )g_pLTServer->GetClientUserData( hIterClient ); if( !pPlayerObj ) { sPlayerHandle = ""; } else { sPlayerHandle = pPlayerObj->GetNetUniqueName( ); } cMsg.WriteString( sPlayerHandle.c_str( )); hIterClient = g_pLTServer->GetNextClient( hIterClient ); } // Write out the the list terminator. cMsg.Writeuint16(0xFFFF); SendMessage( hClient, *cMsg ); return true; }
bool ScmdServer_Impl::HandleListBans( HCLIENT hClient, ILTMessage_Read& msg ) { CAutoMessage cMsg; cMsg.Writeuint8( MID_SCMD ); cMsg.Writeuint8( kScmdCommandListBans ); cMsg.Writeuint8( kScmdCommandStatusOk ); char szBannedIP[16] = ""; // Tell client about all the bans. BanIPMgr::BanList const& banList = BanIPMgr::Instance( ).GetBanList( ); cMsg.Writeuint16( banList.size( )); for( BanIPMgr::BanList::const_iterator iter = banList.begin( ); iter != banList.end( ); iter++ ) { BanIPMgr::ClientIP const& clientIP = *iter; BanIPMgr::Instance( ).ConvertClientIPToString( clientIP, szBannedIP, ARRAY_LEN( szBannedIP )); cMsg.WriteString( szBannedIP ); } SendMessage( hClient, *cMsg ); return true; }
void CreateClientWeaponFX(CLIENTWEAPONFX & theStruct) { if (!g_pLTServer) return; // make sure the impact FX in valid ASSERT( ( 0 <= theStruct.eImpactType ) || ( IMPACT_TYPE_COUNT > theStruct.eImpactType ) ); // If this is a moveable object, set the flags of fx to ignore // marks and smoke... if (IsMoveable(theStruct.hObj)) { theStruct.wIgnoreFX |= WFX_MARK; // Create a server-side mark if applicable... if (CanMarkObject(theStruct.hObj)) { AMMO const *pAmmo = g_pWeaponMgr->GetAmmo(theStruct.nAmmoId); if (pAmmo) { if (pAmmo->pImpactFX) { if (WFX_MARK & pAmmo->pImpactFX->nFlags) { CreateServerMark((CLIENTWEAPONFX)theStruct); } } // Create an exit mark if applicable... if (pAmmo->pFireFX) { if (WFX_EXITMARK & pAmmo->pFireFX->nFlags) { CreateServerExitMark((const CLIENTWEAPONFX)theStruct); } } } } } // Do impact dings if applicable... if (!(IsMultiplayerGame() && IsCharacter(theStruct.hObj))) { theStruct.wIgnoreFX |= WFX_IMPACTDING; } // [KLS 2/28/02] - If the object hit is a character, re-evaluate the surface type. // We do this here because the process of applying damage to the character may have // changed the character's surface type (e.g., from Armor to Flesh). if (IsCharacter(theStruct.hObj)) { theStruct.nSurfaceType = GetSurfaceType(theStruct.hObj); } // Tell all the clients who can see this fx about the fx... CAutoMessage cMsg; cMsg.Writeuint8(SFX_WEAPON_ID); cMsg.WriteObject(theStruct.hObj); cMsg.WriteObject(theStruct.hFiredFrom); cMsg.Writeuint8(theStruct.nWeaponId); cMsg.Writeuint8(theStruct.nAmmoId); cMsg.Writeuint8(theStruct.nSurfaceType); cMsg.Writeuint16(theStruct.wIgnoreFX); cMsg.Writeuint8(theStruct.nShooterId); cMsg.WriteLTVector(theStruct.vFirePos); cMsg.WriteLTVector(theStruct.vPos); cMsg.WriteLTVector(theStruct.vSurfaceNormal); cMsg.Writeuint8(theStruct.eImpactType); g_pLTServer->SendSFXMessage(cMsg.Read(), theStruct.vPos, 0); }
// ----------------------------------------------------------------------- // // // ROUTINE: CDebugLineFX::Update // // PURPOSE: Checks for new lines, clients, or a clear line and sends // the data down to any clients. // // ----------------------------------------------------------------------- // void DebugLineSystem::Update() { if( !m_hObject ) return; if( nextLineToSend != lines.end() || m_bClearOldLines ) { // Set up the message. CAutoMessage cMsg; cMsg.Writeuint8( MID_SFX_MESSAGE ); // Record the ID and server object, used to route the message. cMsg.Writeuint8( SFX_DEBUGLINE_ID ); cMsg.WriteObject( m_hObject ); // Record the number of entries. const int num_lines_left = (lines.end() - nextLineToSend); if( num_lines_left < s_MaxLinesPerMessage ) { cMsg.Writeuint16( num_lines_left ); } else { cMsg.Writeuint16( s_MaxLinesPerMessage ); } // Record the maximum number of lines. cMsg.Writeuint32( m_nMaxLines ); // Tell whether we want to clear old lines or not, cMsg.Writeuint8( m_bClearOldLines ); // Record each entry. int num_lines_sent = 0; LTVector system_center(0,0,0); LTFLOAT system_center_count = 0; while( nextLineToSend != lines.end() && num_lines_sent < s_MaxLinesPerMessage) { cMsg.WriteType( *nextLineToSend ); ++nextLineToSend; ++num_lines_sent; } #ifdef LINESYSTEM_DEBUG g_pLTServer->CPrint("Sent %d lines. %d lines left to send.", num_lines_sent, lines.end() - nextLineToSend ); #endif cMsg.WriteString( m_DebugString.c_str() ); // Send the message! g_pLTServer->SendToClient(cMsg.Read(), LTNULL, MESSAGE_GUARANTEED); // If we have cleared out our lines and have no more to send, // why should we exist? if( m_bClearOldLines && lines.empty() ) { char szObjectName[256]; g_pLTServer->GetObjectName(m_hObject, szObjectName, 256); LineSystem::SystemMap::iterator iter = LineSystem::g_systems.find( std::string(szObjectName) ); if( iter != LineSystem::g_systems.end() ) { LineSystem::g_systems.erase(iter); } g_pLTServer->RemoveObject(m_hObject); } // Reset m_bClearOldLines so that we don't re-enter this block. m_bClearOldLines = false; } }
void CTO2GameServerShell::Update(LTFLOAT timeElapsed) { // Update the main server first CGameServerShell::Update(timeElapsed); m_VersionMgr.Update(); if (!GetServerDir()) return; //if we're hosting LANOnly game, don't publish the server if( m_ServerGameOptions.m_bLANOnly ) return; // Are we still waiting? static std::string status; switch (GetServerDir()->GetCurStatus()) { case IServerDirectory::eStatus_Processing : status =""; break; case IServerDirectory::eStatus_Waiting : if (status.empty()) status = GetServerDir()->GetLastRequestResultString(); break; case IServerDirectory::eStatus_Error : { IServerDirectory::ERequest eErrorRequest = GetServerDir()->GetLastErrorRequest(); status = GetServerDir()->GetLastRequestResultString(); GetServerDir()->ProcessRequestList(); } break; }; // Publish the server if we've waited long enough since the last directory update uint32 nCurTime = (uint32)GetTickCount(); if ((m_nLastPublishTime == 0) || ((nCurTime - m_nLastPublishTime) > k_nRepublishDelay)) { status = ""; m_nLastPublishTime = nCurTime; uint32 nMax = 0; g_pLTServer->GetMaxConnections(nMax); // If not run by a dedicated server, we need to add one connection // for the local host. if( !m_ServerGameOptions.m_bDedicated ) nMax++; GetServerDir()->SetActivePeer(0); CAutoMessage cMsg; // Update the summary info cMsg.WriteString(GetHostName()); GetServerDir()->SetActivePeerInfo(IServerDirectory::ePeerInfo_Name, *cMsg.Read()); char fname[_MAX_FNAME] = ""; _splitpath( GetCurLevel(), NULL, NULL, fname, NULL ); // Update the summary info cMsg.WriteString(g_pVersionMgr->GetBuild()); cMsg.WriteString( fname ); cMsg.Writeuint8(GetNumPlayers()); cMsg.Writeuint8(nMax); cMsg.Writebool(m_ServerGameOptions.m_bUsePassword); cMsg.Writeuint8((uint8)GetGameType()); cMsg.WriteString( m_ServerGameOptions.m_sModName.c_str() ); GetServerDir()->SetActivePeerInfo(IServerDirectory::ePeerInfo_Summary, *cMsg.Read()); // Update the details ServerMissionSettings sms = g_pServerMissionMgr->GetServerSettings(); cMsg.Writebool(sms.m_bUseSkills); cMsg.Writebool(sms.m_bFriendlyFire); cMsg.Writeuint8(sms.m_nMPDifficulty); cMsg.Writefloat(sms.m_fPlayerDiffFactor); CPlayerObj* pPlayer = GetFirstNetPlayer(); while (pPlayer) { //has player info cMsg.Writebool(true); cMsg.WriteString(pPlayer->GetNetUniqueName()); cMsg.Writeuint16( Min( GetPlayerPing(pPlayer), ( uint32 )65535 )); pPlayer = GetNextNetPlayer(); }; //end of player info cMsg.Writebool(false); cMsg.Writeuint8(sms.m_nRunSpeed); cMsg.Writeuint8(sms.m_nScoreLimit); cMsg.Writeuint8(sms.m_nTimeLimit); GetServerDir()->SetActivePeerInfo(IServerDirectory::ePeerInfo_Details, *cMsg.Read()); // Update the port char aHostAddr[16]; uint16 nHostPort; g_pLTServer->GetTcpIpAddress(aHostAddr, sizeof(aHostAddr), nHostPort); cMsg.Writeuint16(nHostPort); GetServerDir()->SetActivePeerInfo(IServerDirectory::ePeerInfo_Port, *cMsg.Read()); // Tell serverdir again about info, but in service specific manner. PeerInfo_Service_Titan peerInfo; peerInfo.m_sHostName = GetHostName( ); peerInfo.m_sCurWorld = fname; peerInfo.m_nCurNumPlayers = GetNumPlayers( ); peerInfo.m_nMaxNumPlayers = nMax; peerInfo.m_bUsePassword = m_ServerGameOptions.m_bUsePassword; peerInfo.m_sGameType = GameTypeToString( GetGameType( )); peerInfo.m_nScoreLimit = sms.m_nScoreLimit; peerInfo.m_nTimeLimit = sms.m_nTimeLimit; PeerInfo_Service_Titan::Player player; CPlayerObj::PlayerObjList::const_iterator iter = CPlayerObj::GetPlayerObjList( ).begin( ); while( iter != CPlayerObj::GetPlayerObjList( ).end( )) { CPlayerObj* pPlayerObj = *iter; player.m_sName = pPlayerObj->GetNetUniqueName( ); player.m_nScore = pPlayerObj->GetPlayerScore()->GetScore( ); float fPing; g_pLTServer->GetClientPing( pPlayerObj->GetClient( ), fPing ); player.m_nPing = ( uint16 )( fPing + 0.5f ); peerInfo.m_PlayerList.push_back( player ); iter++; } cMsg.Writeuint32(( uint32 )&peerInfo ); GetServerDir()->SetActivePeerInfo(IServerDirectory::ePeerInfo_Service, *cMsg.Read()); // Tell the world about me... GetServerDir()->QueueRequest(IServerDirectory::eRequest_Publish_Server); } }
// ----------------------------------------------------------------------- // // // ROUTINE: CDebugLineFX::Update // // PURPOSE: Checks for new lines, clients, or a clear line and sends // the data down to any clients. // // ----------------------------------------------------------------------- // void DebugLineSystem::Update() { if( !m_hObject ) return; while( ( !m_lstDebugLines.empty() ) || m_bClearOldLines ) { // Set up the message. CAutoMessage cMsg; cMsg.Writeuint8( MID_SFX_MESSAGE ); // Record the ID and server object, used to route the message. cMsg.Writeuint8( SFX_DEBUGLINE_ID ); cMsg.WriteObject( m_hObject ); // Record the number of entries. int cLines = m_lstDebugLines.size(); if( cLines < s_MaxLinesPerMessage ) { cMsg.Writeuint16( cLines ); } else { cMsg.Writeuint16( s_MaxLinesPerMessage ); } // Tell whether we want to clear old lines or not, cMsg.Writebool( m_bClearOldLines ); cMsg.Writebool( m_bRelative ); // Record each entry. int iLine=0; DEBUG_LINE_LIST::iterator itLine; for( itLine = m_lstDebugLines.begin(); itLine != m_lstDebugLines.end(); ++itLine ) { cMsg.WriteType( *itLine ); ++iLine; if( iLine >= s_MaxLinesPerMessage ) { break; } } m_lstDebugLines.erase( m_lstDebugLines.begin(), itLine ); cMsg.WriteString( m_DebugString.c_str() ); cMsg.WriteLTVector( m_vDebugStringPos ); // Send the message! g_pLTServer->SendToClient(cMsg.Read(), NULL, MESSAGE_GUARANTEED); // If we have cleared out our lines and have no more to send, // why should we exist? if( m_bClearOldLines && ( cLines == 0 ) ) { char szObjectName[256]; g_pLTServer->GetObjectName(m_hObject, szObjectName, LTARRAYSIZE(szObjectName)); LineSystem::SystemMap::iterator iter = LineSystem::g_systems.find( szObjectName ); if( iter != LineSystem::g_systems.end() ) { LineSystem::g_systems.erase(iter); } g_pLTServer->RemoveObject(m_hObject); } // Reset m_bClearOldLines so that we don't re-enter this block. m_bClearOldLines = false; } }