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(); } } }
public async Task <List <Guild> > GetAllGuildsAsync() { await databaseLock.WaitAsync(); try { using (var guildStorage = new GuildStorage()) { return(await guildStorage.GetAllGuildsAsync()); } } finally { databaseLock.Release(); } }
public async Task <Guild> GetOrCreateGuildAsync(ulong guildId) { await databaseLock.WaitAsync(); try { using (var guildStorage = new GuildStorage()) { return(await guildStorage.GetOrCreateGuildAsync(guildId)); } } finally { databaseLock.Release(); } }
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(); }
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(); } } }
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 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"); } }); }
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); } }
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; } } }