diff --git a/src/NadekoBot/Migrations/20160825131849_FirstMigration.Designer.cs b/src/NadekoBot/Migrations/20160825172257_first.Designer.cs similarity index 64% rename from src/NadekoBot/Migrations/20160825131849_FirstMigration.Designer.cs rename to src/NadekoBot/Migrations/20160825172257_first.Designer.cs index 26120b33..d445b8da 100644 --- a/src/NadekoBot/Migrations/20160825131849_FirstMigration.Designer.cs +++ b/src/NadekoBot/Migrations/20160825172257_first.Designer.cs @@ -8,14 +8,58 @@ using NadekoBot.Services.Database.Impl; namespace NadekoBot.Migrations { [DbContext(typeof(NadekoSqliteContext))] - [Migration("20160825131849_FirstMigration")] - partial class FirstMigration + [Migration("20160825172257_first")] + partial class first { protected override void BuildTargetModel(ModelBuilder modelBuilder) { modelBuilder .HasAnnotation("ProductVersion", "1.0.0-rtm-21431"); + modelBuilder.Entity("NadekoBot.Services.Database.Models.ClashCaller", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BaseDestroyed"); + + b.Property("CallUser"); + + b.Property("ClashWarId"); + + b.Property("Stars"); + + b.Property("TimeAdded"); + + b.HasKey("Id"); + + b.HasIndex("ClashWarId"); + + b.ToTable("ClashCallers"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ClashWar", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ChannelId"); + + b.Property("EnemyClan"); + + b.Property("GuildId"); + + b.Property("Size"); + + b.Property("StartedAt"); + + b.Property("WarState"); + + b.HasKey("Id"); + + b.ToTable("ClashOfClans"); + }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.Donator", b => { b.Property("Id") @@ -98,6 +142,14 @@ namespace NadekoBot.Migrations b.ToTable("Quotes"); }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ClashCaller", b => + { + b.HasOne("NadekoBot.Services.Database.Models.ClashWar", "ClashWar") + .WithMany("Bases") + .HasForeignKey("ClashWarId") + .OnDelete(DeleteBehavior.Cascade); + }); } } } diff --git a/src/NadekoBot/Migrations/20160825131849_FirstMigration.cs b/src/NadekoBot/Migrations/20160825172257_first.cs similarity index 62% rename from src/NadekoBot/Migrations/20160825131849_FirstMigration.cs rename to src/NadekoBot/Migrations/20160825172257_first.cs index 2e6c1b48..f9a4b3c6 100644 --- a/src/NadekoBot/Migrations/20160825131849_FirstMigration.cs +++ b/src/NadekoBot/Migrations/20160825172257_first.cs @@ -4,10 +4,28 @@ using Microsoft.EntityFrameworkCore.Migrations; namespace NadekoBot.Migrations { - public partial class FirstMigration : Migration + public partial class first : Migration { protected override void Up(MigrationBuilder migrationBuilder) { + migrationBuilder.CreateTable( + name: "ClashOfClans", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Autoincrement", true), + ChannelId = table.Column(nullable: false), + EnemyClan = table.Column(nullable: true), + GuildId = table.Column(nullable: false), + Size = table.Column(nullable: false), + StartedAt = table.Column(nullable: false), + WarState = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClashOfClans", x => x.Id); + }); + migrationBuilder.CreateTable( name: "Donators", columns: table => new @@ -66,6 +84,34 @@ namespace NadekoBot.Migrations table.PrimaryKey("PK_Quotes", x => x.Id); }); + migrationBuilder.CreateTable( + name: "ClashCallers", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Autoincrement", true), + BaseDestroyed = table.Column(nullable: false), + CallUser = table.Column(nullable: true), + ClashWarId = table.Column(nullable: false), + Stars = table.Column(nullable: false), + TimeAdded = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClashCallers", x => x.Id); + table.ForeignKey( + name: "FK_ClashCallers_ClashOfClans_ClashWarId", + column: x => x.ClashWarId, + principalTable: "ClashOfClans", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_ClashCallers_ClashWarId", + table: "ClashCallers", + column: "ClashWarId"); + migrationBuilder.CreateIndex( name: "IX_Donators_UserId", table: "Donators", @@ -81,6 +127,9 @@ namespace NadekoBot.Migrations protected override void Down(MigrationBuilder migrationBuilder) { + migrationBuilder.DropTable( + name: "ClashCallers"); + migrationBuilder.DropTable( name: "Donators"); @@ -89,6 +138,9 @@ namespace NadekoBot.Migrations migrationBuilder.DropTable( name: "Quotes"); + + migrationBuilder.DropTable( + name: "ClashOfClans"); } } } diff --git a/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs b/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs index d40b25fd..02d12786 100644 --- a/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs +++ b/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs @@ -15,6 +15,50 @@ namespace NadekoBot.Migrations modelBuilder .HasAnnotation("ProductVersion", "1.0.0-rtm-21431"); + modelBuilder.Entity("NadekoBot.Services.Database.Models.ClashCaller", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BaseDestroyed"); + + b.Property("CallUser"); + + b.Property("ClashWarId"); + + b.Property("Stars"); + + b.Property("TimeAdded"); + + b.HasKey("Id"); + + b.HasIndex("ClashWarId"); + + b.ToTable("ClashCallers"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ClashWar", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ChannelId"); + + b.Property("EnemyClan"); + + b.Property("GuildId"); + + b.Property("Size"); + + b.Property("StartedAt"); + + b.Property("WarState"); + + b.HasKey("Id"); + + b.ToTable("ClashOfClans"); + }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.Donator", b => { b.Property("Id") @@ -97,6 +141,14 @@ namespace NadekoBot.Migrations b.ToTable("Quotes"); }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ClashCaller", b => + { + b.HasOne("NadekoBot.Services.Database.Models.ClashWar", "ClashWar") + .WithMany("Bases") + .HasForeignKey("ClashWarId") + .OnDelete(DeleteBehavior.Cascade); + }); } } } diff --git a/src/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs b/src/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs index 5e3a55ed..0f50af71 100644 --- a/src/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs +++ b/src/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs @@ -2,7 +2,6 @@ using Discord; using Discord.Commands; using Discord.WebSocket; using NadekoBot.Attributes; -using NadekoBot.Classes; using NadekoBot.Extensions; using System; using System.Collections.Concurrent; diff --git a/src/NadekoBot/Modules/Administration/Commands/ServerGreetCommands.cs b/src/NadekoBot/Modules/Administration/Commands/ServerGreetCommands.cs index d06ad852..3a2bebd5 100644 --- a/src/NadekoBot/Modules/Administration/Commands/ServerGreetCommands.cs +++ b/src/NadekoBot/Modules/Administration/Commands/ServerGreetCommands.cs @@ -1,7 +1,6 @@ using Discord; using Discord.Commands; using NadekoBot.Attributes; -using NadekoBot.Classes; using NadekoBot.Services; using NadekoBot.Services.Database.Models; using NLog; diff --git a/src/NadekoBot/Modules/ClashOfClans/ClashOfClans.cs b/src/NadekoBot/Modules/ClashOfClans/ClashOfClans.cs index 072d89a1..e45536f8 100644 --- a/src/NadekoBot/Modules/ClashOfClans/ClashOfClans.cs +++ b/src/NadekoBot/Modules/ClashOfClans/ClashOfClans.cs @@ -1,5 +1,4 @@ using Discord.Commands; -using NadekoBot.Classes.ClashOfClans; using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -9,23 +8,43 @@ using Discord; using NadekoBot.Services; using NadekoBot.Attributes; using Discord.WebSocket; +using NadekoBot.Services.Database.Models; +using System.Linq; +using NadekoBot.Services.Database; //todo DB namespace NadekoBot.Modules.ClashOfClans { - [Module(",",AppendSpace = false)] + [Module(",", AppendSpace = false)] public class ClashOfClans : DiscordModule { public static ConcurrentDictionary> ClashWars { get; set; } = new ConcurrentDictionary>(); public ClashOfClans(ILocalization loc, CommandService cmds, IBotConfiguration config, DiscordSocketClient client) : base(loc, cmds, config, client) { + using (var uow = DbHandler.UnitOfWork()) + { + ClashWars = new ConcurrentDictionary>( + uow.ClashOfClans + .GetAll() + .Select(cw => { + cw.Channel = NadekoBot.Client.GetGuilds() + .FirstOrDefault(s => s.Id == cw.GuildId)? + .GetChannels() + .FirstOrDefault(c => c.Id == cw.ChannelId) + as ITextChannel; + cw.Bases.Capacity = cw.Size; + return cw; + }) + .GroupBy(cw => cw.GuildId) + .ToDictionary(g => g.Key, g => g.ToList())); + } } private static async Task CheckWar(TimeSpan callExpire, ClashWar war) { var Bases = war.Bases; - for (var i = 0; i < Bases.Length; i++) + for (var i = 0; i < Bases.Capacity; i++) { if (Bases[i] == null) continue; if (!Bases[i].BaseDestroyed && DateTime.UtcNow - Bases[i].TimeAdded >= callExpire) @@ -62,7 +81,7 @@ namespace NadekoBot.Modules.ClashOfClans } - var cw = new ClashWar(enemyClan, size, channel.Guild.Id, imsg.Channel.Id); + var cw = await CreateWar(enemyClan, size, channel.Guild.Id, imsg.Channel.Id); //cw.Start(); wars.Add(cw); @@ -94,6 +113,7 @@ namespace NadekoBot.Modules.ClashOfClans { await channel.SendMessageAsync($"🔰**WAR AGAINST {war.ShortPrint()} HAS ALREADY STARTED**").ConfigureAwait(false); } + SaveWar(war); } [LocalizedCommand, LocalizedDescription, LocalizedSummary] @@ -136,7 +156,7 @@ namespace NadekoBot.Modules.ClashOfClans await channel.SendMessageAsync("💢🔰 **That war does not exist.**").ConfigureAwait(false); return; } - await channel.SendMessageAsync(warsInfo.Item1[warsInfo.Item2].ToString()).ConfigureAwait(false); + await channel.SendMessageAsync(warsInfo.Item1[warsInfo.Item2].ToPrettyString()).ConfigureAwait(false); } [LocalizedCommand, LocalizedDescription, LocalizedSummary] @@ -158,6 +178,7 @@ namespace NadekoBot.Modules.ClashOfClans { var war = warsInfo.Item1[warsInfo.Item2]; war.Call(usr, baseNumber - 1); + SaveWar(war); await channel.SendMessageAsync($"🔰**{usr}** claimed a base #{baseNumber} for a war against {war.ShortPrint()}").ConfigureAwait(false); } catch (Exception ex) @@ -202,7 +223,9 @@ namespace NadekoBot.Modules.ClashOfClans await channel.SendMessageAsync("💢🔰 That war does not exist.").ConfigureAwait(false); return; } - warsInfo.Item1[warsInfo.Item2].End(); + var war = warsInfo.Item1[warsInfo.Item2]; + war.End(); + SaveWar(war); await channel.SendMessageAsync($"❗🔰**War against {warsInfo.Item1[warsInfo.Item2].ShortPrint()} ended.**").ConfigureAwait(false); var size = warsInfo.Item1[warsInfo.Item2].Size; @@ -229,6 +252,7 @@ namespace NadekoBot.Modules.ClashOfClans { var war = warsInfo.Item1[warsInfo.Item2]; var baseNumber = war.Uncall(usr); + SaveWar(war); await channel.SendMessageAsync($"🔰 @{usr} has **UNCLAIMED** a base #{baseNumber + 1} from a war against {war.ShortPrint()}").ConfigureAwait(false); } catch (Exception ex) @@ -255,6 +279,7 @@ namespace NadekoBot.Modules.ClashOfClans try { var baseNum = war.FinishClaim(usr, stars); + SaveWar(war); await channel.SendMessageAsync($"❗🔰{imsg.Author.Mention} **DESTROYED** a base #{baseNum + 1} in a war against {war.ShortPrint()}").ConfigureAwait(false); } catch (Exception ex) @@ -282,5 +307,48 @@ namespace NadekoBot.Modules.ClashOfClans //get the actual war return new Tuple, int>(wars, num); } + + public static async Task CreateWar(string enemyClan, int size, ulong serverId, ulong channelId) + { + using (var uow = DbHandler.UnitOfWork()) + { + var cw = new ClashWar + { + EnemyClan = enemyClan, + Size = size, + Bases = new List(size), + GuildId = serverId, + ChannelId = channelId, + Channel = NadekoBot.Client.GetGuilds() + .FirstOrDefault(s => s.Id == serverId)? + .GetChannels() + .FirstOrDefault(c => c.Id == channelId) + as ITextChannel + }; + uow.ClashOfClans.Add(cw); + await uow.CompleteAsync(); + return cw; + } + } + + public static void SaveWar(ClashWar cw) + { + if (cw.WarState == ClashWar.StateOfWar.Ended) + { + using (var uow = DbHandler.UnitOfWork()) + { + uow.ClashOfClans.Remove(cw); + uow.CompleteAsync(); + } + return; + } + + + using (var uow = DbHandler.UnitOfWork()) + { + uow.ClashOfClans.Update(cw); + uow.CompleteAsync(); + } + } } } diff --git a/src/NadekoBot/Modules/ClashOfClans/ClashWar.cs b/src/NadekoBot/Modules/ClashOfClans/ClashWar.cs deleted file mode 100644 index f193b0e4..00000000 --- a/src/NadekoBot/Modules/ClashOfClans/ClashWar.cs +++ /dev/null @@ -1,183 +0,0 @@ -using Discord; -using Newtonsoft.Json; -using System; -using System.Linq; -using System.Text; - -namespace NadekoBot.Classes.ClashOfClans -{ - public class ClashWar - { - public enum DestroyStars - { - One, Two, Three - } - public enum StateOfWar - { - Started, Ended, Created - } - - public class Caller - { - public string CallUser { get; set; } - - public DateTime TimeAdded { get; set; } - - public bool BaseDestroyed { get; set; } - - public int Stars { get; set; } = 3; - - public Caller() { } - - public Caller(string callUser, DateTime timeAdded, bool baseDestroyed) - { - CallUser = callUser; - TimeAdded = timeAdded; - BaseDestroyed = baseDestroyed; - } - - public void ResetTime() - { - TimeAdded = DateTime.UtcNow; - } - - public void Destroy() - { - BaseDestroyed = true; - } - } - private static TimeSpan callExpire => new TimeSpan(2, 0, 0); - - public string EnemyClan { get; set; } - public int Size { get; set; } - - public Caller[] Bases { get; set; } - public StateOfWar WarState { get; set; } = StateOfWar.Created; - //public bool Started { get; set; } = false; - public DateTime StartedAt { get; set; } - //public bool Ended { get; private set; } = false; - - public ulong ServerId { get; set; } - public ulong ChannelId { get; set; } - - [JsonIgnore] - public ITextChannel Channel { get; internal set; } - - /// - /// This init is purely for the deserialization - /// - public ClashWar() { } - - public ClashWar(string enemyClan, int size, ulong serverId, ulong channelId) - { - this.EnemyClan = enemyClan; - this.Size = size; - this.Bases = new Caller[size]; - this.ServerId = serverId; - this.ChannelId = channelId; - this.Channel = NadekoBot.Client.GetGuildsAsync() //nice api you got here volt, - .GetAwaiter() //especially like how getguildsasync isn't async at all internally. - .GetResult() //But hey, lib has to be async kek - .FirstOrDefault(s => s.Id == serverId)? // srsly - .GetChannelsAsync() //wtf is this - .GetAwaiter() // oh i know, its the implementation detail - .GetResult() // and makes library look consistent - .FirstOrDefault(c => c.Id == channelId) // its not common sense to make library work like this. - as ITextChannel; // oh and don't forget to cast it to this arbitrary bullshit - } - - public void End() - { - //Ended = true; - WarState = StateOfWar.Ended; - } - - public void Call(string u, int baseNumber) - { - if (baseNumber < 0 || baseNumber >= Bases.Length) - throw new ArgumentException("Invalid base number"); - if (Bases[baseNumber] != null) - throw new ArgumentException("That base is already claimed."); - for (var i = 0; i < Bases.Length; i++) - { - if (Bases[i]?.BaseDestroyed == false && Bases[i]?.CallUser == u) - throw new ArgumentException($"@{u} You already claimed base #{i + 1}. You can't claim a new one."); - } - - Bases[baseNumber] = new Caller(u.Trim(), DateTime.UtcNow, false); - } - - public void Start() - { - if (WarState == StateOfWar.Started) - throw new InvalidOperationException("War already started"); - //if (Started) - // throw new InvalidOperationException(); - //Started = true; - WarState = StateOfWar.Started; - StartedAt = DateTime.UtcNow; - foreach (var b in Bases.Where(b => b != null)) - { - b.ResetTime(); - } - } - - public int Uncall(string user) - { - user = user.Trim(); - for (var i = 0; i < Bases.Length; i++) - { - if (Bases[i]?.CallUser != user) continue; - Bases[i] = null; - return i; - } - throw new InvalidOperationException("You are not participating in that war."); - } - - public string ShortPrint() => - $"`{EnemyClan}` ({Size} v {Size})"; - - public override string ToString() - { - var sb = new StringBuilder(); - - sb.AppendLine($"🔰**WAR AGAINST `{EnemyClan}` ({Size} v {Size}) INFO:**"); - if (WarState == StateOfWar.Created) - sb.AppendLine("`not started`"); - for (var i = 0; i < Bases.Length; i++) - { - if (Bases[i] == null) - { - sb.AppendLine($"`{i + 1}.` ❌*unclaimed*"); - } - else - { - if (Bases[i].BaseDestroyed) - { - sb.AppendLine($"`{i + 1}.` ✅ `{Bases[i].CallUser}` {new string('⭐', Bases[i].Stars)}"); - } - else - { - var left = (WarState == StateOfWar.Started) ? callExpire - (DateTime.UtcNow - Bases[i].TimeAdded) : callExpire; - sb.AppendLine($"`{i + 1}.` ✅ `{Bases[i].CallUser}` {left.Hours}h {left.Minutes}m {left.Seconds}s left"); - } - } - - } - return sb.ToString(); - } - - public int FinishClaim(string user, int stars = 3) - { - user = user.Trim(); - for (var i = 0; i < Bases.Length; i++) - { - if (Bases[i]?.BaseDestroyed != false || Bases[i]?.CallUser != user) continue; - Bases[i].BaseDestroyed = true; - Bases[i].Stars = stars; - return i; - } - throw new InvalidOperationException($"@{user} You are either not participating in that war, or you already destroyed a base."); - } - } -} diff --git a/src/NadekoBot/Modules/ClashOfClans/Extensions.cs b/src/NadekoBot/Modules/ClashOfClans/Extensions.cs new file mode 100644 index 00000000..b367f0a6 --- /dev/null +++ b/src/NadekoBot/Modules/ClashOfClans/Extensions.cs @@ -0,0 +1,124 @@ +using Discord; +using Discord.WebSocket; +using NadekoBot.Services.Database.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static NadekoBot.Services.Database.Models.ClashWar; + +namespace NadekoBot.Modules.ClashOfClans +{ + public static class Extensions + { + public static void ResetTime(this ClashCaller c) + { + c.TimeAdded = DateTime.UtcNow; + } + + public static void Destroy(this ClashCaller c) + { + c.BaseDestroyed = true; + } + + public static void End(this ClashWar cw) + { + //Ended = true; + cw.WarState = StateOfWar.Ended; + } + + public static void Call(this ClashWar cw, string u, int baseNumber) + { + if (baseNumber < 0 || baseNumber >= cw.Bases.Capacity) + throw new ArgumentException("Invalid base number"); + if (cw.Bases[baseNumber] != null) + throw new ArgumentException("That base is already claimed."); + for (var i = 0; i < cw.Bases.Capacity; i++) + { + if (cw.Bases[i]?.BaseDestroyed == false && cw.Bases[i]?.CallUser == u) + throw new ArgumentException($"@{u} You already claimed base #{i + 1}. You can't claim a new one."); + } + + cw.Bases[baseNumber] = new ClashCaller() { + CallUser = u.Trim(), + TimeAdded = DateTime.UtcNow, + BaseDestroyed = false + }; + } + + public static void Start(this ClashWar cw) + { + if (cw.WarState == StateOfWar.Started) + throw new InvalidOperationException("War already started"); + //if (Started) + // throw new InvalidOperationException(); + //Started = true; + cw.WarState = StateOfWar.Started; + cw.StartedAt = DateTime.UtcNow; + foreach (var b in cw.Bases.Where(b => b != null)) + { + b.ResetTime(); + } + } + + public static int Uncall(this ClashWar cw, string user) + { + user = user.Trim(); + for (var i = 0; i < cw.Bases.Capacity; i++) + { + if (cw.Bases[i]?.CallUser != user) continue; + cw.Bases[i] = null; + return i; + } + throw new InvalidOperationException("You are not participating in that war."); + } + + public static string ShortPrint(this ClashWar cw) => + $"`{cw.EnemyClan}` ({cw.Size} v {cw.Size})"; + + public static string ToPrettyString(this ClashWar cw) + { + var sb = new StringBuilder(); + + sb.AppendLine($"🔰**WAR AGAINST `{cw.EnemyClan}` ({cw.Size} v {cw.Size}) INFO:**"); + if (cw.WarState == StateOfWar.Created) + sb.AppendLine("`not started`"); + var twoHours = new TimeSpan(2, 0, 0); + for (var i = 0; i < cw.Bases.Capacity; i++) + { + if (cw.Bases[i] == null) + { + sb.AppendLine($"`{i + 1}.` ❌*unclaimed*"); + } + else + { + if (cw.Bases[i].BaseDestroyed) + { + sb.AppendLine($"`{i + 1}.` ✅ `{cw.Bases[i].CallUser}` {new string('⭐', cw.Bases[i].Stars)}"); + } + else + { + var left = (cw.WarState == StateOfWar.Started) ? twoHours - (DateTime.UtcNow - cw.Bases[i].TimeAdded) : twoHours; + sb.AppendLine($"`{i + 1}.` ✅ `{cw.Bases[i].CallUser}` {left.Hours}h {left.Minutes}m {left.Seconds}s left"); + } + } + + } + return sb.ToString(); + } + + public static int FinishClaim(this ClashWar cw, string user, int stars = 3) + { + user = user.Trim(); + for (var i = 0; i < cw.Bases.Capacity; i++) + { + if (cw.Bases[i]?.BaseDestroyed != false || cw.Bases[i]?.CallUser != user) continue; + cw.Bases[i].BaseDestroyed = true; + cw.Bases[i].Stars = stars; + return i; + } + throw new InvalidOperationException($"@{user} You are either not participating in that war, or you already destroyed a base."); + } + } +} \ No newline at end of file diff --git a/src/NadekoBot/Modules/Gambling/Commands/AnimalRacing.cs b/src/NadekoBot/Modules/Gambling/Commands/AnimalRacing.cs index 380b11c2..765f49b9 100644 --- a/src/NadekoBot/Modules/Gambling/Commands/AnimalRacing.cs +++ b/src/NadekoBot/Modules/Gambling/Commands/AnimalRacing.cs @@ -1,7 +1,6 @@ using Discord; using Discord.Commands; using NadekoBot.Attributes; -using NadekoBot.Classes; using NadekoBot.Extensions; using System; using System.Collections.Concurrent; diff --git a/src/NadekoBot/Modules/Gambling/Commands/DiceRollCommand.cs b/src/NadekoBot/Modules/Gambling/Commands/DiceRollCommand.cs index e281ed7a..eba98e1a 100644 --- a/src/NadekoBot/Modules/Gambling/Commands/DiceRollCommand.cs +++ b/src/NadekoBot/Modules/Gambling/Commands/DiceRollCommand.cs @@ -1,7 +1,6 @@ using Discord; using Discord.Commands; using NadekoBot.Attributes; -using NadekoBot.Classes; using NadekoBot.Extensions; using System; using System.Collections.Generic; diff --git a/src/NadekoBot/Modules/Music/Classes/Song.cs b/src/NadekoBot/Modules/Music/Classes/Song.cs index db4b06ea..372e598b 100644 --- a/src/NadekoBot/Modules/Music/Classes/Song.cs +++ b/src/NadekoBot/Modules/Music/Classes/Song.cs @@ -1,5 +1,4 @@ using Discord.Audio; -using NadekoBot.Classes; using NadekoBot.Extensions; using System; using System.Diagnostics; diff --git a/src/NadekoBot/Modules/Music/Classes/SoundCloud.cs b/src/NadekoBot/Modules/Music/Classes/SoundCloud.cs index 88c5bdbe..c788ed74 100644 --- a/src/NadekoBot/Modules/Music/Classes/SoundCloud.cs +++ b/src/NadekoBot/Modules/Music/Classes/SoundCloud.cs @@ -1,5 +1,4 @@ -using NadekoBot.Classes; -using Newtonsoft.Json; +using Newtonsoft.Json; using System; using System.Linq; using System.Net.Http; diff --git a/src/NadekoBot/Modules/Searches/Commands/OsuCommands.cs b/src/NadekoBot/Modules/Searches/Commands/OsuCommands.cs index 6988f59d..9c024d53 100644 --- a/src/NadekoBot/Modules/Searches/Commands/OsuCommands.cs +++ b/src/NadekoBot/Modules/Searches/Commands/OsuCommands.cs @@ -1,7 +1,6 @@ using Discord; using Discord.Commands; using NadekoBot.Attributes; -using NadekoBot.Classes; using NadekoBot.Extensions; using Newtonsoft.Json.Linq; using NLog; diff --git a/src/NadekoBot/Services/Database/IUnitOfWork.cs b/src/NadekoBot/Services/Database/IUnitOfWork.cs index 2b37dc5d..74956906 100644 --- a/src/NadekoBot/Services/Database/IUnitOfWork.cs +++ b/src/NadekoBot/Services/Database/IUnitOfWork.cs @@ -12,6 +12,8 @@ namespace NadekoBot.Services.Database IQuoteRepository Quotes { get; } IConfigRepository GuildConfigs { get; } IDonatorsRepository Donators { get; } + IClashOfClansRepository ClashOfClans { get; } + int Complete(); Task CompleteAsync(); } diff --git a/src/NadekoBot/Services/Database/Models/ClashCaller.cs b/src/NadekoBot/Services/Database/Models/ClashCaller.cs new file mode 100644 index 00000000..2f875049 --- /dev/null +++ b/src/NadekoBot/Services/Database/Models/ClashCaller.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NadekoBot.Services.Database.Models +{ + public class ClashCaller : DbEntity + { + public string CallUser { get; set; } + + public DateTime TimeAdded { get; set; } + + public bool BaseDestroyed { get; set; } + + public int Stars { get; set; } = 3; + + public int ClashWarId { get; set; } + + [ForeignKey(nameof(ClashWarId))] + public ClashWar ClashWar { get; set; } + } +} diff --git a/src/NadekoBot/Services/Database/Models/ClashWar.cs b/src/NadekoBot/Services/Database/Models/ClashWar.cs new file mode 100644 index 00000000..2daaf699 --- /dev/null +++ b/src/NadekoBot/Services/Database/Models/ClashWar.cs @@ -0,0 +1,36 @@ +using Discord; +using Discord.WebSocket; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NadekoBot.Services.Database.Models +{ + public class ClashWar : DbEntity + { + public enum DestroyStars + { + One, Two, Three + } + public enum StateOfWar + { + Started, Ended, Created + } + + public string EnemyClan { get; set; } + public int Size { get; set; } + public StateOfWar WarState { get; set; } = StateOfWar.Created; + public DateTime StartedAt { get; set; } + + public ulong GuildId { get; set; } + public ulong ChannelId { get; set; } + + [NotMapped] + public ITextChannel Channel { get; internal set; } + + public List Bases { get; set; } + } +} diff --git a/src/NadekoBot/Services/Database/NadekoContext.cs b/src/NadekoBot/Services/Database/NadekoContext.cs index 8f2c2a1f..4676c3fb 100644 --- a/src/NadekoBot/Services/Database/NadekoContext.cs +++ b/src/NadekoBot/Services/Database/NadekoContext.cs @@ -13,6 +13,8 @@ namespace NadekoBot.Services.Database public DbSet Quotes { get; set; } public DbSet Donators { get; set; } public DbSet GuildConfigs { get; set; } + public DbSet ClashOfClans { get; set; } + public DbSet ClashCallers { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { @@ -40,6 +42,15 @@ namespace NadekoBot.Services.Database .IsUnique(); #endregion + + #region ClashOfClans + + var callersEntity = modelBuilder.Entity(); + callersEntity + .HasOne(c => c.ClashWar) + .WithMany(c => c.Bases); + + #endregion } protected abstract override void OnConfiguring(DbContextOptionsBuilder optionsBuilder); } diff --git a/src/NadekoBot/Services/Database/Repositories/IClashOfClansRepository.cs b/src/NadekoBot/Services/Database/Repositories/IClashOfClansRepository.cs new file mode 100644 index 00000000..1d395d4d --- /dev/null +++ b/src/NadekoBot/Services/Database/Repositories/IClashOfClansRepository.cs @@ -0,0 +1,14 @@ +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 IClashOfClansRepository : IRepository + { + + } +} diff --git a/src/NadekoBot/Services/Database/Repositories/Impl/ClashOfClansRepository.cs b/src/NadekoBot/Services/Database/Repositories/Impl/ClashOfClansRepository.cs new file mode 100644 index 00000000..c2016800 --- /dev/null +++ b/src/NadekoBot/Services/Database/Repositories/Impl/ClashOfClansRepository.cs @@ -0,0 +1,17 @@ +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 ClashOfClansRepository : Repository, IClashOfClansRepository + { + public ClashOfClansRepository(DbContext context) : base(context) + { + } + } +} diff --git a/src/NadekoBot/Services/Database/UnitOfWork.cs b/src/NadekoBot/Services/Database/UnitOfWork.cs index 1768f7de..2565a228 100644 --- a/src/NadekoBot/Services/Database/UnitOfWork.cs +++ b/src/NadekoBot/Services/Database/UnitOfWork.cs @@ -21,6 +21,9 @@ namespace NadekoBot.Services.Database private IDonatorsRepository _donators; public IDonatorsRepository Donators => _donators ?? (_donators = new DonatorsRepository(_context)); + private IClashOfClansRepository _clashOfClans; + public IClashOfClansRepository ClashOfClans => _clashOfClans ?? (_clashOfClans = new ClashOfClansRepository(_context)); + public UnitOfWork(NadekoContext context) { _context = context;