/************************************************************************ * timing.c : launch operations that happen each clock tick, and * * set open_state boolean to correct status, based on the "hours" * * file which governs the operational hours of the mud * ***********************************************************************/ #include <sys/signal.h> #include <sys/time.h> #include <errno.h> #include <sys/stat.h> #include <unistd.h> #include "kernel.h" #include "mobile.h" #include "climate.h" #include "move.h" #include "timing.h" #include "bprintf.h" #include "sendsys.h" #include "log.h" #include "fight.h" #include "mud.h" #include "locations.h" #include "objects.h" #include "idlookup.h" #include "client.h" #include "wizard.h" #define SECS_IN_A_MIN 60 #define SECS_IN_AN_HOUR (SECS_IN_A_MIN*60) #define SECS_IN_A_DAY (SECS_IN_AN_HOUR*24) #define SECS_IN_A_WEEK (SECS_IN_A_DAY*7) extern void storeplayers(void); #ifdef _NETBSD_ extern const char *sys_errlist[]; #elseif _OLD_LINUX_ extern char *sys_errlist[]; #endif #ifdef IO_STATS extern int bytes_read; extern int bytes_sent; extern int sock_conns; extern int cut_conns; extern int unres_hosts; #endif extern int aberfd; extern int dnsfd; extern Boolean auto_restart; char *time2ascii (time_t t) { static char timestr[30]; if (t == 0) t = global_clock; strcpy(timestr, ctime(&t)); *strchr(timestr, '\n') = 0; return(timestr); } /* The TIME command. List game time elapsed, current time, last reset */ void timecom (void) { bprintf ("Elapsed Time : "); eltime (); bprintf ("Current Time : %s\n", time2ascii (TIME_CURRENT)); bprintf ("Last Reset : %s", ctime (&last_reset)); } void uptimecom (void) { bprintf ("Elapsed Time : %s\n", sec_to_str (global_clock-last_startup)); bprintf ("Been Up Since : %s", ctime (&last_startup)); bprintf ("AberChat Status : %s\n", (aberfd != -1) ? "Operational": "Down"); #ifdef IO_STATS if (plev(mynum) > LVL_WIZARD) { bprintf ("Unresolved hosts : %d [DNS Server: %s]\n", unres_hosts, dnsfd != -1 ? "Operational" : "Down"); bprintf ("Bytes [in/out] : %d / %d\n", bytes_read, bytes_sent); bprintf ("Connects [cut/total] : %d / %d\n", cut_conns, sock_conns); } #endif bprintf ("Number of Resets : %d\n", numresets); bprintf ("Number of Reboots : %d\n", numreboots); bprintf ("Recovered Crashes : %d\n", numcrashes); } /* Prints the game time elapsed */ void eltime (void) { long int et = global_clock - last_reset; if (et > SECS_IN_A_DAY) bprintf ("&+WOver a day!"); else bprintf ("&+W%s", sec_to_str (et)); bprintf ("\n"); } /* Takes a number of seconds as input and converts this to seconds, * minutes, hours, days, which is returned if the pointers != NULL. */ static void split_time (long int sec, int *secs, int *min, int *hrs, int *days) { int s = 0, m = 0, h = 0, d = 0; if (sec >= SECS_IN_A_DAY) { d = sec / SECS_IN_A_DAY; sec -= d * SECS_IN_A_DAY; } if (sec >= SECS_IN_AN_HOUR) { h = sec / SECS_IN_AN_HOUR; sec -= h * SECS_IN_AN_HOUR; } if (sec >= SECS_IN_A_MIN) { m = sec / SECS_IN_A_MIN; sec -= m * SECS_IN_A_MIN; } s = sec; /* Assign return values: */ if (secs != NULL) *secs = s; if (min != NULL) *min = m; if (hrs != NULL) *hrs = h; if (days != NULL) *days = d; } /* Takes a number of seconds as input and returns a pointer to a string * containing the amount of time in english, ex: "2 hours, 3 minutes"..etc.. */ char *sec_to_str (long int seconds) { static char str[50]; int sec, min, hrs, days; char aux[15]; *str = '\0'; split_time (seconds, &sec, &min, &hrs, &days); if (days > 0) { sprintf (str, "%d day%s", days, (days == 1) ? "" : "s"); } if (hrs > 0) { if (days > 0) strcat (str, ", "); sprintf (aux, "%d hour%s", hrs, (hrs == 1) ? "" : "s"); strcat (str, aux); } if (min > 0) { if (days > 0 || hrs > 0) strcat (str, ", "); sprintf (aux, "%d minute%s", min, (min == 1) ? "" : "s"); strcat (str, aux); } if (sec > 0) { if (days > 0 || hrs > 0 || min > 0) strcat (str, ", "); sprintf (aux, "%d second%s", sec, (sec == 1) ? "" : "s"); strcat (str, aux); } return (str); } /* Takes a number of seconds as input and returns a pointer to a string * containing hh:mm:ss. */ char *sec_to_hhmmss (long int seconds) { static char str[25]; int sec, min, hrs, days; split_time (seconds, &sec, &min, &hrs, &days); if (days > 0) { hrs += days * 24; } sprintf (str, "%02d:%02d:%02d", hrs, min, sec); return (str); } /* Returns time t rounded to the nearest minute. */ time_t round_to_min (time_t t) { t += SECS_IN_A_MIN / 2; return (t -= t % SECS_IN_A_MIN); } /* Like ctime(3) but strips the seconds, year-part and the \n. */ char *my_ctime (time_t * clock) { char *t = ctime (clock); t[16] = '\0'; return t; } void on_timer (void) { static long int n = 0; static const int interupts_per_hour = 3600 / TIMER_INTERRUPT; int plx; setup_globals(-1); fflush(logptr); fflush(clogptr); #ifdef ABERCHAT if (auto_restart && aberfd == -1 && !(n % 150)) aberchat_autorecon(); #endif if (++n % interupts_per_hour != 0 || time (&global_clock) == -1) global_clock += TIMER_INTERRUPT; loop_all_players (); regenerate (); special_events (SP_ALL); update_weather(); #ifdef SAVE_HTML if (!(n % 30)) /* store players html every min */ storeplayers(); #endif for (plx = 0; plx < max_players; plx++) { if (is_in_game(plx)) do_ingame(plx); else if (is_conn(plx)) { if ((global_clock - logged_on(plx)) > RES_TM && limbo(plx)) enter_game(plx); else if ((global_clock - logged_on(plx)) > CONNECT_TM) close_sock(fildes(plx)); } } } void do_ingame(int plx) { setup_globals (plx); handle_duration (plx); cur_player->cast_spell = False; if (False); #ifdef LOCMIN_VILLAGE else if (ploc(mynum) == LOC_VILLAGE_EMERGENCY && prndsinroom(mynum) >= cur_player->work) exit_hospital(); #endif else if (cur_player->crawl > 10) cur_player->crawl -= 10; else if (linkdead(real_mynum) && global_clock - prlast_cmd(mynum) > LD_TM) auto_tout(); else if (global_clock - prlast_cmd(real_mynum) > IDLE_TM) auto_tout(); else if (cur_player->crawl > 0) { dodirn(False, cur_player->crawl); cur_player->crawl = 0; } }