00001
00002
00003
00004
00005 #include "copyright.h"
00006 #include "config.h"
00007
00008 #include <signal.h>
00009
00010 #include "mudconf.h"
00011 #include "config.h"
00012 #include "db.h"
00013 #include "interface.h"
00014 #include "match.h"
00015 #include "externs.h"
00016 #include "command.h"
00017 #include "attrs.h"
00018 #include "powers.h"
00019
00020 extern void pool_reset(void);
00021 extern void do_second(void);
00022 extern void fork_and_dump(int key);
00023 extern unsigned int alarm(unsigned int seconds);
00024 extern void pcache_trim(void);
00025 void check_events(void);
00026
00027 void timer_callback(int fd, short event, void *arg);
00028
00029 static struct timeval tv = { 0, 100000 };
00030 static struct event timer_event;
00031
00032 void init_timer()
00033 {
00034 mudstate.now = time(NULL);
00035 mudstate.dump_counter =
00036 ((mudconf.dump_offset ==
00037 0) ? mudconf.dump_interval : mudconf.dump_offset) + mudstate.now;
00038 mudstate.check_counter =
00039 ((mudconf.check_offset ==
00040 0) ? mudconf.check_interval : mudconf.check_offset) + mudstate.now;
00041 mudstate.idle_counter = mudconf.idle_interval + mudstate.now;
00042 mudstate.mstats_counter = 15 + mudstate.now;
00043 mudstate.events_counter = 900 + mudstate.now;
00044 evtimer_set(&timer_event, timer_callback, NULL);
00045 evtimer_add(&timer_event, &tv);
00046 }
00047
00048 #undef DISPATCH_DEBUG
00049
00050 #ifdef DISPATCH_DEBUG
00051 #define DPSET(n) mudstate.debug_cmd = (char *) n
00052 #else
00053 #define DPSET(n)
00054 #endif
00055
00056 void check_idle(void)
00057 {
00058 DESC *d, *dnext;
00059 time_t idletime;
00060
00061 DESC_SAFEITER_ALL(d, dnext) {
00062 if(d->flags & DS_CONNECTED) {
00063 idletime = mudstate.now - d->last_time;
00064 if((idletime > d->timeout) && !Can_Idle(d->player)) {
00065 queue_string(d, "*** Inactivity Timeout ***\r\n");
00066 shutdownsock(d, R_TIMEOUT);
00067 } else if(mudconf.idle_wiz_dark &&
00068 (idletime > mudconf.idle_timeout) && Can_Idle(d->player)
00069 && !Dark(d->player)) {
00070 s_Flags(d->player, Flags(d->player) | DARK);
00071 d->flags |= DS_AUTODARK;
00072 }
00073 } else {
00074 idletime = mudstate.now - d->connected_at;
00075 if(idletime > mudconf.conn_timeout) {
00076 queue_string(d, "*** Login Timeout ***\r\n");
00077 shutdownsock(d, R_TIMEOUT);
00078 }
00079 }
00080 }
00081 }
00082
00083 void check_events(void)
00084 {
00085 struct tm *ltime;
00086 dbref thing, parent;
00087 int lev;
00088
00089 ltime = localtime(&mudstate.now);
00090 if((ltime->tm_hour == mudconf.events_daily_hour)
00091 && !(mudstate.events_flag & ET_DAILY)) {
00092 mudstate.events_flag = mudstate.events_flag | ET_DAILY;
00093 DO_WHOLE_DB(thing) {
00094 if(Going(thing))
00095 continue;
00096
00097 ITER_PARENTS(thing, parent, lev) {
00098 if(Flags2(thing) & HAS_DAILY) {
00099 did_it(Owner(thing), thing, 0, NULL, 0, NULL, A_DAILY,
00100 (char **) NULL, 0);
00101
00102 break;
00103 }
00104 }
00105 }
00106 }
00107 if(ltime->tm_hour != mudstate.events_lasthour) {
00108 if(mudstate.events_lasthour >= 0) {
00109
00110 DO_WHOLE_DB(thing) {
00111 if(Going(thing))
00112 continue;
00113
00114 ITER_PARENTS(thing, parent, lev) {
00115 if(Flags2(thing) & HAS_HOURLY) {
00116 did_it(Owner(thing), thing, 0, NULL, 0, NULL,
00117 A_HOURLY, (char **) NULL, 0);
00118
00119 break;
00120 }
00121 }
00122 }
00123
00124 }
00125 mudstate.events_lasthour = ltime->tm_hour;
00126 }
00127 if(ltime->tm_hour == 23) {
00128
00129
00130 mudstate.events_flag = 0;
00131 }
00132 }
00133
00134
00135 void dispatch()
00136 {
00137 char *cmdsave;
00138
00139 #ifdef USE_PYTHON
00140 mudstate.debug_cmd = "< Python >";
00141 updatePython();
00142 #endif
00143
00144 cmdsave = mudstate.debug_cmd;
00145 DPSET("< dispatch >");
00146
00147
00148
00149
00150 if(!mudstate.alarm_triggered)
00151 return;
00152 mudstate.alarm_triggered = 0;
00153 mudstate.now = time(NULL);
00154
00155 do_second();
00156
00157
00158
00159
00160
00161 if((mudconf.control_flags & CF_DBCHECK) &&
00162 (mudstate.check_counter <= mudstate.now)) {
00163 mudstate.check_counter = mudconf.check_interval + mudstate.now;
00164 DPSET("< dbck >");
00165 do_dbck(NOTHING, NOTHING, 0);
00166 pcache_trim();
00167 }
00168
00169
00170
00171
00172 if((mudconf.control_flags & CF_CHECKPOINT) &&
00173 (mudstate.dump_counter <= mudstate.now)) {
00174 mudstate.dump_counter = mudconf.dump_interval + mudstate.now;
00175 DPSET("< dump >");
00176 fork_and_dump(0);
00177 }
00178
00179
00180
00181
00182
00183
00184 if(mudconf.have_specials)
00185 UpdateSpecialObjects();
00186
00187
00188
00189
00190
00191 if((mudconf.control_flags & CF_IDLECHECK) &&
00192 (mudstate.idle_counter <= mudstate.now)) {
00193 mudstate.idle_counter = mudconf.idle_interval + mudstate.now;
00194 DPSET("< idlecheck >");
00195 check_idle();
00196
00197 }
00198
00199
00200
00201
00202 if((mudconf.control_flags & CF_EVENTCHECK) &&
00203 (mudstate.events_counter <= mudstate.now)) {
00204 mudstate.events_counter = 900 + mudstate.now;
00205 DPSET("< eventcheck >");
00206 check_events();
00207 }
00208 #ifdef HAVE_GETRUSAGE
00209
00210
00211
00212
00213 if(mudstate.mstats_counter <= mudstate.now) {
00214
00215 int curr;
00216
00217 mudstate.mstats_counter = 15 + mudstate.now;
00218 curr = mudstate.mstat_curr;
00219 if(mudstate.now > mudstate.mstat_secs[curr]) {
00220
00221 struct rusage usage;
00222
00223 curr = 1 - curr;
00224 getrusage(RUSAGE_SELF, &usage);
00225 mudstate.mstat_ixrss[curr] = usage.ru_ixrss;
00226 mudstate.mstat_idrss[curr] = usage.ru_idrss;
00227 mudstate.mstat_isrss[curr] = usage.ru_isrss;
00228 mudstate.mstat_secs[curr] = mudstate.now;
00229 mudstate.mstat_curr = curr;
00230 }
00231 }
00232 #endif
00233
00234 mudstate.debug_cmd = cmdsave;
00235 }
00236
00237 void timer_callback(int fd, short event, void *arg)
00238 {
00239 mudstate.alarm_triggered = 1;
00240 evtimer_add(&timer_event, &tv);
00241 dispatch();
00242 }
00243
00247 void do_timewarp(dbref player, dbref cause, int key, char *arg)
00248 {
00249 int secs;
00250
00251 secs = atoi(arg);
00252
00253 if((key == 0) || (key & TWARP_QUEUE))
00254
00255
00256 do_queue(player, cause, QUEUE_WARP, arg);
00257 if(key & TWARP_DUMP)
00258 mudstate.dump_counter -= secs;
00259 if(key & TWARP_CLEAN)
00260 mudstate.check_counter -= secs;
00261 if(key & TWARP_IDLE)
00262 mudstate.idle_counter -= secs;
00263 if(key & TWARP_EVENTS)
00264 mudstate.events_counter -= secs;
00265 }