eventmud/doc/
eventmud/help/
/*
 * This file contains the dynamic help system.
 * If you wish to update a help file, simply edit
 * the entry in ../help/ and the mud will load the
 * new version next time someone tries to access
 * that help file.
 */
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <time.h>
#include <dirent.h> 

/* include main header file */
#include "mud.h"

HELP_DATA   *   help_list = NULL; /* the linked list of help files     */
char        *   greeting;         /* the welcome greeting              */
char        *   motd;             /* the MOTD help file                */

/*
 * Check_help()
 *
 * This function first sees if there is a valid
 * help file in the help_list, should there be
 * no helpfile in the help_list, it will check
 * the ../help/ directory for a suitable helpfile
 * entry. Even if it finds the helpfile in the
 * help_list, it will still check the ../help/
 * directory, and should the file be newer than
 * the currently loaded helpfile, it will reload
 * the helpfile.
 */
bool check_help(D_MOBILE *dMob, char *helpfile)
{
  HELP_DATA *pHelp;
  char buf[MAX_HELP_ENTRY + 80];
  char *entry, *hFile;
  bool found = FALSE;

  hFile = capitalize(helpfile);

  for (pHelp = help_list; pHelp; pHelp = pHelp->next)
  {
    if (is_prefix(helpfile, pHelp->keyword))
    {
      found = TRUE;
      break;
    }
  }

  /* If there is an updated version we load it */
  if (found)
  {
    if (last_modified(hFile) > pHelp->load_time)
    {
      free(pHelp->text);
      pHelp->text = strdup(read_help_entry(hFile));
    }
  }
  else /* is there a version at all ?? */
  {
    if ((entry = read_help_entry(hFile)) == NULL)
      return FALSE;
    else
    {
      if ((pHelp = malloc(sizeof(*pHelp))) == NULL)
      { 
        bug("Check_help: Cannot allocate memory.");
        abort();
      }
      pHelp->keyword    =  strdup(hFile);
      pHelp->text       =  strdup(entry);
      pHelp->load_time  =  time(NULL);
      add_help(pHelp);
    }
  }

  sprintf(buf, "=== %s ===\n\r%s", pHelp->keyword, pHelp->text);
  text_to_mobile(dMob, buf);
  return TRUE;
}

/*
 * Loads all the helpfiles found in ../help/
 */
void load_helps()
{
  HELP_DATA *new_help;
  char buf[MAX_BUFFER];
  char *s;
  DIR *directory;
  struct dirent *entry;

  log_string("Load_helps: getting all help files.");

  directory = opendir("../help/");
  for (entry = readdir(directory); entry; entry = readdir(directory))
  {
    if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, ".."))
      continue;

    sprintf(buf, "../help/%s", entry->d_name);
    s = read_help_entry(buf);

    if (s == NULL)
    {
      bug("load_helps: Helpfile %s does not exist.", buf);
      continue;
    }

    if ((new_help = malloc(sizeof(*new_help))) == NULL)
    {
      bug("Load_helps: Cannot allocate memory.");
      abort();
    }

    new_help->keyword    =  strdup(entry->d_name);
    new_help->text       =  strdup(s);
    new_help->load_time  =  time(NULL);
    add_help(new_help);

    if (compares("GREETING", new_help->keyword))
      greeting = new_help->text;
    else if (compares("MOTD", new_help->keyword))
      motd = new_help->text;
  }
  closedir(directory);
}

void add_help(HELP_DATA *help)
{
  HELP_DATA *pHelp = NULL;
  HELP_DATA *prev = NULL;
  bool done = FALSE;
  int i;

  if (help_list == NULL)
  {
    help_list = help;
    help->next = NULL;
  }
  else
  {
    for (pHelp = help_list; pHelp; pHelp = pHelp->next)
    {
      if (toupper((int) help->keyword[0]) > toupper((int) pHelp->keyword[0]))
      {
        prev = pHelp;
        continue;
      }
      else if (toupper((int) help->keyword[0]) == toupper((int) pHelp->keyword[0]))
      {
        for (i = 0; help->keyword[i] != '\0' && pHelp->keyword[i] != '\0'; i++)
        {
          if (toupper((int) help->keyword[i]) > toupper((int) pHelp->keyword[i]))
          {
            prev = pHelp;
            break;
          }

          if (help->keyword[i+1] == '\0')
          {
            done = TRUE;
            break;
          }

          /* Helpfile should previous to this helpfile entry */
          if (toupper((int) help->keyword[i]) == toupper((int) pHelp->keyword[i]))
          {
            prev = pHelp;
            break;
          }

          /* less than or at the end of the word */
          if (toupper((int) help->keyword[i]) < toupper((int) pHelp->keyword[i]))
          {
            done = TRUE;
            break;
          }
        }

        if (!done)
          continue;
      }

      break;
    }

    if (prev == NULL)
    {
      help->next = help_list;
      help_list = help;
    }
    else
    {
      help->next = prev->next;
      prev->next = help;
    }
  }
}