foundationI_fluffos_v1/
foundationI_fluffos_v1/bin/
foundationI_fluffos_v1/fluffos-2.9-ds2.12/
foundationI_fluffos_v1/fluffos-2.9-ds2.12/ChangeLog.old/
foundationI_fluffos_v1/fluffos-2.9-ds2.12/Win32/
foundationI_fluffos_v1/fluffos-2.9-ds2.12/compat/
foundationI_fluffos_v1/fluffos-2.9-ds2.12/compat/simuls/
foundationI_fluffos_v1/fluffos-2.9-ds2.12/include/
foundationI_fluffos_v1/fluffos-2.9-ds2.12/testsuite/
foundationI_fluffos_v1/fluffos-2.9-ds2.12/testsuite/clone/
foundationI_fluffos_v1/fluffos-2.9-ds2.12/testsuite/command/
foundationI_fluffos_v1/fluffos-2.9-ds2.12/testsuite/data/
foundationI_fluffos_v1/fluffos-2.9-ds2.12/testsuite/etc/
foundationI_fluffos_v1/fluffos-2.9-ds2.12/testsuite/include/
foundationI_fluffos_v1/fluffos-2.9-ds2.12/testsuite/inherit/
foundationI_fluffos_v1/fluffos-2.9-ds2.12/testsuite/inherit/master/
foundationI_fluffos_v1/fluffos-2.9-ds2.12/testsuite/log/
foundationI_fluffos_v1/fluffos-2.9-ds2.12/testsuite/single/
foundationI_fluffos_v1/fluffos-2.9-ds2.12/testsuite/single/tests/compiler/
foundationI_fluffos_v1/fluffos-2.9-ds2.12/testsuite/single/tests/efuns/
foundationI_fluffos_v1/fluffos-2.9-ds2.12/testsuite/single/tests/operators/
foundationI_fluffos_v1/fluffos-2.9-ds2.12/testsuite/u/
foundationI_fluffos_v1/fluffos-2.9-ds2.12/tmp/
foundationI_fluffos_v1/fluffos-2.9-ds2.12/windows/
foundationI_fluffos_v1/lib/
foundationI_fluffos_v1/lib/cmds/ambassador/
foundationI_fluffos_v1/lib/cmds/database/
foundationI_fluffos_v1/lib/cmds/soul/
foundationI_fluffos_v1/lib/daemon/include/
foundationI_fluffos_v1/lib/daemon/save/
foundationI_fluffos_v1/lib/daemon/services/
foundationI_fluffos_v1/lib/daemon/soul/
foundationI_fluffos_v1/lib/doc/build/
foundationI_fluffos_v1/lib/doc/build/room/
foundationI_fluffos_v1/lib/doc/build/virtual/
foundationI_fluffos_v1/lib/doc/driver/
foundationI_fluffos_v1/lib/doc/efun/
foundationI_fluffos_v1/lib/doc/etc/
foundationI_fluffos_v1/lib/doc/help/creator/
foundationI_fluffos_v1/lib/doc/help/hm/
foundationI_fluffos_v1/lib/doc/help/user/
foundationI_fluffos_v1/lib/doc/lpc/basic/
foundationI_fluffos_v1/lib/doc/lpc/data_types/
foundationI_fluffos_v1/lib/doc/lpc/etc/
foundationI_fluffos_v1/lib/doc/lpc/intermediate/
foundationI_fluffos_v1/lib/doc/lpc/types/
foundationI_fluffos_v1/lib/doc/mudlib/
foundationI_fluffos_v1/lib/doc/mudlib/features/
foundationI_fluffos_v1/lib/domains/Examples/etc/
foundationI_fluffos_v1/lib/domains/Examples/room/
foundationI_fluffos_v1/lib/domains/Examples/virtual/
foundationI_fluffos_v1/lib/domains/Examples/virtual/exaA/
foundationI_fluffos_v1/lib/domains/Examples/virtual/exaB/
foundationI_fluffos_v1/lib/domains/Examples/weapon/
foundationI_fluffos_v1/lib/domains/Standard/
foundationI_fluffos_v1/lib/domains/Standard/pools/
foundationI_fluffos_v1/lib/domains/Standard/std/
foundationI_fluffos_v1/lib/domains/Standard/xtra/
foundationI_fluffos_v1/lib/include/
foundationI_fluffos_v1/lib/news/
foundationI_fluffos_v1/lib/secure/cfg/
foundationI_fluffos_v1/lib/secure/cmds/adm/
foundationI_fluffos_v1/lib/secure/cmds/ambassador/
foundationI_fluffos_v1/lib/secure/cmds/mortal/
foundationI_fluffos_v1/lib/secure/etc/
foundationI_fluffos_v1/lib/secure/etc/approval/
foundationI_fluffos_v1/lib/secure/etc/elections/
foundationI_fluffos_v1/lib/secure/etc/mudlib/
foundationI_fluffos_v1/lib/secure/etc/quests/
foundationI_fluffos_v1/lib/secure/save/daemon/
foundationI_fluffos_v1/lib/secure/save/postal/d/descartes/
foundationI_fluffos_v1/lib/secure/save/users/d/
foundationI_fluffos_v1/lib/secure/std/
foundationI_fluffos_v1/lib/std/obj/
foundationI_fluffos_v1/lib/std/room/
foundationI_fluffos_v1/lib/std/user/
foundationI_fluffos_v1/lib/std/virtual/
foundationI_fluffos_v1/old/
foundationI_fluffos_v1/win32/
// File:        _call.c
// Mudlib:      Nightmare (but see credits)
// Purpose:     allow wizards to call functions in objects
// Credits:     see _refs.c

#include <daemons.h>
#include <std.h>

inherit DAEMON;
inherit REFS_D;

#define SYNTAX "Syntax: call <object>;<function>;<arg>;<arg>\n"
#define FUNC_LIST ({\
  "query_rname",\
  "query_title",\
  "query_email",\
  "query_ip",\
  "query_class",\
  "query_race",\
  "query_guild",\
  "query_level",\
  "query_hp",\
  "query_max_hp",\
  "query_attackers",\
  "query_hunted",\
  })
#define TAB "\t"

mixed do_call( object ob, string func, mixed args );

cmd_call( string a )
{
  string str, *exp_a;
  mixed objs, funcs, args, tmp, ret, rets;
  object ob;
  int i, s, fi, fs;

  if( !a ) { notify_fail( SYNTAX ); return 0; }
    if((string)previous_object()->query_position() == "ambassador") return 0;

  // In general logging calls is a bad idea since the effect can be duplicated
  // very easily by eval or by an object in the wizards directory
  // *shrug* Nightmare wanted it however, so I've #ifdef'ed it.
    log_file( "adm/calls",
      this_player()-> query_name() + " under privs " + query_privs(previous_object()) + " " +
      ctime( time() ) + "\n" + a + "\n" 
    );
  exp_a = explode( a, ";" );
  s = sizeof( exp_a );
  objs = exp_a[0];
  if( s > 1 ) funcs = exp_a[1];
  else funcs = FUNC_LIST;
  if( s == 3 ) args = ({ exp_a[2] });
  if( s > 3 ) args = exp_a[2..(s-1)];

  objs = resolv_ref( objs );
  if( objs == "users" ) objs = users();
  if( !pointerp( objs ) ) objs = ({ objs });
  tmp = ({ });
  s = sizeof( objs );
  for( i = 0 ; i < s ; i++ )
  {
    if( stringp( objs[i] ) ) ob = get_objects( objs[i],0,1 );
    else if( objectp( objs[i] ) ) ob = objs[i];
    if( !ob ) write( "Can't identify " + identify( objs[i] ) +
      " as an object." );
    else tmp += ({ ob });
  }
  if( !sizeof( tmp ) ) return 1;
  objs = tmp;

  funcs = resolv_ref( funcs );
  if( !pointerp( funcs ) ) funcs = ({ funcs });
  tmp = ({ });
  s = sizeof( funcs );
  for( i = 0 ; i < s ; i ++ )
  {
    if( stringp( funcs[i] ) ) tmp += ({ funcs[i] });
    else write( "Can't identify " + identify( funcs[i] )+
      " as a string." );
  }
  if( !sizeof( tmp ) ) return 1;
  funcs = tmp;

  if( pointerp( args ) && ( s = sizeof( args ) ) )
    for( i = 0 ; i < s ; i++ )
      args[i] = resolv_ref( resolv_str( args[i] ) );

  rets = ({ });
  s = sizeof( objs );
  fs = sizeof( funcs );
  for( i = 0 ; i < s ; i++ )
  {
    str = identify( objs[i] );
    for( fi = 0 ; fi < fs ; fi++ )
    {
      ret = do_call( objs[i], funcs[fi], args );
      if( ret[0] ) rets += ({ ret[0] });
      if( fs == 1 ) str = wrap( str + ret[1] );
      else str += (fi?"":"\n") + wrap( ret[1] );
    }
    message("Ninfo", str, this_player());
  }
  switch( sizeof( rets ) )
  {
    case 0: rets = 0; break;
    case 1: rets = rets[0];
  }
  set_ref( 0, rets );

  return 1;
}

do_call( object ob, string func, mixed args )
{
  mixed ret, err;
  int i, s;
  string str;
  object shad;
  function f;

  if( !function_exists( func, ob ) )
  {
    // This needs #ifdef HAS_SHADOW (MudOS driver 0.9.17.3 onwards)
    if( ob != shad ) return ({ 0, "- does not contain " + func + "()" });
  }
  str = "-> " + func;
  if( pointerp( args ) && ( s = sizeof( args ) ) )
  {
    str += "( ";
    for( i = 0 ; i < s ; i++ )
    {
      if( i ) str += ", ";
      str += identify( args[i] );
    }
    str += " )";
  } else str += "()";
    
/*
// how does one do this using function type variables?
  f = (: ob, func :);
  switch( s )
  {
    case 0: err=catch(ret=(*f));break;
    case 1: err=catch(ret=(*f)(args[0]));break;
    case 2: err=catch(ret=(*f)(args[0],args[1]));break;
    case 3: err=catch(ret=(*f)(args[0],args[1],args[2]));break;
    case 4: err=catch(ret=(*f)(args[0],args[1],args[2],args[3]));break;
    default: err=catch(ret=(*f)(args[0],args[1],args[2],args[3],args[4]));break;
  }
*/
  switch( s )
  {
    case 0: err=catch(ret=call_other(ob,func));break;
    case 1: err=catch(ret=call_other(ob,func,args[0]));break;
    case 2: err=catch(ret=call_other(ob,func,args[0],args[1]));break;
    case 3: err=catch(ret=call_other(ob,func,args[0],args[1],args[2]));break;
    default: err=catch(ret=call_other(ob,func,args[0],args[1],args[2],args[3]));
  }

  if( err ) return ({ 0, str + TAB + "= ERR(" + identify( err ) + ")" });
  return ({ ret, str + TAB + "= " + identify( ret ) });
}

int help()
{
    message("Nhelp", SYNTAX+
    "Effect: Calls the function <function> in object <object>,\n"+
    "passing as many arguments <arg> as you give.\n"+ 
    "If no function is specified a dump of the object is given.\n"+
    "<object> and <function> can be arrays (eg \"users\")\n"+
    "See also: refs\n", this_player());
  return 1;
}