示例#1
0
static void* do_service(void *data)
{
  CallbackData* temp_data = data;
  temp_data->result = enet_host_service(temp_data->connection->host, temp_data->connection->event, temp_data->timeout);
  return NULL;
}
示例#2
0
文件: Server.cpp 项目: wen96/pl-man2
void
Server::Run()
{
	ENetEvent event;

	string clave = "hola";
	string foo = "";
	cout << "Servido a la escucha..." << endl;
	while (true)
	{
		foo = "";
		enet_host_service (server, & event, 10000);
	    switch (event.type)
	    {

	    //Si se ha producido un evento de conexion
	    case ENET_EVENT_TYPE_CONNECT:

	        cout << "Nuevo cliente conectado. " <<
	        event.peer->address.host << ":" <<
	        event.peer->address.port << endl;

	        break;
	    //Evento de recibo de mensajes
	    case ENET_EVENT_TYPE_RECEIVE:


	    	foo.append(reinterpret_cast<const char*>(event.packet->data));

	    	if(foo == clave)
	    	{
	    		ENetPacket *response = enet_packet_create ("pepe", strlen
	    			        	("pepe") + 1, ENET_PACKET_FLAG_RELIABLE);
	    		enet_host_broadcast (server, 0, response);
	    	}
	    	else
	    	enet_host_broadcast (server, 0, event.packet);
	        /*cout << "Se ha recibido del cliente: " << event.packet->data << endl;
	        stringstream ss;
	        ss << event.packet->data;
	        ENetPacket *response = enet_packet_create (ss.str(), strlen
	        	(event.packet->data) + 1, ENET_PACKET_FLAG_RELIABLE);
	        enet_host_broadcast (server, 0, response);

	        enet_host_broadcast (server, 0, response);
	        enet_packet_destroy (event.packet);*/
	        break;

	    case ENET_EVENT_TYPE_DISCONNECT:
	    	cout << "Se ha desconectado el cliente" << endl;
	        event.peer -> data = NULL;
	        break;
	    case ENET_EVENT_TYPE_NONE:
	    	cout << "Se ha desconectado el cliente" << endl;
	    	        break;

	    }
	}


	enet_host_destroy(server);
}
示例#3
0
bool NetPlayClient::Connect()
{
  // send connect message
  sf::Packet spac;
  spac << scm_rev_git_str;
  spac << netplay_dolphin_ver;
  spac << m_player_name;
  Send(spac);
  enet_host_flush(m_client);
  sf::Packet rpac;
  // TODO: make this not hang
  ENetEvent netEvent;
  if (enet_host_service(m_client, &netEvent, 5000) > 0 && netEvent.type == ENET_EVENT_TYPE_RECEIVE)
  {
    rpac.append(netEvent.packet->data, netEvent.packet->dataLength);
    enet_packet_destroy(netEvent.packet);
  }
  else
  {
    return false;
  }

  MessageId error;
  rpac >> error;

  // got error message
  if (error)
  {
    switch (error)
    {
    case CON_ERR_SERVER_FULL:
      PanicAlertT("The server is full!");
      break;
    case CON_ERR_VERSION_MISMATCH:
      PanicAlertT("The server and client's NetPlay versions are incompatible!");
      break;
    case CON_ERR_GAME_RUNNING:
      PanicAlertT("The server responded: the game is currently running!");
      break;
    default:
      PanicAlertT("The server sent an unknown error message!");
      break;
    }

    Disconnect();
    return false;
  }
  else
  {
    rpac >> m_pid;

    Player player;
    player.name = m_player_name;
    player.pid = m_pid;
    player.revision = netplay_dolphin_ver;

    // add self to player list
    m_players[m_pid] = player;
    m_local_player = &m_players[m_pid];

    m_dialog->Update();

    m_is_connected = true;

    return true;
  }
}
示例#4
0
int main (int argc, char ** argv){
  printf("-- enetTests started --\n");
  if (enet_initialize () != 0){
    fprintf (stderr, "An error occurred while initializing ENet.\n");
    return EXIT_FAILURE;
  }
  ENetAddress address;
  ENetHost * server;
  /* Bind the server to the default localhost.     */
  /* A specific host address can be specified by   */
  /* enet_address_set_host (& address, "x.x.x.x"); */
  address.host = ENET_HOST_ANY;
  /* Bind the server to port 1234. */
  address.port = 1234;

  server = enet_host_create (& address /* the address to bind the server host to */,
                               32      /* allow up to 32 clients and/or outgoing connections */,
                                2      /* allow up to 2 channels to be used, 0 and 1 */,
                                0      /* assume any amount of incoming bandwidth */,
                                0      /* assume any amount of outgoing bandwidth */);

  if (server == NULL){
      fprintf (stderr, "An error occurred while trying to create an ENet server host.\n");
      exit (EXIT_FAILURE);
  }

  ENetHost * client;
  client = enet_host_create (NULL /* create a client host */,
              1 /* only allow 1 outgoing connection */,
              2 /* allow up 2 channels to be used, 0 and 1 */,
              57600 / 8 /* 56K modem with 56 Kbps downstream bandwidth */,
              14400 / 8 /* 56K modem with 14 Kbps upstream bandwidth */);
  if (client == NULL)
  {
      fprintf (stderr, "An error occurred while trying to create an ENet client host.\n");
      exit (EXIT_FAILURE);
  }


  ENetAddress dstaddress;
  ENetEvent event;
  ENetPeer *peer;

  /* Connect to some.server.net:1234. */
  enet_address_set_host (& dstaddress, "localhost");
  dstaddress.port = 1234;
  /* Initiate the connection, allocating the two channels 0 and 1. */
  peer = enet_host_connect (client, & dstaddress, 2, 0);
  if (peer == NULL){
     fprintf (stderr,  "No available peers for initiating an ENet connection.\n");
     exit (EXIT_FAILURE);
  }

  waitEvents(client, 100, "client send connect");

  waitEvents(server, 100, "server wait connect");

  /* Wait up to 5 seconds for the connection attempt to succeed. */
  if (enet_host_service (client, & event, 5000) > 0 && event.type == ENET_EVENT_TYPE_CONNECT){
      printf("Connection to localhost:1234 succeeded\n");
  }else{
      /* Either the 5 seconds are up or a disconnect event was */
      /* received. Reset the peer in the event the 5 seconds   */
      /* had run out without any significant event.            */
      enet_peer_reset (peer);
      fprintf (stderr, "Connection to localhost:1234 failed\n");
      exit(EXIT_FAILURE);
  }

  /* Create a reliable packet of size 7 containing "packet\0" */
  ENetPacket * packet = enet_packet_create ("packet",
                                            strlen ("packet") + 1,
                                            ENET_PACKET_FLAG_RELIABLE);
  /* Extend the packet so and append the string "foo", so it now */
  /* contains "packetfoo\0"                                      */
  enet_packet_resize (packet, strlen ("packetfoo") + 1);
  strcpy ((char*)& packet -> data [strlen ("packet")], "foo");
  /* Send the packet to the peer over channel id 0. */
  /* One could also broadcast the packet by         */
  /* enet_host_broadcast (host, 0, packet);         */
  enet_peer_send (peer, 0, packet);
  /* One could just use enet_host_service() instead. */

  waitEvents(client, 100, "client send msg");

  waitEvents(server, 100, "server wait connect");
  waitEvents(server, 100, "server wait msg");


  enet_peer_disconnect (peer, 0);

  waitEvents(client, 100, "client send disconnect");
  waitEvents(server, 100, "server wait disconnect");

  if(waitEvents(client, 100, "client wait disconnect")!=ENET_EVENT_TYPE_DISCONNECT){
    /* We've arrived here, so the disconnect attempt didn't */
    /* succeed yet.  Force the connection down.             */
    enet_peer_reset (peer);
    fprintf(stderr, "received event is not disconnect, will reset the peer\n");
    exit(EXIT_FAILURE);
  }

  enet_host_destroy(client);
  enet_host_destroy(server);
  enet_deinitialize();
  printf("-- enetTests Finished --\n");
  return EXIT_SUCCESS;
}
示例#5
0
/** \brief Thread function checking if data is received.
 *  This function tries to get data from network low-level functions as
 *  often as possible. When something is received, it generates an
 *  event and passes it to the Network Manager.
 *  \param self : used to pass the ENet host to the function.
 */
void* STKHost::mainLoop(void* self)
{
    VS::setThreadName("STKHost");
    ENetEvent event;
    STKHost* myself = (STKHost*)(self);
    ENetHost* host = myself->m_network->getENetHost();

    if(NetworkConfig::get()->isServer() && 
        NetworkConfig::get()->isLAN()      )
    {
        TransportAddress address(0, 2757);
        ENetAddress eaddr = address.toEnetAddress();
        myself->m_lan_network = new Network(1, 1, 0, 0, &eaddr);
    }

    while (!myself->mustStopListening())
    {
        if(myself->m_lan_network)
        {
            myself->handleLANRequests();
        }   // if discovery host

        while (enet_host_service(host, &event, 20) != 0)
        {
            if (event.type == ENET_EVENT_TYPE_NONE)
                continue;

            // Create an STKEvent with the event data. This will also
            // create the peer if it doesn't exist already
            Event* stk_event = new Event(&event);
            if (stk_event->getType() == EVENT_TYPE_MESSAGE)
                Network::logPacket(stk_event->data(), true);

            Log::verbose("STKHost", "Event of type %d received",
                         (int)(stk_event->getType()));
            STKPeer* peer = stk_event->getPeer();
            if (stk_event->getType() == EVENT_TYPE_CONNECTED)
            {
                Log::info("STKHost", "A client has just connected. There are "
                          "now %lu peers.", myself->m_peers.size());
                Log::debug("STKHost", "Addresses are : %lx, %lx",
                           stk_event->getPeer(), peer);
            }   // EVENT_TYPE_CONNECTED
            else if (stk_event->getType() == EVENT_TYPE_MESSAGE)
            {
                TransportAddress stk_addr(peer->getAddress());
                Log::verbose("NetworkManager",
                             "Message, Sender : %s, message = \"%s\"",
                             stk_addr.toString(/*show port*/false).c_str(),
                             stk_event->data().std_string().c_str());

            }   // if message event

            // notify for the event now.
            ProtocolManager::getInstance()->propagateEvent(stk_event);
            
        }   // while enet_host_service
    }   // while !mustStopListening

    free(myself->m_listening_thread);
    myself->m_listening_thread = NULL;
    Log::info("STKHost", "Listening has been stopped");
    return NULL;
}   // mainLoop
示例#6
0
int main(int argc, char *argv[])
{
	ENetAddress address;
	ENetHost *server;
	ENetEvent event;
	int serviceResult;

	puts("Starting server");

	if (enet_initialize() != 0)
	{
		puts("Error initialising enet");
		exit(EXIT_FAILURE);
	}


	/* Bind the server to the default localhost.     */
	/* A specific host address can be specified by   */
	/* enet_address_set_host (& address, "x.x.x.x"); */
	address.host = ENET_HOST_ANY;
	/* Bind the server to port 1234. */
	address.port = 1234;

	server = enet_host_create(&address,
		32,   /* number of clients */
		2,    /* number of channels */
		0,    /* Any incoming bandwith */
		0);   /* Any outgoing bandwith */

	if (server == NULL)
	{
		puts("Could not create server host");
		exit(EXIT_FAILURE);
	}


	while (true)
	{
		serviceResult = 1;

		/* Keep doing host_service until no events are left */
		while (serviceResult > 0)
		{
			/* Wait up to 1000 milliseconds for an event. */
			serviceResult = enet_host_service(server, &event, 1000);

			if (serviceResult > 0)
			{

				switch (event.type)
				{
				case ENET_EVENT_TYPE_CONNECT:
					printf("A new client connected from %x:%u.\n",
						event.peer->address.host,
						event.peer->address.port);

					/* Store any relevant client information here. */
					event.peer->data = (void*)"Client information";

					break;

				case ENET_EVENT_TYPE_RECEIVE:
					printf("A packet of length %u containing '%s' was "
						"received from %s on channel %u.\n",
						event.packet->dataLength,
						event.packet->data,
						event.peer->data,
						event.channelID);

					/* Tell all clients about this message */
					enet_host_broadcast(server, 0, event.packet);

					break;

				case ENET_EVENT_TYPE_DISCONNECT:
					printf("%s disconnected.\n", event.peer->data);

					/* Reset the peer's client information. */

					event.peer->data = NULL;

					break;
				}
			}
			else if (serviceResult > 0)
			{
				puts("Error with servicing the server");
				exit(EXIT_FAILURE);
			}
		}

	}

	enet_host_destroy(server);
	enet_deinitialize();

	return 0;

}
示例#7
0
文件: URClient.cpp 项目: uberpixel/Ur
	void Client::Step()
	{
		ENetEvent event;
		
		while(enet_host_service(_host, &event, 1) > 0)
		{
			switch(event.type)
			{
				case ENET_EVENT_TYPE_RECEIVE:
				{
					Packet packet(event.packet->data, event.packet->dataLength);
					enet_packet_destroy(event.packet);
					
					switch(packet.GetType())
					{
						case Packet::Type::Handshake:
							_clientID = packet.ReadUInt32();
							
							RNDebug("Received handshake. I'm client %d", _clientID);
							break;
							
						case Packet::Type::ClientConnected:
						{
							uint32 client = packet.ReadUInt32();
							
							if(client != _clientID)
							{
								RNDebug("Another client, %d, connected", client);
								World::GetSharedInstance()->GetEnemyWithID(client);
							}
							
							break;
						}
						case Packet::Type::ClientDisconnected:
						{
							uint32 client = packet.ReadUInt32();
							
							if(client != _clientID)
							{
								RNDebug("Client %d disconnected", client);
								World::GetSharedInstance()->RemoveEnemy(client);
							}
							
							break;
						}
							
							
						case Packet::Type::PositionUpdate:
						{
							uint32 client = packet.ReadUInt32();
							
							if(client != _clientID)
							{
								Enemy *enemy = World::GetSharedInstance()->GetEnemyWithID(client);
								enemy->UpdateFromPacket(packet);
							}
							
							break;
						}
							
						case Packet::Type::ShotsFired:
						{
							uint32 client = packet.ReadUInt32();
							
							if(client != _clientID)
							{
								Missile *missile = new Missile(client, packet);
								missile->Release();
							}
							
							break;
						}
							
						case Packet::Type::GoodHit:
						{
							uint32 client = packet.ReadUInt32();
							uint32 shooter = packet.ReadUInt32();
							RN::Vector3 position(packet.ReadFloat(), packet.ReadFloat(), packet.ReadFloat());
							
							if(client == _clientID)
								SpaceShip::GetLocalShip()->TakeHit(position, shooter);
							
							Explosion *explosion = new Explosion();
							explosion->SetPosition(position);
							explosion->Autorelease();
							
							break;
						}
							
						case Packet::Type::GoodKill:
						{
							uint32 client = packet.ReadUInt32();
							uint32 killer = packet.ReadUInt32();
							
							RNDebug("Good kill on %d by %d", client, killer);
							
							if(killer == _clientID)
								World::GetSharedInstance()->TallyKill();
							
							RN::Vector3 position(packet.ReadFloat(), packet.ReadFloat(), packet.ReadFloat());
							
							Explosion *explosion = new Explosion();
							explosion->SetPosition(position);
							explosion->Autorelease();
							
						}
					
						default:
							break;
					}
					
					break;
				}
					
				case ENET_EVENT_TYPE_DISCONNECT:
					break;
					
				default:
					break;
			}
		}
	}
示例#8
0
void RemoteRulesManager::update(const double& timeStep)
{	
	ENetEvent event;

	while(enet_host_service(m_client, &event, 0) > 0)
	{
		switch (event.type)
		{
		case ENET_EVENT_TYPE_CONNECT:
			{
				sendMessage(MessagePtr(new Hello("Client")), ENET_PACKET_FLAG_RELIABLE);
			}
			break;

		case ENET_EVENT_TYPE_RECEIVE:
			updateMessages(event.packet->data, event.packet->dataLength);

			for(auto msg : m_messageQueue)
			{
				switch(msg->getType())
				{
				case S_WELCOME:
					std::cout<<"GOT WELCOME "<<msg->getData()<<std::endl;
					m_isWaiting = false;
					break;
				case G_UPDATE_POS:
					m_pongScene->updateOpponentPos(((UpdatePos*)msg.get())->getPosition());
					break;
				case G_BALLSTATE:
					{
						BallState* ballState = (BallState*)msg.get();
						m_pongScene->updateBallState(
							ballState->getPosition(), 
							ballState->getVelocity(), 
							ballState->getAngularVelocity(), 
							ballState->getServe(),
							ballState->getHitMagnitude());
					}
					break;
				case G_META:
					{
						MetaGameInfo* meta = (MetaGameInfo*)msg.get();
						switch(meta->getEventType())
						{
						case MetaGameInfo::META_ROUND_START:
							m_pongScene->onNewRound(
								meta->getLocalScore(),
								meta->getRemoteScore(),
								meta->getServe(),
								meta->getWinner());
							break;
						case MetaGameInfo::META_GAME_OVER:
							m_pongScene->onGameOver(
								meta->getLocalScore(),
								meta->getRemoteScore(),
								meta->getWinner());
							break;
						}
					}
					break;
				}
			}
			m_messageQueue.clear();

			//std::cout<<"Got data: "<< event.packet->dataLength << std::endl;
			break;

		case ENET_EVENT_TYPE_DISCONNECT:
			std::cout<<"Client disconnected: "<< event.peer->address.host << " : " << event.peer->address.port<<std::endl;
			break;
		}
	}
}
示例#9
0
void 
shmup_game_update(shmup_game *g, double t, double dt)
{
	static int tick = 0;
	static int mx, my;
	int i;
	ENetEvent event;
	ENetPacket *packet;
	bullet *b;
	
	tick++;
	
	while (enet_host_service(g->host, &event, 0) > 0) {
		switch (event.type) {
			case ENET_EVENT_TYPE_CONNECT:
				printf("A new client connected from %x:%u.\n", 
					event.peer->address.host,
					event.peer->address.port);
				
//				sprintf(event.peer->data, "client %x.", event.peer->address.host);				
				g->player[g->num_players].pos = v2(g->window_width/2, g->window_height/2);
				g->player[g->num_players].vel = v2zero;
				g->player[g->num_players].acc = v2zero;
				g->num_players++;
				break;
			case ENET_EVENT_TYPE_RECEIVE:
				g->player[1].keyflags = (short) *event.packet->data;
//				event.packet->dataLength,
//				event.packet->data,
//				event.peer->data,
//				event.channelID);
				enet_packet_destroy(event.packet);
				break;				
			case ENET_EVENT_TYPE_DISCONNECT:
				printf("%s disconected.\n", event.peer->data);
				/* Reset the peer's client information. */				
				event.peer->data = NULL;
				break;
			case ENET_EVENT_TYPE_NONE:
				break;
		}
	}

	glfwGetMousePos(&mx, &my);
	g->emitter.x = (double) mx;
	g->emitter.y = (double) g->window_height-my;
	
	if (glfwGetMouseButton(GLFW_MOUSE_BUTTON_LEFT))
		shmup_game_fire(g, 40, 0, v2zero, v2zero, v2zero);
	
	if (glfwGetMouseButton(GLFW_MOUSE_BUTTON_RIGHT))
		shmup_game_fire(g, 40, 1, v2zero, v2zero, v2zero);
	
	if (glfwGetKey('1')) 
		g->render_type = 1;
	
	if (glfwGetKey('2')) 
		g->render_type = 2;
	
	g->player->keyflags = KF_NONE;
	if (glfwGetKey('A')) g->player->keyflags |= KF_MOV_L;
	if (glfwGetKey('D')) g->player->keyflags |= KF_MOV_R;
	if (glfwGetKey('W')) g->player->keyflags |= KF_MOV_U;
	if (glfwGetKey('S')) g->player->keyflags |= KF_MOV_D;
	if (glfwGetKey(GLFW_KEY_SPACE)) g->player->keyflags |= KF_FIR_1;
	
	for (i=0; i < g->num_players; i++) {
		player_update(g, &g->player[i], dt);
	}
		
	b = g->bpool->bdata;
	/* 
	 * be careful with this pointer, as this data may be moved by the 
	 * bpool_resize function! Make sure it points to the right place.
	 */	 
	
	/* do updates */
	for (i=0; i < g->bpool->n_active; i++) {
		bullet_update(&b[i], dt);
	}
	
	/* do collisions */
	for (i=0; i < g->bpool->n_active; i++) {		
		if (!point_vs_aabb(b[i].pos, v2zero, v2(g->window_width, g->window_height)))
			bpool_deactivate(g->bpool, i--); 
	}

	
	if (g->network_type == CLIENT) {
		packet = enet_packet_create(&g->player->keyflags, sizeof(short), ENET_PACKET_FLAG_RELIABLE);	
		enet_peer_send(g->peer, 0, packet);
	} else {
		packet = enet_packet_create(&g->player->keyflags, sizeof(short), ENET_PACKET_FLAG_RELIABLE);	
		enet_host_broadcast(g->host, 0, packet);
	}

}
示例#10
0
文件: test_enet.cpp 项目: kooiot/rdc
int main()
{
	int id = 10000;
	std::string sip = "127.0.0.1";
	int sport = 6602;

	ENetPeer* Peers[2];
	Peers[0] = NULL;
	Peers[1] = NULL;
	enet_initialize();

	ENetAddress address;
	ENetHost * remote;
	address.host = ENET_HOST_ANY;
	address.port = 6680;

	remote = enet_host_create(&address /* the address to bind the server host to */,
		128 * 16     /* allow up to 32 clients and/or outgoing connections */,
		17     /* allow up to 2 channels to be used, 0 and 1 */,
		0      /* assume any amount of incoming bandwidth */,
		0      /* assume any amount of outgoing bandwidth */);
	if (remote == NULL)
	{
		fprintf(stderr,
			"An error occurred while trying to create an ENet server host.\n");
		exit(EXIT_FAILURE);
	}


	void* ctx = zmq_ctx_new();
	void* req = zmq_socket(ctx, ZMQ_REQ);
	int timeo = 0;
	int rc = zmq_setsockopt(req, ZMQ_LINGER, &timeo, sizeof(int));
	std::stringstream ss;
	ss << "tcp://" << sip << ":" << sport;
	rc = zmq_connect(req, ss.str().c_str());

	IPInfo info;
	info.port = 6680;
	sprintf(info.sip, "%s", sip.c_str());
	if (send_add_stream(id, req, info)) {
		std::thread* hb = new std::thread([id, req, info] {
			while (true) {
#ifndef RDC_LINUX_SYS
				Sleep(5000);
#else
				sleep(5);
#endif
				if (!send_heartbeat_stream(id, req, info))
				{
					exit(EXIT_FAILURE);
				}
			}
		});
		printf("%s\n", "Initialized!");
	}
	ENetEvent event;
	/* Wait up to 1000 milliseconds for an event. */
	while (enet_host_service(remote, &event, 1000) >= 0)
	{
		switch (event.type)
		{
		case ENET_EVENT_TYPE_CONNECT:
			printf("A new client connected from %x:%u.\n",
				event.peer->address.host,
				event.peer->address.port);
			/* Store any relevant client information here. */
			{
				int index = 0;
				if (Peers[0] != NULL)
					index = 1;
				event.peer->data = &Peers[(index + 1) % 2];
				Peers[index] = event.peer;
			}
			break;
		case ENET_EVENT_TYPE_RECEIVE:
			//printf("A packet of length %u was received from %s on channel %u.\n",
			//	event.packet->dataLength,
			//	event.peer->data,
			//	event.channelID);
			{
				ENetPeer* peer = *(ENetPeer**)event.peer->data;
				if (peer) {
					putc('.', stdout);
					auto p = enet_packet_create(event.packet->data, event.packet->dataLength, ENET_PACKET_FLAG_RELIABLE);
					enet_peer_send(peer, event.channelID, p);
				}
			}

			/* Clean up the packet now that we're done using it. */
			enet_packet_destroy(event.packet);

			break;

		case ENET_EVENT_TYPE_DISCONNECT:
			printf("%s disconnected.\n", event.peer->data);
			/* Reset the peer's client information. */
			event.peer->data = NULL;
			break;
		}
	}
    return 0;
}
示例#11
0
void joynet_poll_server(JOYNET_SERVER * sp)
{
	if(sp && sp->host)
	{
		while(enet_host_service(sp->host, &sp->event, 0))
		{
			switch(sp->event.type)
			{
				/* a connection has been received */
				case ENET_EVENT_TYPE_CONNECT:
				{
					int client = joynet_server_find_free_client(sp);
					
					if(client >= 0)
					{
						sp->client[client]->peer = sp->event.peer;
					}
					sp->client[client]->peer->data = malloc(sizeof(int));
					if(!sp->client[client]->peer->data)
					{
						/* need error system */
					}
					else
					{
						joynet_serialize(sp->serial_data, sp->client[client]->peer->data);
						joynet_putl(sp->serial_data, client);
					}
					sp->client[client]->user = client;
					strcpy(sp->client[client]->screen_name, "");
					break;
				}
				
				/* client disconnected */
				case ENET_EVENT_TYPE_DISCONNECT:
				{
					sp->client[joynet_get_client_from_peer(sp, sp->event.peer)]->peer = NULL;
					break;
				}
				
				/* packet received */
				case ENET_EVENT_TYPE_RECEIVE:
				{
					JOYNET_MESSAGE message;
					joynet_decode_message(&message, &sp->event);
					switch(sp->event.channelID)
					{
						case JOYNET_CHANNEL_SYSTEM:
						{
							break;
						}
						case JOYNET_CHANNEL_CHAT:
						{
							joynet_handle_server_chat_message(sp, &message);
							break;
						}
						case JOYNET_CHANNEL_GAME:
						{
							joynet_handle_server_game_message(sp, &message);
							break;
						}
					}
					
					if(sp->channel_callback[sp->event.channelID])
					{
						sp->channel_callback[sp->event.channelID](&message);
					}
					break;
				}
				default:
				{
					break;
				}
			}
			if(sp->internal_callback)
			{
				sp->internal_callback(&sp->event);
			}
			if(sp->global_callback)
			{
				sp->global_callback(&sp->event);
			}
		}
	}
}
示例#12
0
void LocalRulesManager::update(const double& timeStep)
{	
	ENetEvent event;

	while(enet_host_service(m_server, &event, 0) > 0)
	{
		switch (event.type)
		{
		case ENET_EVENT_TYPE_CONNECT:
			std::cout<<"Client connected: "<< event.peer->address.host << " : " << event.peer->address.port<<std::endl;
			break;

		case ENET_EVENT_TYPE_RECEIVE:
			updateMessages(event.packet->data, event.packet->dataLength);

			for(auto msg : m_messageQueue)
			{
				switch(msg->getType())
				{
				case C_HELLO:
					{
						sendMessage(MessagePtr(new Welcome("Server")), ENET_PACKET_FLAG_RELIABLE);
						m_isWaiting = false;
					}
					break;
				case G_UPDATE_POS:
					m_pongScene->updateOpponentPos(((UpdatePos*)msg.get())->getPosition());
					break;
				case G_BALLEVENT:
					{
						//std::cout<<"Ball event: " << (int)((BallEvent*)msg.get())->getEventType() << "  "<< (int)((BallEvent*)msg.get())->getPlayerId() << std::endl;
						BallEvent* evt = (BallEvent*)msg.get();
						switch(evt->getEventType())
						{
						case BallEvent::BALLEVENT_TABLE:	
							m_gameRules->onBallHitTable(evt->getPlayerId());
							break;
						case BallEvent::BALLEVENT_RACKET:	
							m_gameRules->onBallHitRacket(evt->getPlayerId());
							break;
						case BallEvent::BALLEVENT_OUTSIDE:	
							m_gameRules->onBallOut();
							break;
						}

						checkGameRules();
					}
					break;
				case G_BALLSTATE:
					{
						BallState* ballState = (BallState*)msg.get();
						m_pongScene->updateBallState(
							ballState->getPosition(), 
							ballState->getVelocity(), 
							ballState->getAngularVelocity(), 
							ballState->getServe(),
							ballState->getHitMagnitude());
						if(ballState->getServe() != 0)
							m_gameRules->onNewRound();
					}
					break;
				}
			}
			m_messageQueue.clear();

			//std::cout<<"Got data: "<< event.packet->dataLength << std::endl;
			break;

		case ENET_EVENT_TYPE_DISCONNECT:
			std::cout<<"Client disconnected: "<< event.peer->address.host << " : " << event.peer->address.port<<std::endl;
			break;
		}
	}
}
示例#13
0
void gets2c()           // get updates from the server
{
    ENetEvent event;
    if(!clienthost) return;
    if(connpeer && totalmillis/3000 > connmillis/3000)
    {
        conoutf("attempting to connect...");
        connmillis = totalmillis;
        ++connattempts; 
        if(connattempts > 3)
        {
            conoutf("\f3could not connect to server");
            abortconnect();
            return;
        }
    }
    while(clienthost && enet_host_service(clienthost, &event, 0)>0)
    switch(event.type)
    {
        case ENET_EVENT_TYPE_CONNECT:
            disconnect(false, false); 
            localdisconnect(false);
            curpeer = connpeer;
            connpeer = NULL;
            conoutf("connected to server");
            throttle();
            if(GETIV(rate)) setrate(GETIV(rate));
            game::gameconnect(true);
            break;
         
        case ENET_EVENT_TYPE_RECEIVE:
#if CLIENT // INTENSITY
            if(discmillis) conoutf("attempting to disconnect...");
            else localservertoclient(event.channelID, event.packet);
            enet_packet_destroy(event.packet);
#else // SERVER
            assert(0);
#endif
            break;

        case ENET_EVENT_TYPE_DISCONNECT:
//            LogicSystem::init(); // INTENSITY: Not sure about this...?

            extern const char *disc_reasons[];
            if(event.data>=DISC_NUM) event.data = DISC_NONE;
            if(event.peer==connpeer)
            {
                conoutf("\f3could not connect to server");
                abortconnect();
            }
            else
            {
                if(!discmillis || event.data) conoutf("\f3server network error, disconnecting (%s) ...", disc_reasons[event.data]);
                disconnect();
            }
            return;

        default:
            break;
    }
}
示例#14
0
void clientkeepalive() { if(clienthost) enet_host_service(clienthost, NULL, 0); }
示例#15
0
		void Manager::update()
		{
			assert(_host);

			ENetEvent event;

			for (;;)
			{
				int serviceResponse = enet_host_service(_host, &event, 0);
				if (serviceResponse == 0)
					break;

				if (serviceResponse < 0) {
					std::cerr << "Event handling failed." << std::endl;
					break;
				}

				if (serviceResponse > 0)
				{
					switch (event.type)
					{
					case ENET_EVENT_TYPE_CONNECT:
					{
						clientLocal = new Client(event.peer);
						event.peer->data = clientLocal;
						clientLocal->setID(_nbPlayer);
						if (Engine::instance->getInstanceType() == Engine::InstanceType::CLIENT)
							Engine::instance->GetEntityLocal()->setID(_nbPlayer);
						_eventListener->onConnected(*clientLocal);
						sf::Packet packet;
						packet << "id" << _nbPlayer;
						send(*clientLocal, packet);
						_nbPlayer++;

						std::list<gameplay::PlayerEntity*> theList = Engine::instance->getEntities();

						if (Engine::instance->getInstanceType() == Engine::InstanceType::SERVER)
						{
							//récupère les anciens joueurs
							for (std::list<gameplay::PlayerEntity*>::iterator it = theList.begin(); it != theList.end(); ++it)
							{
								gameplay::PlayerEntity* p = reinterpret_cast<gameplay::PlayerEntity*>(*it);
								if (p->getID() != clientLocal->getID())
								{
									sf::Packet createPacket;
									createPacket << "createPlayer" << p->getID();
									send(*clientLocal, createPacket);
								}
							}
							//notifie les autres qu'on se créé
							CreatePlayerOnClients(clientLocal->getID());
						}
						break;
					}

					case ENET_EVENT_TYPE_RECEIVE:
					{
						Client *client = reinterpret_cast<Client*>(event.peer->data);
						sf::Packet packet;
						packet.append(event.packet->data, event.packet->dataLength);
						_eventListener->onMessageReceived(*client, packet);
						enet_packet_destroy(event.packet);
						break;
					}

					case ENET_EVENT_TYPE_DISCONNECT:
					{
						Client *client = reinterpret_cast<Client*>(event.peer->data);
						_eventListener->onDisconnected(*client);
						delete client;
						break;
					}
					}
				}
			}
		}
示例#16
0
		void CNetManager::update(const u32 timeOut)
		{
			if(connectionStatus == EICS_FAILED)
				return;

			if(mode == ENM_CLIENT)
			{
				ENetEvent event;

				for(u32 i = 0; i < netIterations;i++)
				{
					if(!(enet_host_service(host, &event, i ? 1 : timeOut) > 0))
						break;

					switch (event.type)
					{
					case ENET_EVENT_TYPE_RECEIVE:
						{
							enet_uint8* buff = event.packet->data;

							if(event.channelID == 1)
							{
								u8 packiden = 0;
								memcpy((char*)&packiden,buff,1);

								if(packiden == 3)
								{
									connectionStatus = EICS_ESTABLISHED;
									if(pHandler) pHandler->onConnect(0);
								}
							}
							else
							{
								if(verbose)
									std::cout	<< "irrNetLite: A packet of length "
												<< event.packet->dataLength
												<< " was received.\n";

								SInPacket inpacket((c8*)buff, event.packet->dataLength);

								if(pHandler)
									pHandler->handlePacket(inpacket);
							}

							buff = 0;
							enet_packet_destroy(event.packet);
							break;
						}
					case ENET_EVENT_TYPE_DISCONNECT:
						std::cout << "irrNetLite: Connection to server lost.\n";

						event.peer->data = 0;
						connectionStatus = EICS_FAILED;

						if(pHandler)
							pHandler->onDisconnect(0);
					default:
						break;
					}
				}

			}
			else // (mode == ENM_SERVER)
			{
				ENetEvent event;

				for(u32 i = 0;i < netIterations;i++)
				{
					if(!(enet_host_service (host, &event, i ? 1 : timeOut) > 0))
						break;

					switch (event.type)
					{
					case ENET_EVENT_TYPE_CONNECT:
						{
							if(verbose)
								std::cout	<< "irrNetLite: A new client connected from "
											<< event.peer->address.host << ":"
											<< event.peer->address.port << std::endl;

							u16 pID = 1;

							while(pID < netParams.maxClients && players[pID] != 0)
								pID++;

							if(pID >= netParams.maxClients)
							{
								if(verbose)
									std::cout 	<< "irrNetLite: Warning: Client rejected. Too many clients."
												<< std::endl;

								pID = 0;
							}
							else
							{
								event.peer->data = players[pID] = new SPeerData(pID, event.peer);
							}

							c8 buffer[3];
							u8 packid = 4;
							memcpy(buffer, (char*)&packid, 1);
							memcpy(buffer+1, (char*)&pID, 2);
							ENetPacket* packet;
							packet = enet_packet_create(buffer, 3, ENET_PACKET_FLAG_RELIABLE);
							enet_peer_send(event.peer, 1, packet);
							enet_host_flush(host);

							if(pID == 0) enet_peer_reset(event.peer);

							break;
						}
					case ENET_EVENT_TYPE_RECEIVE:
						{
							enet_uint8* buff = event.packet->data;

							if(event.channelID == 1)
							{
								u8 packiden = 0;
								memcpy((char*)&packiden, buff, 1);

								if(packiden == 3)
								{
									ENetPacket* packet = enet_packet_create(&packiden, 1, ENET_PACKET_FLAG_RELIABLE);
									enet_peer_send(event.peer, 1, packet);
									SPeerData* currentPeer = reinterpret_cast<SPeerData*>(event.peer->data);
									if(currentPeer && pHandler) pHandler->onConnect(currentPeer->playerID);
								}
							}
							else
							{
								SPeerData* currentPeer = reinterpret_cast<SPeerData*>(event.peer->data);

								if(currentPeer)
								{
									SInPacket inPacket((c8*)buff, event.packet->dataLength);
									inPacket.setPlayerId(currentPeer->playerID);

									if(verbose)
										std::cout	<< "irrNetLite: A packet of length "
													<< event.packet->dataLength
													<< " from player number "
													<< currentPeer->playerID
													<< " was received.\n";

									if(pHandler)
										pHandler->handlePacket(inPacket);

									if(globPacketRelay)
									{
										SOutPacket relayPacket((c8*)buff, event.packet->dataLength);

										const u32 playersSize = players.size();
										for(u32 i = 0;i < playersSize;++i)
											if(players[i] && players[i] != currentPeer)
												sendOutPacket(relayPacket, i);
									}
								}
							}

							buff = 0;
							enet_packet_destroy(event.packet);
							break;
						}
					case ENET_EVENT_TYPE_DISCONNECT:
						{
							SPeerData* pData = reinterpret_cast<SPeerData*>(event.peer->data);

							if(pData)
							{
								if(verbose)
									std::cout	<< "irrNetLite: Player number "
												<< pData->playerID
												<< " disconnected.\n";

								if(pHandler) pHandler->onDisconnect(pData->playerID);

								players[pData->playerID] = 0;
								delete pData;
								event.peer->data = 0;
							}
						}
					default:
						break;
					}
				}
			}
		}
示例#17
0
// Receive packets from the network and buffers and create ConnectionEvents
void Connection::receive()
{
	if (!m_enet_host) {
		return;
	}
	ENetEvent event;
	int ret = enet_host_service(m_enet_host, & event, 10);
	if (ret > 0)
	{
		m_last_recieved = porting::getTimeMs();
		m_last_recieved_warn = 0;
		switch (event.type)
		{
		case ENET_EVENT_TYPE_CONNECT:
			{
				//MutexAutoLock peerlock(m_peers_mutex);
				u16 peer_id = 0;
				static u16 last_try = PEER_ID_SERVER + 1;
				if (m_peers.size() > 0) {
					for (int i = 0; i < 1000; ++i) {
						if (last_try > 30000)
							last_try = PEER_ID_SERVER;
						++last_try;
						if (!m_peers.count(last_try)) {
							peer_id = last_try;
							break;
						}
					}
				} else {
					peer_id = last_try;
				}
				if (!peer_id)
					last_try = peer_id = m_peers.rbegin()->first + 1;

				m_peers.set(peer_id, event.peer);
				m_peers_address.set(peer_id, Address(event.peer->address.host, event.peer->address.port));

				event.peer->data = new u16;
				*((u16*)event.peer->data) = peer_id;

				// Create peer addition event
				ConnectionEvent e;
				e.peerAdded(peer_id);
				putEvent(e);
			}
			break;
		case ENET_EVENT_TYPE_RECEIVE:
			{
				ConnectionEvent e;
				SharedBuffer<u8> resultdata(event.packet->data, event.packet->dataLength);
				e.dataReceived(*(u16*)event.peer->data, resultdata);
				putEvent(e);
			}

			/* Clean up the packet now that we're done using it. */
			enet_packet_destroy (event.packet);
			break;
		case ENET_EVENT_TYPE_DISCONNECT:
			deletePeer(*((u16*)event.peer->data), false);

			/* Reset the peer's client information. */
			delete (u16*)event.peer->data;

			break;
		case ENET_EVENT_TYPE_NONE:
			break;
		}
	} else if (ret < 0) {
		infostream<<"recieve enet_host_service failed = "<< ret << std::endl;
		if (m_peers.count(PEER_ID_SERVER))
			deletePeer(PEER_ID_SERVER,  false);
	} else { //0
		if (m_peers.count(PEER_ID_SERVER) && m_last_recieved) { //ugly fix. todo: fix enet and remove
			unsigned int time = porting::getTimeMs();
			const unsigned int t1 = 10000, t2 = 30000 * timeout_mul, t3 = 60000 * timeout_mul;
			unsigned int wait = time - m_last_recieved;
			if (wait > t3 && m_last_recieved_warn > t2) {
				errorstream<<"connection lost [60s], disconnecting."<<std::endl;
#if defined(__has_feature)
#if __has_feature(thread_sanitizer) || __has_feature(address_sanitizer)
				if (0)
#endif
#endif
				{
					deletePeer(PEER_ID_SERVER,  false);
				}
				m_last_recieved_warn = 0;
				m_last_recieved = 0;
			} else if (wait > t2 && m_last_recieved_warn > t1 && m_last_recieved_warn < t2) {
				errorstream<<"connection lost [30s]!"<<std::endl;
				m_last_recieved_warn = time - m_last_recieved;
			} else if (wait > t1 && m_last_recieved_warn < t1) {
				errorstream<<"connection lost [10s]? ping."<<std::endl;
				enet_peer_ping(m_peers.get(PEER_ID_SERVER));
				m_last_recieved_warn = wait;
			}
		}
	}
}
示例#18
0
		bool CNetManager::setUpClient(const c8* addressc, const u32 port)
		{
			mode = ENM_CLIENT;

			if(verbose)
				std::cout << "irrNetLite: Creating client!" << std::endl;

			host = enet_host_create(NULL, 1, netParams.downBandwidth / 8, netParams.upBandwidth / 8);

			ENetEvent event;

			enet_address_set_host(&address, addressc);
			address.port = port;

			if(verbose)
				std::cout	<< "irrNetLite: Connecting to "
							<< addressc	<< ":" << port << std::endl;

			// Sets up two channels.
			peer = enet_host_connect(host, &address, 2);

			if(peer == NULL)
			{
				std::cout << "irrNetLite: Error: Could not resolve server address. Connection failed.\n";
				return false;
			}

			if(!(	enet_host_service(host, &event, netParams.connectionTimeout) > 0 &&
					event.type == ENET_EVENT_TYPE_CONNECT))
			{
				enet_peer_reset(peer);

				std::cout << "irrNetLite: Error: Connection timed out. Connection failed.\n";
				return false;
			}

			while(enet_host_service(host, &event, netParams.connectionTimeout) > 0)
			{
				if(event.channelID == 1 && event.type == ENET_EVENT_TYPE_RECEIVE)
				{
					enet_uint8* buff = event.packet->data;

					u8 packiden = 0;
					memcpy((char*)&packiden, buff, 1);

					if(packiden == 4)
					{
						memcpy((char*)&playerID, buff+1, 2);

						if(playerID == 0)
						{
							std::cout << "irrNetLite: Error: Null player ID recieved. Server likely full.";
							enet_peer_reset(event.peer);
							return false;
						}

						if(verbose)
							std::cout << "irrNetLite: Player ID is " << playerID << ".\n";

						u8 packid = 3;
						ENetPacket* packet = enet_packet_create(&packid, 1, ENET_PACKET_FLAG_RELIABLE);
						enet_host_broadcast(host, 1, packet);

						return true;
					}
				}
			}

			std::cout << "irrNetLite: Error: Failed to recieve Player ID. Connection failed.\n";
			return false;
		}
示例#19
0
Message* GetMessage ()
{
	ENetEvent event;
	if (enet_host_service(serverHost, &event, 0))
	{
		Message* msg = NULL;
		unsigned int clientID = 0;
		for (ClientMap::iterator iter = clients.begin(); iter != clients.end(); iter++)
		{
			if (iter->second == event.peer)
			{
				clientID = iter->first;
			}
		}
		switch (event.type)
		{
			case ENET_EVENT_TYPE_CONNECT:
				msg = new Message ( "CONNECT", NULL, 0 );
				clientID = nextClientID++;
				msg->clientID = clientID;
				clients[clientID] = event.peer;
				badMessage[clientID][0] = 0; //clear bad-message entry so it can be used
				Message* keymsg;
				Message* ivmsg;
				
				//make and share encryption keys
			//ADAM	makeBlowKey[clientID];
			//ADAM	keymsg = new Message( "BLOWKEY", sessionKey[clientID], 16 ); //make a message with the blowkey
			//ADAM	SendMessage( clientID, keymsg ); //send the blowkey
				
			//ADAM	ivmsg = new Message( "BLOWIV" , sessionIV[clientID], 8 ); //make a message with the blowIV
			//ADAM	SendMessage( clientID, ivmsg ); //send the IV
				break;
			case ENET_EVENT_TYPE_DISCONNECT:
				{
					msg = new Message ( "DISCONNECT", NULL, 0 );
					msg->clientID = clientID;
					ClientMap::iterator iter = clients.find(clientID);
					clients.erase(iter);
				}
				break;
			case ENET_EVENT_TYPE_RECEIVE:
				msg = MessageEncoding::Decode(event.packet);

				if(msg == NULL)
				{
					if (badMessageCount[clientID] >= 4)
					{
						KillClient(clientID);
					}
					else
					{
						BadClient(clientID);
					}
				}
				else 
                {
					msg->clientID = clientID;
				/*	
					if( Blowfish::do_decrypt(msg, sessionKey[clientID], sessionIV[clientID]) == false) // msg is passed by reference. Return 0 on error.
					{
				 //do something with the bad message
					} else {
						//do something with the recieved message
				 
					}
				 */ //disabled until finished implementation
				}
				
				enet_packet_destroy(event.packet);
				break;
		}
		return msg;
	}
	return NULL;
}
示例#20
0
int main (int argc, char ** argv) {
    prev = getthetime();
    (void) signal(SIGINT,leave);

    if (enet_initialize () != 0) {
        fprintf (stderr, "An error occurred while initializing ENet.\n");
        return EXIT_FAILURE;
    }

    atexit (enet_deinitialize);


    address.host = ENET_HOST_ANY;
    address.port = 5001;

    enetserver = enet_host_create (& address /* the address to bind the server host to */,
                                   32      /* allow up to 32 clients and/or outgoing connections */,
                                   0      /* allow up to 2 channels to be used, 0 and 1 */,
                                   0      /* assume any amount of incoming bandwidth */,
                                   0      /* assume any amount of outgoing bandwidth */);
    if (enetserver== NULL) {
        fprintf (stderr,
                 "An error occurred while trying to create an ENet server host.\n");
        exit (EXIT_FAILURE);
    }

    tronserver = server_init(enetserver);
    atexit(clean_up);
    printf("This is the TronClone Server.\nPush ^c to kill the server.\n");

    /* Main game loop */
    while(1) {
        int i, index, temp;
        char buf[80];
        if (enet_host_service (enetserver, & event, 10) > 0) {
            switch (event.type) {
            case ENET_EVENT_TYPE_CONNECT:
                enet_address_get_host_ip(&event.peer->address, buf, sizeof buf);
                printf ("A new client connected from %s\n",
                        buf);
                server_add_user(tronserver, event.peer);
                break;

            case ENET_EVENT_TYPE_RECEIVE:
                server_process_packet(tronserver, event);
                enet_packet_destroy (event.packet);
                break;

            case ENET_EVENT_TYPE_DISCONNECT:
                enet_address_get_host_ip(&event.peer->address, buf, sizeof buf);
                printf ("A client disconnected from %s: %u.\n",
                        buf,
                        event.peer -> address.port);

                server_remove_user(tronserver, event.peer);
                event.peer -> data = NULL;
                break;
            }
        }

        now = getthetime();
        double h = (now-prev)/1000000.0f;
        server_update(tronserver, h);
        prev = now;
    }
    clean_up();
}
示例#21
0
int main(int argc, char* argv[]) {
	ENetHost *client;
	ENetAddress address;
	ENetPeer *peer;
	ENetEvent event;
	char message[1024];
	int serviceResult;

	puts("Starting client");

	if (enet_initialize() != 0) {
		fprintf(stderr, "Error initialising enet");
		exit(EXIT_FAILURE);

	}

	client = enet_host_create(NULL, /* create a client host */
		1,    /* number of clients */
		2,    /* number of channels */
		57600 / 8,    /* incoming bandwith */
		14400 / 8);   /* outgoing bandwith */

	if (client == NULL) {
		fprintf(stderr, "Could not create client host");
		exit(EXIT_FAILURE);

	}


	enet_address_set_host(&address, "localhost");
	address.port = 1234;

	peer = enet_host_connect(client,
		&address,    /* address to connect to */
		2,           /* number of channels */
		0);          /* user data supplied to
						  the receiving host */

	if (peer == NULL) {
		fprintf(stderr, "No available peers for initiating an ENet "
			"connection.\n");
		exit(EXIT_FAILURE);

	}


	/* Try to connect to server within 5 seconds */
	if (enet_host_service(client, &event, 5000) > 0 &&
		event.type == ENET_EVENT_TYPE_CONNECT)
	{
		puts("Connection to server succeeded.");
	}
	else
	{
		/* Either the 5 seconds are up or a disconnect event was */
		/* received. Reset the peer in the event the 5 seconds   */
		/* had run out without any significant event.            */
		enet_peer_reset(peer);

		fprintf(stderr, "Connection to server failed.");
		exit(EXIT_FAILURE);
	}

	while (true)
	{
		serviceResult = 1;

		/* Keep doing host_service until no events are left */
		while (serviceResult > 0)
		{
			serviceResult = enet_host_service(client, &event, 0);

			if (serviceResult > 0)
			{
				switch (event.type)
				{
				case ENET_EVENT_TYPE_CONNECT:
					printf("A new client connected from %x:%u.\n",
						event.peer->address.host,
						event.peer->address.port);

					event.peer->data = (void*)"New User";
					break;

				case ENET_EVENT_TYPE_RECEIVE:
					printf("A packet of length %u containing '%s' was "
						"received from %s on channel %u.\n",
						event.packet->dataLength,
						event.packet->data,
						event.peer->data,
						event.channelID);

					/* Clean up the packet now that we're done using it.
						> */
					enet_packet_destroy(event.packet);

					break;

				case ENET_EVENT_TYPE_DISCONNECT:
					printf("%s disconnected.\n", event.peer->data);

					break;
				}
			}
			else if (serviceResult > 0)
			{
				puts("Error with servicing the client");
				exit(EXIT_FAILURE);
			}

		}


		printf("Say> ");
#ifdef _WIN32
		gets_s(message, 1024);
#else
		gets(message);
#endif
		if (strcmp(message, "exit") == 0 ||
			strcmp(message, "quit") == 0) {
			break;

		}

		if (strlen(message) > 0) {
			ENetPacket *packet = enet_packet_create(message, strlen
			(message) + 1, ENET_PACKET_FLAG_RELIABLE);
			enet_peer_send(peer, 0, packet);

		}

	}

	enet_peer_disconnect(peer, 0);

	/* Allow up to 3 seconds for the disconnect to succeed */
	/* and drop any packets received packets */
	while (enet_host_service(client, &event, 3000) > 0)
	{

		switch (event.type)
		{
		case ENET_EVENT_TYPE_RECEIVE:
			enet_packet_destroy(event.packet);
			break;

		case ENET_EVENT_TYPE_DISCONNECT:
			puts("Disconnection succeeded.");
			break;
		}
	}


	enet_host_destroy(client);
	enet_deinitialize();

	return 0;


}
示例#22
0
	void Server::pollEvents()
	{
		ENetEvent event;

		if(enet_host_service (mServer, &event, 0) > 0)
		{
			if(event.type==ENET_EVENT_TYPE_CONNECT)
			{
				bool found = false;
				for(int i=0;i<255;++i)
				{
					if(mClients.find(i)==mClients.end())
					{
						found = true;
						mClients[i] = event.peer;
						AssignPacket ap(i);
						sendPacket(&ap,false,i);
						std::cout<<"Assigning Client ID... (ID: "<<i<<")\n";
						break;
					}
				}
				if(!found)
					std::cout<<"SHIT! Something went wrong!\n";
			}
			else if(event.type==ENET_EVENT_TYPE_RECEIVE)
			{
				byte id = event.packet->data[0];
				if(id<3||id>5)
					recievePacket(event.packet);
				else
				{
					if(id==3)
					{
						IntroPacket ap(event.packet->data,event.packet->dataLength);
						std::cout<<"Client introduced: "<<ap.name<<" (ID: "
							<<static_cast<int>(ap.id)<<")\n";
						
						std::map<byte,String>::iterator iter = mClientNames.begin();
						for(iter;iter!=mClientNames.end();++iter)
						{
							sendPacket(&SpawnPacket(iter->second,iter->first),false,ap.id);
						}
						
						SpawnPacket sp(ap.name,ap.id);
						mClientNames[ap.id] = ap.name;
						sendPacket(&sp);
						for(uint i=0;i<mConnectCallbacks.size();++i)
						{
							mConnectCallbacks[i](ap.id);
						}
					}
				}
				enet_packet_destroy(event.packet);
			}
			else if(event.type==ENET_EVENT_TYPE_DISCONNECT)
			{
				std::map<byte,ENetPeer*>::iterator it = mClients.begin();
				for(it;it!=mClients.end();++it)
				{
					if(it->second==event.peer)
					{
						std::cout<<"Disconnected Client (ID: "<<static_cast<int>(it->first)<<")\n";
						mClientNames.erase(mClientNames.find(it->first));
						mClients.erase(it);
						sendPacket(&QuitPacket(it->first));// notify everyone
						break;
					}
				}
			}
		}
	}
void NetworkedMultiplayerENet::poll(){

	ERR_FAIL_COND(!active);

	_pop_current_packet();

	ENetEvent event;
	/* Wait up to 1000 milliseconds for an event. */
	while (true) {

		if (!host || !active) //might have been disconnected while emitting a notification
			return;

		int ret = enet_host_service (host, & event, 1);

		if (ret<0) {
			//error, do something?
			break;
		} else if (ret==0) {
			break;
		}

		switch (event.type)
		{
			case ENET_EVENT_TYPE_CONNECT: {
				/* Store any relevant client information here. */

				if (server && refuse_connections) {
					enet_peer_reset(event.peer);
					break;
				}

				IP_Address ip;
				ip.host=event.peer -> address.host;

				int *new_id = memnew( int );
				*new_id = event.data;

				if (*new_id==0) { //data zero is sent by server (enet won't let you configure this). Server is always 1
					*new_id=1;
				}

				event.peer->data=new_id;

				peer_map[*new_id]=event.peer;

				connection_status=CONNECTION_CONNECTED; //if connecting, this means it connected t something!

				emit_signal("peer_connected",*new_id);

				if (server) {
					//someone connected, let it know of all the peers available
					for (Map<int,ENetPeer*>::Element *E=peer_map.front();E;E=E->next()) {

						if (E->key()==*new_id)
							continue;
						//send existing peers to new peer
						ENetPacket * packet = enet_packet_create (NULL,8,ENET_PACKET_FLAG_RELIABLE);
						encode_uint32(SYSMSG_ADD_PEER,&packet->data[0]);
						encode_uint32(E->key(),&packet->data[4]);
						enet_peer_send(event.peer,1,packet);
						//send the new peer to existing peers
						packet = enet_packet_create (NULL,8,ENET_PACKET_FLAG_RELIABLE);
						encode_uint32(SYSMSG_ADD_PEER,&packet->data[0]);
						encode_uint32(*new_id,&packet->data[4]);
						enet_peer_send(E->get(),1,packet);
					}
				} else {

					emit_signal("connection_succeeded");
				}

			} break;
			case ENET_EVENT_TYPE_DISCONNECT: {

				/* Reset the peer's client information. */

				int *id = (int*)event.peer -> data;



				if (!id) {
					if (!server) {
						emit_signal("connection_failed");
					}
				} else {

					if (server) {
						//someone disconnected, let it know to everyone else
						for (Map<int,ENetPeer*>::Element *E=peer_map.front();E;E=E->next()) {

							if (E->key()==*id)
								continue;
							//send the new peer to existing peers
							ENetPacket* packet = enet_packet_create (NULL,8,ENET_PACKET_FLAG_RELIABLE);
							encode_uint32(SYSMSG_REMOVE_PEER,&packet->data[0]);
							encode_uint32(*id,&packet->data[4]);
							enet_peer_send(E->get(),1,packet);
						}
					} else if (!server) {
						emit_signal("server_disconnected");
						close_connection();
						return;
					}

					emit_signal("peer_disconnected",*id);
					peer_map.erase(*id);
					memdelete( id );

				}


			} break;
			case ENET_EVENT_TYPE_RECEIVE: {


				if (event.channelID==1) {
					//some config message
					ERR_CONTINUE( event.packet->dataLength < 8);

					int msg = decode_uint32(&event.packet->data[0]);
					int id = decode_uint32(&event.packet->data[4]);

					switch(msg) {
						case SYSMSG_ADD_PEER: {

							peer_map[id]=NULL;
							emit_signal("peer_connected",id);

						} break;
						case SYSMSG_REMOVE_PEER: {

							peer_map.erase(id);
							emit_signal("peer_disconnected",id);
						} break;
					}

					enet_packet_destroy(event.packet);
				} else if (event.channelID==0){

					Packet packet;
					packet.packet = event.packet;

					int *id = (int*)event.peer -> data;

					ERR_CONTINUE(event.packet->dataLength<12)


					uint32_t source = decode_uint32(&event.packet->data[0]);
					int target = decode_uint32(&event.packet->data[4]);
					uint32_t flags = decode_uint32(&event.packet->data[8]);

					packet.from=source;

					if (server) {

						packet.from=*id;

						if (target==0) {
							//re-send the everyone but sender :|

							incoming_packets.push_back(packet);
							//and make copies for sending
							for (Map<int,ENetPeer*>::Element *E=peer_map.front();E;E=E->next()) {

								if (uint32_t(E->key())==source) //do not resend to self
									continue;

								ENetPacket* packet2 = enet_packet_create (packet.packet->data,packet.packet->dataLength,flags);

								enet_peer_send(E->get(),0,packet2);
							}

						} else if (target<0) {
							//to all but one

							//and make copies for sending
							for (Map<int,ENetPeer*>::Element *E=peer_map.front();E;E=E->next()) {

								if (uint32_t(E->key())==source || E->key()==-target) //do not resend to self, also do not send to excluded
									continue;

								ENetPacket* packet2 = enet_packet_create (packet.packet->data,packet.packet->dataLength,flags);

								enet_peer_send(E->get(),0,packet2);
							}

							if (-target != 1) {
								//server is not excluded
								incoming_packets.push_back(packet);
							} else {
								//server is excluded, erase packet
								enet_packet_destroy(packet.packet);
							}

						} else if (target==1) {
							//to myself and only myself
							incoming_packets.push_back(packet);
						} else {
							//to someone else, specifically
							ERR_CONTINUE(!peer_map.has(target));
							enet_peer_send(peer_map[target],0,packet.packet);
						}
					} else {

						incoming_packets.push_back(packet);
					}


					//destroy packet later..
				} else {
					ERR_CONTINUE(true);
				}


			}break;
			case ENET_EVENT_TYPE_NONE: {
				//do nothing
			} break;
		}
	}
}
示例#24
0
int
main(int argc, char **argv)
{
  int i, j, RetVal = 1;
  pthread_t KeyboardThread;

  // Parse the command-line arguments.
  for (i = 1; i < argc; i++)
    {
      if (!strcmp(argv[i], "--client"))
        IsServer = 0;
      else if (!strcmp(argv[i], "--server"))
        IsServer = 1;
      else if (1 == sscanf (argv[i], "--port=%d", &j))
        Port = j;
      else
        {
          fprintf(stderr, "USAGE:\n");
          fprintf(stderr, "     enetHostTest [OPTIONS]\n");
          fprintf(stderr, "The allowed OPTIONS are:\n");
          fprintf(stderr, "--help    Display this help-info.\n");
          fprintf(stderr, "--server  Start a server.\n");
          fprintf(stderr, "--client  Start a client (the default).\n");
          fprintf(stderr, "--port=P  Defaults to --port=%d.\n", PORT);
          return (1);
        }
    }

  // Initialize the socket library.
  if (enet_initialize() != 0)
    {
      fprintf(stderr, "An error occurred while initializing ENet.\n");
      return EXIT_FAILURE;
    }
  atexit(enet_deinitialize);

  //---------------------------------------------------------------------------
  // Set up the host as either a client or a server.  In either
  // case, the variable "host" will be used as a pointer to the host.
  if (IsServer)
    {
      ENetAddress address;
      ENetHost *server;

      fprintf(stderr, "Starting up enet server.\n");

      /* Bind the server to the default localhost.     */
      /* A specific host address can be specified by   */
      /* enet_address_set_host (& address, "x.x.x.x"); */

      address.host = ENET_HOST_ANY;
      /* Bind the server to port. */
      address.port = Port;

      server = enet_host_create(&address, 32, 1, 0, 0);
      if (server == NULL)
        {
          fprintf(stderr,
              "An error occurred while trying to create an ENet server host.\n");
          exit(EXIT_FAILURE);
        }
      host = server;
    }
  else // !IsServer, so must be a client.
    {
      ENetHost *client;

      fprintf(stderr, "Starting up enet client.\n");

      client = enet_host_create(NULL, 1, 2, 0, 0);

      if (client == NULL)
        {
          fprintf(stderr,
              "An error occurred while trying to create an ENet client host.\n");
          exit(EXIT_FAILURE);
        }
      host = client;

    }

  //---------------------------------------------------------------------------
  // Start up another thread to get keyboard commands, so as to be able to 
  // initiate messages over the socket connection.  
  i = pthread_create(&KeyboardThread, NULL, KeyboardThreadFunction, NULL);
  if (i != 0)
    {
      fprintf(stderr, "Keyboard thread creation failed with code %d.\n", i);
      goto Done;
    }

  //---------------------------------------------------------------------------
  // Infinite loop to service the host.
  while (1)
    {
      ENetEvent event;
      ENetAddress address;

      // Connect to the server, if necessary.
      if (!IsServer && peer == NULL)
        {
          enet_address_set_host(&address, "localhost");
          address.port = Port;
          peer = enet_host_connect(host, &address, 2, 0);
          if (peer == NULL)
            {
              fprintf(stderr, "\rConnection failed.\n" PROMPT);
#ifdef WIN32
              Sleep (100);
#else
              usleep(100 * 1000);
#endif
            }
        }

      // Service the host for incoming packets, connects, disconnects.
      enet_host_service(host, &event, 1000);
      switch (event.type)
        {
      case ENET_EVENT_TYPE_CONNECT:
        fprintf(stderr, "\rA new client connected from 0x%08X:%u.\n" PROMPT,
            event.peer -> address.host, event.peer -> address.port);

        /* Store any relevant client information here. */
        event.peer -> data = "Client information";

        break;

      case ENET_EVENT_TYPE_RECEIVE:
        fprintf (stderr, "\r");
        printf(
            "%u 0x%08X:%u \"%s\"\n",
            event.packet -> dataLength,
            event.peer -> address.host, event.peer -> address.port,
            event.packet -> data);
        fflush(stdout);
        fprintf (stderr, PROMPT);

        /* Clean up the packet now that we're done using it. */
        enet_packet_destroy(event.packet);

        break;

      case ENET_EVENT_TYPE_DISCONNECT:
        fprintf(stderr, "\r0x%08X:%u disconnected.\n" PROMPT,
            event.peer -> address.host, event.peer -> address.port);

        /* Reset the peer's client information. */

        event.peer -> data = NULL;
        if (!IsServer)
          peer = NULL;

        break;

      default:
        //printf ("No events.\n");
        break;
        }
    }

  RetVal = 0;
  Done: ;
  enet_host_destroy(host);
  return (RetVal);
}
void PNetworkServer::update()
{
    if (m_state == NETWORK_CONNECTED)
    {
        pint32 ret;
        while ((ret = enet_host_service(m_data->server, &m_data->event, P_NETWORK_POLL_TIME)) > 0)
        // FIXME: why enet_host_check_events doesn't work as enet_host_service()?
        //while ((ret = enet_host_check_events(m_data->server, &m_data->event)) > 0)
        {
            switch (m_data->event.type)
            {
                case ENET_EVENT_TYPE_CONNECT:
                    {
                        puint32 id = m_nextId++;
                        PNetworkPeer *peer = onPeerConnected(id);
                        if (peer != P_NULL)
                        {
                            m_peers.insert(id, peer);
                            peer->data()->peer = m_data->event.peer;
                        }
                        m_data->event.peer->data = PNEW(puint32);
                        *(puint32*)(m_data->event.peer->data) = id;
                    }
                    break;
                case ENET_EVENT_TYPE_RECEIVE:
                    {
                        puint32 id = *(puint32*)(m_data->event.peer->data);
                        PMap<puint32, PNetworkPeer*>::iterator it = m_peers.find(id);
                        if (it != m_peers.end())
                        {
                            onMessageReceived(it.value(), (const puint8 *)(m_data->event.packet->data), 
                                m_data->event.packet->dataLength);
                        }
                        else
                        {
                            PLOG_ERROR("Failed to find network connection %d.", id);
                        }
                        enet_packet_destroy (m_data->event.packet);
                    }
                    break;
                case ENET_EVENT_TYPE_DISCONNECT:
                    {
                        puint32 id = *(puint32*)(m_data->event.peer->data);
                        PMap<puint32, PNetworkPeer*>::iterator it = m_peers.find(id);
                        if (it != m_peers.end())
                        {
                            onPeerDisconnected(it.value());
                            PDELETE(it.value());
                            m_peers.erase(it);
                            puint32 *tmp = (puint32*)(m_data->event.peer->data);
                            PDELETE(tmp);
                        }
                        else
                        {
                            PLOG_ERROR("Failed to find network connection %d.", id);
                        }
                    }
                    break;
                default:
                    PASSERT_NOTREACHABLE("Unknown server side event.");
                    break;
            }
        }

        if (ret < 0)
        {
            m_state = NETWORK_ERROR;
        }
    }
}
示例#26
0
bool NetServer::ServerStep()
{
	// use lastTic to keep track of how many tics per second we have; control "tics per second"
	// perform any periodic, timed events here

	ENetEvent event;
	int status = enet_host_service(server, &event, HOST_TIMEOUT);

	if (status < 0) return false; // ERROR happened! Server shut down!	

	TimedEvent();

	if (status == 0) return true; // nothing to do, try again later

	switch(event.type)
	{
	case ENET_EVENT_TYPE_CONNECT:
		{
			printf ("A new client (%d) connected from %x:%u.\n", 
				event.peer,
				event.peer -> address.host,
				event.peer -> address.port);

			client *c = new client;
			char hostname[256] = "error";
			enet_address_get_host_ip(&event.peer->address, hostname, 256);
			printf("%s connected\n", hostname);

			if (event.peer != master)
			{
				c->hostname = string(hostname);
				c->peer = event.peer;
				c->state = ST_AUTH;

				// associate peer with the client object for them
				event.peer->data = c;

				// Call HandleConnect method of the game logic
				// if it returns false, then that means connection denied, otherwise specifies state client is in
				// also add to list of clients
				if (HandleConnect(event.peer)) {
					bool client_added = false;
					for (size_t i = 0; i < clients.size(); i++) {
						if (clients.at(i)->state == ST_EMPTY) {
							clients.at(i) = c;
							client_added = true;
							break;
						}
					}
					if (!client_added)
						clients.push_back(c);
				} else {
					enet_peer_disconnect(event.peer, 121);
				}
			} else {
				MasterCheckin();
			}
			break;
		}

	case ENET_EVENT_TYPE_DISCONNECT:
		{
			if (event.peer != master) {
				printf ("%d disconnected.\n", event.peer);

				// Call HandleDisconnect method some form of id for the connection
				HandleDisconnect(323, event.peer);

				// free up this client slot for reuse
				((client*) event.peer->data)->state = ST_EMPTY;
			} else {
				printf ("Master timed out.\n");
				master = 0;
			}
			break;
		}
	case ENET_EVENT_TYPE_RECEIVE:
		{
			char hostname[256] = "error";
			enet_address_get_host_ip(&event.peer->address, hostname, 256);
			printf("receiving packet.\n");
			printf ("A packet of length %u ",
				event.packet -> dataLength);
			printf("containing %s ",
				event.packet -> data);
			printf("was received from %s ",
				hostname);
			printf("on channel %u.\n",
				event.channelID);
			/*printf ("A packet of length %u containing %s was received from %s on channel %u.\n",
			event.packet -> dataLength,
			event.packet -> data,
			((client*)event.peer -> data)->hostname.c_str(),
			event.channelID);*/

			client *c = (client*) event.peer->data;

			// Call Packet Handler to deal with packets, and send a response
			HandlePacket(event.packet->data, event.packet->dataLength, event.peer);

			if (event.packet->referenceCount == 0) enet_packet_destroy(event.packet);
			break;
		}
	default:
		break;
	}
	enet_host_flush(server);
	return true;
}
示例#27
0
bool CNetServerWorker::RunStep()
{
	// Check for messages from the game thread.
	// (Do as little work as possible while the mutex is held open,
	// to avoid performance problems and deadlocks.)
	
	m_ScriptInterface->GetRuntime()->MaybeIncrementalGC(0.5f);
	
	JSContext* cx = m_ScriptInterface->GetContext();
	JSAutoRequest rq(cx);

	std::vector<std::pair<int, CStr> > newAssignPlayer;
	std::vector<bool> newStartGame;
	std::vector<std::pair<CStr, int> > newPlayerReady;
	std::vector<bool> newPlayerResetReady;
	std::vector<std::string> newGameAttributes;
	std::vector<u32> newTurnLength;

	{
		CScopeLock lock(m_WorkerMutex);

		if (m_Shutdown)
			return false;

		newStartGame.swap(m_StartGameQueue);
		newPlayerReady.swap(m_PlayerReadyQueue);
		newPlayerResetReady.swap(m_PlayerResetReadyQueue);
		newAssignPlayer.swap(m_AssignPlayerQueue);
		newGameAttributes.swap(m_GameAttributesQueue);
		newTurnLength.swap(m_TurnLengthQueue);
	}

	for (size_t i = 0; i < newAssignPlayer.size(); ++i)
		AssignPlayer(newAssignPlayer[i].first, newAssignPlayer[i].second);

	for (size_t i = 0; i < newPlayerReady.size(); ++i)
		SetPlayerReady(newPlayerReady[i].first, newPlayerReady[i].second);

	if (!newPlayerResetReady.empty())
		ClearAllPlayerReady();

	if (!newGameAttributes.empty())
	{
		JS::RootedValue gameAttributesVal(cx);
		GetScriptInterface().ParseJSON(newGameAttributes.back(), &gameAttributesVal);
		UpdateGameAttributes(&gameAttributesVal);
	}

	if (!newTurnLength.empty())
		SetTurnLength(newTurnLength.back());

	// Do StartGame last, so we have the most up-to-date game attributes when we start
	if (!newStartGame.empty())
		StartGame();

	// Perform file transfers
	for (size_t i = 0; i < m_Sessions.size(); ++i)
		m_Sessions[i]->GetFileTransferer().Poll();

	// Process network events:

	ENetEvent event;
	int status = enet_host_service(m_Host, &event, HOST_SERVICE_TIMEOUT);
	if (status < 0)
	{
		LOGERROR("CNetServerWorker: enet_host_service failed (%d)", status);
		// TODO: notify game that the server has shut down
		return false;
	}

	if (status == 0)
	{
		// Reached timeout with no events - try again
		return true;
	}

	// Process the event:

	switch (event.type)
	{
	case ENET_EVENT_TYPE_CONNECT:
	{
		// Report the client address
		char hostname[256] = "(error)";
		enet_address_get_host_ip(&event.peer->address, hostname, ARRAY_SIZE(hostname));
		LOGMESSAGE("Net server: Received connection from %s:%u", hostname, (unsigned int)event.peer->address.port);

		// Set up a session object for this peer

		CNetServerSession* session = new CNetServerSession(*this, event.peer);

		m_Sessions.push_back(session);

		SetupSession(session);

		ENSURE(event.peer->data == NULL);
		event.peer->data = session;

		HandleConnect(session);

		break;
	}

	case ENET_EVENT_TYPE_DISCONNECT:
	{
		// If there is an active session with this peer, then reset and delete it

		CNetServerSession* session = static_cast<CNetServerSession*>(event.peer->data);
		if (session)
		{
			LOGMESSAGE("Net server: Disconnected %s", DebugName(session).c_str());

			// Remove the session first, so we won't send player-update messages to it
			// when updating the FSM
			m_Sessions.erase(remove(m_Sessions.begin(), m_Sessions.end(), session), m_Sessions.end());

			session->Update((uint)NMT_CONNECTION_LOST, NULL);

			delete session;
			event.peer->data = NULL;
		}

		break;
	}

	case ENET_EVENT_TYPE_RECEIVE:
	{
		// If there is an active session with this peer, then process the message

		CNetServerSession* session = static_cast<CNetServerSession*>(event.peer->data);
		if (session)
		{
			// Create message from raw data
			CNetMessage* msg = CNetMessageFactory::CreateMessage(event.packet->data, event.packet->dataLength, GetScriptInterface());
			if (msg)
			{
				LOGMESSAGE("Net server: Received message %s of size %lu from %s", msg->ToString().c_str(), (unsigned long)msg->GetSerializedLength(), DebugName(session).c_str());

				HandleMessageReceive(msg, session);

				delete msg;
			}
		}

		// Done using the packet
		enet_packet_destroy(event.packet);

		break;
	}

	case ENET_EVENT_TYPE_NONE:
		break;
	}

	return true;
}
示例#28
0
void NetClient::calc()
{
    ENetEvent event;

    if (me && server)
     while (enet_host_service(me, &event, 0) > 0) {

        char type = (event.type == ENET_EVENT_TYPE_RECEIVE)
                  ? (char) event.packet->data[0]
                  : LEMNET_NOTHING;

        if (event.type == ENET_EVENT_TYPE_CONNECT) {
            // Server shall check if protocols and versions match.
            send_welcome_data();
        }

        else if (event.type == ENET_EVENT_TYPE_DISCONNECT) {
            exit = true;
        }

        else if (type == LEMNET_DISCON_SILENT) {
            exit = true;
        }

        else if (type == LEMNET_WELCOME_DATA) {
            // The server sends out packets of this sort, but that only
            // happens to inform clients before 2009 Oct 25 of their very
            // old version. The server will probably stop that in some
            // months, and until then we simply ignore these.
        }

        else if (type == LEMNET_YOU_TOO_OLD
         ||      type == LEMNET_YOU_TOO_NEW) {
            const bool old = (type == LEMNET_YOU_TOO_OLD);
            if  (old) Console::push_back(Language::net_chat_we_too_old);
            else      Console::push_back(Language::net_chat_we_too_new);
            std::string msg = Language::net_chat_version_yours;
            msg += Help::version_to_string(gloB->version);
            msg += Language::net_chat_version_server;
            msg += Help::version_to_string(
                    get_uint32_from(event.packet->data + 2));
            msg += '.';
            Console::push_back(msg);
            if (old) Console::push_back(Language::net_chat_please_download);
            else     Console::push_back(Language::net_chat_server_update);
            // The server will throw us out.
        }

        else if (type == LEMNET_SOMEONE_OLD
         ||      type == LEMNET_SOMEONE_NEW) {
            int who_nr = event.packet->data[1];
            PlDatIt who = players.begin();
            while (who != players.end() && who->number != who_nr) ++who;

            if (type == LEMNET_SOMEONE_NEW) {
                Console::push_back(Language::net_chat_someone_new);
                Console::push_back(Language::net_chat_server_update);
            }
            // There exists someone with that number
            else if (who != players.end()) {
                std::string s = who->name + ' '
                              + Language::net_chat_named_guy_old;
                Console::push_back(s);
            }
            else Console::push_back(Language::net_chat_someone_old);
            // This is independent from new or old
            if (who != players.end()) {
                // reset player
                players.erase(who);
                set_nobody_ready();
                player_data_change = true;
            }
        }

        else if (type == LEMNET_RECHECK) {
            send_welcome_data();
        }

        else if (type == LEMNET_ASSIGN_NUMBER) {
            PlayerData pd(event.packet->data[2],
             gloB->user_name.c_str());
            // choose some color to get us started based on the player number
            // this might be already taken though by others, the code here
            // is just a very simple algorithm
            pd.style =
                pd.number % (LixEn::STYLE_MAX - LixEn::RED) + LixEn::RED;
            if (useR->network_last_style >= LixEn::RED
             && useR->network_last_style < LixEn::STYLE_MAX)
                pd.style = static_cast <char> (useR->network_last_style);
            // The lobby saves the style to useR->...

            players.clear();
            players.push_back(pd);
            ourself = players.begin();

            ENetPacket* p = pd.create_packet();
            enet_peer_send(server, LEMNET_CHANNEL_MAIN, p);
        }

        else if (type == LEMNET_ROOM_DATA) {
            rooms.clear();
            for (int room = 0; room < NETWORK_ROOMS_MAX; ++room)
             if (event.packet->data[2 + room] > 0) {
                RoomData rd;
                rd.number  = room;
                rd.members = event.packet->data[2 + room];
                rooms.insert(rd);
            }
            room_data_change = true;
        }

        else if (type == LEMNET_ROOM_CHANGE) {
            // Throw out all people other than us, because we'll soon receive
            // LEMNET_PLAYER_BEFORE packets for everyone in the new room.
            PlayerData temp_ourself = *ourself;
            players.clear();
            players.push_back(temp_ourself);
            ourself = players.begin();
            const char target_room = event.packet->data[2];
            if (ourself->room == -1)
             Console::push_back(Language::net_chat_we_connected);
            else if (target_room == 0)
             Console::push_back(Language::net_chat_we_in_lobby);
            else {
                std::ostringstream message;
                message << Language::net_chat_we_in_room
                        << (int) target_room
                        << Language::net_chat_we_in_room_2;
                Console::push_back(message.str());
            }
            ourself->room = target_room;
        }

        else if (type == LEMNET_PLAYER_DATA
         ||      type == LEMNET_PLAYER_BEFORE) {
            PlayerData pd;
            pd.read_from(event.packet);
            PlDatIt known = get_player(pd.number);

            // A new person has joined
            if (known == players.end()) {
                // Insert new data before the first higher data, so that
                // the players list is still sorted by operator <.
                PlDatIt insert_here = --players.end();
                while (insert_here != --players.begin()
                 && pd < *insert_here) --insert_here;
                players.insert(++insert_here, pd);
                set_nobody_ready();
                if (type == LEMNET_PLAYER_DATA) {
                    std::ostringstream message;
                    message << pd.name;
                    if (ourself->room == 0)
                        message << Language::net_chat_player_in_lobby;
                    else {
                        message << Language::net_chat_player_in_room;
                        message << (int) ourself->room;
                        message << Language::net_chat_player_in_room_2;
                    }
                    Console::push_back(message.str());
                    Sound::play_loud(Sound::JOIN);
                }
            }
            else {
                // Only the information about readiness doesn't set back
                // all ready states. Everything else does.
                // snr = set nobody ready
                bool dont_call_snr = *known == pd;
                known->ready  = !known->ready; // *known will be overwr. anyway
                dont_call_snr = dont_call_snr || *known == pd;
                *known = pd;
                if (!dont_call_snr) set_nobody_ready();
            }
            player_data_change = true;
        }

        else if (type == LEMNET_PLAYER_CLEAR
         ||      type == LEMNET_PLAYER_OUT_TO) {
            unsigned nr = event.packet->data[1];
            PlDatIt who = get_player(nr);
            if (who != players.end()) {
                std::ostringstream message;
                message << who->name;
                if (type == LEMNET_PLAYER_CLEAR) {
                    message << Language::net_chat_disconnection;
                }
                else {
                    int room = event.packet->data[2];
                    if (room == 0) {
                        message << Language::net_chat_player_out_lobby;
                    }
                    else {
                        message << Language::net_chat_player_out_room;
                        message << room;
                        message << Language::net_chat_player_out_room_2;
                    }
                }
                Console::push_back(message.str());
                players.erase(who);
                player_data_change = true;
                set_nobody_ready();
            }
        }

        else if (type == LEMNET_LEVEL_FILE) {
            set_nobody_ready();
            std::istringstream str((char*) event.packet->data + 2);
            level.load_from_stream(str);
            level_change = true;

            PlDatIt who = get_player(event.packet->data[1]);
            if (who != players.end()) {
                std::ostringstream msg;
                msg << who->name << ' ' << Language::net_chat_level_change
                    << ' ' << level.get_name();
                Console::push_back(msg.str());
            }
        }

        else if (type == LEMNET_CHAT_MESSAGE) {
            std::string message = (const char*) &event.packet->data[2];
            Console::push_back(message, true); // true = weiss
        }

        else if (type == LEMNET_GAME_START) {
            // Reset things to make it possible to play multiple games one
            // after another
            set_nobody_ready();
            replay_data.clear();
            permu = Permu(event.packet->data[2],(char*)event.packet->data + 3);

            // Jetzt aber... auf geht's!
            game_start = true;
            updates_change = 0;

            std::ostringstream start_message;
            start_message << Language::net_game_start;
            if (useR->key_chat > 0
             && useR->key_chat < KEY_MAX) {
                start_message << Language::net_game_how_to_chat_1;
                start_message << Help::scancode_to_string(useR->key_chat);
                start_message << Language::net_game_how_to_chat_2;
            }
            Console::push_back(start_message.str());
        }

        else if (type == LEMNET_GAME_END) {
            game_end = true;
            Console::push_back(Language::net_game_end);
        }

        else if (type == LEMNET_REPLAY_DATA) {
            // Only make available if we aren't the sender
            if (event.packet->data[1] != ourself->number) {
                ReplayData data;
                data.read_from(event.packet);
                replay_data.push_back(data);
            }
        }

        else if (type == LEMNET_UPDATES) {
            updates_change = get_uint32_from(&event.packet->data[2]);
        }

        if (event.type == ENET_EVENT_TYPE_RECEIVE)
         enet_packet_destroy(event.packet);
    }
}
示例#29
0
// called from ---GUI--- thread
NetPlayClient::NetPlayClient(const std::string& address, const u16 port, NetPlayUI* dialog,
                             const std::string& name, bool traversal,
                             const std::string& centralServer, u16 centralPort)
    : m_dialog(dialog), m_player_name(name)
{
  ClearBuffers();

  if (!traversal)
  {
    // Direct Connection
    m_client = enet_host_create(nullptr, 1, 3, 0, 0);

    if (m_client == nullptr)
    {
      PanicAlertT("Couldn't Create Client");
    }

    ENetAddress addr;
    enet_address_set_host(&addr, address.c_str());
    addr.port = port;

    m_server = enet_host_connect(m_client, &addr, 3, 0);

    if (m_server == nullptr)
    {
      PanicAlertT("Couldn't create peer.");
    }

    ENetEvent netEvent;
    int net = enet_host_service(m_client, &netEvent, 5000);
    if (net > 0 && netEvent.type == ENET_EVENT_TYPE_CONNECT)
    {
      if (Connect())
      {
        m_client->intercept = ENetUtil::InterceptCallback;
        m_thread = std::thread(&NetPlayClient::ThreadFunc, this);
      }
    }
    else
    {
      PanicAlertT("Failed to Connect!");
    }
  }
  else
  {
    if (address.size() > NETPLAY_CODE_SIZE)
    {
      PanicAlertT("Host code size is to large.\nPlease recheck that you have the correct code");
      return;
    }

    if (!EnsureTraversalClient(centralServer, centralPort))
      return;
    m_client = g_MainNetHost.get();

    m_traversal_client = g_TraversalClient.get();

    // If we were disconnected in the background, reconnect.
    if (m_traversal_client->m_State == TraversalClient::Failure)
      m_traversal_client->ReconnectToServer();
    m_traversal_client->m_Client = this;
    m_host_spec = address;
    m_connection_state = ConnectionState::WaitingForTraversalClientConnection;
    OnTraversalStateChanged();
    m_connecting = true;

    Common::Timer connect_timer;
    connect_timer.Start();

    while (m_connecting)
    {
      ENetEvent netEvent;
      if (m_traversal_client)
        m_traversal_client->HandleResends();

      while (enet_host_service(m_client, &netEvent, 4) > 0)
      {
        sf::Packet rpac;
        switch (netEvent.type)
        {
        case ENET_EVENT_TYPE_CONNECT:
          m_server = netEvent.peer;
          if (Connect())
          {
            m_connection_state = ConnectionState::Connected;
            m_thread = std::thread(&NetPlayClient::ThreadFunc, this);
          }
          return;
        default:
          break;
        }
      }
      if (connect_timer.GetTimeElapsed() > 5000)
        break;
    }
    PanicAlertT("Failed To Connect!");
  }
}
示例#30
0
文件: server.c 项目: Cloudef/nethck
/* \brief update enet state internally */
static int _nethckEnetUpdate(void)
{
   __NETHCKclient client;
   ENetEvent event;
   unsigned int packets = 0;
   TRACE(2);

   /* wait up to 1000 milliseconds for an event */
   while (enet_host_service(_NETHCKserver.enet, &event, 1000) > 0) {
      switch (event.type) {
         case ENET_EVENT_TYPE_CONNECT:
            printf("A new client connected from %x:%u.\n",
                  event.peer->address.host,
                  event.peer->address.port);

            /* fill new client struct */
            memset(&client, 0, sizeof(__NETHCKclient));
            enet_address_get_host_ip(&event.peer->address, client.host, sizeof(client.host));
            event.peer->data = _nethckServerNewClient(&client);
            break;

         case ENET_EVENT_TYPE_RECEIVE:
            /* manage packet by kind */
            printf("A packet of length %zu was received on channel %u.\n",
                  event.packet->dataLength, event.channelID);
            printf("ID: %d\n", ((nethckPacket*)event.packet->data)->type);
            switch (((nethckPacket*)event.packet->data)->type) {
               case NETHCK_PACKET_OBJECT:
                  _nethckServerManagePacketObject(event.packet->data);
                  break;
               case NETHCK_PACKET_OBJECT_TRANSLATION:
               case NETHCK_PACKET_OBJECT_MATERIAL:
               case NETHCK_PACKET_OBJECT_TEXTURE:
               default:
                  break;
            }

            /* echo the packet to clients */
            enet_host_broadcast(_NETHCKserver.enet, 0, event.packet);

            /* clean up the packet now that we're done using it. */
            //enet_packet_destroy(event.packet);
            break;

         case ENET_EVENT_TYPE_DISCONNECT:
            printf("%s disconected.\n", ((__NETHCKclient*)event.peer->data)->host);

            /* free the client */
            _nethckServerFreeClient(event.peer->data);
            event.peer->data = NULL;
            break;

         default:
            break;
      }
      ++packets;
   }

   RET(2, "%u", packets);
   return packets;
}