/* -*- LPC -*- */ /* * $Locker: $ * $Id: cloner.c,v 1.6 2002/03/21 11:23:20 taffyd Exp $ * $Log: cloner.c,v $ * Revision 1.6 2002/03/21 11:23:20 taffyd * Made it only do one lot of writes at once, so that any objects which add multiple cloner entries at once don't cause lots of disk writes. * Also made it use previous_object() in the log_file() if there's no this_player(). * * Revision 1.5 2001/03/24 01:53:24 ceres * Added illegal object stuff * * Revision 1.4 2000/11/01 07:12:44 ceres * Oops, that didn't work, try it htis way instead * * Revision 1.2 1998/02/22 03:48:07 presto * No changes * * Revision 1.1 1998/01/06 04:54:05 ceres * Initial revision * */ /** * Used for mapping deleted files to new ones when things are changed. * Updated to a more tidy mechanism by Ceres 14/3/96 * <p> * Usage: call add_mapping(from, to) /global/cloner */ #define SAVE_FILE "/save/cloner" #define SAVE_FILE_DELAY 15 /* How long a mapping lasts, currently 3 months */ #define LIFE_TIME 7257600 inherit "/std/object"; mapping changes; mapping illegal; private nosave int _save_file_call_out; /** * This method returns the list of currently moved objects. */ mapping query_changes() { return changes; } /* query_changes() */ /** * Saves the current configuration. */ void save_file() { _save_file_call_out = 0; unguarded((: save_object, SAVE_FILE:)); } /* save_file() */ /** * Loads the current configuration. */ void load_file() { if (file_size(SAVE_FILE + ".o") > 0) unguarded((: restore_object, SAVE_FILE:)); } /* load_file() */ void setup() { changes = ([]); illegal = ([]); load_file(); _save_file_call_out = 0; } /* setup() */ /** * Try and clone the passed in object. If the name exists in the changes * array then the new file name is cloned instead of the old one. * @param word the name of the file to clone * @return the cloned object * @see other_file() * @see list_mappings() */ object clone( string word ) { string new_file; object thing; if ( changes[ word ] && new_file = changes[ word ][ 0 ] ) word = new_file; catch( thing = clone_object( word ) ); return thing; } /* clone() */ /** * This method returns the mapped name of the object. If no mapping * exists the passed in value is returned directly. * @param word the object name to get a mapping for * @return the file to use * @see clone() * @see list_mappings() */ string other_file( string word ) { if ( changes[ word ] ) return changes[ word ][ 0 ]; return word; } /* other_file() */ /** * Use this function to add a new mapping of one filename to another. * Means that if an object of type 'from' is attempted to be cloned * an object of type 'to' will be cloned instead. * @param from the old object name * @param to the new object name * @return 1 on success, 0 on failure * @see remove_mapping() * @see list_mappings() */ int add_mapping( string from, string to ) { string obj_name; if(from[<2..] == ".c") from = from[0..<3]; if(to[<2..] == ".c") to = to[0..<3]; if((file_size(to) < 1) && (file_size(to+".c") < 1)) { write("Destination file does not exist\n"); return 0; } changes[from] = ({to, time()}); if ( !_save_file_call_out ) { _save_file_call_out = call_out( (: save_file :), SAVE_FILE_DELAY ); } if ( !this_player() ) { obj_name = file_name( previous_object() ); } else { obj_name = this_player()->query_cap_name(); } write("Mapping of "+from+" to "+to+" added.\n"); log_file("CLONER", "Mapping of "+from+" to "+to+" added by "+ obj_name +" at "+ctime(time())+".\n"); remove_call_out("clean_up"); call_out("clean_up", 120 + random(500)); return 1; } /* add_mapping() */ /** * Removes a mapping from the object. This looks to see if an mapping * exists for the object and removes it if it does. * @param from the object to remove the mapping from * @return 1 on success and 0 on failure * @see add_mapping() * @see list_mappings() */ int remove_mapping( string from ) { string obj_name; if ( changes && changes[ from ] ) { map_delete( changes, from ); save_file(); write( "Mapping of " + from + " removed.\n" ); if ( !this_player() ) { obj_name = file_name( previous_object() ); } else { obj_name = this_player()->query_cap_name(); } log_file( "CLONER", "Mapping of " + from + " removed by " + obj_name + " at " + ctime( time() ) + ".\n" ); return 1; } write("No mapping found for " + from + ".\n"); return 0; } /* remove_mapping() */ /** * This method returns a list of all the current mappings. If a * pattern is given, then only files which contain that string will * be returned. * @param str the pattern to search for * @return the list of mappings * @see add_mapping() * @see remove_mapping() */ string list_mappings( string str ) { string from, retval; retval = ""; foreach(from in keys(changes)) { if (!str || strsrch(from, str) != -1 || strsrch(changes[from][0], str) != -1) retval += from + " -> " + changes[from][0] + "\n"; } return retval; } /* list_mappings() */ /** * This method is used to add objects that we don't want to be reloaded. * This is for those objects that are clones of /std/object or /obj/armour * or something but which are wrongly configured. * * @example add_illegal("/obj/armour", "blue robe", "/obj/armours/robe.arm); * * @param basename the base filename of the object * @param short the short name of the object * @param replacement the replacement object. * @return 1 for success, 0 for failure */ int add_illegal(string basename, string short, string replacement) { if(!illegal) illegal = ([ ]); if(illegal[basename + ":" + short]) return 0; if((file_size(replacement) < 1) && (file_size(replacement+".c") < 1)) return 0; illegal[basename + ":" + short] = replacement; save_file(); return 1; } /** * Remove an item from the illegal array * @param basename the basename of the object. * @param short the shortname of the object. * @return 1 for success, 0 for failure */ int remove_illegal(string basename, string short) { if(!illegal) return 0; if(!illegal[basename+":"+short]) return 0; map_delete(illegal, basename+":"+short); save_file(); return 1; } /** * List the illegal objects. */ mapping query_illegal() { return illegal; } /** * Determine if a given object is illegal. * @param basename the basename of the object. * @param short the shortname of the object. * @return 1 for success, 0 for failure */ string illegal_thing(string basename, string short) { if(!illegal) return 0; return illegal[basename + ":" + short]; } /** @ignore yes */ void clean_up() { string from; mixed *to; foreach(from, to in changes) if ((to[1] < time() - LIFE_TIME) || ((file_size(to[0]) < 1) && (file_size(to[0] + ".c") < 1))) map_delete(changes, from); save_file(); } /* clean_up() */