/* Do not remove the headers from this file! see /USAGE for more info. */ /* Spell Daemon -- keep track of what spells are valid... ** ** This currently keeps track of the dirs that hold spells and the spells ** contained in those dirs. ** ** Rust @ lima.mudlib.org */ #include <assert.h> #include <security.h> #include <commands.h> inherit M_DAEMON_DATA; #define PRIV_REQUIRED "Mudlib:daemons" // Save this.... private string array spell_dirs = ({}); // Map the name of the spell to its object name. // We build this each create. private nosave mapping spell_table = ([ ]); void add_spell_dir(string dir) { if ( !check_privilege(PRIV_REQUIRED) ) return; ENSURE(dir && is_directory(dir)); ENSURE(member_array(dir, spell_dirs) == -1); if ( dir[<1] != '/' ) dir += "/"; spell_dirs += ({ dir }); save_me(); } void remove_spell_dir(string dir) { if ( !check_privilege(PRIV_REQUIRED) ) return; ENSURE(dir && member_array(dir, spell_dirs) != -1); spell_dirs -= ({ dir }); save_me(); } // We need to do this due to parser limitations. private int valid_spell_name(string spell_name) { return stringp(spell_name) && regexp(spell_name, "^[a-zA-Z0-9 '-]+$"); } private void build_spell_table() { string * bad_dirs = ({ }); // Not necessary, and would be a bad thing if we didn't rebuild the spell // table each time. spell_dirs -= ({ 0 }); foreach ( string dir in spell_dirs ) { if ( !is_directory(dir) ) { // Dir has been removed bad_dirs += ({ dir }); continue; } foreach ( string file in get_dir(dir + "*.c") ) { string obname = dir + file[0..<3]; string spell_name; if ( catch(spell_name = obname->get_spell_name()) ) continue; if ( !valid_spell_name(spell_name) ) { // log it... continue; } if ( spell_table[spell_name] ) { // log it.... continue; } spell_table[spell_name] = obname; } } if ( sizeof(bad_dirs) ) { spell_dirs -= bad_dirs; save_me(); } } string get_spell_obname(string spell_name) { return spell_table[spell_name]; } void create() { ::create(); build_spell_table(); } /* strip leading "the/a/an"; strip trailing "spell" */ private nomask string find_spell_obname(string spell) { string array parts = explode(spell, " "); if ( sizeof(parts) > 1 ) { switch ( parts[0] ) { case "the": case "a": case "an": parts = parts[1..]; break; default: break; } } if ( sizeof(parts) > 1 && parts[<1] == "spell" ) parts = parts[0..<2]; return spell_table[implode(parts, " ")]; } varargs mixed check_valid_spell(string spell, int has_target, int has_reagent) { string spell_obname; ENSURE(previous_object() == find_object(VERB_OB_CAST)); spell_obname = find_spell_obname(spell); if ( !spell_obname ) return "You know of no such spell.\n"; return spell_obname->_check_valid_spell(has_target, has_reagent); } varargs mixed check_valid_target(string spell, object target, mixed has_reagent) { string spell_obname; ENSURE(previous_object() == find_object(VERB_OB_CAST)); spell_obname = find_spell_obname(spell); if ( !spell_obname ) return "You know of no such spell.\n"; return spell_obname->_check_valid_target(target, has_reagent); } varargs mixed check_valid_reagent(string spell, object reagent, mixed has_target) { string spell_obname; ENSURE(previous_object() == find_object(VERB_OB_CAST)); spell_obname = find_spell_obname(spell); if ( !spell_obname ) return "You know of no such spell.\n"; return spell_obname->_check_valid_reagent(reagent, has_target); } varargs void cast_spell(string spell, object target, object reagent) { string spell_obname; ENSURE(previous_object() == find_object(VERB_OB_CAST)); spell_obname = find_spell_obname(spell); ENSURE(spell_obname); return spell_obname->_cast_spell(target, reagent); } void register_spell() { string spell_name = previous_object()->get_spell_name(); string spell_info = spell_table[spell_name]; ENSURE(spell_name /* You didn't provide a spell name. */); ENSURE(valid_spell_name(spell_name) /* Your spell name wasn't valid. */); if ( !spell_info ) { string obname = file_name(previous_object()); string * file_info = split_path(obname); int dir_index = member_array(file_info[0], spell_dirs); if ( dir_index == -1 ) error("spell is not in a legal directory\n"); spell_table[spell_name] = obname; } ENSURE(find_object(get_spell_obname(spell_name)) == previous_object() /* Some other spell already has this name.*/); }