#include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> #include "externs.h" #include "db.h" #include "powers.h" #include "com.h" COM *chanlist = NULL; extern int quiet_reboot; void load_com_db() { FILE *fp; COM *c, *cnew; COM_P *cp, *cpnew; char *filename = "db/com.db"; char buf[4096]; int num_channels, num_players; OBJ *who; if(!(fp = fopen(filename, "r"))) { log_error(tprintf("Couldn't load \"%s\" for reading!", filename)); return; } fgets(buf, sizeof(buf), fp); num_channels = atoi(buf); if(!quiet_reboot && num_channels) { notify_all2(tprintf("Loading com system: %d channel%s", num_channels, check_plural(num_channels, "", "s")), NULL); flush_all_output(); } while(num_channels--) { fgets(buf, sizeof(buf), fp); num_players = atoi(buf); cnew = (COM *)stack_alloc(sizeof(COM), 1, 0); cnew->plist = NULL; cnew->next = NULL; fgets(buf, sizeof(buf), fp); *(buf+strlen(buf)-1) = '\0'; SET(cnew->name, buf); fgets(buf, sizeof(buf), fp); cnew->owner = (who = find_object(atoi(buf)))?who:root_obj; fgets(buf, sizeof(buf), fp); *(buf+strlen(buf)-1) = '\0'; SET(cnew->lock, buf); fgets(buf, sizeof(buf), fp); *(buf+strlen(buf)-1) = '\0'; SET(cnew->join_msg, buf); while(num_players--) { cpnew = (COM_P *)stack_alloc(sizeof(COM_P), 1, 0); fgets(buf, sizeof(buf), fp); if(!(who = find_object(atoi(buf))) || Typeof(who) != TYPE_PLAYER) { stack_free(cpnew); fgets(buf, sizeof(buf), fp); fgets(buf, sizeof(buf), fp); fgets(buf, sizeof(buf), fp); continue; } cpnew->player = who; fgets(buf, sizeof(buf), fp); *(buf+strlen(buf)-1) = '\0'; SET(cpnew->color, buf); fgets(buf, sizeof(buf), fp); *(buf+strlen(buf)-1) = '\0'; SET(cpnew->alias, buf); fgets(buf, sizeof(buf), fp); cpnew->flags = atoi(buf); cpnew->next = NULL; if(!cnew->plist) cnew->plist = cpnew; else { for(cp = cnew->plist;cp->next;cp = cp->next); cp->next = cpnew; } } if(!chanlist) chanlist = cnew; else { for(c = chanlist;c->next;c = c->next); c->next = cnew; } } fclose(fp); } void save_com_db() { COM *c; COM_P *cp; int num_channels, num_players; FILE *fp; char *filename = "db/com.db"; if(!(fp = fopen(filename, "w"))) { log_error(tprintf("Couldn't open \"%s\" for writing!", filename)); return; } num_channels = 0; for(c = chanlist;c;c = c->next) num_channels++; fprintf(fp, "%d\n", num_channels); for(c = chanlist;c;c = c->next) { num_players = 0; for(cp = c->plist;cp;cp = cp->next) num_players++; fprintf(fp, "%d\n", num_players); fprintf(fp, "%s\n", c->name); fprintf(fp, "%d\n", c->owner->dbref); fprintf(fp, "%s\n", c->lock); fprintf(fp, "%s\n", c->join_msg); for(cp = c->plist;cp;cp = cp->next) { fprintf(fp, "%d\n", cp->player->dbref); fprintf(fp, "%s\n", cp->color); fprintf(fp, "%s\n", cp->alias); fprintf(fp, "%d\n", cp->flags); } } fclose(fp); } /* See if this player can join this channel */ char chk_comlock(OBJ *player, COM *chan) { return(eval_boolexp(player, player, chan->lock)); } COM *find_channel(OBJ *player, char *chan) { COM *c; COM_P *cp; for(c = chanlist;c;c = c->next) { if(!string_compare(c->name, chan)) break; if(player) for(cp = c->plist;cp;cp = cp->next) if(cp->player == player) if(!string_compare(cp->alias, chan)) return(c); } return(c); } COM_P *is_on_channel(OBJ *player, COM *c, char check) { COM_P *cp; for(cp = c->plist;cp;cp = cp->next) if(cp->player == player) return((check)?((cp->flags & COM_OFF)?NULL:cp):cp); return(NULL); } static COM *find_default_channel(OBJ *player) { COM *c; COM_P *cp; for(c = chanlist;c;c = c->next) for(cp = c->plist;cp;cp = cp->next) if(cp->player == player) if(cp->flags & COM_DEFAULT) return(c); return(c); } static int owns_channels(OBJ *player) { COM *c; int total = 0; for(c = chanlist;c;c = c->next) if(c->owner == player) total++; return(total); } static int cquota_left(OBJ *player) { return(atoi(atr_get(player, "Cquota"))-owns_channels(player)); } static void chk_can_keep_com_alias(char *chan) { COM *c; COM_P *cp; for(c = chanlist;c;c = c->next) { for(cp = c->plist;cp;cp = cp->next) if(!string_compare(cp->alias, chan)) { cp->alias = stack_string_realloc(cp->alias, ""); notify(cp->player, tprintf("Your alias for channel \"%s\" was removed.", c->name)); } } } static int ok_channel_name(char *chan) { if(!*chan || strchr(chan, ';') || strchr(chan, ' ') || strchr(chan, '|')) { return(0); } return(1); } void do_create_channel(OBJ *player, char *chan) { COM *c, *new; char cname[4096]; strcpy(cname, strip_color(chan)); if(cquota_left(player) <= 0 && !power(player, POW_NOQUOTA)) { notify(player, "You have no quota left to create channels."); return; } if((get_class(player) != CLASS_DIR && *cname == '*') || (get_class(player) < CLASS_ADMIN && *cname == '.')) { notify(player, "Channels beginning with '*' and '.' are reserved."); return; } if(!ok_channel_name(cname)) { notify(player, "You can't name a channel that!"); return; } if((c = find_channel(NULL, cname))) { notify(player, tprintf("Channel \"%s\" already exists.", c->name)); return; } new = (COM *)stack_alloc(sizeof(COM), 1, 0); SET(new->name, cname); SET(new->lock, ""); SET(new->join_msg, ""); new->owner = player; new->plist = NULL; new->next = NULL; /* Place the new channel on the end of the list */ if(!chanlist) chanlist = new; else { for(c = chanlist;c->next;c = c->next); c->next = new; } notify(player, tprintf("Channel \"%s\" created.", cname)); chk_can_keep_com_alias(cname); } void do_delete_channel(OBJ *player, char *chan) { COM *c, *cprev = NULL; COM_P *cp, *cpnext; for(c = chanlist;c;c = c->next) { if(!string_compare(c->name, chan)) break; cprev = c; } if(!c) { notify(player, tprintf("Channel \"%s\" doesn't exist.", chan)); return; } if(c->owner != player && !power(player, POW_CHANNEL)) { notify(player, perm_denied()); return; } com_send(chan, NULL, "* This channel is being deleted. Byebye."); notify(player, tprintf("Channel \"%s\" has been deleted.", c->name)); if(cprev) cprev->next = c->next; else chanlist = c->next; for(cp = c->plist;cp;cp = cpnext) { cpnext = cp->next; stack_free(cp->alias); stack_free(cp->color); stack_free(cp); } stack_free(c->name); stack_free(c->lock); stack_free(c); } void com_send(char *chan, OBJ *player, char *msg) { COM *c; COM_P *cp; char buf[4096]; strcpy(buf, msg); if(!(c = find_channel(player, chan))) return; for(cp = c->plist;cp;cp = cp->next) if(!(cp->flags & COM_OFF)) notify(cp->player, tprintf("|+W|[|%s|%s|+W|]|n| %s", cp->color, chan, buf)); } static void do_list_channels(OBJ *player) { COM *c; COM_P *cp; int total = 0; char buf[4096]; for(c = chanlist;c;c = c->next) if(is_on_channel(player, c, 0)) break; if(!c) { notify(player, "You're not on any channels."); return; } notify(player, tprintf("|+B|.%s.", my_string("-", 49))); notify(player, tprintf("|+B|||+W|%s|+B||", my_center("Channel List", 49))); notify(player, tprintf("|+B||%s|", my_string("-", 49))); notify(player, tprintf("|+B|||+W|%s|+B|||+W|%s|+B|||+W| Status |+B|||+W| Lock |+B||", my_center("Name", 25), my_center("Alias", 7))); notify(player, tprintf("|+B||%s|%s|--------|------|", my_string("-", 25), my_string("-", 7))); for(c = chanlist;c;c = c->next) { if((cp = is_on_channel(player, c, 0))) { total++; sprintf(buf, "|+B|| |%s|%s|+B|| |%s|%s|+B|||%s|%s|+B||", cp->color, my_ljust(c->name, 24), cp->color, my_ljust(cp->alias, 6), cp->color, my_center((cp->flags & COM_OFF)?"OFF":"ON", 8)); sprintf(buf+strlen(buf), "|%s|%s|+B||", cp->color, my_center((*(c->lock))?"YES":"NO", 6)); notify(player, buf); } } c = find_default_channel(player); notify(player, tprintf("|+B||%s|", my_string("-", 49))); notify(player, tprintf("|+B|| %s|+B||", my_ljust(tprintf("|+W|Total Channels : |+Y|%d", total), 48))); notify(player, tprintf("|+B|| %s|+B||", my_ljust(tprintf("|+W|Default Channel: |+Y|%s", (c)?c->name:"NONE"), 48))); notify(player, tprintf("|+B|`%s'", my_string("-", 49))); } void do_join_channel(OBJ *player, char *chan) { COM *c; COM_P *cp, *new; char *alias, *color; /* Parse up chan into channel name, alias, and color */ /* See if they specified an alias */ if((alias = strchr(chan, ';'))) { *alias++ = '\0'; if((color = strchr(alias, ','))) *color++ = '\0'; else color = "n"; if(*alias) { for(c = chanlist;c;c = c->next) for(cp = c->plist;cp;cp = cp->next) if(cp->player == player) if(!string_compare(cp->alias, alias)) { notify(player, tprintf("You already have \"%s\" as a channel alias!", alias)); return; } } } else { alias = ""; if((color = strchr(chan, ','))) *color++ = '\0'; else color = "n"; } if(*color) if(!my_is_color(color)) { notify(player, tprintf("\"%s\" is not a valid color!", color)); return; } /* Reserve channels beginning with * for directors */ if(*chan == '*') if(get_class(player) != CLASS_DIR && !power(player, POW_CHANNEL)) { notify(player, perm_denied()); return; } /* Reserve channels beginning with . for directors and admins */ if(*chan == '.') if(get_class(player) != CLASS_DIR && get_class(player) != CLASS_ADMIN && !power(player, POW_CHANNEL)) { notify(player, perm_denied()); return; } /* Reserve channels beginning with _ for anyone higher than a citizen */ if(*chan == '_') if(get_class(player) < CLASS_PCITIZEN && !power(player, POW_CHANNEL)) { notify(player, perm_denied()); return; } if(!(c = find_channel(player, chan))) { notify(player, tprintf("Channel \"%s\" doesn't exist.", chan)); return; } if(!chk_comlock(player, c) && !power(player, POW_CHANNEL)) { notify(player, "You're not allowed to join that channel."); return; } if(is_on_channel(player, c, 0)) { notify(player, "You're already on that channel."); return; } new = (COM_P *)stack_alloc(sizeof(COM_P), 1, 0); SET(new->color, color); SET(new->alias, alias); new->player = player; new->flags = 0; new->next = NULL; if(!c->plist) c->plist = new; else { for(cp = c->plist;cp->next;cp = cp->next); cp->next = new; } if(!*atr_get(player, "LHIDE")) com_send(c->name, NULL, tprintf("* %s has joined this channel.", name(player))); if(!find_default_channel(player)) { new->flags |= COM_DEFAULT; notify(player, tprintf("\"%s\" is now your default channel.", c->name)); } if(*(c->join_msg)) notify(player, tprintf("|R|* |+B|Join Message|+W|: |n|%s", c->join_msg)); } void do_leave_channel(OBJ *player, char *chan) { COM *c; COM_P *cp, *cpprev = NULL; if(!(c = find_channel(player, chan))) { notify(player, tprintf("Channel \"%s\" doesn't exist.", chan)); return; } for(cp = c->plist;cp;cp = cp->next) { if(cp->player == player) break; cpprev = cp; } if(!cp) { notify(player, "You're not on that channel."); return; } if(!*atr_get(player, "LHIDE")) com_send(c->name, NULL, tprintf("* %s has left this channel.", name(player))); if(!cpprev) c->plist = cp->next; else cpprev->next = cp->next; stack_free(cp->color); stack_free(cp->alias); stack_free(cp); } static void make_default_channel(OBJ *player, char *chan) { COM *c, *cold; COM_P *cp, *cpold; if(!(c = find_channel(player, chan))) { notify(player, tprintf("Channel \"%s\" doesn't exist.", chan)); return; } if(!(cp = is_on_channel(player, c, 0))) { notify(player, tprintf("You're not on that channel.")); return; } /* See if they already have a default channel */ if((cold = find_default_channel(player))) { cpold = is_on_channel(player, cold, 0); cpold->flags &= ~COM_DEFAULT; } cp->flags |= COM_DEFAULT; notify(player, tprintf("Your default channel is now \"%s\".", c->name)); } static void do_com_color(OBJ *player, char *chan) { COM *c; COM_P *cp; char *color; if(!(color = strchr(chan, ',')) || !*(color+1)) { notify(player, "You need to specify a color."); return; } *color++ = '\0'; if(!my_is_color(color)) { notify(player, tprintf("\"%s\" is not a valid color.", color)); return; } if(!(c = find_channel(player, chan))) { notify(player, tprintf("Channel \"%s\" doesn't exist.", chan)); return; } if(!(cp = is_on_channel(player, c, 0))) { notify(player, "You aren't on that channel."); return; } cp->color = stack_string_realloc(cp->color, color); notify(player, tprintf("Color for channel \"%s\" is now: |%s|%s", c->name, cp->color, cp->color)); } static void do_com_alias(OBJ *player, char *chan) { COM *c; COM_P *cp; char *alias; if(!(alias = strchr(chan, ',')) || !*(alias+1)) { notify(player, "You need to specify an alias."); return; } *alias++ = '\0'; for(c = chanlist;c;c = c->next) for(cp = c->plist;cp;cp = cp->next) if(!string_compare(c->name, alias) || (cp->player == player && !string_compare(cp->alias, alias))) { notify(player, "You may not use that as an alias."); return; } if(!(c = find_channel(player, chan))) { notify(player, tprintf("Channel \"%s\" doesn't exist.", chan)); return; } if(!(cp = is_on_channel(player, c, 0))) { notify(player, "You aren't on that channel."); return; } cp->alias = stack_string_realloc(cp->alias, alias); notify(player, tprintf("Alias for channel \"%s\" is now: %s", c->name, cp->alias)); } static void do_com_list(OBJ *player, char *chan) { COM *c; COM_P *cp; int total_players; DDATA *d; char cbuf[4096]; if(*chan) { if(!power(player, POW_CHANNEL)) { notify(player, perm_denied()); return; } if(!(c = find_channel(player, chan))) { notify(player, tprintf("Channel \"%s\" doesn't exist.", chan)); return; } notify(player, tprintf("Player list for channel \"%s\":", c->name)); for(cp = c->plist;cp;cp = cp->next) { if((d = is_idle(cp->player))) sprintf(cbuf, "(%s) ", time_format(now-d->last_time, 1)); else *cbuf = '\0'; notify(player, tprintf("%s |+W|%s%s%s", unparse_object(player, cp->player), (is_connected_raw(cp->player))?"(CONNECTED) ":"", cbuf, (*atr_get(cp->player, "LHIDE"))?"(HIDDEN) ":"")); } return; } notify(player, tprintf("|+B|.%s.", my_string("-", 57))); notify(player, tprintf("|+B|||+W|%s|+B||", my_center("Channel List", 57))); notify(player, tprintf("|+B||%s|", my_string("-", 57))); notify(player, tprintf("|+B|||+Y|%s|+B|||+Y|%s|+B|||+Y|%s|+B|||+Y|%s|+B||", my_center("NAME", 20), my_center("OWNER", 20), my_center("PLAYERS", 9), my_center("ON?", 5))); notify(player, tprintf("|+B||%s|", my_string("-", 57))); for(c = chanlist;c;c = c->next) { total_players = 0; for(cp = c->plist;cp;cp = cp->next) total_players++; notify(player, tprintf("|+B|| |+C|%s|+B|| %s|+B|||+C|%s |+B|| |+C|%s|+B||", my_ljust(c->name, 19), my_ljust(unparse_object(player, c->owner), 19), my_rjust(comma(tprintf("%d", total_players)), 8), my_ljust((is_on_channel(player, c, 0))?"YES":"NO", 4))); } notify(player, tprintf("|+B|`%s'", my_string("-", 57))); } static void do_com_boot(OBJ *player, char *chan) { COM *c; COM_P *cp, *cpnext; char *p; OBJ *who; char *chanfull; if(!(p = strchr(chan, ','))) { notify(player, "You can't use this command that way!"); return; } *p++ = '\0'; if(!(c = find_channel(player, chan))) { notify(player, tprintf("Channel \"%s\" doesn't exist.", chan)); return; } if(c->owner != player && !power(player, POW_CHANNEL)) { notify(player, "You need to be the owner of the channel to do that."); return; } if(!strcmp(p, "ALL")) { for(cp = c->plist;cp;cp = cpnext) { cpnext = cp->next; if(cp->player == player) continue; notify(cp->player, tprintf("You have been booted from channel \"%s\"", c->name)); do_leave_channel(cp->player, c->name); } log_important(tprintf("%s booted everybody from channel %s", name(player), c->name)); return; } if(!(who = match_player(NULL, p))) { notify(player, tprintf("I don't know who \"%s\" is!", p)); return; } if(player == who) { notify(player, "You can't boot yourself off a channel!"); return; } if(!(cp = is_on_channel(who, c, 0))) { notify(player, tprintf("%s isn't on that channel!", name(who))); return; } chanfull = unparse_com_alias(player, chan); do_leave_channel(who, chanfull); notify(who, tprintf("You have been booted from channel \"%s\"", chanfull)); notify(player, tprintf("%s has been booted from channel \"%s\"", name(who), chanfull)); com_send(chanfull, NULL, tprintf("%s has been booted from this channel", name(who))); log_important(tprintf("%s booted %s from channel \"%s\"", name(player), name(who), chanfull)); } static void do_com_lock(OBJ *player, char *chan) { COM *c; char *lock; char *p; if(!(lock = strchr(chan, ','))) { if(!(c = find_channel(player, chan))) { notify(player, tprintf("Channel \"%s\" doesn't exist.", chan)); return; } if(!*(c->lock)) notify(player, tprintf("There is no lock for channel \"%s\".", c->name)); else notify(player, tprintf("Lock for channel \"%s\" is: %s", c->name, unprocess_lock(player, c->lock))); return; } *lock++ = '\0'; if(!(c = find_channel(player, chan))) { notify(player, tprintf("Channel \"%s\" doesn't exist.", chan)); return; } if(c->owner != player && !power(player, POW_CHANNEL)) { notify(player, "You need to be the owner of the channel to do that."); return; } if(!(p = process_lock(player, lock))) return; c->lock = stack_string_realloc(c->lock, p); if(!*p) notify(player, tprintf("Lock removed for channel \"%s\".", c->name)); else notify(player, tprintf("Lock for channel \"%s\" is now: %s", c->name, unprocess_lock(player, c->lock))); } static void do_com_stat(OBJ *player, char *chan) { COM *c; COM_P *cp; int ctr = 0; if(!(c = find_channel(player, chan))) { notify(player, tprintf("Channel \"%s\" doesn't exist.", chan)); return; } for(cp = c->plist;cp;cp = cp->next) ctr++; notify(player, tprintf("|+B|Name |+W|: |+C|%s", c->name)); notify(player, tprintf("|+B|Owner |+W|: %s", unparse_object(player, c->owner))); notify(player, tprintf("|+B|Players |+W|: |+C|%d", ctr)); notify(player, tprintf("|+B|Lock |+W|: |+C|%s", (*c->lock)?unprocess_lock(player, c->lock):"NONE")); notify(player, tprintf("|+B|Join Message|+W|: |+C|%s", (*c->join_msg)?c->join_msg:"NONE")); } static void do_com_name(OBJ *player, char *chan) { COM *c, *c2; char new_name[4096]; char *p; if((p = strchr(chan, ','))) { *p++ = '\0'; strcpy(new_name, strip_color(p)); } if(!(c = find_channel(player, chan))) { notify(player, tprintf("Channel \"%s\" doesn't exist.", chan)); return; } if(!p) { notify(player, tprintf("|+B|Channel name|+W|: |+C|%s", c->name)); return; } if(c->owner != player && !power(player, POW_CHANNEL)) { notify(player, "You need to be the owner of the channel to do that."); return; } if((get_class(player) != CLASS_DIR && *new_name == '*') || (get_class(player) < CLASS_ADMIN && *new_name == '.')) { notify(player, "Channels beginning with '*' and '.' are reserved."); return; } if(!ok_channel_name(new_name)) { notify(player, "You can't name a channel that!"); return; } if((c2 = find_channel(NULL, new_name))) { if(string_compare(c2->name, new_name)) { notify(player, tprintf("Channel \"%s\" already exists.", c2->name)); return; } } com_send(c->name, NULL, tprintf("This channel is being renamed to: %s", new_name)); c->name = stack_string_realloc(c->name, new_name); notify(player, tprintf("|+B|Channel name|+W|: |+C|%s", new_name)); chk_can_keep_com_alias(new_name); } static void do_com_jmesg(OBJ *player, char *chan) { COM *c; char *msg; if((msg = strchr(chan, ','))) *msg++ = '\0'; if(!(c = find_channel(player, chan))) { notify(player, tprintf("Channel \"%s\" doesn't exist.", chan)); return; } if(!msg) { notify(player, tprintf("|+B|Join message|+W|: |+C|%s", c->join_msg)); return; } if(c->owner != player && !power(player, POW_CHANNEL)) { notify(player, "You need to be the owner of the channel to do that."); return; } c->join_msg = stack_string_realloc(c->join_msg, msg); notify(player, tprintf("|+B|Join message|+W|: |+C|%s", msg)); } /* Turn all channels on for player */ static void do_com_on(OBJ *player) { COM *c; COM_P *cp; for(c = chanlist;c;c = c->next) if((cp = is_on_channel(player, c, 0))) if(cp->flags & COM_OFF) { if(!*atr_get(player, "LHIDE")) com_send(c->name, NULL, tprintf("* %s has turned this channel on.", name(player))); cp->flags &= ~COM_OFF; } notify(player, "All your channels have been turned on."); } /* Turn all channels off for player */ static void do_com_off(OBJ *player) { COM *c; COM_P *cp; for(c = chanlist;c;c = c->next) if((cp = is_on_channel(player, c, 0))) if(!(cp->flags & COM_OFF)) { cp->flags |= COM_OFF; if(!*atr_get(player, "LHIDE")) com_send(c->name, NULL, tprintf("* %s has turned this channel off.", name(player))); } notify(player, "All your channels have been turned off."); } void do_channel(OBJ *player, char *arg1, char *arg2) { if(Typeof(player) != TYPE_PLAYER) { notify(player, "Only real players can use channels."); return; } if(!*arg1) { do_list_channels(player); return; } if(*arg1 == '+') { do_join_channel(player, arg1+1); return; } if(*arg1 == '-') { do_leave_channel(player, arg1+1); return; } if(!string_compare("list", arg1)) { do_com_list(player, arg2); return; } if(!string_compare("on", arg1)) { do_com_on(player); return; } if(!string_compare("off", arg1)) { do_com_off(player); return; } if(!*arg2) { make_default_channel(player, arg1); return; } if(string_prefix("create", arg1)) { do_create_channel(player, arg2); return; } if(string_prefix("delete", arg1)) { do_delete_channel(player, arg2); return; } if(string_prefix("color", arg1)) { do_com_color(player, arg2); return; } if(string_prefix("alias", arg1)) { do_com_alias(player, arg2); return; } if(string_prefix("boot", arg1)) { do_com_boot(player, arg2); return; } if(string_prefix("jmesg", arg1)) { do_com_jmesg(player, arg2); return; } if(string_prefix("lock", arg1)) { do_com_lock(player, arg2); return; } if(string_prefix("stat", arg1)) { do_com_stat(player, arg2); return; } if(string_prefix("name", arg1)) { do_com_name(player, arg2); return; } notify(player, "You can't use this command that way!"); } static void do_com_who(OBJ *player, COM *c) { char buf[4096]; COM_P *cp; int num_hidden = 0, total = 0, num_active = 0; char idle_buf[4096]; DDATA *d; notify(player, tprintf("|+W|Who's on channel \"%s\"?", c->name)); for(cp = c->plist;cp;cp = cp->next) { if(!is_connected_raw(cp->player)) continue; if(cp->flags & COM_OFF) continue; if((d = is_idle(cp->player))) sprintf(idle_buf, "(%s) ", time_format(now-d->last_time, 1)); else *idle_buf = '\0'; total++; if(!could_doit(player, cp->player, "LHIDE")) { if(controls(player, cp->player, POW_WHO)) { notify(player, tprintf("%s |+W|%s(HIDDEN)", unparse_object(player, cp->player), idle_buf)); if(!*idle_buf) num_active++; } num_hidden++; } else { notify(player, tprintf("%s |+W|%s", unparse_object(player, cp->player), idle_buf)); if(!*idle_buf) num_active++; } } notify(player, "|+W|----------"); sprintf(buf, "|+W|%d |+B|Total", total); if(num_hidden) strcat(buf, tprintf(", |+W|%d |+B|Hidden", num_hidden)); if(num_active) strcat(buf, tprintf(", |+W|%d |+B|Active", num_active)); notify(player, buf); } void do_com(OBJ *player, char *chan, char *msg) { COM *c; COM_P *cp; char buf[4096], buf2[4096]; int type; if(!*chan) { if(!(c = find_default_channel(player))) { notify(player, "You have no default channel."); return; } cp = is_on_channel(player, c, 0); } else { if(!(c = find_channel(player, chan))) { notify(player, tprintf("Channel \"%s\" doesn't exist.", chan)); return; } if(!(cp = is_on_channel(player, c, 0))) { notify(player, "You aren't on that channel."); return; } } if(!string_compare(msg, "on")) { if(!(cp->flags & COM_OFF)) notify(player, "You already have that channel turned on!"); else { cp->flags &= ~COM_OFF; if(!*atr_get(player, "LHIDE")) com_send(c->name, NULL, tprintf("* %s has turned this channel on.", name(player))); } return; } if(!string_compare(msg, "off")) { if(cp->flags & COM_OFF) notify(player, "You already have that channel turned off!"); else { if(!*atr_get(player, "LHIDE")) com_send(c->name, NULL, tprintf("* %s has turned this channel off.", name(player))); cp->flags |= COM_OFF; } return; } if(cp->flags & COM_OFF) { notify(player, "You have that channel turned off."); return; } if(!string_compare(msg, "who")) { do_com_who(player, c); return; } type = unparse_tothink(player, msg, buf2, 1, 0x3); if(type == 0) sprintf(buf, "%s: %s", name(player), buf2); else if(type == 1) sprintf(buf, "%s %s", name(player), buf2); else sprintf(buf, "%s %s", poss(player), buf2); com_send(c->name, player, buf); } char *unparse_com_alias(OBJ *player, char *chan) { COM *c; COM_P *cp; for(c = chanlist;c;c = c->next) for(cp = c->plist;cp;cp = cp->next) if(cp->player == player) if(!string_compare(chan, c->name) || !string_compare(chan, cp->alias)) { return(c->name); } return(""); } void do_cquota(OBJ *player, char *arg1, char *arg2) { char buf[4096]; OBJ *victim; int limit; if(!*arg1) victim = player; else if(!(victim = match_player(NULL, arg1))) { notify(player, no_match(arg1)); return; } if(!controls(player, victim, POW_SETQUOTA)) { notify(player, perm_denied()); return; } if(!*arg2) limit = atoi(atr_get(victim, "CQUOTA")); else { if(!power(player, POW_SETQUOTA)) { notify(player, perm_denied()); return; } if((limit = atoi(arg2)) < 0) { notify(player, "Cannot set a player's cquota to a negative number!"); return; } atr_add(victim, "CQUOTA", tprintf("%d", limit)); } if(power(victim, POW_NOQUOTA)) strcpy(buf, "UNLIMITED"); else sprintf(buf, "%d", limit); notify(player, tprintf("|+B|Channels|+W|: |+C|%d |+B|Limit|+W|: |+C|%s", owns_channels(victim), buf)); } void rem_from_channels(OBJ *player) { COM *c; for(c = chanlist;c;c = c->next) if(is_on_channel(player, c, 0)) do_leave_channel(player, c->name); } void free_channels() { COM *c, *cnext; COM_P *cp, *cpnext; for(c = chanlist;c;c = cnext) { cnext = c->next; for(cp = c->plist;cp;cp = cpnext) { cpnext = cp->next; stack_free(cp->color); stack_free(cp->alias); stack_free(cp); } stack_free(c->name); stack_free(c->lock); stack_free(c->join_msg); stack_free(c); } }