/*
* commac.c
*/
/*
* $Id: commac.c,v 1.3 2005/08/08 09:43:05 murrayma Exp $
*/
#include "copyright.h"
#include "config.h"
#include <ctype.h>
#include <sys/types.h>
#include "db.h"
#include "interface.h"
#include "match.h"
#include "config.h"
#include "externs.h"
#include "commac.h"
extern void load_comsystem(FILE *);
extern void load_macros(FILE *);
extern void save_comsystem(FILE *);
extern void save_macros(FILE *);
void load_comsys_and_macros(char *filename) {
FILE *fp;
int i;
char buffer[200];
for (i = 0; i < NUM_COMMAC; i++)
commac_table[i] = NULL;
if (!(fp = fopen(filename, "r"))) {
fprintf(stderr, "Error: Couldn't find %s.\n", filename);
} else {
fprintf(stderr, "LOADING: %s\n", filename);
if (fscanf(fp, "*** Begin %s ***\n", buffer) == 1 &&
!strcmp(buffer, "COMMAC")) {
load_commac(fp);
} else {
fprintf(stderr, "Error: Couldn't find Begin COMMAC in %s.",
filename);
return;
}
if (fscanf(fp, "*** Begin %s ***\n", buffer) == 1 &&
!strcmp(buffer, "COMSYS")) {
load_comsystem(fp);
} else {
fprintf(stderr, "Error: Couldn't find Begin COMSYS in %s.",
filename);
return;
}
if (fscanf(fp, "*** Begin %s ***\n", buffer) == 1 &&
!strcmp(buffer, "MACRO")) {
load_macros(fp);
} else {
fprintf(stderr, "Error: Couldn't find Begin MACRO in %s.",
filename);
return;
}
fclose(fp);
fprintf(stderr, "LOADING: %s (done)\n", filename);
}
}
void save_comsys_and_macros(char *filename) {
FILE *fp;
char buffer[500];
sprintf(buffer, "%s.#", filename);
if (!(fp = fopen(buffer, "w"))) {
fprintf(stderr, "Unable to open %s for writing.\n", buffer);
return;
}
fprintf(fp, "*** Begin COMMAC ***\n");
save_commac(fp);
fprintf(fp, "*** Begin COMSYS ***\n");
save_comsystem(fp);
fprintf(fp, "*** Begin MACRO ***\n");
save_macros(fp);
fclose(fp);
rename(buffer, filename);
}
void load_commac(FILE * fp) {
int i, j;
char buffer[100];
int np;
struct commac *c;
char *t;
char in;
fscanf(fp, "%d\n", &np);
for (i = 0; i < np; i++) {
c = create_new_commac();
fscanf(fp, "%d %d %d %d %d %d %d %d\n", &(c->who),
&(c->numchannels), &(c->macros[0]), &(c->macros[1]),
&c->macros[2], &(c->macros[3]), &(c->macros[4]), &(c->curmac));
c->maxchannels = c->numchannels;
if (c->maxchannels > 0) {
c->alias = (char *) malloc(c->maxchannels * 6);
c->channels =
(char **) malloc(sizeof(char *) * c->maxchannels);
for (j = 0; j < c->numchannels; j++) {
t = c->alias + j * 6;
while ((in = fgetc(fp)) != ' ')
*t++ = in;
*t = 0;
fscanf(fp, "%[^\n]\n", buffer);
c->channels[j] = (char *) malloc(strlen(buffer) + 1);
StringCopy(c->channels[j], buffer);
}
sort_com_aliases(c);
} else {
c->alias = NULL;
c->channels = NULL;
}
if ((Typeof(c->who) == TYPE_PLAYER) || (!God(Owner(c->who))) ||
((!Going(c->who))))
add_commac(c);
purge_commac();
}
}
void purge_commac(void) {
struct commac *c;
struct commac *d;
int i;
#ifdef ABORT_PURGE_COMSYS
return;
#endif /*
* * ABORT_PURGE_COMSYS
*/
for (i = 0; i < NUM_COMMAC; i++) {
c = commac_table[i];
while (c) {
d = c;
c = c->next;
if (d->numchannels == 0 && d->curmac == -1 &&
d->macros[1] == -1 && d->macros[2] == -1 &&
d->macros[3] == -1 && d->macros[4] == -1 &&
d->macros[0] == -1) {
del_commac(d->who);
continue;
}
/*
* if ((Typeof(d->who) != TYPE_PLAYER) && (God(Owner(d->who))) &&
* * (Going(d->who)))
*/
if (Typeof(d->who) == TYPE_PLAYER)
continue;
if (God(Owner(d->who)) && Going(d->who)) {
del_commac(d->who);
continue;
}
}
}
}
void save_commac(FILE * fp) {
int np;
struct commac *c;
int i, j;
purge_commac();
np = 0;
for (i = 0; i < NUM_COMMAC; i++) {
c = commac_table[i];
while (c) {
np++;
c = c->next;
}
}
fprintf(fp, "%d\n", np);
for (i = 0; i < NUM_COMMAC; i++) {
c = commac_table[i];
while (c) {
fprintf(fp, "%d %d %d %d %d %d %d %d\n", c->who,
c->numchannels, c->macros[0], c->macros[1], c->macros[2],
c->macros[3], c->macros[4], c->curmac);
for (j = 0; j < c->numchannels; j++) {
fprintf(fp, "%s %s\n", c->alias + j * 6, c->channels[j]);
}
c = c->next;
}
}
}
struct commac *create_new_commac(void) {
struct commac *c;
int i;
c = (struct commac *) malloc(sizeof(struct commac));
c->who = -1;
c->numchannels = 0;
c->maxchannels = 0;
c->alias = NULL;
c->channels = NULL;
c->curmac = -1;
for (i = 0; i < 5; i++)
c->macros[i] = -1;
c->next = NULL;
return c;
}
struct commac *get_commac(dbref which) {
struct commac *c;
if (which < 0)
return NULL;
c = commac_table[which % NUM_COMMAC];
while (c && (c->who != which))
c = c->next;
if (!c) {
c = create_new_commac();
c->who = which;
add_commac(c);
}
return c;
}
void add_commac(struct commac *c) {
if (c->who < 0)
return;
c->next = commac_table[c->who % NUM_COMMAC];
commac_table[c->who % NUM_COMMAC] = c;
}
void del_commac(dbref who) {
struct commac *c;
struct commac *last;
if (who < 0)
return;
c = commac_table[who % NUM_COMMAC];
if (c == NULL)
return;
if (c->who == who) {
commac_table[who % NUM_COMMAC] = c->next;
destroy_commac(c);
return;
}
last = c;
c = c->next;
while (c) {
if (c->who == who) {
last->next = c->next;
destroy_commac(c);
return;
}
last = c;
c = c->next;
}
}
void destroy_commac(struct commac *c) {
int i;
free(c->alias);
for (i = 0; i < c->numchannels; i++)
free(c->channels[i]);
free(c->channels);
free(c);
}
void sort_com_aliases(struct commac *c) {
int i;
int cont;
char buffer[10];
char *s;
cont = 1;
while (cont) {
cont = 0;
for (i = 0; i < c->numchannels - 1; i++)
if (strcasecmp(c->alias + i * 6, c->alias + (i + 1) * 6) > 0) {
StringCopy(buffer, c->alias + i * 6);
StringCopy(c->alias + i * 6, c->alias + (i + 1) * 6);
StringCopy(c->alias + (i + 1) * 6, buffer);
s = c->channels[i];
c->channels[i] = c->channels[i + 1];
c->channels[i + 1] = s;
cont = 1;
}
}
}