Esempio n. 1
0
        public async Task <Guild> GetOrCreateGuildAsync(ulong guildId)
        {
            await databaseLock.WaitAsync();

            try
            {
                using (var guildStorage = new GuildStorage())
                {
                    return(await guildStorage.GetOrCreateGuildAsync(guildId));
                }
            }
            finally
            {
                databaseLock.Release();
            }
        }
Esempio n. 2
0
        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();
                }
            }
        }
Esempio n. 3
0
        private async Task Resolve(ulong guildId, int caseId, bool isInmemory, bool force, bool doLock = true)
        {
            using (var guildStorage = new GuildStorage())
            {
                if (isInmemory)
                {
                    var c = InmemoryExpiringCases.FirstOrDefault(x => x.Key.Id == caseId && x.Key.GuildId == guildId);
                    InmemoryExpiringCases.Remove(c.Key, out CancellationTokenSource cts);
                    cts.Dispose();
                }

                var discordService = _serviceProvider.GetService <DiscordService>();

                var guild = discordService.discordClient.GetGuild(guildId);
                if (guild == null)
                {
                    throw new NullReferenceException("Unknown guild.");
                }

                var currentUser = guild.CurrentUser;

                if (!currentUser.GuildPermissions.BanMembers || !currentUser.GuildPermissions.ManageRoles || !currentUser.GuildPermissions.KickMembers || !currentUser.GuildPermissions.ManageChannels)
                {
                    throw new InvalidOperationException("Don't have enough permissions.");
                }


                var dbService     = _serviceProvider.GetService <DatabaseService>();
                var helperService = _serviceProvider.GetService <HelperService>();


                var dbguild = await guildStorage.GetOrCreateGuildAsync(guildId);

                var guildCase = dbguild.Cases.FirstOrDefault(x => x.Id == caseId);

                guildCase.Resolved = true;
                if (force)
                {
                    guildCase.ForceResolved = true;
                }

                await dbService.UpdateCaseAsync(guildCase, doLock);

                var target = guild.GetUser(guildCase.TargetId) ?? (IUser)(await discordService.discordClient.Rest.GetUserAsync(guildCase.TargetId));

                switch (guildCase.ActionType)
                {
                case ActionType.Warn:
                    await UpdateDiscordMessage(guildCase);

                    await dbService.CreateNewCaseAsync(guild, "Warn expired.", ActionType.Unwarn, 0, discordService.discordClient.CurrentUser, target, doLock, guildCase.Id);

                    break;

                case ActionType.TempMute:
                    await UpdateDiscordMessage(guildCase);

                    IRole muteRole = guild.GetRole(dbguild.MuteRoleId);
                    if (muteRole != null)
                    {
                        if (target is SocketGuildUser guildTarget)
                        {
                            await guildTarget.RemoveRoleAsync(muteRole);
                        }
                    }

                    await dbService.CreateNewCaseAsync(guild, "Temporary mute expired.", ActionType.Unmute, 0, discordService.discordClient.CurrentUser, target, doLock, guildCase.Id);

                    break;

                case ActionType.TempBan:
                    await UpdateDiscordMessage(guildCase);

                    await dbService.CreateNewCaseAsync(guild, "Temporary ban expired.", ActionType.Unban, 0, discordService.discordClient.CurrentUser, target, doLock);

                    break;

                default:
                    break;
                }
            }
        }