Ejemplo n.º 1
0
void CGameGibManager::AddGibToLRU( CBaseAnimating *pEntity )
{
	int i, next;

	if ( pEntity == NULL )
		return;

	//Find stale gibs.
	for ( i = m_LRU.Head(); i < m_LRU.InvalidIndex(); i = next )
	{
		next = m_LRU.Next(i);

		if ( m_LRU[i].Get() == NULL )
		{
			m_LRU.Remove(i);
		}
	}

	// We're not tracking gibs at the moment
	if ( m_iCurrentMaxPieces <= 0 )
		return;

	while ( m_LRU.Count() >= m_iCurrentMaxPieces )
	{
		i = m_LRU.Head();

		//TODO: Make this fade out instead of pop.
		UTIL_Remove( m_LRU[i] );
		m_LRU.Remove(i);
	}
	
	m_LRU.AddToTail( pEntity );
	m_iLastFrame = gpGlobals->framecount;
}
void CFrameSnapshotManager::LevelChanged()
{
	// Clear all lists...
	Assert( m_FrameSnapshots.Count() == 0 );

	// Release the most recent snapshot...
	m_PackedEntities.RemoveAll();
	memset( m_pPackedData, 0xFF, MAX_EDICTS * sizeof(PackedEntityHandle_t) );
}
void HandleFoundryEntitySpawnRecords()
{
	if ( g_FoundryEntitySpawnRecords.Count() == 0 )
		return;

	VPROF("HandleFoundryEntitySpawnRecords");

	// Create all the entities.
	CUtlVector<CBaseEntity*> newEnts;
	
	CMapEntitySpawner spawner;
	spawner.m_bFoundryMode = true;

	FOR_EACH_LL( g_FoundryEntitySpawnRecords, i )
	{
		CFoundryEntitySpawnRecord *pRecord = g_FoundryEntitySpawnRecords[i];

		if ( pRecord->m_iEntityIndex > 0 )
		{
			gEntList.ForceEntSerialNumber( pRecord->m_iEntityIndex, pRecord->m_iSerialNumber );
			engine->ForceFlushEntity( pRecord->m_iEntityIndex );
		}

		// Figure out the class name.
		CEntityMapData entData( pRecord->m_VMFText.Base() );
		char szClassName[MAPKEY_MAXLENGTH];
		if ( !entData.ExtractValue( "classname", szClassName ) )
		{
			Assert( false );
			continue;
		}

		// Respawn it in the same slot.
		int nIndexToSpawn = pRecord->m_iEntityIndex;
		if ( nIndexToSpawn == 0 )
			nIndexToSpawn = -1;

		CBaseEntity *pNewEntity = ::CreateEntityByName( szClassName, nIndexToSpawn );
		if ( !pNewEntity )
		{
			Warning( "HandleFoundryEntitySpawnRecords - CreateEntityByName( %s, %d ) failed\n", szClassName, pRecord->m_iEntityIndex );
			continue;
		}

		const char *pBaseMapDataForThisEntity = entData.CurrentBufferPosition();
		pNewEntity->ParseMapData( &entData );

		if ( pRecord->m_debugOverlays != -1 )
			pNewEntity->m_debugOverlays = pRecord->m_debugOverlays;

		pNewEntity->m_iHammerID = pRecord->m_iHammerID;

		spawner.AddEntity( pNewEntity, pBaseMapDataForThisEntity, (entData.CurrentBufferPosition() - pBaseMapDataForThisEntity) + 2 );
	}
Ejemplo n.º 4
0
//-----------------------------------------------------------------------------
// Purpose: Gets any failed sends - returns any packet that could not be delivered
//-----------------------------------------------------------------------------
IReceiveMessage *CTrackerNET::GetFailedMessage()
{
	if (m_FailedMsgs.Count())
	{
		// pop the failed message from the front of the queue and return it
		FailedMsg_t &msg = m_FailedMsgs[m_FailedMsgs.Head()];
		IReceiveMessage *recvMsg = msg.message;
		m_FailedMsgs.Remove(m_FailedMsgs.Head());
		return recvMsg;
	}

	return NULL;
}
Ejemplo n.º 5
0
//-----------------------------------------------------------------------------
// Purpose: Checks for any waiting messages
//-----------------------------------------------------------------------------
IReceiveMessage *CTrackerNET::GetIncomingData()
{
	// check the receive list
	if (m_ReceivedMsgs.Count())
	{
		int head = m_ReceivedMsgs.Head();
		IReceiveMessage *msg = m_ReceivedMsgs[head].message;
		m_ReceivedMsgs.Remove(head);
		return msg;
	}

	return NULL;
}
Ejemplo n.º 6
0
bool CGameGibManager::AllowedToSpawnGib( void )
{
	if ( m_bAllowNewGibs )
		return true;

	// We're not tracking gibs at the moment
	if ( m_iCurrentMaxPieces < 0 )
		return true;

	if ( m_iCurrentMaxPieces == 0 )
		return false;

	if ( m_iLastFrame == gpGlobals->framecount )
	{
		if ( m_LRU.Count() >= m_iCurrentMaxPieces )
		{
			return false;
		}
	}

	return true;
}
Ejemplo n.º 7
0
//-----------------------------------------------------------------------------
// Purpose: Checks to see if we need to send any ack packets 
//			in response to reliable messages we've received
//-----------------------------------------------------------------------------
void CTrackerNET::CheckSendingAcknowledgements()
{
	float time = (float)m_pThreads->GetTime();

	// the target list is in order of ackTime's
	while (m_TargetList.Count())
	{
		int targetIndex = m_TargetList.Head();
		NetworkTarget_t &target = m_TargetList[targetIndex];

		if (!target.needAck)
			break;	// target does not need acknowledging, we're at the end of the list

		if (target.ackTime > time)
			break;	// this packet not yet ready to be acknowledged

		if (target.incomingSequence > target.incomingAcknowledged)
		{
			// send an acknowledgement
			ISendMessage *pMsg = CreateMessage(TMSG_ACK);
			pMsg->SetNetAddress(target.netAddress);
			SendMessage(pMsg, NET_UNRELIABLE);
		}

		// this target has been acknowledged, move to the end of the list
		target.needAck = false;
		m_TargetList.Unlink(targetIndex);
		m_TargetList.LinkToTail(targetIndex);

		// check to see if the highest ack target needs to be reset
		if (targetIndex == m_iHighestAckTarget)
		{
			m_iHighestAckTarget = -1;
		}
	}
}
Ejemplo n.º 8
0
bool CHLTVClientState::ProcessPacketEntities( SVC_PacketEntities *entmsg )
{
	CClientFrame *oldFrame = NULL;

#ifdef _HLTVTEST
	if ( g_RecvDecoders.Count() == 0 )
		return false;
#endif

	if ( entmsg->m_bIsDelta )
	{
		if ( GetServerTickCount() == entmsg->m_nDeltaFrom )
		{
			Host_Error( "Update self-referencing, connection dropped.\n" );
			return false;
		}

		// Otherwise, mark where we are valid to and point to the packet entities we'll be updating from.
		oldFrame = m_pHLTV->GetClientFrame( entmsg->m_nDeltaFrom );
	}

	// create new empty snapshot
	CFrameSnapshot* pSnapshot = framesnapshotmanager->CreateEmptySnapshot( GetServerTickCount(), entmsg->m_nMaxEntries );

	Assert( m_pNewClientFrame == NULL );
	
	m_pNewClientFrame = new CClientFrame( pSnapshot );

	Assert( entmsg->m_nBaseline >= 0 && entmsg->m_nBaseline < 2 );

	if ( entmsg->m_bUpdateBaseline )
	{
		// server requested to use this snapshot as baseline update
		int nUpdateBaseline = (entmsg->m_nBaseline == 0) ? 1 : 0;
		CopyEntityBaseline( entmsg->m_nBaseline, nUpdateBaseline );

		// send new baseline acknowledgement(as reliable)
		CLC_BaselineAck baseline( GetServerTickCount(), entmsg->m_nBaseline );
		m_NetChannel->SendNetMsg( baseline, true );
	}

	// copy classes and serial numbers from current frame
	if ( m_pCurrentClientFrame )
	{
		CFrameSnapshot* pLastSnapshot = m_pCurrentClientFrame->GetSnapshot();
		CFrameSnapshotEntry *pEntry = pSnapshot->m_pEntities;
		CFrameSnapshotEntry *pLastEntry = pLastSnapshot->m_pEntities;

		Assert( pLastSnapshot->m_nNumEntities <= pSnapshot->m_nNumEntities );

		for ( int i = 0; i<pLastSnapshot->m_nNumEntities; i++ )
		{
			pEntry->m_nSerialNumber = pLastEntry->m_nSerialNumber; 
			pEntry->m_pClass = pLastEntry->m_pClass;

			pEntry++;
			pLastEntry++;
		}
	}

	CEntityReadInfo u;
	u.m_pBuf = &entmsg->m_DataIn;
	u.m_pFrom = oldFrame;
	u.m_pTo = m_pNewClientFrame;
	u.m_bAsDelta = entmsg->m_bIsDelta;
	u.m_nHeaderCount = entmsg->m_nUpdatedEntries;
	u.m_nBaseline = entmsg->m_nBaseline;
	u.m_bUpdateBaselines = entmsg->m_bUpdateBaseline;

	ReadPacketEntities( u );

	// adjust reference count to be 1
	pSnapshot->ReleaseReference();

	return CBaseClientState::ProcessPacketEntities( entmsg );
}
Ejemplo n.º 9
0
	~CEffectChecker()
	{
		Assert( g_ParticleEffects.Count() == 0 );
	}
Ejemplo n.º 10
0
//-----------------------------------------------------------------------------
// Purpose: message pump
//			loops through and sends all active messages
//			note that more messages may be posted during the process
//-----------------------------------------------------------------------------
bool CVGui::DispatchMessages()
{
	int time = g_pSystem->GetTimeMillis();

	m_InDispatcher = true;
	bool doneWork = (m_MessageQueue.Count() > 12);

	bool bUsingDelayedQueue = (m_DelayedMessageQueue.Count() > 0);

	// Need two passes because we send the mouse move message after all
	// other messages are done, but the mouse move message may itself generate
	// some more messages
	int nPassCount = 0;
	while ( nPassCount < 2 )
	{
		while (m_MessageQueue.Count() > 0 || (m_SecondaryQueue.Count() > 0) || bUsingDelayedQueue)
		{
			// get the first message
			MessageItem_t *messageItem = NULL;
			int messageIndex = 0;

			// use the secondary queue until it empties. empty it after each message in the
			// primary queue. this makes primary messages completely resolve 
			bool bUsingSecondaryQueue = (m_SecondaryQueue.Count() > 0);
			if (bUsingSecondaryQueue)
			{
				doneWork = true;
				messageIndex = m_SecondaryQueue.Head();
				messageItem = &m_SecondaryQueue[messageIndex];
			}
			else if (bUsingDelayedQueue)
			{
				if (m_DelayedMessageQueue.Count() >0)
				{
					messageItem = (MessageItem_t*)&m_DelayedMessageQueue.ElementAtHead();
				}
				if (!messageItem || messageItem->_arrivalTime > time)
				{
					// no more items in the delayed message queue, move to the system queue
					bUsingDelayedQueue = false;
					continue;
				}
			}
			else
			{
				messageIndex = m_MessageQueue.Head();
				messageItem = &m_MessageQueue[messageIndex];
			}

			// message debug code 

			if ( m_bDebugMessages )
			{
				char *qname = bUsingSecondaryQueue ? "Secondary" : "Primary";

				if (strcmp(messageItem->_params->GetName(), "Tick")
					&& strcmp(messageItem->_params->GetName(), "MouseFocusTicked") 
					&& strcmp(messageItem->_params->GetName(), "KeyFocusTicked")
					&& strcmp(messageItem->_params->GetName(), "CursorMoved"))
				{
					if (!stricmp(messageItem->_params->GetName(), "command"))
					{
						g_pIVgui->DPrintf2( "%s Queue dispatching command( %s, %s -- %i )\n", qname, messageItem->_params->GetName(), messageItem->_params->GetString("command"), messageItem->_messageID );
					}
					else
					{
						g_pIVgui->DPrintf2( "%s Queue dispatching( %s -- %i )\n", qname ,messageItem->_params->GetName(), messageItem->_messageID );
					}
				}
			}

			// send it
			KeyValues *params = messageItem->_params;

			// Deal with special internal cursor movement messages
			if ( messageItem->_messageTo == 0xFFFFFFFF )
			{
				if ( !Q_stricmp( params->GetName(), "SetCursorPosInternal" ) )
				{
					int nXPos = params->GetInt( "xpos", 0 );
					int nYPos = params->GetInt( "ypos", 0 );
					g_pInput->UpdateCursorPosInternal( nXPos, nYPos );
				}
			}
			else
			{
				VPanel *vto = (VPanel *)g_pIVgui->HandleToPanel(messageItem->_messageTo);
				if (vto)
				{
					//			Msg("Sending message: %s to %s\n", params ? params->GetName() : "\"\"", vto->GetName() ? vto->GetName() : "\"\"");
					vto->SendMessage(params, g_pIVgui->HandleToPanel(messageItem->_from));
				}
			}

			// free the keyvalues memory
			// we can't reference the messageItem pointer anymore since the queue might have moved in memory
			if (params)
			{
				params->deleteThis();
			}

			// remove it from the queue
			if (bUsingSecondaryQueue)
			{
				m_SecondaryQueue.Remove(messageIndex);
			}
			else if (bUsingDelayedQueue)
			{
				m_DelayedMessageQueue.RemoveAtHead();
			}
			else
			{
				m_MessageQueue.Remove(messageIndex);
			}
		}

		++nPassCount;
		if ( nPassCount == 1 )
		{
			// Specifically post the current mouse position as a message
			g_pInput->PostCursorMessage();
		}
	}

	// Make sure the windows cursor is in the right place after processing input 
	// Needs to be done here because a message provoked by the cursor moved
	// message may move the cursor also
	g_pInput->HandleExplicitSetCursor( );

	m_InDispatcher = false;
	return doneWork;
}
Ejemplo n.º 11
0
//-----------------------------------------------------------------------------
// Purpose: Checks to see if we should resend any reliable packets
//-----------------------------------------------------------------------------
void CTrackerNET::CheckReliablePacketSending()
{
	float time = m_pThreads->GetTime();

	// reliable packets are held in the m_ReliableMessages queue in the order that they were sent
	// if a packet is resent, it is moved to the end of the queue
	// packets are also checked at this time to see if they have been acknowledged
	while (m_ReliableMessages.Count())
	{
		// get the first message
		int index = m_ReliableMessages.Head();

		// get the message
		SentMessage_t &msg = m_ReliableMessages[index];

		// check the resend time, if it's not time to resend then we have nothing more to do 
		if (msg.resendTime > time)
			break;	

		// get the network target for this message
		if (!m_TargetList.IsValidIndex(msg.networkTargetHandle) 
			|| !m_TargetList.IsInList(msg.networkTargetHandle) 
			|| m_TargetList[msg.networkTargetHandle].targetID != msg.networkTargetID)
		{
			// message's target has been removed, kill
			if (msg.message)
			{
				msg.message->deleteThis();
			}
			m_ReliableMessages.Remove(index);
			continue;
		}

		NetworkTarget_t &target = m_TargetList[msg.networkTargetHandle];

		// check to see if it's already been acknowledged
		if (msg.sequenceNumber <= target.outgoingAcknowledged)
		{
			// message has been acknowledged, kill
			if (msg.message)
			{
				msg.message->deleteThis();
			}
			m_ReliableMessages.Remove(index);

			// move onto next message
			continue;
		}

		// check to see if we should resend this packet
		msg.resendAttempt++;
		if (msg.resendAttempt < MAX_SEND_ATTEMPTS)
		{
			// only send the message if it's in the message send window
			if (msg.sequenceNumber < target.outgoingAcknowledged + MESSAGE_WINDOW)
			{
				WriteToLog("-> Resending '%d' (os:%d > %d) (%s)\n", msg.message->GetMsgID(), msg.sequenceNumber, target.outgoingAcknowledged, target.netAddress.ToStaticString());

				// send that it again
				InternalSendMessage(msg.message, &target, msg.sequenceNumber);
			}
			else
			{
				// hold back on sending the message
				WriteToLog("-> Holding back resend '%d' (os:%d > %d) (%s)\n", msg.message->GetMsgID(), msg.sequenceNumber, target.outgoingAcknowledged, target.netAddress.ToStaticString());
				msg.resendAttempt--;
			}

			// set the time before retrying again
			// send times: 0.0 1.5 1.5 1.5 (1.5) = 6.0 second timeout, 4 packets sent
			msg.resendTime = time + RESEND_TIME;

			// move it to the end of the list
			m_ReliableMessages.Unlink(index);
			m_ReliableMessages.LinkToTail(index);

			// next packet
			continue;
		}

		// target has failed to respond, remove the target and respond with a failed message
		WriteToLog("Could not deliver packet: %d (os:%d)\n", msg.message->GetMsgID(), msg.sequenceNumber);

		// send back a send failure message to the app
		// convert the send message into a receive message
		CSendMessage *sendMsg = dynamic_cast<CSendMessage *>(msg.message);
		if (sendMsg)
		{
			IBinaryBuffer *buf = sendMsg->GetBuffer();
			
			buf->SetPosition(buf->GetBufferData());
			buf->Advance(buf->GetReservedSize());
			CReceiveMessage *failMsg = new CReceiveMessage(buf, true);

			if (failMsg->IsValid())
			{
				failMsg->SetFailed();
				failMsg->SetNetAddress(target.netAddress);
				failMsg->SetSessionID(sendMsg->SessionID());

				int newIndex = m_FailedMsgs.AddToTail();
				FailedMsg_t &fmsg = m_FailedMsgs[newIndex];
				fmsg.message = failMsg;
			}
			else
			{
				delete failMsg;
			}
		}

		// target not responding, so cancel the connection
		// remove from target map
		int mapindex = FindTargetIndexByAddress(target.netAddress);
		assert(m_TargetMap.IsValidIndex(mapindex));
		m_TargetMap.RemoveAt(mapindex);

		// remove target from list
		m_TargetList.Remove(msg.networkTargetHandle);
		
		// message will automatically be delete since it's target is gone
	}
}