# include <config.h> # undef status # include <status.h> # include "/dgd/lib/privilege.h" object *usr; /* user array just before a swapout */ /* * NAME: load() * DESCRIPTION: load a castle */ private void load(string castle) { rlimits (MAXDEPTH; MAXTICKS) { call_other(castle, "???"); return; } } /* * NAME: initialize() * DESCRIPTION: called once at game startup */ static void initialize() { string *castles, castle, err; object *precomp; int i, sz, t; precomp = status()[ST_PRECOMPILED]; for (i = 0, sz = sizeof(precomp); i < sz; i++) { send_message("Precompiled: " + object_name(precomp[i]) + "\n"); } send_message("\nLoading init file room/init_file\n"); castles = explode(read_file("/room/init_file"), "\n"); for (i = 0, sz = sizeof(castles); i < sz; i++) { castle = castles[i]; if (strlen(castle) != 0 && castle[0] != '#') { send_message("Preloading: " + castle); t = time(); if (castle[strlen(castle) - 2 ..] == ".c") { castle = castle[0 .. strlen(castle) - 3]; } err = catch(load(castle)); if (err == 0) { send_message(" " + (time() - t) + ".0\n"); } else { send_message(err + "\n"); } } } send_message("Setting up ipc.\n"); } /* * NAME: set_users() * DESCRIPTION: keep a copy of the users array */ void set_users() { if (PRIVILEGED()) { usr = users(); } } /* * NAME: restored() * DESCRIPTION: re-initialize the system after a restore */ static void restored() { object *precomp; int i, sz; precomp = status()[ST_PRECOMPILED]; for (i = 0, sz = sizeof(precomp); i < sz; i++) { send_message("Precompiled: " + object_name(precomp[i]) + "\n"); } if (usr != 0) { for (i = 0, sz = sizeof(usr); i < sz; i++) { catch(usr[i]->force_close()); } } usr = 0; send_message("\nState restored.\nSetting up ipc.\n"); } /* * NAME: path_read() * DESCRIPTION: handle an editor read path */ string path_read(string path) { if (path != "" && path[0] != '/') { path = "/" + this_user()->query_player()->query_path() + "/" + path; } return this_user()->query_player()->valid_read(path); } /* * NAME: path_write() * DESCRIPTION: handle an editor write path */ string path_write(string path) { if (path != "" && path[0] != '/') { path = "/" + this_user()->query_player()->query_path() + "/" + path; } return this_user()->query_player()->valid_write(path); } /* * NAME: path_object() * DESCRIPTION: translate an object path */ string path_object(string path) { int i; if (sscanf(path, "../%*s") != 0 || sscanf(path, "%*s/../%*s") != 0) { error("Illegal path"); } if ((i=strlen(path)) >= 2 && path[i - 2 ..] == ".c") { return path[0 .. i - 3]; } return path; } /* * NAME: call_object() * DESCRIPTION: get the object to call with call_other */ static object call_object(string file) { object obj; file = path_object(file); obj = find_object(file); if (obj == 0) { obj = compile_object(file); } return obj; } /* * NAME: inherit_program() * DESCRIPTION: get an object to inherit */ static object inherit_program(string file, string path) { return call_object(path); } /* * NAME: path_include() * DESCRIPTION: translate an include path */ string path_include(string file, string path) { if (path[0] != '/') { return file + "/../" + path; } return path; } /* * NAME: remove_program() * DESCRIPTION: the last reference to a program is removed */ static void remove_program(string name) { } /* * NAME: recompile() * DESCRIPTION: (not) used to recompile objects */ static void recompile(object obj) { } /* * NAME: telnet_connect() * DESCRIPTION: return a player object */ static object telnet_connect() { object user, player; GLOBAL->set_this_player(0); user = find_object(USER); if (user == 0) { user = compile_object(USER); } user = clone_object(user); player = MASTER->connect(); user->set_player(player); player->_F_user(user); return user; } /* * NAME: binary_connect() * DESCRIPTION: return another player object (just to test) */ static object binary_connect() { object user, player; GLOBAL->set_this_player(0); user = find_object(USER); if (user == 0) { user = compile_object(USER); } user = clone_object(user); player = MASTER->connect(); user->set_player(player); player->_F_user(user); return user; } /* * NAME: runtime_error() * DESCRIPTION: log a runtime error */ static void runtime_error(string error, int caught) { mixed **trace; string progname, objname, function, str; int i, sz, line, len; object player; if (caught) { return; } send_message(error + "\n"); trace = call_trace(); if ((sz=sizeof(trace) - 1) != 0) { for (i = 0; i < sz; i++) { progname = trace[i][1]; function = trace[i][2]; if (progname == AUTO && strlen(function) > 3) { switch (function[0 .. 2]) { case "bad": progname = trace[i - 1][1]; function = trace[i - 1][2]; case "_F_": case "_Q_": continue; default: break; } } objname = trace[i][0]; line = trace[i][3]; if (line == 0) { str = " "; } else { str = " " + line; str = str[strlen(str) - 4 ..]; } str += " " + function + " "; len = strlen(function); if (len < 17) { str += " "[len ..]; } str += progname; if (progname != objname) { len = strlen(progname); if (len < strlen(objname) && progname == objname[.. len - 1]) { str += " (" + objname[len ..] + ")"; } else { str += " (" + objname + ")"; } } send_message(str + "\n"); } player = GLOBAL->query_this_player(); if (player != 0 && function_object("valid_player", player) == PLAYER && player->_Q_user() != 0) { if (player->query_level() < 21) { player->catch_tell("Your significant mind notices the fabric " + "of space.\n"); } else { player->catch_tell(error + "\nObject: " + objname + ", program: " + progname + ", line " + line + "\n"); } } } } /* * NAME: compile_error() * DESCRIPTION: deal with a compilation error */ void compile_error(string file, int line, string err) { string wizard; err = file + ", " + line + ": " + err + "\n"; send_message(err); if (sscanf(file, "/players/%s/", wizard) != 0) { write_file("/log/" + wizard, err); } else { write_file("/log/log", err); } } /* * NAME: interrupt() * DESCRIPTION: deal with a kill signal */ static void interrupt() { send_message("Shutdown by interrupt.\n"); shutdown(); } int shutting_down; /* * NAME: start_shut_down() * DESCRIPTION: start shutting down the game */ void start_shut_down() { if (PRIVILEGED() && shutting_down == 0) { shutting_down = call_out("do_shutdown", 1); } } /* * NAME: do_shutdown() * DESCRIPTION: actually shut down the game */ static void do_shutdown() { object *u, player; int i; u = users(); for (i = 0; i < sizeof(u); i++) { u[i]->catch_tell("Deegeedee shouts: Mud shutting down immediately.\n"); } for (i = 0; i < sizeof(u); i++) { player = u[i]->query_player(); GLOBAL->set_this_player(player); catch(player->quit()); } send_message("Shutdown.\n"); shutdown(); } /* * NAME: compile_rlimits() * DESCRIPTION: determine at compile time if usage of rlimits is unrestricted */ static int compile_rlimits(string objname) { return objname == USER; } /* * NAME: runtime_rlimits() * DESCRIPTION: restrict rlimits at runtime */ static int runtime_rlimits(object obj, int depth, int ticks) { return 0; /* No. */ }