/* * parse.c */ #include <ctype.h> #include <sys/time.h> #include <signal.h> #include <sys/wait.h> #include <sys/types.h> #include <string.h> #include <memory.h> #include <malloc.h> #include <stdlib.h> #include "config.h" #include "player.h" #include "fix.h" #include "clist.h" #include "channel.h" /* externs */ extern char *end_string(), *splice_argument(player *, char *, char *, int); extern int nhash_update[], update[], true_count_su(), session_reset, emote_no_break(); extern file load_file(), load_file_verbose(char *, int); extern void sync_notes(); extern void log(char *, char *); extern char *full_name(player *); extern void tell_player(player *, char *); extern void tell_room(room *, char *); extern void save_player(player *); extern void do_inform(player *, char *); extern void destroy_player(player *); extern void do_prompt(player *, char *); extern void sync_to_file(char, int); extern void handle_error(char *); extern char *convert_time(time_t); extern char *do_alias_match(player *, char *); extern void move_to(player *, char *, int); extern player *find_player_global(char *), *find_player_absolute_quiet(char *), *p_sess; extern char shutdown_reason[]; extern void do_backup(); extern alias *get_alias(player *, char *); extern void SUWALL(), LOGF(); /* interns */ struct command *last_com; char *stack_check; int nsync = 0, synct = 0, sync_counter = 0, note_sync = NOTE_SYNC_TIME; /* int mem_use_log_count = 0; */ int account_wobble = 1; int performance_timer = 0; struct command *help_list = 0; file help_file = {0, 0}; time_t shutdown_count = -1; /* returns the first char of the input buffer */ char *first_char(player * p) { char *scan; scan = p->ibuffer; while (*scan && isspace(*scan)) *scan++; return scan; } /* what happens if bad stack detected */ void bad_stack() { int missing; missing = (int) stack - (int) stack_check; if (last_com) sprintf(stack_check, "Bad stack in function %s, missing %d bytes", last_com->text, missing); else sprintf(stack_check, "Bad stack somewhere, missing %d bytes", missing); stack = end_string(stack_check); log("stack", stack_check); stack = stack_check; } /* flag changing routines */ /* returns the value of a flag from the flag list */ int get_flag(flag_list * list, char *str) { for (; list->text; list++) if (!strcmp(list->text, str)) return list->change; return 0; } /* routine to get the next part of an arg */ char *next_space(char *str) { while (*str && *str != ' ') str++; if (*str == ' ') { while (*str == ' ') str++; str--; } return str; } /* view command lists */ int command_prescan (player * p, char *str) { char *oldstack; if (!*str || !strcasecmp(str, "?") || !strcasecmp(str, "help")) { oldstack = stack; sprintf(stack, " Format: commands [all|comm|move|desc|info|soc|sys|item|"); stack = strchr(stack, 0); if (p->residency & LIST) { strcpy(stack, "list|"); stack = strchr(stack, 0); } if (p->residency & BUILD) { strcpy(stack, "room|"); stack = strchr(stack, 0); } if (p->residency & (PSU|SU)) { strcpy(stack, "su|"); stack = strchr(stack, 0); } if (p->residency & (TESTCHAR | LOWER_ADMIN | ADMIN)) { strcpy(stack, "ad|"); stack = strchr(stack, 0); } strcpy(stack, "misc]\n"); stack = end_string(stack); tell_player(p, oldstack); stack = oldstack; return THE_EVIL_Q; } /* ok check for what area was inputted, and return appropriate value. */ if(!strcasecmp(str, "all")) { tell_player(p, " Your complete set of commands"); return 0; /* do all commands =) */ } if (!strcasecmp(str, "comm") || !strcasecmp(str, "talk")) { tell_player(p, " Your communication commands"); return COMMc; } if (p->residency & LIST && (!strcasecmp(str, "list"))) { tell_player(p, " Your list commands"); return LISTc; } if (p->residency & BUILD && (!strcasecmp(str, "room"))) { tell_player(p, " Your room commands"); return ROOMc; } if (!strcasecmp(str, "go") || !strcasecmp(str, "move")) { tell_player(p, " Your movement commands"); return MOVEc; } if (!strcasecmp(str, "item")) { tell_player(p, " Your item commands"); return ITEMc; } if (!strcasecmp(str, "info")) { tell_player(p, " Your information commands"); return INFOc; } if (!strcasecmp(str, "sys") || !strcasecmp(str, "toggles")) { tell_player(p, " Your system toggle commands"); return SYSc; } if (!strcasecmp(str, "desc") || !strcasecmp(str, "personalize")) { tell_player(p, " Your personalization commands"); return DESCc; } if (!strcasecmp(str, "soc") || !strcasecmp(str, "social")) { tell_player(p, " Your available socials"); return SOCIALc; } if (!strcasecmp(str, "misc")) { tell_player(p, " Your miscellaneous commands"); return MISCc; } if (p->residency & PSU && (!strcasecmp(str, "su") || !strcasecmp(str, "super"))) { tell_player(p, " Your super user level commands"); return SUPERc; } if (p->residency & (LOWER_ADMIN | ADMIN | TESTCHAR) && (!strcasecmp(str, "ad") || !strcasecmp(str, "admin"))) { tell_player(p, " Your Administration level commands"); return ADMINc; } /* ok the area or priv check was invalid - so report error. */ tell_player(p, " That area not found. Type commands ? to list valid areas.\n"); return THE_EVIL_Q; /* a stupid return yes, but it'll do the job */ } void view_commands(player * p, char *str) { struct command *comlist; char *oldstack; char *plyr; int s; int choice; player *p2; plyr = next_space(str); *plyr++ = 0; oldstack = stack; choice = command_prescan(p, str); /* why the evil q? Cuz I'm a trekker :P */ if (choice == THE_EVIL_Q) return; if (*plyr && p->residency & ADMIN) { p2 = find_player_absolute_quiet(plyr); if (!p2) { tell_player(p,"\nThat player is not logged in right now.\n"); return; } sprintf(stack, " (for %s) ... \n", p2->name); stack = end_string(stack); tell_player(p, oldstack); stack = oldstack; } else { strcpy(stack, "... \n"); stack = strchr(stack, 0); p2 = p; } for (s = 0; s < 27; s++) { for (comlist = coms[s]; comlist->text; comlist++) { if ((!comlist->level || ((p2->residency) & comlist->level)) && (!comlist->andlevel || ((p2->residency) & comlist->andlevel)) && ((!choice || comlist->section & choice) && !(comlist->section & INVISc))) { /* got rid of that damn comma here */ sprintf(stack, "%s ", comlist->text); stack = strchr(stack, 0); } } } stack -= 1; *stack++ = '\n'; *stack++ = 0; tell_player(p, oldstack); stack = oldstack; } void view_sub_commands(player * p, struct command * comlist) { char *oldstack; oldstack = stack; strcpy(stack, " Available sub commands ...\n"); stack = strchr(stack, 0); for (; comlist->text; comlist++) if (((!comlist->level) || ((p->residency) & (comlist->level))) && ((!comlist->andlevel) || ((p->residency) & (comlist->andlevel)))) { sprintf(stack, "%s, ", comlist->text); stack = strchr(stack, 0); } stack -= 2; *stack++ = '\n'; *stack++ = 0; tell_player(p, oldstack); stack = oldstack; } /* initialise the hash array */ void init_parser() { int i; struct command *scan; scan = complete_list; for (i = 0; i < 27; i++) { coms[i] = scan; while (scan->text) scan++; scan++; } } /* see if any commands fit the bill */ char *do_match(char *str, struct command * com_entry) { char *t; for (t = com_entry->text; *t; t++, str++) if (tolower(*str) != *t) return 0; if ((com_entry->space) && (*str) && (!isspace(*str))) return 0; while (*str && isspace(*str)) str++; return str; } /* execute a function from a sub command list */ void sub_command(player * p, char *str, struct command * comlist) { char *oldstack, *rol; void (*fn) (); oldstack = stack; /* Lowercase string here, line in case the person was rm_capped */ if (p->system_flags & DECAPPED) lower_case(str); while (comlist->text) { if (((!comlist->level) || ((p->residency) & (comlist->level))) && ((!comlist->andlevel) || ((p->residency) & (comlist->andlevel)))) { rol = do_match(str, comlist); if (rol) { last_com = comlist; stack_check = stack; sys_flags &= ~ROOM_TAG; command_type &= ~ROOM; fn = comlist->function; (*fn) (p, rol); if (stack != stack_check) bad_stack(); sys_flags &= ~(FAILED_COMMAND | PIPE | ROOM_TAG | FRIEND_TAG | OFRIEND_TAG | EVERYONE_TAG); command_type = 0; return; } } comlist++; } rol = str; while (*rol && !isspace(*rol)) rol++; *rol = 0; sprintf(oldstack, " Cannot find sub command '%s'\n", str); stack = end_string(oldstack); tell_player(p, oldstack); stack = oldstack; } /* match commands to the main command lists */ void old_match_commands(player * p, char *str) { struct command *comlist; char *rol, *oldstack, *space; void (*fn) (); oldstack = stack; while (*str && *str == ' ') str++; space = strchr(str, 0); space--; while (*space == ' ') *space-- = 0; if (!*str) return; /* Lowercase string here, line in case the person was rm_capped */ if (p->system_flags & DECAPPED) lower_case(str); if (isalpha(*str)) comlist = coms[((int) (tolower(*str)) - (int) 'a' + 1)]; else comlist = coms[0]; while (comlist->text) { if (((!comlist->level) || ((p->residency) & (comlist->level))) && ((!comlist->andlevel) || ((p->residency) & (comlist->andlevel)))) { rol = do_match(str, comlist); if (rol) { last_com = comlist; stack_check = stack; sys_flags &= ~ROOM_TAG; command_type &= ~ROOM; fn = comlist->function; (*fn) (p, rol); if (stack != stack_check) bad_stack(); sys_flags &= ~(FAILED_COMMAND|PIPE|ROOM_TAG|FRIEND_TAG|OFRIEND_TAG|EVERYONE_TAG); command_type = 0; return; } } comlist++; } p->antipipe++; /* if (p->antipipe > 30) { quit(p, 0); return; } */ rol = str; while (*rol && !isspace(*rol)) rol++; *rol = 0; sprintf(oldstack, " Cannot find command '%s'\n", str); stack = end_string(oldstack); tell_player(p, oldstack); stack = oldstack; } void match_commands(player * p, char *str) { char *rol, holder[1000]; alias *al; if (!(p->saved)) { old_match_commands(p, str); return; } /* lets try an alias match first */ rol = do_alias_match(p, str); if (strcmp(rol, "\n")) { al = get_alias(p, str); if (!al) { tell_player(p, " Alias matching error\n"); return; } /* NEED TO LOOP THROUGH HERE */ strcpy(holder,splice_argument(p, al->sub, rol, 0)); while (holder[0]) { if (p->system_flags & DECAPPED) lower_case(holder); old_match_commands(p, holder); strcpy(holder,splice_argument(p, al->sub, rol, 1)); } } else old_match_commands(p, str); } /* handle input from one player */ void input_for_one(player * p) { char *pick; void (*fn) (); if (p->input_to_fn) { p->idle = 0; p->idle_index = 0; p->idle_msg[0] = 0; last_com = &input_to; stack_check = stack; fn = p->input_to_fn; sys_flags &= ~ROOM_TAG; command_type &= ~ROOM; (*fn) (p, p->ibuffer); if (stack != stack_check) bad_stack(); sys_flags &= ~(FAILED_COMMAND|PIPE|ROOM_TAG|FRIEND_TAG|OFRIEND_TAG|EVERYONE_TAG); command_type = 0; return; } if (!p->ibuffer[0]) return; p->idle = 0; p->idle_index = 0; p->idle_msg[0] = 0; action = "doing command"; if (p->ibuffer[0] != '#') { if (p->custom_flags & CONVERSE) { pick = p->ibuffer; while (*pick && isspace(*pick)) pick++; if (*pick) if (*pick == '/' || *pick == '.') if (current_room == prison && !(p->residency & (ADMIN | SU))) sub_command(p, pick + 1, restricted_list); else match_commands(p, pick + 1); else if (!isalpha(*pick)) if (current_room == prison && !(p->residency & (ADMIN | SU))) sub_command(p, pick, restricted_list); else match_commands(p, pick); else say(p, pick); } else if (current_room == prison && !(p->residency & (ADMIN | SU))) sub_command(p, p->ibuffer, restricted_list); else match_commands(p, p->ibuffer); } } void su_quit_log(player * p) { char *oldstack; int csu; csu = true_count_su(); oldstack = stack; sprintf(stack, "%s leaves -- %d sus left", p->name, csu - 1); stack = end_string(stack); log ("su", oldstack); stack = oldstack; } /* scan through the players and see if anything needs doing */ void process_players() { player *scan, *sparky; char *oldstack, *hasta; int chan; if (current_players > max_ppl_on_so_far) max_ppl_on_so_far = current_players; for (scan = flatlist_start; scan; scan = sparky) { sparky = scan->flat_next; if (scan->flat_next) if (((player *)scan->flat_next)->flat_previous != scan) { raw_wall("\n\n -=> Non-terminated flatlist <=-\n\n"); raw_wall("\n\n -=> Dumping end off of list <=-\n\n"); scan->flat_next=NULL; } if ((scan->fd < 0) || (scan->flags & PANIC) || (scan->flags & CHUCKOUT)) { oldstack = stack; current_player = scan; if (scan->location && scan->name[0] && !(scan->flags & RECONNECTION)) { if (scan->residency & SU && true_count_su() <= 1) su_quit_log(scan); hasta = do_alias_match(scan, "_logoff"); if (strcmp(hasta, "\n")) { match_commands(scan, "_logoff"); } if (scan == p_sess) { session_reset = 0; } for (chan=0; chan<NUM_CHANNELS; chan++) { if(scan->chanflags & (1<<chan)) { channelquitbyint(scan, chan); } } if (strlen(scan->logoffmsg) < 1) sprintf(stack, "%s hear%s %s parents calling and trot%s away.\n", scan->name, single_s(scan), gstring_possessive(scan), single_s(scan)); else { if (emote_no_break(*scan->logoffmsg)) sprintf(stack, "%s%s\n", scan->name, scan->logoffmsg); else sprintf(stack, "%s %s\n", scan->name, scan->logoffmsg); } stack = end_string(stack); command_type |= LOGOUT_TAG; tell_room(scan->location, oldstack); command_type &= ~LOGOUT_TAG; stack = oldstack; save_player(scan); } if (!(scan->flags & RECONNECTION)) { command_type = 0; if (scan->gender==PLURAL) do_inform(scan, "[%s have left] %s"); else do_inform(scan, "[%s has left] %s"); if (scan->saved && !(scan->flags & NO_SAVE_LAST_ON)) scan->saved->last_on = time(0); } if (sys_flags & VERBOSE || scan->residency == 0) { if (scan->name[0]) sprintf(oldstack, "%s has disconnected from %s", scan->name, scan->inet_addr); else sprintf(oldstack, "Disconnect from login. [%s]", scan->inet_addr); stack = end_string(oldstack); log("newconn", oldstack); } destroy_player(scan); current_player = 0; stack = oldstack; } else if (scan->flags & INPUT_READY) { /* there used to be this here... if (!(scan->lagged) && !(scan->flags & PERM_LAG)) for reference... */ if (!(scan->lagged) && !(scan->system_flags & SAVE_LAGGED)) { current_player = scan; current_room = scan->location; input_for_one(scan); action = "processing players"; current_player = 0; current_room = 0; sys_color_atm = SYSsc; #ifdef PC if (scan->flags & PROMPT && scan == input_player) #else if (scan->flags & PROMPT) #endif { if (scan->custom_flags & CONVERSE) do_prompt(scan, scan->converse_prompt); else do_prompt(scan, scan->prompt); } } memset(scan->ibuffer, 0, IBUFFER_LENGTH); scan->flags &= ~INPUT_READY; } } } /* timer things */ /* automessages */ void do_automessage(room * r) { int count = 0, type; char *scan, *oldstack; oldstack = stack; scan = r->automessage.where; if (!scan) { r->flags &= ~AUTO_MESSAGE; return; } for (; *scan; scan++) if (*scan == '\n') count++; if (!count) { FREE(r->automessage.where); r->automessage.where = 0; r->automessage.length = 0; r->flags &= ~AUTO_MESSAGE; stack = oldstack; return; } count = rand() % count; for (scan = r->automessage.where; count; count--, scan++) while (*scan != '\n') scan++; while (*scan != '\n') *stack++ = *scan++; *stack++ = '\n'; *stack++ = 0; type = command_type; command_type = AUTO; tell_room(r, oldstack); command_type = type; r->auto_count = r->auto_base + (rand() & 63); stack = oldstack; } /* file syncing */ void do_sync() { int origin; action = "doing sync"; sync_counter = SYNC_TIME; origin = synct; while (!update[synct]) { synct = (synct + 1) % 26; if (synct == origin) break; } if (update[synct]) { sync_to_file(synct + 'a', 0); synct = (synct + 1) % 26; } } /* this is the actual timer pling */ void actual_timer() { static int pling = TIMER_CLICK; player *scan, *wibble; time_t t; int i; if (sys_flags & PANIC) return; #if !defined(hpux) && !defined(linux) if ((int) signal(SIGALRM, actual_timer) < 0) handle_error("Can't set timer signal."); #endif /* hpux */ t = time(0); if ((splat_timeout - t) <= 0) splat1 = splat2 = 0; pling--; if (pling) return; pling = TIMER_CLICK; sys_flags |= DO_TIMER; /* if (mem_use_log_count > 0) mem_use_log_count--; */ if (shutdown_count > 0) shutdown_count--; for (i=0; i < NUM_CHANNELS; i++) { if (channel[i].inuse) { channel[i].idle++; if (!channel[i].numppl) channeldestroy(i, "No one left on channel !!\n"); else if (channel[i].numppl <= 1 && (time(0) - channel[i].starttime) > CHANNEL_TIMEOUT) channeldestroy(i, "Channel destroyed: There are too few users.\n"); else if (channel[i].idle > CHANNEL_TIMEOUT) channeldestroy(i, "Channel destroyed due to lack of use -- too idle.\n"); } } for (scan = flatlist_start; scan; scan = scan->flat_next) if (!(scan->flags & PANIC)) { scan->idle++; scan->idle_index++; scan->total_login++; if (scan->total_login % ONE_HOUR == 0) scan->pennies += 10; if (scan->pennies > 100000) scan->pennies = 100000; if (scan->residency && !(scan->residency & NO_SYNC) && scan->total_login % 1200 == 800 ) save_player(scan); if (scan->location && !strcmp(scan->location->owner->lower_name, "main")) scan->time_in_main++; if (scan->script && scan->script > 1) scan->script--; if (scan->timer_fn && scan->timer_count > 0) scan->timer_count--; if (scan->no_shout > 0) scan->no_shout--; if (scan->no_move > 0 && !(scan->system_flags & SAVED_RM_MOVE)) scan->no_move--; if (scan->lagged > 0) scan->lagged--; if (scan->shout_index > 0) scan->shout_index--; /* for sing */ if (scan->no_sing > 0) scan->no_sing--; /* for asty's idle thang */ if (scan->idle_index > 300 && !(scan->residency & ADMIN)) { scan->total_idle_time += (290 + (rand() % 40)); scan->idle_index = 0; } if (scan->jail_timeout > 0) scan->jail_timeout--; /* unidle admins */ if(scan->idle > 3000 && scan->residency & ADMIN) scan->idle = 0; /* timing out REALLY idle gits... */ if(scan->idle == 3000 || scan->idle == 3300 || (!(scan->residency) && (scan->idle == 1500 || scan->idle == 1620))) { scan->total_idle_time +=(1500 + (rand() % 500)); TELLPLAYER(scan, " -=*> Warning - you are now %d minutes idle.\007\n", scan->idle/ONE_MINUTE); } if(scan->idle == 3540 || (!(scan->residency) && scan->idle == 1740)) { scan->total_idle_time +=(1500 + (rand() % 500)); TELLPLAYER(scan, " -=*> You're %d minutes idle. 1 minute till auto-disconnect.\007\n", scan->idle/ONE_MINUTE); } if(scan->idle >= ONE_HOUR || (!(scan->residency) && scan->idle >= (ONE_HOUR/2))) { TELLPLAYER(scan, " Thank you for visiting.. but next time, when you decide to leave, " " you ought quit for yourself... Bye bye.\n"); scan->total_idle_time +=(3000 + (rand() % 1000)); scan->idled_out_count++; log("idle", scan->lower_name); quit(scan, 0); } } net_count--; if (!net_count) { net_count = 10; in_total += in_current; out_total += out_current; in_pack_total += in_pack_current; out_pack_total += out_pack_current; in_bps = in_current / 10; out_bps = out_current / 10; in_pps = in_pack_current / 10; out_pps = out_pack_current / 10; in_average = (in_average + in_bps) >> 1; out_average = (out_average + out_bps) >> 1; in_pack_average = (in_pack_average + in_pps) >> 1; out_pack_average = (out_pack_average + out_pps) >> 1; in_current = 0; out_current = 0; in_pack_current = 0; out_pack_current = 0; } } /* the timer function */ void timer_function() { player *scan, *old_current; void (*fn) (); room *r, **list; char *oldstack, *text; int count = 0, pcount = 0; char *action_cpy; struct tm *ts; time_t t; #if !defined(linux) struct mallinfo minfo; #else /* struct mstats memstats; */ #endif /* LINUX */ if (!(sys_flags & DO_TIMER)) return; sys_flags &= ~DO_TIMER; waitpid((pid_t) - 1, (int *) 0, WNOHANG); /* wait3(0,WNOHANG,0); */ old_current = current_player; action_cpy = action; oldstack = stack; /* if (mem_use_log_count == 0) { #if !defined(linux) minfo = mallinfo(); sprintf(stack, "Total arena space - %d", minfo.arena); #else memstats = mstats(); sprintf(stack, "Total heap size - %d", memstats.bytes_total); #endif stack = end_string(stack); log("mem", oldstack); stack = oldstack; mem_use_log_count = ONE_MINUTE; } */ if (shutdown_count > -1) { command_type |= HIGHLIGHT; switch (shutdown_count) { case ONE_YEAR: raw_wall("\n\n -=*> Your attention please. <*=-\n" " -=*> We'll be rebooting in exactly one year <*=-\n" " -=*> Anyone still here at that time needs help! <*=-\n\n"); break; case ONE_DAY: raw_wall("\n -=*> We'll shutdown this time tomorrow -- Where will you be? Eh? <*=-\n\n"); break; case (15 * ONE_MINUTE): raw_wall("\n -=*> Reboot in 15 mins, most people can have sex in less time... <*=-\n\n"); break; case (10 * ONE_MINUTE): raw_wall("\n -=*> Reboot in 10 mins, Speedy Gonzalez waves to you. Arriva ;-) <*=-\n\n"); break; case (5 * ONE_MINUTE): raw_wall("\n -=*> Reboot in 5 mins, there's plenty of time to edit your list. <*=-\n\n"); break; case (3 * ONE_MINUTE): raw_wall("\n -=*> Reboot in 3 mins, last chance to talk silly admins outta it <*=-\n\n"); break; case (2 * ONE_MINUTE): raw_wall("\n -=*> Reboot in 2 mins, so the three ring circus will be closing. <*=-\n\n"); break; case ONE_MINUTE: raw_wall("\n -=*> Reboot in 1 minute, well be right back up.. (traP hopes...) <*=-\n\n"); break; case 45: raw_wall("\n -=*> Reboot in 45 secs, (this space for rent - call 18009110000) <*=-\n\n"); break; case 30: raw_wall("\n -=*> Reboot in 30 secs, Watch all the people start logging off.. <*=-\n\n"); break; case 15: raw_wall("\n -=*> Reboot in 15 secs, We should be back up in 30 seconds or so <*=-\n\n"); break; case 10: raw_wall("\n -=*> Reboot in 10 secs, Initiating final liftoff sequence now... <*=-\n"); break; case 9: raw_wall("\n -=*> Reboot in 9\n"); break; case 8: raw_wall("\n 8\n"); break; case 7: raw_wall("\n 7\n"); break; case 6: raw_wall("\n 6\n"); break; case 5: raw_wall("\n 5\n"); break; case 4: raw_wall("\n 4\n"); break; case 3: raw_wall("\n 3\n"); break; case 2: raw_wall("\n 2\n"); break; case 1: raw_wall("\n 1\n"); break; case 0: log("shutdown", shutdown_reason); sys_flags |= SHUTDOWN; stack = oldstack; return; } command_type &= ~HIGHLIGHT; } if (sync_counter) sync_counter--; else do_sync(); if (note_sync) note_sync--; else { note_sync = NOTE_SYNC_TIME; sync_notes(1); } align(stack); list = (room **) stack; for (scan = flatlist_start; scan; scan = scan->flat_next) { if (!(scan->flags & PANIC)) { if (scan->script && scan->script == 1) { text = stack; sprintf(text, " Time is now %s.\n" " Scripting stopped ...\n", convert_time(time(0))); stack = end_string(text); tell_player(scan, text); stack = text; scan->script = 0; } if (scan->timer_fn && !scan->timer_count) { current_player = scan; fn = scan->timer_fn; sys_flags &= ~ROOM_TAG; command_type &= ~ROOM; (*fn) (scan); scan->timer_fn = 0; scan->timer_count = -1; } current_player = old_current; action = "processing autos"; r = scan->location; if (r) { pcount++; if (r->flags & AUTO_MESSAGE && !(r->flags & AUTOS_TAG)) { if (!r->auto_count) do_automessage(r); else r->auto_count--; *(room **) stack = r; stack += sizeof(room *); count++; r->flags |= AUTOS_TAG; } } /* Jail timeout thang */ if (scan->jail_timeout == 0 && scan->location == prison) { command_type |= HIGHLIGHT; tell_player(scan, " After serving your sentence you are flung out" " to society again.\n"); command_type &= ~HIGHLIGHT; move_to(scan, ENTRANCE_ROOM, 0); } } } for (; count; count--, list++) (*list)->flags &= ~AUTOS_TAG; stack = oldstack; action = action_cpy; current_players = pcount; t = time(0); ts = localtime(&t); if (t%ONE_DAY == BACKUP_TIME) { do_backup(); } /* * if (!account_wobble && (ts->tm_hour)==0) { account_wobble=1; * do_birthdays(); } */ if (account_wobble == 1 && ((ts->tm_hour) == 3)) { account_wobble = 2; /* system("bin/account &"); */ } if (account_wobble == 2 && ((ts->tm_hour) > 3)) account_wobble = 1; } /* the help system (aargh argh argh) */ /* look through all possible places to find a bit of help */ struct command *find_help(char *str) { struct command *comlist; if (isalpha(*str)) comlist = coms[((int) (tolower(*str)) - (int) 'a' + 1)]; else comlist = coms[0]; for (; comlist->text; comlist++) if (do_match(str, comlist)) return comlist; comlist = help_list; if (!comlist) return 0; for (; comlist->text; comlist++) if (do_match(str, comlist)) return comlist; return 0; } void next_line(file * hf) { while (hf->length > 0 && *(hf->where) != '\n') { hf->where++; hf->length--; } if (hf->length > 0) { hf->where++; hf->length--; } } void init_help() { file hf; struct command *found, *hstart; char *oldstack, *start, *scan; int length; oldstack = stack; if (sys_flags & VERBOSE) log("boot", "Loading help pages"); if (help_list) free(help_list); help_list = 0; if (help_file.where) free(help_file.where); help_file = load_file("doc/help"); hf = help_file; align(stack); hstart = (struct command *) stack; while (hf.length > 0) { while (hf.length > 0 && *(hf.where) != ':') next_line(&hf); if (hf.length > 0) { scan = hf.where; next_line(&hf); *scan++ = 0; while (scan != hf.where) { start = scan; while (*scan != ',' && *scan != '\n') scan++; *scan++ = 0; found = find_help(start); if (!found) { found = (struct command *) stack; stack += sizeof(struct command); found->text = start; found->function = 0; found->level = 0; found->andlevel = 0; found->space = 1; found->section = 0; } found->help = hf.where; } } } *(hf.where - 1) = 0; found = (struct command *) stack; stack += sizeof(struct command); found->text = 0; found->function = 0; found->level = 0; found->andlevel = 0; found->space = 0; found->help = 0; found->section = 0; length = (int) stack - (int) hstart; help_list = (struct command *) malloc(length); memcpy(help_list, hstart, length); stack = oldstack; } /* load that help file in */ int get_help(player * p, char *str) { int fail = 0; file text; char *oldstack; oldstack = stack; if (*str == '.') return 0; sprintf(stack, "doc/%s.help", str); stack = end_string(stack); text = load_file_verbose(oldstack, 0); if (text.where) { if (*(text.where)) { stack = oldstack; sprintf(stack, "-----| Online Help System |-----------------------" "-------------------------\n%s\n---------------------------------" "------------------------------------------\n", text.where); stack = end_string(stack); pager(p, oldstack, 1); fail = 1; } else fail = 0; free(text.where); } stack = oldstack; return fail; } int get_victim(player * p, char *text) { return 0; } /* the help command */ void help(player * p, char *str) { char *oldstack; struct command *fn, *comlist; oldstack = stack; if (!*str) { if (p->residency) str = "general"; else str = "newbie"; } /* so ressies can see "help su" */ if (!strcasecmp(str, "su")) { str = "superuser"; } if (isalpha(*str)) comlist = coms[((int) (tolower(*str)) - (int) 'a' + 1)]; else comlist = coms[0]; /* Here it is - check person's privs before helping them =) */ for(; comlist->text; comlist++) if(!strcmp(comlist->text, str)) if((!(p->residency & comlist->level)) && comlist->level != 0) str = " "; fn = find_help(str); if (!fn || !(fn->help)) { if (get_help(p, str)) return; sprintf(stack, " Cannot find any help on that subject. \n"); stack = end_string(stack); if (p->custom_flags & NO_PAGER) tell_player(p, oldstack); else pager(p, oldstack, 0); stack = oldstack; return; } if (!strcasecmp(str, "newbie")) if (get_victim(p, fn->help)) { stack = oldstack; return; } sprintf(stack, "-----| Online Help System |-----------------------" "-------------------------\n%s\n---------------------------------" "------------------------------------------\n", fn->help); stack = end_string(stack); if (p->custom_flags & NO_PAGER) tell_player(p, oldstack); else pager(p, oldstack, 0); stack = oldstack; } void forcehelp(player * p, char *str) { player *p2; char *temp; temp = next_space(str); *temp++ = 0; if (!*str) { tell_player(p, " Format: forcehelp <player> <help file>\n"); return; } p2 = find_player_global(str); if (!p2) return; tell_player(p2, " -=> I think you need to read this ... \n"); help (p2, temp); SUWALL(" -=*> %s shows help '%s' to %s\n", p->name, temp, p2->name); LOGF("forcehelp", "%s forcehelpped '%s' to %s.", p->name, temp, p2->name); } void redtape(player * p, char *str) { player *p2; char *temp, *oldstack; temp = next_space(str); *temp++ = 0; oldstack = stack; if ((!*str) || (!*temp)) { tell_player(p, " Format: redtape <git> <SuperUser/Minister/etc>\n"); return; } p2 = find_player_global(str); if (!p2) return; sprintf(stack, "\n -=*> %s may be able to help you better. \n\n", temp); stack = end_string(oldstack); command_type |= HIGHLIGHT; tell_player(p2, oldstack); command_type &= ~HIGHLIGHT; stack = oldstack; sprintf(stack, " -=*> %s pushes %s towards %s\n", p->name, p2->name, temp); stack = end_string(oldstack); su_wall (oldstack); stack = oldstack; } /* !!!!!!!!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!! Modifying this function in ANY way without the permission of at least 2 of the following (trap, astyanax, vallie, nogard) is a blatent violation of the licence under which you obtained this program. */ void pg_version(player *p, char *str) { TELLPLAYER(p, "\n" " This talker is based on Playground 96: ver. 5.0 \n" " by traP, astyanax, vallie, and Nogard. \n" " Playground 96 was itself based on Summink by \n" " Athanasius, which was based on EW-too by Simon Marsh \n" "\n"); }