diff --git a/.gitignore b/.gitignore index e5c7adbc..d9b88ac7 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ obj/ Tests/bin src/NadekoBot/credentials.json src/NadekoBot/project.lock.json +src/NadekoBot/data/* # NuGet Packages *.nupkg diff --git a/discord.net b/discord.net index fa06826f..e8550fa4 160000 --- a/discord.net +++ b/discord.net @@ -1 +1 @@ -Subproject commit fa06826f92fd020f2af5f48aa25784d10239f668 +Subproject commit e8550fa462f86e0338925547dfe99242bfc1fdcc diff --git a/src/NadekoBot/Attributes/OwnerOnlyAttribute.cs b/src/NadekoBot/Attributes/OwnerOnlyAttribute.cs index c29cc346..8236f1d1 100644 --- a/src/NadekoBot/Attributes/OwnerOnlyAttribute.cs +++ b/src/NadekoBot/Attributes/OwnerOnlyAttribute.cs @@ -1,12 +1,11 @@ -using System.Threading.Tasks; -using Discord.Commands; -using Discord; +//using System.Threading.Tasks; +//using Discord.Commands; +//using Discord; -namespace NadekoBot.Attributes { - public class OwnerOnlyAttribute : PreconditionAttribute - { - - public override Task CheckPermissions(IMessage context, Command executingCommand, object moduleInstance) => - Task.FromResult((NadekoBot.Credentials.IsOwner(context.Author) ? PreconditionResult.FromSuccess() : PreconditionResult.FromError("Not owner"))); - } -} \ No newline at end of file +//namespace NadekoBot.Attributes { +// public class OwnerOnlyAttribute : PreconditionAttribute +// { +// public override Task CheckPermissions(IUserMessage context, Command executingCommand, object moduleInstance) => +// Task.FromResult((NadekoBot.Credentials.IsOwner(context.Author) ? PreconditionResult.FromSuccess() : PreconditionResult.FromError("Not owner"))); +// } +//} \ No newline at end of file diff --git a/src/NadekoBot/Migrations/20160825131849_FirstMigration.Designer.cs b/src/NadekoBot/Migrations/20160825131849_FirstMigration.Designer.cs deleted file mode 100644 index 26120b33..00000000 --- a/src/NadekoBot/Migrations/20160825131849_FirstMigration.Designer.cs +++ /dev/null @@ -1,103 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Migrations; -using NadekoBot.Services.Database.Impl; - -namespace NadekoBot.Migrations -{ - [DbContext(typeof(NadekoSqliteContext))] - [Migration("20160825131849_FirstMigration")] - partial class FirstMigration - { - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { - modelBuilder - .HasAnnotation("ProductVersion", "1.0.0-rtm-21431"); - - modelBuilder.Entity("NadekoBot.Services.Database.Models.Donator", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("Amount"); - - b.Property("Name"); - - b.Property("UserId"); - - b.HasKey("Id"); - - b.HasIndex("UserId") - .IsUnique(); - - b.ToTable("Donators"); - }); - - modelBuilder.Entity("NadekoBot.Services.Database.Models.GuildConfig", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("AutoAssignRoleId"); - - b.Property("AutoDeleteByeMessages"); - - b.Property("AutoDeleteGreetMessages"); - - b.Property("AutoDeleteGreetMessagesTimer"); - - b.Property("ByeMessageChannelId"); - - b.Property("ChannelByeMessageText"); - - b.Property("ChannelGreetMessageText"); - - b.Property("DeleteMessageOnCommand"); - - b.Property("DmGreetMessageText"); - - b.Property("GreetMessageChannelId"); - - b.Property("GuildId"); - - b.Property("SendChannelByeMessage"); - - b.Property("SendChannelGreetMessage"); - - b.Property("SendDmGreetMessage"); - - b.HasKey("Id"); - - b.HasIndex("GuildId") - .IsUnique(); - - b.ToTable("GuildConfigs"); - }); - - modelBuilder.Entity("NadekoBot.Services.Database.Models.Quote", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("AuthorId"); - - b.Property("AuthorName") - .IsRequired(); - - b.Property("GuildId"); - - b.Property("Keyword") - .IsRequired(); - - b.Property("Text") - .IsRequired(); - - b.HasKey("Id"); - - b.ToTable("Quotes"); - }); - } - } -} diff --git a/src/NadekoBot/Migrations/20160825131849_FirstMigration.cs b/src/NadekoBot/Migrations/20160825131849_FirstMigration.cs deleted file mode 100644 index 2e6c1b48..00000000 --- a/src/NadekoBot/Migrations/20160825131849_FirstMigration.cs +++ /dev/null @@ -1,94 +0,0 @@ -using System; -using System.Collections.Generic; -using Microsoft.EntityFrameworkCore.Migrations; - -namespace NadekoBot.Migrations -{ - public partial class FirstMigration : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "Donators", - columns: table => new - { - Id = table.Column(nullable: false) - .Annotation("Autoincrement", true), - Amount = table.Column(nullable: false), - Name = table.Column(nullable: true), - UserId = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Donators", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "GuildConfigs", - columns: table => new - { - Id = table.Column(nullable: false) - .Annotation("Autoincrement", true), - AutoAssignRoleId = table.Column(nullable: false), - AutoDeleteByeMessages = table.Column(nullable: false), - AutoDeleteGreetMessages = table.Column(nullable: false), - AutoDeleteGreetMessagesTimer = 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), - GreetMessageChannelId = table.Column(nullable: false), - GuildId = table.Column(nullable: false), - SendChannelByeMessage = table.Column(nullable: false), - SendChannelGreetMessage = table.Column(nullable: false), - SendDmGreetMessage = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_GuildConfigs", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "Quotes", - columns: table => new - { - Id = table.Column(nullable: false) - .Annotation("Autoincrement", true), - AuthorId = table.Column(nullable: false), - AuthorName = table.Column(nullable: false), - GuildId = table.Column(nullable: false), - Keyword = table.Column(nullable: false), - Text = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Quotes", x => x.Id); - }); - - migrationBuilder.CreateIndex( - name: "IX_Donators_UserId", - table: "Donators", - column: "UserId", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_GuildConfigs_GuildId", - table: "GuildConfigs", - column: "GuildId", - unique: true); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "Donators"); - - migrationBuilder.DropTable( - name: "GuildConfigs"); - - migrationBuilder.DropTable( - name: "Quotes"); - } - } -} diff --git a/src/NadekoBot/Migrations/20160828000228_first.Designer.cs b/src/NadekoBot/Migrations/20160828000228_first.Designer.cs new file mode 100644 index 00000000..43f73276 --- /dev/null +++ b/src/NadekoBot/Migrations/20160828000228_first.Designer.cs @@ -0,0 +1,345 @@ +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using NadekoBot.Services.Database.Impl; + +namespace NadekoBot.Migrations +{ + [DbContext(typeof(NadekoSqliteContext))] + [Migration("20160828000228_first")] + partial class first + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { + modelBuilder + .HasAnnotation("ProductVersion", "1.0.0-rtm-21431"); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.BlacklistItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BotConfigId"); + + b.Property("ItemId"); + + b.HasKey("Id"); + + b.HasIndex("BotConfigId"); + + b.ToTable("BlacklistItem"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.BotConfig", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BufferSize"); + + b.Property("CurrencyName"); + + b.Property("CurrencyPluralName"); + + b.Property("CurrencySign"); + + b.Property("DontJoinServers"); + + b.Property("ForwardMessages"); + + b.Property("ForwardToAllOwners"); + + b.Property("RemindMessageFormat"); + + b.Property("RotatingStatuses"); + + b.HasKey("Id"); + + b.ToTable("BotConfig"); + }); + + 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") + .ValueGeneratedOnAdd(); + + b.Property("Amount"); + + b.Property("Name"); + + b.Property("UserId"); + + b.HasKey("Id"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("Donators"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.EightBallResponse", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BotConfigId"); + + b.Property("Text"); + + b.HasKey("Id"); + + b.HasIndex("BotConfigId"); + + b.ToTable("EightBallResponse"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.GuildConfig", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AutoAssignRoleId"); + + b.Property("AutoDeleteByeMessages"); + + b.Property("AutoDeleteGreetMessages"); + + b.Property("AutoDeleteGreetMessagesTimer"); + + b.Property("AutoDeleteSelfAssignedRoleMessages"); + + b.Property("ByeMessageChannelId"); + + b.Property("ChannelByeMessageText"); + + b.Property("ChannelGreetMessageText"); + + b.Property("DeleteMessageOnCommand"); + + b.Property("DmGreetMessageText"); + + b.Property("ExclusiveSelfAssignedRoles"); + + b.Property("GreetMessageChannelId"); + + b.Property("GuildId"); + + b.Property("SendChannelByeMessage"); + + b.Property("SendChannelGreetMessage"); + + b.Property("SendDmGreetMessage"); + + b.HasKey("Id"); + + b.HasIndex("GuildId") + .IsUnique(); + + b.ToTable("GuildConfigs"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ModulePrefix", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BotConfigId"); + + b.Property("ModuleName"); + + b.Property("Prefix"); + + b.HasKey("Id"); + + b.HasIndex("BotConfigId"); + + b.ToTable("ModulePrefix"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.PlayingStatus", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BotConfigId"); + + b.Property("Status"); + + b.HasKey("Id"); + + b.HasIndex("BotConfigId"); + + b.ToTable("PlayingStatus"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.Quote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("AuthorId"); + + b.Property("AuthorName") + .IsRequired(); + + b.Property("GuildId"); + + b.Property("Keyword") + .IsRequired(); + + b.Property("Text") + .IsRequired(); + + b.HasKey("Id"); + + b.ToTable("Quotes"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.RaceAnimal", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BotConfigId"); + + b.Property("Icon"); + + b.Property("Name"); + + b.HasKey("Id"); + + b.HasIndex("BotConfigId"); + + b.ToTable("RaceAnimal"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.Reminder", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ChannelId"); + + b.Property("IsPrivate"); + + b.Property("Message"); + + b.Property("ServerId"); + + b.Property("UserId"); + + b.Property("When"); + + b.HasKey("Id"); + + 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.BlacklistItem", b => + { + b.HasOne("NadekoBot.Services.Database.Models.BotConfig") + .WithMany("Blacklist") + .HasForeignKey("BotConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ClashCaller", b => + { + b.HasOne("NadekoBot.Services.Database.Models.ClashWar", "ClashWar") + .WithMany("Bases") + .HasForeignKey("ClashWarId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.EightBallResponse", b => + { + b.HasOne("NadekoBot.Services.Database.Models.BotConfig") + .WithMany("EightBallResponses") + .HasForeignKey("BotConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ModulePrefix", b => + { + b.HasOne("NadekoBot.Services.Database.Models.BotConfig") + .WithMany("ModulePrefixes") + .HasForeignKey("BotConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.PlayingStatus", b => + { + b.HasOne("NadekoBot.Services.Database.Models.BotConfig") + .WithMany("RotatingStatusMessages") + .HasForeignKey("BotConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.RaceAnimal", b => + { + b.HasOne("NadekoBot.Services.Database.Models.BotConfig") + .WithMany("RaceAnimals") + .HasForeignKey("BotConfigId"); + }); + } + } +} diff --git a/src/NadekoBot/Migrations/20160828000228_first.cs b/src/NadekoBot/Migrations/20160828000228_first.cs new file mode 100644 index 00000000..081d2cb9 --- /dev/null +++ b/src/NadekoBot/Migrations/20160828000228_first.cs @@ -0,0 +1,358 @@ +using System; +using System.Collections.Generic; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace NadekoBot.Migrations +{ + public partial class first : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "BotConfig", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Autoincrement", true), + BufferSize = table.Column(nullable: false), + CurrencyName = table.Column(nullable: true), + CurrencyPluralName = table.Column(nullable: true), + CurrencySign = table.Column(nullable: true), + DontJoinServers = table.Column(nullable: false), + ForwardMessages = table.Column(nullable: false), + ForwardToAllOwners = table.Column(nullable: false), + RemindMessageFormat = table.Column(nullable: true), + RotatingStatuses = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_BotConfig", x => x.Id); + }); + + 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 + { + Id = table.Column(nullable: false) + .Annotation("Autoincrement", true), + Amount = table.Column(nullable: false), + Name = table.Column(nullable: true), + UserId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Donators", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "GuildConfigs", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Autoincrement", true), + AutoAssignRoleId = table.Column(nullable: false), + 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), + SendChannelGreetMessage = table.Column(nullable: false), + SendDmGreetMessage = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_GuildConfigs", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Quotes", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Autoincrement", true), + AuthorId = table.Column(nullable: false), + AuthorName = table.Column(nullable: false), + GuildId = table.Column(nullable: false), + Keyword = table.Column(nullable: false), + Text = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Quotes", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Reminders", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Autoincrement", true), + ChannelId = table.Column(nullable: false), + IsPrivate = table.Column(nullable: false), + Message = table.Column(nullable: true), + ServerId = table.Column(nullable: false), + UserId = table.Column(nullable: false), + When = table.Column(nullable: false) + }, + constraints: table => + { + 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: "BlacklistItem", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Autoincrement", true), + BotConfigId = table.Column(nullable: true), + ItemId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_BlacklistItem", x => x.Id); + table.ForeignKey( + name: "FK_BlacklistItem_BotConfig_BotConfigId", + column: x => x.BotConfigId, + principalTable: "BotConfig", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "EightBallResponse", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Autoincrement", true), + BotConfigId = table.Column(nullable: true), + Text = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_EightBallResponse", x => x.Id); + table.ForeignKey( + name: "FK_EightBallResponse_BotConfig_BotConfigId", + column: x => x.BotConfigId, + principalTable: "BotConfig", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "ModulePrefix", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Autoincrement", true), + BotConfigId = table.Column(nullable: true), + ModuleName = table.Column(nullable: true), + Prefix = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_ModulePrefix", x => x.Id); + table.ForeignKey( + name: "FK_ModulePrefix_BotConfig_BotConfigId", + column: x => x.BotConfigId, + principalTable: "BotConfig", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "PlayingStatus", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Autoincrement", true), + BotConfigId = table.Column(nullable: true), + Status = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_PlayingStatus", x => x.Id); + table.ForeignKey( + name: "FK_PlayingStatus_BotConfig_BotConfigId", + column: x => x.BotConfigId, + principalTable: "BotConfig", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "RaceAnimal", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Autoincrement", true), + BotConfigId = table.Column(nullable: true), + Icon = table.Column(nullable: true), + Name = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_RaceAnimal", x => x.Id); + table.ForeignKey( + name: "FK_RaceAnimal_BotConfig_BotConfigId", + column: x => x.BotConfigId, + principalTable: "BotConfig", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + 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_BlacklistItem_BotConfigId", + table: "BlacklistItem", + column: "BotConfigId"); + + migrationBuilder.CreateIndex( + name: "IX_ClashCallers_ClashWarId", + table: "ClashCallers", + column: "ClashWarId"); + + migrationBuilder.CreateIndex( + name: "IX_Donators_UserId", + table: "Donators", + column: "UserId", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_EightBallResponse_BotConfigId", + table: "EightBallResponse", + column: "BotConfigId"); + + migrationBuilder.CreateIndex( + name: "IX_GuildConfigs_GuildId", + table: "GuildConfigs", + column: "GuildId", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_ModulePrefix_BotConfigId", + table: "ModulePrefix", + column: "BotConfigId"); + + migrationBuilder.CreateIndex( + name: "IX_PlayingStatus_BotConfigId", + table: "PlayingStatus", + column: "BotConfigId"); + + migrationBuilder.CreateIndex( + name: "IX_RaceAnimal_BotConfigId", + table: "RaceAnimal", + column: "BotConfigId"); + + migrationBuilder.CreateIndex( + name: "IX_SelfAssignableRoles_GuildId_RoleId", + table: "SelfAssignableRoles", + columns: new[] { "GuildId", "RoleId" }, + unique: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "BlacklistItem"); + + migrationBuilder.DropTable( + name: "ClashCallers"); + + migrationBuilder.DropTable( + name: "Donators"); + + migrationBuilder.DropTable( + name: "EightBallResponse"); + + migrationBuilder.DropTable( + name: "GuildConfigs"); + + migrationBuilder.DropTable( + name: "ModulePrefix"); + + migrationBuilder.DropTable( + name: "PlayingStatus"); + + migrationBuilder.DropTable( + name: "Quotes"); + + migrationBuilder.DropTable( + name: "RaceAnimal"); + + migrationBuilder.DropTable( + name: "Reminders"); + + migrationBuilder.DropTable( + name: "SelfAssignableRoles"); + + migrationBuilder.DropTable( + name: "ClashOfClans"); + + migrationBuilder.DropTable( + name: "BotConfig"); + } + } +} diff --git a/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs b/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs index d40b25fd..b9042c98 100644 --- a/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs +++ b/src/NadekoBot/Migrations/NadekoSqliteContextModelSnapshot.cs @@ -15,6 +15,94 @@ namespace NadekoBot.Migrations modelBuilder .HasAnnotation("ProductVersion", "1.0.0-rtm-21431"); + modelBuilder.Entity("NadekoBot.Services.Database.Models.BlacklistItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BotConfigId"); + + b.Property("ItemId"); + + b.HasKey("Id"); + + b.HasIndex("BotConfigId"); + + b.ToTable("BlacklistItem"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.BotConfig", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BufferSize"); + + b.Property("CurrencyName"); + + b.Property("CurrencyPluralName"); + + b.Property("CurrencySign"); + + b.Property("DontJoinServers"); + + b.Property("ForwardMessages"); + + b.Property("ForwardToAllOwners"); + + b.Property("RemindMessageFormat"); + + b.Property("RotatingStatuses"); + + b.HasKey("Id"); + + b.ToTable("BotConfig"); + }); + + 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") @@ -34,6 +122,22 @@ namespace NadekoBot.Migrations b.ToTable("Donators"); }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.EightBallResponse", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BotConfigId"); + + b.Property("Text"); + + b.HasKey("Id"); + + b.HasIndex("BotConfigId"); + + b.ToTable("EightBallResponse"); + }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.GuildConfig", b => { b.Property("Id") @@ -47,6 +151,8 @@ namespace NadekoBot.Migrations b.Property("AutoDeleteGreetMessagesTimer"); + b.Property("AutoDeleteSelfAssignedRoleMessages"); + b.Property("ByeMessageChannelId"); b.Property("ChannelByeMessageText"); @@ -57,6 +163,8 @@ namespace NadekoBot.Migrations b.Property("DmGreetMessageText"); + b.Property("ExclusiveSelfAssignedRoles"); + b.Property("GreetMessageChannelId"); b.Property("GuildId"); @@ -75,6 +183,40 @@ namespace NadekoBot.Migrations b.ToTable("GuildConfigs"); }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.ModulePrefix", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BotConfigId"); + + b.Property("ModuleName"); + + b.Property("Prefix"); + + b.HasKey("Id"); + + b.HasIndex("BotConfigId"); + + b.ToTable("ModulePrefix"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.PlayingStatus", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BotConfigId"); + + b.Property("Status"); + + b.HasKey("Id"); + + b.HasIndex("BotConfigId"); + + b.ToTable("PlayingStatus"); + }); + modelBuilder.Entity("NadekoBot.Services.Database.Models.Quote", b => { b.Property("Id") @@ -97,6 +239,106 @@ namespace NadekoBot.Migrations b.ToTable("Quotes"); }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.RaceAnimal", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("BotConfigId"); + + b.Property("Icon"); + + b.Property("Name"); + + b.HasKey("Id"); + + b.HasIndex("BotConfigId"); + + b.ToTable("RaceAnimal"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.Reminder", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("ChannelId"); + + b.Property("IsPrivate"); + + b.Property("Message"); + + b.Property("ServerId"); + + b.Property("UserId"); + + b.Property("When"); + + b.HasKey("Id"); + + 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.BlacklistItem", b => + { + b.HasOne("NadekoBot.Services.Database.Models.BotConfig") + .WithMany("Blacklist") + .HasForeignKey("BotConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ClashCaller", b => + { + b.HasOne("NadekoBot.Services.Database.Models.ClashWar", "ClashWar") + .WithMany("Bases") + .HasForeignKey("ClashWarId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.EightBallResponse", b => + { + b.HasOne("NadekoBot.Services.Database.Models.BotConfig") + .WithMany("EightBallResponses") + .HasForeignKey("BotConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.ModulePrefix", b => + { + b.HasOne("NadekoBot.Services.Database.Models.BotConfig") + .WithMany("ModulePrefixes") + .HasForeignKey("BotConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.PlayingStatus", b => + { + b.HasOne("NadekoBot.Services.Database.Models.BotConfig") + .WithMany("RotatingStatusMessages") + .HasForeignKey("BotConfigId"); + }); + + modelBuilder.Entity("NadekoBot.Services.Database.Models.RaceAnimal", b => + { + b.HasOne("NadekoBot.Services.Database.Models.BotConfig") + .WithMany("RaceAnimals") + .HasForeignKey("BotConfigId"); + }); } } } diff --git a/src/NadekoBot/Modules/Administration/Administration.cs b/src/NadekoBot/Modules/Administration/Administration.cs index 345b8949..b96ec950 100644 --- a/src/NadekoBot/Modules/Administration/Administration.cs +++ b/src/NadekoBot/Modules/Administration/Administration.cs @@ -20,16 +20,16 @@ namespace NadekoBot.Modules.Administration [Module(".", AppendSpace = false)] public partial class Administration : DiscordModule { - public Administration(ILocalization loc, CommandService cmds, IBotConfiguration config, DiscordSocketClient client) : base(loc, cmds, config, client) + public Administration(ILocalization loc, CommandService cmds, DiscordSocketClient client) : base(loc, cmds, client) { } ////todo owner only //[LocalizedCommand, LocalizedDescription, LocalizedSummary] //[RequireContext(ContextType.Guild)] - //public async Task Restart(IMessage imsg) + //public async Task Restart(IUserMessage umsg) //{ - // var channel = (ITextChannel)imsg.Channel; + // var channel = (ITextChannel)umsg.Channel; // await channel.SendMessageAsync("`Restarting in 2 seconds...`"); // await Task.Delay(2000); @@ -40,9 +40,9 @@ namespace NadekoBot.Modules.Administration [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] [RequirePermission(GuildPermission.Administrator)] - public async Task Delmsgoncmd(IMessage imsg) + public async Task Delmsgoncmd(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; GuildConfig conf; using (var uow = DbHandler.UnitOfWork()) { @@ -60,9 +60,9 @@ namespace NadekoBot.Modules.Administration [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] [RequirePermission(GuildPermission.ManageRoles)] - public async Task Setrole(IMessage imsg, IGuildUser usr, [Remainder] IRole role) + public async Task Setrole(IUserMessage umsg, IGuildUser usr, [Remainder] IRole role) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; try { await usr.AddRolesAsync(role).ConfigureAwait(false); @@ -78,9 +78,9 @@ namespace NadekoBot.Modules.Administration [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] [RequirePermission(GuildPermission.ManageRoles)] - public async Task Removerole(IMessage imsg, IGuildUser usr, [Remainder] IRole role) + public async Task Removerole(IUserMessage umsg, IGuildUser usr, [Remainder] IRole role) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; try { await usr.RemoveRolesAsync(role).ConfigureAwait(false); @@ -95,9 +95,9 @@ namespace NadekoBot.Modules.Administration [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] [RequirePermission(GuildPermission.ManageRoles)] - public async Task RenameRole(IMessage imsg, IRole roleToEdit, string newname) + public async Task RenameRole(IUserMessage umsg, IRole roleToEdit, string newname) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; try { if (roleToEdit.Position > (await channel.Guild.GetCurrentUserAsync().ConfigureAwait(false)).Roles.Max(r => r.Position)) @@ -117,9 +117,9 @@ namespace NadekoBot.Modules.Administration [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] [RequirePermission(GuildPermission.ManageRoles)] - public async Task RemoveAllRoles(IMessage imsg, [Remainder] IGuildUser user) + public async Task RemoveAllRoles(IUserMessage umsg, [Remainder] IGuildUser user) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; try { @@ -135,9 +135,9 @@ namespace NadekoBot.Modules.Administration [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] [RequirePermission(GuildPermission.ManageRoles)] - public async Task CreateRole(IMessage imsg, [Remainder] string roleName = null) + public async Task CreateRole(IUserMessage umsg, [Remainder] string roleName = null) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; if (string.IsNullOrWhiteSpace(roleName)) @@ -156,9 +156,9 @@ namespace NadekoBot.Modules.Administration [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] [RequirePermission(GuildPermission.ManageRoles)] - public async Task RoleColor(IMessage imsg, params string[] args) + public async Task RoleColor(IUserMessage umsg, params string[] args) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; if (args.Count() != 2 && args.Count() != 4) { @@ -194,9 +194,9 @@ namespace NadekoBot.Modules.Administration [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] [RequirePermission(GuildPermission.BanMembers)] - public async Task Ban(IMessage imsg, IGuildUser user) + public async Task Ban(IUserMessage umsg, IGuildUser user) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; var msg = ""; @@ -221,9 +221,9 @@ namespace NadekoBot.Modules.Administration [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] [RequirePermission(GuildPermission.BanMembers)] - public async Task Softban(IMessage imsg, IGuildUser user, [Remainder] string msg = null) + public async Task Softban(IUserMessage umsg, IGuildUser user, [Remainder] string msg = null) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; if (!string.IsNullOrWhiteSpace(msg)) { @@ -246,9 +246,9 @@ namespace NadekoBot.Modules.Administration [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Kick(IMessage imsg, IGuildUser user, [Remainder] string msg = null) + public async Task Kick(IUserMessage umsg, IGuildUser user, [Remainder] string msg = null) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; if (user == null) { @@ -275,9 +275,9 @@ namespace NadekoBot.Modules.Administration [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] [RequirePermission(GuildPermission.MuteMembers)] - public async Task Mute(IMessage imsg, params IGuildUser[] users) + public async Task Mute(IUserMessage umsg, params IGuildUser[] users) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; if (!users.Any()) return; @@ -298,9 +298,9 @@ namespace NadekoBot.Modules.Administration [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] [RequirePermission(GuildPermission.MuteMembers)] - public async Task Unmute(IMessage imsg, params IGuildUser[] users) + public async Task Unmute(IUserMessage umsg, params IGuildUser[] users) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; if (!users.Any()) return; @@ -321,9 +321,9 @@ namespace NadekoBot.Modules.Administration [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] [RequirePermission(GuildPermission.DeafenMembers)] - public async Task Deafen(IMessage imsg, params IGuildUser[] users) + public async Task Deafen(IUserMessage umsg, params IGuildUser[] users) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; if (!users.Any()) return; @@ -344,9 +344,9 @@ namespace NadekoBot.Modules.Administration [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] [RequirePermission(GuildPermission.DeafenMembers)] - public async Task UnDeafen(IMessage imsg, params IGuildUser[] users) + public async Task UnDeafen(IUserMessage umsg, params IGuildUser[] users) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; if (!users.Any()) return; @@ -367,18 +367,18 @@ namespace NadekoBot.Modules.Administration [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] [RequirePermission(GuildPermission.ManageChannels)] - public async Task DelVoiChanl(IMessage imsg, [Remainder] IVoiceChannel voiceChannel) + public async Task DelVoiChanl(IUserMessage umsg, [Remainder] IVoiceChannel voiceChannel) { await voiceChannel.DeleteAsync().ConfigureAwait(false); - await imsg.Channel.SendMessageAsync($"Removed channel **{voiceChannel.Name}**.").ConfigureAwait(false); + await umsg.Channel.SendMessageAsync($"Removed channel **{voiceChannel.Name}**.").ConfigureAwait(false); } [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] [RequirePermission(GuildPermission.ManageChannels)] - public async Task CreatVoiChanl(IMessage imsg, [Remainder] string channelName) + public async Task CreatVoiChanl(IUserMessage umsg, [Remainder] string channelName) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; //todo actually print info about created channel var ch = await channel.Guild.CreateVoiceChannelAsync(channelName).ConfigureAwait(false); await channel.SendMessageAsync($"Created voice channel **{ch.Name}**, id `{ch.Id}`.").ConfigureAwait(false); @@ -387,7 +387,7 @@ namespace NadekoBot.Modules.Administration [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] [RequirePermission(GuildPermission.ManageChannels)] - public async Task DelTxtChanl(IMessage imsg, [Remainder] ITextChannel channel) + public async Task DelTxtChanl(IUserMessage umsg, [Remainder] ITextChannel channel) { await channel.DeleteAsync().ConfigureAwait(false); await channel.SendMessageAsync($"Removed text channel **{channel.Name}**, id `{channel.Id}`.").ConfigureAwait(false); @@ -396,9 +396,9 @@ namespace NadekoBot.Modules.Administration [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] [RequirePermission(GuildPermission.ManageChannels)] - public async Task CreaTxtChanl(IMessage imsg, [Remainder] string channelName) + public async Task CreaTxtChanl(IUserMessage umsg, [Remainder] string channelName) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; //todo actually print info about created channel var txtCh = await channel.Guild.CreateTextChannelAsync(channelName).ConfigureAwait(false); await channel.SendMessageAsync($"Added text channel **{txtCh.Name}**, id `{txtCh.Id}`.").ConfigureAwait(false); @@ -407,9 +407,9 @@ namespace NadekoBot.Modules.Administration [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] [RequirePermission(GuildPermission.ManageChannels)] - public async Task SetTopic(IMessage imsg, [Remainder] string topic = null) + public async Task SetTopic(IUserMessage umsg, [Remainder] string topic = null) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; topic = topic ?? ""; await (channel as ITextChannel).ModifyAsync(c => c.Topic = topic); await channel.SendMessageAsync(":ok: **New channel topic set.**").ConfigureAwait(false); @@ -418,9 +418,9 @@ namespace NadekoBot.Modules.Administration [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] [RequirePermission(GuildPermission.ManageChannels)] - public async Task SetChanlName(IMessage imsg, [Remainder] string name) + public async Task SetChanlName(IUserMessage umsg, [Remainder] string name) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; await channel.ModifyAsync(c => c.Name = name).ConfigureAwait(false); await channel.SendMessageAsync(":ok: **New channel name set.**").ConfigureAwait(false); @@ -430,24 +430,24 @@ namespace NadekoBot.Modules.Administration //delets her own messages, no perm required [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Prune(IMessage imsg) + public async Task Prune(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; var user = await channel.Guild.GetCurrentUserAsync(); - var enumerable = (await imsg.Channel.GetMessagesAsync()).Where(x => x.Author.Id == user.Id); - await imsg.Channel.DeleteMessagesAsync(enumerable); + var enumerable = (await umsg.Channel.GetMessagesAsync()).Where(x => x.Author.Id == user.Id); + await umsg.Channel.DeleteMessagesAsync(enumerable); } // prune x [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] [RequirePermission(ChannelPermission.ManageMessages)] - public async Task Prune(IMessage msg, int count) + public async Task Prune(IUserMessage msg, int count) { var channel = msg.Channel as ITextChannel; - await msg.DeleteAsync(); + await (msg as IUserMessage).DeleteAsync(); while (count > 0) { int limit = (count < 100) ? count : 100; @@ -462,7 +462,7 @@ namespace NadekoBot.Modules.Administration //prune @user [x] [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Prune(IMessage msg, IGuildUser user, int count = 100) + public async Task Prune(IUserMessage msg, IGuildUser user, int count = 100) { var channel = msg.Channel as ITextChannel; int limit = (count < 100) ? count : 100; @@ -472,9 +472,9 @@ namespace NadekoBot.Modules.Administration ////todo owner only //[LocalizedCommand, LocalizedDescription, LocalizedSummary] //[RequireContext(ContextType.Guild)] - //public async Task Die(IMessage imsg) + //public async Task Die(IUserMessage umsg) //{ - // var channel = (ITextChannel)imsg.Channel; + // var channel = (ITextChannel)umsg.Channel; // await channel.SendMessageAsync("`Shutting down.`").ConfigureAwait(false); // await Task.Delay(2000).ConfigureAwait(false); @@ -484,18 +484,18 @@ namespace NadekoBot.Modules.Administration ////todo owner only //[LocalizedCommand, LocalizedDescription, LocalizedSummary] //[RequireContext(ContextType.Guild)] - //public async Task Setname(IMessage imsg, [Remainder] string newName = null) + //public async Task Setname(IUserMessage umsg, [Remainder] string newName = null) //{ - // var channel = (ITextChannel)imsg.Channel; + // var channel = (ITextChannel)umsg.Channel; //} ////todo owner only //[LocalizedCommand, LocalizedDescription, LocalizedSummary] //[RequireContext(ContextType.Guild)] - //public async Task NewAvatar(IMessage imsg, [Remainder] string img = null) + //public async Task NewAvatar(IUserMessage umsg, [Remainder] string img = null) //{ - // var channel = (ITextChannel)imsg.Channel; + // var channel = (ITextChannel)umsg.Channel; // if (string.IsNullOrWhiteSpace(img)) // return; @@ -512,9 +512,9 @@ namespace NadekoBot.Modules.Administration ////todo owner only //[LocalizedCommand, LocalizedDescription, LocalizedSummary] //[RequireContext(ContextType.Guild)] - //public async Task SetGame(IMessage imsg, [Remainder] string game = null) + //public async Task SetGame(IUserMessage umsg, [Remainder] string game = null) //{ - // var channel = (ITextChannel)imsg.Channel; + // var channel = (ITextChannel)umsg.Channel; // game = game ?? ""; @@ -524,9 +524,9 @@ namespace NadekoBot.Modules.Administration ////todo owner only //[LocalizedCommand, LocalizedDescription, LocalizedSummary] //[RequireContext(ContextType.Guild)] - //public async Task Send(IMessage imsg, string where, [Remainder] string msg = null) + //public async Task Send(IUserMessage umsg, string where, [Remainder] string msg = null) //{ - // var channel = (ITextChannel)imsg.Channel; + // var channel = (ITextChannel)umsg.Channel; // if (string.IsNullOrWhiteSpace(msg)) // return; @@ -569,9 +569,9 @@ namespace NadekoBot.Modules.Administration ////todo owner only //[LocalizedCommand, LocalizedDescription, LocalizedSummary] //[RequireContext(ContextType.Guild)] - //public async Task Announce(IMessage imsg, [Remainder] string message) + //public async Task Announce(IUserMessage umsg, [Remainder] string message) //{ - // var channel = (ITextChannel)imsg.Channel; + // var channel = (ITextChannel)umsg.Channel; // foreach (var ch in (await _client.GetGuildsAsync().ConfigureAwait(false)).Select(async g => await g.GetDefaultChannelAsync().ConfigureAwait(false))) // { @@ -584,21 +584,21 @@ namespace NadekoBot.Modules.Administration ////todo owner only //[LocalizedCommand, LocalizedDescription, LocalizedSummary] //[RequireContext(ContextType.Guild)] - //public async Task SaveChat(IMessage imsg, int cnt) + //public async Task SaveChat(IUserMessage umsg, int cnt) //{ - // var channel = (ITextChannel)imsg.Channel; + // var channel = (ITextChannel)umsg.Channel; // ulong? lastmsgId = null; // var sb = new StringBuilder(); - // var msgs = new List(cnt); + // var msgs = new List(cnt); // while (cnt > 0) // { // var dlcnt = cnt < 100 ? cnt : 100; - // IReadOnlyCollection dledMsgs; + // IReadOnlyCollection dledMsgs; // if (lastmsgId == null) - // dledMsgs = await imsg.Channel.GetMessagesAsync(cnt).ConfigureAwait(false); + // dledMsgs = await umsg.Channel.GetMessagesAsync(cnt).ConfigureAwait(false); // else - // dledMsgs = await imsg.Channel.GetMessagesAsync(lastmsgId.Value, Direction.Before, dlcnt); + // dledMsgs = await umsg.Channel.GetMessagesAsync(lastmsgId.Value, Direction.Before, dlcnt); // if (!dledMsgs.Any()) // break; @@ -608,7 +608,7 @@ namespace NadekoBot.Modules.Administration // cnt -= 100; // } // var title = $"Chatlog-{channel.Guild.Name}/#{channel.Name}-{DateTime.Now}.txt"; - // await (imsg.Author as IGuildUser).SendFileAsync( + // await (umsg.Author as IGuildUser).SendFileAsync( // await JsonConvert.SerializeObject(new { Messages = msgs.Select(s => s.ToString()) }, Formatting.Indented).ToStream().ConfigureAwait(false), // title, title).ConfigureAwait(false); //} @@ -617,11 +617,11 @@ namespace NadekoBot.Modules.Administration [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] [RequirePermission(GuildPermission.MentionEveryone)] - public async Task MentionRole(IMessage imsg, params IRole[] roles) + public async Task MentionRole(IUserMessage umsg, params IRole[] roles) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; - string send = $"--{imsg.Author.Mention} has invoked a mention on the following roles--"; + string send = $"--{umsg.Author.Mention} has invoked a mention on the following roles--"; foreach (var role in roles) { send += $"\n`{role.Name}`\n"; @@ -641,9 +641,9 @@ namespace NadekoBot.Modules.Administration [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Donators(IMessage imsg) + public async Task Donators(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; IEnumerable donatorsOrdered; using (var uow = DbHandler.UnitOfWork()) { @@ -657,9 +657,9 @@ namespace NadekoBot.Modules.Administration [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Donadd(IMessage imsg, IUser donator, int amount) + public async Task Donadd(IUserMessage umsg, IUser donator, int amount) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; Donator don; using (var uow = DbHandler.UnitOfWork()) diff --git a/src/NadekoBot/Modules/Administration/Commands/AutoAssignRoleCommands.cs b/src/NadekoBot/Modules/Administration/Commands/AutoAssignRoleCommands.cs index 8927720e..ff2342cd 100644 --- a/src/NadekoBot/Modules/Administration/Commands/AutoAssignRoleCommands.cs +++ b/src/NadekoBot/Modules/Administration/Commands/AutoAssignRoleCommands.cs @@ -41,9 +41,9 @@ namespace NadekoBot.Modules.Administration [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] [RequirePermission(GuildPermission.ManageRoles)] - public async Task AutoAssignRole(IMessage imsg, [Remainder] IRole role = null) + public async Task AutoAssignRole(IUserMessage umsg, [Remainder] IRole role = null) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; GuildConfig conf; using (var uow = DbHandler.UnitOfWork()) diff --git a/src/NadekoBot/Modules/Administration/Commands/CrossServerTextChannel.cs b/src/NadekoBot/Modules/Administration/Commands/CrossServerTextChannel.cs index 81343c62..5c0bd358 100644 --- a/src/NadekoBot/Modules/Administration/Commands/CrossServerTextChannel.cs +++ b/src/NadekoBot/Modules/Administration/Commands/CrossServerTextChannel.cs @@ -18,7 +18,7 @@ // { // try // { -// if (imsg.Author.Id == NadekoBot.Client.CurrentUser.Id) return; +// if (umsg.Author.Id == NadekoBot.Client.CurrentUser.Id) return; // foreach (var subscriber in Subscribers) // { // var set = subscriber.Value; @@ -26,7 +26,7 @@ // continue; // foreach (var chan in set.Except(new[] { e.Channel })) // { -// await chan.SendMessageAsync(GetText(e.Server, e.Channel, imsg.Author, e.Message)).ConfigureAwait(false); +// await chan.SendMessageAsync(GetText(e.Server, e.Channel, umsg.Author, e.Message)).ConfigureAwait(false); // } // } // } @@ -46,9 +46,9 @@ // { // var msg = chan.Messages // .FirstOrDefault(m => -// m.RawText == GetText(e.Server, e.Channel, imsg.Author, e.Before)); +// m.RawText == GetText(e.Server, e.Channel, umsg.Author, e.Before)); // if (msg != default(Message)) -// await msg.Edit(GetText(e.Server, e.Channel, imsg.Author, e.After)).ConfigureAwait(false); +// await msg.Edit(GetText(e.Server, e.Channel, umsg.Author, e.After)).ConfigureAwait(false); // } // } @@ -75,7 +75,7 @@ // if (Subscribers.TryAdd(token, set)) // { // set.Add(e.Channel); -// await imsg.Author.SendMessageAsync("This is your CSC token:" + token.ToString()).ConfigureAwait(false); +// await umsg.Author.SendMessageAsync("This is your CSC token:" + token.ToString()).ConfigureAwait(false); // } // }); diff --git a/src/NadekoBot/Modules/Administration/Commands/IncidentsCommands.cs b/src/NadekoBot/Modules/Administration/Commands/IncidentsCommands.cs deleted file mode 100644 index 5fd22dda..00000000 --- a/src/NadekoBot/Modules/Administration/Commands/IncidentsCommands.cs +++ /dev/null @@ -1,48 +0,0 @@ -//using Discord.Commands; -//using NadekoBot.Classes; -//using NadekoBot.DataModels; -//using NadekoBot.Modules.Permissions.Classes; -//using System.IO; -//using System.Linq; - -////todo DB -//namespace NadekoBot.Modules.Administration -//{ -// internal class IncidentsCommands : DiscordCommand -// { -// public IncidentsCommands(DiscordModule module) : base(module) { } -// internal override void Init(CommandGroupBuilder cgb) -// { -// cgb.CreateCommand(Module.Prefix + "listincidents") -// .Alias(Prefix + "lin") -// .Description($"List all UNREAD incidents and flags them as read. **Needs Manage Server Permissions.**| `{Prefix}lin`") -// .AddCheck(SimpleCheckers.ManageServer()) -// .Do(async e => -// { -// var sid = (long)e.Server.Id; -// var incs = DbHandler.Instance.FindAll(i => i.ServerId == sid && i.Read == false); -// DbHandler.Instance.Connection.UpdateAll(incs.Select(i => { i.Read = true; return i; })); - -// await imsg.Author.SendMessageAsync(string.Join("\n----------------------", incs.Select(i => i.Text))); -// }); - -// cgb.CreateCommand(Module.Prefix + "listallincidents") -// .Alias(Prefix + "lain") -// .Description($"Sends you a file containing all incidents and flags them as read. **Needs Manage Server Permissions.**| `{Prefix}lain`") -// .AddCheck(SimpleCheckers.ManageServer()) -// .Do(async e => -// { -// var sid = (long)e.Server.Id; -// var incs = DbHandler.Instance.FindAll(i => i.ServerId == sid); -// DbHandler.Instance.Connection.UpdateAll(incs.Select(i => { i.Read = true; return i; })); -// var data = string.Join("\n----------------------\n", incs.Select(i => i.Text)); -// MemoryStream ms = new MemoryStream(); -// var sw = new StreamWriter(ms); -// sw.WriteLine(data); -// sw.Flush(); -// sw.BaseStream.Position = 0; -// await imsg.Author.SendFile("incidents.txt", sw.BaseStream); -// }); -// } -// } -//} diff --git a/src/NadekoBot/Modules/Administration/Commands/LogCommand.cs b/src/NadekoBot/Modules/Administration/Commands/LogCommand.cs index a2ba8b43..012a580a 100644 --- a/src/NadekoBot/Modules/Administration/Commands/LogCommand.cs +++ b/src/NadekoBot/Modules/Administration/Commands/LogCommand.cs @@ -36,17 +36,17 @@ // NadekoBot.Client.MessageReceived += async (s, e) => // { -// if (e.Channel.IsPrivate || imsg.Author.Id == NadekoBot.Client.CurrentUser.Id) +// if (e.Channel.IsPrivate || umsg.Author.Id == NadekoBot.Client.CurrentUser.Id) // return; // if (!SpecificConfigurations.Default.Of(e.Server.Id).SendPrivateMessageOnMention) return; // try // { -// var usr = e.Message.MentionedUsers.FirstOrDefault(u => u != imsg.Author); +// var usr = e.Message.MentionedUsers.FirstOrDefault(u => u != umsg.Author); // if (usr?.Status != UserStatus.Offline) // return; // await channel.SendMessageAsync($"User `{usr.Name}` is offline. PM sent.").ConfigureAwait(false); // await usr.SendMessageAsync( -// $"User `{imsg.Author.Username}` mentioned you on " + +// $"User `{umsg.Author.Username}` mentioned you on " + // $"`{e.Server.Name}` server while you were offline.\n" + // $"`Message:` {e.Message.Text}").ConfigureAwait(false); // } @@ -148,7 +148,7 @@ // Channel ch; // if ((ch = e.Server.TextChannels.Where(tc => tc.Id == chId).FirstOrDefault()) == null) // return; -// await ch.SendMessageAsync($"`{prettyCurrentTime}`♻`User was unbanned:` **{imsg.Author.Username}** ({imsg.Author.Id})").ConfigureAwait(false); +// await ch.SendMessageAsync($"`{prettyCurrentTime}`♻`User was unbanned:` **{umsg.Author.Username}** ({umsg.Author.Id})").ConfigureAwait(false); // } // catch { } // } @@ -163,7 +163,7 @@ // Channel ch; // if ((ch = e.Server.TextChannels.Where(tc => tc.Id == chId).FirstOrDefault()) == null) // return; -// await ch.SendMessageAsync($"`{prettyCurrentTime}`✅`User joined:` **{imsg.Author.Username}** ({imsg.Author.Id})").ConfigureAwait(false); +// await ch.SendMessageAsync($"`{prettyCurrentTime}`✅`User joined:` **{umsg.Author.Username}** ({umsg.Author.Id})").ConfigureAwait(false); // } // catch { } // } @@ -178,7 +178,7 @@ // Channel ch; // if ((ch = e.Server.TextChannels.Where(tc => tc.Id == chId).FirstOrDefault()) == null) // return; -// await ch.SendMessageAsync($"`{prettyCurrentTime}`❗`User left:` **{imsg.Author.Username}** ({imsg.Author.Id})").ConfigureAwait(false); +// await ch.SendMessageAsync($"`{prettyCurrentTime}`❗`User left:` **{umsg.Author.Username}** ({umsg.Author.Id})").ConfigureAwait(false); // } // catch { } // } @@ -193,7 +193,7 @@ // Channel ch; // if ((ch = e.Server.TextChannels.Where(tc => tc.Id == chId).FirstOrDefault()) == null) // return; -// await ch.SendMessageAsync($"❗`{prettyCurrentTime}`❌`User banned:` **{imsg.Author.Username}** ({imsg.Author.Id})").ConfigureAwait(false); +// await ch.SendMessageAsync($"❗`{prettyCurrentTime}`❌`User banned:` **{umsg.Author.Username}** ({umsg.Author.Id})").ConfigureAwait(false); // } // catch { } // } @@ -202,7 +202,7 @@ // { // try // { -// if (e.Server == null || e.Channel.IsPrivate || imsg.Author.Id == NadekoBot.Client.CurrentUser.Id) +// if (e.Server == null || e.Channel.IsPrivate || umsg.Author.Id == NadekoBot.Client.CurrentUser.Id) // return; // var config = SpecificConfigurations.Default.Of(e.Server.Id); // var chId = config.LogServerChannel; @@ -215,13 +215,13 @@ // { // await ch.SendMessageAsync( // $@"🕔`{prettyCurrentTime}` **New Message** `#{e.Channel.Name}` -//👤`{imsg.Author?.ToString() ?? ("NULL")}` {e.Message.Text.Unmention()}").ConfigureAwait(false); +//👤`{umsg.Author?.ToString() ?? ("NULL")}` {e.Message.Text.Unmention()}").ConfigureAwait(false); // } // else // { // await ch.SendMessageAsync( // $@"🕔`{prettyCurrentTime}` **File Uploaded** `#{e.Channel.Name}` -//👤`{imsg.Author?.ToString() ?? ("NULL")}` {e.Message.Attachments.FirstOrDefault()?.ProxyUrl}").ConfigureAwait(false); +//👤`{umsg.Author?.ToString() ?? ("NULL")}` {e.Message.Attachments.FirstOrDefault()?.ProxyUrl}").ConfigureAwait(false); // } // } @@ -231,7 +231,7 @@ // { // try // { -// if (e.Server == null || e.Channel.IsPrivate || imsg.Author?.Id == NadekoBot.Client.CurrentUser.Id) +// if (e.Server == null || e.Channel.IsPrivate || umsg.Author?.Id == NadekoBot.Client.CurrentUser.Id) // return; // var config = SpecificConfigurations.Default.Of(e.Server.Id); // var chId = config.LogServerChannel; @@ -244,13 +244,13 @@ // { // await ch.SendMessageAsync( // $@"🕔`{prettyCurrentTime}` **Message** 🚮 `#{e.Channel.Name}` -//👤`{imsg.Author?.ToString() ?? ("NULL")}` {e.Message.Text.Unmention()}").ConfigureAwait(false); +//👤`{umsg.Author?.ToString() ?? ("NULL")}` {e.Message.Text.Unmention()}").ConfigureAwait(false); // } // else // { // await ch.SendMessageAsync( // $@"🕔`{prettyCurrentTime}` **File Deleted** `#{e.Channel.Name}` -//👤`{imsg.Author?.ToString() ?? ("NULL")}` {e.Message.Attachments.FirstOrDefault()?.ProxyUrl}").ConfigureAwait(false); +//👤`{umsg.Author?.ToString() ?? ("NULL")}` {e.Message.Attachments.FirstOrDefault()?.ProxyUrl}").ConfigureAwait(false); // } // } // catch { } @@ -259,7 +259,7 @@ // { // try // { -// if (e.Server == null || e.Channel.IsPrivate || imsg.Author?.Id == NadekoBot.Client.CurrentUser.Id) +// if (e.Server == null || e.Channel.IsPrivate || umsg.Author?.Id == NadekoBot.Client.CurrentUser.Id) // return; // var config = SpecificConfigurations.Default.Of(e.Server.Id); // var chId = config.LogServerChannel; @@ -270,7 +270,7 @@ // return; // await ch.SendMessageAsync( // $@"🕔`{prettyCurrentTime}` **Message** 📝 `#{e.Channel.Name}` -//👤`{imsg.Author?.ToString() ?? ("NULL")}` +//👤`{umsg.Author?.ToString() ?? ("NULL")}` // `Old:` {e.Before.Text.Unmention()} // `New:` {e.After.Text.Unmention()}").ConfigureAwait(false); // } @@ -466,19 +466,19 @@ // return; // } -// if (imsg.Author.VoiceChannel == null) +// if (umsg.Author.VoiceChannel == null) // { // await channel.SendMessageAsync("💢 You are not in a voice channel right now. If you are, please rejoin it.").ConfigureAwait(false); // return; // } // ulong throwaway; -// if (!config.VoiceChannelLog.TryRemove(imsg.Author.VoiceChannel.Id, out throwaway)) +// if (!config.VoiceChannelLog.TryRemove(umsg.Author.VoiceChannel.Id, out throwaway)) // { -// config.VoiceChannelLog.TryAdd(imsg.Author.VoiceChannel.Id, e.Channel.Id); -// await channel.SendMessageAsync($"`Logging user updates for` {imsg.Author.VoiceChannel.Mention} `voice channel.`").ConfigureAwait(false); +// config.VoiceChannelLog.TryAdd(umsg.Author.VoiceChannel.Id, e.Channel.Id); +// await channel.SendMessageAsync($"`Logging user updates for` {umsg.Author.VoiceChannel.Mention} `voice channel.`").ConfigureAwait(false); // } // else -// await channel.SendMessageAsync($"`Stopped logging user updates for` {imsg.Author.VoiceChannel.Mention} `voice channel.`").ConfigureAwait(false); +// await channel.SendMessageAsync($"`Stopped logging user updates for` {umsg.Author.VoiceChannel.Mention} `voice channel.`").ConfigureAwait(false); // }); // } // } diff --git a/src/NadekoBot/Modules/Administration/Commands/MessageRepeater.cs b/src/NadekoBot/Modules/Administration/Commands/MessageRepeater.cs index 0be2230e..520372db 100644 --- a/src/NadekoBot/Modules/Administration/Commands/MessageRepeater.cs +++ b/src/NadekoBot/Modules/Administration/Commands/MessageRepeater.cs @@ -1,130 +1,130 @@ -//using Discord; -//using Discord.Commands; -//using NadekoBot.Classes; -//using NadekoBot.Modules.Permissions.Classes; -//using System; -//using System.Collections.Concurrent; -//using System.Threading.Tasks; -//using System.Timers; -////todo DB -////todo persist restarts -//namespace NadekoBot.Modules.Administration -//{ -// class MessageRepeater : DiscordCommand -// { -// private readonly ConcurrentDictionary repeaters = new ConcurrentDictionary(); -// private class Repeater -// { -// [Newtonsoft.Json.JsonIgnore] -// public Timer MessageTimer { get; set; } -// [Newtonsoft.Json.JsonIgnore] -// public Channel RepeatingChannel { get; set; } +using Discord; +using Discord.Commands; +using NadekoBot.Classes; +using NadekoBot.Modules.Permissions.Classes; +using System; +using System.Collections.Concurrent; +using System.Threading.Tasks; +using System.Timers; -// public ulong RepeatingServerId { get; set; } -// public ulong RepeatingChannelId { get; set; } -// public Message lastMessage { get; set; } = null; -// public string RepeatingMessage { get; set; } -// public int Interval { get; set; } +//todo DB +namespace NadekoBot.Modules.Administration +{ + class MessageRepeater : DiscordCommand + { + private readonly ConcurrentDictionary repeaters = new ConcurrentDictionary(); + private class Repeater + { + [Newtonsoft.Json.JsonIgnore] + public Timer MessageTimer { get; set; } + [Newtonsoft.Json.JsonIgnore] + public Channel RepeatingChannel { get; set; } -// public Repeater Start() -// { -// MessageTimer = new Timer { Interval = Interval }; -// MessageTimer.Elapsed += async (s, e) => await Invoke(); -// return this; -// } + public ulong RepeatingServerId { get; set; } + public ulong RepeatingChannelId { get; set; } + public Message lastMessage { get; set; } = null; + public string RepeatingMessage { get; set; } + public int Interval { get; set; } -// public async Task Invoke() -// { -// var ch = RepeatingChannel; -// var msg = RepeatingMessage; -// if (ch != null && !string.IsNullOrWhiteSpace(msg)) -// { -// try -// { -// if (lastMessage != null) -// await lastMessage.Delete().ConfigureAwait(false); -// } -// catch { } -// try -// { -// lastMessage = await ch.SendMessageAsync(msg).ConfigureAwait(false); -// } -// catch { } -// } -// } -// } -// internal override void Init(CommandGroupBuilder cgb) -// { + public Repeater Start() + { + MessageTimer = new Timer { Interval = Interval }; + MessageTimer.Elapsed += async (s, e) => await Invoke(); + return this; + } -// cgb.CreateCommand(Module.Prefix + "repeatinvoke") -// .Alias(Module.Prefix + "repinv") -// .Description($"Immediately shows the repeat message and restarts the timer. **Needs Manage Messages Permissions.**| `{Prefix}repinv`") -// .AddCheck(SimpleCheckers.ManageMessages()) -// .Do(async e => -// { -// Repeater rep; -// if (!repeaters.TryGetValue(e.Server, out rep)) -// { -// await channel.SendMessageAsync("`No repeating message found on this server.`"); -// return; -// } + public async Task Invoke() + { + var ch = RepeatingChannel; + var msg = RepeatingMessage; + if (ch != null && !string.IsNullOrWhiteSpace(msg)) + { + try + { + if (lastMessage != null) + await lastMessage.Delete().ConfigureAwait(false); + } + catch { } + try + { + lastMessage = await ch.SendMessageAsync(msg).ConfigureAwait(false); + } + catch { } + } + } + } + internal override void Init(CommandGroupBuilder cgb) + { -// await rep.Invoke(); -// }); + cgb.CreateCommand(Module.Prefix + "repeatinvoke") + .Alias(Module.Prefix + "repinv") + .Description($"Immediately shows the repeat message and restarts the timer. **Needs Manage Messages Permissions.**| `{Prefix}repinv`") + .AddCheck(SimpleCheckers.ManageMessages()) + .Do(async e => + { + Repeater rep; + if (!repeaters.TryGetValue(e.Server, out rep)) + { + await channel.SendMessageAsync("`No repeating message found on this server.`"); + return; + } -// cgb.CreateCommand(Module.Prefix + "repeat") -// .Description("Repeat a message every X minutes. If no parameters are specified, " + -// $"repeat is disabled. **Needs Manage Messages Permissions.** |`{Prefix}repeat 5 Hello there`") -// .Parameter("minutes", ParameterType.Optional) -// .Parameter("msg", ParameterType.Unparsed) -// .AddCheck(SimpleCheckers.ManageMessages()) -// .Do(async e => -// { -// var minutesStr = minutes; -// var msg = msg; + await rep.Invoke(); + }); -// // if both null, disable -// if (string.IsNullOrWhiteSpace(msg) && string.IsNullOrWhiteSpace(minutesStr)) -// { + cgb.CreateCommand(Module.Prefix + "repeat") + .Description("Repeat a message every X minutes. If no parameters are specified, " + + $"repeat is disabled. **Needs Manage Messages Permissions.** |`{Prefix}repeat 5 Hello there`") + .Parameter("minutes", ParameterType.Optional) + .Parameter("msg", ParameterType.Unparsed) + .AddCheck(SimpleCheckers.ManageMessages()) + .Do(async e => + { + var minutesStr = minutes; + var msg = msg; -// Repeater rep; -// if (!repeaters.TryRemove(e.Server, out rep)) -// return; -// rep.MessageTimer.Stop(); -// await channel.SendMessageAsync("Repeating disabled").ConfigureAwait(false); -// return; -// } -// int minutes; -// if (!int.TryParse(minutesStr, out minutes) || minutes < 1 || minutes > 1440) -// { -// await channel.SendMessageAsync("Invalid value").ConfigureAwait(false); -// return; -// } + // if both null, disable + if (string.IsNullOrWhiteSpace(msg) && string.IsNullOrWhiteSpace(minutesStr)) + { -// var repeater = repeaters.GetOrAdd( -// e.Server, -// s => new Repeater -// { -// Interval = minutes * 60 * 1000, -// RepeatingChannel = e.Channel, -// RepeatingChannelId = e.Channel.Id, -// RepeatingServerId = e.Server.Id, -// }.Start() -// ); + Repeater rep; + if (!repeaters.TryRemove(e.Server, out rep)) + return; + rep.MessageTimer.Stop(); + await channel.SendMessageAsync("Repeating disabled").ConfigureAwait(false); + return; + } + int minutes; + if (!int.TryParse(minutesStr, out minutes) || minutes < 1 || minutes > 1440) + { + await channel.SendMessageAsync("Invalid value").ConfigureAwait(false); + return; + } -// if (!string.IsNullOrWhiteSpace(msg)) -// repeater.RepeatingMessage = msg; + var repeater = repeaters.GetOrAdd( + e.Server, + s => new Repeater + { + Interval = minutes * 60 * 1000, + RepeatingChannel = e.Channel, + RepeatingChannelId = e.Channel.Id, + RepeatingServerId = e.Server.Id, + }.Start() + ); -// repeater.MessageTimer.Stop(); -// repeater.MessageTimer.Start(); + if (!string.IsNullOrWhiteSpace(msg)) + repeater.RepeatingMessage = msg; -// await channel.SendMessageAsync(String.Format("👌 Repeating `{0}` every " + -// "**{1}** minutes on {2} channel.", -// repeater.RepeatingMessage, minutes, repeater.RepeatingChannel)) -// .ConfigureAwait(false); -// }); -// } + repeater.MessageTimer.Stop(); + repeater.MessageTimer.Start(); -// public MessageRepeater(DiscordModule module) : base(module) { } -// } -//} + await channel.SendMessageAsync(String.Format("👌 Repeating `{0}` every " + + "**{1}** minutes on {2} channel.", + repeater.RepeatingMessage, minutes, repeater.RepeatingChannel)) + .ConfigureAwait(false); + }); + } + + public MessageRepeater(DiscordModule module) : base(module) { } + } +} diff --git a/src/NadekoBot/Modules/Administration/Commands/PlayingRotate.cs b/src/NadekoBot/Modules/Administration/Commands/PlayingRotate.cs deleted file mode 100644 index d1537e50..00000000 --- a/src/NadekoBot/Modules/Administration/Commands/PlayingRotate.cs +++ /dev/null @@ -1,168 +0,0 @@ -//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; - -////todo DB -//namespace NadekoBot.Modules.Administration -//{ -// internal class PlayingRotate : DiscordCommand -// { -// private static readonly Timer timer = new Timer(20000); - -// 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()} -// }; - -// private readonly SemaphoreSlim playingPlaceholderLock = new SemaphoreSlim(1,1); - -// 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 { } -// }; - -// timer.Enabled = NadekoBot.Config.IsRotatingStatus; -// } - -// 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); -// }; - -// 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); -// }); - -// 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); -// }); - -// 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); -// }); -// } -// } -//} diff --git a/src/NadekoBot/Modules/Administration/Commands/PlayingRotateCommands.cs b/src/NadekoBot/Modules/Administration/Commands/PlayingRotateCommands.cs new file mode 100644 index 00000000..34e36096 --- /dev/null +++ b/src/NadekoBot/Modules/Administration/Commands/PlayingRotateCommands.cs @@ -0,0 +1,169 @@ +using Discord; +using Discord.Commands; +using Discord.WebSocket; +using NadekoBot.Attributes; +using NadekoBot.Services; +using NadekoBot.Services.Database; +using NadekoBot.Services.Database.Models; +using NLog; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +//todo owner only +namespace NadekoBot.Modules.Administration +{ + public partial class Administration + { + [Group] + public class PlayingRotateCommands + { + private Logger _log { get; } + + public PlayingRotateCommands() + { + _log = LogManager.GetCurrentClassLogger(); + Task.Run(async () => + { + var index = 0; + do + { + try + { + BotConfig conf; + using (var uow = DbHandler.UnitOfWork()) + { + conf = uow.BotConfig.GetOrCreate(); + } + + if (!conf.RotatingStatuses) + continue; + else + { + if (index >= conf.RotatingStatusMessages.Count) + index = 0; + + if (!conf.RotatingStatusMessages.Any()) + continue; + + await NadekoBot.Client + .GetCurrentUser() + .ModifyStatusAsync(mpp => mpp.Game = new Game(conf.RotatingStatusMessages[index++].Status)) + .ConfigureAwait(false); + } + } + catch (Exception ex) + { + _log.Warn("Rotating playing status errored.\n" + ex); + } + finally + { + await Task.Delay(15000); + } + } while (true); + }); + } + + 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()} + }; + + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + public async Task RotatePlaying(IUserMessage umsg) + { + var channel = (ITextChannel)umsg.Channel; + + bool status; + using (var uow = DbHandler.UnitOfWork()) + { + var config = uow.BotConfig.GetOrCreate(); + + status = config.RotatingStatuses = !config.RotatingStatuses; + await uow.CompleteAsync(); + } + if (status) + await channel.SendMessageAsync("`Rotating playing status enabled.`"); + else + await channel.SendMessageAsync("`Rotating playing status disabled.`"); + } + + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + public async Task AddPlaying(IUserMessage umsg, [Remainder] string status) + { + var channel = (ITextChannel)umsg.Channel; + + using (var uow = DbHandler.UnitOfWork()) + { + var config = uow.BotConfig.GetOrCreate(); + config.RotatingStatusMessages.Add(new PlayingStatus { Status = status }); + await uow.CompleteAsync(); + } + + await channel.SendMessageAsync("`Added.`").ConfigureAwait(false); + } + + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + public async Task ListPlaying(IUserMessage umsg) + { + var channel = (ITextChannel)umsg.Channel; + + List statuses; + using (var uow = DbHandler.UnitOfWork()) + { + statuses = uow.BotConfig.GetOrCreate().RotatingStatusMessages; + } + + if (!statuses.Any()) + await channel.SendMessageAsync("`No rotating playing statuses set.`"); + else + { + var i = 1; + await channel.SendMessageAsync($"{umsg.Author.Mention} `Here is a list of rotating statuses:`\n\n\t" + string.Join("\n\t", statuses.Select(rs => $"`{i++}.` {rs.Status}"))); + } + + } + + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + public async Task RemovePlaying(IUserMessage umsg, int index) + { + var channel = (ITextChannel)umsg.Channel; + index -= 1; + + string msg = ""; + using (var uow = DbHandler.UnitOfWork()) + { + var config = uow.BotConfig.GetOrCreate(); + + if (index >= config.RotatingStatusMessages.Count) + return; + msg = config.RotatingStatusMessages[index].Status; + config.RotatingStatusMessages.RemoveAt(index); + await uow.CompleteAsync(); + } + await channel.SendMessageAsync($"`Removed the the playing message:` {msg}").ConfigureAwait(false); + } + } + } +} \ No newline at end of file diff --git a/src/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs b/src/NadekoBot/Modules/Administration/Commands/RatelimitCommand.cs index 5e3a55ed..16ae221e 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; @@ -26,36 +25,37 @@ namespace NadekoBot.Modules.Administration this._client = NadekoBot.Client; - _client.MessageReceived += async (imsg) => + _client.MessageReceived += async (umsg) => { - var channel = (ITextChannel)imsg.Channel; + var usrMsg = umsg as IUserMessage; + var channel = usrMsg.Channel as ITextChannel; - if (channel == null || await imsg.IsAuthor()) + if (channel == null || await usrMsg.IsAuthor()) return; ConcurrentDictionary userTimePair; if (!RatelimitingChannels.TryGetValue(channel.Id, out userTimePair)) return; DateTime lastMessageTime; - if (userTimePair.TryGetValue(imsg.Author.Id, out lastMessageTime)) + if (userTimePair.TryGetValue(usrMsg.Author.Id, out lastMessageTime)) { if (DateTime.Now - lastMessageTime < ratelimitTime) { try { - await imsg.DeleteAsync().ConfigureAwait(false); + await usrMsg.DeleteAsync().ConfigureAwait(false); } catch { } return; } } - userTimePair.AddOrUpdate(imsg.Author.Id, id => DateTime.Now, (id, dt) => DateTime.Now); + userTimePair.AddOrUpdate(usrMsg.Author.Id, id => DateTime.Now, (id, dt) => DateTime.Now); }; } [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Slowmode(IMessage imsg) + public async Task Slowmode(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; ConcurrentDictionary throwaway; if (RatelimitingChannels.TryRemove(channel.Id, out throwaway)) diff --git a/src/NadekoBot/Modules/Administration/Commands/SelfAssignedRolesCommand.cs b/src/NadekoBot/Modules/Administration/Commands/SelfAssignedRolesCommand.cs index 7171a63d..ccb62d6e 100644 --- a/src/NadekoBot/Modules/Administration/Commands/SelfAssignedRolesCommand.cs +++ b/src/NadekoBot/Modules/Administration/Commands/SelfAssignedRolesCommand.cs @@ -1,207 +1,233 @@ -//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(IUserMessage umsg, [Remainder] IRole role) + { + var channel = (ITextChannel)umsg.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(IUserMessage umsg, [Remainder] IRole role) + { + var channel = (ITextChannel)umsg.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(IUserMessage umsg) + { + var channel = (ITextChannel)umsg.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(IUserMessage umsg) + { + var channel = (ITextChannel)umsg.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(IUserMessage umsg, [Remainder] IRole role) + { + var channel = (ITextChannel)umsg.Channel; + var guildUser = (IGuildUser)umsg.Author; + var usrMsg = (IUserMessage)umsg; + + 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 usrMsg.DeleteAsync().ConfigureAwait(false); } catch { } + }); + } + } + + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + public async Task Iamnot(IUserMessage umsg, [Remainder] IRole role) + { + var channel = (ITextChannel)umsg.Channel; + var guildUser = (IGuildUser)umsg.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 umsg.DeleteAsync().ConfigureAwait(false); } catch { } + }); + } + } + } + } +} \ No newline at end of file diff --git a/src/NadekoBot/Modules/Administration/Commands/SelfCommands.cs b/src/NadekoBot/Modules/Administration/Commands/SelfCommands.cs index e7cb5744..fc6052cf 100644 --- a/src/NadekoBot/Modules/Administration/Commands/SelfCommands.cs +++ b/src/NadekoBot/Modules/Administration/Commands/SelfCommands.cs @@ -22,9 +22,9 @@ // [LocalizedCommand, LocalizedDescription, LocalizedSummary] // [RequireContext(ContextType.Guild)] -// public async Task Leave(IMessage imsg, [Remainder] string guildStr) +// public async Task Leave(IUserMessage umsg, [Remainder] string guildStr) // { -// var channel = (ITextChannel)imsg.Channel; +// var channel = (ITextChannel)umsg.Channel; // guildStr = guildStr.ToUpperInvariant(); // var server = _client.GetGuilds().FirstOrDefault(g => g.Id.ToString() == guildStr) ?? _client.GetGuilds().FirstOrDefault(g => g.Name.ToUpperInvariant() == guildStr); diff --git a/src/NadekoBot/Modules/Administration/Commands/ServerGreetCommands.cs b/src/NadekoBot/Modules/Administration/Commands/ServerGreetCommands.cs index d06ad852..98867f8e 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; @@ -110,9 +109,9 @@ namespace NadekoBot.Modules.Administration [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] [RequirePermission(GuildPermission.ManageGuild)] - public async Task GreetDel(IMessage imsg) + public async Task GreetDel(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; GuildConfig conf; using (var uow = DbHandler.UnitOfWork()) @@ -132,9 +131,9 @@ namespace NadekoBot.Modules.Administration [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] [RequirePermission(GuildPermission.ManageGuild)] - public async Task Greet(IMessage imsg) + public async Task Greet(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; GuildConfig conf; using (var uow = DbHandler.UnitOfWork()) @@ -155,9 +154,9 @@ namespace NadekoBot.Modules.Administration [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] [RequirePermission(GuildPermission.ManageGuild)] - public async Task GreetMsg(IMessage imsg, [Remainder] string text) + public async Task GreetMsg(IUserMessage umsg, [Remainder] string text) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; GuildConfig conf; using (var uow = DbHandler.UnitOfWork()) @@ -184,9 +183,9 @@ namespace NadekoBot.Modules.Administration [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] [RequirePermission(GuildPermission.ManageGuild)] - public async Task GreetDm(IMessage imsg) + public async Task GreetDm(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; GuildConfig conf; using (var uow = DbHandler.UnitOfWork()) @@ -206,9 +205,9 @@ namespace NadekoBot.Modules.Administration [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] [RequirePermission(GuildPermission.ManageGuild)] - public async Task GreetDmMsg(IMessage imsg, [Remainder] string text) + public async Task GreetDmMsg(IUserMessage umsg, [Remainder] string text) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; GuildConfig conf; using (var uow = DbHandler.UnitOfWork()) @@ -235,9 +234,9 @@ namespace NadekoBot.Modules.Administration [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] [RequirePermission(GuildPermission.ManageGuild)] - public async Task Bye(IMessage imsg) + public async Task Bye(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; GuildConfig conf; using (var uow = DbHandler.UnitOfWork()) @@ -258,9 +257,9 @@ namespace NadekoBot.Modules.Administration [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] [RequirePermission(GuildPermission.ManageGuild)] - public async Task ByeMsg(IMessage imsg, [Remainder] string text) + public async Task ByeMsg(IUserMessage umsg, [Remainder] string text) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; GuildConfig conf; using (var uow = DbHandler.UnitOfWork()) @@ -287,9 +286,9 @@ namespace NadekoBot.Modules.Administration [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] [RequirePermission(GuildPermission.ManageGuild)] - public async Task ByeDel(IMessage imsg) + public async Task ByeDel(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; GuildConfig conf; using (var uow = DbHandler.UnitOfWork()) diff --git a/src/NadekoBot/Modules/ClashOfClans/ClashOfClans.cs b/src/NadekoBot/Modules/ClashOfClans/ClashOfClans.cs index 072d89a1..0cbc22b8 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) + public ClashOfClans(ILocalization loc, CommandService cmds, DiscordSocketClient client) : base(loc, cmds, 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) @@ -38,11 +57,11 @@ namespace NadekoBot.Modules.ClashOfClans [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task CreateWar(IMessage imsg, int size, [Remainder] string enemyClan = null) + public async Task CreateWar(IUserMessage umsg, int size, [Remainder] string enemyClan = null) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; - if (!(imsg.Author as IGuildUser).GuildPermissions.ManageChannels) + if (!(umsg.Author as IGuildUser).GuildPermissions.ManageChannels) return; if (string.IsNullOrWhiteSpace(enemyClan)) @@ -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, umsg.Channel.Id); //cw.Start(); wars.Add(cw); @@ -71,14 +90,14 @@ namespace NadekoBot.Modules.ClashOfClans [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task StartWar(IMessage imsg, [Remainder] string number = null) + public async Task StartWar(IUserMessage umsg, [Remainder] string number = null) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; int num = 0; int.TryParse(number, out num); - var warsInfo = GetWarInfo(imsg, num); + var warsInfo = GetWarInfo(umsg, num); if (warsInfo == null) { await channel.SendMessageAsync("💢🔰 **That war does not exist.**").ConfigureAwait(false); @@ -94,13 +113,14 @@ namespace NadekoBot.Modules.ClashOfClans { await channel.SendMessageAsync($"🔰**WAR AGAINST {war.ShortPrint()} HAS ALREADY STARTED**").ConfigureAwait(false); } + SaveWar(war); } [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task ListWar(IMessage imsg, [Remainder] string number = null) + public async Task ListWar(IUserMessage umsg, [Remainder] string number = null) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; // if number is null, print all wars in a short way if (string.IsNullOrWhiteSpace(number)) @@ -130,21 +150,21 @@ namespace NadekoBot.Modules.ClashOfClans var num = 0; int.TryParse(number, out num); //if number is not null, print the war needed - var warsInfo = GetWarInfo(imsg, num); + var warsInfo = GetWarInfo(umsg, num); if (warsInfo == null) { 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] [RequireContext(ContextType.Guild)] - public async Task Claim(IMessage imsg, int number, int baseNumber, [Remainder] string other_name = null) + public async Task Claim(IUserMessage umsg, int number, int baseNumber, [Remainder] string other_name = null) { - var channel = (ITextChannel)imsg.Channel; - var warsInfo = GetWarInfo(imsg, number); + var channel = (ITextChannel)umsg.Channel; + var warsInfo = GetWarInfo(umsg, number); if (warsInfo == null || warsInfo.Item1.Count == 0) { await channel.SendMessageAsync("💢🔰 **That war does not exist.**").ConfigureAwait(false); @@ -152,12 +172,13 @@ namespace NadekoBot.Modules.ClashOfClans } var usr = string.IsNullOrWhiteSpace(other_name) ? - imsg.Author.Username : + umsg.Author.Username : other_name; try { 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) @@ -168,41 +189,43 @@ namespace NadekoBot.Modules.ClashOfClans [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task ClaimFinish1(IMessage imsg, int number, int baseNumber, [Remainder] string other_name = null) + public async Task ClaimFinish1(IUserMessage umsg, int number, int baseNumber, [Remainder] string other_name = null) { - var channel = (ITextChannel)imsg.Channel; - await FinishClaim(imsg, number, baseNumber, other_name, 1); + var channel = (ITextChannel)umsg.Channel; + await FinishClaim(umsg, number, baseNumber, other_name, 1); } [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task ClaimFinish2(IMessage imsg, int number, int baseNumber, [Remainder] string other_name = null) + public async Task ClaimFinish2(IUserMessage umsg, int number, int baseNumber, [Remainder] string other_name = null) { - var channel = (ITextChannel)imsg.Channel; - await FinishClaim(imsg, number, baseNumber, other_name, 2); + var channel = (ITextChannel)umsg.Channel; + await FinishClaim(umsg, number, baseNumber, other_name, 2); } [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task ClaimFinish(IMessage imsg, int number, int baseNumber, [Remainder] string other_name = null) + public async Task ClaimFinish(IUserMessage umsg, int number, int baseNumber, [Remainder] string other_name = null) { - var channel = (ITextChannel)imsg.Channel; - await FinishClaim(imsg, number, baseNumber, other_name); + var channel = (ITextChannel)umsg.Channel; + await FinishClaim(umsg, number, baseNumber, other_name); } [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task EndWar(IMessage imsg, int number) + public async Task EndWar(IUserMessage umsg, int number) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; - var warsInfo = GetWarInfo(imsg,number); + var warsInfo = GetWarInfo(umsg,number); if (warsInfo == null) { 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; @@ -211,11 +234,11 @@ namespace NadekoBot.Modules.ClashOfClans [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Unclaim(IMessage imsg, int number, [Remainder] string otherName = null) + public async Task Unclaim(IUserMessage umsg, int number, [Remainder] string otherName = null) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; - var warsInfo = GetWarInfo(imsg, number); + var warsInfo = GetWarInfo(umsg, number); if (warsInfo == null || warsInfo.Item1.Count == 0) { await channel.SendMessageAsync("💢🔰 **That war does not exist.**").ConfigureAwait(false); @@ -223,12 +246,13 @@ namespace NadekoBot.Modules.ClashOfClans } var usr = string.IsNullOrWhiteSpace(otherName) ? - imsg.Author.Username : + umsg.Author.Username : otherName; try { 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) @@ -237,10 +261,10 @@ namespace NadekoBot.Modules.ClashOfClans } } - private async Task FinishClaim(IMessage imsg, int number, int baseNumber, [Remainder] string other_name, int stars = 3) + private async Task FinishClaim(IUserMessage umsg, int number, int baseNumber, [Remainder] string other_name, int stars = 3) { - var channel = (ITextChannel)imsg.Channel; - var warInfo = GetWarInfo(imsg, number); + var channel = (ITextChannel)umsg.Channel; + var warInfo = GetWarInfo(umsg, number); if (warInfo == null || warInfo.Item1.Count == 0) { await channel.SendMessageAsync("💢🔰 **That war does not exist.**").ConfigureAwait(false); @@ -248,14 +272,15 @@ namespace NadekoBot.Modules.ClashOfClans } var usr = string.IsNullOrWhiteSpace(other_name) ? - imsg.Author.Username : + umsg.Author.Username : other_name; var war = warInfo.Item1[warInfo.Item2]; try { var baseNum = war.FinishClaim(usr, stars); - await channel.SendMessageAsync($"❗🔰{imsg.Author.Mention} **DESTROYED** a base #{baseNum + 1} in a war against {war.ShortPrint()}").ConfigureAwait(false); + SaveWar(war); + await channel.SendMessageAsync($"❗🔰{umsg.Author.Mention} **DESTROYED** a base #{baseNum + 1} in a war against {war.ShortPrint()}").ConfigureAwait(false); } catch (Exception ex) { @@ -263,9 +288,9 @@ namespace NadekoBot.Modules.ClashOfClans } } - private static Tuple, int> GetWarInfo(IMessage imsg, int num) + private static Tuple, int> GetWarInfo(IUserMessage umsg, int num) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; //check if there are any wars List wars = null; ClashWars.TryGetValue(channel.Guild.Id, out wars); @@ -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/DiscordModule.cs b/src/NadekoBot/Modules/DiscordModule.cs index bf8719f1..47fdfdf9 100644 --- a/src/NadekoBot/Modules/DiscordModule.cs +++ b/src/NadekoBot/Modules/DiscordModule.cs @@ -10,15 +10,13 @@ namespace NadekoBot.Modules { protected ILocalization _l; protected CommandService _commands; - protected IBotConfiguration _config; protected DiscordSocketClient _client; protected Logger _log; - public DiscordModule(ILocalization loc, CommandService cmds, IBotConfiguration config, DiscordSocketClient client) + public DiscordModule(ILocalization loc, CommandService cmds, DiscordSocketClient client) { _l = loc; _commands = cmds; - _config = config; _client = client; _log = LogManager.GetCurrentClassLogger(); } diff --git a/src/NadekoBot/Modules/Gambling/Commands/AnimalRacing.cs b/src/NadekoBot/Modules/Gambling/Commands/AnimalRacing.cs index 380b11c2..79f496ec 100644 --- a/src/NadekoBot/Modules/Gambling/Commands/AnimalRacing.cs +++ b/src/NadekoBot/Modules/Gambling/Commands/AnimalRacing.cs @@ -1,8 +1,9 @@ using Discord; using Discord.Commands; using NadekoBot.Attributes; -using NadekoBot.Classes; using NadekoBot.Extensions; +using NadekoBot.Services; +using NadekoBot.Services.Database; using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -21,9 +22,9 @@ namespace NadekoBot.Modules.Gambling [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Race(IMessage imsg) + public async Task Race(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; var ar = new AnimalRace(channel.Guild.Id, channel); @@ -33,24 +34,24 @@ namespace NadekoBot.Modules.Gambling [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task JoinRace(IMessage imsg, int amount = 0) + public async Task JoinRace(IUserMessage umsg, int amount = 0) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; if (amount < 0) amount = 0; //todo DB - //var userFlowers = Gambling.GetUserFlowers(imsg.Author.Id); + //var userFlowers = Gambling.GetUserFlowers(umsg.Author.Id); //if (userFlowers < amount) //{ - // await channel.SendMessageAsync($"{imsg.Author.Mention} You don't have enough {NadekoBot.Config.CurrencyName}s. You only have {userFlowers}{NadekoBot.Config.CurrencySign}.").ConfigureAwait(false); + // await channel.SendMessageAsync($"{umsg.Author.Mention} You don't have enough {NadekoBot.Config.CurrencyName}s. You only have {userFlowers}{NadekoBot.Config.CurrencySign}.").ConfigureAwait(false); // return; //} //if (amount > 0) - // await FlowersHandler.RemoveFlowers(imsg.Author, "BetRace", (int)amount, true).ConfigureAwait(false); + // await FlowersHandler.RemoveFlowers(umsg.Author, "BetRace", (int)amount, true).ConfigureAwait(false); AnimalRace ar; if (!AnimalRaces.TryGetValue(channel.Guild.Id, out ar)) @@ -58,13 +59,13 @@ namespace NadekoBot.Modules.Gambling await channel.SendMessageAsync("No race exists on this server"); return; } - await ar.JoinRace(imsg.Author as IGuildUser, amount); + await ar.JoinRace(umsg.Author as IGuildUser, amount); } public class AnimalRace { - private ConcurrentQueue animals = new ConcurrentQueue(NadekoBot.Config.RaceAnimals.Shuffle()); + private ConcurrentQueue animals { get; } public bool Fail { get; internal set; } @@ -84,6 +85,13 @@ namespace NadekoBot.Modules.Gambling Fail = true; return; } + + using (var uow = DbHandler.UnitOfWork()) + { + animals = new ConcurrentQueue(uow.BotConfig.GetOrCreate().RaceAnimals.Select(ra=>ra.Icon).Shuffle()); + } + + var cancelSource = new CancellationTokenSource(); var token = cancelSource.Token; var fullgame = CheckForFullGameAsync(token); @@ -131,7 +139,7 @@ namespace NadekoBot.Modules.Gambling { var rng = new Random(); Participant winner = null; - IMessage msg = null; + IUserMessage msg = null; int place = 1; try { @@ -185,7 +193,7 @@ namespace NadekoBot.Modules.Gambling var wonAmount = winner.AmountBet * (participants.Count - 1); //todo DB //await FlowersHandler.AddFlowersAsync(winner.User, "Won a Race", wonAmount).ConfigureAwait(false); - await raceChannel.SendMessageAsync($"🏁 {winner.User.Mention} as {winner.Animal} **Won the race and {wonAmount}{NadekoBot.Config.Currency.Sign}!**").ConfigureAwait(false); + await raceChannel.SendMessageAsync($"🏁 {winner.User.Mention} as {winner.Animal} **Won the race and {wonAmount}{CurrencySign}!**").ConfigureAwait(false); } else { @@ -196,7 +204,10 @@ namespace NadekoBot.Modules.Gambling private async Task Client_MessageReceived(IMessage imsg) { - if (await imsg.IsAuthor() || !(imsg.Channel is ITextChannel) || imsg.Channel != raceChannel) + var msg = imsg as IUserMessage; + if (msg == null) + return; + if (await msg.IsAuthor() || !(imsg.Channel is ITextChannel) || imsg.Channel != raceChannel) return; messagesSinceGameStarted++; } @@ -229,7 +240,7 @@ namespace NadekoBot.Modules.Gambling return false; } participants.Add(p); - await raceChannel.SendMessageAsync($"{u.Mention} **joined the race as a {p.Animal}" + (amount > 0 ? $" and bet {amount} {(amount == 1? NadekoBot.Config.Currency.Name: NadekoBot.Config.Currency.PluralName)}!**" : "**")); + await raceChannel.SendMessageAsync($"{u.Mention} **joined the race as a {p.Animal}" + (amount > 0 ? $" and bet {amount} {(amount == 1? CurrencyName : CurrencyPluralName)}!**" : "**")); return true; } } diff --git a/src/NadekoBot/Modules/Gambling/Commands/DiceRollCommand.cs b/src/NadekoBot/Modules/Gambling/Commands/DiceRollCommand.cs index e281ed7a..9741fa97 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; @@ -17,16 +16,16 @@ namespace NadekoBot.Modules.Gambling ////todo drawing //[LocalizedCommand, LocalizedDescription, LocalizedSummary] //[RequireContext(ContextType.Guild)] - //public Task Roll(IMessage imsg, [Remainder] string arg = null) => - // InternalRoll(imsg, arg, true); + //public Task Roll(IUserMessage umsg, [Remainder] string arg = null) => + // InternalRoll(umsg, arg, true); //[LocalizedCommand, LocalizedDescription, LocalizedSummary] //[RequireContext(ContextType.Guild)] - //public Task Rolluo(IMessage imsg, [Remainder] string arg = null) => - // InternalRoll(imsg, arg, false); + //public Task Rolluo(IUserMessage umsg, [Remainder] string arg = null) => + // InternalRoll(umsg, arg, false); - //private async Task InternalRoll(IMessage imsg, string arg, bool ordered) { - // var channel = (ITextChannel)imsg.Channel; + //private async Task InternalRoll(IUserMessage umsg, string arg, bool ordered) { + // var channel = (ITextChannel)umsg.Channel; // var r = new Random(); // if (string.IsNullOrWhiteSpace(arg)) // { @@ -108,9 +107,9 @@ namespace NadekoBot.Modules.Gambling [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task NRoll(IMessage imsg, [Remainder] string range) + public async Task NRoll(IUserMessage umsg, [Remainder] string range) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; try @@ -131,7 +130,7 @@ namespace NadekoBot.Modules.Gambling rolled = new Random().Next(0, int.Parse(range) + 1); } - await channel.SendMessageAsync($"{imsg.Author.Mention} rolled **{rolled}**.").ConfigureAwait(false); + await channel.SendMessageAsync($"{umsg.Author.Mention} rolled **{rolled}**.").ConfigureAwait(false); } catch (Exception ex) { diff --git a/src/NadekoBot/Modules/Gambling/Commands/DrawCommand.cs b/src/NadekoBot/Modules/Gambling/Commands/DrawCommand.cs index 75939c89..099649f6 100644 --- a/src/NadekoBot/Modules/Gambling/Commands/DrawCommand.cs +++ b/src/NadekoBot/Modules/Gambling/Commands/DrawCommand.cs @@ -80,7 +80,7 @@ // await e.Channel.SendFile(images.Count + " cards.jpg", bitmap.ToStream()).ConfigureAwait(false); // if (cardObjects.Count == 5) // { -// await channel.SendMessageAsync($"{imsg.Author.Mention} `{Cards.GetHandValue(cardObjects)}`").ConfigureAwait(false); +// await channel.SendMessageAsync($"{umsg.Author.Mention} `{Cards.GetHandValue(cardObjects)}`").ConfigureAwait(false); // } // } // catch (Exception ex) diff --git a/src/NadekoBot/Modules/Gambling/Commands/FlipCoinCommand.cs b/src/NadekoBot/Modules/Gambling/Commands/FlipCoinCommand.cs index 3b0b9401..9f30701f 100644 --- a/src/NadekoBot/Modules/Gambling/Commands/FlipCoinCommand.cs +++ b/src/NadekoBot/Modules/Gambling/Commands/FlipCoinCommand.cs @@ -44,15 +44,15 @@ // if (!int.TryParse(amountstr, out amount) || amount < 1) // return; -// var userFlowers = Gambling.GetUserFlowers(imsg.Author.Id); +// var userFlowers = Gambling.GetUserFlowers(umsg.Author.Id); // if (userFlowers < amount) // { -// await channel.SendMessageAsync($"{imsg.Author.Mention} You don't have enough {NadekoBot.Config.CurrencyName}s. You only have {userFlowers}{NadekoBot.Config.CurrencySign}.").ConfigureAwait(false); +// await channel.SendMessageAsync($"{umsg.Author.Mention} You don't have enough {NadekoBot.Config.CurrencyName}s. You only have {userFlowers}{NadekoBot.Config.CurrencySign}.").ConfigureAwait(false); // return; // } -// await FlowersHandler.RemoveFlowers(imsg.Author, "Betflip Gamble", (int)amount, true).ConfigureAwait(false); +// await FlowersHandler.RemoveFlowers(umsg.Author, "Betflip Gamble", (int)amount, true).ConfigureAwait(false); // //heads = true // //tails = false @@ -69,12 +69,12 @@ // string str; // if (guess == result) // { -// str = $"{imsg.Author.Mention}`You guessed it!` You won {amount * 2}{NadekoBot.Config.CurrencySign}"; -// await FlowersHandler.AddFlowersAsync(imsg.Author, "Betflip Gamble", amount * 2, true).ConfigureAwait(false); +// str = $"{umsg.Author.Mention}`You guessed it!` You won {amount * 2}{NadekoBot.Config.CurrencySign}"; +// await FlowersHandler.AddFlowersAsync(umsg.Author, "Betflip Gamble", amount * 2, true).ConfigureAwait(false); // } // else -// str = $"{imsg.Author.Mention}`More luck next time.`"; +// str = $"{umsg.Author.Mention}`More luck next time.`"; // await channel.SendMessageAsync(str).ConfigureAwait(false); // }; diff --git a/src/NadekoBot/Modules/Gambling/Gambling.cs b/src/NadekoBot/Modules/Gambling/Gambling.cs index 72d72fb4..87a07fab 100644 --- a/src/NadekoBot/Modules/Gambling/Gambling.cs +++ b/src/NadekoBot/Modules/Gambling/Gambling.cs @@ -8,6 +8,7 @@ using System.Text; using System.Threading.Tasks; using NadekoBot.Services; using Discord.WebSocket; +using NadekoBot.Services.Database; //todo DB namespace NadekoBot.Modules.Gambling @@ -15,15 +16,28 @@ namespace NadekoBot.Modules.Gambling [Module("$", AppendSpace = false)] public partial class Gambling : DiscordModule { - public Gambling(ILocalization loc, CommandService cmds, IBotConfiguration config, DiscordSocketClient client) : base(loc, cmds, config, client) + public static string CurrencyName { get; set; } + public static string CurrencyPluralName { get; set; } + public static string CurrencySign { get; set; } + + public Gambling(ILocalization loc, CommandService cmds, DiscordSocketClient client) : base(loc, cmds, client) { + using (var uow = DbHandler.UnitOfWork()) + { + var conf = uow.BotConfig.GetOrCreate(); + + CurrencyName = conf.CurrencyName; + CurrencySign = conf.CurrencySign; + CurrencyPluralName = conf.CurrencyPluralName; + } + } [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Raffle(IMessage imsg, [Remainder] IRole role = null) + public async Task Raffle(IUserMessage umsg, [Remainder] IRole role = null) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; role = role ?? channel.Guild.EveryoneRole; @@ -37,11 +51,11 @@ namespace NadekoBot.Modules.Gambling ////todo DB //[LocalizedCommand("$$$"), LocalizedDescription("$$$"), LocalizedSummary("$$$")] //[RequireContext(ContextType.Guild)] - //public async Task Cash(IMessage imsg, [Remainder] string arg) + //public async Task Cash(IUserMessage umsg, [Remainder] string arg) //{ - // var channel = (ITextChannel)imsg.Channel; + // var channel = (ITextChannel)umsg.Channel; - // var usr = e.Message.MentionedUsers.FirstOrDefault() ?? imsg.Author; + // var usr = e.Message.MentionedUsers.FirstOrDefault() ?? umsg.Author; // var pts = GetUserFlowers(usr.Id); // var str = $"{usr.Name} has {pts} {NadekoBot.Config.CurrencySign}"; // await channel.SendMessageAsync(str).ConfigureAwait(false); @@ -50,23 +64,23 @@ namespace NadekoBot.Modules.Gambling ////todo DB //[LocalizedCommand, LocalizedDescription, LocalizedSummary] //[RequireContext(ContextType.Guild)] - //public async Task Give(IMessage imsg, long amount, [Remainder] IUser receiver) + //public async Task Give(IUserMessage umsg, long amount, [Remainder] IUser receiver) //{ - // var channel = (ITextChannel)imsg.Channel; + // var channel = (ITextChannel)umsg.Channel; // if (amount <= 0) // return; - // var userFlowers = GetUserFlowers(imsg.Author.Id); + // var userFlowers = GetUserFlowers(umsg.Author.Id); // if (userFlowers < amount) // { - // await channel.SendMessageAsync($"{imsg.Author.Mention} You don't have enough {NadekoBot.Config.CurrencyName}s. You only have {userFlowers}{NadekoBot.Config.CurrencySign}.").ConfigureAwait(false); + // await channel.SendMessageAsync($"{umsg.Author.Mention} You don't have enough {NadekoBot.Config.CurrencyName}s. You only have {userFlowers}{NadekoBot.Config.CurrencySign}.").ConfigureAwait(false); // return; // } - // await FlowersHandler.RemoveFlowers(imsg.Author, "Gift", (int)amount, true).ConfigureAwait(false); + // await FlowersHandler.RemoveFlowers(umsg.Author, "Gift", (int)amount, true).ConfigureAwait(false); // await FlowersHandler.AddFlowersAsync(receiver, "Gift", (int)amount).ConfigureAwait(false); - // await channel.SendMessageAsync($"{imsg.Author.Mention} successfully sent {amount} {NadekoBot.Config.CurrencyName}s to {receiver.Mention}!").ConfigureAwait(false); + // await channel.SendMessageAsync($"{umsg.Author.Mention} successfully sent {amount} {NadekoBot.Config.CurrencyName}s to {receiver.Mention}!").ConfigureAwait(false); //} @@ -74,64 +88,64 @@ namespace NadekoBot.Modules.Gambling ////todo owner only //[LocalizedCommand, LocalizedDescription, LocalizedSummary] //[RequireContext(ContextType.Guild)] - //public Task Award(IMessage imsg, long amount, [Remainder] IGuildUser usr) => - // Award(imsg, amount, usr.Id); + //public Task Award(IUserMessage umsg, long amount, [Remainder] IGuildUser usr) => + // Award(umsg, amount, usr.Id); //[LocalizedCommand, LocalizedDescription, LocalizedSummary] //[RequireContext(ContextType.Guild)] - //public async Task Award(IMessage imsg, long amount, [Remainder] ulong usrId) + //public async Task Award(IUserMessage umsg, long amount, [Remainder] ulong usrId) //{ - // var channel = (ITextChannel)imsg.Channel; + // var channel = (ITextChannel)umsg.Channel; // if (amount <= 0) // return; - // await FlowersHandler.AddFlowersAsync(usrId, $"Awarded by bot owner. ({imsg.Author.Username}/{imsg.Author.Id})", (int)amount).ConfigureAwait(false); + // await FlowersHandler.AddFlowersAsync(usrId, $"Awarded by bot owner. ({umsg.Author.Username}/{umsg.Author.Id})", (int)amount).ConfigureAwait(false); - // await channel.SendMessageAsync($"{imsg.Author.Mention} successfully awarded {amount} {NadekoBot.Config.CurrencyName}s to <@{usrId}>!").ConfigureAwait(false); + // await channel.SendMessageAsync($"{umsg.Author.Mention} successfully awarded {amount} {NadekoBot.Config.CurrencyName}s to <@{usrId}>!").ConfigureAwait(false); //} ////todo owner only ////todo DB //[LocalizedCommand, LocalizedDescription, LocalizedSummary] //[RequireContext(ContextType.Guild)] - //public Task Take(IMessage imsg, long amount, [Remainder] IGuildUser user) => - // Take(imsg, amount, user.Id); + //public Task Take(IUserMessage umsg, long amount, [Remainder] IGuildUser user) => + // Take(umsg, amount, user.Id); //[LocalizedCommand, LocalizedDescription, LocalizedSummary] //[RequireContext(ContextType.Guild)] - //public async Task Take(IMessage imsg, long amount, [Remainder] ulong usrId) + //public async Task Take(IUserMessage umsg, long amount, [Remainder] ulong usrId) //{ - // var channel = (ITextChannel)imsg.Channel; + // var channel = (ITextChannel)umsg.Channel; // if (amount <= 0) // return; - // await FlowersHandler.RemoveFlowers(usrId, $"Taken by bot owner.({imsg.Author.Username}/{imsg.Author.Id})", (int)amount).ConfigureAwait(false); + // await FlowersHandler.RemoveFlowers(usrId, $"Taken by bot owner.({umsg.Author.Username}/{umsg.Author.Id})", (int)amount).ConfigureAwait(false); - // await channel.SendMessageAsync($"{imsg.Author.Mention} successfully took {amount} {NadekoBot.Config.CurrencyName}s from <@{usrId}>!").ConfigureAwait(false); + // await channel.SendMessageAsync($"{umsg.Author.Mention} successfully took {amount} {NadekoBot.Config.CurrencyName}s from <@{usrId}>!").ConfigureAwait(false); //} //[LocalizedCommand, LocalizedDescription, LocalizedSummary] //[RequireContext(ContextType.Guild)] - //public async Task BetRoll(IMessage imsg, int amount) + //public async Task BetRoll(IUserMessage umsg, int amount) //{ - // var channel = (ITextChannel)imsg.Channel; + // var channel = (ITextChannel)umsg.Channel; // if (amount < 1) // return; - // var userFlowers = GetUserFlowers(imsg.Author.Id); + // var userFlowers = GetUserFlowers(umsg.Author.Id); // if (userFlowers < amount) // { - // await channel.SendMessageAsync($"{imsg.Author.Mention} You don't have enough {NadekoBot.Config.CurrencyName}s. You only have {userFlowers}{NadekoBot.Config.CurrencySign}.").ConfigureAwait(false); + // await channel.SendMessageAsync($"{umsg.Author.Mention} You don't have enough {NadekoBot.Config.CurrencyName}s. You only have {userFlowers}{NadekoBot.Config.CurrencySign}.").ConfigureAwait(false); // return; // } - // await FlowersHandler.RemoveFlowers(imsg.Author, "Betroll Gamble", (int)amount, true).ConfigureAwait(false); + // await FlowersHandler.RemoveFlowers(umsg.Author, "Betroll Gamble", (int)amount, true).ConfigureAwait(false); // var rng = new Random().Next(0, 101); - // var str = $"{imsg.Author.Mention} `You rolled {rng}.` "; + // var str = $"{umsg.Author.Mention} `You rolled {rng}.` "; // if (rng < 67) // { // str += "Better luck next time."; @@ -139,17 +153,17 @@ namespace NadekoBot.Modules.Gambling // else if (rng < 90) // { // str += $"Congratulations! You won {amount * 2}{NadekoBot.Config.CurrencySign} for rolling above 66"; - // await FlowersHandler.AddFlowersAsync(imsg.Author, "Betroll Gamble", amount * 2, true).ConfigureAwait(false); + // await FlowersHandler.AddFlowersAsync(umsg.Author, "Betroll Gamble", amount * 2, true).ConfigureAwait(false); // } // else if (rng < 100) // { // str += $"Congratulations! You won {amount * 3}{NadekoBot.Config.CurrencySign} for rolling above 90."; - // await FlowersHandler.AddFlowersAsync(imsg.Author, "Betroll Gamble", amount * 3, true).ConfigureAwait(false); + // await FlowersHandler.AddFlowersAsync(umsg.Author, "Betroll Gamble", amount * 3, true).ConfigureAwait(false); // } // else // { // str += $"👑 Congratulations! You won {amount * 10}{NadekoBot.Config.CurrencySign} for rolling **100**. 👑"; - // await FlowersHandler.AddFlowersAsync(imsg.Author, "Betroll Gamble", amount * 10, true).ConfigureAwait(false); + // await FlowersHandler.AddFlowersAsync(umsg.Author, "Betroll Gamble", amount * 10, true).ConfigureAwait(false); // } // await channel.SendMessageAsync(str).ConfigureAwait(false); @@ -158,9 +172,9 @@ namespace NadekoBot.Modules.Gambling ////todo DB // [LocalizedCommand, LocalizedDescription, LocalizedSummary] // [RequireContext(ContextType.Guild)] -// public async Task Leaderboard(IMessage imsg) +// public async Task Leaderboard(IUserMessage umsg) // { -// var channel = (ITextChannel)imsg.Channel; +// var channel = (ITextChannel)umsg.Channel; // var richestTemp = DbHandler.Instance.GetTopRichest(); // var richest = richestTemp as CurrencyState[] ?? richestTemp.ToArray(); diff --git a/src/NadekoBot/Modules/Games/Commands/LeetCommands.cs b/src/NadekoBot/Modules/Games/Commands/LeetCommands.cs index a17bc3d3..26408cd2 100644 --- a/src/NadekoBot/Modules/Games/Commands/LeetCommands.cs +++ b/src/NadekoBot/Modules/Games/Commands/LeetCommands.cs @@ -14,9 +14,9 @@ namespace NadekoBot.Modules.Games { [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Leet(IMessage imsg, int level, [Remainder] string text = null) + public async Task Leet(IUserMessage umsg, int level, [Remainder] string text = null) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; text = text.Trim(); if (string.IsNullOrWhiteSpace(text)) diff --git a/src/NadekoBot/Modules/Games/Commands/PlantAndPickCommands.cs b/src/NadekoBot/Modules/Games/Commands/PlantAndPickCommands.cs index b670c633..6b144495 100644 --- a/src/NadekoBot/Modules/Games/Commands/PlantAndPickCommands.cs +++ b/src/NadekoBot/Modules/Games/Commands/PlantAndPickCommands.cs @@ -79,8 +79,8 @@ // foreach(var msgToDelete in msgs) // await msgToDelete.Delete().ConfigureAwait(false); -// await FlowersHandler.AddFlowersAsync(imsg.Author, "Picked a flower.", 1, true).ConfigureAwait(false); -// var msg = await channel.SendMessageAsync($"**{imsg.Author.Username}** picked a {NadekoBot.Config.CurrencyName}!").ConfigureAwait(false); +// await FlowersHandler.AddFlowersAsync(umsg.Author, "Picked a flower.", 1, true).ConfigureAwait(false); +// var msg = await channel.SendMessageAsync($"**{umsg.Author.Username}** picked a {NadekoBot.Config.CurrencyName}!").ConfigureAwait(false); // ThreadPool.QueueUserWorkItem(async (state) => // { // try @@ -104,7 +104,7 @@ // await channel.SendMessageAsync($"There is already a {NadekoBot.Config.CurrencyName} in this channel.").ConfigureAwait(false); // return; // } -// var removed = await FlowersHandler.RemoveFlowers(imsg.Author, "Planted a flower.", 1, true).ConfigureAwait(false); +// var removed = await FlowersHandler.RemoveFlowers(umsg.Author, "Planted a flower.", 1, true).ConfigureAwait(false); // if (!removed) // { // await channel.SendMessageAsync($"You don't have any {NadekoBot.Config.CurrencyName}s.").ConfigureAwait(false); @@ -118,7 +118,7 @@ // else // msg = await e.Channel.SendFile(file).ConfigureAwait(false); // var vowelFirst = new[] { 'a', 'e', 'i', 'o', 'u' }.Contains(NadekoBot.Config.CurrencyName[0]); -// var msg2 = await channel.SendMessageAsync($"Oh how Nice! **{imsg.Author.Username}** planted {(vowelFirst ? "an" : "a")} {NadekoBot.Config.CurrencyName}. Pick it using {Module.Prefix}pick").ConfigureAwait(false); +// var msg2 = await channel.SendMessageAsync($"Oh how Nice! **{umsg.Author.Username}** planted {(vowelFirst ? "an" : "a")} {NadekoBot.Config.CurrencyName}. Pick it using {Module.Prefix}pick").ConfigureAwait(false); // plantedFlowerChannels.TryAdd(e.Channel.Id, new[] { msg, msg2 }); // } // finally { locker.Release(); } diff --git a/src/NadekoBot/Modules/Games/Commands/PollCommands.cs b/src/NadekoBot/Modules/Games/Commands/PollCommands.cs index 95900dcc..0e579ff9 100644 --- a/src/NadekoBot/Modules/Games/Commands/PollCommands.cs +++ b/src/NadekoBot/Modules/Games/Commands/PollCommands.cs @@ -17,11 +17,11 @@ namespace NadekoBot.Modules.Games [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Poll(IMessage imsg, [Remainder] string arg = null) + public async Task Poll(IUserMessage umsg, [Remainder] string arg = null) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; - if (!(imsg.Author as IGuildUser).GuildPermissions.ManageChannels) + if (!(umsg.Author as IGuildUser).GuildPermissions.ManageChannels) return; if (string.IsNullOrWhiteSpace(arg) || !arg.Contains(";")) return; @@ -29,7 +29,7 @@ namespace NadekoBot.Modules.Games if (data.Length < 3) return; - var poll = new Poll(imsg, data[0], data.Skip(1)); + var poll = new Poll(umsg, data[0], data.Skip(1)); if (ActivePolls.TryAdd(channel.Guild, poll)) { await poll.StartPoll().ConfigureAwait(false); @@ -38,11 +38,11 @@ namespace NadekoBot.Modules.Games [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Pollend(IMessage imsg) + public async Task Pollend(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; - if (!(imsg.Author as IGuildUser).GuildPermissions.ManageChannels) + if (!(umsg.Author as IGuildUser).GuildPermissions.ManageChannels) return; Poll poll; ActivePolls.TryGetValue(channel.Guild, out poll); @@ -52,16 +52,16 @@ namespace NadekoBot.Modules.Games public class Poll { - private readonly IMessage imsg; + private readonly IUserMessage umsg; private readonly string[] answers; private ConcurrentDictionary participants = new ConcurrentDictionary(); private readonly string question; private DateTime started; private CancellationTokenSource pollCancellationSource = new CancellationTokenSource(); - public Poll(IMessage imsg, string question, IEnumerable enumerable) + public Poll(IUserMessage umsg, string question, IEnumerable enumerable) { - this.imsg = imsg; + this.umsg = umsg; this.question = question; this.answers = enumerable as string[] ?? enumerable.ToArray(); } @@ -70,13 +70,13 @@ namespace NadekoBot.Modules.Games { started = DateTime.Now; NadekoBot.Client.MessageReceived += Vote; - var msgToSend = $@"📃**{imsg.Author.Username}** has created a poll which requires your attention: + var msgToSend = $@"📃**{umsg.Author.Username}** has created a poll which requires your attention: **{question}**\n"; var num = 1; msgToSend = answers.Aggregate(msgToSend, (current, answ) => current + $"`{num++}.` **{answ}**\n"); msgToSend += "\n**Private Message me with the corresponding number of the answer.**"; - await imsg.Channel.SendMessageAsync(msgToSend).ConfigureAwait(false); + await umsg.Channel.SendMessageAsync(msgToSend).ConfigureAwait(false); } public async Task StopPoll(IGuildChannel ch) @@ -91,7 +91,7 @@ namespace NadekoBot.Modules.Games var totalVotesCast = results.Sum(kvp => kvp.Value); if (totalVotesCast == 0) { - await imsg.Channel.SendMessageAsync("📄 **No votes have been cast.**").ConfigureAwait(false); + await umsg.Channel.SendMessageAsync("📄 **No votes have been cast.**").ConfigureAwait(false); return; } var closeMessage = $"--------------**POLL CLOSED**--------------\n" + @@ -100,7 +100,7 @@ namespace NadekoBot.Modules.Games $" has {kvp.Value} votes." + $"({kvp.Value * 1.0f / totalVotesCast * 100}%)\n"); - await imsg.Channel.SendMessageAsync($"📄 **Total votes cast**: {totalVotesCast}\n{closeMessage}").ConfigureAwait(false); + await umsg.Channel.SendMessageAsync($"📄 **Total votes cast**: {totalVotesCast}\n{closeMessage}").ConfigureAwait(false); } catch (Exception ex) { @@ -108,8 +108,11 @@ namespace NadekoBot.Modules.Games } } - private async Task Vote(IMessage msg) + private async Task Vote(IMessage imsg) { + var msg = imsg as ISystemMessage; + if (msg == null) + return; try { IPrivateChannel ch; diff --git a/src/NadekoBot/Modules/Games/Commands/SpeedTypingCommands.cs b/src/NadekoBot/Modules/Games/Commands/SpeedTypingCommands.cs index eb5e8a9f..875f235c 100644 --- a/src/NadekoBot/Modules/Games/Commands/SpeedTypingCommands.cs +++ b/src/NadekoBot/Modules/Games/Commands/SpeedTypingCommands.cs @@ -103,16 +103,16 @@ // { // try // { -// if (e.Channel == null || e.Channel.Id != channel.Id || imsg.Author.Id == NadekoBot.Client.CurrentUser.Id) return; +// if (e.Channel == null || e.Channel.Id != channel.Id || umsg.Author.Id == NadekoBot.Client.CurrentUser.Id) return; // var guess = e.Message.RawText; // var distance = CurrentSentence.LevenshteinDistance(guess); // var decision = Judge(distance, guess.Length); -// if (decision && !finishedUserIds.Contains(imsg.Author.Id)) +// if (decision && !finishedUserIds.Contains(umsg.Author.Id)) // { -// finishedUserIds.Add(imsg.Author.Id); -// await channel.Send($"{imsg.Author.Mention} finished in **{sw.Elapsed.Seconds}** seconds with { distance } errors, **{ CurrentSentence.Length / WORD_VALUE / sw.Elapsed.Seconds * 60 }** WPM!").ConfigureAwait(false); +// finishedUserIds.Add(umsg.Author.Id); +// await channel.Send($"{umsg.Author.Mention} finished in **{sw.Elapsed.Seconds}** seconds with { distance } errors, **{ CurrentSentence.Length / WORD_VALUE / sw.Elapsed.Seconds * 60 }** WPM!").ConfigureAwait(false); // if (finishedUserIds.Count % 2 == 0) // { // await channel.SendMessageAsync($":exclamation: `A lot of people finished, here is the text for those still typing:`\n\n:book:**{CurrentSentence}**:book:").ConfigureAwait(false); @@ -139,7 +139,7 @@ // public Func DoFunc() => // async e => // { -// var game = RunningContests.GetOrAdd(imsg.Author.Server.Id, id => new TypingGame(e.Channel)); +// var game = RunningContests.GetOrAdd(umsg.Author.Server.Id, id => new TypingGame(e.Channel)); // if (game.IsActive) // { @@ -158,7 +158,7 @@ // async e => // { // TypingGame game; -// if (RunningContests.TryRemove(imsg.Author.Server.Id, out game)) +// if (RunningContests.TryRemove(umsg.Author.Server.Id, out game)) // { // await game.Stop().ConfigureAwait(false); // return; @@ -181,7 +181,7 @@ // .Parameter("text", ParameterType.Unparsed) // .Do(async e => // { -// if (!NadekoBot.IsOwner(imsg.Author.Id) || string.IsNullOrWhiteSpace(text)) return; +// if (!NadekoBot.IsOwner(umsg.Author.Id) || string.IsNullOrWhiteSpace(text)) return; // DbHandler.Instance.Connection.Insert(new TypingArticle // { diff --git a/src/NadekoBot/Modules/Games/Commands/Trivia/TriviaGame.cs b/src/NadekoBot/Modules/Games/Commands/Trivia/TriviaGame.cs index 271ca03c..a86f2558 100644 --- a/src/NadekoBot/Modules/Games/Commands/Trivia/TriviaGame.cs +++ b/src/NadekoBot/Modules/Games/Commands/Trivia/TriviaGame.cs @@ -104,19 +104,23 @@ namespace NadekoBot.Modules.Games.Trivia private async Task PotentialGuess(IMessage imsg) { + var umsg = imsg as IUserMessage; + if (umsg == null) + return; + try { - if (!(imsg.Channel is IGuildChannel && imsg.Channel is ITextChannel)) return; - if ((imsg.Channel as ITextChannel).Guild != guild) return; - if (imsg.Author.Id == (await NadekoBot.Client.GetCurrentUserAsync()).Id) return; + if (!(umsg.Channel is IGuildChannel && umsg.Channel is ITextChannel)) return; + if ((umsg.Channel as ITextChannel).Guild != guild) return; + if (umsg.Author.Id == (await NadekoBot.Client.GetCurrentUserAsync()).Id) return; - var guildUser = imsg.Author as IGuildUser; + var guildUser = umsg.Author as IGuildUser; var guess = false; await _guessLock.WaitAsync().ConfigureAwait(false); try { - if (GameActive && CurrentQuestion.IsAnswerCorrect(imsg.Content) && !triviaCancelSource.IsCancellationRequested) + if (GameActive && CurrentQuestion.IsAnswerCorrect(umsg.Content) && !triviaCancelSource.IsCancellationRequested) { Users.AddOrUpdate(guildUser, 0, (gu, old) => old++); guess = true; diff --git a/src/NadekoBot/Modules/Games/Commands/TriviaCommands.cs b/src/NadekoBot/Modules/Games/Commands/TriviaCommands.cs index e2c7c347..13c0adaf 100644 --- a/src/NadekoBot/Modules/Games/Commands/TriviaCommands.cs +++ b/src/NadekoBot/Modules/Games/Commands/TriviaCommands.cs @@ -19,9 +19,9 @@ namespace NadekoBot.Modules.Games [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Trivia(IMessage imsg, string[] args) + public async Task Trivia(IUserMessage umsg, string[] args) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; TriviaGame trivia; if (!RunningTrivias.TryGetValue(channel.Guild.Id, out trivia)) @@ -34,7 +34,7 @@ namespace NadekoBot.Modules.Games }).Where(t => t.Item1).Select(t => t.Item2).FirstOrDefault(); if (number < 0) return; - var triviaGame = new TriviaGame(channel.Guild, imsg.Channel as ITextChannel, showHints, number == 0 ? 10 : number); + var triviaGame = new TriviaGame(channel.Guild, umsg.Channel as ITextChannel, showHints, number == 0 ? 10 : number); if (RunningTrivias.TryAdd(channel.Guild.Id, triviaGame)) await channel.SendMessageAsync($"**Trivia game started! {triviaGame.WinRequirement} points needed to win.**").ConfigureAwait(false); else @@ -46,9 +46,9 @@ namespace NadekoBot.Modules.Games [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Tl(IMessage imsg) + public async Task Tl(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; TriviaGame trivia; if (RunningTrivias.TryGetValue(channel.Guild.Id, out trivia)) @@ -59,9 +59,9 @@ namespace NadekoBot.Modules.Games [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Tq(IMessage imsg) + public async Task Tq(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; TriviaGame trivia; if (RunningTrivias.TryRemove(channel.Guild.Id, out trivia)) diff --git a/src/NadekoBot/Modules/Games/Games.cs b/src/NadekoBot/Modules/Games/Games.cs index 861d4697..4b29e7da 100644 --- a/src/NadekoBot/Modules/Games/Games.cs +++ b/src/NadekoBot/Modules/Games/Games.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Collections.Generic; using NadekoBot.Extensions; using Discord.WebSocket; +using NadekoBot.Services.Database; namespace NadekoBot.Modules.Games { @@ -15,17 +16,23 @@ namespace NadekoBot.Modules.Games public partial class Games : DiscordModule { //todo DB - private IEnumerable _8BallResponses; - public Games(ILocalization loc, CommandService cmds, IBotConfiguration config, DiscordSocketClient client) : base(loc, cmds, config, client) + private IEnumerable _8BallResponses { + get { + using (var uow = DbHandler.UnitOfWork()) + { + return uow.BotConfig.GetOrCreate().EightBallResponses.Select(ebr => ebr.Text); + } + } + } + public Games(ILocalization loc, CommandService cmds, DiscordSocketClient client) : base(loc, cmds, client) { - _8BallResponses = config.EightBallResponses; } [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Choose(IMessage imsg, [Remainder] string list = null) + public async Task Choose(IUserMessage umsg, [Remainder] string list = null) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; if (string.IsNullOrWhiteSpace(list)) return; var listArr = list.Split(';'); @@ -37,9 +44,9 @@ namespace NadekoBot.Modules.Games [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task _8Ball(IMessage imsg, [Remainder] string question = null) + public async Task _8Ball(IUserMessage umsg, [Remainder] string question = null) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; if (string.IsNullOrWhiteSpace(question)) return; @@ -50,9 +57,9 @@ namespace NadekoBot.Modules.Games [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Rps(IMessage imsg, string input) + public async Task Rps(IUserMessage umsg, string input) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; Func GetRPSPick = (p) => { @@ -93,16 +100,16 @@ namespace NadekoBot.Modules.Games (pick == 2 && nadekoPick == 0)) msg = $"{(await NadekoBot.Client.GetCurrentUserAsync()).Mention} won! :{GetRPSPick(nadekoPick)}: beats :{GetRPSPick(pick)}:"; else - msg = $"{imsg.Author.Mention} won! :{GetRPSPick(pick)}: beats :{GetRPSPick(nadekoPick)}:"; + msg = $"{umsg.Author.Mention} won! :{GetRPSPick(pick)}: beats :{GetRPSPick(nadekoPick)}:"; await channel.SendMessageAsync(msg).ConfigureAwait(false); } [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Linux(IMessage imsg, string guhnoo, string loonix) + public async Task Linux(IUserMessage umsg, string guhnoo, string loonix) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; await channel.SendMessageAsync( $@"I'd just like to interject for moment. What you're refering to as {loonix}, is in fact, {guhnoo}/{loonix}, or as I've recently taken to calling it, {guhnoo} plus {loonix}. {loonix} is not an operating system unto itself, but rather another free component of a fully functioning {guhnoo} system made useful by the {guhnoo} corelibs, shell utilities and vital system components comprising a full OS as defined by POSIX. diff --git a/src/NadekoBot/Modules/Help/Help.cs b/src/NadekoBot/Modules/Help/Help.cs index 68e9cca4..c62c39c4 100644 --- a/src/NadekoBot/Modules/Help/Help.cs +++ b/src/NadekoBot/Modules/Help/Help.cs @@ -21,15 +21,15 @@ namespace NadekoBot.Modules.Help return str + String.Format(str, NadekoBot.Credentials.ClientId); } } - public Help(ILocalization loc, CommandService cmds, IBotConfiguration config, DiscordSocketClient client) : base(loc, cmds, config, client) + public Help(ILocalization loc, CommandService cmds, DiscordSocketClient client) : base(loc, cmds, client) { } [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Modules(IMessage imsg) + public async Task Modules(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; await channel.SendMessageAsync("`List of modules:` \n• " + string.Join("\n• ", _commands.Modules.Select(m => m.Name)) + $"\n`Type \"-commands module_name\" to get a list of commands in that module.`") .ConfigureAwait(false); @@ -37,9 +37,9 @@ namespace NadekoBot.Modules.Help [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Commands(IMessage imsg, [Remainder] string module = null) + public async Task Commands(IUserMessage umsg, [Remainder] string module = null) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; module = module?.Trim().ToUpperInvariant(); if (string.IsNullOrWhiteSpace(module)) @@ -67,14 +67,14 @@ namespace NadekoBot.Modules.Help [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task H(IMessage imsg, [Remainder] string comToFind = null) + public async Task H(IUserMessage umsg, [Remainder] string comToFind = null) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; comToFind = comToFind?.ToLowerInvariant(); if (string.IsNullOrWhiteSpace(comToFind)) { - await (await (imsg.Author as IGuildUser).CreateDMChannelAsync()).SendMessageAsync(HelpString).ConfigureAwait(false); + await (await (umsg.Author as IGuildUser).CreateDMChannelAsync()).SendMessageAsync(HelpString).ConfigureAwait(false); return; } var com = _commands.Commands.FirstOrDefault(c => c.Text.ToLowerInvariant() == comToFind); @@ -88,7 +88,7 @@ namespace NadekoBot.Modules.Help [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Hgit(IMessage imsg) + public async Task Hgit(IUserMessage umsg) { var helpstr = new StringBuilder(); @@ -115,9 +115,9 @@ namespace NadekoBot.Modules.Help [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Guide(IMessage imsg) + public async Task Guide(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; await channel.SendMessageAsync( @"**LIST OF COMMANDS**: @@ -126,9 +126,9 @@ namespace NadekoBot.Modules.Help [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Donate(IMessage imsg) + public async Task Donate(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; await channel.SendMessageAsync( $@"You can support the project on patreon. or diff --git a/src/NadekoBot/Modules/Music/Classes/Song.cs b/src/NadekoBot/Modules/Music/Classes/Song.cs index db4b06ea..f6827d2a 100644 --- a/src/NadekoBot/Modules/Music/Classes/Song.cs +++ b/src/NadekoBot/Modules/Music/Classes/Song.cs @@ -1,6 +1,6 @@ using Discord.Audio; -using NadekoBot.Classes; using NadekoBot.Extensions; +using NLog; using System; using System.Diagnostics; using System.Diagnostics.Contracts; @@ -41,11 +41,17 @@ namespace NadekoBot.Modules.Music.Classes return $"【{(int)time.TotalMinutes}m {time.Seconds}s】"; } + const int milliseconds = 20; + const int samplesPerFrame = (48000 / 1000) * milliseconds; + const int frameBytes = 3840; //16-bit, 2 channels + private ulong bytesSent { get; set; } = 0; public bool PrintStatusMessage { get; set; } = true; private int skipTo = 0; + private Logger _log; + public int SkipTo { get { return SkipTo; } set { @@ -57,6 +63,7 @@ namespace NadekoBot.Modules.Music.Classes public Song(SongInfo songInfo) { this.SongInfo = songInfo; + this._log = LogManager.GetCurrentClassLogger(); } public Song Clone() @@ -77,10 +84,8 @@ namespace NadekoBot.Modules.Music.Classes { var filename = Path.Combine(Music.MusicDataPath, DateTime.Now.UnixTimestamp().ToString()); - SongBuffer sb = new SongBuffer(filename, SongInfo, skipTo); - var bufferTask = sb.BufferSong(cancelToken).ConfigureAwait(false); - - var inStream = new FileStream(sb.GetNextFile(), FileMode.OpenOrCreate, FileAccess.Read, FileShare.Write); ; + SongBuffer inStream = new SongBuffer(MusicPlayer, filename, SongInfo, skipTo); + var bufferTask = inStream.BufferSong(cancelToken).ConfigureAwait(false); bytesSent = 0; @@ -88,49 +93,43 @@ namespace NadekoBot.Modules.Music.Classes { var attempt = 0; - var prebufferingTask = CheckPrebufferingAsync(inStream, sb, cancelToken); + var prebufferingTask = CheckPrebufferingAsync(inStream, cancelToken); var sw = new Stopwatch(); sw.Start(); var t = await Task.WhenAny(prebufferingTask, Task.Delay(5000, cancelToken)); if (t != prebufferingTask) { - Console.WriteLine("Prebuffering timed out or canceled. Cannot get any data from the stream."); + _log.Debug("Prebuffering timed out or canceled. Cannot get any data from the stream."); return; } else if(prebufferingTask.IsCanceled) { - Console.WriteLine("Prebuffering timed out. Cannot get any data from the stream."); + _log.Debug("Prebuffering timed out. Cannot get any data from the stream."); return; } sw.Stop(); - Console.WriteLine("Prebuffering successfully completed in "+ sw.Elapsed); + _log.Debug("Prebuffering successfully completed in "+ sw.Elapsed); + var outStream = voiceClient.CreatePCMStream(960); - var outStream = voiceClient.CreatePCMStream(3840); - - const int blockSize = 3840; - byte[] buffer = new byte[blockSize]; + int nextTime = Environment.TickCount + milliseconds; + + byte[] buffer = new byte[frameBytes]; while (!cancelToken.IsCancellationRequested) { //Console.WriteLine($"Read: {songBuffer.ReadPosition}\nWrite: {songBuffer.WritePosition}\nContentLength:{songBuffer.ContentLength}\n---------"); var read = inStream.Read(buffer, 0, buffer.Length); //await inStream.CopyToAsync(voiceClient.OutputStream); + _log.Debug("read {0}", read); unchecked { bytesSent += (ulong)read; } - if (read < blockSize) + if (read < frameBytes) { - if (sb.IsNextFileReady()) - { - inStream.Dispose(); - inStream = new FileStream(sb.GetNextFile(), FileMode.Open, FileAccess.Read, FileShare.Write); - read += inStream.Read(buffer, read, buffer.Length - read); - attempt = 0; - } if (read == 0) { - if (sb.BufferingCompleted) + if (inStream.BufferingCompleted) break; if (attempt++ == 20) { @@ -149,7 +148,13 @@ namespace NadekoBot.Modules.Music.Classes while (this.MusicPlayer.Paused) await Task.Delay(200, cancelToken).ConfigureAwait(false); + buffer = AdjustVolume(buffer, MusicPlayer.Volume); + if (read != frameBytes) continue; + nextTime = unchecked(nextTime + milliseconds); + int delayMillis = unchecked(nextTime - Environment.TickCount); + if (delayMillis > 0) + await Task.Delay(delayMillis, cancelToken).ConfigureAwait(false); await outStream.WriteAsync(buffer, 0, read); } } @@ -158,18 +163,16 @@ namespace NadekoBot.Modules.Music.Classes await bufferTask; if(inStream != null) inStream.Dispose(); - Console.WriteLine("l"); - sb.CleanFiles(); } } - private async Task CheckPrebufferingAsync(Stream inStream, SongBuffer sb, CancellationToken cancelToken) + private async Task CheckPrebufferingAsync(SongBuffer inStream, CancellationToken cancelToken) { - while (!sb.BufferingCompleted && inStream.Length < 2.MiB()) + while (!inStream.BufferingCompleted && inStream.Length < 10.MiB()) { await Task.Delay(100, cancelToken); } - Console.WriteLine("Buffering successfull"); + _log.Debug("Buffering successfull"); } /* diff --git a/src/NadekoBot/Modules/Music/Classes/SongBuffer.cs b/src/NadekoBot/Modules/Music/Classes/SongBuffer.cs index d9192940..a53d7d0b 100644 --- a/src/NadekoBot/Modules/Music/Classes/SongBuffer.cs +++ b/src/NadekoBot/Modules/Music/Classes/SongBuffer.cs @@ -15,23 +15,27 @@ namespace NadekoBot.Modules.Music.Classes /// Create a buffer for a song file. It will create multiples files to ensure, that radio don't fill up disk space. /// It also help for large music by deleting files that are already seen. /// - class SongBuffer + class SongBuffer : Stream { - public SongBuffer(string basename, SongInfo songInfo, int skipTo) + public SongBuffer(MusicPlayer musicPlayer, string basename, SongInfo songInfo, int skipTo) { + MusicPlayer = musicPlayer; Basename = basename; SongInfo = songInfo; SkipTo = skipTo; + CurrentFileStream = new FileStream(this.GetNextFile(), FileMode.OpenOrCreate, FileAccess.Read, FileShare.Write); } + MusicPlayer MusicPlayer; + private string Basename; private SongInfo SongInfo; private int SkipTo; - private static int MAX_FILE_SIZE = 20.MiB(); + private static int MAX_FILE_SIZE = 2.MiB(); private long FileNumber = -1; @@ -41,6 +45,8 @@ namespace NadekoBot.Modules.Music.Classes private ulong CurrentBufferSize = 0; + private FileStream CurrentFileStream; + public Task BufferSong(CancellationToken cancelToken) => Task.Factory.StartNew(async () => { @@ -122,7 +128,7 @@ Check the guides for your platform on how to setup ffmpeg correctly: /// Return the next file to read, and delete the old one /// /// Name of the file to read - public string GetNextFile() + private string GetNextFile() { string filename = Basename + "-" + NextFileToRead; @@ -139,12 +145,12 @@ Check the guides for your platform on how to setup ffmpeg correctly: return filename; } - public bool IsNextFileReady() + private bool IsNextFileReady() { return NextFileToRead <= FileNumber; } - public void CleanFiles() + private void CleanFiles() { for (long i = NextFileToRead - 1 ; i <= FileNumber; i++) { @@ -155,5 +161,68 @@ Check the guides for your platform on how to setup ffmpeg correctly: catch { } } } + + //Stream part + + public override bool CanRead => true; + + public override bool CanSeek => false; + + public override bool CanWrite => false; + + public override long Length => (long) CurrentBufferSize; + + public override long Position + { + get + { + return 0; + } + + set + { + + } + } + + public override void Flush() { } + + public override int Read(byte[] buffer, int offset, int count) + { + int read = CurrentFileStream.Read(buffer, offset, count); + if(read < count) + { + if (!BufferingCompleted || IsNextFileReady()) + { + CurrentFileStream.Dispose(); + CurrentFileStream = new FileStream(GetNextFile(), FileMode.OpenOrCreate, FileAccess.Read, FileShare.Write); + read += CurrentFileStream.Read(buffer, read + offset, count - read); + } + } + return read; + } + + public override long Seek(long offset, SeekOrigin origin) + { + throw new NotImplementedException(); + } + + public override void SetLength(long value) + { + throw new NotImplementedException(); + } + + public override void Write(byte[] buffer, int offset, int count) + { + throw new NotImplementedException(); + } + + public new void Dispose() + { + CurrentFileStream.Dispose(); + MusicPlayer.SongCancelSource.Cancel(); + CleanFiles(); + base.Dispose(); + } } } 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/Music/Music.cs b/src/NadekoBot/Modules/Music/Music.cs index 4d773f5f..2bb4d62c 100644 --- a/src/NadekoBot/Modules/Music/Music.cs +++ b/src/NadekoBot/Modules/Music/Music.cs @@ -24,7 +24,7 @@ namespace NadekoBot.Modules.Music public const string MusicDataPath = "data/musicdata"; private IGoogleApiService _google; - public Music(ILocalization loc, CommandService cmds, IBotConfiguration config, DiscordSocketClient client, IGoogleApiService google) : base(loc, cmds, config, client) + public Music(ILocalization loc, CommandService cmds, DiscordSocketClient client, IGoogleApiService google) : base(loc, cmds, client) { //it can fail if its currenctly opened or doesn't exist. Either way i don't care try { Directory.Delete(MusicDataPath, true); } catch { } @@ -36,25 +36,25 @@ namespace NadekoBot.Modules.Music [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Next(IMessage imsg) + public async Task Next(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; MusicPlayer musicPlayer; if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) return; - if (musicPlayer.PlaybackVoiceChannel == ((IGuildUser)imsg.Author).VoiceChannel) + if (musicPlayer.PlaybackVoiceChannel == ((IGuildUser)umsg.Author).VoiceChannel) musicPlayer.Next(); } [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Stop(IMessage imsg) + public async Task Stop(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; MusicPlayer musicPlayer; if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) return; - if (((IGuildUser)imsg.Author).VoiceChannel == musicPlayer.PlaybackVoiceChannel) + if (((IGuildUser)umsg.Author).VoiceChannel == musicPlayer.PlaybackVoiceChannel) { musicPlayer.Autoplay = false; musicPlayer.Stop(); @@ -63,25 +63,25 @@ namespace NadekoBot.Modules.Music [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Destroy(IMessage imsg) + public async Task Destroy(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; MusicPlayer musicPlayer; if (!MusicPlayers.TryRemove(channel.Guild.Id, out musicPlayer)) return; - if (((IGuildUser)imsg.Author).VoiceChannel == musicPlayer.PlaybackVoiceChannel) + if (((IGuildUser)umsg.Author).VoiceChannel == musicPlayer.PlaybackVoiceChannel) musicPlayer.Destroy(); } [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Pause(IMessage imsg) + public async Task Pause(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; MusicPlayer musicPlayer; if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) return; - if (((IGuildUser)imsg.Author).VoiceChannel != musicPlayer.PlaybackVoiceChannel) + if (((IGuildUser)umsg.Author).VoiceChannel != musicPlayer.PlaybackVoiceChannel) return; musicPlayer.TogglePause(); if (musicPlayer.Paused) @@ -92,37 +92,37 @@ namespace NadekoBot.Modules.Music [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Queue(IMessage imsg, [Remainder] string query) + public async Task Queue(IUserMessage umsg, [Remainder] string query) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; - await QueueSong(((IGuildUser)imsg.Author), channel, ((IGuildUser)imsg.Author).VoiceChannel, query).ConfigureAwait(false); + await QueueSong(((IGuildUser)umsg.Author), channel, ((IGuildUser)umsg.Author).VoiceChannel, query).ConfigureAwait(false); if (channel.Guild.GetCurrentUser().GetPermissions(channel).ManageMessages) { await Task.Delay(10000).ConfigureAwait(false); - await imsg.DeleteAsync().ConfigureAwait(false); + await ((IUserMessage)umsg).DeleteAsync().ConfigureAwait(false); } } [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task SoundCloudQueue(IMessage imsg, [Remainder] string query) + public async Task SoundCloudQueue(IUserMessage umsg, [Remainder] string query) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; - await QueueSong(((IGuildUser)imsg.Author), channel, ((IGuildUser)imsg.Author).VoiceChannel, query, musicType: MusicType.Soundcloud).ConfigureAwait(false); + await QueueSong(((IGuildUser)umsg.Author), channel, ((IGuildUser)umsg.Author).VoiceChannel, query, musicType: MusicType.Soundcloud).ConfigureAwait(false); if (channel.Guild.GetCurrentUser().GetPermissions(channel).ManageMessages) { await Task.Delay(10000).ConfigureAwait(false); - await imsg.DeleteAsync().ConfigureAwait(false); + await ((IUserMessage)umsg).DeleteAsync().ConfigureAwait(false); } } [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task ListQueue(IMessage imsg, int page = 1) + public async Task ListQueue(IUserMessage umsg, int page = 1) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; MusicPlayer musicPlayer; if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) { @@ -153,9 +153,9 @@ namespace NadekoBot.Modules.Music [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task NowPlaying(IMessage imsg) + public async Task NowPlaying(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; MusicPlayer musicPlayer; if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) return; @@ -168,13 +168,13 @@ namespace NadekoBot.Modules.Music [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Volume(IMessage imsg, int val) + public async Task Volume(IUserMessage umsg, int val) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; MusicPlayer musicPlayer; if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) return; - if (((IGuildUser)imsg.Author).VoiceChannel != musicPlayer.PlaybackVoiceChannel) + if (((IGuildUser)umsg.Author).VoiceChannel != musicPlayer.PlaybackVoiceChannel) return; if (val < 0) return; @@ -184,9 +184,9 @@ namespace NadekoBot.Modules.Music ////todo DB //[LocalizedCommand, LocalizedDescription, LocalizedSummary] //[RequireContext(ContextType.Guild)] - //public async Task Defvol(IMessage imsg, [Remainder] int val) + //public async Task Defvol(IUserMessage umsg, [Remainder] int val) //{ - // var channel = (ITextChannel)imsg.Channel; + // var channel = (ITextChannel)umsg.Channel; // var arg = val; // float volume; // if (!float.TryParse(arg, out volume) || volume < 0 || volume > 100) @@ -201,39 +201,39 @@ namespace NadekoBot.Modules.Music [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Mute(IMessage imsg) + public async Task Mute(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; MusicPlayer musicPlayer; if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) return; - if (((IGuildUser)imsg.Author).VoiceChannel != musicPlayer.PlaybackVoiceChannel) + if (((IGuildUser)umsg.Author).VoiceChannel != musicPlayer.PlaybackVoiceChannel) return; musicPlayer.SetVolume(0); } [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Max(IMessage imsg) + public async Task Max(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; MusicPlayer musicPlayer; if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) return; - if (((IGuildUser)imsg.Author).VoiceChannel != musicPlayer.PlaybackVoiceChannel) + if (((IGuildUser)umsg.Author).VoiceChannel != musicPlayer.PlaybackVoiceChannel) return; musicPlayer.SetVolume(100); } [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Shuffle(IMessage imsg) + public async Task Shuffle(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; MusicPlayer musicPlayer; if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) return; - if (((IGuildUser)imsg.Author).VoiceChannel != musicPlayer.PlaybackVoiceChannel) + if (((IGuildUser)umsg.Author).VoiceChannel != musicPlayer.PlaybackVoiceChannel) return; if (musicPlayer.Playlist.Count < 2) { @@ -247,13 +247,13 @@ namespace NadekoBot.Modules.Music [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Playlist(IMessage imsg, [Remainder] string playlist) + public async Task Playlist(IUserMessage umsg, [Remainder] string playlist) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; var arg = playlist; if (string.IsNullOrWhiteSpace(arg)) return; - if (((IGuildUser)imsg.Author).VoiceChannel?.Guild != channel.Guild) + if (((IGuildUser)umsg.Author).VoiceChannel?.Guild != channel.Guild) { await channel.SendMessageAsync("💢 You need to be in a voice channel on this server.\n If you are already in a voice channel, try rejoining it.").ConfigureAwait(false); return; @@ -278,7 +278,7 @@ namespace NadekoBot.Modules.Music { try { - await QueueSong(((IGuildUser)imsg.Author), channel, ((IGuildUser)imsg.Author).VoiceChannel, id, true).ConfigureAwait(false); + await QueueSong(((IGuildUser)umsg.Author), channel, ((IGuildUser)umsg.Author).VoiceChannel, id, true).ConfigureAwait(false); } catch (PlaylistFullException) { break; } @@ -289,9 +289,9 @@ namespace NadekoBot.Modules.Music [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task SoundCloudPl(IMessage imsg, [Remainder] string pl) + public async Task SoundCloudPl(IUserMessage umsg, [Remainder] string pl) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; pl = pl?.Trim(); if (string.IsNullOrWhiteSpace(pl)) @@ -300,7 +300,7 @@ namespace NadekoBot.Modules.Music using (var http = new HttpClient()) { var scvids = JObject.Parse(await http.GetStringAsync($"http://api.soundcloud.com/resolve?url={pl}&client_id={NadekoBot.Credentials.SoundCloudClientId}").ConfigureAwait(false))["tracks"].ToObject(); - await QueueSong(((IGuildUser)imsg.Author), channel, ((IGuildUser)imsg.Author).VoiceChannel, scvids[0].TrackLink).ConfigureAwait(false); + await QueueSong(((IGuildUser)umsg.Author), channel, ((IGuildUser)umsg.Author).VoiceChannel, scvids[0].TrackLink).ConfigureAwait(false); MusicPlayer mp; if (!MusicPlayers.TryGetValue(channel.Guild.Id, out mp)) @@ -317,7 +317,7 @@ namespace NadekoBot.Modules.Music Uri = svideo.StreamLink, ProviderType = MusicType.Normal, Query = svideo.TrackLink, - }), ((IGuildUser)imsg.Author).Username); + }), ((IGuildUser)umsg.Author).Username); } catch (PlaylistFullException) { break; } } @@ -326,9 +326,9 @@ namespace NadekoBot.Modules.Music [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task LocalPl(IMessage imsg, [Remainder] string directory) + public async Task LocalPl(IUserMessage umsg, [Remainder] string directory) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; var arg = directory; if (string.IsNullOrWhiteSpace(arg)) return; @@ -340,7 +340,7 @@ namespace NadekoBot.Modules.Music { try { - await QueueSong(((IGuildUser)imsg.Author), channel, ((IGuildUser)imsg.Author).VoiceChannel, file.FullName, true, MusicType.Local).ConfigureAwait(false); + await QueueSong(((IGuildUser)umsg.Author), channel, ((IGuildUser)umsg.Author).VoiceChannel, file.FullName, true, MusicType.Local).ConfigureAwait(false); } catch (PlaylistFullException) { @@ -355,41 +355,41 @@ namespace NadekoBot.Modules.Music [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Radio(IMessage imsg, string radio_link) + public async Task Radio(IUserMessage umsg, string radio_link) { - var channel = (ITextChannel)imsg.Channel; - if (((IGuildUser)imsg.Author).VoiceChannel?.Guild != channel.Guild) + var channel = (ITextChannel)umsg.Channel; + if (((IGuildUser)umsg.Author).VoiceChannel?.Guild != channel.Guild) { await channel.SendMessageAsync("💢 You need to be in a voice channel on this server.\n If you are already in a voice channel, try rejoining it.").ConfigureAwait(false); return; } - await QueueSong(((IGuildUser)imsg.Author), channel, ((IGuildUser)imsg.Author).VoiceChannel, radio_link, musicType: MusicType.Radio).ConfigureAwait(false); + await QueueSong(((IGuildUser)umsg.Author), channel, ((IGuildUser)umsg.Author).VoiceChannel, radio_link, musicType: MusicType.Radio).ConfigureAwait(false); if (channel.Guild.GetCurrentUser().GetPermissions(channel).ManageMessages) { await Task.Delay(10000).ConfigureAwait(false); - await imsg.DeleteAsync().ConfigureAwait(false); + await ((IUserMessage)umsg).DeleteAsync().ConfigureAwait(false); } } [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Local(IMessage imsg, [Remainder] string path) + public async Task Local(IUserMessage umsg, [Remainder] string path) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; var arg = path; if (string.IsNullOrWhiteSpace(arg)) return; - await QueueSong(((IGuildUser)imsg.Author), channel, ((IGuildUser)imsg.Author).VoiceChannel, path, musicType: MusicType.Local).ConfigureAwait(false); + await QueueSong(((IGuildUser)umsg.Author), channel, ((IGuildUser)umsg.Author).VoiceChannel, path, musicType: MusicType.Local).ConfigureAwait(false); } [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Move(IMessage imsg) + public async Task Move(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; MusicPlayer musicPlayer; - var voiceChannel = ((IGuildUser)imsg.Author).VoiceChannel; + var voiceChannel = ((IGuildUser)umsg.Author).VoiceChannel; if (voiceChannel == null || voiceChannel.Guild != channel.Guild || !MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) return; musicPlayer.MoveToVoiceChannel(voiceChannel); @@ -397,16 +397,16 @@ namespace NadekoBot.Modules.Music [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Remove(IMessage imsg, int num) + public async Task Remove(IUserMessage umsg, int num) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; MusicPlayer musicPlayer; if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) { return; } - if (((IGuildUser)imsg.Author).VoiceChannel != musicPlayer.PlaybackVoiceChannel) + if (((IGuildUser)umsg.Author).VoiceChannel != musicPlayer.PlaybackVoiceChannel) return; if (num <= 0 || num > musicPlayer.Playlist.Count) return; @@ -417,9 +417,9 @@ namespace NadekoBot.Modules.Music //todo fix [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Remove(IMessage imsg, string all) + public async Task Remove(IUserMessage umsg, string all) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; if (all.Trim().ToUpperInvariant() != "ALL") return; @@ -432,9 +432,9 @@ namespace NadekoBot.Modules.Music [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task MoveSong(IMessage imsg, [Remainder] string fromto) + public async Task MoveSong(IUserMessage umsg, [Remainder] string fromto) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; MusicPlayer musicPlayer; if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) { @@ -468,9 +468,9 @@ namespace NadekoBot.Modules.Music [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task SetMaxQueue(IMessage imsg, uint size) + public async Task SetMaxQueue(IUserMessage umsg, uint size) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; MusicPlayer musicPlayer; if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) { @@ -482,9 +482,9 @@ namespace NadekoBot.Modules.Music [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task ReptCurSong(IMessage imsg) + public async Task ReptCurSong(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; MusicPlayer musicPlayer; if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) return; @@ -500,9 +500,9 @@ namespace NadekoBot.Modules.Music [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task RepeatPl(IMessage imsg) + public async Task RepeatPl(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; MusicPlayer musicPlayer; if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) return; @@ -513,46 +513,46 @@ namespace NadekoBot.Modules.Music /// //[LocalizedCommand, LocalizedDescription, LocalizedSummary] //[RequireContext(ContextType.Guild)] - //public async Task Save(IMessage imsg, [Remainder] string name) + //public async Task Save(IUserMessage umsg, [Remainder] string name) //{ - // var channel = (ITextChannel)imsg.Channel; + // var channel = (ITextChannel)umsg.Channel; //} //[LocalizedCommand, LocalizedDescription, LocalizedSummary] //[RequireContext(ContextType.Guild)] - //public async Task Load(IMessage imsg, [Remainder] string name) + //public async Task Load(IUserMessage umsg, [Remainder] string name) //{ - // var channel = (ITextChannel)imsg.Channel; + // var channel = (ITextChannel)umsg.Channel; //} //[LocalizedCommand, LocalizedDescription, LocalizedSummary] //[RequireContext(ContextType.Guild)] - //public async Task Playlists(IMessage imsg, [Remainder] string num) + //public async Task Playlists(IUserMessage umsg, [Remainder] string num) //{ - // var channel = (ITextChannel)imsg.Channel; + // var channel = (ITextChannel)umsg.Channel; //} //[LocalizedCommand, LocalizedDescription, LocalizedSummary] //[RequireContext(ContextType.Guild)] - //public async Task DeletePlaylist(IMessage imsg, [Remainder] string pl) + //public async Task DeletePlaylist(IUserMessage umsg, [Remainder] string pl) //{ - // var channel = (ITextChannel)imsg.Channel; + // var channel = (ITextChannel)umsg.Channel; //} [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Goto(IMessage imsg, int time) + public async Task Goto(IUserMessage umsg, int time) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; MusicPlayer musicPlayer; if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) return; - if (((IGuildUser)imsg.Author).VoiceChannel != musicPlayer.PlaybackVoiceChannel) + if (((IGuildUser)umsg.Author).VoiceChannel != musicPlayer.PlaybackVoiceChannel) return; if (time < 0) @@ -582,9 +582,9 @@ namespace NadekoBot.Modules.Music [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task GetLink(IMessage imsg, int index = 0) + public async Task GetLink(IUserMessage umsg, int index = 0) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; MusicPlayer musicPlayer; if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) return; @@ -617,9 +617,9 @@ namespace NadekoBot.Modules.Music [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Autoplay(IMessage imsg) + public async Task Autoplay(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; MusicPlayer musicPlayer; if (!MusicPlayers.TryGetValue(channel.Guild.Id, out musicPlayer)) return; @@ -644,12 +644,12 @@ namespace NadekoBot.Modules.Music var musicPlayer = MusicPlayers.GetOrAdd(textCh.Guild.Id, server => { //todo DB - float vol = 100;// SpecificConfigurations.Default.Of(server.Id).DefaultMusicVolume; + float vol = 1;// SpecificConfigurations.Default.Of(server.Id).DefaultMusicVolume; var mp = new MusicPlayer(voiceCh, vol); - IMessage playingMessage = null; - IMessage lastFinishedMessage = null; + IUserMessage playingMessage = null; + IUserMessage lastFinishedMessage = null; mp.OnCompleted += async (s, song) => { if (song.PrintStatusMessage) diff --git a/src/NadekoBot/Modules/NSFW/NSFW.cs b/src/NadekoBot/Modules/NSFW/NSFW.cs index 3fb08633..407f2116 100644 --- a/src/NadekoBot/Modules/NSFW/NSFW.cs +++ b/src/NadekoBot/Modules/NSFW/NSFW.cs @@ -18,15 +18,15 @@ namespace NadekoBot.Modules.NSFW [Module("~", AppendSpace = false)] public class NSFW : DiscordModule { - public NSFW(ILocalization loc, CommandService cmds, IBotConfiguration config, DiscordSocketClient client) : base(loc, cmds, config, client) + public NSFW(ILocalization loc, CommandService cmds, DiscordSocketClient client) : base(loc, cmds, client) { } [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Hentai(IMessage imsg, [Remainder] string tag = null) + public async Task Hentai(IUserMessage umsg, [Remainder] string tag = null) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; tag = tag?.Trim() ?? ""; @@ -43,9 +43,9 @@ namespace NadekoBot.Modules.NSFW [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Danbooru(IMessage imsg, [Remainder] string tag = null) + public async Task Danbooru(IUserMessage umsg, [Remainder] string tag = null) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; tag = tag?.Trim() ?? ""; var link = await GetDanbooruImageLink(tag).ConfigureAwait(false); @@ -57,9 +57,9 @@ namespace NadekoBot.Modules.NSFW [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Gelbooru(IMessage imsg, [Remainder] string tag = null) + public async Task Gelbooru(IUserMessage umsg, [Remainder] string tag = null) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; tag = tag?.Trim() ?? ""; var link = await GetRule34ImageLink(tag).ConfigureAwait(false); @@ -71,9 +71,9 @@ namespace NadekoBot.Modules.NSFW [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Rule34(IMessage imsg, [Remainder] string tag = null) + public async Task Rule34(IUserMessage umsg, [Remainder] string tag = null) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; tag = tag?.Trim() ?? ""; var link = await GetGelbooruImageLink(tag).ConfigureAwait(false); @@ -85,9 +85,9 @@ namespace NadekoBot.Modules.NSFW [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task E621(IMessage imsg, [Remainder] string tag = null) + public async Task E621(IUserMessage umsg, [Remainder] string tag = null) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; tag = tag?.Trim() ?? ""; var link = await GetE621ImageLink(tag).ConfigureAwait(false); @@ -99,18 +99,18 @@ namespace NadekoBot.Modules.NSFW [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Cp(IMessage imsg) + public async Task Cp(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; await channel.SendMessageAsync("http://i.imgur.com/MZkY1md.jpg").ConfigureAwait(false); } [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Boobs(IMessage imsg) + public async Task Boobs(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; try { JToken obj; @@ -128,9 +128,9 @@ namespace NadekoBot.Modules.NSFW [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Butts(IMessage imsg) + public async Task Butts(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; try { diff --git a/src/NadekoBot/Modules/Pokemon/Pokemon.cs b/src/NadekoBot/Modules/Pokemon/Pokemon.cs index fef39c40..6418fcdf 100644 --- a/src/NadekoBot/Modules/Pokemon/Pokemon.cs +++ b/src/NadekoBot/Modules/Pokemon/Pokemon.cs @@ -10,16 +10,16 @@ namespace NadekoBot.Modules.Games [Module(">", AppendSpace = false)] public partial class Pokemon : DiscordModule { - public Pokemon(ILocalization loc, CommandService cmds, IBotConfiguration config, DiscordSocketClient client) : base(loc, cmds, config, client) + public Pokemon(ILocalization loc, CommandService cmds, DiscordSocketClient client) : base(loc, cmds, client) { } //todo Dragon should PR this in [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Poke(IMessage imsg) + public async Task Poke(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; } diff --git a/src/NadekoBot/Modules/Searches/Commands/AnimeSearchCommands.cs b/src/NadekoBot/Modules/Searches/Commands/AnimeSearchCommands.cs index de6bf340..769c989d 100644 --- a/src/NadekoBot/Modules/Searches/Commands/AnimeSearchCommands.cs +++ b/src/NadekoBot/Modules/Searches/Commands/AnimeSearchCommands.cs @@ -13,11 +13,11 @@ // { // [LocalizedCommand, LocalizedDescription, LocalizedSummary] // [RequireContext(ContextType.Guild)] -// public async Task Anime(IMessage imsg, [Remainder] string query = null) +// public async Task Anime(IUserMessage umsg, [Remainder] string query = null) // { -// var channel = (ITextChannel)imsg.Channel; +// var channel = (ITextChannel)umsg.Channel; -// if (!(await ValidateQuery(imsg.Channel as ITextChannel, query).ConfigureAwait(false))) return; +// if (!(await ValidateQuery(umsg.Channel as ITextChannel, query).ConfigureAwait(false))) return; // string result; // try // { @@ -34,11 +34,11 @@ // [LocalizedCommand, LocalizedDescription, LocalizedSummary] // [RequireContext(ContextType.Guild)] -// public async Task Manga(IMessage imsg, [Remainder] string query = null) +// public async Task Manga(IUserMessage umsg, [Remainder] string query = null) // { -// var channel = (ITextChannel)imsg.Channel; +// var channel = (ITextChannel)umsg.Channel; -// if (!(await ValidateQuery(imsg.Channel as ITextChannel, query).ConfigureAwait(false))) return; +// if (!(await ValidateQuery(umsg.Channel as ITextChannel, query).ConfigureAwait(false))) return; // string result; // try // { diff --git a/src/NadekoBot/Modules/Searches/Commands/CalcCommand.cs b/src/NadekoBot/Modules/Searches/Commands/CalcCommand.cs index ad3b7401..dd2e7d35 100644 --- a/src/NadekoBot/Modules/Searches/Commands/CalcCommand.cs +++ b/src/NadekoBot/Modules/Searches/Commands/CalcCommand.cs @@ -16,7 +16,7 @@ namespace NadekoBot.Modules.Searches { [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public static async Task Calculate(IMessage msg, [Remainder] string expression) + public static async Task Calculate(IUserMessage msg, [Remainder] string expression) { try { @@ -43,7 +43,7 @@ namespace NadekoBot.Modules.Searches [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task CalcOps(IMessage msg) + public async Task CalcOps(IUserMessage msg) { StringBuilder builder = new StringBuilder(); var selection = typeof(Math).GetTypeInfo().GetMethods().Except(typeof(object).GetTypeInfo().GetMethods()).Select(x => diff --git a/src/NadekoBot/Modules/Searches/Commands/JokeCommands.cs b/src/NadekoBot/Modules/Searches/Commands/JokeCommands.cs index 450c126b..9f01b70f 100644 --- a/src/NadekoBot/Modules/Searches/Commands/JokeCommands.cs +++ b/src/NadekoBot/Modules/Searches/Commands/JokeCommands.cs @@ -44,9 +44,9 @@ namespace NadekoBot.Modules.Searches [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Yomama(IMessage imsg) + public async Task Yomama(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; using (var http = new HttpClient()) { var response = await http.GetStringAsync("http://api.yomomma.info/").ConfigureAwait(false); @@ -56,9 +56,9 @@ namespace NadekoBot.Modules.Searches [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Randjoke(IMessage imsg) + public async Task Randjoke(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; using (var http = new HttpClient()) { var response = await http.GetStringAsync("http://tambal.azurewebsites.net/joke/random").ConfigureAwait(false); @@ -68,9 +68,9 @@ namespace NadekoBot.Modules.Searches [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task ChuckNorris(IMessage imsg) + public async Task ChuckNorris(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; using (var http = new HttpClient()) { var response = await http.GetStringAsync("http://api.icndb.com/jokes/random/").ConfigureAwait(false); @@ -80,9 +80,9 @@ namespace NadekoBot.Modules.Searches [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task WowJoke(IMessage imsg) + public async Task WowJoke(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; if (!wowJokes.Any()) { @@ -92,9 +92,9 @@ namespace NadekoBot.Modules.Searches [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task MagicItem(IMessage imsg) + public async Task MagicItem(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; var rng = new Random(); var item = magicItems[rng.Next(0, magicItems.Count)].ToString(); diff --git a/src/NadekoBot/Modules/Searches/Commands/LoLCommands.cs b/src/NadekoBot/Modules/Searches/Commands/LoLCommands.cs index 81366edf..8e52985a 100644 --- a/src/NadekoBot/Modules/Searches/Commands/LoLCommands.cs +++ b/src/NadekoBot/Modules/Searches/Commands/LoLCommands.cs @@ -33,9 +33,9 @@ namespace NadekoBot.Modules.Searches [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Lolban(IMessage imsg) + public async Task Lolban(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; diff --git a/src/NadekoBot/Modules/Searches/Commands/MemegenCommands.cs b/src/NadekoBot/Modules/Searches/Commands/MemegenCommands.cs index b6ce9b79..16995259 100644 --- a/src/NadekoBot/Modules/Searches/Commands/MemegenCommands.cs +++ b/src/NadekoBot/Modules/Searches/Commands/MemegenCommands.cs @@ -17,9 +17,9 @@ namespace NadekoBot.Modules.Searches { [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Memelist(IMessage imsg) + public async Task Memelist(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; using (var http = new HttpClient()) { var data = JsonConvert.DeserializeObject>(await http.GetStringAsync("http://memegen.link/templates/")) @@ -31,9 +31,9 @@ namespace NadekoBot.Modules.Searches [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Memegen(IMessage imsg, string meme, string topText, string botText) + public async Task Memegen(IUserMessage umsg, string meme, string topText, string botText) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; var top = Uri.EscapeDataString(topText.Replace(' ', '-')); var bot = Uri.EscapeDataString(botText.Replace(' ', '-')); diff --git a/src/NadekoBot/Modules/Searches/Commands/OsuCommands.cs b/src/NadekoBot/Modules/Searches/Commands/OsuCommands.cs index 6988f59d..6fd23a29 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; @@ -28,9 +27,9 @@ namespace NadekoBot.Modules.Searches } [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Osu(IMessage imsg, string usr, string mode) + public async Task Osu(IUserMessage umsg, string usr, string mode) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; if (string.IsNullOrWhiteSpace(usr)) return; @@ -61,9 +60,9 @@ namespace NadekoBot.Modules.Searches [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Osub(IMessage imsg, [Remainder] string map) + public async Task Osub(IUserMessage umsg, [Remainder] string map) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.OsuApiKey)) { @@ -98,9 +97,9 @@ namespace NadekoBot.Modules.Searches [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Osu5(IMessage imsg, string user, [Remainder] string mode) + public async Task Osu5(IUserMessage umsg, string user, [Remainder] string mode) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; if (string.IsNullOrWhiteSpace(NadekoBot.Credentials.OsuApiKey)) { await channel.SendMessageAsync("💢 An osu! API key is required.").ConfigureAwait(false); diff --git a/src/NadekoBot/Modules/Searches/Commands/PokemonSearchCommands.cs b/src/NadekoBot/Modules/Searches/Commands/PokemonSearchCommands.cs index 9a5e0d3a..38e737d2 100644 --- a/src/NadekoBot/Modules/Searches/Commands/PokemonSearchCommands.cs +++ b/src/NadekoBot/Modules/Searches/Commands/PokemonSearchCommands.cs @@ -41,9 +41,9 @@ namespace NadekoBot.Modules.Searches [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Pokemon(IMessage imsg, [Remainder] string pokemon = null) + public async Task Pokemon(IUserMessage umsg, [Remainder] string pokemon = null) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; pokemon = pokemon?.Trim().ToUpperInvariant(); if (string.IsNullOrWhiteSpace(pokemon)) @@ -62,9 +62,9 @@ namespace NadekoBot.Modules.Searches [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task PokemonAbility(IMessage imsg, [Remainder] string ability = null) + public async Task PokemonAbility(IUserMessage umsg, [Remainder] string ability = null) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; ability = ability?.Trim().ToUpperInvariant().Replace(" ", ""); if (string.IsNullOrWhiteSpace(ability)) diff --git a/src/NadekoBot/Modules/Searches/Commands/StreamNotificationCommands.cs b/src/NadekoBot/Modules/Searches/Commands/StreamNotificationCommands.cs index 529d7fe3..92e14b69 100644 --- a/src/NadekoBot/Modules/Searches/Commands/StreamNotificationCommands.cs +++ b/src/NadekoBot/Modules/Searches/Commands/StreamNotificationCommands.cs @@ -258,7 +258,7 @@ // config.ObservingStreams.Remove(toRemove); // await ConfigHandler.SaveConfig().ConfigureAwait(false); -// await channel.SendMessageAsync($":ok: Removed `{toRemovimsg.Authorname}`'s stream from notifications.").ConfigureAwait(false); +// await channel.SendMessageAsync($":ok: Removed `{toRemovumsg.Authorname}`'s stream from notifications.").ConfigureAwait(false); // }); // cgb.CreateCommand(Module.Prefix + "liststreams") diff --git a/src/NadekoBot/Modules/Searches/Searches.cs b/src/NadekoBot/Modules/Searches/Searches.cs index b729efa7..99aeb95b 100644 --- a/src/NadekoBot/Modules/Searches/Searches.cs +++ b/src/NadekoBot/Modules/Searches/Searches.cs @@ -21,16 +21,16 @@ namespace NadekoBot.Modules.Searches { private IGoogleApiService _google { get; } - public Searches(ILocalization loc, CommandService cmds, IBotConfiguration config, DiscordSocketClient client, IGoogleApiService youtube) : base(loc, cmds, config, client) + public Searches(ILocalization loc, CommandService cmds, DiscordSocketClient client, IGoogleApiService youtube) : base(loc, cmds, client) { _google = youtube; } [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Weather(IMessage imsg, string city, string country) + public async Task Weather(IUserMessage umsg, string city, string country) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; city = city.Replace(" ", ""); country = city.Replace(" ", ""); string response; @@ -49,10 +49,10 @@ $@"🌍 **Weather for** 【{obj["target"]}】 [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Youtube(IMessage imsg, [Remainder] string query = null) + public async Task Youtube(IUserMessage umsg, [Remainder] string query = null) { - var channel = (ITextChannel)imsg.Channel; - if (!(await ValidateQuery(imsg.Channel as ITextChannel, query).ConfigureAwait(false))) return; + var channel = (ITextChannel)umsg.Channel; + if (!(await ValidateQuery(umsg.Channel as ITextChannel, query).ConfigureAwait(false))) return; var result = (await _google.GetVideosByKeywordsAsync(query, 1)).FirstOrDefault(); if (string.IsNullOrWhiteSpace(result)) { @@ -64,12 +64,12 @@ $@"🌍 **Weather for** 【{obj["target"]}】 [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Imdb(IMessage imsg, [Remainder] string query = null) + public async Task Imdb(IUserMessage umsg, [Remainder] string query = null) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; - if (!(await ValidateQuery(imsg.Channel as ITextChannel, query).ConfigureAwait(false))) return; - await imsg.Channel.TriggerTypingAsync().ConfigureAwait(false); + if (!(await ValidateQuery(umsg.Channel as ITextChannel, query).ConfigureAwait(false))) return; + await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false); string result; try { @@ -88,9 +88,9 @@ $@"🌍 **Weather for** 【{obj["target"]}】 [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task RandomCat(IMessage imsg) + public async Task RandomCat(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; using (var http = new HttpClient()) { await channel.SendMessageAsync(JObject.Parse( @@ -101,9 +101,9 @@ $@"🌍 **Weather for** 【{obj["target"]}】 [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task RandomDog(IMessage imsg) + public async Task RandomDog(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; using (var http = new HttpClient()) { await channel.SendMessageAsync("http://random.dog/" + await http.GetStringAsync("http://random.dog/woof").ConfigureAwait(false)).ConfigureAwait(false); @@ -112,9 +112,9 @@ $@"🌍 **Weather for** 【{obj["target"]}】 [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task I(IMessage imsg, [Remainder] string query = null) + public async Task I(IUserMessage umsg, [Remainder] string query = null) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; if (string.IsNullOrWhiteSpace(query)) return; @@ -142,9 +142,9 @@ $@"🌍 **Weather for** 【{obj["target"]}】 [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Ir(IMessage imsg, [Remainder] string query = null) + public async Task Ir(IUserMessage umsg, [Remainder] string query = null) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; if (string.IsNullOrWhiteSpace(query)) return; @@ -174,9 +174,9 @@ $@"🌍 **Weather for** 【{obj["target"]}】 [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Lmgtfy(IMessage imsg, [Remainder] string ffs = null) + public async Task Lmgtfy(IUserMessage umsg, [Remainder] string ffs = null) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; if (string.IsNullOrWhiteSpace(ffs)) @@ -188,9 +188,9 @@ $@"🌍 **Weather for** 【{obj["target"]}】 [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Google(IMessage imsg, [Remainder] string terms = null) + public async Task Google(IUserMessage umsg, [Remainder] string terms = null) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; terms = terms?.Trim(); @@ -202,16 +202,16 @@ $@"🌍 **Weather for** 【{obj["target"]}】 ////todo drawing //[LocalizedCommand, LocalizedDescription, LocalizedSummary] //[RequireContext(ContextType.Guild)] - //public async Task Hearthstone(IMessage imsg, [Remainder] string name = null) + //public async Task Hearthstone(IUserMessage umsg, [Remainder] string name = null) //{ - // var channel = (ITextChannel)imsg.Channel; + // var channel = (ITextChannel)umsg.Channel; // var arg = name; // if (string.IsNullOrWhiteSpace(arg)) // { // await channel.SendMessageAsync("💢 Please enter a card name to search for.").ConfigureAwait(false); // return; // } - // await imsg.Channel.TriggerTypingAsync().ConfigureAwait(false); + // await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false); // string response = ""; // using (var http = new HttpClient()) // { @@ -247,9 +247,9 @@ $@"🌍 **Weather for** 【{obj["target"]}】 [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Ud(IMessage imsg, [Remainder] string query = null) + public async Task Ud(IUserMessage umsg, [Remainder] string query = null) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; var arg = query; if (string.IsNullOrWhiteSpace(arg)) @@ -257,7 +257,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】 await channel.SendMessageAsync("💢 Please enter a search term.").ConfigureAwait(false); return; } - await imsg.Channel.TriggerTypingAsync().ConfigureAwait(false); + await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false); using (var http = new HttpClient()) { http.DefaultRequestHeaders.Clear(); @@ -281,9 +281,9 @@ $@"🌍 **Weather for** 【{obj["target"]}】 [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Hashtag(IMessage imsg, [Remainder] string query = null) + public async Task Hashtag(IUserMessage umsg, [Remainder] string query = null) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; var arg = query; if (string.IsNullOrWhiteSpace(arg)) @@ -291,7 +291,7 @@ $@"🌍 **Weather for** 【{obj["target"]}】 await channel.SendMessageAsync("💢 Please enter a search term.").ConfigureAwait(false); return; } - await imsg.Channel.TriggerTypingAsync().ConfigureAwait(false); + await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false); string res = ""; using (var http = new HttpClient()) { @@ -316,9 +316,9 @@ $@"🌍 **Weather for** 【{obj["target"]}】 [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Catfact(IMessage imsg) + public async Task Catfact(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; using (var http = new HttpClient()) { var response = await http.GetStringAsync("http://catfacts-api.appspot.com/api/facts").ConfigureAwait(false); @@ -330,9 +330,9 @@ $@"🌍 **Weather for** 【{obj["target"]}】 [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Revav(IMessage imsg, [Remainder] string arg = null) + public async Task Revav(IUserMessage umsg, [Remainder] string arg = null) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; var usrStr = arg?.Trim().ToUpperInvariant(); if (string.IsNullOrWhiteSpace(usrStr)) @@ -347,9 +347,9 @@ $@"🌍 **Weather for** 【{obj["target"]}】 [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Revimg(IMessage imsg, [Remainder] string imageLink = null) + public async Task Revimg(IUserMessage umsg, [Remainder] string imageLink = null) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; imageLink = imageLink?.Trim() ?? ""; if (string.IsNullOrWhiteSpace(imageLink)) @@ -359,9 +359,9 @@ $@"🌍 **Weather for** 【{obj["target"]}】 [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Safebooru(IMessage imsg, [Remainder] string tag = null) + public async Task Safebooru(IUserMessage umsg, [Remainder] string tag = null) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; tag = tag?.Trim() ?? ""; var link = await GetSafebooruImageLink(tag).ConfigureAwait(false); @@ -373,9 +373,9 @@ $@"🌍 **Weather for** 【{obj["target"]}】 [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Wiki(IMessage imsg, [Remainder] string query = null) + public async Task Wiki(IUserMessage umsg, [Remainder] string query = null) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; query = query?.Trim(); if (string.IsNullOrWhiteSpace(query)) @@ -394,9 +394,9 @@ $@"🌍 **Weather for** 【{obj["target"]}】 ////todo drawing //[LocalizedCommand, LocalizedDescription, LocalizedSummary] //[RequireContext(ContextType.Guild)] - //public async Task Clr(IMessage imsg, [Remainder] string color = null) + //public async Task Clr(IUserMessage umsg, [Remainder] string color = null) //{ - // var channel = (ITextChannel)imsg.Channel; + // var channel = (ITextChannel)umsg.Channel; // color = color?.Trim().Replace("#", ""); // if (string.IsNullOrWhiteSpace((string)color)) @@ -419,13 +419,13 @@ $@"🌍 **Weather for** 【{obj["target"]}】 [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Videocall(IMessage imsg, [Remainder] string arg = null) + public async Task Videocall(IUserMessage umsg, [Remainder] string arg = null) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; try { - var allUsrs = imsg.MentionedUsers.Append(imsg.Author); + var allUsrs = umsg.MentionedUsers.Append(umsg.Author); var allUsrsArray = allUsrs.ToArray(); var str = allUsrsArray.Aggregate("http://appear.in/", (current, usr) => current + Uri.EscapeUriString(usr.Username[0].ToString())); str += new Random().Next(); @@ -442,11 +442,11 @@ $@"🌍 **Weather for** 【{obj["target"]}】 [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Avatar(IMessage imsg, [Remainder] string mention = null) + public async Task Avatar(IUserMessage umsg, [Remainder] string mention = null) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; - var usr = imsg.MentionedUsers.FirstOrDefault(); + var usr = umsg.MentionedUsers.FirstOrDefault(); if (usr == null) { await channel.SendMessageAsync("Invalid user specified.").ConfigureAwait(false); diff --git a/src/NadekoBot/Modules/Translator/Translator.cs b/src/NadekoBot/Modules/Translator/Translator.cs index 2003f5d4..425d9b0c 100644 --- a/src/NadekoBot/Modules/Translator/Translator.cs +++ b/src/NadekoBot/Modules/Translator/Translator.cs @@ -12,15 +12,15 @@ namespace NadekoBot.Modules.Translator [Module("~", AppendSpace = false)] public class Translator : DiscordModule { - public Translator(ILocalization loc, CommandService cmds, IBotConfiguration config, DiscordSocketClient client) : base(loc, cmds, config, client) + public Translator(ILocalization loc, CommandService cmds, DiscordSocketClient client) : base(loc, cmds, client) { } [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Translate(IMessage imsg, string langs, [Remainder] string text = null) + public async Task Translate(IUserMessage umsg, string langs, [Remainder] string text = null) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; try { @@ -33,7 +33,7 @@ namespace NadekoBot.Modules.Translator if (string.IsNullOrWhiteSpace(text)) return; - await imsg.Channel.TriggerTypingAsync().ConfigureAwait(false); + await umsg.Channel.TriggerTypingAsync().ConfigureAwait(false); string translation = await GoogleTranslator.Instance.Translate(text, from, to).ConfigureAwait(false); await channel.SendMessageAsync(translation).ConfigureAwait(false); } @@ -46,9 +46,9 @@ namespace NadekoBot.Modules.Translator [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Translangs(IMessage imsg) + public async Task Translangs(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; await channel.SendTableAsync(GoogleTranslator.Instance.Languages, str => $"{str,-15}", columns: 3); } diff --git a/src/NadekoBot/Modules/Trello/Trello.cs b/src/NadekoBot/Modules/Trello/Trello.cs index 820b0379..18e1a4d5 100644 --- a/src/NadekoBot/Modules/Trello/Trello.cs +++ b/src/NadekoBot/Modules/Trello/Trello.cs @@ -75,7 +75,7 @@ // .Parameter("board_id", Discord.Commands.ParameterType.Required) // .Do(async e => // { -// if (!NadekoBot.IsOwner(imsg.Author.Id)) return; +// if (!NadekoBot.IsOwner(umsg.Author.Id)) return; // if (bound != null) return; // try // { @@ -95,7 +95,7 @@ // .Description($"Unbinds a bot from the channel and board. **Bot Owner Only!**| `{Prefix}unbind`") // .Do(async e => // { -// if (!NadekoBot.IsOwner(imsg.Author.Id)) return; +// if (!NadekoBot.IsOwner(umsg.Author.Id)) return; // if (bound == null || bound != e.Channel) return; // t.Stop(); // bound = null; @@ -109,7 +109,7 @@ // .Description($"Lists all lists, yo ;) **Bot Owner Only!**| `{Prefix}list`") // .Do(async e => // { -// if (!NadekoBot.IsOwner(imsg.Author.Id)) return; +// if (!NadekoBot.IsOwner(umsg.Author.Id)) return; // if (bound == null || board == null || bound != e.Channel) return; // await channel.SendMessageAsync("Lists for a board '" + board.Name + "'\n" + string.Join("\n", board.Lists.Select(l => "**• " + l.ToString() + "**"))) // .ConfigureAwait(false); @@ -120,7 +120,7 @@ // .Parameter("list_name", Discord.Commands.ParameterType.Unparsed) // .Do(async e => // { -// if (!NadekoBot.IsOwner(imsg.Author.Id)) return; +// if (!NadekoBot.IsOwner(umsg.Author.Id)) return; // if (bound == null || board == null || bound != e.Channel || list_name == null) return; // int num; diff --git a/src/NadekoBot/Modules/Utility/Commands/InfoCommands.cs b/src/NadekoBot/Modules/Utility/Commands/InfoCommands.cs index 4e8be7f8..7102addf 100644 --- a/src/NadekoBot/Modules/Utility/Commands/InfoCommands.cs +++ b/src/NadekoBot/Modules/Utility/Commands/InfoCommands.cs @@ -13,7 +13,7 @@ namespace NadekoBot.Modules.Utility { [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task ServerInfo(IMessage msg, string guild = null) + public async Task ServerInfo(IUserMessage msg, string guild = null) { var channel = msg.Channel as ITextChannel; guild = guild?.ToUpperInvariant(); @@ -48,7 +48,7 @@ namespace NadekoBot.Modules.Utility [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task ChannelInfo(IMessage msg, ITextChannel channel = null) + public async Task ChannelInfo(IUserMessage msg, ITextChannel channel = null) { var ch = channel ?? msg.Channel as ITextChannel; if (ch == null) @@ -64,7 +64,7 @@ namespace NadekoBot.Modules.Utility [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task UserInfo(IMessage msg, IGuildUser usr = null) + public async Task UserInfo(IUserMessage msg, IGuildUser usr = null) { var channel = msg.Channel as ITextChannel; var user = usr ?? msg.Author as IGuildUser; diff --git a/src/NadekoBot/Modules/Utility/Commands/QuoteCommands.cs b/src/NadekoBot/Modules/Utility/Commands/QuoteCommands.cs index 34a181c8..d1206ee6 100644 --- a/src/NadekoBot/Modules/Utility/Commands/QuoteCommands.cs +++ b/src/NadekoBot/Modules/Utility/Commands/QuoteCommands.cs @@ -16,9 +16,9 @@ namespace NadekoBot.Modules.Utility { [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task ShowQuote(IMessage imsg, string keyword) + public async Task ShowQuote(IUserMessage umsg, string keyword) { - var channel = imsg.Channel as ITextChannel; + var channel = umsg.Channel as ITextChannel; if (string.IsNullOrWhiteSpace(keyword)) return; @@ -28,7 +28,7 @@ namespace NadekoBot.Modules.Utility Quote quote; using (var uow = DbHandler.Instance.GetUnitOfWork()) { - quote = await uow.Quotes.GetRandomQuoteByKeywordAsync(channel.Guild.Id, keyword); + quote = await uow.Quotes.GetRandomQuoteByKeywordAsync(channel.Guild.Id, keyword).ConfigureAwait(false); } if (quote == null) @@ -39,9 +39,9 @@ namespace NadekoBot.Modules.Utility [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task AddQuote(IMessage imsg, string keyword, [Remainder] string text) + public async Task AddQuote(IUserMessage umsg, string keyword, [Remainder] string text) { - var channel = imsg.Channel as ITextChannel; + var channel = umsg.Channel as ITextChannel; if (string.IsNullOrWhiteSpace(keyword) || string.IsNullOrWhiteSpace(text)) return; @@ -52,22 +52,22 @@ namespace NadekoBot.Modules.Utility { uow.Quotes.Add(new Quote { - AuthorId = imsg.Author.Id, - AuthorName = imsg.Author.Username, + AuthorId = umsg.Author.Id, + AuthorName = umsg.Author.Username, GuildId = channel.Guild.Id, Keyword = keyword, Text = text, }); - await uow.CompleteAsync(); - await channel.SendMessageAsync("`Quote added.`"); + await uow.CompleteAsync().ConfigureAwait(false); + await channel.SendMessageAsync("`Quote added.`").ConfigureAwait(false); } } [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task DeleteQuote(IMessage imsg, string keyword) + public async Task DeleteQuote(IUserMessage umsg, string keyword) { - var channel = imsg.Channel as ITextChannel; + var channel = umsg.Channel as ITextChannel; if (string.IsNullOrWhiteSpace(keyword)) return; @@ -92,9 +92,9 @@ namespace NadekoBot.Modules.Utility [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task DelAllQuotes(IMessage imsg, string keyword) + public async Task DelAllQuotes(IUserMessage umsg, string keyword) { - var channel = imsg.Channel as ITextChannel; + var channel = umsg.Channel as ITextChannel; if (string.IsNullOrWhiteSpace(keyword)) return; diff --git a/src/NadekoBot/Modules/Utility/Commands/Remind.cs b/src/NadekoBot/Modules/Utility/Commands/Remind.cs index f6c67748..d115e921 100644 --- a/src/NadekoBot/Modules/Utility/Commands/Remind.cs +++ b/src/NadekoBot/Modules/Utility/Commands/Remind.cs @@ -1,197 +1,209 @@ -//using Discord; -//using Discord.Commands; -//using NadekoBot.Classes; -//using NadekoBot.DataModels; -//using NadekoBot.Modules.Permissions.Classes; -//using System; -//using System.Collections.Generic; -//using System.Linq; -//using System.Text.RegularExpressions; -//using System.Timers; +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.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; -//namespace NadekoBot.Modules.Utility -//{ -// class Remind : DiscordCommand -// { +namespace NadekoBot.Modules.Utility +{ + public partial class Utility + { + [Group] + public class RemindCommands + { -// Regex regex = new Regex(@"^(?:(?\d)mo)?(?:(?\d)w)?(?:(?\d{1,2})d)?(?:(?\d{1,2})h)?(?:(?\d{1,2})m)?$", -// RegexOptions.Compiled | RegexOptions.Multiline); + Regex regex = new Regex(@"^(?:(?\d)mo)?(?:(?\d)w)?(?:(?\d{1,2})d)?(?:(?\d{1,2})h)?(?:(?\d{1,2})m)?$", + RegexOptions.Compiled | RegexOptions.Multiline); -// List reminders = new List(); + private string RemindMessageFormat { get; } -// IDictionary> replacements = new Dictionary> -// { -// { "%message%" , (r) => r.Message }, -// { "%user%", (r) => $"<@!{r.UserId}>" }, -// { "%target%", (r) => r.IsPrivate ? "Direct Message" : $"<#{r.ChannelId}>"} -// }; + IDictionary> replacements = new Dictionary> + { + { "%message%" , (r) => r.Message }, + { "%user%", (r) => $"<@!{r.UserId}>" }, + { "%target%", (r) => r.IsPrivate ? "Direct Message" : $"<#{r.ChannelId}>"} + }; -// public Remind(DiscordModule module) : base(module) -// { -// var remList = DbHandler.Instance.GetAllRows(); + public RemindCommands() + { + List reminders; + using (var uow = DbHandler.UnitOfWork()) + { + reminders = uow.Reminders.GetAll().ToList(); -// reminders = remList.Select(StartNewReminder).ToList(); -// } + RemindMessageFormat = uow.BotConfig.GetOrCreate().RemindMessageFormat; + } -// private Timer StartNewReminder(Reminder r) -// { -// var now = DateTime.Now; -// var twoMins = new TimeSpan(0, 2, 0); -// TimeSpan time = (r.When - now) < twoMins -// ? twoMins //if the time is less than 2 minutes, -// : r.When - now; //it will send the message 2 minutes after start -// //To account for high bot startup times -// if (time.TotalMilliseconds > int.MaxValue) -// return null; -// var t = new Timer(time.TotalMilliseconds); -// t.Elapsed += async (s, e) => -// { -// try -// { -// Channel ch; -// if (r.IsPrivate) -// { -// ch = NadekoBot.Client.PrivateChannels.FirstOrDefault(c => (long)c.Id == r.ChannelId); -// if (ch == null) -// ch = await NadekoBot.Client.CreatePrivateChannel((ulong)r.ChannelId).ConfigureAwait(false); -// } -// else -// ch = NadekoBot.Client.GetServer((ulong)r.ServerId)?.GetChannel((ulong)r.ChannelId); + foreach (var r in reminders) + { + var t = StartReminder(r); + } + } -// if (ch == null) -// return; + private async Task StartReminder(Reminder r) + { + var now = DateTime.Now; + var twoMins = new TimeSpan(0, 2, 0); + TimeSpan time = r.When - now; -// await ch.SendMessageAsync( -// replacements.Aggregate(NadekoBot.Config.RemindMessageFormat, -// (cur, replace) => cur.Replace(replace.Key, replace.Value(r))) -// ).ConfigureAwait(false); //it works trust me + if (time.TotalMilliseconds > int.MaxValue) + return; -// } -// catch (Exception ex) -// { -// Console.WriteLine($"Timer error! {ex}"); -// } -// finally -// { -// DbHandler.Instance.Delete(r.Id.Value); -// t.Stop(); -// t.Dispose(); -// } -// }; -// t.Start(); -// return t; -// } + await Task.Delay(time); + try + { + IMessageChannel ch; + if (r.IsPrivate) + { + ch = await NadekoBot.Client.GetDMChannelAsync(r.ChannelId).ConfigureAwait(false); + } + else + { + ch = NadekoBot.Client.GetGuilds() + .Where(g => g.Id == r.ServerId) + .FirstOrDefault() + .GetTextChannels() + .Where(c => c.Id == r.ChannelId) + .FirstOrDefault(); + } + if (ch == null) + return; -// internal override void Init(CommandGroupBuilder cgb) -// { -// cgb.CreateCommand(Module.Prefix + "remind") -// .Description("Sends a message to you or a channel after certain amount of time. " + -// "First argument is me/here/'channelname'. Second argument is time in a descending order (mo>w>d>h>m) example: 1w5d3h10m. " + -// "Third argument is a (multiword)message. " + -// $" | `{Prefix}remind me 1d5h Do something` or `{Prefix}remind #general Start now!`") -// .Parameter("meorchannel", ParameterType.Required) -// .Parameter("time", ParameterType.Required) -// .Parameter("message", ParameterType.Unparsed) -// .Do(async e => -// { -// var meorchStr = meorchannel.ToUpperInvariant(); -// Channel ch; -// bool isPrivate = false; -// if (meorchStr == "ME") -// { -// isPrivate = true; -// ch = await imsg.Author.CreatePMChannel().ConfigureAwait(false); -// } -// else if (meorchStr == "HERE") -// { -// ch = e.Channel; -// } -// else -// { -// ch = e.Server.FindChannels(meorchStr).FirstOrDefault(); -// } + await ch.SendMessageAsync( + replacements.Aggregate(RemindMessageFormat, + (cur, replace) => cur.Replace(replace.Key, replace.Value(r))) + ).ConfigureAwait(false); //it works trust me -// if (ch == null) -// { -// await channel.SendMessageAsync($"{imsg.Author.Mention} Something went wrong (channel cannot be found) ;(").ConfigureAwait(false); -// return; -// } + } + catch (Exception ex) + { + Console.WriteLine($"Timer error! {ex}"); + } + finally + { + using (var uow = DbHandler.UnitOfWork()) + { + uow.Reminders.Remove(r); + await uow.CompleteAsync(); + } + } + } -// var timeStr = time; + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + public async Task Remind(IUserMessage umsg, string meorchannel, string timeStr, [Remainder] string message) + { + var channel = (ITextChannel)umsg.Channel; -// var m = regex.Match(timeStr); + var meorchStr = meorchannel.ToUpperInvariant(); + IMessageChannel ch; + bool isPrivate = false; + if (meorchStr == "ME") + { + isPrivate = true; + ch = await ((IGuildUser)umsg.Author).CreateDMChannelAsync().ConfigureAwait(false); + } + else if (meorchStr == "HERE") + { + ch = channel; + } + else + { + ch = channel.Guild.GetTextChannels().FirstOrDefault(c => c.Name == meorchStr || c.Id.ToString() == meorchStr); + } -// if (m.Length == 0) -// { -// await channel.SendMessageAsync("Not a valid time format blablabla").ConfigureAwait(false); -// return; -// } + if (ch == null) + { + await channel.SendMessageAsync($"{umsg.Author.Mention} Something went wrong (channel cannot be found) ;(").ConfigureAwait(false); + return; + } -// string output = ""; -// var namesAndValues = new Dictionary(); + var m = regex.Match(timeStr); -// foreach (var groupName in regex.GetGroupNames()) -// { -// if (groupName == "0") continue; -// int value = 0; -// int.TryParse(m.Groups[groupName].Value, out value); + if (m.Length == 0) + { + await channel.SendMessageAsync("Not a valid time format blablabla").ConfigureAwait(false); + return; + } -// if (string.IsNullOrEmpty(m.Groups[groupName].Value)) -// { -// namesAndValues[groupName] = 0; -// continue; -// } -// else if (value < 1 || -// (groupName == "months" && value > 1) || -// (groupName == "weeks" && value > 4) || -// (groupName == "days" && value >= 7) || -// (groupName == "hours" && value > 23) || -// (groupName == "minutes" && value > 59)) -// { -// await channel.SendMessageAsync($"Invalid {groupName} value.").ConfigureAwait(false); -// return; -// } -// else -// namesAndValues[groupName] = value; -// output += m.Groups[groupName].Value + " " + groupName + " "; -// } -// var time = DateTime.Now + new TimeSpan(30 * namesAndValues["months"] + -// 7 * namesAndValues["weeks"] + -// namesAndValues["days"], -// namesAndValues["hours"], -// namesAndValues["minutes"], -// 0); + string output = ""; + var namesAndValues = new Dictionary(); -// var rem = new Reminder -// { -// ChannelId = (long)ch.Id, -// IsPrivate = isPrivate, -// When = time, -// Message = message, -// UserId = (long)imsg.Author.Id, -// ServerId = (long)e.Server.Id -// }; -// DbHandler.Instance.Connection.Insert(rem); + foreach (var groupName in regex.GetGroupNames()) + { + if (groupName == "0") continue; + int value = 0; + int.TryParse(m.Groups[groupName].Value, out value); -// reminders.Add(StartNewReminder(rem)); + if (string.IsNullOrEmpty(m.Groups[groupName].Value)) + { + namesAndValues[groupName] = 0; + continue; + } + else if (value < 1 || + (groupName == "months" && value > 1) || + (groupName == "weeks" && value > 4) || + (groupName == "days" && value >= 7) || + (groupName == "hours" && value > 23) || + (groupName == "minutes" && value > 59)) + { + await channel.SendMessageAsync($"Invalid {groupName} value.").ConfigureAwait(false); + return; + } + else + namesAndValues[groupName] = value; + output += m.Groups[groupName].Value + " " + groupName + " "; + } + var time = DateTime.Now + new TimeSpan(30 * namesAndValues["months"] + + 7 * namesAndValues["weeks"] + + namesAndValues["days"], + namesAndValues["hours"], + namesAndValues["minutes"], + 0); -// await channel.SendMessageAsync($"⏰ I will remind \"{ch.Name}\" to \"{message.ToString()}\" in {output}. ({time:d.M.yyyy.} at {time:HH:mm})").ConfigureAwait(false); -// }); -// cgb.CreateCommand(Module.Prefix + "remindmsg") -// .Description("Sets message for when the remind is triggered. " + -// " Available placeholders are %user% - user who ran the command, %message% -" + -// $" Message specified in the remind, %target% - target channel of the remind. **Bot Owner Only!** | `{Prefix}remindmsg do something else`") -// .Parameter("msg", ParameterType.Unparsed) -// .AddCheck(SimpleCheckers.OwnerOnly()) -// .Do(async e => -// { -// var arg = msg?.Trim(); -// if (string.IsNullOrWhiteSpace(arg)) -// return; + var rem = new Reminder + { + ChannelId = ch.Id, + IsPrivate = isPrivate, + When = time, + Message = message, + UserId = umsg.Author.Id, + ServerId = channel.Guild.Id + }; -// NadekoBot.Config.RemindMessageFormat = arg; -// await channel.SendMessageAsync("`New remind message set.`"); -// }); -// } -// } -//} + using (var uow = DbHandler.UnitOfWork()) + { + uow.Reminders.Add(rem); + await uow.CompleteAsync(); + } + + await channel.SendMessageAsync($"⏰ I will remind \"{(ch is ITextChannel ? ((ITextChannel)ch).Name : umsg.Author.Username)}\" to \"{message.ToString()}\" in {output}. ({time:d.M.yyyy.} at {time:HH:mm})").ConfigureAwait(false); + await StartReminder(rem); + } + + ////todo owner only + //[LocalizedCommand, LocalizedDescription, LocalizedSummary] + //[RequireContext(ContextType.Guild)] + //public async Task RemindTemplate(IUserMessage umsg, [Remainder] string arg) + //{ + // var channel = (ITextChannel)umsg.Channel; + + + // arg = arg?.Trim(); + // if (string.IsNullOrWhiteSpace(arg)) + // return; + + // NadekoBot.Config.RemindMessageFormat = arg; + // await channel.SendMessageAsync("`New remind message set.`"); + //} + } + } +} \ No newline at end of file diff --git a/src/NadekoBot/Modules/Utility/Utility.cs b/src/NadekoBot/Modules/Utility/Utility.cs index 12ff226e..07499f5a 100644 --- a/src/NadekoBot/Modules/Utility/Utility.cs +++ b/src/NadekoBot/Modules/Utility/Utility.cs @@ -18,20 +18,20 @@ namespace NadekoBot.Modules.Utility [Module(".", AppendSpace = false)] public partial class Utility : DiscordModule { - public Utility(ILocalization loc, CommandService cmds, IBotConfiguration config, DiscordSocketClient client) : base(loc, cmds, config, client) + public Utility(ILocalization loc, CommandService cmds, DiscordSocketClient client) : base(loc, cmds, client) { } [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task WhosPlaying(IMessage imsg, [Remainder] string game = null) + public async Task WhosPlaying(IUserMessage umsg, [Remainder] string game = null) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; game = game.Trim().ToUpperInvariant(); if (string.IsNullOrWhiteSpace(game)) return; - var arr = (await (imsg.Channel as IGuildChannel).Guild.GetUsersAsync()) + var arr = (await (umsg.Channel as IGuildChannel).Guild.GetUsersAsync()) .Where(u => u.Game?.Name?.ToUpperInvariant() == game) .Select(u => u.Username) .ToList(); @@ -45,11 +45,11 @@ namespace NadekoBot.Modules.Utility [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task InRole(IMessage imsg, [Remainder] string roles = null) + public async Task InRole(IUserMessage umsg, [Remainder] string roles = null) { if (string.IsNullOrWhiteSpace(roles)) return; - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; var arg = roles.Split(',').Select(r => r.Trim().ToUpperInvariant()); string send = _l["`Here is a list of users in a specfic role:`"]; foreach (var roleStr in arg.Where(str => !string.IsNullOrWhiteSpace(str) && str != "@EVERYONE" && str != "EVERYONE")) @@ -57,14 +57,14 @@ namespace NadekoBot.Modules.Utility var role = channel.Guild.Roles.Where(r => r.Name.ToUpperInvariant() == roleStr).FirstOrDefault(); if (role == null) continue; send += $"\n`{role.Name}`\n"; - send += string.Join(", ", (await channel.Guild.GetUsersAsync()).Where(u => u.Roles.Contains(role)).Select(u => u.ToString())); + send += string.Join(", ", channel.Guild.GetUsers().Where(u => u.Roles.Contains(role)).Select(u => u.ToString())); } - var usr = imsg.Author as IGuildUser; + var usr = umsg.Author as IGuildUser; while (send.Length > 2000) { if (!usr.GetPermissions(channel).ManageMessages) { - await channel.SendMessageAsync($"{usr.Mention} you are not allowed to use this command on roles with a lot of users in them to prevent abuse."); + await channel.SendMessageAsync($"{usr.Mention} you are not allowed to use this command on roles with a lot of users in them to prevent abuse.").ConfigureAwait(false); return; } var curstr = send.Substring(0, 2000); @@ -78,7 +78,7 @@ namespace NadekoBot.Modules.Utility [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task CheckMyPerms(IMessage msg) + public async Task CheckMyPerms(IUserMessage msg) { StringBuilder builder = new StringBuilder("```\n"); @@ -95,28 +95,28 @@ namespace NadekoBot.Modules.Utility [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task UserId(IMessage msg, IGuildUser target = null) + public async Task UserId(IUserMessage msg, IGuildUser target = null) { var usr = target ?? msg.Author; - await msg.Reply($"Id of the user { usr.Username } is { usr.Id })"); + await msg.Reply($"Id of the user { usr.Username } is { usr.Id })").ConfigureAwait(false); } [LocalizedCommand, LocalizedDescription, LocalizedSummary] - public async Task ChannelId(IMessage msg) + public async Task ChannelId(IUserMessage msg) { - await msg.Reply($"This Channel's ID is {msg.Channel.Id}"); + await msg.Reply($"This Channel's ID is {msg.Channel.Id}").ConfigureAwait(false); } [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task ServerId(IMessage msg) + public async Task ServerId(IUserMessage msg) { - await msg.Reply($"This server's ID is {(msg.Channel as ITextChannel).Guild.Id}"); + await msg.Reply($"This server's ID is {(msg.Channel as ITextChannel).Guild.Id}").ConfigureAwait(false); } [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Roles(IMessage msg, IGuildUser target = null) + public async Task Roles(IUserMessage msg, IGuildUser target = null) { var guild = (msg.Channel as ITextChannel).Guild; if (target != null) @@ -131,9 +131,22 @@ namespace NadekoBot.Modules.Utility [LocalizedCommand, LocalizedDescription, LocalizedSummary] [RequireContext(ContextType.Guild)] - public async Task Stats(IMessage imsg) + public async Task ChannelTopic(IUserMessage umsg) { - var channel = (ITextChannel)imsg.Channel; + var channel = (ITextChannel)umsg.Channel; + + var topic = channel.Topic; + if (string.IsNullOrWhiteSpace(topic)) + await channel.SendMessageAsync("`No topic set.`"); + else + await channel.SendMessageAsync("`Topic:` " + topic); + } + + [LocalizedCommand, LocalizedDescription, LocalizedSummary] + [RequireContext(ContextType.Guild)] + public async Task Stats(IUserMessage umsg) + { + var channel = (ITextChannel)umsg.Channel; await channel.SendMessageAsync(await NadekoBot.Stats.Print()); } diff --git a/src/NadekoBot/NadekoBot.cs b/src/NadekoBot/NadekoBot.cs index 23df420e..89e37170 100644 --- a/src/NadekoBot/NadekoBot.cs +++ b/src/NadekoBot/NadekoBot.cs @@ -20,7 +20,6 @@ namespace NadekoBot public static CommandService Commands { get; private set; } public static DiscordSocketClient Client { get; private set; } - public static BotConfiguration Config { get; private set; } public static Localization Localizer { get; private set; } public static BotCredentials Credentials { get; private set; } @@ -34,7 +33,7 @@ namespace NadekoBot //create client Client = new DiscordSocketClient(new DiscordSocketConfig { - AudioMode = Discord.Audio.AudioMode.Incoming, + AudioMode = Discord.Audio.AudioMode.Outgoing, LargeThreshold = 200, LogLevel = LogSeverity.Warning, }); @@ -42,7 +41,6 @@ namespace NadekoBot //initialize Services Credentials = new BotCredentials(); Commands = new CommandService(); - Config = new BotConfiguration(); Localizer = new Localization(); Google = new GoogleApiService(); Stats = new StatsService(Client); @@ -51,7 +49,6 @@ namespace NadekoBot //setup DI var depMap = new DependencyMap(); depMap.Add(Localizer); - depMap.Add(Config); depMap.Add(Client); depMap.Add(Commands); depMap.Add(Google); @@ -91,15 +88,18 @@ namespace NadekoBot } } - private Task Client_MessageReceived(IMessage imsg) + private Task Client_MessageReceived(IMessage umsg) { + var usrMsg = umsg as IUserMessage; + if (usrMsg == null) + return Task.CompletedTask; var throwaway = Task.Run(async () => { var sw = new Stopwatch(); sw.Start(); - var t = await Commands.Execute(imsg, imsg.Content); + var t = await Commands.Execute(usrMsg, usrMsg.Content); sw.Stop(); - var channel = (imsg.Channel as ITextChannel); + var channel = (umsg.Channel as ITextChannel); if (t.IsSuccess) { @@ -108,10 +108,10 @@ namespace NadekoBot "Server: {1}\n\t" + "Channel: {2}\n\t" + "Message: {3}", - imsg.Author + " [" + imsg.Author.Id + "]", // {0} + umsg.Author + " [" + umsg.Author.Id + "]", // {0} (channel == null ? "PRIVATE" : channel.Guild.Name + " [" + channel.Guild.Id + "]"), // {1} (channel == null ? "PRIVATE" : channel.Name + " [" + channel.Id + "]"), //{2} - imsg.Content, // {3} + umsg.Content, // {3} sw.Elapsed.TotalSeconds // {4} ); } @@ -123,10 +123,10 @@ namespace NadekoBot "Channel: {2}\n\t" + "Message: {3}\n\t" + "Error: {4}", - imsg.Author + " [" + imsg.Author.Id + "]", // {0} + umsg.Author + " [" + umsg.Author.Id + "]", // {0} (channel == null ? "PRIVATE" : channel.Guild.Name + " [" + channel.Guild.Id + "]"), // {1} (channel == null ? "PRIVATE" : channel.Name + " [" + channel.Id + "]"), //{2} - imsg.Content,// {3} + umsg.Content,// {3} t.ErrorReason, // {4} sw.Elapsed.TotalSeconds //{5} ); diff --git a/src/NadekoBot/Resources/CommandStrings.Designer.cs b/src/NadekoBot/Resources/CommandStrings.Designer.cs index 3ed74b6a..380f6767 100644 --- a/src/NadekoBot/Resources/CommandStrings.Designer.cs +++ b/src/NadekoBot/Resources/CommandStrings.Designer.cs @@ -6647,6 +6647,33 @@ namespace NadekoBot.Resources { } } + /// + /// Looks up a localized string similar to toggle whether the self-assigned roles should be exclusive. + /// + public static string tesar_desc { + get { + return ResourceManager.GetString("tesar_desc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to `.tesar`. + /// + public static string tesar_summary { + get { + return ResourceManager.GetString("tesar_summary", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to tesar. + /// + public static string tesar_text { + get { + return ResourceManager.GetString("tesar_text", resourceCulture); + } + } + /// /// Looks up a localized string similar to Shows a current trivia leaderboard.. /// @@ -6674,33 +6701,6 @@ namespace NadekoBot.Resources { } } - /// - /// Looks up a localized string similar to toggle whether the self-assigned roles should be exclusive. - /// - public static string togglexclsar_desc { - get { - return ResourceManager.GetString("togglexclsar_desc", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to `.tesar`. - /// - public static string togglexclsar_summary { - get { - return ResourceManager.GetString("togglexclsar_summary", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to togglexclsar. - /// - public static string togglexclsar_text { - get { - return ResourceManager.GetString("togglexclsar_text", resourceCulture); - } - } - /// /// Looks up a localized string similar to Quits current trivia after current question.. /// diff --git a/src/NadekoBot/Resources/CommandStrings.resx b/src/NadekoBot/Resources/CommandStrings.resx index 38be8b2c..d18d35b8 100644 --- a/src/NadekoBot/Resources/CommandStrings.resx +++ b/src/NadekoBot/Resources/CommandStrings.resx @@ -405,13 +405,13 @@ `.lsar` - - togglexclsar + + tesar - + toggle whether the self-assigned roles should be exclusive - + `.tesar` diff --git a/src/NadekoBot/Resources/ResponseStrings.Designer.cs b/src/NadekoBot/Resources/ResponseStrings.Designer.cs index 15ceb39d..72395491 100644 --- a/src/NadekoBot/Resources/ResponseStrings.Designer.cs +++ b/src/NadekoBot/Resources/ResponseStrings.Designer.cs @@ -58,14 +58,5 @@ namespace NadekoBot.Resources { resourceCulture = value; } } - - /// - /// Looks up a localized string similar to TESTING. - /// - public static string test { - get { - return ResourceManager.GetString("test", resourceCulture); - } - } } } diff --git a/src/NadekoBot/Resources/ResponseStrings.resx b/src/NadekoBot/Resources/ResponseStrings.resx index 188ec335..1af7de15 100644 --- a/src/NadekoBot/Resources/ResponseStrings.resx +++ b/src/NadekoBot/Resources/ResponseStrings.resx @@ -117,7 +117,4 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - TESTING - \ No newline at end of file diff --git a/src/NadekoBot/Services/Database/IUnitOfWork.cs b/src/NadekoBot/Services/Database/IUnitOfWork.cs index 2b37dc5d..3a3fb2c2 100644 --- a/src/NadekoBot/Services/Database/IUnitOfWork.cs +++ b/src/NadekoBot/Services/Database/IUnitOfWork.cs @@ -10,8 +10,13 @@ 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; } + IBotConfigRepository BotConfig { get; } + int Complete(); Task CompleteAsync(); } diff --git a/src/NadekoBot/Services/Database/Models/BotConfig.cs b/src/NadekoBot/Services/Database/Models/BotConfig.cs new file mode 100644 index 00000000..6bb02fb3 --- /dev/null +++ b/src/NadekoBot/Services/Database/Models/BotConfig.cs @@ -0,0 +1,115 @@ +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 BotConfig : DbEntity + { + public HashSet Blacklist { get; set; } + public ulong BufferSize { get; set; } = 4000000; + public bool DontJoinServers { get; set; } = false; + public bool ForwardMessages { get; set; } = true; + public bool ForwardToAllOwners { get; set; } = true; + + public List ModulePrefixes { get; set; } = new List() + { + new ModulePrefix() { ModuleName="Administration", Prefix="." }, + new ModulePrefix() { ModuleName="Searches", Prefix="~" }, + new ModulePrefix() { ModuleName="NSFW", Prefix="~" }, + new ModulePrefix() { ModuleName="ClashOfClans", Prefix="," }, + new ModulePrefix() { ModuleName="Help", Prefix="-" }, + new ModulePrefix() { ModuleName="Music", Prefix="!!" }, + new ModulePrefix() { ModuleName="Trello", Prefix="trello" }, + new ModulePrefix() { ModuleName="Games", Prefix=">" }, + new ModulePrefix() { ModuleName="Gambling", Prefix="$" }, + new ModulePrefix() { ModuleName="Permissions", Prefix=";" }, + new ModulePrefix() { ModuleName="Pokemon", Prefix=">" }, + new ModulePrefix() { ModuleName="Utility", Prefix="." } + }; + + public List RotatingStatusMessages { get; set; } = new List(); + + public bool RotatingStatuses { get; set; } = false; + public string RemindMessageFormat { get; set; } = "❗⏰**I've been told to remind you to '%message%' now by %user%.**⏰❗"; + + + public string CurrencySign { get; set; } = "🌸"; + public string CurrencyName { get; set; } = "Nadeko Flower"; + public string CurrencyPluralName { get; set; } = "Nadeko Flowers"; + + public List EightBallResponses { get; set; } = new List + { + new EightBallResponse() { Text = "Most definitely yes" }, + new EightBallResponse() { Text = "For sure" }, + new EightBallResponse() { Text = "Totally!" }, + new EightBallResponse() { Text = "As I see it, yes" }, + new EightBallResponse() { Text = "My sources say yes" }, + new EightBallResponse() { Text = "Yes" }, + new EightBallResponse() { Text = "Most likely" }, + new EightBallResponse() { Text = "Perhaps" }, + new EightBallResponse() { Text = "Maybe" }, + new EightBallResponse() { Text = "Not sure" }, + new EightBallResponse() { Text = "It is uncertain" }, + new EightBallResponse() { Text = "Ask me again later" }, + new EightBallResponse() { Text = "Don't count on it" }, + new EightBallResponse() { Text = "Probably not" }, + new EightBallResponse() { Text = "Very doubtful" }, + new EightBallResponse() { Text = "Most likely no" }, + new EightBallResponse() { Text = "Nope" }, + new EightBallResponse() { Text = "No" }, + new EightBallResponse() { Text = "My sources say no" }, + new EightBallResponse() { Text = "Dont even think about it" }, + new EightBallResponse() { Text = "Definitely no" }, + new EightBallResponse() { Text = "NO - It may cause disease contraction" } + }; + + public List RaceAnimals { get; set; } = new List + { + new RaceAnimal { Icon = "🐼", Name = "Panda" }, + new RaceAnimal { Icon = "🐻", Name = "Bear" }, + new RaceAnimal { Icon = "🐧", Name = "Pengu" }, + new RaceAnimal { Icon = "🐨", Name = "Koala" }, + new RaceAnimal { Icon = "🐬", Name = "Dolphin" }, + new RaceAnimal { Icon = "🐞", Name = "Ladybird" }, + new RaceAnimal { Icon = "🦀", Name = "Crab" }, + new RaceAnimal { Icon = "🦄", Name = "Unicorn" } + }; + } + + public class PlayingStatus :DbEntity + { + public string Status { get; set; } + } + + public class BlacklistItem : DbEntity + { + public ulong ItemId { get; set; } + public enum BlacklistType + { + Server, + Channel, + User + } + } + + public class EightBallResponse : DbEntity + { + public string Text { get; set; } + } + + public class RaceAnimal : DbEntity + { + public string Icon { get; set; } + public string Name { get; set; } + } + + public class ModulePrefix : DbEntity + { + public string ModuleName { get; set; } + public string Prefix { get; set; } + } +} 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/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/Reminder.cs b/src/NadekoBot/Services/Database/Models/Reminder.cs new file mode 100644 index 00000000..693cac31 --- /dev/null +++ b/src/NadekoBot/Services/Database/Models/Reminder.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NadekoBot.Services.Database.Models +{ + public class Reminder : DbEntity + { + public DateTime When { get; set; } + public ulong ChannelId { get; set; } + public ulong ServerId { get; set; } + public ulong UserId { get; set; } + public string Message { get; set; } + public bool IsPrivate { 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 8f2c2a1f..378c1637 100644 --- a/src/NadekoBot/Services/Database/NadekoContext.cs +++ b/src/NadekoBot/Services/Database/NadekoContext.cs @@ -13,6 +13,11 @@ 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; } + public DbSet Reminders { get; set; } + public DbSet SelfAssignableRoles { get; set; } + public DbSet BotConfig { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { @@ -21,8 +26,7 @@ namespace NadekoBot.Services.Database var quoteEntity = modelBuilder.Entity(); #endregion - - + #region Donators var donatorEntity = modelBuilder.Entity(); @@ -40,6 +44,25 @@ namespace NadekoBot.Services.Database .IsUnique(); #endregion + + #region ClashOfClans + + var callersEntity = modelBuilder.Entity(); + callersEntity + .HasOne(c => c.ClashWar) + .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/IBotConfigRepository.cs b/src/NadekoBot/Services/Database/Repositories/IBotConfigRepository.cs new file mode 100644 index 00000000..c82ed462 --- /dev/null +++ b/src/NadekoBot/Services/Database/Repositories/IBotConfigRepository.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 IBotConfigRepository : IRepository + { + BotConfig GetOrCreate(); + } +} 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/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/IReminderRepository.cs b/src/NadekoBot/Services/Database/Repositories/IReminderRepository.cs new file mode 100644 index 00000000..8a1ef365 --- /dev/null +++ b/src/NadekoBot/Services/Database/Repositories/IReminderRepository.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 IReminderRepository : IRepository + { + + } +} 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/BotConfigRepository.cs b/src/NadekoBot/Services/Database/Repositories/Impl/BotConfigRepository.cs new file mode 100644 index 00000000..78c4e086 --- /dev/null +++ b/src/NadekoBot/Services/Database/Repositories/Impl/BotConfigRepository.cs @@ -0,0 +1,34 @@ +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 BotConfigRepository : Repository, IBotConfigRepository + { + public BotConfigRepository(DbContext context) : base(context) + { + } + + public BotConfig GetOrCreate() + { + var config = _set.Include(bc => bc.RotatingStatusMessages) + .Include(bc => bc.RaceAnimals) + .Include(bc => bc.Blacklist) + .Include(bc => bc.EightBallResponses) + .Include(bc => bc.ModulePrefixes) + .FirstOrDefault(); + + if (config == null) + { + _set.Add(config = new BotConfig()); + _context.SaveChanges(); + } + return config; + } + } +} 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/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/ReminderRepository.cs b/src/NadekoBot/Services/Database/Repositories/Impl/ReminderRepository.cs new file mode 100644 index 00000000..d2e74452 --- /dev/null +++ b/src/NadekoBot/Services/Database/Repositories/Impl/ReminderRepository.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 ReminderRepository : Repository, IReminderRepository + { + public ReminderRepository(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..17c4caf0 --- /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).ToList(); + } +} diff --git a/src/NadekoBot/Services/Database/UnitOfWork.cs b/src/NadekoBot/Services/Database/UnitOfWork.cs index 1768f7de..5550bc6c 100644 --- a/src/NadekoBot/Services/Database/UnitOfWork.cs +++ b/src/NadekoBot/Services/Database/UnitOfWork.cs @@ -15,12 +15,24 @@ 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)); + private IClashOfClansRepository _clashOfClans; + public IClashOfClansRepository ClashOfClans => _clashOfClans ?? (_clashOfClans = new ClashOfClansRepository(_context)); + + private IReminderRepository _reminders; + public IReminderRepository Reminders => _reminders ?? (_reminders = new ReminderRepository(_context)); + + private ISelfAssignedRolesRepository _selfAssignedRoles; + public ISelfAssignedRolesRepository SelfAssignedRoles => _selfAssignedRoles ?? (_selfAssignedRoles = new SelfAssignedRolesRepository(_context)); + + private IBotConfigRepository _botConfig; + public IBotConfigRepository BotConfig => _botConfig ?? (_botConfig = new BotConfigRepository(_context)); + public UnitOfWork(NadekoContext context) { _context = context; diff --git a/src/NadekoBot/Services/IBotConfiguration.cs b/src/NadekoBot/Services/IBotConfiguration.cs deleted file mode 100644 index 4b6a9898..00000000 --- a/src/NadekoBot/Services/IBotConfiguration.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System.Collections.Generic; - -namespace NadekoBot.Services -{ - public interface IBotConfiguration - { - bool DontJoinServers { get; set; } - bool ForwardMessages { get; set; } - bool ForwardToAllOwners { get; set; } - - bool RotatePlayingStatus { get; set; } - List PlayingStatuses { get; set; } - - ulong BufferSize { get; set; } - List RaceAnimals { get; set; } - string RemindMessageFormat { get; set; } - - - HashSet BlacklistedServers { get; set; } - HashSet BlacklistedChannels { get; set; } - HashSet BlacklistedUsers { get; set; } - - List EightBallResponses { get; set; } - Currency Currency { get; set; } - - ModulePrefixes ModulePrefixes { get; set; } - } - - public class Currency { - public string Sign { get; set; } - public string Name { get; set; } - public string PluralName { get; set; } - } - - public class ModulePrefixes - { - public string Administration { get; set; } = "."; - public string Searches { get; set; } = "~"; - public string NSFW { get; set; } = "~"; - public string Conversations { get; set; } = "<@{0}>"; - public string ClashOfClans { get; set; } = ","; - public string Help { get; set; } = "-"; - public string Music { get; set; } = "!!"; - public string Trello { get; set; } = "trello "; - public string Games { get; set; } = ">"; - public string Gambling { get; set; } = "$"; - public string Permissions { get; set; } = ";"; - public string Programming { get; set; } = "%"; - public string Pokemon { get; set; } = ">"; - public string Utility { get; set; } = "."; - } -} diff --git a/src/NadekoBot/Services/Impl/BotConfiguration.cs b/src/NadekoBot/Services/Impl/BotConfiguration.cs deleted file mode 100644 index 8d6c17b0..00000000 --- a/src/NadekoBot/Services/Impl/BotConfiguration.cs +++ /dev/null @@ -1,92 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace NadekoBot.Services.Impl -{ - public class BotConfiguration : IBotConfiguration - { - internal Task _8BallResponses; - - public HashSet BlacklistedChannels { get; set; } = new HashSet(); - - public HashSet BlacklistedServers { get; set; } = new HashSet(); - - public HashSet BlacklistedUsers { get; set; } = new HashSet(); - - public ulong BufferSize { get; set; } = 4000000; - - public bool DontJoinServers { get; set; } = false; - - public bool ForwardMessages { get; set; } = true; - - public bool ForwardToAllOwners { get; set; } = true; - - public ModulePrefixes ModulePrefixes { get; set; } = new ModulePrefixes - { - Administration = ".", - ClashOfClans = ",", - Conversations = "<@{0}>", - Gambling = "$", - Games = ">", - Pokemon = ">", - Help = "-", - Music = "!!", - NSFW = "~", - Permissions = ";", - Programming = "%", - Searches = "~", - Trello = "trello", - Utility = "." - }; - - public List PlayingStatuses { get; set; } = new List(); - - public string RemindMessageFormat { get; set; } = "❗⏰**I've been told to remind you to '%message%' now by %user%.**⏰❗"; - - public bool RotatePlayingStatus { get; set; } = false; - - public Currency Currency { get; set; } = new Currency - { - Name = "Nadeko Flower", - PluralName = "Nadeko Flowers", - Sign = "🌸", - }; - - public List EightBallResponses { get; set; } = new List - { - "Most definitely yes", - "For sure", - "As I see it, yes", - "My sources say yes", - "Yes", - "Most likely", - "Perhaps", - "Maybe", - "Not sure", - "It is uncertain", - "Ask me again later", - "Don't count on it", - "Probably not", - "Very doubtful", - "Most likely no", - "Nope", - "No", - "My sources say no", - "Dont even think about it", - "Definitely no", - "NO - It may cause disease contraction" - }; - - public List RaceAnimals { get; set; } = new List - { - "🐼", - "🐻", - "🐧", - "🐨", - "🐬", - "🐞", - "🦀", - "🦄" - }; - } -} diff --git a/src/NadekoBot/_Extensions/Extensions.cs b/src/NadekoBot/_Extensions/Extensions.cs index 5e574c07..ecd748a1 100644 --- a/src/NadekoBot/_Extensions/Extensions.cs +++ b/src/NadekoBot/_Extensions/Extensions.cs @@ -24,29 +24,29 @@ namespace NadekoBot.Extensions public static double UnixTimestamp(this DateTime dt) => dt.ToUniversalTime().Subtract(new DateTime(1970, 1, 1)).TotalSeconds; - public static async Task SendMessageAsync(this IGuildUser user, string message, bool isTTS = false) => + public static async Task SendMessageAsync(this IGuildUser user, string message, bool isTTS = false) => await (await user.CreateDMChannelAsync().ConfigureAwait(false)).SendMessageAsync(message, isTTS).ConfigureAwait(false); - public static async Task SendFileAsync(this IGuildUser user, string filePath, string caption = null, bool isTTS = false) => + public static async Task SendFileAsync(this IGuildUser user, string filePath, string caption = null, bool isTTS = false) => await (await user.CreateDMChannelAsync().ConfigureAwait(false)).SendFileAsync(filePath, caption, isTTS).ConfigureAwait(false); - public static async Task SendFileAsync(this IGuildUser user, Stream fileStream, string fileName, string caption = null, bool isTTS = false) => + public static async Task SendFileAsync(this IGuildUser user, Stream fileStream, string fileName, string caption = null, bool isTTS = false) => await (await user.CreateDMChannelAsync().ConfigureAwait(false)).SendFileAsync(fileStream, fileName, caption, isTTS).ConfigureAwait(false); - public static async Task Reply(this IMessage msg, string content) => + public static async Task Reply(this IUserMessage msg, string content) => await msg.Channel.SendMessageAsync(content).ConfigureAwait(false); - public static Task IsAuthor(this IMessage msg) => + public static Task IsAuthor(this IUserMessage msg) => Task.FromResult(NadekoBot.Client.GetCurrentUser().Id == msg.Author.Id); public static IEnumerable Members(this IRole role) => NadekoBot.Client.GetGuilds().Where(g => g.Id == role.GuildId).FirstOrDefault()?.GetUsers().Where(u => u.Roles.Contains(role)) ?? Enumerable.Empty(); - public static async Task ReplyLong(this IMessage msg, string content, string breakOn = "\n", string addToEnd = "", string addToStart = "") + public static async Task ReplyLong(this IUserMessage msg, string content, string breakOn = "\n", string addToEnd = "", string addToStart = "") { if (content.Length < 2000) return new[] { await msg.Channel.SendMessageAsync(content).ConfigureAwait(false) }; - var list = new List(); + var list = new List(); var temp = Regex.Split(content, breakOn).Select(x => x += breakOn).ToList(); string toolong; @@ -77,7 +77,7 @@ namespace NadekoBot.Extensions return list.ToArray(); } - public static Task SendTableAsync(this IMessageChannel ch, string seed, IEnumerable items, Func howToPrint, int columns = 3) + public static Task SendTableAsync(this IMessageChannel ch, string seed, IEnumerable items, Func howToPrint, int columns = 3) { var i = 0; return ch.SendMessageAsync($@"{seed}```xl @@ -86,7 +86,7 @@ namespace NadekoBot.Extensions ```"); } - public static Task SendTableAsync(this IMessageChannel ch, IEnumerable items, Func howToPrint, int columns = 3) + public static Task SendTableAsync(this IMessageChannel ch, IEnumerable items, Func howToPrint, int columns = 3) { return ch.SendTableAsync("", items, howToPrint, columns); } diff --git a/src/NadekoBot/_Models/DataModels/Reminder.cs b/src/NadekoBot/_Models/DataModels/Reminder.cs deleted file mode 100644 index 043700fd..00000000 --- a/src/NadekoBot/_Models/DataModels/Reminder.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; - -namespace NadekoBot.DataModels -{ - class Reminder : IDataModel - { - public DateTime When { get; set; } - public long ChannelId { get; set; } - public long ServerId { get; set; } - public long UserId { get; set; } - public string Message { get; set; } - public bool IsPrivate { get; set; } - } -} diff --git a/src/NadekoBot/_Modules/CustomReactions/CustomReactions.cs b/src/NadekoBot/_Modules/CustomReactions/CustomReactions.cs index af36cd94..920675b4 100644 --- a/src/NadekoBot/_Modules/CustomReactions/CustomReactions.cs +++ b/src/NadekoBot/_Modules/CustomReactions/CustomReactions.cs @@ -31,7 +31,7 @@ namespace NadekoBot.Modules.CustomReactions }else return rng.Next().ToString(); } }, {new Regex("%mention%"), (e,m) => NadekoBot.BotMention }, - {new Regex("%user%"), (e,m) => imsg.Author.Mention }, + {new Regex("%user%"), (e,m) => umsg.Author.Mention }, {new Regex("%target%"), (e,m) => args?.Trim() ?? "" }, }; diff --git a/src/NadekoBot/_Modules/Permissions/Classes/PermissionChecker.cs b/src/NadekoBot/_Modules/Permissions/Classes/PermissionChecker.cs index 7770af4a..cf658aad 100644 --- a/src/NadekoBot/_Modules/Permissions/Classes/PermissionChecker.cs +++ b/src/NadekoBot/_Modules/Permissions/Classes/PermissionChecker.cs @@ -119,10 +119,10 @@ namespace NadekoBot.Modules.Permissions.Classes case PermissionsHandler.PermissionBanType.RoleBanModule: msg = $"You do not have a **role** which permits you the usage of **{command.Category}** module."; break; - case PermissionsHandler.PermissionBanTypimsg.AuthorBanCommand: + case PermissionsHandler.PermissionBanTypumsg.AuthorBanCommand: msg = $"{user.Mention}, You have been banned from using **{command.Text}** command."; break; - case PermissionsHandler.PermissionBanTypimsg.AuthorBanModule: + case PermissionsHandler.PermissionBanTypumsg.AuthorBanModule: msg = $"{user.Mention}, You have been banned from using **{command.Category}** module."; break; default: diff --git a/src/NadekoBot/_Modules/Permissions/Classes/PermissionsHandler.cs b/src/NadekoBot/_Modules/Permissions/Classes/PermissionsHandler.cs index ed5b1b58..6839b276 100644 --- a/src/NadekoBot/_Modules/Permissions/Classes/PermissionsHandler.cs +++ b/src/NadekoBot/_Modules/Permissions/Classes/PermissionsHandler.cs @@ -142,10 +142,10 @@ namespace NadekoBot.Modules.Permissions.Classes //user if (serverPerms.UserPermissions.TryGetValue(user.Id, out perm) && perm.Modules.TryGetValue(command.Category, out val) && val == false) - return PermissionBanTypimsg.AuthorBanModule; + return PermissionBanTypumsg.AuthorBanModule; if (serverPerms.UserPermissions.TryGetValue(user.Id, out perm) && perm.Commands.TryGetValue(command.Text, out val) && val == false) - return PermissionBanTypimsg.AuthorBanCommand; + return PermissionBanTypumsg.AuthorBanCommand; return PermissionBanType.None; } diff --git a/src/NadekoBot/_Modules/Permissions/PermissionsModule.cs b/src/NadekoBot/_Modules/Permissions/PermissionsModule.cs index b0cdbe87..69d70eac 100644 --- a/src/NadekoBot/_Modules/Permissions/PermissionsModule.cs +++ b/src/NadekoBot/_Modules/Permissions/PermissionsModule.cs @@ -224,7 +224,7 @@ namespace NadekoBot.Modules.Permissions .Parameter("user", ParameterType.Unparsed) .Do(async e => { - var user = imsg.Author; + var user = umsg.Author; if (!string.IsNullOrWhiteSpace(user)) try { diff --git a/src/NadekoBot/project.lock.json b/src/NadekoBot/project.lock.json index ebd101b1..57023365 100644 --- a/src/NadekoBot/project.lock.json +++ b/src/NadekoBot/project.lock.json @@ -3161,7 +3161,7 @@ "lib/portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10/libvideo.dll": {} } }, - "Discord.Net/1.0.0-dev": { + "Discord.Net/1.0.0-beta": { "type": "project", "framework": ".NETStandard,Version=v1.3", "dependencies": { @@ -3188,7 +3188,7 @@ "netstandard1.3/Discord.Net.dll": {} } }, - "Discord.Net.Commands/1.0.0-dev": { + "Discord.Net.Commands/1.0.0-beta": { "type": "project", "framework": ".NETStandard,Version=v1.3", "dependencies": { @@ -9019,12 +9019,12 @@ "lib/portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10/libvideo.dll" ] }, - "Discord.Net/1.0.0-dev": { + "Discord.Net/1.0.0-beta": { "type": "project", "path": "../../discord.net/src/Discord.Net/project.json", "msbuildProject": "../../discord.net/src/Discord.Net/Discord.Net.xproj" }, - "Discord.Net.Commands/1.0.0-dev": { + "Discord.Net.Commands/1.0.0-beta": { "type": "project", "path": "../../discord.net/src/Discord.Net.Commands/project.json", "msbuildProject": "../../discord.net/src/Discord.Net.Commands/Discord.Net.Commands.xproj"