Page 1 of 1

invoking "UndoPlayer"

Posted: September 19th, 2012, 2:09 am
by OfficerFlake
Hi. is there a quick way can force an undo player, all in one action, without having to type "/ok"

my idea is a ban and undo command... but I can't undo!

I'm after the equivilent of: "/UndoPlayer <target> 5h"

Re: invoking "UndoPlayer"

Posted: September 19th, 2012, 2:31 am
by fragmer
Well, I suggest taking a look at the source code of /UndoPlayer command ;)

Basically, what you want to do is:
  1. Get your World and target's PlayerInfo objects ready.
  2. Use one of the world.BlockDB.Lookup overloads to get a list of changes to undo.
  3. If any changes were found, launch a BlockDBDrawOperation with the given parameters, to apply the changes to the world.
Here is the most basic way of doing it:

Code: Select all

static void UndoPlayer( Player player, PlayerInfo target, World world, TimeSpan timespan ){
    BlockDBEntry[] changes = world.BlockDB.Lookup( Int32.MaxValue, target, false, timespan );
    if( changes.Length > 0 ){
        BlockDBDrawOperation op = new BlockDBDrawOperation( player, "UndoPlayer", "", 0 );
        op.Prepare( new Vector3I[0], changes );
        op.Begin();
    }
}
Note that DrawOperations require a player to take "ownership" of it. That's done to allow permission-checks for block placement, logging, ability to /Undo, etc. That's where the first parameter of the above method (Player player) comes in.

Also you might want to invoke this method on a background thread (Scheduler.NewBackgroundTask) to avoid lagging up the player. BlockDB.Lookup() might take a while to finish, depending on database size.