private static BlockDBUndoArgs ParseBlockDBUndoParams( Player player, Command cmd, string cmdName, bool not )
{
// check if command's being called by a worldless player (e.g. console)
World playerWorld = player.World;
if ( playerWorld == null )
PlayerOpException.ThrowNoWorld( player );
// ensure that BlockDB is enabled
if ( !BlockDB.IsEnabledGlobally ) {
player.Message( "&W{0}: BlockDB is disabled on this server.", cmdName );
return null;
}
if ( !playerWorld.BlockDB.IsEnabled ) {
player.Message( "&W{0}: BlockDB is disabled in this world.", cmdName );
return null;
}
// parse first and consequent parameters (player names)
HashSet<PlayerInfo> targets = new HashSet<PlayerInfo>();
bool allPlayers = false;
string name = cmd.Next();
switch (name)
{
case null:
return null;
case "*":
if ( not ) {
player.Message( "{0}: \"*\" not allowed (cannot undo \"everyone except everyone\")", cmdName );
return null;
}
if ( allPlayers ) {
player.Message( "{0}: \"*\" was listed twice.", cmdName );
return null;
}
allPlayers = true;
break;
default:
{
// individual player
PlayerInfo target = PlayerDB.FindPlayerInfoOrPrintMatches( player, name );
if ( target == null ) {
return null;
}
if ( targets.Contains( target ) ) {
player.Message( "{0}: Player {1}&S was listed twice.",
target.ClassyName, cmdName );
return null;
}
// make sure player has the permission
if ( !not &&
player.Info != target && !player.Can( Permission.UndoAll ) &&
!player.Can( Permission.UndoOthersActions, target.Rank ) ) {
player.Message( "&W{0}: You may only undo actions of players ranked {1}&S or lower.",
cmdName,
player.Info.Rank.GetLimit( Permission.UndoOthersActions ).ClassyName );
player.Message( "Player {0}&S is ranked {1}",
target.ClassyName, target.Rank.ClassyName );
return null;
}
targets.Add( target );
}
break;
}
// parse the 2nd parameter - either numeric or time limit
string range = cmd.Next();
if ( range == null ) {
CdUndoPlayer.PrintUsage( player );
return null;
}
if ( targets.Count == 0 && !allPlayers ) {
player.Message( "{0}: Specify at least one player name, or \"*\" to undo everyone.", cmdName );
return null;
}
if ( targets.Count > 0 && allPlayers ) {
player.Message( "{0}: Cannot mix player names and \"*\".", cmdName );
return null;
}
// undoing everyone ('*' in place of player name) requires UndoAll permission
if ( ( not || allPlayers ) && !player.Can( Permission.UndoAll ) ) {
player.MessageNoAccess( Permission.UndoAll );
return null;
}
int countLimit;
TimeSpan ageLimit = TimeSpan.Zero;
if ( !Int32.TryParse( range, out countLimit ) && !range.TryParseMiniTimespan( out ageLimit ) ) {
player.Message( "{0}: Second parameter should be a number or a timespan.", cmdName );
return null;
}
if ( ageLimit > DateTimeUtil.MaxTimeSpan ) {
player.MessageMaxTimeSpan();
return null;
}
// Queue UndoPlayerCallback to run
return new BlockDBUndoArgs {
Player = player,
AgeLimit = ageLimit,
CountLimit = countLimit,
Area = player.WorldMap.Bounds,
World = playerWorld,
Targets = targets.ToArray(),
Not = not
};
}