// File : /std/body.c // // This file contains the code common to all player bodies. It is inherited // by ghost.c, the ghost body, and living.c, which is the file containing // the code common to the monster body and the player body. // This file was created 3-10-93 by Mobydick@TMI-2, in conjunction with // Watcher@TMI-2 as part of creating the new bodies system, which in turn // was made possible by the work on login.c done by Buddha@TMI-2 in // January 1993. // // All of the functions in this file were in the original user.c found // at TMI-2 before the bodies project was launched. Its documentation is // as follows: // Original Authors: Sulam and Buddha @ The Mud Institute // Many other people have added to this as well. // This file has a long revision history dating back to the // hideous mudlib.n and is now probably not at all the same. // // This file is a part of the TMI-2 distribution mudlib. // Please keep this header with any code within. #include <config.h> #include <mudlib.h> #include <daemons.h> #include <net/daemons.h> #include <body.h> #include <logs.h> #include <priv.h> #include <uid.h> #include <move.h> #include <commands.h> #include <messages.h> inherit "/std/body/attack.c" ; inherit "/std/body/track.c" ; inherit "/std/body/alias.c" ; inherit "/std/body/wild_card.c" ; inherit "/std/body/more.c" ; // Rust changed this from static to nomask // 3-2-94 static nomask object link ; private string __Term; static private mapping __TermInfo; // Prototypes. The important one is the user/nonuser recognition function. //void save_data() ; void set_term(string str); string query_term(); void basic_commands() ; mixed query_env (string env); static void init_commands(); // Connection link support functions nomask object query_link() { return link; } void set_link(object ob) { if (geteuid(previous_object()) != ROOT_UID && base_name(previous_object()) != CONNECTION) return; link = ob; } // Inspiral made this nomask on 94 - 02 - 25 // hope this doesn't break things. nomask mixed link_data(string what) { if (!link) return 0; return (mixed)link->query(what); } // User debug function void debug(string mess) { #ifdef DEBUG message(MSG_DEBUG, mess, this_player()); #endif } // This function switchs the user from its present body to // that of a ghost when they "die". static object create_ghost() { object ghost, old; // First confirm the body has a link if(!link) return 0; ghost = new(GHOST); old = environment(this_object()); link->set("dead", 1); link->set("tmp_body", ghost); if(!link->switch_body()) { message(MSG_SYSTEM, "Error in the ghost body transfer. Please inform an Admin.\n", this_player()); return 0; } ghost->set("name", link_data("name") ); ghost->init_setup(); ghost->setup_ghost(); link = 0; #ifdef GHOST_START_LOCATION if(catch(call_other(GHOST_START_LOCATION, "???")) || catch(ghost->move(GHOST_START_LOCATION) != MOVE_OK)) ghost->move(START); #else ghost->move(environment()); #endif if(environment(ghost) != old) tell_room(environment(ghost), "The ghost of " + (string)ghost->query("cap_name") + " shimmers " + "into sight.\n", ({ ghost })); return ghost; } // The force hook. int force_me(string cmd) { string tmp, verb; int res; if (previous_object()) tmp = geteuid(previous_object()) ; else tmp = geteuid(this_object()) ; if(tmp != ROOT_UID && tmp != geteuid(this_object())) return 0; // Process command for aliases/nicknames/etc if(interactive(this_object())) cmd = (string)this_object()->process_input(cmd); verb = explode(cmd, " ")[0]; // Check to make sure the force is not an illegal force. If so, // block it and notify all the parties of the foul deed. if(BAD_FORCE_VERBS && member_array(verb, BAD_FORCE_VERBS) != -1) { message(MSG_SYSTEM, (string)this_player()->query("cap_name") + " using " + identify(previous_object()) + " tried to force you to " + cmd + ".\n", this_object()); message(MSG_SYSTEM, "Illegal force attempt blocked and noted.\n", this_player()); #ifdef BAD_FORCE log_file(BAD_FORCE, wrap((string)this_player()->query("cap_name") + " using " + identify(previous_object()) + " tried to force " + (string)query("cap_name") + " to " + cmd + " [" + extract(ctime(time()),4,15) + "]\n")); #endif return 0; } res = command(cmd); return res; } // This function initializes the body shell prior to transfer // of the user connection. void init_setup() { // Set object's living name for hash table set_living_name( query("name") ); // Set user's euid permissions seteuid( getuid(this_object()) ); // Start this user's heartbeat set_heart_beat(1); // Set user object's id and ip properties set( "id", ({ query("name") }) ); set( "ip", query_ip_name(this_object()) ); // Enable wizard status if user fulfills prerequisites if(link && (int)(link -> query("wizard"))){ set("wizard", 1, MASTER_ONLY); enable_wizard(); } else set("wizard", 0, MASTER_ONLY); // Enable basic user commands defined in specific body basic_commands(); // Initialize body's standard command catch init_commands(); // Setup user's autosave call system #ifdef AUTOSAVE call_out("autosave_user", AUTOSAVE); #endif // Setup important body system presents. set("volume", 500) ; set ("capacity", 5000-(int)this_object()->coins_carried()) ; // Reset the weapon and armor defaults set ("weapon1",0) ; set ("weapon2",0) ; set ("armor", ([]) ) ; // Retrieve autoload requests this_object()->load_autoload_obj(); // Initialize the tsh system here so all bodies get it call_out("initialize_tsh", 0); // Setup the message buffer system ... make sure its OWNER_ONLY set("message_buffer", "", OWNER_ONLY); set("buffer_flag", 0, READ_ONLY); } void enable_me() { if (geteuid(previous_object()) != ROOT_UID) return ; enable_wizard() ; } nomask void disable_me() { if (previous_object() == find_object(CMD_DEWIZ)) disable_wizard() ; } void receive_message(string Class, string msg) { object shell; string foo ; int htime; // Invisibility screen. This should catch all tells and says and so forth, // and all soul commands, and most command messages. if (this_player() && this_object() != this_player()) { if((int)this_player()->query("invisible") == 1 && !wizardp(this_object())) return; if((int)this_player()->query("invisible") == 2 && !adminp(geteuid(this_object()))) return; } // If this_object() is a monster, pass the message so // aggressive monsters can react to certain messages. if((int)query("npc")) this_object()->relay_message(Class, msg); // If the player is being harassed, then the "harass" flag will be // set by the "harass" command, and everything will be logged to a // file until the flag is disabled. if ((htime = (int)query("harass")) && htime > 0) { if (htime < time()) { set("harass", 0); receive_message("write", "What you see is no longer being logged.\n"); log_file(HARASS_DIR+"/"+ geteuid(), "Harass Log stopped: " + ctime(time()) + "\n========================================\n"); } else log_file(HARASS_DIR+"/" + geteuid(), msg ); } // Message buffering system when user is busy (ie: writing notes) // We are applying the message directly to the mapping because we // want all messages to be stored there (regardless of source), // which would normally be blocked by the OWNER_ONLY security. #ifdef MESSAGE_BUFFER if(query_env("enable_buffer") && query("buffer_flag") && Class != "write") { ob_data["message_buffer"] = ob_data["message_buffer"] + msg; return; } #endif // Mudlib support for user environment shell shell = present("shell", this_object()); if(shell && previous_object() != shell && base_name(shell) + ".c" == (string)query("shell")) { shell->receive_message(Class, msg); } else { /* This will strip ANSI sequences. You may worship Mobydick. */ if (query_env("STRIP_ANSI")) { msg = TERMINAL_D->filter_colours(msg) ; receive(msg) ; return ; } /* Terminal stuff added by Descartes of Borg 940520 */ if(Class == "system" || Class == "help" || strsrch(msg,"%^") == -1) receive(msg); else { string *words; int i; if(!__TermInfo) __TermInfo = (mapping)TERMINAL_D->query_term_info(query_term()); i = sizeof(words = explode(msg, "%^")); while(i--) if(__TermInfo[words[i]]) words[i] = __TermInfo[words[i]]; receive(sprintf("%s%s", implode(words, ""), __TermInfo["RESET"])); } } } // This function dumps the contents of the MESSAGE_BUFFER to the user's // more pager for output. #ifdef MESSAGE_BUFFER int dump_buffer() { string *dump, output; if(geteuid(previous_object()) != geteuid(this_object())) return 0; output = query("message_buffer"); set("buffer_flag", 0); if(!output || output == "") return 0; dump = ({ "\n" + bold("[Queued message buffer output]") }) + explode(output, "\n"); this_object()->more(dump); set("message_buffer", ""); return 1; } #endif // This is a new apply in MudOS 0.9.16.18. If a wizard is snooping a // player, then the snooped messages are passed to this function. // We either pass it off to a mudlib shell, or receive it as normal. void receive_snoop (string str) { object shell; // replace_string(str, ESC, " "); // This disables the escape code. // Mudlib support for user environment shell shell = present("shell", this_object()); if(shell && previous_object() != shell && base_name(shell) + ".c" == (string)query("shell")) shell->receive_message("snoop", "% " + str); else receive("% " + str); } void net_dead() { if (userp(this_object())) { message(MSG_SYSTEM, "Body.c netdead() called save_data\n", this_player()); this_object()->save_data(); } message(MSG_MOVEMENT, (string)query("cap_name") + " has gone net-dead.\n", environment(), this_object()); ANNOUNCE->announce_user(this_object(), 3); // CMWHO_D->remove_user(this_object()); set_heart_beat(0); #ifdef NETDEAD_LOG log_file(NETDEAD_LOG, query("cap_name") + ": net-dead\t\t" + ctime(time()) + " from " + query("ip") + "\n"); #endif link->remove(); } void restart_heart() { message(MSG_MOVEMENT, query("cap_name")+" has reconnected.\n", environment(), this_object()); message(MSG_MOVEMENT, "Reconnected.\n", this_object()); ANNOUNCE->announce_user(this_object(), 2); set_heart_beat(1); } string local_commands() { mixed *cmds; int i; string result; if(geteuid(previous_object()) != ROOT_UID && !adminp(geteuid(previous_object()))) return "You aren't authorized to check this information.\n"; cmds = commands(); if (!sizeof(cmds)) return "No commands available"; result = ""; while (i < sizeof(cmds)) { result += (cmds[i][0] + " "); i++; } return result + "\n"; } mixed *user_commands() { return commands(); } // this is here in case someone inherits this object and doesn't // define save_data() - the driver doesn't like the results at all // // Actually, the new drivers with fixed inheritance chokes on it, // so I commented it out again. See Changelogs of v20.18 and onwards // Leto 112594 //void save_data() { ; } void set_term(string str) { __TermInfo = (mapping)TERMINAL_D->query_term_info(__Term = str); } string query_term() { return __Term; }