/* ************************************************************************ * file: autowiz.c Part of CircleMUD * * Usage: self-updating wizlists * * Written by Jeremy Elson * * All Rights Reserved * * Copyright (C) 1993 The Trustees of The Johns Hopkins University * ************************************************************************* */ #include "conf.h" #include "sysdep.h" #include <signal.h> #include "structs.h" #include "utils.h" #include "db.h" #define IMM_LMARG " " #define IMM_NSIZE 16 #define LINE_LEN 64 #define MIN_LEVEL LVL_IMMORT /* max level that should be in columns instead of centered */ #define COL_LEVEL LVL_IMMORT struct name_rec { char name[25]; struct name_rec *next; }; struct control_rec { int level; char *level_name; }; struct level_rec { struct control_rec *params; struct level_rec *next; struct name_rec *names; }; struct control_rec level_params[] = { {LVL_IMMORT, "Immortals"}, {LVL_GOD, "Gods"}, {LVL_GRGOD, "Greater Gods"}, {LVL_IMPL, "Implementors"}, {0, ""} }; struct level_rec *levels = 0; void initialize(void) { struct level_rec *tmp; int i = 0; while (level_params[i].level > 0) { tmp = (struct level_rec *) malloc(sizeof(struct level_rec)); tmp->names = 0; tmp->params = &(level_params[i++]); tmp->next = levels; levels = tmp; } } void read_file(void) { void add_name(byte level, char *name); char *CAP(char *txt); int get_line(FILE * fl, char *buf); bitvector_t asciiflag_conv(char *flag); FILE *fl; int recs, i, last = 0, level = 0, flags = 0; char index_name[40], line[256], bits[64]; char name[MAX_NAME_LENGTH]; long id = 0; sprintf(index_name, "%s%s", LIB_PLRFILES, INDEX_FILE); if (!(fl = fopen(index_name, "r"))) { perror("Error opening playerfile"); exit(1); } /* count the number of players in the index */ recs = 0; while (get_line(fl, line)) if (*line != '~') recs++; rewind(fl); for (i = 0; i < recs; i++) { get_line(fl, line); sscanf(line, "%ld %s %d %s %d", &id, name, &level, bits, &last); CAP(name); flags = asciiflag_conv(bits); if (level >= MIN_LEVEL && !(IS_SET(flags, PINDEX_NOWIZLIST)) && !(IS_SET(flags, PINDEX_DELETED))) add_name(level, name); } fclose(fl); } void add_name(byte level, char *name) { struct name_rec *tmp; struct level_rec *curr_level; char *ptr; if (!*name) return; for (ptr = name; *ptr; ptr++) if (!isalpha(*ptr)) return; tmp = (struct name_rec *) malloc(sizeof(struct name_rec)); strcpy(tmp->name, name); tmp->next = 0; curr_level = levels; while (curr_level->params->level > level) curr_level = curr_level->next; tmp->next = curr_level->names; curr_level->names = tmp; } void sort_names(void) { struct level_rec *curr_level; struct name_rec *a, *b; char temp[100]; for (curr_level = levels; curr_level; curr_level = curr_level->next) { for (a = curr_level->names; a && a->next; a = a->next) { for (b = a->next; b; b = b->next) { if (strcmp(a->name, b->name) > 0) { strcpy(temp, a->name); strcpy(a->name, b->name); strcpy(b->name, temp); } } } } } void write_wizlist(FILE * out, int minlev, int maxlev) { char buf[100]; struct level_rec *curr_level; struct name_rec *curr_name; int i, j; fprintf(out, "*******************************************************************************\n" "* The following people have reached immortality on tbaMUD. *\n" "*******************************************************************************\n\n"); for (curr_level = levels; curr_level; curr_level = curr_level->next) { if (curr_level->params->level < minlev || curr_level->params->level > maxlev) continue; i = 39 - (strlen(curr_level->params->level_name) >> 1); for (j = 1; j <= i; j++) fputc(' ', out); fprintf(out, "%s\n", curr_level->params->level_name); for (j = 1; j <= i; j++) fputc(' ', out); for (j = 1; j <= strlen(curr_level->params->level_name); j++) fputc('~', out); fprintf(out, "\n"); strcpy(buf, ""); curr_name = curr_level->names; while (curr_name) { strcat(buf, curr_name->name); if (strlen(buf) > LINE_LEN) { if (curr_level->params->level <= COL_LEVEL) fprintf(out, IMM_LMARG); else { i = 40 - (strlen(buf) >> 1); for (j = 1; j <= i; j++) fputc(' ', out); } fprintf(out, "%s\n", buf); strcpy(buf, ""); } else { if (curr_level->params->level <= COL_LEVEL) { for (j = 1; j <= (IMM_NSIZE - strlen(curr_name->name)); j++) strcat(buf, " "); } if (curr_level->params->level > COL_LEVEL) strcat(buf, " "); } curr_name = curr_name->next; } if (*buf) { if (curr_level->params->level <= COL_LEVEL) fprintf(out, "%s%s\n", IMM_LMARG, buf); else { i = 40 - (strlen(buf) >> 1); for (j = 1; j <= i; j++) fputc(' ', out); fprintf(out, "%s\n", buf); } } fprintf(out, "\n"); } } int main(int argc, char **argv) { int wizlevel, immlevel, pid = 0; FILE *fl; if (argc != 5 && argc != 6) { printf("Format: %s wizlev wizlistfile immlev immlistfile [pid to signal]\n", argv[0]); exit(0); } wizlevel = atoi(argv[1]); immlevel = atoi(argv[3]); #ifdef CIRCLE_UNIX /* Perhaps #ifndef CIRCLE_WINDOWS but ... */ if (argc == 6) pid = atoi(argv[5]); #endif initialize(); read_file(); sort_names(); fl = fopen(argv[2], "w"); write_wizlist(fl, wizlevel, LVL_IMPL); fclose(fl); fl = fopen(argv[4], "w"); write_wizlist(fl, immlevel, wizlevel - 1); fclose(fl); #ifdef CIRCLE_UNIX /* ... I don't have the platforms to test. */ if (pid) kill(pid, SIGUSR1); #endif return (0); } char *CAP(char *txt) { *txt = UPPER(*txt); return (txt); } /* get_line reads the next non-blank line off of the input stream. The newline * character is removed from the input. Lines which begin with '*' are * considered to be comments. Returns the number of lines advanced in the * file. */ int get_line(FILE * fl, char *buf) { char temp[256]; int lines = 0; do { fgets(temp, 256, fl); if (feof(fl)) return (0); lines++; } while (*temp == '*' || *temp == '\n'); temp[strlen(temp) - 1] = '\0'; strcpy(buf, temp); return (lines); } bitvector_t asciiflag_conv(char *flag) { bitvector_t flags = 0; int is_number = 1; register char *p; for (p = flag; *p; p++) { if (islower(*p)) flags |= 1 << (*p - 'a'); else if (isupper(*p)) flags |= 1 << (26 + (*p - 'A')); if (!isdigit(*p)) is_number = 0; } if (is_number) flags = atol(flag); return (flags); }