// comsys.cpp // // * $Id: comsys.cpp,v 1.12 2000/09/07 07:31:38 sdennis Exp $ // #include "copyright.h" #include "autoconf.h" #include "config.h" #include "externs.h" #include <sys/types.h> #include "ansi.h" #include "db.h" #include "interface.h" #include "attrs.h" #include "match.h" #include "config.h" #include "flags.h" #include "powers.h" #include "functions.h" #include "comsys.h" int num_channels; int max_channels; struct channel **channels; comsys_t *comsys_table[NUM_COMSYS]; // Return value must be free_lbuf'ed. // char *RestrictTitleValue(char *pTitleRequest) { // First, remove all '\r\n\t' from the string. // char *pNewTitle = RemoveSetOfCharacters(pTitleRequest, "\r\n\t"); // Optimize/terminate any ANSI in the string. // char NewTitle_ANSI[MAX_TITLE_LEN+1]; int nVisualWidth; int nLen = ANSI_TruncateToField(pNewTitle, sizeof(NewTitle_ANSI), NewTitle_ANSI, sizeof(NewTitle_ANSI), &nVisualWidth, FALSE); memcpy(pNewTitle, NewTitle_ANSI, nLen+1); return pNewTitle; } void do_setnewtitle(dbref player, struct channel *ch, char *pValidatedTitle) { struct comuser *user = select_user(ch, player); if (ch && user) { if (user->title) { MEMFREE(user->title); } user->title = StringClone(pValidatedTitle); } } void load_comsys(char *filename) { int i; char buffer[200]; for (i = 0; i < NUM_COMSYS; i++) { comsys_table[i] = NULL; } FILE *fp = fopen(filename, "rb"); if (!fp) { Log.printf("Error: Couldn't find %s.\n", filename); } else { DebugTotalFiles++; Log.printf("LOADING: %s\n", filename); if (fscanf(fp, "*** Begin %s ***\n", buffer) == 1 && !strcmp(buffer, "COMMAC")) { load_old_channels(fp); } else if (!strcmp(buffer, "CHANNELS")) { load_channels(fp); } else { Log.printf("Error: Couldn't find Begin CHANNELS in %s.", filename); return; } if (fscanf(fp, "*** Begin %s ***\n", buffer) == 1 && !strcmp(buffer, "COMSYS")) { load_comsystem(fp); } else { Log.printf("Error: Couldn't find Begin COMSYS in %s.", filename); return; } if (fclose(fp) == 0) { DebugTotalFiles--; } Log.printf("LOADING: %s (done)\n", filename); } } void save_comsys(char *filename) { char buffer[500]; sprintf(buffer, "%s.#", filename); FILE *fp = fopen(buffer, "wb"); if (!fp) { Log.printf("Unable to open %s for writing.\n", buffer); return; } DebugTotalFiles++; fprintf(fp, "*** Begin CHANNELS ***\n"); save_channels(fp); fprintf(fp, "*** Begin COMSYS ***\n"); save_comsystem(fp); if (fclose(fp) == 0) { DebugTotalFiles--; } ReplaceFile(buffer, filename); } // Aliases must be between 1 and 5 characters. No spaces. No ANSI. // char *MakeCanonicalComAlias(const char *pAlias, int *nValidAlias, BOOL *bValidAlias) { static char Buffer[6]; *nValidAlias = 0; *bValidAlias = FALSE; if (!pAlias) { return NULL; } const char *p = pAlias; char *q = Buffer; int n = 0; while (*p) { if (!Tiny_IsPrint[(unsigned char)*p] || *p == ' ') { return NULL; } if (n <= 5) { n++; *q++ = *p; } p++; } *q = '\0'; if (n < 1 || 5 < n) { return FALSE; } *nValidAlias = n; *bValidAlias = TRUE; return Buffer; } BOOL ParseChannelLine(char *pBuffer, char *pAlias5, char **ppChannelName) { // Fetch alias portion. We need to find the first space. // char *p = strchr(pBuffer, ' '); if (!p) return FALSE; *p = '\0'; BOOL bValidAlias; int nValidAlias; char *pValidAlias = MakeCanonicalComAlias(pBuffer, &nValidAlias, &bValidAlias); if (!bValidAlias) { return FALSE; } strcpy(pAlias5, pValidAlias); // Skip any leading space before the channel name. // p++; while (Tiny_IsSpace[(unsigned char)*p]) { p++; } if (*p == '\0') { return FALSE; } // The rest of the line is the channel name. // *ppChannelName = StringClone(p); return TRUE; } void load_channels(FILE *fp) { int i, j; char buffer[LBUF_SIZE]; int np; comsys_t *c; fscanf(fp, "%d\n", &np); for (i = 0; i < np; i++) { c = create_new_comsys(); fscanf(fp, "%d %d\n", &(c->who), &(c->numchannels)); c->maxchannels = c->numchannels; if (c->maxchannels > 0) { c->alias = (char *)MEMALLOC(c->maxchannels * 6); ISOUTOFMEMORY(c->alias); c->channels = (char **)MEMALLOC(sizeof(char *) * c->maxchannels); ISOUTOFMEMORY(c->channels); for (j = 0; j < c->numchannels; j++) { fscanf(fp, "%[^\n]\n", buffer); if (!ParseChannelLine(buffer, c->alias + j * 6, c->channels+j)) { c->numchannels--; j--; } } sort_com_aliases(c); } else { c->alias = NULL; c->channels = NULL; } if (c->who >= 0 && c->who < mudstate.db_top) { if ((Typeof(c->who) == TYPE_PLAYER) || (!God(Owner(c->who))) || ((!Going(c->who)))) { add_comsys(c); } } else { Log.printf("dbref %d out of range [0, %d)\n", c->who, mudstate.db_top); } purge_comsystem(); } } void load_old_channels(FILE *fp) { int i, j, k; char buffer[LBUF_SIZE]; int np; comsys_t *c; char *t; char in; fscanf(fp, "%d\n", &np); for (i = 0; i < np; i++) { c = create_new_comsys(); /* Trash the old values! */ fscanf(fp, "%d %d %d %d %d %d %d %d\n", &(c->who), &(c->numchannels), &k, &k, &k, &k, &k, &k); c->maxchannels = c->numchannels; if (c->maxchannels > 0) { c->alias = (char *)MEMALLOC(c->maxchannels * 6); ISOUTOFMEMORY(c->alias); c->channels = (char **)MEMALLOC(sizeof(char *) * c->maxchannels); ISOUTOFMEMORY(c->channels); 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] = StringClone(buffer); } sort_com_aliases(c); } else { c->alias = NULL; c->channels = NULL; } if (c->who >= 0 && c->who < mudstate.db_top) { if ((Typeof(c->who) == TYPE_PLAYER) || (!God(Owner(c->who))) || ((!Going(c->who)))) { add_comsys(c); } } else { Log.printf("load_old_channels: dbref %d out of range [0, %d)\n", c->who, mudstate.db_top); } purge_comsystem(); } } void purge_comsystem(void) { comsys_t *c; comsys_t *d; int i; #ifdef ABORT_PURGE_COMSYS return; #endif /* * * ABORT_PURGE_COMSYS */ for (i = 0; i < NUM_COMSYS; i++) { c = comsys_table[i]; while (c) { d = c; c = c->next; if (d->numchannels == 0) { del_comsys(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_comsys(d->who); continue; } } } } void save_channels(FILE *fp) { int np; comsys_t *c; int i, j; purge_comsystem(); np = 0; for (i = 0; i < NUM_COMSYS; i++) { c = comsys_table[i]; while (c) { np++; c = c->next; } } fprintf(fp, "%d\n", np); for (i = 0; i < NUM_COMSYS; i++) { c = comsys_table[i]; while (c) { fprintf(fp, "%d %d\n", c->who, c->numchannels); for (j = 0; j < c->numchannels; j++) { fprintf(fp, "%s %s\n", c->alias + j * 6, c->channels[j]); } c = c->next; } } } comsys_t *create_new_comsys(void) { comsys_t *c; c = (comsys_t *)MEMALLOC(sizeof(comsys_t)); ISOUTOFMEMORY(c); c->who = -1; c->numchannels = 0; c->maxchannels = 0; c->alias = NULL; c->channels = NULL; c->next = NULL; return c; } comsys_t *get_comsys(dbref which) { comsys_t *c; if (which < 0) return NULL; c = comsys_table[which % NUM_COMSYS]; while (c && (c->who != which)) c = c->next; if (!c) { c = create_new_comsys(); c->who = which; add_comsys(c); } return c; } void add_comsys(comsys_t *c) { if (c->who < 0 || c->who >= mudstate.db_top) { Log.printf("add_comsys: dbref %d out of range [0, %d)\n", c->who, mudstate.db_top); return; } c->next = comsys_table[c->who % NUM_COMSYS]; comsys_table[c->who % NUM_COMSYS] = c; } void del_comsys(dbref who) { comsys_t *c; comsys_t *last; if (who < 0 || who >= mudstate.db_top) { Log.printf("del_comsys: dbref %d out of range [0, %d)\n", who, mudstate.db_top); return; } c = comsys_table[who % NUM_COMSYS]; if (c == NULL) return; if (c->who == who) { comsys_table[who % NUM_COMSYS] = c->next; destroy_comsys(c); return; } last = c; c = c->next; while (c) { if (c->who == who) { last->next = c->next; destroy_comsys(c); return; } last = c; c = c->next; } } void destroy_comsys(comsys_t *c) { int i; if (c->alias) { MEMFREE(c->alias); } for (i = 0; i < c->numchannels; i++) { MEMFREE(c->channels[i]); } if (c->channels) { MEMFREE(c->channels); } MEMFREE(c); } void sort_com_aliases(comsys_t *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 (strcmp(c->alias + i * 6, c->alias + (i + 1) * 6) > 0) { strcpy(buffer, c->alias + i * 6); strcpy(c->alias + i * 6, c->alias + (i + 1) * 6); strcpy(c->alias + (i + 1) * 6, buffer); s = c->channels[i]; c->channels[i] = c->channels[i + 1]; c->channels[i + 1] = s; cont = 1; } } } } char *get_channel_from_alias(dbref player, char *alias) { comsys_t *c; int first, last, current; int dir; c = get_comsys(player); current = 0; first = 0; last = c->numchannels - 1; dir = 1; while (dir && (first <= last)) { current = (first + last) / 2; dir = strcmp(alias, c->alias + 6 * current); if (dir < 0) last = current - 1; else first = current + 1; } if (!dir) return c->channels[current]; else return ""; } void load_comsystem(FILE *fp) { int i, j, dummy; int nc, new0 = 0; struct channel *ch; struct comuser *user; char temp[1000]; char buf[8]; num_channels = 0; fgets(buf, sizeof(buf), fp); if (!strncmp(buf, "+V1", 3)) { new0 = 1; fscanf(fp, "%d\n", &nc); } else { nc = Tiny_atol(buf); } num_channels = nc; for (i = 0; i < nc; i++) { ch = (struct channel *)MEMALLOC(sizeof(struct channel)); ISOUTOFMEMORY(ch); fscanf(fp, "%[^\n]\n", temp); strcpy(ch->name, temp); ch->on_users = NULL; hashaddLEN(ch->name, strlen(ch->name), (int *)ch, &mudstate.channel_htab); if (new0) { fscanf(fp, "%d %d %d %d %d %d %d %d\n", &(ch->type), &(ch->temp1), &(ch->temp2), &(ch->charge), &(ch->charge_who), &(ch->amount_col), &(ch->num_messages), &(ch->chan_obj)); } else { fscanf(fp, "%d %d %d %d %d %d %d %d %d %d\n", &(ch->type), &(dummy), &(ch->temp1), &(ch->temp2), &(dummy), &(ch->charge), &(ch->charge_who), &(ch->amount_col), &(ch->num_messages), &(ch->chan_obj)); } fscanf(fp, "%d\n", &(ch->num_users)); ch->max_users = ch->num_users; if (ch->num_users > 0) { ch->users = (struct comuser **)calloc(ch->max_users, sizeof(struct comuser *)); for (j = 0; j < ch->num_users; j++) { user = (struct comuser *)MEMALLOC(sizeof(struct comuser)); ISOUTOFMEMORY(user); ch->users[j] = user; if (new0) { fscanf(fp, "%d %d\n", &(user->who), &(user->bUserIsOn)); } else { fscanf(fp, "%d %d %d", &(user->who), &(dummy), &(dummy)); fscanf(fp, "%d\n", &(user->bUserIsOn)); } fscanf(fp, "%[^\n]\n", temp); user->title = StringClone(temp+2); if (user->who >= 0 && user->who < mudstate.db_top) { if ( !(isPlayer(user->who)) && !(Going(user->who) && (God(Owner(user->who))))) { do_joinchannel(user->who, ch); user->on_next = ch->on_users; ch->on_users = user; } else { user->on_next = ch->on_users; ch->on_users = user; } } else { Log.printf("load_comsystem: dbref %d out of range [0, %d)\n", user->who, mudstate.db_top); } } sort_users(ch); } else { ch->users = NULL; } } } void save_comsystem(FILE *fp) { struct channel *ch; struct comuser *user; int j; fprintf(fp, "+V1\n"); fprintf(fp, "%d\n", num_channels); for (ch = (struct channel *)hash_firstentry(&mudstate.channel_htab); ch; ch = (struct channel *)hash_nextentry(&mudstate.channel_htab)) { fprintf(fp, "%s\n", ch->name); fprintf(fp, "%d %d %d %d %d %d %d %d\n", ch->type, ch->temp1, ch->temp2, ch->charge, ch->charge_who, ch->amount_col, ch->num_messages, ch->chan_obj); // Count the number of 'valid' users to dump. // int nUsers = 0; for (j = 0; j < ch->num_users; j++) { user = ch->users[j]; if (user->who >= 0 && user->who < mudstate.db_top) { nUsers++; } } fprintf(fp, "%d\n", nUsers); for (j = 0; j < ch->num_users; j++) { user = ch->users[j]; if (user->who >= 0 && user->who < mudstate.db_top) { user = ch->users[j]; fprintf(fp, "%d %d\n", user->who, user->bUserIsOn); if (user->title[0] != '\0') fprintf(fp, "t:%s\n", user->title); else fprintf(fp, "t:\n"); } } } } void do_processcom(dbref player, char *arg1, char *arg2) { char *mess, *bp; if ((strlen(arg1) + strlen(arg2)) > 3500) { arg2[3500] = '\0'; // TODO: Incorrect logic that doesn't hurt anything. } if (!*arg2) { raw_notify(player, "No message."); return; } struct channel *ch = select_channel(arg1); if (!ch) { raw_notify(player, tprintf("Unknown channel %s.", arg1)); return; } struct comuser *user = select_user(ch, player); if (!user) { raw_notify(player, "You are not listed as on that channel. Delete this alias and readd."); return; } if (!strcmp(arg2, "on")) { do_joinchannel(player, ch); } else if (!strcmp(arg2, "off")) { do_leavechannel(player, ch); } else if (!user->bUserIsOn) { raw_notify(player, tprintf("You must be on %s to do that.", arg1)); return; } else if (!strcmp(arg2, "who")) { do_comwho(player, ch); } else if (!(do_test_access(player, CHANNEL_TRANSMIT, ch))) { raw_notify(player, "That channel type cannot be transmitted on."); return; } else { if (!payfor(player, Guest(player) ? 0 : ch->charge)) { notify(player, tprintf("You don't have enough %s.", mudconf.many_coins)); return; } else { ch->amount_col += ch->charge; giveto(ch->charge_who, ch->charge); } bp = mess = alloc_lbuf("do_processcom"); if ((*arg2) == ':') { if (user->title[0] != '\0') { // There is a comtitle. // if (ch->type & CHANNEL_SPOOF) { safe_tprintf_str(mess, &bp, "[%s] %s %s", arg1, user->title, arg2 + 1); } else { safe_tprintf_str(mess, &bp, "[%s] %s %s %s", arg1, user->title, Name(player), arg2 + 1); } } else { safe_tprintf_str(mess, &bp, "[%s] %s %s", arg1, Name(player), arg2 + 1); } } else if ((*arg2) == ';') { if (user->title[0] != '\0') { // There is a comtitle // if (ch->type & CHANNEL_SPOOF) { safe_tprintf_str(mess, &bp, "[%s] %s%s", arg1, user->title, arg2 + 1); } else { safe_tprintf_str(mess, &bp, "[%s] %s %s%s", arg1, user->title, Name(player), arg2 + 1); } } else { safe_tprintf_str(mess, &bp, "[%s] %s%s", arg1, Name(player), arg2 + 1); } } else { if (user->title[0] != '\0') { // There is a comtitle // if (ch->type & CHANNEL_SPOOF) { safe_tprintf_str(mess, &bp, "[%s] %s says, \"%s\"", arg1, user->title, arg2); } else { safe_tprintf_str(mess, &bp, "[%s] %s %s says, \"%s\"", arg1, user->title, Name(player), arg2); } } else { safe_tprintf_str(mess, &bp, "[%s] %s says, \"%s\"", arg1, Name(player), arg2); } } do_comsend(ch, mess); free_lbuf(mess); } } void do_comsend(struct channel *ch, char *msgNormal) { struct comuser *user; ch->num_messages++; for (user = ch->on_users; user; user = user->on_next) { if (user->bUserIsOn) { if (do_test_access(user->who, CHANNEL_RECEIVE, ch)) { if ((Typeof(user->who) == TYPE_PLAYER) && Connected(user->who)) raw_notify(user->who, msgNormal); else notify(user->who, msgNormal); } } } } void do_joinchannel(dbref player, struct channel *ch) { char temp[1000]; struct comuser *user; struct comuser **cu; int i; user = select_user(ch, player); if (!user) { ch->num_users++; if (ch->num_users >= ch->max_users) { ch->max_users += 10; cu = (struct comuser **)MEMALLOC(sizeof(struct comuser *) * ch->max_users); ISOUTOFMEMORY(cu); for (i = 0; i < (ch->num_users - 1); i++) { cu[i] = ch->users[i]; } MEMFREE(ch->users); ch->users = cu; } user = (struct comuser *)MEMALLOC(sizeof(struct comuser)); ISOUTOFMEMORY(user); for (i = ch->num_users - 1; i > 0 && ch->users[i - 1]->who > player; i--) { ch->users[i] = ch->users[i - 1]; } ch->users[i] = user; user->who = player; user->bUserIsOn = 1; user->title = StringClone(""); // if (Connected(player))&&(isPlayer(player)) // if UNDEAD(player) { user->on_next = ch->on_users; ch->on_users = user; } } else if (!user->bUserIsOn) { user->bUserIsOn = 1; } else { raw_notify(player, tprintf("You are already on channel %s.", ch->name)); return; } if (!Dark(player)) { if (user->title[0] != '\0') { // There is a comtitle // if (ch->type & CHANNEL_SPOOF) { sprintf(temp, "[%s] %s has joined this channel.", ch->name, user->title); } else { sprintf(temp, "[%s] %s %s has joined this channel.", ch->name, user->title, Name(player)); } } else { sprintf(temp, "[%s] %s has joined this channel.", ch->name, Name(player)); } do_comsend(ch, temp); } } void do_leavechannel(dbref player, struct channel *ch) { struct comuser *user; char temp[1000]; user = select_user(ch, player); raw_notify(player, tprintf("You have left channel %s.", ch->name)); if ((user->bUserIsOn) && (!Dark(player))) { if (user->title[0] != '\0') { // There is a comtitle // if (ch->type & CHANNEL_SPOOF) { sprintf(temp, "[%s] %s has left this channel.", ch->name, user->title); } else { sprintf(temp, "[%s] %s %s has left this channel.", ch->name, user->title, Name(player)); } } else { sprintf(temp, "[%s] %s has left this channel.", ch->name, Name(player)); } do_comsend(ch, temp); } user->bUserIsOn = 0; } void do_comwho_line ( dbref player, struct channel *ch, struct comuser *user ) { char *msg; char *buff = NULL; if (user->title[0] != '\0') { // There is a comtitle // if (Staff(player)) { buff = unparse_object(player, user->who, 0); if (ch->type & CHANNEL_SPOOF) { msg = tprintf("%s as %s", buff, user->title); } else { msg = tprintf("%s as %s %s", buff, user->title, buff); } } else { if (ch->type & CHANNEL_SPOOF) { msg = user->title; } else { buff = unparse_object(player, user->who, 0); msg = tprintf("%s %s", user->title, buff); } } } else { buff = unparse_object(player, user->who, 0); msg = buff; } raw_notify(player, msg); if (buff) { free_lbuf(buff); } } void do_comwho(dbref player, struct channel *ch) { struct comuser *user; raw_notify(player, "-- Players --"); for (user = ch->on_users; user; user = user->on_next) { if (Typeof(user->who) == TYPE_PLAYER) { if (Connected(user->who) && (!Dark(user->who) || Wizard_Who(player))) { if (user->bUserIsOn) { do_comwho_line(player, ch, user); } } else if (!Dark(user->who)) { do_comdisconnectchannel(user->who, ch->name); } } } raw_notify(player, "-- Objects --"); for (user = ch->on_users; user; user = user->on_next) { if (Typeof(user->who) != TYPE_PLAYER) { if ((Going(user->who)) && (God(Owner(user->who)))) { do_comdisconnectchannel(user->who, ch->name); } else if (user->bUserIsOn) { do_comwho_line(player, ch, user); } } } raw_notify(player, tprintf("-- %s --", ch->name)); } struct channel *select_channel(char *channel) { struct channel *cp; cp = (struct channel *)hashfindLEN(channel, strlen(channel), &mudstate.channel_htab); if (!cp) return NULL; else return cp; } struct comuser *select_user(struct channel *ch, dbref player) { int first, last, current; int dir; if (!ch) return NULL; first = 0; last = ch->num_users - 1; dir = 1; current = (first + last) / 2; while (dir && (first <= last)) { current = (first + last) / 2; if (ch->users[current] == NULL) { last--; continue; } if (ch->users[current]->who == player) dir = 0; else if (ch->users[current]->who < player) { dir = 1; first = current + 1; } else { dir = -1; last = current - 1; } } if (!dir) return ch->users[current]; else return NULL; } void do_addcom(dbref player, dbref cause, int key, char *arg1, char *arg2) { char channel[MAX_CHANNEL_LEN+1]; char title[MAX_TITLE_LEN+1]; char Buffer[MAX_CHANNEL_LEN+1]; struct channel *ch; char *s, *t; int i, j, where; comsys_t *c; char *na; char **nc; if (!mudconf.have_comsys) { raw_notify(player, "Comsys disabled."); return; } BOOL bValidAlias; int nValidAlias; char *pValidAlias = MakeCanonicalComAlias(arg1, &nValidAlias, &bValidAlias); if (!bValidAlias) { raw_notify(player, "You need to specify a valid alias."); return; } s = arg2; if (!*s) { raw_notify(player, "You need to specify a channel."); return; } t = channel; while (*s && (*s != ',') && ((t - channel) < MAX_CHANNEL_LEN)) { if (*s != ' ') *t++ = *s++; else s++; } *t = '\0'; t = title; *t = '\0'; if (*s) { // Read title // s++; while (*s && ((t - title) < MAX_TITLE_LEN)) { *t++ = *s++; } *t = '\0'; } ch = select_channel(channel); if (!ch) { int nVisualWidth; ANSI_TruncateToField(channel, sizeof(Buffer), Buffer, sizeof(Buffer), &nVisualWidth, FALSE); raw_notify(player, tprintf("Channel %s does not exist yet.", Buffer)); return; } if (!(do_test_access(player, CHANNEL_JOIN, ch))) { raw_notify(player, "Sorry, this channel type does not allow you to join."); return; } if (select_user(ch, player)) { raw_notify(player, tprintf("Warning: You are already on that channel.")); } c = get_comsys(player); for (j = 0; j < c->numchannels && (strcmp(pValidAlias, c->alias + j * 6) > 0); j++) { // Nothing ; } if (j < c->numchannels && !strcmp(pValidAlias, c->alias + j * 6)) { char *p = tprintf("That alias is already in use for channel %s.", c->channels[j]); raw_notify(player, p); return; } if (c->numchannels >= c->maxchannels) { c->maxchannels += 10; na = (char *)MEMALLOC(6 * c->maxchannels); ISOUTOFMEMORY(na); nc = (char **)MEMALLOC(sizeof(char *) * c->maxchannels); ISOUTOFMEMORY(nc); for (i = 0; i < c->numchannels; i++) { strcpy(na + i * 6, c->alias + i * 6); nc[i] = c->channels[i]; } if (c->alias) { MEMFREE(c->alias); } if (c->channels) { MEMFREE(c->channels); } c->alias = na; c->channels = nc; } where = c->numchannels++; for (i = where; i > j; i--) { strcpy(c->alias + i * 6, c->alias + (i - 1) * 6); c->channels[i] = c->channels[i - 1]; } where = j; memcpy(c->alias + where * 6, pValidAlias, nValidAlias); *(c->alias + where * 6 + nValidAlias) = '\0'; c->channels[where] = StringClone(channel); do_joinchannel(player, ch); char *pValidatedTitleValue = RestrictTitleValue(title); do_setnewtitle(player, ch, pValidatedTitleValue); if (pValidatedTitleValue[0] == '\0') { raw_notify(player, tprintf("Channel %s added with alias %s.", channel, pValidAlias)); } else { raw_notify(player, tprintf("Channel %s added with alias %s and title %s.", channel, pValidAlias, pValidatedTitleValue)); } } void do_delcom(dbref player, dbref cause, int key, char *arg1) { int i; comsys_t *c; if (!mudconf.have_comsys) { raw_notify(player, "Comsys disabled."); return; } if (!arg1) { raw_notify(player, "Need an alias to delete."); return; } c = get_comsys(player); for (i = 0; i < c->numchannels; i++) { if (!strcmp(arg1, c->alias + i * 6)) { do_delcomchannel(player, c->channels[i]); raw_notify(player, tprintf("Channel %s deleted.", c->channels[i])); MEMFREE(c->channels[i]); c->numchannels--; for (; i < c->numchannels; i++) { strcpy(c->alias + i * 6, c->alias + i * 6 + 6); c->channels[i] = c->channels[i + 1]; } return; } } raw_notify(player, "Unable to find that alias."); } void do_delcomchannel(dbref player, char *channel) { struct comuser *user; int i; int j; struct channel *ch = select_channel(channel); if (!ch) { raw_notify(player, tprintf("Unknown channel %s.", channel)); } else { j = 0; for (i = 0; i < ch->num_users && !j; i++) { user = ch->users[i]; if (user->who == player) { do_comdisconnectchannel(player, channel); if (user->bUserIsOn && (!Dark(player))) { char *p; if (user->title[0] != '\0') { // There is a comtitle. // if (ch->type & CHANNEL_SPOOF) { p = tprintf("[%s] %s has left this channel.", channel, user->title); } else { p = tprintf("[%s] %s %s has left this channel.", channel, user->title, Name(player)); } } else { p = tprintf("[%s] %s has left this channel.", channel, Name(player)); } do_comsend(ch, p); } raw_notify(player, tprintf("You have left channel %s.", channel)); if (user->title) { MEMFREE(user->title); } MEMFREE(user); j = 1; } } if (j) { ch->num_users--; for (i--; i < ch->num_users; i++) { ch->users[i] = ch->users[i + 1]; } } } } void do_createchannel(dbref player, dbref cause, int key, char *channel) { struct channel *newchannel; if (select_channel(channel)) { raw_notify(player, tprintf("Channel %s already exists.", channel)); return; } if (!*channel) { raw_notify(player, "You must specify a channel to create."); return; } if (!(Comm_All(player))) { raw_notify(player, "You do not have permission to do that."); return; } newchannel = (struct channel *)MEMALLOC(sizeof(struct channel)); ISOUTOFMEMORY(newchannel); strncpy(newchannel->name, channel, MAX_CHANNEL_LEN); newchannel->name[MAX_CHANNEL_LEN] = '\0'; newchannel->type = 127; newchannel->temp1 = 0; newchannel->temp2 = 0; newchannel->charge = 0; newchannel->charge_who = player; newchannel->amount_col = 0; newchannel->num_users = 0; newchannel->max_users = 0; newchannel->users = NULL; newchannel->on_users = NULL; newchannel->chan_obj = NOTHING; newchannel->num_messages = 0; num_channels++; hashaddLEN(newchannel->name, strlen(newchannel->name), (int *)newchannel, &mudstate.channel_htab); raw_notify(player, tprintf("Channel %s created.", channel)); } void do_destroychannel(dbref player, dbref cause, int key, char *channel) { struct channel *ch; int j; if (!mudconf.have_comsys) { raw_notify(player, "Comsys disabled."); return; } ch = (struct channel *)hashfindLEN(channel, strlen(channel), &mudstate.channel_htab); if (!ch) { raw_notify(player, tprintf("Could not find channel %s.", channel)); return; } else if (!(Comm_All(player)) && (player != ch->charge_who)) { raw_notify(player, "You do not have permission to do that. "); return; } num_channels--; hashdeleteLEN(channel, strlen(channel), &mudstate.channel_htab); for (j = 0; j < ch->num_users; j++) { MEMFREE(ch->users[j]); } MEMFREE(ch->users); MEMFREE(ch); raw_notify(player, tprintf("Channel %s destroyed.", channel)); } #if 0 void do_cleanupchannels(void) { struct channel *ch; for (ch = (struct channel *)hash_firstentry(&mudstate.channel_htab); ch; ch = (struct channel *)hash_nextentry(&mudstate.channel_htab)) { struct comuser *user, *prevuser = NULL; for (user = ch->on_users; user; ) { if (Typeof(user->who) == TYPE_PLAYER) { if (!(do_test_access(user->who, CHANNEL_JOIN, ch))) //if (!Connected(user->who)) { // Go looking for user in the array. // int bFound = FALSE; int iPos; for (iPos = 0; iPos < ch->num_users && !bFound; iPos++) { if (ch->users[iPos] == user) { bFound = TRUE; } } if (bFound) { // Remove user from the array. // ch->num_users--; for (iPos--; iPos < ch->num_users; iPos++) { ch->users[iPos] = ch->users[iPos+1]; } // Save user pointer for later reporting and freeing. // struct comuser *cuVictim = user; // Unlink user from the list, and decide who to look at next. // if (prevuser) { prevuser->on_next = user->on_next; } else { ch->on_users = user->on_next; } user = user->on_next; // Reporting // if (!Dark(cuVictim->who)) { char buff[LBUF_SIZE]; if (cuVictim->title[0] != '\0') { // There is a comtitle. // if (ch->type & CHANNEL_SPOOF) { sprintf(buff, "[%s] The system boots %s off the channel.", ch->name, cuVictim->title); } else { sprintf(buff, "[%s] The system boots %s %s off the channel.", ch->name, cuVictim->title, Name(cuVictim->who)); } } else { sprintf(buff, "[%s] The system boots %s off the channel.", ch->name, Name(cuVictim->who)); } do_comsend(ch, buff); } raw_notify(cuVictim->who, tprintf("The system has booted you off channel %s.", ch->name)); // Freeing // if (cuVictim->title) { MEMFREE(cuVictim->title); } MEMFREE(cuVictim); continue; } } } prevuser = user; user = user->on_next; } } } #endif void do_listchannels(dbref player) { struct channel *ch; char temp[LBUF_SIZE]; int perm = Comm_All(player); if (!perm) { raw_notify(player, "Warning: Only public channels and your channels will be shown."); } raw_notify(player, "*** Channel --Flags-- Obj Own Charge Balance Users Messages"); for (ch = (struct channel *)hash_firstentry(&mudstate.channel_htab); ch; ch = (struct channel *)hash_nextentry(&mudstate.channel_htab)) { if (perm || (ch->type & CHANNEL_PUBLIC) || ch->charge_who == player) { sprintf(temp, "%c%c%c %-13.13s %c%c%c/%c%c%c %5d %5d %8d %8d %6d %10d", (ch->type & (CHANNEL_PUBLIC)) ? 'P' : '-', (ch->type & (CHANNEL_LOUD)) ? 'L' : '-', (ch->type & (CHANNEL_SPOOF)) ? 'S' : '-', ch->name, (ch->type & (CHANNEL_PL_MULT * CHANNEL_JOIN)) ? 'J' : '-', (ch->type & (CHANNEL_PL_MULT * CHANNEL_TRANSMIT)) ? 'X' : '-', (ch->type & (CHANNEL_PL_MULT * CHANNEL_RECEIVE)) ? 'R' : '-', (ch->type & (CHANNEL_OBJ_MULT * CHANNEL_JOIN)) ? 'j' : '-', (ch->type & (CHANNEL_OBJ_MULT * CHANNEL_TRANSMIT)) ? 'x' : '-', (ch->type & (CHANNEL_OBJ_MULT * CHANNEL_RECEIVE)) ? 'r' : '-', (ch->chan_obj != NOTHING) ? ch->chan_obj : -1, ch->charge_who, ch->charge, ch->amount_col, ch->num_users, ch->num_messages); raw_notify(player, temp); } } raw_notify(player, "-- End of list of Channels --"); } void do_comtitle(dbref player, dbref cause, int key, char *arg1, char *arg2) { char channel[MAX_CHANNEL_LEN+1]; if (!mudconf.have_comsys) { raw_notify(player, "Comsys disabled."); return; } if (!*arg1) { raw_notify(player, "Need an alias to do comtitle."); return; } strcpy(channel, get_channel_from_alias(player, arg1)); if (channel[0] == '\0') { raw_notify(player, "Unknown alias"); return; } struct channel *ch = select_channel(channel); if (ch) { if (select_user(ch, player)) { char *pValidatedTitleValue = RestrictTitleValue(arg2); do_setnewtitle(player, ch, pValidatedTitleValue); raw_notify(player, tprintf("Title set to '%s' on channel %s.", pValidatedTitleValue, channel)); free_lbuf(pValidatedTitleValue); } } else { raw_notify(player, "Illegal comsys alias, please delete."); } } void do_comlist(dbref player, dbref cause, int key) { comsys_t *c; int i; if (!mudconf.have_comsys) { raw_notify(player, "Comsys disabled."); return; } c = get_comsys(player); raw_notify(player, "Alias Channel Status Title"); for (i = 0; i < c->numchannels; i++) { struct comuser *user = select_user(select_channel(c->channels[i]), player); if (user) { char *p = tprintf("%-9.9s %-18.18s %-6.6s %s", c->alias + i * 6, c->channels[i], (user->bUserIsOn ? "on" : "off"), user->title); raw_notify(player, p); } else { raw_notify(player, tprintf("Bad Comsys Alias: %s for Channel: %s", c->alias + i * 6, c->channels[i])); } } raw_notify(player, "-- End of comlist --"); } void do_channelnuke(dbref player) { struct channel *ch; int j; for (ch = (struct channel *)hash_firstentry(&mudstate.channel_htab); ch; ch = (struct channel *)hash_nextentry(&mudstate.channel_htab)) { if (ch->charge_who == player) { num_channels--; hashdeleteLEN(ch->name, strlen(ch->name), &mudstate.channel_htab); for (j = 0; j < ch->num_users; j++) { MEMFREE(ch->users[j]); } MEMFREE(ch->users); MEMFREE(ch); } } } void do_clearcom(dbref player, dbref unused1, int unused2) { int i; comsys_t *c; if (!mudconf.have_comsys) { raw_notify(player, "Comsys disabled."); return; } c = get_comsys(player); for (i = (c->numchannels) - 1; i > -1; --i) { do_delcom(player, player, 0, c->alias + i * 6); } } void do_allcom(dbref player, dbref cause, int key, char *arg1) { int i; comsys_t *c; if (!mudconf.have_comsys) { raw_notify(player, "Comsys disabled."); return; } c = get_comsys(player); if ( strcmp(arg1, "who") != 0 && strcmp(arg1, "on") != 0 && strcmp(arg1, "off") != 0) { raw_notify(player, "Only options available are: on, off and who."); return; } for (i = 0; i < c->numchannels; i++) { do_processcom(player, c->channels[i], arg1); if (strcmp(arg1, "who") == 0) { raw_notify(player, ""); } } } void sort_users(struct channel *ch) { int i; int nu; int done; struct comuser *user; nu = ch->num_users; done = 0; while (!done) { done = 1; for (i = 0; i < (nu - 1); i++) { if (ch->users[i]->who > ch->users[i + 1]->who) { user = ch->users[i]; ch->users[i] = ch->users[i + 1]; ch->users[i + 1] = user; done = 0; } } } } void do_channelwho(dbref player, dbref cause, int key, char *arg1) { struct comuser *user; char channel[MAX_CHANNEL_LEN+1]; int flag; char *s; char *t; char *buff; char temp[LBUF_SIZE]; int i; if (!mudconf.have_comsys) { raw_notify(player, "Comsys disabled."); return; } s = arg1; t = channel; while (*s && *s != '/' && ((t - channel) < MAX_CHANNEL_LEN)) { *t++ = *s++; } *t = 0; flag = 0; if (*s && *(s + 1)) flag = (*(s + 1) == 'a'); struct channel *ch = select_channel(channel); if (!ch) { raw_notify(player, tprintf("Unknown channel %s.", channel)); return; } if (!((Comm_All(player)) || (player == ch->charge_who))) { raw_notify(player, "You do not have permission to do that. (Not owner or admin.)"); return; } raw_notify(player, tprintf("-- %s --", ch->name)); raw_notify(player, tprintf("%-29.29s %-6.6s %-6.6s", "Name", "Status", "Player")); for (i = 0; i < ch->num_users; i++) { user = ch->users[i]; if ((flag || UNDEAD(user->who)) && (!Dark(user->who) || Wizard_Who(player))) { buff = unparse_object(player, user->who, 0); sprintf(temp, "%-29.29s %-6.6s %-6.6s", strip_ansi(buff), ((user->bUserIsOn) ? "on " : "off"), (Typeof(user->who) == TYPE_PLAYER) ? "yes" : "no "); raw_notify(player, temp); free_lbuf(buff); } } raw_notify(player, tprintf("-- %s --", ch->name)); } void do_comdisconnectraw_notify(dbref player, char *chan) { struct channel *ch = select_channel(chan); if (!ch) return; struct comuser *cu = select_user(ch, player); if (!cu) return; if ((ch->type & CHANNEL_LOUD) && (cu->bUserIsOn) && (!Dark(player))) { char *buff = alloc_lbuf("do_comconnect"); if (cu->title[0] != '\0') { // There is a comtitle. // if (ch->type & CHANNEL_SPOOF) { sprintf(buff, "[%s] %s has disconnected.", ch->name, cu->title); } else { sprintf(buff, "[%s] %s %s has disconnected.", ch->name, cu->title, Name(player)); } } else { sprintf(buff, "[%s] %s has disconnected.", ch->name, Name(player)); } do_comsend(ch, buff); free_lbuf(buff); } } void do_comconnectraw_notify(dbref player, char *chan) { char *buff; struct channel *ch = select_channel(chan); if (!ch) return; struct comuser *cu = select_user(ch, player); if (!cu) return; if ((ch->type & CHANNEL_LOUD) && (cu->bUserIsOn) && (!Dark(player))) { buff = alloc_lbuf("do_comconnect"); if (cu->title[0] != '\0') { // There is a comtitle. // if (ch->type & CHANNEL_SPOOF) { sprintf(buff, "[%s] %s has connected.", ch->name, cu->title); } else { sprintf(buff, "[%s] %s %s has connected.", ch->name, cu->title, Name(player)); } } else { sprintf(buff, "[%s] %s has connected.", ch->name, Name(player)); } do_comsend(ch, buff); free_lbuf(buff); } } void do_comconnectchannel(dbref player, char *channel, char *alias, int i) { struct comuser *user; struct channel *ch = select_channel(channel); if (ch) { for (user = ch->on_users; user && user->who != player; user = user->on_next) ; if (!user) { user = select_user(ch, player); if (user) { user->on_next = ch->on_users; ch->on_users = user; } else { raw_notify(player, tprintf("Bad Comsys Alias: %s for Channel: %s", alias + i * 6, channel)); } } } else { raw_notify(player, tprintf("Bad Comsys Alias: %s for Channel: %s", alias + i * 6, channel)); } } void do_comdisconnect(dbref player) { int i; comsys_t *c; c = get_comsys(player); for (i = 0; i < c->numchannels; i++) { do_comdisconnectchannel(player, c->channels[i]); #ifdef CHANNEL_LOUD do_comdisconnectraw_notify(player, c->channels[i]); #endif } } void do_comconnect(dbref player) { comsys_t *c; int i; c = get_comsys(player); for (i = 0; i < c->numchannels; i++) { do_comconnectchannel(player, c->channels[i], c->alias, i); do_comconnectraw_notify(player, c->channels[i]); } } void do_comdisconnectchannel(dbref player, char *channel) { struct comuser *prevuser = NULL; struct channel *ch = select_channel(channel); if (!ch) return; struct comuser *user; for (user = ch->on_users; user;) { if (user->who == player) { if (prevuser) prevuser->on_next = user->on_next; else ch->on_users = user->on_next; return; } else { prevuser = user; user = user->on_next; } } } void do_editchannel(dbref player, dbref cause, int flag, char *arg1, char *arg2) { char *s; int add_remove = 1; if (!mudconf.have_comsys) { raw_notify(player, "Comsys disabled."); return; } struct channel *ch = select_channel(arg1); if (!ch) { raw_notify(player, tprintf("Unknown channel %s.", arg1)); return; } if (!((Comm_All(player)) || (player == ch->charge_who))) { raw_notify(player, "You do not have permission to do that. (Not owner or Admin.)"); return; } s = arg2; if (*s == '!') { add_remove = 0; s++; } switch (flag) { case 0: { int who = lookup_player(player, arg2, 1); if (NOTHING == who) { raw_notify(player, "Invalid player."); } else { ch->charge_who = who; raw_notify(player, "Set."); } } break; case 1: ch->charge = Tiny_atol(arg2); raw_notify(player, "Set."); break; case 3: if (strcmp(s, "join") == 0) { if (add_remove) { ch->type |= (CHANNEL_PL_MULT * CHANNEL_JOIN); raw_notify(player, "@cpflags: Set."); } else { ch->type &= ~(CHANNEL_PL_MULT * CHANNEL_JOIN); raw_notify(player, "@cpflags: Cleared."); } } else if (strcmp(s, "receive") == 0) { if (add_remove) { ch->type |= (CHANNEL_PL_MULT * CHANNEL_RECEIVE); raw_notify(player, "@cpflags: Set."); } else { ch->type &= ~(CHANNEL_PL_MULT * CHANNEL_RECEIVE); raw_notify(player, "@cpflags: Cleared."); } } else if (strcmp(s, "transmit") == 0) { if (add_remove) { ch->type |= (CHANNEL_PL_MULT * CHANNEL_TRANSMIT); raw_notify(player, "@cpflags: Set."); } else { ch->type &= ~(CHANNEL_PL_MULT * CHANNEL_TRANSMIT); raw_notify(player, "@cpflags: Cleared."); } } else { raw_notify(player, "@cpflags: Unknown Flag."); } break; case 4: if (strcmp(s, "join") == 0) { if (add_remove) { ch->type |= (CHANNEL_OBJ_MULT * CHANNEL_JOIN); raw_notify(player, "@coflags: Set."); } else { ch->type &= ~(CHANNEL_OBJ_MULT * CHANNEL_JOIN); raw_notify(player, "@coflags: Cleared."); } } else if (strcmp(s, "receive") == 0) { if (add_remove) { ch->type |= (CHANNEL_OBJ_MULT * CHANNEL_RECEIVE); raw_notify(player, "@coflags: Set."); } else { ch->type &= ~(CHANNEL_OBJ_MULT * CHANNEL_RECEIVE); raw_notify(player, "@coflags: Cleared."); } } else if (strcmp(s, "transmit") == 0) { if (add_remove) { ch->type |= (CHANNEL_OBJ_MULT * CHANNEL_TRANSMIT); raw_notify(player, "@coflags: Set."); } else { ch->type &= ~(CHANNEL_OBJ_MULT * CHANNEL_TRANSMIT); raw_notify(player, "@coflags: Cleared."); } } else { raw_notify(player, "@coflags: Unknown Flag."); } break; } } int do_test_access(dbref player, long access, struct channel *chan) { long flag_value = access; if (Comm_All(player)) { return 1; } // Channel objects allow custom locks for channels. The normal // lock is used to see if they can join that channel. The enterlock // is checked to see if they can receive messages on it. The // Uselock is checked to see if they can transmit on it. Note: // These checks do not supercede the normal channel flags. If a // channel is set JOIN for players, ALL players can join the // channel, whether or not they pass the lock. Same for all // channel object locks. // if (chan->chan_obj != NOTHING && chan->chan_obj != 0) { if (flag_value & CHANNEL_JOIN) { if (could_doit(player, chan->chan_obj, A_LOCK)) return 1; } if (flag_value & CHANNEL_TRANSMIT) { if (could_doit(player, chan->chan_obj, A_LUSE)) return 1; } if (flag_value & CHANNEL_RECEIVE) { if (could_doit(player, chan->chan_obj, A_LENTER)) return 1; } } if (Typeof(player) == TYPE_PLAYER) { flag_value *= CHANNEL_PL_MULT; } else { flag_value *= CHANNEL_OBJ_MULT; } // Mask out CHANNEL_PUBLIC, CHANNEL_LOUD, and CHANNEL_SPOOF // flag_value &= 0xFF; return (((long)chan->type & flag_value)); } // 1 means continue, 0 means stop // int do_comsystem(dbref who, char *cmd) { char *t; char *alias = alloc_lbuf("do_comsystem"); char *s = alias; for (t = cmd; *t && *t != ' '; *s++ = *t++) { ; // Nothing. } *s = '\0'; if (*t) { t++; } char *ch = get_channel_from_alias(who, alias); if (ch[0] != '\0') { do_processcom(who, ch, t); free_lbuf(alias); return 0; } else { free_lbuf(alias); } return 1; } void do_cemit(dbref player, dbref cause, int key, char *chan, char *text) { if (!mudconf.have_comsys) { raw_notify(player, "Comsys disabled."); return; } struct channel *ch = select_channel(chan); if (!ch) { raw_notify(player, tprintf("Channel %s does not exist.", chan)); return; } if ((player != ch->charge_who) && (!Comm_All(player))) { raw_notify(player, NOPERM_MESSAGE); return; } if (key == CEMIT_NOHEADER) { do_comsend(ch, text); } else { do_comsend(ch, tprintf("[%s] %s", chan, text)); } } void do_chopen(dbref player, dbref cause, int key, char *chan, char *object) { if (!mudconf.have_comsys) { raw_notify(player, "Comsys disabled."); return; } if (key == CSET_LIST) { do_chanlist(player, NOTHING, 1); return; } char *msg = NULL; char *buff; dbref thing; struct channel *ch = select_channel(chan); if (!ch) { msg = tprintf("@cset: Channel %s does not exist.", chan); raw_notify(player, msg); return; } if ((player != ch->charge_who) && (!Comm_All(player))) { raw_notify(player, NOPERM_MESSAGE); return; } switch (key) { case CSET_PUBLIC: ch->type |= CHANNEL_PUBLIC; msg = tprintf("@cset: Channel %s placed on the public listings.", chan); break; case CSET_PRIVATE: ch->type &= ~CHANNEL_PUBLIC; msg = tprintf("@cset: Channel %s taken off the public listings." ,chan); break; case CSET_LOUD: ch->type |= CHANNEL_LOUD; msg = tprintf("@cset: Channel %s now sends connect/disconnect msgs.", chan); break; case CSET_QUIET: ch->type &= ~CHANNEL_LOUD; msg = tprintf("@cset: Channel %s connect/disconnect msgs muted.", chan); break; case CSET_SPOOF: ch->type |= CHANNEL_SPOOF; msg = tprintf("@cset: Channel %s set spoofable.", chan); break; case CSET_NOSPOOF: ch->type &= ~CHANNEL_SPOOF; msg = tprintf("@cset: Channel %s set unspoofable.", chan); break; case CSET_OBJECT: init_match(player, object, NOTYPE); match_everything(0); thing = match_result(); ch->chan_obj = thing; if (thing == NOTHING) { msg = tprintf("Channel %s is now disassociated from any channel object.", ch->name); } else { buff = unparse_object(player, thing, 0); msg = tprintf("Channel %s is now using %s as channel object.", ch->name, buff); free_lbuf(buff); } break; } raw_notify(player, msg); } void do_chboot(dbref player, dbref cause, int key, char *channel, char *victim) { dbref thing; char buff[LBUF_SIZE]; char buf2[LBUF_SIZE]; // I sure hope it's not going to be that long. // if (!mudconf.have_comsys) { raw_notify(player, "Comsys disabled."); return; } struct channel *ch = select_channel(channel); if (!ch) { raw_notify(player, "@cboot: Unknown channel."); return; } struct comuser *user = select_user(ch, player); if (!user) { raw_notify(player, "@cboot: You are not on that channel."); return; } if (!(ch->charge_who == player) && !Comm_All(player)) { raw_notify(player, "@cboot: You can't do that!"); return; } thing = match_thing(player, victim); if (thing == NOTHING) { return; } struct comuser *vu = select_user(ch, thing); if (!vu) { raw_notify(player, tprintf("@cboot: %s in not on the channel.", Name(thing))); return; } // We should be in the clear now. ;) // if (user->title[0] != '\0') { // There is a comtitle. // if (ch->type & CHANNEL_SPOOF) { strcpy(buf2, user->title); } else { sprintf(buf2, "%s %s", user->title, Name(player)); } } else { strcpy(buf2, Name(player)); } if (vu->title[0] != '\0') { // There is a comtitle. // if (ch->type & CHANNEL_SPOOF) { sprintf(buff, "[%s] %s boots %s off the channel.", ch->name, buf2, vu->title); } else { sprintf(buff, "[%s] %s boots %s %s off the channel.", ch->name, buf2, vu->title, Name(thing)); } } else { sprintf(buff, "[%s] %s boots %s off the channel.", ch->name, buf2, Name(thing)); } do_comsend(ch, buff); do_delcomchannel(thing, channel); } void do_chanlist(dbref player, dbref cause, int key) { dbref owner; struct channel *ch; int flags; char *temp; char *buf; char *atrstr; if (!mudconf.have_comsys) { raw_notify(player, "Comsys disabled."); return; } flags = 0; if (key & CLIST_FULL) { do_listchannels(player); return; } temp = alloc_mbuf("do_chanlist_temp"); buf = alloc_mbuf("do_chanlist_buf"); raw_notify(player, "*** Channel Owner Description"); for (ch = (struct channel *)hash_firstentry(&mudstate.channel_htab); ch; ch = (struct channel *)hash_nextentry(&mudstate.channel_htab)) { if (Comm_All(player) || (ch->type & CHANNEL_PUBLIC) || ch->charge_who == player) { atrstr = atr_pget(ch->chan_obj, A_DESC, &owner, &flags); if ((ch->chan_obj == NOTHING) || !*atrstr) strcpy(buf, "No description."); else sprintf(buf, "%-54.54s", atrstr); free_lbuf(atrstr); sprintf(temp, "%c%c%c %-13.13s %-15.15s %-45.45s", (ch->type & (CHANNEL_PUBLIC)) ? 'P' : '-', (ch->type & (CHANNEL_LOUD)) ? 'L' : '-', (ch->type & (CHANNEL_SPOOF)) ? 'S' : '-', ch->name, Name(ch->charge_who), buf); raw_notify(player, temp); } } free_mbuf(temp); free_mbuf(buf); raw_notify(player, "-- End of list of Channels --"); } // Returns a player's comtitle for a named channel. // FUNCTION(fun_comtitle) { if (!mudconf.have_comsys) { safe_str("#-1 COMSYS DISABLED", buff, bufc); return; } dbref victim = lookup_player(player, fargs[0], 1); comsys_t *c = get_comsys(player); if (victim == NOTHING) { safe_str("#-1 PLAYER DOES NOT EXIST", buff, bufc); return; } struct channel *chn = select_channel(fargs[1]); if (!chn) { safe_str("#-1 CHANNEL DOES NOT EXIST", buff, bufc); return; } struct comuser *user; int i; int onchannel = 0; if (Wizard(player)) { onchannel = 1; } else { for (i = 0; i < c->numchannels; i++) { user = select_user(chn, player); if (user) { onchannel = 1; break; } } } if (!onchannel) { safe_str("#-1 PERMISSION DENIED", buff, bufc); return; } for (i = 0; i < c->numchannels; i++) { user = select_user(chn, victim); if (user) { safe_str(user->title, buff, bufc); return; } } safe_str("#-1 PLAYER NOT ON THAT CHANNEL", buff, bufc); } // Returns a player's comsys alias for a named channel. // FUNCTION(fun_comalias) { if (!mudconf.have_comsys) { safe_str("#-1 COMSYS DISABLED", buff, bufc); return; } dbref victim = lookup_player(player, fargs[0], 1); comsys_t *c = get_comsys(player); if (victim == NOTHING) { safe_str("#-1 PLAYER DOES NOT EXIST", buff, bufc); return; } struct channel *chn = select_channel(fargs[1]); if (!chn) { safe_str("#-1 CHANNEL DOES NOT EXIST", buff, bufc); return; } int i; struct comuser *user; int onchannel = 0; if (Wizard(player)) { onchannel = 1; } else { for (i = 0; i < c->numchannels; i++) { user = select_user(chn, player); if (user) { onchannel = 1; break; } } } if (!onchannel) { safe_str("#-1 PERMISSION DENIED", buff, bufc); return; } comsys_t *cc = get_comsys(victim); for (i = 0; i < cc->numchannels; i++) { if (!strcmp(fargs[1], cc->channels[i])) { safe_str(cc->alias + i * 6, buff, bufc); return; } } safe_str("#-1 PLAYER NOT ON THAT CHANNEL", buff, bufc); } // Returns a list of channels. // FUNCTION(fun_channels) { if (!mudconf.have_comsys) { safe_str("#-1 COMSYS DISABLED", buff, bufc); return; } char *outbuff = alloc_lbuf("fun_comlist_outbuff"); *outbuff='\0'; struct channel *chn; for (chn = (struct channel *)hash_firstentry(&mudstate.channel_htab); chn; chn = (struct channel *)hash_nextentry(&mudstate.channel_htab)) { if ( Comm_All(player) || (chn->type & CHANNEL_PUBLIC) || chn->charge_who == player) { strcat(outbuff, chn->name); strcat(outbuff, " "); } } safe_str(outbuff, buff, bufc); free_lbuf(outbuff); }