diff --git a/src/NadekoBot/Migrations/20160825184527_first.Designer.cs b/src/NadekoBot/Migrations/20160826172044_first.Designer.cs similarity index 88% rename from src/NadekoBot/Migrations/20160825184527_first.Designer.cs rename to src/NadekoBot/Migrations/20160826172044_first.Designer.cs index 67cccb93..fa569835 100644 --- a/src/NadekoBot/Migrations/20160825184527_first.Designer.cs +++ b/src/NadekoBot/Migrations/20160826172044_first.Designer.cs @@ -8,7 +8,7 @@ using NadekoBot.Services.Database.Impl; namespace NadekoBot.Migrations { [DbContext(typeof(NadekoSqliteContext))] - [Migration("20160825184527_first")] + [Migration("20160826172044_first")] partial class first { protected override void BuildTargetModel(ModelBuilder modelBuilder) @@ -92,6 +92,8 @@ namespace NadekoBot.Migrations b.Property("AutoDeleteGreetMessagesTimer"); + b.Property("AutoDeleteSelfAssignedRoleMessages"); + b.Property("ByeMessageChannelId"); b.Property("ChannelByeMessageText"); @@ -102,6 +104,8 @@ namespace NadekoBot.Migrations b.Property("DmGreetMessageText"); + b.Property("ExclusiveSelfAssignedRoles"); + b.Property("GreetMessageChannelId"); b.Property("GuildId"); @@ -165,6 +169,23 @@ namespace NadekoBot.Migrations b.ToTable("Reminders"); }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.SelfAssignedRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("GuildId"); + + b.Property("RoleId"); + + b.HasKey("Id"); + + b.HasIndex("GuildId", "RoleId") + .IsUnique(); + + b.ToTable("SelfAssignableRoles"); + }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.ClashCaller", b => { b.HasOne("NadekoBot.Services.Database.Models.ClashWar", "ClashWar") diff --git a/src/NadekoBot/Migrations/20160825184527_first.cs b/src/NadekoBot/Migrations/20160826172044_first.cs similarity index 86% rename from src/NadekoBot/Migrations/20160825184527_first.cs rename to src/NadekoBot/Migrations/20160826172044_first.cs index 0ebda92c..6c8e4660 100644 --- a/src/NadekoBot/Migrations/20160825184527_first.cs +++ b/src/NadekoBot/Migrations/20160826172044_first.cs @@ -51,11 +51,13 @@ namespace NadekoBot.Migrations AutoDeleteByeMessages = table.Column(nullable: false), AutoDeleteGreetMessages = table.Column(nullable: false), AutoDeleteGreetMessagesTimer = table.Column(nullable: false), + AutoDeleteSelfAssignedRoleMessages = table.Column(nullable: false), ByeMessageChannelId = table.Column(nullable: false), ChannelByeMessageText = table.Column(nullable: true), ChannelGreetMessageText = table.Column(nullable: true), DeleteMessageOnCommand = table.Column(nullable: false), DmGreetMessageText = table.Column(nullable: true), + ExclusiveSelfAssignedRoles = table.Column(nullable: false), GreetMessageChannelId = table.Column(nullable: false), GuildId = table.Column(nullable: false), SendChannelByeMessage = table.Column(nullable: false), @@ -102,6 +104,20 @@ namespace NadekoBot.Migrations table.PrimaryKey("PK_Reminders", x => x.Id); }); + migrationBuilder.CreateTable( + name: "SelfAssignableRoles", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Autoincrement", true), + GuildId = table.Column(nullable: false), + RoleId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_SelfAssignableRoles", x => x.Id); + }); + migrationBuilder.CreateTable( name: "ClashCallers", columns: table => new @@ -141,6 +157,12 @@ namespace NadekoBot.Migrations table: "GuildConfigs", column: "GuildId", unique: true); + + migrationBuilder.CreateIndex( + name: "IX_SelfAssignableRoles_GuildId_RoleId", + table: "SelfAssignableRoles", + columns: new[] { "GuildId", "RoleId" }, + unique: true); } protected override void Down(MigrationBuilder migrationBuilder) @@ -160,6 +182,9 @@ namespace NadekoBot.Migrations migrationBuilder.DropTable( name: "Reminders"); + migrationBuilder.DropTable( + name: "SelfAssignableRoles"); + migrationBuilder.DropTable( name: "ClashOfClans"); } diff --git a/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs b/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs index fe3144fd..5ea3a8d4 100644 --- a/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs +++ b/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs @@ -91,6 +91,8 @@ namespace NadekoBot.Migrations b.Property("AutoDeleteGreetMessagesTimer"); + b.Property("AutoDeleteSelfAssignedRoleMessages"); + b.Property("ByeMessageChannelId"); b.Property("ChannelByeMessageText"); @@ -101,6 +103,8 @@ namespace NadekoBot.Migrations b.Property("DmGreetMessageText"); + b.Property("ExclusiveSelfAssignedRoles"); + b.Property("GreetMessageChannelId"); b.Property("GuildId"); @@ -164,6 +168,23 @@ namespace NadekoBot.Migrations b.ToTable("Reminders"); }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.SelfAssignedRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("GuildId"); + + b.Property("RoleId"); + + b.HasKey("Id"); + + b.HasIndex("GuildId", "RoleId") + .IsUnique(); + + b.ToTable("SelfAssignableRoles"); + }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.ClashCaller", b => { b.HasOne("NadekoBot.Services.Database.Models.ClashWar", "ClashWar") diff --git a/src/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs b/src/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs index 0f50af71..9ff16258 100644 --- a/src/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs +++ b/src/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs @@ -27,7 +27,7 @@ namespace NadekoBot.Modules.Administration _client.MessageReceived += async (imsg) => { - var channel = (ITextChannel)imsg.Channel; + var channel = imsg.Channel as ITextChannel; if (channel == null || await imsg.IsAuthor()) return; diff --git a/src/NadekoBot/Modules/Administration/Commands/SelfAssignedRolesCommand.cs b/src/NadekoBot/Modules/Administration/Commands/SelfAssignedRolesCommand.cs index 7171a63d..62367330 100644 --- a/src/NadekoBot/Modules/Administration/Commands/SelfAssignedRolesCommand.cs +++ b/src/NadekoBot/Modules/Administration/Commands/SelfAssignedRolesCommand.cs @@ -1,207 +1,232 @@ -//using Discord.Commands; -//using Discord.Net; -//using NadekoBot.Classes; -//using NadekoBot.Modules.Permissions.Classes; -//using System; -//using System.Collections.Generic; -//using System.Linq; -//using System.Text; -//using System.Threading.Tasks; -////todo DB -//namespace NadekoBot.Modules.Administration -//{ -// internal class SelfAssignedRolesCommand : DiscordCommand -// { -// public SelfAssignedRolesCommand(DiscordModule module) : base(module) { } -// internal override void Init(CommandGroupBuilder cgb) -// { -// cgb.CreateCommand(Module.Prefix + "asar") -// .Description("Adds a role, or list of roles separated by whitespace" + -// $"(use quotations for multiword roles) to the list of self-assignable roles. **Needs Manage Roles Permissions.**| `{Prefix}asar Gamer`") -// .Parameter("roles", ParameterType.Multiple) -// .AddCheck(SimpleCheckers.CanManageRoles) -// .Do(async e => -// { -// var config = SpecificConfigurations.Default.Of(e.Server.Id); -// var msg = new StringBuilder(); -// foreach (var arg in e.Args) -// { -// var role = e.Server.FindRoles(arg.Trim()).FirstOrDefault(); -// if (role == null) -// msg.AppendLine($":anger:Role **{arg}** not found."); -// else -// { -// if (config.ListOfSelfAssignableRoles.Contains(role.Id)) -// { -// msg.AppendLine($":anger:Role **{role.Name}** is already in the list."); -// continue; -// } -// config.ListOfSelfAssignableRoles.Add(role.Id); -// msg.AppendLine($":ok:Role **{role.Name}** added to the list."); -// } -// } -// await channel.SendMessageAsync(msg.ToString()).ConfigureAwait(false); -// }); +using Discord; +using Discord.Commands; +using Discord.Net; +using NadekoBot.Attributes; +using NadekoBot.Services; +using NadekoBot.Services.Database; +using NadekoBot.Services.Database.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +//todo DB +namespace NadekoBot.Modules.Administration +{ + public partial class Administration + { + [Group] + public class SelfAssignedRolesCommands + { -// cgb.CreateCommand(Module.Prefix + "rsar") -// .Description($"Removes a specified role from the list of self-assignable roles. | `{Prefix}rsar`") -// .Parameter("role", ParameterType.Unparsed) -// .AddCheck(SimpleCheckers.CanManageRoles) -// .Do(async e => -// { -// var roleName = role?.Trim(); -// if (string.IsNullOrWhiteSpace(roleName)) -// return; -// var role = e.Server.FindRoles(roleName).FirstOrDefault(); -// if (role == null) -// { -// await channel.SendMessageAsync(":anger:That role does not exist.").ConfigureAwait(false); -// return; -// } -// var config = SpecificConfigurations.Default.Of(e.Server.Id); -// if (!config.ListOfSelfAssignableRoles.Contains(role.Id)) -// { -// await channel.SendMessageAsync(":anger:That role is not self-assignable.").ConfigureAwait(false); -// return; -// } -// config.ListOfSelfAssignableRoles.Remove(role.Id); -// await channel.SendMessageAsync($":ok:**{role.Name}** has been removed from the list of self-assignable roles").ConfigureAwait(false); -// }); + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + [RequirePermission(GuildPermission.ManageRoles)] + public async Task Asar(IMessage imsg, [Remainder] IRole role) + { + var channel = (ITextChannel)imsg.Channel; -// cgb.CreateCommand(Module.Prefix + "lsar") -// .Description($"Lists all self-assignable roles. | `{Prefix}lsar`") -// .Parameter("roles", ParameterType.Multiple) -// .Do(async e => -// { -// var config = SpecificConfigurations.Default.Of(e.Server.Id); -// var msg = new StringBuilder($"There are `{config.ListOfSelfAssignableRoles.Count}` self assignable roles:\n"); -// var toRemove = new HashSet(); -// foreach (var roleId in config.ListOfSelfAssignableRoles.OrderBy(r => r.ToString())) -// { -// var role = e.Server.GetRole(roleId); -// if (role == null) -// { -// msg.Append($"`{roleId} not found. Cleaned up.`, "); -// toRemove.Add(roleId); -// } -// else -// { -// msg.Append($"**{role.Name}**, "); -// } -// } -// foreach (var id in toRemove) -// { -// config.ListOfSelfAssignableRoles.Remove(id); -// } -// await channel.SendMessageAsync(msg.ToString()).ConfigureAwait(false); -// }); + IEnumerable roles; + string msg; + using (var uow = DbHandler.UnitOfWork()) + { + roles = uow.SelfAssignedRoles.GetFromGuild(channel.Guild.Id); + if (roles.Any(s => s.RoleId == role.Id && s.GuildId == role.GuildId)) + { + msg = $":anger:Role **{role.Name}** is already in the list."; + } + else + { + uow.SelfAssignedRoles.Add(new SelfAssignedRole { + RoleId = role.Id, + GuildId = role.GuildId + }); + await uow.CompleteAsync(); + msg = $":ok:Role **{role.Name}** added to the list."; + } + } + await channel.SendMessageAsync(msg.ToString()).ConfigureAwait(false); + } + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + [RequirePermission(GuildPermission.ManageRoles)] + public async Task Rsar(IMessage imsg, [Remainder] IRole role) + { + var channel = (ITextChannel)imsg.Channel; -// cgb.CreateCommand(Module.Prefix + "togglexclsar").Alias(Module.Prefix + "tesar") -// .Description($"toggle whether the self-assigned roles should be exclusive | `{Prefix}tesar`") -// .AddCheck(SimpleCheckers.CanManageRoles) -// .Do(async e => -// { -// var config = SpecificConfigurations.Default.Of(e.Server.Id); -// config.ExclusiveSelfAssignedRoles = !config.ExclusiveSelfAssignedRoles; -// string exl = config.ExclusiveSelfAssignedRoles ? "exclusive" : "not exclusive"; -// await channel.SendMessageAsync("Self assigned roles are now " + exl); -// }); + bool success; + using (var uow = DbHandler.UnitOfWork()) + { + success = uow.SelfAssignedRoles.DeleteByGuildAndRoleId(role.GuildId, role.Id); + await uow.CompleteAsync(); + } + if (success) + { + await channel.SendMessageAsync(":anger:That role is not self-assignable.").ConfigureAwait(false); + return; + } + await channel.SendMessageAsync($":ok:**{role.Name}** has been removed from the list of self-assignable roles").ConfigureAwait(false); + } -// cgb.CreateCommand(Module.Prefix + "iam") -// .Description("Adds a role to you that you choose. " + -// "Role must be on a list of self-assignable roles." + -// $" | `{Prefix}iam Gamer`") -// .Parameter("role", ParameterType.Unparsed) -// .Do(async e => -// { -// var roleName = role?.Trim(); -// if (string.IsNullOrWhiteSpace(roleName)) -// return; -// var role = e.Server.FindRoles(roleName).FirstOrDefault(); -// if (role == null) -// { -// await channel.SendMessageAsync(":anger:That role does not exist.").ConfigureAwait(false); -// return; -// } -// var config = SpecificConfigurations.Default.Of(e.Server.Id); -// if (!config.ListOfSelfAssignableRoles.Contains(role.Id)) -// { -// await channel.SendMessageAsync(":anger:That role is not self-assignable.").ConfigureAwait(false); -// return; -// } -// if (imsg.Author.HasRole(role)) -// { -// await channel.SendMessageAsync($":anger:You already have {role.Name} role.").ConfigureAwait(false); -// return; -// } -// var sameRoles = imsg.Author.Roles.Where(r => config.ListOfSelfAssignableRoles.Contains(r.Id)); -// if (config.ExclusiveSelfAssignedRoles && sameRoles.Any()) -// { -// await channel.SendMessageAsync($":anger:You already have {sameRoles.FirstOrDefault().Name} role.").ConfigureAwait(false); -// return; -// } -// try -// { -// await imsg.Author.AddRoles(role).ConfigureAwait(false); -// } -// catch (HttpException ex) when (ex.StatusCode == System.Net.HttpStatusCode.InternalServerError) -// { -// } -// catch (Exception ex) -// { -// await channel.SendMessageAsync($":anger:`I am unable to add that role to you. I can't add roles to owners or other roles higher than my role in the role hierarchy.`").ConfigureAwait(false); -// return; -// } -// var msg = await channel.SendMessageAsync($":ok:You now have {role.Name} role.").ConfigureAwait(false); -// await Task.Delay(3000).ConfigureAwait(false); -// await msg.Delete().ConfigureAwait(false); -// try -// { -// await e.Message.Delete().ConfigureAwait(false); -// } -// catch { } -// }); + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + public async Task Lsar(IMessage imsg) + { + var channel = (ITextChannel)imsg.Channel; -// cgb.CreateCommand(Module.Prefix + "iamnot") -// .Alias(Module.Prefix + "iamn") -// .Description("Removes a role to you that you choose. " + -// "Role must be on a list of self-assignable roles." + -// $" | `{Prefix}iamn Gamer`") -// .Parameter("role", ParameterType.Unparsed) -// .Do(async e => -// { -// var roleName = role?.Trim(); -// if (string.IsNullOrWhiteSpace(roleName)) -// return; -// var role = e.Server.FindRoles(roleName).FirstOrDefault(); -// if (role == null) -// { -// await channel.SendMessageAsync(":anger:That role does not exist.").ConfigureAwait(false); -// return; -// } -// var config = SpecificConfigurations.Default.Of(e.Server.Id); -// if (!config.ListOfSelfAssignableRoles.Contains(role.Id)) -// { -// await channel.SendMessageAsync(":anger:That role is not self-assignable.").ConfigureAwait(false); -// return; -// } -// if (!imsg.Author.HasRole(role)) -// { -// await channel.SendMessageAsync($":anger:You don't have {role.Name} role.").ConfigureAwait(false); -// return; -// } -// await imsg.Author.RemoveRoles(role).ConfigureAwait(false); -// var msg = await channel.SendMessageAsync($":ok:Successfuly removed {role.Name} role from you.").ConfigureAwait(false); -// await Task.Delay(3000).ConfigureAwait(false); -// await msg.Delete().ConfigureAwait(false); -// try -// { -// await e.Message.Delete().ConfigureAwait(false); -// } -// catch { } -// }); -// } -// } -//} + var toRemove = new HashSet(); + var removeMsg = new StringBuilder(); + var msg = new StringBuilder(); + using (var uow = DbHandler.UnitOfWork()) + { + var roleModels = uow.SelfAssignedRoles.GetFromGuild(channel.Guild.Id); + msg.AppendLine($"There are `{roleModels.Count()}` self assignable roles:"); + + foreach (var roleModel in roleModels) + { + var role = channel.Guild.Roles.FirstOrDefault(r => r.Id == roleModel.RoleId); + if (role == null) + { + uow.SelfAssignedRoles.Remove(roleModel); + } + else + { + msg.Append($"**{role.Name}**, "); + } + } + foreach (var role in toRemove) + { + removeMsg.AppendLine($"`{role.RoleId} not found. Cleaned up.`"); + } + await uow.CompleteAsync(); + } + await channel.SendMessageAsync(msg.ToString() + "\n\n" + removeMsg.ToString()).ConfigureAwait(false); + } + + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + [RequirePermission(GuildPermission.ManageRoles)] + public async Task Tesar(IMessage imsg) + { + var channel = (ITextChannel)imsg.Channel; + + bool areExclusive; + using (var uow = DbHandler.UnitOfWork()) + { + var config = uow.GuildConfigs.For(channel.Guild.Id); + + areExclusive = config.ExclusiveSelfAssignedRoles = !config.ExclusiveSelfAssignedRoles; + await uow.CompleteAsync(); + } + string exl = areExclusive ? "exclusive." : "not exclusive."; + await channel.SendMessageAsync("Self assigned roles are now " + exl); + } + + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + public async Task Iam(IMessage imsg, [Remainder] IRole role) + { + var channel = (ITextChannel)imsg.Channel; + var guildUser = (IGuildUser)imsg.Author; + + GuildConfig conf; + IEnumerable roles; + using (var uow = DbHandler.UnitOfWork()) + { + conf = uow.GuildConfigs.For(channel.Guild.Id); + roles = uow.SelfAssignedRoles.GetFromGuild(channel.Guild.Id); + } + SelfAssignedRole roleModel; + if ((roleModel = roles.FirstOrDefault(r=>r.RoleId == role.Id)) == null) + { + await channel.SendMessageAsync(":anger:That role is not self-assignable.").ConfigureAwait(false); + return; + } + if (guildUser.Roles.Contains(role)) + { + await channel.SendMessageAsync($":anger:You already have {role.Name} role.").ConfigureAwait(false); + return; + } + + if (conf.ExclusiveSelfAssignedRoles) + { + var sameRoles = guildUser.Roles.Where(r => roles.Any(rm => rm.RoleId == r.Id)); + if (sameRoles.Any()) + { + await channel.SendMessageAsync($":anger:You already have {sameRoles.FirstOrDefault().Name} exclusive self-assigned role.").ConfigureAwait(false); + return; + } + } + try + { + await guildUser.AddRolesAsync(role).ConfigureAwait(false); + } + catch (Exception) + { + await channel.SendMessageAsync($":anger:`I am unable to add that role to you. I can't add roles to owners or other roles higher than my role in the role hierarchy.`").ConfigureAwait(false); + return; + } + var msg = await channel.SendMessageAsync($":ok:You now have {role.Name} role.").ConfigureAwait(false); + + if (conf.AutoDeleteSelfAssignedRoleMessages) + { + var t = Task.Run(async () => + { + await Task.Delay(3000).ConfigureAwait(false); + try { await msg.DeleteAsync().ConfigureAwait(false); } catch { } // if 502 or something, i don't want bot crashing + try { await imsg.DeleteAsync().ConfigureAwait(false); } catch { } + }); + } + } + + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + public async Task Iamnot(IMessage imsg, IRole role) + { + var channel = (ITextChannel)imsg.Channel; + var guildUser = (IGuildUser)imsg.Author; + + GuildConfig conf; + IEnumerable roles; + using (var uow = DbHandler.UnitOfWork()) + { + conf = uow.GuildConfigs.For(channel.Guild.Id); + roles = uow.SelfAssignedRoles.GetFromGuild(channel.Guild.Id); + } + SelfAssignedRole roleModel; + if ((roleModel = roles.FirstOrDefault(r => r.RoleId == role.Id)) == null) + { + await channel.SendMessageAsync(":anger:That role is not self-assignable.").ConfigureAwait(false); + return; + } + if (!guildUser.Roles.Contains(role)) + { + await channel.SendMessageAsync($":anger:You don't have {role.Name} role.").ConfigureAwait(false); + return; + } + try + { + await guildUser.RemoveRolesAsync(role).ConfigureAwait(false); + } + catch (Exception) + { + await channel.SendMessageAsync($":anger:`I am unable to add that role to you. I can't remove roles to owners or other roles higher than my role in the role hierarchy.`").ConfigureAwait(false); + return; + } + var msg = await channel.SendMessageAsync($":ok: You no longer have {role.Name} role.").ConfigureAwait(false); + + if (conf.AutoDeleteSelfAssignedRoleMessages) + { + var t = Task.Run(async () => + { + await Task.Delay(3000).ConfigureAwait(false); + try { await msg.DeleteAsync().ConfigureAwait(false); } catch { } // if 502 or something, i don't want bot crashing + try { await imsg.DeleteAsync().ConfigureAwait(false); } catch { } + }); + } + } + } + } +} \ No newline at end of file diff --git a/src/NadekoBot/Services/Database/IUnitOfWork.cs b/src/NadekoBot/Services/Database/IUnitOfWork.cs index f2f49a09..6db44ae8 100644 --- a/src/NadekoBot/Services/Database/IUnitOfWork.cs +++ b/src/NadekoBot/Services/Database/IUnitOfWork.cs @@ -10,10 +10,11 @@ namespace NadekoBot.Services.Database public interface IUnitOfWork : IDisposable { IQuoteRepository Quotes { get; } - IConfigRepository GuildConfigs { get; } + IGuildConfigRepository GuildConfigs { get; } IDonatorsRepository Donators { get; } IClashOfClansRepository ClashOfClans { get; } IReminderRepository Reminders { get; } + ISelfAssignedRolesRepository SelfAssignedRoles { get; } int Complete(); Task CompleteAsync(); diff --git a/src/NadekoBot/Services/Database/Models/GuildConfig.cs b/src/NadekoBot/Services/Database/Models/GuildConfig.cs index c872d761..77c1d966 100644 --- a/src/NadekoBot/Services/Database/Models/GuildConfig.cs +++ b/src/NadekoBot/Services/Database/Models/GuildConfig.cs @@ -28,5 +28,8 @@ namespace NadekoBot.Services.Database.Models public bool SendChannelByeMessage { get; set; } public string ChannelByeMessageText { get; set; } = "%user% has left!"; + //self assignable roles + public bool ExclusiveSelfAssignedRoles { get; set; } + public bool AutoDeleteSelfAssignedRoleMessages { get; set; } } } diff --git a/src/NadekoBot/Services/Database/Models/SelfAssignableRole.cs b/src/NadekoBot/Services/Database/Models/SelfAssignableRole.cs new file mode 100644 index 00000000..df2593c8 --- /dev/null +++ b/src/NadekoBot/Services/Database/Models/SelfAssignableRole.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NadekoBot.Services.Database.Models +{ + public class SelfAssignedRole : DbEntity + { + public ulong GuildId { get; set; } + public ulong RoleId { get; set; } + } +} diff --git a/src/NadekoBot/Services/Database/NadekoContext.cs b/src/NadekoBot/Services/Database/NadekoContext.cs index 5bc4cc1f..e576ec62 100644 --- a/src/NadekoBot/Services/Database/NadekoContext.cs +++ b/src/NadekoBot/Services/Database/NadekoContext.cs @@ -16,6 +16,7 @@ namespace NadekoBot.Services.Database public DbSet ClashOfClans { get; set; } public DbSet ClashCallers { get; set; } public DbSet Reminders { get; set; } + public DbSet SelfAssignableRoles { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { @@ -52,6 +53,16 @@ namespace NadekoBot.Services.Database .WithMany(c => c.Bases); #endregion + + #region Self Assignable Roles + + var selfassignableRolesEntity = modelBuilder.Entity(); + + selfassignableRolesEntity + .HasIndex(s => new { s.GuildId, s.RoleId }) + .IsUnique(); + + #endregion } protected abstract override void OnConfiguring(DbContextOptionsBuilder optionsBuilder); } diff --git a/src/NadekoBot/Services/Database/Repositories/IConfigRepository.cs b/src/NadekoBot/Services/Database/Repositories/IGuildConfigRepository.cs similarity index 81% rename from src/NadekoBot/Services/Database/Repositories/IConfigRepository.cs rename to src/NadekoBot/Services/Database/Repositories/IGuildConfigRepository.cs index b1544711..70e602f7 100644 --- a/src/NadekoBot/Services/Database/Repositories/IConfigRepository.cs +++ b/src/NadekoBot/Services/Database/Repositories/IGuildConfigRepository.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; namespace NadekoBot.Services.Database.Repositories { - public interface IConfigRepository : IRepository + public interface IGuildConfigRepository : IRepository { GuildConfig For(ulong guildId); } diff --git a/src/NadekoBot/Services/Database/Repositories/ISelfAssignedRolesRepository.cs b/src/NadekoBot/Services/Database/Repositories/ISelfAssignedRolesRepository.cs new file mode 100644 index 00000000..805a1537 --- /dev/null +++ b/src/NadekoBot/Services/Database/Repositories/ISelfAssignedRolesRepository.cs @@ -0,0 +1,15 @@ +using NadekoBot.Services.Database.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NadekoBot.Services.Database.Repositories +{ + public interface ISelfAssignedRolesRepository : IRepository + { + bool DeleteByGuildAndRoleId(ulong guildId, ulong roleId); + IEnumerable GetFromGuild(ulong guildId); + } +} diff --git a/src/NadekoBot/Services/Database/Repositories/Impl/ConfigRepository.cs b/src/NadekoBot/Services/Database/Repositories/Impl/GuildConfigRepository.cs similarity index 84% rename from src/NadekoBot/Services/Database/Repositories/Impl/ConfigRepository.cs rename to src/NadekoBot/Services/Database/Repositories/Impl/GuildConfigRepository.cs index 6df83e3b..13f05404 100644 --- a/src/NadekoBot/Services/Database/Repositories/Impl/ConfigRepository.cs +++ b/src/NadekoBot/Services/Database/Repositories/Impl/GuildConfigRepository.cs @@ -8,9 +8,9 @@ using Microsoft.EntityFrameworkCore; namespace NadekoBot.Services.Database.Repositories.Impl { - public class ConfigRepository : Repository, IConfigRepository + public class GuildConfigRepository : Repository, IGuildConfigRepository { - public ConfigRepository(DbContext context) : base(context) + public GuildConfigRepository(DbContext context) : base(context) { } /// diff --git a/src/NadekoBot/Services/Database/Repositories/Impl/SelfAssignedRolesRepository.cs b/src/NadekoBot/Services/Database/Repositories/Impl/SelfAssignedRolesRepository.cs new file mode 100644 index 00000000..3e980e10 --- /dev/null +++ b/src/NadekoBot/Services/Database/Repositories/Impl/SelfAssignedRolesRepository.cs @@ -0,0 +1,31 @@ +using NadekoBot.Services.Database.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; + +namespace NadekoBot.Services.Database.Repositories.Impl +{ + public class SelfAssignedRolesRepository : Repository, ISelfAssignedRolesRepository + { + public SelfAssignedRolesRepository(DbContext context) : base(context) + { + } + + public bool DeleteByGuildAndRoleId(ulong guildId, ulong roleId) + { + var role = _set.Where(s => s.GuildId == guildId && s.RoleId == roleId).FirstOrDefault(); + + if (role == null) + return false; + + _set.Remove(role); + return true; + } + + public IEnumerable GetFromGuild(ulong guildId) => + _set.Where(s => s.GuildId == guildId); + } +} diff --git a/src/NadekoBot/Services/Database/UnitOfWork.cs b/src/NadekoBot/Services/Database/UnitOfWork.cs index ec4858c0..b1680a63 100644 --- a/src/NadekoBot/Services/Database/UnitOfWork.cs +++ b/src/NadekoBot/Services/Database/UnitOfWork.cs @@ -15,8 +15,8 @@ namespace NadekoBot.Services.Database private IQuoteRepository _quotes; public IQuoteRepository Quotes => _quotes ?? (_quotes = new QuoteRepository(_context)); - private IConfigRepository _guildConfigs; - public IConfigRepository GuildConfigs => _guildConfigs ?? (_guildConfigs = new ConfigRepository(_context)); + private IGuildConfigRepository _guildConfigs; + public IGuildConfigRepository GuildConfigs => _guildConfigs ?? (_guildConfigs = new GuildConfigRepository(_context)); private IDonatorsRepository _donators; public IDonatorsRepository Donators => _donators ?? (_donators = new DonatorsRepository(_context)); @@ -27,6 +27,9 @@ namespace NadekoBot.Services.Database private IReminderRepository _reminders; public IReminderRepository Reminders => _reminders ?? (_reminders = new ReminderRepository(_context)); + private ISelfAssignedRolesRepository _selfAssignedRoles; + public ISelfAssignedRolesRepository SelfAssignedRoles => _selfAssignedRoles ?? (_selfAssignedRoles = new SelfAssignedRolesRepository(_context)); + public UnitOfWork(NadekoContext context) { _context = context;