lotos123/
lotos123/datafiles/conffiles/
lotos123/datafiles/counters/
lotos123/datafiles/fonts/
lotos123/datafiles/helpfiles/
lotos123/datafiles/killmsgs/
lotos123/datafiles/mapfiles/
lotos123/datafiles/motds/motd1/
lotos123/datafiles/motds/motd2/
lotos123/datafiles/pictfiles/
lotos123/datafiles/plfiles/
lotos123/datafiles/plfiles/helpfiles/
lotos123/datafiles/screens/
lotos123/datafiles/textfiles/
lotos123/datafiles/trfiles/
lotos123/datafiles/votefiles/
lotos123/datafiles/votefiles/1/
lotos123/datafiles/votefiles/2/
lotos123/src/plugins/
lotos123/userfiles/
lotos123/userfiles/bin/
/* vi: set ts=4 sw=4 ai: */
/*
 * s_events.c
 *
 *   Lotos v1.2.3  : (c) 1999-2003 Pavol Hluchy (Lopo)
 *   last update   : 30.1.2003
 *   email         : lotos@losys.sk
 *   homepage      : lotos.losys.sk
 */

#ifndef __S_EVENTS_C__
#define __S_EVENTS_C__ 1

#include <unistd.h>
#include <time.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>

#include "define.h"
#include "prototypes.h"
#include "obj_sys.h"
#include "obj_syspp.h"
#include "s_events.h"


void do_events(int sig)
{
	set_crash();
	set_date_time();
	check_reboot_shutdown();
	check_idle_and_timeout();
#ifdef NETLINKS
	check_nethangs_send_keepalives(); 
#endif
	check_messages(NULL,0);
	reset_alarm();
	transport();
	plugin_triggers(NULL, "");
	check_alarm();
	if (syspp->auto_save!=(-1))
		check_autosave();
	check_credit_updates();
	check_lynx();
	check_pings();
}


/*** Set global vars. hours,minutes,seconds,date,day,month,year ***/
void set_date_time(void)
{
	struct tm *tm_struct; /* structure is defined in time.h */
	time_t tm_num;

	set_crash();
/* Set up the structure */
	time(&tm_num);
	tm_struct=localtime(&tm_num);

/* Get the values */
	tday=tm_struct->tm_yday;
	tyear=1900+tm_struct->tm_year; /* Will this work past the year 2000? Hmm... */
	tmonth=tm_struct->tm_mon;
	tmday=tm_struct->tm_mday;
	twday=tm_struct->tm_wday;
	thour=tm_struct->tm_hour;
	tmin=tm_struct->tm_min;
	tsec=tm_struct->tm_sec; 
}


/*** See if timed reboot or shutdown is underway ***/
void check_reboot_shutdown(void)
{
	int secs;
	char *w[]={ "~FRVypnutie","~FYRestart" };

	set_crash();
if (amsys->rs_user==NULL) return;
amsys->rs_countdown-=amsys->heartbeat;
if (amsys->rs_countdown<=0) talker_shutdown(amsys->rs_user,NULL,amsys->rs_which);

/* Print countdown message every minute unless we have less than 1 minute
   to go when we print every 10 secs */
secs=(int)(time(0)-amsys->rs_announce);
if (amsys->rs_countdown>=60 && (secs>=60 || amsys->rs_countdown%60==0)) {
  vwrite_room(NULL, "~OLSYSTEM: %s za %d minut%s, %d sekund%s.\n",
	  w[amsys->rs_which], amsys->rs_countdown/60, grm_num(1, amsys->rs_countdown/60),
	  amsys->rs_countdown%60, grm_num(1, amsys->rs_countdown%60));
  amsys->rs_announce=time(0);
  }
if (amsys->rs_countdown<60 && (secs>=10 || amsys->rs_countdown<=10)) {
  vwrite_room(NULL,"~OLSYSTEM: %s za %d sekund%s.\n",w[amsys->rs_which],amsys->rs_countdown,grm_num(1, amsys->rs_countdown));
  amsys->rs_announce=time(0);
  }
}


/*** login_time_out is the length of time someone can idle at login, 
     user_idle_time is the length of time they can idle once logged in. 
     Also ups users total login time. ***/
void check_idle_and_timeout(void)
{
	UR_OBJECT user=user_first,next;
	int tm;

	set_crash();
/* Use while loop here instead of for loop for when user structure gets
   destructed, we may lose ->next link and crash the program */
	while (user) {
		next=user->next;
		if (user->type==CLONE_TYPE) {  user=next;  continue;  }
		user->total_login+=amsys->heartbeat; 
		if (user->level>amsys->time_out_maxlevel) {  user=next;  continue;  }
		tm=(int)(time(0) - user->last_input);
		if (user->login && tm>=amsys->login_idle_time) {
			write_user(user, login_timeout);
			disconnect_user(user);
			user=next;
			continue;
			}
		if (syspp->auto_afk
		    && tm>=syspp->auto_afk_time
		    && !user->afk
		    && !user->login) {
			afk(user, auto_afk_mesg);
			user=next;
			continue;
			}
		if (user->warned) {
			if (tm<amsys->user_idle_time-60) {  user->warned=0;  continue;  }
			if (tm>=amsys->user_idle_time) {
				write_user(user,"\n\n\07~FR~OL~LI*** You have been timed out. ***\n\n");
				disconnect_user(user);
				user=next;
				continue;
				}
			}
		if ((!user->afk || (user->afk && amsys->time_out_afks)) 
		    && !user->login 
		    && !user->warned
		    && tm>=amsys->user_idle_time-60) {
#ifdef PUEBLO
			audioprompt(user, 4, 0);
#endif
			vwrite_user(user,"\n\07~FY~OL~LI*** POZOR - Mas 1 minutu aby si nieco napisal%s lebo ta vydrbkam !***\n\n", grm_gnd(4, user->gender));
			user->warned=1;
			}
		user=next;
		}
}


void reset_alarm(void)
{
	set_crash();
	SIGNAL(SIGALRM,do_events);
	alarm(amsys->heartbeat);
}


void check_alarm(void)
{
	UR_OBJECT user=user_first, next;

	set_crash();
	while (user) {
		next=user->next;
		if (user->alarm) {
			if (user->atime) user->atime-=amsys->heartbeat;
			if (user->atime<=0)
				vwrite_user(user, "%s~FR~OLBudik ti zvoni !!!~RS (vypnes ho '.alarm stop')\n",
					(user->ignore.beeps)?"":"\07");
			}
		user=next;
		}
}


void check_autosave(void)
{
	set_crash();
	syspp->autosave+=amsys->heartbeat;
	if (syspp->autosave>=(syspp->auto_save*60)) {
		force_save(NULL);
		write_duty(GOD, "Automatic saved user's details\n", NULL, NULL, 0);
		syspp->autosave=0;
		}
}

void check_lynx(void)
{
	UR_OBJECT user=user_first, next;
	pid_t pid;
	char fname[FNAME_LEN];

	set_crash();
	while (user) {
		next=user->next;
		if (user->lynx) {
			sprintf(fname, "%s/%s.lynx", TEMPFILES, user->name);
			pid=waitpid(user->lynx, (int *) NULL, WNOHANG);
			if (pid==user->lynx) {
				user->lynx=0;
				write_user(user, "~CTpozadovana www stranka:\n");
				switch (more(user, user->socket, fname)) {
					case 0: write_user(user, "nemozem najst nacitanu stranku"); break;
					case 1: user->misc_op=2; break;
					}
				}
			else if (pid==-1) {
				write_user(user, "chyba pri nacitavani dokumentu\n");
				}
			}
		user=next;
		}
}

void check_pings(void)
{
	UR_OBJECT user=user_first, next;

	while (user) {
		next=user->next;
		if (user->type==CLONE_TYPE || user->type==BOT_TYPE) {
			user=next;
			continue;
			}
		if (!user->next_ping || user->next_ping<-1) {
			user->next_ping=-1;
			ping_timed(user);
			}
		if (user->next_ping>0) user->next_ping-=amsys->heartbeat;
		else if (user->next_ping<-1) user->next_ping=PINGINTERVAL;
		user=next;
		}
}

#endif /* __S_EVENTS_C__ */