Ejemplo n.º 1
0
/* returns >= 0 if action/size has been set to a valid action
   returns -1 for failure (disconnect, timeout, too many bad actions, etc) */
static int readPlayerResponse( const Game *game,
			       const MatchState *state,
			       const int quiet,
			       const uint8_t seat,
			       const struct timeval *sendTime,
			       ErrorInfo *errorInfo,
			       ReadBuf *readBuf,
			       Action *action,
			       struct timeval *recvTime )
{
  int c, r;
  MatchState tempState;
  char line[ MAX_LINE_LEN ];

  while( 1 ) {

    /* read a line of input from player */
    struct timeval start;
    gettimeofday( &start, NULL );
    if( getLine( readBuf, MAX_LINE_LEN, line,
		 errorInfo->maxResponseMicros ) <= 0 ) {
      /* couldn't get any input from player */

      struct timeval after;
      gettimeofday( &after, NULL );
      uint64_t micros_spent =
	(uint64_t)( after.tv_sec - start.tv_sec ) * 1000000
	+ ( after.tv_usec - start.tv_usec );
      fprintf( stderr, "ERROR: could not get action from seat %"PRIu8"\n",
	       seat + 1 );
      // Print out how much time has passed so we can see if this was a
      // timeout as opposed to some other sort of failure (e.g., socket
      // closing).
      fprintf( stderr, "%.1f seconds spent waiting; timeout %.1f\n",
	       micros_spent / 1000000.0,
	       errorInfo->maxResponseMicros / 1000000.0);
      return -1;
    }

    /* note when the message arrived */
    gettimeofday( recvTime, NULL );

    /* log the response */
    if( !quiet ) {
      fprintf( stderr, "FROM %d at %zu.%06zu %s", seat + 1,
	       recvTime->tv_sec, recvTime->tv_usec, line );
    }

    /* ignore comments */
    if( line[ 0 ] == '#' || line[ 0 ] == ';' ) {
      continue;
    }

    /* check for any timeout issues */
    if( checkErrorTimes( seat, sendTime, recvTime, errorInfo ) < 0 ) {

      fprintf( stderr, "ERROR: seat %"PRIu8" ran out of time\n", seat + 1 );
      return -1;
    }

    /* parse out the state */
    c = readMatchState( line, game, &tempState );
    if( c < 0 ) {
      /* couldn't get an intelligible state */

      fprintf( stderr, "WARNING: bad state format in response\n" );
      continue;
    }

    /* ignore responses that don't match the current state */
    if( !matchStatesEqual( game, state, &tempState ) ) {

      fprintf( stderr, "WARNING: ignoring un-requested response\n" );
      continue;
    }

    /* get the action */
    if( line[ c++ ] != ':'
	|| ( r = readAction( &line[ c ], game, action ) ) < 0 ) {

      if( checkErrorInvalidAction( seat, errorInfo ) < 0 ) {

	fprintf( stderr, "ERROR: bad action format in response\n" );
      }

      fprintf( stderr,
	       "WARNING: bad action format in response, changed to call\n" );
      action->type = a_call;
      action->size = 0;
      goto doneRead;
    }
    c += r;

    /* make sure the action is valid */
    if( !isValidAction( game, &state->state, 1, action ) ) {

      if( checkErrorInvalidAction( seat, errorInfo ) < 0 ) {

	fprintf( stderr, "ERROR: invalid action\n" );
	return -1;
      }

      fprintf( stderr, "WARNING: invalid action, changed to call\n" );
      action->type = a_call;
      action->size = 0;
    }

    goto doneRead;
  }

 doneRead:
  return 0;
}
Ejemplo n.º 2
0
/* returns >= 0 if action/size has been set to a valid action
   returns -1 for failure (disconnect, timeout, too many bad actions, etc) */
static int readPlayerResponse( const Game *game, const MatchState *state,
			       const int quiet, const uint8_t seat,
			       const struct timeval *sendTime,
			       ErrorInfo *errorInfo,
			       int seatFD, ReadBuf *readBuf,
			       Action *action, struct timeval *recvTime )
{
  int c, r;
  MatchState tempState;
  char line[ MAX_LINE_LEN ];

  while( 1 ) {

    /* read a line of input from player */
    if( getLine( seatFD, readBuf, MAX_LINE_LEN, line,
		 errorInfo->maxResponseMicros ) <= 0 ) {
      /* couldn't get any input from player */

      fprintf( stderr, "ERROR: could not get action from seat %"PRIu8"\n",
	       seat + 1 );
      return -1;
    }

    /* note when the message arrived */
    gettimeofday( recvTime, NULL );

    /* log the response */
    if( !quiet ) {
      fprintf( stderr, "FROM %d at %zu.%06zu %s", seat + 1,
	       recvTime->tv_sec, recvTime->tv_usec, line );
    }

    /* ignore comments */
    if( line[ 0 ] == '#' || line[ 0 ] == ';' ) {
      continue;
    }

    /* check for any timeout issues */
    if( checkErrorTimes( seat, sendTime, recvTime, errorInfo ) < 0 ) {

      fprintf( stderr, "ERROR: seat %"PRIu8" ran out of time\n", seat + 1 );
      return -1;
    }

    /* parse out the state */
    c = readMatchState( line, game, &tempState );
    if( c < 0 ) {
      /* couldn't get an intelligible state */

      fprintf( stderr, "WARNING: bad state format in response\n" );
      continue;
    }

    /* ignore responses that don't match the current state */
    if( !matchStatesEqual( game, state, &tempState ) ) {

      fprintf( stderr, "WARNING: ignoring un-requested response\n" );
      continue;
    }

    /* get the action */
    if( line[ c++ ] != ':'
	|| ( r = readAction( &line[ c ], game, action ) ) < 0 ) {

      if( checkErrorInvalidAction( seat, errorInfo ) < 0 ) {

	fprintf( stderr, "ERROR: bad action format in response\n" );
      }

      fprintf( stderr,
	       "WARNING: bad action format in response, changed to call\n" );
      action->type = call;
      action->size = 0;
      goto doneRead;
    }
    c += r;

    /* make sure the action is valid */
    if( !isValidAction( game, &state->state, 1, action ) ) {

      if( checkErrorInvalidAction( seat, errorInfo ) < 0 ) {

	fprintf( stderr, "ERROR: invalid action\n" );
	return -1;
      }

      fprintf( stderr, "WARNING: invalid action, changed to call\n" );
      action->type = call;
      action->size = 0;
    }

    goto doneRead;
  }

 doneRead:
  return 0;
}