/* * Playground+ - channel.c * All new and improved channel code written by Silver (main, spod & zchannel) * ---------------------------------------------------------------------------- * Serious rewrite of channel commands using generalisations, by blimey * saved on hundreds of lines of ghastly repeated code * * Repeated code? Me? Never .. oops [whistles innocently] -- Silver */ #include <time.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <stddef.h> #include <stdarg.h> #include "include/config.h" #include "include/player.h" #include "include/proto.h" #ifdef INTERCOM void ichan_wall(char *); void i_chan(char *,...); #include "include/intercom.h" extern nameban *check_intercom_banished_name (char *); #endif /* * Shadow Realms channel code -- by blimey * */ char *how_to_say(char *str) { for (; *str; str++); switch (*(--str)) { case '?': return "asks"; case '!': return "exclaims"; default: return "says"; } } /* * Here are the higher order definitions of channel commands -- blimey * */ void channel_emote(player * p, char *str, void (*the_wall) (char *,...)) { if (p->flags & FROGGED) str = "shakes a broken rattle"; if ((*str == '`') || (*str == '\'')) the_wall("%s%s^N\n", p->name, str); else the_wall("%s %s^N\n", p->name, str); } void channel_say(player * p, char *str, void (*the_wall) (char *,...)) { the_wall("%s %s '%s%s^N'\n", p->name, how_to_say(str), str, (p->flags & FROGGED ? " and WHERE'S MY RATTLE?!" : "")); } void channel_sing(player * p, char *str, void (*the_wall) (char *,...)) { the_wall("%s sings o/~ %s ^No/~%s\n", p->name, str, (p->flags & FROGGED ? " while shaking a broken rattle" : "")); } void channel_think(player * p, char *str, void (*the_wall) (char *,...)) { the_wall("%s thinks %s. o O ( %s ^N)\n", p->name, (p->flags & FROGGED ? "in an infantile fashion " : ""), str); } /* Silver did these 3 rather handy funtions :) */ /* Awwww, gee thanks :o) --Silver */ /* Main Channel */ void ppl_wall(char *str) { player *scan; for (scan = flatlist_start; scan; scan = scan->flat_next) { if (scan->residency && !(scan->misc_flags & NO_MAIN_CHANNEL) && scan->location) { if (scan->misc_flags & CHAN_HI) { command_type |= HIGHLIGHT; } sys_color_atm = UCOsc; tell_player(scan, str); sys_color_atm = SYSsc; if (scan->misc_flags & CHAN_HI) { command_type &= ~HIGHLIGHT; } } } } /* Spod channel */ void spod_wall(char *str) { player *scan; for (scan = flatlist_start; scan; scan = scan->flat_next) { if ((scan->residency & SPOD) && !(scan->misc_flags & NO_SPOD_CHANNEL) && scan->location) { if (scan->misc_flags & CHAN_HI) { command_type |= HIGHLIGHT; } sys_color_atm = UCEsc; tell_player(scan, str); sys_color_atm = SYSsc; if (scan->misc_flags & CHAN_HI) { command_type &= ~HIGHLIGHT; } } } } /* ZChannels */ void zwall(char *str) { player *scan, *p = current_player; /* blimey changed this */ for (scan = flatlist_start; scan; scan = scan->flat_next) { if (scan->residency && !strcasecmp(scan->zchannel, p->zchannel) && scan->location) { if (scan->misc_flags & CHAN_HI) { command_type |= HIGHLIGHT; } sys_color_atm = ZCHsc; tell_player(scan, str); scan->zcidle = 0; /* reset that channels idle time */ sys_color_atm = SYSsc; if (scan->misc_flags & CHAN_HI) { command_type &= ~HIGHLIGHT; } } else /* if we get here, then they've got this set wrongly so */ scan->misc_flags &=~ SEE_DEBUG_CHANNEL; /* turn it off */ } } /* A debugging one */ void debug_wall(char *str) { player *scan; for (scan = flatlist_start; scan; scan = scan->flat_next) { if (scan->residency & DEBUG) { if ((scan->misc_flags & SEE_DEBUG_CHANNEL) && scan->location) { if (scan->misc_flags & CHAN_HI) { command_type |= HIGHLIGHT; } TELLPLAYER(scan, "%s %s\n", get_config_msg("debug_chan"), str); if (scan->misc_flags & CHAN_HI) { command_type &= ~HIGHLIGHT; } } } } } /* * blimey wrote this .... * */ void any_chan(char *prefix, void (*the_wall) (char *), char *format, va_list ap) { char *oldstack = stack; command_type = 0; sprintf(stack, "%s ", prefix); stack = strchr(stack, 0); vsprintf(stack, format, ap); stack = end_string(stack); the_wall(oldstack); stack = oldstack; } void au_chan(char *format,...) { va_list x; va_start(x, format); any_chan(get_config_msg("admin_chan"), au_wall, format, x); va_end(x); } void cu_chan(char *format,...) { va_list x; va_start(x, format); any_chan(get_config_msg("main_chan"), ppl_wall, format, x); va_end(x); } #ifdef HC_CHANNEL void hu_chan(char *format,...) { va_list x; va_start(x, format); any_chan(get_config_msg("hc_chan"), hc_wall, format, x); va_end(x); } #endif void pu_chan(char *format,...) { va_list x; va_start(x, format); any_chan(get_config_msg("spod_chan"), spod_wall, format, x); va_end(x); } void su_chan(char *format,...) { va_list x; va_start(x, format); any_chan(get_config_msg("su_chan"), su_wall, format, x); va_end(x); } void zu_chan(char *format,...) { va_list x; char *oldstack = stack; sprintf(stack, "<(%s)>", current_player->zchannel); stack += 1 + strlen(stack); va_start(x, format); any_chan(oldstack, zwall, format, x); va_end(x); stack = oldstack; } int got_msg(player * p, char *str, char *cname) { if (!*str) TELLPLAYER(p, " Format: %s <message>\n", cname); return *str; } void toggle_debug_channel(player * p, char *str) { if (p->misc_flags & SEE_DEBUG_CHANNEL) { p->misc_flags &= ~SEE_DEBUG_CHANNEL; tell_player(p, " You ignore the debug channel.\n"); } else { p->misc_flags |= SEE_DEBUG_CHANNEL; tell_player(p, " You start viewing the debug channel.\n"); } } void channel_toggle(player * p, void (*the_wall) (char *,...), int flag) { if (p->misc_flags & flag) { p->misc_flags &= ~flag; the_wall("++ %s joins the channel ++\n", p->name); #ifdef INTERCOM if (flag == NO_INTERCOM_CHANNEL) intercom_channel_action(p, "join"); #endif } else { the_wall("-- %s leaves the channel --\n", p->name); p->misc_flags |= flag; #ifdef INTERCOM if (flag == NO_INTERCOM_CHANNEL) intercom_channel_action(p, "leave"); #endif } } int not_blocking_su_channel(player * p) { if (!(p->flags & BLOCK_SU)) return 1; tell_player(p, " You are off duty, so you can't use the channel.\n"); return 0; } int is_on_channel(player * p, int flag) { char *which = NULL; if (!(p->misc_flags & flag)) return 1; switch (flag) { case NO_SPOD_CHANNEL: which = "spod"; break; case NO_MAIN_CHANNEL: which = "main"; break; #ifdef INTERCOM case NO_INTERCOM_CHANNEL: which = "intercom"; break; #endif /* add in any more channels here ... */ } TELLPLAYER(p, " You aren't on the %s channel!\n", which); return 0; } int is_on_zchannel(player * p) { if (!p->zchannel[0]) tell_player(p, " You aren't on any zchannel!\n"); return p->zchannel[0]; } /* * Actual channel command functions now follow -- blimey * */ void chanhi(player * p, char *str) { TELLPLAYER(p, " Channels will no%c be hilited.\n", (p->misc_flags ^= CHAN_HI) & CHAN_HI ? 'w' : 't'); } /* toggle whether the su channel is highlighted or not */ void su_hilited(player * p, char *str) { TELLPLAYER(p, " You will %sget the su channel hilited.\n", (p->misc_flags ^= SU_HILITED) & SU_HILITED ? "" : "not "); } /* * Admin channel * */ void adminemote(player * p, char *str) { if (got_msg(p, str, "ae") && not_blocking_su_channel(p)) channel_emote(p, str, au_chan); } void adminsing(player * p, char *str) { if (got_msg(p, str, "as") && not_blocking_su_channel(p)) channel_sing(p, str, au_chan); } void adminthink(player * p, char *str) { if (got_msg(p, str, "at") && not_blocking_su_channel(p)) channel_think(p, str, au_chan); } void ad(player * p, char *str) { if (got_msg(p, str, "au") && not_blocking_su_channel(p)) channel_say(p, str, au_chan); } /* * Main channel * */ void ce(player * p, char *str) { if (got_msg(p, str, "ce") && is_on_channel(p, NO_MAIN_CHANNEL)) channel_emote(p, str, cu_chan); } void cs(player * p, char *str) { if (got_msg(p, str, "cs") && is_on_channel(p, NO_MAIN_CHANNEL)) channel_sing(p, str, cu_chan); } void ct(player * p, char *str) { if (got_msg(p, str, "ct") && is_on_channel(p, NO_MAIN_CHANNEL)) channel_think(p, str, cu_chan); } void cu(player * p, char *str) { if (got_msg(p, str, "cu") && is_on_channel(p, NO_MAIN_CHANNEL)) channel_say(p, str, cu_chan); } #ifdef HC_CHANNEL /* HCAdmin channel - not one I particulary want but this was requested */ /* Bah! -- Silver */ /* Note - HC channel colour is the same as the admin channel colour. I could have given it a new colour BUT it would mean that PG+ was not directly compatable with PG pfiles (you would have had to run the pfiles through a convertor) so its a programming challenge for you to code it in! */ void he(player * p, char *str) { if (got_msg(p, str, "he") && not_blocking_su_channel(p)) channel_emote(p, str, hu_chan); } void hs(player * p, char *str) { if (got_msg(p, str, "hs") && not_blocking_su_channel(p)) channel_sing(p, str, hu_chan); } void ht(player * p, char *str) { if (got_msg(p, str, "ht") && not_blocking_su_channel(p)) channel_think(p, str, hu_chan); } void hd(player * p, char *str) { if (got_msg(p, str, "hu") && not_blocking_su_channel(p)) channel_say(p, str, hu_chan); } #endif /* * Spod channel * */ void pe(player * p, char *str) { if (got_msg(p, str, "pe") && is_on_channel(p, NO_SPOD_CHANNEL)) channel_emote(p, str, pu_chan); } void ps(player * p, char *str) { if (got_msg(p, str, "ps") && is_on_channel(p, NO_SPOD_CHANNEL)) channel_sing(p, str, pu_chan); } void pt(player * p, char *str) { if (got_msg(p, str, "pt") && is_on_channel(p, NO_SPOD_CHANNEL)) channel_think(p, str, pu_chan); } void pu(player * p, char *str) { if (got_msg(p, str, "pu") && is_on_channel(p, NO_SPOD_CHANNEL)) channel_say(p, str, pu_chan); } /* * SU channel * */ void suemote(player * p, char *str) { if (got_msg(p, str, "se") && not_blocking_su_channel(p)) channel_emote(p, str, su_chan); } void susing(player * p, char *str) { if (got_msg(p, str, "ss") && not_blocking_su_channel(p)) channel_sing(p, str, su_chan); } void suthink(player * p, char *str) { if (got_msg(p, str, "st") && not_blocking_su_channel(p)) channel_think(p, str, su_chan); } void su(player * p, char *str) { if (got_msg(p, str, "su") && not_blocking_su_channel(p)) channel_say(p, str, su_chan); } /* * Z - Channels * */ void ze(player * p, char *str) { if (got_msg(p, str, "ze") && is_on_zchannel(p)) channel_emote(p, str, zu_chan); } void zs(player * p, char *str) { if (got_msg(p, str, "zs") && is_on_zchannel(p)) channel_sing(p, str, zu_chan); } void zt(player * p, char *str) { if (got_msg(p, str, "zt") && is_on_zchannel(p)) channel_think(p, str, zu_chan); } void zu(player * p, char *str) { if (got_msg(p, str, "zu") && is_on_zchannel(p)) channel_say(p, str, zu_chan); } /* * Rest of file is Silver's work * */ /* Thank you blimey and I present to you ... ZChannel stuff :o) */ void zc(player * p, char *str) { char *oldstack = stack; char *check; player *scan; int newchan = 1; char chan_copy[20]; if (!*str) { if (p->zchannel[0]) { ENDSTACK("<(%s)> -- %s leaves this channel --\n", p->zchannel, p->name); zwall(oldstack); stack = oldstack; p->zchannel[0] = '\0'; } else tell_player(p, " Format: zc <channel name to join or create>\n"); return; } if (strlen(str) < 3 || strlen(str) > 14) { tell_player(p, "Z Channel names must be between 3 and 14 characters\n"); return; } for (check = str; *check; check++) { switch (*check) { case '^': tell_player(p, " You may not have colours in your channel name.\n"); return; case ' ': tell_player(p, " You may not have spaces in your channel name.\n"); return; case ',': tell_player(p, " You may not have commas in your channel name.\n"); return; case '{': case '}': case '*': case '<': case '>': case '[': case ']': TELLPLAYER(p, " You may not have %c in your channel name.\n", *check); return; case '(': tell_player(p, " You may not have brackets in your channel name.\n"); return; case ')': tell_player(p, " You may not have brackets in your channel name.\n"); return; } } if (!strcasecmp(str, p->zchannel)) { tell_player(p, "Erm, you're already on that channel!\n"); return; } /* Makes a copy of the channel name, converts it into lower case and does all the necessary checks. This means that ststr can pick up on reserved names and people don't moan becuase they can't use mixed case channel names -- Silver */ strcpy(chan_copy, str); /* copy it */ lower_case(chan_copy); /* convert it all to lower case */ /* Here you need to enter the name of any channel names you DONT want people to use */ if (strstr(chan_copy, "channel") || strstr(chan_copy, "spod") || strstr(chan_copy, "admin") || strstr(chan_copy, "su")) { tell_player(p, " Sorry but that channel name is reserved.\n"); return; } if (p->zchannel[0]) { ENDSTACK("<(%s)> -- %s leaves this channel --\n", p->zchannel, p->name); zwall(oldstack); stack = oldstack; } for (scan = flatlist_start; scan; scan = scan->flat_next) if (!strcasecmp(scan->zchannel, str) && scan->location) { strcpy(p->zchannel, scan->zchannel); newchan = 0; } if (newchan == 1) strcpy(p->zchannel, str); if (newchan) ENDSTACK("<(%s)> ++ %s creates and joins this channel ++\n", p->zchannel, p->name); else ENDSTACK("<(%s)> ++ %s joins this channel ++\n", p->zchannel, p->name); zwall(oldstack); stack = oldstack; LOGF("channel", "%s creates a zchannel called '%s'", p->name, str); } void lsz(player * p, char *str) { char *oldstack; player *scan, *scan2; int count = 0; int noz = 0; oldstack = stack; pstack_mid("Active Z-Channels"); ADDSTACK("\nZ Channel Name Number of people Idle Time\n"); for (scan = flatlist_start; scan; scan = scan->flat_next) scan->zchannellisted = 0; for (scan = flatlist_start; scan; scan = scan->flat_next) { if (strlen(scan->zchannel) > 0 && scan->zchannellisted != 1) { count = 0; for (scan2 = flatlist_start; scan2; scan2 = scan2->flat_next) { if (!strcasecmp(scan2->zchannel, scan->zchannel)) { count++; scan2->zchannellisted = 1; } } if (count > 0) { ADDSTACK("%-30s %d (%2d:%.2d idle)\n", scan->zchannel, count, scan->zcidle / 60, scan->zcidle % 60); noz++; } } } if (noz == 0) { tell_player(p, " There are no Z Channels currently active\n"); stack = oldstack; return; } ENDSTACK("\n" LINE); tell_player(p, oldstack); stack = oldstack; } /* zw, cw and pw commands */ void z_who(player * p, char *str) { char *oldstack = stack; char top[70]; if (!is_on_zchannel(p)) /* blimey */ return; sprintf(top, "People listening to zchannel '%s'", p->zchannel); pstack_mid(top); who_on_chan(p, 1); tell_player(p, oldstack); stack = oldstack; } void m_who(player * p, char *str) { char *oldstack = stack; pstack_mid("People listening to the main channel"); who_on_chan(p, 2); tell_player(p, oldstack); stack = oldstack; } void a_who(player * p, char *str) { char *oldstack = stack; char midder[160]; sprintf(midder, "People listening to the %s channel", get_config_msg("admin_name")); pstack_mid(midder); who_on_chan(p, 3); tell_player(p, oldstack); stack = oldstack; } void s_who(player * p, char *str) { char *oldstack = stack; char midder[160]; sprintf(midder, "People listening to the %s channel", get_config_msg("su_name")); pstack_mid(midder); who_on_chan(p, 4); tell_player(p, oldstack); stack = oldstack; } void p_who(player * p, char *str) { char *oldstack = stack; pstack_mid("People listening to the spod channel"); who_on_chan(p, 5); tell_player(p, oldstack); stack = oldstack; } #ifdef HC_CHANNEL void h_who(player * p, char *str) { char *oldstack = stack; char midder[160]; sprintf(midder, "People listening to the %s channel", get_config_msg("hc_name")); pstack_mid(midder); who_on_chan(p, 6); tell_player(p, oldstack); stack = oldstack; } #endif void who_on_chan(player * p, int chan) { player *scan; int flag = 0; sprintf(stack, "\n"); stack = strchr(stack, 0); for (scan = flatlist_start; scan; scan = scan->flat_next) { if (scan->residency && scan->location) { flag = 0; if (chan == 1 && !strcasecmp(p->zchannel, scan->zchannel)) flag = 1; if (chan == 2 && !(scan->misc_flags & NO_MAIN_CHANNEL)) flag = 1; if (chan == 3 && !(scan->flags & BLOCK_SU) && (scan->residency & LOWER_ADMIN)) flag = 1; if (chan == 4 && (!(scan->flags & BLOCK_SU)) && scan->residency & PSU) flag = 1; if (chan == 5 && (scan->residency & SPOD) && !(scan->misc_flags & NO_SPOD_CHANNEL)) flag = 1; #ifdef HC_CHANNEL if (chan == 6 && (!(scan->flags & BLOCK_SU)) && scan->residency & HCADMIN) flag = 1; #endif if (flag) { sprintf(stack, "%s ", scan->name); stack = strchr(stack, 0); } } } sprintf(stack, "\n\n" LINE); stack = end_string(stack); } /* Superuser channel deletion */ void zdel(player * p, char *str) { char *oldstack = stack; char *reason; player *scan; int found = 0; if (!(reason = strchr(str, ' '))) { tell_player(p, " Format: zdel <channel name> <reason>\n" " Reason is logged and also sent to that channel!\n"); return; } *reason++ = 0; for (scan = flatlist_start; scan; scan = scan->flat_next) if (!strcasecmp(scan->zchannel, str) && scan->location) { sprintf(stack, "<(%s)> -- %s is destroying this channel. Reason: %s --\n", scan->zchannel, p->name, reason); stack = end_string(stack); if (scan->misc_flags & CHAN_HI) command_type |= HIGHLIGHT; sys_color_atm = UCEsc; tell_player(scan, oldstack); sys_color_atm = SYSsc; if (scan->misc_flags & CHAN_HI) command_type &= ~HIGHLIGHT; stack = oldstack; strcpy(scan->zchannel, ""); found = 1; } if (found == 0) { tell_player(p, " That channel doesn't exist!\n"); return; } SW_BUT(p, " -=*> %s destroys the '%s' channel for the reason: %s\n", p->name, str, reason); tell_player(p, " Channel destroyed and reason logged\n"); LOGF("channel", "%s destroyed '%s'. Reason: %s", p->name, str, reason); } /* The muffle command */ void muffle(player * p, char *str) { char *oldstack = stack; player *p2 = p; char title[70]; if ((*str && p->residency & LOWER_ADMIN)) { p2 = find_player_global_quiet(str); if (p2) *str = 0; } if (!*str) { if (p2 != p) sprintf(title, "Muffle information for %s", p2->name); else sprintf(title, "Muffle information"); pstack_mid(title); ADDSTACK("\nMain channel "); if (p2->misc_flags & NO_MAIN_CHANNEL) ADDSTACK("<ignoring>\n"); else ADDSTACK("<listening>\n"); #ifdef INTERCOM ADDSTACK("Intercom channel "); if (p2->misc_flags & NO_INTERCOM_CHANNEL) ADDSTACK("<ignoring>\n"); else ADDSTACK("<listening>\n"); #endif if (p2->residency & SPOD) { ADDSTACK("Spod channel "); if (p2->misc_flags & NO_SPOD_CHANNEL) ADDSTACK("<ignoring>\n"); else ADDSTACK("<listening>\n"); } ADDSTACK("Sessions "); if (p2->custom_flags & YES_SESSION) ADDSTACK("<off>\n"); else ADDSTACK("<on>\n"); ADDSTACK("Clock "); if (p2->custom_flags & NO_CLOCK) ADDSTACK("<off>\n"); else ADDSTACK("<on>\n"); ADDSTACK("Dynatext "); if (p2->custom_flags & NO_DYNATEXT) ADDSTACK("<ignoring>\n"); else ADDSTACK("<seeing>\n"); if (p2->residency & DEBUG) { ADDSTACK("Debug channel "); if (p2->misc_flags & SEE_DEBUG_CHANNEL) ADDSTACK("<listening>\n"); else ADDSTACK("<ignoring>\n"); } ENDSTACK("\n" LINE); tell_player(p, oldstack); stack = oldstack; return; } if (strstr(str, "mai")) channel_toggle(p, cu_chan, NO_MAIN_CHANNEL); /* blimey */ #ifdef INTERCOM else if (strstr(str, "int") || strstr(str, "ich")) channel_toggle(p, i_chan, NO_INTERCOM_CHANNEL); /* Silver */ #endif else if (strstr(str, "spo") && p->residency & SPOD) channel_toggle(p, pu_chan, NO_SPOD_CHANNEL); /* blimey */ else if (strstr(str, "ses")) set_yes_session(p, ""); else if (strstr(str, "clo")) toggle_view_clock(p, ""); else if (strstr(str, "dyn")) toggle_yes_dynatext(p, ""); else if (strstr(str, "deb") && p->residency & DEBUG) toggle_debug_channel(p, ""); else { tell_player(p, " Format: muffle <section>\n" " Where section can be: main"); if (p->residency & SPOD) tell_player(p, ", spod"); if (p->residency & DEBUG) tell_player(p, ", debug"); tell_player(p, ", session, clock, dynatext\n"); } } /* Version information */ void channel_version() { sprintf(stack, " -=*> Channel code v2.0 (by Silver and blimey) installed.\n"); stack = strchr(stack, 0); } #ifdef INTERCOM #include "channel2.c" #endif