static void WorldAccessHandler( [NotNull] Player player, Command cmd ) {
if( player == null ) throw new ArgumentNullException( "player" );
string worldName = cmd.Next();
// Print information about the current world
if( worldName == null ) {
if( player.World == null ) {
player.Message( "When calling /WAccess from console, you must specify a world name." );
} else {
player.Message( player.World.AccessSecurity.GetDescription( player.World, "world", "accessed" ) );
}
return;
}
// Find a world by name
World world = WorldManager.FindWorldOrPrintMatches( player, worldName );
if( world == null ) return;
string name = cmd.Next();
if( name == null ) {
player.Message( world.AccessSecurity.GetDescription( world, "world", "accessed" ) );
return;
}
if( world == WorldManager.MainWorld ) {
player.Message( "The main world cannot have access restrictions." );
return;
}
bool changesWereMade = false;
do {
// Whitelisting individuals
if( name.StartsWith( "+" ) ) {
if( name.Length == 1 ) {
CdWorldAccess.PrintUsage( player );
break;
}
PlayerInfo info = PlayerDB.FindPlayerInfoOrPrintMatches( player, name.Substring( 1 ) );
if( info == null ) return;
// prevent players from whitelisting themselves to bypass protection
if( player.Info == info && !player.Info.Rank.AllowSecurityCircumvention ) {
switch( world.AccessSecurity.CheckDetailed( player.Info ) ) {
case SecurityCheckResult.RankTooLow:
player.Message( "&WYou must be {0}&W+ to add yourself to the access whitelist of {1}",
world.AccessSecurity.MinRank.ClassyName,
world.ClassyName );
continue;
// TODO: RankTooHigh
case SecurityCheckResult.BlackListed:
player.Message( "&WYou cannot remove yourself from the access blacklist of {0}",
world.ClassyName );
continue;
}
}
if( world.AccessSecurity.CheckDetailed( info ) == SecurityCheckResult.Allowed ) {
player.Message( "{0}&S is already allowed to access {1}&S (by rank)",
info.ClassyName, world.ClassyName );
continue;
}
Player target = info.PlayerObject;
if( target == player ) target = null; // to avoid duplicate messages
switch( world.AccessSecurity.Include( info ) ) {
case PermissionOverride.Deny:
if( world.AccessSecurity.Check( info ) ) {
player.Message( "{0}&S is no longer barred from accessing {1}",
info.ClassyName, world.ClassyName );
if( target != null ) {
target.Message( "You can now access world {0}&S (removed from blacklist by {1}&S).",
world.ClassyName, player.ClassyName );
}
} else {
player.Message( "{0}&S was removed from the access blacklist of {1}&S. " +
"Player is still NOT allowed to join (by rank).",
info.ClassyName, world.ClassyName );
if( target != null ) {
target.Message( "You were removed from the access blacklist of world {0}&S by {1}&S. " +
"You are still NOT allowed to join (by rank).",
player.ClassyName, world.ClassyName );
}
}
Logger.Log( LogType.UserActivity,
"{0} removed {1} from the access blacklist of {2}",
player.Name, info.Name, world.Name );
changesWereMade = true;
break;
case PermissionOverride.None:
player.Message( "{0}&S is now allowed to access {1}",
info.ClassyName, world.ClassyName );
if( target != null ) {
target.Message( "You can now access world {0}&S (whitelisted by {1}&S).",
world.ClassyName, player.ClassyName );
}
Logger.Log( LogType.UserActivity,
"{0} added {1} to the access whitelist on world {2}",
player.Name, info.Name, world.Name );
changesWereMade = true;
break;
case PermissionOverride.Allow:
player.Message( "{0}&S is already on the access whitelist of {1}",
info.ClassyName, world.ClassyName );
break;
}
// Blacklisting individuals
} else if( name.StartsWith( "-" ) ) {
if( name.Length == 1 ) {
CdWorldAccess.PrintUsage( player );
break;
}
PlayerInfo info = PlayerDB.FindPlayerInfoOrPrintMatches( player, name.Substring( 1 ) );
if( info == null ) return;
if( world.AccessSecurity.CheckDetailed( info ) == SecurityCheckResult.RankTooHigh ||
world.AccessSecurity.CheckDetailed( info ) == SecurityCheckResult.RankTooLow ) {
player.Message( "{0}&S is already barred from accessing {1}&S (by rank)",
info.ClassyName, world.ClassyName );
continue;
}
Player target = info.PlayerObject;
if( target == player ) target = null; // to avoid duplicate messages
switch( world.AccessSecurity.Exclude( info ) ) {
case PermissionOverride.Deny:
player.Message( "{0}&S is already on access blacklist of {1}",
info.ClassyName, world.ClassyName );
break;
case PermissionOverride.None:
player.Message( "{0}&S is now barred from accessing {1}",
info.ClassyName, world.ClassyName );
if( target != null ) {
target.Message( "&WYou were barred by {0}&W from accessing world {1}",
player.ClassyName, world.ClassyName );
}
Logger.Log( LogType.UserActivity,
"{0} added {1} to the access blacklist on world {2}",
player.Name, info.Name, world.Name );
changesWereMade = true;
break;
case PermissionOverride.Allow:
if( world.AccessSecurity.Check( info ) ) {
player.Message( "{0}&S is no longer on the access whitelist of {1}&S. " +
"Player is still allowed to join (by rank).",
info.ClassyName, world.ClassyName );
if( target != null ) {
target.Message( "You were removed from the access whitelist of world {0}&S by {1}&S. " +
"You are still allowed to join (by rank).",
player.ClassyName, world.ClassyName );
}
} else {
player.Message( "{0}&S is no longer allowed to access {1}",
info.ClassyName, world.ClassyName );
if( target != null ) {
target.Message( "&WYou can no longer access world {0}&W (removed from whitelist by {1}&W).",
world.ClassyName, player.ClassyName );
}
}
Logger.Log( LogType.UserActivity,
"{0} removed {1} from the access whitelist on world {2}",
player.Name, info.Name, world.Name );
changesWereMade = true;
break;
}
// Setting minimum rank
} else {
Rank rank = RankManager.FindRank( name );
if( rank == null ) {
player.MessageNoRank( name );
} else if( !player.Info.Rank.AllowSecurityCircumvention &&
world.AccessSecurity.MinRank > rank &&
world.AccessSecurity.MinRank > player.Info.Rank ) {
player.Message( "&WYou must be ranked {0}&W+ to lower the access rank for world {1}",
world.AccessSecurity.MinRank.ClassyName, world.ClassyName );
} else {
// list players who are redundantly blacklisted
var exceptionList = world.AccessSecurity.ExceptionList;
PlayerInfo[] noLongerExcluded = exceptionList.Excluded.Where( excludedPlayer => excludedPlayer.Rank < rank ).ToArray();
if( noLongerExcluded.Length > 0 ) {
player.Message( "Following players no longer need to be blacklisted to be barred from {0}&S: {1}",
world.ClassyName,
noLongerExcluded.JoinToClassyString() );
}
// list players who are redundantly whitelisted
PlayerInfo[] noLongerIncluded = exceptionList.Included.Where( includedPlayer => includedPlayer.Rank >= rank ).ToArray();
if( noLongerIncluded.Length > 0 ) {
player.Message( "Following players no longer need to be whitelisted to access {0}&S: {1}",
world.ClassyName,
noLongerIncluded.JoinToClassyString() );
}
// apply changes
world.AccessSecurity.MinRank = rank;
changesWereMade = true;
if( world.AccessSecurity.MinRank == RankManager.LowestRank ) {
Server.Message( "{0}&S made the world {1}&S accessible to everyone.",
player.ClassyName, world.ClassyName );
} else {
Server.Message( "{0}&S made the world {1}&S accessible only by {2}+",
player.ClassyName, world.ClassyName,
world.AccessSecurity.MinRank.ClassyName );
}
Logger.Log( LogType.UserActivity,
"{0} set access rank for world {1} to {2}+",
player.Name, world.Name, world.AccessSecurity.MinRank.Name );
}
}
} while( (name = cmd.Next()) != null );
if( changesWereMade ) {
var playersWhoCantStay = world.Players.Where( p => !p.CanJoin( world ) );
foreach( Player p in playersWhoCantStay ) {
p.Message( "&WYou are no longer allowed to join world {0}", world.ClassyName );
p.JoinWorld( WorldManager.MainWorld, WorldChangeReason.PermissionChanged );
}
WorldManager.SaveWorldList();
}
}