/// <summary> Mutes this player (prevents from writing chat messages). </summary> /// <param name="player"> Player who is doing the muting. </param> /// <param name="duration"> Duration of the mute. If a player is already muted for same or greater length of time, /// PlayerOpException is thrown with NoActionNeeded code. If a player is already muted for a shorter length of time, /// the mute duration is extended. </param> /// <param name="announce"> Whether to announce muting publicly on the sever. </param> /// <param name="raiseEvents"> Whether to raise PlayerInfo.MuteChanging and MuteChanged events. </param> public void Mute( [NotNull] Player player, TimeSpan duration, bool announce, bool raiseEvents ) { if( player == null ) throw new ArgumentNullException( "player" ); if( duration <= TimeSpan.Zero ) { throw new ArgumentException( "Mute duration may not be zero or negative.", "duration" ); } // Check if player is trying to mute self if( player.Info == this ) { PlayerOpException.ThrowCannotTargetSelf( player, this, "mute" ); } lock( syncRoot ) { // Check if player can mute in general if( !player.Can( Permission.Mute ) ) { PlayerOpException.ThrowPermissionMissing( player, this, "mute", Permission.Mute ); } // Check if player has sufficient rank permissions if( !player.Can( Permission.Mute, Rank ) ) { PlayerOpException.ThrowPermissionLimit( player, this, "mute", Permission.Mute ); } // Check if target is already muted for longer DateTime newMutedUntil = DateTime.UtcNow.Add( duration ); if( newMutedUntil > MutedUntil ) { // raise PlayerInfo.MuteChanging event if( raiseEvents ) { var e = new PlayerInfoMuteChangingEventArgs( this, player, duration, false, announce ); RaiseMuteChangingEvent( e ); if( e.Cancel ) PlayerOpException.ThrowCanceled( player, this ); announce = e.Announce; duration = e.Duration; } // actually mute MutedUntil = newMutedUntil; MutedBy = player.Name; // raise PlayerInfo.MuteChanged event if( raiseEvents ) { RaiseMuteChangedEvent( this, player, duration, false, announce ); } // log and announce mute publicly Logger.Log( LogType.UserActivity, "Player {0} was muted by {1} for {2}", Name, player.Name, duration ); if( announce ) { Player target = PlayerObject; if( target != null ) { target.Message( "You were muted by {0}&S for {1}", player.ClassyName, duration.ToMiniString() ); } Server.Message( target, "&SPlayer {0}&S was muted by {1}&S for {2}", ClassyName, player.ClassyName, duration.ToMiniString() ); } } else { // no action needed - already muted for same or longer duration string msg = String.Format( "Player {0} was already muted by {1} ({2} left)", ClassyName, MutedBy, TimeMutedLeft.ToMiniString() ); string colorMsg = String.Format( "&SPlayer {0}&S was already muted by {1}&S ({2} left)", ClassyName, MutedByClassy, TimeMutedLeft.ToMiniString() ); throw new PlayerOpException( player, this, PlayerOpExceptionCode.NoActionNeeded, msg, colorMsg ); } } }
static bool RaiseMuteChangingEvent( [NotNull] PlayerInfo target, [NotNull] Player muter, TimeSpan duration, bool unmuting, bool announce ) { var h = MuteChanging; if( h == null ) return false; var e = new PlayerInfoMuteChangingEventArgs( target, muter, duration, unmuting, announce ); h( null, e ); return !e.Cancel; }
/// <summary> Unmutes this player (allows them to write chat again). </summary> /// <param name="player"> Player who is doing the unmuting. </param> /// <param name="announce"> Whether to announce unmuting publicly on the sever. </param> /// <param name="raiseEvents"> Whether to raise PlayerInfo.MuteChanging and MuteChanged events. </param> public void Unmute( [NotNull] Player player, bool announce, bool raiseEvents ) { if( player == null ) throw new ArgumentNullException( "player" ); // Check if player is trying to unmute self if( player.Info == this ) { PlayerOpException.ThrowCannotTargetSelf( player, this, "unmute" ); } lock( syncRoot ) { TimeSpan timeLeft = TimeMutedLeft; // Check if player can unmute in general if( !player.Can( Permission.Mute ) ) { PlayerOpException.ThrowPermissionMissing( player, this, "unmute", Permission.Mute ); } if( timeLeft <= TimeSpan.Zero ) { string msg = String.Format( "Player {0} is not currently muted.", Name ); string msgColor = String.Format( "&SPlayer {0}&S is not currently muted.", ClassyName ); throw new PlayerOpException( player, this, PlayerOpExceptionCode.NoActionNeeded, msg, msgColor ); } // raise PlayerInfo.MuteChanging event if( raiseEvents ) { var e = new PlayerInfoMuteChangingEventArgs( this, player, timeLeft, true, announce ); RaiseMuteChangingEvent( e ); if( e.Cancel ) PlayerOpException.ThrowCanceled( player, this ); announce = e.Announce; } Unmute(); // raise PlayerInfo.MuteChanged event if( raiseEvents ) { RaiseMuteChangedEvent( this, player, timeLeft, true, announce ); } // log and announce mute publicly Logger.Log( LogType.UserActivity, "Player {0} was unmuted by {1} ({2} was left on the mute)", Name, player.Name, timeLeft ); if( announce ) { Player target = PlayerObject; if( target != null ) { target.Message( "You were unmuted by {0}", player.ClassyName ); } Server.Message( target, "&SPlayer {0}&S was unmuted by {1}", ClassyName, player.ClassyName ); } } }