|
Atrinik Server 2.5
|
00001 /************************************************************************ 00002 * Atrinik, a Multiplayer Online Role Playing Game * 00003 * * 00004 * Copyright (C) 2009-2011 Alex Tokar and Atrinik Development Team * 00005 * * 00006 * Fork from Daimonin (Massive Multiplayer Online Role Playing Game) * 00007 * and Crossfire (Multiplayer game for X-windows). * 00008 * * 00009 * This program is free software; you can redistribute it and/or modify * 00010 * it under the terms of the GNU General Public License as published by * 00011 * the Free Software Foundation; either version 2 of the License, or * 00012 * (at your option) any later version. * 00013 * * 00014 * This program is distributed in the hope that it will be useful, * 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00017 * GNU General Public License for more details. * 00018 * * 00019 * You should have received a copy of the GNU General Public License * 00020 * along with this program; if not, write to the Free Software * 00021 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 00022 * * 00023 * The author can be reached at admin@atrinik.org * 00024 ************************************************************************/ 00025 00030 #include <global.h> 00031 00032 long max_time = MAX_TIME; 00033 00035 #define PBUFLEN 100 00036 00038 static long process_utime_save[PBUFLEN]; 00040 static long psaveind; 00042 static long process_max_utime = 0; 00044 static long process_min_utime = 999999999; 00045 static long process_tot_mtime; 00046 long pticks; 00047 static long process_utime_long_count; 00048 00050 const char *season_name[SEASONS_PER_YEAR + 1] = 00051 { 00052 "The Season of New Year", 00053 "The Season of Growth", 00054 "The Season of Harvest", 00055 "The Season of Decay", 00056 "The Season of the Blizzard", 00057 "\n" 00058 }; 00059 00061 const char *weekdays[DAYS_PER_WEEK] = 00062 { 00063 "the Day of the Moon", 00064 "the Day of the Bull", 00065 "the Day of the Deception", 00066 "the Day of Thunder", 00067 "the Day of Freedom", 00068 "the Day of the Great Gods", 00069 "the Day of the Sun" 00070 }; 00071 00073 const char *month_name[MONTHS_PER_YEAR] = 00074 { 00075 "Month of the Ice Dragon", 00076 "Month of the Frost Giant", 00077 "Month of the Clouds", 00078 "Month of Gaea", 00079 "Month of the Harvest", 00080 "Month of Futility", 00081 "Month of the Dragon", 00082 "Month of the Sun", 00083 "Month of the Falling", 00084 "Month of the Dark Shades", 00085 "Month of the Great Infernus", 00086 "Month of the Ancient Darkness", 00087 }; 00088 00090 const char *periodsofday[PERIODS_PER_DAY] = { 00091 "Night", 00092 "Dawn", 00093 "Morning", 00094 "Noon", 00095 "Evening", 00096 "Dusk" 00097 }; 00098 00101 void reset_sleep() 00102 { 00103 int i; 00104 00105 for (i = 0; i < PBUFLEN; i++) 00106 { 00107 process_utime_save[i] = 0; 00108 } 00109 00110 psaveind = 0; 00111 process_max_utime = 0; 00112 process_min_utime = 999999999; 00113 process_tot_mtime = 0; 00114 pticks = 0; 00115 00116 (void) GETTIMEOFDAY(&last_time); 00117 } 00118 00121 static void log_time(long process_utime) 00122 { 00123 pticks++; 00124 00125 if (++psaveind >= PBUFLEN) 00126 { 00127 psaveind = 0; 00128 } 00129 00130 process_utime_save[psaveind] = process_utime; 00131 00132 if (process_utime > process_max_utime) 00133 { 00134 process_max_utime = process_utime; 00135 } 00136 00137 if (process_utime < process_min_utime) 00138 { 00139 process_min_utime = process_utime; 00140 } 00141 00142 process_tot_mtime += process_utime / 1000; 00143 } 00144 00149 void sleep_delta() 00150 { 00151 static struct timeval new_time; 00152 static struct timeval def_time = {0, 100000}; 00153 static struct timeval sleep_time; 00154 long sleep_sec, sleep_usec; 00155 00156 (void) GETTIMEOFDAY(&new_time); 00157 00158 sleep_sec = last_time.tv_sec - new_time.tv_sec; 00159 sleep_usec = max_time - (new_time.tv_usec - last_time.tv_usec); 00160 00161 /* This is very ugly, but probably the fastest for our use: */ 00162 while (sleep_usec < 0) 00163 { 00164 sleep_usec += 1000000; 00165 sleep_sec -= 1; 00166 } 00167 00168 while (sleep_usec > 1000000) 00169 { 00170 sleep_usec -= 1000000; 00171 sleep_sec += 1; 00172 } 00173 00174 log_time((new_time.tv_sec - last_time.tv_sec) * 1000000 + new_time.tv_usec - last_time.tv_usec); 00175 00176 if (sleep_sec >= 0 && sleep_usec > 0) 00177 { 00178 sleep_time.tv_sec = sleep_sec; 00179 sleep_time.tv_usec = sleep_usec; 00180 00181 /*LOG(llevDebug, "SLEEP-Time: %ds and %dus\n", sleep_time.tv_sec, sleep_time.tv_usec);*/ 00182 /* we ignore seconds to sleep - there is NO reason to put the server 00183 * for even a single second to sleep when there is someone connected. */ 00184 if (sleep_time.tv_sec || sleep_time.tv_usec > 500000) 00185 { 00186 LOG(llevBug, "sleep_delta(): sleep delta out of range! (%"FMT64U"s %"FMT64U"us)\n", (uint64) sleep_time.tv_sec, (uint64) sleep_time.tv_usec); 00187 } 00188 00189 #ifndef WIN32 00190 /* 'select' doesn't work on Windows, 'Sleep' is used instead */ 00191 if (sleep_time.tv_sec || sleep_time.tv_usec > 500000) 00192 { 00193 select(0, NULL, NULL, NULL, &def_time); 00194 } 00195 else 00196 { 00197 select(0, NULL, NULL, NULL, &sleep_time); 00198 } 00199 #else 00200 if (sleep_time.tv_usec >= 1000) 00201 { 00202 Sleep((int) (sleep_time.tv_usec / 1000)); 00203 } 00204 else if (sleep_time.tv_usec) 00205 { 00206 Sleep(1); 00207 } 00208 #endif 00209 } 00210 else 00211 { 00212 process_utime_long_count++; 00213 } 00214 00215 /* Set last_time to when we're expected to wake up: */ 00216 last_time.tv_usec += max_time; 00217 00218 while (last_time.tv_usec > 1000000) 00219 { 00220 last_time.tv_usec -= 1000000; 00221 last_time.tv_sec++; 00222 } 00223 00224 /* Don't do too much catching up: 00225 * (Things can still get jerky on a slow/loaded computer) */ 00226 if (last_time.tv_sec * 1000000 + last_time.tv_usec < new_time.tv_sec * 1000000 + new_time.tv_usec) 00227 { 00228 last_time.tv_sec = new_time.tv_sec; 00229 last_time.tv_usec = new_time.tv_usec; 00230 } 00231 } 00232 00237 void set_max_time(long t) 00238 { 00239 max_time = t; 00240 } 00241 00245 void get_tod(timeofday_t *tod) 00246 { 00247 tod->year = todtick / HOURS_PER_YEAR; 00248 tod->month = (todtick / HOURS_PER_MONTH) % MONTHS_PER_YEAR; 00249 tod->day = (todtick % HOURS_PER_MONTH) / DAYS_PER_MONTH; 00250 tod->dayofweek = tod->day % DAYS_PER_WEEK; 00251 tod->hour = todtick % HOURS_PER_DAY; 00252 tod->minute = (pticks % PTICKS_PER_CLOCK) / (PTICKS_PER_CLOCK / 58); 00253 00254 if (tod->minute > 59) 00255 { 00256 tod->minute = 59; 00257 } 00258 00259 tod->weekofmonth = tod->day / WEEKS_PER_MONTH; 00260 00261 if (tod->month < 3) 00262 { 00263 tod->season = 0; 00264 } 00265 else if (tod->month < 6) 00266 { 00267 tod->season = 1; 00268 } 00269 else if (tod->month < 9) 00270 { 00271 tod->season = 2; 00272 } 00273 else if (tod->month < 12) 00274 { 00275 tod->season = 3; 00276 } 00277 else 00278 { 00279 tod->season = 4; 00280 } 00281 00282 /* Until 4:59 */ 00283 if (tod->hour < 5) 00284 { 00285 tod->periodofday = 0; 00286 } 00287 else if (tod->hour < 8) 00288 { 00289 tod->periodofday = 1; 00290 } 00291 else if (tod->hour < 13) 00292 { 00293 tod->periodofday = 2; 00294 } 00295 else if (tod->hour < 15) 00296 { 00297 tod->periodofday = 3; 00298 } 00299 else if (tod->hour < 20) 00300 { 00301 tod->periodofday = 4; 00302 } 00303 else if (tod->hour < 23) 00304 { 00305 tod->periodofday = 5; 00306 } 00307 /* Back to night */ 00308 else 00309 { 00310 tod->periodofday = 0; 00311 } 00312 } 00313 00317 void print_tod(object *op) 00318 { 00319 timeofday_t tod; 00320 char *suf; 00321 int day; 00322 00323 get_tod(&tod); 00324 new_draw_info_format(0, COLOR_WHITE, op, "It is %d minute%s past %d o'clock %s, on %s", tod.minute, ((tod.minute == 1) ? "" : "s"), ((tod.hour % (HOURS_PER_DAY / 2) == 0) ? (HOURS_PER_DAY / 2) : ((tod.hour) % (HOURS_PER_DAY / 2))), ((tod.hour >= (HOURS_PER_DAY / 2)) ? "pm" : "am"), weekdays[tod.dayofweek]); 00325 00326 day = tod.day + 1; 00327 00328 if (day == 1 || ((day % 10) == 1 && day > 20)) 00329 { 00330 suf = "st"; 00331 } 00332 else if (day == 2 || ((day % 10) == 2 && day > 20)) 00333 { 00334 suf = "nd"; 00335 } 00336 else if (day == 3 || ((day % 10) == 3 && day > 20)) 00337 { 00338 suf = "rd"; 00339 } 00340 else 00341 { 00342 suf = "th"; 00343 } 00344 00345 new_draw_info_format(0, COLOR_WHITE, op, "The %d%s Day of the %s, Year %d", day, suf, month_name[tod.month], tod.year + 1); 00346 new_draw_info_format(0, COLOR_WHITE, op, "Time of Year: %s", season_name[tod.season]); 00347 } 00348 00352 void time_info(object *op) 00353 { 00354 int tot = 0, maxt = 0, mint = 99999999, long_count = 0, i; 00355 00356 print_tod(op); 00357 00358 if (!QUERY_FLAG(op, FLAG_WIZ)) 00359 { 00360 return; 00361 } 00362 00363 new_draw_info_format(0, COLOR_WHITE, op, "Total time:\nticks=%ld time=%ld.%2ld", pticks, process_tot_mtime / 1000, process_tot_mtime % 1000); 00364 new_draw_info_format(0, COLOR_WHITE, op, "avg time=%ldms max time=%ldms min time=%ldms", process_tot_mtime / pticks, process_max_utime / 1000, process_min_utime / 1000); 00365 new_draw_info_format(0, COLOR_WHITE, op, "ticks longer than max time (%ldms) = %ld (%ld%%)", max_time / 1000, process_utime_long_count, 100 * process_utime_long_count / pticks); 00366 new_draw_info_format(0, COLOR_WHITE, op, "Time last %ld ticks:", pticks > PBUFLEN ? PBUFLEN : pticks); 00367 00368 for (i = 0; i < (pticks > PBUFLEN ? PBUFLEN : pticks); i++) 00369 { 00370 tot += process_utime_save[i]; 00371 00372 if (process_utime_save[i] > maxt) 00373 { 00374 maxt = process_utime_save[i]; 00375 } 00376 00377 if (process_utime_save[i] < mint) 00378 { 00379 mint = process_utime_save[i]; 00380 } 00381 00382 if (process_utime_save[i] > max_time) 00383 { 00384 long_count++; 00385 } 00386 } 00387 00388 new_draw_info_format(0, COLOR_WHITE, op, "avg time=%ldms max time=%dms min time=%dms", tot / (pticks > PBUFLEN ? PBUFLEN : pticks) / 1000, maxt / 1000, mint / 1000); 00389 new_draw_info_format(0, COLOR_WHITE, op, "ticks longer than max time (%ldms) = %d (%ld%%)", max_time / 1000, long_count, 100 * long_count / (pticks > PBUFLEN ? PBUFLEN : pticks)); 00390 } 00391 00395 long seconds() 00396 { 00397 struct timeval now; 00398 00399 (void) GETTIMEOFDAY(&now); 00400 return now.tv_sec; 00401 }
1.7.4