Example #1
0
bool ServerConnector::ConnectToServer()
{
	// Already connected
	if (_isConnected) 
		return true;

	Log::Debug("Connecting to server %s:%u...", _host.c_str(), _tcpPort);

	_udpSocket = new Socket(UDP, _host, _udpPort);
	_tcpSocket = new SocketTCP(_host, _tcpPort);
	if (!_tcpSocket->IsConnectionOpen()) {
		Log::Error("Unable to connect to host %s:%u", 
				_host.c_str(), _tcpPort);
		CleanUpSockets();
		return false;
	}

	// Send a PACKET_JOIN_REQUEST 
	JoinRequestPacket pkt;
	pkt.port = _udpSocket->GetListenPortUDP();
	if (!_tcpSocket->SendPacket(&pkt)) {
		Log::Error("Unable to send PACKET_JOIN_REQUEST packet to %s:%u", 
				_host.c_str(), _tcpPort);
		CleanUpSockets();
		return false;
	}

	// Wait up to 10 seconds for a resopnse.
	// The only accepted response to a PACKET_JOIN_REQUEST
	// is a PACKET_JOIN_RESPONSE. If anything else is sent from
	// the server, ignore it's contents and log a warning. 
	std::time_t start = time(0);
	while (time(0) - start < 10) {
		while (_tcpSocket->HasActivity()) {
			Packet *pkt = _tcpSocket->GetPacket();
			if (pkt->GetPacketType() == PACKET_JOIN_RESPONSE) {
				JoinResponsePacket *respkt = (JoinResponsePacket*)pkt;
				
				if (!respkt->response) {
					Log::Error("Unable to connect to server: server rejected");
					CleanUpSockets();
					delete respkt;
					return false;
				} else {
					delete pkt;
					_playerID = respkt->playerID;
					_team = (Team)respkt->team;
					_isConnected = true;

					Log::Debug("Connected to server %s:%u",
							_host.c_str(), _tcpPort);
					Log::Verbose("PlayerID: %i", _playerID);
					Log::Verbose("Team: %s", (_team == TEAM_SPY ? "Spy" : "Merc"));
					return true;
				}
			} else {
				Log::Warning("Receved unexpected packet %s (expected PACKET_JOIN_RESPONSE)", 
						PacketTypeStr(pkt->GetPacketType()).c_str());
				delete pkt;
			}
		}

		// Sleep for 10ms
		usleep(10 * 1000);	
	}
	
	Log::Error("Failed to connect to server: connection timed out");
	CleanUpSockets();
	return false;
}