/* * comsys.c */ /* * $Id: comsys.c,v 1.4 1995/11/22 23:33:17 root Exp $ */ #include <ctype.h> #include <sys/types.h> #include "copyright.h" #include "autoconf.h" #include "db.h" #include "interface.h" #include "attrs.h" #include "match.h" #include "config.h" #include "externs.h" #include "flags.h" #include "powers.h" #include "comsys.h" /* * This is the hash table for channel names */ void NDECL(init_chantab) { hashinit(&mudstate.channel_htab, 30 * HASH_FACTOR); } char *get_channel_from_alias(player, alias) dbref player; char *alias; { struct commac *c; int first, last, current; int dir; c = get_commac(player); 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 ""; } char *load_comsystem(fp) FILE *fp; { int i, j, dummy; int nc, new = 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)) { new = 1; fscanf(fp, "%d\n", &nc); } else { nc = atoi(buf); } num_channels = nc; for (i = 0; i < nc; i++) { ch = (struct channel *)malloc(sizeof(struct channel)); fscanf(fp, "%[^\n]\n", temp); StringCopy(ch->name, temp); ch->on_users = NULL; hashadd(ch->name, (int *)ch, &mudstate.channel_htab); if (new) { 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 *)malloc(sizeof(struct comuser)); ch->users[j] = user; if (new) { fscanf(fp, "%d %d\n", &(user->who), &(user->on)); } else { fscanf(fp, "%d %d %d", &(user->who), &(dummy), &(dummy)); fscanf(fp, "%d\n", &(user->on)); } fscanf(fp, "%[^\n]\n", temp); if (strlen(temp + 2) > 0) { user->title = (char *)malloc(strlen(temp + 2) + 1); StringCopy(user->title, temp + 2); } else { user->title = (char *)malloc(1); user->title[0] = 0; } 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; } } sort_users(ch); } else ch->users = NULL; } } char *save_comsystem(fp) FILE *fp; { struct channel *ch; struct comuser *user; int i, 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); fprintf(fp, "%d\n", ch->num_users); for (j = 0; j < ch->num_users; j++) { user = ch->users[j]; fprintf(fp, "%d %d\n", user->who, user->on); if (strlen(user->title)) fprintf(fp, "t:%s\n", user->title); else fprintf(fp, "t:\n"); } } } char *do_processcom(player, arg1, arg2) dbref player; char *arg1; char *arg2; { char mess[LBUF_SIZE]; struct channel *ch; struct comuser *user; if ((strlen(arg1) + strlen(arg2)) > 3500) { arg2[3500] = '\0'; } if (!*arg2) { raw_notify(player, "No message."); return; } if (!(ch = select_channel(arg1))) { raw_notify(player, tprintf("Unknown channel %s.", arg1)); return; } if (!(user = select_user(ch, player))) { 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->on) { 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); } if ((*arg2) == ':') { if (strlen(user->title)) sprintf(mess, "[%s] %s %s %s", arg1, user->title, names[player], arg2 + 1); else sprintf(mess, "[%s] %s %s", arg1, names[player], arg2 + 1); } else if ((*arg2) == ';') { if (strlen(user->title)) sprintf(mess, "[%s] %s %s%s", arg1, user->title, names[player], arg2 + 1); else sprintf(mess, "[%s] %s%s", arg1, names[player], arg2 + 1); } else if (strlen(user->title)) sprintf(mess, "[%s] %s %s says, \"%s\"", arg1, user->title, names[player], arg2); else sprintf(mess, "[%s] %s says, \"%s\"", arg1, names[player], arg2); do_comsend(ch, mess); } } char *do_comsend(ch, mess) struct channel *ch; char *mess; { struct comuser *user; ch->num_messages++; for (user = ch->on_users; user; user = user->on_next) { if (user->on && Connected(user->who)) if (do_test_access(user->who, CHANNEL_RECIEVE, ch)) raw_notify(user->who, mess); } } char *do_joinchannel(player, ch) 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 **) malloc(sizeof(struct comuser *) * ch->max_users); for (i = 0; i < (ch->num_users - 1); i++) cu[i] = ch->users[i]; free(ch->users); ch->users = cu; } user = (struct comuser *)malloc(sizeof(struct comuser)); 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->on = 1; user->title = (char *)malloc(1); user->title[0] = 0; /* * if (Connected(player))&&(isPlayer(player)) */ if UNDEAD (player) { user->on_next = ch->on_users; ch->on_users = user; } } else if (!user->on) { raw_notify(player, tprintf("You have joined channel %s.", ch->name)); user->on = 1; } else { raw_notify(player, tprintf("You are already on channel %s.", ch->name)); return; } sprintf(temp, "[%s] %s has joined this channel.", ch->name, names[player]); do_comsend(ch, temp); } char *do_leavechannel(player, ch) dbref player; struct channel *ch; { struct comuser *user; char temp[1000]; user = select_user(ch, player); if (user->on) { sprintf(temp, "[%s] %s has left this channel.", ch->name, names[player]); do_comsend(ch, temp); } user->on = 0; } char *do_comwho(player, ch) dbref player; struct channel *ch; { struct comuser *user; char *buff; 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) || WizRoy(player))) { if (user->on) { buff = unparse_object(player, user->who, 0); raw_notify(player, tprintf("%s", buff)); free_lbuf(buff); } } 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->on) { buff = unparse_object(player, user->who, 0); raw_notify(player, tprintf("%s", buff)); free_lbuf(buff); } } raw_notify(player, tprintf("-- %s --", ch->name)); } struct channel *select_channel(channel) char *channel; { struct channel *cp; cp = (struct channel *)hashfind(channel, &mudstate.channel_htab); if (!cp) return NULL; else return cp; } struct comuser *select_user(ch, player) 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(player, cause, key, arg1, arg2) dbref player, cause; int key; char *arg1; char *arg2; { char channel[200]; char title[1000]; char buffer[100]; struct channel *ch; char *s, *t; int i, j, where; struct commac *c; char *na; char **nc; if (!mudconf.have_comsys) { raw_notify(player, "Comsys disabled."); return; } if (!*arg1) { raw_notify(player, "You need to specify an alias."); return; } s = arg2; if (!*s) { raw_notify(player, "You need to specify a channel."); return; } t = channel; while (*s && *s != ',') { if (*s != ' ') *t++ = *s++; else s++; } *t = '\0'; t = title; *t = '\0'; if (*s) { /* * Read title */ s++; while (*s) *t++ = *s++; *t = '\0'; } if (!(ch = select_channel(channel))) { raw_notify(player, tprintf("Channel %s does not exist yet.", channel)); 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_commac(player); for (j = 0; j < c->numchannels && (strcmp(arg1, c->alias + j * 6) > 0); j++) ; if (j < c->numchannels && !strcmp(arg1, c->alias + j * 6)) { sprintf(buffer, "That alias is already in use for channel %s.", c->channels[j]); raw_notify(player, buffer); return; } if (c->numchannels >= c->maxchannels) { c->maxchannels += 10; na = (char *)malloc(6 * c->maxchannels); nc = (char **)malloc(sizeof(char *) * c->maxchannels); for (i = 0; i < c->numchannels; i++) { StringCopy(na + i * 6, c->alias + i * 6); nc[i] = c->channels[i]; } free(c->alias); free(c->channels); c->alias = na; c->channels = nc; } where = c->numchannels++; for (i = where; i > j; i--) { StringCopy(c->alias + i * 6, c->alias + (i - 1) * 6); c->channels[i] = c->channels[i - 1]; } where = j; StringCopyTrunc(c->alias + where * 6, arg1, 5); *(c->alias + where * 6 + 5) = '\0'; c->channels[where] = (char *)malloc(strlen(channel) + 1); StringCopy(c->channels[where], channel); do_joinchannel(player, ch); do_setnewtitle(player, ch, title); if (title[0]) raw_notify(player, tprintf( "Channel %s added with alias %s and title %s.", channel, arg1, title)); else raw_notify(player, tprintf( "Channel %s added with alias %s.", channel, arg1)); } char *do_setnewtitle(player, ch, title) dbref player; struct channel *ch; char *title; { struct comuser *user; user = select_user(ch, player); if (ch && user) { if (user->title) free(user->title); if (strlen(title) > 0) { user->title = (char *)malloc(strlen(title) + 1); StringCopy(user->title, title); } else { user->title = (char *)malloc(1); user->title[0] = 0; } } } void do_delcom(player, cause, key, arg1) dbref player, cause; int key; char *arg1; { int i; struct commac *c; if (!mudconf.have_comsys) { raw_notify(player, "Comsys disabled."); return; } if (!arg1) { raw_notify(player, "Need an alias to delete."); return; } c = get_commac(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])); free(c->channels[i]); c->numchannels--; for (; i < c->numchannels; i++) { StringCopy(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."); } char *do_delcomchannel(player, channel) dbref player; char *channel; { struct channel *ch; struct comuser *user; char temp[1000]; int i; int j; if (!(ch = select_channel(channel))) { 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->on) { sprintf(temp, "[%s] %s has left this channel.", channel, names[player]); do_comsend(ch, temp); } raw_notify(player, tprintf("You have left channel %s.", channel)); if (user->title) free(user->title); free(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(player, cause, key, channel) dbref player, cause; int key; char *channel; { struct channel *newchannel; struct channel **nc; int i; 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 *)malloc(sizeof(struct channel)); StringCopyTrunc(newchannel->name, channel, CHAN_NAME_LEN - 1); newchannel->name[CHAN_NAME_LEN - 1] = '\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++; hashadd(newchannel->name, (int *)newchannel, &mudstate.channel_htab); raw_notify(player, tprintf("Channel %s created.", channel)); } void do_destroychannel(player, cause, key, channel) dbref player, cause; int key; char *channel; { struct channel *ch; int j; if (!mudconf.have_comsys) { raw_notify(player, "Comsys disabled."); return; } ch = (struct channel *)hashfind(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--; hashdelete(channel, &mudstate.channel_htab); for (j = 0; j < ch->num_users; j++) { free(ch->users[j]); } free(ch->users); free(ch); raw_notify(player, tprintf("Channel %s destroyed.", channel)); } char *do_listchannels(player) dbref player; { struct channel *ch; char temp[1000]; int i, perm; if (!(perm = Comm_All(player))) { 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 %-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->name, (ch->type & (CHANNEL_PL_MULT * CHANNEL_JOIN)) ? 'J' : '-', (ch->type & (CHANNEL_PL_MULT * CHANNEL_TRANSMIT)) ? 'X' : '-', (ch->type & (CHANNEL_PL_MULT * CHANNEL_RECIEVE)) ? 'R' : '-', (ch->type & (CHANNEL_OBJ_MULT * CHANNEL_JOIN)) ? 'j' : '-', (ch->type & (CHANNEL_OBJ_MULT * CHANNEL_TRANSMIT)) ? 'x' : '-', (ch->type & (CHANNEL_OBJ_MULT * CHANNEL_RECIEVE)) ? '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(player, cause, key, arg1, arg2) dbref player, cause; int key; char *arg1; char *arg2; { struct channel *ch; char channel[50]; if (!mudconf.have_comsys) { raw_notify(player, "Comsys disabled."); return; } if (!*arg1) { raw_notify(player, "Need an alias to do comtitle."); return; } StringCopy(channel, get_channel_from_alias(player, arg1)); if (strlen(channel) == 0) { raw_notify(player, "Unknown alias"); return; } if ((ch = select_channel(channel)) && select_user(ch, player)) { raw_notify(player, tprintf("Title set to '%s' on channel %s.", arg2, channel)); do_setnewtitle(player, ch, arg2); } if (!ch) { raw_notify(player, "Illegal comsys alias, please delete."); return; } } void do_comlist(player, cause, key) dbref player, cause; int key; { struct comuser *user; struct commac *c; int i; char temp[200]; if (!mudconf.have_comsys) { raw_notify(player, "Comsys disabled."); return; } c = get_commac(player); raw_notify(player, "Alias Channel Title Status"); for (i = 0; i < c->numchannels; i++) { if ((user = select_user(select_channel(c->channels[i]), player))) { sprintf(temp, "%-9.9s %-19.19s %-39.39s %s", c->alias + i * 6, c->channels[i], user->title, (user->on ? "on" : "off")); raw_notify(player, temp); } 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 --"); } char *do_channelnuke(player) dbref player; { struct channel *ch; int i, 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--; hashdelete(ch->name, &mudstate.channel_htab); for (j = 0; j < ch->num_users; j++) free(ch->users[j]); free(ch->users); free(ch); } } } void do_clearcom(player, cause, key) dbref player, cause; int key; { int i; struct commac *c; if (!mudconf.have_comsys) { raw_notify(player, "Comsys disabled."); return; } c = get_commac(player); for (i = (c->numchannels) - 1; i > -1; --i) { do_delcom(player, player, 0, c->alias + i * 6); } } void do_allcom(player, cause, key, arg1) dbref player, cause; int key; char *arg1; { int i; struct commac *c; char temparg[50];; if (!mudconf.have_comsys) { raw_notify(player, "Comsys disabled."); return; } c = get_commac(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, ""); } } char *sort_users(ch) 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(player, cause, key, arg1) dbref player, cause; int key; char *arg1; { struct channel *ch; struct comuser *user; char channel[100]; int flag; char *s; char *t; char *buff; char temp[100]; int i; if (!mudconf.have_comsys) { raw_notify(player, "Comsys disabled."); return; } s = arg1; t = channel; while (*s && *s != '/') *t++ = *s++; *t = 0; flag = 0; if (*s && *(s + 1)) flag = (*(s + 1) == 'a'); if (!(ch = select_channel(channel))) { 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)) { buff = unparse_object(player, user->who, 0); sprintf(temp, "%-29.29s %-6.6s %-6.6s", strip_ansi(buff), ((user->on) ? "on " : "off"), (Typeof(user->who) == TYPE_PLAYER) ? "yes" : "no "); raw_notify(player, temp); free_lbuf(buff); } } raw_notify(player, tprintf("-- %s --", ch->name)); } char *do_comdisconnectraw_notify(player, chan) dbref player; char *chan; { struct channel *ch; struct comuser *cu; char *buff; if (!(ch = select_channel(chan))) return; if (!(cu = select_user(ch, player))) return; if ((ch->type & CHANNEL_LOUD) && (cu->on) && (!Dark(player))) { buff = alloc_lbuf("do_comconnect"); sprintf(buff, "[%s] %s has disconnected.", ch->name, Name(player)); do_comsend(ch, buff); free_lbuf(buff); } } char *do_comconnectraw_notify(player, chan) dbref player; char *chan; { struct channel *ch; struct comuser *cu; char *buff; if (!(ch = select_channel(chan))) return; if (!(cu = select_user(ch, player))) return; if ((ch->type & CHANNEL_LOUD) && (cu->on) && (!Dark(player))) { buff = alloc_lbuf("do_comconnect"); sprintf(buff, "[%s] %s has connected.", ch->name, Name(player)); do_comsend(ch, buff); free_lbuf(buff); } } char *do_comconnectchannel(player, channel, alias, i) dbref player; char *channel; char *alias; int i; { struct channel *ch; struct comuser *user; if ((ch = select_channel(channel))) { for (user = ch->on_users; user && user->who != player; user = user->on_next) ; if (!user) if ((user = select_user(ch, player))) { 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)); } char *do_comdisconnect(player) dbref player; { int i; struct commac *c; c = get_commac(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 } } char *do_comconnect(player) dbref player; { struct commac *c; int i; c = get_commac(player); for (i = 0; i < c->numchannels; i++) { do_comconnectchannel(player, c->channels[i], c->alias, i); do_comconnectraw_notify(player, c->channels[i]); } } char *do_comdisconnectchannel(player, channel) dbref player; char *channel; { struct comuser *user, *prevuser; struct channel *ch; prevuser = NULL; if (!(ch = select_channel(channel))) return; 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(player, cause, flag, arg1, arg2) dbref player, cause; int flag; char *arg1; char *arg2; { char *s; struct channel *ch; int add_remove = 1; if (!mudconf.have_comsys) { raw_notify(player, "Comsys disabled."); return; } if (!(ch = select_channel(arg1))) { 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; } for (s = arg2; *s; s++) if (isspace(*s)) *s = *(s + 1); s = arg2; if (*s == '!') { add_remove = 0; s++; } switch (flag) { case 0: if (lookup_player(player, arg2, 1) != NOTHING) { ch->charge_who = lookup_player(player, arg2, 1); raw_notify(player, "Set."); return; } else { raw_notify(player, "Invalid player."); return; } case 1: ch->charge = atoi(arg2); raw_notify(player, "Set."); return; case 3: if (strcmp(s, "join") == 0) { add_remove ? (ch->type |= (CHANNEL_PL_MULT * CHANNEL_JOIN)) : (ch->type &= ~(CHANNEL_PL_MULT * CHANNEL_JOIN)); raw_notify(player, (add_remove) ? "@cpflags: Set." : "@cpflags: Cleared."); return; } if (strcmp(s, "receive") == 0) { add_remove ? (ch->type |= (CHANNEL_PL_MULT * CHANNEL_RECIEVE)) : (ch->type &= ~(CHANNEL_PL_MULT * CHANNEL_RECIEVE)); raw_notify(player, (add_remove) ? "@cpflags: Set." : "@cpflags: Cleared."); return; } if (strcmp(s, "transmit") == 0) { add_remove ? (ch->type |= (CHANNEL_PL_MULT * CHANNEL_TRANSMIT)) : (ch->type &= ~(CHANNEL_PL_MULT * CHANNEL_TRANSMIT)); raw_notify(player, (add_remove) ? "@cpflags: Set." : "@cpflags: Cleared."); return; } raw_notify(player, "@cpflags: Unknown Flag."); break; case 4: if (strcmp(s, "join") == 0) { add_remove ? (ch->type |= (CHANNEL_OBJ_MULT * CHANNEL_JOIN)) : (ch->type &= ~(CHANNEL_OBJ_MULT * CHANNEL_JOIN)); raw_notify(player, (add_remove) ? "@coflags: Set." : "@coflags: Cleared."); return; } if (strcmp(s, "receive") == 0) { add_remove ? (ch->type |= (CHANNEL_OBJ_MULT * CHANNEL_RECIEVE)) : (ch->type &= ~(CHANNEL_OBJ_MULT * CHANNEL_RECIEVE)); raw_notify(player, (add_remove) ? "@coflags: Set." : "@coflags: Cleared."); return; } if (strcmp(s, "transmit") == 0) { add_remove ? (ch->type |= (CHANNEL_OBJ_MULT * CHANNEL_TRANSMIT)) : (ch->type &= ~(CHANNEL_OBJ_MULT * CHANNEL_TRANSMIT)); raw_notify(player, (add_remove) ? "@coflags: Set." : "@coflags: Cleared."); return; } raw_notify(player, "@coflags: Unknown Flag."); break; } return; } int do_test_access(player, access, chan) dbref player; long access; struct channel *chan; { long flag_value = access; if (Comm_All(player)) return (1); if ((flag_value & CHANNEL_JOIN) && 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 ((flag_value & CHANNEL_JOIN) && !((chan->chan_obj == NOTHING) || (chan->chan_obj == 0))) { if (could_doit(player, chan->chan_obj, A_LOCK)) return (1); } if ((flag_value & CHANNEL_TRANSMIT) && !((chan->chan_obj == NOTHING) || (chan->chan_obj == 0))) { if (could_doit(player, chan->chan_obj, A_LUSE)) return (1); } if ((flag_value & CHANNEL_RECIEVE) && !((chan->chan_obj == NOTHING) || (chan->chan_obj == 0))) { 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; flag_value &= 0xFF; /* * Mask out CHANNEL_PUBLIC and CHANNEL_LOUD * * * * * * * * * * * * just to be paranoid. * ^_^ */ return (((long)chan->type & flag_value)); } int do_comsystem(who, cmd) /* * * 1 means continue, 0 means stop */ dbref who; char *cmd; { char *t; char *ch; char *alias; char *s; alias = alloc_lbuf("do_comsystem"); s = alias; for (t = cmd; *t && *t != ' '; *s++ = *t++) ; *s = '\0'; if (*t) t++; ch = get_channel_from_alias(who, alias); if (strlen(ch) > 0) { do_processcom(who, ch, t); free_lbuf(alias); return 0; } else free_lbuf(alias); return 1; } char *do_chclose(player, chan) dbref player; char *chan; { struct channel *ch; if (!(ch = select_channel(chan))) { raw_notify(player, tprintf("@cset: Channel %s does not exist.", chan)); return; } if ((player != ch->charge_who) && (!Comm_All(player))) { raw_notify(player, "@cset: Permission denied."); return; } ch->type &= (~(CHANNEL_PUBLIC)); raw_notify(player, tprintf("@cset: Channel %s taken off the public listings." ,chan)); return; } void do_cemit(player, cause, key, chan, text) dbref player, cause; int key; char *chan, *text; { struct channel *ch; if (!mudconf.have_comsys) { raw_notify(player, "Comsys disabled."); return; } if (!(ch = select_channel(chan))) { raw_notify(player, tprintf("Channel %s does not exist.", chan)); return; } if ((player != ch->charge_who) && (!Comm_All(player))) { raw_notify(player, "Permission denied."); return; } if (key == CEMIT_NOHEADER) do_comsend(ch, text); else do_comsend(ch, tprintf("[%s] %s", chan, text)); } void do_chopen(player, cause, key, chan, object) dbref player, cause; int key; char *chan, *object; { struct channel *ch; if (!mudconf.have_comsys) { raw_notify(player, "Comsys disabled."); return; } switch (key) { case CSET_PRIVATE: do_chclose(player, chan); return; case CSET_LOUD: do_chloud(player, chan); return; case CSET_QUIET: do_chsquelch(player, chan); return; case CSET_LIST: do_chanlist(player, NOTHING, 1); return; case CSET_OBJECT: do_chanobj(player, chan, object); return; } if (!(ch = select_channel(chan))) { raw_notify(player, tprintf("@cset: Channel %s does not exist.", chan)); return; } if ((player != ch->charge_who) && (!Comm_All(player))) { raw_notify(player, "@cset: Permission denied."); return; } ch->type |= (CHANNEL_PUBLIC); raw_notify(player, tprintf("@cset: Channel %s placed on the public listings." ,chan)); return; } char *do_chloud(player, chan) dbref player; char *chan; { struct channel *ch; if (!(ch = select_channel(chan))) { raw_notify(player, tprintf("@cset: Channel %s does not exist.", chan)); return; } if ((player != ch->charge_who) && (!Comm_All(player))) { raw_notify(player, "@cset: Permission denied."); return; } ch->type |= (CHANNEL_LOUD); raw_notify(player, tprintf("@cset: Channel %s now sends connect/disconnect msgs." ,chan)); return; } char *do_chsquelch(player, chan) dbref player; char *chan; { struct channel *ch; if (!(ch = select_channel(chan))) { raw_notify(player, tprintf("@cset: Channel %s does not exist.", chan)); return; } if ((player != ch->charge_who) && (!Comm_All(player))) { raw_notify(player, "@cset: Permission denied."); return; } ch->type &= ~(CHANNEL_LOUD); raw_notify(player, tprintf("@cset: Channel %s connect/disconnect msgs muted." ,chan)); return; } void do_chboot(player, cause, key, channel, victim) dbref player, cause; int key; char *channel; char *victim; { struct comuser *user; struct channel *ch; struct comuser *vu; dbref thing; char buff[200]; /* * * * I sure hope it's not going to be that * * * * * * * * * long. */ if (!mudconf.have_comsys) { raw_notify(player, "Comsys disabled."); return; } if (!(ch = select_channel(channel))) { raw_notify(player, "@cboot: Unknown channel."); return; } if (!(user = select_user(ch, player))) { raw_notify(player, "@cboot: You are not on that channel."); return; } if (!(Chan_Boot(user) || (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) { raw_notify(player, "I don't see that here."); return; } if (!(vu = select_user(ch, thing))) { raw_notify(player, tprintf("@cboot: %s in not on the channel.", Name(thing))); return; } /* * We should be in the clear now. :) */ sprintf(buff, "[%s] %s boots %s off the channel.", ch->name, Name(player), Name(thing)); do_comsend(ch, buff); do_delcomchannel(thing, channel); } char *do_chanobj(player, channel, object) dbref player; char *channel; char *object; { struct channel *ch; dbref thing; char *buff; init_match(player, object, NOTYPE); match_everything(0); thing = match_result(); if (!(ch = select_channel(channel))) { raw_notify(player, "That channel does not exist."); return; } if (thing == NOTHING) { ch->chan_obj = NOTHING; raw_notify(player, "Set."); return; } if (!(ch->charge_who == player) && !Comm_All(player)) { raw_notify(player, "Permission denied."); return; } ch->chan_obj = thing; buff = unparse_object(player, thing, 0); raw_notify(player, tprintf("Channel %s is now using %s as channel object.", ch->name, buff)); free_lbuf(buff); } void do_chanlist(player, cause, key) dbref player, cause; int key; { dbref owner; struct channel *ch; int i, flags; char *temp; char *buf; char *atrstr; if (!mudconf.have_comsys) { raw_notify(player, "Comsys disabled."); return; } flags = (int)NULL; 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) sprintf(buf, "%s", "No description."); else sprintf(buf, "%-54.54s", atrstr); free_lbuf(atrstr); sprintf(temp, "%c%c %-13.13s %-15.15s %-45.45s", (ch->type & (CHANNEL_PUBLIC)) ? 'P' : '-', (ch->type & (CHANNEL_LOUD)) ? 'L' : '-', 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 --"); }