Example #1
0
bool CGameClient::IsHearingClient( int index ) const
{
	if ( IsHLTV() )
		return true;

	if ( index == GetPlayerSlot() )
		return m_bVoiceLoopback;
	
	CGameClient *pClient = sv.Client( index );
	return pClient->m_VoiceStreams.Get( GetPlayerSlot() ) != 0;
}
Example #2
0
	void ServerSession::ClientConnected(Network::Slot slot)
	{
		mClientTimeout[slot] = C_TIMEOUT;
		if (GetPlayerSlot(C_STATUS_OPEN) == C_PLAYER_NONE)
		{
			// Refuse the player, since we have too many players
			mServer->Send(slot, RefuseMessage(RefuseReason::TooManyPlayers));
			mClientsToRemove.push_back(slot);
		}
		else
		{
			// Add client as pending client
			mPendingClients.push_back(slot);
		}
	}
Example #3
0
	void ServerSession::ClientDisconnected(Network::Slot slot)
	{
		PlayerID playerSlot = GetPlayerSlot(slot);
		if (playerSlot != C_PLAYER_NONE)
		{
			// TODO: Think about boot
			// TODO: Don't think about boot

			// TODO: Think about timeout?
			// TODO: Should we think about timeout?
			// TODO: Don't think about timeout.

			// TODO: Forget about boot.
			// TODO: Forget about timeout (keep it in mind, though)

			// REDO: Think about timeout.
			// TODO: Ponder meaning of life.

			// TODO: Give up.

			Network::RemovePlayerReason::RemovePlayerReason reason = Network::RemovePlayerReason::Left;
			for (unsigned int i = 0; i < mPlayers.size(); ++i)
			{
				if (mPlayers[i] != NULL && mPlayerClients[i] >= 0 && mServer->IsConnected(mPlayerClients[i]))
				{
					mServer->Send(mPlayerClients[i], Network::RemovePlayerMessage(playerSlot, reason));
				}
			}

			if (mSessionNotifiee != NULL)
				mSessionNotifiee->PlayerDisconnected(playerSlot, mPlayers[playerSlot]->GetName(), reason);

			SafeDelete(mPlayers[playerSlot]);	// Delete player? More proper to make it into an open slot?
			mPlayerClients[playerSlot] = C_STATUS_OPEN;
		}
		else
		{
			std::vector<ClientSlot>::iterator it;

			it = std::find(mPendingClients.begin(), mPendingClients.end(), slot);
			if (it != mPendingClients.end())
				mPendingClients.erase(it);

			it = std::find(mClientsToRemove.begin(), mClientsToRemove.end(), slot);
			if (it != mClientsToRemove.end())
				mClientsToRemove.erase(it);
		}
	}
Example #4
0
	void ServerSession::HandleJoinMessage(Network::Slot clientSlot, const std::string& name)
	{
		bool playerValid = true;
		RefuseReason::RefuseReason reason;

		// Find an open slot
		PlayerID openPlayerID = GetPlayerSlot(C_STATUS_OPEN);
		if (openPlayerID == C_PLAYER_NONE)
		{
			// There are no open slots
			playerValid = false;
			reason = RefuseReason::TooManyPlayers;
		}
		
		// If an open slot is found, check the player's name
		if (playerValid)
		{
			for (PlayerID i = 0; i < mPlayers.size(); ++i)
			{
				if (mPlayers[i] != NULL && mPlayers[i]->GetName() == name)
				{
					playerValid = false;
					reason = RefuseReason::InvalidName;
					break;
				}
			}
		}		

		// If the player is valid, add them to the open slot
		if (playerValid)
		{
			mServer->Send(clientSlot, AcceptMessage(mPlayers.size(), openPlayerID));
			AddPlayer(openPlayerID, clientSlot, name, 0);
		}
		else
		{
			// Refuse the player
			mClientsToRemove.push_back(clientSlot);
			mServer->Send(clientSlot, RefuseMessage(reason));
		}

		std::vector<ClientSlot>::iterator it = std::find(mPendingClients.begin(), mPendingClients.end(), clientSlot);
		if (it != mPendingClients.end())
			mPendingClients.erase(it);
	}
Example #5
0
	void ServerSession::Update(const GameTime& gameTime)
	{
		// Update the server
		mServer->Update();
		
		// Handle all messages
		Network::SlotMessage message;
		while ((message = mServer->PopMessage()).mMessage != NULL)
		{
			// Get the player this message is about
			//PlayerID slot = GetPlayerID(message.mSlot);

			// If we've received a message, update timeout (unless they're marked to be removed)
			if (std::find(mClientsToRemove.begin(), mClientsToRemove.end(), message.mSlot) == mClientsToRemove.end())
			{
				mClientTimeout[message.mSlot] = C_TIMEOUT;
			}

			// Parse the message content
			switch (message.mMessage->ID())
			{
				case Network::C_MESSAGE_CHAT:
				{
					Network::ChatMessage* m = static_cast<Network::ChatMessage*>(message.mMessage);

					HandleChatMessage(m->mSourceID, m->mTargetID, m->mRecipient, m->mMessage);
				} break;

				case Network::C_MESSAGE_JOIN:
				{
					Network::JoinMessage* m = static_cast<Network::JoinMessage*>(message.mMessage);
				
					HandleJoinMessage(message.mSlot, m->mName);
				} break;
				
				case Network::C_MESSAGE_LEAVE_GAME:
				{
					Network::LeaveGameMessage* m = static_cast<Network::LeaveGameMessage*>(message.mMessage);

					// Do we need this? Notice this on timeout instead?
				} break;

				case Network::C_MESSAGE_PLACE_PIECE:
				{
					Network::PlacePieceMessage* m = static_cast<Network::PlacePieceMessage*>(message.mMessage);

					// If the move is valid, add the marker and move to the next player
					if (mGrid.GetMarkerInCell(m->mX, m->mY) == C_PLAYER_NONE)
					{
						if (mCurrentPlayer == m->mPlayerID)
						{
							mGrid.AddMarker(Logic::Cell(m->mX, m->mY), m->mPlayerID);
							if (mSessionNotifiee != NULL)
								mSessionNotifiee->PlacePiece(m->mPlayerID, Logic::Cell(m->mX, m->mY));

							mServer->Send(Network::PlacePieceMessage(m->mPlayerID, m->mX, m->mY, -1));

							if (!CheckAndHandleWin())
							{
								mCurrentPlayer = mRuleset->GetNextPlayer(mCurrentPlayer);
							}
						}
					}
					
					mServer->Send(Network::TurnMessage(mCurrentPlayer));
				} break;

				case Network::C_MESSAGE_SET_TEAM:
				{
					Network::SetTeamMessage* m = static_cast<Network::SetTeamMessage*>(message.mMessage);

					assert(mPlayers[m->mPlayerID] != NULL);
					assert(m->mTeam >= C_TEAM_NONE);
					assert(m->mTeam < 2);

					if (GetPlayerSlot(message.mSlot) == m->mPlayerID)
					{
						mPlayers[m->mPlayerID]->SetTeam(m->mTeam);

						if (mSessionNotifiee != NULL)
							mSessionNotifiee->SetTeam(m->mPlayerID, m->mTeam);

						mServer->Send(Network::SetTeamMessage(m->mPlayerID, m->mTeam));
					}
				} break;

				case Network::C_MESSAGE_HIGHLIGHT:
				{
					Network::HighlightMessage* m = static_cast<Network::HighlightMessage*>(message.mMessage);
					PlayerID source = GetPlayerSlot(message.mSlot);

					for (PlayerID s = 0; s < mPlayers.size(); ++s)
					{
						if (mPlayers[s]->GetTeam() == mPlayers[source]->GetTeam() && s != source)
						{
							if (mPlayerClients[s] >= 0)
							{
								// Remote
								mServer->Send(Network::HighlightMessage(m->mX, m->mY, m->mType));
							}
							else
							{
								// Local
								if (mSessionNotifiee != NULL)
									mSessionNotifiee->SetHighlightedCell(Logic::Cell(m->mX, m->mY), m->mType);
							}
						}
					}
				} break;
			}

			SafeDelete(message.mMessage);
		}

		// Decrease timeout
		float dt = gameTime.GetTimeSinceLastTick().Seconds;
		for (TimeoutMap::iterator it = mClientTimeout.begin(); it != mClientTimeout.end(); it++)
		{
			it->second -= dt;
			if (it->second <= 0.0f && mServer->IsConnected(it->first))
			{
				// TODO: Enable timeout again
				mServer->DisconnectClient(it->first);
			}
		}
	}
Example #6
0
bool CGameClient::IsProximityHearingClient( int index ) const
{
	CGameClient *pClient = sv.Client( index );
	return pClient->m_VoiceProximity.Get( GetPlayerSlot() ) != 0;
}