Merge pull request #988 from Kwoth/dev

Update 1.1.3
This commit is contained in:
Master Kwoth 2017-01-18 22:25:13 +01:00 committed by GitHub
commit 40ee70cd7e
41 changed files with 1593 additions and 75 deletions

@ -1 +1 @@
Subproject commit e9dca6c648b23bd9e957d8f9eee516df6ce11091 Subproject commit 58766448d79ac9adec228f341f258aa262a3f278

View File

@ -16,8 +16,8 @@ ________________________________________________________________________________
####Guide ####Guide
- Make sure you have installed both [Git][Git] and the [.NET Core SDK][.NET Core SDK]. - 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`. - 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`) - 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, double-click on `NadekoInstaller.bat` to run it. - Once that's done, right-click on `NadekoInstaller.bat` to run it as Administrator.
- From the options, - From the options,
- Choose `1` to get the **most recent build**. - Choose `1` to get the **most recent build**.
- Choose `2` to get the **stable build**. - Choose `2` to get the **stable build**.
@ -58,7 +58,7 @@ ________________________________________________________________________________
- The bot should have been added to your server. - The bot should have been added to your server.
####Starting the bot ####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, - From the options,
- Choose `3` to **run the bot normally**. - 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.) (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. 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 #### Manual `ffmpeg` setup
- Create a folder named `ffmpeg` in your main Windows directory. We will use **C:\ffmpeg** (for our guide) - 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) - Download FFMPEG through the link https://ffmpeg.zeranoe.com/builds/ (download static build)

View File

@ -12,7 +12,7 @@ namespace NadekoBot.Migrations
name: "BetflipMultiplier", name: "BetflipMultiplier",
table: "BotConfig", table: "BotConfig",
nullable: false, nullable: false,
defaultValue: 1.8f); defaultValue: 1.95f);
migrationBuilder.AddColumn<float>( migrationBuilder.AddColumn<float>(
name: "Betroll100Multiplier", name: "Betroll100Multiplier",
@ -42,7 +42,7 @@ namespace NadekoBot.Migrations
name: "MinimumBetAmount", name: "MinimumBetAmount",
table: "BotConfig", table: "BotConfig",
nullable: false, nullable: false,
defaultValue: 3); defaultValue: 2);
migrationBuilder.AddColumn<int>( migrationBuilder.AddColumn<int>(
name: "TriviaCurrencyReward", name: "TriviaCurrencyReward",

View 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");
});
}
}
}

View 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");
}
}
}

View File

@ -4,6 +4,8 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using NadekoBot.Services.Database; using NadekoBot.Services.Database;
using NadekoBot.Services.Database.Models;
using NadekoBot.Modules.Music.Classes;
namespace NadekoBot.Migrations namespace NadekoBot.Migrations
{ {
@ -118,6 +120,8 @@ namespace NadekoBot.Migrations
b.Property<string>("DMHelpString"); b.Property<string>("DMHelpString");
b.Property<string>("ErrorColor");
b.Property<bool>("ForwardMessages"); b.Property<bool>("ForwardMessages");
b.Property<bool>("ForwardToAllOwners"); b.Property<bool>("ForwardToAllOwners");
@ -128,6 +132,8 @@ namespace NadekoBot.Migrations
b.Property<int>("MinimumBetAmount"); b.Property<int>("MinimumBetAmount");
b.Property<string>("OkColor");
b.Property<string>("RemindMessageFormat"); b.Property<string>("RemindMessageFormat");
b.Property<bool>("RotatingStatuses"); b.Property<bool>("RotatingStatuses");

View File

@ -397,6 +397,8 @@ namespace NadekoBot.Modules.Administration
.AddField(efb => efb.WithName("Old Topic").WithValue(beforeTextChannel.Topic)) .AddField(efb => efb.WithName("Old Topic").WithValue(beforeTextChannel.Topic))
.AddField(efb => efb.WithName("New Topic").WithValue(afterTextChannel.Topic)); .AddField(efb => efb.WithName("New Topic").WithValue(afterTextChannel.Topic));
} }
else
return;
await logChannel.EmbedAsync(embed).ConfigureAwait(false); await logChannel.EmbedAsync(embed).ConfigureAwait(false);
} }

View File

@ -30,15 +30,19 @@ namespace NadekoBot.Modules.Gambling
public async Task StartEvent(CurrencyEvent e) public async Task StartEvent(CurrencyEvent e)
{ {
var channel = (ITextChannel)Context.Channel; var channel = (ITextChannel)Context.Channel;
try
switch (e)
{ {
case CurrencyEvent.FlowerReaction:
await FlowerReactionEvent(Context).ConfigureAwait(false); switch (e)
break; {
default: case CurrencyEvent.FlowerReaction:
break; await FlowerReactionEvent(Context).ConfigureAwait(false);
break;
default:
break;
}
} }
catch { }
} }
@ -48,13 +52,26 @@ namespace NadekoBot.Modules.Gambling
"Add 🌸 reaction to this message to get 100" + NadekoBot.BotConfig.CurrencySign, "Add 🌸 reaction to this message to get 100" + NadekoBot.BotConfig.CurrencySign,
footer: "This event is active for 24 hours.") footer: "This event is active for 24 hours.")
.ConfigureAwait(false); .ConfigureAwait(false);
await msg.AddReactionAsync("🌸").ConfigureAwait(false); try { await msg.AddReactionAsync("🌸").ConfigureAwait(false); }
catch
{
try { await msg.AddReactionAsync("🌸").ConfigureAwait(false); }
catch
{
try { await msg.DeleteAsync().ConfigureAwait(false); }
catch { }
}
}
using (msg.OnReaction(async (r) => using (msg.OnReaction(async (r) =>
{ {
if (r.Emoji.Name == "🌸" && r.User.IsSpecified && _flowerReactionAwardedUsers.Add(r.User.Value.Id)) try
{ {
try { await CurrencyHandler.AddCurrencyAsync(r.User.Value, "Flower Reaction Event", 100, true).ConfigureAwait(false); } catch { } if (r.Emoji.Name == "🌸" && r.User.IsSpecified && _flowerReactionAwardedUsers.Add(r.User.Value.Id))
{
try { await CurrencyHandler.AddCurrencyAsync(r.User.Value, "Flower Reaction Event", 100, false).ConfigureAwait(false); } catch { }
}
} }
catch { }
})) }))
{ {
await Task.Delay(TimeSpan.FromHours(24)).ConfigureAwait(false); await Task.Delay(TimeSpan.FromHours(24)).ConfigureAwait(false);

View File

@ -93,7 +93,7 @@ namespace NadekoBot.Modules.Gambling
str = $"{Context.User.Mention}`Better luck next time.`"; 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);
} }
} }
} }

View File

@ -0,0 +1,301 @@
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))
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);
});
}
}
}
}
}

View File

@ -93,10 +93,10 @@ namespace NadekoBot.Modules.Games
{ {
firstPart = $"{dropAmount} random { NadekoBot.BotConfig.CurrencyPluralName } appeared!"; firstPart = $"{dropAmount} random { NadekoBot.BotConfig.CurrencyPluralName } appeared!";
} }
var file = GetRandomCurrencyImagePath();
var sent = await channel.SendFileAsync( var sent = await channel.SendFileAsync(
File.Open(GetRandomCurrencyImagePath(), FileMode.OpenOrCreate), File.Open(file, FileMode.OpenOrCreate),
"RandomFlower.jpg", new FileInfo(file).Name,
$"❗ {firstPart} Pick it up by typing `{NadekoBot.ModulePrefixes[typeof(Games).Name]}pick`") $"❗ {firstPart} Pick it up by typing `{NadekoBot.ModulePrefixes[typeof(Games).Name]}pick`")
.ConfigureAwait(false); .ConfigureAwait(false);
@ -167,7 +167,7 @@ namespace NadekoBot.Modules.Games
} }
else 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; }); plantedFlowers.AddOrUpdate(Context.Channel.Id, new List<IUserMessage>() { msg }, (id, old) => { old.Add(msg); return old; });
} }

View File

@ -43,7 +43,12 @@ namespace NadekoBot.Modules.Music.Classes
/// </summary> /// </summary>
public uint MaxPlaytimeSeconds { get; set; } = 0; 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> /// <summary>
/// Users who recently got their music wish /// Users who recently got their music wish

View File

@ -37,16 +37,16 @@ namespace NadekoBot.Modules.Music
Directory.CreateDirectory(MusicDataPath); Directory.CreateDirectory(MusicDataPath);
} }
private static async Task Client_UserVoiceStateUpdated(SocketUser iusr, SocketVoiceState oldState, SocketVoiceState newState) private static Task Client_UserVoiceStateUpdated(SocketUser iusr, SocketVoiceState oldState, SocketVoiceState newState)
{ {
var usr = iusr as SocketGuildUser; var usr = iusr as SocketGuildUser;
if (usr == null || if (usr == null ||
oldState.VoiceChannel == newState.VoiceChannel) oldState.VoiceChannel == newState.VoiceChannel)
return; return Task.CompletedTask;
MusicPlayer player; MusicPlayer player;
if (!MusicPlayers.TryGetValue(usr.Guild.Id, out player)) if (!MusicPlayers.TryGetValue(usr.Guild.Id, out player))
return; return Task.CompletedTask;
try try
{ {
@ -61,7 +61,7 @@ namespace NadekoBot.Modules.Music
else if (!player.Paused && newState.VoiceChannel.Users.Count <= 1) // pause if there are no users in the new channel else if (!player.Paused && newState.VoiceChannel.Users.Count <= 1) // pause if there are no users in the new channel
player.TogglePause(); player.TogglePause();
return; return Task.CompletedTask;
} }
@ -74,11 +74,12 @@ namespace NadekoBot.Modules.Music
oldState.VoiceChannel.Users.Count == 1)) oldState.VoiceChannel.Users.Count == 1))
{ {
player.TogglePause(); player.TogglePause();
return; return Task.CompletedTask;
} }
} }
catch { } catch { }
return Task.CompletedTask;
} }
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
@ -203,6 +204,7 @@ namespace NadekoBot.Modules.Music
const int itemsPerPage = 10; const int itemsPerPage = 10;
var total = musicPlayer.TotalPlaytime; var total = musicPlayer.TotalPlaytime;
var totalStr = total == TimeSpan.MaxValue ? "∞" : $"{(int)total.TotalHours}h {total.Minutes}m {total.Seconds}s";
var maxPlaytime = musicPlayer.MaxPlaytimeSeconds; var maxPlaytime = musicPlayer.MaxPlaytimeSeconds;
var lastPage = musicPlayer.Playlist.Count / itemsPerPage; var lastPage = musicPlayer.Playlist.Count / itemsPerPage;
Func<int, EmbedBuilder> printAction = (curPage) => Func<int, EmbedBuilder> printAction = (curPage) =>
@ -217,7 +219,7 @@ namespace NadekoBot.Modules.Music
.Take(itemsPerPage) .Take(itemsPerPage)
.Select(v => $"`{++number}.` {v.PrettyFullName}"))) .Select(v => $"`{++number}.` {v.PrettyFullName}")))
.WithFooter(ef => ef.WithText($"{musicPlayer.PrettyVolume} | {musicPlayer.Playlist.Count} " + .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"))) (musicPlayer.FairPlay ? "✔fairplay" : "✖fairplay") + $" | " + (maxPlaytime == 0 ? "unlimited" : $"{maxPlaytime}s limit")))
.WithOkColor(); .WithOkColor();
@ -803,7 +805,7 @@ namespace NadekoBot.Modules.Music
if (voiceCh == null || voiceCh.Guild != textCh.Guild) if (voiceCh == null || voiceCh.Guild != textCh.Guild)
{ {
if (!silent) 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)); throw new ArgumentNullException(nameof(voiceCh));
} }
if (string.IsNullOrWhiteSpace(query) || query.Length < 3) if (string.IsNullOrWhiteSpace(query) || query.Length < 3)

View File

@ -19,6 +19,7 @@ namespace NadekoBot.Modules.NSFW
[NadekoModule("NSFW", "~")] [NadekoModule("NSFW", "~")]
public class NSFW : DiscordModule public class NSFW : DiscordModule
{ {
#if !GLOBAL_NADEKO
private static ConcurrentDictionary<ulong, Timer> AutoHentaiTimers { get; } = new ConcurrentDictionary<ulong, Timer>(); private static ConcurrentDictionary<ulong, Timer> AutoHentaiTimers { get; } = new ConcurrentDictionary<ulong, Timer>();
private static ConcurrentHashSet<ulong> _hentaiBombBlacklist { get; } = new ConcurrentHashSet<ulong>(); private static ConcurrentHashSet<ulong> _hentaiBombBlacklist { get; } = new ConcurrentHashSet<ulong>();
@ -66,6 +67,7 @@ namespace NadekoBot.Modules.NSFW
InternalHentai(Context.Channel, tag, false); InternalHentai(Context.Channel, tag, false);
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
[RequireUserPermission(ChannelPermission.ManageMessages)]
public async Task AutoHentai(int interval = 0, string tags = null) public async Task AutoHentai(int interval = 0, string tags = null)
{ {
Timer t; Timer t;
@ -188,7 +190,7 @@ namespace NadekoBot.Modules.NSFW
.WithFooter(efb => efb.WithText("e621"))) .WithFooter(efb => efb.WithText("e621")))
.ConfigureAwait(false); .ConfigureAwait(false);
} }
#endif
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
public async Task Cp() public async Task Cp()
{ {
@ -203,7 +205,7 @@ namespace NadekoBot.Modules.NSFW
JToken obj; JToken obj;
using (var http = new HttpClient()) 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); await Context.Channel.SendMessageAsync($"http://media.oboobs.ru/{ obj["preview"].ToString() }").ConfigureAwait(false);
} }
@ -221,7 +223,7 @@ namespace NadekoBot.Modules.NSFW
JToken obj; JToken obj;
using (var http = new HttpClient()) 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); 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); await Context.Channel.SendErrorAsync(ex.Message).ConfigureAwait(false);
} }
} }
#if !GLOBAL_NADEKO
public static Task<string> GetDanbooruImageLink(string tag) => Task.Run(async () => public static Task<string> GetDanbooruImageLink(string tag) => Task.Run(async () =>
{ {
try try
@ -288,4 +290,5 @@ namespace NadekoBot.Modules.NSFW
public static Task<string> GetRule34ImageLink(string tag) => public static Task<string> GetRule34ImageLink(string tag) =>
Searches.Searches.InternalDapiSearch(tag, Searches.Searches.DapiSearchType.Rule34); Searches.Searches.InternalDapiSearch(tag, Searches.Searches.DapiSearchType.Rule34);
} }
#endif
} }

View File

@ -618,9 +618,13 @@ namespace NadekoBot.Modules.Searches
if (usr == null) if (usr == null)
usr = Context.User; usr = Context.User;
var avatarUrl = usr.RealAvatarUrl();
var shortenedAvatarUrl = await NadekoBot.Google.ShortenUrl(avatarUrl).ConfigureAwait(false);
await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor() await Context.Channel.EmbedAsync(new EmbedBuilder().WithOkColor()
.WithTitle($"{usr}'s Avatar") .AddField(efb => efb.WithName("Username").WithValue(usr.ToString()).WithIsInline(false))
.WithImageUrl(usr.AvatarUrl)).ConfigureAwait(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] [NadekoCommand, Usage, Description, Aliases]

View File

@ -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 createdAt = new DateTime(2015, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(guild.Id >> 22);
var sb = new StringBuilder(); var sb = new StringBuilder();
var users = await guild.GetUsersAsync().ConfigureAwait(false); var users = await guild.GetUsersAsync().ConfigureAwait(false);
var features = string.Join("\n", guild.Features);
if (string.IsNullOrWhiteSpace(features))
features = "-";
var embed = new EmbedBuilder() var embed = new EmbedBuilder()
.WithAuthor(eab => eab.WithName("Server Info")) .WithAuthor(eab => eab.WithName("Server Info"))
.WithTitle(guild.Name) .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("**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("**Region**").WithValue(guild.VoiceRegionId.ToString()).WithIsInline(true))
.AddField(fb => fb.WithName("**Roles**").WithValue((guild.Roles.Count - 1).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) .WithImageUrl(guild.IconUrl)
.WithColor(NadekoBot.OkColor); .WithColor(NadekoBot.OkColor);
if (guild.Emojis.Count() > 0) 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); 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)) 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 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("**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)) .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.AvatarUrl) .WithThumbnailUrl(user.RealAvatarUrl())
.WithColor(NadekoBot.OkColor); .WithColor(NadekoBot.OkColor);
await Context.Channel.EmbedAsync(embed).ConfigureAwait(false); await Context.Channel.EmbedAsync(embed).ConfigureAwait(false);
} }

View File

@ -1,5 +1,6 @@
using Discord; using Discord;
using Discord.Commands; using Discord.Commands;
using Discord.Net;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using NadekoBot.Attributes; using NadekoBot.Attributes;
using NadekoBot.Extensions; using NadekoBot.Extensions;
@ -64,7 +65,24 @@ namespace NadekoBot.Modules.Utility
if (oldMsg != null) if (oldMsg != null)
try { await oldMsg.DeleteAsync(); } catch { } 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) { } catch (OperationCanceledException) { }

View File

@ -23,8 +23,8 @@ namespace NadekoBot
{ {
private Logger _log; private Logger _log;
public static Color OkColor { get; } = new Color(0x71cd40); public static Color OkColor { get; }
public static Color ErrorColor { get; } = new Color(0xee281f); public static Color ErrorColor { get; }
public static CommandService CommandService { get; private set; } public static CommandService CommandService { get; private set; }
public static CommandHandler CommandHandler { get; private set; } public static CommandHandler CommandHandler { get; private set; }
@ -49,6 +49,8 @@ namespace NadekoBot
{ {
AllGuildConfigs = uow.GuildConfigs.GetAllGuildConfigs(); AllGuildConfigs = uow.GuildConfigs.GetAllGuildConfigs();
BotConfig = uow.BotConfig.GetOrCreate(); BotConfig = uow.BotConfig.GetOrCreate();
OkColor = new Color(Convert.ToUInt32(BotConfig.OkColor, 16));
ErrorColor = new Color(Convert.ToUInt32(BotConfig.ErrorColor, 16));
} }
} }
@ -67,8 +69,9 @@ namespace NadekoBot
TotalShards = Credentials.TotalShards, TotalShards = Credentials.TotalShards,
ConnectionTimeout = int.MaxValue ConnectionTimeout = int.MaxValue
}); });
#if GLOBAL_NADEKO
Client.Log += Client_Log; Client.Log += Client_Log;
#endif
//initialize Services //initialize Services
CommandService = new CommandService(new CommandServiceConfig() { CommandService = new CommandService(new CommandServiceConfig() {
@ -95,10 +98,8 @@ namespace NadekoBot
//connect //connect
await Client.LoginAsync(TokenType.Bot, Credentials.Token).ConfigureAwait(false); await Client.LoginAsync(TokenType.Bot, Credentials.Token).ConfigureAwait(false);
await Client.ConnectAsync().ConfigureAwait(false); await Client.ConnectAsync().ConfigureAwait(false);
//await Client.DownloadAllUsersAsync().ConfigureAwait(false);
Stats.Initialize(); Stats.Initialize();
#if !GLOBAL_NADEKO
await Client.DownloadAllUsersAsync().ConfigureAwait(false);
#endif
_log.Info("Connected"); _log.Info("Connected");
@ -107,6 +108,7 @@ namespace NadekoBot
ModulePrefixes = new ConcurrentDictionary<string, string>(NadekoBot.BotConfig.ModulePrefixes.OrderByDescending(mp => mp.Prefix.Length).ToDictionary(m => m.ModuleName, m => m.Prefix)); ModulePrefixes = new ConcurrentDictionary<string, string>(NadekoBot.BotConfig.ModulePrefixes.OrderByDescending(mp => mp.Prefix.Length).ToDictionary(m => m.ModuleName, m => m.Prefix));
// start handling messages received in commandhandler // start handling messages received in commandhandler
await CommandHandler.StartHandling().ConfigureAwait(false); await CommandHandler.StartHandling().ConfigureAwait(false);
await CommandService.AddModulesAsync(this.GetType().GetTypeInfo().Assembly).ConfigureAwait(false); await CommandService.AddModulesAsync(this.GetType().GetTypeInfo().Assembly).ConfigureAwait(false);

View File

@ -7079,6 +7079,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&apos;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> /// <summary>
/// Looks up a localized string similar to slowmode. /// Looks up a localized string similar to slowmode.
/// </summary> /// </summary>

View File

@ -2952,4 +2952,31 @@
<data name="startevent_usage" xml:space="preserve"> <data name="startevent_usage" xml:space="preserve">
<value>`{0}startevent flowerreaction`</value> <value>`{0}startevent flowerreaction`</value>
</data> </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>
</root> </root>

View File

@ -30,7 +30,11 @@ namespace NadekoBot.Services
} }
public class CommandHandler public class CommandHandler
{ {
#if GLOBAL_NADEKO
public const int GlobalCommandsCooldown = 1500; public const int GlobalCommandsCooldown = 1500;
#else
public const int GlobalCommandsCooldown = 750;
#endif
private readonly DiscordShardedClient _client; private readonly DiscordShardedClient _client;
private readonly CommandService _commandService; private readonly CommandService _commandService;
@ -119,18 +123,18 @@ namespace NadekoBot.Services
private void LogErroredExecution(SocketUserMessage usrMsg, ExecuteCommandResult exec, SocketTextChannel channel, int ticks) private void LogErroredExecution(SocketUserMessage usrMsg, ExecuteCommandResult exec, SocketTextChannel channel, int ticks)
{ {
_log.Warn("Command Errored after {5}s\n\t" + _log.Warn("Command Errored after {5}s\n\t" +
"User: {0}\n\t" + "User: {0}\n\t" +
"Server: {1}\n\t" + "Server: {1}\n\t" +
"Channel: {2}\n\t" + "Channel: {2}\n\t" +
"Message: {3}\n\t" + "Message: {3}\n\t" +
"Error: {4}", "Error: {4}",
usrMsg.Author + " [" + usrMsg.Author.Id + "]", // {0} usrMsg.Author + " [" + usrMsg.Author.Id + "]", // {0}
(channel == null ? "PRIVATE" : channel.Guild.Name + " [" + channel.Guild.Id + "]"), // {1} (channel == null ? "PRIVATE" : channel.Guild.Name + " [" + channel.Guild.Id + "]"), // {1}
(channel == null ? "PRIVATE" : channel.Name + " [" + channel.Id + "]"), // {2} (channel == null ? "PRIVATE" : channel.Name + " [" + channel.Id + "]"), // {2}
usrMsg.Content,// {3} usrMsg.Content,// {3}
exec.Result.ErrorReason, // {4} exec.Result.ErrorReason, // {4}
ticks * oneThousandth // {5} ticks * oneThousandth // {5}
); );
} }
private async Task<bool> InviteFiltered(IGuild guild, SocketUserMessage usrMsg) private async Task<bool> InviteFiltered(IGuild guild, SocketUserMessage usrMsg)
@ -196,11 +200,6 @@ namespace NadekoBot.Services
// track how many messagges each user is sending // track how many messagges each user is sending
UserMessagesSent.AddOrUpdate(usrMsg.Author.Id, 1, (key, old) => ++old); 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;
var channel = msg.Channel as SocketTextChannel; var channel = msg.Channel as SocketTextChannel;
var guild = channel?.Guild; var guild = channel?.Guild;
@ -367,9 +366,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)) 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)); return new ExecuteCommandResult(cmd, null, await commands[i].ExecuteAsync(context, parseResult, dependencyMap));
} }

View File

@ -25,8 +25,8 @@ namespace NadekoBot.Services.Database.Models
public string CurrencyPluralName { get; set; } = "Nadeko Flowers"; public string CurrencyPluralName { get; set; } = "Nadeko Flowers";
public int TriviaCurrencyReward { get; set; } = 0; public int TriviaCurrencyReward { get; set; } = 0;
public int MinimumBetAmount { get; set; } = 3; public int MinimumBetAmount { get; set; } = 2;
public float BetflipMultiplier { get; set; } = 1.8f; public float BetflipMultiplier { get; set; } = 1.95f;
public int CurrencyDropAmount { get; set; } = 1; public int CurrencyDropAmount { get; set; } = 1;
public float Betroll67Multiplier { get; set; } = 2; public float Betroll67Multiplier { get; set; } = 2;
public float Betroll91Multiplier { get; set; } = 3; public float Betroll91Multiplier { get; set; } = 3;
@ -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"; Nadeko Support Server: https://discord.gg/0ehQwTK2RBjAxzEY";
public int MigrationVersion { get; set; } public int MigrationVersion { get; set; }
public string OkColor { get; set; } = "71cd40";
public string ErrorColor { get; set; } = "ee281f";
} }
public class PlayingStatus :DbEntity public class PlayingStatus :DbEntity

View File

@ -15,7 +15,7 @@ namespace NadekoBot.Services.Impl
private DiscordShardedClient client; private DiscordShardedClient client;
private DateTime started; private DateTime started;
public const string BotVersion = "1.1.1"; public const string BotVersion = "1.1.3";
public string Author => "Kwoth#2560"; public string Author => "Kwoth#2560";
public string Library => "Discord.Net"; public string Library => "Discord.Net";

View File

@ -183,18 +183,18 @@ namespace NadekoBot.Extensions
await (await user.CreateDMChannelAsync().ConfigureAwait(false)).SendMessageAsync(message, isTTS).ConfigureAwait(false); await (await user.CreateDMChannelAsync().ConfigureAwait(false)).SendMessageAsync(message, isTTS).ConfigureAwait(false);
public static async Task<IUserMessage> SendConfirmAsync(this IUser user, string text) 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) 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)); .WithTitle(title).WithUrl(url));
public static async Task<IUserMessage> SendErrorAsync(this IUser user, string title, string error, string url = null) 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)); .WithTitle(title).WithUrl(url));
public static async Task<IUserMessage> SendErrorAsync(this IUser user, string error) 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) => 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); 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); => ch.SendMessageAsync(msg, embed: embed);
public static Task<IUserMessage> SendErrorAsync(this IMessageChannel ch, string title, string error, string url = null, string footer = null) 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))); .WithTitle(title).WithUrl(url).WithFooter(efb => efb.WithText(footer)));
public static Task<IUserMessage> SendErrorAsync(this IMessageChannel ch, string error) 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) 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))); .WithTitle(title).WithUrl(url).WithFooter(efb => efb.WithText(footer)));
public static Task<IUserMessage> SendConfirmAsync(this IMessageChannel ch, string text) 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) 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) public static bool IsDiscordInvite(this string str)
=> filterRegex.IsMatch(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;
}
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 551 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 392 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 553 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 539 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 471 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 542 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 562 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 417 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 597 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 578 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB