/* Do not remove the headers from this file! see /USAGE for more info. */ /* ** channel.c -- intermud channel processing ** ** 95-May-15. Deathblade. Created. ** July 5, 1997: Midhir@Mutants and Machinery added some ** channel listening/ignoring capabilities. */ #include <daemons.h> #include <security.h> #define PRIV_REQUIRED "Mudlib:daemons" nosave private int filter_msg; private int chanlist_id; private mapping chanlist = ([ ]); string* listened_channels = ({}); void send_to_all(string type, mixed * message); void send_to_user(string type, string mudname, string username, mixed * message); void send_to_router(string type, mixed * message); void send_to_mud(string type, string mudname, mixed * message); void return_error(string mudname, string username, string errcode, string errmsg); void add_cache_entry(string mudname, string username, string visname, int gender); string get_visname( string mudname, string username ); string canon_mudname(string mudname); protected nomask int query_chanlist_id() { return chanlist_id; } nomask void channel_rcv_data(string channel_name, string sender_name, string type, mixed data) { if ( filter_msg ) { filter_msg = 0; return; } channel_name = channel_name[5..]; // skip "imud_" switch ( type ) { case "tell": send_to_all("channel-m", ({ channel_name, sender_name, data })); break; case "emote": if ( !strlen( data ) ) break; data = sprintf("$N %s", data); send_to_all("channel-e", ({ channel_name, sender_name, data })); break; case "soul": //### need to work on using channel-t appropriately if ( sizeof( data[0] ) != 2 ) { data = data[<1][<1]; if ( data[<1] == '\n' ) data = data[0..<2]; send_to_all("channel-e", ({ channel_name, sender_name, data })); } else { string target_mud = data[0][1]->query_mud_name() || mud_name(); string target_name = data[0][1]->query_userid(); string all_mess = data[<1][<1]; string targ_mess = data[<1][1]; if ( all_mess[<1] == '\n' ) all_mess = all_mess[0..<2]; if ( targ_mess[<1] == '\n' ) targ_mess = targ_mess[0..<2]; send_to_all("channel-t", ({ channel_name, target_mud, // Target mud target_name, // Target name all_mess, // Message to all targ_mess, // Target message data[0][0]->query_name(), // Sender name get_visname( target_mud, target_name ) || capitalize( target_name ) }) ); } break; } } protected nomask void rcv_chanlist_reply(string orig_mud, string orig_user, string targ_user, mixed * message) { string channel_name; mixed channel_data; string array added_channels = keys(message[1]) - keys(chanlist); string array removed_channels = keys(chanlist) - keys(message[1]); chanlist_id = message[0]; chanlist = message[1]; foreach(channel_name in removed_channels) { string int_name = "imud_" + channel_name; CHANNEL_D->unregister_channels(({ int_name })); } foreach(channel_name in keys(message[1])) { string int_name = "imud_" + channel_name; CHANNEL_D->register_channels(({ int_name })); } chanlist = message[1]; } protected nomask void rcv_chan_who_req(string orig_mud, string orig_user, string targ_user, mixed * message) { object * listeners = CHANNEL_D->query_listeners("imud_" + message[0]); if ( !listeners ) { return_error(orig_mud, orig_user, "unk-channel", sprintf("Never heard of '%s'", message[0])); } else { listeners -= ({ 0, this_object() }); listeners = filter(listeners, (: userp($1) :) ); send_to_user("chan-who-reply", orig_mud, orig_user, ({ message[0], listeners->query_body()->query_name() })); } } protected nomask void rcv_chan_who_reply(string orig_mud, string orig_user, string targ_user, mixed * message) { object p; p = find_user(targ_user); if ( !p ) { return_error(orig_mud, orig_user, "unk-user", sprintf("'%s' is unknown", targ_user)); } else { tell(p, sprintf("%s@%s listeners: ", message[0], orig_mud) + implode(message[1], ", ") + ".\n"); } } string query_userid() { return "limabean"; } protected nomask void rcv_channel_m(string orig_mud, string orig_user, string targ_user, mixed * message) { if ( orig_mud == mud_name() ) return; filter_msg = 1; CHANNEL_D->deliver_tell("imud_" + message[0], sprintf("%s@%s", message[1], orig_mud), message[2]); } protected nomask void rcv_channel_e(string orig_mud, string orig_user, string targ_user, mixed * message) { if ( orig_mud == mud_name() ) return; if ( sizeof(message) != 3 ) { return_error(orig_mud, orig_user, "bad-pkt", "Bad channel-e format. Report to your admin."); return; } /* ** NOTE: we don't need to set filter_msg here. The deliver_channel() ** message will not pass these back to us. Only the tell/emote/soul ** will pass the data through to us. */ CHANNEL_D->deliver_channel("imud_" + message[0], replace_string(message[2], "$N", sprintf("%s@%s", message[1], orig_mud))); } protected nomask void rcv_channel_t(string orig_mud, string orig_user, string targ_user, mixed * message) { string orig_name,targ_name; string targ_mess, all_mess; if ( mud_name() == orig_mud) return ; orig_name = message[5] + "@" + orig_mud; all_mess = replace_string( message[3]+"\n","$N", orig_name ); if ( mud_name() == message[1] ) { object targ_ob = find_body( lower_case( message[2] ) ); targ_name = message[6]; if ( targ_ob ) { targ_mess = replace_string( message[4]+"\n","$N", orig_name ); all_mess = replace_string( all_mess, "$O", targ_name ); filter_msg = 1; CHANNEL_D->deliver_soul( "imud_"+message[0], ({ ({ targ_ob }), ({ targ_mess, all_mess }) }) ); return ; } } else targ_name = message[6] + "@" + message[1]; all_mess = replace_string( all_mess, "$O", targ_name ); CHANNEL_D->deliver_channel( "imud_"+message[0], all_mess ); } protected nomask void rcv_chan_user_req(string orig_mud, string orig_user, string target_user, mixed * message) { object p; p = find_body(message[0]); if ( !p ) { return_error(orig_mud, orig_user, "unk-user", sprintf("'%s' is unknown", message[0])); } else { int gender = p->query_gender(); /* map to I3's concept of gender: male(0), female(1), neuter(2) ours is: neuter(0), male(1), female(2) */ gender = (gender + 2) % 3; /* Lima -> I3 */ send_to_mud("chan-user-reply", orig_mud, ({ message[0], p->query_name(), gender })); } } protected nomask void rcv_chan_user_reply(string orig_mud, string orig_user, string target_user, mixed * message) { int gender = (message[2] + 1) % 3; /* I3 -> Lima */ add_cache_entry(orig_mud, message[0], message[1], gender); /* ### do rest of emote now... */ } //FUNCITON: chan_startup //Register the channels that we listen to with CHANNEL_D protected nomask void chan_startup() { CHANNEL_D->register_channels(map_array(listened_channels, (: "imud_" + $1 :))); } protected nomask void chan_shutdown() { CHANNEL_D->unregister_channels(); } nomask mapping query_chanlist() { return copy(chanlist); } nomask void add_channel(string channel_name, int channel_type) { // if ( !check_privilege(PRIV_REQUIRED) ) // error("security: illegal attempt to create an owned intermud channel\n"); send_to_router("channel-add", ({ channel_name, channel_type })); } nomask void remove_channel(string channel_name) { // if ( !check_privilege(PRIV_REQUIRED) ) // error("security: illegal attempt to remove an owned intermud channel\n"); send_to_router("channel-remove", ({ channel_name })); } nomask void remote_listeners(string mudname, string channel_name) { send_to_mud("chan-who-req", canon_mudname(mudname), ({ channel_name })); } nomask void listen_to_channel(string channel_name) { // if(this_user()) { // if ( !check_privilege(PRIV_REQUIRED) ) // error("security: illegal attempt to add a listened intermud channel\n"); // } if (member_array(channel_name, listened_channels) == -1) listened_channels += ({ channel_name }); send_to_router("channel-listen", ({ channel_name, 1 })); } nomask void ignore_channel(string channel_name) { // if ( !check_privilege(PRIV_REQUIRED) ) // error("security: illegal attempt to remove a listened intermud channel\n"); if (member_array(channel_name, listened_channels) != -1) listened_channels -= ({ channel_name }); send_to_router("channel-listen", ({ channel_name, 0 })); } nomask void ban_mud(string chan, string mud) { if ( !check_privilege(PRIV_REQUIRED) ) error("security: illegal attempt to administer an intermud channel\n"); send_to_router("channel-admin", ({ chan, ({}), ({ mud })})); } nomask void relisten_all_channels() { foreach (string str in listened_channels) listen_to_channel(str); return; } nomask void listen_to_all_channels() { foreach (string str in keys(this_object()->query_chanlist())) { listen_to_channel(str); listened_channels += ({ str }); continue; } } nomask string *query_listened_channels() { return copy(listened_channels); }