$claim, $waifuinfo, $affinity and $divorce commands added for a waifu currency game
This commit is contained in:
		
							
								
								
									
										1089
									
								
								src/NadekoBot/Migrations/20170122044958_waifus.Designer.cs
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										1089
									
								
								src/NadekoBot/Migrations/20170122044958_waifus.Designer.cs
									
									
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										140
									
								
								src/NadekoBot/Migrations/20170122044958_waifus.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								src/NadekoBot/Migrations/20170122044958_waifus.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,140 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using Microsoft.EntityFrameworkCore.Migrations;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Migrations
 | 
			
		||||
{
 | 
			
		||||
    public partial class waifus : Migration
 | 
			
		||||
    {
 | 
			
		||||
        protected override void Up(MigrationBuilder migrationBuilder)
 | 
			
		||||
        {
 | 
			
		||||
            migrationBuilder.CreateTable(
 | 
			
		||||
                name: "DiscordUser",
 | 
			
		||||
                columns: table => new
 | 
			
		||||
                {
 | 
			
		||||
                    Id = table.Column<int>(nullable: false)
 | 
			
		||||
                        .Annotation("Sqlite:Autoincrement", true),
 | 
			
		||||
                    AvatarId = table.Column<string>(nullable: true),
 | 
			
		||||
                    Discriminator = table.Column<string>(nullable: true),
 | 
			
		||||
                    UserId = table.Column<ulong>(nullable: false),
 | 
			
		||||
                    Username = table.Column<string>(nullable: true)
 | 
			
		||||
                },
 | 
			
		||||
                constraints: table =>
 | 
			
		||||
                {
 | 
			
		||||
                    table.PrimaryKey("PK_DiscordUser", x => x.Id);
 | 
			
		||||
                    table.UniqueConstraint("AK_DiscordUser_UserId", x => x.UserId);
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.CreateTable(
 | 
			
		||||
                name: "WaifuInfo",
 | 
			
		||||
                columns: table => new
 | 
			
		||||
                {
 | 
			
		||||
                    Id = table.Column<int>(nullable: false)
 | 
			
		||||
                        .Annotation("Sqlite:Autoincrement", true),
 | 
			
		||||
                    AffinityId = table.Column<int>(nullable: true),
 | 
			
		||||
                    ClaimerId = table.Column<int>(nullable: true),
 | 
			
		||||
                    Price = table.Column<int>(nullable: false),
 | 
			
		||||
                    WaifuId = table.Column<int>(nullable: false)
 | 
			
		||||
                },
 | 
			
		||||
                constraints: table =>
 | 
			
		||||
                {
 | 
			
		||||
                    table.PrimaryKey("PK_WaifuInfo", x => x.Id);
 | 
			
		||||
                    table.ForeignKey(
 | 
			
		||||
                        name: "FK_WaifuInfo_DiscordUser_AffinityId",
 | 
			
		||||
                        column: x => x.AffinityId,
 | 
			
		||||
                        principalTable: "DiscordUser",
 | 
			
		||||
                        principalColumn: "Id",
 | 
			
		||||
                        onDelete: ReferentialAction.Restrict);
 | 
			
		||||
                    table.ForeignKey(
 | 
			
		||||
                        name: "FK_WaifuInfo_DiscordUser_ClaimerId",
 | 
			
		||||
                        column: x => x.ClaimerId,
 | 
			
		||||
                        principalTable: "DiscordUser",
 | 
			
		||||
                        principalColumn: "Id",
 | 
			
		||||
                        onDelete: ReferentialAction.Restrict);
 | 
			
		||||
                    table.ForeignKey(
 | 
			
		||||
                        name: "FK_WaifuInfo_DiscordUser_WaifuId",
 | 
			
		||||
                        column: x => x.WaifuId,
 | 
			
		||||
                        principalTable: "DiscordUser",
 | 
			
		||||
                        principalColumn: "Id",
 | 
			
		||||
                        onDelete: ReferentialAction.Cascade);
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.CreateTable(
 | 
			
		||||
                name: "WaifuUpdates",
 | 
			
		||||
                columns: table => new
 | 
			
		||||
                {
 | 
			
		||||
                    Id = table.Column<int>(nullable: false)
 | 
			
		||||
                        .Annotation("Sqlite:Autoincrement", true),
 | 
			
		||||
                    NewId = table.Column<int>(nullable: true),
 | 
			
		||||
                    OldId = table.Column<int>(nullable: true),
 | 
			
		||||
                    UpdateType = table.Column<int>(nullable: false),
 | 
			
		||||
                    UserId = table.Column<int>(nullable: false)
 | 
			
		||||
                },
 | 
			
		||||
                constraints: table =>
 | 
			
		||||
                {
 | 
			
		||||
                    table.PrimaryKey("PK_WaifuUpdates", x => x.Id);
 | 
			
		||||
                    table.ForeignKey(
 | 
			
		||||
                        name: "FK_WaifuUpdates_DiscordUser_NewId",
 | 
			
		||||
                        column: x => x.NewId,
 | 
			
		||||
                        principalTable: "DiscordUser",
 | 
			
		||||
                        principalColumn: "Id",
 | 
			
		||||
                        onDelete: ReferentialAction.Restrict);
 | 
			
		||||
                    table.ForeignKey(
 | 
			
		||||
                        name: "FK_WaifuUpdates_DiscordUser_OldId",
 | 
			
		||||
                        column: x => x.OldId,
 | 
			
		||||
                        principalTable: "DiscordUser",
 | 
			
		||||
                        principalColumn: "Id",
 | 
			
		||||
                        onDelete: ReferentialAction.Restrict);
 | 
			
		||||
                    table.ForeignKey(
 | 
			
		||||
                        name: "FK_WaifuUpdates_DiscordUser_UserId",
 | 
			
		||||
                        column: x => x.UserId,
 | 
			
		||||
                        principalTable: "DiscordUser",
 | 
			
		||||
                        principalColumn: "Id",
 | 
			
		||||
                        onDelete: ReferentialAction.Cascade);
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.CreateIndex(
 | 
			
		||||
                name: "IX_WaifuInfo_AffinityId",
 | 
			
		||||
                table: "WaifuInfo",
 | 
			
		||||
                column: "AffinityId");
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.CreateIndex(
 | 
			
		||||
                name: "IX_WaifuInfo_ClaimerId",
 | 
			
		||||
                table: "WaifuInfo",
 | 
			
		||||
                column: "ClaimerId");
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.CreateIndex(
 | 
			
		||||
                name: "IX_WaifuInfo_WaifuId",
 | 
			
		||||
                table: "WaifuInfo",
 | 
			
		||||
                column: "WaifuId",
 | 
			
		||||
                unique: true);
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.CreateIndex(
 | 
			
		||||
                name: "IX_WaifuUpdates_NewId",
 | 
			
		||||
                table: "WaifuUpdates",
 | 
			
		||||
                column: "NewId");
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.CreateIndex(
 | 
			
		||||
                name: "IX_WaifuUpdates_OldId",
 | 
			
		||||
                table: "WaifuUpdates",
 | 
			
		||||
                column: "OldId");
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.CreateIndex(
 | 
			
		||||
                name: "IX_WaifuUpdates_UserId",
 | 
			
		||||
                table: "WaifuUpdates",
 | 
			
		||||
                column: "UserId");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void Down(MigrationBuilder migrationBuilder)
 | 
			
		||||
        {
 | 
			
		||||
            migrationBuilder.DropTable(
 | 
			
		||||
                name: "WaifuInfo");
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.DropTable(
 | 
			
		||||
                name: "WaifuUpdates");
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.DropTable(
 | 
			
		||||
                name: "DiscordUser");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -299,6 +299,26 @@ namespace NadekoBot.Migrations
 | 
			
		||||
                    b.ToTable("CustomReactions");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.DiscordUser", b =>
 | 
			
		||||
                {
 | 
			
		||||
                    b.Property<int>("Id")
 | 
			
		||||
                        .ValueGeneratedOnAdd();
 | 
			
		||||
 | 
			
		||||
                    b.Property<string>("AvatarId");
 | 
			
		||||
 | 
			
		||||
                    b.Property<string>("Discriminator");
 | 
			
		||||
 | 
			
		||||
                    b.Property<ulong>("UserId");
 | 
			
		||||
 | 
			
		||||
                    b.Property<string>("Username");
 | 
			
		||||
 | 
			
		||||
                    b.HasKey("Id");
 | 
			
		||||
 | 
			
		||||
                    b.HasAlternateKey("UserId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("DiscordUser");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.Donator", b =>
 | 
			
		||||
                {
 | 
			
		||||
                    b.Property<int>("Id")
 | 
			
		||||
@@ -817,6 +837,55 @@ namespace NadekoBot.Migrations
 | 
			
		||||
                    b.ToTable("PokeGame");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.WaifuInfo", b =>
 | 
			
		||||
                {
 | 
			
		||||
                    b.Property<int>("Id")
 | 
			
		||||
                        .ValueGeneratedOnAdd();
 | 
			
		||||
 | 
			
		||||
                    b.Property<int?>("AffinityId");
 | 
			
		||||
 | 
			
		||||
                    b.Property<int?>("ClaimerId");
 | 
			
		||||
 | 
			
		||||
                    b.Property<int>("Price");
 | 
			
		||||
 | 
			
		||||
                    b.Property<int>("WaifuId");
 | 
			
		||||
 | 
			
		||||
                    b.HasKey("Id");
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("AffinityId");
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("ClaimerId");
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("WaifuId")
 | 
			
		||||
                        .IsUnique();
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("WaifuInfo");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.WaifuUpdate", b =>
 | 
			
		||||
                {
 | 
			
		||||
                    b.Property<int>("Id")
 | 
			
		||||
                        .ValueGeneratedOnAdd();
 | 
			
		||||
 | 
			
		||||
                    b.Property<int?>("NewId");
 | 
			
		||||
 | 
			
		||||
                    b.Property<int?>("OldId");
 | 
			
		||||
 | 
			
		||||
                    b.Property<int>("UpdateType");
 | 
			
		||||
 | 
			
		||||
                    b.Property<int>("UserId");
 | 
			
		||||
 | 
			
		||||
                    b.HasKey("Id");
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("NewId");
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("OldId");
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("UserId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("WaifuUpdates");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiRaidSetting", b =>
 | 
			
		||||
                {
 | 
			
		||||
                    b.HasOne("NadekoBot.Services.Database.Models.GuildConfig", "GuildConfig")
 | 
			
		||||
@@ -982,6 +1051,38 @@ namespace NadekoBot.Migrations
 | 
			
		||||
                        .WithMany("RaceAnimals")
 | 
			
		||||
                        .HasForeignKey("BotConfigId");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.WaifuInfo", b =>
 | 
			
		||||
                {
 | 
			
		||||
                    b.HasOne("NadekoBot.Services.Database.Models.DiscordUser", "Affinity")
 | 
			
		||||
                        .WithMany()
 | 
			
		||||
                        .HasForeignKey("AffinityId");
 | 
			
		||||
 | 
			
		||||
                    b.HasOne("NadekoBot.Services.Database.Models.DiscordUser", "Claimer")
 | 
			
		||||
                        .WithMany()
 | 
			
		||||
                        .HasForeignKey("ClaimerId");
 | 
			
		||||
 | 
			
		||||
                    b.HasOne("NadekoBot.Services.Database.Models.DiscordUser", "Waifu")
 | 
			
		||||
                        .WithOne()
 | 
			
		||||
                        .HasForeignKey("NadekoBot.Services.Database.Models.WaifuInfo", "WaifuId")
 | 
			
		||||
                        .OnDelete(DeleteBehavior.Cascade);
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.WaifuUpdate", b =>
 | 
			
		||||
                {
 | 
			
		||||
                    b.HasOne("NadekoBot.Services.Database.Models.DiscordUser", "New")
 | 
			
		||||
                        .WithMany()
 | 
			
		||||
                        .HasForeignKey("NewId");
 | 
			
		||||
 | 
			
		||||
                    b.HasOne("NadekoBot.Services.Database.Models.DiscordUser", "Old")
 | 
			
		||||
                        .WithMany()
 | 
			
		||||
                        .HasForeignKey("OldId");
 | 
			
		||||
 | 
			
		||||
                    b.HasOne("NadekoBot.Services.Database.Models.DiscordUser", "User")
 | 
			
		||||
                        .WithMany()
 | 
			
		||||
                        .HasForeignKey("UserId")
 | 
			
		||||
                        .OnDelete(DeleteBehavior.Cascade);
 | 
			
		||||
                });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										516
									
								
								src/NadekoBot/Modules/Gambling/Commands/WaifuClaimCommands.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										516
									
								
								src/NadekoBot/Modules/Gambling/Commands/WaifuClaimCommands.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,516 @@
 | 
			
		||||
using Discord;
 | 
			
		||||
using Discord.Commands;
 | 
			
		||||
using NadekoBot.Attributes;
 | 
			
		||||
using NadekoBot.Extensions;
 | 
			
		||||
using NadekoBot.Services;
 | 
			
		||||
using NadekoBot.Services.Database;
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Concurrent;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Gambling
 | 
			
		||||
{
 | 
			
		||||
    public partial class Gambling
 | 
			
		||||
    {
 | 
			
		||||
        public enum ClaimTitles
 | 
			
		||||
        {
 | 
			
		||||
            Lonely,
 | 
			
		||||
            Devoted,
 | 
			
		||||
            Rookie,
 | 
			
		||||
            Schemer,
 | 
			
		||||
            Dilettante,
 | 
			
		||||
            Intermediate,
 | 
			
		||||
            Seducer,
 | 
			
		||||
            Expert,
 | 
			
		||||
            Veteran,
 | 
			
		||||
            Incubis,
 | 
			
		||||
            Harem_King,
 | 
			
		||||
            Harem_God,
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public enum AffinityTitles
 | 
			
		||||
        {
 | 
			
		||||
            Pure,
 | 
			
		||||
            Faithful,
 | 
			
		||||
            Defiled,
 | 
			
		||||
            Cheater,
 | 
			
		||||
            Tainted,
 | 
			
		||||
            Corrupted,
 | 
			
		||||
            Lewd,
 | 
			
		||||
            Sloot,
 | 
			
		||||
            Depraved,
 | 
			
		||||
            Harlot
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Group]
 | 
			
		||||
        public class WaifuClaimCommands : ModuleBase
 | 
			
		||||
        {
 | 
			
		||||
            private static ConcurrentDictionary<ulong, DateTime> _divorceCooldowns { get; } = new ConcurrentDictionary<ulong, DateTime>();
 | 
			
		||||
            private static ConcurrentDictionary<ulong, DateTime> _affinityCooldowns { get; } = new ConcurrentDictionary<ulong, DateTime>();
 | 
			
		||||
 | 
			
		||||
            enum WaifuClaimResult
 | 
			
		||||
            {
 | 
			
		||||
                Success,
 | 
			
		||||
                NotEnoughFunds,
 | 
			
		||||
                InsufficientAmount
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
            public async Task WaifuClaim(int amount, [Remainder]IUser target)
 | 
			
		||||
            {
 | 
			
		||||
                if (amount < 50)
 | 
			
		||||
                {
 | 
			
		||||
                    await Context.Channel.SendErrorAsync($"{Context.User.Mention} No waifu is that cheap. You must pay at least 50{NadekoBot.BotConfig.CurrencySign} to get a waifu, even if their actual value is lower.").ConfigureAwait(false);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (target.Id == Context.User.Id)
 | 
			
		||||
                {
 | 
			
		||||
                    await Context.Channel.SendErrorAsync(Context.User.Mention + " You can't claim yourself.").ConfigureAwait(false);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                WaifuClaimResult result = WaifuClaimResult.NotEnoughFunds;
 | 
			
		||||
                int? oldPrice = null;
 | 
			
		||||
                WaifuInfo w;
 | 
			
		||||
                var isAffinity = false;
 | 
			
		||||
                using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
                {
 | 
			
		||||
                    w = uow.Waifus.ByWaifuUserId(target.Id);
 | 
			
		||||
                    isAffinity = (w?.Affinity?.UserId == Context.User.Id);
 | 
			
		||||
                    if (w == null)
 | 
			
		||||
                    {
 | 
			
		||||
                        var claimer = uow.DiscordUsers.GetOrCreate(Context.User);
 | 
			
		||||
                        var waifu = uow.DiscordUsers.GetOrCreate(target);
 | 
			
		||||
                        if (!await CurrencyHandler.RemoveCurrencyAsync(Context.User.Id, "Claimed Waifu", amount, uow).ConfigureAwait(false))
 | 
			
		||||
                        {
 | 
			
		||||
                            result = WaifuClaimResult.NotEnoughFunds;
 | 
			
		||||
                        }
 | 
			
		||||
                        else
 | 
			
		||||
                        {
 | 
			
		||||
                            uow.Waifus.Add(w = new WaifuInfo()
 | 
			
		||||
                            {
 | 
			
		||||
                                Waifu = waifu,
 | 
			
		||||
                                Claimer = claimer,
 | 
			
		||||
                                Affinity = null,
 | 
			
		||||
                                Price = amount
 | 
			
		||||
                            });
 | 
			
		||||
                            uow._context.WaifuUpdates.Add(new WaifuUpdate()
 | 
			
		||||
                            {
 | 
			
		||||
                                User = waifu,
 | 
			
		||||
                                Old = null,
 | 
			
		||||
                                New = claimer,
 | 
			
		||||
                                UpdateType = WaifuUpdateType.Claimed
 | 
			
		||||
                            });
 | 
			
		||||
                            result = WaifuClaimResult.Success;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    else if (isAffinity && amount >= w.Price * 0.88f)
 | 
			
		||||
                    {
 | 
			
		||||
                        if (!await CurrencyHandler.RemoveCurrencyAsync(Context.User.Id, "Claimed Waifu", amount, uow).ConfigureAwait(false))
 | 
			
		||||
                        {
 | 
			
		||||
                            result = WaifuClaimResult.NotEnoughFunds;
 | 
			
		||||
                        }
 | 
			
		||||
                        else
 | 
			
		||||
                        {
 | 
			
		||||
                            var oldClaimer = w.Claimer;
 | 
			
		||||
                            w.Claimer = uow.DiscordUsers.GetOrCreate(Context.User);
 | 
			
		||||
                            oldPrice = w.Price;
 | 
			
		||||
                            w.Price = amount + (amount / 4);
 | 
			
		||||
                            result = WaifuClaimResult.Success;
 | 
			
		||||
 | 
			
		||||
                            uow._context.WaifuUpdates.Add(new WaifuUpdate()
 | 
			
		||||
                            {
 | 
			
		||||
                                User = w.Waifu,
 | 
			
		||||
                                Old = oldClaimer,
 | 
			
		||||
                                New = w.Claimer,
 | 
			
		||||
                                UpdateType = WaifuUpdateType.Claimed
 | 
			
		||||
                            });
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    else if (amount >= w.Price * 1.1f) // if no affinity
 | 
			
		||||
                    {
 | 
			
		||||
                        if (!await CurrencyHandler.RemoveCurrencyAsync(Context.User.Id, "Claimed Waifu", amount, uow).ConfigureAwait(false))
 | 
			
		||||
                        {
 | 
			
		||||
                            result = WaifuClaimResult.NotEnoughFunds;
 | 
			
		||||
                        }
 | 
			
		||||
                        else
 | 
			
		||||
                        {
 | 
			
		||||
                            var oldClaimer = w.Claimer;
 | 
			
		||||
                            w.Claimer = uow.DiscordUsers.GetOrCreate(Context.User);
 | 
			
		||||
                            oldPrice = w.Price;
 | 
			
		||||
                            w.Price = amount;
 | 
			
		||||
                            result = WaifuClaimResult.Success;
 | 
			
		||||
 | 
			
		||||
                            uow._context.WaifuUpdates.Add(new WaifuUpdate()
 | 
			
		||||
                            {
 | 
			
		||||
                                User = w.Waifu,
 | 
			
		||||
                                Old = oldClaimer,
 | 
			
		||||
                                New = w.Claimer,
 | 
			
		||||
                                UpdateType = WaifuUpdateType.Claimed
 | 
			
		||||
                            });
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                        result = WaifuClaimResult.InsufficientAmount;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                    await uow.CompleteAsync().ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (result == WaifuClaimResult.InsufficientAmount)
 | 
			
		||||
                {
 | 
			
		||||
                    await Context.Channel.SendErrorAsync($"{Context.User.Mention} You must pay {Math.Ceiling(w.Price * (isAffinity ? 0.88f : 1.1f))} or more to claim that waifu!").ConfigureAwait(false);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                else if (result == WaifuClaimResult.NotEnoughFunds)
 | 
			
		||||
                {
 | 
			
		||||
                    await Context.Channel.SendConfirmAsync($"{Context.User.Mention} you don't have {amount}{NadekoBot.BotConfig.CurrencySign}!")
 | 
			
		||||
                            .ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    var msg = $"{Context.User.Mention} claimed {target.Mention} as their waifu for {amount}{NadekoBot.BotConfig.CurrencySign}!";
 | 
			
		||||
                    if (w.Affinity?.UserId == Context.User.Id)
 | 
			
		||||
                        msg += $"\n🎉 Their love is fulfilled! 🎉\n**{target}'s** new value is {w.Price}{NadekoBot.BotConfig.CurrencySign}!";
 | 
			
		||||
                    await Context.Channel.SendConfirmAsync(msg)
 | 
			
		||||
                            .ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public enum DivorceResult
 | 
			
		||||
            {
 | 
			
		||||
                Success,
 | 
			
		||||
                SucessWithPenalty,
 | 
			
		||||
                NotYourWife,
 | 
			
		||||
                Cooldown
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            private static readonly TimeSpan DivorceLimit = TimeSpan.FromHours(6);
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
            public async Task Divorce([Remainder]IUser target)
 | 
			
		||||
            {
 | 
			
		||||
                var channel = (ITextChannel)Context.Channel;
 | 
			
		||||
 | 
			
		||||
                if (target.Id == Context.User.Id)
 | 
			
		||||
                    return;
 | 
			
		||||
 | 
			
		||||
                var result = DivorceResult.NotYourWife;
 | 
			
		||||
                TimeSpan difference = TimeSpan.Zero;
 | 
			
		||||
                var amount = 0;
 | 
			
		||||
                WaifuInfo w = null;
 | 
			
		||||
                using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
                {
 | 
			
		||||
                    w = uow.Waifus.ByWaifuUserId(target.Id);
 | 
			
		||||
                    var now = DateTime.UtcNow;
 | 
			
		||||
                    if (w == null || w.Claimer == null || w.Claimer.UserId != Context.User.Id)
 | 
			
		||||
                        result = DivorceResult.NotYourWife;
 | 
			
		||||
                    else if (_divorceCooldowns.AddOrUpdate(Context.User.Id,
 | 
			
		||||
                        now,
 | 
			
		||||
                        (key, old) => ((difference = now.Subtract(old)) > DivorceLimit) ? now : old) != now)
 | 
			
		||||
                    {
 | 
			
		||||
                        result = DivorceResult.Cooldown;
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        amount = w.Price / 2;
 | 
			
		||||
 | 
			
		||||
                        if (w.Affinity?.UserId == Context.User.Id)
 | 
			
		||||
                        {
 | 
			
		||||
                            await CurrencyHandler.AddCurrencyAsync(w.Waifu.UserId, "Waifu Compensation", amount, uow).ConfigureAwait(false);
 | 
			
		||||
                            w.Price = (int)Math.Floor(w.Price * 0.75f);
 | 
			
		||||
                            result = DivorceResult.SucessWithPenalty;
 | 
			
		||||
                        }
 | 
			
		||||
                        else
 | 
			
		||||
                        {
 | 
			
		||||
                            await CurrencyHandler.AddCurrencyAsync(Context.User.Id, "Waifu Refund", amount, uow).ConfigureAwait(false);
 | 
			
		||||
 | 
			
		||||
                            result = DivorceResult.Success;
 | 
			
		||||
                        }
 | 
			
		||||
                        var oldClaimer = w.Claimer;
 | 
			
		||||
                        w.Claimer = null;
 | 
			
		||||
 | 
			
		||||
                        uow._context.WaifuUpdates.Add(new WaifuUpdate()
 | 
			
		||||
                        {
 | 
			
		||||
                            User = w.Waifu,
 | 
			
		||||
                            Old = oldClaimer,
 | 
			
		||||
                            New = null,
 | 
			
		||||
                            UpdateType = WaifuUpdateType.Claimed
 | 
			
		||||
                        });
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    await uow.CompleteAsync().ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (result == DivorceResult.SucessWithPenalty)
 | 
			
		||||
                {
 | 
			
		||||
                    await Context.Channel.SendConfirmAsync($"{Context.User.Mention} You have divorced a waifu who likes you. You heartless monster.\n{w.Waifu} received {amount}{NadekoBot.BotConfig.CurrencySign} as a compensation.").ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
                else if (result == DivorceResult.Success)
 | 
			
		||||
                {
 | 
			
		||||
                    await Context.Channel.SendConfirmAsync($"{Context.User.Mention} You have divorced a waifu who doesn't like you. You received {amount}{NadekoBot.BotConfig.CurrencySign} back.").ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
                else if (result == DivorceResult.NotYourWife)
 | 
			
		||||
                {
 | 
			
		||||
                    await Context.Channel.SendErrorAsync($"{Context.User.Mention} That waifu is not yours.").ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    var remaining = DivorceLimit.Subtract(difference);
 | 
			
		||||
                    await Context.Channel.SendErrorAsync($"{Context.User.Mention} You divorced recently. You must wait **{remaining.Hours} hours and {remaining.Minutes} minutes** to divorce again.").ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            private static readonly TimeSpan AffinityLimit = TimeSpan.FromMinutes(30);
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
            public async Task WaifuClaimerAffinity([Remainder]IUser u = null)
 | 
			
		||||
            {
 | 
			
		||||
                if (u?.Id == Context.User.Id)
 | 
			
		||||
                {
 | 
			
		||||
                    await Context.Channel.SendErrorAsync($"{Context.User.Mention} you can't set affinity to yourself, you egomaniac.").ConfigureAwait(false);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                DiscordUser oldAff = null;
 | 
			
		||||
                var sucess = false;
 | 
			
		||||
                var cooldown = false;
 | 
			
		||||
                TimeSpan difference = TimeSpan.Zero;
 | 
			
		||||
                using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
                {
 | 
			
		||||
                    var w = uow.Waifus.ByWaifuUserId(Context.User.Id);
 | 
			
		||||
                    var newAff = u == null ? null : uow.DiscordUsers.GetOrCreate(u);
 | 
			
		||||
                    var now = DateTime.UtcNow;
 | 
			
		||||
                    if (w?.Affinity?.UserId == u?.Id)
 | 
			
		||||
                    {
 | 
			
		||||
                        sucess = false;
 | 
			
		||||
                    }
 | 
			
		||||
                    else if (_affinityCooldowns.AddOrUpdate(Context.User.Id,
 | 
			
		||||
                        now,
 | 
			
		||||
                        (key, old) => ((difference = now.Subtract(old)) > AffinityLimit) ? now : old) != now)
 | 
			
		||||
                    {
 | 
			
		||||
                        sucess = false;
 | 
			
		||||
                        cooldown = true;
 | 
			
		||||
                    }
 | 
			
		||||
                    else if (w == null)
 | 
			
		||||
                    {
 | 
			
		||||
                        var thisUser = uow.DiscordUsers.GetOrCreate(Context.User);
 | 
			
		||||
                        uow.Waifus.Add(new WaifuInfo()
 | 
			
		||||
                        {
 | 
			
		||||
                            Affinity = newAff,
 | 
			
		||||
                            Waifu = thisUser,
 | 
			
		||||
                            Price = 1,
 | 
			
		||||
                            Claimer = null
 | 
			
		||||
                        });
 | 
			
		||||
                        sucess = true;
 | 
			
		||||
 | 
			
		||||
                        uow._context.WaifuUpdates.Add(new WaifuUpdate()
 | 
			
		||||
                        {
 | 
			
		||||
                            User = thisUser,
 | 
			
		||||
                            Old = null,
 | 
			
		||||
                            New = newAff,
 | 
			
		||||
                            UpdateType = WaifuUpdateType.AffinityChanged
 | 
			
		||||
                        });
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        if (w.Affinity != null)
 | 
			
		||||
                            oldAff = w.Affinity;
 | 
			
		||||
                        w.Affinity = newAff;
 | 
			
		||||
                        sucess = true;
 | 
			
		||||
 | 
			
		||||
                        uow._context.WaifuUpdates.Add(new WaifuUpdate()
 | 
			
		||||
                        {
 | 
			
		||||
                            User = w.Waifu,
 | 
			
		||||
                            Old = oldAff,
 | 
			
		||||
                            New = newAff,
 | 
			
		||||
                            UpdateType = WaifuUpdateType.AffinityChanged
 | 
			
		||||
                        });
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    await uow.CompleteAsync().ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
                if (!sucess)
 | 
			
		||||
                {
 | 
			
		||||
                    if (cooldown)
 | 
			
		||||
                    {
 | 
			
		||||
                        var remaining = AffinityLimit.Subtract(difference);
 | 
			
		||||
                        await Context.Channel.SendErrorAsync($"{Context.User.Mention} You must wait **{remaining.Hours} hours and {remaining.Minutes} minutes** in order to change your affinity again.").ConfigureAwait(false);
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                        await Context.Channel.SendErrorAsync($"{Context.User.Mention} your affinity is already set to that waifu or you're trying to remove your affinity while not having one.").ConfigureAwait(false);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                if (u == null)
 | 
			
		||||
                    await Context.Channel.SendConfirmAsync("Affinity Reset", $"{Context.User.Mention} Your affinity is reset. You no longer have a person you like.").ConfigureAwait(false);
 | 
			
		||||
                else if (oldAff == null)
 | 
			
		||||
                    await Context.Channel.SendConfirmAsync("Affinity Set", $"{Context.User.Mention} wants to be {u.Mention}'s waifu. Aww <3").ConfigureAwait(false);
 | 
			
		||||
                else
 | 
			
		||||
                    await Context.Channel.SendConfirmAsync("Affinity Changed", $"{Context.User.Mention} changed their affinity from {oldAff} to {u.Mention}.\n\n*This is morally questionable.*🤔").ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
            public async Task WaifuLeaderboard()
 | 
			
		||||
            {
 | 
			
		||||
                IList<WaifuInfo> waifus;
 | 
			
		||||
                using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
                {
 | 
			
		||||
                    waifus = uow.Waifus.GetTop(9);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (waifus.Count == 0)
 | 
			
		||||
                {
 | 
			
		||||
                    await Context.Channel.SendConfirmAsync("No waifus have been claimed yet.").ConfigureAwait(false);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                var embed = new EmbedBuilder()
 | 
			
		||||
                    .WithTitle("Top Waifus")
 | 
			
		||||
                    .WithOkColor();
 | 
			
		||||
 | 
			
		||||
                for (int i = 0; i < waifus.Count; i++)
 | 
			
		||||
                {
 | 
			
		||||
                    var w = waifus[i];
 | 
			
		||||
 | 
			
		||||
                    embed.AddField(efb => efb.WithName("#" + (i + 1) + " - " + w.Price + NadekoBot.BotConfig.CurrencySign).WithValue(w.ToString()).WithIsInline(false));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
            [RequireContext(ContextType.Guild)]
 | 
			
		||||
            public async Task WaifuInfo([Remainder]IUser target = null)
 | 
			
		||||
            {
 | 
			
		||||
                if (target == null)
 | 
			
		||||
                    target = Context.User;
 | 
			
		||||
                WaifuInfo w;
 | 
			
		||||
                IList<WaifuInfo> claims;
 | 
			
		||||
                int divorces = 0;
 | 
			
		||||
                using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
                {
 | 
			
		||||
                    w = uow.Waifus.ByWaifuUserId(target.Id);
 | 
			
		||||
                    claims = uow.Waifus.ByClaimerUserId(target.Id);
 | 
			
		||||
                    divorces = uow._context.WaifuUpdates.Count(x => x.Old != null &&
 | 
			
		||||
                        x.Old.UserId == target.Id &&
 | 
			
		||||
                        x.UpdateType == WaifuUpdateType.Claimed &&
 | 
			
		||||
                        x.New == null);
 | 
			
		||||
                    if (w == null)
 | 
			
		||||
                        uow.Waifus.Add(w = new WaifuInfo()
 | 
			
		||||
                        {
 | 
			
		||||
                            Affinity = null,
 | 
			
		||||
                            Claimer = null,
 | 
			
		||||
                            Price = 1,
 | 
			
		||||
                            Waifu = uow.DiscordUsers.GetOrCreate(target),
 | 
			
		||||
                        });
 | 
			
		||||
                    await uow.CompleteAsync().ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                var claimInfo = GetClaimTitle(target.Id);
 | 
			
		||||
                var affInfo = GetAffinityTitle(target.Id);
 | 
			
		||||
 | 
			
		||||
                var embed = new EmbedBuilder()
 | 
			
		||||
                    .WithOkColor()
 | 
			
		||||
                    .WithTitle("Waifu " + w.Waifu.ToString() + " - \"the " + claimInfo.Title + "\"")
 | 
			
		||||
                    .AddField(efb => efb.WithName("Price").WithValue(w.Price.ToString()).WithIsInline(true))
 | 
			
		||||
                    .AddField(efb => efb.WithName("Claimed by").WithValue(w.Claimer?.ToString() ?? "No one").WithIsInline(true))
 | 
			
		||||
                    .AddField(efb => efb.WithName("Likes").WithValue(w.Affinity?.ToString() ?? "Nobody").WithIsInline(true))
 | 
			
		||||
                    .AddField(efb => efb.WithName("Changes Of Heart").WithValue($"{affInfo.Count} - \"the {affInfo.Title}\"").WithIsInline(true))
 | 
			
		||||
                    .AddField(efb => efb.WithName("Divorces").WithValue(divorces.ToString()).WithIsInline(true))
 | 
			
		||||
                    .AddField(efb => efb.WithName($"Waifus ({claims.Count})").WithValue(claims.Count == 0 ? "Nobody" : string.Join("\n", claims.Select(x => x.Waifu))).WithIsInline(true));
 | 
			
		||||
 | 
			
		||||
                await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            public struct WaifuProfileTitle
 | 
			
		||||
            {
 | 
			
		||||
                public int Count { get; }
 | 
			
		||||
                public string Title { get; }
 | 
			
		||||
 | 
			
		||||
                public WaifuProfileTitle(int count, string title)
 | 
			
		||||
                {
 | 
			
		||||
                    Count = count;
 | 
			
		||||
                    Title = title;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            private static WaifuProfileTitle GetClaimTitle(ulong userId)
 | 
			
		||||
            {
 | 
			
		||||
                int count = 0;
 | 
			
		||||
                using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
                {
 | 
			
		||||
                    count = uow.Waifus.ByClaimerUserId(userId).Count;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                ClaimTitles title = ClaimTitles.Lonely;
 | 
			
		||||
                if (count == 0)
 | 
			
		||||
                    title = ClaimTitles.Lonely;
 | 
			
		||||
                else if (count == 1)
 | 
			
		||||
                    title = ClaimTitles.Devoted;
 | 
			
		||||
                else if (count < 4)
 | 
			
		||||
                    title = ClaimTitles.Rookie;
 | 
			
		||||
                else if (count < 6)
 | 
			
		||||
                    title = ClaimTitles.Schemer;
 | 
			
		||||
                else if (count < 8)
 | 
			
		||||
                    title = ClaimTitles.Dilettante;
 | 
			
		||||
                else if (count < 10)
 | 
			
		||||
                    title = ClaimTitles.Intermediate;
 | 
			
		||||
                else if (count < 12)
 | 
			
		||||
                    title = ClaimTitles.Seducer;
 | 
			
		||||
                else if (count < 15)
 | 
			
		||||
                    title = ClaimTitles.Expert;
 | 
			
		||||
                else if (count < 17)
 | 
			
		||||
                    title = ClaimTitles.Veteran;
 | 
			
		||||
                else if (count < 25)
 | 
			
		||||
                    title = ClaimTitles.Incubis;
 | 
			
		||||
                else if (count < 50)
 | 
			
		||||
                    title = ClaimTitles.Harem_King;
 | 
			
		||||
                else
 | 
			
		||||
                    title = ClaimTitles.Harem_God;
 | 
			
		||||
 | 
			
		||||
                return new WaifuProfileTitle(count, title.ToString().Replace('_', ' '));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            private static WaifuProfileTitle GetAffinityTitle(ulong userId)
 | 
			
		||||
            {
 | 
			
		||||
                int count = 0;
 | 
			
		||||
                using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
                {
 | 
			
		||||
                    count = uow._context.WaifuUpdates.Count(w => w.User.UserId == userId && w.UpdateType == WaifuUpdateType.AffinityChanged);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                AffinityTitles title = AffinityTitles.Pure;
 | 
			
		||||
                if (count < 1)
 | 
			
		||||
                    title = AffinityTitles.Pure;
 | 
			
		||||
                else if (count < 2)
 | 
			
		||||
                    title = AffinityTitles.Faithful;
 | 
			
		||||
                else if (count < 4)
 | 
			
		||||
                    title = AffinityTitles.Defiled;
 | 
			
		||||
                else if (count < 7)
 | 
			
		||||
                    title = AffinityTitles.Cheater;
 | 
			
		||||
                else if (count < 9)
 | 
			
		||||
                    title = AffinityTitles.Tainted;
 | 
			
		||||
                else if (count < 11)
 | 
			
		||||
                    title = AffinityTitles.Corrupted;
 | 
			
		||||
                else if (count < 13)
 | 
			
		||||
                    title = AffinityTitles.Lewd;
 | 
			
		||||
                else if (count < 15)
 | 
			
		||||
                    title = AffinityTitles.Sloot;
 | 
			
		||||
                else if (count < 17)
 | 
			
		||||
                    title = AffinityTitles.Depraved;
 | 
			
		||||
                else if (count < 20)
 | 
			
		||||
                    title = AffinityTitles.Harlot;
 | 
			
		||||
 | 
			
		||||
                return new WaifuProfileTitle(count, title.ToString().Replace('_', ' '));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -147,7 +147,7 @@ namespace NadekoBot.Modules.Gambling
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
        [OwnerOnly]
 | 
			
		||||
        public async Task BrTest(int tests = 1000)
 | 
			
		||||
        public Task BrTest(int tests = 1000)
 | 
			
		||||
        {
 | 
			
		||||
            var t = Task.Run(async () =>
 | 
			
		||||
            {
 | 
			
		||||
@@ -189,10 +189,15 @@ namespace NadekoBot.Modules.Gambling
 | 
			
		||||
                    sb.AppendLine($"x{key} occured {dict[key]} times. {dict[key] * 1.0f / tests * 100}%");
 | 
			
		||||
                    payout += key * dict[key];
 | 
			
		||||
                }
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    await Context.Channel.SendConfirmAsync("BetRoll Test Results", sb.ToString(),
 | 
			
		||||
                        footer: $"Total Bet: {tests * bet} | Payout: {payout * bet} | {payout * 1.0f / tests * 100}%");
 | 
			
		||||
                }
 | 
			
		||||
                catch { }
 | 
			
		||||
 | 
			
		||||
            });
 | 
			
		||||
            return Task.CompletedTask;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [NadekoCommand, Usage, Description, Aliases]
 | 
			
		||||
 
 | 
			
		||||
@@ -48,7 +48,7 @@ namespace NadekoBot.Modules.Utility
 | 
			
		||||
                keyword = keyword.ToUpperInvariant();
 | 
			
		||||
 | 
			
		||||
                Quote quote;
 | 
			
		||||
                using (var uow = DbHandler.Instance.GetUnitOfWork())
 | 
			
		||||
                using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
                {
 | 
			
		||||
                    quote = await uow.Quotes.GetRandomQuoteByKeywordAsync(Context.Guild.Id, keyword).ConfigureAwait(false);
 | 
			
		||||
                }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										135
									
								
								src/NadekoBot/Resources/CommandStrings.Designer.cs
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										135
									
								
								src/NadekoBot/Resources/CommandStrings.Designer.cs
									
									
									
										generated
									
									
									
								
							@@ -2489,6 +2489,33 @@ namespace NadekoBot.Resources {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        ///    Looks up a localized string similar to divorce.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public static string divorce_cmd {
 | 
			
		||||
            get {
 | 
			
		||||
                return ResourceManager.GetString("divorce_cmd", resourceCulture);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        ///    Looks up a localized string similar to Releases your claim on a specific waifu. You will get a part of your money back unless that waifu has an affinity towards you..
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public static string divorce_desc {
 | 
			
		||||
            get {
 | 
			
		||||
                return ResourceManager.GetString("divorce_desc", resourceCulture);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        ///    Looks up a localized string similar to `{0}divorce @CheatingSloot`.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public static string divorce_usage {
 | 
			
		||||
            get {
 | 
			
		||||
                return ResourceManager.GetString("divorce_usage", resourceCulture);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        ///    Looks up a localized string similar to donadd.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
@@ -8375,6 +8402,114 @@ namespace NadekoBot.Resources {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        ///    Looks up a localized string similar to claimwaifu claim.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public static string waifuclaim_cmd {
 | 
			
		||||
            get {
 | 
			
		||||
                return ResourceManager.GetString("waifuclaim_cmd", resourceCulture);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        ///    Looks up a localized string similar to Claim a waifu for yourself by spending currency.  You must spend atleast 10% more than her current value unless she set `{0}affinity` towards you..
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public static string waifuclaim_desc {
 | 
			
		||||
            get {
 | 
			
		||||
                return ResourceManager.GetString("waifuclaim_desc", resourceCulture);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        ///    Looks up a localized string similar to `{0}claim 50 @Himesama`.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public static string waifuclaim_usage {
 | 
			
		||||
            get {
 | 
			
		||||
                return ResourceManager.GetString("waifuclaim_usage", resourceCulture);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        ///    Looks up a localized string similar to affinity.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public static string waifuclaimeraffinity_cmd {
 | 
			
		||||
            get {
 | 
			
		||||
                return ResourceManager.GetString("waifuclaimeraffinity_cmd", resourceCulture);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        ///    Looks up a localized string similar to Sets your affinity towards someone you want to be claimed by. Setting affinity will reduce their `{0}claim` on you by 20%.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public static string waifuclaimeraffinity_desc {
 | 
			
		||||
            get {
 | 
			
		||||
                return ResourceManager.GetString("waifuclaimeraffinity_desc", resourceCulture);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        ///    Looks up a localized string similar to `{0}affinity`.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public static string waifuclaimeraffinity_usage {
 | 
			
		||||
            get {
 | 
			
		||||
                return ResourceManager.GetString("waifuclaimeraffinity_usage", resourceCulture);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        ///    Looks up a localized string similar to waifuinfo waifustats.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public static string waifuinfo_cmd {
 | 
			
		||||
            get {
 | 
			
		||||
                return ResourceManager.GetString("waifuinfo_cmd", resourceCulture);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        ///    Looks up a localized string similar to Shows waifu stats for a target person..
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public static string waifuinfo_desc {
 | 
			
		||||
            get {
 | 
			
		||||
                return ResourceManager.GetString("waifuinfo_desc", resourceCulture);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        ///    Looks up a localized string similar to `{0}waifuinfo @MyCrush`.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public static string waifuinfo_usage {
 | 
			
		||||
            get {
 | 
			
		||||
                return ResourceManager.GetString("waifuinfo_usage", resourceCulture);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        ///    Looks up a localized string similar to waifus waifulb.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public static string waifuleaderboard_cmd {
 | 
			
		||||
            get {
 | 
			
		||||
                return ResourceManager.GetString("waifuleaderboard_cmd", resourceCulture);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        ///    Looks up a localized string similar to Shows top 10 waifus..
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public static string waifuleaderboard_desc {
 | 
			
		||||
            get {
 | 
			
		||||
                return ResourceManager.GetString("waifuleaderboard_desc", resourceCulture);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        ///    Looks up a localized string similar to `{0}waifus`.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public static string waifuleaderboard_usage {
 | 
			
		||||
            get {
 | 
			
		||||
                return ResourceManager.GetString("waifuleaderboard_usage", resourceCulture);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        ///    Looks up a localized string similar to weather we.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
 
 | 
			
		||||
@@ -2979,4 +2979,49 @@
 | 
			
		||||
  <data name="slot_usage" xml:space="preserve">
 | 
			
		||||
    <value>`{0}slot 5`</value>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="waifuclaimeraffinity_cmd" xml:space="preserve">
 | 
			
		||||
    <value>affinity</value>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="waifuclaimeraffinity_desc" xml:space="preserve">
 | 
			
		||||
    <value>Sets your affinity towards someone you want to be claimed by. Setting affinity will reduce their `{0}claim` on you by 20%</value>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="waifuclaimeraffinity_usage" xml:space="preserve">
 | 
			
		||||
    <value>`{0}affinity`</value>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="waifuclaim_cmd" xml:space="preserve">
 | 
			
		||||
    <value>claimwaifu claim</value>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="waifuclaim_desc" xml:space="preserve">
 | 
			
		||||
    <value>Claim a waifu for yourself by spending currency.  You must spend atleast 10% more than her current value unless she set `{0}affinity` towards you.</value>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="waifuclaim_usage" xml:space="preserve">
 | 
			
		||||
    <value>`{0}claim 50 @Himesama`</value>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="waifuleaderboard_cmd" xml:space="preserve">
 | 
			
		||||
    <value>waifus waifulb</value>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="waifuleaderboard_desc" xml:space="preserve">
 | 
			
		||||
    <value>Shows top 10 waifus.</value>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="waifuleaderboard_usage" xml:space="preserve">
 | 
			
		||||
    <value>`{0}waifus`</value>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="divorce_cmd" xml:space="preserve">
 | 
			
		||||
    <value>divorce</value>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="divorce_desc" xml:space="preserve">
 | 
			
		||||
    <value>Releases your claim on a specific waifu. You will get a part of your money back unless that waifu has an affinity towards you.</value>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="divorce_usage" xml:space="preserve">
 | 
			
		||||
    <value>`{0}divorce @CheatingSloot`</value>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="waifuinfo_cmd" xml:space="preserve">
 | 
			
		||||
    <value>waifuinfo waifustats</value>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="waifuinfo_desc" xml:space="preserve">
 | 
			
		||||
    <value>Shows waifu stats for a target person.</value>
 | 
			
		||||
  </data>
 | 
			
		||||
  <data name="waifuinfo_usage" xml:space="preserve">
 | 
			
		||||
    <value>`{0}waifuinfo @MyCrush`</value>
 | 
			
		||||
  </data>
 | 
			
		||||
</root>
 | 
			
		||||
@@ -197,8 +197,10 @@ namespace NadekoBot.Services
 | 
			
		||||
                if (usrMsg == null) //has to be an user message, not system/other messages.
 | 
			
		||||
                    return;
 | 
			
		||||
 | 
			
		||||
#if !GLOBAL_NADEKO
 | 
			
		||||
                // track how many messagges each user is sending
 | 
			
		||||
                UserMessagesSent.AddOrUpdate(usrMsg.Author.Id, 1, (key, old) => ++old);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
                var channel = msg.Channel as SocketTextChannel;
 | 
			
		||||
                var guild = channel?.Guild;
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@ using Discord;
 | 
			
		||||
using NadekoBot.Extensions;
 | 
			
		||||
using NadekoBot.Modules.Gambling;
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
using NadekoBot.Services.Database;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Services
 | 
			
		||||
{
 | 
			
		||||
@@ -19,13 +20,26 @@ namespace NadekoBot.Services
 | 
			
		||||
            return success;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static async Task<bool> RemoveCurrencyAsync(ulong authorId, string reason, long amount)
 | 
			
		||||
        public static async Task<bool> RemoveCurrencyAsync(ulong authorId, string reason, long amount, IUnitOfWork uow = null)
 | 
			
		||||
        {
 | 
			
		||||
            if (amount < 0)
 | 
			
		||||
                throw new ArgumentNullException(nameof(amount));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
            if (uow == null)
 | 
			
		||||
            {
 | 
			
		||||
                using (uow = DbHandler.UnitOfWork())
 | 
			
		||||
                {
 | 
			
		||||
                    var toReturn = InternalRemoveCurrency(authorId, reason, amount, uow);
 | 
			
		||||
                    await uow.CompleteAsync().ConfigureAwait(false);
 | 
			
		||||
                    return toReturn;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return InternalRemoveCurrency(authorId, reason, amount, uow);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static bool InternalRemoveCurrency(ulong authorId, string reason, long amount, IUnitOfWork uow)
 | 
			
		||||
        {
 | 
			
		||||
            var success = uow.Currency.TryUpdateState(authorId, -amount);
 | 
			
		||||
            if (!success)
 | 
			
		||||
@@ -36,9 +50,6 @@ namespace NadekoBot.Services
 | 
			
		||||
                Reason = reason,
 | 
			
		||||
                Amount = -amount,
 | 
			
		||||
            });
 | 
			
		||||
                await uow.CompleteAsync().ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -50,23 +61,30 @@ namespace NadekoBot.Services
 | 
			
		||||
                try { await author.SendConfirmAsync($"`You received:` {amount} {NadekoBot.BotConfig.CurrencySign}\n`Reason:` {reason}").ConfigureAwait(false); } catch { }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static async Task AddCurrencyAsync(ulong receiverId, string reason, long amount)
 | 
			
		||||
        public static async Task AddCurrencyAsync(ulong receiverId, string reason, long amount, IUnitOfWork uow = null)
 | 
			
		||||
        {
 | 
			
		||||
            if (amount < 0)
 | 
			
		||||
                throw new ArgumentNullException(nameof(amount));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            using (var uow = DbHandler.UnitOfWork())
 | 
			
		||||
            {
 | 
			
		||||
                uow.Currency.TryUpdateState(receiverId, amount);
 | 
			
		||||
                uow.CurrencyTransactions.Add(new CurrencyTransaction()
 | 
			
		||||
            var transaction = new CurrencyTransaction()
 | 
			
		||||
            {
 | 
			
		||||
                UserId = receiverId,
 | 
			
		||||
                Reason = reason,
 | 
			
		||||
                Amount = amount,
 | 
			
		||||
                });
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            if (uow == null)
 | 
			
		||||
                using (uow = DbHandler.UnitOfWork())
 | 
			
		||||
                {
 | 
			
		||||
                    uow.Currency.TryUpdateState(receiverId, amount);
 | 
			
		||||
                    uow.CurrencyTransactions.Add(transaction);
 | 
			
		||||
                    await uow.CompleteAsync();
 | 
			
		||||
                }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                uow.Currency.TryUpdateState(receiverId, amount);
 | 
			
		||||
                uow.CurrencyTransactions.Add(transaction);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -21,6 +21,8 @@ namespace NadekoBot.Services.Database
 | 
			
		||||
        ICurrencyTransactionsRepository CurrencyTransactions { get; }
 | 
			
		||||
        IMusicPlaylistRepository MusicPlaylists { get; }
 | 
			
		||||
        IPokeGameRepository PokeGame { get; }
 | 
			
		||||
        IWaifuRepository Waifus { get; }
 | 
			
		||||
        IDiscordUserRepository DiscordUsers { get; }
 | 
			
		||||
 | 
			
		||||
        int Complete();
 | 
			
		||||
        Task<int> CompleteAsync();
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										19
									
								
								src/NadekoBot/Services/Database/Models/DiscordUser.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/NadekoBot/Services/Database/Models/DiscordUser.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class DiscordUser : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public ulong UserId { get; set; }
 | 
			
		||||
        public string Username { get; set; }
 | 
			
		||||
        public string Discriminator { get; set; }
 | 
			
		||||
        public string AvatarId { get; set; }
 | 
			
		||||
 | 
			
		||||
        public override string ToString() => 
 | 
			
		||||
            Username + "#" + Discriminator;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										49
									
								
								src/NadekoBot/Services/Database/Models/Waifu.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								src/NadekoBot/Services/Database/Models/Waifu.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
			
		||||
using NadekoBot.Extensions;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class WaifuInfo : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public int WaifuId { get; set; }
 | 
			
		||||
        public DiscordUser Waifu { get; set; }
 | 
			
		||||
 | 
			
		||||
        public int? ClaimerId { get; set; }
 | 
			
		||||
        public DiscordUser Claimer { get; set; }
 | 
			
		||||
 | 
			
		||||
        public int? AffinityId { get; set; }
 | 
			
		||||
        public DiscordUser Affinity { get; set; }
 | 
			
		||||
 | 
			
		||||
        public int Price { get; set; }
 | 
			
		||||
 | 
			
		||||
        public override string ToString()
 | 
			
		||||
        {
 | 
			
		||||
            var claimer = "no one";
 | 
			
		||||
            var status = "";
 | 
			
		||||
 | 
			
		||||
            var waifuUsername = Waifu.Username.TrimTo(20);
 | 
			
		||||
            var claimerUsername = Claimer?.Username.TrimTo(20);
 | 
			
		||||
 | 
			
		||||
            if (Claimer != null)
 | 
			
		||||
            {
 | 
			
		||||
                claimer = $"{ claimerUsername }#{Claimer.Discriminator}";
 | 
			
		||||
            }
 | 
			
		||||
            if (AffinityId == null)
 | 
			
		||||
            {
 | 
			
		||||
                status = $"... but {waifuUsername}'s heart is empty";
 | 
			
		||||
            }
 | 
			
		||||
            else if (AffinityId == ClaimerId)
 | 
			
		||||
            {
 | 
			
		||||
                status = $"... and {waifuUsername} likes {claimerUsername} too <3";
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                status = $"... but {waifuUsername}'s heart belongs to {Affinity.Username.TrimTo(20)}#{Affinity.Discriminator}";
 | 
			
		||||
            }
 | 
			
		||||
            return $"**{waifuUsername}#{Waifu.Discriminator}** - claimed by **{claimer}**\n\t{status}";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										27
									
								
								src/NadekoBot/Services/Database/Models/WaifuUpdate.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/NadekoBot/Services/Database/Models/WaifuUpdate.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Services.Database.Models
 | 
			
		||||
{
 | 
			
		||||
    public class WaifuUpdate : DbEntity
 | 
			
		||||
    {
 | 
			
		||||
        public int UserId { get; set; }
 | 
			
		||||
        public DiscordUser User { get; set; }
 | 
			
		||||
        public WaifuUpdateType UpdateType { get; set; }
 | 
			
		||||
 | 
			
		||||
        public int? OldId { get; set; }
 | 
			
		||||
        public DiscordUser Old { get; set; }
 | 
			
		||||
 | 
			
		||||
        public int? NewId { get; set; }
 | 
			
		||||
        public DiscordUser New { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public enum WaifuUpdateType
 | 
			
		||||
    {
 | 
			
		||||
        AffinityChanged,
 | 
			
		||||
        Claimed
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -3,9 +3,26 @@ using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
using NadekoBot.Extensions;
 | 
			
		||||
using Microsoft.EntityFrameworkCore.Infrastructure;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Services.Database
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    public class NadekoContextFactory : IDbContextFactory<NadekoContext>
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// :\ Used for migrations
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="options"></param>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        public NadekoContext Create(DbContextFactoryOptions options)
 | 
			
		||||
        {
 | 
			
		||||
            var optionsBuilder = new DbContextOptionsBuilder();
 | 
			
		||||
            optionsBuilder.UseSqlite("Filename=./data/NadekoBot.db");
 | 
			
		||||
            return new NadekoContext(optionsBuilder.Options);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class NadekoContext : DbContext
 | 
			
		||||
    {
 | 
			
		||||
        public DbSet<Quote> Quotes { get; set; }
 | 
			
		||||
@@ -22,6 +39,7 @@ namespace NadekoBot.Services.Database
 | 
			
		||||
        public DbSet<CustomReaction> CustomReactions { get; set; }
 | 
			
		||||
        public DbSet<CurrencyTransaction> CurrencyTransactions { get; set; }
 | 
			
		||||
        public DbSet<UserPokeTypes> PokeGame { get; set; }
 | 
			
		||||
        public DbSet<WaifuUpdate> WaifuUpdates { get; set; }
 | 
			
		||||
 | 
			
		||||
        //logging
 | 
			
		||||
        public DbSet<LogSetting> LogSettings { get; set; }
 | 
			
		||||
@@ -33,23 +51,15 @@ namespace NadekoBot.Services.Database
 | 
			
		||||
        public DbSet<RaceAnimal> RaceAnimals { get; set; }
 | 
			
		||||
        public DbSet<ModulePrefix> ModulePrefixes { get; set; }
 | 
			
		||||
 | 
			
		||||
        public NadekoContext()
 | 
			
		||||
        public NadekoContext() : base()
 | 
			
		||||
        {
 | 
			
		||||
            this.Database.Migrate();
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public NadekoContext(DbContextOptions options) : base(options)
 | 
			
		||||
        {
 | 
			
		||||
            this.Database.Migrate();
 | 
			
		||||
            EnsureSeedData();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ////Uncomment this to db initialisation with dotnet ef migration add [module]
 | 
			
		||||
        //protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
 | 
			
		||||
        //{
 | 
			
		||||
        //    optionsBuilder.UseSqlite("Filename=./data/NadekoBot.db");
 | 
			
		||||
        //}
 | 
			
		||||
 | 
			
		||||
        public void EnsureSeedData()
 | 
			
		||||
        {
 | 
			
		||||
            if (!BotConfig.Any())
 | 
			
		||||
@@ -244,6 +254,24 @@ namespace NadekoBot.Services.Database
 | 
			
		||||
            //    .HasIndex(cp => cp.CommandName)
 | 
			
		||||
            //    .IsUnique();
 | 
			
		||||
            #endregion
 | 
			
		||||
 | 
			
		||||
            #region Waifus
 | 
			
		||||
 | 
			
		||||
            var wi = modelBuilder.Entity<WaifuInfo>();
 | 
			
		||||
            wi.HasOne(x => x.Waifu)
 | 
			
		||||
                .WithOne();
 | 
			
		||||
            //    //.HasForeignKey<WaifuInfo>(w => w.WaifuId)
 | 
			
		||||
            //    //.IsRequired(true);
 | 
			
		||||
 | 
			
		||||
            //wi.HasOne(x => x.Claimer)
 | 
			
		||||
            //    .WithOne();
 | 
			
		||||
            //    //.HasForeignKey<WaifuInfo>(w => w.ClaimerId)
 | 
			
		||||
            //    //.IsRequired(false);
 | 
			
		||||
 | 
			
		||||
            var du = modelBuilder.Entity<DiscordUser>();
 | 
			
		||||
            du.HasAlternateKey(w => w.UserId);
 | 
			
		||||
 | 
			
		||||
            #endregion
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,15 @@
 | 
			
		||||
using Discord;
 | 
			
		||||
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 IDiscordUserRepository : IRepository<DiscordUser>
 | 
			
		||||
    {
 | 
			
		||||
        DiscordUser GetOrCreate(IUser original);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,13 @@
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Services.Database.Repositories
 | 
			
		||||
{
 | 
			
		||||
    public interface IWaifuRepository : IRepository<WaifuInfo>
 | 
			
		||||
    {
 | 
			
		||||
        IList<WaifuInfo> GetTop(int count);
 | 
			
		||||
        WaifuInfo ByWaifuUserId(ulong userId);
 | 
			
		||||
        IList<WaifuInfo> ByClaimerUserId(ulong userId);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,36 @@
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using Discord;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Services.Database.Repositories.Impl
 | 
			
		||||
{
 | 
			
		||||
    public class DiscordUserRepository : Repository<DiscordUser>, IDiscordUserRepository
 | 
			
		||||
    {
 | 
			
		||||
        public DiscordUserRepository(DbContext context) : base(context)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public DiscordUser GetOrCreate(IUser original)
 | 
			
		||||
        {
 | 
			
		||||
            DiscordUser toReturn;
 | 
			
		||||
 | 
			
		||||
            toReturn = _set.FirstOrDefault(u => u.UserId == original.Id);
 | 
			
		||||
 | 
			
		||||
            if (toReturn == null)
 | 
			
		||||
                _set.Add(toReturn = new DiscordUser()
 | 
			
		||||
                {
 | 
			
		||||
                    AvatarId = original.AvatarId,
 | 
			
		||||
                    Discriminator = original.Discriminator,
 | 
			
		||||
                    UserId = original.Id,
 | 
			
		||||
                    Username = original.Username,
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            return toReturn;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,49 @@
 | 
			
		||||
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 WaifuRepository : Repository<WaifuInfo>, IWaifuRepository
 | 
			
		||||
    {
 | 
			
		||||
        public WaifuRepository(DbContext context) : base(context)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public WaifuInfo ByWaifuUserId(ulong userId)
 | 
			
		||||
        {
 | 
			
		||||
            return _set.Include(wi => wi.Waifu)
 | 
			
		||||
                        .Include(wi => wi.Affinity)
 | 
			
		||||
                        .Include(wi => wi.Claimer)
 | 
			
		||||
                        .FirstOrDefault(wi => wi.Waifu.UserId == userId);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public IList<WaifuInfo> ByClaimerUserId(ulong userId)
 | 
			
		||||
        {
 | 
			
		||||
            return _set.Include(wi => wi.Waifu)
 | 
			
		||||
                        .Include(wi => wi.Affinity)
 | 
			
		||||
                        .Include(wi => wi.Claimer)
 | 
			
		||||
                        .Where(wi => wi.Claimer != null && wi.Claimer.UserId == userId)
 | 
			
		||||
                        .ToList();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public IList<WaifuInfo> GetTop(int count)
 | 
			
		||||
        {
 | 
			
		||||
            if (count < 0)
 | 
			
		||||
                throw new ArgumentOutOfRangeException(nameof(count));
 | 
			
		||||
            if (count == 0)
 | 
			
		||||
                return new List<WaifuInfo>();
 | 
			
		||||
 | 
			
		||||
            return _set.Include(wi => wi.Waifu)
 | 
			
		||||
                        .Include(wi => wi.Affinity)
 | 
			
		||||
                        .Include(wi => wi.Claimer)
 | 
			
		||||
                    .OrderByDescending(wi => wi.Price)
 | 
			
		||||
                    .Take(count)
 | 
			
		||||
                    .ToList();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -48,6 +48,12 @@ namespace NadekoBot.Services.Database
 | 
			
		||||
        private IPokeGameRepository _pokegame;
 | 
			
		||||
        public IPokeGameRepository PokeGame => _pokegame ?? (_pokegame = new PokeGameRepository(_context));
 | 
			
		||||
 | 
			
		||||
        private IWaifuRepository _waifus;
 | 
			
		||||
        public IWaifuRepository Waifus => _waifus ?? (_waifus = new WaifuRepository(_context));
 | 
			
		||||
 | 
			
		||||
        private IDiscordUserRepository _discordUsers;
 | 
			
		||||
        public IDiscordUserRepository DiscordUsers => _discordUsers ?? (_discordUsers = new DiscordUserRepository(_context));
 | 
			
		||||
 | 
			
		||||
        public UnitOfWork(NadekoContext context)
 | 
			
		||||
        {
 | 
			
		||||
            _context = context;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,6 @@
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using System;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using Microsoft.EntityFrameworkCore.Infrastructure;
 | 
			
		||||
using NadekoBot.Services.Database;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Services
 | 
			
		||||
@@ -13,7 +15,8 @@ namespace NadekoBot.Services
 | 
			
		||||
 | 
			
		||||
        static DbHandler() { }
 | 
			
		||||
 | 
			
		||||
        private DbHandler() {
 | 
			
		||||
        private DbHandler()
 | 
			
		||||
        {
 | 
			
		||||
            connectionString = NadekoBot.Credentials.Db.ConnectionString;
 | 
			
		||||
            var optionsBuilder = new DbContextOptionsBuilder();
 | 
			
		||||
            optionsBuilder.UseSqlite(NadekoBot.Credentials.Db.ConnectionString);
 | 
			
		||||
@@ -32,10 +35,16 @@ namespace NadekoBot.Services
 | 
			
		||||
            //}
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public NadekoContext GetDbContext() =>
 | 
			
		||||
            new NadekoContext(options);
 | 
			
		||||
        public NadekoContext GetDbContext()
 | 
			
		||||
        {
 | 
			
		||||
            var context = new NadekoContext(options);
 | 
			
		||||
            context.Database.Migrate();
 | 
			
		||||
            context.EnsureSeedData();
 | 
			
		||||
 | 
			
		||||
        public IUnitOfWork GetUnitOfWork() =>
 | 
			
		||||
            return context;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private IUnitOfWork GetUnitOfWork() =>
 | 
			
		||||
            new UnitOfWork(GetDbContext());
 | 
			
		||||
 | 
			
		||||
        public static IUnitOfWork UnitOfWork() =>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user