lima-1.0b5/
lima-1.0b5/driver/
lima-1.0b5/driver/ChangeLog.old/
lima-1.0b5/driver/Win32/
lima-1.0b5/driver/compat/
lima-1.0b5/driver/include/
lima-1.0b5/driver/testsuite/
lima-1.0b5/driver/testsuite/clone/
lima-1.0b5/driver/testsuite/command/
lima-1.0b5/driver/testsuite/data/
lima-1.0b5/driver/testsuite/etc/
lima-1.0b5/driver/testsuite/include/
lima-1.0b5/driver/testsuite/inherit/
lima-1.0b5/driver/testsuite/inherit/master/
lima-1.0b5/driver/testsuite/log/
lima-1.0b5/driver/testsuite/single/
lima-1.0b5/driver/testsuite/single/tests/compiler/
lima-1.0b5/driver/testsuite/single/tests/efuns/
lima-1.0b5/driver/testsuite/single/tests/operators/
lima-1.0b5/driver/testsuite/u/
lima-1.0b5/driver/tmp/
lima-1.0b5/etc/
lima-1.0b5/lib/WWW/help/
lima-1.0b5/lib/cmds/
lima-1.0b5/lib/cmds/create/
lima-1.0b5/lib/cmds/player/attic/
lima-1.0b5/lib/contrib/bboard/
lima-1.0b5/lib/contrib/boards/
lima-1.0b5/lib/contrib/marriage/
lima-1.0b5/lib/contrib/roommaker/
lima-1.0b5/lib/contrib/transient_effect/
lima-1.0b5/lib/daemons/channel/
lima-1.0b5/lib/daemons/imud/
lima-1.0b5/lib/data/
lima-1.0b5/lib/data/config/
lima-1.0b5/lib/data/links/
lima-1.0b5/lib/data/news/
lima-1.0b5/lib/data/players/
lima-1.0b5/lib/data/secure/
lima-1.0b5/lib/domains/
lima-1.0b5/lib/domains/std/2.4.5/maze1/
lima-1.0b5/lib/domains/std/2.4.5/npc/
lima-1.0b5/lib/domains/std/2.4.5/post_dir/
lima-1.0b5/lib/domains/std/2.4.5/sub/
lima-1.0b5/lib/domains/std/camera/
lima-1.0b5/lib/domains/std/config/
lima-1.0b5/lib/domains/std/cult/
lima-1.0b5/lib/domains/std/effects/
lima-1.0b5/lib/domains/std/misc/
lima-1.0b5/lib/domains/std/monsters/
lima-1.0b5/lib/domains/std/recorder/
lima-1.0b5/lib/domains/std/rooms/
lima-1.0b5/lib/domains/std/rooms/beach/
lima-1.0b5/lib/domains/std/rooms/labyrinth/
lima-1.0b5/lib/domains/std/school/
lima-1.0b5/lib/domains/std/school/O/
lima-1.0b5/lib/domains/std/spells/
lima-1.0b5/lib/domains/std/spells/stock-mage/
lima-1.0b5/lib/domains/std/spells/stock-priest/
lima-1.0b5/lib/help/
lima-1.0b5/lib/help/admin/
lima-1.0b5/lib/help/hints/General_Questions/
lima-1.0b5/lib/help/hints/Pirate_Quest/
lima-1.0b5/lib/help/player/
lima-1.0b5/lib/help/player/bin/
lima-1.0b5/lib/help/player/quests/
lima-1.0b5/lib/help/wizard/
lima-1.0b5/lib/help/wizard/coding/guilds/
lima-1.0b5/lib/help/wizard/coding/rooms/
lima-1.0b5/lib/help/wizard/lib/daemons/
lima-1.0b5/lib/help/wizard/lib/lfun/
lima-1.0b5/lib/help/wizard/lib/std/
lima-1.0b5/lib/help/wizard/mudos_doc/
lima-1.0b5/lib/help/wizard/mudos_doc/applies/
lima-1.0b5/lib/help/wizard/mudos_doc/applies/interactive/
lima-1.0b5/lib/help/wizard/mudos_doc/applies/parsing/
lima-1.0b5/lib/help/wizard/mudos_doc/concepts/
lima-1.0b5/lib/help/wizard/mudos_doc/driver/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/arrays/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/buffers/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/compile/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/filesystem/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/floats/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/functions/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/general/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/mappings/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/mixed/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/numbers/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/parsing/
lima-1.0b5/lib/help/wizard/mudos_doc/lpc/constructs/
lima-1.0b5/lib/help/wizard/mudos_doc/lpc/types/
lima-1.0b5/lib/include/driver/
lima-1.0b5/lib/log/
lima-1.0b5/lib/obj/admtool/
lima-1.0b5/lib/obj/admtool/internal/
lima-1.0b5/lib/obj/admtool/mudinfo/
lima-1.0b5/lib/obj/admtool/secure/
lima-1.0b5/lib/obj/secure/
lima-1.0b5/lib/obj/secure/cmd/
lima-1.0b5/lib/obj/secure/mailers/
lima-1.0b5/lib/obj/secure/shell/
lima-1.0b5/lib/obj/secure/shell/classes/
lima-1.0b5/lib/obj/tasktool/
lima-1.0b5/lib/obj/tasktool/internal/
lima-1.0b5/lib/open/
lima-1.0b5/lib/secure/
lima-1.0b5/lib/secure/cgi/
lima-1.0b5/lib/secure/modules/
lima-1.0b5/lib/secure/simul_efun/
lima-1.0b5/lib/std/adversary/
lima-1.0b5/lib/std/adversary/advancement/
lima-1.0b5/lib/std/adversary/armor/
lima-1.0b5/lib/std/adversary/blows/
lima-1.0b5/lib/std/adversary/death/
lima-1.0b5/lib/std/adversary/formula/
lima-1.0b5/lib/std/adversary/health/
lima-1.0b5/lib/std/adversary/pulse/
lima-1.0b5/lib/std/adversary/wield/
lima-1.0b5/lib/std/classes/event_info/
lima-1.0b5/lib/std/container/
lima-1.0b5/lib/std/living/
lima-1.0b5/lib/std/modules/contrib/
lima-1.0b5/lib/std/patterns/
lima-1.0b5/lib/std/race/
lima-1.0b5/lib/std/race/restricted/
lima-1.0b5/lib/std/room/
lima-1.0b5/lib/tmp/
lima-1.0b5/lib/trans/
lima-1.0b5/lib/trans/admincmds/
lima-1.0b5/lib/trans/obj/
lima-1.0b5/lib/wiz/
/* Do not remove the headers from this file! see /USAGE for more info. */

/*
** channel/cmd.c
**
** Part of the CHANNEL_D to handle channel command processing.
*/

#include <classes.h>
#include <channel.h>

inherit CLASS_CHANNEL_INFO;

void create_channel(string channel_name);
class channel_info query_channel_info(string channel_name);
string user_channel_name(string channel_name);
void test_for_purge(string channel_name);

void set_permanent(string channel_name, int is_perm);
void set_flags(string channel_name, int flags);

void deliver_emote(string channel_name,
  string sender_name,
  string message);
void deliver_tell(string channel_name,
  string sender_name,
  string message);
void deliver_soul(string channel_name, mixed * soul);

string make_name_list(mixed * list);

int cmd_moderation(string channel_name, string arg);
void moderation_signoff(string channel_name);
void print_mod_info(string channel_name);


/*
** cmd_channel()
**
** Standard channel processing command for player input.  Most channel-
** oriented systems will use this to get standardized channel manipulation.
**
** channel_type is:
**	0 normal
**	1 intermud
*/
varargs nomask void cmd_channel(string channel_name, string arg,
  int channel_type)
{
    class channel_info ci = query_channel_info(channel_name);
    object user=this_user();
    int listening;
    string user_channel_name;
    string sender_name;

    listening = member_array(channel_name, user->query_channel_list()) != -1;
    user_channel_name = user_channel_name(channel_name);

    if ( !arg || arg == "" )
    {
	if ( listening )
	{
	    printf("You are presently listening to '%s'.\n", user_channel_name);
	    print_mod_info(channel_name);
	}
	else
	{
	    printf("You are not listening to '%s'.\n", user_channel_name);
	}

	return;
    }

    if ( arg[0..3] == "/new" )
    {
	string * options = explode(arg[4..], " ");

	if ( ci )
	{
	    if ( sizeof(options) )
		printf("'%s' already exists; modifying options...\n",
		  user_channel_name);
	    else
		printf("'%s' already exists.\n", user_channel_name);
	}
	else
	{
	    create_channel(channel_name);
	    printf("'%s' has been created.\n", user_channel_name);
	}

	ci = query_channel_info(channel_name);

	foreach ( string option in options )
	{
	    switch ( option )
	    {
	    case "admin":
		if ( !adminp(user) )
		{
		    printf("Only admins can create admin channels.\n");
		    return;
		}
		set_flags(channel_name, CHANNEL_ADMIN_ONLY);
		printf("  --> only admins may tune in\n");
		break;

	    case "wiz":
	    case "wizard":
		/* ### need better security? */
		if ( (ci->flags & CHANNEL_ADMIN_ONLY) && !adminp(user) )
		{
		    printf("Only admins can turn off admin-only.\n");
		    return;
		}
		else if ( !wizardp(user) )
		{
		    printf("Only wizards can create wizard channels.\n");
		    return;
		}
		set_flags(channel_name, CHANNEL_WIZ_ONLY);
		printf("  --> only wizards may tune in\n");
		break;

	    case "permanent":
		/* ### need better security? */
		if ( !adminp(user) )
		{
		    printf("Only admins can tweak permanent channels.\n");
		    return;
		}
		set_permanent(channel_name, 1);
		printf("  --> the channel is permanent\n");
		break;

	    case "nopermanent":
	    case "goaway":
		/* ### need better security? */
		if ( !adminp(user) )
		{
		    printf("Only admins can tweak permanent channels.\n");
		    return;
		}
		set_permanent(channel_name, 0);
		printf("  --> the channel may now go away\n");
		test_for_purge(channel_name);
		break;
	    }
	}

	/* tune the channel in now */
	arg = "/on";
    }
    if ( arg == "/on" )
    {
	if ( listening )
	{
	    printf("You are already listening to '%s'.\n", user_channel_name);
	}
	else if ( !ci )
	{
	    printf("'%s' does not exist. Use /new to create it.\n",
	      user_channel_name);
	    return;
	}
	else
	{
	    /* enforce the channel restrictions now */
	    /* ### not super secure, but screw it :-) */
	    if ( (ci->flags & CHANNEL_WIZ_ONLY) && !wizardp(user) )
	    {
		printf("Sorry, but '%s' is for wizards only.\n",
		  user_channel_name);
		return;
	    }
        if ( (ci->flags & CHANNEL_ADMIN_ONLY) && !adminp(user) && member_array(user->query_userid(), SECURE_D->query_domain_members("admin-channels")) == -1)
	    {
		printf("Sorry, but '%s' is for admins only.\n",
		  user_channel_name);
		return;
	    }
	user->add_channel(channel_name);
	printf("You are now listening to '%s'.\n", user_channel_name);
	}
	
	print_mod_info(channel_name);
	
	return;
    }

    /*
    ** All the following "commands" need to have the player listening
    */
    if ( !listening )
    {
	printf( "You are not listening to %s.\n", channel_name );
	return;
    }

    sender_name = user->query_name();

    if ( arg == "/off" )
    {
	user->remove_channel(channel_name);
	printf("You are no longer listening to '%s'.\n", user_channel_name);

	moderation_signoff(channel_name);
    }
    else if ( arg == "/list" || arg == "/who" )
    {
	tell(user, sprintf("Users listening to '%s': %s.\n",
	    user_channel_name,
	    make_name_list(ci->listeners)), MSG_INDENT);
    }
    else if( arg == "/last" || arg == "/history" )
    {
	string history = implode(ci->history, "");

	if ( history == "" )
	    history = "<none>\n";

	more(sprintf("History of channel '%s':\n%s\n",
	    user_channel_name, history));
    }
    else if( arg == "/clear" )
    {
	if ( adminp(user) || user = ci->moderator )
	{
	    ci->history = ({});
	    write("Channel cleared.\n");
	}
	else
	    error("Illegal attempt to clear channel " +
		  user_channel_name + " by " +
		  capitalize(this_body()->query_userid()) + ".");
    }
    else if ( cmd_moderation(channel_name, arg) )
    {
	/* it was handled */
    }
    else if ( arg[0] == ';' || arg[0] == ':' )
    {
	if ( ci->moderator && ci->speaker &&
	  user != ci->moderator && user != ci->speaker )
	{
	    printf("You are not the speaker on '%s'.\n", user_channel_name);
	}
	else if ( channel_type == CHANNEL_TYPE_IMUD )
	{
	    mixed * soul;
	    string the_soul;

	    if (sscanf(arg[1..],"%s %*s",the_soul)!=2)
		the_soul=arg[1..];
	    if (SOUL_D->query_emote(the_soul))
		soul = SOUL_D->parse_imud_soul(arg[1..]);
	    if ( soul )
		deliver_soul(channel_name, soul);
	    else
		deliver_emote(channel_name, sender_name, arg[1..]);
	}
	else
	{
	    mixed * soul;
	    string the_soul;

	    if (sscanf(arg[1..],"%s %*s",the_soul)!=2)
		the_soul=arg[1..];
	    if (SOUL_D->query_emote(the_soul))
		soul = SOUL_D->parse_soul(arg[1..]);
	    if ( soul )
		deliver_soul(channel_name, soul);
	    else
		deliver_emote(channel_name, sender_name, arg[1..]);
	}
    }
    else
    {
	if ( ci->moderator && ci->speaker &&
	  user != ci->moderator && user != ci->speaker )
	{
	    printf("You are not the speaker on '%s'.\n", user_channel_name);
	}
	else
	{
	    deliver_tell(channel_name, sender_name, arg);
	}
    }
}