public async Task <RuntimeResult> MuteUser(IGuildUser user, params string[] arguments) { if (user.IsBot) { return(CustomResult.FromError("You can't mute bots.")); } if (user.GuildPermissions.PrioritySpeaker) { return(CustomResult.FromError("You can't mute staff.")); } if (arguments.Length < 1) { return(CustomResult.FromError("The correct usage is `;mute <duration> <reason>`")); } string durationStr = arguments[0]; string reason; if (arguments.Length > 1) { string[] reasons = new string[arguments.Length - 1]; Array.Copy(arguments, 1, reasons, 0, arguments.Length - 1); reason = string.Join(" ", reasons); } else { return(CustomResult.FromError("You need to provide a reason.")); } CaptureCollection captures = Regex.Match(durationStr, @"(\d+[a-z]+)+").Groups[1].Captures; DateTime targetTime = DateTime.Now; // this basically means *one* of the values has been wrong, maybe negative or something like that bool validFormat = false; foreach (Capture capture in captures) { // this means, that one *valid* unit has been found, not necessarily a valid valid, this is needed for the case, in which there is // no valid value possible (e.g. 3y), this would cause the for loop to do nothing, but we are unaware of that bool timeUnitApplied = false; foreach (char format in timeFormats) { var captureValue = capture.Value; // this check is needed in order that our durationSplit check makes sense // if the format is not present, the split would return a wrong value, and the check would be wrong if (captureValue.Contains(format)) { timeUnitApplied = true; var durationSplit = captureValue.Split(format); var isNumeric = int.TryParse(durationSplit[0], out int n); if (durationSplit.Length == 2 && durationSplit[1] == "" && isNumeric && n > 0) { switch (format) { case 'm': targetTime = targetTime.AddMinutes(n); break; case 'h': targetTime = targetTime.AddHours(n); break; case 'd': targetTime = targetTime.AddDays(n); break; case 'w': targetTime = targetTime.AddDays(n * 7); break; case 's': targetTime = targetTime.AddSeconds(n); break; default: validFormat = false; goto AfterLoop; } validFormat = true; } else { validFormat = false; goto AfterLoop; } } } if (!timeUnitApplied) { validFormat = false; break; } } AfterLoop: if (!validFormat) { return(CustomResult.FromError("Invalid format, it needs to be positive, and combinations of " + string.Join(", ", timeFormats))); } var author = Context.Message.Author; var guild = Context.Guild; var mutedRoleName = "textmuted"; if (!Global.Roles.ContainsKey(mutedRoleName)) { return(CustomResult.FromError("Text mute role has not been configured. Check your DB entry!")); } mutedRoleName = "voicemuted"; if (!Global.Roles.ContainsKey(mutedRoleName)) { return(CustomResult.FromError("Voice mute role has not been configured. Check your DB entry!")); } await Extensions.MuteUser(user); var muteData = new Mute { MuteDate = DateTime.Now, UnmuteDate = targetTime, MutedUser = user.Username + '#' + user.Discriminator, MutedUserID = user.Id, MutedByID = author.Id, MutedBy = author.Username + '#' + author.Discriminator, Reason = reason, MuteEnded = false }; using (var db = new Database()) { db.Mutes.Add(muteData); db.SaveChanges(); } var builder = new EmbedBuilder(); builder.Title = "A user has been muted!"; builder.Color = Color.Red; builder.Timestamp = Context.Message.Timestamp; builder.ThumbnailUrl = user.GetAvatarUrl(); const string discordUrl = "https://discordapp.com/channels/{0}/{1}/{2}"; builder.AddField("Muted User", Extensions.FormatUserName(user)) .AddField("Muted by", Extensions.FormatUserName(author)) .AddField("Location of the mute", $"[#{Context.Message.Channel.Name}]({string.Format(discordUrl, Context.Guild.Id, Context.Channel.Id, Context.Message.Id)})") .AddField("Reason", reason ?? "No reason was provided.") .AddField("Muted until", $"{ targetTime:dd.MM.yyyy HH:mm}") .AddField("Mute id", muteData.ID); await guild.GetTextChannel(Global.Channels["mutes"]).SendMessageAsync(embed: builder.Build()); // in case the mute is shorter than the timer defined in Mutetimer.cs, we better just start the unmuting process directly if (targetTime <= DateTime.Now.AddMinutes(60)) { var difference = targetTime - DateTime.Now; MuteTimerManager.UnmuteUserIn(user.Id, difference, muteData.ID); } return(CustomResult.FromSuccess()); }
public async Task <RuntimeResult> MuteUser(IGuildUser user, params string[] arguments) { if (user.IsBot) { return(CustomResult.FromError("You can't mute bots.")); } if (user.GuildPermissions.PrioritySpeaker) { return(CustomResult.FromError("You can't mute staff.")); } if (arguments.Length < 1) { return(CustomResult.FromError("The correct usage is `;mute <duration> <reason>`")); } string durationStr = arguments[0]; TimeSpan span = Extensions.GetTimeSpanFromString(durationStr); var now = DateTime.Now; DateTime targetTime = now.Add(span); string reason; if (arguments.Length > 1) { string[] reasons = new string[arguments.Length - 1]; Array.Copy(arguments, 1, reasons, 0, arguments.Length - 1); reason = string.Join(" ", reasons); } else { return(CustomResult.FromError("You need to provide a reason.")); } var author = Context.Message.Author; var guild = Context.Guild; var mutedRoleName = "textmuted"; if (!Global.Roles.ContainsKey(mutedRoleName)) { return(CustomResult.FromError("Text mute role has not been configured. Check your DB entry!")); } mutedRoleName = "voicemuted"; if (!Global.Roles.ContainsKey(mutedRoleName)) { return(CustomResult.FromError("Voice mute role has not been configured. Check your DB entry!")); } await Extensions.MuteUser(user); await user.ModifyAsync(x => x.Channel = null); try { const string muteMessage = "You were muted on r/OnePlus for the following reason: {0} until {1} {2}."; await user.SendMessageAsync(string.Format(muteMessage, reason, targetTime, TimeZoneInfo.Local)); } catch (HttpException) { Console.WriteLine("Seems like user disabled the DMs, cannot send message about the mute."); } var muteData = new Mute { MuteDate = now, UnmuteDate = targetTime, MutedUser = user.Username + '#' + user.Discriminator, MutedUserID = user.Id, MutedByID = author.Id, MutedBy = author.Username + '#' + author.Discriminator, Reason = reason, MuteEnded = false }; using (var db = new Database()) { db.Mutes.Add(muteData); db.SaveChanges(); } var builder = new EmbedBuilder(); builder.Title = "A user has been muted!"; builder.Color = Color.Red; builder.Timestamp = Context.Message.Timestamp; builder.ThumbnailUrl = user.GetAvatarUrl(); const string discordUrl = "https://discordapp.com/channels/{0}/{1}/{2}"; builder.AddField("Muted User", Extensions.FormatUserName(user)) .AddField("Muted by", Extensions.FormatUserName(author)) .AddField("Location of the mute", $"[#{Context.Message.Channel.Name}]({string.Format(discordUrl, Context.Guild.Id, Context.Channel.Id, Context.Message.Id)})") .AddField("Reason", reason ?? "No reason was provided.") .AddField("Muted until", $"{ targetTime:dd.MM.yyyy HH:mm}") .AddField("Mute id", muteData.ID); await guild.GetTextChannel(Global.PostTargets[PostTarget.MUTE_LOG]).SendMessageAsync(embed: builder.Build()); // in case the mute is shorter than the timer defined in Mutetimer.cs, we better just start the unmuting process directly if (targetTime <= DateTime.Now.AddMinutes(60)) { var difference = targetTime - DateTime.Now; MuteTimerManager.UnmuteUserIn(user.Id, difference, muteData.ID); using (var db = new Database()) { db.Mutes.Where(m => m.ID == muteData.ID).First().UnmuteScheduled = true; db.SaveChanges(); } } return(CustomResult.FromSuccess()); }
public async Task <RuntimeResult> MuteUser(IGuildUser user, string duration, [Optional][Remainder] string reason) { if (CommandHandler.FeatureFlagDisabled(FeatureFlag.MODERATION)) { return(CustomResult.FromIgnored()); } if (user.IsBot) { return(CustomResult.FromError("You can't mute bots.")); } if (user.GuildPermissions.PrioritySpeaker) { return(CustomResult.FromError("You can't mute staff.")); } TimeSpan span = Extensions.GetTimeSpanFromString(duration); var now = DateTime.Now; DateTime targetTime = now.Add(span); if (reason is null) { return(CustomResult.FromError("You need to provide a reason.")); } var author = Context.Message.Author; var guild = Context.Guild; var mutedRoleName = "textmuted"; if (!Global.Roles.ContainsKey(mutedRoleName)) { return(CustomResult.FromError("Text mute role has not been configured. Check your DB entry!")); } mutedRoleName = "voicemuted"; if (!Global.Roles.ContainsKey(mutedRoleName)) { return(CustomResult.FromError("Voice mute role has not been configured. Check your DB entry!")); } await Extensions.MuteUser(user); await user.ModifyAsync(x => x.Channel = null); try { const string muteMessage = "You were muted on r/OnePlus for the following reason: {0} until {1}."; await user.SendMessageAsync(string.Format(muteMessage, reason, Extensions.FormatDateTime(targetTime))); } catch (HttpException) { await Context.Channel.SendMessageAsync("Seems like user disabled DMs, cannot send message about the mute."); } var muteData = new Mute { MuteDate = now, UnmuteDate = targetTime, MutedUserID = user.Id, MutedByID = author.Id, Reason = reason, MuteEnded = false }; using (var db = new Database()) { db.Mutes.Add(muteData); db.SaveChanges(); } var builder = new EmbedBuilder(); builder.Title = "A user has been muted!"; builder.Color = Color.Red; builder.Timestamp = Context.Message.Timestamp; builder.ThumbnailUrl = user.GetAvatarUrl(); const string discordUrl = "https://discord.com/channels/{0}/{1}/{2}"; builder.AddField("Muted User", Extensions.FormatUserNameDetailed(user)) .AddField("Muted by", Extensions.FormatUserNameDetailed(author)) .AddField("Location of the mute", $"[#{Context.Message.Channel.Name}]({string.Format(discordUrl, Context.Guild.Id, Context.Channel.Id, Context.Message.Id)})") .AddField("Reason", reason ?? "No reason was provided.") .AddField("Mute duration", Extensions.FormatTimeSpan(span)) .AddField("Muted until", $"{ Extensions.FormatDateTime(targetTime)}") .AddField("Mute id", muteData.ID); await guild.GetTextChannel(Global.PostTargets[PostTarget.MUTE_LOG]).SendMessageAsync(embed: builder.Build()); // in case the mute is shorter than the timer defined in Mutetimer.cs, we better just start the unmuting process directly if (targetTime <= DateTime.Now.AddMinutes(60)) { var difference = targetTime - DateTime.Now; MuteTimerManager.UnmuteUserIn(user.Id, difference, muteData.ID); using (var db = new Database()) { db.Mutes.AsQueryable().Where(m => m.ID == muteData.ID).First().UnmuteScheduled = true; db.SaveChanges(); } } return(CustomResult.FromSuccess()); }