#if defined(macintosh) #include <types.h> #else #include <sys/types.h> #include <sys/time.h> #endif #include <cctype> #include <cstdio> #include <cstdlib> #include <cstring> #include <ctime> #include "merc.h" #include "interp.h" #include "tables.h" #include "olc.h" #include "lookup.h" #include "recycle.h" /* * Local functions. */ bool help_find args ((CHAR_DATA *ch, char *argument)); #define HEDIT( fun ) bool fun(CHAR_DATA *ch, char*argument) #define EDIT_HELP(ch, help) ( help = (HELP_DATA *) ch->desc->pEdit ) const struct olc_cmd_type hedit_table[] = { /* { command function }, */ {"keyword", hedit_keyword}, {"text", hedit_text}, {"new", hedit_new}, {"level", hedit_level}, {"commands", show_commands}, {"delete", hedit_delete}, {"list", hedit_list}, {"show", hedit_show}, {"?", show_help}, {NULL, 0} }; HEDIT (hedit_show) { HELP_DATA *help; EDIT_HELP (ch, help); char buf[MSL]; ch_printf(ch, "Keyword : [%s]\n\rLevel : [%d]\n\rText :\n\r", help->keyword, help->level); sprintf(buf, draw_line(ch, "{w-{W-", 0)); send_to_char(buf, ch); ch_printf(ch, "%s-END-\n\r", help->text); sprintf(buf, draw_line(ch, "{w-{W-", 0)); send_to_char(buf, ch); return FALSE; } HEDIT (hedit_level) { HELP_DATA *help; int lev; EDIT_HELP (ch, help); if (IS_NULLSTR (argument) || !is_number (argument)) { send_to_char ("Syntax: level [-1..MAX_LEVEL]\n\r", ch); return FALSE; } lev = atoi (argument); if (lev < -1 || lev > MAX_LEVEL) { printf_to_char (ch, "HEdit : levels are between -1 and %d inclusive.\n\r", MAX_LEVEL); return FALSE; } help->level = lev; send_to_char ("Ok.\n\r", ch); return TRUE; } HEDIT (hedit_keyword) { HELP_DATA *help; EDIT_HELP (ch, help); if (IS_NULLSTR (argument)) { send_to_char ("Syntax: keyword [keywords]\n\r", ch); return FALSE; } free_string (help->keyword); help->keyword = str_dup (argument); send_to_char ("Ok.\n\r", ch); return TRUE; } HEDIT (hedit_new) { char arg[MIL]; HELP_DATA *help; extern HELP_DATA *help_last; if (IS_NULLSTR (argument)) { send_to_char ("Syntax: new [name]\n\r", ch); return FALSE; } argument = one_argument (argument, arg); if (help_lookup (arg)) { send_to_char ("HEdit : help exists.\n\r", ch); return FALSE; } help = new_help (); help->level = 0; help->keyword = str_dup (arg); help->text = str_dup (""); if (help_last) help_last->next = help; if (help_first == NULL) help_first = help; help_last = help; help->next = NULL; ch->desc->pEdit = (HELP_DATA *) help; ch->desc->editor = ED_HELP; ch_printf(ch, "\n\rCreated new help file '%s'.\n\r", help->keyword); return FALSE; } HEDIT (hedit_text) { HELP_DATA *help; EDIT_HELP (ch, help); if (!IS_NULLSTR (argument)) { send_to_char ("Syntax: text\n\r", ch); return FALSE; } string_append (ch, &help->text); return TRUE; } void hedit (CHAR_DATA * ch, char *argument) { HELP_DATA *pHelp; char arg[MAX_INPUT_LENGTH]; char command[MAX_INPUT_LENGTH]; int cmd; if (ch->pcdata->security < 9) { send_to_char("Insufficent security to edit helps.\n\r", ch); edit_done(ch); return; } smash_tilde (argument); strcpy (arg, argument); argument = one_argument (argument, command); EDIT_HELP (ch, pHelp); if (command[0] == '\0') { hedit_show (ch, argument); return; } if (!str_cmp (command, "done")) { edit_done (ch); return; } for (cmd = 0; hedit_table[cmd].name != NULL; cmd++) { if (!str_prefix (command, hedit_table[cmd].name)) { if ((*hedit_table[cmd].olc_fun) (ch, argument)) mud.helps_changed = TRUE; return; } } interpret (ch, arg); return; } void do_hedit( CHAR_DATA *ch, char *argument ) { HELP_DATA *pHelp; char arg1[MIL]; char argall[MAX_INPUT_LENGTH],argone[MAX_INPUT_LENGTH]; bool found = FALSE; strcpy(arg1,argument); /*if(!str_cmp (arg2,"new")) { if (argument[0] == '\0') { send_to_char("Syntax: hedit new [topic]\n\r",ch); return; } ch_printf(ch, "Passing argument to hedit_new: %s\n\r", argument); if (hedit_new(ch, argument) ) ch->desc->editor = ED_HELP; return; }*/ if(argument[0] != '\0') { argall[0] = '\0'; while (argument[0] != '\0' ) { argument = one_argument(argument,argone); //argone = new, argument = whatever if (argall[0] != '\0') strcat(argall," "); strcat(argall,argone); } for ( pHelp = help_first; pHelp != NULL; pHelp = pHelp->next ) { if ( is_name( argall, pHelp->keyword ) ) { ch->desc->pEdit=(void *)pHelp; ch->desc->editor= ED_HELP; found = TRUE; ch_printf(ch, "Now editing help '%s'.", pHelp->keyword); return; } } } if(!found) { argument = one_argument(arg1, arg1); if(!str_cmp(arg1,"new")) { if (argument[0] == '\0') { send_to_char("Syntax: hedit new [topic]\n\r",ch); return; } if (hedit_new(ch, argument) ) ch->desc->editor = ED_HELP; return; } } send_to_char( "HEdit: There is no default help to edit.\n\r", ch ); return; } HEDIT (hedit_delete) { HELP_DATA *pHelp, *temp; DESCRIPTOR_DATA *d; EDIT_HELP (ch, pHelp); //JH kick everyone off the helpfile, even the deleter for (d = descriptor_list; d; d = d->next) if (d->editor == ED_HELP && pHelp == (HELP_DATA *) d->pEdit) edit_done (d->character); if (help_first == pHelp) help_first = help_first->next; else { for (temp = help_first; temp; temp = temp->next) if (temp->next == pHelp) break; if (!temp) { bugf ("hedit_delete : help %s not found in help_first", pHelp->keyword); return FALSE; } temp->next = pHelp->next; } free_help (pHelp); send_to_char ("Help file deleted.\n\r", ch); return TRUE; } HEDIT (hedit_list) { char buf[MIL]; int cnt = 0; HELP_DATA *pHelp; BUFFER *buffer; EDIT_HELP (ch, pHelp); if (!str_cmp (argument, "all")) { buffer = new_buf (); for (pHelp = help_first; pHelp; pHelp = pHelp->next) { sprintf (buf, "%3d. %-14.14s%s", cnt, pHelp->keyword, cnt % 4 == 3 ? "\n\r" : " "); add_buf (buffer, buf); cnt++; } if (cnt % 4) add_buf (buffer, "\n\r"); page_to_char (buf_string (buffer), ch); free_buf(buffer); return FALSE; } if (IS_NULLSTR (argument)) { send_to_char ("Syntax: list all\n\r", ch); return FALSE; } return FALSE; } /* Syntax(s): help <letter> - list help files that start with <letter> help 2.<keyword> - find second occurance of <keyword> help <keyword> - find first occurance of <keyword>, put the rest into 'related helps'. This help system either entirely lifted from Ryan Jennings' 1stMUD or coded based on 1stMUD's do_help. 1stMUD: http://sourceforge.net/projects/firstmud/ */ void do_help (CHAR_DATA * ch, char *argument) { HELP_DATA *pHelp; bool found = FALSE; bool list = FALSE; char argall[MIL], argone[MIL], argall2[MIL]; char nohelp[MIL]; char *ptr; BUFFER *buffer; BUFFER *related; int counter = 0, number, count = 0; char buf[MSL]; if (argument[0] == '\0') argument = "summary"; argall[0] = '\0'; //ch_printf(ch, "argument: %s\n\r", argument); if (!str_prefix("find", argument)) { argument = one_argument(argument, argone); //ch_printf(ch, "argument: %s argone: %s\n\r", argument, argone); help_find(ch, argument); return; } while (argument[0] != '\0') { argument = one_argument(argument, argone); if (argall[0] != '\0') strcat(argall, " "); strcat(argall, argone); } buffer = new_buf(); related = new_buf(); /* allows for help 2.keyword */ number = number_argument(argall, argall2); strcpy(nohelp, argall2); for (pHelp = help_first; pHelp != NULL; pHelp = pHelp->next) { if (pHelp->level > get_trust(ch)) continue; if (!is_name(argall2, pHelp->keyword)) continue; if (list || (strlen(argall2) == 1)) { counter++; sprintf(buf, "%3d) %s\n\r", counter, pHelp->keyword); add_buf(buffer, buf); list = TRUE; found = TRUE; continue; } if (found) { sprintf(buf, "%s, ", pHelp->keyword); add_buf(related, buf); continue; } if (++count == number) { add_buf(buffer, draw_line(ch, "{w-{W-", 0)); sprintf(buf, "Help keywords: %s\n\r", pHelp->keyword); add_buf(buffer, buf); add_buf(buffer, draw_line(ch, "{w-{W-", 0)); if (pHelp->text[0] == '.') add_buf(buffer, pHelp->text + 1); else add_buf(buffer, pHelp->text); add_buf(buffer, draw_line(ch, "{w-{W-", 0)); found = TRUE; } else { sprintf(buf, "%s, ", pHelp->keyword); add_buf(related, buf); } } if (list) { char *text; //removed the 'const' qualifier because I don't want to rewrite free_string char buf[MIL]; text = str_dup(buf_string(buffer)); clear_buf(buffer); sprintf(buf, "Help files that start with the letter '%s'.\n\r", argall2); add_buf(buffer, buf); add_buf(buffer, draw_line(ch, "{w-{W-", 0)); add_buf(buffer, text); add_buf(buffer, draw_line(ch, "{w-{W-", 0)); sprintf(buf, "%d total help files.\n\r", counter); add_buf(buffer, buf); free_string(text); } else if (!found) { ptr = nohelp; //changed JH 3/11/2004 11:43PM if (!str_prefix(ptr, "find")) one_argument(ptr, argone); ch_printf(ch, "No help found for %s. Trying a search...\n\r\n\r", ptr); if (!help_find(ch, ptr)) { sprintf(log_buf, "Missing Help: %s", ptr); wiznet(log_buf, ch, NULL, 0, 0, 0); } free_buf(buffer); free_buf(related); return; } else if (related->string != NULL && related->string[0] != '\0') { related->string[strlen(related->string) - 2] = '.'; related->string[strlen(related->string) - 1] = '\0'; /* sprintf(buf, "See Also : %s\n\r%s\n\r", buf_string(related), draw_line(ch, "{w-{W-", 0));*/ //JH changed above because I felt like it 6/17/2004 12:21AM sprintf(buf, "See Also: %s\n\r", buf_string(related)); add_buf(buffer, buf); } page_to_char(buf_string(buffer), ch); free_buf(buffer); free_buf(related); return; } bool help_find (CHAR_DATA *ch, char *argument) { bool Found = FALSE; HELP_DATA *pHelp; char buf[MSL]; //int len, linelen = 0; int col = 0; BUFFER *buffer; if (!argument || argument[0] == '\0' || strlen(argument) < 2) { send_to_char("Help find requires at least a 2 letter argument.\n\r", ch); return FALSE; } buffer = new_buf(); sprintf(buf, "Helpfiles with '%s' contained within:\n\r", argument); add_buf(buffer, buf); add_buf(buffer, draw_line(ch,"{w-{W-", 0)); for (pHelp = help_first; pHelp != NULL; pHelp = pHelp->next) { if (pHelp->level > get_trust(ch)) continue; if (stristr(pHelp->text, argument) != NULL) { Found = TRUE; if (col++ > 2) { add_buf(buffer, "\n\r"); col = 0; } sprintf(buf, "%-16.16s ", pHelp->keyword); add_buf(buffer, buf); continue; } } if (!Found) add_buf(buffer, "None.\n\r"); else add_buf(buffer, "\n\r"); page_to_char(buf_string(buffer), ch); free_buf(buffer); return Found; } void do_hlookup (CHAR_DATA * ch, char *argument) { HELP_DATA *pHelp; int cmd, wrap = 0; BUFFER *buf; char bufx[MIL]; bool Found = FALSE; buf = new_buf(); for (cmd = 0; cmd_table[cmd].name[0] != '\0'; cmd++) { //Prevent ' and . and / shitola, also prevent false postives ('reboo' vs 'reboot') if ((strlen(cmd_table[cmd].name) < 2) || !cmd_table[cmd].show) continue; Found = FALSE; for (pHelp = help_first; pHelp != NULL; pHelp = pHelp->next) { if (is_exact_name (cmd_table[cmd].name, pHelp->keyword)) { Found = TRUE; break; } } if (!Found) { add_buf(buf, "{Y*"); sprintf(bufx, "{C%-12s", cmd_table[cmd].name); add_buf(buf, bufx); if (++wrap % 6 == 0) add_buf(buf, "\n\r"); } } add_buf(buf, "\n\r"); send_to_char("Missing helpfiles for the following commands:\n\r", ch); send_to_char(draw_line(ch, "{g-{G-", 0), ch); page_to_char(buf_string(buf), ch); free_buf(buf); return; } void do_oldhelp (CHAR_DATA * ch, char *argument) { HELP_DATA *pHelp; BUFFER *output; bool found = FALSE; char argall[MAX_INPUT_LENGTH], argone[MAX_INPUT_LENGTH]; int level; output = new_buf (); if (argument[0] == '\0') argument = "summary"; /* this parts handles help a b so that it returns help 'a b' */ argall[0] = '\0'; while (argument[0] != '\0') { argument = one_argument (argument, argone); if (argall[0] != '\0') strcat (argall, " "); strcat (argall, argone); } for (pHelp = help_first; pHelp != NULL; pHelp = pHelp->next) { level = (pHelp->level < 0) ? -1 * pHelp->level - 1 : pHelp->level; if (level > get_trust (ch)) continue; if (is_name (argall, pHelp->keyword)) { /* add seperator if found */ if (found) add_buf (output, "\n\r============================================================\n\r\n\r"); if (pHelp->level >= 0 && str_cmp (argall, "imotd")) { add_buf (output, pHelp->keyword); add_buf (output, "\n\r"); } /* * Strip leading '.' to allow initial blanks. */ if (pHelp->text[0] == '.') add_buf (output, pHelp->text + 1); else add_buf (output, pHelp->text); found = TRUE; /* small hack :) */ if (ch->desc != NULL && ch->desc->connected != CON_PLAYING && ch->desc->connected != CON_GEN_GROUPS) break; } } if (!found) { send_to_char ("No help on that word.\n\r", ch); /* * Let's log unmet help requests so studious IMP's can improve their help files ;-) * But to avoid idiots, we will check the length of the help request, and trim to * a reasonable length (set it by redefining MAX_CMD_LEN in merc.h). -- JR */ if (strlen(argall) > MAX_CMD_LEN) { argall[MAX_CMD_LEN - 1] = '\0'; writelogf ("Excessive command length: %s requested %s.", ch, argall); send_to_char ("That was rude!\n\r", ch); } /* OHELPS_FILE is the "orphaned helps" files. Defined in merc.h -- JR */ else { append_file (ch, OHELPS_FILE, argall); } } else page_to_char (buf_string (output), ch); free_buf (output); }