public async Task <CommandResult> SetThresholdAction([IsntActionType(ActionType.Unban, ActionType.Unmute, ActionType.Unwarn, ActionType.Warn, ActionType.HackBan)] ActionType value, TimeSpan?expiry = null) { var g = await _databaseService.GetOrCreateGuildAsync(Context.Guild); if (value == g.WarnThresholdActionType && ((expiry != null && (int)expiry.Value.TotalSeconds == g.WarnThresholdActionExpiry) || (expiry == null && g.WarnThresholdActionExpiry == 0))) { return(new QuiccbanFailResult(string.Format(_responseService.Get("warn_threshold_already_same"), value))); } if ((value == ActionType.TempBan || value == ActionType.TempMute) && expiry == null) { return(new QuiccbanFailResult(string.Format(_responseService.Get("temp_action_require_time")))); } g.WarnThresholdActionType = value; g.WarnThresholdActionExpiry = expiry != null ? (int)expiry?.TotalSeconds : 0; await _databaseService.UpdateGuildAsync(g); return(new QuiccbanSuccessResult(string.Format(_responseService.Get("warn_threshold_action_success"), value, expiry == null ? "no expiry" : expiry.Value.Humanize(4) + " expiry"))); }
public async Task <Case> CreateNewCaseAsync(IGuild guild, string reason, ActionType actionType, int actionExpiry, IUser issuer, IUser target, bool doLock = true, int tiedDo = 0) { if (doLock) { await databaseLock.WaitAsync(); } try { var currentUser = await guild.GetCurrentUserAsync(); if (!currentUser.GuildPermissions.BanMembers || !currentUser.GuildPermissions.ManageRoles || !currentUser.GuildPermissions.KickMembers || !currentUser.GuildPermissions.ManageChannels) { throw new InvalidOperationException("Don't have enough permissions."); } using (var guildStorage = new GuildStorage()) { var dbGuild = await guildStorage.GetOrCreateGuildAsync(guild.Id); if (dbGuild.ModlogChannelId == 0) { throw new InvalidOperationException("Can't create a new case without a log channel."); } var issuerId = issuer.Id; var targetId = target.Id; Case @case = new Case { Reason = reason, ActionType = actionType, IssuerId = issuerId, TargetId = targetId, ActionExpiry = actionExpiry, UnixTimestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), ForceResolved = false, Id = dbGuild.Cases.LastOrDefault() == null ? 1 : dbGuild.Cases.LastOrDefault().Id + 1, TiedTo = tiedDo }; switch (actionType) { case ActionType.Warn: case ActionType.TempBan: case ActionType.TempMute: @case.Resolved = false; break; default: @case.Resolved = true; break; } dbGuild.Cases.Add(@case); guildStorage.Update(dbGuild); await guildStorage.SaveChangesAsync(); var latestCase = dbGuild.Cases.LastOrDefault(); var discordService = _serviceProvider.GetService <DiscordService>(); var logChannel = discordService.discordClient.GetChannel(dbGuild.ModlogChannelId) as SocketTextChannel; if (logChannel == null) { throw new InvalidOperationException("Can't log to a channel that doesn't exist"); } IUserMessage msg = null; switch (dbGuild.LogStyle) { case LogStyle.Basic: msg = await logChannel.SendMessageAsync(await _helperService.ConstructCaseMessageAsync(latestCase)); break; case LogStyle.Modern: var eb = new EmbedBuilder(); eb.WithTitle($"Case **{latestCase.Id}** » {latestCase.ActionType.Humanize()}"); eb.WithDescription(await _helperService.ConstructCaseMessageAsync(latestCase)); msg = await logChannel.SendMessageAsync(embed : eb.Build()); break; } latestCase.DiscordMessageId = msg.Id; guildStorage.Update(dbGuild); await guildStorage.SaveChangesAsync(); if (latestCase.ActionType == ActionType.Warn || latestCase.ActionExpiry > 0) { _caseHandlingService.TryAdd(latestCase); } if (actionType == ActionType.Warn) { if (dbGuild.Cases.Count(x => !x.Resolved && x.ActionType == ActionType.Warn && x.TargetId == targetId) > dbGuild.WarnThreshold) { if (!dbGuild.Cases.Any(x => !x.Resolved && x.ActionType == dbGuild.WarnThresholdActionType)) { _ = Task.Delay(100).ContinueWith(async _ => { await databaseLock.WaitAsync(); try { currentUser = await guild.GetCurrentUserAsync(); if (!currentUser.GuildPermissions.BanMembers || !currentUser.GuildPermissions.ManageRoles || !currentUser.GuildPermissions.KickMembers || !currentUser.GuildPermissions.ManageChannels) { throw new InvalidOperationException("Don't have enough permissions."); } var socketguild = discordService.discordClient.GetGuild(guild.Id); var user = socketguild.GetUser(targetId); switch (dbGuild.WarnThresholdActionType) { case ActionType.Mute: case ActionType.TempMute: IRole muteRole = socketguild.GetRole(dbGuild.MuteRoleId); if (muteRole == null) { muteRole = await _helperService.CreateMuteRoleAsync(dbGuild, false); } await user.AddRoleAsync(muteRole); break; case ActionType.Ban: case ActionType.TempBan: await user.BanAsync(0, "Warn threshold crossed."); break; case ActionType.Kick: await user.KickAsync("Warn threshold crossed."); break; default: break; } await CreateNewCaseAsync(guild, "Warn threshold crossed.", dbGuild.WarnThresholdActionType, dbGuild.WarnThresholdActionExpiry, discordService.discordClient.CurrentUser, target, false); } finally { databaseLock.Release(); } }); } } } _ = Task.Run(async() => { await _serviceProvider.GetService <IHubContext <SocketHub> >().Clients.All.SendAsync("NEW_CASE", new APICase(latestCase, new User(target), new User(issuer))); }); return(latestCase); } } finally { if (doLock) { databaseLock.Release(); } } }
public Task <CommandResult> HistoryAsync(SocketGuildUser u, [IsntActionType(ActionType.None)] ActionType type = default, bool onlyActive = false) => HistoryAsync(u, onlyActive, type);
public async Task <CommandResult> HistoryAsync(SocketGuildUser u, bool onlyActive = false, [IsntActionType(ActionType.None)] ActionType type = default) { try { var dbGuild = await _databaseService.GetOrCreateGuildAsync(Context.Guild); var history = type == default ? dbGuild.Cases.Where(x => x.TargetId == u.Id) : dbGuild.Cases.Where(x => x.TargetId == u.Id && x.ActionType == type); history = onlyActive ? history.Where(x => !x.Resolved) : history; Console.WriteLine("aaa"); if (!history.Any()) { return(new QuiccbanFailResult(string.Format(_responseService.Get("history_no_cases"), u.ToString(), u.Mention, onlyActive ? "active " : ""))); } Console.WriteLine("bbb"); List <Embed> embeds = new List <Embed>(); var historyGrouping = history.OrderByDescending(x => x.Id).Select((@case, index) => new { Case = @case, Index = index }).GroupBy(x => x.Index / 5, x => x.Case); foreach (var group in historyGrouping) { embeds.Add(await _helperService.ConstructHistoryEmbedAsync(group, u)); } if (embeds.Count > 1) { var paginatedMessage = new PaginatedMessage { Pages = embeds }; var criterion = new Criteria <SocketReaction>(); criterion.AddCriterion(new EnsureReactionFromSourceUserCriterion()); await _interactiveService.SendPaginatedMessageAsync(Context, paginatedMessage, criterion); } else { await ReplyAsync(embed : embeds.FirstOrDefault()); } return(new QuiccbanSuccessResult()); } catch (Exception e) { Console.WriteLine(e); return(new QuiccbanSuccessResult()); } }