/*
 * Whitelist will allow players to restrict the domains that are able to login to their character. It functions
 * the same as a reverse site ban, basically. This code was written for AckFUSS with a tiny bit of C++ (bitset),
 * but should be simple to modify and fit into any Diku-derived base. If your MUD does not have ch_printf(), add
 * it or simply replace it with snprintf(buf,stuff) like usual.
 *
 * Add the following to your pc_data struct in your main header file (mud.h, merc.h, etc):
 * char *whitelist[MAX_HOSTS];
 *
 * Add the following to the header file you keep config values in (config.h, mud.h, etc):
 * #define MAX_HOSTS 3
 * #define ACT_WHITELIST <next free bitvector>
 *
 * In your save.c file, if you have a SAVE_REVISION system, increment the revision and add the following into
 * fread_char() and fwrite_char() in the appropriate places with similar code.
 *
 * fprintf( fp, "Whitelist      ");
 *  for( cnt = 0; cnt < MAX_HOSTS; cnt++ )
 *   fprintf(fp,"%s~",ch->pcdata->whitelist[cnt]);
 * fprintf( fp, "\n");
 *
 * if( !str_cmp( word, "Whitelist" ) && !IS_NPC(ch) )
 * {
 *  if( cur_revision >= SAVE_REVISION )
 *  {
 *   for( short i = 0; i < MAX_HOSTS; i++ )
 *    ch->pcdata->whitelist[i] = fread_string( fp );
 *  }
 *  else
 *   SKEY("Host",ch->pcdata->whitelist[0],fread_string(fp));
 *
 * Also in save.c, or wherever you initialize your ch->pcdata struct on load, add the following:
 * for( short i = 0; i < MAX_HOSTS; i++ )
 *  whitelist[i] = &str_empty[0];
 *
 * In comm.c add the following below any deny/ban code. Adjust/remove the monitor_chan() call as needed.
 *
 * if( ch->act.test(ACT_WHITELIST) )
 * {
 *  bool found = false;
 *
 *  for( short i = 0; i < MAX_HOSTS; i++ )
 *   if( ch->pcdata->whitelist[i] != str_empty && !str_prefix(ch->pcdata->whitelist[i],d->host) )
 *    found = true;
 *
 *  if( !found )
 *  {
 *   snprintf(log_buf,(2 * MIL),"Whitelist prohibited login %s@%s.",argument,d->host);
 *   log_string(log_buf);
 *   monitor_chan(log_buf,MONITOR_CONNECT);
 *   write_to_buffer(d,"This is not an approved connection domain for this character.\r\n");
 *   close_socket(d);
 *   return;
 *  }
 * }
 *
 * If your MUD has a do_config() or similar command where autoloot, autosac, etc are handled,
 * drop this in or write something appropriate to allow players to toggle their WHITELIST flag.
 *
 * send_to_char( ch->act.test(ACT_WHITELIST)
 *  ? "@@d[@@a+WHITELIST @@d]@@a You may only login from your whitelist domains.@@N\r\n"
 *  : "@@d[@@c-whitelist @@d]@@c You may login from any domain.@@N\r\n", ch );
 *
 * Add the appropriate inclusions to your interp.c command table, and anyplace else you need to define
 * commands, then drop the below command in a file and you should be good to go!
 *
 * Feel free to modify this code to suit your needs, and if you have a great improvement I wouldn't mind if you
 * shared it with me either, if you're so inclined :D. All I ask is to give me credit for the code if you do
 * choose to use it.
 *
 * --Kline (Matt Goff)
*/

void do_whitelist(CHAR_DATA *ch, char *argument)
{
 char *farg;
 char arg1[MSL] = {'\0'}, arg2[MSL] = {'\0'};
 short i = 0;

 farg = argument;
 farg = one_argument(farg,arg1);
 farg = one_argument(farg,arg2);

 if( arg1[0] == '\0' )
 {
  ch_printf(ch,"You are limited to [%2d] whitelist sites. Whitelist status: [%14s]\r\n",MAX_HOSTS,ch->act.test(ACT_WHITELIST) ? "@@rACTIVE@@N" : "@@eINACTIVE@@N" );
  send_to_char("---------------------------------------------------------------------\r\n",ch);
  for( i = 0; i < MAX_HOSTS; i++ )
   ch_printf(ch,"  [%2d] %s\r\n",i,ch->pcdata->whitelist[i]);
  return;
 }
 if( !str_prefix(arg1,"add") )
 {
  for( i = 0; i < MAX_HOSTS; i++ )
  {
   if( ch->pcdata->whitelist[i] == &str_empty[0] )
   {
    if( arg2[0] == '\0' || strlen(arg2) < 8 )
    {
     send_to_char("Host must be at least 8 characters long.\r\n",ch);
     return;
    }
    ch->pcdata->whitelist[i] = str_dup(arg2);
    send_to_char("Whitelist updated.\r\n",ch);
    return;
   }
  }
  send_to_char("Your whitelist is full. Please delete an entry first.\r\n",ch);
  return;
 }
 else if( !str_prefix(arg1,"del") )
 {
  if( arg2[0] == '\0' )
  {
   send_to_char("You must supply a host to delete.\r\n",ch);
   return;
  }
  for( i = 0; i < MAX_HOSTS; i++ )
  {
   if( !str_cmp(arg2,ch->pcdata->whitelist[i]) )
   {
    ch_printf(ch,"Host %s has been removed from your whitelist.\r\n",ch->pcdata->whitelist[i]);
    free_string(ch->pcdata->whitelist[i]);
    ch->pcdata->whitelist[i] = &str_empty[0];
    return;
   }
  }
  send_to_char("That host was not found. Did you spell it exactly as it is listed in your whitelist?\r\n",ch);
  return;
 }
 else
  do_whitelist(ch);

 return;
}