Ejemplo n.º 1
0
int NetClient::receiver (void* instance){ /** CRITICA **/
	NetClient* pNetClient = (NetClient *) instance;

	UDPpacket* in_packet;
	TiXmlDocument* xmlcontainer = new TiXmlDocument();
	TiXmlElement* net_msg;
	string msg_type;
	int msg_id;
	string plyName;
	char* data = NULL;


	in_packet = SDLNet_AllocPacket(NetControl::M_PACKET_SIZE);

	while (!pNetClient->m_stopClient){
		pNetClient->m_threadReceiverReady = true;
		while(!SDLNet_UDP_Recv(pNetClient->m_sock, in_packet)){
			pNetClient->checkServerTimeout();
			
			if (pNetClient->m_stopClient)
				break;
			
			SDL_Delay(NetControl::M_RECEIVER_DELAY); //  RECEIVER_DELAY/1000 seconds
		}

		if (pNetClient->m_stopClient)
			break;
			
			pNetClient->m_lastServerMsg = SDL_GetTicks();
	
		data = new char[in_packet->len];
		memcpy (data, in_packet->data, in_packet->len);
	
		xmlcontainer->Clear();
		xmlcontainer->Parse( data );
		net_msg = xmlcontainer->RootElement();

		if ( data ) 
			delete [] data;
	
		if( m_pNetClient->handleMessage(net_msg) ) continue;
		
		msg_type = net_msg->Attribute( "TYPE" );
		net_msg->QueryIntAttribute( "ID", &msg_id );
	
		if ( net_msg->Attribute( "PLYNAME" ) )
			plyName = net_msg->Attribute( "PLYNAME" );
		else
			plyName = "unnamed";
	
		NetControl::waitForSync();
		//SDL_SemWait (NetControl::m_pSemNetAndLocalSync);
		SDL_SemWait (pNetClient->m_pSemEntityValues); /** comecando a mexer nas entidades... travar acesso **/
	
	
		if (msg_type == "ENT"){ //nessa situacao, supoe-se que o cliente ja saiba da existencia
			//da origem dessa mensagem, portanto o lugar no vetor ja existe!
			EntityFactory* pEntityFactory = EntityFactory::getInstance();
	
			pNetClient->checkOtherPlayer( msg_id , plyName);
	
			IEntity* newEntity = pEntityFactory->loadEntity( net_msg );
	
			int ent_id;
			net_msg->QueryIntAttribute( "ENTID", &ent_id );
	
			while (pNetClient->m_vOthersEntities[msg_id].size() <= ent_id){
				pNetClient->m_vOthersEntities[msg_id].push_back( NULL );
			}
	
			pNetClient->m_vOthersEntities[msg_id][ent_id] = newEntity;
		}
	
	
		if (msg_type == "RMENT"){
			EntityFactory* pEntityFactory = EntityFactory::getInstance();
			string uniqueId = net_msg->Attribute( "UNIQUEID" );
			int entId;
			net_msg->Attribute( "ENTID" , &entId );
			
			pNetClient->m_vOthersEntities[msg_id][entId] = NULL;
	
			pEntityFactory->rmEntity( pEntityFactory->getEntity( uniqueId ) );
		}
	
	
		if (msg_type == "LGNGRA"){ //arranja um lugar no vetor de outras entidades para o novo vizinho
			pNetClient->checkOtherPlayer( msg_id , plyName );
		}
	
	
		if (msg_type == "BYE"){ //aqui supoe-se que ja exista a posicao msg_id no vector
			pNetClient->rmOtherPlayer( msg_id );
		}
	
	
		if (msg_type == "TIMEOUT_BYE"){ //o servidor informou que o cliente (msg_id) desconectou-se por timeout
			pNetClient->rmOtherPlayer( msg_id );
		}
	
	
		if (msg_type == "CUS"){ //mensagem personalizada
			NetCustomMessage* cus_msg = new NetCustomMessage(net_msg);
			//adiconar *net_msg a um vector (ou outro container) para uso futuro pelo usuario
			pNetClient->m_qCustomMessageQueue.push( cus_msg );
		}
	
	
		if (msg_type == "SERVER_CLOSED"){
			pNetClient->stopEverything();
			break;
		}
			
			
		if (msg_type == "SERVER_PING"){
			pNetClient->answerPing();
		}
	
	
		SDL_SemPost (pNetClient->m_pSemEntityValues); /** terminou de mexer nas entidades... liberar acesso **/
		NetControl::postForSync();
		//SDL_SemPost (NetControl::m_pSemNetAndLocalSync);
	}
	
	SDLNet_FreePacket( in_packet );
	if ( xmlcontainer ) 
		delete ( xmlcontainer );

	return 0;
}