// /adm/daemons/multi_d.c // A Nightmarish object. // Keeps track of multiple characters (See also: /bin/adm/_link.c) // Created by Pallando (93-05-26) // NB No checks have been put in to prevent wizards faking calls. // I'll leave the Law arches to decide how paranoid they wish to be. 8-) // 3600 = 60 * 60 = number of second in an hour = // amount of time after logging out that a user can log in a second character #include <save.h> #include <security.h> #define DELAY_PERIOD 3600 mapping links; string *non_voting; static mapping entered; static void save_data() { save_object(SAVE_MULTI); } static void restore_data() { restore_object(SAVE_MULTI); } void create() { restore_data(); if( !links ) links = ([]); if( !non_voting ) non_voting = ({ }); entered = ([ ]); } void list_links() { string *names; int loop; names = keys( links ); names -= non_voting; loop = sizeof( names ); if( !loop ) { write( "No multiple characters yet."); return; } write( "The following multiple characters are registered:"); while( loop-- ) write( names[loop] + " is also: " + implode( links[names[loop]], ", " )); } mixed is_linked_char( string name ) { return links[name]; } int non_voter( string name ) { return -1 != member_array( name, non_voting ); } int make_link( string *names ) { int loop, size; if( !pointerp( names ) ) return 0; size = sizeof( names ); if( size < 2 ) return 0; for( loop = 0 ; loop < size ; loop++ ) if( links[names[loop]] ) { write( names[loop] + " is already in a link." ); return 0; } non_voting += names[1..size-1]; for( loop = 0 ; loop < size ; loop++ ) links[names[loop]] = ( names - names[loop..loop] ); save_data(); return 1; } int unlink( string name ) { // If name is the main character, break the entire link // Otherwise just remove name fom it. string *names; int loop, size; names = ({ name }) + links[name]; size = sizeof( names ); for( loop = 0 ; loop < size ; loop++ ) map_delete( links, names[loop] ); if( ( size > 2 ) && non_voter( name ) ) { non_voting -= names; make_link( names[1..size-1] ); } else { non_voting -= names; save_data(); } return 1; } /************** Functions to keep track of who has logged in or out ***/ // Called by the remove() function in /std/user.c void quit( string name ) { if( !name ) return; if( links[name] ) { if( !entered[name] ) { // Possible cheat attempt. // Law can decide if they want to log it or not. // Will also be caused if chars are linked while logged in. } entered[name] = time(); } } // Called by the switch_player() function in /adm/login.c int query_prevent_login( string name ) { // Put a test for arches here, if you want to make sure they can // always log in. string *names; // st = -1 if character is logged in, else time of logout int loop, size, st; if( !name ) return 0; if( undefinedp( names = links[name] ) ) return 0; // Always allow arches in. if( member_group( name, "superuser" ) || member_group( name, "assist" ) ) return 0; size = sizeof( names ); for( loop = 0 ; loop < size ; loop++ ) { // The next line is only useful in the case that you link some chars // While they are loged in, then one logs out and trys to log in again. if( find_player( names[loop] ) ) entered[names[loop]] = -1; if( st = entered[names[loop]] ) { if( st < 0 ) { write( "Another character of yours, " + capitalize( names[loop] ) + " is already logged in." ); // Log this event if you want to. return 1; // prevent login } if( ( time() - st ) < DELAY_PERIOD ) { write( "Sorry, " + capitalize( names[loop] ) + " logged out only "+ ( time() - st ) / 60 + " minutes ago. Try later." ); // Log this event if you want to. return 1; } map_delete( entered, names[loop] ); } } entered[name] = -1; return 0; }