MOO-cows Mailing List Archive

[Prev][Next][Index][Thread]

Re: force_input() and $do_command()



>At 12:06 PM 7/4/96 PDT, Jefferson Dubrule wrote:
>>At 01:57 PM 7/2/96 PDT, Joe Shaw wrote:
>>>The in-db parsing for this is handled in $do_command(). I ran a few tests:
>>>I ran a command by myself, it worked just fine. I connected as a test
>>>character and evalled the force_input() line for the exact same command.
>>>It worked just fine. Now, I logged out as that character and tried again:
>>>No dice.
>>
>>Here's a solution:
>>
>>Log the guy in!  Before trying to force_input() any of his commands,
>>call $network:open("127.0.0.1", $network.port, <player to log in>);
>>
>>Then do force_input() on him, and it will work fine.  When you are
>>finished, boot_player() him.
>
>What about non-lambda cores?  What about NPCs?  What does the third argument
>do, and how does it do it?

Doh!  <open mouth, insert foot>  It isn't this easy, however it can be done.
This works fine on non-lambda cores, as it only uses built-ins.

The code is in two places, $network:animate, and a modification to
$network:incoming_connection.  One additional property is required on $network.

$network:incoming_connection is called by $do_login_command whenever a new
connection is made to the server.
It looks at each connection and decides whether it is an outbound or inbound
connection.  If it is an inbound connection, it generally returns 0.  By
putting the following lines in to check whether it is an animation, it will
sense these and log the player in.

... perms checks/outbound stuff ...
elseif (index(connection_name(what), " from localhost, port "))
  animation = this.animations[1][2];
  set_connection_option(this.animations[1][1], "hold-input", 1);
  this.animations = listdelete(this.animations, 1);
  return animation;
else
  return 0;
endif


Also, this verb needs to be added:

@prop $network.animations {}
@verb $network:animate tnt
@program $network:animate
":animate(player)";
"Open a dummy network connection that simulates the connection of a player.
The object
specified must be a player (though it need not be a $player).";
if (typeof(args[1]) != OBJ || !valid(args[1]) || !is_player(args[1]))
  return E_INVARG;
elseif (!$perm_utils:controls(caller_perms(), args[1]))
  return E_PERM;
elseif (typeof(connection = open_network_connection("127.0.0.1", this.port))
== ERR)
  return connection;
else
  this.animations = {@this.animations, {connection, args[1]}};
  return connection;
endif
.

And, for convenience, you may want these verbs on your $wizard class:

@verb $wiz:">*" any any any
@program $wiz:>
if (verb[1..2] == ">>")
  puppet = $string_utils:match_player(verb[3..$]);
  if (!valid(puppet))
    return player:tell("Invalid player name, \"", verb[3..$], "\".");
  endif
  player.puppet = puppet;
else
  puppet = player.puppet;
  (length(verb) > 1) && (args = {verb[2..$], @args});
endif
force_input(puppet, $string_utils:from_list(args, " "));
.

@verb $wiz:"@animate" any none none
@program $wiz:@animate
if (valid(puppet = $string_utils:match_player(dobjstr)))
  $network:animate(puppet);
  player:tell($string_utils:nn(puppet), " animated.");
else
  return player:tell("Invalid player, \"", dobjstr, "\".");
endif
.


Does this clear everything up?  (I hope so)

Please let me know if this opens up horrible security holes or something.



Follow-Ups:

Home | Subject Index | Thread Index