mirror of
				https://gitlab.com/Kwoth/nadekobot.git
				synced 2025-11-04 00:34:26 -05:00 
			
		
		
		
	- Re-added .qap / .queueautoplay
- Several strings and commands related to music have been changed - Changed .ms / .movesong to .tm / .trackmove but kept old aliases - Changed ~~song~~ -> rack throughout music module strings - Updated CHANGELOG.md
This commit is contained in:
		@@ -38,6 +38,11 @@ public class MusicPlayerSettings
 | 
			
		||||
    ///     Selected quality preset for the music player
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public QualityPreset QualityPreset { get; set; }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     Whether the bot will automatically queue related songs
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public bool AutoPlay { get; set; }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public enum QualityPreset
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2760
									
								
								src/NadekoBot/Migrations/20220213123633_music-autoplay.Designer.cs
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										2760
									
								
								src/NadekoBot/Migrations/20220213123633_music-autoplay.Designer.cs
									
									
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										69
									
								
								src/NadekoBot/Migrations/20220213123633_music-autoplay.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								src/NadekoBot/Migrations/20220213123633_music-autoplay.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,69 @@
 | 
			
		||||
using Microsoft.EntityFrameworkCore.Migrations;
 | 
			
		||||
 | 
			
		||||
#nullable disable
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Migrations
 | 
			
		||||
{
 | 
			
		||||
    public partial class musicautoplay : Migration
 | 
			
		||||
    {
 | 
			
		||||
        protected override void Up(MigrationBuilder migrationBuilder)
 | 
			
		||||
        {
 | 
			
		||||
            // these 2 settings weren't being used for a long time
 | 
			
		||||
            migrationBuilder.DropColumn(
 | 
			
		||||
                name: "AutoDeleteByeMessages",
 | 
			
		||||
                table: "GuildConfigs");
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.DropColumn(
 | 
			
		||||
                name: "AutoDeleteGreetMessages",
 | 
			
		||||
                table: "GuildConfigs");
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.AlterColumn<long>(
 | 
			
		||||
                name: "Weight",
 | 
			
		||||
                table: "Warnings",
 | 
			
		||||
                type: "INTEGER",
 | 
			
		||||
                nullable: false,
 | 
			
		||||
                defaultValue: 1L,
 | 
			
		||||
                oldClrType: typeof(int),
 | 
			
		||||
                oldType: "INTEGER",
 | 
			
		||||
                oldDefaultValue: 1);
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.AddColumn<bool>(
 | 
			
		||||
                name: "AutoPlay",
 | 
			
		||||
                table: "MusicPlayerSettings",
 | 
			
		||||
                type: "INTEGER",
 | 
			
		||||
                nullable: false,
 | 
			
		||||
                defaultValue: false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void Down(MigrationBuilder migrationBuilder)
 | 
			
		||||
        {
 | 
			
		||||
            migrationBuilder.DropColumn(
 | 
			
		||||
                name: "AutoPlay",
 | 
			
		||||
                table: "MusicPlayerSettings");
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.AlterColumn<int>(
 | 
			
		||||
                name: "Weight",
 | 
			
		||||
                table: "Warnings",
 | 
			
		||||
                type: "INTEGER",
 | 
			
		||||
                nullable: false,
 | 
			
		||||
                defaultValue: 1,
 | 
			
		||||
                oldClrType: typeof(long),
 | 
			
		||||
                oldType: "INTEGER",
 | 
			
		||||
                oldDefaultValue: 1L);
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.AddColumn<bool>(
 | 
			
		||||
                name: "AutoDeleteByeMessages",
 | 
			
		||||
                table: "GuildConfigs",
 | 
			
		||||
                type: "INTEGER",
 | 
			
		||||
                nullable: false,
 | 
			
		||||
                defaultValue: false);
 | 
			
		||||
 | 
			
		||||
            migrationBuilder.AddColumn<bool>(
 | 
			
		||||
                name: "AutoDeleteGreetMessages",
 | 
			
		||||
                table: "GuildConfigs",
 | 
			
		||||
                type: "INTEGER",
 | 
			
		||||
                nullable: false,
 | 
			
		||||
                defaultValue: false);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -15,7 +15,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
        protected override void BuildModel(ModelBuilder modelBuilder)
 | 
			
		||||
        {
 | 
			
		||||
#pragma warning disable 612, 618
 | 
			
		||||
            modelBuilder.HasAnnotation("ProductVersion", "6.0.1");
 | 
			
		||||
            modelBuilder.HasAnnotation("ProductVersion", "6.0.2");
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Db.Models.ClubApplicants", b =>
 | 
			
		||||
                {
 | 
			
		||||
@@ -29,7 +29,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("UserId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("ClubApplicants", (string)null);
 | 
			
		||||
                    b.ToTable("ClubApplicants");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Db.Models.ClubBans", b =>
 | 
			
		||||
@@ -44,7 +44,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("UserId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("ClubBans", (string)null);
 | 
			
		||||
                    b.ToTable("ClubBans");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Db.Models.ClubInfo", b =>
 | 
			
		||||
@@ -86,7 +86,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
                    b.HasIndex("OwnerId")
 | 
			
		||||
                        .IsUnique();
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("Clubs", (string)null);
 | 
			
		||||
                    b.ToTable("Clubs");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Db.Models.DiscordUser", b =>
 | 
			
		||||
@@ -155,7 +155,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("UserId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("DiscordUser", (string)null);
 | 
			
		||||
                    b.ToTable("DiscordUser");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Db.Models.FollowedStream", b =>
 | 
			
		||||
@@ -189,7 +189,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("GuildConfigId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("FollowedStream", (string)null);
 | 
			
		||||
                    b.ToTable("FollowedStream");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiAltSetting", b =>
 | 
			
		||||
@@ -218,7 +218,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
                    b.HasIndex("GuildConfigId")
 | 
			
		||||
                        .IsUnique();
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("AntiAltSetting", (string)null);
 | 
			
		||||
                    b.ToTable("AntiAltSetting");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiRaidSetting", b =>
 | 
			
		||||
@@ -250,7 +250,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
                    b.HasIndex("GuildConfigId")
 | 
			
		||||
                        .IsUnique();
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("AntiRaidSetting", (string)null);
 | 
			
		||||
                    b.ToTable("AntiRaidSetting");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiSpamIgnore", b =>
 | 
			
		||||
@@ -272,7 +272,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("AntiSpamSettingId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("AntiSpamIgnore", (string)null);
 | 
			
		||||
                    b.ToTable("AntiSpamIgnore");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.AntiSpamSetting", b =>
 | 
			
		||||
@@ -304,7 +304,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
                    b.HasIndex("GuildConfigId")
 | 
			
		||||
                        .IsUnique();
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("AntiSpamSetting", (string)null);
 | 
			
		||||
                    b.ToTable("AntiSpamSetting");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.AutoCommand", b =>
 | 
			
		||||
@@ -342,7 +342,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasKey("Id");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("AutoCommands", (string)null);
 | 
			
		||||
                    b.ToTable("AutoCommands");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.AutoTranslateChannel", b =>
 | 
			
		||||
@@ -370,7 +370,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("GuildId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("AutoTranslateChannels", (string)null);
 | 
			
		||||
                    b.ToTable("AutoTranslateChannels");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.AutoTranslateUser", b =>
 | 
			
		||||
@@ -398,7 +398,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasAlternateKey("ChannelId", "UserId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("AutoTranslateUsers", (string)null);
 | 
			
		||||
                    b.ToTable("AutoTranslateUsers");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.BanTemplate", b =>
 | 
			
		||||
@@ -421,7 +421,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
                    b.HasIndex("GuildId")
 | 
			
		||||
                        .IsUnique();
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("BanTemplates", (string)null);
 | 
			
		||||
                    b.ToTable("BanTemplates");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.BlacklistEntry", b =>
 | 
			
		||||
@@ -441,7 +441,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasKey("Id");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("Blacklist", (string)null);
 | 
			
		||||
                    b.ToTable("Blacklist");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.CommandAlias", b =>
 | 
			
		||||
@@ -466,7 +466,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("GuildConfigId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("CommandAlias", (string)null);
 | 
			
		||||
                    b.ToTable("CommandAlias");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.CommandCooldown", b =>
 | 
			
		||||
@@ -491,7 +491,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("GuildConfigId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("CommandCooldown", (string)null);
 | 
			
		||||
                    b.ToTable("CommandCooldown");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.CurrencyTransaction", b =>
 | 
			
		||||
@@ -529,7 +529,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("UserId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("CurrencyTransactions", (string)null);
 | 
			
		||||
                    b.ToTable("CurrencyTransactions");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.DelMsgOnCmdChannel", b =>
 | 
			
		||||
@@ -554,7 +554,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("GuildConfigId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("DelMsgOnCmdChannel", (string)null);
 | 
			
		||||
                    b.ToTable("DelMsgOnCmdChannel");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.DiscordPermOverride", b =>
 | 
			
		||||
@@ -580,7 +580,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
                    b.HasIndex("GuildId", "Command")
 | 
			
		||||
                        .IsUnique();
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("DiscordPermOverrides", (string)null);
 | 
			
		||||
                    b.ToTable("DiscordPermOverrides");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.ExcludedItem", b =>
 | 
			
		||||
@@ -605,7 +605,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("XpSettingsId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("ExcludedItem", (string)null);
 | 
			
		||||
                    b.ToTable("ExcludedItem");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.FeedSub", b =>
 | 
			
		||||
@@ -631,7 +631,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasAlternateKey("GuildConfigId", "Url");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("FeedSub", (string)null);
 | 
			
		||||
                    b.ToTable("FeedSub");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.FilterChannelId", b =>
 | 
			
		||||
@@ -653,7 +653,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("GuildConfigId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("FilterChannelId", (string)null);
 | 
			
		||||
                    b.ToTable("FilterChannelId");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.FilteredWord", b =>
 | 
			
		||||
@@ -675,7 +675,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("GuildConfigId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("FilteredWord", (string)null);
 | 
			
		||||
                    b.ToTable("FilteredWord");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.FilterLinksChannelId", b =>
 | 
			
		||||
@@ -697,7 +697,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("GuildConfigId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("FilterLinksChannelId", (string)null);
 | 
			
		||||
                    b.ToTable("FilterLinksChannelId");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.FilterWordsChannelId", b =>
 | 
			
		||||
@@ -719,7 +719,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("GuildConfigId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("FilterWordsChannelId", (string)null);
 | 
			
		||||
                    b.ToTable("FilterWordsChannelId");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.GCChannelId", b =>
 | 
			
		||||
@@ -741,7 +741,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("GuildConfigId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("GCChannelId", (string)null);
 | 
			
		||||
                    b.ToTable("GCChannelId");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.GroupName", b =>
 | 
			
		||||
@@ -767,7 +767,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
                    b.HasIndex("GuildConfigId", "Number")
 | 
			
		||||
                        .IsUnique();
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("GroupName", (string)null);
 | 
			
		||||
                    b.ToTable("GroupName");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.GuildConfig", b =>
 | 
			
		||||
@@ -779,15 +779,9 @@ namespace NadekoBot.Migrations
 | 
			
		||||
                    b.Property<string>("AutoAssignRoleIds")
 | 
			
		||||
                        .HasColumnType("TEXT");
 | 
			
		||||
 | 
			
		||||
                    b.Property<bool>("AutoDeleteByeMessages")
 | 
			
		||||
                        .HasColumnType("INTEGER");
 | 
			
		||||
 | 
			
		||||
                    b.Property<int>("AutoDeleteByeMessagesTimer")
 | 
			
		||||
                        .HasColumnType("INTEGER");
 | 
			
		||||
 | 
			
		||||
                    b.Property<bool>("AutoDeleteGreetMessages")
 | 
			
		||||
                        .HasColumnType("INTEGER");
 | 
			
		||||
 | 
			
		||||
                    b.Property<int>("AutoDeleteGreetMessagesTimer")
 | 
			
		||||
                        .HasColumnType("INTEGER");
 | 
			
		||||
 | 
			
		||||
@@ -897,7 +891,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("WarnExpireHours");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("GuildConfigs", (string)null);
 | 
			
		||||
                    b.ToTable("GuildConfigs");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredLogItem", b =>
 | 
			
		||||
@@ -923,7 +917,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
                    b.HasIndex("LogSettingId", "LogItemId", "ItemType")
 | 
			
		||||
                        .IsUnique();
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("IgnoredLogChannels", (string)null);
 | 
			
		||||
                    b.ToTable("IgnoredLogChannels");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.IgnoredVoicePresenceChannel", b =>
 | 
			
		||||
@@ -945,7 +939,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("LogSettingId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("IgnoredVoicePresenceCHannels", (string)null);
 | 
			
		||||
                    b.ToTable("IgnoredVoicePresenceCHannels");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.ImageOnlyChannel", b =>
 | 
			
		||||
@@ -968,7 +962,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
                    b.HasIndex("ChannelId")
 | 
			
		||||
                        .IsUnique();
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("ImageOnlyChannels", (string)null);
 | 
			
		||||
                    b.ToTable("ImageOnlyChannels");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.LogSetting", b =>
 | 
			
		||||
@@ -1033,7 +1027,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
                    b.HasIndex("GuildId")
 | 
			
		||||
                        .IsUnique();
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("LogSettings", (string)null);
 | 
			
		||||
                    b.ToTable("LogSettings");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.MusicPlayerSettings", b =>
 | 
			
		||||
@@ -1045,6 +1039,9 @@ namespace NadekoBot.Migrations
 | 
			
		||||
                    b.Property<bool>("AutoDisconnect")
 | 
			
		||||
                        .HasColumnType("INTEGER");
 | 
			
		||||
 | 
			
		||||
                    b.Property<bool>("AutoPlay")
 | 
			
		||||
                        .HasColumnType("INTEGER");
 | 
			
		||||
 | 
			
		||||
                    b.Property<ulong>("GuildId")
 | 
			
		||||
                        .HasColumnType("INTEGER");
 | 
			
		||||
 | 
			
		||||
@@ -1067,7 +1064,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
                    b.HasIndex("GuildId")
 | 
			
		||||
                        .IsUnique();
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("MusicPlayerSettings", (string)null);
 | 
			
		||||
                    b.ToTable("MusicPlayerSettings");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.MusicPlaylist", b =>
 | 
			
		||||
@@ -1090,7 +1087,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasKey("Id");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("MusicPlaylists", (string)null);
 | 
			
		||||
                    b.ToTable("MusicPlaylists");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.MutedUserId", b =>
 | 
			
		||||
@@ -1112,7 +1109,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("GuildConfigId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("MutedUserId", (string)null);
 | 
			
		||||
                    b.ToTable("MutedUserId");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.NadekoExpression", b =>
 | 
			
		||||
@@ -1150,7 +1147,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasKey("Id");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("Expressions", (string)null);
 | 
			
		||||
                    b.ToTable("Expressions");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.NsfwBlacklistedTag", b =>
 | 
			
		||||
@@ -1172,7 +1169,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("GuildId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("NsfwBlacklistedTags", (string)null);
 | 
			
		||||
                    b.ToTable("NsfwBlacklistedTags");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.Permissionv2", b =>
 | 
			
		||||
@@ -1212,7 +1209,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("GuildConfigId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("Permissions", (string)null);
 | 
			
		||||
                    b.ToTable("Permissions");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.PlantedCurrency", b =>
 | 
			
		||||
@@ -1249,7 +1246,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
                    b.HasIndex("MessageId")
 | 
			
		||||
                        .IsUnique();
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("PlantedCurrency", (string)null);
 | 
			
		||||
                    b.ToTable("PlantedCurrency");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.PlaylistSong", b =>
 | 
			
		||||
@@ -1283,7 +1280,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("MusicPlaylistId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("PlaylistSong", (string)null);
 | 
			
		||||
                    b.ToTable("PlaylistSong");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.Poll", b =>
 | 
			
		||||
@@ -1309,7 +1306,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
                    b.HasIndex("GuildId")
 | 
			
		||||
                        .IsUnique();
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("Poll", (string)null);
 | 
			
		||||
                    b.ToTable("Poll");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.PollAnswer", b =>
 | 
			
		||||
@@ -1334,7 +1331,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("PollId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("PollAnswer", (string)null);
 | 
			
		||||
                    b.ToTable("PollAnswer");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.PollVote", b =>
 | 
			
		||||
@@ -1359,7 +1356,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("PollId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("PollVote", (string)null);
 | 
			
		||||
                    b.ToTable("PollVote");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.Quote", b =>
 | 
			
		||||
@@ -1395,7 +1392,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("Keyword");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("Quotes", (string)null);
 | 
			
		||||
                    b.ToTable("Quotes");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.ReactionRole", b =>
 | 
			
		||||
@@ -1420,7 +1417,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("ReactionRoleMessageId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("ReactionRole", (string)null);
 | 
			
		||||
                    b.ToTable("ReactionRole");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.ReactionRoleMessage", b =>
 | 
			
		||||
@@ -1451,7 +1448,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("GuildConfigId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("ReactionRoleMessage", (string)null);
 | 
			
		||||
                    b.ToTable("ReactionRoleMessage");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.Reminder", b =>
 | 
			
		||||
@@ -1485,7 +1482,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("When");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("Reminders", (string)null);
 | 
			
		||||
                    b.ToTable("Reminders");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.Repeater", b =>
 | 
			
		||||
@@ -1520,7 +1517,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasKey("Id");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("Repeaters", (string)null);
 | 
			
		||||
                    b.ToTable("Repeaters");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.RewardedUser", b =>
 | 
			
		||||
@@ -1549,7 +1546,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
                    b.HasIndex("PatreonUserId")
 | 
			
		||||
                        .IsUnique();
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("RewardedUsers", (string)null);
 | 
			
		||||
                    b.ToTable("RewardedUsers");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.RotatingPlayingStatus", b =>
 | 
			
		||||
@@ -1569,7 +1566,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasKey("Id");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("RotatingStatus", (string)null);
 | 
			
		||||
                    b.ToTable("RotatingStatus");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.SelfAssignedRole", b =>
 | 
			
		||||
@@ -1600,7 +1597,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
                    b.HasIndex("GuildId", "RoleId")
 | 
			
		||||
                        .IsUnique();
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("SelfAssignableRoles", (string)null);
 | 
			
		||||
                    b.ToTable("SelfAssignableRoles");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.ShopEntry", b =>
 | 
			
		||||
@@ -1640,7 +1637,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("GuildConfigId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("ShopEntry", (string)null);
 | 
			
		||||
                    b.ToTable("ShopEntry");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.ShopEntryItem", b =>
 | 
			
		||||
@@ -1662,7 +1659,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("ShopEntryId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("ShopEntryItem", (string)null);
 | 
			
		||||
                    b.ToTable("ShopEntryItem");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredRole", b =>
 | 
			
		||||
@@ -1684,7 +1681,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("GuildConfigId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("SlowmodeIgnoredRole", (string)null);
 | 
			
		||||
                    b.ToTable("SlowmodeIgnoredRole");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.SlowmodeIgnoredUser", b =>
 | 
			
		||||
@@ -1706,7 +1703,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("GuildConfigId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("SlowmodeIgnoredUser", (string)null);
 | 
			
		||||
                    b.ToTable("SlowmodeIgnoredUser");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleBlacklistedUser", b =>
 | 
			
		||||
@@ -1731,7 +1728,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("StreamRoleSettingsId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("StreamRoleBlacklistedUser", (string)null);
 | 
			
		||||
                    b.ToTable("StreamRoleBlacklistedUser");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleSettings", b =>
 | 
			
		||||
@@ -1763,7 +1760,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
                    b.HasIndex("GuildConfigId")
 | 
			
		||||
                        .IsUnique();
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("StreamRoleSettings", (string)null);
 | 
			
		||||
                    b.ToTable("StreamRoleSettings");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.StreamRoleWhitelistedUser", b =>
 | 
			
		||||
@@ -1788,7 +1785,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("StreamRoleSettingsId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("StreamRoleWhitelistedUser", (string)null);
 | 
			
		||||
                    b.ToTable("StreamRoleWhitelistedUser");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.UnbanTimer", b =>
 | 
			
		||||
@@ -1813,7 +1810,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("GuildConfigId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("UnbanTimer", (string)null);
 | 
			
		||||
                    b.ToTable("UnbanTimer");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.UnmuteTimer", b =>
 | 
			
		||||
@@ -1838,7 +1835,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("GuildConfigId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("UnmuteTimer", (string)null);
 | 
			
		||||
                    b.ToTable("UnmuteTimer");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.UnroleTimer", b =>
 | 
			
		||||
@@ -1866,7 +1863,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("GuildConfigId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("UnroleTimer", (string)null);
 | 
			
		||||
                    b.ToTable("UnroleTimer");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.UserXpStats", b =>
 | 
			
		||||
@@ -1911,7 +1908,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
                    b.HasIndex("UserId", "GuildId")
 | 
			
		||||
                        .IsUnique();
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("UserXpStats", (string)null);
 | 
			
		||||
                    b.ToTable("UserXpStats");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.VcRoleInfo", b =>
 | 
			
		||||
@@ -1936,7 +1933,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("GuildConfigId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("VcRoleInfo", (string)null);
 | 
			
		||||
                    b.ToTable("VcRoleInfo");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.WaifuInfo", b =>
 | 
			
		||||
@@ -1954,7 +1951,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
                    b.Property<DateTime?>("DateAdded")
 | 
			
		||||
                        .HasColumnType("TEXT");
 | 
			
		||||
 | 
			
		||||
                    b.Property<int>("Price")
 | 
			
		||||
                    b.Property<long>("Price")
 | 
			
		||||
                        .HasColumnType("INTEGER");
 | 
			
		||||
 | 
			
		||||
                    b.Property<int>("WaifuId")
 | 
			
		||||
@@ -1971,7 +1968,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
                    b.HasIndex("WaifuId")
 | 
			
		||||
                        .IsUnique();
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("WaifuInfo", (string)null);
 | 
			
		||||
                    b.ToTable("WaifuInfo");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.WaifuItem", b =>
 | 
			
		||||
@@ -1996,7 +1993,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("WaifuInfoId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("WaifuItem", (string)null);
 | 
			
		||||
                    b.ToTable("WaifuItem");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.WaifuUpdate", b =>
 | 
			
		||||
@@ -2028,7 +2025,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("UserId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("WaifuUpdates", (string)null);
 | 
			
		||||
                    b.ToTable("WaifuUpdates");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.Warning", b =>
 | 
			
		||||
@@ -2058,10 +2055,10 @@ namespace NadekoBot.Migrations
 | 
			
		||||
                    b.Property<ulong>("UserId")
 | 
			
		||||
                        .HasColumnType("INTEGER");
 | 
			
		||||
 | 
			
		||||
                    b.Property<int>("Weight")
 | 
			
		||||
                    b.Property<long>("Weight")
 | 
			
		||||
                        .ValueGeneratedOnAdd()
 | 
			
		||||
                        .HasColumnType("INTEGER")
 | 
			
		||||
                        .HasDefaultValue(1);
 | 
			
		||||
                        .HasDefaultValue(1L);
 | 
			
		||||
 | 
			
		||||
                    b.HasKey("Id");
 | 
			
		||||
 | 
			
		||||
@@ -2071,7 +2068,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("UserId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("Warnings", (string)null);
 | 
			
		||||
                    b.ToTable("Warnings");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.WarningPunishment", b =>
 | 
			
		||||
@@ -2102,7 +2099,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("GuildConfigId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("WarningPunishment", (string)null);
 | 
			
		||||
                    b.ToTable("WarningPunishment");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.XpCurrencyReward", b =>
 | 
			
		||||
@@ -2127,7 +2124,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
 | 
			
		||||
                    b.HasIndex("XpSettingsId");
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("XpCurrencyReward", (string)null);
 | 
			
		||||
                    b.ToTable("XpCurrencyReward");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.XpRoleReward", b =>
 | 
			
		||||
@@ -2156,7 +2153,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
                    b.HasIndex("XpSettingsId", "Level")
 | 
			
		||||
                        .IsUnique();
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("XpRoleReward", (string)null);
 | 
			
		||||
                    b.ToTable("XpRoleReward");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Services.Database.Models.XpSettings", b =>
 | 
			
		||||
@@ -2179,7 +2176,7 @@ namespace NadekoBot.Migrations
 | 
			
		||||
                    b.HasIndex("GuildConfigId")
 | 
			
		||||
                        .IsUnique();
 | 
			
		||||
 | 
			
		||||
                    b.ToTable("XpSettings", (string)null);
 | 
			
		||||
                    b.ToTable("XpSettings");
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            modelBuilder.Entity("NadekoBot.Db.Models.ClubApplicants", b =>
 | 
			
		||||
 
 | 
			
		||||
@@ -103,7 +103,7 @@ public sealed partial class Music : NadekoModule<IMusicService>
 | 
			
		||||
        var (trackInfo, index) = await mp.TryEnqueueTrackAsync(query, ctx.User.ToString(), asNext, forcePlatform);
 | 
			
		||||
        if (trackInfo is null)
 | 
			
		||||
        {
 | 
			
		||||
            await ReplyErrorLocalizedAsync(strs.song_not_found);
 | 
			
		||||
            await ReplyErrorLocalizedAsync(strs.track_not_found);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -111,7 +111,7 @@ public sealed partial class Music : NadekoModule<IMusicService>
 | 
			
		||||
        {
 | 
			
		||||
            var embed = _eb.Create()
 | 
			
		||||
                           .WithOkColor()
 | 
			
		||||
                           .WithAuthor(GetText(strs.queued_song) + " #" + (index + 1), MUSIC_ICON_URL)
 | 
			
		||||
                           .WithAuthor(GetText(strs.queued_track) + " #" + (index + 1), MUSIC_ICON_URL)
 | 
			
		||||
                           .WithDescription($"{trackInfo.PrettyName()}\n{GetText(strs.queue)} ")
 | 
			
		||||
                           .WithFooter(trackInfo.Platform.ToString());
 | 
			
		||||
 | 
			
		||||
@@ -248,7 +248,7 @@ public sealed partial class Music : NadekoModule<IMusicService>
 | 
			
		||||
    [RequireContext(ContextType.Guild)]
 | 
			
		||||
    public async partial Task ListQueue()
 | 
			
		||||
    {
 | 
			
		||||
        // show page with the current song
 | 
			
		||||
        // show page with the current track
 | 
			
		||||
        if (!_service.TryGetMusicPlayer(ctx.Guild.Id, out var mp))
 | 
			
		||||
        {
 | 
			
		||||
            await ReplyErrorLocalizedAsync(strs.no_player);
 | 
			
		||||
@@ -291,8 +291,8 @@ public sealed partial class Music : NadekoModule<IMusicService>
 | 
			
		||||
                add += "🔂 " + GetText(strs.repeating_track) + "\n";
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                // if (mp.Autoplay)
 | 
			
		||||
                //     add += "↪ " + GetText(strs.autoplaying) + "\n";
 | 
			
		||||
                if (mp.AutoPlay)
 | 
			
		||||
                    add += "↪ " + GetText(strs.autoplaying) + "\n";
 | 
			
		||||
                // if (mp.FairPlay && !mp.Autoplay)
 | 
			
		||||
                //     add += " " + GetText(strs.fairplay) + "\n";
 | 
			
		||||
                if (repeatType == PlayerRepeatType.Queue)
 | 
			
		||||
@@ -339,7 +339,7 @@ public sealed partial class Music : NadekoModule<IMusicService>
 | 
			
		||||
 | 
			
		||||
        if (videos.Count == 0)
 | 
			
		||||
        {
 | 
			
		||||
            await ReplyErrorLocalizedAsync(strs.song_not_found);
 | 
			
		||||
            await ReplyErrorLocalizedAsync(strs.track_not_found);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -388,7 +388,7 @@ public sealed partial class Music : NadekoModule<IMusicService>
 | 
			
		||||
    {
 | 
			
		||||
        if (index < 1)
 | 
			
		||||
        {
 | 
			
		||||
            await ReplyErrorLocalizedAsync(strs.removed_song_error);
 | 
			
		||||
            await ReplyErrorLocalizedAsync(strs.removed_track_error);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -402,16 +402,16 @@ public sealed partial class Music : NadekoModule<IMusicService>
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!mp.TryRemoveTrackAt(index - 1, out var song))
 | 
			
		||||
        if (!mp.TryRemoveTrackAt(index - 1, out var track))
 | 
			
		||||
        {
 | 
			
		||||
            await ReplyErrorLocalizedAsync(strs.removed_song_error);
 | 
			
		||||
            await ReplyErrorLocalizedAsync(strs.removed_track_error);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        var embed = _eb.Create()
 | 
			
		||||
                       .WithAuthor(GetText(strs.removed_song) + " #" + index, MUSIC_ICON_URL)
 | 
			
		||||
                       .WithDescription(song.PrettyName())
 | 
			
		||||
                       .WithFooter(song.PrettyInfo())
 | 
			
		||||
                       .WithAuthor(GetText(strs.removed_track) + " #" + index, MUSIC_ICON_URL)
 | 
			
		||||
                       .WithDescription(track.PrettyName())
 | 
			
		||||
                       .WithFooter(track.PrettyInfo())
 | 
			
		||||
                       .WithErrorColor();
 | 
			
		||||
 | 
			
		||||
        await _service.SendToOutputAsync(ctx.Guild.Id, embed);
 | 
			
		||||
@@ -550,7 +550,7 @@ public sealed partial class Music : NadekoModule<IMusicService>
 | 
			
		||||
 | 
			
		||||
    [Cmd]
 | 
			
		||||
    [RequireContext(ContextType.Guild)]
 | 
			
		||||
    public async partial Task MoveSong(int from, int to)
 | 
			
		||||
    public async partial Task TrackMove(int from, int to)
 | 
			
		||||
    {
 | 
			
		||||
        if (--from < 0 || --to < 0 || from == to)
 | 
			
		||||
        {
 | 
			
		||||
@@ -578,7 +578,7 @@ public sealed partial class Music : NadekoModule<IMusicService>
 | 
			
		||||
 | 
			
		||||
        var embed = _eb.Create()
 | 
			
		||||
                       .WithTitle(track.Title.TrimTo(65))
 | 
			
		||||
                       .WithAuthor(GetText(strs.song_moved), MUSIC_ICON_URL)
 | 
			
		||||
                       .WithAuthor(GetText(strs.track_moved), MUSIC_ICON_URL)
 | 
			
		||||
                       .AddField(GetText(strs.from_position), $"#{from + 1}", true)
 | 
			
		||||
                       .AddField(GetText(strs.to_position), $"#{to + 1}", true)
 | 
			
		||||
                       .WithOkColor();
 | 
			
		||||
@@ -744,4 +744,15 @@ public sealed partial class Music : NadekoModule<IMusicService>
 | 
			
		||||
        await _service.SetMusicQualityAsync(ctx.Guild.Id, preset);
 | 
			
		||||
        await ReplyConfirmLocalizedAsync(strs.music_quality_set(Format.Bold(preset.ToString())));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Cmd]
 | 
			
		||||
    [RequireContext(ContextType.Guild)]
 | 
			
		||||
    public async partial Task QueueAutoPlay()
 | 
			
		||||
    {
 | 
			
		||||
        var newValue = await _service.ToggleQueueAutoPlayAsync(ctx.Guild.Id);
 | 
			
		||||
        if (newValue)
 | 
			
		||||
            await ReplyConfirmLocalizedAsync(strs.music_autoplay_on);
 | 
			
		||||
        else
 | 
			
		||||
            await ReplyConfirmLocalizedAsync(strs.music_autoplay_off);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -32,4 +32,5 @@ public interface IMusicService : IPlaceholderProvider
 | 
			
		||||
    Task<bool> ToggleAutoDisconnectAsync(ulong guildId);
 | 
			
		||||
    Task<QualityPreset> GetMusicQualityAsync(ulong guildId);
 | 
			
		||||
    Task SetMusicQualityAsync(ulong guildId, QualityPreset preset);
 | 
			
		||||
    Task<bool> ToggleQueueAutoPlayAsync(ulong guildId);
 | 
			
		||||
}
 | 
			
		||||
@@ -156,7 +156,12 @@ public sealed class MusicService : IMusicService
 | 
			
		||||
 | 
			
		||||
        _outputChannels[guildId] = (defaultChannel, overrideChannel);
 | 
			
		||||
 | 
			
		||||
        var mp = new MusicPlayer(queue, resolver, proxy, settings.QualityPreset);
 | 
			
		||||
        var mp = new MusicPlayer(queue,
 | 
			
		||||
            resolver,
 | 
			
		||||
            proxy,
 | 
			
		||||
            _googleApiService,
 | 
			
		||||
            settings.QualityPreset,
 | 
			
		||||
            settings.AutoPlay);
 | 
			
		||||
 | 
			
		||||
        mp.SetRepeat(settings.PlayerRepeat);
 | 
			
		||||
 | 
			
		||||
@@ -191,7 +196,7 @@ public sealed class MusicService : IMusicService
 | 
			
		||||
            _ = lastFinishedMessage?.DeleteAsync();
 | 
			
		||||
            var embed = _eb.Create()
 | 
			
		||||
                           .WithOkColor()
 | 
			
		||||
                           .WithAuthor(GetText(guildId, strs.finished_song), Music.MUSIC_ICON_URL)
 | 
			
		||||
                           .WithAuthor(GetText(guildId, strs.finished_track), Music.MUSIC_ICON_URL)
 | 
			
		||||
                           .WithDescription(trackInfo.PrettyName())
 | 
			
		||||
                           .WithFooter(trackInfo.PrettyTotalTime());
 | 
			
		||||
 | 
			
		||||
@@ -207,7 +212,7 @@ public sealed class MusicService : IMusicService
 | 
			
		||||
            _ = lastPlayingMessage?.DeleteAsync();
 | 
			
		||||
            var embed = _eb.Create()
 | 
			
		||||
                           .WithOkColor()
 | 
			
		||||
                           .WithAuthor(GetText(guildId, strs.playing_song(index + 1)), Music.MUSIC_ICON_URL)
 | 
			
		||||
                           .WithAuthor(GetText(guildId, strs.playing_track(index + 1)), Music.MUSIC_ICON_URL)
 | 
			
		||||
                           .WithDescription(trackInfo.PrettyName())
 | 
			
		||||
                           .WithFooter($"{mp.PrettyVolume()} | {trackInfo.PrettyInfo()}");
 | 
			
		||||
 | 
			
		||||
@@ -288,7 +293,7 @@ public sealed class MusicService : IMusicService
 | 
			
		||||
 | 
			
		||||
    public IEnumerable<(string Name, Func<string> Func)> GetPlaceholders()
 | 
			
		||||
    {
 | 
			
		||||
        // random song that's playing
 | 
			
		||||
        // random track that's playing
 | 
			
		||||
        yield return ("%music.playing%", () =>
 | 
			
		||||
        {
 | 
			
		||||
            var randomPlayingTrack = _players.Select(x => x.Value.GetCurrentTrack(out _))
 | 
			
		||||
@@ -438,5 +443,17 @@ public sealed class MusicService : IMusicService
 | 
			
		||||
            },
 | 
			
		||||
            preset);
 | 
			
		||||
 | 
			
		||||
    public async Task<bool> ToggleQueueAutoPlayAsync(ulong guildId)
 | 
			
		||||
    {
 | 
			
		||||
        var newValue = false;
 | 
			
		||||
        await ModifySettingsInternalAsync(guildId,
 | 
			
		||||
            (settings, _) => newValue = settings.AutoPlay = !settings.AutoPlay,
 | 
			
		||||
            false);
 | 
			
		||||
 | 
			
		||||
        if (TryGetMusicPlayer(guildId, out var mp))
 | 
			
		||||
            mp.AutoPlay = newValue;
 | 
			
		||||
        return newValue;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #endregion
 | 
			
		||||
}
 | 
			
		||||
@@ -10,6 +10,7 @@ public interface IMusicPlayer : IDisposable
 | 
			
		||||
    bool IsKilled { get; }
 | 
			
		||||
    int CurrentIndex { get; }
 | 
			
		||||
    public PlayerRepeatType Repeat { get; }
 | 
			
		||||
    bool AutoPlay { get; set; }
 | 
			
		||||
 | 
			
		||||
    void Stop();
 | 
			
		||||
    void Clear();
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@
 | 
			
		||||
 | 
			
		||||
public interface ITrackInfo
 | 
			
		||||
{
 | 
			
		||||
    public string Id => string.Empty;
 | 
			
		||||
    public string Title { get; }
 | 
			
		||||
    public string Url { get; }
 | 
			
		||||
    public string Thumbnail { get; }
 | 
			
		||||
 
 | 
			
		||||
@@ -28,6 +28,7 @@ public sealed class MusicPlayer : IMusicPlayer
 | 
			
		||||
    private readonly IMusicQueue _queue;
 | 
			
		||||
    private readonly ITrackResolveProvider _trackResolveProvider;
 | 
			
		||||
    private readonly IVoiceProxy _proxy;
 | 
			
		||||
    private readonly IGoogleApiService _googleApiService;
 | 
			
		||||
    private readonly ISongBuffer _songBuffer;
 | 
			
		||||
 | 
			
		||||
    private bool skipped;
 | 
			
		||||
@@ -35,15 +36,21 @@ public sealed class MusicPlayer : IMusicPlayer
 | 
			
		||||
    private readonly Thread _thread;
 | 
			
		||||
    private readonly Random _rng;
 | 
			
		||||
 | 
			
		||||
    public bool AutoPlay { get; set; }
 | 
			
		||||
 | 
			
		||||
    public MusicPlayer(
 | 
			
		||||
        IMusicQueue queue,
 | 
			
		||||
        ITrackResolveProvider trackResolveProvider,
 | 
			
		||||
        IVoiceProxy proxy,
 | 
			
		||||
        QualityPreset qualityPreset)
 | 
			
		||||
        IGoogleApiService googleApiService,
 | 
			
		||||
        QualityPreset qualityPreset,
 | 
			
		||||
        bool autoPlay)
 | 
			
		||||
    {
 | 
			
		||||
        _queue = queue;
 | 
			
		||||
        _trackResolveProvider = trackResolveProvider;
 | 
			
		||||
        _proxy = proxy;
 | 
			
		||||
        _googleApiService = googleApiService;
 | 
			
		||||
        AutoPlay = autoPlay;
 | 
			
		||||
        _rng = new NadekoRandom();
 | 
			
		||||
 | 
			
		||||
        _vc = GetVoiceClient(qualityPreset);
 | 
			
		||||
@@ -265,7 +272,29 @@ public sealed class MusicPlayer : IMusicPlayer
 | 
			
		||||
            {
 | 
			
		||||
                cancellationTokenSource.Cancel();
 | 
			
		||||
                // turn off green in vc
 | 
			
		||||
 | 
			
		||||
                _ = OnCompleted?.Invoke(this, track);
 | 
			
		||||
                
 | 
			
		||||
                // todo update when settings are changed
 | 
			
		||||
                if (AutoPlay && track.Platform == MusicPlatform.Youtube)
 | 
			
		||||
                {
 | 
			
		||||
                    try
 | 
			
		||||
                    {
 | 
			
		||||
                        var relatedSongs = await _googleApiService.GetRelatedVideosAsync(track.TrackInfo.Id, 5);
 | 
			
		||||
                        var related = relatedSongs.Shuffle().FirstOrDefault();
 | 
			
		||||
                        if (related is not null)
 | 
			
		||||
                        {
 | 
			
		||||
                            var relatedTrack = await _trackResolveProvider.QuerySongAsync(related, MusicPlatform.Youtube);
 | 
			
		||||
                            if (relatedTrack is not null)
 | 
			
		||||
                                EnqueueTrack(relatedTrack, "Autoplay");
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    catch (Exception ex)
 | 
			
		||||
                    {
 | 
			
		||||
                        Log.Warning(ex, "Failed queueing a related song via autoplay");
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                HandleQueuePostTrack();
 | 
			
		||||
                skipped = false;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,30 +1,15 @@
 | 
			
		||||
namespace NadekoBot.Modules.Music;
 | 
			
		||||
 | 
			
		||||
public sealed class RemoteTrackInfo : ITrackInfo
 | 
			
		||||
public sealed record RemoteTrackInfo(
 | 
			
		||||
    string Id,
 | 
			
		||||
    string Title,
 | 
			
		||||
    string Url,
 | 
			
		||||
    string Thumbnail,
 | 
			
		||||
    TimeSpan Duration,
 | 
			
		||||
    MusicPlatform Platform,
 | 
			
		||||
    Func<Task<string?>> _streamFactory) : ITrackInfo
 | 
			
		||||
{
 | 
			
		||||
    public string Title { get; }
 | 
			
		||||
    public string Url { get; }
 | 
			
		||||
    public string Thumbnail { get; }
 | 
			
		||||
    public TimeSpan Duration { get; }
 | 
			
		||||
    public MusicPlatform Platform { get; }
 | 
			
		||||
 | 
			
		||||
    private readonly Func<Task<string?>> _streamFactory;
 | 
			
		||||
 | 
			
		||||
    public RemoteTrackInfo(
 | 
			
		||||
        string title,
 | 
			
		||||
        string url,
 | 
			
		||||
        string thumbnail,
 | 
			
		||||
        TimeSpan duration,
 | 
			
		||||
        MusicPlatform platform,
 | 
			
		||||
        Func<Task<string?>> streamFactory)
 | 
			
		||||
    {
 | 
			
		||||
        _streamFactory = streamFactory;
 | 
			
		||||
        Title = title;
 | 
			
		||||
        Url = url;
 | 
			
		||||
        Thumbnail = thumbnail;
 | 
			
		||||
        Duration = duration;
 | 
			
		||||
        Platform = platform;
 | 
			
		||||
    }
 | 
			
		||||
    private readonly Func<Task<string?>> _streamFactory = _streamFactory;
 | 
			
		||||
 | 
			
		||||
    public async ValueTask<string?> GetStreamUrl()
 | 
			
		||||
        => await _streamFactory();
 | 
			
		||||
 
 | 
			
		||||
@@ -94,7 +94,9 @@ public sealed class YtdlYoutubeResolver : IYoutubeResolver
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private ITrackInfo DataToInfo(in YtTrackData trackData)
 | 
			
		||||
        => new RemoteTrackInfo(trackData.Title,
 | 
			
		||||
        => new RemoteTrackInfo(
 | 
			
		||||
            trackData.Id,
 | 
			
		||||
            trackData.Title,
 | 
			
		||||
            $"https://youtube.com/watch?v={trackData.Id}",
 | 
			
		||||
            trackData.Thumbnail,
 | 
			
		||||
            trackData.Duration,
 | 
			
		||||
 
 | 
			
		||||
@@ -4,8 +4,6 @@ using System.Globalization;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Modules.Searches;
 | 
			
		||||
 | 
			
		||||
// todo weighted warnings fix
 | 
			
		||||
// todo autoplay/fairplay
 | 
			
		||||
public partial class Searches
 | 
			
		||||
{
 | 
			
		||||
    public partial class FinanceCommands : NadekoSubmodule<CryptoService>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
#nullable disable
 | 
			
		||||
// #nullable disable
 | 
			
		||||
// using NadekoBot.Db.Models;
 | 
			
		||||
// using System;
 | 
			
		||||
// using System.Collections.Generic;
 | 
			
		||||
// using System.Linq;
 | 
			
		||||
@@ -10,6 +11,7 @@
 | 
			
		||||
// using NadekoBot.Services.Database.Models;
 | 
			
		||||
// using NadekoBot.Extensions;
 | 
			
		||||
// using Serilog;
 | 
			
		||||
// using TwitchLib.Api;
 | 
			
		||||
// using JsonSerializer = System.Text.Json.JsonSerializer;
 | 
			
		||||
//
 | 
			
		||||
// namespace NadekoBot.Modules.Searches.Common.StreamNotifications.Providers
 | 
			
		||||
@@ -25,33 +27,17 @@
 | 
			
		||||
//         public override FollowedStream.FType Platform => FollowedStream.FType.Twitch;
 | 
			
		||||
//
 | 
			
		||||
//         private (string Token, DateTime Expiry) _token = default;
 | 
			
		||||
//     
 | 
			
		||||
//         private readonly TwitchAPI _api;
 | 
			
		||||
//
 | 
			
		||||
//         public TwitchHelixProvider(IHttpClientFactory httpClientFactory)
 | 
			
		||||
//         {
 | 
			
		||||
//             _httpClientFactory = httpClientFactory;
 | 
			
		||||
//             _api = new TwitchAPI();
 | 
			
		||||
//         }
 | 
			
		||||
//
 | 
			
		||||
//         private async Task EnsureTokenValidAsync()
 | 
			
		||||
//         {
 | 
			
		||||
//             if (_token != default && (DateTime.UtcNow - _token.Expiry) > TimeSpan.FromHours(1))
 | 
			
		||||
//                 return;
 | 
			
		||||
//             => await _api.Auth.GetAccessTokenAsync();
 | 
			
		||||
//
 | 
			
		||||
//             const string clientId = string.Empty;
 | 
			
		||||
//             const string clientSecret = string.Empty;
 | 
			
		||||
//             
 | 
			
		||||
//             var client = _httpClientFactory.CreateClient();
 | 
			
		||||
//             var res = await client.PostAsync("https://id.twitch.tv/oauth2/token" +
 | 
			
		||||
//                                         $"?client_id={clientId}" +
 | 
			
		||||
//                                         $"&client_secret={clientSecret}" +
 | 
			
		||||
//                                         "&grant_type=client_credentials", new StringContent(""));
 | 
			
		||||
//
 | 
			
		||||
//             var data = JsonDocument.Parse(await res.Content.ReadAsStringAsync()).RootElement;
 | 
			
		||||
//
 | 
			
		||||
//             _token = (data.GetProperty("access_token").GetString(),
 | 
			
		||||
//                 DateTime.UtcNow + TimeSpan.FromSeconds(data.GetProperty("expires_in").GetInt32()));
 | 
			
		||||
//
 | 
			
		||||
//         }
 | 
			
		||||
//     
 | 
			
		||||
//         public override Task<bool> IsValidUrl(string url)
 | 
			
		||||
//         {
 | 
			
		||||
//             var match = Regex.Match(url);
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,7 @@ public interface IGoogleApiService
 | 
			
		||||
    Task<IEnumerable<string>> GetVideoLinksByKeywordAsync(string keywords, int count = 1);
 | 
			
		||||
    Task<IEnumerable<(string Name, string Id, string Url)>> GetVideoInfosByKeywordAsync(string keywords, int count = 1);
 | 
			
		||||
    Task<IEnumerable<string>> GetPlaylistIdsByKeywordsAsync(string keywords, int count = 1);
 | 
			
		||||
    Task<IEnumerable<string>> GetRelatedVideosAsync(string url, int count = 1);
 | 
			
		||||
    Task<IEnumerable<string>> GetRelatedVideosAsync(string id, int count = 1, string user = null);
 | 
			
		||||
    Task<IEnumerable<string>> GetPlaylistTracksAsync(string playlistId, int count = 50);
 | 
			
		||||
    Task<IReadOnlyDictionary<string, TimeSpan>> GetVideoDurationsAsync(IEnumerable<string> videoIds);
 | 
			
		||||
    Task<ImageResult> GetImageAsync(string query);
 | 
			
		||||
 
 | 
			
		||||
@@ -194,8 +194,7 @@ public class GoogleApiService : IGoogleApiService, INService
 | 
			
		||||
        return (await query.ExecuteAsync()).Items.Select(i => i.Id.PlaylistId);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // todo future add quota users
 | 
			
		||||
    public async Task<IEnumerable<string>> GetRelatedVideosAsync(string id, int count = 1)
 | 
			
		||||
    public async Task<IEnumerable<string>> GetRelatedVideosAsync(string id, int count = 1, string user = null)
 | 
			
		||||
    {
 | 
			
		||||
        if (string.IsNullOrWhiteSpace(id))
 | 
			
		||||
            throw new ArgumentNullException(nameof(id));
 | 
			
		||||
@@ -207,6 +206,7 @@ public class GoogleApiService : IGoogleApiService, INService
 | 
			
		||||
        query.MaxResults = count;
 | 
			
		||||
        query.RelatedToVideoId = id;
 | 
			
		||||
        query.Type = "video";
 | 
			
		||||
        query.QuotaUser = user;
 | 
			
		||||
        return (await query.ExecuteAsync()).Items.Select(i => "http://www.youtube.com/watch?v=" + i.Id.VideoId);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -472,13 +472,19 @@ trackremove:
 | 
			
		||||
- songremove
 | 
			
		||||
- srm
 | 
			
		||||
- trackremove
 | 
			
		||||
movesong:
 | 
			
		||||
- trm
 | 
			
		||||
trackmove:
 | 
			
		||||
- trackmove
 | 
			
		||||
- tm
 | 
			
		||||
- movesong
 | 
			
		||||
- ms
 | 
			
		||||
queuerepeat:
 | 
			
		||||
- queuerepeat
 | 
			
		||||
- qrp
 | 
			
		||||
- rpl
 | 
			
		||||
queueautoplay:
 | 
			
		||||
- queueautoplay
 | 
			
		||||
- qap
 | 
			
		||||
save:
 | 
			
		||||
- save
 | 
			
		||||
streamrole:
 | 
			
		||||
 
 | 
			
		||||
@@ -849,7 +849,7 @@ trackremove:
 | 
			
		||||
    - "5"
 | 
			
		||||
    - "all"
 | 
			
		||||
    - ""
 | 
			
		||||
movesong:
 | 
			
		||||
trackmove:
 | 
			
		||||
  desc: "Moves a song from one position to another."
 | 
			
		||||
  args:
 | 
			
		||||
    - "5 3"
 | 
			
		||||
@@ -888,7 +888,7 @@ deleteplaylist:
 | 
			
		||||
  desc: "Deletes a saved playlist using its id. Works only if you made it or if you are the bot owner."
 | 
			
		||||
  args:
 | 
			
		||||
    - "5"
 | 
			
		||||
autoplay:
 | 
			
		||||
queueautoplay:
 | 
			
		||||
  desc: "Toggles autoplay - When the song is finished, automatically queue a related Youtube song. (Works only for Youtube songs and when queue is empty)"
 | 
			
		||||
  args:
 | 
			
		||||
    - ""
 | 
			
		||||
 
 | 
			
		||||
@@ -354,10 +354,10 @@
 | 
			
		||||
  "ttt_time_expired": "Time expired!",
 | 
			
		||||
  "ttt_users_move": "{0}'s move",
 | 
			
		||||
  "vs": "{0} vs {1}",
 | 
			
		||||
  "attempting_to_queue": "Attempting to queue {0} songs...",
 | 
			
		||||
  "attempting_to_queue": "Attempting to queue {0} tracks...",
 | 
			
		||||
  "dir_queue_complete": "Directory queue complete.",
 | 
			
		||||
  "fairplay": "Fairplay",
 | 
			
		||||
  "finished_song": "Finished song",
 | 
			
		||||
  "finished_track": "Track Finished",
 | 
			
		||||
  "fp_disabled": "Fair play disabled.",
 | 
			
		||||
  "fp_enabled": "Fair play enabled.",
 | 
			
		||||
  "from_position": "From position",
 | 
			
		||||
@@ -366,8 +366,8 @@
 | 
			
		||||
  "no_player": "No active music player.",
 | 
			
		||||
  "no_search_results": "No search results.",
 | 
			
		||||
  "player_queue": "Player queue - Page {0}/{1}",
 | 
			
		||||
  "playing_song": "Playing song #{0}",
 | 
			
		||||
  "playlists": "`#{0}` - **{1}** by *{2}* ({3} songs)",
 | 
			
		||||
  "playing_track": "Playing track #{0}",
 | 
			
		||||
  "playlists": "`#{0}` - **{1}** by *{2}* ({3} tracks)",
 | 
			
		||||
  "playlists_page": "Page {0} of saved playlists",
 | 
			
		||||
  "playlist_deleted": "Playlist deleted.",
 | 
			
		||||
  "playlist_delete_fail": "Failed to delete that playlist. It either doesn't exist, or you are not its author.",
 | 
			
		||||
@@ -375,17 +375,20 @@
 | 
			
		||||
  "playlist_queue_complete": "Playlist queue complete.",
 | 
			
		||||
  "playlist_saved": "Playlist saved",
 | 
			
		||||
  "queue": "Queue",
 | 
			
		||||
  "queued_song": "Queued song",
 | 
			
		||||
  "queued_track": "Queued track",
 | 
			
		||||
  "queue_cleared": "Music queue cleared.",
 | 
			
		||||
  "removed_song": "Removed song",
 | 
			
		||||
  "removed_track": "Removed track",
 | 
			
		||||
  "repeating_none": "Player will stop once the end of queue is reached.",
 | 
			
		||||
  "repeating_queue": "Player will repeat the queue.",
 | 
			
		||||
  "repeating_track": "Player will keep repeating the same track.",
 | 
			
		||||
  "set_music_channel": "I will now output playing, finished, paused and removed songs in this channel.",
 | 
			
		||||
  "unset_music_channel": "I will now output playing, finished, paused and removed songs of the newly created music players in the channel music was started from.",
 | 
			
		||||
  "autoplaying": "Automatically adds related tracks.",
 | 
			
		||||
  "set_music_channel": "I will now output playing, finished, paused and removed tracks in this channel.",
 | 
			
		||||
  "unset_music_channel": "I will now output playing, finished, paused and removed tracks of the newly created music players in the channel music was started from.",
 | 
			
		||||
  "current_music_quality": "Currently set music quality is: {0}",
 | 
			
		||||
  "music_quality_set": "Music quality has been set to {0}. You will have to destroy and restart music player for the change to take effect.",
 | 
			
		||||
  "song_moved": "Song moved",
 | 
			
		||||
  "music_autoplay_on": "Music autoplay enabled. I will automatically queue related tracks after each track finishes playing.",
 | 
			
		||||
  "music_autoplay_off": "Music autoplay disabled.",
 | 
			
		||||
  "track_moved": "Track moved",
 | 
			
		||||
  "to_position": "To position",
 | 
			
		||||
  "volume_input_invalid": "Volume must be between 0 and 100",
 | 
			
		||||
  "volume_set": "Volume set to {0}%",
 | 
			
		||||
@@ -731,7 +734,7 @@
 | 
			
		||||
  "timezone_not_found": "Timezone not found. Use \"timezones\" command to see the list of available timezones.",
 | 
			
		||||
  "timezones_available": "Available Timezones",
 | 
			
		||||
  "perm_override": "Users will need {0} permission in order to run {1} command.",
 | 
			
		||||
  "song_not_found": "No song found.",
 | 
			
		||||
  "track_not_found": "No track found.",
 | 
			
		||||
  "define_unknown": "Can't find the definition for that term.",
 | 
			
		||||
  "verbose_errors_enabled": "Incorrectly used commands will now show errors.",
 | 
			
		||||
  "verbose_errors_disabled": "Incorrectly used commands will no longer show errors.",
 | 
			
		||||
@@ -741,7 +744,7 @@
 | 
			
		||||
  "module": "Module: {0}",
 | 
			
		||||
  "hangman_stopped": "Hangman game stopped.",
 | 
			
		||||
  "queue_stopped": "Player is stopped. Use {0} command to start playing.",
 | 
			
		||||
  "removed_song_error": "Song on that index doesn't exist",
 | 
			
		||||
  "removed_track_error": "Track on that index doesn't exist",
 | 
			
		||||
  "queue_shuffled": "Music queue has been shuffled.",
 | 
			
		||||
  "warnings_list": "List of all warned users on the server",
 | 
			
		||||
  "redacted_too_long": "Redacted because it's too long.",
 | 
			
		||||
@@ -873,8 +876,8 @@
 | 
			
		||||
  "rafflecur_joined": "User {0} joined the raffle",
 | 
			
		||||
  "rafflecur_already_joined": "You have already joined this raffle or the value you used is not valid.",
 | 
			
		||||
  "rafflecur_ended": "{0} raffle ended. {1} won {2}!",
 | 
			
		||||
  "autodc_enable": "I will disconnect from the voice channel when there are no more songs to play.",
 | 
			
		||||
  "autodc_disable": "I will no longer disconnect from the voice channel when there are no more songs to play.",
 | 
			
		||||
  "autodc_enable": "I will disconnect from the voice channel when there are no more tracks to play.",
 | 
			
		||||
  "autodc_disable": "I will no longer disconnect from the voice channel when there are no more tracks to play.",
 | 
			
		||||
  "timely_none": "Bot owner didn't specify a timely reward.",
 | 
			
		||||
  "timely_already_claimed": "You've already claimed your timely reward. You can get it again in {0}.",
 | 
			
		||||
  "timely": "You've claimed your {0}. You can claim again in {1}h",
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user