Esempio n. 1
0
void LightGroup::UpdateClients()
{
	// Calculate our current color
	LTVector vColor = (m_bOn) ? m_vColor : LTVector(0.0f, 0.0f, 0.0f);

	{
		// Set up the update message
		CAutoMessage cMsg;
		cMsg.Writeuint8(MID_SFX_MESSAGE);
		cMsg.Writeuint8(SFX_LIGHTGROUP_ID);
		cMsg.WriteObject(m_hObject);
		cMsg.Writeuint32(m_nID);
		cMsg.WriteLTVector(vColor);

		// Send the message to all connected clients
		g_pLTServer->SendToClient(cMsg.Read(), LTNULL, MESSAGE_GUARANTEED);
	}
	
	{
		CAutoMessage cMsg;
		cMsg.Writeuint8(SFX_LIGHTGROUP_ID);

		cMsg.Writeuint32(m_nID);
		cMsg.WriteLTVector(vColor);

		// Make sure new clients will get the message
		g_pLTServer->SetObjectSFXMessage(m_hObject, cMsg.Read());
	}

	m_bClientNeedsUpdate = false;
}
void CClientMeleeCollisionController::HandleBlocked(HOBJECT hTarget, const LTVector& vPos, const LTVector& vDir)
{
	// Get the proper weapon record...
	CClientWeapon* pClientWeapon = g_pClientWeaponMgr->GetCurrentClientWeapon();
	HWEAPON hWeapon = pClientWeapon ? pClientWeapon->GetWeaponRecord() : NULL;	//!!ARL: Use Attacker's weapon instead?  (will need to be sent from server - probably along with block info)
	HWEAPONDATA hWeaponData = g_pWeaponDB->GetWeaponData(hWeapon, !USE_AI_DATA);

	// Spawn a block effect for it...
	const char* pszBlockFX = g_pWeaponDB->GetString(hWeaponData, "BlockFX");
	CLIENTFX_CREATESTRUCT fxcs(pszBlockFX, 0, LTRigidTransform(vPos, LTRotation(vDir, LTVector(0,1,0))));
	g_pGameClientShell->GetSimulationTimeClientFXMgr().CreateClientFX(NULL, fxcs, true);

	// Let the server objects know they've blocked / been blocked.
	CAutoMessage cMsg;
	cMsg.Writeuint8(MID_OBJECT_MESSAGE);
	cMsg.WriteObject(m_hObject);
	cMsg.Writeuint32(MID_MELEEBLOCK);
	cMsg.WriteObject(hTarget);
	g_pLTClient->SendToServer(cMsg.Read(), MESSAGE_GUARANTEED);

	// Disable attacker's collision (i.e. stop attacking).
	DisableCollisions();

	// For local player attackers, send a BlockRecoil stimulus so a proper animation can be played.
	if (m_hObject == g_pPlayerMgr->GetMoveMgr()->GetObject())
	{
		CPlayerBodyMgr::Instance().HandleAnimationStimulus("CS_RecoilFromBlock");
	}
}
Esempio n. 3
0
void Door::UpdateSector( bool bSectorActive )
{
	for(uint32 nCurrSector = 0; nCurrSector < knNumSectors; nCurrSector++)
	{
		// Do nothing if we don't have a sector
		if( m_sSectorName[nCurrSector].empty() )
			return;

		// Just in case we get in here before we expect to, update the sector ID..
		if( !m_nSectorID[nCurrSector] )
		{
			if( g_pLTServer->GetSectorID( m_sSectorName[nCurrSector].c_str(), &m_nSectorID[nCurrSector] ) != LT_OK )
			{
				// If we can't find the sector, dump a warning and forget...
				char aNameBuff[256];
				g_pLTServer->GetObjectName( m_hObject, aNameBuff, LTARRAYSIZE(aNameBuff) );
				g_pLTServer->CPrint( "Invalid sector specified in door %s: %s", aNameBuff, m_sSectorName[nCurrSector].c_str() );
				m_sSectorName[nCurrSector].clear();
				return;
			}
		}

		m_bSectorsActive = bSectorActive;

		// Send the dynamic sector message to all connected clients...
		// This is temporary until we get the new networking architecture in place.
		// We can't do it with an FX object because activeworldmodels already have an FX object...
		CAutoMessage cMsg;
		cMsg.Writeuint8( MID_DYNAMIC_SECTOR );
		cMsg.Writeuint32( m_nSectorID[nCurrSector] );
		cMsg.Writebool( bSectorActive );

		g_pLTServer->SendToClient( cMsg.Read(), NULL, MESSAGE_GUARANTEED);
	}
}
Esempio n. 4
0
void DecisionObject::Show(bool bShow, bool bForceShow)
{
	if( m_bLock )
		return;

	// Send message to clients telling them about the DecisionObject...

	CAutoMessage cMsg;

	cMsg.Writeuint8(MID_DECISION);

	m_bVisible = bShow;


	if (bShow)
	{
		cMsg.Writeuint8(LTTRUE);
		cMsg.Writeuint8( (bForceShow ? LTTRUE : LTFALSE) );
		for (int i=0; i < MAX_DECISION_CHOICES; i++)
		{
			cMsg.Writeuint32(m_ChoiceData[i].nStringID);
		}
		cMsg.WriteObject(m_hObject);
		cMsg.Writefloat(m_fRadius);
	}
	else
	{
		cMsg.Writeuint8(LTFALSE);
		cMsg.WriteObject(m_hObject);
	}
	g_pLTServer->SendToClient(cMsg.Read(), LTNULL, MESSAGE_GUARANTEED);
}
Esempio n. 5
0
void CCheatMgr::SendCheatMessage( CheatCode nCheatCode, uint32 nData )
{
	// Send the Message to the server
	CAutoMessage cMsg;
	cMsg.Writeuint8(MID_PLAYER_CHEAT);
	cMsg.Writeuint8((uint8)nCheatCode);
	cMsg.Writeuint32(nData);
	g_pLTClient->SendToServer(cMsg.Read(), MESSAGE_GUARANTEED);
}
Esempio n. 6
0
void SpecialMove::WriteSFXMsg(CAutoMessage& cMsg)
{
	// Set our special effect message.
	cMsg.Writeuint8(GetSFXID());
	cMsg.Writeuint32(m_eAnimation);
	cMsg.Writefloat(m_fActivateDist);
	cMsg.Writebool(m_bOn);
	cMsg.Writebool(m_bRadial);

	// Piggyback our Activate data.
	m_ActivateTypeHandler.WriteActivateTypeMsg(cMsg);
}
Esempio n. 7
0
LTRESULT SendEmptyObjectMsg(uint32 nMsgID, HOBJECT hSource, HOBJECT hDest, uint32 nFlags)
{
	LTRESULT nResult;

	CAutoMessage cMsg;

	cMsg.Writeuint32(nMsgID);

	nResult = g_pLTServer->SendToObject(cMsg.Read(), hSource, hDest, nFlags);

	return nResult;
}
void CClientWeaponDisc::SendDefendMessage( uint8 cBlockMsgType, uint32 nAni ) const
{
    LTRESULT ltResult;
    CAutoMessage cMsg;

    cMsg.Writeuint8( MID_PROJECTILE );

    // write the projectile subtype
    cMsg.Writeuint8( cBlockMsgType );

    // write the weapon type for server validation
    cMsg.Writeuint8( m_nAmmoId );

    // write the current timestamp (in milliseconds)
    cMsg.Writeuint32(
        static_cast< int >( g_pLTClient->GetTime() * 1000.0f )
    );

    // get the swat defenese animation length
    uint32 nLength;
    ltResult =
        g_pModelLT->GetAnimLength(
            m_hObject,
            nAni,
            nLength
        );
    ASSERT( LT_OK == ltResult );

    // write the length
    cMsg.Writeuint32( nLength );

    // send the message
    ltResult =
        g_pLTClient->SendToServer(
            cMsg.Read(),
            MESSAGE_GUARANTEED
        );
    ASSERT( LT_OK == ltResult );
}
void CClientMeleeCollisionController::HandleCollision(HOBJECT hTarget, HMODELNODE hNodeHit, EPhysicsGroup eHitPhysics, const LTVector& vPos, const LTVector& vDir)
{
	// Check if the attack has been blocked via rigidbody...
	if (eHitPhysics == PhysicsUtilities::ePhysicsGroup_UserBlockMelee)
	{
		HandleBlocked(hTarget, vPos, vDir);
		return;
	}

	// Check if the attack has been blocked via forced blocking (what the AI does)...
	CCharacterFX* pTargetFX = g_pGameClientShell->GetSFXMgr()->GetCharacterFX(hTarget);
	if (pTargetFX && pTargetFX->IsBlocking())
	{
		HandleBlocked(hTarget, vPos, vDir);
		return;
	}

	// Handle normal damage...
	CAutoMessage cMsg;
	cMsg.Writeuint8(MID_OBJECT_MESSAGE);
	cMsg.WriteObject(m_hObject);
	cMsg.Writeuint32(MID_MELEEATTACK);
	cMsg.WriteObject(hTarget);
	cMsg.Writeuint32(hNodeHit);
	cMsg.WriteLTVector(vPos);
	cMsg.WriteLTVector(vDir);
	cMsg.Writeint32(g_pGameClientShell->GetServerRealTimeMS());
	g_pLTClient->SendToServer(cMsg.Read(), MESSAGE_GUARANTEED);

	//!!ARL: Maybe DisableCollisions for hTarget if they are blocking?
	// (to avoid the weirdness of taking damage but still blocking the attack)

	// For local player targets, send an AttackRecoil stimulus so a proper animation can be played.
	if (hTarget == g_pPlayerMgr->GetMoveMgr()->GetObject())
	{
		CPlayerBodyMgr::Instance().HandleAnimationStimulus("CS_RecoilFromAttack");
	}
}
Esempio n. 10
0
void SpecialFX::TurnON()
{
	if (!m_bLoop)
	{
		// We can turn on (create) non-looping fx as often as we want...
		::PlayClientFX(m_sFxName, m_hObject, m_hTargetObj, LTNULL, LTNULL, LTNULL, m_dwFxFlags);

		if (m_bOneTime)
		{
			g_pLTServer->RemoveObject(m_hObject);
		}

		if( m_bRemoveTarget )
		{
			g_pLTServer->RemoveObject( m_hTargetObj );
		}
	}
	else if (!m_bIsOn)
	{
		CAutoMessage cMsg;
		cMsg.Writeuint8( SFX_CLIENTFXGROUP );
		cMsg.WriteString( m_sFxName );
		cMsg.Writeuint32( m_dwFxFlags );

		if( m_hTargetObj )
		{
			cMsg.Writeuint8( true );
			cMsg.WriteObject( m_hTargetObj );

			LTVector vPos;
			g_pLTServer->GetObjectPos( m_hTargetObj, &vPos );

			cMsg.WriteCompPos( vPos );
		}
		else
		{
			cMsg.Writeuint8( false );
		}
	
		g_pLTServer->SetObjectSFXMessage( m_hObject, cMsg.Read() );

		// Set flags so the client knows we are on...
		g_pCommonLT->SetObjectFlags( m_hObject, OFT_Flags, FLAG_FORCECLIENTUPDATE, FLAG_FORCECLIENTUPDATE );
		g_pCommonLT->SetObjectFlags( m_hObject, OFT_User, USRFLG_SFX_ON, USRFLG_SFX_ON );
	}

	m_bIsOn = true;
}	
Esempio n. 11
0
void SetObjectClientFXMsg( HOBJECT hObj, char *sName, uint32 dwFlags )
{
// [KLS 5/19/02] This really should be depricated, the only place that is 
// currently using it is the KeyItem and that object really shouldn't be
// turning itself into a half-prop/half-special fx mutant.

	CAutoMessage cMsg;
	cMsg.Writeuint8( SFX_CLIENTFXGROUP );
	cMsg.WriteString( sName );
	cMsg.Writeuint32( dwFlags );

	// Do not use any target information...
	cMsg.Writeuint8( false );
	
	g_pLTServer->SetObjectSFXMessage( hObj, cMsg.Read() );
}
Esempio n. 12
0
LTRESULT CTO2GameServerShell::OnServerInitialized()
{
	LTRESULT nResult = CGameServerShell::OnServerInitialized();

	// Don't do anything special if we're playing single-player
	if (!IsMultiplayerGame( ))
	{
		SetServerDir(0);
		return nResult;
	}

	IServerDirectory *pServerDir = Factory_Create_IServerDirectory_Titan( false, *g_pLTServer, NULL );
	if( !pServerDir )
	{	
		ASSERT( !"ServerDir is NULL!" );
		return LT_ERROR;
	}
	SetServerDir(pServerDir);

	// Set the game's name
	pServerDir->SetGameName(g_pVersionMgr->GetNetGameName());
	// Set the version
	pServerDir->SetVersion(g_pVersionMgr->GetNetVersion());
	pServerDir->SetRegion(g_pVersionMgr->GetNetRegion());
	// Set up the network messaging header
	CAutoMessage cMsg;
	cMsg.Writeuint8(0xD); // SMSG_MESSAGE
	cMsg.Writeuint8(MID_MULTIPLAYER_SERVERDIR);
	pServerDir->SetNetHeader(*cMsg.Read());

	StartupInfo_Titan startupInfo;
	startupInfo.m_sGameSpyName = "nolf2";
	// Obfuscate the secret key a little.
	startupInfo.m_sGameSpySecretKey = "g";
	startupInfo.m_sGameSpySecretKey += "3";
	startupInfo.m_sGameSpySecretKey += "F";
	startupInfo.m_sGameSpySecretKey += "o";
	startupInfo.m_sGameSpySecretKey += "6";
	startupInfo.m_sGameSpySecretKey += "x";
	cMsg.Writeuint32(( uint32 )&startupInfo );
	pServerDir->SetStartupInfo( *cMsg.Read( ));

	return nResult;
}
Esempio n. 13
0
void ModItem::ObjectTouch(HOBJECT hObject, bool bForcePickup/*=false*/)
{
    if (!hObject) return;

    // If we hit non-player objects, just ignore them...

    if (IsPlayer(hObject))
    {
        CPlayerObj* pPlayer = (CPlayerObj*)g_pLTServer->HandleToObject(hObject);

        if (pPlayer && !pPlayer->IsDead())
        {
            SetPlayerObj(hObject);

            CAutoMessage cMsg;
            cMsg.Writeuint32(MID_ADDMOD);
            cMsg.Writeuint8((uint8)m_nModId);
            g_pLTServer->SendToObject(cMsg.Read(), m_hObject, hObject, MESSAGE_GUARANTEED);
        }
    }
}
Esempio n. 14
0
void WeaponItem::ObjectTouch(HOBJECT hObject, bool bForcePickup/*=false*/)
{
	if (!hObject) return;

	// If we hit non-player objects, just ignore them...

	if (IsPlayer(hObject))
	{
        CCharacter* pCharObj = (CCharacter*)g_pLTServer->HandleToObject(hObject);

		if (pCharObj && !pCharObj->IsDead())
		{
			CAutoMessage cMsg;
			cMsg.Writeuint32(MID_ADDWEAPON);
			cMsg.Writeuint8(m_nWeaponId);
            cMsg.Writeuint8(m_nAmmoId);
            cMsg.Writeint32(m_nAmmo);
			cMsg.Writebool(bForcePickup);
			g_pLTServer->SendToObject(cMsg.Read(), m_hObject, hObject, MESSAGE_GUARANTEED);
		}
	}
}
bool ServerPhysicsCollisionMgr::HandleRigidBodyCollision( CollisionData& collisionData )
{
	if( !PhysicsCollisionMgr::HandleRigidBodyCollision( collisionData ))
		return false;

	// Check if this event needs to get sent to the client.
	if( collisionData.bSendToClient )
	{
		CAutoMessage cMsg;
		cMsg.Writeuint8( MID_PHYSICSCOLLISION );
		// We send the rigidbody values down to the client, even though
		// they can't be dereferenced.  They will be used to
		// uniquely identify this collision event on the client.
		cMsg.Writeuint32(( uint32 )collisionData.hBodyA );
		cMsg.Writeuint32(( uint32 )collisionData.hBodyB );
		// Send the objects down if we had rigid bodies.  We
		// can't get the objects without the rigid bodies, so
		// only sending them when we have non-null rigid bodies saves bandwidth.
		if( collisionData.hBodyA != INVALID_PHYSICS_RIGID_BODY )
			cMsg.WriteObject( collisionData.hObjectA );
		if( collisionData.hBodyB != INVALID_PHYSICS_RIGID_BODY )
			cMsg.WriteObject( collisionData.hObjectB );
		// We can write out 8bits of index here because we already
		// have a 255 limit on collisionproperties, since they must fit in the userflags.
		cMsg.Writeuint8(( uint8 )g_pLTDatabase->GetRecordIndex( collisionData.hCollisionPropertyA ));
		cMsg.Writeuint8(( uint8 )g_pLTDatabase->GetRecordIndex( collisionData.hCollisionPropertyB ));
		// Super fine resolution of the impulse isn't necessary
		// since the data tables are defined with integers.
		cMsg.Writefloat(collisionData.fImpulse);
		cMsg.WriteLTVector( collisionData.vCollisionPt );
		cMsg.WriteLTVector( collisionData.vCollisionNormal );
		// We're sending unguaranteed, since it's not essential the client is informed,
		// since it's just sounds and clientfx.
		g_pLTServer->SendToClient( cMsg.Read(), NULL, 0 );
	}

	return true;
}
Esempio n. 16
0
void AmmoBox::ObjectTouch(HOBJECT hObject, bool bForcePickup/*=false*/)
{
	if (!hObject) return;

	// If we hit non-player objects, just ignore them...

	if (IsPlayer(hObject))
	{
        CCharacter* pCharObj = (CCharacter*)g_pLTServer->HandleToObject(hObject);

		if (pCharObj && !pCharObj->IsDead())
		{
			int nValidIds = 0;
			for (int i=0; i < AB_MAX_TYPES; i++)
			{
				if (m_nAmmoId[i] != WMGR_INVALID_ID && m_nAmmoCount[i] > 0)
				{
					nValidIds++;
				}
			}
			if (nValidIds)
			{
				CAutoMessage cMsg;
				cMsg.Writeuint32(MID_AMMOBOX);
				cMsg.Writeuint8(nValidIds);
				for (int i=0; i < AB_MAX_TYPES; i++)
				{
					if (m_nAmmoId[i] != WMGR_INVALID_ID && m_nAmmoCount[i] > 0)
					{
						cMsg.Writeuint8(m_nAmmoId[i]);
						cMsg.Writeint32(m_nAmmoCount[i]);
					}
				}
				g_pLTServer->SendToObject(cMsg.Read(), m_hObject, hObject, MESSAGE_GUARANTEED);
			}
		}
	}
}
Esempio n. 17
0
void ClientVoteMgr::CallVoteKick(VoteType eVoteType, uint32 nClientID)
{
	if (IsVoteInProgress())
	{
		g_pTransmission->Show("ScreenVote_VoteInProgress");
		return;
	}
	if (IsVoteDelayed())
	{
		wchar_t szMsg[256];
		szMsg[0] = '\0';
		FormatString("ScreenVote_VoteDelayed",szMsg,LTARRAYSIZE(szMsg),(uint32)m_VoteDelayTimer.GetTimeLeft());
		g_pTransmission->Show(szMsg);
		return;
	}


	CAutoMessage cMsg;
	cMsg.Writeuint8( MID_VOTE );
	cMsg.WriteBits( eVote_Start, FNumBitsExclusive<kNumVoteActions>::k_nValue );
	cMsg.WriteBits( eVoteType, FNumBitsExclusive<kNumVoteTypes>::k_nValue );
	cMsg.Writeuint32( nClientID );
	g_pLTClient->SendToServer( cMsg.Read(), MESSAGE_GUARANTEED );
}
Esempio n. 18
0
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);
	}
}
Esempio n. 19
0
uint32 Turret::ObjectMessageFn( HOBJECT hSender, ILTMessage_Read *pMsg )
{
	// Reset message to begining...
	pMsg->SeekTo( 0 );

	uint32 dwMsgId = pMsg->Readuint32( );
	switch( dwMsgId )
	{
		case MID_DAMAGE	:
		{
			uint32 dwMsgPos = pMsg->Tell( );

			// Process base first so the dead flag gets set...
			uint32 dwRet = GameBase::ObjectMessageFn( hSender, pMsg );

			if( m_Damage.IsDead( ))
			{
				OnDeath( );
			}
			else
			{
				// Determine the percentage of health left on the turret...
				// This will be used to create certain ClientFX based on damage states...
				float fHealthPercent = 0.0f;
				if( m_Damage.GetMaxHitPoints( ) > 0.0f )
				{
					fHealthPercent = m_Damage.GetHitPoints( ) / m_Damage.GetMaxHitPoints( );
				}

				HATTRIBUTE hDamageStateStruct = g_pWeaponDB->GetAttribute( m_hTurret, WDB_TURRET_DamageState );
				uint32 nNumDamageStates = g_pWeaponDB->GetNumValues( hDamageStateStruct );

				uint32 nDamageState;
				for( nDamageState = 0; nDamageState < nNumDamageStates; ++nDamageState )
				{
					// Run through the damage states and determine which ones to display...
					HATTRIBUTE hAttrib = g_pWeaponDB->GetStructAttribute( hDamageStateStruct, nDamageState, WDB_TURRET_fHealthPercent );
					float fDamageStatePercent = g_pWeaponDB->GetFloat( hAttrib );

					if( nDamageState > m_nCurDamageState &&
						fDamageStatePercent >= fHealthPercent )
					{
						m_nCurDamageState = nDamageState;
					}
				}

				// Send damage msg to operating client...
				CPlayerObj *pPlayer = dynamic_cast<CPlayerObj*>(g_pLTServer->HandleToObject( m_hOperatingObject ));
				if( pPlayer )
				{
					CAutoMessage cMsg;
					cMsg.Writeuint8( MID_SFX_MESSAGE );
					cMsg.Writeuint8( SFX_TURRET_ID );
					cMsg.WriteObject( m_hObject );
					cMsg.Writeuint8( kTurretFXMsg_Damage );
					cMsg.Writeuint32( m_nCurDamageState );
					g_pLTServer->SendToClient( cMsg.Read( ), pPlayer->GetClient( ), MESSAGE_GUARANTEED );
				}
			}

			return dwRet;
		}
		break;
	}

	return GameBase::ObjectMessageFn( hSender, pMsg );
}
Esempio n. 20
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;

	}
}
Esempio n. 21
0
void ServerVoteMgr::HandleVoteStart(HCLIENT hSender, ILTMessage_Read* pMsg)
{
	if (!hSender)
	{
		return;
	}

	if (IsVoteInProgress())
	{
		// Tell the player why their vote didn't start
		SendCancelVoteInProgress( hSender );
		return;

	}

	VoteType eVoteType = (VoteType)pMsg->ReadBits( FNumBitsExclusive<kNumVoteTypes>::k_nValue );

	//check to see if we have a real client
	uint32 nCallerID = g_pLTServer->GetClientID( hSender );
	HCLIENT hCallerClient = g_pLTServer->GetClientHandle( nCallerID );
	if( !hCallerClient )
		return;
	GameClientData* pCallerGameClientData = ServerConnectionMgr::Instance().GetGameClientData( hCallerClient );
	if( !pCallerGameClientData )
		return;

	//check to see if the client has a live player...
	if (!GameModeMgr::Instance( ).m_grbAllowDeadVoting)
	{
		CPlayerObj* pPlayerObj = ( CPlayerObj* )g_pLTServer->HandleToObject( pCallerGameClientData->GetPlayer( ));
		if( !pPlayerObj || !pPlayerObj->IsAlive( ))
		{
			return;
		}
	};
	

	

	// Make sure we start fresh.
	ClearVote( );

	switch(eVoteType)
	{
	case eVote_Kick:
	case eVote_TeamKick:
	case eVote_Ban:
		{
			uint32 nTargetID = pMsg->Readuint32();
			HCLIENT hTargetClient = g_pLTServer->GetClientHandle( nTargetID );
			if( !hTargetClient )
				return;
			GameClientData* pTargetGameClientData = ServerConnectionMgr::Instance().GetGameClientData( hTargetClient );
			if( !pTargetGameClientData )
				return;
	
			// Iterate through all the clients and see if anyone is ready to vote.
			ServerConnectionMgr::GameClientDataList& gameClientDataList = ServerConnectionMgr::Instance( ).GetGameClientDataList( );
			ServerConnectionMgr::GameClientDataList::iterator iter = gameClientDataList.begin( );
			for( ; iter != gameClientDataList.end( ); iter++ )
			{
				GameClientData* pGameClientData = *iter;
				if( !pGameClientData->GetClient( ))
					continue;

				// Skip clients that aren't ready to play yet.
				if( pGameClientData->GetClientConnectionState() != eClientConnectionState_InWorld )
					continue;

				// Client must have reached the inworld state.
				if( !pGameClientData->IsClientInWorld( ))
					continue;

				// Restrict elibible voters if it's a team kick.
				if( eVoteType == eVote_TeamKick )
				{
					if( pCallerGameClientData->GetLastTeamId() != pGameClientData->GetLastTeamId( ))
						continue;
				}

				// Add to the eligible voter list.
				m_lstEligibleVoter.push_back( pGameClientData->GetClient( ));
			}

			// Check if we have a quorum of voters.
			uint32 nQuorum = ( eVoteType == eVote_TeamKick ) ? GameModeMgr::Instance().m_ServerSettings.m_nMinPlayersForTeamVote :
				GameModeMgr::Instance().m_ServerSettings.m_nMinPlayersForVote;

			//figure out how many votes are needed to pass
			uint8	nVotesNeeded = ((m_lstEligibleVoter.size() + 2) / 2); //the "+ 2" is here to ensure a majority not just half

			//if we have less than the "minimum" number of players, the vote must pass unanimously
			if( m_lstEligibleVoter.size( ) < nQuorum )
			{
				nVotesNeeded = m_lstEligibleVoter.size( );
			}

			// Put the caller on the list of voters already cast.
			m_lstVoterCastYes.push_back( pCallerGameClientData->GetClient( ));

			float fDuration = GameModeMgr::Instance().m_ServerSettings.m_nVoteLifetime;
			m_VoteTimer.Start(fDuration);

			m_CurrentVote.m_eVoteType = eVoteType;
			m_CurrentVote.m_nVoteID = m_CurrentVote.m_nVoteID++; //increment vote ID so that each vote is more or less unique... will wrap after 256 votes
			m_CurrentVote.m_nTargetID = nTargetID;
			m_CurrentVote.m_nCallerID = nCallerID;
			m_CurrentVote.m_nNoVotes = 0;
			m_CurrentVote.m_nYesVotes = 1;
			m_CurrentVote.m_nVotesNeeded = nVotesNeeded;

			CAutoMessage cMsg;
			cMsg.Writeuint8( MID_VOTE );
			cMsg.WriteBits( eVote_Start, FNumBitsExclusive<kNumVoteActions>::k_nValue );
			cMsg.Writeuint8( m_CurrentVote.m_nVoteID );
			cMsg.WriteBits( eVoteType, FNumBitsExclusive<kNumVoteTypes>::k_nValue );
			cMsg.Writeuint32( nCallerID );
			cMsg.Writeuint32( nTargetID );
			cMsg.Writeuint8( m_CurrentVote.m_nVotesNeeded );
			cMsg.Writedouble( m_VoteTimer.GetTimeLeft( ));

			// Send the vote start info to the eligible voters.
			SendToEligibleVoters( *cMsg.Read( ));

			// Check if we've already achieved necessary votes.
			CheckVoteStatus();
		}
		break;
	case eVote_NextRound:
	case eVote_NextMap:
		{
	
			// Iterate through all the clients and see if anyone is ready to vote.
			ServerConnectionMgr::GameClientDataList& gameClientDataList = ServerConnectionMgr::Instance( ).GetGameClientDataList( );
			ServerConnectionMgr::GameClientDataList::iterator iter = gameClientDataList.begin( );
			for( ; iter != gameClientDataList.end( ); iter++ )
			{
				GameClientData* pGameClientData = *iter;
				if( !pGameClientData->GetClient( ))
					continue;

				// Skip clients that aren't ready to play yet.
				if( pGameClientData->GetClientConnectionState() != eClientConnectionState_InWorld )
					continue;

				// Client must have reached the inworld state.
				if( !pGameClientData->IsClientInWorld( ))
					continue;

				// Add to the eligible voter list.
				m_lstEligibleVoter.push_back( pGameClientData->GetClient( ));
			}

			// Check if we have a quorum of voters.
			uint32 nQuorum = GameModeMgr::Instance().m_ServerSettings.m_nMinPlayersForVote;

			//figure out how many votes are needed to pass
			uint8	nVotesNeeded = ((m_lstEligibleVoter.size() + 2) / 2); //the "+ 2" is here to ensure a majority not just half
			//if we have less than the "minimum" number of players, the vote must pass unanimously
			if( m_lstEligibleVoter.size( ) < nQuorum )
			{
				nVotesNeeded = m_lstEligibleVoter.size( );
			}

			// Put the caller on the list of voters already cast.
			m_lstVoterCastYes.push_back( pCallerGameClientData->GetClient( ));

			float fDuration = GameModeMgr::Instance().m_ServerSettings.m_nVoteLifetime;
			m_VoteTimer.Start(fDuration);

			m_CurrentVote.m_eVoteType = eVoteType;
			m_CurrentVote.m_nVoteID = m_CurrentVote.m_nVoteID++; //increment vote ID so that each vote is more or less unique... will wrap after 256 votes
			m_CurrentVote.m_nTargetID = 0;
			m_CurrentVote.m_nCallerID = nCallerID;
			m_CurrentVote.m_nNoVotes = 0;
			m_CurrentVote.m_nYesVotes = 1;
			m_CurrentVote.m_nVotesNeeded = nVotesNeeded;

			CAutoMessage cMsg;
			cMsg.Writeuint8( MID_VOTE );
			cMsg.WriteBits( eVote_Start, FNumBitsExclusive<kNumVoteActions>::k_nValue );
			cMsg.Writeuint8( m_CurrentVote.m_nVoteID );
			cMsg.WriteBits( eVoteType, FNumBitsExclusive<kNumVoteTypes>::k_nValue );
			cMsg.Writeuint32( nCallerID );
			cMsg.Writeuint32( 0 );
			cMsg.Writeuint8( m_CurrentVote.m_nVotesNeeded );
			cMsg.Writedouble( m_VoteTimer.GetTimeLeft( ));

			// Send the vote start info to the eligible voters.
			SendToEligibleVoters( *cMsg.Read( ));

			// Check if we've already achieved necessary votes.
			CheckVoteStatus();
		}
		break;
	case eVote_SelectMap:
		{
			uint32 nMapIndex = pMsg->Readuint32();
			uint32 nCallerID = g_pLTServer->GetClientID( hSender );
			HCLIENT hCallerClient = g_pLTServer->GetClientHandle( nCallerID );
			if( !hCallerClient )
				return;
			GameClientData* pCallerGameClientData = ServerConnectionMgr::Instance().GetGameClientData( hCallerClient );
			if( !pCallerGameClientData )
				return;

			// Iterate through all the clients and see if anyone is ready to vote.
			ServerConnectionMgr::GameClientDataList& gameClientDataList = ServerConnectionMgr::Instance( ).GetGameClientDataList( );
			ServerConnectionMgr::GameClientDataList::iterator iter = gameClientDataList.begin( );
			for( ; iter != gameClientDataList.end( ); iter++ )
			{
				GameClientData* pGameClientData = *iter;
				if( !pGameClientData->GetClient( ))
					continue;

				// Skip clients that aren't ready to play yet.
				if( pGameClientData->GetClientConnectionState() != eClientConnectionState_InWorld )
					continue;

				// Client must have reached the inworld state.
				if( !pGameClientData->IsClientInWorld( ))
					continue;

				// Add to the eligible voter list.
				m_lstEligibleVoter.push_back( pGameClientData->GetClient( ));
			}

			// Check if we have a quorum of voters.
			uint32 nQuorum = GameModeMgr::Instance().m_ServerSettings.m_nMinPlayersForVote;
			//figure out how many votes are needed to pass
			uint8	nVotesNeeded = ((m_lstEligibleVoter.size() + 2) / 2); //the "+ 2" is here to ensure a majority not just half

			//if we have less than the "minimum" number of players, the vote must pass unanimously
			if( m_lstEligibleVoter.size( ) < nQuorum )
			{
				nVotesNeeded = m_lstEligibleVoter.size( );
			}

			// Put the caller on the list of voters already cast.
			m_lstVoterCastYes.push_back( pCallerGameClientData->GetClient( ));

			float fDuration = GameModeMgr::Instance().m_ServerSettings.m_nVoteLifetime;
			m_VoteTimer.Start(fDuration);

			m_CurrentVote.m_eVoteType = eVoteType;
			m_CurrentVote.m_nVoteID = m_CurrentVote.m_nVoteID++; //increment vote ID so that each vote is more or less unique... will wrap after 256 votes
			m_CurrentVote.m_nTargetID = nMapIndex;
			m_CurrentVote.m_nCallerID = nCallerID;
			m_CurrentVote.m_nNoVotes = 0;
			m_CurrentVote.m_nYesVotes = 1;
			m_CurrentVote.m_nVotesNeeded = nVotesNeeded;

			CAutoMessage cMsg;
			cMsg.Writeuint8( MID_VOTE );
			cMsg.WriteBits( eVote_Start, FNumBitsExclusive<kNumVoteActions>::k_nValue );
			cMsg.Writeuint8( m_CurrentVote.m_nVoteID );
			cMsg.WriteBits( eVoteType, FNumBitsExclusive<kNumVoteTypes>::k_nValue );
			cMsg.Writeuint32( nCallerID );
			cMsg.Writeuint32( nMapIndex );
			cMsg.Writeuint8( m_CurrentVote.m_nVotesNeeded );
			cMsg.Writedouble( m_VoteTimer.GetTimeLeft( ));

			// Send the vote start info to the eligible voters.
			SendToEligibleVoters( *cMsg.Read( ));

			// Check if we've already achieved necessary votes.
			CheckVoteStatus();
		}
		break;

	}
}