예제 #1
0
/*!
 * Main loop of the internet protocol service
 */
void
serve_clients_internet_protocol (global_status_type * global_status,
				 global_option_type * global_option)
{

  int player_index;

  for (player_index = 0; player_index < MAX_NUMBER_PLAYER; player_index++)
    {
      global_status->next_frame_to_send[player_index] = 1;
      global_status->input_value[player_index] = 0;
    }

  /* Allocate memory for the history */
  init_internet_history ();

  /* Prepare memory releasing at the end of the program */
  atexit (release_internet_history);

  init_frame_status (global_status, global_option);

  global_status->start_time =
    (double) SDL_GetTicks () / (double) SDL_TICKS_PER_SECOND;

  for (;;)
    {

#if defined(DEBUG)
      fprintf (stderr,
	       "Waiting for status packets while preparing frame %u\ntime = %u\n",
	       global_status->frame_number, SDL_GetTicks ());
#endif

      /* Let packets accumulate for a short amount of time */
      SDL_Delay (get_remaining_time (global_status));

#if defined(DEBUG)
      fprintf (stderr, "Finished sleeping, time = %u\n", SDL_GetTicks ());
#endif

      while (read_incoming_server_packet (global_status) != 0)
	{

#if defined(DEBUG)
	  fprintf (stderr, "Got a packet\n");
#endif

	  /* Stores the incoming status */
	  store_remote_status_internet (global_status, global_option);
	}

      send_internet_digest (global_status, global_option);

    }

  /* While the above loop is infinite, this won't be called */
  release_internet_history ();

}
예제 #2
0
/*!
 * Main loop of the lan protocol service
 */
void
serve_clients_lan_protocol (global_status_type * global_status,
			    global_option_type * global_option)
{

  init_frame_status (global_status, global_option);

  for (;;)
    {
      int number_ready_socket;

#if defined(DEBUG)
      fprintf (stderr, "Waiting for status packets for frame %u\n",
	       global_status->frame_number);
#endif

      number_ready_socket =
        SDLNet_CheckSockets (global_status->server_socket_set,
			     SERVER_SOCKET_TIMEOUT);

      if (number_ready_socket == -1)
	{
	  fprintf (stderr, "Error in socket waiting (disconnection ?).\n");
	  break;
	}

      if (number_ready_socket == 1)
	{

#if defined(DEBUG)
	  fprintf (stderr, "Got a packet\n");
#endif

	  /* We're awaiting a packet in the server socket */
	  if (read_incoming_server_packet (global_status))
	    {
	      /* Stores the incoming status and updates clients status accordingly */
	      store_remote_status_lan (global_status, global_option);

	      /* Sends packet (if needed) to client accordingly to their status */
	      send_digest_lan_packets (global_status, global_option);
	    }

	}

    }
}
예제 #3
0
/*!
 * main loop. Accept contribution from clients and dispatch digest of
 * the frame to all clients
 */
void
serve_dispatch (global_option_type * global_option)
{

  global_status_type global_status;
  int client_index;

  /*
   * Initialize global_status fields
   */
  global_status.frame_number = 1;
  global_status.number_identified_players = 0;
  global_status.number_allocation_request = 0;
#if defined(GTK)
	gtk_stop_asked = 0;
#endif

  for (client_index = 0; client_index < MAX_NUMBER_PLAYER; client_index++)
    {
      global_status.player_status[client_index] = UNIDENTIFIED;
    }

  global_status.server_socket = SDLNet_UDP_Open (global_option->server_port);
  if (global_status.server_socket == NULL)
    {
      printf_screen ("Couldn't open UDP socket on port %d.\nCheck privileges and availability.\n",
		     global_option->server_port);
      return;
    }

  /* global_status.server_socket is ready to serve our needs :) */

  global_status.current_packet = SDLNet_AllocPacket (CLIENT_PACKET_SIZE);

  if (global_status.current_packet == NULL)
    {
      SDLNet_UDP_Close (global_status.server_socket);
      printf_screen ("Failed to allocate a buffer for receiving client packets (size: %d bytes) (Not enough memory ?)",
		     CLIENT_PACKET_SIZE);
      return;
    }

  global_status.digest_packet = SDLNet_AllocPacket (SERVER_PACKET_SIZE);

  if (global_status.digest_packet == NULL)
    {
      SDLNet_UDP_Close (global_status.server_socket);
      SDLNet_FreePacket (global_status.digest_packet);
      printf_screen ("Failed to allocate a buffer for sending packets (size: %d bytes) (Not enough memory ?)",
		     SERVER_PACKET_SIZE);
      return;
    }

  /* Allocate enough space for a single socket */
  global_status.server_socket_set = SDLNet_AllocSocketSet (1);

  if (global_status.server_socket_set == NULL)
    {
      SDLNet_UDP_Close (global_status.server_socket);
      SDLNet_FreePacket (global_status.current_packet);
      SDLNet_FreePacket (global_status.digest_packet);
      printf_screen ("Couldn't allocate a socket set (not enough memory ?).\n");
      return;
    }

  if (SDLNet_UDP_AddSocket (global_status.server_socket_set, global_status.server_socket) !=
      1)
    {
      SDLNet_UDP_Close (global_status.server_socket);
      SDLNet_FreePacket (global_status.current_packet);
      SDLNet_FreePacket (global_status.digest_packet);
      SDLNet_FreeSocketSet (global_status.server_socket_set);
      printf_screen ("Error when adding socket to socket set.\n");
      return;
    }

  /* Identification loop */

  /*
   * We're expecting identification packets until we've filled all slots, then
   * we can proceed to the real meat
   */

  for (;;)
    {

      int number_ready_socket;

#if defined(DEBUG)
      printf_screen ("Waiting for identification\n");
#endif

      
      if (read_incoming_server_packet (&global_status))
	{
	  identify_client (&global_status, global_option);
	  
	  if (count_remaining_slot (&global_status, global_option) == 0)
	    {
	      /* Perfect, we've finished the identification of all slots */
	      break;
	    }
	  
	  printf_screen("%d slots open.\n", count_remaining_slot (&global_status, global_option));
	  
	  /* Going back to the identification loop */
	  continue;
	  
	}

#if defined(GTK)

      gtk_iteration = GTK_SERVER_SOCKET_RATIO;

      do {
	number_ready_socket =
	  SDLNet_CheckSockets (global_status.server_socket_set, SERVER_SOCKET_TIMEOUT / GTK_SERVER_SOCKET_RATIO);
	  
	while (gtk_events_pending())
	{
	  if (gtk_main_iteration())
	  {
	  	gtk_stop_asked = 1;
	  }
	}
      } while ( (number_ready_socket == 0) && (--gtk_iteration != 0) && !gtk_stop_asked);
#else

      number_ready_socket =
	SDLNet_CheckSockets (global_status.server_socket_set, SERVER_SOCKET_TIMEOUT);      

#endif

	if (gtk_stop_asked)
	{
		break;
	}

      if (number_ready_socket == -1)
	{
	  printf_screen ("Error in socket waiting (disconnection ?).\n");
	  break;
	}

      if (number_ready_socket == 1)
	{

#if defined(DEBUG)
	  printf_screen ("Got a packet\n");
#endif

	  /* We're awaiting a packet in the server socket */
	  if (read_incoming_server_packet (&global_status))
	    {

	      /*
	       * If we haven't identified all clients yet, we're trying to use the current packet
	       * to improve our knowledge of the typography
	       */
	      identify_client (&global_status, global_option);
	      
	      if (count_remaining_slot (&global_status, global_option) == 0)
		{
		  /* Perfect, we've finished the identification of all slots */
		  break;
		}

	      printf_screen("%d slots open.\n", count_remaining_slot (&global_status, global_option));

	    }
    }

	
	}

	if (!gtk_stop_asked)
	{

  printf_screen ("Identification finished\n");

#if defined(DEBUG)
  for (client_index = 0; client_index < MAX_NUMBER_PLAYER; client_index++)
    {
      printf_screen ("Mapping[%d] = { { 0x%08X, %d }, %d }\n", client_index,
		     global_status.input_mapping[client_index].address.host,
		     global_status.input_mapping[client_index].address.port,
		     global_status.input_mapping[client_index].remote_input_device);
    }
#endif

  switch (global_option->type_server)
    {
    case LAN_PROTOCOL_TYPE:
      serve_clients_lan_protocol(&global_status, global_option);
      break;
    case INTERNET_PROTOCOL_TYPE:
      serve_clients_internet_protocol(&global_status, global_option);
      break;
    default:
      printf_screen("Internal error, unknown internal server type : %d\n", global_option->type_server);
      break;
    }
  } // gtk_stop_asked
      
  /*
   * Free resources
   */
  SDLNet_FreePacket (global_status.current_packet);
  SDLNet_FreePacket (global_status.digest_packet);
  SDLNet_FreeSocketSet (global_status.server_socket_set);
  SDLNet_UDP_Close (global_status.server_socket);
  global_status.server_socket = NULL;

}