/* $Log:	input.c,v $
 * Revision 1.4  92/03/19  21:34:40  terence
 * Added UDP mods (version 0.2, 3/17/92)
 * 
 * Revision 1.3  92/03/11  23:36:50  terence
 * added Tedd Hadley's snippet fix:
 * 
 *         FD_ZERO(&readfds);
 *         FD_SET(sock, &readfds);
 *         if (udpSock >= 0)
 *                 FD_SET(udpSock, &readfds);
 *         if (select(32, &readfds, 0, 0, &timeout) != 0) {
 *             readFromClient();
 *         }
 * 
 * Revision 1.2  92/03/11  15:53:31  terence
 * added UDP mods
 *  */

/*
 * input.c
 */
#include "copyright.h"

#include <stdio.h>
#include <math.h>
#include <sys/param.h>
#ifdef SCO
#include <sys/itimer.h>
#else
#include <sys/time.h>
#endif
#include <sys/types.h>
#include <signal.h>
#include <errno.h>
#include "defs.h"
#include INC_SYS_SELECT
#include "struct.h"
#include "data.h"

#define GHOSTTIME       (30 * 1000000 / UPDATE) /* 30 secs */

static int sendflag=0;
static int do_update =1;

void setflag()
{

HANDLE_SIG(SIGALRM,setflag);

  if (do_update)
    intrupt();
  else 	
    sendflag=1;

  if (me->p_updates > delay) {
    me->p_flags &= ~(PFWAR);
  }
  if (me->p_updates > rdelay) {
    me->p_flags &= ~(PFREFITTING);
  }
#ifdef PING             /* this will ghostbust a player if
                           no ping has been received in 5 seconds */
     if(ping_allow_ghostbust && me->p_status == PALIVE && ping_ghostbust >
        ping_ghostbust_interval){
        /* ghostbusted */
        me->p_ghostbuster = GHOSTTIME;
	ping_ghostbust = 0;
	ERROR(2,("GHOSTBUSTED from ping: %c%c: %s@%s\n", me->p_mapchars[0],
                                                       me->p_mapchars[1],
                                                       login, host));
        fflush(stderr);
     }
     else
#endif /*PING*/

  me->p_ghostbuster = 0;
}

resurrect()
{
  register int i;

  SIGNAL(SIGALRM, SIG_IGN);
#ifndef SCO /* SCO doesn't have SIGIO, so why bother ignoring it? */
  SIGNAL(SIGIO, SIG_IGN);
#endif

  if (!testtime) {
      ERROR(2,("input.c/resurrect: The client went away! (%s@%s)\n",
	me->p_login,
	me->p_monitor));
      ERROR(2,("input.c/resurrect: I will attempt to resurrect him!\n"));
  }

  commMode = COMM_TCP;
  if (udpSock >= 0)
      closeUdpConn();

  /* For next two minutes, we try to restore connection */
  shutdown(sock, 2);
  sock= -1;
  for (i=0;; i++) {
    me->p_ghostbuster = 0;
    if (testtime == 1)
	sleep(1);
    else
	sleep(5);
    if (connectToClient(host, nextSocket)) break;
    if (((i>=5) && testtime) || ((i>=23) && (!testtime))) {
	ERROR(2,("input.c: Oh well, maybe I'm getting rusty! (%s@%s) exits\n",
		me ->p_login, me->p_monitor));
	freeslot(me);
	exit(0);
    }
  }
  if (testtime) {
   	me->p_whydead = KQUIT;
     	me->p_status = PEXPLODE;
     	ERROR(3,("User attempted to used old reserved.c"));
     	new_warning(UNDEF,"Only RSA clients are valid. Please use a blessed one.");
  }
  else {
	ERROR(2,("input.c/resurrect: A miracle! He's Alive!\n"));
	testtime = -1;	/* Do verification after GB  - NBT */
  }
  SIGNAL(SIGALRM, setflag);
  return 1;
}

input()
{
    fd_set readfds;
    static struct timeval    poll = {2, 0};	

    SIGNAL(SIGALRM, setflag);

    /* Idea:  read from client often, send to client not so often */
    while (1) {
	if (isClientDead()) {
	    if (noressurect){
		freeslot(me);
		exit(0);
	    }
	    resurrect();
	}
	if (! status -> gameup){
	    freeslot(me);
	    exit(0);
	}
        FD_ZERO(&readfds);
        FD_SET(sock, &readfds);
        if (udpSock >= 0)
                FD_SET(udpSock, &readfds);
	poll.tv_sec=2;
	poll.tv_usec=0;
	if (select(32, &readfds, 0, 0, &poll) > 0) {
	    do_update = 0;
#ifdef PING                     /* reset this here also */
            ping_ghostbust = 0;
#endif

	    if (me->p_updates > delay) {
	        me->p_flags &= ~(PFWAR);
	    }
	    if (me->p_updates > rdelay) {
	        me->p_flags &= ~(PFREFITTING);
	    }

	    readFromClient();
	    if (sendflag) {
	      intrupt();
	      sendflag=0;
	    }
	    do_update = 1;
	}

    }
}


