Esempio n. 1
0
        public async Task UpdateCaseAsync(Case @case, bool doLock)
        {
            if (doLock)
            {
                await databaseLock.WaitAsync();
            }
            try
            {
                using (var guildStorage = new GuildStorage())
                {
                    var guildCase = @case.Guild.Cases.FirstOrDefault(x => x.Id == @case.Id);

                    guildCase = @case;

                    guildStorage.Update(@case.Guild);

                    await guildStorage.SaveChangesAsync();
                }
            }
            finally
            {
                if (doLock)
                {
                    databaseLock.Release();
                }
            }
        }
Esempio n. 2
0
        public async Task <List <Guild> > GetAllGuildsAsync()
        {
            await databaseLock.WaitAsync();

            try
            {
                using (var guildStorage = new GuildStorage())
                {
                    return(await guildStorage.GetAllGuildsAsync());
                }
            }
            finally
            {
                databaseLock.Release();
            }
        }
Esempio n. 3
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. 4
0
        public Guild(MySqlDataReader reader, MySqlConnection con)
        {
            ID   = reader.GetInt32("ID");
            Name = reader.GetString("GuildName");
            // _Password = (byte[])reader.GetValue("Password");
            _Password         = new byte[12];
            AllowGuildWar     = reader.GetBoolean("AllowGuildWar");
            Message           = reader.GetString("GuildMessage");
            MessageCreateTime = reader.GetDateTime(8);
            MessageCreaterID  = reader.GetInt32("CreaterID");
            CreateTime        = DateTime.Now;//read later
            GuildMoney        = reader.GetInt64("GuildMoney");

            Members      = new List <GuildMember>();
            ThreadLocker = new object();
            GuildStore   = new GuildStorage(this);
            Load();
        }
Esempio n. 5
0
        public async Task UpdateGuildAsync(Guild guild, bool doLock = true)
        {
            if (doLock)
            {
                await databaseLock.WaitAsync();
            }
            try
            {
                using (var guildStorage = new GuildStorage())
                {
                    guildStorage.Update(guild);

                    await guildStorage.SaveChangesAsync();
                }
            }
            finally
            {
                if (doLock)
                {
                    databaseLock.Release();
                }
            }
        }
Esempio n. 6
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. 7
0
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            try
            {
                using (var guildStorage = new GuildStorage())
                {
                    Logger.LogInformation("Ensuring database is created.");
                    guildStorage.Database.EnsureCreated();
                    Logger.LogInformation("Success.");
                }
            }
            catch
            {
                Logger.LogCritical("Failed to generate/load database. Exiting.");
                Environment.Exit(0);
            }

            app.ApplicationServices.GetService <DiscordService>();

            var options = new ForwardedHeadersOptions
            {
                ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
            };

            app.UseForwardedHeaders(options);

            app.UseAuthentication();
            app.UseResponseCompression();

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
            }

            app.UseStaticFiles();
            app.UseSpaStaticFiles();


            app.UseSignalR(routes =>
            {
                routes.MapHub <SocketHub>("/api/ws");
            });

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller}/{action=Index}/{id?}");
            });



            app.UseSpa(spa =>
            {
                spa.Options.SourcePath = "ClientApp";

                if (env.IsDevelopment())
                {
                    spa.UseReactDevelopmentServer(npmScript: "start");
                }
            });
        }
Esempio n. 8
0
        public async Task ResolveAsync(Case guildCase, IUser resolver, string reason, bool force, bool doLock)
        {
            if (resolver != null)
            {
                var inmem = InmemoryExpiringCases.FirstOrDefault(x => x.Key.Id == guildCase.Id && x.Key.GuildId == guildCase.GuildId);
                if (inmem.Key == null)
                {
                    return;
                }

                if (!InmemoryExpiringCases.TryRemove(inmem.Key, out CancellationTokenSource cts))
                {
                    return;
                }

                cts.Cancel();
                cts.Dispose();


                using (var guildStorage = new GuildStorage())
                {
                    var discordService = _serviceProvider.GetService <DiscordService>();

                    var guild = discordService.discordClient.GetGuild(guildCase.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 config        = _serviceProvider.GetService <Config>();


                    guildCase.Resolved      = true;
                    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, reason, ActionType.Unwarn, 0, resolver, target, doLock, guildCase.Id);

                        break;

                    case ActionType.TempMute:
                    case ActionType.Mute:
                        await UpdateDiscordMessage(guildCase);

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

                        await dbService.CreateNewCaseAsync(guild, reason, ActionType.Unmute, 0, resolver, target, doLock, guildCase.Id);

                        break;

                    case ActionType.TempBan:
                    case ActionType.Ban:
                    case ActionType.HackBan:
                        var bans = await guild.GetBansAsync();

                        if (bans.Any(x => x.User.Id == guildCase.TargetId))
                        {
                            await guild.RemoveBanAsync(guildCase.TargetId);
                        }
                        await UpdateDiscordMessage(guildCase);

                        await dbService.CreateNewCaseAsync(guild, reason, ActionType.Unban, 0, resolver, target, doLock, guildCase.Id);

                        break;

                    default:
                        break;
                    }
                }
            }
            else
            {
                await Resolve(guildCase.GuildId, guildCase.Id, false, force, doLock);
            }
        }
Esempio n. 9
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;
                }
            }
        }