muse1.7b4/
muse1.7b4/config/
muse1.7b4/doc/
muse1.7b4/run/
muse1.7b4/run/db/
muse1.7b4/src/
muse1.7b4/src/db/
muse1.7b4/src/files/
muse1.7b4/src/io/
muse1.7b4/src/prog/
muse1.7b4/src/util/
/* player_list.c */
/* $Id: players.c,v 1.8 1993/09/07 18:24:42 nils Exp $ */

#include "copyright.h"
#include <ctype.h>
#include "db.h"
#include "config.h"
#include "interface.h"
#include "externs.h"
#include "nalloc.h"

#define PLAYER_LIST_SIZE (1 << 12) /* must be a power of 2 */

static dbref hash_function_table[256];
static int hft_initialized = 0;
static NALLOC *pla;

#define DOWNCASE(x) to_lower(x)
struct pl_elt {
  dbref player;		/* pointer to player */
  /* key is db[player].name */
  struct pl_elt *next;
};

static void init_hft()
{
  int i;
  pla=na_open(sizeof(struct pl_elt));
  
  for(i = 0; i < 256; i++) {
    hash_function_table[i] = random() & (PLAYER_LIST_SIZE - 1);
  }
  hft_initialized = 1;
}

static dbref hash_function(string)
 char *string;
{
  dbref hash;
  
  if(!hft_initialized) init_hft();
  hash = 0;
  for(; *string; string++) {
    hash ^= ((hash >> 1) ^ hash_function_table[(int)DOWNCASE(*string)]);
  }
  return(hash);
}

static struct pl_elt *player_list[PLAYER_LIST_SIZE];
static int pl_used = 0;

void clear_players()
{
  int i;
  struct pl_elt *e;
  struct pl_elt *next;
  
  for(i = 0; i < PLAYER_LIST_SIZE; i++) {
    if(pl_used) {
      for(e = player_list[i]; e; e = next) {
	next = e->next;
	na_free(pla,e);
      }
    }
    player_list[i] = 0;
  }
  pl_used = 1;
}

void add_player(player)
     dbref player;
{
  dbref hash;
  struct pl_elt *e;
  
  hash = hash_function(db[player].name);
  e=(struct pl_elt *)na_get(pla);
  e->player = player;
  e->next = player_list[hash];
  player_list[hash] = e;
  if(*atr_get(player,A_ALIAS)) {
    hash = hash_function(atr_get(player,A_ALIAS));
    e=(struct pl_elt *)na_get(pla);
    e->player = player;
    e->next = player_list[hash];
    player_list[hash]=e;
  }
}

dbref lookup_player(name)
     char *name;
{
  struct pl_elt *e;
  dbref a;

  while (name[0] == '*') name++;
  for(e = player_list[hash_function(name)]; e; e = e->next) {
    if(!string_compare(db[e->player].name, name) ||
       !string_compare(atr_get(e->player,A_ALIAS),name)) return e->player;
  }
  if(name[0] == '#' && name[1]) {
    a = atoi(name+1);
    if (a>=0 && a<db_top) return a;
  }
  return NOTHING;
}

void delete_player(player)
     dbref player;
{
  dbref hash;
  struct pl_elt *prev;
  struct pl_elt *e;
  
  hash = hash_function(db[player].name);
  if((e = player_list[hash]) == 0) {
    return;
  } else if(e->player == player) {
    /* it's the first one */
    player_list[hash] = e->next;
    na_free(pla,e);
  } else {
    for(prev = e, e = e->next; e; prev = e, e = e->next) {
      if(e->player == player) {
	/* got it */
	prev->next = e->next;
	na_free(pla,e);
	break;
      }
    }
  }
  if(*atr_get(player,A_ALIAS)) {
    hash = hash_function(atr_get(player,A_ALIAS));
    if((e = player_list[hash]) == 0) {
      return;
    } else if(e->player == player) {
      /* it's the first one */
      player_list[hash] = e->next;
      na_free(pla,e);
    } else {
      for(prev = e, e = e->next; e; prev = e, e = e->next) {
	if(e->player == player) {
	  /* got it */
	  prev->next = e->next;
	  na_free(pla,e);
	  break;
	}
      }
    }
  }
}