@ -1 +1 @@
|
||||
Subproject commit f27cce0854abc42b92d29f9040625238a8991999
|
||||
Subproject commit 58766448d79ac9adec228f341f258aa262a3f278
|
@ -125,6 +125,14 @@ Command and aliases | Description | Usage
|
||||
### Gambling
|
||||
Command and aliases | Description | Usage
|
||||
----------------|--------------|-------
|
||||
`$claimwaifu` `$claim` | Claim a waifu for yourself by spending currency. You must spend atleast 10% more than her current value unless she set `$affinity` towards you. | `$claim 50 @Himesama`
|
||||
`$divorce` | Releases your claim on a specific waifu. You will get some of the money you've spent back unless that waifu has an affinity towards you. 6 hours cooldown. | `$divorce @CheatingSloot`
|
||||
`$affinity` | Sets your affinity towards someone you want to be claimed by. Setting affinity will reduce their `$claim` on you by 20%. You can leave second argument empty to clear your affinity. 30 minutes cooldown. | `$affinity @MyHusband` or `$affinity`
|
||||
`$waifus` `$waifulb` | Shows top 9 waifus. | `$waifus`
|
||||
`$waifuinfo` `$waifustats` | Shows waifu stats for a target person. Defaults to you if no user is provided. | `$waifuinfo @MyCrush` or `$waifuinfo`
|
||||
`$slotstats` | Shows the total stats of the slot command for this bot's session. **Bot Owner only.** | `$slotstats`
|
||||
`$slottest` | Tests to see how much slots payout for X number of plays. **Bot Owner only.** | `$slottest 1000`
|
||||
`$slot` | Play Nadeko slots. Max bet is 999. 3 seconds cooldown per user. | `$slot 5`
|
||||
`$flip` | Flips coin(s) - heads or tails, and shows an image. | `$flip` or `$flip 3`
|
||||
`$betflip` `$bf` | Bet to guess will the result be heads or tails. Guessing awards you 1.8x the currency you've bet. | `$bf 5 heads` or `$bf 3 t`
|
||||
`$draw` | Draws a card from the deck.If you supply number X, she draws up to 5 cards from the deck. | `$draw` or `$draw 5`
|
||||
@ -132,6 +140,7 @@ Command and aliases | Description | Usage
|
||||
`$roll` | Rolls 0-100. If you supply a number [x] it rolls up to 30 normal dice. If you split 2 numbers with letter d (xdy) it will roll x dice from 1 to y. Y can be a letter 'F' if you want to roll fate dice instead of dnd. | `$roll` or `$roll 7` or `$roll 3d5` or `$roll 5dF`
|
||||
`$rolluo` | Rolls X normal dice (up to 30) unordered. If you split 2 numbers with letter d (xdy) it will roll x dice from 1 to y. | `$rolluo` or `$rolluo 7` or `$rolluo 3d5`
|
||||
`$nroll` | Rolls in a given range. | `$nroll 5` (rolls 0-5) or `$nroll 5-15`
|
||||
`$startevent` | Starts one of the events seen on public nadeko. **Bot Owner only.** | `$startevent flowerreaction`
|
||||
`$race` | Starts a new animal race. | `$race`
|
||||
`$joinrace` `$jr` | Joins a new race. You can specify an amount of currency for betting (optional). You will get YourBet*(participants-1) back if you win. | `$jr` or `$jr 5`
|
||||
`$raffle` | Prints a name and ID of a random user from the online list from the (optional) role. | `$raffle` or `$raffle RoleName`
|
||||
@ -206,7 +215,6 @@ Command and aliases | Description | Usage
|
||||
`!!localplaylst` `!!lopl` | Queues all songs from a directory. **Bot Owner only.** | `!!lopl C:/music/classical`
|
||||
`!!radio` `!!ra` | Queues a radio stream from a link. It can be a direct mp3 radio stream, .m3u, .pls .asx or .xspf (Usage Video: <https://streamable.com/al54>) | `!!ra radio link here`
|
||||
`!!local` `!!lo` | Queues a local file by specifying a full path. **Bot Owner only.** | `!!lo C:/music/mysong.mp3`
|
||||
`!!move` `!!mv` | Moves the bot to your voice channel. (works only if music is already playing) | `!!mv`
|
||||
`!!remove` `!!rm` | Remove a song by its # in the queue, or 'all' to remove whole queue. | `!!rm 5`
|
||||
`!!movesong` `!!ms` | Moves a song from one position to another. | `!!ms 5>3`
|
||||
`!!setmaxqueue` `!!smq` | Sets a maximum queue size. Supply 0 or no argument to have no limit. | `!!smq 50` or `!!smq`
|
||||
@ -226,7 +234,7 @@ Command and aliases | Description | Usage
|
||||
Command and aliases | Description | Usage
|
||||
----------------|--------------|-------
|
||||
`~hentai` | Shows a hentai image from a random website (gelbooru or danbooru or konachan or atfbooru or yandere) with a given tag. Tag is optional but preferred. Only 1 tag allowed. | `~hentai yuri`
|
||||
`~autohentai` | Posts a hentai every X seconds with a random tag from the provided tags. Use `|` to separate tags. 20 seconds minimum. Provide no arguments to disable. | `~autohentai 30 yuri|tail|long_hair` or `~autohentai`
|
||||
`~autohentai` | Posts a hentai every X seconds with a random tag from the provided tags. Use `|` to separate tags. 20 seconds minimum. Provide no arguments to disable. **Requires ManageMessages channel permission.** | `~autohentai 30 yuri|tail|long_hair` or `~autohentai`
|
||||
`~hentaibomb` | Shows a total 5 images (from gelbooru, danbooru, konachan, yandere and atfbooru). Tag is optional but preferred. | `~hentaibomb yuri`
|
||||
`~danbooru` | Shows a random hentai image from danbooru with a given tag. Tag is optional but preferred. (multiple tags are appended with +) | `~danbooru yuri+kissing`
|
||||
`~yandere` | Shows a random image from yandere with a given tag. Tag is optional but preferred. (multiple tags are appended with +) | `~yandere tag1+tag2`
|
||||
@ -249,6 +257,7 @@ Command and aliases | Description | Usage
|
||||
`;chnlfilterwords` `;cfw` | Toggles automatic deleting of messages containing banned words on the channel. Does not negate the ;srvrfilterwords enabled setting. Does not affect bot owner. | `;cfw`
|
||||
`;fw` | Adds or removes (if it exists) a word from the list of filtered words. Use`;sfw` or `;cfw` to toggle filtering. | `;fw poop`
|
||||
`;lstfilterwords` `;lfw` | Shows a list of filtered words. | `;lfw`
|
||||
`;cmdcosts` | Shows a list of command costs. Paginated with 9 command per page. | `;cmdcosts` or `;cmdcosts 2`
|
||||
`;cmdcooldown` `;cmdcd` | Sets a cooldown per user for a command. Set to 0 to remove the cooldown. | `;cmdcd "some cmd" 5`
|
||||
`;allcmdcooldowns` `;acmdcds` | Shows a list of all commands and their respective cooldowns. | `;acmdcds`
|
||||
`;ubl` | Either [add]s or [rem]oves a user specified by a mention or ID from a blacklist. **Bot Owner only.** | `;ubl add @SomeUser` or `;ubl rem 12312312313`
|
||||
|
@ -16,8 +16,8 @@ ________________________________________________________________________________
|
||||
####Guide
|
||||
- Make sure you have installed both [Git][Git] and the [.NET Core SDK][.NET Core SDK].
|
||||
- Create a **new folder** anywhere you like and name it `Nadeko`.
|
||||
- Next, [Right-Click on this link](https://github.com/Kwoth/NadekoBotInstallerWin/raw/master/NadekoInstaller.bat) and select **Save link as** and save the file `NadekoInstaller.bat` inside the `Nadeko` folder that we created earlier. (**DO NOT** rename the file `NadekoInstaller.bat`)
|
||||
- Once that's done, double-click on `NadekoInstaller.bat` to run it.
|
||||
- Next, [Right-Click on this link](https://github.com/Kwoth/NadekoBotInstallerWin/raw/master/NadekoInstaller.bat) and select **Save link as** and save the file `NadekoInstaller.bat` inside the `Nadeko` folder that we created earlier. (Please **DO NOT** rename the file `NadekoInstaller.bat`.)
|
||||
- Once that's done, right-click on `NadekoInstaller.bat` to run it as Administrator.
|
||||
- From the options,
|
||||
- Choose `1` to get the **most recent build**.
|
||||
- Choose `2` to get the **stable build**.
|
||||
@ -58,7 +58,7 @@ ________________________________________________________________________________
|
||||
- The bot should have been added to your server.
|
||||
|
||||
####Starting the bot
|
||||
- Go to the `Nadeko` folder that we have created earlier, and run the `NadekoInstaller.bat` file.
|
||||
- Go to the `Nadeko` folder that we have created earlier, and run the `NadekoInstaller.bat` file as Administrator.
|
||||
- From the options,
|
||||
- Choose `3` to **run the bot normally**.
|
||||
(with normal-run the bot will shutdown and will stay offline if it disconnects by the use of `.die` command until you manually run it again. Useful if you want to test the bot.)
|
||||
@ -83,6 +83,16 @@ ________________________________________________________________________________
|
||||
|
||||
In order to have a functioning music module, you need to install ffmpeg and setup api keys.
|
||||
|
||||
#### Setting up `ffmpeg` using NadekoBot Client!
|
||||
- Go to the `Nadeko` folder that we have created earlier, and run the `NadekoInstaller.bat` file as Administrator.
|
||||
- From the options select `6` Install ffmpeg (for music)
|
||||
- Next, **Press Any Key** if you are running as Administrator or just close and relaunch it as Administrator using mouse right-click.
|
||||
- Wait for it to finish installing and backing up existing.
|
||||
- Once done, you should see "ffmpeg Installation complete!".
|
||||
- Next, **Press Any Key** to go back to NadekoBot Client.
|
||||
- Press `3` to run the bot normally just to test music. (optional)
|
||||
- `ffmpeg` installation for Music is now complete.
|
||||
|
||||
#### Manual `ffmpeg` setup
|
||||
- Create a folder named `ffmpeg` in your main Windows directory. We will use **C:\ffmpeg** (for our guide)
|
||||
- Download FFMPEG through the link https://ffmpeg.zeranoe.com/builds/ (download static build)
|
||||
|
@ -12,7 +12,7 @@ namespace NadekoBot.Migrations
|
||||
name: "BetflipMultiplier",
|
||||
table: "BotConfig",
|
||||
nullable: false,
|
||||
defaultValue: 1.8f);
|
||||
defaultValue: 1.95f);
|
||||
|
||||
migrationBuilder.AddColumn<float>(
|
||||
name: "Betroll100Multiplier",
|
||||
@ -30,7 +30,7 @@ namespace NadekoBot.Migrations
|
||||
name: "Betroll91Multiplier",
|
||||
table: "BotConfig",
|
||||
nullable: false,
|
||||
defaultValue: 3f);
|
||||
defaultValue: 4f);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "CurrencyDropAmount",
|
||||
@ -42,7 +42,7 @@ namespace NadekoBot.Migrations
|
||||
name: "MinimumBetAmount",
|
||||
table: "BotConfig",
|
||||
nullable: false,
|
||||
defaultValue: 3);
|
||||
defaultValue: 2);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "TriviaCurrencyReward",
|
||||
|
988
src/NadekoBot/Migrations/20170118202307_ok-error-colors.Designer.cs
generated
Normal file
@ -0,0 +1,988 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using NadekoBot.Services.Database;
|
||||
using NadekoBot.Services.Database.Models;
|
||||
using NadekoBot.Modules.Music.Classes;
|
||||
|
||||
namespace NadekoBot.Migrations
|
||||
{
|
||||
[DbContext(typeof(NadekoContext))]
|
||||
[Migration("20170118202307_ok-error-colors")]
|
||||
partial class okerrorcolors
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "1.1.0-rtm-22752");
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiRaidSetting", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int>("Action");
|
||||
|
||||
b.Property<int>("GuildConfigId");
|
||||
|
||||
b.Property<int>("Seconds");
|
||||
|
||||
b.Property<int>("UserThreshold");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("AntiRaidSetting");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiSpamIgnore", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("AntiSpamSettingId");
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AntiSpamSettingId");
|
||||
|
||||
b.ToTable("AntiSpamIgnore");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiSpamSetting", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int>("Action");
|
||||
|
||||
b.Property<int>("GuildConfigId");
|
||||
|
||||
b.Property<int>("MessageThreshold");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("AntiSpamSetting");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.BlacklistItem", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<ulong>("ItemId");
|
||||
|
||||
b.Property<int>("Type");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("BlacklistItem");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.BotConfig", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<float>("BetflipMultiplier");
|
||||
|
||||
b.Property<float>("Betroll100Multiplier");
|
||||
|
||||
b.Property<float>("Betroll67Multiplier");
|
||||
|
||||
b.Property<float>("Betroll91Multiplier");
|
||||
|
||||
b.Property<ulong>("BufferSize");
|
||||
|
||||
b.Property<int>("CurrencyDropAmount");
|
||||
|
||||
b.Property<float>("CurrencyGenerationChance");
|
||||
|
||||
b.Property<int>("CurrencyGenerationCooldown");
|
||||
|
||||
b.Property<string>("CurrencyName");
|
||||
|
||||
b.Property<string>("CurrencyPluralName");
|
||||
|
||||
b.Property<string>("CurrencySign");
|
||||
|
||||
b.Property<string>("DMHelpString");
|
||||
|
||||
b.Property<string>("ErrorColor");
|
||||
|
||||
b.Property<bool>("ForwardMessages");
|
||||
|
||||
b.Property<bool>("ForwardToAllOwners");
|
||||
|
||||
b.Property<string>("HelpString");
|
||||
|
||||
b.Property<int>("MigrationVersion");
|
||||
|
||||
b.Property<int>("MinimumBetAmount");
|
||||
|
||||
b.Property<string>("OkColor");
|
||||
|
||||
b.Property<string>("RemindMessageFormat");
|
||||
|
||||
b.Property<bool>("RotatingStatuses");
|
||||
|
||||
b.Property<int>("TriviaCurrencyReward");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("BotConfig");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.ClashCaller", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<bool>("BaseDestroyed");
|
||||
|
||||
b.Property<string>("CallUser");
|
||||
|
||||
b.Property<int>("ClashWarId");
|
||||
|
||||
b.Property<int?>("SequenceNumber");
|
||||
|
||||
b.Property<int>("Stars");
|
||||
|
||||
b.Property<DateTime>("TimeAdded");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ClashWarId");
|
||||
|
||||
b.ToTable("ClashCallers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.ClashWar", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<string>("EnemyClan");
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<int>("Size");
|
||||
|
||||
b.Property<DateTime>("StartedAt");
|
||||
|
||||
b.Property<int>("WarState");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("ClashOfClans");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.CommandCooldown", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("CommandName");
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.Property<int>("Seconds");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("CommandCooldown");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.CommandPrice", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<string>("CommandName");
|
||||
|
||||
b.Property<int>("Price");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.HasIndex("Price")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("CommandPrice");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.ConvertUnit", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("InternalTrigger");
|
||||
|
||||
b.Property<decimal>("Modifier");
|
||||
|
||||
b.Property<string>("UnitType");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("ConversionUnits");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.Currency", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<long>("Amount");
|
||||
|
||||
b.Property<ulong>("UserId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Currency");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.CurrencyTransaction", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<long>("Amount");
|
||||
|
||||
b.Property<string>("Reason");
|
||||
|
||||
b.Property<ulong>("UserId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("CurrencyTransactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.CustomReaction", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong?>("GuildId");
|
||||
|
||||
b.Property<bool>("IsRegex");
|
||||
|
||||
b.Property<bool>("OwnerOnly");
|
||||
|
||||
b.Property<string>("Response");
|
||||
|
||||
b.Property<string>("Trigger");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("CustomReactions");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.Donator", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int>("Amount");
|
||||
|
||||
b.Property<string>("Name");
|
||||
|
||||
b.Property<ulong>("UserId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Donators");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.EightBallResponse", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<string>("Text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("EightBallResponses");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.FilterChannelId", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.Property<int?>("GuildConfigId1");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.HasIndex("GuildConfigId1");
|
||||
|
||||
b.ToTable("FilterChannelId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.FilteredWord", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.Property<string>("Word");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("FilteredWord");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.FollowedStream", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<int>("Type");
|
||||
|
||||
b.Property<string>("Username");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("FollowedStream");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.GCChannelId", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("GCChannelId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.GuildConfig", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("AutoAssignRoleId");
|
||||
|
||||
b.Property<bool>("AutoDeleteByeMessages");
|
||||
|
||||
b.Property<int>("AutoDeleteByeMessagesTimer");
|
||||
|
||||
b.Property<bool>("AutoDeleteGreetMessages");
|
||||
|
||||
b.Property<int>("AutoDeleteGreetMessagesTimer");
|
||||
|
||||
b.Property<bool>("AutoDeleteSelfAssignedRoleMessages");
|
||||
|
||||
b.Property<ulong>("ByeMessageChannelId");
|
||||
|
||||
b.Property<string>("ChannelByeMessageText");
|
||||
|
||||
b.Property<string>("ChannelGreetMessageText");
|
||||
|
||||
b.Property<bool>("CleverbotEnabled");
|
||||
|
||||
b.Property<float>("DefaultMusicVolume");
|
||||
|
||||
b.Property<bool>("DeleteMessageOnCommand");
|
||||
|
||||
b.Property<string>("DmGreetMessageText");
|
||||
|
||||
b.Property<bool>("ExclusiveSelfAssignedRoles");
|
||||
|
||||
b.Property<bool>("FilterInvites");
|
||||
|
||||
b.Property<bool>("FilterWords");
|
||||
|
||||
b.Property<ulong>("GreetMessageChannelId");
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<int?>("LogSettingId");
|
||||
|
||||
b.Property<string>("MuteRoleName");
|
||||
|
||||
b.Property<string>("PermissionRole");
|
||||
|
||||
b.Property<int?>("RootPermissionId");
|
||||
|
||||
b.Property<bool>("SendChannelByeMessage");
|
||||
|
||||
b.Property<bool>("SendChannelGreetMessage");
|
||||
|
||||
b.Property<bool>("SendDmGreetMessage");
|
||||
|
||||
b.Property<bool>("VerbosePermissions");
|
||||
|
||||
b.Property<bool>("VoicePlusTextEnabled");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildId")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("LogSettingId");
|
||||
|
||||
b.HasIndex("RootPermissionId");
|
||||
|
||||
b.ToTable("GuildConfigs");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.GuildRepeater", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<TimeSpan>("Interval");
|
||||
|
||||
b.Property<string>("Message");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("GuildRepeater");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredLogChannel", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("LogSettingId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("LogSettingId");
|
||||
|
||||
b.ToTable("IgnoredLogChannels");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredVoicePresenceChannel", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<int?>("LogSettingId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("LogSettingId");
|
||||
|
||||
b.ToTable("IgnoredVoicePresenceCHannels");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.LogSetting", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<bool>("ChannelCreated");
|
||||
|
||||
b.Property<ulong?>("ChannelCreatedId");
|
||||
|
||||
b.Property<bool>("ChannelDestroyed");
|
||||
|
||||
b.Property<ulong?>("ChannelDestroyedId");
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<bool>("ChannelUpdated");
|
||||
|
||||
b.Property<ulong?>("ChannelUpdatedId");
|
||||
|
||||
b.Property<bool>("IsLogging");
|
||||
|
||||
b.Property<ulong?>("LogOtherId");
|
||||
|
||||
b.Property<bool>("LogUserPresence");
|
||||
|
||||
b.Property<ulong?>("LogUserPresenceId");
|
||||
|
||||
b.Property<bool>("LogVoicePresence");
|
||||
|
||||
b.Property<ulong?>("LogVoicePresenceId");
|
||||
|
||||
b.Property<ulong?>("LogVoicePresenceTTSId");
|
||||
|
||||
b.Property<bool>("MessageDeleted");
|
||||
|
||||
b.Property<ulong?>("MessageDeletedId");
|
||||
|
||||
b.Property<bool>("MessageUpdated");
|
||||
|
||||
b.Property<ulong?>("MessageUpdatedId");
|
||||
|
||||
b.Property<bool>("UserBanned");
|
||||
|
||||
b.Property<ulong?>("UserBannedId");
|
||||
|
||||
b.Property<bool>("UserJoined");
|
||||
|
||||
b.Property<ulong?>("UserJoinedId");
|
||||
|
||||
b.Property<bool>("UserLeft");
|
||||
|
||||
b.Property<ulong?>("UserLeftId");
|
||||
|
||||
b.Property<ulong?>("UserMutedId");
|
||||
|
||||
b.Property<ulong>("UserPresenceChannelId");
|
||||
|
||||
b.Property<bool>("UserUnbanned");
|
||||
|
||||
b.Property<ulong?>("UserUnbannedId");
|
||||
|
||||
b.Property<bool>("UserUpdated");
|
||||
|
||||
b.Property<ulong?>("UserUpdatedId");
|
||||
|
||||
b.Property<ulong>("VoicePresenceChannelId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("LogSettings");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.ModulePrefix", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<string>("ModuleName");
|
||||
|
||||
b.Property<string>("Prefix");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("ModulePrefixes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.MusicPlaylist", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("Author");
|
||||
|
||||
b.Property<ulong>("AuthorId");
|
||||
|
||||
b.Property<string>("Name");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("MusicPlaylists");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.MutedUserId", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("GuildConfigId");
|
||||
|
||||
b.Property<ulong>("UserId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildConfigId");
|
||||
|
||||
b.ToTable("MutedUserId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.Permission", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("NextId");
|
||||
|
||||
b.Property<int>("PrimaryTarget");
|
||||
|
||||
b.Property<ulong>("PrimaryTargetId");
|
||||
|
||||
b.Property<int>("SecondaryTarget");
|
||||
|
||||
b.Property<string>("SecondaryTargetName");
|
||||
|
||||
b.Property<bool>("State");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NextId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("Permission");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.PlayingStatus", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<string>("Status");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("PlayingStatus");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.PlaylistSong", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("MusicPlaylistId");
|
||||
|
||||
b.Property<string>("Provider");
|
||||
|
||||
b.Property<int>("ProviderType");
|
||||
|
||||
b.Property<string>("Query");
|
||||
|
||||
b.Property<string>("Title");
|
||||
|
||||
b.Property<string>("Uri");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("MusicPlaylistId");
|
||||
|
||||
b.ToTable("PlaylistSong");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.Quote", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("AuthorId");
|
||||
|
||||
b.Property<string>("AuthorName")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<string>("Keyword")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<string>("Text")
|
||||
.IsRequired();
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Quotes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.RaceAnimal", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int?>("BotConfigId");
|
||||
|
||||
b.Property<string>("Icon");
|
||||
|
||||
b.Property<string>("Name");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BotConfigId");
|
||||
|
||||
b.ToTable("RaceAnimals");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.Reminder", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("ChannelId");
|
||||
|
||||
b.Property<bool>("IsPrivate");
|
||||
|
||||
b.Property<string>("Message");
|
||||
|
||||
b.Property<ulong>("ServerId");
|
||||
|
||||
b.Property<ulong>("UserId");
|
||||
|
||||
b.Property<DateTime>("When");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Reminders");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.SelfAssignedRole", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("GuildId");
|
||||
|
||||
b.Property<ulong>("RoleId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GuildId", "RoleId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("SelfAssignableRoles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.UserPokeTypes", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<ulong>("UserId");
|
||||
|
||||
b.Property<string>("type");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId")
|
||||
.IsUnique();
|
||||
|
||||
b.ToTable("PokeGame");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiRaidSetting", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Services.Database.Models.GuildConfig", "GuildConfig")
|
||||
.WithOne("AntiRaidSetting")
|
||||
.HasForeignKey("NadekoBot.Services.Database.Models.AntiRaidSetting", "GuildConfigId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiSpamIgnore", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Services.Database.Models.AntiSpamSetting")
|
||||
.WithMany("IgnoredChannels")
|
||||
.HasForeignKey("AntiSpamSettingId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiSpamSetting", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Services.Database.Models.GuildConfig", "GuildConfig")
|
||||
.WithOne("AntiSpamSetting")
|
||||
.HasForeignKey("NadekoBot.Services.Database.Models.AntiSpamSetting", "GuildConfigId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
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.CommandCooldown", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Services.Database.Models.GuildConfig")
|
||||
.WithMany("CommandCooldowns")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.CommandPrice", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Services.Database.Models.BotConfig")
|
||||
.WithMany("CommandPrices")
|
||||
.HasForeignKey("BotConfigId");
|
||||
});
|
||||
|
||||
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.FilterChannelId", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Services.Database.Models.GuildConfig")
|
||||
.WithMany("FilterInvitesChannelIds")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
|
||||
b.HasOne("NadekoBot.Services.Database.Models.GuildConfig")
|
||||
.WithMany("FilterWordsChannelIds")
|
||||
.HasForeignKey("GuildConfigId1");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.FilteredWord", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Services.Database.Models.GuildConfig")
|
||||
.WithMany("FilteredWords")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.FollowedStream", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Services.Database.Models.GuildConfig")
|
||||
.WithMany("FollowedStreams")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.GCChannelId", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Services.Database.Models.GuildConfig")
|
||||
.WithMany("GenerateCurrencyChannelIds")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.GuildConfig", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Services.Database.Models.LogSetting", "LogSetting")
|
||||
.WithMany()
|
||||
.HasForeignKey("LogSettingId");
|
||||
|
||||
b.HasOne("NadekoBot.Services.Database.Models.Permission", "RootPermission")
|
||||
.WithMany()
|
||||
.HasForeignKey("RootPermissionId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.GuildRepeater", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Services.Database.Models.GuildConfig")
|
||||
.WithMany("GuildRepeaters")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredLogChannel", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Services.Database.Models.LogSetting", "LogSetting")
|
||||
.WithMany("IgnoredChannels")
|
||||
.HasForeignKey("LogSettingId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredVoicePresenceChannel", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Services.Database.Models.LogSetting", "LogSetting")
|
||||
.WithMany("IgnoredVoicePresenceChannelIds")
|
||||
.HasForeignKey("LogSettingId");
|
||||
});
|
||||
|
||||
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.MutedUserId", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Services.Database.Models.GuildConfig")
|
||||
.WithMany("MutedUsers")
|
||||
.HasForeignKey("GuildConfigId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.Permission", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Services.Database.Models.Permission", "Next")
|
||||
.WithOne("Previous")
|
||||
.HasForeignKey("NadekoBot.Services.Database.Models.Permission", "NextId");
|
||||
});
|
||||
|
||||
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.PlaylistSong", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Services.Database.Models.MusicPlaylist")
|
||||
.WithMany("Songs")
|
||||
.HasForeignKey("MusicPlaylistId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.RaceAnimal", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Services.Database.Models.BotConfig")
|
||||
.WithMany("RaceAnimals")
|
||||
.HasForeignKey("BotConfigId");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
35
src/NadekoBot/Migrations/20170118202307_ok-error-colors.cs
Normal file
@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
namespace NadekoBot.Migrations
|
||||
{
|
||||
public partial class okerrorcolors : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "ErrorColor",
|
||||
table: "BotConfig",
|
||||
nullable: false,
|
||||
defaultValue: "ee281f");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "OkColor",
|
||||
table: "BotConfig",
|
||||
nullable: false,
|
||||
defaultValue: "71cd40");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "ErrorColor",
|
||||
table: "BotConfig");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "OkColor",
|
||||
table: "BotConfig");
|
||||
}
|
||||
}
|
||||
}
|
1089
src/NadekoBot/Migrations/20170122044958_waifus.Designer.cs
generated
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");
|
||||
}
|
||||
}
|
||||
}
|
@ -4,6 +4,8 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using NadekoBot.Services.Database;
|
||||
using NadekoBot.Services.Database.Models;
|
||||
using NadekoBot.Modules.Music.Classes;
|
||||
|
||||
namespace NadekoBot.Migrations
|
||||
{
|
||||
@ -118,6 +120,8 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.Property<string>("DMHelpString");
|
||||
|
||||
b.Property<string>("ErrorColor");
|
||||
|
||||
b.Property<bool>("ForwardMessages");
|
||||
|
||||
b.Property<bool>("ForwardToAllOwners");
|
||||
@ -128,6 +132,8 @@ namespace NadekoBot.Migrations
|
||||
|
||||
b.Property<int>("MinimumBetAmount");
|
||||
|
||||
b.Property<string>("OkColor");
|
||||
|
||||
b.Property<string>("RemindMessageFormat");
|
||||
|
||||
b.Property<bool>("RotatingStatuses");
|
||||
@ -293,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")
|
||||
@ -811,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")
|
||||
@ -976,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);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ namespace NadekoBot.Modules.Gambling
|
||||
str = $"{Context.User.Mention}`Better luck next time.`";
|
||||
}
|
||||
|
||||
await Context.Channel.SendFileAsync(File.Open(imgPathToSend, FileMode.OpenOrCreate), "coin.jpg", str).ConfigureAwait(false);
|
||||
await Context.Channel.SendFileAsync(File.Open(imgPathToSend, FileMode.OpenOrCreate), new FileInfo(imgPathToSend).Name, str).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
304
src/NadekoBot/Modules/Gambling/Commands/Slots.cs
Normal file
@ -0,0 +1,304 @@
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
using NadekoBot.Attributes;
|
||||
using NadekoBot.Extensions;
|
||||
using NadekoBot.Services;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Modules.Gambling
|
||||
{
|
||||
public partial class Gambling
|
||||
{
|
||||
[Group]
|
||||
public class Slots : ModuleBase
|
||||
{
|
||||
private static int totalBet = 0;
|
||||
private static int totalPaidOut = 0;
|
||||
|
||||
private const string backgroundPath = "data/slots/background.png";
|
||||
|
||||
private static readonly byte[] backgroundBuffer;
|
||||
private static readonly byte[][] numbersBuffer = new byte[10][];
|
||||
private static readonly byte[][] emojiBuffer;
|
||||
|
||||
const int alphaCutOut = byte.MaxValue / 3;
|
||||
|
||||
static Slots()
|
||||
{
|
||||
backgroundBuffer = File.ReadAllBytes(backgroundPath);
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
numbersBuffer[i] = File.ReadAllBytes("data/slots/" + i + ".png");
|
||||
}
|
||||
int throwaway;
|
||||
var emojiFiles = Directory.GetFiles("data/slots/emojis/", "*.png")
|
||||
.Where(f => int.TryParse(Path.GetFileNameWithoutExtension(f), out throwaway))
|
||||
.OrderBy(f => int.Parse(Path.GetFileNameWithoutExtension(f)))
|
||||
.ToArray();
|
||||
|
||||
emojiBuffer = new byte[emojiFiles.Length][];
|
||||
for (int i = 0; i < emojiFiles.Length; i++)
|
||||
{
|
||||
emojiBuffer[i] = File.ReadAllBytes(emojiFiles[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static MemoryStream InternalGetStream(string path)
|
||||
{
|
||||
var ms = new MemoryStream();
|
||||
using (var fs = File.Open(path, FileMode.Open))
|
||||
{
|
||||
fs.CopyTo(ms);
|
||||
fs.Flush();
|
||||
}
|
||||
ms.Position = 0;
|
||||
return ms;
|
||||
}
|
||||
|
||||
//here is a payout chart
|
||||
//https://lh6.googleusercontent.com/-i1hjAJy_kN4/UswKxmhrbPI/AAAAAAAAB1U/82wq_4ZZc-Y/DE6B0895-6FC1-48BE-AC4F-14D1B91AB75B.jpg
|
||||
//thanks to judge for helping me with this
|
||||
|
||||
public class SlotMachine
|
||||
{
|
||||
public const int MaxValue = 5;
|
||||
|
||||
static readonly List<Func<int[], int>> winningCombos = new List<Func<int[], int>>()
|
||||
{
|
||||
//three flowers
|
||||
(arr) => arr.All(a=>a==MaxValue) ? 30 : 0,
|
||||
//three of the same
|
||||
(arr) => !arr.Any(a => a != arr[0]) ? 10 : 0,
|
||||
//two flowers
|
||||
(arr) => arr.Count(a => a == MaxValue) == 2 ? 4 : 0,
|
||||
//one flower
|
||||
(arr) => arr.Any(a => a == MaxValue) ? 1 : 0,
|
||||
};
|
||||
|
||||
public static SlotResult Pull()
|
||||
{
|
||||
var numbers = new int[3];
|
||||
for (int i = 0; i < numbers.Length; i++)
|
||||
{
|
||||
numbers[i] = new NadekoRandom().Next(0, MaxValue + 1);
|
||||
}
|
||||
int multi = 0;
|
||||
for (int i = 0; i < winningCombos.Count; i++)
|
||||
{
|
||||
multi = winningCombos[i](numbers);
|
||||
if (multi != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return new SlotResult(numbers, multi);
|
||||
}
|
||||
|
||||
public struct SlotResult
|
||||
{
|
||||
public int[] Numbers { get; }
|
||||
public int Multiplier { get; }
|
||||
public SlotResult(int[] nums, int multi)
|
||||
{
|
||||
this.Numbers = nums;
|
||||
this.Multiplier = multi;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[OwnerOnly]
|
||||
public async Task SlotStats()
|
||||
{
|
||||
//i remembered to not be a moron
|
||||
var paid = totalPaidOut;
|
||||
var bet = totalBet;
|
||||
|
||||
if (bet <= 0)
|
||||
bet = 1;
|
||||
|
||||
var embed = new EmbedBuilder()
|
||||
.WithOkColor()
|
||||
.WithTitle("Slot Stats")
|
||||
.AddField(efb => efb.WithName("Total Bet").WithValue(bet.ToString()).WithIsInline(true))
|
||||
.AddField(efb => efb.WithName("Paid Out").WithValue(paid.ToString()).WithIsInline(true))
|
||||
.WithFooter(efb => efb.WithText($"Payout Rate: {paid * 1.0 / bet * 100:f4}%"));
|
||||
|
||||
await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[OwnerOnly]
|
||||
public async Task SlotTest(int tests = 1000)
|
||||
{
|
||||
if (tests <= 0)
|
||||
return;
|
||||
//multi vs how many times it occured
|
||||
var dict = new Dictionary<int, int>();
|
||||
for (int i = 0; i < tests; i++)
|
||||
{
|
||||
var res = SlotMachine.Pull();
|
||||
if (dict.ContainsKey(res.Multiplier))
|
||||
dict[res.Multiplier] += 1;
|
||||
else
|
||||
dict.Add(res.Multiplier, 1);
|
||||
}
|
||||
|
||||
var sb = new StringBuilder();
|
||||
const int bet = 1;
|
||||
int payout = 0;
|
||||
foreach (var key in dict.Keys.OrderByDescending(x=>x))
|
||||
{
|
||||
sb.AppendLine($"x{key} occured {dict[key]} times. {dict[key] * 1.0f / tests * 100}%");
|
||||
payout += key * dict[key];
|
||||
}
|
||||
await Context.Channel.SendConfirmAsync("Slot Test Results", sb.ToString(),
|
||||
footer: $"Total Bet: {tests * bet} | Payout: {payout * bet} | {payout * 1.0f / tests * 100}%");
|
||||
}
|
||||
|
||||
static HashSet<ulong> runningUsers = new HashSet<ulong>();
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
public async Task Slot(int amount = 0)
|
||||
{
|
||||
if (!runningUsers.Add(Context.User.Id))
|
||||
return;
|
||||
try
|
||||
{
|
||||
if (amount < 1)
|
||||
{
|
||||
await Context.Channel.SendErrorAsync($"You can't bet less than 1{NadekoBot.BotConfig.CurrencySign}").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (amount > 999)
|
||||
{
|
||||
await Context.Channel.SendErrorAsync($"You can't bet more than 999{NadekoBot.BotConfig.CurrencySign}").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!await CurrencyHandler.RemoveCurrencyAsync(Context.User, "Slot Machine", amount, false))
|
||||
{
|
||||
await Context.Channel.SendErrorAsync($"You don't have enough {NadekoBot.BotConfig.CurrencySign}.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
Interlocked.Add(ref totalBet, amount);
|
||||
using (var bgFileStream = new MemoryStream(backgroundBuffer))
|
||||
{
|
||||
var bgImage = new ImageSharp.Image(bgFileStream);
|
||||
|
||||
var result = SlotMachine.Pull();
|
||||
int[] numbers = result.Numbers;
|
||||
using (var bgPixels = bgImage.Lock())
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
using (var file = new MemoryStream(emojiBuffer[numbers[i]]))
|
||||
{
|
||||
var randomImage = new ImageSharp.Image(file);
|
||||
using (var toAdd = randomImage.Lock())
|
||||
{
|
||||
for (int j = 0; j < toAdd.Width; j++)
|
||||
{
|
||||
for (int k = 0; k < toAdd.Height; k++)
|
||||
{
|
||||
var x = 95 + 142 * i + j;
|
||||
int y = 330 + k;
|
||||
var toSet = toAdd[j, k];
|
||||
if (toSet.A < alphaCutOut)
|
||||
continue;
|
||||
bgPixels[x, y] = toAdd[j, k];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var won = amount * result.Multiplier;
|
||||
var printWon = won;
|
||||
var n = 0;
|
||||
do
|
||||
{
|
||||
var digit = printWon % 10;
|
||||
using (var fs = new MemoryStream(numbersBuffer[digit]))
|
||||
{
|
||||
var img = new ImageSharp.Image(fs);
|
||||
using (var pixels = img.Lock())
|
||||
{
|
||||
for (int i = 0; i < pixels.Width; i++)
|
||||
{
|
||||
for (int j = 0; j < pixels.Height; j++)
|
||||
{
|
||||
if (pixels[i, j].A < alphaCutOut)
|
||||
continue;
|
||||
var x = 230 - n * 16 + i;
|
||||
bgPixels[x, 462 + j] = pixels[i, j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
n++;
|
||||
} while ((printWon /= 10) != 0);
|
||||
|
||||
var printAmount = amount;
|
||||
n = 0;
|
||||
do
|
||||
{
|
||||
var digit = printAmount % 10;
|
||||
using (var fs = new MemoryStream(numbersBuffer[digit]))
|
||||
{
|
||||
var img = new ImageSharp.Image(fs);
|
||||
using (var pixels = img.Lock())
|
||||
{
|
||||
for (int i = 0; i < pixels.Width; i++)
|
||||
{
|
||||
for (int j = 0; j < pixels.Height; j++)
|
||||
{
|
||||
if (pixels[i, j].A < alphaCutOut)
|
||||
continue;
|
||||
var x = 395 - n * 16 + i;
|
||||
bgPixels[x, 462 + j] = pixels[i, j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
n++;
|
||||
} while ((printAmount /= 10) != 0);
|
||||
}
|
||||
|
||||
var msg = "Better luck next time ^_^";
|
||||
if (result.Multiplier != 0)
|
||||
{
|
||||
await CurrencyHandler.AddCurrencyAsync(Context.User, $"Slot Machine x{result.Multiplier}", amount * result.Multiplier, false);
|
||||
Interlocked.Add(ref totalPaidOut, amount * result.Multiplier);
|
||||
if (result.Multiplier == 1)
|
||||
msg = $"A single {NadekoBot.BotConfig.CurrencySign}, x1 - Try again!";
|
||||
else if (result.Multiplier == 4)
|
||||
msg = $"Good job! Two {NadekoBot.BotConfig.CurrencySign} - bet x4";
|
||||
else if (result.Multiplier == 10)
|
||||
msg = "Wow! Lucky! Three of a kind! x10";
|
||||
else if (result.Multiplier == 30)
|
||||
msg = "WOAAHHHHHH!!! Congratulations!!! x30";
|
||||
}
|
||||
|
||||
await Context.Channel.SendFileAsync(bgImage.ToStream(), "result.png", Context.User.Mention + " " + msg + $"\n`Bet:`{amount} `Won:` {amount * result.Multiplier}{NadekoBot.BotConfig.CurrencySign}").ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
var t = Task.Run(async () =>
|
||||
{
|
||||
await Task.Delay(3000);
|
||||
runningUsers.Remove(Context.User.Id);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
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('_', ' '));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -145,6 +145,61 @@ namespace NadekoBot.Modules.Gambling
|
||||
await Context.Channel.SendErrorAsync($"{Context.User.Mention} was unable to take {amount} {(amount == 1 ? CurrencyName : CurrencyPluralName)} from `{usrId}` because the user doesn't have that much {CurrencyPluralName}!").ConfigureAwait(false);
|
||||
}
|
||||
|
||||
//[NadekoCommand, Usage, Description, Aliases]
|
||||
//[OwnerOnly]
|
||||
//public Task BrTest(int tests = 1000)
|
||||
//{
|
||||
// var t = Task.Run(async () =>
|
||||
// {
|
||||
// if (tests <= 0)
|
||||
// return;
|
||||
// //multi vs how many times it occured
|
||||
// var dict = new Dictionary<int, int>();
|
||||
// var generator = new NadekoRandom();
|
||||
// for (int i = 0; i < tests; i++)
|
||||
// {
|
||||
// var rng = generator.Next(0, 101);
|
||||
// var mult = 0;
|
||||
// if (rng < 67)
|
||||
// {
|
||||
// mult = 0;
|
||||
// }
|
||||
// else if (rng < 91)
|
||||
// {
|
||||
// mult = 2;
|
||||
// }
|
||||
// else if (rng < 100)
|
||||
// {
|
||||
// mult = 4;
|
||||
// }
|
||||
// else
|
||||
// mult = 10;
|
||||
|
||||
// if (dict.ContainsKey(mult))
|
||||
// dict[mult] += 1;
|
||||
// else
|
||||
// dict.Add(mult, 1);
|
||||
// }
|
||||
|
||||
// var sb = new StringBuilder();
|
||||
// const int bet = 1;
|
||||
// int payout = 0;
|
||||
// foreach (var key in dict.Keys.OrderByDescending(x => x))
|
||||
// {
|
||||
// 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]
|
||||
public async Task BetRoll(long amount)
|
||||
{
|
||||
|
@ -93,10 +93,10 @@ namespace NadekoBot.Modules.Games
|
||||
{
|
||||
firstPart = $"{dropAmount} random { NadekoBot.BotConfig.CurrencyPluralName } appeared!";
|
||||
}
|
||||
|
||||
var file = GetRandomCurrencyImagePath();
|
||||
var sent = await channel.SendFileAsync(
|
||||
File.Open(GetRandomCurrencyImagePath(), FileMode.OpenOrCreate),
|
||||
"RandomFlower.jpg",
|
||||
File.Open(file, FileMode.OpenOrCreate),
|
||||
new FileInfo(file).Name,
|
||||
$"❗ {firstPart} Pick it up by typing `{NadekoBot.ModulePrefixes[typeof(Games).Name]}pick`")
|
||||
.ConfigureAwait(false);
|
||||
|
||||
@ -167,7 +167,7 @@ namespace NadekoBot.Modules.Games
|
||||
}
|
||||
else
|
||||
{
|
||||
msg = await Context.Channel.SendFileAsync(File.Open(file, FileMode.OpenOrCreate), "plant.jpg", msgToSend).ConfigureAwait(false);
|
||||
msg = await Context.Channel.SendFileAsync(File.Open(file, FileMode.OpenOrCreate), new FileInfo(file).Name, msgToSend).ConfigureAwait(false);
|
||||
}
|
||||
plantedFlowers.AddOrUpdate(Context.Channel.Id, new List<IUserMessage>() { msg }, (id, old) => { old.Add(msg); return old; });
|
||||
}
|
||||
|
@ -43,7 +43,12 @@ namespace NadekoBot.Modules.Music.Classes
|
||||
/// </summary>
|
||||
public uint MaxPlaytimeSeconds { get; set; } = 0;
|
||||
|
||||
public TimeSpan TotalPlaytime => new TimeSpan(playlist.Sum(s => s.TotalTime.Ticks));
|
||||
|
||||
// this should be written better
|
||||
public TimeSpan TotalPlaytime =>
|
||||
playlist.Any(s => s.TotalTime == TimeSpan.MaxValue) ?
|
||||
TimeSpan.MaxValue :
|
||||
new TimeSpan(playlist.Sum(s => s.TotalTime.Ticks));
|
||||
|
||||
/// <summary>
|
||||
/// Users who recently got their music wish
|
||||
|
@ -204,6 +204,7 @@ namespace NadekoBot.Modules.Music
|
||||
const int itemsPerPage = 10;
|
||||
|
||||
var total = musicPlayer.TotalPlaytime;
|
||||
var totalStr = total == TimeSpan.MaxValue ? "∞" : $"{(int)total.TotalHours}h {total.Minutes}m {total.Seconds}s";
|
||||
var maxPlaytime = musicPlayer.MaxPlaytimeSeconds;
|
||||
var lastPage = musicPlayer.Playlist.Count / itemsPerPage;
|
||||
Func<int, EmbedBuilder> printAction = (curPage) =>
|
||||
@ -218,7 +219,7 @@ namespace NadekoBot.Modules.Music
|
||||
.Take(itemsPerPage)
|
||||
.Select(v => $"`{++number}.` {v.PrettyFullName}")))
|
||||
.WithFooter(ef => ef.WithText($"{musicPlayer.PrettyVolume} | {musicPlayer.Playlist.Count} " +
|
||||
$"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {(int)total.TotalHours}h {total.Minutes}m {total.Seconds}s | " +
|
||||
$"{("tracks".SnPl(musicPlayer.Playlist.Count))} | {totalStr} | " +
|
||||
(musicPlayer.FairPlay ? "✔️fairplay" : "✖️fairplay") + $" | " + (maxPlaytime == 0 ? "unlimited" : $"{maxPlaytime}s limit")))
|
||||
.WithOkColor();
|
||||
|
||||
@ -804,7 +805,7 @@ namespace NadekoBot.Modules.Music
|
||||
if (voiceCh == null || voiceCh.Guild != textCh.Guild)
|
||||
{
|
||||
if (!silent)
|
||||
await textCh.SendErrorAsync("💢 You need to be in a voice channel on this server.\n If you are already in a voice (ITextChannel)Context.Channel, try rejoining.").ConfigureAwait(false);
|
||||
await textCh.SendErrorAsync($"💢 You need to be in a voice channel on this server.").ConfigureAwait(false);
|
||||
throw new ArgumentNullException(nameof(voiceCh));
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(query) || query.Length < 3)
|
||||
|
@ -19,6 +19,7 @@ namespace NadekoBot.Modules.NSFW
|
||||
[NadekoModule("NSFW", "~")]
|
||||
public class NSFW : DiscordModule
|
||||
{
|
||||
#if !GLOBAL_NADEKO
|
||||
private static ConcurrentDictionary<ulong, Timer> AutoHentaiTimers { get; } = new ConcurrentDictionary<ulong, Timer>();
|
||||
private static ConcurrentHashSet<ulong> _hentaiBombBlacklist { get; } = new ConcurrentHashSet<ulong>();
|
||||
|
||||
@ -66,6 +67,7 @@ namespace NadekoBot.Modules.NSFW
|
||||
InternalHentai(Context.Channel, tag, false);
|
||||
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
[RequireUserPermission(ChannelPermission.ManageMessages)]
|
||||
public async Task AutoHentai(int interval = 0, string tags = null)
|
||||
{
|
||||
Timer t;
|
||||
@ -188,7 +190,7 @@ namespace NadekoBot.Modules.NSFW
|
||||
.WithFooter(efb => efb.WithText("e621")))
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
#endif
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
public async Task Cp()
|
||||
{
|
||||
@ -203,7 +205,7 @@ namespace NadekoBot.Modules.NSFW
|
||||
JToken obj;
|
||||
using (var http = new HttpClient())
|
||||
{
|
||||
obj = JArray.Parse(await http.GetStringAsync($"http://api.oboobs.ru/boobs/{ new NadekoRandom().Next(0, 10229) }").ConfigureAwait(false))[0];
|
||||
obj = JArray.Parse(await http.GetStringAsync($"http://api.oboobs.ru/boobs/{ new NadekoRandom().Next(0, 10330) }").ConfigureAwait(false))[0];
|
||||
}
|
||||
await Context.Channel.SendMessageAsync($"http://media.oboobs.ru/{ obj["preview"].ToString() }").ConfigureAwait(false);
|
||||
}
|
||||
@ -221,7 +223,7 @@ namespace NadekoBot.Modules.NSFW
|
||||
JToken obj;
|
||||
using (var http = new HttpClient())
|
||||
{
|
||||
obj = JArray.Parse(await http.GetStringAsync($"http://api.obutts.ru/butts/{ new NadekoRandom().Next(0, 4222) }").ConfigureAwait(false))[0];
|
||||
obj = JArray.Parse(await http.GetStringAsync($"http://api.obutts.ru/butts/{ new NadekoRandom().Next(0, 4335) }").ConfigureAwait(false))[0];
|
||||
}
|
||||
await Context.Channel.SendMessageAsync($"http://media.obutts.ru/{ obj["preview"].ToString() }").ConfigureAwait(false);
|
||||
}
|
||||
@ -230,7 +232,7 @@ namespace NadekoBot.Modules.NSFW
|
||||
await Context.Channel.SendErrorAsync(ex.Message).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
#if !GLOBAL_NADEKO
|
||||
public static Task<string> GetDanbooruImageLink(string tag) => Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
@ -287,5 +289,6 @@ namespace NadekoBot.Modules.NSFW
|
||||
|
||||
public static Task<string> GetRule34ImageLink(string tag) =>
|
||||
Searches.Searches.InternalDapiSearch(tag, Searches.Searches.DapiSearchType.Rule34);
|
||||
#endif
|
||||
}
|
||||
}
|
@ -618,9 +618,13 @@ namespace NadekoBot.Modules.Searches
|
||||
if (usr == null)
|
||||
usr = Context.User;
|
||||
|
||||
var avatarUrl = usr.RealAvatarUrl();
|
||||
var shortenedAvatarUrl = await NadekoBot.Google.ShortenUrl(avatarUrl).ConfigureAwait(false);
|
||||
await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
|
||||
.WithTitle($"{usr}'s Avatar")
|
||||
.WithImageUrl(usr.AvatarUrl)).ConfigureAwait(false);
|
||||
.AddField(efb => efb.WithName("Username").WithValue(usr.ToString()).WithIsInline(false))
|
||||
.AddField(efb => efb.WithName("Avatar Url").WithValue(shortenedAvatarUrl).WithIsInline(false))
|
||||
//.AddField(efb => efb.WithName("Avatar Id").WithValue(usr.AvatarId).WithIsInline(false))
|
||||
.WithThumbnailUrl(avatarUrl), Context.User.Mention).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
[NadekoCommand, Usage, Description, Aliases]
|
||||
|
@ -34,6 +34,9 @@ namespace NadekoBot.Modules.Utility
|
||||
var createdAt = new DateTime(2015, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(guild.Id >> 22);
|
||||
var sb = new StringBuilder();
|
||||
var users = await guild.GetUsersAsync().ConfigureAwait(false);
|
||||
var features = string.Join("\n", guild.Features);
|
||||
if (string.IsNullOrWhiteSpace(features))
|
||||
features = "-";
|
||||
var embed = new EmbedBuilder()
|
||||
.WithAuthor(eab => eab.WithName("Server Info"))
|
||||
.WithTitle(guild.Name)
|
||||
@ -45,11 +48,12 @@ namespace NadekoBot.Modules.Utility
|
||||
.AddField(fb => fb.WithName("**Created At**").WithValue($"{createdAt.ToString("dd.MM.yyyy HH:mm")}").WithIsInline(true))
|
||||
.AddField(fb => fb.WithName("**Region**").WithValue(guild.VoiceRegionId.ToString()).WithIsInline(true))
|
||||
.AddField(fb => fb.WithName("**Roles**").WithValue((guild.Roles.Count - 1).ToString()).WithIsInline(true))
|
||||
.AddField(fb => fb.WithName("**Features**").WithValue(features).WithIsInline(true))
|
||||
.WithImageUrl(guild.IconUrl)
|
||||
.WithColor(NadekoBot.OkColor);
|
||||
if (guild.Emojis.Count() > 0)
|
||||
{
|
||||
embed.AddField(fb => fb.WithName("**Custom Emojis**").WithValue(Format.Italics(string.Join(", ", guild.Emojis))).WithIsInline(true));
|
||||
embed.AddField(fb => fb.WithName("**Custom Emojis**").WithValue(string.Join(" ", guild.Emojis.Select(e => $"{e.Name} <:{e.Name}:{e.Id}>"))));
|
||||
}
|
||||
await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
|
||||
}
|
||||
@ -92,8 +96,8 @@ namespace NadekoBot.Modules.Utility
|
||||
embed.AddField(fb => fb.WithName("**ID**").WithValue(user.Id.ToString()).WithIsInline(true))
|
||||
.AddField(fb => fb.WithName("**Joined Server**").WithValue($"{user.JoinedAt?.ToString("dd.MM.yyyy HH:mm")}").WithIsInline(true))
|
||||
.AddField(fb => fb.WithName("**Joined Discord**").WithValue($"{user.CreatedAt.ToString("dd.MM.yyyy HH:mm")}").WithIsInline(true))
|
||||
.AddField(fb => fb.WithName("**Roles**").WithValue($"**({user.RoleIds.Count})** - {string.Join(", ", user.GetRoles().Where(r => r.Id != r.Guild.EveryoneRole.Id).Select(r => r.Name)).SanitizeMentions()}").WithIsInline(true))
|
||||
.WithThumbnailUrl(user.AvatarUrl)
|
||||
.AddField(fb => fb.WithName("**Roles**").WithValue($"**({user.RoleIds.Count - 1})** - {string.Join("\n", user.GetRoles().Where(r => r.Id != r.Guild.EveryoneRole.Id).Select(r => r.Name)).SanitizeMentions()}").WithIsInline(true))
|
||||
.WithThumbnailUrl(user.RealAvatarUrl())
|
||||
.WithColor(NadekoBot.OkColor);
|
||||
await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
using Discord;
|
||||
using Discord.Commands;
|
||||
using Discord.Net;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using NadekoBot.Attributes;
|
||||
using NadekoBot.Extensions;
|
||||
@ -64,7 +65,24 @@ namespace NadekoBot.Modules.Utility
|
||||
|
||||
if (oldMsg != null)
|
||||
try { await oldMsg.DeleteAsync(); } catch { }
|
||||
try { oldMsg = await Channel.SendMessageAsync(toSend).ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); }
|
||||
try
|
||||
{
|
||||
oldMsg = await Channel.SendMessageAsync(toSend).ConfigureAwait(false);
|
||||
}
|
||||
catch (HttpException ex) when (ex.StatusCode == System.Net.HttpStatusCode.Forbidden)
|
||||
{
|
||||
_log.Warn("Missing permissions. Repeater stopped. ChannelId : {0}", Channel?.Id);
|
||||
return;
|
||||
}
|
||||
catch (HttpException ex) when (ex.StatusCode == System.Net.HttpStatusCode.NotFound)
|
||||
{
|
||||
_log.Warn("Channel not found. Repeater stopped. ChannelId : {0}", Channel?.Id);
|
||||
return;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_log.Warn(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException) { }
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -23,8 +23,8 @@ namespace NadekoBot
|
||||
{
|
||||
private Logger _log;
|
||||
|
||||
public static Color OkColor { get; } = new Color(0x71cd40);
|
||||
public static Color ErrorColor { get; } = new Color(0xee281f);
|
||||
public static Color OkColor { get; }
|
||||
public static Color ErrorColor { get; }
|
||||
|
||||
public static CommandService CommandService { get; private set; }
|
||||
public static CommandHandler CommandHandler { get; private set; }
|
||||
@ -49,6 +49,8 @@ namespace NadekoBot
|
||||
{
|
||||
AllGuildConfigs = uow.GuildConfigs.GetAllGuildConfigs();
|
||||
BotConfig = uow.BotConfig.GetOrCreate();
|
||||
OkColor = new Color(Convert.ToUInt32(BotConfig.OkColor, 16));
|
||||
ErrorColor = new Color(Convert.ToUInt32(BotConfig.ErrorColor, 16));
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,7 +98,7 @@ namespace NadekoBot
|
||||
//connect
|
||||
await Client.LoginAsync(TokenType.Bot, Credentials.Token).ConfigureAwait(false);
|
||||
await Client.ConnectAsync().ConfigureAwait(false);
|
||||
await Client.DownloadAllUsersAsync().ConfigureAwait(false);
|
||||
//await Client.DownloadAllUsersAsync().ConfigureAwait(false);
|
||||
Stats.Initialize();
|
||||
|
||||
_log.Info("Connected");
|
||||
|
216
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 some of the money you've spent back unless that waifu has an affinity towards you. 6 hours cooldown..
|
||||
/// </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>
|
||||
@ -7079,6 +7106,87 @@ namespace NadekoBot.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to slot.
|
||||
/// </summary>
|
||||
public static string slot_cmd {
|
||||
get {
|
||||
return ResourceManager.GetString("slot_cmd", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Play Nadeko slots. Max bet is 999. 3 seconds cooldown per user..
|
||||
/// </summary>
|
||||
public static string slot_desc {
|
||||
get {
|
||||
return ResourceManager.GetString("slot_desc", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to `{0}slot 5`.
|
||||
/// </summary>
|
||||
public static string slot_usage {
|
||||
get {
|
||||
return ResourceManager.GetString("slot_usage", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to slotstats.
|
||||
/// </summary>
|
||||
public static string slotstats_cmd {
|
||||
get {
|
||||
return ResourceManager.GetString("slotstats_cmd", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Shows the total stats of the slot command for this bot's session..
|
||||
/// </summary>
|
||||
public static string slotstats_desc {
|
||||
get {
|
||||
return ResourceManager.GetString("slotstats_desc", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to `{0}slotstats`.
|
||||
/// </summary>
|
||||
public static string slotstats_usage {
|
||||
get {
|
||||
return ResourceManager.GetString("slotstats_usage", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to slottest.
|
||||
/// </summary>
|
||||
public static string slottest_cmd {
|
||||
get {
|
||||
return ResourceManager.GetString("slottest_cmd", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Tests to see how much slots payout for X number of plays..
|
||||
/// </summary>
|
||||
public static string slottest_desc {
|
||||
get {
|
||||
return ResourceManager.GetString("slottest_desc", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to `{0}slottest 1000`.
|
||||
/// </summary>
|
||||
public static string slottest_usage {
|
||||
get {
|
||||
return ResourceManager.GetString("slottest_usage", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to slowmode.
|
||||
/// </summary>
|
||||
@ -8294,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%. You can leave second argument empty to clear your affinity. 30 minutes cooldown..
|
||||
/// </summary>
|
||||
public static string waifuclaimeraffinity_desc {
|
||||
get {
|
||||
return ResourceManager.GetString("waifuclaimeraffinity_desc", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to `{0}affinity @MyHusband` or `{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. Defaults to you if no user is provided..
|
||||
/// </summary>
|
||||
public static string waifuinfo_desc {
|
||||
get {
|
||||
return ResourceManager.GetString("waifuinfo_desc", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to `{0}waifuinfo @MyCrush` or `{0}waifuinfo`.
|
||||
/// </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 9 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>
|
||||
|
@ -2952,4 +2952,76 @@
|
||||
<data name="startevent_usage" xml:space="preserve">
|
||||
<value>`{0}startevent flowerreaction`</value>
|
||||
</data>
|
||||
<data name="slotstats_cmd" xml:space="preserve">
|
||||
<value>slotstats</value>
|
||||
</data>
|
||||
<data name="slotstats_desc" xml:space="preserve">
|
||||
<value>Shows the total stats of the slot command for this bot's session.</value>
|
||||
</data>
|
||||
<data name="slotstats_usage" xml:space="preserve">
|
||||
<value>`{0}slotstats`</value>
|
||||
</data>
|
||||
<data name="slottest_cmd" xml:space="preserve">
|
||||
<value>slottest</value>
|
||||
</data>
|
||||
<data name="slottest_desc" xml:space="preserve">
|
||||
<value>Tests to see how much slots payout for X number of plays.</value>
|
||||
</data>
|
||||
<data name="slottest_usage" xml:space="preserve">
|
||||
<value>`{0}slottest 1000`</value>
|
||||
</data>
|
||||
<data name="slot_cmd" xml:space="preserve">
|
||||
<value>slot</value>
|
||||
</data>
|
||||
<data name="slot_desc" xml:space="preserve">
|
||||
<value>Play Nadeko slots. Max bet is 999. 3 seconds cooldown per user.</value>
|
||||
</data>
|
||||
<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%. You can leave second argument empty to clear your affinity. 30 minutes cooldown.</value>
|
||||
</data>
|
||||
<data name="waifuclaimeraffinity_usage" xml:space="preserve">
|
||||
<value>`{0}affinity @MyHusband` or `{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 9 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 some of the money you've spent back unless that waifu has an affinity towards you. 6 hours cooldown.</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. Defaults to you if no user is provided.</value>
|
||||
</data>
|
||||
<data name="waifuinfo_usage" xml:space="preserve">
|
||||
<value>`{0}waifuinfo @MyCrush` or `{0}waifuinfo`</value>
|
||||
</data>
|
||||
</root>
|
@ -32,7 +32,7 @@ namespace Services.CleverBotApi
|
||||
#if GLOBAL_NADEKO
|
||||
var url = "http://www.cleverbot.com/webservicemin?uc=3210&botapi=nadekobot";
|
||||
#else
|
||||
var url = "http://www.cleverbot.com/webservicemin?uc=3210";
|
||||
var url = "http://www.cleverbot.com/webservicemin?uc=3210&botapi=chatterbotapi";
|
||||
#endif
|
||||
|
||||
switch (type)
|
||||
|
@ -30,7 +30,11 @@ namespace NadekoBot.Services
|
||||
}
|
||||
public class CommandHandler
|
||||
{
|
||||
#if GLOBAL_NADEKO
|
||||
public const int GlobalCommandsCooldown = 1500;
|
||||
#else
|
||||
public const int GlobalCommandsCooldown = 750;
|
||||
#endif
|
||||
|
||||
private readonly DiscordShardedClient _client;
|
||||
private readonly CommandService _commandService;
|
||||
@ -119,18 +123,18 @@ namespace NadekoBot.Services
|
||||
private void LogErroredExecution(SocketUserMessage usrMsg, ExecuteCommandResult exec, SocketTextChannel channel, int ticks)
|
||||
{
|
||||
_log.Warn("Command Errored after {5}s\n\t" +
|
||||
"User: {0}\n\t" +
|
||||
"Server: {1}\n\t" +
|
||||
"Channel: {2}\n\t" +
|
||||
"Message: {3}\n\t" +
|
||||
"Error: {4}",
|
||||
usrMsg.Author + " [" + usrMsg.Author.Id + "]", // {0}
|
||||
(channel == null ? "PRIVATE" : channel.Guild.Name + " [" + channel.Guild.Id + "]"), // {1}
|
||||
(channel == null ? "PRIVATE" : channel.Name + " [" + channel.Id + "]"), // {2}
|
||||
usrMsg.Content,// {3}
|
||||
exec.Result.ErrorReason, // {4}
|
||||
ticks * oneThousandth // {5}
|
||||
);
|
||||
"User: {0}\n\t" +
|
||||
"Server: {1}\n\t" +
|
||||
"Channel: {2}\n\t" +
|
||||
"Message: {3}\n\t" +
|
||||
"Error: {4}",
|
||||
usrMsg.Author + " [" + usrMsg.Author.Id + "]", // {0}
|
||||
(channel == null ? "PRIVATE" : channel.Guild.Name + " [" + channel.Guild.Id + "]"), // {1}
|
||||
(channel == null ? "PRIVATE" : channel.Name + " [" + channel.Id + "]"), // {2}
|
||||
usrMsg.Content,// {3}
|
||||
exec.Result.ErrorReason, // {4}
|
||||
ticks * oneThousandth // {5}
|
||||
);
|
||||
}
|
||||
|
||||
private async Task<bool> InviteFiltered(IGuild guild, SocketUserMessage usrMsg)
|
||||
@ -193,13 +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);
|
||||
|
||||
// Bot will ignore commands which are ran more often than what specified by
|
||||
// GlobalCommandsCooldown constant (miliseconds)
|
||||
if (!UsersOnShortCooldown.Add(usrMsg.Author.Id))
|
||||
return;
|
||||
#endif
|
||||
|
||||
var channel = msg.Channel as SocketTextChannel;
|
||||
var guild = channel?.Guild;
|
||||
@ -216,19 +217,19 @@ namespace NadekoBot.Services
|
||||
if (IsBlacklisted(guild, usrMsg))
|
||||
return;
|
||||
|
||||
var cleverBotRan = await TryRunCleverbot(usrMsg, guild).ConfigureAwait(false);
|
||||
var cleverBotRan = await Task.Run(() => TryRunCleverbot(usrMsg, guild)).ConfigureAwait(false);
|
||||
if (cleverBotRan)
|
||||
return;
|
||||
|
||||
// maybe this message is a custom reaction
|
||||
var crExecuted = await CustomReactions.TryExecuteCustomReaction(usrMsg).ConfigureAwait(false);
|
||||
var crExecuted = await Task.Run(() => CustomReactions.TryExecuteCustomReaction(usrMsg)).ConfigureAwait(false);
|
||||
if (crExecuted) //if it was, don't execute the command
|
||||
return;
|
||||
|
||||
string messageContent = usrMsg.Content;
|
||||
|
||||
// execute the command and measure the time it took
|
||||
var exec = await ExecuteCommand(new CommandContext(_client, usrMsg), messageContent, DependencyMap.Empty, MultiMatchHandling.Best);
|
||||
var exec = await Task.Run(() => ExecuteCommand(new CommandContext(_client, usrMsg), messageContent, DependencyMap.Empty, MultiMatchHandling.Best)).ConfigureAwait(false);
|
||||
execTime = Environment.TickCount - execTime;
|
||||
|
||||
if (exec.Result.IsSuccess)
|
||||
@ -367,9 +368,13 @@ namespace NadekoBot.Services
|
||||
}
|
||||
}
|
||||
|
||||
// Bot will ignore commands which are ran more often than what specified by
|
||||
// GlobalCommandsCooldown constant (miliseconds)
|
||||
if (!UsersOnShortCooldown.Add(context.Message.Author.Id))
|
||||
return new ExecuteCommandResult(cmd, null, SearchResult.FromError(CommandError.Exception, $"You are on a global cooldown."));
|
||||
|
||||
if (CmdCdsCommands.HasCooldown(cmd, context.Guild, context.User))
|
||||
return new ExecuteCommandResult(cmd, null, SearchResult.FromError(CommandError.Exception, $"That command is on cooldown for you."));
|
||||
return new ExecuteCommandResult(cmd, null, SearchResult.FromError(CommandError.Exception, $"That command is on a cooldown for you."));
|
||||
|
||||
return new ExecuteCommandResult(cmd, null, await commands[i].ExecuteAsync(context, parseResult, dependencyMap));
|
||||
}
|
||||
|
@ -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,26 +20,36 @@ 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)
|
||||
{
|
||||
var success = uow.Currency.TryUpdateState(authorId, -amount);
|
||||
if (!success)
|
||||
return false;
|
||||
uow.CurrencyTransactions.Add(new CurrencyTransaction()
|
||||
using (uow = DbHandler.UnitOfWork())
|
||||
{
|
||||
UserId = authorId,
|
||||
Reason = reason,
|
||||
Amount = -amount,
|
||||
});
|
||||
await uow.CompleteAsync().ConfigureAwait(false);
|
||||
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)
|
||||
return false;
|
||||
uow.CurrencyTransactions.Add(new CurrencyTransaction()
|
||||
{
|
||||
UserId = authorId,
|
||||
Reason = reason,
|
||||
Amount = -amount,
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -50,22 +61,29 @@ 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));
|
||||
|
||||
var transaction = new CurrencyTransaction()
|
||||
{
|
||||
UserId = receiverId,
|
||||
Reason = reason,
|
||||
Amount = amount,
|
||||
};
|
||||
|
||||
using (var uow = DbHandler.UnitOfWork())
|
||||
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(new CurrencyTransaction()
|
||||
{
|
||||
UserId = receiverId,
|
||||
Reason = reason,
|
||||
Amount = amount,
|
||||
});
|
||||
await uow.CompleteAsync();
|
||||
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();
|
||||
|
@ -25,11 +25,11 @@ namespace NadekoBot.Services.Database.Models
|
||||
public string CurrencyPluralName { get; set; } = "Nadeko Flowers";
|
||||
|
||||
public int TriviaCurrencyReward { get; set; } = 0;
|
||||
public int MinimumBetAmount { get; set; } = 3;
|
||||
public float BetflipMultiplier { get; set; } = 1.8f;
|
||||
public int MinimumBetAmount { get; set; } = 2;
|
||||
public float BetflipMultiplier { get; set; } = 1.95f;
|
||||
public int CurrencyDropAmount { get; set; } = 1;
|
||||
public float Betroll67Multiplier { get; set; } = 2;
|
||||
public float Betroll91Multiplier { get; set; } = 3;
|
||||
public float Betroll91Multiplier { get; set; } = 4;
|
||||
public float Betroll100Multiplier { get; set; } = 10;
|
||||
//public HashSet<CommandCost> CommandCosts { get; set; } = new HashSet<CommandCost>();
|
||||
|
||||
@ -57,6 +57,9 @@ For a specific command help, use `{1}h CommandName` (for example {1}h !!q)
|
||||
Nadeko Support Server: https://discord.gg/0ehQwTK2RBjAxzEY";
|
||||
|
||||
public int MigrationVersion { get; set; }
|
||||
|
||||
public string OkColor { get; set; } = "71cd40";
|
||||
public string ErrorColor { get; set; } = "ee281f";
|
||||
}
|
||||
|
||||
public class PlayingStatus :DbEntity
|
||||
|
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
@ -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
@ -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,13 +35,19 @@ 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() =>
|
||||
DbHandler.Instance.GetUnitOfWork();
|
||||
}
|
||||
}
|
||||
}
|
@ -15,7 +15,7 @@ namespace NadekoBot.Services.Impl
|
||||
private DiscordShardedClient client;
|
||||
private DateTime started;
|
||||
|
||||
public const string BotVersion = "1.1.1";
|
||||
public const string BotVersion = "1.1.4";
|
||||
|
||||
public string Author => "Kwoth#2560";
|
||||
public string Library => "Discord.Net";
|
||||
|
@ -183,18 +183,18 @@ namespace NadekoBot.Extensions
|
||||
await (await user.CreateDMChannelAsync().ConfigureAwait(false)).SendMessageAsync(message, isTTS).ConfigureAwait(false);
|
||||
|
||||
public static async Task<IUserMessage> SendConfirmAsync(this IUser user, string text)
|
||||
=> await (await user.CreateDMChannelAsync()).SendMessageAsync("", embed: new EmbedBuilder().WithColor(NadekoBot.OkColor).WithDescription(text));
|
||||
=> await (await user.CreateDMChannelAsync()).SendMessageAsync("", embed: new EmbedBuilder().WithOkColor().WithDescription(text));
|
||||
|
||||
public static async Task<IUserMessage> SendConfirmAsync(this IUser user, string title, string text, string url = null)
|
||||
=> await (await user.CreateDMChannelAsync()).SendMessageAsync("", embed: new EmbedBuilder().WithColor(NadekoBot.OkColor).WithDescription(text)
|
||||
=> await (await user.CreateDMChannelAsync()).SendMessageAsync("", embed: new EmbedBuilder().WithOkColor().WithDescription(text)
|
||||
.WithTitle(title).WithUrl(url));
|
||||
|
||||
public static async Task<IUserMessage> SendErrorAsync(this IUser user, string title, string error, string url = null)
|
||||
=> await (await user.CreateDMChannelAsync()).SendMessageAsync("", embed: new EmbedBuilder().WithColor(NadekoBot.OkColor).WithDescription(error)
|
||||
=> await (await user.CreateDMChannelAsync()).SendMessageAsync("", embed: new EmbedBuilder().WithErrorColor().WithDescription(error)
|
||||
.WithTitle(title).WithUrl(url));
|
||||
|
||||
public static async Task<IUserMessage> SendErrorAsync(this IUser user, string error)
|
||||
=> await (await user.CreateDMChannelAsync()).SendMessageAsync("", embed: new EmbedBuilder().WithColor(NadekoBot.OkColor).WithDescription(error));
|
||||
=> await (await user.CreateDMChannelAsync()).SendMessageAsync("", embed: new EmbedBuilder().WithErrorColor().WithDescription(error));
|
||||
|
||||
public static async Task<IUserMessage> SendFileAsync(this IUser user, string filePath, string caption = null, string text = null, bool isTTS = false) =>
|
||||
await (await user.CreateDMChannelAsync().ConfigureAwait(false)).SendFileAsync(File.Open(filePath, FileMode.Open), caption ?? "x", text, isTTS).ConfigureAwait(false);
|
||||
@ -212,18 +212,18 @@ namespace NadekoBot.Extensions
|
||||
=> ch.SendMessageAsync(msg, embed: embed);
|
||||
|
||||
public static Task<IUserMessage> SendErrorAsync(this IMessageChannel ch, string title, string error, string url = null, string footer = null)
|
||||
=> ch.SendMessageAsync("", embed: new EmbedBuilder().WithColor(NadekoBot.ErrorColor).WithDescription(error)
|
||||
=> ch.SendMessageAsync("", embed: new EmbedBuilder().WithErrorColor().WithDescription(error)
|
||||
.WithTitle(title).WithUrl(url).WithFooter(efb => efb.WithText(footer)));
|
||||
|
||||
public static Task<IUserMessage> SendErrorAsync(this IMessageChannel ch, string error)
|
||||
=> ch.SendMessageAsync("", embed: new EmbedBuilder().WithColor(NadekoBot.OkColor).WithDescription(error));
|
||||
=> ch.SendMessageAsync("", embed: new EmbedBuilder().WithErrorColor().WithDescription(error));
|
||||
|
||||
public static Task<IUserMessage> SendConfirmAsync(this IMessageChannel ch, string title, string text, string url = null, string footer = null)
|
||||
=> ch.SendMessageAsync("", embed: new EmbedBuilder().WithColor(NadekoBot.OkColor).WithDescription(text)
|
||||
=> ch.SendMessageAsync("", embed: new EmbedBuilder().WithOkColor().WithDescription(text)
|
||||
.WithTitle(title).WithUrl(url).WithFooter(efb => efb.WithText(footer)));
|
||||
|
||||
public static Task<IUserMessage> SendConfirmAsync(this IMessageChannel ch, string text)
|
||||
=> ch.SendMessageAsync("", embed: new EmbedBuilder().WithColor(NadekoBot.OkColor).WithDescription(text));
|
||||
=> ch.SendMessageAsync("", embed: new EmbedBuilder().WithOkColor().WithDescription(text));
|
||||
|
||||
public static Task<IUserMessage> SendTableAsync<T>(this IMessageChannel ch, string seed, IEnumerable<T> items, Func<T, string> howToPrint, int columns = 3)
|
||||
{
|
||||
@ -425,5 +425,12 @@ namespace NadekoBot.Extensions
|
||||
|
||||
public static bool IsDiscordInvite(this string str)
|
||||
=> filterRegex.IsMatch(str);
|
||||
|
||||
public static string RealAvatarUrl(this IUser usr)
|
||||
{
|
||||
return usr.AvatarId.StartsWith("a_")
|
||||
? $"{DiscordConfig.CDNUrl}avatars/{usr.Id}/{usr.AvatarId}.gif"
|
||||
: usr.AvatarUrl;
|
||||
}
|
||||
}
|
||||
}
|
BIN
src/NadekoBot/data/slots/0.png
Normal file
After Width: | Height: | Size: 551 B |
BIN
src/NadekoBot/data/slots/1.png
Normal file
After Width: | Height: | Size: 392 B |
BIN
src/NadekoBot/data/slots/2.png
Normal file
After Width: | Height: | Size: 553 B |
BIN
src/NadekoBot/data/slots/3.png
Normal file
After Width: | Height: | Size: 539 B |
BIN
src/NadekoBot/data/slots/4.png
Normal file
After Width: | Height: | Size: 471 B |
BIN
src/NadekoBot/data/slots/5.png
Normal file
After Width: | Height: | Size: 542 B |
BIN
src/NadekoBot/data/slots/6.png
Normal file
After Width: | Height: | Size: 562 B |
BIN
src/NadekoBot/data/slots/7.png
Normal file
After Width: | Height: | Size: 417 B |
BIN
src/NadekoBot/data/slots/8.png
Normal file
After Width: | Height: | Size: 597 B |
BIN
src/NadekoBot/data/slots/9.png
Normal file
After Width: | Height: | Size: 578 B |
BIN
src/NadekoBot/data/slots/background.png
Normal file
After Width: | Height: | Size: 111 KiB |
BIN
src/NadekoBot/data/slots/emojis/0.png
Normal file
After Width: | Height: | Size: 8.8 KiB |
BIN
src/NadekoBot/data/slots/emojis/1.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
src/NadekoBot/data/slots/emojis/2.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
src/NadekoBot/data/slots/emojis/3.png
Normal file
After Width: | Height: | Size: 5.7 KiB |
BIN
src/NadekoBot/data/slots/emojis/4.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
src/NadekoBot/data/slots/emojis/5.png
Normal file
After Width: | Height: | Size: 6.2 KiB |