public void ChangeRank( [NotNull] Player player, [NotNull] Rank newRank, [CanBeNull] string reason,
bool announce, bool raiseEvents, bool auto )
{
if ( player == null )
throw new ArgumentNullException( "player" );
if ( newRank == null )
throw new ArgumentNullException( "newRank" );
if ( reason != null && reason.Trim().Length == 0 )
reason = null;
bool promoting = ( newRank > Rank );
string verb = ( promoting ? "promote" : "demote" );
string verbed = ( promoting ? "promoted" : "demoted" );
// Check if player is trying to promote/demote self
if ( player.Info == this ) {
PlayerOpException.ThrowCannotTargetSelf( player, this, verb );
}
// Check if target already has the desired rank
if ( newRank == Rank ) {
string msg = String.Format( "Player {0} is already ranked {1}", Name, Rank.Name );
string colorMsg = String.Format( "&SPlayer {0}&S is already ranked {1}", ClassyName, Rank.ClassyName );
throw new PlayerOpException( player, this, PlayerOpExceptionCode.NoActionNeeded, msg, colorMsg );
}
// Check if player has permissions in general
if ( promoting && !player.Can( Permission.Promote ) ) {
PlayerOpException.ThrowPermissionMissing( player, this, verb, Permission.Promote );
} else if ( !promoting && !player.Can( Permission.Demote ) ) {
PlayerOpException.ThrowPermissionMissing( player, this, verb, Permission.Demote );
}
// Check if player's specific permission limits are enough
if ( promoting && !player.Can( Permission.Promote, newRank ) ) {
string msg = String.Format( "Cannot promote {0} to {1}: you may only promote players up to rank {2}.",
Name, newRank.Name,
player.Info.Rank.GetLimit( Permission.Promote ).Name );
string colorMsg = String.Format( "&SCannot promote {0}&S to {1}&S: you may only promote players up to rank {2}&S.",
ClassyName, newRank.ClassyName,
player.Info.Rank.GetLimit( Permission.Promote ).ClassyName );
throw new PlayerOpException( player, this, PlayerOpExceptionCode.PermissionLimitTooLow,
msg, colorMsg );
} else if ( !promoting && !player.Can( Permission.Demote, Rank ) ) {
string msg = String.Format( "Cannot demote {0} (ranked {1}): you may only demote players ranked {2} or below.",
Name, Rank.Name,
player.Info.Rank.GetLimit( Permission.Demote ).Name );
string colorMsg = String.Format( "&SCannot demote {0}&S (ranked {1}&S): you may only demote players ranked {2}&S or below.",
ClassyName, Rank.ClassyName,
player.Info.Rank.GetLimit( Permission.Demote ).ClassyName );
throw new PlayerOpException( player, this, PlayerOpExceptionCode.PermissionLimitTooLow,
msg, colorMsg );
}
// Check if promotion/demotion reason is required/missing
PlayerOpException.CheckRankChangeReason( reason, player, this, promoting );
RankChangeType changeType;
if ( newRank >= Rank ) {
changeType = ( auto ? RankChangeType.AutoPromoted : RankChangeType.Promoted );
} else {
changeType = ( auto ? RankChangeType.AutoDemoted : RankChangeType.Demoted );
}
// Raise PlayerInfo.RankChanging event
if ( raiseEvents && RaiseRankChangingEvent( this, player, newRank, reason, changeType, announce ) ) {
PlayerOpException.ThrowCancelled( player, this );
}
// Log the rank change
Logger.Log( LogType.UserActivity,
"{0} {1} {2} from {3} to {4}. Reason: {5}",
player.Name, verbed, Name, Rank.Name, newRank.Name, reason ?? "" );
//add promocount
if ( promoting )
player.Info.PromoCount++;
// Actually change rank
Rank oldRank = Rank;
ProcessRankChange( newRank, player.Name, reason, changeType );
// Make necessary adjustments related to rank change
Player target = PlayerObject;
if ( target == null ) {
if ( raiseEvents )
RaiseRankChangedEvent( this, player, oldRank, reason, changeType, announce );
if ( IsHidden && !Rank.Can( Permission.Hide ) ) {
IsHidden = false;
}
} else {
Server.RaisePlayerListChangedEvent();
if ( raiseEvents )
RaiseRankChangedEvent( this, player, oldRank, reason, changeType, announce );
// reset binds (water, lava, admincrete)
target.ResetAllBinds();
// reset admincrete deletion permission
target.Send( PacketWriter.MakeSetPermission( target ) );
if ( target.SupportsBlockPermissions ) {
target.SendBlockPermissions();
}
// cancel selection in progress
if ( target.IsMakingSelection ) {
target.Message( "Selection cancelled." );
target.SelectionCancel();
}
// reset brush to normal, if not allowed to draw advanced
if ( !target.Can( Permission.DrawAdvanced ) ) {
target.Brush = NormalBrushFactory.Instance;
}
// unhide, if needed
if ( IsHidden && !target.Can( Permission.Hide ) ) {
IsHidden = false;
player.Message( "You are no longer hidden." );
}
// check if target is still allowed to spectate
Player spectatedPlayer = target.SpectatedPlayer;
if ( spectatedPlayer != null && !target.Can( Permission.Spectate, spectatedPlayer.Info.Rank ) ) {
target.StopSpectating();
}
// check if others are still allowed to spectate target
foreach ( Player spectator in Server.Players.Where( p => p.SpectatedPlayer == target ) ) {
if ( !spectator.Can( Permission.Spectate, newRank ) ) {
spectator.StopSpectating();
}
}
// ensure copy slot consistency
target.InitCopySlots();
// inform the player of the rank change
target.Message( "You were {0} to {1}&S by {2}",
verbed,
newRank.ClassyName,
player.ClassyName );
if ( reason != null ) {
target.Message( "{0} reason: {1}",
promoting ? "Promotion" : "Demotion",
reason );
}
}
// Announce the rank change
if ( announce ) {
if ( ConfigKey.AnnounceRankChanges.Enabled() ) {
Server.Message( target,
"{0}&S {1} {2}&S from {3}&S to {4}",
player.ClassyName,
verbed,
ClassyName,
oldRank.ClassyName,
newRank.ClassyName );
if ( ConfigKey.AnnounceRankChangeReasons.Enabled() && reason != null ) {
Server.Message( target,
"&S{0} reason: {1}",
promoting ? "Promotion" : "Demotion",
reason );
}
} else {
player.Message( "You {0} {1}&S from {2}&S to {3}",
verbed,
ClassyName,
oldRank.ClassyName,
newRank.ClassyName );
if ( target != null && reason != null ) {
target.Message( "&S{0} reason: {1}",
promoting ? "Promotion" : "Demotion",
reason );
}
}
}
}