diff --git a/src/NadekoBot/Migrations/20160826172044_first.Designer.cs b/src/NadekoBot/Migrations/20160826234229_first.Designer.cs similarity index 86% rename from src/NadekoBot/Migrations/20160826172044_first.Designer.cs rename to src/NadekoBot/Migrations/20160826234229_first.Designer.cs index fa569835..a7fdcfa1 100644 --- a/src/NadekoBot/Migrations/20160826172044_first.Designer.cs +++ b/src/NadekoBot/Migrations/20160826234229_first.Designer.cs @@ -8,7 +8,7 @@ using NadekoBot.Services.Database.Impl; namespace NadekoBot.Migrations { [DbContext(typeof(NadekoSqliteContext))] - [Migration("20160826172044_first")] + [Migration("20160826234229_first")] partial class first { protected override void BuildTargetModel(ModelBuilder modelBuilder) @@ -110,6 +110,8 @@ namespace NadekoBot.Migrations b.Property("GuildId"); + b.Property("RotatingStatuses"); + b.Property("SendChannelByeMessage"); b.Property("SendChannelGreetMessage"); @@ -124,6 +126,22 @@ namespace NadekoBot.Migrations b.ToTable("GuildConfigs"); }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.PlayingStatus", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("GuildConfigId"); + + b.Property("Status"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("PlayingStatus"); + }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.Quote", b => { b.Property("Id") @@ -193,6 +211,13 @@ namespace NadekoBot.Migrations .HasForeignKey("ClashWarId") .OnDelete(DeleteBehavior.Cascade); }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.PlayingStatus", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("RotatingStatusMessages") + .HasForeignKey("GuildConfigId"); + }); } } } diff --git a/src/NadekoBot/Migrations/20160826172044_first.cs b/src/NadekoBot/Migrations/20160826234229_first.cs similarity index 86% rename from src/NadekoBot/Migrations/20160826172044_first.cs rename to src/NadekoBot/Migrations/20160826234229_first.cs index 6c8e4660..6dd4deac 100644 --- a/src/NadekoBot/Migrations/20160826172044_first.cs +++ b/src/NadekoBot/Migrations/20160826234229_first.cs @@ -60,6 +60,7 @@ namespace NadekoBot.Migrations ExclusiveSelfAssignedRoles = table.Column(nullable: false), GreetMessageChannelId = table.Column(nullable: false), GuildId = table.Column(nullable: false), + RotatingStatuses = table.Column(nullable: false), SendChannelByeMessage = table.Column(nullable: false), SendChannelGreetMessage = table.Column(nullable: false), SendDmGreetMessage = table.Column(nullable: false) @@ -141,6 +142,26 @@ namespace NadekoBot.Migrations onDelete: ReferentialAction.Cascade); }); + migrationBuilder.CreateTable( + name: "PlayingStatus", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Autoincrement", true), + GuildConfigId = table.Column(nullable: true), + Status = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_PlayingStatus", x => x.Id); + table.ForeignKey( + name: "FK_PlayingStatus_GuildConfigs_GuildConfigId", + column: x => x.GuildConfigId, + principalTable: "GuildConfigs", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + migrationBuilder.CreateIndex( name: "IX_ClashCallers_ClashWarId", table: "ClashCallers", @@ -158,6 +179,11 @@ namespace NadekoBot.Migrations column: "GuildId", unique: true); + migrationBuilder.CreateIndex( + name: "IX_PlayingStatus_GuildConfigId", + table: "PlayingStatus", + column: "GuildConfigId"); + migrationBuilder.CreateIndex( name: "IX_SelfAssignableRoles_GuildId_RoleId", table: "SelfAssignableRoles", @@ -174,7 +200,7 @@ namespace NadekoBot.Migrations name: "Donators"); migrationBuilder.DropTable( - name: "GuildConfigs"); + name: "PlayingStatus"); migrationBuilder.DropTable( name: "Quotes"); @@ -187,6 +213,9 @@ namespace NadekoBot.Migrations migrationBuilder.DropTable( name: "ClashOfClans"); + + migrationBuilder.DropTable( + name: "GuildConfigs"); } } } diff --git a/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs b/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs index 5ea3a8d4..509a3bd9 100644 --- a/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs +++ b/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs @@ -109,6 +109,8 @@ namespace NadekoBot.Migrations b.Property("GuildId"); + b.Property("RotatingStatuses"); + b.Property("SendChannelByeMessage"); b.Property("SendChannelGreetMessage"); @@ -123,6 +125,22 @@ namespace NadekoBot.Migrations b.ToTable("GuildConfigs"); }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.PlayingStatus", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("GuildConfigId"); + + b.Property("Status"); + + b.HasKey("Id"); + + b.HasIndex("GuildConfigId"); + + b.ToTable("PlayingStatus"); + }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.Quote", b => { b.Property("Id") @@ -192,6 +210,13 @@ namespace NadekoBot.Migrations .HasForeignKey("ClashWarId") .OnDelete(DeleteBehavior.Cascade); }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.PlayingStatus", b => + { + b.HasOne("NadekoBot.Services.Database.Models.GuildConfig") + .WithMany("RotatingStatusMessages") + .HasForeignKey("GuildConfigId"); + }); } } } diff --git a/src/NadekoBot/Modules/Administration/Commands/PlayingRotate.cs b/src/NadekoBot/Modules/Administration/Commands/PlayingRotate.cs index d1537e50..ed3e7e3f 100644 --- a/src/NadekoBot/Modules/Administration/Commands/PlayingRotate.cs +++ b/src/NadekoBot/Modules/Administration/Commands/PlayingRotate.cs @@ -1,168 +1,113 @@ -//using Discord.Commands; -//using NadekoBot.Classes; -//using NadekoBot.Classes.JSONModels; -//using NadekoBot.Modules.Music; -//using NadekoBot.Modules.Permissions.Classes; -//using System; -//using System.Collections.Generic; -//using System.Linq; -//using System.Text; -//using System.Threading; -//using System.Threading.Tasks; -//using System.Timers; -//using Timer = System.Timers.Timer; +using Discord; +using Discord.Commands; +using Discord.WebSocket; +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; +using System.Threading.Tasks; -////todo DB -//namespace NadekoBot.Modules.Administration -//{ -// internal class PlayingRotate : DiscordCommand -// { -// private static readonly Timer timer = new Timer(20000); +//todo owner only +namespace NadekoBot.Modules.Administration +{ + public partial class Administration + { + [Group] + public class PlayingRotateCommands + { + public static Dictionary> PlayingPlaceholders { get; } = + new Dictionary> { + {"%servers%", () => NadekoBot.Client.GetGuilds().Count().ToString()}, + {"%users%", () => NadekoBot.Client.GetGuilds().Select(s => s.GetUsers().Count).Sum().ToString()}, + {"%playing%", () => { + var cnt = Music.Music.MusicPlayers.Count(kvp => kvp.Value.CurrentSong != null); + if (cnt != 1) return cnt.ToString(); + try { + var mp = Music.Music.MusicPlayers.FirstOrDefault(); + return mp.Value.CurrentSong.SongInfo.Title; + } + catch { + return "No songs"; + } + } + }, + {"%queued%", () => Music.Music.MusicPlayers.Sum(kvp => kvp.Value.Playlist.Count).ToString()} + }; -// public static Dictionary> PlayingPlaceholders { get; } = -// new Dictionary> { -// {"%servers%", () => NadekoBot.Client.Servers.Count().ToString()}, -// {"%users%", () => NadekoBot.Client.Servers.SelectMany(s => s.Users).Count().ToString()}, -// {"%playing%", () => { -// var cnt = MusicModule.MusicPlayers.Count(kvp => kvp.Value.CurrentSong != null); -// if (cnt != 1) return cnt.ToString(); -// try { -// var mp = MusicModule.MusicPlayers.FirstOrDefault(); -// return mp.Value.CurrentSong.SongInfo.Title; -// } -// catch { -// return "No songs"; -// } -// } -// }, -// {"%queued%", () => MusicModule.MusicPlayers.Sum(kvp => kvp.Value.Playlist.Count).ToString()}, -// {"%trivia%", () => Games.Commands.TriviaCommands.RunningTrivias.Count.ToString()} -// }; + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + public async Task RotatePlaying(IMessage imsg) + { + var channel = (ITextChannel)imsg.Channel; -// private readonly SemaphoreSlim playingPlaceholderLock = new SemaphoreSlim(1,1); + using (var uow = DbHandler.UnitOfWork()) + { + var config = uow.GuildConfigs.For(channel.Guild.Id); -// public PlayingRotate(DiscordModule module) : base(module) -// { -// var i = -1; -// timer.Elapsed += async (s, e) => -// { -// try -// { -// i++; -// var status = ""; -// //wtf am i doing, just use a queue ffs -// await playingPlaceholderLock.WaitAsync().ConfigureAwait(false); -// try -// { -// if (PlayingPlaceholders.Count == 0 -// || NadekoBot.Config.RotatingStatuses.Count == 0 -// || i >= NadekoBot.Config.RotatingStatuses.Count) -// { -// i = 0; -// } -// status = NadekoBot.Config.RotatingStatuses[i]; -// status = PlayingPlaceholders.Aggregate(status, -// (current, kvp) => current.Replace(kvp.Key, kvp.Value())); -// } -// finally { playingPlaceholderLock.Release(); } -// if (string.IsNullOrWhiteSpace(status)) -// return; -// await Task.Run(() => { NadekoBot.Client.SetGame(status); }); -// } -// catch { } -// }; + config.RotatingStatuses = !config.RotatingStatuses; + await uow.CompleteAsync(); + } + } -// timer.Enabled = NadekoBot.Config.IsRotatingStatus; -// } + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + public async Task AddPlaying(IMessage imsg, string status) + { + var channel = (ITextChannel)imsg.Channel; -// public Func DoFunc() => async e => -// { -// await playingPlaceholderLock.WaitAsync().ConfigureAwait(false); -// try -// { -// if (timer.Enabled) -// timer.Stop(); -// else -// timer.Start(); -// NadekoBot.Config.IsRotatingStatus = timer.Enabled; -// await ConfigHandler.SaveConfig().ConfigureAwait(false); -// } -// finally { -// playingPlaceholderLock.Release(); -// } -// await channel.SendMessageAsync($"❗`Rotating playing status has been {(timer.Enabled ? "enabled" : "disabled")}.`").ConfigureAwait(false); -// }; + using (var uow = DbHandler.UnitOfWork()) + { + var config = uow.GuildConfigs.For(channel.Guild.Id); + config.RotatingStatusMessages.Add(new PlayingStatus { Status = status }); + await uow.CompleteAsync(); + } -// internal override void Init(CommandGroupBuilder cgb) -// { -// cgb.CreateCommand(Module.Prefix + "rotateplaying") -// .Alias(Module.Prefix + "ropl") -// .Description($"Toggles rotation of playing status of the dynamic strings you specified earlier. **Bot Owner Only!** | `{Prefix}ropl`") -// .AddCheck(SimpleCheckers.OwnerOnly()) -// .Do(DoFunc()); + } -// cgb.CreateCommand(Module.Prefix + "addplaying") -// .Alias(Module.Prefix + "adpl") -// .Description("Adds a specified string to the list of playing strings to rotate. " + -// "Supported placeholders: " + string.Join(", ", PlayingPlaceholders.Keys)+ $" **Bot Owner Only!**| `{Prefix}adpl`") -// .Parameter("text", ParameterType.Unparsed) -// .AddCheck(SimpleCheckers.OwnerOnly()) -// .Do(async e => -// { -// var arg = text; -// if (string.IsNullOrWhiteSpace(arg)) -// return; -// await playingPlaceholderLock.WaitAsync().ConfigureAwait(false); -// try -// { -// NadekoBot.Config.RotatingStatuses.Add(arg); -// await ConfigHandler.SaveConfig(); -// } -// finally -// { -// playingPlaceholderLock.Release(); -// } -// await channel.SendMessageAsync("🆗 `Added a new playing string.`").ConfigureAwait(false); -// }); + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + public async Task ListPlaying(IMessage imsg) + { + var channel = (ITextChannel)imsg.Channel; -// cgb.CreateCommand(Module.Prefix + "listplaying") -// .Alias(Module.Prefix + "lipl") -// .Description($"Lists all playing statuses with their corresponding number. **Bot Owner Only!**| `{Prefix}lipl`") -// .AddCheck(SimpleCheckers.OwnerOnly()) -// .Do(async e => -// { -// if (NadekoBot.Config.RotatingStatuses.Count == 0) -// await channel.SendMessageAsync("`There are no playing strings. " + -// "Add some with .addplaying [text] command.`").ConfigureAwait(false); -// var sb = new StringBuilder(); -// for (var i = 0; i < NadekoBot.Config.RotatingStatuses.Count; i++) -// { -// sb.AppendLine($"`{i + 1}.` {NadekoBot.Config.RotatingStatuses[i]}"); -// } -// await channel.SendMessageAsync(sb.ToString()).ConfigureAwait(false); -// }); + List statuses; + using (var uow = DbHandler.UnitOfWork()) + { + statuses = uow.GuildConfigs.For(channel.Guild.Id).RotatingStatusMessages; + } -// cgb.CreateCommand(Module.Prefix + "removeplaying") -// .Alias(Module.Prefix + "repl", Module.Prefix + "rmpl") -// .Description($"Removes a playing string on a given number. **Bot Owner Only!**| `{Prefix}rmpl`") -// .Parameter("number", ParameterType.Required) -// .AddCheck(SimpleCheckers.OwnerOnly()) -// .Do(async e => -// { -// var arg = number; -// int num; -// string str; -// await playingPlaceholderLock.WaitAsync().ConfigureAwait(false); -// try { -// if (!int.TryParse(arg.Trim(), out num) || num <= 0 || num > NadekoBot.Config.RotatingStatuses.Count) -// return; -// str = NadekoBot.Config.RotatingStatuses[num - 1]; -// NadekoBot.Config.RotatingStatuses.RemoveAt(num - 1); -// await ConfigHandler.SaveConfig().ConfigureAwait(false); -// } -// finally { playingPlaceholderLock.Release(); } -// await channel.SendMessageAsync($"🆗 `Removed playing string #{num}`({str})").ConfigureAwait(false); -// }); -// } -// } -//} + if (!statuses.Any()) + await channel.SendMessageAsync("`No rotating playing statuses set.`"); + else + { + var i = 1; + await channel.SendMessageAsync($"{imsg.Author.Mention} Here is a list of rotating statuses:\n" + string.Join("\n", statuses.Select(rs => $"`{i++}.` {rs.Status}\n"))); + } + + } + + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + public async Task RemovePlaying(IMessage imsg, int index) + { + var channel = (ITextChannel)imsg.Channel; + + using (var uow = DbHandler.UnitOfWork()) + { + var config = uow.GuildConfigs.For(channel.Guild.Id); + + if (index >= config.RotatingStatusMessages.Count) + return; + + config.RotatingStatusMessages.RemoveAt(index); + await uow.CompleteAsync(); + } + } + } + } +} \ No newline at end of file diff --git a/src/NadekoBot/Services/Database/Models/GuildConfig.cs b/src/NadekoBot/Services/Database/Models/GuildConfig.cs index 77c1d966..7ffe046f 100644 --- a/src/NadekoBot/Services/Database/Models/GuildConfig.cs +++ b/src/NadekoBot/Services/Database/Models/GuildConfig.cs @@ -31,5 +31,12 @@ namespace NadekoBot.Services.Database.Models //self assignable roles public bool ExclusiveSelfAssignedRoles { get; set; } public bool AutoDeleteSelfAssignedRoleMessages { get; set; } + public bool RotatingStatuses { get; set; } + public List RotatingStatusMessages { get; set; } + } + + public class PlayingStatus : DbEntity + { + public string Status { get; set; } } }